41254 lines
1.5 MiB
Vendored
41254 lines
1.5 MiB
Vendored
/******/ (() => { // webpackBootstrap
|
|
/******/ var __webpack_modules__ = ({
|
|
|
|
/***/ "./node_modules/@vue/compiler-core/dist/compiler-core.esm-bundler.js":
|
|
/*!***************************************************************************!*\
|
|
!*** ./node_modules/@vue/compiler-core/dist/compiler-core.esm-bundler.js ***!
|
|
\***************************************************************************/
|
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ "generateCodeFrame": () => (/* reexport safe */ _vue_shared__WEBPACK_IMPORTED_MODULE_0__.generateCodeFrame),
|
|
/* harmony export */ "BASE_TRANSITION": () => (/* binding */ BASE_TRANSITION),
|
|
/* harmony export */ "CAMELIZE": () => (/* binding */ CAMELIZE),
|
|
/* harmony export */ "CAPITALIZE": () => (/* binding */ CAPITALIZE),
|
|
/* harmony export */ "CREATE_BLOCK": () => (/* binding */ CREATE_BLOCK),
|
|
/* harmony export */ "CREATE_COMMENT": () => (/* binding */ CREATE_COMMENT),
|
|
/* harmony export */ "CREATE_ELEMENT_BLOCK": () => (/* binding */ CREATE_ELEMENT_BLOCK),
|
|
/* harmony export */ "CREATE_ELEMENT_VNODE": () => (/* binding */ CREATE_ELEMENT_VNODE),
|
|
/* harmony export */ "CREATE_SLOTS": () => (/* binding */ CREATE_SLOTS),
|
|
/* harmony export */ "CREATE_STATIC": () => (/* binding */ CREATE_STATIC),
|
|
/* harmony export */ "CREATE_TEXT": () => (/* binding */ CREATE_TEXT),
|
|
/* harmony export */ "CREATE_VNODE": () => (/* binding */ CREATE_VNODE),
|
|
/* harmony export */ "FRAGMENT": () => (/* binding */ FRAGMENT),
|
|
/* harmony export */ "GUARD_REACTIVE_PROPS": () => (/* binding */ GUARD_REACTIVE_PROPS),
|
|
/* harmony export */ "IS_MEMO_SAME": () => (/* binding */ IS_MEMO_SAME),
|
|
/* harmony export */ "IS_REF": () => (/* binding */ IS_REF),
|
|
/* harmony export */ "KEEP_ALIVE": () => (/* binding */ KEEP_ALIVE),
|
|
/* harmony export */ "MERGE_PROPS": () => (/* binding */ MERGE_PROPS),
|
|
/* harmony export */ "NORMALIZE_CLASS": () => (/* binding */ NORMALIZE_CLASS),
|
|
/* harmony export */ "NORMALIZE_PROPS": () => (/* binding */ NORMALIZE_PROPS),
|
|
/* harmony export */ "NORMALIZE_STYLE": () => (/* binding */ NORMALIZE_STYLE),
|
|
/* harmony export */ "OPEN_BLOCK": () => (/* binding */ OPEN_BLOCK),
|
|
/* harmony export */ "POP_SCOPE_ID": () => (/* binding */ POP_SCOPE_ID),
|
|
/* harmony export */ "PUSH_SCOPE_ID": () => (/* binding */ PUSH_SCOPE_ID),
|
|
/* harmony export */ "RENDER_LIST": () => (/* binding */ RENDER_LIST),
|
|
/* harmony export */ "RENDER_SLOT": () => (/* binding */ RENDER_SLOT),
|
|
/* harmony export */ "RESOLVE_COMPONENT": () => (/* binding */ RESOLVE_COMPONENT),
|
|
/* harmony export */ "RESOLVE_DIRECTIVE": () => (/* binding */ RESOLVE_DIRECTIVE),
|
|
/* harmony export */ "RESOLVE_DYNAMIC_COMPONENT": () => (/* binding */ RESOLVE_DYNAMIC_COMPONENT),
|
|
/* harmony export */ "RESOLVE_FILTER": () => (/* binding */ RESOLVE_FILTER),
|
|
/* harmony export */ "SET_BLOCK_TRACKING": () => (/* binding */ SET_BLOCK_TRACKING),
|
|
/* harmony export */ "SUSPENSE": () => (/* binding */ SUSPENSE),
|
|
/* harmony export */ "TELEPORT": () => (/* binding */ TELEPORT),
|
|
/* harmony export */ "TO_DISPLAY_STRING": () => (/* binding */ TO_DISPLAY_STRING),
|
|
/* harmony export */ "TO_HANDLERS": () => (/* binding */ TO_HANDLERS),
|
|
/* harmony export */ "TO_HANDLER_KEY": () => (/* binding */ TO_HANDLER_KEY),
|
|
/* harmony export */ "UNREF": () => (/* binding */ UNREF),
|
|
/* harmony export */ "WITH_CTX": () => (/* binding */ WITH_CTX),
|
|
/* harmony export */ "WITH_DIRECTIVES": () => (/* binding */ WITH_DIRECTIVES),
|
|
/* harmony export */ "WITH_MEMO": () => (/* binding */ WITH_MEMO),
|
|
/* harmony export */ "WITH_SCOPE_ID": () => (/* binding */ WITH_SCOPE_ID),
|
|
/* harmony export */ "advancePositionWithClone": () => (/* binding */ advancePositionWithClone),
|
|
/* harmony export */ "advancePositionWithMutation": () => (/* binding */ advancePositionWithMutation),
|
|
/* harmony export */ "assert": () => (/* binding */ assert),
|
|
/* harmony export */ "baseCompile": () => (/* binding */ baseCompile),
|
|
/* harmony export */ "baseParse": () => (/* binding */ baseParse),
|
|
/* harmony export */ "buildProps": () => (/* binding */ buildProps),
|
|
/* harmony export */ "buildSlots": () => (/* binding */ buildSlots),
|
|
/* harmony export */ "checkCompatEnabled": () => (/* binding */ checkCompatEnabled),
|
|
/* harmony export */ "createArrayExpression": () => (/* binding */ createArrayExpression),
|
|
/* harmony export */ "createAssignmentExpression": () => (/* binding */ createAssignmentExpression),
|
|
/* harmony export */ "createBlockStatement": () => (/* binding */ createBlockStatement),
|
|
/* harmony export */ "createCacheExpression": () => (/* binding */ createCacheExpression),
|
|
/* harmony export */ "createCallExpression": () => (/* binding */ createCallExpression),
|
|
/* harmony export */ "createCompilerError": () => (/* binding */ createCompilerError),
|
|
/* harmony export */ "createCompoundExpression": () => (/* binding */ createCompoundExpression),
|
|
/* harmony export */ "createConditionalExpression": () => (/* binding */ createConditionalExpression),
|
|
/* harmony export */ "createForLoopParams": () => (/* binding */ createForLoopParams),
|
|
/* harmony export */ "createFunctionExpression": () => (/* binding */ createFunctionExpression),
|
|
/* harmony export */ "createIfStatement": () => (/* binding */ createIfStatement),
|
|
/* harmony export */ "createInterpolation": () => (/* binding */ createInterpolation),
|
|
/* harmony export */ "createObjectExpression": () => (/* binding */ createObjectExpression),
|
|
/* harmony export */ "createObjectProperty": () => (/* binding */ createObjectProperty),
|
|
/* harmony export */ "createReturnStatement": () => (/* binding */ createReturnStatement),
|
|
/* harmony export */ "createRoot": () => (/* binding */ createRoot),
|
|
/* harmony export */ "createSequenceExpression": () => (/* binding */ createSequenceExpression),
|
|
/* harmony export */ "createSimpleExpression": () => (/* binding */ createSimpleExpression),
|
|
/* harmony export */ "createStructuralDirectiveTransform": () => (/* binding */ createStructuralDirectiveTransform),
|
|
/* harmony export */ "createTemplateLiteral": () => (/* binding */ createTemplateLiteral),
|
|
/* harmony export */ "createTransformContext": () => (/* binding */ createTransformContext),
|
|
/* harmony export */ "createVNodeCall": () => (/* binding */ createVNodeCall),
|
|
/* harmony export */ "extractIdentifiers": () => (/* binding */ extractIdentifiers),
|
|
/* harmony export */ "findDir": () => (/* binding */ findDir),
|
|
/* harmony export */ "findProp": () => (/* binding */ findProp),
|
|
/* harmony export */ "generate": () => (/* binding */ generate),
|
|
/* harmony export */ "getBaseTransformPreset": () => (/* binding */ getBaseTransformPreset),
|
|
/* harmony export */ "getInnerRange": () => (/* binding */ getInnerRange),
|
|
/* harmony export */ "getMemoedVNodeCall": () => (/* binding */ getMemoedVNodeCall),
|
|
/* harmony export */ "getVNodeBlockHelper": () => (/* binding */ getVNodeBlockHelper),
|
|
/* harmony export */ "getVNodeHelper": () => (/* binding */ getVNodeHelper),
|
|
/* harmony export */ "hasDynamicKeyVBind": () => (/* binding */ hasDynamicKeyVBind),
|
|
/* harmony export */ "hasScopeRef": () => (/* binding */ hasScopeRef),
|
|
/* harmony export */ "helperNameMap": () => (/* binding */ helperNameMap),
|
|
/* harmony export */ "injectProp": () => (/* binding */ injectProp),
|
|
/* harmony export */ "isBindKey": () => (/* binding */ isBindKey),
|
|
/* harmony export */ "isBuiltInType": () => (/* binding */ isBuiltInType),
|
|
/* harmony export */ "isCoreComponent": () => (/* binding */ isCoreComponent),
|
|
/* harmony export */ "isFunctionType": () => (/* binding */ isFunctionType),
|
|
/* harmony export */ "isInDestructureAssignment": () => (/* binding */ isInDestructureAssignment),
|
|
/* harmony export */ "isMemberExpression": () => (/* binding */ isMemberExpression),
|
|
/* harmony export */ "isReferencedIdentifier": () => (/* binding */ isReferencedIdentifier),
|
|
/* harmony export */ "isSimpleIdentifier": () => (/* binding */ isSimpleIdentifier),
|
|
/* harmony export */ "isSlotOutlet": () => (/* binding */ isSlotOutlet),
|
|
/* harmony export */ "isStaticExp": () => (/* binding */ isStaticExp),
|
|
/* harmony export */ "isStaticProperty": () => (/* binding */ isStaticProperty),
|
|
/* harmony export */ "isStaticPropertyKey": () => (/* binding */ isStaticPropertyKey),
|
|
/* harmony export */ "isTemplateNode": () => (/* binding */ isTemplateNode),
|
|
/* harmony export */ "isText": () => (/* binding */ isText),
|
|
/* harmony export */ "isVSlot": () => (/* binding */ isVSlot),
|
|
/* harmony export */ "locStub": () => (/* binding */ locStub),
|
|
/* harmony export */ "makeBlock": () => (/* binding */ makeBlock),
|
|
/* harmony export */ "noopDirectiveTransform": () => (/* binding */ noopDirectiveTransform),
|
|
/* harmony export */ "processExpression": () => (/* binding */ processExpression),
|
|
/* harmony export */ "processFor": () => (/* binding */ processFor),
|
|
/* harmony export */ "processIf": () => (/* binding */ processIf),
|
|
/* harmony export */ "processSlotOutlet": () => (/* binding */ processSlotOutlet),
|
|
/* harmony export */ "registerRuntimeHelpers": () => (/* binding */ registerRuntimeHelpers),
|
|
/* harmony export */ "resolveComponentType": () => (/* binding */ resolveComponentType),
|
|
/* harmony export */ "toValidAssetId": () => (/* binding */ toValidAssetId),
|
|
/* harmony export */ "trackSlotScopes": () => (/* binding */ trackSlotScopes),
|
|
/* harmony export */ "trackVForSlotScopes": () => (/* binding */ trackVForSlotScopes),
|
|
/* harmony export */ "transform": () => (/* binding */ transform),
|
|
/* harmony export */ "transformBind": () => (/* binding */ transformBind),
|
|
/* harmony export */ "transformElement": () => (/* binding */ transformElement),
|
|
/* harmony export */ "transformExpression": () => (/* binding */ transformExpression),
|
|
/* harmony export */ "transformModel": () => (/* binding */ transformModel),
|
|
/* harmony export */ "transformOn": () => (/* binding */ transformOn),
|
|
/* harmony export */ "traverseNode": () => (/* binding */ traverseNode),
|
|
/* harmony export */ "walkBlockDeclarations": () => (/* binding */ walkBlockDeclarations),
|
|
/* harmony export */ "walkFunctionParams": () => (/* binding */ walkFunctionParams),
|
|
/* harmony export */ "walkIdentifiers": () => (/* binding */ walkIdentifiers),
|
|
/* harmony export */ "warnDeprecation": () => (/* binding */ warnDeprecation)
|
|
/* harmony export */ });
|
|
/* harmony import */ var _vue_shared__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @vue/shared */ "./node_modules/@vue/shared/dist/shared.esm-bundler.js");
|
|
|
|
|
|
|
|
function defaultOnError(error) {
|
|
throw error;
|
|
}
|
|
function defaultOnWarn(msg) {
|
|
( true) && console.warn(`[Vue warn] ${msg.message}`);
|
|
}
|
|
function createCompilerError(code, loc, messages, additionalMessage) {
|
|
const msg = true
|
|
? (messages || errorMessages)[code] + (additionalMessage || ``)
|
|
: 0;
|
|
const error = new SyntaxError(String(msg));
|
|
error.code = code;
|
|
error.loc = loc;
|
|
return error;
|
|
}
|
|
const errorMessages = {
|
|
// parse errors
|
|
[0 /* ABRUPT_CLOSING_OF_EMPTY_COMMENT */]: 'Illegal comment.',
|
|
[1 /* CDATA_IN_HTML_CONTENT */]: 'CDATA section is allowed only in XML context.',
|
|
[2 /* DUPLICATE_ATTRIBUTE */]: 'Duplicate attribute.',
|
|
[3 /* END_TAG_WITH_ATTRIBUTES */]: 'End tag cannot have attributes.',
|
|
[4 /* END_TAG_WITH_TRAILING_SOLIDUS */]: "Illegal '/' in tags.",
|
|
[5 /* EOF_BEFORE_TAG_NAME */]: 'Unexpected EOF in tag.',
|
|
[6 /* EOF_IN_CDATA */]: 'Unexpected EOF in CDATA section.',
|
|
[7 /* EOF_IN_COMMENT */]: 'Unexpected EOF in comment.',
|
|
[8 /* EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT */]: 'Unexpected EOF in script.',
|
|
[9 /* EOF_IN_TAG */]: 'Unexpected EOF in tag.',
|
|
[10 /* INCORRECTLY_CLOSED_COMMENT */]: 'Incorrectly closed comment.',
|
|
[11 /* INCORRECTLY_OPENED_COMMENT */]: 'Incorrectly opened comment.',
|
|
[12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */]: "Illegal tag name. Use '<' to print '<'.",
|
|
[13 /* MISSING_ATTRIBUTE_VALUE */]: 'Attribute value was expected.',
|
|
[14 /* MISSING_END_TAG_NAME */]: 'End tag name was expected.',
|
|
[15 /* MISSING_WHITESPACE_BETWEEN_ATTRIBUTES */]: 'Whitespace was expected.',
|
|
[16 /* NESTED_COMMENT */]: "Unexpected '<!--' in comment.",
|
|
[17 /* UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME */]: 'Attribute name cannot contain U+0022 ("), U+0027 (\'), and U+003C (<).',
|
|
[18 /* UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE */]: 'Unquoted attribute value cannot contain U+0022 ("), U+0027 (\'), U+003C (<), U+003D (=), and U+0060 (`).',
|
|
[19 /* UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME */]: "Attribute name cannot start with '='.",
|
|
[21 /* UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME */]: "'<?' is allowed only in XML context.",
|
|
[20 /* UNEXPECTED_NULL_CHARACTER */]: `Unexpected null cahracter.`,
|
|
[22 /* UNEXPECTED_SOLIDUS_IN_TAG */]: "Illegal '/' in tags.",
|
|
// Vue-specific parse errors
|
|
[23 /* X_INVALID_END_TAG */]: 'Invalid end tag.',
|
|
[24 /* X_MISSING_END_TAG */]: 'Element is missing end tag.',
|
|
[25 /* X_MISSING_INTERPOLATION_END */]: 'Interpolation end sign was not found.',
|
|
[26 /* X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END */]: 'End bracket for dynamic directive argument was not found. ' +
|
|
'Note that dynamic directive argument cannot contain spaces.',
|
|
// transform errors
|
|
[27 /* X_V_IF_NO_EXPRESSION */]: `v-if/v-else-if is missing expression.`,
|
|
[28 /* X_V_IF_SAME_KEY */]: `v-if/else branches must use unique keys.`,
|
|
[29 /* X_V_ELSE_NO_ADJACENT_IF */]: `v-else/v-else-if has no adjacent v-if.`,
|
|
[30 /* X_V_FOR_NO_EXPRESSION */]: `v-for is missing expression.`,
|
|
[31 /* X_V_FOR_MALFORMED_EXPRESSION */]: `v-for has invalid expression.`,
|
|
[32 /* X_V_FOR_TEMPLATE_KEY_PLACEMENT */]: `<template v-for> key should be placed on the <template> tag.`,
|
|
[33 /* X_V_BIND_NO_EXPRESSION */]: `v-bind is missing expression.`,
|
|
[34 /* X_V_ON_NO_EXPRESSION */]: `v-on is missing expression.`,
|
|
[35 /* X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET */]: `Unexpected custom directive on <slot> outlet.`,
|
|
[36 /* X_V_SLOT_MIXED_SLOT_USAGE */]: `Mixed v-slot usage on both the component and nested <template>.` +
|
|
`When there are multiple named slots, all slots should use <template> ` +
|
|
`syntax to avoid scope ambiguity.`,
|
|
[37 /* X_V_SLOT_DUPLICATE_SLOT_NAMES */]: `Duplicate slot names found. `,
|
|
[38 /* X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN */]: `Extraneous children found when component already has explicitly named ` +
|
|
`default slot. These children will be ignored.`,
|
|
[39 /* X_V_SLOT_MISPLACED */]: `v-slot can only be used on components or <template> tags.`,
|
|
[40 /* X_V_MODEL_NO_EXPRESSION */]: `v-model is missing expression.`,
|
|
[41 /* X_V_MODEL_MALFORMED_EXPRESSION */]: `v-model value must be a valid JavaScript member expression.`,
|
|
[42 /* X_V_MODEL_ON_SCOPE_VARIABLE */]: `v-model cannot be used on v-for or v-slot scope variables because they are not writable.`,
|
|
[43 /* X_INVALID_EXPRESSION */]: `Error parsing JavaScript expression: `,
|
|
[44 /* X_KEEP_ALIVE_INVALID_CHILDREN */]: `<KeepAlive> expects exactly one child component.`,
|
|
// generic errors
|
|
[45 /* X_PREFIX_ID_NOT_SUPPORTED */]: `"prefixIdentifiers" option is not supported in this build of compiler.`,
|
|
[46 /* X_MODULE_MODE_NOT_SUPPORTED */]: `ES module mode is not supported in this build of compiler.`,
|
|
[47 /* X_CACHE_HANDLER_NOT_SUPPORTED */]: `"cacheHandlers" option is only supported when the "prefixIdentifiers" option is enabled.`,
|
|
[48 /* X_SCOPE_ID_NOT_SUPPORTED */]: `"scopeId" option is only supported in module mode.`,
|
|
// just to fullfill types
|
|
[49 /* __EXTEND_POINT__ */]: ``
|
|
};
|
|
|
|
const FRAGMENT = Symbol(( true) ? `Fragment` : 0);
|
|
const TELEPORT = Symbol(( true) ? `Teleport` : 0);
|
|
const SUSPENSE = Symbol(( true) ? `Suspense` : 0);
|
|
const KEEP_ALIVE = Symbol(( true) ? `KeepAlive` : 0);
|
|
const BASE_TRANSITION = Symbol(( true) ? `BaseTransition` : 0);
|
|
const OPEN_BLOCK = Symbol(( true) ? `openBlock` : 0);
|
|
const CREATE_BLOCK = Symbol(( true) ? `createBlock` : 0);
|
|
const CREATE_ELEMENT_BLOCK = Symbol(( true) ? `createElementBlock` : 0);
|
|
const CREATE_VNODE = Symbol(( true) ? `createVNode` : 0);
|
|
const CREATE_ELEMENT_VNODE = Symbol(( true) ? `createElementVNode` : 0);
|
|
const CREATE_COMMENT = Symbol(( true) ? `createCommentVNode` : 0);
|
|
const CREATE_TEXT = Symbol(( true) ? `createTextVNode` : 0);
|
|
const CREATE_STATIC = Symbol(( true) ? `createStaticVNode` : 0);
|
|
const RESOLVE_COMPONENT = Symbol(( true) ? `resolveComponent` : 0);
|
|
const RESOLVE_DYNAMIC_COMPONENT = Symbol(( true) ? `resolveDynamicComponent` : 0);
|
|
const RESOLVE_DIRECTIVE = Symbol(( true) ? `resolveDirective` : 0);
|
|
const RESOLVE_FILTER = Symbol(( true) ? `resolveFilter` : 0);
|
|
const WITH_DIRECTIVES = Symbol(( true) ? `withDirectives` : 0);
|
|
const RENDER_LIST = Symbol(( true) ? `renderList` : 0);
|
|
const RENDER_SLOT = Symbol(( true) ? `renderSlot` : 0);
|
|
const CREATE_SLOTS = Symbol(( true) ? `createSlots` : 0);
|
|
const TO_DISPLAY_STRING = Symbol(( true) ? `toDisplayString` : 0);
|
|
const MERGE_PROPS = Symbol(( true) ? `mergeProps` : 0);
|
|
const NORMALIZE_CLASS = Symbol(( true) ? `normalizeClass` : 0);
|
|
const NORMALIZE_STYLE = Symbol(( true) ? `normalizeStyle` : 0);
|
|
const NORMALIZE_PROPS = Symbol(( true) ? `normalizeProps` : 0);
|
|
const GUARD_REACTIVE_PROPS = Symbol(( true) ? `guardReactiveProps` : 0);
|
|
const TO_HANDLERS = Symbol(( true) ? `toHandlers` : 0);
|
|
const CAMELIZE = Symbol(( true) ? `camelize` : 0);
|
|
const CAPITALIZE = Symbol(( true) ? `capitalize` : 0);
|
|
const TO_HANDLER_KEY = Symbol(( true) ? `toHandlerKey` : 0);
|
|
const SET_BLOCK_TRACKING = Symbol(( true) ? `setBlockTracking` : 0);
|
|
const PUSH_SCOPE_ID = Symbol(( true) ? `pushScopeId` : 0);
|
|
const POP_SCOPE_ID = Symbol(( true) ? `popScopeId` : 0);
|
|
const WITH_SCOPE_ID = Symbol(( true) ? `withScopeId` : 0);
|
|
const WITH_CTX = Symbol(( true) ? `withCtx` : 0);
|
|
const UNREF = Symbol(( true) ? `unref` : 0);
|
|
const IS_REF = Symbol(( true) ? `isRef` : 0);
|
|
const WITH_MEMO = Symbol(( true) ? `withMemo` : 0);
|
|
const IS_MEMO_SAME = Symbol(( true) ? `isMemoSame` : 0);
|
|
// Name mapping for runtime helpers that need to be imported from 'vue' in
|
|
// generated code. Make sure these are correctly exported in the runtime!
|
|
// Using `any` here because TS doesn't allow symbols as index type.
|
|
const helperNameMap = {
|
|
[FRAGMENT]: `Fragment`,
|
|
[TELEPORT]: `Teleport`,
|
|
[SUSPENSE]: `Suspense`,
|
|
[KEEP_ALIVE]: `KeepAlive`,
|
|
[BASE_TRANSITION]: `BaseTransition`,
|
|
[OPEN_BLOCK]: `openBlock`,
|
|
[CREATE_BLOCK]: `createBlock`,
|
|
[CREATE_ELEMENT_BLOCK]: `createElementBlock`,
|
|
[CREATE_VNODE]: `createVNode`,
|
|
[CREATE_ELEMENT_VNODE]: `createElementVNode`,
|
|
[CREATE_COMMENT]: `createCommentVNode`,
|
|
[CREATE_TEXT]: `createTextVNode`,
|
|
[CREATE_STATIC]: `createStaticVNode`,
|
|
[RESOLVE_COMPONENT]: `resolveComponent`,
|
|
[RESOLVE_DYNAMIC_COMPONENT]: `resolveDynamicComponent`,
|
|
[RESOLVE_DIRECTIVE]: `resolveDirective`,
|
|
[RESOLVE_FILTER]: `resolveFilter`,
|
|
[WITH_DIRECTIVES]: `withDirectives`,
|
|
[RENDER_LIST]: `renderList`,
|
|
[RENDER_SLOT]: `renderSlot`,
|
|
[CREATE_SLOTS]: `createSlots`,
|
|
[TO_DISPLAY_STRING]: `toDisplayString`,
|
|
[MERGE_PROPS]: `mergeProps`,
|
|
[NORMALIZE_CLASS]: `normalizeClass`,
|
|
[NORMALIZE_STYLE]: `normalizeStyle`,
|
|
[NORMALIZE_PROPS]: `normalizeProps`,
|
|
[GUARD_REACTIVE_PROPS]: `guardReactiveProps`,
|
|
[TO_HANDLERS]: `toHandlers`,
|
|
[CAMELIZE]: `camelize`,
|
|
[CAPITALIZE]: `capitalize`,
|
|
[TO_HANDLER_KEY]: `toHandlerKey`,
|
|
[SET_BLOCK_TRACKING]: `setBlockTracking`,
|
|
[PUSH_SCOPE_ID]: `pushScopeId`,
|
|
[POP_SCOPE_ID]: `popScopeId`,
|
|
[WITH_SCOPE_ID]: `withScopeId`,
|
|
[WITH_CTX]: `withCtx`,
|
|
[UNREF]: `unref`,
|
|
[IS_REF]: `isRef`,
|
|
[WITH_MEMO]: `withMemo`,
|
|
[IS_MEMO_SAME]: `isMemoSame`
|
|
};
|
|
function registerRuntimeHelpers(helpers) {
|
|
Object.getOwnPropertySymbols(helpers).forEach(s => {
|
|
helperNameMap[s] = helpers[s];
|
|
});
|
|
}
|
|
|
|
// AST Utilities ---------------------------------------------------------------
|
|
// Some expressions, e.g. sequence and conditional expressions, are never
|
|
// associated with template nodes, so their source locations are just a stub.
|
|
// Container types like CompoundExpression also don't need a real location.
|
|
const locStub = {
|
|
source: '',
|
|
start: { line: 1, column: 1, offset: 0 },
|
|
end: { line: 1, column: 1, offset: 0 }
|
|
};
|
|
function createRoot(children, loc = locStub) {
|
|
return {
|
|
type: 0 /* ROOT */,
|
|
children,
|
|
helpers: [],
|
|
components: [],
|
|
directives: [],
|
|
hoists: [],
|
|
imports: [],
|
|
cached: 0,
|
|
temps: 0,
|
|
codegenNode: undefined,
|
|
loc
|
|
};
|
|
}
|
|
function createVNodeCall(context, tag, props, children, patchFlag, dynamicProps, directives, isBlock = false, disableTracking = false, isComponent = false, loc = locStub) {
|
|
if (context) {
|
|
if (isBlock) {
|
|
context.helper(OPEN_BLOCK);
|
|
context.helper(getVNodeBlockHelper(context.inSSR, isComponent));
|
|
}
|
|
else {
|
|
context.helper(getVNodeHelper(context.inSSR, isComponent));
|
|
}
|
|
if (directives) {
|
|
context.helper(WITH_DIRECTIVES);
|
|
}
|
|
}
|
|
return {
|
|
type: 13 /* VNODE_CALL */,
|
|
tag,
|
|
props,
|
|
children,
|
|
patchFlag,
|
|
dynamicProps,
|
|
directives,
|
|
isBlock,
|
|
disableTracking,
|
|
isComponent,
|
|
loc
|
|
};
|
|
}
|
|
function createArrayExpression(elements, loc = locStub) {
|
|
return {
|
|
type: 17 /* JS_ARRAY_EXPRESSION */,
|
|
loc,
|
|
elements
|
|
};
|
|
}
|
|
function createObjectExpression(properties, loc = locStub) {
|
|
return {
|
|
type: 15 /* JS_OBJECT_EXPRESSION */,
|
|
loc,
|
|
properties
|
|
};
|
|
}
|
|
function createObjectProperty(key, value) {
|
|
return {
|
|
type: 16 /* JS_PROPERTY */,
|
|
loc: locStub,
|
|
key: (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isString)(key) ? createSimpleExpression(key, true) : key,
|
|
value
|
|
};
|
|
}
|
|
function createSimpleExpression(content, isStatic = false, loc = locStub, constType = 0 /* NOT_CONSTANT */) {
|
|
return {
|
|
type: 4 /* SIMPLE_EXPRESSION */,
|
|
loc,
|
|
content,
|
|
isStatic,
|
|
constType: isStatic ? 3 /* CAN_STRINGIFY */ : constType
|
|
};
|
|
}
|
|
function createInterpolation(content, loc) {
|
|
return {
|
|
type: 5 /* INTERPOLATION */,
|
|
loc,
|
|
content: (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isString)(content)
|
|
? createSimpleExpression(content, false, loc)
|
|
: content
|
|
};
|
|
}
|
|
function createCompoundExpression(children, loc = locStub) {
|
|
return {
|
|
type: 8 /* COMPOUND_EXPRESSION */,
|
|
loc,
|
|
children
|
|
};
|
|
}
|
|
function createCallExpression(callee, args = [], loc = locStub) {
|
|
return {
|
|
type: 14 /* JS_CALL_EXPRESSION */,
|
|
loc,
|
|
callee,
|
|
arguments: args
|
|
};
|
|
}
|
|
function createFunctionExpression(params, returns = undefined, newline = false, isSlot = false, loc = locStub) {
|
|
return {
|
|
type: 18 /* JS_FUNCTION_EXPRESSION */,
|
|
params,
|
|
returns,
|
|
newline,
|
|
isSlot,
|
|
loc
|
|
};
|
|
}
|
|
function createConditionalExpression(test, consequent, alternate, newline = true) {
|
|
return {
|
|
type: 19 /* JS_CONDITIONAL_EXPRESSION */,
|
|
test,
|
|
consequent,
|
|
alternate,
|
|
newline,
|
|
loc: locStub
|
|
};
|
|
}
|
|
function createCacheExpression(index, value, isVNode = false) {
|
|
return {
|
|
type: 20 /* JS_CACHE_EXPRESSION */,
|
|
index,
|
|
value,
|
|
isVNode,
|
|
loc: locStub
|
|
};
|
|
}
|
|
function createBlockStatement(body) {
|
|
return {
|
|
type: 21 /* JS_BLOCK_STATEMENT */,
|
|
body,
|
|
loc: locStub
|
|
};
|
|
}
|
|
function createTemplateLiteral(elements) {
|
|
return {
|
|
type: 22 /* JS_TEMPLATE_LITERAL */,
|
|
elements,
|
|
loc: locStub
|
|
};
|
|
}
|
|
function createIfStatement(test, consequent, alternate) {
|
|
return {
|
|
type: 23 /* JS_IF_STATEMENT */,
|
|
test,
|
|
consequent,
|
|
alternate,
|
|
loc: locStub
|
|
};
|
|
}
|
|
function createAssignmentExpression(left, right) {
|
|
return {
|
|
type: 24 /* JS_ASSIGNMENT_EXPRESSION */,
|
|
left,
|
|
right,
|
|
loc: locStub
|
|
};
|
|
}
|
|
function createSequenceExpression(expressions) {
|
|
return {
|
|
type: 25 /* JS_SEQUENCE_EXPRESSION */,
|
|
expressions,
|
|
loc: locStub
|
|
};
|
|
}
|
|
function createReturnStatement(returns) {
|
|
return {
|
|
type: 26 /* JS_RETURN_STATEMENT */,
|
|
returns,
|
|
loc: locStub
|
|
};
|
|
}
|
|
|
|
const isStaticExp = (p) => p.type === 4 /* SIMPLE_EXPRESSION */ && p.isStatic;
|
|
const isBuiltInType = (tag, expected) => tag === expected || tag === (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.hyphenate)(expected);
|
|
function isCoreComponent(tag) {
|
|
if (isBuiltInType(tag, 'Teleport')) {
|
|
return TELEPORT;
|
|
}
|
|
else if (isBuiltInType(tag, 'Suspense')) {
|
|
return SUSPENSE;
|
|
}
|
|
else if (isBuiltInType(tag, 'KeepAlive')) {
|
|
return KEEP_ALIVE;
|
|
}
|
|
else if (isBuiltInType(tag, 'BaseTransition')) {
|
|
return BASE_TRANSITION;
|
|
}
|
|
}
|
|
const nonIdentifierRE = /^\d|[^\$\w]/;
|
|
const isSimpleIdentifier = (name) => !nonIdentifierRE.test(name);
|
|
const validFirstIdentCharRE = /[A-Za-z_$\xA0-\uFFFF]/;
|
|
const validIdentCharRE = /[\.\?\w$\xA0-\uFFFF]/;
|
|
const whitespaceRE = /\s+[.[]\s*|\s*[.[]\s+/g;
|
|
/**
|
|
* Simple lexer to check if an expression is a member expression. This is
|
|
* lax and only checks validity at the root level (i.e. does not validate exps
|
|
* inside square brackets), but it's ok since these are only used on template
|
|
* expressions and false positives are invalid expressions in the first place.
|
|
*/
|
|
const isMemberExpression = (path) => {
|
|
// remove whitespaces around . or [ first
|
|
path = path.trim().replace(whitespaceRE, s => s.trim());
|
|
let state = 0 /* inMemberExp */;
|
|
let stateStack = [];
|
|
let currentOpenBracketCount = 0;
|
|
let currentOpenParensCount = 0;
|
|
let currentStringType = null;
|
|
for (let i = 0; i < path.length; i++) {
|
|
const char = path.charAt(i);
|
|
switch (state) {
|
|
case 0 /* inMemberExp */:
|
|
if (char === '[') {
|
|
stateStack.push(state);
|
|
state = 1 /* inBrackets */;
|
|
currentOpenBracketCount++;
|
|
}
|
|
else if (char === '(') {
|
|
stateStack.push(state);
|
|
state = 2 /* inParens */;
|
|
currentOpenParensCount++;
|
|
}
|
|
else if (!(i === 0 ? validFirstIdentCharRE : validIdentCharRE).test(char)) {
|
|
return false;
|
|
}
|
|
break;
|
|
case 1 /* inBrackets */:
|
|
if (char === `'` || char === `"` || char === '`') {
|
|
stateStack.push(state);
|
|
state = 3 /* inString */;
|
|
currentStringType = char;
|
|
}
|
|
else if (char === `[`) {
|
|
currentOpenBracketCount++;
|
|
}
|
|
else if (char === `]`) {
|
|
if (!--currentOpenBracketCount) {
|
|
state = stateStack.pop();
|
|
}
|
|
}
|
|
break;
|
|
case 2 /* inParens */:
|
|
if (char === `'` || char === `"` || char === '`') {
|
|
stateStack.push(state);
|
|
state = 3 /* inString */;
|
|
currentStringType = char;
|
|
}
|
|
else if (char === `(`) {
|
|
currentOpenParensCount++;
|
|
}
|
|
else if (char === `)`) {
|
|
// if the exp ends as a call then it should not be considered valid
|
|
if (i === path.length - 1) {
|
|
return false;
|
|
}
|
|
if (!--currentOpenParensCount) {
|
|
state = stateStack.pop();
|
|
}
|
|
}
|
|
break;
|
|
case 3 /* inString */:
|
|
if (char === currentStringType) {
|
|
state = stateStack.pop();
|
|
currentStringType = null;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
return !currentOpenBracketCount && !currentOpenParensCount;
|
|
};
|
|
function getInnerRange(loc, offset, length) {
|
|
const source = loc.source.substr(offset, length);
|
|
const newLoc = {
|
|
source,
|
|
start: advancePositionWithClone(loc.start, loc.source, offset),
|
|
end: loc.end
|
|
};
|
|
if (length != null) {
|
|
newLoc.end = advancePositionWithClone(loc.start, loc.source, offset + length);
|
|
}
|
|
return newLoc;
|
|
}
|
|
function advancePositionWithClone(pos, source, numberOfCharacters = source.length) {
|
|
return advancePositionWithMutation((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.extend)({}, pos), source, numberOfCharacters);
|
|
}
|
|
// advance by mutation without cloning (for performance reasons), since this
|
|
// gets called a lot in the parser
|
|
function advancePositionWithMutation(pos, source, numberOfCharacters = source.length) {
|
|
let linesCount = 0;
|
|
let lastNewLinePos = -1;
|
|
for (let i = 0; i < numberOfCharacters; i++) {
|
|
if (source.charCodeAt(i) === 10 /* newline char code */) {
|
|
linesCount++;
|
|
lastNewLinePos = i;
|
|
}
|
|
}
|
|
pos.offset += numberOfCharacters;
|
|
pos.line += linesCount;
|
|
pos.column =
|
|
lastNewLinePos === -1
|
|
? pos.column + numberOfCharacters
|
|
: numberOfCharacters - lastNewLinePos;
|
|
return pos;
|
|
}
|
|
function assert(condition, msg) {
|
|
/* istanbul ignore if */
|
|
if (!condition) {
|
|
throw new Error(msg || `unexpected compiler condition`);
|
|
}
|
|
}
|
|
function findDir(node, name, allowEmpty = false) {
|
|
for (let i = 0; i < node.props.length; i++) {
|
|
const p = node.props[i];
|
|
if (p.type === 7 /* DIRECTIVE */ &&
|
|
(allowEmpty || p.exp) &&
|
|
((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isString)(name) ? p.name === name : name.test(p.name))) {
|
|
return p;
|
|
}
|
|
}
|
|
}
|
|
function findProp(node, name, dynamicOnly = false, allowEmpty = false) {
|
|
for (let i = 0; i < node.props.length; i++) {
|
|
const p = node.props[i];
|
|
if (p.type === 6 /* ATTRIBUTE */) {
|
|
if (dynamicOnly)
|
|
continue;
|
|
if (p.name === name && (p.value || allowEmpty)) {
|
|
return p;
|
|
}
|
|
}
|
|
else if (p.name === 'bind' &&
|
|
(p.exp || allowEmpty) &&
|
|
isBindKey(p.arg, name)) {
|
|
return p;
|
|
}
|
|
}
|
|
}
|
|
function isBindKey(arg, name) {
|
|
return !!(arg && isStaticExp(arg) && arg.content === name);
|
|
}
|
|
function hasDynamicKeyVBind(node) {
|
|
return node.props.some(p => p.type === 7 /* DIRECTIVE */ &&
|
|
p.name === 'bind' &&
|
|
(!p.arg || // v-bind="obj"
|
|
p.arg.type !== 4 /* SIMPLE_EXPRESSION */ || // v-bind:[_ctx.foo]
|
|
!p.arg.isStatic) // v-bind:[foo]
|
|
);
|
|
}
|
|
function isText(node) {
|
|
return node.type === 5 /* INTERPOLATION */ || node.type === 2 /* TEXT */;
|
|
}
|
|
function isVSlot(p) {
|
|
return p.type === 7 /* DIRECTIVE */ && p.name === 'slot';
|
|
}
|
|
function isTemplateNode(node) {
|
|
return (node.type === 1 /* ELEMENT */ && node.tagType === 3 /* TEMPLATE */);
|
|
}
|
|
function isSlotOutlet(node) {
|
|
return node.type === 1 /* ELEMENT */ && node.tagType === 2 /* SLOT */;
|
|
}
|
|
function getVNodeHelper(ssr, isComponent) {
|
|
return ssr || isComponent ? CREATE_VNODE : CREATE_ELEMENT_VNODE;
|
|
}
|
|
function getVNodeBlockHelper(ssr, isComponent) {
|
|
return ssr || isComponent ? CREATE_BLOCK : CREATE_ELEMENT_BLOCK;
|
|
}
|
|
const propsHelperSet = new Set([NORMALIZE_PROPS, GUARD_REACTIVE_PROPS]);
|
|
function getUnnormalizedProps(props, callPath = []) {
|
|
if (props &&
|
|
!(0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isString)(props) &&
|
|
props.type === 14 /* JS_CALL_EXPRESSION */) {
|
|
const callee = props.callee;
|
|
if (!(0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isString)(callee) && propsHelperSet.has(callee)) {
|
|
return getUnnormalizedProps(props.arguments[0], callPath.concat(props));
|
|
}
|
|
}
|
|
return [props, callPath];
|
|
}
|
|
function injectProp(node, prop, context) {
|
|
let propsWithInjection;
|
|
const originalProps = node.type === 13 /* VNODE_CALL */ ? node.props : node.arguments[2];
|
|
/**
|
|
* 1. mergeProps(...)
|
|
* 2. toHandlers(...)
|
|
* 3. normalizeProps(...)
|
|
* 4. normalizeProps(guardReactiveProps(...))
|
|
*
|
|
* we need to get the real props before normalization
|
|
*/
|
|
let props = originalProps;
|
|
let callPath = [];
|
|
let parentCall;
|
|
if (props &&
|
|
!(0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isString)(props) &&
|
|
props.type === 14 /* JS_CALL_EXPRESSION */) {
|
|
const ret = getUnnormalizedProps(props);
|
|
props = ret[0];
|
|
callPath = ret[1];
|
|
parentCall = callPath[callPath.length - 1];
|
|
}
|
|
if (props == null || (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isString)(props)) {
|
|
propsWithInjection = createObjectExpression([prop]);
|
|
}
|
|
else if (props.type === 14 /* JS_CALL_EXPRESSION */) {
|
|
// merged props... add ours
|
|
// only inject key to object literal if it's the first argument so that
|
|
// if doesn't override user provided keys
|
|
const first = props.arguments[0];
|
|
if (!(0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isString)(first) && first.type === 15 /* JS_OBJECT_EXPRESSION */) {
|
|
first.properties.unshift(prop);
|
|
}
|
|
else {
|
|
if (props.callee === TO_HANDLERS) {
|
|
// #2366
|
|
propsWithInjection = createCallExpression(context.helper(MERGE_PROPS), [
|
|
createObjectExpression([prop]),
|
|
props
|
|
]);
|
|
}
|
|
else {
|
|
props.arguments.unshift(createObjectExpression([prop]));
|
|
}
|
|
}
|
|
!propsWithInjection && (propsWithInjection = props);
|
|
}
|
|
else if (props.type === 15 /* JS_OBJECT_EXPRESSION */) {
|
|
let alreadyExists = false;
|
|
// check existing key to avoid overriding user provided keys
|
|
if (prop.key.type === 4 /* SIMPLE_EXPRESSION */) {
|
|
const propKeyName = prop.key.content;
|
|
alreadyExists = props.properties.some(p => p.key.type === 4 /* SIMPLE_EXPRESSION */ &&
|
|
p.key.content === propKeyName);
|
|
}
|
|
if (!alreadyExists) {
|
|
props.properties.unshift(prop);
|
|
}
|
|
propsWithInjection = props;
|
|
}
|
|
else {
|
|
// single v-bind with expression, return a merged replacement
|
|
propsWithInjection = createCallExpression(context.helper(MERGE_PROPS), [
|
|
createObjectExpression([prop]),
|
|
props
|
|
]);
|
|
// in the case of nested helper call, e.g. `normalizeProps(guardReactiveProps(props))`,
|
|
// it will be rewritten as `normalizeProps(mergeProps({ key: 0 }, props))`,
|
|
// the `guardReactiveProps` will no longer be needed
|
|
if (parentCall && parentCall.callee === GUARD_REACTIVE_PROPS) {
|
|
parentCall = callPath[callPath.length - 2];
|
|
}
|
|
}
|
|
if (node.type === 13 /* VNODE_CALL */) {
|
|
if (parentCall) {
|
|
parentCall.arguments[0] = propsWithInjection;
|
|
}
|
|
else {
|
|
node.props = propsWithInjection;
|
|
}
|
|
}
|
|
else {
|
|
if (parentCall) {
|
|
parentCall.arguments[0] = propsWithInjection;
|
|
}
|
|
else {
|
|
node.arguments[2] = propsWithInjection;
|
|
}
|
|
}
|
|
}
|
|
function toValidAssetId(name, type) {
|
|
// see issue#4422, we need adding identifier on validAssetId if variable `name` has specific character
|
|
return `_${type}_${name.replace(/[^\w]/g, (searchValue, replaceValue) => {
|
|
return searchValue === '-' ? '_' : name.charCodeAt(replaceValue).toString();
|
|
})}`;
|
|
}
|
|
// Check if a node contains expressions that reference current context scope ids
|
|
function hasScopeRef(node, ids) {
|
|
if (!node || Object.keys(ids).length === 0) {
|
|
return false;
|
|
}
|
|
switch (node.type) {
|
|
case 1 /* ELEMENT */:
|
|
for (let i = 0; i < node.props.length; i++) {
|
|
const p = node.props[i];
|
|
if (p.type === 7 /* DIRECTIVE */ &&
|
|
(hasScopeRef(p.arg, ids) || hasScopeRef(p.exp, ids))) {
|
|
return true;
|
|
}
|
|
}
|
|
return node.children.some(c => hasScopeRef(c, ids));
|
|
case 11 /* FOR */:
|
|
if (hasScopeRef(node.source, ids)) {
|
|
return true;
|
|
}
|
|
return node.children.some(c => hasScopeRef(c, ids));
|
|
case 9 /* IF */:
|
|
return node.branches.some(b => hasScopeRef(b, ids));
|
|
case 10 /* IF_BRANCH */:
|
|
if (hasScopeRef(node.condition, ids)) {
|
|
return true;
|
|
}
|
|
return node.children.some(c => hasScopeRef(c, ids));
|
|
case 4 /* SIMPLE_EXPRESSION */:
|
|
return (!node.isStatic &&
|
|
isSimpleIdentifier(node.content) &&
|
|
!!ids[node.content]);
|
|
case 8 /* COMPOUND_EXPRESSION */:
|
|
return node.children.some(c => (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isObject)(c) && hasScopeRef(c, ids));
|
|
case 5 /* INTERPOLATION */:
|
|
case 12 /* TEXT_CALL */:
|
|
return hasScopeRef(node.content, ids);
|
|
case 2 /* TEXT */:
|
|
case 3 /* COMMENT */:
|
|
return false;
|
|
default:
|
|
if ((true)) ;
|
|
return false;
|
|
}
|
|
}
|
|
function getMemoedVNodeCall(node) {
|
|
if (node.type === 14 /* JS_CALL_EXPRESSION */ && node.callee === WITH_MEMO) {
|
|
return node.arguments[1].returns;
|
|
}
|
|
else {
|
|
return node;
|
|
}
|
|
}
|
|
function makeBlock(node, { helper, removeHelper, inSSR }) {
|
|
if (!node.isBlock) {
|
|
node.isBlock = true;
|
|
removeHelper(getVNodeHelper(inSSR, node.isComponent));
|
|
helper(OPEN_BLOCK);
|
|
helper(getVNodeBlockHelper(inSSR, node.isComponent));
|
|
}
|
|
}
|
|
|
|
const deprecationData = {
|
|
["COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */]: {
|
|
message: `Platform-native elements with "is" prop will no longer be ` +
|
|
`treated as components in Vue 3 unless the "is" value is explicitly ` +
|
|
`prefixed with "vue:".`,
|
|
link: `https://v3.vuejs.org/guide/migration/custom-elements-interop.html`
|
|
},
|
|
["COMPILER_V_BIND_SYNC" /* COMPILER_V_BIND_SYNC */]: {
|
|
message: key => `.sync modifier for v-bind has been removed. Use v-model with ` +
|
|
`argument instead. \`v-bind:${key}.sync\` should be changed to ` +
|
|
`\`v-model:${key}\`.`,
|
|
link: `https://v3.vuejs.org/guide/migration/v-model.html`
|
|
},
|
|
["COMPILER_V_BIND_PROP" /* COMPILER_V_BIND_PROP */]: {
|
|
message: `.prop modifier for v-bind has been removed and no longer necessary. ` +
|
|
`Vue 3 will automatically set a binding as DOM property when appropriate.`
|
|
},
|
|
["COMPILER_V_BIND_OBJECT_ORDER" /* COMPILER_V_BIND_OBJECT_ORDER */]: {
|
|
message: `v-bind="obj" usage is now order sensitive and behaves like JavaScript ` +
|
|
`object spread: it will now overwrite an existing non-mergeable attribute ` +
|
|
`that appears before v-bind in the case of conflict. ` +
|
|
`To retain 2.x behavior, move v-bind to make it the first attribute. ` +
|
|
`You can also suppress this warning if the usage is intended.`,
|
|
link: `https://v3.vuejs.org/guide/migration/v-bind.html`
|
|
},
|
|
["COMPILER_V_ON_NATIVE" /* COMPILER_V_ON_NATIVE */]: {
|
|
message: `.native modifier for v-on has been removed as is no longer necessary.`,
|
|
link: `https://v3.vuejs.org/guide/migration/v-on-native-modifier-removed.html`
|
|
},
|
|
["COMPILER_V_IF_V_FOR_PRECEDENCE" /* COMPILER_V_IF_V_FOR_PRECEDENCE */]: {
|
|
message: `v-if / v-for precedence when used on the same element has changed ` +
|
|
`in Vue 3: v-if now takes higher precedence and will no longer have ` +
|
|
`access to v-for scope variables. It is best to avoid the ambiguity ` +
|
|
`with <template> tags or use a computed property that filters v-for ` +
|
|
`data source.`,
|
|
link: `https://v3.vuejs.org/guide/migration/v-if-v-for.html`
|
|
},
|
|
["COMPILER_V_FOR_REF" /* COMPILER_V_FOR_REF */]: {
|
|
message: `Ref usage on v-for no longer creates array ref values in Vue 3. ` +
|
|
`Consider using function refs or refactor to avoid ref usage altogether.`,
|
|
link: `https://v3.vuejs.org/guide/migration/array-refs.html`
|
|
},
|
|
["COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */]: {
|
|
message: `<template> with no special directives will render as a native template ` +
|
|
`element instead of its inner content in Vue 3.`
|
|
},
|
|
["COMPILER_INLINE_TEMPLATE" /* COMPILER_INLINE_TEMPLATE */]: {
|
|
message: `"inline-template" has been removed in Vue 3.`,
|
|
link: `https://v3.vuejs.org/guide/migration/inline-template-attribute.html`
|
|
},
|
|
["COMPILER_FILTER" /* COMPILER_FILTERS */]: {
|
|
message: `filters have been removed in Vue 3. ` +
|
|
`The "|" symbol will be treated as native JavaScript bitwise OR operator. ` +
|
|
`Use method calls or computed properties instead.`,
|
|
link: `https://v3.vuejs.org/guide/migration/filters.html`
|
|
}
|
|
};
|
|
function getCompatValue(key, context) {
|
|
const config = context.options
|
|
? context.options.compatConfig
|
|
: context.compatConfig;
|
|
const value = config && config[key];
|
|
if (key === 'MODE') {
|
|
return value || 3; // compiler defaults to v3 behavior
|
|
}
|
|
else {
|
|
return value;
|
|
}
|
|
}
|
|
function isCompatEnabled(key, context) {
|
|
const mode = getCompatValue('MODE', context);
|
|
const value = getCompatValue(key, context);
|
|
// in v3 mode, only enable if explicitly set to true
|
|
// otherwise enable for any non-false value
|
|
return mode === 3 ? value === true : value !== false;
|
|
}
|
|
function checkCompatEnabled(key, context, loc, ...args) {
|
|
const enabled = isCompatEnabled(key, context);
|
|
if (( true) && enabled) {
|
|
warnDeprecation(key, context, loc, ...args);
|
|
}
|
|
return enabled;
|
|
}
|
|
function warnDeprecation(key, context, loc, ...args) {
|
|
const val = getCompatValue(key, context);
|
|
if (val === 'suppress-warning') {
|
|
return;
|
|
}
|
|
const { message, link } = deprecationData[key];
|
|
const msg = `(deprecation ${key}) ${typeof message === 'function' ? message(...args) : message}${link ? `\n Details: ${link}` : ``}`;
|
|
const err = new SyntaxError(msg);
|
|
err.code = key;
|
|
if (loc)
|
|
err.loc = loc;
|
|
context.onWarn(err);
|
|
}
|
|
|
|
// The default decoder only provides escapes for characters reserved as part of
|
|
// the template syntax, and is only used if the custom renderer did not provide
|
|
// a platform-specific decoder.
|
|
const decodeRE = /&(gt|lt|amp|apos|quot);/g;
|
|
const decodeMap = {
|
|
gt: '>',
|
|
lt: '<',
|
|
amp: '&',
|
|
apos: "'",
|
|
quot: '"'
|
|
};
|
|
const defaultParserOptions = {
|
|
delimiters: [`{{`, `}}`],
|
|
getNamespace: () => 0 /* HTML */,
|
|
getTextMode: () => 0 /* DATA */,
|
|
isVoidTag: _vue_shared__WEBPACK_IMPORTED_MODULE_0__.NO,
|
|
isPreTag: _vue_shared__WEBPACK_IMPORTED_MODULE_0__.NO,
|
|
isCustomElement: _vue_shared__WEBPACK_IMPORTED_MODULE_0__.NO,
|
|
decodeEntities: (rawText) => rawText.replace(decodeRE, (_, p1) => decodeMap[p1]),
|
|
onError: defaultOnError,
|
|
onWarn: defaultOnWarn,
|
|
comments: ("development" !== 'production')
|
|
};
|
|
function baseParse(content, options = {}) {
|
|
const context = createParserContext(content, options);
|
|
const start = getCursor(context);
|
|
return createRoot(parseChildren(context, 0 /* DATA */, []), getSelection(context, start));
|
|
}
|
|
function createParserContext(content, rawOptions) {
|
|
const options = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.extend)({}, defaultParserOptions);
|
|
let key;
|
|
for (key in rawOptions) {
|
|
// @ts-ignore
|
|
options[key] =
|
|
rawOptions[key] === undefined
|
|
? defaultParserOptions[key]
|
|
: rawOptions[key];
|
|
}
|
|
return {
|
|
options,
|
|
column: 1,
|
|
line: 1,
|
|
offset: 0,
|
|
originalSource: content,
|
|
source: content,
|
|
inPre: false,
|
|
inVPre: false,
|
|
onWarn: options.onWarn
|
|
};
|
|
}
|
|
function parseChildren(context, mode, ancestors) {
|
|
const parent = last(ancestors);
|
|
const ns = parent ? parent.ns : 0 /* HTML */;
|
|
const nodes = [];
|
|
while (!isEnd(context, mode, ancestors)) {
|
|
const s = context.source;
|
|
let node = undefined;
|
|
if (mode === 0 /* DATA */ || mode === 1 /* RCDATA */) {
|
|
if (!context.inVPre && startsWith(s, context.options.delimiters[0])) {
|
|
// '{{'
|
|
node = parseInterpolation(context, mode);
|
|
}
|
|
else if (mode === 0 /* DATA */ && s[0] === '<') {
|
|
// https://html.spec.whatwg.org/multipage/parsing.html#tag-open-state
|
|
if (s.length === 1) {
|
|
emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 1);
|
|
}
|
|
else if (s[1] === '!') {
|
|
// https://html.spec.whatwg.org/multipage/parsing.html#markup-declaration-open-state
|
|
if (startsWith(s, '<!--')) {
|
|
node = parseComment(context);
|
|
}
|
|
else if (startsWith(s, '<!DOCTYPE')) {
|
|
// Ignore DOCTYPE by a limitation.
|
|
node = parseBogusComment(context);
|
|
}
|
|
else if (startsWith(s, '<![CDATA[')) {
|
|
if (ns !== 0 /* HTML */) {
|
|
node = parseCDATA(context, ancestors);
|
|
}
|
|
else {
|
|
emitError(context, 1 /* CDATA_IN_HTML_CONTENT */);
|
|
node = parseBogusComment(context);
|
|
}
|
|
}
|
|
else {
|
|
emitError(context, 11 /* INCORRECTLY_OPENED_COMMENT */);
|
|
node = parseBogusComment(context);
|
|
}
|
|
}
|
|
else if (s[1] === '/') {
|
|
// https://html.spec.whatwg.org/multipage/parsing.html#end-tag-open-state
|
|
if (s.length === 2) {
|
|
emitError(context, 5 /* EOF_BEFORE_TAG_NAME */, 2);
|
|
}
|
|
else if (s[2] === '>') {
|
|
emitError(context, 14 /* MISSING_END_TAG_NAME */, 2);
|
|
advanceBy(context, 3);
|
|
continue;
|
|
}
|
|
else if (/[a-z]/i.test(s[2])) {
|
|
emitError(context, 23 /* X_INVALID_END_TAG */);
|
|
parseTag(context, 1 /* End */, parent);
|
|
continue;
|
|
}
|
|
else {
|
|
emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 2);
|
|
node = parseBogusComment(context);
|
|
}
|
|
}
|
|
else if (/[a-z]/i.test(s[1])) {
|
|
node = parseElement(context, ancestors);
|
|
// 2.x <template> with no directive compat
|
|
if (isCompatEnabled("COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */, context) &&
|
|
node &&
|
|
node.tag === 'template' &&
|
|
!node.props.some(p => p.type === 7 /* DIRECTIVE */ &&
|
|
isSpecialTemplateDirective(p.name))) {
|
|
( true) &&
|
|
warnDeprecation("COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */, context, node.loc);
|
|
node = node.children;
|
|
}
|
|
}
|
|
else if (s[1] === '?') {
|
|
emitError(context, 21 /* UNEXPECTED_QUESTION_MARK_INSTEAD_OF_TAG_NAME */, 1);
|
|
node = parseBogusComment(context);
|
|
}
|
|
else {
|
|
emitError(context, 12 /* INVALID_FIRST_CHARACTER_OF_TAG_NAME */, 1);
|
|
}
|
|
}
|
|
}
|
|
if (!node) {
|
|
node = parseText(context, mode);
|
|
}
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isArray)(node)) {
|
|
for (let i = 0; i < node.length; i++) {
|
|
pushNode(nodes, node[i]);
|
|
}
|
|
}
|
|
else {
|
|
pushNode(nodes, node);
|
|
}
|
|
}
|
|
// Whitespace handling strategy like v2
|
|
let removedWhitespace = false;
|
|
if (mode !== 2 /* RAWTEXT */ && mode !== 1 /* RCDATA */) {
|
|
const shouldCondense = context.options.whitespace !== 'preserve';
|
|
for (let i = 0; i < nodes.length; i++) {
|
|
const node = nodes[i];
|
|
if (!context.inPre && node.type === 2 /* TEXT */) {
|
|
if (!/[^\t\r\n\f ]/.test(node.content)) {
|
|
const prev = nodes[i - 1];
|
|
const next = nodes[i + 1];
|
|
// Remove if:
|
|
// - the whitespace is the first or last node, or:
|
|
// - (condense mode) the whitespace is adjacent to a comment, or:
|
|
// - (condense mode) the whitespace is between two elements AND contains newline
|
|
if (!prev ||
|
|
!next ||
|
|
(shouldCondense &&
|
|
(prev.type === 3 /* COMMENT */ ||
|
|
next.type === 3 /* COMMENT */ ||
|
|
(prev.type === 1 /* ELEMENT */ &&
|
|
next.type === 1 /* ELEMENT */ &&
|
|
/[\r\n]/.test(node.content))))) {
|
|
removedWhitespace = true;
|
|
nodes[i] = null;
|
|
}
|
|
else {
|
|
// Otherwise, the whitespace is condensed into a single space
|
|
node.content = ' ';
|
|
}
|
|
}
|
|
else if (shouldCondense) {
|
|
// in condense mode, consecutive whitespaces in text are condensed
|
|
// down to a single space.
|
|
node.content = node.content.replace(/[\t\r\n\f ]+/g, ' ');
|
|
}
|
|
}
|
|
// Remove comment nodes if desired by configuration.
|
|
else if (node.type === 3 /* COMMENT */ && !context.options.comments) {
|
|
removedWhitespace = true;
|
|
nodes[i] = null;
|
|
}
|
|
}
|
|
if (context.inPre && parent && context.options.isPreTag(parent.tag)) {
|
|
// remove leading newline per html spec
|
|
// https://html.spec.whatwg.org/multipage/grouping-content.html#the-pre-element
|
|
const first = nodes[0];
|
|
if (first && first.type === 2 /* TEXT */) {
|
|
first.content = first.content.replace(/^\r?\n/, '');
|
|
}
|
|
}
|
|
}
|
|
return removedWhitespace ? nodes.filter(Boolean) : nodes;
|
|
}
|
|
function pushNode(nodes, node) {
|
|
if (node.type === 2 /* TEXT */) {
|
|
const prev = last(nodes);
|
|
// Merge if both this and the previous node are text and those are
|
|
// consecutive. This happens for cases like "a < b".
|
|
if (prev &&
|
|
prev.type === 2 /* TEXT */ &&
|
|
prev.loc.end.offset === node.loc.start.offset) {
|
|
prev.content += node.content;
|
|
prev.loc.end = node.loc.end;
|
|
prev.loc.source += node.loc.source;
|
|
return;
|
|
}
|
|
}
|
|
nodes.push(node);
|
|
}
|
|
function parseCDATA(context, ancestors) {
|
|
advanceBy(context, 9);
|
|
const nodes = parseChildren(context, 3 /* CDATA */, ancestors);
|
|
if (context.source.length === 0) {
|
|
emitError(context, 6 /* EOF_IN_CDATA */);
|
|
}
|
|
else {
|
|
advanceBy(context, 3);
|
|
}
|
|
return nodes;
|
|
}
|
|
function parseComment(context) {
|
|
const start = getCursor(context);
|
|
let content;
|
|
// Regular comment.
|
|
const match = /--(\!)?>/.exec(context.source);
|
|
if (!match) {
|
|
content = context.source.slice(4);
|
|
advanceBy(context, context.source.length);
|
|
emitError(context, 7 /* EOF_IN_COMMENT */);
|
|
}
|
|
else {
|
|
if (match.index <= 3) {
|
|
emitError(context, 0 /* ABRUPT_CLOSING_OF_EMPTY_COMMENT */);
|
|
}
|
|
if (match[1]) {
|
|
emitError(context, 10 /* INCORRECTLY_CLOSED_COMMENT */);
|
|
}
|
|
content = context.source.slice(4, match.index);
|
|
// Advancing with reporting nested comments.
|
|
const s = context.source.slice(0, match.index);
|
|
let prevIndex = 1, nestedIndex = 0;
|
|
while ((nestedIndex = s.indexOf('<!--', prevIndex)) !== -1) {
|
|
advanceBy(context, nestedIndex - prevIndex + 1);
|
|
if (nestedIndex + 4 < s.length) {
|
|
emitError(context, 16 /* NESTED_COMMENT */);
|
|
}
|
|
prevIndex = nestedIndex + 1;
|
|
}
|
|
advanceBy(context, match.index + match[0].length - prevIndex + 1);
|
|
}
|
|
return {
|
|
type: 3 /* COMMENT */,
|
|
content,
|
|
loc: getSelection(context, start)
|
|
};
|
|
}
|
|
function parseBogusComment(context) {
|
|
const start = getCursor(context);
|
|
const contentStart = context.source[1] === '?' ? 1 : 2;
|
|
let content;
|
|
const closeIndex = context.source.indexOf('>');
|
|
if (closeIndex === -1) {
|
|
content = context.source.slice(contentStart);
|
|
advanceBy(context, context.source.length);
|
|
}
|
|
else {
|
|
content = context.source.slice(contentStart, closeIndex);
|
|
advanceBy(context, closeIndex + 1);
|
|
}
|
|
return {
|
|
type: 3 /* COMMENT */,
|
|
content,
|
|
loc: getSelection(context, start)
|
|
};
|
|
}
|
|
function parseElement(context, ancestors) {
|
|
// Start tag.
|
|
const wasInPre = context.inPre;
|
|
const wasInVPre = context.inVPre;
|
|
const parent = last(ancestors);
|
|
const element = parseTag(context, 0 /* Start */, parent);
|
|
const isPreBoundary = context.inPre && !wasInPre;
|
|
const isVPreBoundary = context.inVPre && !wasInVPre;
|
|
if (element.isSelfClosing || context.options.isVoidTag(element.tag)) {
|
|
// #4030 self-closing <pre> tag
|
|
if (isPreBoundary) {
|
|
context.inPre = false;
|
|
}
|
|
if (isVPreBoundary) {
|
|
context.inVPre = false;
|
|
}
|
|
return element;
|
|
}
|
|
// Children.
|
|
ancestors.push(element);
|
|
const mode = context.options.getTextMode(element, parent);
|
|
const children = parseChildren(context, mode, ancestors);
|
|
ancestors.pop();
|
|
// 2.x inline-template compat
|
|
{
|
|
const inlineTemplateProp = element.props.find(p => p.type === 6 /* ATTRIBUTE */ && p.name === 'inline-template');
|
|
if (inlineTemplateProp &&
|
|
checkCompatEnabled("COMPILER_INLINE_TEMPLATE" /* COMPILER_INLINE_TEMPLATE */, context, inlineTemplateProp.loc)) {
|
|
const loc = getSelection(context, element.loc.end);
|
|
inlineTemplateProp.value = {
|
|
type: 2 /* TEXT */,
|
|
content: loc.source,
|
|
loc
|
|
};
|
|
}
|
|
}
|
|
element.children = children;
|
|
// End tag.
|
|
if (startsWithEndTagOpen(context.source, element.tag)) {
|
|
parseTag(context, 1 /* End */, parent);
|
|
}
|
|
else {
|
|
emitError(context, 24 /* X_MISSING_END_TAG */, 0, element.loc.start);
|
|
if (context.source.length === 0 && element.tag.toLowerCase() === 'script') {
|
|
const first = children[0];
|
|
if (first && startsWith(first.loc.source, '<!--')) {
|
|
emitError(context, 8 /* EOF_IN_SCRIPT_HTML_COMMENT_LIKE_TEXT */);
|
|
}
|
|
}
|
|
}
|
|
element.loc = getSelection(context, element.loc.start);
|
|
if (isPreBoundary) {
|
|
context.inPre = false;
|
|
}
|
|
if (isVPreBoundary) {
|
|
context.inVPre = false;
|
|
}
|
|
return element;
|
|
}
|
|
const isSpecialTemplateDirective = /*#__PURE__*/ (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.makeMap)(`if,else,else-if,for,slot`);
|
|
function parseTag(context, type, parent) {
|
|
// Tag open.
|
|
const start = getCursor(context);
|
|
const match = /^<\/?([a-z][^\t\r\n\f />]*)/i.exec(context.source);
|
|
const tag = match[1];
|
|
const ns = context.options.getNamespace(tag, parent);
|
|
advanceBy(context, match[0].length);
|
|
advanceSpaces(context);
|
|
// save current state in case we need to re-parse attributes with v-pre
|
|
const cursor = getCursor(context);
|
|
const currentSource = context.source;
|
|
// check <pre> tag
|
|
if (context.options.isPreTag(tag)) {
|
|
context.inPre = true;
|
|
}
|
|
// Attributes.
|
|
let props = parseAttributes(context, type);
|
|
// check v-pre
|
|
if (type === 0 /* Start */ &&
|
|
!context.inVPre &&
|
|
props.some(p => p.type === 7 /* DIRECTIVE */ && p.name === 'pre')) {
|
|
context.inVPre = true;
|
|
// reset context
|
|
(0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.extend)(context, cursor);
|
|
context.source = currentSource;
|
|
// re-parse attrs and filter out v-pre itself
|
|
props = parseAttributes(context, type).filter(p => p.name !== 'v-pre');
|
|
}
|
|
// Tag close.
|
|
let isSelfClosing = false;
|
|
if (context.source.length === 0) {
|
|
emitError(context, 9 /* EOF_IN_TAG */);
|
|
}
|
|
else {
|
|
isSelfClosing = startsWith(context.source, '/>');
|
|
if (type === 1 /* End */ && isSelfClosing) {
|
|
emitError(context, 4 /* END_TAG_WITH_TRAILING_SOLIDUS */);
|
|
}
|
|
advanceBy(context, isSelfClosing ? 2 : 1);
|
|
}
|
|
if (type === 1 /* End */) {
|
|
return;
|
|
}
|
|
// 2.x deprecation checks
|
|
if (( true) &&
|
|
isCompatEnabled("COMPILER_V_IF_V_FOR_PRECEDENCE" /* COMPILER_V_IF_V_FOR_PRECEDENCE */, context)) {
|
|
let hasIf = false;
|
|
let hasFor = false;
|
|
for (let i = 0; i < props.length; i++) {
|
|
const p = props[i];
|
|
if (p.type === 7 /* DIRECTIVE */) {
|
|
if (p.name === 'if') {
|
|
hasIf = true;
|
|
}
|
|
else if (p.name === 'for') {
|
|
hasFor = true;
|
|
}
|
|
}
|
|
if (hasIf && hasFor) {
|
|
warnDeprecation("COMPILER_V_IF_V_FOR_PRECEDENCE" /* COMPILER_V_IF_V_FOR_PRECEDENCE */, context, getSelection(context, start));
|
|
}
|
|
}
|
|
}
|
|
let tagType = 0 /* ELEMENT */;
|
|
if (!context.inVPre) {
|
|
if (tag === 'slot') {
|
|
tagType = 2 /* SLOT */;
|
|
}
|
|
else if (tag === 'template') {
|
|
if (props.some(p => p.type === 7 /* DIRECTIVE */ && isSpecialTemplateDirective(p.name))) {
|
|
tagType = 3 /* TEMPLATE */;
|
|
}
|
|
}
|
|
else if (isComponent(tag, props, context)) {
|
|
tagType = 1 /* COMPONENT */;
|
|
}
|
|
}
|
|
return {
|
|
type: 1 /* ELEMENT */,
|
|
ns,
|
|
tag,
|
|
tagType,
|
|
props,
|
|
isSelfClosing,
|
|
children: [],
|
|
loc: getSelection(context, start),
|
|
codegenNode: undefined // to be created during transform phase
|
|
};
|
|
}
|
|
function isComponent(tag, props, context) {
|
|
const options = context.options;
|
|
if (options.isCustomElement(tag)) {
|
|
return false;
|
|
}
|
|
if (tag === 'component' ||
|
|
/^[A-Z]/.test(tag) ||
|
|
isCoreComponent(tag) ||
|
|
(options.isBuiltInComponent && options.isBuiltInComponent(tag)) ||
|
|
(options.isNativeTag && !options.isNativeTag(tag))) {
|
|
return true;
|
|
}
|
|
// at this point the tag should be a native tag, but check for potential "is"
|
|
// casting
|
|
for (let i = 0; i < props.length; i++) {
|
|
const p = props[i];
|
|
if (p.type === 6 /* ATTRIBUTE */) {
|
|
if (p.name === 'is' && p.value) {
|
|
if (p.value.content.startsWith('vue:')) {
|
|
return true;
|
|
}
|
|
else if (checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
// directive
|
|
// v-is (TODO Deprecate)
|
|
if (p.name === 'is') {
|
|
return true;
|
|
}
|
|
else if (
|
|
// :is on plain element - only treat as component in compat mode
|
|
p.name === 'bind' &&
|
|
isBindKey(p.arg, 'is') &&
|
|
true &&
|
|
checkCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function parseAttributes(context, type) {
|
|
const props = [];
|
|
const attributeNames = new Set();
|
|
while (context.source.length > 0 &&
|
|
!startsWith(context.source, '>') &&
|
|
!startsWith(context.source, '/>')) {
|
|
if (startsWith(context.source, '/')) {
|
|
emitError(context, 22 /* UNEXPECTED_SOLIDUS_IN_TAG */);
|
|
advanceBy(context, 1);
|
|
advanceSpaces(context);
|
|
continue;
|
|
}
|
|
if (type === 1 /* End */) {
|
|
emitError(context, 3 /* END_TAG_WITH_ATTRIBUTES */);
|
|
}
|
|
const attr = parseAttribute(context, attributeNames);
|
|
if (type === 0 /* Start */) {
|
|
props.push(attr);
|
|
}
|
|
if (/^[^\t\r\n\f />]/.test(context.source)) {
|
|
emitError(context, 15 /* MISSING_WHITESPACE_BETWEEN_ATTRIBUTES */);
|
|
}
|
|
advanceSpaces(context);
|
|
}
|
|
return props;
|
|
}
|
|
function parseAttribute(context, nameSet) {
|
|
// Name.
|
|
const start = getCursor(context);
|
|
const match = /^[^\t\r\n\f />][^\t\r\n\f />=]*/.exec(context.source);
|
|
const name = match[0];
|
|
if (nameSet.has(name)) {
|
|
emitError(context, 2 /* DUPLICATE_ATTRIBUTE */);
|
|
}
|
|
nameSet.add(name);
|
|
if (name[0] === '=') {
|
|
emitError(context, 19 /* UNEXPECTED_EQUALS_SIGN_BEFORE_ATTRIBUTE_NAME */);
|
|
}
|
|
{
|
|
const pattern = /["'<]/g;
|
|
let m;
|
|
while ((m = pattern.exec(name))) {
|
|
emitError(context, 17 /* UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME */, m.index);
|
|
}
|
|
}
|
|
advanceBy(context, name.length);
|
|
// Value
|
|
let value = undefined;
|
|
if (/^[\t\r\n\f ]*=/.test(context.source)) {
|
|
advanceSpaces(context);
|
|
advanceBy(context, 1);
|
|
advanceSpaces(context);
|
|
value = parseAttributeValue(context);
|
|
if (!value) {
|
|
emitError(context, 13 /* MISSING_ATTRIBUTE_VALUE */);
|
|
}
|
|
}
|
|
const loc = getSelection(context, start);
|
|
if (!context.inVPre && /^(v-|:|\.|@|#)/.test(name)) {
|
|
const match = /(?:^v-([a-z0-9-]+))?(?:(?::|^\.|^@|^#)(\[[^\]]+\]|[^\.]+))?(.+)?$/i.exec(name);
|
|
let isPropShorthand = startsWith(name, '.');
|
|
let dirName = match[1] ||
|
|
(isPropShorthand || startsWith(name, ':')
|
|
? 'bind'
|
|
: startsWith(name, '@')
|
|
? 'on'
|
|
: 'slot');
|
|
let arg;
|
|
if (match[2]) {
|
|
const isSlot = dirName === 'slot';
|
|
const startOffset = name.lastIndexOf(match[2]);
|
|
const loc = getSelection(context, getNewPosition(context, start, startOffset), getNewPosition(context, start, startOffset + match[2].length + ((isSlot && match[3]) || '').length));
|
|
let content = match[2];
|
|
let isStatic = true;
|
|
if (content.startsWith('[')) {
|
|
isStatic = false;
|
|
if (!content.endsWith(']')) {
|
|
emitError(context, 26 /* X_MISSING_DYNAMIC_DIRECTIVE_ARGUMENT_END */);
|
|
}
|
|
content = content.substr(1, content.length - 2);
|
|
}
|
|
else if (isSlot) {
|
|
// #1241 special case for v-slot: vuetify relies extensively on slot
|
|
// names containing dots. v-slot doesn't have any modifiers and Vue 2.x
|
|
// supports such usage so we are keeping it consistent with 2.x.
|
|
content += match[3] || '';
|
|
}
|
|
arg = {
|
|
type: 4 /* SIMPLE_EXPRESSION */,
|
|
content,
|
|
isStatic,
|
|
constType: isStatic
|
|
? 3 /* CAN_STRINGIFY */
|
|
: 0 /* NOT_CONSTANT */,
|
|
loc
|
|
};
|
|
}
|
|
if (value && value.isQuoted) {
|
|
const valueLoc = value.loc;
|
|
valueLoc.start.offset++;
|
|
valueLoc.start.column++;
|
|
valueLoc.end = advancePositionWithClone(valueLoc.start, value.content);
|
|
valueLoc.source = valueLoc.source.slice(1, -1);
|
|
}
|
|
const modifiers = match[3] ? match[3].substr(1).split('.') : [];
|
|
if (isPropShorthand)
|
|
modifiers.push('prop');
|
|
// 2.x compat v-bind:foo.sync -> v-model:foo
|
|
if (dirName === 'bind' && arg) {
|
|
if (modifiers.includes('sync') &&
|
|
checkCompatEnabled("COMPILER_V_BIND_SYNC" /* COMPILER_V_BIND_SYNC */, context, loc, arg.loc.source)) {
|
|
dirName = 'model';
|
|
modifiers.splice(modifiers.indexOf('sync'), 1);
|
|
}
|
|
if (( true) && modifiers.includes('prop')) {
|
|
checkCompatEnabled("COMPILER_V_BIND_PROP" /* COMPILER_V_BIND_PROP */, context, loc);
|
|
}
|
|
}
|
|
return {
|
|
type: 7 /* DIRECTIVE */,
|
|
name: dirName,
|
|
exp: value && {
|
|
type: 4 /* SIMPLE_EXPRESSION */,
|
|
content: value.content,
|
|
isStatic: false,
|
|
// Treat as non-constant by default. This can be potentially set to
|
|
// other values by `transformExpression` to make it eligible for hoisting.
|
|
constType: 0 /* NOT_CONSTANT */,
|
|
loc: value.loc
|
|
},
|
|
arg,
|
|
modifiers,
|
|
loc
|
|
};
|
|
}
|
|
return {
|
|
type: 6 /* ATTRIBUTE */,
|
|
name,
|
|
value: value && {
|
|
type: 2 /* TEXT */,
|
|
content: value.content,
|
|
loc: value.loc
|
|
},
|
|
loc
|
|
};
|
|
}
|
|
function parseAttributeValue(context) {
|
|
const start = getCursor(context);
|
|
let content;
|
|
const quote = context.source[0];
|
|
const isQuoted = quote === `"` || quote === `'`;
|
|
if (isQuoted) {
|
|
// Quoted value.
|
|
advanceBy(context, 1);
|
|
const endIndex = context.source.indexOf(quote);
|
|
if (endIndex === -1) {
|
|
content = parseTextData(context, context.source.length, 4 /* ATTRIBUTE_VALUE */);
|
|
}
|
|
else {
|
|
content = parseTextData(context, endIndex, 4 /* ATTRIBUTE_VALUE */);
|
|
advanceBy(context, 1);
|
|
}
|
|
}
|
|
else {
|
|
// Unquoted
|
|
const match = /^[^\t\r\n\f >]+/.exec(context.source);
|
|
if (!match) {
|
|
return undefined;
|
|
}
|
|
const unexpectedChars = /["'<=`]/g;
|
|
let m;
|
|
while ((m = unexpectedChars.exec(match[0]))) {
|
|
emitError(context, 18 /* UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE */, m.index);
|
|
}
|
|
content = parseTextData(context, match[0].length, 4 /* ATTRIBUTE_VALUE */);
|
|
}
|
|
return { content, isQuoted, loc: getSelection(context, start) };
|
|
}
|
|
function parseInterpolation(context, mode) {
|
|
const [open, close] = context.options.delimiters;
|
|
const closeIndex = context.source.indexOf(close, open.length);
|
|
if (closeIndex === -1) {
|
|
emitError(context, 25 /* X_MISSING_INTERPOLATION_END */);
|
|
return undefined;
|
|
}
|
|
const start = getCursor(context);
|
|
advanceBy(context, open.length);
|
|
const innerStart = getCursor(context);
|
|
const innerEnd = getCursor(context);
|
|
const rawContentLength = closeIndex - open.length;
|
|
const rawContent = context.source.slice(0, rawContentLength);
|
|
const preTrimContent = parseTextData(context, rawContentLength, mode);
|
|
const content = preTrimContent.trim();
|
|
const startOffset = preTrimContent.indexOf(content);
|
|
if (startOffset > 0) {
|
|
advancePositionWithMutation(innerStart, rawContent, startOffset);
|
|
}
|
|
const endOffset = rawContentLength - (preTrimContent.length - content.length - startOffset);
|
|
advancePositionWithMutation(innerEnd, rawContent, endOffset);
|
|
advanceBy(context, close.length);
|
|
return {
|
|
type: 5 /* INTERPOLATION */,
|
|
content: {
|
|
type: 4 /* SIMPLE_EXPRESSION */,
|
|
isStatic: false,
|
|
// Set `isConstant` to false by default and will decide in transformExpression
|
|
constType: 0 /* NOT_CONSTANT */,
|
|
content,
|
|
loc: getSelection(context, innerStart, innerEnd)
|
|
},
|
|
loc: getSelection(context, start)
|
|
};
|
|
}
|
|
function parseText(context, mode) {
|
|
const endTokens = ['<', context.options.delimiters[0]];
|
|
if (mode === 3 /* CDATA */) {
|
|
endTokens.push(']]>');
|
|
}
|
|
let endIndex = context.source.length;
|
|
for (let i = 0; i < endTokens.length; i++) {
|
|
const index = context.source.indexOf(endTokens[i], 1);
|
|
if (index !== -1 && endIndex > index) {
|
|
endIndex = index;
|
|
}
|
|
}
|
|
const start = getCursor(context);
|
|
const content = parseTextData(context, endIndex, mode);
|
|
return {
|
|
type: 2 /* TEXT */,
|
|
content,
|
|
loc: getSelection(context, start)
|
|
};
|
|
}
|
|
/**
|
|
* Get text data with a given length from the current location.
|
|
* This translates HTML entities in the text data.
|
|
*/
|
|
function parseTextData(context, length, mode) {
|
|
const rawText = context.source.slice(0, length);
|
|
advanceBy(context, length);
|
|
if (mode === 2 /* RAWTEXT */ ||
|
|
mode === 3 /* CDATA */ ||
|
|
rawText.indexOf('&') === -1) {
|
|
return rawText;
|
|
}
|
|
else {
|
|
// DATA or RCDATA containing "&"". Entity decoding required.
|
|
return context.options.decodeEntities(rawText, mode === 4 /* ATTRIBUTE_VALUE */);
|
|
}
|
|
}
|
|
function getCursor(context) {
|
|
const { column, line, offset } = context;
|
|
return { column, line, offset };
|
|
}
|
|
function getSelection(context, start, end) {
|
|
end = end || getCursor(context);
|
|
return {
|
|
start,
|
|
end,
|
|
source: context.originalSource.slice(start.offset, end.offset)
|
|
};
|
|
}
|
|
function last(xs) {
|
|
return xs[xs.length - 1];
|
|
}
|
|
function startsWith(source, searchString) {
|
|
return source.startsWith(searchString);
|
|
}
|
|
function advanceBy(context, numberOfCharacters) {
|
|
const { source } = context;
|
|
advancePositionWithMutation(context, source, numberOfCharacters);
|
|
context.source = source.slice(numberOfCharacters);
|
|
}
|
|
function advanceSpaces(context) {
|
|
const match = /^[\t\r\n\f ]+/.exec(context.source);
|
|
if (match) {
|
|
advanceBy(context, match[0].length);
|
|
}
|
|
}
|
|
function getNewPosition(context, start, numberOfCharacters) {
|
|
return advancePositionWithClone(start, context.originalSource.slice(start.offset, numberOfCharacters), numberOfCharacters);
|
|
}
|
|
function emitError(context, code, offset, loc = getCursor(context)) {
|
|
if (offset) {
|
|
loc.offset += offset;
|
|
loc.column += offset;
|
|
}
|
|
context.options.onError(createCompilerError(code, {
|
|
start: loc,
|
|
end: loc,
|
|
source: ''
|
|
}));
|
|
}
|
|
function isEnd(context, mode, ancestors) {
|
|
const s = context.source;
|
|
switch (mode) {
|
|
case 0 /* DATA */:
|
|
if (startsWith(s, '</')) {
|
|
// TODO: probably bad performance
|
|
for (let i = ancestors.length - 1; i >= 0; --i) {
|
|
if (startsWithEndTagOpen(s, ancestors[i].tag)) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case 1 /* RCDATA */:
|
|
case 2 /* RAWTEXT */: {
|
|
const parent = last(ancestors);
|
|
if (parent && startsWithEndTagOpen(s, parent.tag)) {
|
|
return true;
|
|
}
|
|
break;
|
|
}
|
|
case 3 /* CDATA */:
|
|
if (startsWith(s, ']]>')) {
|
|
return true;
|
|
}
|
|
break;
|
|
}
|
|
return !s;
|
|
}
|
|
function startsWithEndTagOpen(source, tag) {
|
|
return (startsWith(source, '</') &&
|
|
source.substr(2, tag.length).toLowerCase() === tag.toLowerCase() &&
|
|
/[\t\r\n\f />]/.test(source[2 + tag.length] || '>'));
|
|
}
|
|
|
|
function hoistStatic(root, context) {
|
|
walk(root, context,
|
|
// Root node is unfortunately non-hoistable due to potential parent
|
|
// fallthrough attributes.
|
|
isSingleElementRoot(root, root.children[0]));
|
|
}
|
|
function isSingleElementRoot(root, child) {
|
|
const { children } = root;
|
|
return (children.length === 1 &&
|
|
child.type === 1 /* ELEMENT */ &&
|
|
!isSlotOutlet(child));
|
|
}
|
|
function walk(node, context, doNotHoistNode = false) {
|
|
// Some transforms, e.g. transformAssetUrls from @vue/compiler-sfc, replaces
|
|
// static bindings with expressions. These expressions are guaranteed to be
|
|
// constant so they are still eligible for hoisting, but they are only
|
|
// available at runtime and therefore cannot be evaluated ahead of time.
|
|
// This is only a concern for pre-stringification (via transformHoist by
|
|
// @vue/compiler-dom), but doing it here allows us to perform only one full
|
|
// walk of the AST and allow `stringifyStatic` to stop walking as soon as its
|
|
// stringficiation threshold is met.
|
|
let canStringify = true;
|
|
const { children } = node;
|
|
const originalCount = children.length;
|
|
let hoistedCount = 0;
|
|
for (let i = 0; i < children.length; i++) {
|
|
const child = children[i];
|
|
// only plain elements & text calls are eligible for hoisting.
|
|
if (child.type === 1 /* ELEMENT */ &&
|
|
child.tagType === 0 /* ELEMENT */) {
|
|
const constantType = doNotHoistNode
|
|
? 0 /* NOT_CONSTANT */
|
|
: getConstantType(child, context);
|
|
if (constantType > 0 /* NOT_CONSTANT */) {
|
|
if (constantType < 3 /* CAN_STRINGIFY */) {
|
|
canStringify = false;
|
|
}
|
|
if (constantType >= 2 /* CAN_HOIST */) {
|
|
child.codegenNode.patchFlag =
|
|
-1 /* HOISTED */ + (( true) ? ` /* HOISTED */` : 0);
|
|
child.codegenNode = context.hoist(child.codegenNode);
|
|
hoistedCount++;
|
|
continue;
|
|
}
|
|
}
|
|
else {
|
|
// node may contain dynamic children, but its props may be eligible for
|
|
// hoisting.
|
|
const codegenNode = child.codegenNode;
|
|
if (codegenNode.type === 13 /* VNODE_CALL */) {
|
|
const flag = getPatchFlag(codegenNode);
|
|
if ((!flag ||
|
|
flag === 512 /* NEED_PATCH */ ||
|
|
flag === 1 /* TEXT */) &&
|
|
getGeneratedPropsConstantType(child, context) >=
|
|
2 /* CAN_HOIST */) {
|
|
const props = getNodeProps(child);
|
|
if (props) {
|
|
codegenNode.props = context.hoist(props);
|
|
}
|
|
}
|
|
if (codegenNode.dynamicProps) {
|
|
codegenNode.dynamicProps = context.hoist(codegenNode.dynamicProps);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (child.type === 12 /* TEXT_CALL */) {
|
|
const contentType = getConstantType(child.content, context);
|
|
if (contentType > 0) {
|
|
if (contentType < 3 /* CAN_STRINGIFY */) {
|
|
canStringify = false;
|
|
}
|
|
if (contentType >= 2 /* CAN_HOIST */) {
|
|
child.codegenNode = context.hoist(child.codegenNode);
|
|
hoistedCount++;
|
|
}
|
|
}
|
|
}
|
|
// walk further
|
|
if (child.type === 1 /* ELEMENT */) {
|
|
const isComponent = child.tagType === 1 /* COMPONENT */;
|
|
if (isComponent) {
|
|
context.scopes.vSlot++;
|
|
}
|
|
walk(child, context);
|
|
if (isComponent) {
|
|
context.scopes.vSlot--;
|
|
}
|
|
}
|
|
else if (child.type === 11 /* FOR */) {
|
|
// Do not hoist v-for single child because it has to be a block
|
|
walk(child, context, child.children.length === 1);
|
|
}
|
|
else if (child.type === 9 /* IF */) {
|
|
for (let i = 0; i < child.branches.length; i++) {
|
|
// Do not hoist v-if single child because it has to be a block
|
|
walk(child.branches[i], context, child.branches[i].children.length === 1);
|
|
}
|
|
}
|
|
}
|
|
if (canStringify && hoistedCount && context.transformHoist) {
|
|
context.transformHoist(children, context, node);
|
|
}
|
|
// all children were hoisted - the entire children array is hoistable.
|
|
if (hoistedCount &&
|
|
hoistedCount === originalCount &&
|
|
node.type === 1 /* ELEMENT */ &&
|
|
node.tagType === 0 /* ELEMENT */ &&
|
|
node.codegenNode &&
|
|
node.codegenNode.type === 13 /* VNODE_CALL */ &&
|
|
(0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isArray)(node.codegenNode.children)) {
|
|
node.codegenNode.children = context.hoist(createArrayExpression(node.codegenNode.children));
|
|
}
|
|
}
|
|
function getConstantType(node, context) {
|
|
const { constantCache } = context;
|
|
switch (node.type) {
|
|
case 1 /* ELEMENT */:
|
|
if (node.tagType !== 0 /* ELEMENT */) {
|
|
return 0 /* NOT_CONSTANT */;
|
|
}
|
|
const cached = constantCache.get(node);
|
|
if (cached !== undefined) {
|
|
return cached;
|
|
}
|
|
const codegenNode = node.codegenNode;
|
|
if (codegenNode.type !== 13 /* VNODE_CALL */) {
|
|
return 0 /* NOT_CONSTANT */;
|
|
}
|
|
const flag = getPatchFlag(codegenNode);
|
|
if (!flag) {
|
|
let returnType = 3 /* CAN_STRINGIFY */;
|
|
// Element itself has no patch flag. However we still need to check:
|
|
// 1. Even for a node with no patch flag, it is possible for it to contain
|
|
// non-hoistable expressions that refers to scope variables, e.g. compiler
|
|
// injected keys or cached event handlers. Therefore we need to always
|
|
// check the codegenNode's props to be sure.
|
|
const generatedPropsType = getGeneratedPropsConstantType(node, context);
|
|
if (generatedPropsType === 0 /* NOT_CONSTANT */) {
|
|
constantCache.set(node, 0 /* NOT_CONSTANT */);
|
|
return 0 /* NOT_CONSTANT */;
|
|
}
|
|
if (generatedPropsType < returnType) {
|
|
returnType = generatedPropsType;
|
|
}
|
|
// 2. its children.
|
|
for (let i = 0; i < node.children.length; i++) {
|
|
const childType = getConstantType(node.children[i], context);
|
|
if (childType === 0 /* NOT_CONSTANT */) {
|
|
constantCache.set(node, 0 /* NOT_CONSTANT */);
|
|
return 0 /* NOT_CONSTANT */;
|
|
}
|
|
if (childType < returnType) {
|
|
returnType = childType;
|
|
}
|
|
}
|
|
// 3. if the type is not already CAN_SKIP_PATCH which is the lowest non-0
|
|
// type, check if any of the props can cause the type to be lowered
|
|
// we can skip can_patch because it's guaranteed by the absence of a
|
|
// patchFlag.
|
|
if (returnType > 1 /* CAN_SKIP_PATCH */) {
|
|
for (let i = 0; i < node.props.length; i++) {
|
|
const p = node.props[i];
|
|
if (p.type === 7 /* DIRECTIVE */ && p.name === 'bind' && p.exp) {
|
|
const expType = getConstantType(p.exp, context);
|
|
if (expType === 0 /* NOT_CONSTANT */) {
|
|
constantCache.set(node, 0 /* NOT_CONSTANT */);
|
|
return 0 /* NOT_CONSTANT */;
|
|
}
|
|
if (expType < returnType) {
|
|
returnType = expType;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// only svg/foreignObject could be block here, however if they are
|
|
// static then they don't need to be blocks since there will be no
|
|
// nested updates.
|
|
if (codegenNode.isBlock) {
|
|
context.removeHelper(OPEN_BLOCK);
|
|
context.removeHelper(getVNodeBlockHelper(context.inSSR, codegenNode.isComponent));
|
|
codegenNode.isBlock = false;
|
|
context.helper(getVNodeHelper(context.inSSR, codegenNode.isComponent));
|
|
}
|
|
constantCache.set(node, returnType);
|
|
return returnType;
|
|
}
|
|
else {
|
|
constantCache.set(node, 0 /* NOT_CONSTANT */);
|
|
return 0 /* NOT_CONSTANT */;
|
|
}
|
|
case 2 /* TEXT */:
|
|
case 3 /* COMMENT */:
|
|
return 3 /* CAN_STRINGIFY */;
|
|
case 9 /* IF */:
|
|
case 11 /* FOR */:
|
|
case 10 /* IF_BRANCH */:
|
|
return 0 /* NOT_CONSTANT */;
|
|
case 5 /* INTERPOLATION */:
|
|
case 12 /* TEXT_CALL */:
|
|
return getConstantType(node.content, context);
|
|
case 4 /* SIMPLE_EXPRESSION */:
|
|
return node.constType;
|
|
case 8 /* COMPOUND_EXPRESSION */:
|
|
let returnType = 3 /* CAN_STRINGIFY */;
|
|
for (let i = 0; i < node.children.length; i++) {
|
|
const child = node.children[i];
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isString)(child) || (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isSymbol)(child)) {
|
|
continue;
|
|
}
|
|
const childType = getConstantType(child, context);
|
|
if (childType === 0 /* NOT_CONSTANT */) {
|
|
return 0 /* NOT_CONSTANT */;
|
|
}
|
|
else if (childType < returnType) {
|
|
returnType = childType;
|
|
}
|
|
}
|
|
return returnType;
|
|
default:
|
|
if ((true)) ;
|
|
return 0 /* NOT_CONSTANT */;
|
|
}
|
|
}
|
|
const allowHoistedHelperSet = new Set([
|
|
NORMALIZE_CLASS,
|
|
NORMALIZE_STYLE,
|
|
NORMALIZE_PROPS,
|
|
GUARD_REACTIVE_PROPS
|
|
]);
|
|
function getConstantTypeOfHelperCall(value, context) {
|
|
if (value.type === 14 /* JS_CALL_EXPRESSION */ &&
|
|
!(0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isString)(value.callee) &&
|
|
allowHoistedHelperSet.has(value.callee)) {
|
|
const arg = value.arguments[0];
|
|
if (arg.type === 4 /* SIMPLE_EXPRESSION */) {
|
|
return getConstantType(arg, context);
|
|
}
|
|
else if (arg.type === 14 /* JS_CALL_EXPRESSION */) {
|
|
// in the case of nested helper call, e.g. `normalizeProps(guardReactiveProps(exp))`
|
|
return getConstantTypeOfHelperCall(arg, context);
|
|
}
|
|
}
|
|
return 0 /* NOT_CONSTANT */;
|
|
}
|
|
function getGeneratedPropsConstantType(node, context) {
|
|
let returnType = 3 /* CAN_STRINGIFY */;
|
|
const props = getNodeProps(node);
|
|
if (props && props.type === 15 /* JS_OBJECT_EXPRESSION */) {
|
|
const { properties } = props;
|
|
for (let i = 0; i < properties.length; i++) {
|
|
const { key, value } = properties[i];
|
|
const keyType = getConstantType(key, context);
|
|
if (keyType === 0 /* NOT_CONSTANT */) {
|
|
return keyType;
|
|
}
|
|
if (keyType < returnType) {
|
|
returnType = keyType;
|
|
}
|
|
let valueType;
|
|
if (value.type === 4 /* SIMPLE_EXPRESSION */) {
|
|
valueType = getConstantType(value, context);
|
|
}
|
|
else if (value.type === 14 /* JS_CALL_EXPRESSION */) {
|
|
// some helper calls can be hoisted,
|
|
// such as the `normalizeProps` generated by the compiler for pre-normalize class,
|
|
// in this case we need to respect the ConstanType of the helper's argments
|
|
valueType = getConstantTypeOfHelperCall(value, context);
|
|
}
|
|
else {
|
|
valueType = 0 /* NOT_CONSTANT */;
|
|
}
|
|
if (valueType === 0 /* NOT_CONSTANT */) {
|
|
return valueType;
|
|
}
|
|
if (valueType < returnType) {
|
|
returnType = valueType;
|
|
}
|
|
}
|
|
}
|
|
return returnType;
|
|
}
|
|
function getNodeProps(node) {
|
|
const codegenNode = node.codegenNode;
|
|
if (codegenNode.type === 13 /* VNODE_CALL */) {
|
|
return codegenNode.props;
|
|
}
|
|
}
|
|
function getPatchFlag(node) {
|
|
const flag = node.patchFlag;
|
|
return flag ? parseInt(flag, 10) : undefined;
|
|
}
|
|
|
|
function createTransformContext(root, { filename = '', prefixIdentifiers = false, hoistStatic = false, cacheHandlers = false, nodeTransforms = [], directiveTransforms = {}, transformHoist = null, isBuiltInComponent = _vue_shared__WEBPACK_IMPORTED_MODULE_0__.NOOP, isCustomElement = _vue_shared__WEBPACK_IMPORTED_MODULE_0__.NOOP, expressionPlugins = [], scopeId = null, slotted = true, ssr = false, inSSR = false, ssrCssVars = ``, bindingMetadata = _vue_shared__WEBPACK_IMPORTED_MODULE_0__.EMPTY_OBJ, inline = false, isTS = false, onError = defaultOnError, onWarn = defaultOnWarn, compatConfig }) {
|
|
const nameMatch = filename.replace(/\?.*$/, '').match(/([^/\\]+)\.\w+$/);
|
|
const context = {
|
|
// options
|
|
selfName: nameMatch && (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.capitalize)((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.camelize)(nameMatch[1])),
|
|
prefixIdentifiers,
|
|
hoistStatic,
|
|
cacheHandlers,
|
|
nodeTransforms,
|
|
directiveTransforms,
|
|
transformHoist,
|
|
isBuiltInComponent,
|
|
isCustomElement,
|
|
expressionPlugins,
|
|
scopeId,
|
|
slotted,
|
|
ssr,
|
|
inSSR,
|
|
ssrCssVars,
|
|
bindingMetadata,
|
|
inline,
|
|
isTS,
|
|
onError,
|
|
onWarn,
|
|
compatConfig,
|
|
// state
|
|
root,
|
|
helpers: new Map(),
|
|
components: new Set(),
|
|
directives: new Set(),
|
|
hoists: [],
|
|
imports: [],
|
|
constantCache: new Map(),
|
|
temps: 0,
|
|
cached: 0,
|
|
identifiers: Object.create(null),
|
|
scopes: {
|
|
vFor: 0,
|
|
vSlot: 0,
|
|
vPre: 0,
|
|
vOnce: 0
|
|
},
|
|
parent: null,
|
|
currentNode: root,
|
|
childIndex: 0,
|
|
inVOnce: false,
|
|
// methods
|
|
helper(name) {
|
|
const count = context.helpers.get(name) || 0;
|
|
context.helpers.set(name, count + 1);
|
|
return name;
|
|
},
|
|
removeHelper(name) {
|
|
const count = context.helpers.get(name);
|
|
if (count) {
|
|
const currentCount = count - 1;
|
|
if (!currentCount) {
|
|
context.helpers.delete(name);
|
|
}
|
|
else {
|
|
context.helpers.set(name, currentCount);
|
|
}
|
|
}
|
|
},
|
|
helperString(name) {
|
|
return `_${helperNameMap[context.helper(name)]}`;
|
|
},
|
|
replaceNode(node) {
|
|
/* istanbul ignore if */
|
|
if ((true)) {
|
|
if (!context.currentNode) {
|
|
throw new Error(`Node being replaced is already removed.`);
|
|
}
|
|
if (!context.parent) {
|
|
throw new Error(`Cannot replace root node.`);
|
|
}
|
|
}
|
|
context.parent.children[context.childIndex] = context.currentNode = node;
|
|
},
|
|
removeNode(node) {
|
|
if (( true) && !context.parent) {
|
|
throw new Error(`Cannot remove root node.`);
|
|
}
|
|
const list = context.parent.children;
|
|
const removalIndex = node
|
|
? list.indexOf(node)
|
|
: context.currentNode
|
|
? context.childIndex
|
|
: -1;
|
|
/* istanbul ignore if */
|
|
if (( true) && removalIndex < 0) {
|
|
throw new Error(`node being removed is not a child of current parent`);
|
|
}
|
|
if (!node || node === context.currentNode) {
|
|
// current node removed
|
|
context.currentNode = null;
|
|
context.onNodeRemoved();
|
|
}
|
|
else {
|
|
// sibling node removed
|
|
if (context.childIndex > removalIndex) {
|
|
context.childIndex--;
|
|
context.onNodeRemoved();
|
|
}
|
|
}
|
|
context.parent.children.splice(removalIndex, 1);
|
|
},
|
|
onNodeRemoved: () => { },
|
|
addIdentifiers(exp) {
|
|
},
|
|
removeIdentifiers(exp) {
|
|
},
|
|
hoist(exp) {
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isString)(exp))
|
|
exp = createSimpleExpression(exp);
|
|
context.hoists.push(exp);
|
|
const identifier = createSimpleExpression(`_hoisted_${context.hoists.length}`, false, exp.loc, 2 /* CAN_HOIST */);
|
|
identifier.hoisted = exp;
|
|
return identifier;
|
|
},
|
|
cache(exp, isVNode = false) {
|
|
return createCacheExpression(context.cached++, exp, isVNode);
|
|
}
|
|
};
|
|
{
|
|
context.filters = new Set();
|
|
}
|
|
return context;
|
|
}
|
|
function transform(root, options) {
|
|
const context = createTransformContext(root, options);
|
|
traverseNode(root, context);
|
|
if (options.hoistStatic) {
|
|
hoistStatic(root, context);
|
|
}
|
|
if (!options.ssr) {
|
|
createRootCodegen(root, context);
|
|
}
|
|
// finalize meta information
|
|
root.helpers = [...context.helpers.keys()];
|
|
root.components = [...context.components];
|
|
root.directives = [...context.directives];
|
|
root.imports = context.imports;
|
|
root.hoists = context.hoists;
|
|
root.temps = context.temps;
|
|
root.cached = context.cached;
|
|
{
|
|
root.filters = [...context.filters];
|
|
}
|
|
}
|
|
function createRootCodegen(root, context) {
|
|
const { helper } = context;
|
|
const { children } = root;
|
|
if (children.length === 1) {
|
|
const child = children[0];
|
|
// if the single child is an element, turn it into a block.
|
|
if (isSingleElementRoot(root, child) && child.codegenNode) {
|
|
// single element root is never hoisted so codegenNode will never be
|
|
// SimpleExpressionNode
|
|
const codegenNode = child.codegenNode;
|
|
if (codegenNode.type === 13 /* VNODE_CALL */) {
|
|
makeBlock(codegenNode, context);
|
|
}
|
|
root.codegenNode = codegenNode;
|
|
}
|
|
else {
|
|
// - single <slot/>, IfNode, ForNode: already blocks.
|
|
// - single text node: always patched.
|
|
// root codegen falls through via genNode()
|
|
root.codegenNode = child;
|
|
}
|
|
}
|
|
else if (children.length > 1) {
|
|
// root has multiple nodes - return a fragment block.
|
|
let patchFlag = 64 /* STABLE_FRAGMENT */;
|
|
let patchFlagText = _vue_shared__WEBPACK_IMPORTED_MODULE_0__.PatchFlagNames[64];
|
|
// check if the fragment actually contains a single valid child with
|
|
// the rest being comments
|
|
if (( true) &&
|
|
children.filter(c => c.type !== 3 /* COMMENT */).length === 1) {
|
|
patchFlag |= 2048 /* DEV_ROOT_FRAGMENT */;
|
|
patchFlagText += `, ${_vue_shared__WEBPACK_IMPORTED_MODULE_0__.PatchFlagNames[2048]}`;
|
|
}
|
|
root.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, root.children, patchFlag + (( true) ? ` /* ${patchFlagText} */` : 0), undefined, undefined, true, undefined, false /* isComponent */);
|
|
}
|
|
else ;
|
|
}
|
|
function traverseChildren(parent, context) {
|
|
let i = 0;
|
|
const nodeRemoved = () => {
|
|
i--;
|
|
};
|
|
for (; i < parent.children.length; i++) {
|
|
const child = parent.children[i];
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isString)(child))
|
|
continue;
|
|
context.parent = parent;
|
|
context.childIndex = i;
|
|
context.onNodeRemoved = nodeRemoved;
|
|
traverseNode(child, context);
|
|
}
|
|
}
|
|
function traverseNode(node, context) {
|
|
context.currentNode = node;
|
|
// apply transform plugins
|
|
const { nodeTransforms } = context;
|
|
const exitFns = [];
|
|
for (let i = 0; i < nodeTransforms.length; i++) {
|
|
const onExit = nodeTransforms[i](node, context);
|
|
if (onExit) {
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isArray)(onExit)) {
|
|
exitFns.push(...onExit);
|
|
}
|
|
else {
|
|
exitFns.push(onExit);
|
|
}
|
|
}
|
|
if (!context.currentNode) {
|
|
// node was removed
|
|
return;
|
|
}
|
|
else {
|
|
// node may have been replaced
|
|
node = context.currentNode;
|
|
}
|
|
}
|
|
switch (node.type) {
|
|
case 3 /* COMMENT */:
|
|
if (!context.ssr) {
|
|
// inject import for the Comment symbol, which is needed for creating
|
|
// comment nodes with `createVNode`
|
|
context.helper(CREATE_COMMENT);
|
|
}
|
|
break;
|
|
case 5 /* INTERPOLATION */:
|
|
// no need to traverse, but we need to inject toString helper
|
|
if (!context.ssr) {
|
|
context.helper(TO_DISPLAY_STRING);
|
|
}
|
|
break;
|
|
// for container types, further traverse downwards
|
|
case 9 /* IF */:
|
|
for (let i = 0; i < node.branches.length; i++) {
|
|
traverseNode(node.branches[i], context);
|
|
}
|
|
break;
|
|
case 10 /* IF_BRANCH */:
|
|
case 11 /* FOR */:
|
|
case 1 /* ELEMENT */:
|
|
case 0 /* ROOT */:
|
|
traverseChildren(node, context);
|
|
break;
|
|
}
|
|
// exit transforms
|
|
context.currentNode = node;
|
|
let i = exitFns.length;
|
|
while (i--) {
|
|
exitFns[i]();
|
|
}
|
|
}
|
|
function createStructuralDirectiveTransform(name, fn) {
|
|
const matches = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isString)(name)
|
|
? (n) => n === name
|
|
: (n) => name.test(n);
|
|
return (node, context) => {
|
|
if (node.type === 1 /* ELEMENT */) {
|
|
const { props } = node;
|
|
// structural directive transforms are not concerned with slots
|
|
// as they are handled separately in vSlot.ts
|
|
if (node.tagType === 3 /* TEMPLATE */ && props.some(isVSlot)) {
|
|
return;
|
|
}
|
|
const exitFns = [];
|
|
for (let i = 0; i < props.length; i++) {
|
|
const prop = props[i];
|
|
if (prop.type === 7 /* DIRECTIVE */ && matches(prop.name)) {
|
|
// structural directives are removed to avoid infinite recursion
|
|
// also we remove them *before* applying so that it can further
|
|
// traverse itself in case it moves the node around
|
|
props.splice(i, 1);
|
|
i--;
|
|
const onExit = fn(node, prop, context);
|
|
if (onExit)
|
|
exitFns.push(onExit);
|
|
}
|
|
}
|
|
return exitFns;
|
|
}
|
|
};
|
|
}
|
|
|
|
const PURE_ANNOTATION = `/*#__PURE__*/`;
|
|
function createCodegenContext(ast, { mode = 'function', prefixIdentifiers = mode === 'module', sourceMap = false, filename = `template.vue.html`, scopeId = null, optimizeImports = false, runtimeGlobalName = `Vue`, runtimeModuleName = `vue`, ssr = false, isTS = false, inSSR = false }) {
|
|
const context = {
|
|
mode,
|
|
prefixIdentifiers,
|
|
sourceMap,
|
|
filename,
|
|
scopeId,
|
|
optimizeImports,
|
|
runtimeGlobalName,
|
|
runtimeModuleName,
|
|
ssr,
|
|
isTS,
|
|
inSSR,
|
|
source: ast.loc.source,
|
|
code: ``,
|
|
column: 1,
|
|
line: 1,
|
|
offset: 0,
|
|
indentLevel: 0,
|
|
pure: false,
|
|
map: undefined,
|
|
helper(key) {
|
|
return `_${helperNameMap[key]}`;
|
|
},
|
|
push(code, node) {
|
|
context.code += code;
|
|
},
|
|
indent() {
|
|
newline(++context.indentLevel);
|
|
},
|
|
deindent(withoutNewLine = false) {
|
|
if (withoutNewLine) {
|
|
--context.indentLevel;
|
|
}
|
|
else {
|
|
newline(--context.indentLevel);
|
|
}
|
|
},
|
|
newline() {
|
|
newline(context.indentLevel);
|
|
}
|
|
};
|
|
function newline(n) {
|
|
context.push('\n' + ` `.repeat(n));
|
|
}
|
|
return context;
|
|
}
|
|
function generate(ast, options = {}) {
|
|
const context = createCodegenContext(ast, options);
|
|
if (options.onContextCreated)
|
|
options.onContextCreated(context);
|
|
const { mode, push, prefixIdentifiers, indent, deindent, newline, scopeId, ssr } = context;
|
|
const hasHelpers = ast.helpers.length > 0;
|
|
const useWithBlock = !prefixIdentifiers && mode !== 'module';
|
|
// preambles
|
|
// in setup() inline mode, the preamble is generated in a sub context
|
|
// and returned separately.
|
|
const preambleContext = context;
|
|
{
|
|
genFunctionPreamble(ast, preambleContext);
|
|
}
|
|
// enter render function
|
|
const functionName = ssr ? `ssrRender` : `render`;
|
|
const args = ssr ? ['_ctx', '_push', '_parent', '_attrs'] : ['_ctx', '_cache'];
|
|
const signature = args.join(', ');
|
|
{
|
|
push(`function ${functionName}(${signature}) {`);
|
|
}
|
|
indent();
|
|
if (useWithBlock) {
|
|
push(`with (_ctx) {`);
|
|
indent();
|
|
// function mode const declarations should be inside with block
|
|
// also they should be renamed to avoid collision with user properties
|
|
if (hasHelpers) {
|
|
push(`const { ${ast.helpers
|
|
.map(s => `${helperNameMap[s]}: _${helperNameMap[s]}`)
|
|
.join(', ')} } = _Vue`);
|
|
push(`\n`);
|
|
newline();
|
|
}
|
|
}
|
|
// generate asset resolution statements
|
|
if (ast.components.length) {
|
|
genAssets(ast.components, 'component', context);
|
|
if (ast.directives.length || ast.temps > 0) {
|
|
newline();
|
|
}
|
|
}
|
|
if (ast.directives.length) {
|
|
genAssets(ast.directives, 'directive', context);
|
|
if (ast.temps > 0) {
|
|
newline();
|
|
}
|
|
}
|
|
if (ast.filters && ast.filters.length) {
|
|
newline();
|
|
genAssets(ast.filters, 'filter', context);
|
|
newline();
|
|
}
|
|
if (ast.temps > 0) {
|
|
push(`let `);
|
|
for (let i = 0; i < ast.temps; i++) {
|
|
push(`${i > 0 ? `, ` : ``}_temp${i}`);
|
|
}
|
|
}
|
|
if (ast.components.length || ast.directives.length || ast.temps) {
|
|
push(`\n`);
|
|
newline();
|
|
}
|
|
// generate the VNode tree expression
|
|
if (!ssr) {
|
|
push(`return `);
|
|
}
|
|
if (ast.codegenNode) {
|
|
genNode(ast.codegenNode, context);
|
|
}
|
|
else {
|
|
push(`null`);
|
|
}
|
|
if (useWithBlock) {
|
|
deindent();
|
|
push(`}`);
|
|
}
|
|
deindent();
|
|
push(`}`);
|
|
return {
|
|
ast,
|
|
code: context.code,
|
|
preamble: ``,
|
|
// SourceMapGenerator does have toJSON() method but it's not in the types
|
|
map: context.map ? context.map.toJSON() : undefined
|
|
};
|
|
}
|
|
function genFunctionPreamble(ast, context) {
|
|
const { ssr, prefixIdentifiers, push, newline, runtimeModuleName, runtimeGlobalName } = context;
|
|
const VueBinding = runtimeGlobalName;
|
|
const aliasHelper = (s) => `${helperNameMap[s]}: _${helperNameMap[s]}`;
|
|
// Generate const declaration for helpers
|
|
// In prefix mode, we place the const declaration at top so it's done
|
|
// only once; But if we not prefixing, we place the declaration inside the
|
|
// with block so it doesn't incur the `in` check cost for every helper access.
|
|
if (ast.helpers.length > 0) {
|
|
{
|
|
// "with" mode.
|
|
// save Vue in a separate variable to avoid collision
|
|
push(`const _Vue = ${VueBinding}\n`);
|
|
// in "with" mode, helpers are declared inside the with block to avoid
|
|
// has check cost, but hoists are lifted out of the function - we need
|
|
// to provide the helper here.
|
|
if (ast.hoists.length) {
|
|
const staticHelpers = [
|
|
CREATE_VNODE,
|
|
CREATE_ELEMENT_VNODE,
|
|
CREATE_COMMENT,
|
|
CREATE_TEXT,
|
|
CREATE_STATIC
|
|
]
|
|
.filter(helper => ast.helpers.includes(helper))
|
|
.map(aliasHelper)
|
|
.join(', ');
|
|
push(`const { ${staticHelpers} } = _Vue\n`);
|
|
}
|
|
}
|
|
}
|
|
genHoists(ast.hoists, context);
|
|
newline();
|
|
push(`return `);
|
|
}
|
|
function genAssets(assets, type, { helper, push, newline, isTS }) {
|
|
const resolver = helper(type === 'filter'
|
|
? RESOLVE_FILTER
|
|
: type === 'component'
|
|
? RESOLVE_COMPONENT
|
|
: RESOLVE_DIRECTIVE);
|
|
for (let i = 0; i < assets.length; i++) {
|
|
let id = assets[i];
|
|
// potential component implicit self-reference inferred from SFC filename
|
|
const maybeSelfReference = id.endsWith('__self');
|
|
if (maybeSelfReference) {
|
|
id = id.slice(0, -6);
|
|
}
|
|
push(`const ${toValidAssetId(id, type)} = ${resolver}(${JSON.stringify(id)}${maybeSelfReference ? `, true` : ``})${isTS ? `!` : ``}`);
|
|
if (i < assets.length - 1) {
|
|
newline();
|
|
}
|
|
}
|
|
}
|
|
function genHoists(hoists, context) {
|
|
if (!hoists.length) {
|
|
return;
|
|
}
|
|
context.pure = true;
|
|
const { push, newline, helper, scopeId, mode } = context;
|
|
newline();
|
|
hoists.forEach((exp, i) => {
|
|
if (exp) {
|
|
push(`const _hoisted_${i + 1} = `);
|
|
genNode(exp, context);
|
|
newline();
|
|
}
|
|
});
|
|
context.pure = false;
|
|
}
|
|
function isText$1(n) {
|
|
return ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isString)(n) ||
|
|
n.type === 4 /* SIMPLE_EXPRESSION */ ||
|
|
n.type === 2 /* TEXT */ ||
|
|
n.type === 5 /* INTERPOLATION */ ||
|
|
n.type === 8 /* COMPOUND_EXPRESSION */);
|
|
}
|
|
function genNodeListAsArray(nodes, context) {
|
|
const multilines = nodes.length > 3 ||
|
|
((( true)) && nodes.some(n => (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isArray)(n) || !isText$1(n)));
|
|
context.push(`[`);
|
|
multilines && context.indent();
|
|
genNodeList(nodes, context, multilines);
|
|
multilines && context.deindent();
|
|
context.push(`]`);
|
|
}
|
|
function genNodeList(nodes, context, multilines = false, comma = true) {
|
|
const { push, newline } = context;
|
|
for (let i = 0; i < nodes.length; i++) {
|
|
const node = nodes[i];
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isString)(node)) {
|
|
push(node);
|
|
}
|
|
else if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isArray)(node)) {
|
|
genNodeListAsArray(node, context);
|
|
}
|
|
else {
|
|
genNode(node, context);
|
|
}
|
|
if (i < nodes.length - 1) {
|
|
if (multilines) {
|
|
comma && push(',');
|
|
newline();
|
|
}
|
|
else {
|
|
comma && push(', ');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function genNode(node, context) {
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isString)(node)) {
|
|
context.push(node);
|
|
return;
|
|
}
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isSymbol)(node)) {
|
|
context.push(context.helper(node));
|
|
return;
|
|
}
|
|
switch (node.type) {
|
|
case 1 /* ELEMENT */:
|
|
case 9 /* IF */:
|
|
case 11 /* FOR */:
|
|
( true) &&
|
|
assert(node.codegenNode != null, `Codegen node is missing for element/if/for node. ` +
|
|
`Apply appropriate transforms first.`);
|
|
genNode(node.codegenNode, context);
|
|
break;
|
|
case 2 /* TEXT */:
|
|
genText(node, context);
|
|
break;
|
|
case 4 /* SIMPLE_EXPRESSION */:
|
|
genExpression(node, context);
|
|
break;
|
|
case 5 /* INTERPOLATION */:
|
|
genInterpolation(node, context);
|
|
break;
|
|
case 12 /* TEXT_CALL */:
|
|
genNode(node.codegenNode, context);
|
|
break;
|
|
case 8 /* COMPOUND_EXPRESSION */:
|
|
genCompoundExpression(node, context);
|
|
break;
|
|
case 3 /* COMMENT */:
|
|
genComment(node, context);
|
|
break;
|
|
case 13 /* VNODE_CALL */:
|
|
genVNodeCall(node, context);
|
|
break;
|
|
case 14 /* JS_CALL_EXPRESSION */:
|
|
genCallExpression(node, context);
|
|
break;
|
|
case 15 /* JS_OBJECT_EXPRESSION */:
|
|
genObjectExpression(node, context);
|
|
break;
|
|
case 17 /* JS_ARRAY_EXPRESSION */:
|
|
genArrayExpression(node, context);
|
|
break;
|
|
case 18 /* JS_FUNCTION_EXPRESSION */:
|
|
genFunctionExpression(node, context);
|
|
break;
|
|
case 19 /* JS_CONDITIONAL_EXPRESSION */:
|
|
genConditionalExpression(node, context);
|
|
break;
|
|
case 20 /* JS_CACHE_EXPRESSION */:
|
|
genCacheExpression(node, context);
|
|
break;
|
|
case 21 /* JS_BLOCK_STATEMENT */:
|
|
genNodeList(node.body, context, true, false);
|
|
break;
|
|
// SSR only types
|
|
case 22 /* JS_TEMPLATE_LITERAL */:
|
|
break;
|
|
case 23 /* JS_IF_STATEMENT */:
|
|
break;
|
|
case 24 /* JS_ASSIGNMENT_EXPRESSION */:
|
|
break;
|
|
case 25 /* JS_SEQUENCE_EXPRESSION */:
|
|
break;
|
|
case 26 /* JS_RETURN_STATEMENT */:
|
|
break;
|
|
/* istanbul ignore next */
|
|
case 10 /* IF_BRANCH */:
|
|
// noop
|
|
break;
|
|
default:
|
|
if ((true)) {
|
|
assert(false, `unhandled codegen node type: ${node.type}`);
|
|
// make sure we exhaust all possible types
|
|
const exhaustiveCheck = node;
|
|
return exhaustiveCheck;
|
|
}
|
|
}
|
|
}
|
|
function genText(node, context) {
|
|
context.push(JSON.stringify(node.content), node);
|
|
}
|
|
function genExpression(node, context) {
|
|
const { content, isStatic } = node;
|
|
context.push(isStatic ? JSON.stringify(content) : content, node);
|
|
}
|
|
function genInterpolation(node, context) {
|
|
const { push, helper, pure } = context;
|
|
if (pure)
|
|
push(PURE_ANNOTATION);
|
|
push(`${helper(TO_DISPLAY_STRING)}(`);
|
|
genNode(node.content, context);
|
|
push(`)`);
|
|
}
|
|
function genCompoundExpression(node, context) {
|
|
for (let i = 0; i < node.children.length; i++) {
|
|
const child = node.children[i];
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isString)(child)) {
|
|
context.push(child);
|
|
}
|
|
else {
|
|
genNode(child, context);
|
|
}
|
|
}
|
|
}
|
|
function genExpressionAsPropertyKey(node, context) {
|
|
const { push } = context;
|
|
if (node.type === 8 /* COMPOUND_EXPRESSION */) {
|
|
push(`[`);
|
|
genCompoundExpression(node, context);
|
|
push(`]`);
|
|
}
|
|
else if (node.isStatic) {
|
|
// only quote keys if necessary
|
|
const text = isSimpleIdentifier(node.content)
|
|
? node.content
|
|
: JSON.stringify(node.content);
|
|
push(text, node);
|
|
}
|
|
else {
|
|
push(`[${node.content}]`, node);
|
|
}
|
|
}
|
|
function genComment(node, context) {
|
|
const { push, helper, pure } = context;
|
|
if (pure) {
|
|
push(PURE_ANNOTATION);
|
|
}
|
|
push(`${helper(CREATE_COMMENT)}(${JSON.stringify(node.content)})`, node);
|
|
}
|
|
function genVNodeCall(node, context) {
|
|
const { push, helper, pure } = context;
|
|
const { tag, props, children, patchFlag, dynamicProps, directives, isBlock, disableTracking, isComponent } = node;
|
|
if (directives) {
|
|
push(helper(WITH_DIRECTIVES) + `(`);
|
|
}
|
|
if (isBlock) {
|
|
push(`(${helper(OPEN_BLOCK)}(${disableTracking ? `true` : ``}), `);
|
|
}
|
|
if (pure) {
|
|
push(PURE_ANNOTATION);
|
|
}
|
|
const callHelper = isBlock
|
|
? getVNodeBlockHelper(context.inSSR, isComponent)
|
|
: getVNodeHelper(context.inSSR, isComponent);
|
|
push(helper(callHelper) + `(`, node);
|
|
genNodeList(genNullableArgs([tag, props, children, patchFlag, dynamicProps]), context);
|
|
push(`)`);
|
|
if (isBlock) {
|
|
push(`)`);
|
|
}
|
|
if (directives) {
|
|
push(`, `);
|
|
genNode(directives, context);
|
|
push(`)`);
|
|
}
|
|
}
|
|
function genNullableArgs(args) {
|
|
let i = args.length;
|
|
while (i--) {
|
|
if (args[i] != null)
|
|
break;
|
|
}
|
|
return args.slice(0, i + 1).map(arg => arg || `null`);
|
|
}
|
|
// JavaScript
|
|
function genCallExpression(node, context) {
|
|
const { push, helper, pure } = context;
|
|
const callee = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isString)(node.callee) ? node.callee : helper(node.callee);
|
|
if (pure) {
|
|
push(PURE_ANNOTATION);
|
|
}
|
|
push(callee + `(`, node);
|
|
genNodeList(node.arguments, context);
|
|
push(`)`);
|
|
}
|
|
function genObjectExpression(node, context) {
|
|
const { push, indent, deindent, newline } = context;
|
|
const { properties } = node;
|
|
if (!properties.length) {
|
|
push(`{}`, node);
|
|
return;
|
|
}
|
|
const multilines = properties.length > 1 ||
|
|
((( true)) &&
|
|
properties.some(p => p.value.type !== 4 /* SIMPLE_EXPRESSION */));
|
|
push(multilines ? `{` : `{ `);
|
|
multilines && indent();
|
|
for (let i = 0; i < properties.length; i++) {
|
|
const { key, value } = properties[i];
|
|
// key
|
|
genExpressionAsPropertyKey(key, context);
|
|
push(`: `);
|
|
// value
|
|
genNode(value, context);
|
|
if (i < properties.length - 1) {
|
|
// will only reach this if it's multilines
|
|
push(`,`);
|
|
newline();
|
|
}
|
|
}
|
|
multilines && deindent();
|
|
push(multilines ? `}` : ` }`);
|
|
}
|
|
function genArrayExpression(node, context) {
|
|
genNodeListAsArray(node.elements, context);
|
|
}
|
|
function genFunctionExpression(node, context) {
|
|
const { push, indent, deindent } = context;
|
|
const { params, returns, body, newline, isSlot } = node;
|
|
if (isSlot) {
|
|
// wrap slot functions with owner context
|
|
push(`_${helperNameMap[WITH_CTX]}(`);
|
|
}
|
|
push(`(`, node);
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isArray)(params)) {
|
|
genNodeList(params, context);
|
|
}
|
|
else if (params) {
|
|
genNode(params, context);
|
|
}
|
|
push(`) => `);
|
|
if (newline || body) {
|
|
push(`{`);
|
|
indent();
|
|
}
|
|
if (returns) {
|
|
if (newline) {
|
|
push(`return `);
|
|
}
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isArray)(returns)) {
|
|
genNodeListAsArray(returns, context);
|
|
}
|
|
else {
|
|
genNode(returns, context);
|
|
}
|
|
}
|
|
else if (body) {
|
|
genNode(body, context);
|
|
}
|
|
if (newline || body) {
|
|
deindent();
|
|
push(`}`);
|
|
}
|
|
if (isSlot) {
|
|
if (node.isNonScopedSlot) {
|
|
push(`, undefined, true`);
|
|
}
|
|
push(`)`);
|
|
}
|
|
}
|
|
function genConditionalExpression(node, context) {
|
|
const { test, consequent, alternate, newline: needNewline } = node;
|
|
const { push, indent, deindent, newline } = context;
|
|
if (test.type === 4 /* SIMPLE_EXPRESSION */) {
|
|
const needsParens = !isSimpleIdentifier(test.content);
|
|
needsParens && push(`(`);
|
|
genExpression(test, context);
|
|
needsParens && push(`)`);
|
|
}
|
|
else {
|
|
push(`(`);
|
|
genNode(test, context);
|
|
push(`)`);
|
|
}
|
|
needNewline && indent();
|
|
context.indentLevel++;
|
|
needNewline || push(` `);
|
|
push(`? `);
|
|
genNode(consequent, context);
|
|
context.indentLevel--;
|
|
needNewline && newline();
|
|
needNewline || push(` `);
|
|
push(`: `);
|
|
const isNested = alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */;
|
|
if (!isNested) {
|
|
context.indentLevel++;
|
|
}
|
|
genNode(alternate, context);
|
|
if (!isNested) {
|
|
context.indentLevel--;
|
|
}
|
|
needNewline && deindent(true /* without newline */);
|
|
}
|
|
function genCacheExpression(node, context) {
|
|
const { push, helper, indent, deindent, newline } = context;
|
|
push(`_cache[${node.index}] || (`);
|
|
if (node.isVNode) {
|
|
indent();
|
|
push(`${helper(SET_BLOCK_TRACKING)}(-1),`);
|
|
newline();
|
|
}
|
|
push(`_cache[${node.index}] = `);
|
|
genNode(node.value, context);
|
|
if (node.isVNode) {
|
|
push(`,`);
|
|
newline();
|
|
push(`${helper(SET_BLOCK_TRACKING)}(1),`);
|
|
newline();
|
|
push(`_cache[${node.index}]`);
|
|
deindent();
|
|
}
|
|
push(`)`);
|
|
}
|
|
|
|
function walkIdentifiers(root, onIdentifier, includeAll = false, parentStack = [], knownIds = Object.create(null)) {
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
function isReferencedIdentifier(id, parent, parentStack) {
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
function isInDestructureAssignment(parent, parentStack) {
|
|
if (parent &&
|
|
(parent.type === 'ObjectProperty' || parent.type === 'ArrayPattern')) {
|
|
let i = parentStack.length;
|
|
while (i--) {
|
|
const p = parentStack[i];
|
|
if (p.type === 'AssignmentExpression') {
|
|
return true;
|
|
}
|
|
else if (p.type !== 'ObjectProperty' && !p.type.endsWith('Pattern')) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
function walkFunctionParams(node, onIdent) {
|
|
for (const p of node.params) {
|
|
for (const id of extractIdentifiers(p)) {
|
|
onIdent(id);
|
|
}
|
|
}
|
|
}
|
|
function walkBlockDeclarations(block, onIdent) {
|
|
for (const stmt of block.body) {
|
|
if (stmt.type === 'VariableDeclaration') {
|
|
if (stmt.declare)
|
|
continue;
|
|
for (const decl of stmt.declarations) {
|
|
for (const id of extractIdentifiers(decl.id)) {
|
|
onIdent(id);
|
|
}
|
|
}
|
|
}
|
|
else if (stmt.type === 'FunctionDeclaration' ||
|
|
stmt.type === 'ClassDeclaration') {
|
|
if (stmt.declare || !stmt.id)
|
|
continue;
|
|
onIdent(stmt.id);
|
|
}
|
|
}
|
|
}
|
|
function extractIdentifiers(param, nodes = []) {
|
|
switch (param.type) {
|
|
case 'Identifier':
|
|
nodes.push(param);
|
|
break;
|
|
case 'MemberExpression':
|
|
let object = param;
|
|
while (object.type === 'MemberExpression') {
|
|
object = object.object;
|
|
}
|
|
nodes.push(object);
|
|
break;
|
|
case 'ObjectPattern':
|
|
for (const prop of param.properties) {
|
|
if (prop.type === 'RestElement') {
|
|
extractIdentifiers(prop.argument, nodes);
|
|
}
|
|
else {
|
|
extractIdentifiers(prop.value, nodes);
|
|
}
|
|
}
|
|
break;
|
|
case 'ArrayPattern':
|
|
param.elements.forEach(element => {
|
|
if (element)
|
|
extractIdentifiers(element, nodes);
|
|
});
|
|
break;
|
|
case 'RestElement':
|
|
extractIdentifiers(param.argument, nodes);
|
|
break;
|
|
case 'AssignmentPattern':
|
|
extractIdentifiers(param.left, nodes);
|
|
break;
|
|
}
|
|
return nodes;
|
|
}
|
|
const isFunctionType = (node) => {
|
|
return /Function(?:Expression|Declaration)$|Method$/.test(node.type);
|
|
};
|
|
const isStaticProperty = (node) => node &&
|
|
(node.type === 'ObjectProperty' || node.type === 'ObjectMethod') &&
|
|
!node.computed;
|
|
const isStaticPropertyKey = (node, parent) => isStaticProperty(parent) && parent.key === node;
|
|
|
|
// these keywords should not appear inside expressions, but operators like
|
|
// typeof, instanceof and in are allowed
|
|
const prohibitedKeywordRE = new RegExp('\\b' +
|
|
('do,if,for,let,new,try,var,case,else,with,await,break,catch,class,const,' +
|
|
'super,throw,while,yield,delete,export,import,return,switch,default,' +
|
|
'extends,finally,continue,debugger,function,arguments,typeof,void')
|
|
.split(',')
|
|
.join('\\b|\\b') +
|
|
'\\b');
|
|
// strip strings in expressions
|
|
const stripStringRE = /'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|`(?:[^`\\]|\\.)*\$\{|\}(?:[^`\\]|\\.)*`|`(?:[^`\\]|\\.)*`/g;
|
|
/**
|
|
* Validate a non-prefixed expression.
|
|
* This is only called when using the in-browser runtime compiler since it
|
|
* doesn't prefix expressions.
|
|
*/
|
|
function validateBrowserExpression(node, context, asParams = false, asRawStatements = false) {
|
|
const exp = node.content;
|
|
// empty expressions are validated per-directive since some directives
|
|
// do allow empty expressions.
|
|
if (!exp.trim()) {
|
|
return;
|
|
}
|
|
try {
|
|
new Function(asRawStatements
|
|
? ` ${exp} `
|
|
: `return ${asParams ? `(${exp}) => {}` : `(${exp})`}`);
|
|
}
|
|
catch (e) {
|
|
let message = e.message;
|
|
const keywordMatch = exp
|
|
.replace(stripStringRE, '')
|
|
.match(prohibitedKeywordRE);
|
|
if (keywordMatch) {
|
|
message = `avoid using JavaScript keyword as property name: "${keywordMatch[0]}"`;
|
|
}
|
|
context.onError(createCompilerError(43 /* X_INVALID_EXPRESSION */, node.loc, undefined, message));
|
|
}
|
|
}
|
|
|
|
const transformExpression = (node, context) => {
|
|
if (node.type === 5 /* INTERPOLATION */) {
|
|
node.content = processExpression(node.content, context);
|
|
}
|
|
else if (node.type === 1 /* ELEMENT */) {
|
|
// handle directives on element
|
|
for (let i = 0; i < node.props.length; i++) {
|
|
const dir = node.props[i];
|
|
// do not process for v-on & v-for since they are special handled
|
|
if (dir.type === 7 /* DIRECTIVE */ && dir.name !== 'for') {
|
|
const exp = dir.exp;
|
|
const arg = dir.arg;
|
|
// do not process exp if this is v-on:arg - we need special handling
|
|
// for wrapping inline statements.
|
|
if (exp &&
|
|
exp.type === 4 /* SIMPLE_EXPRESSION */ &&
|
|
!(dir.name === 'on' && arg)) {
|
|
dir.exp = processExpression(exp, context,
|
|
// slot args must be processed as function params
|
|
dir.name === 'slot');
|
|
}
|
|
if (arg && arg.type === 4 /* SIMPLE_EXPRESSION */ && !arg.isStatic) {
|
|
dir.arg = processExpression(arg, context);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
// Important: since this function uses Node.js only dependencies, it should
|
|
// always be used with a leading !true check so that it can be
|
|
// tree-shaken from the browser build.
|
|
function processExpression(node, context,
|
|
// some expressions like v-slot props & v-for aliases should be parsed as
|
|
// function params
|
|
asParams = false,
|
|
// v-on handler values may contain multiple statements
|
|
asRawStatements = false) {
|
|
{
|
|
if ((true)) {
|
|
// simple in-browser validation (same logic in 2.x)
|
|
validateBrowserExpression(node, context, asParams, asRawStatements);
|
|
}
|
|
return node;
|
|
}
|
|
}
|
|
|
|
const transformIf = createStructuralDirectiveTransform(/^(if|else|else-if)$/, (node, dir, context) => {
|
|
return processIf(node, dir, context, (ifNode, branch, isRoot) => {
|
|
// #1587: We need to dynamically increment the key based on the current
|
|
// node's sibling nodes, since chained v-if/else branches are
|
|
// rendered at the same depth
|
|
const siblings = context.parent.children;
|
|
let i = siblings.indexOf(ifNode);
|
|
let key = 0;
|
|
while (i-- >= 0) {
|
|
const sibling = siblings[i];
|
|
if (sibling && sibling.type === 9 /* IF */) {
|
|
key += sibling.branches.length;
|
|
}
|
|
}
|
|
// Exit callback. Complete the codegenNode when all children have been
|
|
// transformed.
|
|
return () => {
|
|
if (isRoot) {
|
|
ifNode.codegenNode = createCodegenNodeForBranch(branch, key, context);
|
|
}
|
|
else {
|
|
// attach this branch's codegen node to the v-if root.
|
|
const parentCondition = getParentCondition(ifNode.codegenNode);
|
|
parentCondition.alternate = createCodegenNodeForBranch(branch, key + ifNode.branches.length - 1, context);
|
|
}
|
|
};
|
|
});
|
|
});
|
|
// target-agnostic transform used for both Client and SSR
|
|
function processIf(node, dir, context, processCodegen) {
|
|
if (dir.name !== 'else' &&
|
|
(!dir.exp || !dir.exp.content.trim())) {
|
|
const loc = dir.exp ? dir.exp.loc : node.loc;
|
|
context.onError(createCompilerError(27 /* X_V_IF_NO_EXPRESSION */, dir.loc));
|
|
dir.exp = createSimpleExpression(`true`, false, loc);
|
|
}
|
|
if ( true && dir.exp) {
|
|
validateBrowserExpression(dir.exp, context);
|
|
}
|
|
if (dir.name === 'if') {
|
|
const branch = createIfBranch(node, dir);
|
|
const ifNode = {
|
|
type: 9 /* IF */,
|
|
loc: node.loc,
|
|
branches: [branch]
|
|
};
|
|
context.replaceNode(ifNode);
|
|
if (processCodegen) {
|
|
return processCodegen(ifNode, branch, true);
|
|
}
|
|
}
|
|
else {
|
|
// locate the adjacent v-if
|
|
const siblings = context.parent.children;
|
|
const comments = [];
|
|
let i = siblings.indexOf(node);
|
|
while (i-- >= -1) {
|
|
const sibling = siblings[i];
|
|
if (( true) && sibling && sibling.type === 3 /* COMMENT */) {
|
|
context.removeNode(sibling);
|
|
comments.unshift(sibling);
|
|
continue;
|
|
}
|
|
if (sibling &&
|
|
sibling.type === 2 /* TEXT */ &&
|
|
!sibling.content.trim().length) {
|
|
context.removeNode(sibling);
|
|
continue;
|
|
}
|
|
if (sibling && sibling.type === 9 /* IF */) {
|
|
// move the node to the if node's branches
|
|
context.removeNode();
|
|
const branch = createIfBranch(node, dir);
|
|
if (( true) &&
|
|
comments.length &&
|
|
// #3619 ignore comments if the v-if is direct child of <transition>
|
|
!(context.parent &&
|
|
context.parent.type === 1 /* ELEMENT */ &&
|
|
isBuiltInType(context.parent.tag, 'transition'))) {
|
|
branch.children = [...comments, ...branch.children];
|
|
}
|
|
// check if user is forcing same key on different branches
|
|
if (true) {
|
|
const key = branch.userKey;
|
|
if (key) {
|
|
sibling.branches.forEach(({ userKey }) => {
|
|
if (isSameKey(userKey, key)) {
|
|
context.onError(createCompilerError(28 /* X_V_IF_SAME_KEY */, branch.userKey.loc));
|
|
}
|
|
});
|
|
}
|
|
}
|
|
sibling.branches.push(branch);
|
|
const onExit = processCodegen && processCodegen(sibling, branch, false);
|
|
// since the branch was removed, it will not be traversed.
|
|
// make sure to traverse here.
|
|
traverseNode(branch, context);
|
|
// call on exit
|
|
if (onExit)
|
|
onExit();
|
|
// make sure to reset currentNode after traversal to indicate this
|
|
// node has been removed.
|
|
context.currentNode = null;
|
|
}
|
|
else {
|
|
context.onError(createCompilerError(29 /* X_V_ELSE_NO_ADJACENT_IF */, node.loc));
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
function createIfBranch(node, dir) {
|
|
return {
|
|
type: 10 /* IF_BRANCH */,
|
|
loc: node.loc,
|
|
condition: dir.name === 'else' ? undefined : dir.exp,
|
|
children: node.tagType === 3 /* TEMPLATE */ && !findDir(node, 'for')
|
|
? node.children
|
|
: [node],
|
|
userKey: findProp(node, `key`)
|
|
};
|
|
}
|
|
function createCodegenNodeForBranch(branch, keyIndex, context) {
|
|
if (branch.condition) {
|
|
return createConditionalExpression(branch.condition, createChildrenCodegenNode(branch, keyIndex, context),
|
|
// make sure to pass in asBlock: true so that the comment node call
|
|
// closes the current block.
|
|
createCallExpression(context.helper(CREATE_COMMENT), [
|
|
( true) ? '"v-if"' : 0,
|
|
'true'
|
|
]));
|
|
}
|
|
else {
|
|
return createChildrenCodegenNode(branch, keyIndex, context);
|
|
}
|
|
}
|
|
function createChildrenCodegenNode(branch, keyIndex, context) {
|
|
const { helper } = context;
|
|
const keyProperty = createObjectProperty(`key`, createSimpleExpression(`${keyIndex}`, false, locStub, 2 /* CAN_HOIST */));
|
|
const { children } = branch;
|
|
const firstChild = children[0];
|
|
const needFragmentWrapper = children.length !== 1 || firstChild.type !== 1 /* ELEMENT */;
|
|
if (needFragmentWrapper) {
|
|
if (children.length === 1 && firstChild.type === 11 /* FOR */) {
|
|
// optimize away nested fragments when child is a ForNode
|
|
const vnodeCall = firstChild.codegenNode;
|
|
injectProp(vnodeCall, keyProperty, context);
|
|
return vnodeCall;
|
|
}
|
|
else {
|
|
let patchFlag = 64 /* STABLE_FRAGMENT */;
|
|
let patchFlagText = _vue_shared__WEBPACK_IMPORTED_MODULE_0__.PatchFlagNames[64];
|
|
// check if the fragment actually contains a single valid child with
|
|
// the rest being comments
|
|
if (( true) &&
|
|
children.filter(c => c.type !== 3 /* COMMENT */).length === 1) {
|
|
patchFlag |= 2048 /* DEV_ROOT_FRAGMENT */;
|
|
patchFlagText += `, ${_vue_shared__WEBPACK_IMPORTED_MODULE_0__.PatchFlagNames[2048]}`;
|
|
}
|
|
return createVNodeCall(context, helper(FRAGMENT), createObjectExpression([keyProperty]), children, patchFlag + (( true) ? ` /* ${patchFlagText} */` : 0), undefined, undefined, true, false, false /* isComponent */, branch.loc);
|
|
}
|
|
}
|
|
else {
|
|
const ret = firstChild.codegenNode;
|
|
const vnodeCall = getMemoedVNodeCall(ret);
|
|
// Change createVNode to createBlock.
|
|
if (vnodeCall.type === 13 /* VNODE_CALL */) {
|
|
makeBlock(vnodeCall, context);
|
|
}
|
|
// inject branch key
|
|
injectProp(vnodeCall, keyProperty, context);
|
|
return ret;
|
|
}
|
|
}
|
|
function isSameKey(a, b) {
|
|
if (!a || a.type !== b.type) {
|
|
return false;
|
|
}
|
|
if (a.type === 6 /* ATTRIBUTE */) {
|
|
if (a.value.content !== b.value.content) {
|
|
return false;
|
|
}
|
|
}
|
|
else {
|
|
// directive
|
|
const exp = a.exp;
|
|
const branchExp = b.exp;
|
|
if (exp.type !== branchExp.type) {
|
|
return false;
|
|
}
|
|
if (exp.type !== 4 /* SIMPLE_EXPRESSION */ ||
|
|
exp.isStatic !== branchExp.isStatic ||
|
|
exp.content !== branchExp.content) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
function getParentCondition(node) {
|
|
while (true) {
|
|
if (node.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {
|
|
if (node.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {
|
|
node = node.alternate;
|
|
}
|
|
else {
|
|
return node;
|
|
}
|
|
}
|
|
else if (node.type === 20 /* JS_CACHE_EXPRESSION */) {
|
|
node = node.value;
|
|
}
|
|
}
|
|
}
|
|
|
|
const transformFor = createStructuralDirectiveTransform('for', (node, dir, context) => {
|
|
const { helper, removeHelper } = context;
|
|
return processFor(node, dir, context, forNode => {
|
|
// create the loop render function expression now, and add the
|
|
// iterator on exit after all children have been traversed
|
|
const renderExp = createCallExpression(helper(RENDER_LIST), [
|
|
forNode.source
|
|
]);
|
|
const memo = findDir(node, 'memo');
|
|
const keyProp = findProp(node, `key`);
|
|
const keyExp = keyProp &&
|
|
(keyProp.type === 6 /* ATTRIBUTE */
|
|
? createSimpleExpression(keyProp.value.content, true)
|
|
: keyProp.exp);
|
|
const keyProperty = keyProp ? createObjectProperty(`key`, keyExp) : null;
|
|
const isStableFragment = forNode.source.type === 4 /* SIMPLE_EXPRESSION */ &&
|
|
forNode.source.constType > 0 /* NOT_CONSTANT */;
|
|
const fragmentFlag = isStableFragment
|
|
? 64 /* STABLE_FRAGMENT */
|
|
: keyProp
|
|
? 128 /* KEYED_FRAGMENT */
|
|
: 256 /* UNKEYED_FRAGMENT */;
|
|
forNode.codegenNode = createVNodeCall(context, helper(FRAGMENT), undefined, renderExp, fragmentFlag +
|
|
(( true) ? ` /* ${_vue_shared__WEBPACK_IMPORTED_MODULE_0__.PatchFlagNames[fragmentFlag]} */` : 0), undefined, undefined, true /* isBlock */, !isStableFragment /* disableTracking */, false /* isComponent */, node.loc);
|
|
return () => {
|
|
// finish the codegen now that all children have been traversed
|
|
let childBlock;
|
|
const isTemplate = isTemplateNode(node);
|
|
const { children } = forNode;
|
|
// check <template v-for> key placement
|
|
if (( true) && isTemplate) {
|
|
node.children.some(c => {
|
|
if (c.type === 1 /* ELEMENT */) {
|
|
const key = findProp(c, 'key');
|
|
if (key) {
|
|
context.onError(createCompilerError(32 /* X_V_FOR_TEMPLATE_KEY_PLACEMENT */, key.loc));
|
|
return true;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
const needFragmentWrapper = children.length !== 1 || children[0].type !== 1 /* ELEMENT */;
|
|
const slotOutlet = isSlotOutlet(node)
|
|
? node
|
|
: isTemplate &&
|
|
node.children.length === 1 &&
|
|
isSlotOutlet(node.children[0])
|
|
? node.children[0] // api-extractor somehow fails to infer this
|
|
: null;
|
|
if (slotOutlet) {
|
|
// <slot v-for="..."> or <template v-for="..."><slot/></template>
|
|
childBlock = slotOutlet.codegenNode;
|
|
if (isTemplate && keyProperty) {
|
|
// <template v-for="..." :key="..."><slot/></template>
|
|
// we need to inject the key to the renderSlot() call.
|
|
// the props for renderSlot is passed as the 3rd argument.
|
|
injectProp(childBlock, keyProperty, context);
|
|
}
|
|
}
|
|
else if (needFragmentWrapper) {
|
|
// <template v-for="..."> with text or multi-elements
|
|
// should generate a fragment block for each loop
|
|
childBlock = createVNodeCall(context, helper(FRAGMENT), keyProperty ? createObjectExpression([keyProperty]) : undefined, node.children, 64 /* STABLE_FRAGMENT */ +
|
|
(( true)
|
|
? ` /* ${_vue_shared__WEBPACK_IMPORTED_MODULE_0__.PatchFlagNames[64]} */`
|
|
: 0), undefined, undefined, true, undefined, false /* isComponent */);
|
|
}
|
|
else {
|
|
// Normal element v-for. Directly use the child's codegenNode
|
|
// but mark it as a block.
|
|
childBlock = children[0]
|
|
.codegenNode;
|
|
if (isTemplate && keyProperty) {
|
|
injectProp(childBlock, keyProperty, context);
|
|
}
|
|
if (childBlock.isBlock !== !isStableFragment) {
|
|
if (childBlock.isBlock) {
|
|
// switch from block to vnode
|
|
removeHelper(OPEN_BLOCK);
|
|
removeHelper(getVNodeBlockHelper(context.inSSR, childBlock.isComponent));
|
|
}
|
|
else {
|
|
// switch from vnode to block
|
|
removeHelper(getVNodeHelper(context.inSSR, childBlock.isComponent));
|
|
}
|
|
}
|
|
childBlock.isBlock = !isStableFragment;
|
|
if (childBlock.isBlock) {
|
|
helper(OPEN_BLOCK);
|
|
helper(getVNodeBlockHelper(context.inSSR, childBlock.isComponent));
|
|
}
|
|
else {
|
|
helper(getVNodeHelper(context.inSSR, childBlock.isComponent));
|
|
}
|
|
}
|
|
if (memo) {
|
|
const loop = createFunctionExpression(createForLoopParams(forNode.parseResult, [
|
|
createSimpleExpression(`_cached`)
|
|
]));
|
|
loop.body = createBlockStatement([
|
|
createCompoundExpression([`const _memo = (`, memo.exp, `)`]),
|
|
createCompoundExpression([
|
|
`if (_cached`,
|
|
...(keyExp ? [` && _cached.key === `, keyExp] : []),
|
|
` && ${context.helperString(IS_MEMO_SAME)}(_cached, _memo)) return _cached`
|
|
]),
|
|
createCompoundExpression([`const _item = `, childBlock]),
|
|
createSimpleExpression(`_item.memo = _memo`),
|
|
createSimpleExpression(`return _item`)
|
|
]);
|
|
renderExp.arguments.push(loop, createSimpleExpression(`_cache`), createSimpleExpression(String(context.cached++)));
|
|
}
|
|
else {
|
|
renderExp.arguments.push(createFunctionExpression(createForLoopParams(forNode.parseResult), childBlock, true /* force newline */));
|
|
}
|
|
};
|
|
});
|
|
});
|
|
// target-agnostic transform used for both Client and SSR
|
|
function processFor(node, dir, context, processCodegen) {
|
|
if (!dir.exp) {
|
|
context.onError(createCompilerError(30 /* X_V_FOR_NO_EXPRESSION */, dir.loc));
|
|
return;
|
|
}
|
|
const parseResult = parseForExpression(
|
|
// can only be simple expression because vFor transform is applied
|
|
// before expression transform.
|
|
dir.exp, context);
|
|
if (!parseResult) {
|
|
context.onError(createCompilerError(31 /* X_V_FOR_MALFORMED_EXPRESSION */, dir.loc));
|
|
return;
|
|
}
|
|
const { addIdentifiers, removeIdentifiers, scopes } = context;
|
|
const { source, value, key, index } = parseResult;
|
|
const forNode = {
|
|
type: 11 /* FOR */,
|
|
loc: dir.loc,
|
|
source,
|
|
valueAlias: value,
|
|
keyAlias: key,
|
|
objectIndexAlias: index,
|
|
parseResult,
|
|
children: isTemplateNode(node) ? node.children : [node]
|
|
};
|
|
context.replaceNode(forNode);
|
|
// bookkeeping
|
|
scopes.vFor++;
|
|
const onExit = processCodegen && processCodegen(forNode);
|
|
return () => {
|
|
scopes.vFor--;
|
|
if (onExit)
|
|
onExit();
|
|
};
|
|
}
|
|
const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/;
|
|
// This regex doesn't cover the case if key or index aliases have destructuring,
|
|
// but those do not make sense in the first place, so this works in practice.
|
|
const forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/;
|
|
const stripParensRE = /^\(|\)$/g;
|
|
function parseForExpression(input, context) {
|
|
const loc = input.loc;
|
|
const exp = input.content;
|
|
const inMatch = exp.match(forAliasRE);
|
|
if (!inMatch)
|
|
return;
|
|
const [, LHS, RHS] = inMatch;
|
|
const result = {
|
|
source: createAliasExpression(loc, RHS.trim(), exp.indexOf(RHS, LHS.length)),
|
|
value: undefined,
|
|
key: undefined,
|
|
index: undefined
|
|
};
|
|
if (true) {
|
|
validateBrowserExpression(result.source, context);
|
|
}
|
|
let valueContent = LHS.trim().replace(stripParensRE, '').trim();
|
|
const trimmedOffset = LHS.indexOf(valueContent);
|
|
const iteratorMatch = valueContent.match(forIteratorRE);
|
|
if (iteratorMatch) {
|
|
valueContent = valueContent.replace(forIteratorRE, '').trim();
|
|
const keyContent = iteratorMatch[1].trim();
|
|
let keyOffset;
|
|
if (keyContent) {
|
|
keyOffset = exp.indexOf(keyContent, trimmedOffset + valueContent.length);
|
|
result.key = createAliasExpression(loc, keyContent, keyOffset);
|
|
if (true) {
|
|
validateBrowserExpression(result.key, context, true);
|
|
}
|
|
}
|
|
if (iteratorMatch[2]) {
|
|
const indexContent = iteratorMatch[2].trim();
|
|
if (indexContent) {
|
|
result.index = createAliasExpression(loc, indexContent, exp.indexOf(indexContent, result.key
|
|
? keyOffset + keyContent.length
|
|
: trimmedOffset + valueContent.length));
|
|
if (true) {
|
|
validateBrowserExpression(result.index, context, true);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (valueContent) {
|
|
result.value = createAliasExpression(loc, valueContent, trimmedOffset);
|
|
if (true) {
|
|
validateBrowserExpression(result.value, context, true);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
function createAliasExpression(range, content, offset) {
|
|
return createSimpleExpression(content, false, getInnerRange(range, offset, content.length));
|
|
}
|
|
function createForLoopParams({ value, key, index }, memoArgs = []) {
|
|
return createParamsList([value, key, index, ...memoArgs]);
|
|
}
|
|
function createParamsList(args) {
|
|
let i = args.length;
|
|
while (i--) {
|
|
if (args[i])
|
|
break;
|
|
}
|
|
return args
|
|
.slice(0, i + 1)
|
|
.map((arg, i) => arg || createSimpleExpression(`_`.repeat(i + 1), false));
|
|
}
|
|
|
|
const defaultFallback = createSimpleExpression(`undefined`, false);
|
|
// A NodeTransform that:
|
|
// 1. Tracks scope identifiers for scoped slots so that they don't get prefixed
|
|
// by transformExpression. This is only applied in non-browser builds with
|
|
// { prefixIdentifiers: true }.
|
|
// 2. Track v-slot depths so that we know a slot is inside another slot.
|
|
// Note the exit callback is executed before buildSlots() on the same node,
|
|
// so only nested slots see positive numbers.
|
|
const trackSlotScopes = (node, context) => {
|
|
if (node.type === 1 /* ELEMENT */ &&
|
|
(node.tagType === 1 /* COMPONENT */ ||
|
|
node.tagType === 3 /* TEMPLATE */)) {
|
|
// We are only checking non-empty v-slot here
|
|
// since we only care about slots that introduce scope variables.
|
|
const vSlot = findDir(node, 'slot');
|
|
if (vSlot) {
|
|
vSlot.exp;
|
|
context.scopes.vSlot++;
|
|
return () => {
|
|
context.scopes.vSlot--;
|
|
};
|
|
}
|
|
}
|
|
};
|
|
// A NodeTransform that tracks scope identifiers for scoped slots with v-for.
|
|
// This transform is only applied in non-browser builds with { prefixIdentifiers: true }
|
|
const trackVForSlotScopes = (node, context) => {
|
|
let vFor;
|
|
if (isTemplateNode(node) &&
|
|
node.props.some(isVSlot) &&
|
|
(vFor = findDir(node, 'for'))) {
|
|
const result = (vFor.parseResult = parseForExpression(vFor.exp, context));
|
|
if (result) {
|
|
const { value, key, index } = result;
|
|
const { addIdentifiers, removeIdentifiers } = context;
|
|
value && addIdentifiers(value);
|
|
key && addIdentifiers(key);
|
|
index && addIdentifiers(index);
|
|
return () => {
|
|
value && removeIdentifiers(value);
|
|
key && removeIdentifiers(key);
|
|
index && removeIdentifiers(index);
|
|
};
|
|
}
|
|
}
|
|
};
|
|
const buildClientSlotFn = (props, children, loc) => createFunctionExpression(props, children, false /* newline */, true /* isSlot */, children.length ? children[0].loc : loc);
|
|
// Instead of being a DirectiveTransform, v-slot processing is called during
|
|
// transformElement to build the slots object for a component.
|
|
function buildSlots(node, context, buildSlotFn = buildClientSlotFn) {
|
|
context.helper(WITH_CTX);
|
|
const { children, loc } = node;
|
|
const slotsProperties = [];
|
|
const dynamicSlots = [];
|
|
// If the slot is inside a v-for or another v-slot, force it to be dynamic
|
|
// since it likely uses a scope variable.
|
|
let hasDynamicSlots = context.scopes.vSlot > 0 || context.scopes.vFor > 0;
|
|
// 1. Check for slot with slotProps on component itself.
|
|
// <Comp v-slot="{ prop }"/>
|
|
const onComponentSlot = findDir(node, 'slot', true);
|
|
if (onComponentSlot) {
|
|
const { arg, exp } = onComponentSlot;
|
|
if (arg && !isStaticExp(arg)) {
|
|
hasDynamicSlots = true;
|
|
}
|
|
slotsProperties.push(createObjectProperty(arg || createSimpleExpression('default', true), buildSlotFn(exp, children, loc)));
|
|
}
|
|
// 2. Iterate through children and check for template slots
|
|
// <template v-slot:foo="{ prop }">
|
|
let hasTemplateSlots = false;
|
|
let hasNamedDefaultSlot = false;
|
|
const implicitDefaultChildren = [];
|
|
const seenSlotNames = new Set();
|
|
for (let i = 0; i < children.length; i++) {
|
|
const slotElement = children[i];
|
|
let slotDir;
|
|
if (!isTemplateNode(slotElement) ||
|
|
!(slotDir = findDir(slotElement, 'slot', true))) {
|
|
// not a <template v-slot>, skip.
|
|
if (slotElement.type !== 3 /* COMMENT */) {
|
|
implicitDefaultChildren.push(slotElement);
|
|
}
|
|
continue;
|
|
}
|
|
if (onComponentSlot) {
|
|
// already has on-component slot - this is incorrect usage.
|
|
context.onError(createCompilerError(36 /* X_V_SLOT_MIXED_SLOT_USAGE */, slotDir.loc));
|
|
break;
|
|
}
|
|
hasTemplateSlots = true;
|
|
const { children: slotChildren, loc: slotLoc } = slotElement;
|
|
const { arg: slotName = createSimpleExpression(`default`, true), exp: slotProps, loc: dirLoc } = slotDir;
|
|
// check if name is dynamic.
|
|
let staticSlotName;
|
|
if (isStaticExp(slotName)) {
|
|
staticSlotName = slotName ? slotName.content : `default`;
|
|
}
|
|
else {
|
|
hasDynamicSlots = true;
|
|
}
|
|
const slotFunction = buildSlotFn(slotProps, slotChildren, slotLoc);
|
|
// check if this slot is conditional (v-if/v-for)
|
|
let vIf;
|
|
let vElse;
|
|
let vFor;
|
|
if ((vIf = findDir(slotElement, 'if'))) {
|
|
hasDynamicSlots = true;
|
|
dynamicSlots.push(createConditionalExpression(vIf.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback));
|
|
}
|
|
else if ((vElse = findDir(slotElement, /^else(-if)?$/, true /* allowEmpty */))) {
|
|
// find adjacent v-if
|
|
let j = i;
|
|
let prev;
|
|
while (j--) {
|
|
prev = children[j];
|
|
if (prev.type !== 3 /* COMMENT */) {
|
|
break;
|
|
}
|
|
}
|
|
if (prev && isTemplateNode(prev) && findDir(prev, 'if')) {
|
|
// remove node
|
|
children.splice(i, 1);
|
|
i--;
|
|
// attach this slot to previous conditional
|
|
let conditional = dynamicSlots[dynamicSlots.length - 1];
|
|
while (conditional.alternate.type === 19 /* JS_CONDITIONAL_EXPRESSION */) {
|
|
conditional = conditional.alternate;
|
|
}
|
|
conditional.alternate = vElse.exp
|
|
? createConditionalExpression(vElse.exp, buildDynamicSlot(slotName, slotFunction), defaultFallback)
|
|
: buildDynamicSlot(slotName, slotFunction);
|
|
}
|
|
else {
|
|
context.onError(createCompilerError(29 /* X_V_ELSE_NO_ADJACENT_IF */, vElse.loc));
|
|
}
|
|
}
|
|
else if ((vFor = findDir(slotElement, 'for'))) {
|
|
hasDynamicSlots = true;
|
|
const parseResult = vFor.parseResult ||
|
|
parseForExpression(vFor.exp, context);
|
|
if (parseResult) {
|
|
// Render the dynamic slots as an array and add it to the createSlot()
|
|
// args. The runtime knows how to handle it appropriately.
|
|
dynamicSlots.push(createCallExpression(context.helper(RENDER_LIST), [
|
|
parseResult.source,
|
|
createFunctionExpression(createForLoopParams(parseResult), buildDynamicSlot(slotName, slotFunction), true /* force newline */)
|
|
]));
|
|
}
|
|
else {
|
|
context.onError(createCompilerError(31 /* X_V_FOR_MALFORMED_EXPRESSION */, vFor.loc));
|
|
}
|
|
}
|
|
else {
|
|
// check duplicate static names
|
|
if (staticSlotName) {
|
|
if (seenSlotNames.has(staticSlotName)) {
|
|
context.onError(createCompilerError(37 /* X_V_SLOT_DUPLICATE_SLOT_NAMES */, dirLoc));
|
|
continue;
|
|
}
|
|
seenSlotNames.add(staticSlotName);
|
|
if (staticSlotName === 'default') {
|
|
hasNamedDefaultSlot = true;
|
|
}
|
|
}
|
|
slotsProperties.push(createObjectProperty(slotName, slotFunction));
|
|
}
|
|
}
|
|
if (!onComponentSlot) {
|
|
const buildDefaultSlotProperty = (props, children) => {
|
|
const fn = buildSlotFn(props, children, loc);
|
|
if (context.compatConfig) {
|
|
fn.isNonScopedSlot = true;
|
|
}
|
|
return createObjectProperty(`default`, fn);
|
|
};
|
|
if (!hasTemplateSlots) {
|
|
// implicit default slot (on component)
|
|
slotsProperties.push(buildDefaultSlotProperty(undefined, children));
|
|
}
|
|
else if (implicitDefaultChildren.length &&
|
|
// #3766
|
|
// with whitespace: 'preserve', whitespaces between slots will end up in
|
|
// implicitDefaultChildren. Ignore if all implicit children are whitespaces.
|
|
implicitDefaultChildren.some(node => isNonWhitespaceContent(node))) {
|
|
// implicit default slot (mixed with named slots)
|
|
if (hasNamedDefaultSlot) {
|
|
context.onError(createCompilerError(38 /* X_V_SLOT_EXTRANEOUS_DEFAULT_SLOT_CHILDREN */, implicitDefaultChildren[0].loc));
|
|
}
|
|
else {
|
|
slotsProperties.push(buildDefaultSlotProperty(undefined, implicitDefaultChildren));
|
|
}
|
|
}
|
|
}
|
|
const slotFlag = hasDynamicSlots
|
|
? 2 /* DYNAMIC */
|
|
: hasForwardedSlots(node.children)
|
|
? 3 /* FORWARDED */
|
|
: 1 /* STABLE */;
|
|
let slots = createObjectExpression(slotsProperties.concat(createObjectProperty(`_`,
|
|
// 2 = compiled but dynamic = can skip normalization, but must run diff
|
|
// 1 = compiled and static = can skip normalization AND diff as optimized
|
|
createSimpleExpression(slotFlag + (( true) ? ` /* ${_vue_shared__WEBPACK_IMPORTED_MODULE_0__.slotFlagsText[slotFlag]} */` : 0), false))), loc);
|
|
if (dynamicSlots.length) {
|
|
slots = createCallExpression(context.helper(CREATE_SLOTS), [
|
|
slots,
|
|
createArrayExpression(dynamicSlots)
|
|
]);
|
|
}
|
|
return {
|
|
slots,
|
|
hasDynamicSlots
|
|
};
|
|
}
|
|
function buildDynamicSlot(name, fn) {
|
|
return createObjectExpression([
|
|
createObjectProperty(`name`, name),
|
|
createObjectProperty(`fn`, fn)
|
|
]);
|
|
}
|
|
function hasForwardedSlots(children) {
|
|
for (let i = 0; i < children.length; i++) {
|
|
const child = children[i];
|
|
switch (child.type) {
|
|
case 1 /* ELEMENT */:
|
|
if (child.tagType === 2 /* SLOT */ ||
|
|
hasForwardedSlots(child.children)) {
|
|
return true;
|
|
}
|
|
break;
|
|
case 9 /* IF */:
|
|
if (hasForwardedSlots(child.branches))
|
|
return true;
|
|
break;
|
|
case 10 /* IF_BRANCH */:
|
|
case 11 /* FOR */:
|
|
if (hasForwardedSlots(child.children))
|
|
return true;
|
|
break;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
function isNonWhitespaceContent(node) {
|
|
if (node.type !== 2 /* TEXT */ && node.type !== 12 /* TEXT_CALL */)
|
|
return true;
|
|
return node.type === 2 /* TEXT */
|
|
? !!node.content.trim()
|
|
: isNonWhitespaceContent(node.content);
|
|
}
|
|
|
|
// some directive transforms (e.g. v-model) may return a symbol for runtime
|
|
// import, which should be used instead of a resolveDirective call.
|
|
const directiveImportMap = new WeakMap();
|
|
// generate a JavaScript AST for this element's codegen
|
|
const transformElement = (node, context) => {
|
|
// perform the work on exit, after all child expressions have been
|
|
// processed and merged.
|
|
return function postTransformElement() {
|
|
node = context.currentNode;
|
|
if (!(node.type === 1 /* ELEMENT */ &&
|
|
(node.tagType === 0 /* ELEMENT */ ||
|
|
node.tagType === 1 /* COMPONENT */))) {
|
|
return;
|
|
}
|
|
const { tag, props } = node;
|
|
const isComponent = node.tagType === 1 /* COMPONENT */;
|
|
// The goal of the transform is to create a codegenNode implementing the
|
|
// VNodeCall interface.
|
|
let vnodeTag = isComponent
|
|
? resolveComponentType(node, context)
|
|
: `"${tag}"`;
|
|
const isDynamicComponent = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isObject)(vnodeTag) && vnodeTag.callee === RESOLVE_DYNAMIC_COMPONENT;
|
|
let vnodeProps;
|
|
let vnodeChildren;
|
|
let vnodePatchFlag;
|
|
let patchFlag = 0;
|
|
let vnodeDynamicProps;
|
|
let dynamicPropNames;
|
|
let vnodeDirectives;
|
|
let shouldUseBlock =
|
|
// dynamic component may resolve to plain elements
|
|
isDynamicComponent ||
|
|
vnodeTag === TELEPORT ||
|
|
vnodeTag === SUSPENSE ||
|
|
(!isComponent &&
|
|
// <svg> and <foreignObject> must be forced into blocks so that block
|
|
// updates inside get proper isSVG flag at runtime. (#639, #643)
|
|
// This is technically web-specific, but splitting the logic out of core
|
|
// leads to too much unnecessary complexity.
|
|
(tag === 'svg' ||
|
|
tag === 'foreignObject' ||
|
|
// #938: elements with dynamic keys should be forced into blocks
|
|
findProp(node, 'key', true)));
|
|
// props
|
|
if (props.length > 0) {
|
|
const propsBuildResult = buildProps(node, context);
|
|
vnodeProps = propsBuildResult.props;
|
|
patchFlag = propsBuildResult.patchFlag;
|
|
dynamicPropNames = propsBuildResult.dynamicPropNames;
|
|
const directives = propsBuildResult.directives;
|
|
vnodeDirectives =
|
|
directives && directives.length
|
|
? createArrayExpression(directives.map(dir => buildDirectiveArgs(dir, context)))
|
|
: undefined;
|
|
}
|
|
// children
|
|
if (node.children.length > 0) {
|
|
if (vnodeTag === KEEP_ALIVE) {
|
|
// Although a built-in component, we compile KeepAlive with raw children
|
|
// instead of slot functions so that it can be used inside Transition
|
|
// or other Transition-wrapping HOCs.
|
|
// To ensure correct updates with block optimizations, we need to:
|
|
// 1. Force keep-alive into a block. This avoids its children being
|
|
// collected by a parent block.
|
|
shouldUseBlock = true;
|
|
// 2. Force keep-alive to always be updated, since it uses raw children.
|
|
patchFlag |= 1024 /* DYNAMIC_SLOTS */;
|
|
if (( true) && node.children.length > 1) {
|
|
context.onError(createCompilerError(44 /* X_KEEP_ALIVE_INVALID_CHILDREN */, {
|
|
start: node.children[0].loc.start,
|
|
end: node.children[node.children.length - 1].loc.end,
|
|
source: ''
|
|
}));
|
|
}
|
|
}
|
|
const shouldBuildAsSlots = isComponent &&
|
|
// Teleport is not a real component and has dedicated runtime handling
|
|
vnodeTag !== TELEPORT &&
|
|
// explained above.
|
|
vnodeTag !== KEEP_ALIVE;
|
|
if (shouldBuildAsSlots) {
|
|
const { slots, hasDynamicSlots } = buildSlots(node, context);
|
|
vnodeChildren = slots;
|
|
if (hasDynamicSlots) {
|
|
patchFlag |= 1024 /* DYNAMIC_SLOTS */;
|
|
}
|
|
}
|
|
else if (node.children.length === 1 && vnodeTag !== TELEPORT) {
|
|
const child = node.children[0];
|
|
const type = child.type;
|
|
// check for dynamic text children
|
|
const hasDynamicTextChild = type === 5 /* INTERPOLATION */ ||
|
|
type === 8 /* COMPOUND_EXPRESSION */;
|
|
if (hasDynamicTextChild &&
|
|
getConstantType(child, context) === 0 /* NOT_CONSTANT */) {
|
|
patchFlag |= 1 /* TEXT */;
|
|
}
|
|
// pass directly if the only child is a text node
|
|
// (plain / interpolation / expression)
|
|
if (hasDynamicTextChild || type === 2 /* TEXT */) {
|
|
vnodeChildren = child;
|
|
}
|
|
else {
|
|
vnodeChildren = node.children;
|
|
}
|
|
}
|
|
else {
|
|
vnodeChildren = node.children;
|
|
}
|
|
}
|
|
// patchFlag & dynamicPropNames
|
|
if (patchFlag !== 0) {
|
|
if ((true)) {
|
|
if (patchFlag < 0) {
|
|
// special flags (negative and mutually exclusive)
|
|
vnodePatchFlag = patchFlag + ` /* ${_vue_shared__WEBPACK_IMPORTED_MODULE_0__.PatchFlagNames[patchFlag]} */`;
|
|
}
|
|
else {
|
|
// bitwise flags
|
|
const flagNames = Object.keys(_vue_shared__WEBPACK_IMPORTED_MODULE_0__.PatchFlagNames)
|
|
.map(Number)
|
|
.filter(n => n > 0 && patchFlag & n)
|
|
.map(n => _vue_shared__WEBPACK_IMPORTED_MODULE_0__.PatchFlagNames[n])
|
|
.join(`, `);
|
|
vnodePatchFlag = patchFlag + ` /* ${flagNames} */`;
|
|
}
|
|
}
|
|
else {}
|
|
if (dynamicPropNames && dynamicPropNames.length) {
|
|
vnodeDynamicProps = stringifyDynamicPropNames(dynamicPropNames);
|
|
}
|
|
}
|
|
node.codegenNode = createVNodeCall(context, vnodeTag, vnodeProps, vnodeChildren, vnodePatchFlag, vnodeDynamicProps, vnodeDirectives, !!shouldUseBlock, false /* disableTracking */, isComponent, node.loc);
|
|
};
|
|
};
|
|
function resolveComponentType(node, context, ssr = false) {
|
|
let { tag } = node;
|
|
// 1. dynamic component
|
|
const isExplicitDynamic = isComponentTag(tag);
|
|
const isProp = findProp(node, 'is');
|
|
if (isProp) {
|
|
if (isExplicitDynamic ||
|
|
(isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context))) {
|
|
const exp = isProp.type === 6 /* ATTRIBUTE */
|
|
? isProp.value && createSimpleExpression(isProp.value.content, true)
|
|
: isProp.exp;
|
|
if (exp) {
|
|
return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [
|
|
exp
|
|
]);
|
|
}
|
|
}
|
|
else if (isProp.type === 6 /* ATTRIBUTE */ &&
|
|
isProp.value.content.startsWith('vue:')) {
|
|
// <button is="vue:xxx">
|
|
// if not <component>, only is value that starts with "vue:" will be
|
|
// treated as component by the parse phase and reach here, unless it's
|
|
// compat mode where all is values are considered components
|
|
tag = isProp.value.content.slice(4);
|
|
}
|
|
}
|
|
// 1.5 v-is (TODO: Deprecate)
|
|
const isDir = !isExplicitDynamic && findDir(node, 'is');
|
|
if (isDir && isDir.exp) {
|
|
return createCallExpression(context.helper(RESOLVE_DYNAMIC_COMPONENT), [
|
|
isDir.exp
|
|
]);
|
|
}
|
|
// 2. built-in components (Teleport, Transition, KeepAlive, Suspense...)
|
|
const builtIn = isCoreComponent(tag) || context.isBuiltInComponent(tag);
|
|
if (builtIn) {
|
|
// built-ins are simply fallthroughs / have special handling during ssr
|
|
// so we don't need to import their runtime equivalents
|
|
if (!ssr)
|
|
context.helper(builtIn);
|
|
return builtIn;
|
|
}
|
|
// 5. user component (resolve)
|
|
context.helper(RESOLVE_COMPONENT);
|
|
context.components.add(tag);
|
|
return toValidAssetId(tag, `component`);
|
|
}
|
|
function buildProps(node, context, props = node.props, ssr = false) {
|
|
const { tag, loc: elementLoc } = node;
|
|
const isComponent = node.tagType === 1 /* COMPONENT */;
|
|
let properties = [];
|
|
const mergeArgs = [];
|
|
const runtimeDirectives = [];
|
|
// patchFlag analysis
|
|
let patchFlag = 0;
|
|
let hasRef = false;
|
|
let hasClassBinding = false;
|
|
let hasStyleBinding = false;
|
|
let hasHydrationEventBinding = false;
|
|
let hasDynamicKeys = false;
|
|
let hasVnodeHook = false;
|
|
const dynamicPropNames = [];
|
|
const analyzePatchFlag = ({ key, value }) => {
|
|
if (isStaticExp(key)) {
|
|
const name = key.content;
|
|
const isEventHandler = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isOn)(name);
|
|
if (!isComponent &&
|
|
isEventHandler &&
|
|
// omit the flag for click handlers because hydration gives click
|
|
// dedicated fast path.
|
|
name.toLowerCase() !== 'onclick' &&
|
|
// omit v-model handlers
|
|
name !== 'onUpdate:modelValue' &&
|
|
// omit onVnodeXXX hooks
|
|
!(0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isReservedProp)(name)) {
|
|
hasHydrationEventBinding = true;
|
|
}
|
|
if (isEventHandler && (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isReservedProp)(name)) {
|
|
hasVnodeHook = true;
|
|
}
|
|
if (value.type === 20 /* JS_CACHE_EXPRESSION */ ||
|
|
((value.type === 4 /* SIMPLE_EXPRESSION */ ||
|
|
value.type === 8 /* COMPOUND_EXPRESSION */) &&
|
|
getConstantType(value, context) > 0)) {
|
|
// skip if the prop is a cached handler or has constant value
|
|
return;
|
|
}
|
|
if (name === 'ref') {
|
|
hasRef = true;
|
|
}
|
|
else if (name === 'class') {
|
|
hasClassBinding = true;
|
|
}
|
|
else if (name === 'style') {
|
|
hasStyleBinding = true;
|
|
}
|
|
else if (name !== 'key' && !dynamicPropNames.includes(name)) {
|
|
dynamicPropNames.push(name);
|
|
}
|
|
// treat the dynamic class and style binding of the component as dynamic props
|
|
if (isComponent &&
|
|
(name === 'class' || name === 'style') &&
|
|
!dynamicPropNames.includes(name)) {
|
|
dynamicPropNames.push(name);
|
|
}
|
|
}
|
|
else {
|
|
hasDynamicKeys = true;
|
|
}
|
|
};
|
|
for (let i = 0; i < props.length; i++) {
|
|
// static attribute
|
|
const prop = props[i];
|
|
if (prop.type === 6 /* ATTRIBUTE */) {
|
|
const { loc, name, value } = prop;
|
|
let isStatic = true;
|
|
if (name === 'ref') {
|
|
hasRef = true;
|
|
}
|
|
// skip is on <component>, or is="vue:xxx"
|
|
if (name === 'is' &&
|
|
(isComponentTag(tag) ||
|
|
(value && value.content.startsWith('vue:')) ||
|
|
(isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context)))) {
|
|
continue;
|
|
}
|
|
properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), createSimpleExpression(value ? value.content : '', isStatic, value ? value.loc : loc)));
|
|
}
|
|
else {
|
|
// directives
|
|
const { name, arg, exp, loc } = prop;
|
|
const isVBind = name === 'bind';
|
|
const isVOn = name === 'on';
|
|
// skip v-slot - it is handled by its dedicated transform.
|
|
if (name === 'slot') {
|
|
if (!isComponent) {
|
|
context.onError(createCompilerError(39 /* X_V_SLOT_MISPLACED */, loc));
|
|
}
|
|
continue;
|
|
}
|
|
// skip v-once/v-memo - they are handled by dedicated transforms.
|
|
if (name === 'once' || name === 'memo') {
|
|
continue;
|
|
}
|
|
// skip v-is and :is on <component>
|
|
if (name === 'is' ||
|
|
(isVBind &&
|
|
isBindKey(arg, 'is') &&
|
|
(isComponentTag(tag) ||
|
|
(isCompatEnabled("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context))))) {
|
|
continue;
|
|
}
|
|
// skip v-on in SSR compilation
|
|
if (isVOn && ssr) {
|
|
continue;
|
|
}
|
|
// special case for v-bind and v-on with no argument
|
|
if (!arg && (isVBind || isVOn)) {
|
|
hasDynamicKeys = true;
|
|
if (exp) {
|
|
if (properties.length) {
|
|
mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));
|
|
properties = [];
|
|
}
|
|
if (isVBind) {
|
|
{
|
|
// 2.x v-bind object order compat
|
|
if ((true)) {
|
|
const hasOverridableKeys = mergeArgs.some(arg => {
|
|
if (arg.type === 15 /* JS_OBJECT_EXPRESSION */) {
|
|
return arg.properties.some(({ key }) => {
|
|
if (key.type !== 4 /* SIMPLE_EXPRESSION */ ||
|
|
!key.isStatic) {
|
|
return true;
|
|
}
|
|
return (key.content !== 'class' &&
|
|
key.content !== 'style' &&
|
|
!(0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isOn)(key.content));
|
|
});
|
|
}
|
|
else {
|
|
// dynamic expression
|
|
return true;
|
|
}
|
|
});
|
|
if (hasOverridableKeys) {
|
|
checkCompatEnabled("COMPILER_V_BIND_OBJECT_ORDER" /* COMPILER_V_BIND_OBJECT_ORDER */, context, loc);
|
|
}
|
|
}
|
|
if (isCompatEnabled("COMPILER_V_BIND_OBJECT_ORDER" /* COMPILER_V_BIND_OBJECT_ORDER */, context)) {
|
|
mergeArgs.unshift(exp);
|
|
continue;
|
|
}
|
|
}
|
|
mergeArgs.push(exp);
|
|
}
|
|
else {
|
|
// v-on="obj" -> toHandlers(obj)
|
|
mergeArgs.push({
|
|
type: 14 /* JS_CALL_EXPRESSION */,
|
|
loc,
|
|
callee: context.helper(TO_HANDLERS),
|
|
arguments: [exp]
|
|
});
|
|
}
|
|
}
|
|
else {
|
|
context.onError(createCompilerError(isVBind
|
|
? 33 /* X_V_BIND_NO_EXPRESSION */
|
|
: 34 /* X_V_ON_NO_EXPRESSION */, loc));
|
|
}
|
|
continue;
|
|
}
|
|
const directiveTransform = context.directiveTransforms[name];
|
|
if (directiveTransform) {
|
|
// has built-in directive transform.
|
|
const { props, needRuntime } = directiveTransform(prop, node, context);
|
|
!ssr && props.forEach(analyzePatchFlag);
|
|
properties.push(...props);
|
|
if (needRuntime) {
|
|
runtimeDirectives.push(prop);
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isSymbol)(needRuntime)) {
|
|
directiveImportMap.set(prop, needRuntime);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
// no built-in transform, this is a user custom directive.
|
|
runtimeDirectives.push(prop);
|
|
}
|
|
}
|
|
if (prop.type === 6 /* ATTRIBUTE */ &&
|
|
prop.name === 'ref' &&
|
|
context.scopes.vFor > 0 &&
|
|
checkCompatEnabled("COMPILER_V_FOR_REF" /* COMPILER_V_FOR_REF */, context, prop.loc)) {
|
|
properties.push(createObjectProperty(createSimpleExpression('refInFor', true), createSimpleExpression('true', false)));
|
|
}
|
|
}
|
|
let propsExpression = undefined;
|
|
// has v-bind="object" or v-on="object", wrap with mergeProps
|
|
if (mergeArgs.length) {
|
|
if (properties.length) {
|
|
mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));
|
|
}
|
|
if (mergeArgs.length > 1) {
|
|
propsExpression = createCallExpression(context.helper(MERGE_PROPS), mergeArgs, elementLoc);
|
|
}
|
|
else {
|
|
// single v-bind with nothing else - no need for a mergeProps call
|
|
propsExpression = mergeArgs[0];
|
|
}
|
|
}
|
|
else if (properties.length) {
|
|
propsExpression = createObjectExpression(dedupeProperties(properties), elementLoc);
|
|
}
|
|
// patchFlag analysis
|
|
if (hasDynamicKeys) {
|
|
patchFlag |= 16 /* FULL_PROPS */;
|
|
}
|
|
else {
|
|
if (hasClassBinding && !isComponent) {
|
|
patchFlag |= 2 /* CLASS */;
|
|
}
|
|
if (hasStyleBinding && !isComponent) {
|
|
patchFlag |= 4 /* STYLE */;
|
|
}
|
|
if (dynamicPropNames.length) {
|
|
patchFlag |= 8 /* PROPS */;
|
|
}
|
|
if (hasHydrationEventBinding) {
|
|
patchFlag |= 32 /* HYDRATE_EVENTS */;
|
|
}
|
|
}
|
|
if ((patchFlag === 0 || patchFlag === 32 /* HYDRATE_EVENTS */) &&
|
|
(hasRef || hasVnodeHook || runtimeDirectives.length > 0)) {
|
|
patchFlag |= 512 /* NEED_PATCH */;
|
|
}
|
|
// pre-normalize props, SSR is skipped for now
|
|
if (!context.inSSR && propsExpression) {
|
|
switch (propsExpression.type) {
|
|
case 15 /* JS_OBJECT_EXPRESSION */:
|
|
// means that there is no v-bind,
|
|
// but still need to deal with dynamic key binding
|
|
let classKeyIndex = -1;
|
|
let styleKeyIndex = -1;
|
|
let hasDynamicKey = false;
|
|
for (let i = 0; i < propsExpression.properties.length; i++) {
|
|
const key = propsExpression.properties[i].key;
|
|
if (isStaticExp(key)) {
|
|
if (key.content === 'class') {
|
|
classKeyIndex = i;
|
|
}
|
|
else if (key.content === 'style') {
|
|
styleKeyIndex = i;
|
|
}
|
|
}
|
|
else if (!key.isHandlerKey) {
|
|
hasDynamicKey = true;
|
|
}
|
|
}
|
|
const classProp = propsExpression.properties[classKeyIndex];
|
|
const styleProp = propsExpression.properties[styleKeyIndex];
|
|
// no dynamic key
|
|
if (!hasDynamicKey) {
|
|
if (classProp && !isStaticExp(classProp.value)) {
|
|
classProp.value = createCallExpression(context.helper(NORMALIZE_CLASS), [classProp.value]);
|
|
}
|
|
if (styleProp &&
|
|
!isStaticExp(styleProp.value) &&
|
|
// the static style is compiled into an object,
|
|
// so use `hasStyleBinding` to ensure that it is a dynamic style binding
|
|
(hasStyleBinding ||
|
|
// v-bind:style and style both exist,
|
|
// v-bind:style with static literal object
|
|
styleProp.value.type === 17 /* JS_ARRAY_EXPRESSION */)) {
|
|
styleProp.value = createCallExpression(context.helper(NORMALIZE_STYLE), [styleProp.value]);
|
|
}
|
|
}
|
|
else {
|
|
// dynamic key binding, wrap with `normalizeProps`
|
|
propsExpression = createCallExpression(context.helper(NORMALIZE_PROPS), [propsExpression]);
|
|
}
|
|
break;
|
|
case 14 /* JS_CALL_EXPRESSION */:
|
|
// mergeProps call, do nothing
|
|
break;
|
|
default:
|
|
// single v-bind
|
|
propsExpression = createCallExpression(context.helper(NORMALIZE_PROPS), [
|
|
createCallExpression(context.helper(GUARD_REACTIVE_PROPS), [
|
|
propsExpression
|
|
])
|
|
]);
|
|
break;
|
|
}
|
|
}
|
|
return {
|
|
props: propsExpression,
|
|
directives: runtimeDirectives,
|
|
patchFlag,
|
|
dynamicPropNames
|
|
};
|
|
}
|
|
// Dedupe props in an object literal.
|
|
// Literal duplicated attributes would have been warned during the parse phase,
|
|
// however, it's possible to encounter duplicated `onXXX` handlers with different
|
|
// modifiers. We also need to merge static and dynamic class / style attributes.
|
|
// - onXXX handlers / style: merge into array
|
|
// - class: merge into single expression with concatenation
|
|
function dedupeProperties(properties) {
|
|
const knownProps = new Map();
|
|
const deduped = [];
|
|
for (let i = 0; i < properties.length; i++) {
|
|
const prop = properties[i];
|
|
// dynamic keys are always allowed
|
|
if (prop.key.type === 8 /* COMPOUND_EXPRESSION */ || !prop.key.isStatic) {
|
|
deduped.push(prop);
|
|
continue;
|
|
}
|
|
const name = prop.key.content;
|
|
const existing = knownProps.get(name);
|
|
if (existing) {
|
|
if (name === 'style' || name === 'class' || name.startsWith('on')) {
|
|
mergeAsArray(existing, prop);
|
|
}
|
|
// unexpected duplicate, should have emitted error during parse
|
|
}
|
|
else {
|
|
knownProps.set(name, prop);
|
|
deduped.push(prop);
|
|
}
|
|
}
|
|
return deduped;
|
|
}
|
|
function mergeAsArray(existing, incoming) {
|
|
if (existing.value.type === 17 /* JS_ARRAY_EXPRESSION */) {
|
|
existing.value.elements.push(incoming.value);
|
|
}
|
|
else {
|
|
existing.value = createArrayExpression([existing.value, incoming.value], existing.loc);
|
|
}
|
|
}
|
|
function buildDirectiveArgs(dir, context) {
|
|
const dirArgs = [];
|
|
const runtime = directiveImportMap.get(dir);
|
|
if (runtime) {
|
|
// built-in directive with runtime
|
|
dirArgs.push(context.helperString(runtime));
|
|
}
|
|
else {
|
|
{
|
|
// inject statement for resolving directive
|
|
context.helper(RESOLVE_DIRECTIVE);
|
|
context.directives.add(dir.name);
|
|
dirArgs.push(toValidAssetId(dir.name, `directive`));
|
|
}
|
|
}
|
|
const { loc } = dir;
|
|
if (dir.exp)
|
|
dirArgs.push(dir.exp);
|
|
if (dir.arg) {
|
|
if (!dir.exp) {
|
|
dirArgs.push(`void 0`);
|
|
}
|
|
dirArgs.push(dir.arg);
|
|
}
|
|
if (Object.keys(dir.modifiers).length) {
|
|
if (!dir.arg) {
|
|
if (!dir.exp) {
|
|
dirArgs.push(`void 0`);
|
|
}
|
|
dirArgs.push(`void 0`);
|
|
}
|
|
const trueExpression = createSimpleExpression(`true`, false, loc);
|
|
dirArgs.push(createObjectExpression(dir.modifiers.map(modifier => createObjectProperty(modifier, trueExpression)), loc));
|
|
}
|
|
return createArrayExpression(dirArgs, dir.loc);
|
|
}
|
|
function stringifyDynamicPropNames(props) {
|
|
let propsNamesString = `[`;
|
|
for (let i = 0, l = props.length; i < l; i++) {
|
|
propsNamesString += JSON.stringify(props[i]);
|
|
if (i < l - 1)
|
|
propsNamesString += ', ';
|
|
}
|
|
return propsNamesString + `]`;
|
|
}
|
|
function isComponentTag(tag) {
|
|
return tag[0].toLowerCase() + tag.slice(1) === 'component';
|
|
}
|
|
|
|
( true)
|
|
? Object.freeze({})
|
|
: 0;
|
|
( true) ? Object.freeze([]) : 0;
|
|
const cacheStringFunction = (fn) => {
|
|
const cache = Object.create(null);
|
|
return ((str) => {
|
|
const hit = cache[str];
|
|
return hit || (cache[str] = fn(str));
|
|
});
|
|
};
|
|
const camelizeRE = /-(\w)/g;
|
|
/**
|
|
* @private
|
|
*/
|
|
const camelize = cacheStringFunction((str) => {
|
|
return str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : ''));
|
|
});
|
|
|
|
const transformSlotOutlet = (node, context) => {
|
|
if (isSlotOutlet(node)) {
|
|
const { children, loc } = node;
|
|
const { slotName, slotProps } = processSlotOutlet(node, context);
|
|
const slotArgs = [
|
|
context.prefixIdentifiers ? `_ctx.$slots` : `$slots`,
|
|
slotName
|
|
];
|
|
if (slotProps) {
|
|
slotArgs.push(slotProps);
|
|
}
|
|
if (children.length) {
|
|
if (!slotProps) {
|
|
slotArgs.push(`{}`);
|
|
}
|
|
slotArgs.push(createFunctionExpression([], children, false, false, loc));
|
|
}
|
|
if (context.scopeId && !context.slotted) {
|
|
if (!slotProps) {
|
|
slotArgs.push(`{}`);
|
|
}
|
|
if (!children.length) {
|
|
slotArgs.push(`undefined`);
|
|
}
|
|
slotArgs.push(`true`);
|
|
}
|
|
node.codegenNode = createCallExpression(context.helper(RENDER_SLOT), slotArgs, loc);
|
|
}
|
|
};
|
|
function processSlotOutlet(node, context) {
|
|
let slotName = `"default"`;
|
|
let slotProps = undefined;
|
|
const nonNameProps = [];
|
|
for (let i = 0; i < node.props.length; i++) {
|
|
const p = node.props[i];
|
|
if (p.type === 6 /* ATTRIBUTE */) {
|
|
if (p.value) {
|
|
if (p.name === 'name') {
|
|
slotName = JSON.stringify(p.value.content);
|
|
}
|
|
else {
|
|
p.name = camelize(p.name);
|
|
nonNameProps.push(p);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
if (p.name === 'bind' && isBindKey(p.arg, 'name')) {
|
|
if (p.exp)
|
|
slotName = p.exp;
|
|
}
|
|
else {
|
|
if (p.name === 'bind' && p.arg && isStaticExp(p.arg)) {
|
|
p.arg.content = camelize(p.arg.content);
|
|
}
|
|
nonNameProps.push(p);
|
|
}
|
|
}
|
|
}
|
|
if (nonNameProps.length > 0) {
|
|
const { props, directives } = buildProps(node, context, nonNameProps);
|
|
slotProps = props;
|
|
if (directives.length) {
|
|
context.onError(createCompilerError(35 /* X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET */, directives[0].loc));
|
|
}
|
|
}
|
|
return {
|
|
slotName,
|
|
slotProps
|
|
};
|
|
}
|
|
|
|
const fnExpRE = /^\s*([\w$_]+|\([^)]*?\))\s*=>|^\s*function(?:\s+[\w$]+)?\s*\(/;
|
|
const transformOn = (dir, node, context, augmentor) => {
|
|
const { loc, modifiers, arg } = dir;
|
|
if (!dir.exp && !modifiers.length) {
|
|
context.onError(createCompilerError(34 /* X_V_ON_NO_EXPRESSION */, loc));
|
|
}
|
|
let eventName;
|
|
if (arg.type === 4 /* SIMPLE_EXPRESSION */) {
|
|
if (arg.isStatic) {
|
|
const rawName = arg.content;
|
|
// for all event listeners, auto convert it to camelCase. See issue #2249
|
|
eventName = createSimpleExpression((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.toHandlerKey)((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.camelize)(rawName)), true, arg.loc);
|
|
}
|
|
else {
|
|
// #2388
|
|
eventName = createCompoundExpression([
|
|
`${context.helperString(TO_HANDLER_KEY)}(`,
|
|
arg,
|
|
`)`
|
|
]);
|
|
}
|
|
}
|
|
else {
|
|
// already a compound expression.
|
|
eventName = arg;
|
|
eventName.children.unshift(`${context.helperString(TO_HANDLER_KEY)}(`);
|
|
eventName.children.push(`)`);
|
|
}
|
|
// handler processing
|
|
let exp = dir.exp;
|
|
if (exp && !exp.content.trim()) {
|
|
exp = undefined;
|
|
}
|
|
let shouldCache = context.cacheHandlers && !exp && !context.inVOnce;
|
|
if (exp) {
|
|
const isMemberExp = isMemberExpression(exp.content);
|
|
const isInlineStatement = !(isMemberExp || fnExpRE.test(exp.content));
|
|
const hasMultipleStatements = exp.content.includes(`;`);
|
|
if (true) {
|
|
validateBrowserExpression(exp, context, false, hasMultipleStatements);
|
|
}
|
|
if (isInlineStatement || (shouldCache && isMemberExp)) {
|
|
// wrap inline statement in a function expression
|
|
exp = createCompoundExpression([
|
|
`${isInlineStatement
|
|
? `$event`
|
|
: `${``}(...args)`} => ${hasMultipleStatements ? `{` : `(`}`,
|
|
exp,
|
|
hasMultipleStatements ? `}` : `)`
|
|
]);
|
|
}
|
|
}
|
|
let ret = {
|
|
props: [
|
|
createObjectProperty(eventName, exp || createSimpleExpression(`() => {}`, false, loc))
|
|
]
|
|
};
|
|
// apply extended compiler augmentor
|
|
if (augmentor) {
|
|
ret = augmentor(ret);
|
|
}
|
|
if (shouldCache) {
|
|
// cache handlers so that it's always the same handler being passed down.
|
|
// this avoids unnecessary re-renders when users use inline handlers on
|
|
// components.
|
|
ret.props[0].value = context.cache(ret.props[0].value);
|
|
}
|
|
// mark the key as handler for props normalization check
|
|
ret.props.forEach(p => (p.key.isHandlerKey = true));
|
|
return ret;
|
|
};
|
|
|
|
// v-bind without arg is handled directly in ./transformElements.ts due to it affecting
|
|
// codegen for the entire props object. This transform here is only for v-bind
|
|
// *with* args.
|
|
const transformBind = (dir, _node, context) => {
|
|
const { exp, modifiers, loc } = dir;
|
|
const arg = dir.arg;
|
|
if (arg.type !== 4 /* SIMPLE_EXPRESSION */) {
|
|
arg.children.unshift(`(`);
|
|
arg.children.push(`) || ""`);
|
|
}
|
|
else if (!arg.isStatic) {
|
|
arg.content = `${arg.content} || ""`;
|
|
}
|
|
// .sync is replaced by v-model:arg
|
|
if (modifiers.includes('camel')) {
|
|
if (arg.type === 4 /* SIMPLE_EXPRESSION */) {
|
|
if (arg.isStatic) {
|
|
arg.content = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.camelize)(arg.content);
|
|
}
|
|
else {
|
|
arg.content = `${context.helperString(CAMELIZE)}(${arg.content})`;
|
|
}
|
|
}
|
|
else {
|
|
arg.children.unshift(`${context.helperString(CAMELIZE)}(`);
|
|
arg.children.push(`)`);
|
|
}
|
|
}
|
|
if (!context.inSSR) {
|
|
if (modifiers.includes('prop')) {
|
|
injectPrefix(arg, '.');
|
|
}
|
|
if (modifiers.includes('attr')) {
|
|
injectPrefix(arg, '^');
|
|
}
|
|
}
|
|
if (!exp ||
|
|
(exp.type === 4 /* SIMPLE_EXPRESSION */ && !exp.content.trim())) {
|
|
context.onError(createCompilerError(33 /* X_V_BIND_NO_EXPRESSION */, loc));
|
|
return {
|
|
props: [createObjectProperty(arg, createSimpleExpression('', true, loc))]
|
|
};
|
|
}
|
|
return {
|
|
props: [createObjectProperty(arg, exp)]
|
|
};
|
|
};
|
|
const injectPrefix = (arg, prefix) => {
|
|
if (arg.type === 4 /* SIMPLE_EXPRESSION */) {
|
|
if (arg.isStatic) {
|
|
arg.content = prefix + arg.content;
|
|
}
|
|
else {
|
|
arg.content = `\`${prefix}\${${arg.content}}\``;
|
|
}
|
|
}
|
|
else {
|
|
arg.children.unshift(`'${prefix}' + (`);
|
|
arg.children.push(`)`);
|
|
}
|
|
};
|
|
|
|
// Merge adjacent text nodes and expressions into a single expression
|
|
// e.g. <div>abc {{ d }} {{ e }}</div> should have a single expression node as child.
|
|
const transformText = (node, context) => {
|
|
if (node.type === 0 /* ROOT */ ||
|
|
node.type === 1 /* ELEMENT */ ||
|
|
node.type === 11 /* FOR */ ||
|
|
node.type === 10 /* IF_BRANCH */) {
|
|
// perform the transform on node exit so that all expressions have already
|
|
// been processed.
|
|
return () => {
|
|
const children = node.children;
|
|
let currentContainer = undefined;
|
|
let hasText = false;
|
|
for (let i = 0; i < children.length; i++) {
|
|
const child = children[i];
|
|
if (isText(child)) {
|
|
hasText = true;
|
|
for (let j = i + 1; j < children.length; j++) {
|
|
const next = children[j];
|
|
if (isText(next)) {
|
|
if (!currentContainer) {
|
|
currentContainer = children[i] = {
|
|
type: 8 /* COMPOUND_EXPRESSION */,
|
|
loc: child.loc,
|
|
children: [child]
|
|
};
|
|
}
|
|
// merge adjacent text node into current
|
|
currentContainer.children.push(` + `, next);
|
|
children.splice(j, 1);
|
|
j--;
|
|
}
|
|
else {
|
|
currentContainer = undefined;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (!hasText ||
|
|
// if this is a plain element with a single text child, leave it
|
|
// as-is since the runtime has dedicated fast path for this by directly
|
|
// setting textContent of the element.
|
|
// for component root it's always normalized anyway.
|
|
(children.length === 1 &&
|
|
(node.type === 0 /* ROOT */ ||
|
|
(node.type === 1 /* ELEMENT */ &&
|
|
node.tagType === 0 /* ELEMENT */ &&
|
|
// #3756
|
|
// custom directives can potentially add DOM elements arbitrarily,
|
|
// we need to avoid setting textContent of the element at runtime
|
|
// to avoid accidentally overwriting the DOM elements added
|
|
// by the user through custom directives.
|
|
!node.props.find(p => p.type === 7 /* DIRECTIVE */ &&
|
|
!context.directiveTransforms[p.name]) &&
|
|
// in compat mode, <template> tags with no special directives
|
|
// will be rendered as a fragment so its children must be
|
|
// converted into vnodes.
|
|
!(node.tag === 'template'))))) {
|
|
return;
|
|
}
|
|
// pre-convert text nodes into createTextVNode(text) calls to avoid
|
|
// runtime normalization.
|
|
for (let i = 0; i < children.length; i++) {
|
|
const child = children[i];
|
|
if (isText(child) || child.type === 8 /* COMPOUND_EXPRESSION */) {
|
|
const callArgs = [];
|
|
// createTextVNode defaults to single whitespace, so if it is a
|
|
// single space the code could be an empty call to save bytes.
|
|
if (child.type !== 2 /* TEXT */ || child.content !== ' ') {
|
|
callArgs.push(child);
|
|
}
|
|
// mark dynamic text with flag so it gets patched inside a block
|
|
if (!context.ssr &&
|
|
getConstantType(child, context) === 0 /* NOT_CONSTANT */) {
|
|
callArgs.push(1 /* TEXT */ +
|
|
(( true) ? ` /* ${_vue_shared__WEBPACK_IMPORTED_MODULE_0__.PatchFlagNames[1]} */` : 0));
|
|
}
|
|
children[i] = {
|
|
type: 12 /* TEXT_CALL */,
|
|
content: child,
|
|
loc: child.loc,
|
|
codegenNode: createCallExpression(context.helper(CREATE_TEXT), callArgs)
|
|
};
|
|
}
|
|
}
|
|
};
|
|
}
|
|
};
|
|
|
|
const seen = new WeakSet();
|
|
const transformOnce = (node, context) => {
|
|
if (node.type === 1 /* ELEMENT */ && findDir(node, 'once', true)) {
|
|
if (seen.has(node) || context.inVOnce) {
|
|
return;
|
|
}
|
|
seen.add(node);
|
|
context.inVOnce = true;
|
|
context.helper(SET_BLOCK_TRACKING);
|
|
return () => {
|
|
context.inVOnce = false;
|
|
const cur = context.currentNode;
|
|
if (cur.codegenNode) {
|
|
cur.codegenNode = context.cache(cur.codegenNode, true /* isVNode */);
|
|
}
|
|
};
|
|
}
|
|
};
|
|
|
|
const transformModel = (dir, node, context) => {
|
|
const { exp, arg } = dir;
|
|
if (!exp) {
|
|
context.onError(createCompilerError(40 /* X_V_MODEL_NO_EXPRESSION */, dir.loc));
|
|
return createTransformProps();
|
|
}
|
|
const rawExp = exp.loc.source;
|
|
const expString = exp.type === 4 /* SIMPLE_EXPRESSION */ ? exp.content : rawExp;
|
|
// im SFC <script setup> inline mode, the exp may have been transformed into
|
|
// _unref(exp)
|
|
context.bindingMetadata[rawExp];
|
|
const maybeRef = !true /* SETUP_CONST */;
|
|
if (!expString.trim() || (!isMemberExpression(expString) && !maybeRef)) {
|
|
context.onError(createCompilerError(41 /* X_V_MODEL_MALFORMED_EXPRESSION */, exp.loc));
|
|
return createTransformProps();
|
|
}
|
|
const propName = arg ? arg : createSimpleExpression('modelValue', true);
|
|
const eventName = arg
|
|
? isStaticExp(arg)
|
|
? `onUpdate:${arg.content}`
|
|
: createCompoundExpression(['"onUpdate:" + ', arg])
|
|
: `onUpdate:modelValue`;
|
|
let assignmentExp;
|
|
const eventArg = context.isTS ? `($event: any)` : `$event`;
|
|
{
|
|
assignmentExp = createCompoundExpression([
|
|
`${eventArg} => (`,
|
|
exp,
|
|
` = $event)`
|
|
]);
|
|
}
|
|
const props = [
|
|
// modelValue: foo
|
|
createObjectProperty(propName, dir.exp),
|
|
// "onUpdate:modelValue": $event => (foo = $event)
|
|
createObjectProperty(eventName, assignmentExp)
|
|
];
|
|
// modelModifiers: { foo: true, "bar-baz": true }
|
|
if (dir.modifiers.length && node.tagType === 1 /* COMPONENT */) {
|
|
const modifiers = dir.modifiers
|
|
.map(m => (isSimpleIdentifier(m) ? m : JSON.stringify(m)) + `: true`)
|
|
.join(`, `);
|
|
const modifiersKey = arg
|
|
? isStaticExp(arg)
|
|
? `${arg.content}Modifiers`
|
|
: createCompoundExpression([arg, ' + "Modifiers"'])
|
|
: `modelModifiers`;
|
|
props.push(createObjectProperty(modifiersKey, createSimpleExpression(`{ ${modifiers} }`, false, dir.loc, 2 /* CAN_HOIST */)));
|
|
}
|
|
return createTransformProps(props);
|
|
};
|
|
function createTransformProps(props = []) {
|
|
return { props };
|
|
}
|
|
|
|
const validDivisionCharRE = /[\w).+\-_$\]]/;
|
|
const transformFilter = (node, context) => {
|
|
if (!isCompatEnabled("COMPILER_FILTER" /* COMPILER_FILTERS */, context)) {
|
|
return;
|
|
}
|
|
if (node.type === 5 /* INTERPOLATION */) {
|
|
// filter rewrite is applied before expression transform so only
|
|
// simple expressions are possible at this stage
|
|
rewriteFilter(node.content, context);
|
|
}
|
|
if (node.type === 1 /* ELEMENT */) {
|
|
node.props.forEach((prop) => {
|
|
if (prop.type === 7 /* DIRECTIVE */ &&
|
|
prop.name !== 'for' &&
|
|
prop.exp) {
|
|
rewriteFilter(prop.exp, context);
|
|
}
|
|
});
|
|
}
|
|
};
|
|
function rewriteFilter(node, context) {
|
|
if (node.type === 4 /* SIMPLE_EXPRESSION */) {
|
|
parseFilter(node, context);
|
|
}
|
|
else {
|
|
for (let i = 0; i < node.children.length; i++) {
|
|
const child = node.children[i];
|
|
if (typeof child !== 'object')
|
|
continue;
|
|
if (child.type === 4 /* SIMPLE_EXPRESSION */) {
|
|
parseFilter(child, context);
|
|
}
|
|
else if (child.type === 8 /* COMPOUND_EXPRESSION */) {
|
|
rewriteFilter(node, context);
|
|
}
|
|
else if (child.type === 5 /* INTERPOLATION */) {
|
|
rewriteFilter(child.content, context);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function parseFilter(node, context) {
|
|
const exp = node.content;
|
|
let inSingle = false;
|
|
let inDouble = false;
|
|
let inTemplateString = false;
|
|
let inRegex = false;
|
|
let curly = 0;
|
|
let square = 0;
|
|
let paren = 0;
|
|
let lastFilterIndex = 0;
|
|
let c, prev, i, expression, filters = [];
|
|
for (i = 0; i < exp.length; i++) {
|
|
prev = c;
|
|
c = exp.charCodeAt(i);
|
|
if (inSingle) {
|
|
if (c === 0x27 && prev !== 0x5c)
|
|
inSingle = false;
|
|
}
|
|
else if (inDouble) {
|
|
if (c === 0x22 && prev !== 0x5c)
|
|
inDouble = false;
|
|
}
|
|
else if (inTemplateString) {
|
|
if (c === 0x60 && prev !== 0x5c)
|
|
inTemplateString = false;
|
|
}
|
|
else if (inRegex) {
|
|
if (c === 0x2f && prev !== 0x5c)
|
|
inRegex = false;
|
|
}
|
|
else if (c === 0x7c && // pipe
|
|
exp.charCodeAt(i + 1) !== 0x7c &&
|
|
exp.charCodeAt(i - 1) !== 0x7c &&
|
|
!curly &&
|
|
!square &&
|
|
!paren) {
|
|
if (expression === undefined) {
|
|
// first filter, end of expression
|
|
lastFilterIndex = i + 1;
|
|
expression = exp.slice(0, i).trim();
|
|
}
|
|
else {
|
|
pushFilter();
|
|
}
|
|
}
|
|
else {
|
|
switch (c) {
|
|
case 0x22:
|
|
inDouble = true;
|
|
break; // "
|
|
case 0x27:
|
|
inSingle = true;
|
|
break; // '
|
|
case 0x60:
|
|
inTemplateString = true;
|
|
break; // `
|
|
case 0x28:
|
|
paren++;
|
|
break; // (
|
|
case 0x29:
|
|
paren--;
|
|
break; // )
|
|
case 0x5b:
|
|
square++;
|
|
break; // [
|
|
case 0x5d:
|
|
square--;
|
|
break; // ]
|
|
case 0x7b:
|
|
curly++;
|
|
break; // {
|
|
case 0x7d:
|
|
curly--;
|
|
break; // }
|
|
}
|
|
if (c === 0x2f) {
|
|
// /
|
|
let j = i - 1;
|
|
let p;
|
|
// find first non-whitespace prev char
|
|
for (; j >= 0; j--) {
|
|
p = exp.charAt(j);
|
|
if (p !== ' ')
|
|
break;
|
|
}
|
|
if (!p || !validDivisionCharRE.test(p)) {
|
|
inRegex = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (expression === undefined) {
|
|
expression = exp.slice(0, i).trim();
|
|
}
|
|
else if (lastFilterIndex !== 0) {
|
|
pushFilter();
|
|
}
|
|
function pushFilter() {
|
|
filters.push(exp.slice(lastFilterIndex, i).trim());
|
|
lastFilterIndex = i + 1;
|
|
}
|
|
if (filters.length) {
|
|
( true) &&
|
|
warnDeprecation("COMPILER_FILTER" /* COMPILER_FILTERS */, context, node.loc);
|
|
for (i = 0; i < filters.length; i++) {
|
|
expression = wrapFilter(expression, filters[i], context);
|
|
}
|
|
node.content = expression;
|
|
}
|
|
}
|
|
function wrapFilter(exp, filter, context) {
|
|
context.helper(RESOLVE_FILTER);
|
|
const i = filter.indexOf('(');
|
|
if (i < 0) {
|
|
context.filters.add(filter);
|
|
return `${toValidAssetId(filter, 'filter')}(${exp})`;
|
|
}
|
|
else {
|
|
const name = filter.slice(0, i);
|
|
const args = filter.slice(i + 1);
|
|
context.filters.add(name);
|
|
return `${toValidAssetId(name, 'filter')}(${exp}${args !== ')' ? ',' + args : args}`;
|
|
}
|
|
}
|
|
|
|
const seen$1 = new WeakSet();
|
|
const transformMemo = (node, context) => {
|
|
if (node.type === 1 /* ELEMENT */) {
|
|
const dir = findDir(node, 'memo');
|
|
if (!dir || seen$1.has(node)) {
|
|
return;
|
|
}
|
|
seen$1.add(node);
|
|
return () => {
|
|
const codegenNode = node.codegenNode ||
|
|
context.currentNode.codegenNode;
|
|
if (codegenNode && codegenNode.type === 13 /* VNODE_CALL */) {
|
|
// non-component sub tree should be turned into a block
|
|
if (node.tagType !== 1 /* COMPONENT */) {
|
|
makeBlock(codegenNode, context);
|
|
}
|
|
node.codegenNode = createCallExpression(context.helper(WITH_MEMO), [
|
|
dir.exp,
|
|
createFunctionExpression(undefined, codegenNode),
|
|
`_cache`,
|
|
String(context.cached++)
|
|
]);
|
|
}
|
|
};
|
|
}
|
|
};
|
|
|
|
function getBaseTransformPreset(prefixIdentifiers) {
|
|
return [
|
|
[
|
|
transformOnce,
|
|
transformIf,
|
|
transformMemo,
|
|
transformFor,
|
|
...([transformFilter] ),
|
|
...(( true)
|
|
? [transformExpression]
|
|
: 0),
|
|
transformSlotOutlet,
|
|
transformElement,
|
|
trackSlotScopes,
|
|
transformText
|
|
],
|
|
{
|
|
on: transformOn,
|
|
bind: transformBind,
|
|
model: transformModel
|
|
}
|
|
];
|
|
}
|
|
// we name it `baseCompile` so that higher order compilers like
|
|
// @vue/compiler-dom can export `compile` while re-exporting everything else.
|
|
function baseCompile(template, options = {}) {
|
|
const onError = options.onError || defaultOnError;
|
|
const isModuleMode = options.mode === 'module';
|
|
/* istanbul ignore if */
|
|
{
|
|
if (options.prefixIdentifiers === true) {
|
|
onError(createCompilerError(45 /* X_PREFIX_ID_NOT_SUPPORTED */));
|
|
}
|
|
else if (isModuleMode) {
|
|
onError(createCompilerError(46 /* X_MODULE_MODE_NOT_SUPPORTED */));
|
|
}
|
|
}
|
|
const prefixIdentifiers = !true ;
|
|
if (options.cacheHandlers) {
|
|
onError(createCompilerError(47 /* X_CACHE_HANDLER_NOT_SUPPORTED */));
|
|
}
|
|
if (options.scopeId && !isModuleMode) {
|
|
onError(createCompilerError(48 /* X_SCOPE_ID_NOT_SUPPORTED */));
|
|
}
|
|
const ast = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isString)(template) ? baseParse(template, options) : template;
|
|
const [nodeTransforms, directiveTransforms] = getBaseTransformPreset();
|
|
transform(ast, (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.extend)({}, options, {
|
|
prefixIdentifiers,
|
|
nodeTransforms: [
|
|
...nodeTransforms,
|
|
...(options.nodeTransforms || []) // user transforms
|
|
],
|
|
directiveTransforms: (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.extend)({}, directiveTransforms, options.directiveTransforms || {} // user transforms
|
|
)
|
|
}));
|
|
return generate(ast, (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.extend)({}, options, {
|
|
prefixIdentifiers
|
|
}));
|
|
}
|
|
|
|
const noopDirectiveTransform = () => ({ props: [] });
|
|
|
|
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/@vue/compiler-dom/dist/compiler-dom.esm-bundler.js":
|
|
/*!*************************************************************************!*\
|
|
!*** ./node_modules/@vue/compiler-dom/dist/compiler-dom.esm-bundler.js ***!
|
|
\*************************************************************************/
|
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ "BASE_TRANSITION": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.BASE_TRANSITION),
|
|
/* harmony export */ "CAMELIZE": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.CAMELIZE),
|
|
/* harmony export */ "CAPITALIZE": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.CAPITALIZE),
|
|
/* harmony export */ "CREATE_BLOCK": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.CREATE_BLOCK),
|
|
/* harmony export */ "CREATE_COMMENT": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.CREATE_COMMENT),
|
|
/* harmony export */ "CREATE_ELEMENT_BLOCK": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.CREATE_ELEMENT_BLOCK),
|
|
/* harmony export */ "CREATE_ELEMENT_VNODE": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.CREATE_ELEMENT_VNODE),
|
|
/* harmony export */ "CREATE_SLOTS": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.CREATE_SLOTS),
|
|
/* harmony export */ "CREATE_STATIC": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.CREATE_STATIC),
|
|
/* harmony export */ "CREATE_TEXT": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.CREATE_TEXT),
|
|
/* harmony export */ "CREATE_VNODE": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.CREATE_VNODE),
|
|
/* harmony export */ "FRAGMENT": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.FRAGMENT),
|
|
/* harmony export */ "GUARD_REACTIVE_PROPS": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.GUARD_REACTIVE_PROPS),
|
|
/* harmony export */ "IS_MEMO_SAME": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.IS_MEMO_SAME),
|
|
/* harmony export */ "IS_REF": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.IS_REF),
|
|
/* harmony export */ "KEEP_ALIVE": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.KEEP_ALIVE),
|
|
/* harmony export */ "MERGE_PROPS": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.MERGE_PROPS),
|
|
/* harmony export */ "NORMALIZE_CLASS": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.NORMALIZE_CLASS),
|
|
/* harmony export */ "NORMALIZE_PROPS": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.NORMALIZE_PROPS),
|
|
/* harmony export */ "NORMALIZE_STYLE": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.NORMALIZE_STYLE),
|
|
/* harmony export */ "OPEN_BLOCK": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.OPEN_BLOCK),
|
|
/* harmony export */ "POP_SCOPE_ID": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.POP_SCOPE_ID),
|
|
/* harmony export */ "PUSH_SCOPE_ID": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.PUSH_SCOPE_ID),
|
|
/* harmony export */ "RENDER_LIST": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.RENDER_LIST),
|
|
/* harmony export */ "RENDER_SLOT": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.RENDER_SLOT),
|
|
/* harmony export */ "RESOLVE_COMPONENT": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.RESOLVE_COMPONENT),
|
|
/* harmony export */ "RESOLVE_DIRECTIVE": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.RESOLVE_DIRECTIVE),
|
|
/* harmony export */ "RESOLVE_DYNAMIC_COMPONENT": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.RESOLVE_DYNAMIC_COMPONENT),
|
|
/* harmony export */ "RESOLVE_FILTER": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.RESOLVE_FILTER),
|
|
/* harmony export */ "SET_BLOCK_TRACKING": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.SET_BLOCK_TRACKING),
|
|
/* harmony export */ "SUSPENSE": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.SUSPENSE),
|
|
/* harmony export */ "TELEPORT": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.TELEPORT),
|
|
/* harmony export */ "TO_DISPLAY_STRING": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.TO_DISPLAY_STRING),
|
|
/* harmony export */ "TO_HANDLERS": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.TO_HANDLERS),
|
|
/* harmony export */ "TO_HANDLER_KEY": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.TO_HANDLER_KEY),
|
|
/* harmony export */ "UNREF": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.UNREF),
|
|
/* harmony export */ "WITH_CTX": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.WITH_CTX),
|
|
/* harmony export */ "WITH_DIRECTIVES": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.WITH_DIRECTIVES),
|
|
/* harmony export */ "WITH_MEMO": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.WITH_MEMO),
|
|
/* harmony export */ "WITH_SCOPE_ID": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.WITH_SCOPE_ID),
|
|
/* harmony export */ "advancePositionWithClone": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.advancePositionWithClone),
|
|
/* harmony export */ "advancePositionWithMutation": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.advancePositionWithMutation),
|
|
/* harmony export */ "assert": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.assert),
|
|
/* harmony export */ "baseCompile": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.baseCompile),
|
|
/* harmony export */ "baseParse": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.baseParse),
|
|
/* harmony export */ "buildProps": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.buildProps),
|
|
/* harmony export */ "buildSlots": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.buildSlots),
|
|
/* harmony export */ "checkCompatEnabled": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.checkCompatEnabled),
|
|
/* harmony export */ "createArrayExpression": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.createArrayExpression),
|
|
/* harmony export */ "createAssignmentExpression": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.createAssignmentExpression),
|
|
/* harmony export */ "createBlockStatement": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.createBlockStatement),
|
|
/* harmony export */ "createCacheExpression": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.createCacheExpression),
|
|
/* harmony export */ "createCallExpression": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.createCallExpression),
|
|
/* harmony export */ "createCompilerError": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.createCompilerError),
|
|
/* harmony export */ "createCompoundExpression": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.createCompoundExpression),
|
|
/* harmony export */ "createConditionalExpression": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.createConditionalExpression),
|
|
/* harmony export */ "createForLoopParams": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.createForLoopParams),
|
|
/* harmony export */ "createFunctionExpression": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.createFunctionExpression),
|
|
/* harmony export */ "createIfStatement": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.createIfStatement),
|
|
/* harmony export */ "createInterpolation": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.createInterpolation),
|
|
/* harmony export */ "createObjectExpression": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.createObjectExpression),
|
|
/* harmony export */ "createObjectProperty": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.createObjectProperty),
|
|
/* harmony export */ "createReturnStatement": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.createReturnStatement),
|
|
/* harmony export */ "createRoot": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.createRoot),
|
|
/* harmony export */ "createSequenceExpression": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.createSequenceExpression),
|
|
/* harmony export */ "createSimpleExpression": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.createSimpleExpression),
|
|
/* harmony export */ "createStructuralDirectiveTransform": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.createStructuralDirectiveTransform),
|
|
/* harmony export */ "createTemplateLiteral": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.createTemplateLiteral),
|
|
/* harmony export */ "createTransformContext": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.createTransformContext),
|
|
/* harmony export */ "createVNodeCall": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.createVNodeCall),
|
|
/* harmony export */ "extractIdentifiers": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.extractIdentifiers),
|
|
/* harmony export */ "findDir": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.findDir),
|
|
/* harmony export */ "findProp": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.findProp),
|
|
/* harmony export */ "generate": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.generate),
|
|
/* harmony export */ "generateCodeFrame": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.generateCodeFrame),
|
|
/* harmony export */ "getBaseTransformPreset": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.getBaseTransformPreset),
|
|
/* harmony export */ "getInnerRange": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.getInnerRange),
|
|
/* harmony export */ "getMemoedVNodeCall": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.getMemoedVNodeCall),
|
|
/* harmony export */ "getVNodeBlockHelper": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.getVNodeBlockHelper),
|
|
/* harmony export */ "getVNodeHelper": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.getVNodeHelper),
|
|
/* harmony export */ "hasDynamicKeyVBind": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.hasDynamicKeyVBind),
|
|
/* harmony export */ "hasScopeRef": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.hasScopeRef),
|
|
/* harmony export */ "helperNameMap": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.helperNameMap),
|
|
/* harmony export */ "injectProp": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.injectProp),
|
|
/* harmony export */ "isBindKey": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.isBindKey),
|
|
/* harmony export */ "isBuiltInType": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.isBuiltInType),
|
|
/* harmony export */ "isCoreComponent": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.isCoreComponent),
|
|
/* harmony export */ "isFunctionType": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.isFunctionType),
|
|
/* harmony export */ "isInDestructureAssignment": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.isInDestructureAssignment),
|
|
/* harmony export */ "isMemberExpression": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.isMemberExpression),
|
|
/* harmony export */ "isReferencedIdentifier": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.isReferencedIdentifier),
|
|
/* harmony export */ "isSimpleIdentifier": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.isSimpleIdentifier),
|
|
/* harmony export */ "isSlotOutlet": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.isSlotOutlet),
|
|
/* harmony export */ "isStaticExp": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.isStaticExp),
|
|
/* harmony export */ "isStaticProperty": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.isStaticProperty),
|
|
/* harmony export */ "isStaticPropertyKey": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.isStaticPropertyKey),
|
|
/* harmony export */ "isTemplateNode": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.isTemplateNode),
|
|
/* harmony export */ "isText": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.isText),
|
|
/* harmony export */ "isVSlot": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.isVSlot),
|
|
/* harmony export */ "locStub": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.locStub),
|
|
/* harmony export */ "makeBlock": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.makeBlock),
|
|
/* harmony export */ "noopDirectiveTransform": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.noopDirectiveTransform),
|
|
/* harmony export */ "processExpression": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.processExpression),
|
|
/* harmony export */ "processFor": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.processFor),
|
|
/* harmony export */ "processIf": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.processIf),
|
|
/* harmony export */ "processSlotOutlet": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.processSlotOutlet),
|
|
/* harmony export */ "registerRuntimeHelpers": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.registerRuntimeHelpers),
|
|
/* harmony export */ "resolveComponentType": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.resolveComponentType),
|
|
/* harmony export */ "toValidAssetId": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.toValidAssetId),
|
|
/* harmony export */ "trackSlotScopes": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.trackSlotScopes),
|
|
/* harmony export */ "trackVForSlotScopes": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.trackVForSlotScopes),
|
|
/* harmony export */ "transform": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.transform),
|
|
/* harmony export */ "transformBind": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.transformBind),
|
|
/* harmony export */ "transformElement": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.transformElement),
|
|
/* harmony export */ "transformExpression": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.transformExpression),
|
|
/* harmony export */ "transformModel": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.transformModel),
|
|
/* harmony export */ "transformOn": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.transformOn),
|
|
/* harmony export */ "traverseNode": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.traverseNode),
|
|
/* harmony export */ "walkBlockDeclarations": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.walkBlockDeclarations),
|
|
/* harmony export */ "walkFunctionParams": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.walkFunctionParams),
|
|
/* harmony export */ "walkIdentifiers": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.walkIdentifiers),
|
|
/* harmony export */ "warnDeprecation": () => (/* reexport safe */ _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.warnDeprecation),
|
|
/* harmony export */ "DOMDirectiveTransforms": () => (/* binding */ DOMDirectiveTransforms),
|
|
/* harmony export */ "DOMNodeTransforms": () => (/* binding */ DOMNodeTransforms),
|
|
/* harmony export */ "TRANSITION": () => (/* binding */ TRANSITION),
|
|
/* harmony export */ "TRANSITION_GROUP": () => (/* binding */ TRANSITION_GROUP),
|
|
/* harmony export */ "V_MODEL_CHECKBOX": () => (/* binding */ V_MODEL_CHECKBOX),
|
|
/* harmony export */ "V_MODEL_DYNAMIC": () => (/* binding */ V_MODEL_DYNAMIC),
|
|
/* harmony export */ "V_MODEL_RADIO": () => (/* binding */ V_MODEL_RADIO),
|
|
/* harmony export */ "V_MODEL_SELECT": () => (/* binding */ V_MODEL_SELECT),
|
|
/* harmony export */ "V_MODEL_TEXT": () => (/* binding */ V_MODEL_TEXT),
|
|
/* harmony export */ "V_ON_WITH_KEYS": () => (/* binding */ V_ON_WITH_KEYS),
|
|
/* harmony export */ "V_ON_WITH_MODIFIERS": () => (/* binding */ V_ON_WITH_MODIFIERS),
|
|
/* harmony export */ "V_SHOW": () => (/* binding */ V_SHOW),
|
|
/* harmony export */ "compile": () => (/* binding */ compile),
|
|
/* harmony export */ "createDOMCompilerError": () => (/* binding */ createDOMCompilerError),
|
|
/* harmony export */ "parse": () => (/* binding */ parse),
|
|
/* harmony export */ "parserOptions": () => (/* binding */ parserOptions),
|
|
/* harmony export */ "transformStyle": () => (/* binding */ transformStyle)
|
|
/* harmony export */ });
|
|
/* harmony import */ var _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @vue/compiler-core */ "./node_modules/@vue/compiler-core/dist/compiler-core.esm-bundler.js");
|
|
/* harmony import */ var _vue_shared__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @vue/shared */ "./node_modules/@vue/shared/dist/shared.esm-bundler.js");
|
|
|
|
|
|
|
|
|
|
const V_MODEL_RADIO = Symbol(( true) ? `vModelRadio` : 0);
|
|
const V_MODEL_CHECKBOX = Symbol(( true) ? `vModelCheckbox` : 0);
|
|
const V_MODEL_TEXT = Symbol(( true) ? `vModelText` : 0);
|
|
const V_MODEL_SELECT = Symbol(( true) ? `vModelSelect` : 0);
|
|
const V_MODEL_DYNAMIC = Symbol(( true) ? `vModelDynamic` : 0);
|
|
const V_ON_WITH_MODIFIERS = Symbol(( true) ? `vOnModifiersGuard` : 0);
|
|
const V_ON_WITH_KEYS = Symbol(( true) ? `vOnKeysGuard` : 0);
|
|
const V_SHOW = Symbol(( true) ? `vShow` : 0);
|
|
const TRANSITION = Symbol(( true) ? `Transition` : 0);
|
|
const TRANSITION_GROUP = Symbol(( true) ? `TransitionGroup` : 0);
|
|
(0,_vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.registerRuntimeHelpers)({
|
|
[V_MODEL_RADIO]: `vModelRadio`,
|
|
[V_MODEL_CHECKBOX]: `vModelCheckbox`,
|
|
[V_MODEL_TEXT]: `vModelText`,
|
|
[V_MODEL_SELECT]: `vModelSelect`,
|
|
[V_MODEL_DYNAMIC]: `vModelDynamic`,
|
|
[V_ON_WITH_MODIFIERS]: `withModifiers`,
|
|
[V_ON_WITH_KEYS]: `withKeys`,
|
|
[V_SHOW]: `vShow`,
|
|
[TRANSITION]: `Transition`,
|
|
[TRANSITION_GROUP]: `TransitionGroup`
|
|
});
|
|
|
|
/* eslint-disable no-restricted-globals */
|
|
let decoder;
|
|
function decodeHtmlBrowser(raw, asAttr = false) {
|
|
if (!decoder) {
|
|
decoder = document.createElement('div');
|
|
}
|
|
if (asAttr) {
|
|
decoder.innerHTML = `<div foo="${raw.replace(/"/g, '"')}">`;
|
|
return decoder.children[0].getAttribute('foo');
|
|
}
|
|
else {
|
|
decoder.innerHTML = raw;
|
|
return decoder.textContent;
|
|
}
|
|
}
|
|
|
|
const isRawTextContainer = /*#__PURE__*/ (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.makeMap)('style,iframe,script,noscript', true);
|
|
const parserOptions = {
|
|
isVoidTag: _vue_shared__WEBPACK_IMPORTED_MODULE_1__.isVoidTag,
|
|
isNativeTag: tag => (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isHTMLTag)(tag) || (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isSVGTag)(tag),
|
|
isPreTag: tag => tag === 'pre',
|
|
decodeEntities: decodeHtmlBrowser ,
|
|
isBuiltInComponent: (tag) => {
|
|
if ((0,_vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.isBuiltInType)(tag, `Transition`)) {
|
|
return TRANSITION;
|
|
}
|
|
else if ((0,_vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.isBuiltInType)(tag, `TransitionGroup`)) {
|
|
return TRANSITION_GROUP;
|
|
}
|
|
},
|
|
// https://html.spec.whatwg.org/multipage/parsing.html#tree-construction-dispatcher
|
|
getNamespace(tag, parent) {
|
|
let ns = parent ? parent.ns : 0 /* HTML */;
|
|
if (parent && ns === 2 /* MATH_ML */) {
|
|
if (parent.tag === 'annotation-xml') {
|
|
if (tag === 'svg') {
|
|
return 1 /* SVG */;
|
|
}
|
|
if (parent.props.some(a => a.type === 6 /* ATTRIBUTE */ &&
|
|
a.name === 'encoding' &&
|
|
a.value != null &&
|
|
(a.value.content === 'text/html' ||
|
|
a.value.content === 'application/xhtml+xml'))) {
|
|
ns = 0 /* HTML */;
|
|
}
|
|
}
|
|
else if (/^m(?:[ions]|text)$/.test(parent.tag) &&
|
|
tag !== 'mglyph' &&
|
|
tag !== 'malignmark') {
|
|
ns = 0 /* HTML */;
|
|
}
|
|
}
|
|
else if (parent && ns === 1 /* SVG */) {
|
|
if (parent.tag === 'foreignObject' ||
|
|
parent.tag === 'desc' ||
|
|
parent.tag === 'title') {
|
|
ns = 0 /* HTML */;
|
|
}
|
|
}
|
|
if (ns === 0 /* HTML */) {
|
|
if (tag === 'svg') {
|
|
return 1 /* SVG */;
|
|
}
|
|
if (tag === 'math') {
|
|
return 2 /* MATH_ML */;
|
|
}
|
|
}
|
|
return ns;
|
|
},
|
|
// https://html.spec.whatwg.org/multipage/parsing.html#parsing-html-fragments
|
|
getTextMode({ tag, ns }) {
|
|
if (ns === 0 /* HTML */) {
|
|
if (tag === 'textarea' || tag === 'title') {
|
|
return 1 /* RCDATA */;
|
|
}
|
|
if (isRawTextContainer(tag)) {
|
|
return 2 /* RAWTEXT */;
|
|
}
|
|
}
|
|
return 0 /* DATA */;
|
|
}
|
|
};
|
|
|
|
// Parse inline CSS strings for static style attributes into an object.
|
|
// This is a NodeTransform since it works on the static `style` attribute and
|
|
// converts it into a dynamic equivalent:
|
|
// style="color: red" -> :style='{ "color": "red" }'
|
|
// It is then processed by `transformElement` and included in the generated
|
|
// props.
|
|
const transformStyle = node => {
|
|
if (node.type === 1 /* ELEMENT */) {
|
|
node.props.forEach((p, i) => {
|
|
if (p.type === 6 /* ATTRIBUTE */ && p.name === 'style' && p.value) {
|
|
// replace p with an expression node
|
|
node.props[i] = {
|
|
type: 7 /* DIRECTIVE */,
|
|
name: `bind`,
|
|
arg: (0,_vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.createSimpleExpression)(`style`, true, p.loc),
|
|
exp: parseInlineCSS(p.value.content, p.loc),
|
|
modifiers: [],
|
|
loc: p.loc
|
|
};
|
|
}
|
|
});
|
|
}
|
|
};
|
|
const parseInlineCSS = (cssText, loc) => {
|
|
const normalized = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.parseStringStyle)(cssText);
|
|
return (0,_vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.createSimpleExpression)(JSON.stringify(normalized), false, loc, 3 /* CAN_STRINGIFY */);
|
|
};
|
|
|
|
function createDOMCompilerError(code, loc) {
|
|
return (0,_vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.createCompilerError)(code, loc, true ? DOMErrorMessages : 0);
|
|
}
|
|
const DOMErrorMessages = {
|
|
[49 /* X_V_HTML_NO_EXPRESSION */]: `v-html is missing expression.`,
|
|
[50 /* X_V_HTML_WITH_CHILDREN */]: `v-html will override element children.`,
|
|
[51 /* X_V_TEXT_NO_EXPRESSION */]: `v-text is missing expression.`,
|
|
[52 /* X_V_TEXT_WITH_CHILDREN */]: `v-text will override element children.`,
|
|
[53 /* X_V_MODEL_ON_INVALID_ELEMENT */]: `v-model can only be used on <input>, <textarea> and <select> elements.`,
|
|
[54 /* X_V_MODEL_ARG_ON_ELEMENT */]: `v-model argument is not supported on plain elements.`,
|
|
[55 /* X_V_MODEL_ON_FILE_INPUT_ELEMENT */]: `v-model cannot be used on file inputs since they are read-only. Use a v-on:change listener instead.`,
|
|
[56 /* X_V_MODEL_UNNECESSARY_VALUE */]: `Unnecessary value binding used alongside v-model. It will interfere with v-model's behavior.`,
|
|
[57 /* X_V_SHOW_NO_EXPRESSION */]: `v-show is missing expression.`,
|
|
[58 /* X_TRANSITION_INVALID_CHILDREN */]: `<Transition> expects exactly one child element or component.`,
|
|
[59 /* X_IGNORED_SIDE_EFFECT_TAG */]: `Tags with side effect (<script> and <style>) are ignored in client component templates.`
|
|
};
|
|
|
|
const transformVHtml = (dir, node, context) => {
|
|
const { exp, loc } = dir;
|
|
if (!exp) {
|
|
context.onError(createDOMCompilerError(49 /* X_V_HTML_NO_EXPRESSION */, loc));
|
|
}
|
|
if (node.children.length) {
|
|
context.onError(createDOMCompilerError(50 /* X_V_HTML_WITH_CHILDREN */, loc));
|
|
node.children.length = 0;
|
|
}
|
|
return {
|
|
props: [
|
|
(0,_vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.createObjectProperty)((0,_vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.createSimpleExpression)(`innerHTML`, true, loc), exp || (0,_vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.createSimpleExpression)('', true))
|
|
]
|
|
};
|
|
};
|
|
|
|
const transformVText = (dir, node, context) => {
|
|
const { exp, loc } = dir;
|
|
if (!exp) {
|
|
context.onError(createDOMCompilerError(51 /* X_V_TEXT_NO_EXPRESSION */, loc));
|
|
}
|
|
if (node.children.length) {
|
|
context.onError(createDOMCompilerError(52 /* X_V_TEXT_WITH_CHILDREN */, loc));
|
|
node.children.length = 0;
|
|
}
|
|
return {
|
|
props: [
|
|
(0,_vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.createObjectProperty)((0,_vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.createSimpleExpression)(`textContent`, true), exp
|
|
? (0,_vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.createCallExpression)(context.helperString(_vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.TO_DISPLAY_STRING), [exp], loc)
|
|
: (0,_vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.createSimpleExpression)('', true))
|
|
]
|
|
};
|
|
};
|
|
|
|
const transformModel = (dir, node, context) => {
|
|
const baseResult = (0,_vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.transformModel)(dir, node, context);
|
|
// base transform has errors OR component v-model (only need props)
|
|
if (!baseResult.props.length || node.tagType === 1 /* COMPONENT */) {
|
|
return baseResult;
|
|
}
|
|
if (dir.arg) {
|
|
context.onError(createDOMCompilerError(54 /* X_V_MODEL_ARG_ON_ELEMENT */, dir.arg.loc));
|
|
}
|
|
function checkDuplicatedValue() {
|
|
const value = (0,_vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.findProp)(node, 'value');
|
|
if (value) {
|
|
context.onError(createDOMCompilerError(56 /* X_V_MODEL_UNNECESSARY_VALUE */, value.loc));
|
|
}
|
|
}
|
|
const { tag } = node;
|
|
const isCustomElement = context.isCustomElement(tag);
|
|
if (tag === 'input' ||
|
|
tag === 'textarea' ||
|
|
tag === 'select' ||
|
|
isCustomElement) {
|
|
let directiveToUse = V_MODEL_TEXT;
|
|
let isInvalidType = false;
|
|
if (tag === 'input' || isCustomElement) {
|
|
const type = (0,_vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.findProp)(node, `type`);
|
|
if (type) {
|
|
if (type.type === 7 /* DIRECTIVE */) {
|
|
// :type="foo"
|
|
directiveToUse = V_MODEL_DYNAMIC;
|
|
}
|
|
else if (type.value) {
|
|
switch (type.value.content) {
|
|
case 'radio':
|
|
directiveToUse = V_MODEL_RADIO;
|
|
break;
|
|
case 'checkbox':
|
|
directiveToUse = V_MODEL_CHECKBOX;
|
|
break;
|
|
case 'file':
|
|
isInvalidType = true;
|
|
context.onError(createDOMCompilerError(55 /* X_V_MODEL_ON_FILE_INPUT_ELEMENT */, dir.loc));
|
|
break;
|
|
default:
|
|
// text type
|
|
( true) && checkDuplicatedValue();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else if ((0,_vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.hasDynamicKeyVBind)(node)) {
|
|
// element has bindings with dynamic keys, which can possibly contain
|
|
// "type".
|
|
directiveToUse = V_MODEL_DYNAMIC;
|
|
}
|
|
else {
|
|
// text type
|
|
( true) && checkDuplicatedValue();
|
|
}
|
|
}
|
|
else if (tag === 'select') {
|
|
directiveToUse = V_MODEL_SELECT;
|
|
}
|
|
else {
|
|
// textarea
|
|
( true) && checkDuplicatedValue();
|
|
}
|
|
// inject runtime directive
|
|
// by returning the helper symbol via needRuntime
|
|
// the import will replaced a resolveDirective call.
|
|
if (!isInvalidType) {
|
|
baseResult.needRuntime = context.helper(directiveToUse);
|
|
}
|
|
}
|
|
else {
|
|
context.onError(createDOMCompilerError(53 /* X_V_MODEL_ON_INVALID_ELEMENT */, dir.loc));
|
|
}
|
|
// native vmodel doesn't need the `modelValue` props since they are also
|
|
// passed to the runtime as `binding.value`. removing it reduces code size.
|
|
baseResult.props = baseResult.props.filter(p => !(p.key.type === 4 /* SIMPLE_EXPRESSION */ &&
|
|
p.key.content === 'modelValue'));
|
|
return baseResult;
|
|
};
|
|
|
|
const isEventOptionModifier = /*#__PURE__*/ (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.makeMap)(`passive,once,capture`);
|
|
const isNonKeyModifier = /*#__PURE__*/ (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.makeMap)(
|
|
// event propagation management
|
|
`stop,prevent,self,` +
|
|
// system modifiers + exact
|
|
`ctrl,shift,alt,meta,exact,` +
|
|
// mouse
|
|
`middle`);
|
|
// left & right could be mouse or key modifiers based on event type
|
|
const maybeKeyModifier = /*#__PURE__*/ (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.makeMap)('left,right');
|
|
const isKeyboardEvent = /*#__PURE__*/ (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.makeMap)(`onkeyup,onkeydown,onkeypress`, true);
|
|
const resolveModifiers = (key, modifiers, context, loc) => {
|
|
const keyModifiers = [];
|
|
const nonKeyModifiers = [];
|
|
const eventOptionModifiers = [];
|
|
for (let i = 0; i < modifiers.length; i++) {
|
|
const modifier = modifiers[i];
|
|
if (modifier === 'native' &&
|
|
(0,_vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.checkCompatEnabled)("COMPILER_V_ON_NATIVE" /* COMPILER_V_ON_NATIVE */, context, loc)) {
|
|
eventOptionModifiers.push(modifier);
|
|
}
|
|
else if (isEventOptionModifier(modifier)) {
|
|
// eventOptionModifiers: modifiers for addEventListener() options,
|
|
// e.g. .passive & .capture
|
|
eventOptionModifiers.push(modifier);
|
|
}
|
|
else {
|
|
// runtimeModifiers: modifiers that needs runtime guards
|
|
if (maybeKeyModifier(modifier)) {
|
|
if ((0,_vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.isStaticExp)(key)) {
|
|
if (isKeyboardEvent(key.content)) {
|
|
keyModifiers.push(modifier);
|
|
}
|
|
else {
|
|
nonKeyModifiers.push(modifier);
|
|
}
|
|
}
|
|
else {
|
|
keyModifiers.push(modifier);
|
|
nonKeyModifiers.push(modifier);
|
|
}
|
|
}
|
|
else {
|
|
if (isNonKeyModifier(modifier)) {
|
|
nonKeyModifiers.push(modifier);
|
|
}
|
|
else {
|
|
keyModifiers.push(modifier);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return {
|
|
keyModifiers,
|
|
nonKeyModifiers,
|
|
eventOptionModifiers
|
|
};
|
|
};
|
|
const transformClick = (key, event) => {
|
|
const isStaticClick = (0,_vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.isStaticExp)(key) && key.content.toLowerCase() === 'onclick';
|
|
return isStaticClick
|
|
? (0,_vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.createSimpleExpression)(event, true)
|
|
: key.type !== 4 /* SIMPLE_EXPRESSION */
|
|
? (0,_vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.createCompoundExpression)([
|
|
`(`,
|
|
key,
|
|
`) === "onClick" ? "${event}" : (`,
|
|
key,
|
|
`)`
|
|
])
|
|
: key;
|
|
};
|
|
const transformOn = (dir, node, context) => {
|
|
return (0,_vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.transformOn)(dir, node, context, baseResult => {
|
|
const { modifiers } = dir;
|
|
if (!modifiers.length)
|
|
return baseResult;
|
|
let { key, value: handlerExp } = baseResult.props[0];
|
|
const { keyModifiers, nonKeyModifiers, eventOptionModifiers } = resolveModifiers(key, modifiers, context, dir.loc);
|
|
// normalize click.right and click.middle since they don't actually fire
|
|
if (nonKeyModifiers.includes('right')) {
|
|
key = transformClick(key, `onContextmenu`);
|
|
}
|
|
if (nonKeyModifiers.includes('middle')) {
|
|
key = transformClick(key, `onMouseup`);
|
|
}
|
|
if (nonKeyModifiers.length) {
|
|
handlerExp = (0,_vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.createCallExpression)(context.helper(V_ON_WITH_MODIFIERS), [
|
|
handlerExp,
|
|
JSON.stringify(nonKeyModifiers)
|
|
]);
|
|
}
|
|
if (keyModifiers.length &&
|
|
// if event name is dynamic, always wrap with keys guard
|
|
(!(0,_vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.isStaticExp)(key) || isKeyboardEvent(key.content))) {
|
|
handlerExp = (0,_vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.createCallExpression)(context.helper(V_ON_WITH_KEYS), [
|
|
handlerExp,
|
|
JSON.stringify(keyModifiers)
|
|
]);
|
|
}
|
|
if (eventOptionModifiers.length) {
|
|
const modifierPostfix = eventOptionModifiers.map(_vue_shared__WEBPACK_IMPORTED_MODULE_1__.capitalize).join('');
|
|
key = (0,_vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.isStaticExp)(key)
|
|
? (0,_vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.createSimpleExpression)(`${key.content}${modifierPostfix}`, true)
|
|
: (0,_vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.createCompoundExpression)([`(`, key, `) + "${modifierPostfix}"`]);
|
|
}
|
|
return {
|
|
props: [(0,_vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.createObjectProperty)(key, handlerExp)]
|
|
};
|
|
});
|
|
};
|
|
|
|
const transformShow = (dir, node, context) => {
|
|
const { exp, loc } = dir;
|
|
if (!exp) {
|
|
context.onError(createDOMCompilerError(57 /* X_V_SHOW_NO_EXPRESSION */, loc));
|
|
}
|
|
return {
|
|
props: [],
|
|
needRuntime: context.helper(V_SHOW)
|
|
};
|
|
};
|
|
|
|
const warnTransitionChildren = (node, context) => {
|
|
if (node.type === 1 /* ELEMENT */ &&
|
|
node.tagType === 1 /* COMPONENT */) {
|
|
const component = context.isBuiltInComponent(node.tag);
|
|
if (component === TRANSITION) {
|
|
return () => {
|
|
if (node.children.length && hasMultipleChildren(node)) {
|
|
context.onError(createDOMCompilerError(58 /* X_TRANSITION_INVALID_CHILDREN */, {
|
|
start: node.children[0].loc.start,
|
|
end: node.children[node.children.length - 1].loc.end,
|
|
source: ''
|
|
}));
|
|
}
|
|
};
|
|
}
|
|
}
|
|
};
|
|
function hasMultipleChildren(node) {
|
|
// #1352 filter out potential comment nodes.
|
|
const children = (node.children = node.children.filter(c => c.type !== 3 /* COMMENT */));
|
|
const child = children[0];
|
|
return (children.length !== 1 ||
|
|
child.type === 11 /* FOR */ ||
|
|
(child.type === 9 /* IF */ && child.branches.some(hasMultipleChildren)));
|
|
}
|
|
|
|
const ignoreSideEffectTags = (node, context) => {
|
|
if (node.type === 1 /* ELEMENT */ &&
|
|
node.tagType === 0 /* ELEMENT */ &&
|
|
(node.tag === 'script' || node.tag === 'style')) {
|
|
context.onError(createDOMCompilerError(59 /* X_IGNORED_SIDE_EFFECT_TAG */, node.loc));
|
|
context.removeNode();
|
|
}
|
|
};
|
|
|
|
const DOMNodeTransforms = [
|
|
transformStyle,
|
|
...(( true) ? [warnTransitionChildren] : 0)
|
|
];
|
|
const DOMDirectiveTransforms = {
|
|
cloak: _vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.noopDirectiveTransform,
|
|
html: transformVHtml,
|
|
text: transformVText,
|
|
model: transformModel,
|
|
on: transformOn,
|
|
show: transformShow
|
|
};
|
|
function compile(template, options = {}) {
|
|
return (0,_vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.baseCompile)(template, (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.extend)({}, parserOptions, options, {
|
|
nodeTransforms: [
|
|
// ignore <script> and <tag>
|
|
// this is not put inside DOMNodeTransforms because that list is used
|
|
// by compiler-ssr to generate vnode fallback branches
|
|
ignoreSideEffectTags,
|
|
...DOMNodeTransforms,
|
|
...(options.nodeTransforms || [])
|
|
],
|
|
directiveTransforms: (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.extend)({}, DOMDirectiveTransforms, options.directiveTransforms || {}),
|
|
transformHoist: null
|
|
}));
|
|
}
|
|
function parse(template, options = {}) {
|
|
return (0,_vue_compiler_core__WEBPACK_IMPORTED_MODULE_0__.baseParse)(template, (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.extend)({}, parserOptions, options));
|
|
}
|
|
|
|
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/@vue/devtools-api/lib/esm/api/api.js":
|
|
/*!***********************************************************!*\
|
|
!*** ./node_modules/@vue/devtools-api/lib/esm/api/api.js ***!
|
|
\***********************************************************/
|
|
/***/ (() => {
|
|
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/@vue/devtools-api/lib/esm/api/app.js":
|
|
/*!***********************************************************!*\
|
|
!*** ./node_modules/@vue/devtools-api/lib/esm/api/app.js ***!
|
|
\***********************************************************/
|
|
/***/ (() => {
|
|
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/@vue/devtools-api/lib/esm/api/component.js":
|
|
/*!*****************************************************************!*\
|
|
!*** ./node_modules/@vue/devtools-api/lib/esm/api/component.js ***!
|
|
\*****************************************************************/
|
|
/***/ (() => {
|
|
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/@vue/devtools-api/lib/esm/api/context.js":
|
|
/*!***************************************************************!*\
|
|
!*** ./node_modules/@vue/devtools-api/lib/esm/api/context.js ***!
|
|
\***************************************************************/
|
|
/***/ (() => {
|
|
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/@vue/devtools-api/lib/esm/api/hooks.js":
|
|
/*!*************************************************************!*\
|
|
!*** ./node_modules/@vue/devtools-api/lib/esm/api/hooks.js ***!
|
|
\*************************************************************/
|
|
/***/ (() => {
|
|
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/@vue/devtools-api/lib/esm/api/index.js":
|
|
/*!*************************************************************!*\
|
|
!*** ./node_modules/@vue/devtools-api/lib/esm/api/index.js ***!
|
|
\*************************************************************/
|
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./api */ "./node_modules/@vue/devtools-api/lib/esm/api/api.js");
|
|
/* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_api__WEBPACK_IMPORTED_MODULE_0__);
|
|
/* harmony reexport (unknown) */ var __WEBPACK_REEXPORT_OBJECT__ = {};
|
|
/* harmony reexport (unknown) */ for(const __WEBPACK_IMPORT_KEY__ in _api__WEBPACK_IMPORTED_MODULE_0__) if(__WEBPACK_IMPORT_KEY__ !== "default") __WEBPACK_REEXPORT_OBJECT__[__WEBPACK_IMPORT_KEY__] = () => _api__WEBPACK_IMPORTED_MODULE_0__[__WEBPACK_IMPORT_KEY__]
|
|
/* harmony reexport (unknown) */ __webpack_require__.d(__webpack_exports__, __WEBPACK_REEXPORT_OBJECT__);
|
|
/* harmony import */ var _app__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./app */ "./node_modules/@vue/devtools-api/lib/esm/api/app.js");
|
|
/* harmony import */ var _app__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_app__WEBPACK_IMPORTED_MODULE_1__);
|
|
/* harmony reexport (unknown) */ var __WEBPACK_REEXPORT_OBJECT__ = {};
|
|
/* harmony reexport (unknown) */ for(const __WEBPACK_IMPORT_KEY__ in _app__WEBPACK_IMPORTED_MODULE_1__) if(__WEBPACK_IMPORT_KEY__ !== "default") __WEBPACK_REEXPORT_OBJECT__[__WEBPACK_IMPORT_KEY__] = () => _app__WEBPACK_IMPORTED_MODULE_1__[__WEBPACK_IMPORT_KEY__]
|
|
/* harmony reexport (unknown) */ __webpack_require__.d(__webpack_exports__, __WEBPACK_REEXPORT_OBJECT__);
|
|
/* harmony import */ var _component__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./component */ "./node_modules/@vue/devtools-api/lib/esm/api/component.js");
|
|
/* harmony import */ var _component__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_component__WEBPACK_IMPORTED_MODULE_2__);
|
|
/* harmony reexport (unknown) */ var __WEBPACK_REEXPORT_OBJECT__ = {};
|
|
/* harmony reexport (unknown) */ for(const __WEBPACK_IMPORT_KEY__ in _component__WEBPACK_IMPORTED_MODULE_2__) if(__WEBPACK_IMPORT_KEY__ !== "default") __WEBPACK_REEXPORT_OBJECT__[__WEBPACK_IMPORT_KEY__] = () => _component__WEBPACK_IMPORTED_MODULE_2__[__WEBPACK_IMPORT_KEY__]
|
|
/* harmony reexport (unknown) */ __webpack_require__.d(__webpack_exports__, __WEBPACK_REEXPORT_OBJECT__);
|
|
/* harmony import */ var _context__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./context */ "./node_modules/@vue/devtools-api/lib/esm/api/context.js");
|
|
/* harmony import */ var _context__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_context__WEBPACK_IMPORTED_MODULE_3__);
|
|
/* harmony reexport (unknown) */ var __WEBPACK_REEXPORT_OBJECT__ = {};
|
|
/* harmony reexport (unknown) */ for(const __WEBPACK_IMPORT_KEY__ in _context__WEBPACK_IMPORTED_MODULE_3__) if(__WEBPACK_IMPORT_KEY__ !== "default") __WEBPACK_REEXPORT_OBJECT__[__WEBPACK_IMPORT_KEY__] = () => _context__WEBPACK_IMPORTED_MODULE_3__[__WEBPACK_IMPORT_KEY__]
|
|
/* harmony reexport (unknown) */ __webpack_require__.d(__webpack_exports__, __WEBPACK_REEXPORT_OBJECT__);
|
|
/* harmony import */ var _hooks__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./hooks */ "./node_modules/@vue/devtools-api/lib/esm/api/hooks.js");
|
|
/* harmony import */ var _hooks__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_hooks__WEBPACK_IMPORTED_MODULE_4__);
|
|
/* harmony reexport (unknown) */ var __WEBPACK_REEXPORT_OBJECT__ = {};
|
|
/* harmony reexport (unknown) */ for(const __WEBPACK_IMPORT_KEY__ in _hooks__WEBPACK_IMPORTED_MODULE_4__) if(__WEBPACK_IMPORT_KEY__ !== "default") __WEBPACK_REEXPORT_OBJECT__[__WEBPACK_IMPORT_KEY__] = () => _hooks__WEBPACK_IMPORTED_MODULE_4__[__WEBPACK_IMPORT_KEY__]
|
|
/* harmony reexport (unknown) */ __webpack_require__.d(__webpack_exports__, __WEBPACK_REEXPORT_OBJECT__);
|
|
/* harmony import */ var _util__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./util */ "./node_modules/@vue/devtools-api/lib/esm/api/util.js");
|
|
/* harmony import */ var _util__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(_util__WEBPACK_IMPORTED_MODULE_5__);
|
|
/* harmony reexport (unknown) */ var __WEBPACK_REEXPORT_OBJECT__ = {};
|
|
/* harmony reexport (unknown) */ for(const __WEBPACK_IMPORT_KEY__ in _util__WEBPACK_IMPORTED_MODULE_5__) if(__WEBPACK_IMPORT_KEY__ !== "default") __WEBPACK_REEXPORT_OBJECT__[__WEBPACK_IMPORT_KEY__] = () => _util__WEBPACK_IMPORTED_MODULE_5__[__WEBPACK_IMPORT_KEY__]
|
|
/* harmony reexport (unknown) */ __webpack_require__.d(__webpack_exports__, __WEBPACK_REEXPORT_OBJECT__);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/@vue/devtools-api/lib/esm/api/util.js":
|
|
/*!************************************************************!*\
|
|
!*** ./node_modules/@vue/devtools-api/lib/esm/api/util.js ***!
|
|
\************************************************************/
|
|
/***/ (() => {
|
|
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/@vue/devtools-api/lib/esm/const.js":
|
|
/*!*********************************************************!*\
|
|
!*** ./node_modules/@vue/devtools-api/lib/esm/const.js ***!
|
|
\*********************************************************/
|
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ "HOOK_SETUP": () => (/* binding */ HOOK_SETUP)
|
|
/* harmony export */ });
|
|
const HOOK_SETUP = 'devtools-plugin:setup';
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/@vue/devtools-api/lib/esm/env.js":
|
|
/*!*******************************************************!*\
|
|
!*** ./node_modules/@vue/devtools-api/lib/esm/env.js ***!
|
|
\*******************************************************/
|
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ "getDevtoolsGlobalHook": () => (/* binding */ getDevtoolsGlobalHook),
|
|
/* harmony export */ "getTarget": () => (/* binding */ getTarget)
|
|
/* harmony export */ });
|
|
function getDevtoolsGlobalHook() {
|
|
return getTarget().__VUE_DEVTOOLS_GLOBAL_HOOK__;
|
|
}
|
|
function getTarget() {
|
|
// @ts-ignore
|
|
return typeof navigator !== 'undefined'
|
|
? window
|
|
: typeof __webpack_require__.g !== 'undefined'
|
|
? __webpack_require__.g
|
|
: {};
|
|
}
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/@vue/devtools-api/lib/esm/index.js":
|
|
/*!*********************************************************!*\
|
|
!*** ./node_modules/@vue/devtools-api/lib/esm/index.js ***!
|
|
\*********************************************************/
|
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ "setupDevtoolsPlugin": () => (/* binding */ setupDevtoolsPlugin)
|
|
/* harmony export */ });
|
|
/* harmony import */ var _env__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./env */ "./node_modules/@vue/devtools-api/lib/esm/env.js");
|
|
/* harmony import */ var _const__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./const */ "./node_modules/@vue/devtools-api/lib/esm/const.js");
|
|
/* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./api */ "./node_modules/@vue/devtools-api/lib/esm/api/index.js");
|
|
/* harmony reexport (unknown) */ var __WEBPACK_REEXPORT_OBJECT__ = {};
|
|
/* harmony reexport (unknown) */ for(const __WEBPACK_IMPORT_KEY__ in _api__WEBPACK_IMPORTED_MODULE_0__) if(["default","setupDevtoolsPlugin"].indexOf(__WEBPACK_IMPORT_KEY__) < 0) __WEBPACK_REEXPORT_OBJECT__[__WEBPACK_IMPORT_KEY__] = () => _api__WEBPACK_IMPORTED_MODULE_0__[__WEBPACK_IMPORT_KEY__]
|
|
/* harmony reexport (unknown) */ __webpack_require__.d(__webpack_exports__, __WEBPACK_REEXPORT_OBJECT__);
|
|
|
|
|
|
|
|
function setupDevtoolsPlugin(pluginDescriptor, setupFn) {
|
|
const hook = (0,_env__WEBPACK_IMPORTED_MODULE_1__.getDevtoolsGlobalHook)();
|
|
if (hook) {
|
|
hook.emit(_const__WEBPACK_IMPORTED_MODULE_2__.HOOK_SETUP, pluginDescriptor, setupFn);
|
|
}
|
|
else {
|
|
const target = (0,_env__WEBPACK_IMPORTED_MODULE_1__.getTarget)();
|
|
const list = target.__VUE_DEVTOOLS_PLUGINS__ = target.__VUE_DEVTOOLS_PLUGINS__ || [];
|
|
list.push({
|
|
pluginDescriptor,
|
|
setupFn
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/@vue/reactivity/dist/reactivity.esm-bundler.js":
|
|
/*!*********************************************************************!*\
|
|
!*** ./node_modules/@vue/reactivity/dist/reactivity.esm-bundler.js ***!
|
|
\*********************************************************************/
|
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ "EffectScope": () => (/* binding */ EffectScope),
|
|
/* harmony export */ "ITERATE_KEY": () => (/* binding */ ITERATE_KEY),
|
|
/* harmony export */ "ReactiveEffect": () => (/* binding */ ReactiveEffect),
|
|
/* harmony export */ "computed": () => (/* binding */ computed),
|
|
/* harmony export */ "customRef": () => (/* binding */ customRef),
|
|
/* harmony export */ "deferredComputed": () => (/* binding */ deferredComputed),
|
|
/* harmony export */ "effect": () => (/* binding */ effect),
|
|
/* harmony export */ "effectScope": () => (/* binding */ effectScope),
|
|
/* harmony export */ "enableTracking": () => (/* binding */ enableTracking),
|
|
/* harmony export */ "getCurrentScope": () => (/* binding */ getCurrentScope),
|
|
/* harmony export */ "isProxy": () => (/* binding */ isProxy),
|
|
/* harmony export */ "isReactive": () => (/* binding */ isReactive),
|
|
/* harmony export */ "isReadonly": () => (/* binding */ isReadonly),
|
|
/* harmony export */ "isRef": () => (/* binding */ isRef),
|
|
/* harmony export */ "markRaw": () => (/* binding */ markRaw),
|
|
/* harmony export */ "onScopeDispose": () => (/* binding */ onScopeDispose),
|
|
/* harmony export */ "pauseTracking": () => (/* binding */ pauseTracking),
|
|
/* harmony export */ "proxyRefs": () => (/* binding */ proxyRefs),
|
|
/* harmony export */ "reactive": () => (/* binding */ reactive),
|
|
/* harmony export */ "readonly": () => (/* binding */ readonly),
|
|
/* harmony export */ "ref": () => (/* binding */ ref),
|
|
/* harmony export */ "resetTracking": () => (/* binding */ resetTracking),
|
|
/* harmony export */ "shallowReactive": () => (/* binding */ shallowReactive),
|
|
/* harmony export */ "shallowReadonly": () => (/* binding */ shallowReadonly),
|
|
/* harmony export */ "shallowRef": () => (/* binding */ shallowRef),
|
|
/* harmony export */ "stop": () => (/* binding */ stop),
|
|
/* harmony export */ "toRaw": () => (/* binding */ toRaw),
|
|
/* harmony export */ "toRef": () => (/* binding */ toRef),
|
|
/* harmony export */ "toRefs": () => (/* binding */ toRefs),
|
|
/* harmony export */ "track": () => (/* binding */ track),
|
|
/* harmony export */ "trigger": () => (/* binding */ trigger),
|
|
/* harmony export */ "triggerRef": () => (/* binding */ triggerRef),
|
|
/* harmony export */ "unref": () => (/* binding */ unref)
|
|
/* harmony export */ });
|
|
/* harmony import */ var _vue_shared__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @vue/shared */ "./node_modules/@vue/shared/dist/shared.esm-bundler.js");
|
|
|
|
|
|
function warn(msg, ...args) {
|
|
console.warn(`[Vue warn] ${msg}`, ...args);
|
|
}
|
|
|
|
let activeEffectScope;
|
|
const effectScopeStack = [];
|
|
class EffectScope {
|
|
constructor(detached = false) {
|
|
this.active = true;
|
|
this.effects = [];
|
|
this.cleanups = [];
|
|
if (!detached && activeEffectScope) {
|
|
this.parent = activeEffectScope;
|
|
this.index =
|
|
(activeEffectScope.scopes || (activeEffectScope.scopes = [])).push(this) - 1;
|
|
}
|
|
}
|
|
run(fn) {
|
|
if (this.active) {
|
|
try {
|
|
this.on();
|
|
return fn();
|
|
}
|
|
finally {
|
|
this.off();
|
|
}
|
|
}
|
|
else if ((true)) {
|
|
warn(`cannot run an inactive effect scope.`);
|
|
}
|
|
}
|
|
on() {
|
|
if (this.active) {
|
|
effectScopeStack.push(this);
|
|
activeEffectScope = this;
|
|
}
|
|
}
|
|
off() {
|
|
if (this.active) {
|
|
effectScopeStack.pop();
|
|
activeEffectScope = effectScopeStack[effectScopeStack.length - 1];
|
|
}
|
|
}
|
|
stop(fromParent) {
|
|
if (this.active) {
|
|
this.effects.forEach(e => e.stop());
|
|
this.cleanups.forEach(cleanup => cleanup());
|
|
if (this.scopes) {
|
|
this.scopes.forEach(e => e.stop(true));
|
|
}
|
|
// nested scope, dereference from parent to avoid memory leaks
|
|
if (this.parent && !fromParent) {
|
|
// optimized O(1) removal
|
|
const last = this.parent.scopes.pop();
|
|
if (last && last !== this) {
|
|
this.parent.scopes[this.index] = last;
|
|
last.index = this.index;
|
|
}
|
|
}
|
|
this.active = false;
|
|
}
|
|
}
|
|
}
|
|
function effectScope(detached) {
|
|
return new EffectScope(detached);
|
|
}
|
|
function recordEffectScope(effect, scope) {
|
|
scope = scope || activeEffectScope;
|
|
if (scope && scope.active) {
|
|
scope.effects.push(effect);
|
|
}
|
|
}
|
|
function getCurrentScope() {
|
|
return activeEffectScope;
|
|
}
|
|
function onScopeDispose(fn) {
|
|
if (activeEffectScope) {
|
|
activeEffectScope.cleanups.push(fn);
|
|
}
|
|
else if ((true)) {
|
|
warn(`onScopeDispose() is called when there is no active effect scope` +
|
|
` to be associated with.`);
|
|
}
|
|
}
|
|
|
|
const createDep = (effects) => {
|
|
const dep = new Set(effects);
|
|
dep.w = 0;
|
|
dep.n = 0;
|
|
return dep;
|
|
};
|
|
const wasTracked = (dep) => (dep.w & trackOpBit) > 0;
|
|
const newTracked = (dep) => (dep.n & trackOpBit) > 0;
|
|
const initDepMarkers = ({ deps }) => {
|
|
if (deps.length) {
|
|
for (let i = 0; i < deps.length; i++) {
|
|
deps[i].w |= trackOpBit; // set was tracked
|
|
}
|
|
}
|
|
};
|
|
const finalizeDepMarkers = (effect) => {
|
|
const { deps } = effect;
|
|
if (deps.length) {
|
|
let ptr = 0;
|
|
for (let i = 0; i < deps.length; i++) {
|
|
const dep = deps[i];
|
|
if (wasTracked(dep) && !newTracked(dep)) {
|
|
dep.delete(effect);
|
|
}
|
|
else {
|
|
deps[ptr++] = dep;
|
|
}
|
|
// clear bits
|
|
dep.w &= ~trackOpBit;
|
|
dep.n &= ~trackOpBit;
|
|
}
|
|
deps.length = ptr;
|
|
}
|
|
};
|
|
|
|
const targetMap = new WeakMap();
|
|
// The number of effects currently being tracked recursively.
|
|
let effectTrackDepth = 0;
|
|
let trackOpBit = 1;
|
|
/**
|
|
* The bitwise track markers support at most 30 levels op recursion.
|
|
* This value is chosen to enable modern JS engines to use a SMI on all platforms.
|
|
* When recursion depth is greater, fall back to using a full cleanup.
|
|
*/
|
|
const maxMarkerBits = 30;
|
|
const effectStack = [];
|
|
let activeEffect;
|
|
const ITERATE_KEY = Symbol(( true) ? 'iterate' : 0);
|
|
const MAP_KEY_ITERATE_KEY = Symbol(( true) ? 'Map key iterate' : 0);
|
|
class ReactiveEffect {
|
|
constructor(fn, scheduler = null, scope) {
|
|
this.fn = fn;
|
|
this.scheduler = scheduler;
|
|
this.active = true;
|
|
this.deps = [];
|
|
recordEffectScope(this, scope);
|
|
}
|
|
run() {
|
|
if (!this.active) {
|
|
return this.fn();
|
|
}
|
|
if (!effectStack.includes(this)) {
|
|
try {
|
|
effectStack.push((activeEffect = this));
|
|
enableTracking();
|
|
trackOpBit = 1 << ++effectTrackDepth;
|
|
if (effectTrackDepth <= maxMarkerBits) {
|
|
initDepMarkers(this);
|
|
}
|
|
else {
|
|
cleanupEffect(this);
|
|
}
|
|
return this.fn();
|
|
}
|
|
finally {
|
|
if (effectTrackDepth <= maxMarkerBits) {
|
|
finalizeDepMarkers(this);
|
|
}
|
|
trackOpBit = 1 << --effectTrackDepth;
|
|
resetTracking();
|
|
effectStack.pop();
|
|
const n = effectStack.length;
|
|
activeEffect = n > 0 ? effectStack[n - 1] : undefined;
|
|
}
|
|
}
|
|
}
|
|
stop() {
|
|
if (this.active) {
|
|
cleanupEffect(this);
|
|
if (this.onStop) {
|
|
this.onStop();
|
|
}
|
|
this.active = false;
|
|
}
|
|
}
|
|
}
|
|
function cleanupEffect(effect) {
|
|
const { deps } = effect;
|
|
if (deps.length) {
|
|
for (let i = 0; i < deps.length; i++) {
|
|
deps[i].delete(effect);
|
|
}
|
|
deps.length = 0;
|
|
}
|
|
}
|
|
function effect(fn, options) {
|
|
if (fn.effect) {
|
|
fn = fn.effect.fn;
|
|
}
|
|
const _effect = new ReactiveEffect(fn);
|
|
if (options) {
|
|
(0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.extend)(_effect, options);
|
|
if (options.scope)
|
|
recordEffectScope(_effect, options.scope);
|
|
}
|
|
if (!options || !options.lazy) {
|
|
_effect.run();
|
|
}
|
|
const runner = _effect.run.bind(_effect);
|
|
runner.effect = _effect;
|
|
return runner;
|
|
}
|
|
function stop(runner) {
|
|
runner.effect.stop();
|
|
}
|
|
let shouldTrack = true;
|
|
const trackStack = [];
|
|
function pauseTracking() {
|
|
trackStack.push(shouldTrack);
|
|
shouldTrack = false;
|
|
}
|
|
function enableTracking() {
|
|
trackStack.push(shouldTrack);
|
|
shouldTrack = true;
|
|
}
|
|
function resetTracking() {
|
|
const last = trackStack.pop();
|
|
shouldTrack = last === undefined ? true : last;
|
|
}
|
|
function track(target, type, key) {
|
|
if (!isTracking()) {
|
|
return;
|
|
}
|
|
let depsMap = targetMap.get(target);
|
|
if (!depsMap) {
|
|
targetMap.set(target, (depsMap = new Map()));
|
|
}
|
|
let dep = depsMap.get(key);
|
|
if (!dep) {
|
|
depsMap.set(key, (dep = createDep()));
|
|
}
|
|
const eventInfo = ( true)
|
|
? { effect: activeEffect, target, type, key }
|
|
: 0;
|
|
trackEffects(dep, eventInfo);
|
|
}
|
|
function isTracking() {
|
|
return shouldTrack && activeEffect !== undefined;
|
|
}
|
|
function trackEffects(dep, debuggerEventExtraInfo) {
|
|
let shouldTrack = false;
|
|
if (effectTrackDepth <= maxMarkerBits) {
|
|
if (!newTracked(dep)) {
|
|
dep.n |= trackOpBit; // set newly tracked
|
|
shouldTrack = !wasTracked(dep);
|
|
}
|
|
}
|
|
else {
|
|
// Full cleanup mode.
|
|
shouldTrack = !dep.has(activeEffect);
|
|
}
|
|
if (shouldTrack) {
|
|
dep.add(activeEffect);
|
|
activeEffect.deps.push(dep);
|
|
if (( true) && activeEffect.onTrack) {
|
|
activeEffect.onTrack(Object.assign({
|
|
effect: activeEffect
|
|
}, debuggerEventExtraInfo));
|
|
}
|
|
}
|
|
}
|
|
function trigger(target, type, key, newValue, oldValue, oldTarget) {
|
|
const depsMap = targetMap.get(target);
|
|
if (!depsMap) {
|
|
// never been tracked
|
|
return;
|
|
}
|
|
let deps = [];
|
|
if (type === "clear" /* CLEAR */) {
|
|
// collection being cleared
|
|
// trigger all effects for target
|
|
deps = [...depsMap.values()];
|
|
}
|
|
else if (key === 'length' && (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isArray)(target)) {
|
|
depsMap.forEach((dep, key) => {
|
|
if (key === 'length' || key >= newValue) {
|
|
deps.push(dep);
|
|
}
|
|
});
|
|
}
|
|
else {
|
|
// schedule runs for SET | ADD | DELETE
|
|
if (key !== void 0) {
|
|
deps.push(depsMap.get(key));
|
|
}
|
|
// also run for iteration key on ADD | DELETE | Map.SET
|
|
switch (type) {
|
|
case "add" /* ADD */:
|
|
if (!(0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isArray)(target)) {
|
|
deps.push(depsMap.get(ITERATE_KEY));
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isMap)(target)) {
|
|
deps.push(depsMap.get(MAP_KEY_ITERATE_KEY));
|
|
}
|
|
}
|
|
else if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isIntegerKey)(key)) {
|
|
// new index added to array -> length changes
|
|
deps.push(depsMap.get('length'));
|
|
}
|
|
break;
|
|
case "delete" /* DELETE */:
|
|
if (!(0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isArray)(target)) {
|
|
deps.push(depsMap.get(ITERATE_KEY));
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isMap)(target)) {
|
|
deps.push(depsMap.get(MAP_KEY_ITERATE_KEY));
|
|
}
|
|
}
|
|
break;
|
|
case "set" /* SET */:
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isMap)(target)) {
|
|
deps.push(depsMap.get(ITERATE_KEY));
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
const eventInfo = ( true)
|
|
? { target, type, key, newValue, oldValue, oldTarget }
|
|
: 0;
|
|
if (deps.length === 1) {
|
|
if (deps[0]) {
|
|
if ((true)) {
|
|
triggerEffects(deps[0], eventInfo);
|
|
}
|
|
else {}
|
|
}
|
|
}
|
|
else {
|
|
const effects = [];
|
|
for (const dep of deps) {
|
|
if (dep) {
|
|
effects.push(...dep);
|
|
}
|
|
}
|
|
if ((true)) {
|
|
triggerEffects(createDep(effects), eventInfo);
|
|
}
|
|
else {}
|
|
}
|
|
}
|
|
function triggerEffects(dep, debuggerEventExtraInfo) {
|
|
// spread into array for stabilization
|
|
for (const effect of (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isArray)(dep) ? dep : [...dep]) {
|
|
if (effect !== activeEffect || effect.allowRecurse) {
|
|
if (( true) && effect.onTrigger) {
|
|
effect.onTrigger((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.extend)({ effect }, debuggerEventExtraInfo));
|
|
}
|
|
if (effect.scheduler) {
|
|
effect.scheduler();
|
|
}
|
|
else {
|
|
effect.run();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
const isNonTrackableKeys = /*#__PURE__*/ (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.makeMap)(`__proto__,__v_isRef,__isVue`);
|
|
const builtInSymbols = new Set(Object.getOwnPropertyNames(Symbol)
|
|
.map(key => Symbol[key])
|
|
.filter(_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isSymbol));
|
|
const get = /*#__PURE__*/ createGetter();
|
|
const shallowGet = /*#__PURE__*/ createGetter(false, true);
|
|
const readonlyGet = /*#__PURE__*/ createGetter(true);
|
|
const shallowReadonlyGet = /*#__PURE__*/ createGetter(true, true);
|
|
const arrayInstrumentations = /*#__PURE__*/ createArrayInstrumentations();
|
|
function createArrayInstrumentations() {
|
|
const instrumentations = {};
|
|
['includes', 'indexOf', 'lastIndexOf'].forEach(key => {
|
|
instrumentations[key] = function (...args) {
|
|
const arr = toRaw(this);
|
|
for (let i = 0, l = this.length; i < l; i++) {
|
|
track(arr, "get" /* GET */, i + '');
|
|
}
|
|
// we run the method using the original args first (which may be reactive)
|
|
const res = arr[key](...args);
|
|
if (res === -1 || res === false) {
|
|
// if that didn't work, run it again using raw values.
|
|
return arr[key](...args.map(toRaw));
|
|
}
|
|
else {
|
|
return res;
|
|
}
|
|
};
|
|
});
|
|
['push', 'pop', 'shift', 'unshift', 'splice'].forEach(key => {
|
|
instrumentations[key] = function (...args) {
|
|
pauseTracking();
|
|
const res = toRaw(this)[key].apply(this, args);
|
|
resetTracking();
|
|
return res;
|
|
};
|
|
});
|
|
return instrumentations;
|
|
}
|
|
function createGetter(isReadonly = false, shallow = false) {
|
|
return function get(target, key, receiver) {
|
|
if (key === "__v_isReactive" /* IS_REACTIVE */) {
|
|
return !isReadonly;
|
|
}
|
|
else if (key === "__v_isReadonly" /* IS_READONLY */) {
|
|
return isReadonly;
|
|
}
|
|
else if (key === "__v_raw" /* RAW */ &&
|
|
receiver ===
|
|
(isReadonly
|
|
? shallow
|
|
? shallowReadonlyMap
|
|
: readonlyMap
|
|
: shallow
|
|
? shallowReactiveMap
|
|
: reactiveMap).get(target)) {
|
|
return target;
|
|
}
|
|
const targetIsArray = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isArray)(target);
|
|
if (!isReadonly && targetIsArray && (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.hasOwn)(arrayInstrumentations, key)) {
|
|
return Reflect.get(arrayInstrumentations, key, receiver);
|
|
}
|
|
const res = Reflect.get(target, key, receiver);
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isSymbol)(key) ? builtInSymbols.has(key) : isNonTrackableKeys(key)) {
|
|
return res;
|
|
}
|
|
if (!isReadonly) {
|
|
track(target, "get" /* GET */, key);
|
|
}
|
|
if (shallow) {
|
|
return res;
|
|
}
|
|
if (isRef(res)) {
|
|
// ref unwrapping - does not apply for Array + integer key.
|
|
const shouldUnwrap = !targetIsArray || !(0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isIntegerKey)(key);
|
|
return shouldUnwrap ? res.value : res;
|
|
}
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isObject)(res)) {
|
|
// Convert returned value into a proxy as well. we do the isObject check
|
|
// here to avoid invalid value warning. Also need to lazy access readonly
|
|
// and reactive here to avoid circular dependency.
|
|
return isReadonly ? readonly(res) : reactive(res);
|
|
}
|
|
return res;
|
|
};
|
|
}
|
|
const set = /*#__PURE__*/ createSetter();
|
|
const shallowSet = /*#__PURE__*/ createSetter(true);
|
|
function createSetter(shallow = false) {
|
|
return function set(target, key, value, receiver) {
|
|
let oldValue = target[key];
|
|
if (!shallow) {
|
|
value = toRaw(value);
|
|
oldValue = toRaw(oldValue);
|
|
if (!(0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isArray)(target) && isRef(oldValue) && !isRef(value)) {
|
|
oldValue.value = value;
|
|
return true;
|
|
}
|
|
}
|
|
const hadKey = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isArray)(target) && (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isIntegerKey)(key)
|
|
? Number(key) < target.length
|
|
: (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.hasOwn)(target, key);
|
|
const result = Reflect.set(target, key, value, receiver);
|
|
// don't trigger if target is something up in the prototype chain of original
|
|
if (target === toRaw(receiver)) {
|
|
if (!hadKey) {
|
|
trigger(target, "add" /* ADD */, key, value);
|
|
}
|
|
else if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.hasChanged)(value, oldValue)) {
|
|
trigger(target, "set" /* SET */, key, value, oldValue);
|
|
}
|
|
}
|
|
return result;
|
|
};
|
|
}
|
|
function deleteProperty(target, key) {
|
|
const hadKey = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.hasOwn)(target, key);
|
|
const oldValue = target[key];
|
|
const result = Reflect.deleteProperty(target, key);
|
|
if (result && hadKey) {
|
|
trigger(target, "delete" /* DELETE */, key, undefined, oldValue);
|
|
}
|
|
return result;
|
|
}
|
|
function has(target, key) {
|
|
const result = Reflect.has(target, key);
|
|
if (!(0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isSymbol)(key) || !builtInSymbols.has(key)) {
|
|
track(target, "has" /* HAS */, key);
|
|
}
|
|
return result;
|
|
}
|
|
function ownKeys(target) {
|
|
track(target, "iterate" /* ITERATE */, (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isArray)(target) ? 'length' : ITERATE_KEY);
|
|
return Reflect.ownKeys(target);
|
|
}
|
|
const mutableHandlers = {
|
|
get,
|
|
set,
|
|
deleteProperty,
|
|
has,
|
|
ownKeys
|
|
};
|
|
const readonlyHandlers = {
|
|
get: readonlyGet,
|
|
set(target, key) {
|
|
if ((true)) {
|
|
console.warn(`Set operation on key "${String(key)}" failed: target is readonly.`, target);
|
|
}
|
|
return true;
|
|
},
|
|
deleteProperty(target, key) {
|
|
if ((true)) {
|
|
console.warn(`Delete operation on key "${String(key)}" failed: target is readonly.`, target);
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
const shallowReactiveHandlers = /*#__PURE__*/ (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.extend)({}, mutableHandlers, {
|
|
get: shallowGet,
|
|
set: shallowSet
|
|
});
|
|
// Props handlers are special in the sense that it should not unwrap top-level
|
|
// refs (in order to allow refs to be explicitly passed down), but should
|
|
// retain the reactivity of the normal readonly object.
|
|
const shallowReadonlyHandlers = /*#__PURE__*/ (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.extend)({}, readonlyHandlers, {
|
|
get: shallowReadonlyGet
|
|
});
|
|
|
|
const toReactive = (value) => (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isObject)(value) ? reactive(value) : value;
|
|
const toReadonly = (value) => (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isObject)(value) ? readonly(value) : value;
|
|
const toShallow = (value) => value;
|
|
const getProto = (v) => Reflect.getPrototypeOf(v);
|
|
function get$1(target, key, isReadonly = false, isShallow = false) {
|
|
// #1772: readonly(reactive(Map)) should return readonly + reactive version
|
|
// of the value
|
|
target = target["__v_raw" /* RAW */];
|
|
const rawTarget = toRaw(target);
|
|
const rawKey = toRaw(key);
|
|
if (key !== rawKey) {
|
|
!isReadonly && track(rawTarget, "get" /* GET */, key);
|
|
}
|
|
!isReadonly && track(rawTarget, "get" /* GET */, rawKey);
|
|
const { has } = getProto(rawTarget);
|
|
const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive;
|
|
if (has.call(rawTarget, key)) {
|
|
return wrap(target.get(key));
|
|
}
|
|
else if (has.call(rawTarget, rawKey)) {
|
|
return wrap(target.get(rawKey));
|
|
}
|
|
else if (target !== rawTarget) {
|
|
// #3602 readonly(reactive(Map))
|
|
// ensure that the nested reactive `Map` can do tracking for itself
|
|
target.get(key);
|
|
}
|
|
}
|
|
function has$1(key, isReadonly = false) {
|
|
const target = this["__v_raw" /* RAW */];
|
|
const rawTarget = toRaw(target);
|
|
const rawKey = toRaw(key);
|
|
if (key !== rawKey) {
|
|
!isReadonly && track(rawTarget, "has" /* HAS */, key);
|
|
}
|
|
!isReadonly && track(rawTarget, "has" /* HAS */, rawKey);
|
|
return key === rawKey
|
|
? target.has(key)
|
|
: target.has(key) || target.has(rawKey);
|
|
}
|
|
function size(target, isReadonly = false) {
|
|
target = target["__v_raw" /* RAW */];
|
|
!isReadonly && track(toRaw(target), "iterate" /* ITERATE */, ITERATE_KEY);
|
|
return Reflect.get(target, 'size', target);
|
|
}
|
|
function add(value) {
|
|
value = toRaw(value);
|
|
const target = toRaw(this);
|
|
const proto = getProto(target);
|
|
const hadKey = proto.has.call(target, value);
|
|
if (!hadKey) {
|
|
target.add(value);
|
|
trigger(target, "add" /* ADD */, value, value);
|
|
}
|
|
return this;
|
|
}
|
|
function set$1(key, value) {
|
|
value = toRaw(value);
|
|
const target = toRaw(this);
|
|
const { has, get } = getProto(target);
|
|
let hadKey = has.call(target, key);
|
|
if (!hadKey) {
|
|
key = toRaw(key);
|
|
hadKey = has.call(target, key);
|
|
}
|
|
else if ((true)) {
|
|
checkIdentityKeys(target, has, key);
|
|
}
|
|
const oldValue = get.call(target, key);
|
|
target.set(key, value);
|
|
if (!hadKey) {
|
|
trigger(target, "add" /* ADD */, key, value);
|
|
}
|
|
else if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.hasChanged)(value, oldValue)) {
|
|
trigger(target, "set" /* SET */, key, value, oldValue);
|
|
}
|
|
return this;
|
|
}
|
|
function deleteEntry(key) {
|
|
const target = toRaw(this);
|
|
const { has, get } = getProto(target);
|
|
let hadKey = has.call(target, key);
|
|
if (!hadKey) {
|
|
key = toRaw(key);
|
|
hadKey = has.call(target, key);
|
|
}
|
|
else if ((true)) {
|
|
checkIdentityKeys(target, has, key);
|
|
}
|
|
const oldValue = get ? get.call(target, key) : undefined;
|
|
// forward the operation before queueing reactions
|
|
const result = target.delete(key);
|
|
if (hadKey) {
|
|
trigger(target, "delete" /* DELETE */, key, undefined, oldValue);
|
|
}
|
|
return result;
|
|
}
|
|
function clear() {
|
|
const target = toRaw(this);
|
|
const hadItems = target.size !== 0;
|
|
const oldTarget = ( true)
|
|
? (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isMap)(target)
|
|
? new Map(target)
|
|
: new Set(target)
|
|
: 0;
|
|
// forward the operation before queueing reactions
|
|
const result = target.clear();
|
|
if (hadItems) {
|
|
trigger(target, "clear" /* CLEAR */, undefined, undefined, oldTarget);
|
|
}
|
|
return result;
|
|
}
|
|
function createForEach(isReadonly, isShallow) {
|
|
return function forEach(callback, thisArg) {
|
|
const observed = this;
|
|
const target = observed["__v_raw" /* RAW */];
|
|
const rawTarget = toRaw(target);
|
|
const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive;
|
|
!isReadonly && track(rawTarget, "iterate" /* ITERATE */, ITERATE_KEY);
|
|
return target.forEach((value, key) => {
|
|
// important: make sure the callback is
|
|
// 1. invoked with the reactive map as `this` and 3rd arg
|
|
// 2. the value received should be a corresponding reactive/readonly.
|
|
return callback.call(thisArg, wrap(value), wrap(key), observed);
|
|
});
|
|
};
|
|
}
|
|
function createIterableMethod(method, isReadonly, isShallow) {
|
|
return function (...args) {
|
|
const target = this["__v_raw" /* RAW */];
|
|
const rawTarget = toRaw(target);
|
|
const targetIsMap = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isMap)(rawTarget);
|
|
const isPair = method === 'entries' || (method === Symbol.iterator && targetIsMap);
|
|
const isKeyOnly = method === 'keys' && targetIsMap;
|
|
const innerIterator = target[method](...args);
|
|
const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive;
|
|
!isReadonly &&
|
|
track(rawTarget, "iterate" /* ITERATE */, isKeyOnly ? MAP_KEY_ITERATE_KEY : ITERATE_KEY);
|
|
// return a wrapped iterator which returns observed versions of the
|
|
// values emitted from the real iterator
|
|
return {
|
|
// iterator protocol
|
|
next() {
|
|
const { value, done } = innerIterator.next();
|
|
return done
|
|
? { value, done }
|
|
: {
|
|
value: isPair ? [wrap(value[0]), wrap(value[1])] : wrap(value),
|
|
done
|
|
};
|
|
},
|
|
// iterable protocol
|
|
[Symbol.iterator]() {
|
|
return this;
|
|
}
|
|
};
|
|
};
|
|
}
|
|
function createReadonlyMethod(type) {
|
|
return function (...args) {
|
|
if ((true)) {
|
|
const key = args[0] ? `on key "${args[0]}" ` : ``;
|
|
console.warn(`${(0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.capitalize)(type)} operation ${key}failed: target is readonly.`, toRaw(this));
|
|
}
|
|
return type === "delete" /* DELETE */ ? false : this;
|
|
};
|
|
}
|
|
function createInstrumentations() {
|
|
const mutableInstrumentations = {
|
|
get(key) {
|
|
return get$1(this, key);
|
|
},
|
|
get size() {
|
|
return size(this);
|
|
},
|
|
has: has$1,
|
|
add,
|
|
set: set$1,
|
|
delete: deleteEntry,
|
|
clear,
|
|
forEach: createForEach(false, false)
|
|
};
|
|
const shallowInstrumentations = {
|
|
get(key) {
|
|
return get$1(this, key, false, true);
|
|
},
|
|
get size() {
|
|
return size(this);
|
|
},
|
|
has: has$1,
|
|
add,
|
|
set: set$1,
|
|
delete: deleteEntry,
|
|
clear,
|
|
forEach: createForEach(false, true)
|
|
};
|
|
const readonlyInstrumentations = {
|
|
get(key) {
|
|
return get$1(this, key, true);
|
|
},
|
|
get size() {
|
|
return size(this, true);
|
|
},
|
|
has(key) {
|
|
return has$1.call(this, key, true);
|
|
},
|
|
add: createReadonlyMethod("add" /* ADD */),
|
|
set: createReadonlyMethod("set" /* SET */),
|
|
delete: createReadonlyMethod("delete" /* DELETE */),
|
|
clear: createReadonlyMethod("clear" /* CLEAR */),
|
|
forEach: createForEach(true, false)
|
|
};
|
|
const shallowReadonlyInstrumentations = {
|
|
get(key) {
|
|
return get$1(this, key, true, true);
|
|
},
|
|
get size() {
|
|
return size(this, true);
|
|
},
|
|
has(key) {
|
|
return has$1.call(this, key, true);
|
|
},
|
|
add: createReadonlyMethod("add" /* ADD */),
|
|
set: createReadonlyMethod("set" /* SET */),
|
|
delete: createReadonlyMethod("delete" /* DELETE */),
|
|
clear: createReadonlyMethod("clear" /* CLEAR */),
|
|
forEach: createForEach(true, true)
|
|
};
|
|
const iteratorMethods = ['keys', 'values', 'entries', Symbol.iterator];
|
|
iteratorMethods.forEach(method => {
|
|
mutableInstrumentations[method] = createIterableMethod(method, false, false);
|
|
readonlyInstrumentations[method] = createIterableMethod(method, true, false);
|
|
shallowInstrumentations[method] = createIterableMethod(method, false, true);
|
|
shallowReadonlyInstrumentations[method] = createIterableMethod(method, true, true);
|
|
});
|
|
return [
|
|
mutableInstrumentations,
|
|
readonlyInstrumentations,
|
|
shallowInstrumentations,
|
|
shallowReadonlyInstrumentations
|
|
];
|
|
}
|
|
const [mutableInstrumentations, readonlyInstrumentations, shallowInstrumentations, shallowReadonlyInstrumentations] = /* #__PURE__*/ createInstrumentations();
|
|
function createInstrumentationGetter(isReadonly, shallow) {
|
|
const instrumentations = shallow
|
|
? isReadonly
|
|
? shallowReadonlyInstrumentations
|
|
: shallowInstrumentations
|
|
: isReadonly
|
|
? readonlyInstrumentations
|
|
: mutableInstrumentations;
|
|
return (target, key, receiver) => {
|
|
if (key === "__v_isReactive" /* IS_REACTIVE */) {
|
|
return !isReadonly;
|
|
}
|
|
else if (key === "__v_isReadonly" /* IS_READONLY */) {
|
|
return isReadonly;
|
|
}
|
|
else if (key === "__v_raw" /* RAW */) {
|
|
return target;
|
|
}
|
|
return Reflect.get((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.hasOwn)(instrumentations, key) && key in target
|
|
? instrumentations
|
|
: target, key, receiver);
|
|
};
|
|
}
|
|
const mutableCollectionHandlers = {
|
|
get: /*#__PURE__*/ createInstrumentationGetter(false, false)
|
|
};
|
|
const shallowCollectionHandlers = {
|
|
get: /*#__PURE__*/ createInstrumentationGetter(false, true)
|
|
};
|
|
const readonlyCollectionHandlers = {
|
|
get: /*#__PURE__*/ createInstrumentationGetter(true, false)
|
|
};
|
|
const shallowReadonlyCollectionHandlers = {
|
|
get: /*#__PURE__*/ createInstrumentationGetter(true, true)
|
|
};
|
|
function checkIdentityKeys(target, has, key) {
|
|
const rawKey = toRaw(key);
|
|
if (rawKey !== key && has.call(target, rawKey)) {
|
|
const type = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.toRawType)(target);
|
|
console.warn(`Reactive ${type} contains both the raw and reactive ` +
|
|
`versions of the same object${type === `Map` ? ` as keys` : ``}, ` +
|
|
`which can lead to inconsistencies. ` +
|
|
`Avoid differentiating between the raw and reactive versions ` +
|
|
`of an object and only use the reactive version if possible.`);
|
|
}
|
|
}
|
|
|
|
const reactiveMap = new WeakMap();
|
|
const shallowReactiveMap = new WeakMap();
|
|
const readonlyMap = new WeakMap();
|
|
const shallowReadonlyMap = new WeakMap();
|
|
function targetTypeMap(rawType) {
|
|
switch (rawType) {
|
|
case 'Object':
|
|
case 'Array':
|
|
return 1 /* COMMON */;
|
|
case 'Map':
|
|
case 'Set':
|
|
case 'WeakMap':
|
|
case 'WeakSet':
|
|
return 2 /* COLLECTION */;
|
|
default:
|
|
return 0 /* INVALID */;
|
|
}
|
|
}
|
|
function getTargetType(value) {
|
|
return value["__v_skip" /* SKIP */] || !Object.isExtensible(value)
|
|
? 0 /* INVALID */
|
|
: targetTypeMap((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.toRawType)(value));
|
|
}
|
|
function reactive(target) {
|
|
// if trying to observe a readonly proxy, return the readonly version.
|
|
if (target && target["__v_isReadonly" /* IS_READONLY */]) {
|
|
return target;
|
|
}
|
|
return createReactiveObject(target, false, mutableHandlers, mutableCollectionHandlers, reactiveMap);
|
|
}
|
|
/**
|
|
* Return a shallowly-reactive copy of the original object, where only the root
|
|
* level properties are reactive. It also does not auto-unwrap refs (even at the
|
|
* root level).
|
|
*/
|
|
function shallowReactive(target) {
|
|
return createReactiveObject(target, false, shallowReactiveHandlers, shallowCollectionHandlers, shallowReactiveMap);
|
|
}
|
|
/**
|
|
* Creates a readonly copy of the original object. Note the returned copy is not
|
|
* made reactive, but `readonly` can be called on an already reactive object.
|
|
*/
|
|
function readonly(target) {
|
|
return createReactiveObject(target, true, readonlyHandlers, readonlyCollectionHandlers, readonlyMap);
|
|
}
|
|
/**
|
|
* Returns a reactive-copy of the original object, where only the root level
|
|
* properties are readonly, and does NOT unwrap refs nor recursively convert
|
|
* returned properties.
|
|
* This is used for creating the props proxy object for stateful components.
|
|
*/
|
|
function shallowReadonly(target) {
|
|
return createReactiveObject(target, true, shallowReadonlyHandlers, shallowReadonlyCollectionHandlers, shallowReadonlyMap);
|
|
}
|
|
function createReactiveObject(target, isReadonly, baseHandlers, collectionHandlers, proxyMap) {
|
|
if (!(0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isObject)(target)) {
|
|
if ((true)) {
|
|
console.warn(`value cannot be made reactive: ${String(target)}`);
|
|
}
|
|
return target;
|
|
}
|
|
// target is already a Proxy, return it.
|
|
// exception: calling readonly() on a reactive object
|
|
if (target["__v_raw" /* RAW */] &&
|
|
!(isReadonly && target["__v_isReactive" /* IS_REACTIVE */])) {
|
|
return target;
|
|
}
|
|
// target already has corresponding Proxy
|
|
const existingProxy = proxyMap.get(target);
|
|
if (existingProxy) {
|
|
return existingProxy;
|
|
}
|
|
// only a whitelist of value types can be observed.
|
|
const targetType = getTargetType(target);
|
|
if (targetType === 0 /* INVALID */) {
|
|
return target;
|
|
}
|
|
const proxy = new Proxy(target, targetType === 2 /* COLLECTION */ ? collectionHandlers : baseHandlers);
|
|
proxyMap.set(target, proxy);
|
|
return proxy;
|
|
}
|
|
function isReactive(value) {
|
|
if (isReadonly(value)) {
|
|
return isReactive(value["__v_raw" /* RAW */]);
|
|
}
|
|
return !!(value && value["__v_isReactive" /* IS_REACTIVE */]);
|
|
}
|
|
function isReadonly(value) {
|
|
return !!(value && value["__v_isReadonly" /* IS_READONLY */]);
|
|
}
|
|
function isProxy(value) {
|
|
return isReactive(value) || isReadonly(value);
|
|
}
|
|
function toRaw(observed) {
|
|
const raw = observed && observed["__v_raw" /* RAW */];
|
|
return raw ? toRaw(raw) : observed;
|
|
}
|
|
function markRaw(value) {
|
|
(0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.def)(value, "__v_skip" /* SKIP */, true);
|
|
return value;
|
|
}
|
|
|
|
function trackRefValue(ref) {
|
|
if (isTracking()) {
|
|
ref = toRaw(ref);
|
|
if (!ref.dep) {
|
|
ref.dep = createDep();
|
|
}
|
|
if ((true)) {
|
|
trackEffects(ref.dep, {
|
|
target: ref,
|
|
type: "get" /* GET */,
|
|
key: 'value'
|
|
});
|
|
}
|
|
else {}
|
|
}
|
|
}
|
|
function triggerRefValue(ref, newVal) {
|
|
ref = toRaw(ref);
|
|
if (ref.dep) {
|
|
if ((true)) {
|
|
triggerEffects(ref.dep, {
|
|
target: ref,
|
|
type: "set" /* SET */,
|
|
key: 'value',
|
|
newValue: newVal
|
|
});
|
|
}
|
|
else {}
|
|
}
|
|
}
|
|
const convert = (val) => (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isObject)(val) ? reactive(val) : val;
|
|
function isRef(r) {
|
|
return Boolean(r && r.__v_isRef === true);
|
|
}
|
|
function ref(value) {
|
|
return createRef(value, false);
|
|
}
|
|
function shallowRef(value) {
|
|
return createRef(value, true);
|
|
}
|
|
class RefImpl {
|
|
constructor(value, _shallow) {
|
|
this._shallow = _shallow;
|
|
this.dep = undefined;
|
|
this.__v_isRef = true;
|
|
this._rawValue = _shallow ? value : toRaw(value);
|
|
this._value = _shallow ? value : convert(value);
|
|
}
|
|
get value() {
|
|
trackRefValue(this);
|
|
return this._value;
|
|
}
|
|
set value(newVal) {
|
|
newVal = this._shallow ? newVal : toRaw(newVal);
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.hasChanged)(newVal, this._rawValue)) {
|
|
this._rawValue = newVal;
|
|
this._value = this._shallow ? newVal : convert(newVal);
|
|
triggerRefValue(this, newVal);
|
|
}
|
|
}
|
|
}
|
|
function createRef(rawValue, shallow) {
|
|
if (isRef(rawValue)) {
|
|
return rawValue;
|
|
}
|
|
return new RefImpl(rawValue, shallow);
|
|
}
|
|
function triggerRef(ref) {
|
|
triggerRefValue(ref, ( true) ? ref.value : 0);
|
|
}
|
|
function unref(ref) {
|
|
return isRef(ref) ? ref.value : ref;
|
|
}
|
|
const shallowUnwrapHandlers = {
|
|
get: (target, key, receiver) => unref(Reflect.get(target, key, receiver)),
|
|
set: (target, key, value, receiver) => {
|
|
const oldValue = target[key];
|
|
if (isRef(oldValue) && !isRef(value)) {
|
|
oldValue.value = value;
|
|
return true;
|
|
}
|
|
else {
|
|
return Reflect.set(target, key, value, receiver);
|
|
}
|
|
}
|
|
};
|
|
function proxyRefs(objectWithRefs) {
|
|
return isReactive(objectWithRefs)
|
|
? objectWithRefs
|
|
: new Proxy(objectWithRefs, shallowUnwrapHandlers);
|
|
}
|
|
class CustomRefImpl {
|
|
constructor(factory) {
|
|
this.dep = undefined;
|
|
this.__v_isRef = true;
|
|
const { get, set } = factory(() => trackRefValue(this), () => triggerRefValue(this));
|
|
this._get = get;
|
|
this._set = set;
|
|
}
|
|
get value() {
|
|
return this._get();
|
|
}
|
|
set value(newVal) {
|
|
this._set(newVal);
|
|
}
|
|
}
|
|
function customRef(factory) {
|
|
return new CustomRefImpl(factory);
|
|
}
|
|
function toRefs(object) {
|
|
if (( true) && !isProxy(object)) {
|
|
console.warn(`toRefs() expects a reactive object but received a plain one.`);
|
|
}
|
|
const ret = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isArray)(object) ? new Array(object.length) : {};
|
|
for (const key in object) {
|
|
ret[key] = toRef(object, key);
|
|
}
|
|
return ret;
|
|
}
|
|
class ObjectRefImpl {
|
|
constructor(_object, _key) {
|
|
this._object = _object;
|
|
this._key = _key;
|
|
this.__v_isRef = true;
|
|
}
|
|
get value() {
|
|
return this._object[this._key];
|
|
}
|
|
set value(newVal) {
|
|
this._object[this._key] = newVal;
|
|
}
|
|
}
|
|
function toRef(object, key) {
|
|
const val = object[key];
|
|
return isRef(val) ? val : new ObjectRefImpl(object, key);
|
|
}
|
|
|
|
class ComputedRefImpl {
|
|
constructor(getter, _setter, isReadonly) {
|
|
this._setter = _setter;
|
|
this.dep = undefined;
|
|
this._dirty = true;
|
|
this.__v_isRef = true;
|
|
this.effect = new ReactiveEffect(getter, () => {
|
|
if (!this._dirty) {
|
|
this._dirty = true;
|
|
triggerRefValue(this);
|
|
}
|
|
});
|
|
this["__v_isReadonly" /* IS_READONLY */] = isReadonly;
|
|
}
|
|
get value() {
|
|
// the computed ref may get wrapped by other proxies e.g. readonly() #3376
|
|
const self = toRaw(this);
|
|
trackRefValue(self);
|
|
if (self._dirty) {
|
|
self._dirty = false;
|
|
self._value = self.effect.run();
|
|
}
|
|
return self._value;
|
|
}
|
|
set value(newValue) {
|
|
this._setter(newValue);
|
|
}
|
|
}
|
|
function computed(getterOrOptions, debugOptions) {
|
|
let getter;
|
|
let setter;
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isFunction)(getterOrOptions)) {
|
|
getter = getterOrOptions;
|
|
setter = ( true)
|
|
? () => {
|
|
console.warn('Write operation failed: computed value is readonly');
|
|
}
|
|
: 0;
|
|
}
|
|
else {
|
|
getter = getterOrOptions.get;
|
|
setter = getterOrOptions.set;
|
|
}
|
|
const cRef = new ComputedRefImpl(getter, setter, (0,_vue_shared__WEBPACK_IMPORTED_MODULE_0__.isFunction)(getterOrOptions) || !getterOrOptions.set);
|
|
if (( true) && debugOptions) {
|
|
cRef.effect.onTrack = debugOptions.onTrack;
|
|
cRef.effect.onTrigger = debugOptions.onTrigger;
|
|
}
|
|
return cRef;
|
|
}
|
|
|
|
var _a;
|
|
const tick = Promise.resolve();
|
|
const queue = [];
|
|
let queued = false;
|
|
const scheduler = (fn) => {
|
|
queue.push(fn);
|
|
if (!queued) {
|
|
queued = true;
|
|
tick.then(flush);
|
|
}
|
|
};
|
|
const flush = () => {
|
|
for (let i = 0; i < queue.length; i++) {
|
|
queue[i]();
|
|
}
|
|
queue.length = 0;
|
|
queued = false;
|
|
};
|
|
class DeferredComputedRefImpl {
|
|
constructor(getter) {
|
|
this.dep = undefined;
|
|
this._dirty = true;
|
|
this.__v_isRef = true;
|
|
this[_a] = true;
|
|
let compareTarget;
|
|
let hasCompareTarget = false;
|
|
let scheduled = false;
|
|
this.effect = new ReactiveEffect(getter, (computedTrigger) => {
|
|
if (this.dep) {
|
|
if (computedTrigger) {
|
|
compareTarget = this._value;
|
|
hasCompareTarget = true;
|
|
}
|
|
else if (!scheduled) {
|
|
const valueToCompare = hasCompareTarget ? compareTarget : this._value;
|
|
scheduled = true;
|
|
hasCompareTarget = false;
|
|
scheduler(() => {
|
|
if (this.effect.active && this._get() !== valueToCompare) {
|
|
triggerRefValue(this);
|
|
}
|
|
scheduled = false;
|
|
});
|
|
}
|
|
// chained upstream computeds are notified synchronously to ensure
|
|
// value invalidation in case of sync access; normal effects are
|
|
// deferred to be triggered in scheduler.
|
|
for (const e of this.dep) {
|
|
if (e.computed) {
|
|
e.scheduler(true /* computedTrigger */);
|
|
}
|
|
}
|
|
}
|
|
this._dirty = true;
|
|
});
|
|
this.effect.computed = true;
|
|
}
|
|
_get() {
|
|
if (this._dirty) {
|
|
this._dirty = false;
|
|
return (this._value = this.effect.run());
|
|
}
|
|
return this._value;
|
|
}
|
|
get value() {
|
|
trackRefValue(this);
|
|
// the computed ref may get wrapped by other proxies e.g. readonly() #3376
|
|
return toRaw(this)._get();
|
|
}
|
|
}
|
|
_a = "__v_isReadonly" /* IS_READONLY */;
|
|
function deferredComputed(getter) {
|
|
return new DeferredComputedRefImpl(getter);
|
|
}
|
|
|
|
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js":
|
|
/*!*************************************************************************!*\
|
|
!*** ./node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js ***!
|
|
\*************************************************************************/
|
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ "EffectScope": () => (/* reexport safe */ _vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.EffectScope),
|
|
/* harmony export */ "ReactiveEffect": () => (/* reexport safe */ _vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.ReactiveEffect),
|
|
/* harmony export */ "computed": () => (/* reexport safe */ _vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.computed),
|
|
/* harmony export */ "customRef": () => (/* reexport safe */ _vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.customRef),
|
|
/* harmony export */ "effect": () => (/* reexport safe */ _vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.effect),
|
|
/* harmony export */ "effectScope": () => (/* reexport safe */ _vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.effectScope),
|
|
/* harmony export */ "getCurrentScope": () => (/* reexport safe */ _vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.getCurrentScope),
|
|
/* harmony export */ "isProxy": () => (/* reexport safe */ _vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.isProxy),
|
|
/* harmony export */ "isReactive": () => (/* reexport safe */ _vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.isReactive),
|
|
/* harmony export */ "isReadonly": () => (/* reexport safe */ _vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.isReadonly),
|
|
/* harmony export */ "isRef": () => (/* reexport safe */ _vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.isRef),
|
|
/* harmony export */ "markRaw": () => (/* reexport safe */ _vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.markRaw),
|
|
/* harmony export */ "onScopeDispose": () => (/* reexport safe */ _vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.onScopeDispose),
|
|
/* harmony export */ "proxyRefs": () => (/* reexport safe */ _vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.proxyRefs),
|
|
/* harmony export */ "reactive": () => (/* reexport safe */ _vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.reactive),
|
|
/* harmony export */ "readonly": () => (/* reexport safe */ _vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.readonly),
|
|
/* harmony export */ "ref": () => (/* reexport safe */ _vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.ref),
|
|
/* harmony export */ "shallowReactive": () => (/* reexport safe */ _vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.shallowReactive),
|
|
/* harmony export */ "shallowReadonly": () => (/* reexport safe */ _vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.shallowReadonly),
|
|
/* harmony export */ "shallowRef": () => (/* reexport safe */ _vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.shallowRef),
|
|
/* harmony export */ "stop": () => (/* reexport safe */ _vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.stop),
|
|
/* harmony export */ "toRaw": () => (/* reexport safe */ _vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.toRaw),
|
|
/* harmony export */ "toRef": () => (/* reexport safe */ _vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.toRef),
|
|
/* harmony export */ "toRefs": () => (/* reexport safe */ _vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.toRefs),
|
|
/* harmony export */ "triggerRef": () => (/* reexport safe */ _vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.triggerRef),
|
|
/* harmony export */ "unref": () => (/* reexport safe */ _vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.unref),
|
|
/* harmony export */ "camelize": () => (/* reexport safe */ _vue_shared__WEBPACK_IMPORTED_MODULE_1__.camelize),
|
|
/* harmony export */ "capitalize": () => (/* reexport safe */ _vue_shared__WEBPACK_IMPORTED_MODULE_1__.capitalize),
|
|
/* harmony export */ "normalizeClass": () => (/* reexport safe */ _vue_shared__WEBPACK_IMPORTED_MODULE_1__.normalizeClass),
|
|
/* harmony export */ "normalizeProps": () => (/* reexport safe */ _vue_shared__WEBPACK_IMPORTED_MODULE_1__.normalizeProps),
|
|
/* harmony export */ "normalizeStyle": () => (/* reexport safe */ _vue_shared__WEBPACK_IMPORTED_MODULE_1__.normalizeStyle),
|
|
/* harmony export */ "toDisplayString": () => (/* reexport safe */ _vue_shared__WEBPACK_IMPORTED_MODULE_1__.toDisplayString),
|
|
/* harmony export */ "toHandlerKey": () => (/* reexport safe */ _vue_shared__WEBPACK_IMPORTED_MODULE_1__.toHandlerKey),
|
|
/* harmony export */ "BaseTransition": () => (/* binding */ BaseTransition),
|
|
/* harmony export */ "Comment": () => (/* binding */ Comment$1),
|
|
/* harmony export */ "Fragment": () => (/* binding */ Fragment),
|
|
/* harmony export */ "KeepAlive": () => (/* binding */ KeepAlive),
|
|
/* harmony export */ "Static": () => (/* binding */ Static),
|
|
/* harmony export */ "Suspense": () => (/* binding */ Suspense),
|
|
/* harmony export */ "Teleport": () => (/* binding */ Teleport),
|
|
/* harmony export */ "Text": () => (/* binding */ Text),
|
|
/* harmony export */ "callWithAsyncErrorHandling": () => (/* binding */ callWithAsyncErrorHandling),
|
|
/* harmony export */ "callWithErrorHandling": () => (/* binding */ callWithErrorHandling),
|
|
/* harmony export */ "cloneVNode": () => (/* binding */ cloneVNode),
|
|
/* harmony export */ "compatUtils": () => (/* binding */ compatUtils),
|
|
/* harmony export */ "createBlock": () => (/* binding */ createBlock),
|
|
/* harmony export */ "createCommentVNode": () => (/* binding */ createCommentVNode),
|
|
/* harmony export */ "createElementBlock": () => (/* binding */ createElementBlock),
|
|
/* harmony export */ "createElementVNode": () => (/* binding */ createBaseVNode),
|
|
/* harmony export */ "createHydrationRenderer": () => (/* binding */ createHydrationRenderer),
|
|
/* harmony export */ "createRenderer": () => (/* binding */ createRenderer),
|
|
/* harmony export */ "createSlots": () => (/* binding */ createSlots),
|
|
/* harmony export */ "createStaticVNode": () => (/* binding */ createStaticVNode),
|
|
/* harmony export */ "createTextVNode": () => (/* binding */ createTextVNode),
|
|
/* harmony export */ "createVNode": () => (/* binding */ createVNode),
|
|
/* harmony export */ "defineAsyncComponent": () => (/* binding */ defineAsyncComponent),
|
|
/* harmony export */ "defineComponent": () => (/* binding */ defineComponent),
|
|
/* harmony export */ "defineEmits": () => (/* binding */ defineEmits),
|
|
/* harmony export */ "defineExpose": () => (/* binding */ defineExpose),
|
|
/* harmony export */ "defineProps": () => (/* binding */ defineProps),
|
|
/* harmony export */ "devtools": () => (/* binding */ devtools),
|
|
/* harmony export */ "getCurrentInstance": () => (/* binding */ getCurrentInstance),
|
|
/* harmony export */ "getTransitionRawChildren": () => (/* binding */ getTransitionRawChildren),
|
|
/* harmony export */ "guardReactiveProps": () => (/* binding */ guardReactiveProps),
|
|
/* harmony export */ "h": () => (/* binding */ h),
|
|
/* harmony export */ "handleError": () => (/* binding */ handleError),
|
|
/* harmony export */ "initCustomFormatter": () => (/* binding */ initCustomFormatter),
|
|
/* harmony export */ "inject": () => (/* binding */ inject),
|
|
/* harmony export */ "isMemoSame": () => (/* binding */ isMemoSame),
|
|
/* harmony export */ "isRuntimeOnly": () => (/* binding */ isRuntimeOnly),
|
|
/* harmony export */ "isVNode": () => (/* binding */ isVNode),
|
|
/* harmony export */ "mergeDefaults": () => (/* binding */ mergeDefaults),
|
|
/* harmony export */ "mergeProps": () => (/* binding */ mergeProps),
|
|
/* harmony export */ "nextTick": () => (/* binding */ nextTick),
|
|
/* harmony export */ "onActivated": () => (/* binding */ onActivated),
|
|
/* harmony export */ "onBeforeMount": () => (/* binding */ onBeforeMount),
|
|
/* harmony export */ "onBeforeUnmount": () => (/* binding */ onBeforeUnmount),
|
|
/* harmony export */ "onBeforeUpdate": () => (/* binding */ onBeforeUpdate),
|
|
/* harmony export */ "onDeactivated": () => (/* binding */ onDeactivated),
|
|
/* harmony export */ "onErrorCaptured": () => (/* binding */ onErrorCaptured),
|
|
/* harmony export */ "onMounted": () => (/* binding */ onMounted),
|
|
/* harmony export */ "onRenderTracked": () => (/* binding */ onRenderTracked),
|
|
/* harmony export */ "onRenderTriggered": () => (/* binding */ onRenderTriggered),
|
|
/* harmony export */ "onServerPrefetch": () => (/* binding */ onServerPrefetch),
|
|
/* harmony export */ "onUnmounted": () => (/* binding */ onUnmounted),
|
|
/* harmony export */ "onUpdated": () => (/* binding */ onUpdated),
|
|
/* harmony export */ "openBlock": () => (/* binding */ openBlock),
|
|
/* harmony export */ "popScopeId": () => (/* binding */ popScopeId),
|
|
/* harmony export */ "provide": () => (/* binding */ provide),
|
|
/* harmony export */ "pushScopeId": () => (/* binding */ pushScopeId),
|
|
/* harmony export */ "queuePostFlushCb": () => (/* binding */ queuePostFlushCb),
|
|
/* harmony export */ "registerRuntimeCompiler": () => (/* binding */ registerRuntimeCompiler),
|
|
/* harmony export */ "renderList": () => (/* binding */ renderList),
|
|
/* harmony export */ "renderSlot": () => (/* binding */ renderSlot),
|
|
/* harmony export */ "resolveComponent": () => (/* binding */ resolveComponent),
|
|
/* harmony export */ "resolveDirective": () => (/* binding */ resolveDirective),
|
|
/* harmony export */ "resolveDynamicComponent": () => (/* binding */ resolveDynamicComponent),
|
|
/* harmony export */ "resolveFilter": () => (/* binding */ resolveFilter),
|
|
/* harmony export */ "resolveTransitionHooks": () => (/* binding */ resolveTransitionHooks),
|
|
/* harmony export */ "setBlockTracking": () => (/* binding */ setBlockTracking),
|
|
/* harmony export */ "setDevtoolsHook": () => (/* binding */ setDevtoolsHook),
|
|
/* harmony export */ "setTransitionHooks": () => (/* binding */ setTransitionHooks),
|
|
/* harmony export */ "ssrContextKey": () => (/* binding */ ssrContextKey),
|
|
/* harmony export */ "ssrUtils": () => (/* binding */ ssrUtils),
|
|
/* harmony export */ "toHandlers": () => (/* binding */ toHandlers),
|
|
/* harmony export */ "transformVNodeArgs": () => (/* binding */ transformVNodeArgs),
|
|
/* harmony export */ "useAttrs": () => (/* binding */ useAttrs),
|
|
/* harmony export */ "useSSRContext": () => (/* binding */ useSSRContext),
|
|
/* harmony export */ "useSlots": () => (/* binding */ useSlots),
|
|
/* harmony export */ "useTransitionState": () => (/* binding */ useTransitionState),
|
|
/* harmony export */ "version": () => (/* binding */ version),
|
|
/* harmony export */ "warn": () => (/* binding */ warn),
|
|
/* harmony export */ "watch": () => (/* binding */ watch),
|
|
/* harmony export */ "watchEffect": () => (/* binding */ watchEffect),
|
|
/* harmony export */ "watchPostEffect": () => (/* binding */ watchPostEffect),
|
|
/* harmony export */ "watchSyncEffect": () => (/* binding */ watchSyncEffect),
|
|
/* harmony export */ "withAsyncContext": () => (/* binding */ withAsyncContext),
|
|
/* harmony export */ "withCtx": () => (/* binding */ withCtx),
|
|
/* harmony export */ "withDefaults": () => (/* binding */ withDefaults),
|
|
/* harmony export */ "withDirectives": () => (/* binding */ withDirectives),
|
|
/* harmony export */ "withMemo": () => (/* binding */ withMemo),
|
|
/* harmony export */ "withScopeId": () => (/* binding */ withScopeId)
|
|
/* harmony export */ });
|
|
/* harmony import */ var _vue_reactivity__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @vue/reactivity */ "./node_modules/@vue/reactivity/dist/reactivity.esm-bundler.js");
|
|
/* harmony import */ var _vue_shared__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @vue/shared */ "./node_modules/@vue/shared/dist/shared.esm-bundler.js");
|
|
|
|
|
|
|
|
|
|
|
|
/* eslint-disable no-restricted-globals */
|
|
let isHmrUpdating = false;
|
|
const hmrDirtyComponents = new Set();
|
|
// Expose the HMR runtime on the global object
|
|
// This makes it entirely tree-shakable without polluting the exports and makes
|
|
// it easier to be used in toolings like vue-loader
|
|
// Note: for a component to be eligible for HMR it also needs the __hmrId option
|
|
// to be set so that its instances can be registered / removed.
|
|
if ((true)) {
|
|
const globalObject = typeof __webpack_require__.g !== 'undefined'
|
|
? __webpack_require__.g
|
|
: typeof self !== 'undefined'
|
|
? self
|
|
: typeof window !== 'undefined'
|
|
? window
|
|
: {};
|
|
globalObject.__VUE_HMR_RUNTIME__ = {
|
|
createRecord: tryWrap(createRecord),
|
|
rerender: tryWrap(rerender),
|
|
reload: tryWrap(reload)
|
|
};
|
|
}
|
|
const map = new Map();
|
|
function registerHMR(instance) {
|
|
const id = instance.type.__hmrId;
|
|
let record = map.get(id);
|
|
if (!record) {
|
|
createRecord(id, instance.type);
|
|
record = map.get(id);
|
|
}
|
|
record.instances.add(instance);
|
|
}
|
|
function unregisterHMR(instance) {
|
|
map.get(instance.type.__hmrId).instances.delete(instance);
|
|
}
|
|
function createRecord(id, component) {
|
|
if (!component) {
|
|
warn(`HMR API usage is out of date.\n` +
|
|
`Please upgrade vue-loader/vite/rollup-plugin-vue or other relevant ` +
|
|
`dependency that handles Vue SFC compilation.`);
|
|
component = {};
|
|
}
|
|
if (map.has(id)) {
|
|
return false;
|
|
}
|
|
map.set(id, {
|
|
component: isClassComponent(component) ? component.__vccOpts : component,
|
|
instances: new Set()
|
|
});
|
|
return true;
|
|
}
|
|
function rerender(id, newRender) {
|
|
const record = map.get(id);
|
|
if (!record)
|
|
return;
|
|
if (newRender)
|
|
record.component.render = newRender;
|
|
// Array.from creates a snapshot which avoids the set being mutated during
|
|
// updates
|
|
Array.from(record.instances).forEach(instance => {
|
|
if (newRender) {
|
|
instance.render = newRender;
|
|
}
|
|
instance.renderCache = [];
|
|
// this flag forces child components with slot content to update
|
|
isHmrUpdating = true;
|
|
instance.update();
|
|
isHmrUpdating = false;
|
|
});
|
|
}
|
|
function reload(id, newComp) {
|
|
const record = map.get(id);
|
|
if (!record)
|
|
return;
|
|
// Array.from creates a snapshot which avoids the set being mutated during
|
|
// updates
|
|
const { component, instances } = record;
|
|
if (!hmrDirtyComponents.has(component)) {
|
|
// 1. Update existing comp definition to match new one
|
|
newComp = isClassComponent(newComp) ? newComp.__vccOpts : newComp;
|
|
(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.extend)(component, newComp);
|
|
for (const key in component) {
|
|
if (key !== '__file' && !(key in newComp)) {
|
|
delete component[key];
|
|
}
|
|
}
|
|
// 2. Mark component dirty. This forces the renderer to replace the component
|
|
// on patch.
|
|
hmrDirtyComponents.add(component);
|
|
// 3. Make sure to unmark the component after the reload.
|
|
queuePostFlushCb(() => {
|
|
hmrDirtyComponents.delete(component);
|
|
});
|
|
}
|
|
Array.from(instances).forEach(instance => {
|
|
// invalidate options resolution cache
|
|
instance.appContext.optionsCache.delete(instance.type);
|
|
if (instance.ceReload) {
|
|
// custom element
|
|
hmrDirtyComponents.add(component);
|
|
instance.ceReload(newComp.styles);
|
|
hmrDirtyComponents.delete(component);
|
|
}
|
|
else if (instance.parent) {
|
|
// 4. Force the parent instance to re-render. This will cause all updated
|
|
// components to be unmounted and re-mounted. Queue the update so that we
|
|
// don't end up forcing the same parent to re-render multiple times.
|
|
queueJob(instance.parent.update);
|
|
// instance is the inner component of an async custom element
|
|
// invoke to reset styles
|
|
if (instance.parent.type.__asyncLoader &&
|
|
instance.parent.ceReload) {
|
|
instance.parent.ceReload(newComp.styles);
|
|
}
|
|
}
|
|
else if (instance.appContext.reload) {
|
|
// root instance mounted via createApp() has a reload method
|
|
instance.appContext.reload();
|
|
}
|
|
else if (typeof window !== 'undefined') {
|
|
// root instance inside tree created via raw render(). Force reload.
|
|
window.location.reload();
|
|
}
|
|
else {
|
|
console.warn('[HMR] Root or manually mounted instance modified. Full reload required.');
|
|
}
|
|
});
|
|
}
|
|
function tryWrap(fn) {
|
|
return (id, arg) => {
|
|
try {
|
|
return fn(id, arg);
|
|
}
|
|
catch (e) {
|
|
console.error(e);
|
|
console.warn(`[HMR] Something went wrong during Vue component hot-reload. ` +
|
|
`Full reload required.`);
|
|
}
|
|
};
|
|
}
|
|
|
|
let devtools;
|
|
function setDevtoolsHook(hook) {
|
|
devtools = hook;
|
|
}
|
|
function devtoolsInitApp(app, version) {
|
|
// TODO queue if devtools is undefined
|
|
if (!devtools)
|
|
return;
|
|
devtools.emit("app:init" /* APP_INIT */, app, version, {
|
|
Fragment,
|
|
Text,
|
|
Comment: Comment$1,
|
|
Static
|
|
});
|
|
}
|
|
function devtoolsUnmountApp(app) {
|
|
if (!devtools)
|
|
return;
|
|
devtools.emit("app:unmount" /* APP_UNMOUNT */, app);
|
|
}
|
|
const devtoolsComponentAdded = /*#__PURE__*/ createDevtoolsComponentHook("component:added" /* COMPONENT_ADDED */);
|
|
const devtoolsComponentUpdated =
|
|
/*#__PURE__*/ createDevtoolsComponentHook("component:updated" /* COMPONENT_UPDATED */);
|
|
const devtoolsComponentRemoved =
|
|
/*#__PURE__*/ createDevtoolsComponentHook("component:removed" /* COMPONENT_REMOVED */);
|
|
function createDevtoolsComponentHook(hook) {
|
|
return (component) => {
|
|
if (!devtools)
|
|
return;
|
|
devtools.emit(hook, component.appContext.app, component.uid, component.parent ? component.parent.uid : undefined, component);
|
|
};
|
|
}
|
|
const devtoolsPerfStart = /*#__PURE__*/ createDevtoolsPerformanceHook("perf:start" /* PERFORMANCE_START */);
|
|
const devtoolsPerfEnd = /*#__PURE__*/ createDevtoolsPerformanceHook("perf:end" /* PERFORMANCE_END */);
|
|
function createDevtoolsPerformanceHook(hook) {
|
|
return (component, type, time) => {
|
|
if (!devtools)
|
|
return;
|
|
devtools.emit(hook, component.appContext.app, component.uid, component, type, time);
|
|
};
|
|
}
|
|
function devtoolsComponentEmit(component, event, params) {
|
|
if (!devtools)
|
|
return;
|
|
devtools.emit("component:emit" /* COMPONENT_EMIT */, component.appContext.app, component, event, params);
|
|
}
|
|
|
|
const deprecationData = {
|
|
["GLOBAL_MOUNT" /* GLOBAL_MOUNT */]: {
|
|
message: `The global app bootstrapping API has changed: vm.$mount() and the "el" ` +
|
|
`option have been removed. Use createApp(RootComponent).mount() instead.`,
|
|
link: `https://v3.vuejs.org/guide/migration/global-api.html#mounting-app-instance`
|
|
},
|
|
["GLOBAL_MOUNT_CONTAINER" /* GLOBAL_MOUNT_CONTAINER */]: {
|
|
message: `Vue detected directives on the mount container. ` +
|
|
`In Vue 3, the container is no longer considered part of the template ` +
|
|
`and will not be processed/replaced.`,
|
|
link: `https://v3.vuejs.org/guide/migration/mount-changes.html`
|
|
},
|
|
["GLOBAL_EXTEND" /* GLOBAL_EXTEND */]: {
|
|
message: `Vue.extend() has been removed in Vue 3. ` +
|
|
`Use defineComponent() instead.`,
|
|
link: `https://v3.vuejs.org/api/global-api.html#definecomponent`
|
|
},
|
|
["GLOBAL_PROTOTYPE" /* GLOBAL_PROTOTYPE */]: {
|
|
message: `Vue.prototype is no longer available in Vue 3. ` +
|
|
`Use app.config.globalProperties instead.`,
|
|
link: `https://v3.vuejs.org/guide/migration/global-api.html#vue-prototype-replaced-by-config-globalproperties`
|
|
},
|
|
["GLOBAL_SET" /* GLOBAL_SET */]: {
|
|
message: `Vue.set() has been removed as it is no longer needed in Vue 3. ` +
|
|
`Simply use native JavaScript mutations.`
|
|
},
|
|
["GLOBAL_DELETE" /* GLOBAL_DELETE */]: {
|
|
message: `Vue.delete() has been removed as it is no longer needed in Vue 3. ` +
|
|
`Simply use native JavaScript mutations.`
|
|
},
|
|
["GLOBAL_OBSERVABLE" /* GLOBAL_OBSERVABLE */]: {
|
|
message: `Vue.observable() has been removed. ` +
|
|
`Use \`import { reactive } from "vue"\` from Composition API instead.`,
|
|
link: `https://v3.vuejs.org/api/basic-reactivity.html`
|
|
},
|
|
["GLOBAL_PRIVATE_UTIL" /* GLOBAL_PRIVATE_UTIL */]: {
|
|
message: `Vue.util has been removed. Please refactor to avoid its usage ` +
|
|
`since it was an internal API even in Vue 2.`
|
|
},
|
|
["CONFIG_SILENT" /* CONFIG_SILENT */]: {
|
|
message: `config.silent has been removed because it is not good practice to ` +
|
|
`intentionally suppress warnings. You can use your browser console's ` +
|
|
`filter features to focus on relevant messages.`
|
|
},
|
|
["CONFIG_DEVTOOLS" /* CONFIG_DEVTOOLS */]: {
|
|
message: `config.devtools has been removed. To enable devtools for ` +
|
|
`production, configure the __VUE_PROD_DEVTOOLS__ compile-time flag.`,
|
|
link: `https://github.com/vuejs/vue-next/tree/master/packages/vue#bundler-build-feature-flags`
|
|
},
|
|
["CONFIG_KEY_CODES" /* CONFIG_KEY_CODES */]: {
|
|
message: `config.keyCodes has been removed. ` +
|
|
`In Vue 3, you can directly use the kebab-case key names as v-on modifiers.`,
|
|
link: `https://v3.vuejs.org/guide/migration/keycode-modifiers.html`
|
|
},
|
|
["CONFIG_PRODUCTION_TIP" /* CONFIG_PRODUCTION_TIP */]: {
|
|
message: `config.productionTip has been removed.`,
|
|
link: `https://v3.vuejs.org/guide/migration/global-api.html#config-productiontip-removed`
|
|
},
|
|
["CONFIG_IGNORED_ELEMENTS" /* CONFIG_IGNORED_ELEMENTS */]: {
|
|
message: () => {
|
|
let msg = `config.ignoredElements has been removed.`;
|
|
if (isRuntimeOnly()) {
|
|
msg += ` Pass the "isCustomElement" option to @vue/compiler-dom instead.`;
|
|
}
|
|
else {
|
|
msg += ` Use config.isCustomElement instead.`;
|
|
}
|
|
return msg;
|
|
},
|
|
link: `https://v3.vuejs.org/guide/migration/global-api.html#config-ignoredelements-is-now-config-iscustomelement`
|
|
},
|
|
["CONFIG_WHITESPACE" /* CONFIG_WHITESPACE */]: {
|
|
// this warning is only relevant in the full build when using runtime
|
|
// compilation, so it's put in the runtime compatConfig list.
|
|
message: `Vue 3 compiler's whitespace option will default to "condense" instead of ` +
|
|
`"preserve". To suppress this warning, provide an explicit value for ` +
|
|
`\`config.compilerOptions.whitespace\`.`
|
|
},
|
|
["CONFIG_OPTION_MERGE_STRATS" /* CONFIG_OPTION_MERGE_STRATS */]: {
|
|
message: `config.optionMergeStrategies no longer exposes internal strategies. ` +
|
|
`Use custom merge functions instead.`
|
|
},
|
|
["INSTANCE_SET" /* INSTANCE_SET */]: {
|
|
message: `vm.$set() has been removed as it is no longer needed in Vue 3. ` +
|
|
`Simply use native JavaScript mutations.`
|
|
},
|
|
["INSTANCE_DELETE" /* INSTANCE_DELETE */]: {
|
|
message: `vm.$delete() has been removed as it is no longer needed in Vue 3. ` +
|
|
`Simply use native JavaScript mutations.`
|
|
},
|
|
["INSTANCE_DESTROY" /* INSTANCE_DESTROY */]: {
|
|
message: `vm.$destroy() has been removed. Use app.unmount() instead.`,
|
|
link: `https://v3.vuejs.org/api/application-api.html#unmount`
|
|
},
|
|
["INSTANCE_EVENT_EMITTER" /* INSTANCE_EVENT_EMITTER */]: {
|
|
message: `vm.$on/$once/$off() have been removed. ` +
|
|
`Use an external event emitter library instead.`,
|
|
link: `https://v3.vuejs.org/guide/migration/events-api.html`
|
|
},
|
|
["INSTANCE_EVENT_HOOKS" /* INSTANCE_EVENT_HOOKS */]: {
|
|
message: event => `"${event}" lifecycle events are no longer supported. From templates, ` +
|
|
`use the "vnode" prefix instead of "hook:". For example, @${event} ` +
|
|
`should be changed to @vnode-${event.slice(5)}. ` +
|
|
`From JavaScript, use Composition API to dynamically register lifecycle ` +
|
|
`hooks.`,
|
|
link: `https://v3.vuejs.org/guide/migration/vnode-lifecycle-events.html`
|
|
},
|
|
["INSTANCE_CHILDREN" /* INSTANCE_CHILDREN */]: {
|
|
message: `vm.$children has been removed. Consider refactoring your logic ` +
|
|
`to avoid relying on direct access to child components.`,
|
|
link: `https://v3.vuejs.org/guide/migration/children.html`
|
|
},
|
|
["INSTANCE_LISTENERS" /* INSTANCE_LISTENERS */]: {
|
|
message: `vm.$listeners has been removed. In Vue 3, parent v-on listeners are ` +
|
|
`included in vm.$attrs and it is no longer necessary to separately use ` +
|
|
`v-on="$listeners" if you are already using v-bind="$attrs". ` +
|
|
`(Note: the Vue 3 behavior only applies if this compat config is disabled)`,
|
|
link: `https://v3.vuejs.org/guide/migration/listeners-removed.html`
|
|
},
|
|
["INSTANCE_SCOPED_SLOTS" /* INSTANCE_SCOPED_SLOTS */]: {
|
|
message: `vm.$scopedSlots has been removed. Use vm.$slots instead.`,
|
|
link: `https://v3.vuejs.org/guide/migration/slots-unification.html`
|
|
},
|
|
["INSTANCE_ATTRS_CLASS_STYLE" /* INSTANCE_ATTRS_CLASS_STYLE */]: {
|
|
message: componentName => `Component <${componentName || 'Anonymous'}> has \`inheritAttrs: false\` but is ` +
|
|
`relying on class/style fallthrough from parent. In Vue 3, class/style ` +
|
|
`are now included in $attrs and will no longer fallthrough when ` +
|
|
`inheritAttrs is false. If you are already using v-bind="$attrs" on ` +
|
|
`component root it should render the same end result. ` +
|
|
`If you are binding $attrs to a non-root element and expecting ` +
|
|
`class/style to fallthrough on root, you will need to now manually bind ` +
|
|
`them on root via :class="$attrs.class".`,
|
|
link: `https://v3.vuejs.org/guide/migration/attrs-includes-class-style.html`
|
|
},
|
|
["OPTIONS_DATA_FN" /* OPTIONS_DATA_FN */]: {
|
|
message: `The "data" option can no longer be a plain object. ` +
|
|
`Always use a function.`,
|
|
link: `https://v3.vuejs.org/guide/migration/data-option.html`
|
|
},
|
|
["OPTIONS_DATA_MERGE" /* OPTIONS_DATA_MERGE */]: {
|
|
message: (key) => `Detected conflicting key "${key}" when merging data option values. ` +
|
|
`In Vue 3, data keys are merged shallowly and will override one another.`,
|
|
link: `https://v3.vuejs.org/guide/migration/data-option.html#mixin-merge-behavior-change`
|
|
},
|
|
["OPTIONS_BEFORE_DESTROY" /* OPTIONS_BEFORE_DESTROY */]: {
|
|
message: `\`beforeDestroy\` has been renamed to \`beforeUnmount\`.`
|
|
},
|
|
["OPTIONS_DESTROYED" /* OPTIONS_DESTROYED */]: {
|
|
message: `\`destroyed\` has been renamed to \`unmounted\`.`
|
|
},
|
|
["WATCH_ARRAY" /* WATCH_ARRAY */]: {
|
|
message: `"watch" option or vm.$watch on an array value will no longer ` +
|
|
`trigger on array mutation unless the "deep" option is specified. ` +
|
|
`If current usage is intended, you can disable the compat behavior and ` +
|
|
`suppress this warning with:` +
|
|
`\n\n configureCompat({ ${"WATCH_ARRAY" /* WATCH_ARRAY */}: false })\n`,
|
|
link: `https://v3.vuejs.org/guide/migration/watch.html`
|
|
},
|
|
["PROPS_DEFAULT_THIS" /* PROPS_DEFAULT_THIS */]: {
|
|
message: (key) => `props default value function no longer has access to "this". The compat ` +
|
|
`build only offers access to this.$options.` +
|
|
`(found in prop "${key}")`,
|
|
link: `https://v3.vuejs.org/guide/migration/props-default-this.html`
|
|
},
|
|
["CUSTOM_DIR" /* CUSTOM_DIR */]: {
|
|
message: (legacyHook, newHook) => `Custom directive hook "${legacyHook}" has been removed. ` +
|
|
`Use "${newHook}" instead.`,
|
|
link: `https://v3.vuejs.org/guide/migration/custom-directives.html`
|
|
},
|
|
["V_FOR_REF" /* V_FOR_REF */]: {
|
|
message: `Ref usage on v-for no longer creates array ref values in Vue 3. ` +
|
|
`Consider using function refs or refactor to avoid ref usage altogether.`,
|
|
link: `https://v3.vuejs.org/guide/migration/array-refs.html`
|
|
},
|
|
["V_ON_KEYCODE_MODIFIER" /* V_ON_KEYCODE_MODIFIER */]: {
|
|
message: `Using keyCode as v-on modifier is no longer supported. ` +
|
|
`Use kebab-case key name modifiers instead.`,
|
|
link: `https://v3.vuejs.org/guide/migration/keycode-modifiers.html`
|
|
},
|
|
["ATTR_FALSE_VALUE" /* ATTR_FALSE_VALUE */]: {
|
|
message: (name) => `Attribute "${name}" with v-bind value \`false\` will render ` +
|
|
`${name}="false" instead of removing it in Vue 3. To remove the attribute, ` +
|
|
`use \`null\` or \`undefined\` instead. If the usage is intended, ` +
|
|
`you can disable the compat behavior and suppress this warning with:` +
|
|
`\n\n configureCompat({ ${"ATTR_FALSE_VALUE" /* ATTR_FALSE_VALUE */}: false })\n`,
|
|
link: `https://v3.vuejs.org/guide/migration/attribute-coercion.html`
|
|
},
|
|
["ATTR_ENUMERATED_COERCION" /* ATTR_ENUMERATED_COERCION */]: {
|
|
message: (name, value, coerced) => `Enumerated attribute "${name}" with v-bind value \`${value}\` will ` +
|
|
`${value === null ? `be removed` : `render the value as-is`} instead of coercing the value to "${coerced}" in Vue 3. ` +
|
|
`Always use explicit "true" or "false" values for enumerated attributes. ` +
|
|
`If the usage is intended, ` +
|
|
`you can disable the compat behavior and suppress this warning with:` +
|
|
`\n\n configureCompat({ ${"ATTR_ENUMERATED_COERCION" /* ATTR_ENUMERATED_COERCION */}: false })\n`,
|
|
link: `https://v3.vuejs.org/guide/migration/attribute-coercion.html`
|
|
},
|
|
["TRANSITION_CLASSES" /* TRANSITION_CLASSES */]: {
|
|
message: `` // this feature cannot be runtime-detected
|
|
},
|
|
["TRANSITION_GROUP_ROOT" /* TRANSITION_GROUP_ROOT */]: {
|
|
message: `<TransitionGroup> no longer renders a root <span> element by ` +
|
|
`default if no "tag" prop is specified. If you do not rely on the span ` +
|
|
`for styling, you can disable the compat behavior and suppress this ` +
|
|
`warning with:` +
|
|
`\n\n configureCompat({ ${"TRANSITION_GROUP_ROOT" /* TRANSITION_GROUP_ROOT */}: false })\n`,
|
|
link: `https://v3.vuejs.org/guide/migration/transition-group.html`
|
|
},
|
|
["COMPONENT_ASYNC" /* COMPONENT_ASYNC */]: {
|
|
message: (comp) => {
|
|
const name = getComponentName(comp);
|
|
return (`Async component${name ? ` <${name}>` : `s`} should be explicitly created via \`defineAsyncComponent()\` ` +
|
|
`in Vue 3. Plain functions will be treated as functional components in ` +
|
|
`non-compat build. If you have already migrated all async component ` +
|
|
`usage and intend to use plain functions for functional components, ` +
|
|
`you can disable the compat behavior and suppress this ` +
|
|
`warning with:` +
|
|
`\n\n configureCompat({ ${"COMPONENT_ASYNC" /* COMPONENT_ASYNC */}: false })\n`);
|
|
},
|
|
link: `https://v3.vuejs.org/guide/migration/async-components.html`
|
|
},
|
|
["COMPONENT_FUNCTIONAL" /* COMPONENT_FUNCTIONAL */]: {
|
|
message: (comp) => {
|
|
const name = getComponentName(comp);
|
|
return (`Functional component${name ? ` <${name}>` : `s`} should be defined as a plain function in Vue 3. The "functional" ` +
|
|
`option has been removed. NOTE: Before migrating to use plain ` +
|
|
`functions for functional components, first make sure that all async ` +
|
|
`components usage have been migrated and its compat behavior has ` +
|
|
`been disabled.`);
|
|
},
|
|
link: `https://v3.vuejs.org/guide/migration/functional-components.html`
|
|
},
|
|
["COMPONENT_V_MODEL" /* COMPONENT_V_MODEL */]: {
|
|
message: (comp) => {
|
|
const configMsg = `opt-in to ` +
|
|
`Vue 3 behavior on a per-component basis with \`compatConfig: { ${"COMPONENT_V_MODEL" /* COMPONENT_V_MODEL */}: false }\`.`;
|
|
if (comp.props &&
|
|
((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isArray)(comp.props)
|
|
? comp.props.includes('modelValue')
|
|
: (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.hasOwn)(comp.props, 'modelValue'))) {
|
|
return (`Component delcares "modelValue" prop, which is Vue 3 usage, but ` +
|
|
`is running under Vue 2 compat v-model behavior. You can ${configMsg}`);
|
|
}
|
|
return (`v-model usage on component has changed in Vue 3. Component that expects ` +
|
|
`to work with v-model should now use the "modelValue" prop and emit the ` +
|
|
`"update:modelValue" event. You can update the usage and then ${configMsg}`);
|
|
},
|
|
link: `https://v3.vuejs.org/guide/migration/v-model.html`
|
|
},
|
|
["RENDER_FUNCTION" /* RENDER_FUNCTION */]: {
|
|
message: `Vue 3's render function API has changed. ` +
|
|
`You can opt-in to the new API with:` +
|
|
`\n\n configureCompat({ ${"RENDER_FUNCTION" /* RENDER_FUNCTION */}: false })\n` +
|
|
`\n (This can also be done per-component via the "compatConfig" option.)`,
|
|
link: `https://v3.vuejs.org/guide/migration/render-function-api.html`
|
|
},
|
|
["FILTERS" /* FILTERS */]: {
|
|
message: `filters have been removed in Vue 3. ` +
|
|
`The "|" symbol will be treated as native JavaScript bitwise OR operator. ` +
|
|
`Use method calls or computed properties instead.`,
|
|
link: `https://v3.vuejs.org/guide/migration/filters.html`
|
|
},
|
|
["PRIVATE_APIS" /* PRIVATE_APIS */]: {
|
|
message: name => `"${name}" is a Vue 2 private API that no longer exists in Vue 3. ` +
|
|
`If you are seeing this warning only due to a dependency, you can ` +
|
|
`suppress this warning via { PRIVATE_APIS: 'supress-warning' }.`
|
|
}
|
|
};
|
|
const instanceWarned = Object.create(null);
|
|
const warnCount = Object.create(null);
|
|
function warnDeprecation(key, instance, ...args) {
|
|
if (false) {}
|
|
instance = instance || getCurrentInstance();
|
|
// check user config
|
|
const config = getCompatConfigForKey(key, instance);
|
|
if (config === 'suppress-warning') {
|
|
return;
|
|
}
|
|
const dupKey = key + args.join('');
|
|
let compId = instance && formatComponentName(instance, instance.type);
|
|
if (compId === 'Anonymous' && instance) {
|
|
compId = instance.uid;
|
|
}
|
|
// skip if the same warning is emitted for the same component type
|
|
const componentDupKey = dupKey + compId;
|
|
if (componentDupKey in instanceWarned) {
|
|
return;
|
|
}
|
|
instanceWarned[componentDupKey] = true;
|
|
// same warning, but different component. skip the long message and just
|
|
// log the key and count.
|
|
if (dupKey in warnCount) {
|
|
warn(`(deprecation ${key}) (${++warnCount[dupKey] + 1})`);
|
|
return;
|
|
}
|
|
warnCount[dupKey] = 0;
|
|
const { message, link } = deprecationData[key];
|
|
warn(`(deprecation ${key}) ${typeof message === 'function' ? message(...args) : message}${link ? `\n Details: ${link}` : ``}`);
|
|
if (!isCompatEnabled(key, instance, true)) {
|
|
console.error(`^ The above deprecation's compat behavior is disabled and will likely ` +
|
|
`lead to runtime errors.`);
|
|
}
|
|
}
|
|
const globalCompatConfig = {
|
|
MODE: 2
|
|
};
|
|
function getCompatConfigForKey(key, instance) {
|
|
const instanceConfig = instance && instance.type.compatConfig;
|
|
if (instanceConfig && key in instanceConfig) {
|
|
return instanceConfig[key];
|
|
}
|
|
return globalCompatConfig[key];
|
|
}
|
|
function isCompatEnabled(key, instance, enableForBuiltIn = false) {
|
|
// skip compat for built-in components
|
|
if (!enableForBuiltIn && instance && instance.type.__isBuiltIn) {
|
|
return false;
|
|
}
|
|
const rawMode = getCompatConfigForKey('MODE', instance) || 2;
|
|
const val = getCompatConfigForKey(key, instance);
|
|
const mode = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isFunction)(rawMode)
|
|
? rawMode(instance && instance.type)
|
|
: rawMode;
|
|
if (mode === 2) {
|
|
return val !== false;
|
|
}
|
|
else {
|
|
return val === true || val === 'suppress-warning';
|
|
}
|
|
}
|
|
|
|
function emit(instance, event, ...rawArgs) {
|
|
const props = instance.vnode.props || _vue_shared__WEBPACK_IMPORTED_MODULE_1__.EMPTY_OBJ;
|
|
if ((true)) {
|
|
const { emitsOptions, propsOptions: [propsOptions] } = instance;
|
|
if (emitsOptions) {
|
|
if (!(event in emitsOptions) &&
|
|
!(false )) {
|
|
if (!propsOptions || !((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.toHandlerKey)(event) in propsOptions)) {
|
|
warn(`Component emitted event "${event}" but it is neither declared in ` +
|
|
`the emits option nor as an "${(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.toHandlerKey)(event)}" prop.`);
|
|
}
|
|
}
|
|
else {
|
|
const validator = emitsOptions[event];
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isFunction)(validator)) {
|
|
const isValid = validator(...rawArgs);
|
|
if (!isValid) {
|
|
warn(`Invalid event arguments: event validation failed for event "${event}".`);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
let args = rawArgs;
|
|
const isModelListener = event.startsWith('update:');
|
|
// for v-model update:xxx events, apply modifiers on args
|
|
const modelArg = isModelListener && event.slice(7);
|
|
if (modelArg && modelArg in props) {
|
|
const modifiersKey = `${modelArg === 'modelValue' ? 'model' : modelArg}Modifiers`;
|
|
const { number, trim } = props[modifiersKey] || _vue_shared__WEBPACK_IMPORTED_MODULE_1__.EMPTY_OBJ;
|
|
if (trim) {
|
|
args = rawArgs.map(a => a.trim());
|
|
}
|
|
else if (number) {
|
|
args = rawArgs.map(_vue_shared__WEBPACK_IMPORTED_MODULE_1__.toNumber);
|
|
}
|
|
}
|
|
if (true) {
|
|
devtoolsComponentEmit(instance, event, args);
|
|
}
|
|
if ((true)) {
|
|
const lowerCaseEvent = event.toLowerCase();
|
|
if (lowerCaseEvent !== event && props[(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.toHandlerKey)(lowerCaseEvent)]) {
|
|
warn(`Event "${lowerCaseEvent}" is emitted in component ` +
|
|
`${formatComponentName(instance, instance.type)} but the handler is registered for "${event}". ` +
|
|
`Note that HTML attributes are case-insensitive and you cannot use ` +
|
|
`v-on to listen to camelCase events when using in-DOM templates. ` +
|
|
`You should probably use "${(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.hyphenate)(event)}" instead of "${event}".`);
|
|
}
|
|
}
|
|
let handlerName;
|
|
let handler = props[(handlerName = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.toHandlerKey)(event))] ||
|
|
// also try camelCase event handler (#2249)
|
|
props[(handlerName = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.toHandlerKey)((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.camelize)(event)))];
|
|
// for v-model update:xxx events, also trigger kebab-case equivalent
|
|
// for props passed via kebab-case
|
|
if (!handler && isModelListener) {
|
|
handler = props[(handlerName = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.toHandlerKey)((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.hyphenate)(event)))];
|
|
}
|
|
if (handler) {
|
|
callWithAsyncErrorHandling(handler, instance, 6 /* COMPONENT_EVENT_HANDLER */, args);
|
|
}
|
|
const onceHandler = props[handlerName + `Once`];
|
|
if (onceHandler) {
|
|
if (!instance.emitted) {
|
|
instance.emitted = {};
|
|
}
|
|
else if (instance.emitted[handlerName]) {
|
|
return;
|
|
}
|
|
instance.emitted[handlerName] = true;
|
|
callWithAsyncErrorHandling(onceHandler, instance, 6 /* COMPONENT_EVENT_HANDLER */, args);
|
|
}
|
|
}
|
|
function normalizeEmitsOptions(comp, appContext, asMixin = false) {
|
|
const cache = appContext.emitsCache;
|
|
const cached = cache.get(comp);
|
|
if (cached !== undefined) {
|
|
return cached;
|
|
}
|
|
const raw = comp.emits;
|
|
let normalized = {};
|
|
// apply mixin/extends props
|
|
let hasExtends = false;
|
|
if (__VUE_OPTIONS_API__ && !(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isFunction)(comp)) {
|
|
const extendEmits = (raw) => {
|
|
const normalizedFromExtend = normalizeEmitsOptions(raw, appContext, true);
|
|
if (normalizedFromExtend) {
|
|
hasExtends = true;
|
|
(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.extend)(normalized, normalizedFromExtend);
|
|
}
|
|
};
|
|
if (!asMixin && appContext.mixins.length) {
|
|
appContext.mixins.forEach(extendEmits);
|
|
}
|
|
if (comp.extends) {
|
|
extendEmits(comp.extends);
|
|
}
|
|
if (comp.mixins) {
|
|
comp.mixins.forEach(extendEmits);
|
|
}
|
|
}
|
|
if (!raw && !hasExtends) {
|
|
cache.set(comp, null);
|
|
return null;
|
|
}
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isArray)(raw)) {
|
|
raw.forEach(key => (normalized[key] = null));
|
|
}
|
|
else {
|
|
(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.extend)(normalized, raw);
|
|
}
|
|
cache.set(comp, normalized);
|
|
return normalized;
|
|
}
|
|
// Check if an incoming prop key is a declared emit event listener.
|
|
// e.g. With `emits: { click: null }`, props named `onClick` and `onclick` are
|
|
// both considered matched listeners.
|
|
function isEmitListener(options, key) {
|
|
if (!options || !(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isOn)(key)) {
|
|
return false;
|
|
}
|
|
key = key.slice(2).replace(/Once$/, '');
|
|
return ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.hasOwn)(options, key[0].toLowerCase() + key.slice(1)) ||
|
|
(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.hasOwn)(options, (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.hyphenate)(key)) ||
|
|
(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.hasOwn)(options, key));
|
|
}
|
|
|
|
/**
|
|
* mark the current rendering instance for asset resolution (e.g.
|
|
* resolveComponent, resolveDirective) during render
|
|
*/
|
|
let currentRenderingInstance = null;
|
|
let currentScopeId = null;
|
|
/**
|
|
* Note: rendering calls maybe nested. The function returns the parent rendering
|
|
* instance if present, which should be restored after the render is done:
|
|
*
|
|
* ```js
|
|
* const prev = setCurrentRenderingInstance(i)
|
|
* // ...render
|
|
* setCurrentRenderingInstance(prev)
|
|
* ```
|
|
*/
|
|
function setCurrentRenderingInstance(instance) {
|
|
const prev = currentRenderingInstance;
|
|
currentRenderingInstance = instance;
|
|
currentScopeId = (instance && instance.type.__scopeId) || null;
|
|
return prev;
|
|
}
|
|
/**
|
|
* Set scope id when creating hoisted vnodes.
|
|
* @private compiler helper
|
|
*/
|
|
function pushScopeId(id) {
|
|
currentScopeId = id;
|
|
}
|
|
/**
|
|
* Technically we no longer need this after 3.0.8 but we need to keep the same
|
|
* API for backwards compat w/ code generated by compilers.
|
|
* @private
|
|
*/
|
|
function popScopeId() {
|
|
currentScopeId = null;
|
|
}
|
|
/**
|
|
* Only for backwards compat
|
|
* @private
|
|
*/
|
|
const withScopeId = (_id) => withCtx;
|
|
/**
|
|
* Wrap a slot function to memoize current rendering instance
|
|
* @private compiler helper
|
|
*/
|
|
function withCtx(fn, ctx = currentRenderingInstance, isNonScopedSlot // false only
|
|
) {
|
|
if (!ctx)
|
|
return fn;
|
|
// already normalized
|
|
if (fn._n) {
|
|
return fn;
|
|
}
|
|
const renderFnWithContext = (...args) => {
|
|
// If a user calls a compiled slot inside a template expression (#1745), it
|
|
// can mess up block tracking, so by default we disable block tracking and
|
|
// force bail out when invoking a compiled slot (indicated by the ._d flag).
|
|
// This isn't necessary if rendering a compiled `<slot>`, so we flip the
|
|
// ._d flag off when invoking the wrapped fn inside `renderSlot`.
|
|
if (renderFnWithContext._d) {
|
|
setBlockTracking(-1);
|
|
}
|
|
const prevInstance = setCurrentRenderingInstance(ctx);
|
|
const res = fn(...args);
|
|
setCurrentRenderingInstance(prevInstance);
|
|
if (renderFnWithContext._d) {
|
|
setBlockTracking(1);
|
|
}
|
|
if (true) {
|
|
devtoolsComponentUpdated(ctx);
|
|
}
|
|
return res;
|
|
};
|
|
// mark normalized to avoid duplicated wrapping
|
|
renderFnWithContext._n = true;
|
|
// mark this as compiled by default
|
|
// this is used in vnode.ts -> normalizeChildren() to set the slot
|
|
// rendering flag.
|
|
renderFnWithContext._c = true;
|
|
// disable block tracking by default
|
|
renderFnWithContext._d = true;
|
|
return renderFnWithContext;
|
|
}
|
|
|
|
/**
|
|
* dev only flag to track whether $attrs was used during render.
|
|
* If $attrs was used during render then the warning for failed attrs
|
|
* fallthrough can be suppressed.
|
|
*/
|
|
let accessedAttrs = false;
|
|
function markAttrsAccessed() {
|
|
accessedAttrs = true;
|
|
}
|
|
function renderComponentRoot(instance) {
|
|
const { type: Component, vnode, proxy, withProxy, props, propsOptions: [propsOptions], slots, attrs, emit, render, renderCache, data, setupState, ctx, inheritAttrs } = instance;
|
|
let result;
|
|
const prev = setCurrentRenderingInstance(instance);
|
|
if ((true)) {
|
|
accessedAttrs = false;
|
|
}
|
|
try {
|
|
let fallthroughAttrs;
|
|
if (vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */) {
|
|
// withProxy is a proxy with a different `has` trap only for
|
|
// runtime-compiled render functions using `with` block.
|
|
const proxyToUse = withProxy || proxy;
|
|
result = normalizeVNode(render.call(proxyToUse, proxyToUse, renderCache, props, setupState, data, ctx));
|
|
fallthroughAttrs = attrs;
|
|
}
|
|
else {
|
|
// functional
|
|
const render = Component;
|
|
// in dev, mark attrs accessed if optional props (attrs === props)
|
|
if (( true) && attrs === props) {
|
|
markAttrsAccessed();
|
|
}
|
|
result = normalizeVNode(render.length > 1
|
|
? render(props, ( true)
|
|
? {
|
|
get attrs() {
|
|
markAttrsAccessed();
|
|
return attrs;
|
|
},
|
|
slots,
|
|
emit
|
|
}
|
|
: 0)
|
|
: render(props, null /* we know it doesn't need it */));
|
|
fallthroughAttrs = Component.props
|
|
? attrs
|
|
: getFunctionalFallthrough(attrs);
|
|
}
|
|
// attr merging
|
|
// in dev mode, comments are preserved, and it's possible for a template
|
|
// to have comments along side the root element which makes it a fragment
|
|
let root = result;
|
|
let setRoot = undefined;
|
|
if (( true) &&
|
|
result.patchFlag > 0 &&
|
|
result.patchFlag & 2048 /* DEV_ROOT_FRAGMENT */) {
|
|
;
|
|
[root, setRoot] = getChildRoot(result);
|
|
}
|
|
if (fallthroughAttrs && inheritAttrs !== false) {
|
|
const keys = Object.keys(fallthroughAttrs);
|
|
const { shapeFlag } = root;
|
|
if (keys.length) {
|
|
if (shapeFlag & (1 /* ELEMENT */ | 6 /* COMPONENT */)) {
|
|
if (propsOptions && keys.some(_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isModelListener)) {
|
|
// If a v-model listener (onUpdate:xxx) has a corresponding declared
|
|
// prop, it indicates this component expects to handle v-model and
|
|
// it should not fallthrough.
|
|
// related: #1543, #1643, #1989
|
|
fallthroughAttrs = filterModelListeners(fallthroughAttrs, propsOptions);
|
|
}
|
|
root = cloneVNode(root, fallthroughAttrs);
|
|
}
|
|
else if (( true) && !accessedAttrs && root.type !== Comment$1) {
|
|
const allAttrs = Object.keys(attrs);
|
|
const eventAttrs = [];
|
|
const extraAttrs = [];
|
|
for (let i = 0, l = allAttrs.length; i < l; i++) {
|
|
const key = allAttrs[i];
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isOn)(key)) {
|
|
// ignore v-model handlers when they fail to fallthrough
|
|
if (!(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isModelListener)(key)) {
|
|
// remove `on`, lowercase first letter to reflect event casing
|
|
// accurately
|
|
eventAttrs.push(key[2].toLowerCase() + key.slice(3));
|
|
}
|
|
}
|
|
else {
|
|
extraAttrs.push(key);
|
|
}
|
|
}
|
|
if (extraAttrs.length) {
|
|
warn(`Extraneous non-props attributes (` +
|
|
`${extraAttrs.join(', ')}) ` +
|
|
`were passed to component but could not be automatically inherited ` +
|
|
`because component renders fragment or text root nodes.`);
|
|
}
|
|
if (eventAttrs.length) {
|
|
warn(`Extraneous non-emits event listeners (` +
|
|
`${eventAttrs.join(', ')}) ` +
|
|
`were passed to component but could not be automatically inherited ` +
|
|
`because component renders fragment or text root nodes. ` +
|
|
`If the listener is intended to be a component custom event listener only, ` +
|
|
`declare it using the "emits" option.`);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (false) {}
|
|
// inherit directives
|
|
if (vnode.dirs) {
|
|
if (( true) && !isElementRoot(root)) {
|
|
warn(`Runtime directive used on component with non-element root node. ` +
|
|
`The directives will not function as intended.`);
|
|
}
|
|
root.dirs = root.dirs ? root.dirs.concat(vnode.dirs) : vnode.dirs;
|
|
}
|
|
// inherit transition data
|
|
if (vnode.transition) {
|
|
if (( true) && !isElementRoot(root)) {
|
|
warn(`Component inside <Transition> renders non-element root node ` +
|
|
`that cannot be animated.`);
|
|
}
|
|
root.transition = vnode.transition;
|
|
}
|
|
if (( true) && setRoot) {
|
|
setRoot(root);
|
|
}
|
|
else {
|
|
result = root;
|
|
}
|
|
}
|
|
catch (err) {
|
|
blockStack.length = 0;
|
|
handleError(err, instance, 1 /* RENDER_FUNCTION */);
|
|
result = createVNode(Comment$1);
|
|
}
|
|
setCurrentRenderingInstance(prev);
|
|
return result;
|
|
}
|
|
/**
|
|
* dev only
|
|
* In dev mode, template root level comments are rendered, which turns the
|
|
* template into a fragment root, but we need to locate the single element
|
|
* root for attrs and scope id processing.
|
|
*/
|
|
const getChildRoot = (vnode) => {
|
|
const rawChildren = vnode.children;
|
|
const dynamicChildren = vnode.dynamicChildren;
|
|
const childRoot = filterSingleRoot(rawChildren);
|
|
if (!childRoot) {
|
|
return [vnode, undefined];
|
|
}
|
|
const index = rawChildren.indexOf(childRoot);
|
|
const dynamicIndex = dynamicChildren ? dynamicChildren.indexOf(childRoot) : -1;
|
|
const setRoot = (updatedRoot) => {
|
|
rawChildren[index] = updatedRoot;
|
|
if (dynamicChildren) {
|
|
if (dynamicIndex > -1) {
|
|
dynamicChildren[dynamicIndex] = updatedRoot;
|
|
}
|
|
else if (updatedRoot.patchFlag > 0) {
|
|
vnode.dynamicChildren = [...dynamicChildren, updatedRoot];
|
|
}
|
|
}
|
|
};
|
|
return [normalizeVNode(childRoot), setRoot];
|
|
};
|
|
function filterSingleRoot(children) {
|
|
let singleRoot;
|
|
for (let i = 0; i < children.length; i++) {
|
|
const child = children[i];
|
|
if (isVNode(child)) {
|
|
// ignore user comment
|
|
if (child.type !== Comment$1 || child.children === 'v-if') {
|
|
if (singleRoot) {
|
|
// has more than 1 non-comment child, return now
|
|
return;
|
|
}
|
|
else {
|
|
singleRoot = child;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
return;
|
|
}
|
|
}
|
|
return singleRoot;
|
|
}
|
|
const getFunctionalFallthrough = (attrs) => {
|
|
let res;
|
|
for (const key in attrs) {
|
|
if (key === 'class' || key === 'style' || (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isOn)(key)) {
|
|
(res || (res = {}))[key] = attrs[key];
|
|
}
|
|
}
|
|
return res;
|
|
};
|
|
const filterModelListeners = (attrs, props) => {
|
|
const res = {};
|
|
for (const key in attrs) {
|
|
if (!(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isModelListener)(key) || !(key.slice(9) in props)) {
|
|
res[key] = attrs[key];
|
|
}
|
|
}
|
|
return res;
|
|
};
|
|
const isElementRoot = (vnode) => {
|
|
return (vnode.shapeFlag & (6 /* COMPONENT */ | 1 /* ELEMENT */) ||
|
|
vnode.type === Comment$1 // potential v-if branch switch
|
|
);
|
|
};
|
|
function shouldUpdateComponent(prevVNode, nextVNode, optimized) {
|
|
const { props: prevProps, children: prevChildren, component } = prevVNode;
|
|
const { props: nextProps, children: nextChildren, patchFlag } = nextVNode;
|
|
const emits = component.emitsOptions;
|
|
// Parent component's render function was hot-updated. Since this may have
|
|
// caused the child component's slots content to have changed, we need to
|
|
// force the child to update as well.
|
|
if (( true) && (prevChildren || nextChildren) && isHmrUpdating) {
|
|
return true;
|
|
}
|
|
// force child update for runtime directive or transition on component vnode.
|
|
if (nextVNode.dirs || nextVNode.transition) {
|
|
return true;
|
|
}
|
|
if (optimized && patchFlag >= 0) {
|
|
if (patchFlag & 1024 /* DYNAMIC_SLOTS */) {
|
|
// slot content that references values that might have changed,
|
|
// e.g. in a v-for
|
|
return true;
|
|
}
|
|
if (patchFlag & 16 /* FULL_PROPS */) {
|
|
if (!prevProps) {
|
|
return !!nextProps;
|
|
}
|
|
// presence of this flag indicates props are always non-null
|
|
return hasPropsChanged(prevProps, nextProps, emits);
|
|
}
|
|
else if (patchFlag & 8 /* PROPS */) {
|
|
const dynamicProps = nextVNode.dynamicProps;
|
|
for (let i = 0; i < dynamicProps.length; i++) {
|
|
const key = dynamicProps[i];
|
|
if (nextProps[key] !== prevProps[key] &&
|
|
!isEmitListener(emits, key)) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
// this path is only taken by manually written render functions
|
|
// so presence of any children leads to a forced update
|
|
if (prevChildren || nextChildren) {
|
|
if (!nextChildren || !nextChildren.$stable) {
|
|
return true;
|
|
}
|
|
}
|
|
if (prevProps === nextProps) {
|
|
return false;
|
|
}
|
|
if (!prevProps) {
|
|
return !!nextProps;
|
|
}
|
|
if (!nextProps) {
|
|
return true;
|
|
}
|
|
return hasPropsChanged(prevProps, nextProps, emits);
|
|
}
|
|
return false;
|
|
}
|
|
function hasPropsChanged(prevProps, nextProps, emitsOptions) {
|
|
const nextKeys = Object.keys(nextProps);
|
|
if (nextKeys.length !== Object.keys(prevProps).length) {
|
|
return true;
|
|
}
|
|
for (let i = 0; i < nextKeys.length; i++) {
|
|
const key = nextKeys[i];
|
|
if (nextProps[key] !== prevProps[key] &&
|
|
!isEmitListener(emitsOptions, key)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
function updateHOCHostEl({ vnode, parent }, el // HostNode
|
|
) {
|
|
while (parent && parent.subTree === vnode) {
|
|
(vnode = parent.vnode).el = el;
|
|
parent = parent.parent;
|
|
}
|
|
}
|
|
|
|
const isSuspense = (type) => type.__isSuspense;
|
|
// Suspense exposes a component-like API, and is treated like a component
|
|
// in the compiler, but internally it's a special built-in type that hooks
|
|
// directly into the renderer.
|
|
const SuspenseImpl = {
|
|
name: 'Suspense',
|
|
// In order to make Suspense tree-shakable, we need to avoid importing it
|
|
// directly in the renderer. The renderer checks for the __isSuspense flag
|
|
// on a vnode's type and calls the `process` method, passing in renderer
|
|
// internals.
|
|
__isSuspense: true,
|
|
process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized,
|
|
// platform-specific impl passed from renderer
|
|
rendererInternals) {
|
|
if (n1 == null) {
|
|
mountSuspense(n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, rendererInternals);
|
|
}
|
|
else {
|
|
patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, slotScopeIds, optimized, rendererInternals);
|
|
}
|
|
},
|
|
hydrate: hydrateSuspense,
|
|
create: createSuspenseBoundary,
|
|
normalize: normalizeSuspenseChildren
|
|
};
|
|
// Force-casted public typing for h and TSX props inference
|
|
const Suspense = (SuspenseImpl );
|
|
function triggerEvent(vnode, name) {
|
|
const eventListener = vnode.props && vnode.props[name];
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isFunction)(eventListener)) {
|
|
eventListener();
|
|
}
|
|
}
|
|
function mountSuspense(vnode, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, rendererInternals) {
|
|
const { p: patch, o: { createElement } } = rendererInternals;
|
|
const hiddenContainer = createElement('div');
|
|
const suspense = (vnode.suspense = createSuspenseBoundary(vnode, parentSuspense, parentComponent, container, hiddenContainer, anchor, isSVG, slotScopeIds, optimized, rendererInternals));
|
|
// start mounting the content subtree in an off-dom container
|
|
patch(null, (suspense.pendingBranch = vnode.ssContent), hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds);
|
|
// now check if we have encountered any async deps
|
|
if (suspense.deps > 0) {
|
|
// has async
|
|
// invoke @fallback event
|
|
triggerEvent(vnode, 'onPending');
|
|
triggerEvent(vnode, 'onFallback');
|
|
// mount the fallback tree
|
|
patch(null, vnode.ssFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context
|
|
isSVG, slotScopeIds);
|
|
setActiveBranch(suspense, vnode.ssFallback);
|
|
}
|
|
else {
|
|
// Suspense has no async deps. Just resolve.
|
|
suspense.resolve();
|
|
}
|
|
}
|
|
function patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, slotScopeIds, optimized, { p: patch, um: unmount, o: { createElement } }) {
|
|
const suspense = (n2.suspense = n1.suspense);
|
|
suspense.vnode = n2;
|
|
n2.el = n1.el;
|
|
const newBranch = n2.ssContent;
|
|
const newFallback = n2.ssFallback;
|
|
const { activeBranch, pendingBranch, isInFallback, isHydrating } = suspense;
|
|
if (pendingBranch) {
|
|
suspense.pendingBranch = newBranch;
|
|
if (isSameVNodeType(newBranch, pendingBranch)) {
|
|
// same root type but content may have changed.
|
|
patch(pendingBranch, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized);
|
|
if (suspense.deps <= 0) {
|
|
suspense.resolve();
|
|
}
|
|
else if (isInFallback) {
|
|
patch(activeBranch, newFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context
|
|
isSVG, slotScopeIds, optimized);
|
|
setActiveBranch(suspense, newFallback);
|
|
}
|
|
}
|
|
else {
|
|
// toggled before pending tree is resolved
|
|
suspense.pendingId++;
|
|
if (isHydrating) {
|
|
// if toggled before hydration is finished, the current DOM tree is
|
|
// no longer valid. set it as the active branch so it will be unmounted
|
|
// when resolved
|
|
suspense.isHydrating = false;
|
|
suspense.activeBranch = pendingBranch;
|
|
}
|
|
else {
|
|
unmount(pendingBranch, parentComponent, suspense);
|
|
}
|
|
// increment pending ID. this is used to invalidate async callbacks
|
|
// reset suspense state
|
|
suspense.deps = 0;
|
|
// discard effects from pending branch
|
|
suspense.effects.length = 0;
|
|
// discard previous container
|
|
suspense.hiddenContainer = createElement('div');
|
|
if (isInFallback) {
|
|
// already in fallback state
|
|
patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized);
|
|
if (suspense.deps <= 0) {
|
|
suspense.resolve();
|
|
}
|
|
else {
|
|
patch(activeBranch, newFallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context
|
|
isSVG, slotScopeIds, optimized);
|
|
setActiveBranch(suspense, newFallback);
|
|
}
|
|
}
|
|
else if (activeBranch && isSameVNodeType(newBranch, activeBranch)) {
|
|
// toggled "back" to current active branch
|
|
patch(activeBranch, newBranch, container, anchor, parentComponent, suspense, isSVG, slotScopeIds, optimized);
|
|
// force resolve
|
|
suspense.resolve(true);
|
|
}
|
|
else {
|
|
// switched to a 3rd branch
|
|
patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized);
|
|
if (suspense.deps <= 0) {
|
|
suspense.resolve();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
if (activeBranch && isSameVNodeType(newBranch, activeBranch)) {
|
|
// root did not change, just normal patch
|
|
patch(activeBranch, newBranch, container, anchor, parentComponent, suspense, isSVG, slotScopeIds, optimized);
|
|
setActiveBranch(suspense, newBranch);
|
|
}
|
|
else {
|
|
// root node toggled
|
|
// invoke @pending event
|
|
triggerEvent(n2, 'onPending');
|
|
// mount pending branch in off-dom container
|
|
suspense.pendingBranch = newBranch;
|
|
suspense.pendingId++;
|
|
patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized);
|
|
if (suspense.deps <= 0) {
|
|
// incoming branch has no async deps, resolve now.
|
|
suspense.resolve();
|
|
}
|
|
else {
|
|
const { timeout, pendingId } = suspense;
|
|
if (timeout > 0) {
|
|
setTimeout(() => {
|
|
if (suspense.pendingId === pendingId) {
|
|
suspense.fallback(newFallback);
|
|
}
|
|
}, timeout);
|
|
}
|
|
else if (timeout === 0) {
|
|
suspense.fallback(newFallback);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
let hasWarned = false;
|
|
function createSuspenseBoundary(vnode, parent, parentComponent, container, hiddenContainer, anchor, isSVG, slotScopeIds, optimized, rendererInternals, isHydrating = false) {
|
|
/* istanbul ignore if */
|
|
if ( true && !hasWarned) {
|
|
hasWarned = true;
|
|
// @ts-ignore `console.info` cannot be null error
|
|
console[console.info ? 'info' : 'log'](`<Suspense> is an experimental feature and its API will likely change.`);
|
|
}
|
|
const { p: patch, m: move, um: unmount, n: next, o: { parentNode, remove } } = rendererInternals;
|
|
const timeout = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.toNumber)(vnode.props && vnode.props.timeout);
|
|
const suspense = {
|
|
vnode,
|
|
parent,
|
|
parentComponent,
|
|
isSVG,
|
|
container,
|
|
hiddenContainer,
|
|
anchor,
|
|
deps: 0,
|
|
pendingId: 0,
|
|
timeout: typeof timeout === 'number' ? timeout : -1,
|
|
activeBranch: null,
|
|
pendingBranch: null,
|
|
isInFallback: true,
|
|
isHydrating,
|
|
isUnmounted: false,
|
|
effects: [],
|
|
resolve(resume = false) {
|
|
if ((true)) {
|
|
if (!resume && !suspense.pendingBranch) {
|
|
throw new Error(`suspense.resolve() is called without a pending branch.`);
|
|
}
|
|
if (suspense.isUnmounted) {
|
|
throw new Error(`suspense.resolve() is called on an already unmounted suspense boundary.`);
|
|
}
|
|
}
|
|
const { vnode, activeBranch, pendingBranch, pendingId, effects, parentComponent, container } = suspense;
|
|
if (suspense.isHydrating) {
|
|
suspense.isHydrating = false;
|
|
}
|
|
else if (!resume) {
|
|
const delayEnter = activeBranch &&
|
|
pendingBranch.transition &&
|
|
pendingBranch.transition.mode === 'out-in';
|
|
if (delayEnter) {
|
|
activeBranch.transition.afterLeave = () => {
|
|
if (pendingId === suspense.pendingId) {
|
|
move(pendingBranch, container, anchor, 0 /* ENTER */);
|
|
}
|
|
};
|
|
}
|
|
// this is initial anchor on mount
|
|
let { anchor } = suspense;
|
|
// unmount current active tree
|
|
if (activeBranch) {
|
|
// if the fallback tree was mounted, it may have been moved
|
|
// as part of a parent suspense. get the latest anchor for insertion
|
|
anchor = next(activeBranch);
|
|
unmount(activeBranch, parentComponent, suspense, true);
|
|
}
|
|
if (!delayEnter) {
|
|
// move content from off-dom container to actual container
|
|
move(pendingBranch, container, anchor, 0 /* ENTER */);
|
|
}
|
|
}
|
|
setActiveBranch(suspense, pendingBranch);
|
|
suspense.pendingBranch = null;
|
|
suspense.isInFallback = false;
|
|
// flush buffered effects
|
|
// check if there is a pending parent suspense
|
|
let parent = suspense.parent;
|
|
let hasUnresolvedAncestor = false;
|
|
while (parent) {
|
|
if (parent.pendingBranch) {
|
|
// found a pending parent suspense, merge buffered post jobs
|
|
// into that parent
|
|
parent.effects.push(...effects);
|
|
hasUnresolvedAncestor = true;
|
|
break;
|
|
}
|
|
parent = parent.parent;
|
|
}
|
|
// no pending parent suspense, flush all jobs
|
|
if (!hasUnresolvedAncestor) {
|
|
queuePostFlushCb(effects);
|
|
}
|
|
suspense.effects = [];
|
|
// invoke @resolve event
|
|
triggerEvent(vnode, 'onResolve');
|
|
},
|
|
fallback(fallbackVNode) {
|
|
if (!suspense.pendingBranch) {
|
|
return;
|
|
}
|
|
const { vnode, activeBranch, parentComponent, container, isSVG } = suspense;
|
|
// invoke @fallback event
|
|
triggerEvent(vnode, 'onFallback');
|
|
const anchor = next(activeBranch);
|
|
const mountFallback = () => {
|
|
if (!suspense.isInFallback) {
|
|
return;
|
|
}
|
|
// mount the fallback tree
|
|
patch(null, fallbackVNode, container, anchor, parentComponent, null, // fallback tree will not have suspense context
|
|
isSVG, slotScopeIds, optimized);
|
|
setActiveBranch(suspense, fallbackVNode);
|
|
};
|
|
const delayEnter = fallbackVNode.transition && fallbackVNode.transition.mode === 'out-in';
|
|
if (delayEnter) {
|
|
activeBranch.transition.afterLeave = mountFallback;
|
|
}
|
|
suspense.isInFallback = true;
|
|
// unmount current active branch
|
|
unmount(activeBranch, parentComponent, null, // no suspense so unmount hooks fire now
|
|
true // shouldRemove
|
|
);
|
|
if (!delayEnter) {
|
|
mountFallback();
|
|
}
|
|
},
|
|
move(container, anchor, type) {
|
|
suspense.activeBranch &&
|
|
move(suspense.activeBranch, container, anchor, type);
|
|
suspense.container = container;
|
|
},
|
|
next() {
|
|
return suspense.activeBranch && next(suspense.activeBranch);
|
|
},
|
|
registerDep(instance, setupRenderEffect) {
|
|
const isInPendingSuspense = !!suspense.pendingBranch;
|
|
if (isInPendingSuspense) {
|
|
suspense.deps++;
|
|
}
|
|
const hydratedEl = instance.vnode.el;
|
|
instance
|
|
.asyncDep.catch(err => {
|
|
handleError(err, instance, 0 /* SETUP_FUNCTION */);
|
|
})
|
|
.then(asyncSetupResult => {
|
|
// retry when the setup() promise resolves.
|
|
// component may have been unmounted before resolve.
|
|
if (instance.isUnmounted ||
|
|
suspense.isUnmounted ||
|
|
suspense.pendingId !== instance.suspenseId) {
|
|
return;
|
|
}
|
|
// retry from this component
|
|
instance.asyncResolved = true;
|
|
const { vnode } = instance;
|
|
if ((true)) {
|
|
pushWarningContext(vnode);
|
|
}
|
|
handleSetupResult(instance, asyncSetupResult, false);
|
|
if (hydratedEl) {
|
|
// vnode may have been replaced if an update happened before the
|
|
// async dep is resolved.
|
|
vnode.el = hydratedEl;
|
|
}
|
|
const placeholder = !hydratedEl && instance.subTree.el;
|
|
setupRenderEffect(instance, vnode,
|
|
// component may have been moved before resolve.
|
|
// if this is not a hydration, instance.subTree will be the comment
|
|
// placeholder.
|
|
parentNode(hydratedEl || instance.subTree.el),
|
|
// anchor will not be used if this is hydration, so only need to
|
|
// consider the comment placeholder case.
|
|
hydratedEl ? null : next(instance.subTree), suspense, isSVG, optimized);
|
|
if (placeholder) {
|
|
remove(placeholder);
|
|
}
|
|
updateHOCHostEl(instance, vnode.el);
|
|
if ((true)) {
|
|
popWarningContext();
|
|
}
|
|
// only decrease deps count if suspense is not already resolved
|
|
if (isInPendingSuspense && --suspense.deps === 0) {
|
|
suspense.resolve();
|
|
}
|
|
});
|
|
},
|
|
unmount(parentSuspense, doRemove) {
|
|
suspense.isUnmounted = true;
|
|
if (suspense.activeBranch) {
|
|
unmount(suspense.activeBranch, parentComponent, parentSuspense, doRemove);
|
|
}
|
|
if (suspense.pendingBranch) {
|
|
unmount(suspense.pendingBranch, parentComponent, parentSuspense, doRemove);
|
|
}
|
|
}
|
|
};
|
|
return suspense;
|
|
}
|
|
function hydrateSuspense(node, vnode, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, rendererInternals, hydrateNode) {
|
|
/* eslint-disable no-restricted-globals */
|
|
const suspense = (vnode.suspense = createSuspenseBoundary(vnode, parentSuspense, parentComponent, node.parentNode, document.createElement('div'), null, isSVG, slotScopeIds, optimized, rendererInternals, true /* hydrating */));
|
|
// there are two possible scenarios for server-rendered suspense:
|
|
// - success: ssr content should be fully resolved
|
|
// - failure: ssr content should be the fallback branch.
|
|
// however, on the client we don't really know if it has failed or not
|
|
// attempt to hydrate the DOM assuming it has succeeded, but we still
|
|
// need to construct a suspense boundary first
|
|
const result = hydrateNode(node, (suspense.pendingBranch = vnode.ssContent), parentComponent, suspense, slotScopeIds, optimized);
|
|
if (suspense.deps === 0) {
|
|
suspense.resolve();
|
|
}
|
|
return result;
|
|
/* eslint-enable no-restricted-globals */
|
|
}
|
|
function normalizeSuspenseChildren(vnode) {
|
|
const { shapeFlag, children } = vnode;
|
|
const isSlotChildren = shapeFlag & 32 /* SLOTS_CHILDREN */;
|
|
vnode.ssContent = normalizeSuspenseSlot(isSlotChildren ? children.default : children);
|
|
vnode.ssFallback = isSlotChildren
|
|
? normalizeSuspenseSlot(children.fallback)
|
|
: createVNode(Comment);
|
|
}
|
|
function normalizeSuspenseSlot(s) {
|
|
let block;
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isFunction)(s)) {
|
|
const isCompiledSlot = s._c;
|
|
if (isCompiledSlot) {
|
|
// disableTracking: false
|
|
// allow block tracking for compiled slots
|
|
// (see ./componentRenderContext.ts)
|
|
s._d = false;
|
|
openBlock();
|
|
}
|
|
s = s();
|
|
if (isCompiledSlot) {
|
|
s._d = true;
|
|
block = currentBlock;
|
|
closeBlock();
|
|
}
|
|
}
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isArray)(s)) {
|
|
const singleChild = filterSingleRoot(s);
|
|
if (( true) && !singleChild) {
|
|
warn(`<Suspense> slots expect a single root node.`);
|
|
}
|
|
s = singleChild;
|
|
}
|
|
s = normalizeVNode(s);
|
|
if (block && !s.dynamicChildren) {
|
|
s.dynamicChildren = block.filter(c => c !== s);
|
|
}
|
|
return s;
|
|
}
|
|
function queueEffectWithSuspense(fn, suspense) {
|
|
if (suspense && suspense.pendingBranch) {
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isArray)(fn)) {
|
|
suspense.effects.push(...fn);
|
|
}
|
|
else {
|
|
suspense.effects.push(fn);
|
|
}
|
|
}
|
|
else {
|
|
queuePostFlushCb(fn);
|
|
}
|
|
}
|
|
function setActiveBranch(suspense, branch) {
|
|
suspense.activeBranch = branch;
|
|
const { vnode, parentComponent } = suspense;
|
|
const el = (vnode.el = branch.el);
|
|
// in case suspense is the root node of a component,
|
|
// recursively update the HOC el
|
|
if (parentComponent && parentComponent.subTree === vnode) {
|
|
parentComponent.vnode.el = el;
|
|
updateHOCHostEl(parentComponent, el);
|
|
}
|
|
}
|
|
|
|
function provide(key, value) {
|
|
if (!currentInstance) {
|
|
if ((true)) {
|
|
warn(`provide() can only be used inside setup().`);
|
|
}
|
|
}
|
|
else {
|
|
let provides = currentInstance.provides;
|
|
// by default an instance inherits its parent's provides object
|
|
// but when it needs to provide values of its own, it creates its
|
|
// own provides object using parent provides object as prototype.
|
|
// this way in `inject` we can simply look up injections from direct
|
|
// parent and let the prototype chain do the work.
|
|
const parentProvides = currentInstance.parent && currentInstance.parent.provides;
|
|
if (parentProvides === provides) {
|
|
provides = currentInstance.provides = Object.create(parentProvides);
|
|
}
|
|
// TS doesn't allow symbol as index type
|
|
provides[key] = value;
|
|
}
|
|
}
|
|
function inject(key, defaultValue, treatDefaultAsFactory = false) {
|
|
// fallback to `currentRenderingInstance` so that this can be called in
|
|
// a functional component
|
|
const instance = currentInstance || currentRenderingInstance;
|
|
if (instance) {
|
|
// #2400
|
|
// to support `app.use` plugins,
|
|
// fallback to appContext's `provides` if the intance is at root
|
|
const provides = instance.parent == null
|
|
? instance.vnode.appContext && instance.vnode.appContext.provides
|
|
: instance.parent.provides;
|
|
if (provides && key in provides) {
|
|
// TS doesn't allow symbol as index type
|
|
return provides[key];
|
|
}
|
|
else if (arguments.length > 1) {
|
|
return treatDefaultAsFactory && (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isFunction)(defaultValue)
|
|
? defaultValue.call(instance.proxy)
|
|
: defaultValue;
|
|
}
|
|
else if ((true)) {
|
|
warn(`injection "${String(key)}" not found.`);
|
|
}
|
|
}
|
|
else if ((true)) {
|
|
warn(`inject() can only be used inside setup() or functional components.`);
|
|
}
|
|
}
|
|
|
|
function useTransitionState() {
|
|
const state = {
|
|
isMounted: false,
|
|
isLeaving: false,
|
|
isUnmounting: false,
|
|
leavingVNodes: new Map()
|
|
};
|
|
onMounted(() => {
|
|
state.isMounted = true;
|
|
});
|
|
onBeforeUnmount(() => {
|
|
state.isUnmounting = true;
|
|
});
|
|
return state;
|
|
}
|
|
const TransitionHookValidator = [Function, Array];
|
|
const BaseTransitionImpl = {
|
|
name: `BaseTransition`,
|
|
props: {
|
|
mode: String,
|
|
appear: Boolean,
|
|
persisted: Boolean,
|
|
// enter
|
|
onBeforeEnter: TransitionHookValidator,
|
|
onEnter: TransitionHookValidator,
|
|
onAfterEnter: TransitionHookValidator,
|
|
onEnterCancelled: TransitionHookValidator,
|
|
// leave
|
|
onBeforeLeave: TransitionHookValidator,
|
|
onLeave: TransitionHookValidator,
|
|
onAfterLeave: TransitionHookValidator,
|
|
onLeaveCancelled: TransitionHookValidator,
|
|
// appear
|
|
onBeforeAppear: TransitionHookValidator,
|
|
onAppear: TransitionHookValidator,
|
|
onAfterAppear: TransitionHookValidator,
|
|
onAppearCancelled: TransitionHookValidator
|
|
},
|
|
setup(props, { slots }) {
|
|
const instance = getCurrentInstance();
|
|
const state = useTransitionState();
|
|
let prevTransitionKey;
|
|
return () => {
|
|
const children = slots.default && getTransitionRawChildren(slots.default(), true);
|
|
if (!children || !children.length) {
|
|
return;
|
|
}
|
|
// warn multiple elements
|
|
if (( true) && children.length > 1) {
|
|
warn('<transition> can only be used on a single element or component. Use ' +
|
|
'<transition-group> for lists.');
|
|
}
|
|
// there's no need to track reactivity for these props so use the raw
|
|
// props for a bit better perf
|
|
const rawProps = (0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.toRaw)(props);
|
|
const { mode } = rawProps;
|
|
// check mode
|
|
if (( true) && mode && !['in-out', 'out-in', 'default'].includes(mode)) {
|
|
warn(`invalid <transition> mode: ${mode}`);
|
|
}
|
|
// at this point children has a guaranteed length of 1.
|
|
const child = children[0];
|
|
if (state.isLeaving) {
|
|
return emptyPlaceholder(child);
|
|
}
|
|
// in the case of <transition><keep-alive/></transition>, we need to
|
|
// compare the type of the kept-alive children.
|
|
const innerChild = getKeepAliveChild(child);
|
|
if (!innerChild) {
|
|
return emptyPlaceholder(child);
|
|
}
|
|
const enterHooks = resolveTransitionHooks(innerChild, rawProps, state, instance);
|
|
setTransitionHooks(innerChild, enterHooks);
|
|
const oldChild = instance.subTree;
|
|
const oldInnerChild = oldChild && getKeepAliveChild(oldChild);
|
|
let transitionKeyChanged = false;
|
|
const { getTransitionKey } = innerChild.type;
|
|
if (getTransitionKey) {
|
|
const key = getTransitionKey();
|
|
if (prevTransitionKey === undefined) {
|
|
prevTransitionKey = key;
|
|
}
|
|
else if (key !== prevTransitionKey) {
|
|
prevTransitionKey = key;
|
|
transitionKeyChanged = true;
|
|
}
|
|
}
|
|
// handle mode
|
|
if (oldInnerChild &&
|
|
oldInnerChild.type !== Comment$1 &&
|
|
(!isSameVNodeType(innerChild, oldInnerChild) || transitionKeyChanged)) {
|
|
const leavingHooks = resolveTransitionHooks(oldInnerChild, rawProps, state, instance);
|
|
// update old tree's hooks in case of dynamic transition
|
|
setTransitionHooks(oldInnerChild, leavingHooks);
|
|
// switching between different views
|
|
if (mode === 'out-in') {
|
|
state.isLeaving = true;
|
|
// return placeholder node and queue update when leave finishes
|
|
leavingHooks.afterLeave = () => {
|
|
state.isLeaving = false;
|
|
instance.update();
|
|
};
|
|
return emptyPlaceholder(child);
|
|
}
|
|
else if (mode === 'in-out' && innerChild.type !== Comment$1) {
|
|
leavingHooks.delayLeave = (el, earlyRemove, delayedLeave) => {
|
|
const leavingVNodesCache = getLeavingNodesForType(state, oldInnerChild);
|
|
leavingVNodesCache[String(oldInnerChild.key)] = oldInnerChild;
|
|
// early removal callback
|
|
el._leaveCb = () => {
|
|
earlyRemove();
|
|
el._leaveCb = undefined;
|
|
delete enterHooks.delayedLeave;
|
|
};
|
|
enterHooks.delayedLeave = delayedLeave;
|
|
};
|
|
}
|
|
}
|
|
return child;
|
|
};
|
|
}
|
|
};
|
|
// export the public type for h/tsx inference
|
|
// also to avoid inline import() in generated d.ts files
|
|
const BaseTransition = BaseTransitionImpl;
|
|
function getLeavingNodesForType(state, vnode) {
|
|
const { leavingVNodes } = state;
|
|
let leavingVNodesCache = leavingVNodes.get(vnode.type);
|
|
if (!leavingVNodesCache) {
|
|
leavingVNodesCache = Object.create(null);
|
|
leavingVNodes.set(vnode.type, leavingVNodesCache);
|
|
}
|
|
return leavingVNodesCache;
|
|
}
|
|
// The transition hooks are attached to the vnode as vnode.transition
|
|
// and will be called at appropriate timing in the renderer.
|
|
function resolveTransitionHooks(vnode, props, state, instance) {
|
|
const { appear, mode, persisted = false, onBeforeEnter, onEnter, onAfterEnter, onEnterCancelled, onBeforeLeave, onLeave, onAfterLeave, onLeaveCancelled, onBeforeAppear, onAppear, onAfterAppear, onAppearCancelled } = props;
|
|
const key = String(vnode.key);
|
|
const leavingVNodesCache = getLeavingNodesForType(state, vnode);
|
|
const callHook = (hook, args) => {
|
|
hook &&
|
|
callWithAsyncErrorHandling(hook, instance, 9 /* TRANSITION_HOOK */, args);
|
|
};
|
|
const hooks = {
|
|
mode,
|
|
persisted,
|
|
beforeEnter(el) {
|
|
let hook = onBeforeEnter;
|
|
if (!state.isMounted) {
|
|
if (appear) {
|
|
hook = onBeforeAppear || onBeforeEnter;
|
|
}
|
|
else {
|
|
return;
|
|
}
|
|
}
|
|
// for same element (v-show)
|
|
if (el._leaveCb) {
|
|
el._leaveCb(true /* cancelled */);
|
|
}
|
|
// for toggled element with same key (v-if)
|
|
const leavingVNode = leavingVNodesCache[key];
|
|
if (leavingVNode &&
|
|
isSameVNodeType(vnode, leavingVNode) &&
|
|
leavingVNode.el._leaveCb) {
|
|
// force early removal (not cancelled)
|
|
leavingVNode.el._leaveCb();
|
|
}
|
|
callHook(hook, [el]);
|
|
},
|
|
enter(el) {
|
|
let hook = onEnter;
|
|
let afterHook = onAfterEnter;
|
|
let cancelHook = onEnterCancelled;
|
|
if (!state.isMounted) {
|
|
if (appear) {
|
|
hook = onAppear || onEnter;
|
|
afterHook = onAfterAppear || onAfterEnter;
|
|
cancelHook = onAppearCancelled || onEnterCancelled;
|
|
}
|
|
else {
|
|
return;
|
|
}
|
|
}
|
|
let called = false;
|
|
const done = (el._enterCb = (cancelled) => {
|
|
if (called)
|
|
return;
|
|
called = true;
|
|
if (cancelled) {
|
|
callHook(cancelHook, [el]);
|
|
}
|
|
else {
|
|
callHook(afterHook, [el]);
|
|
}
|
|
if (hooks.delayedLeave) {
|
|
hooks.delayedLeave();
|
|
}
|
|
el._enterCb = undefined;
|
|
});
|
|
if (hook) {
|
|
hook(el, done);
|
|
if (hook.length <= 1) {
|
|
done();
|
|
}
|
|
}
|
|
else {
|
|
done();
|
|
}
|
|
},
|
|
leave(el, remove) {
|
|
const key = String(vnode.key);
|
|
if (el._enterCb) {
|
|
el._enterCb(true /* cancelled */);
|
|
}
|
|
if (state.isUnmounting) {
|
|
return remove();
|
|
}
|
|
callHook(onBeforeLeave, [el]);
|
|
let called = false;
|
|
const done = (el._leaveCb = (cancelled) => {
|
|
if (called)
|
|
return;
|
|
called = true;
|
|
remove();
|
|
if (cancelled) {
|
|
callHook(onLeaveCancelled, [el]);
|
|
}
|
|
else {
|
|
callHook(onAfterLeave, [el]);
|
|
}
|
|
el._leaveCb = undefined;
|
|
if (leavingVNodesCache[key] === vnode) {
|
|
delete leavingVNodesCache[key];
|
|
}
|
|
});
|
|
leavingVNodesCache[key] = vnode;
|
|
if (onLeave) {
|
|
onLeave(el, done);
|
|
if (onLeave.length <= 1) {
|
|
done();
|
|
}
|
|
}
|
|
else {
|
|
done();
|
|
}
|
|
},
|
|
clone(vnode) {
|
|
return resolveTransitionHooks(vnode, props, state, instance);
|
|
}
|
|
};
|
|
return hooks;
|
|
}
|
|
// the placeholder really only handles one special case: KeepAlive
|
|
// in the case of a KeepAlive in a leave phase we need to return a KeepAlive
|
|
// placeholder with empty content to avoid the KeepAlive instance from being
|
|
// unmounted.
|
|
function emptyPlaceholder(vnode) {
|
|
if (isKeepAlive(vnode)) {
|
|
vnode = cloneVNode(vnode);
|
|
vnode.children = null;
|
|
return vnode;
|
|
}
|
|
}
|
|
function getKeepAliveChild(vnode) {
|
|
return isKeepAlive(vnode)
|
|
? vnode.children
|
|
? vnode.children[0]
|
|
: undefined
|
|
: vnode;
|
|
}
|
|
function setTransitionHooks(vnode, hooks) {
|
|
if (vnode.shapeFlag & 6 /* COMPONENT */ && vnode.component) {
|
|
setTransitionHooks(vnode.component.subTree, hooks);
|
|
}
|
|
else if (vnode.shapeFlag & 128 /* SUSPENSE */) {
|
|
vnode.ssContent.transition = hooks.clone(vnode.ssContent);
|
|
vnode.ssFallback.transition = hooks.clone(vnode.ssFallback);
|
|
}
|
|
else {
|
|
vnode.transition = hooks;
|
|
}
|
|
}
|
|
function getTransitionRawChildren(children, keepComment = false) {
|
|
let ret = [];
|
|
let keyedFragmentCount = 0;
|
|
for (let i = 0; i < children.length; i++) {
|
|
const child = children[i];
|
|
// handle fragment children case, e.g. v-for
|
|
if (child.type === Fragment) {
|
|
if (child.patchFlag & 128 /* KEYED_FRAGMENT */)
|
|
keyedFragmentCount++;
|
|
ret = ret.concat(getTransitionRawChildren(child.children, keepComment));
|
|
}
|
|
// comment placeholders should be skipped, e.g. v-if
|
|
else if (keepComment || child.type !== Comment$1) {
|
|
ret.push(child);
|
|
}
|
|
}
|
|
// #1126 if a transition children list contains multiple sub fragments, these
|
|
// fragments will be merged into a flat children array. Since each v-for
|
|
// fragment may contain different static bindings inside, we need to de-op
|
|
// these children to force full diffs to ensure correct behavior.
|
|
if (keyedFragmentCount > 1) {
|
|
for (let i = 0; i < ret.length; i++) {
|
|
ret[i].patchFlag = -2 /* BAIL */;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
// implementation, close to no-op
|
|
function defineComponent(options) {
|
|
return (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isFunction)(options) ? { setup: options, name: options.name } : options;
|
|
}
|
|
|
|
const isAsyncWrapper = (i) => !!i.type.__asyncLoader;
|
|
function defineAsyncComponent(source) {
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isFunction)(source)) {
|
|
source = { loader: source };
|
|
}
|
|
const { loader, loadingComponent, errorComponent, delay = 200, timeout, // undefined = never times out
|
|
suspensible = true, onError: userOnError } = source;
|
|
let pendingRequest = null;
|
|
let resolvedComp;
|
|
let retries = 0;
|
|
const retry = () => {
|
|
retries++;
|
|
pendingRequest = null;
|
|
return load();
|
|
};
|
|
const load = () => {
|
|
let thisRequest;
|
|
return (pendingRequest ||
|
|
(thisRequest = pendingRequest =
|
|
loader()
|
|
.catch(err => {
|
|
err = err instanceof Error ? err : new Error(String(err));
|
|
if (userOnError) {
|
|
return new Promise((resolve, reject) => {
|
|
const userRetry = () => resolve(retry());
|
|
const userFail = () => reject(err);
|
|
userOnError(err, userRetry, userFail, retries + 1);
|
|
});
|
|
}
|
|
else {
|
|
throw err;
|
|
}
|
|
})
|
|
.then((comp) => {
|
|
if (thisRequest !== pendingRequest && pendingRequest) {
|
|
return pendingRequest;
|
|
}
|
|
if (( true) && !comp) {
|
|
warn(`Async component loader resolved to undefined. ` +
|
|
`If you are using retry(), make sure to return its return value.`);
|
|
}
|
|
// interop module default
|
|
if (comp &&
|
|
(comp.__esModule || comp[Symbol.toStringTag] === 'Module')) {
|
|
comp = comp.default;
|
|
}
|
|
if (( true) && comp && !(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isObject)(comp) && !(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isFunction)(comp)) {
|
|
throw new Error(`Invalid async component load result: ${comp}`);
|
|
}
|
|
resolvedComp = comp;
|
|
return comp;
|
|
})));
|
|
};
|
|
return defineComponent({
|
|
name: 'AsyncComponentWrapper',
|
|
__asyncLoader: load,
|
|
get __asyncResolved() {
|
|
return resolvedComp;
|
|
},
|
|
setup() {
|
|
const instance = currentInstance;
|
|
// already resolved
|
|
if (resolvedComp) {
|
|
return () => createInnerComp(resolvedComp, instance);
|
|
}
|
|
const onError = (err) => {
|
|
pendingRequest = null;
|
|
handleError(err, instance, 13 /* ASYNC_COMPONENT_LOADER */, !errorComponent /* do not throw in dev if user provided error component */);
|
|
};
|
|
// suspense-controlled or SSR.
|
|
if ((suspensible && instance.suspense) ||
|
|
(false )) {
|
|
return load()
|
|
.then(comp => {
|
|
return () => createInnerComp(comp, instance);
|
|
})
|
|
.catch(err => {
|
|
onError(err);
|
|
return () => errorComponent
|
|
? createVNode(errorComponent, {
|
|
error: err
|
|
})
|
|
: null;
|
|
});
|
|
}
|
|
const loaded = (0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.ref)(false);
|
|
const error = (0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.ref)();
|
|
const delayed = (0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.ref)(!!delay);
|
|
if (delay) {
|
|
setTimeout(() => {
|
|
delayed.value = false;
|
|
}, delay);
|
|
}
|
|
if (timeout != null) {
|
|
setTimeout(() => {
|
|
if (!loaded.value && !error.value) {
|
|
const err = new Error(`Async component timed out after ${timeout}ms.`);
|
|
onError(err);
|
|
error.value = err;
|
|
}
|
|
}, timeout);
|
|
}
|
|
load()
|
|
.then(() => {
|
|
loaded.value = true;
|
|
if (instance.parent && isKeepAlive(instance.parent.vnode)) {
|
|
// parent is keep-alive, force update so the loaded component's
|
|
// name is taken into account
|
|
queueJob(instance.parent.update);
|
|
}
|
|
})
|
|
.catch(err => {
|
|
onError(err);
|
|
error.value = err;
|
|
});
|
|
return () => {
|
|
if (loaded.value && resolvedComp) {
|
|
return createInnerComp(resolvedComp, instance);
|
|
}
|
|
else if (error.value && errorComponent) {
|
|
return createVNode(errorComponent, {
|
|
error: error.value
|
|
});
|
|
}
|
|
else if (loadingComponent && !delayed.value) {
|
|
return createVNode(loadingComponent);
|
|
}
|
|
};
|
|
}
|
|
});
|
|
}
|
|
function createInnerComp(comp, { vnode: { ref, props, children } }) {
|
|
const vnode = createVNode(comp, props, children);
|
|
// ensure inner component inherits the async wrapper's ref owner
|
|
vnode.ref = ref;
|
|
return vnode;
|
|
}
|
|
|
|
const isKeepAlive = (vnode) => vnode.type.__isKeepAlive;
|
|
const KeepAliveImpl = {
|
|
name: `KeepAlive`,
|
|
// Marker for special handling inside the renderer. We are not using a ===
|
|
// check directly on KeepAlive in the renderer, because importing it directly
|
|
// would prevent it from being tree-shaken.
|
|
__isKeepAlive: true,
|
|
props: {
|
|
include: [String, RegExp, Array],
|
|
exclude: [String, RegExp, Array],
|
|
max: [String, Number]
|
|
},
|
|
setup(props, { slots }) {
|
|
const instance = getCurrentInstance();
|
|
// KeepAlive communicates with the instantiated renderer via the
|
|
// ctx where the renderer passes in its internals,
|
|
// and the KeepAlive instance exposes activate/deactivate implementations.
|
|
// The whole point of this is to avoid importing KeepAlive directly in the
|
|
// renderer to facilitate tree-shaking.
|
|
const sharedContext = instance.ctx;
|
|
// if the internal renderer is not registered, it indicates that this is server-side rendering,
|
|
// for KeepAlive, we just need to render its children
|
|
if (!sharedContext.renderer) {
|
|
return slots.default;
|
|
}
|
|
const cache = new Map();
|
|
const keys = new Set();
|
|
let current = null;
|
|
if (true) {
|
|
instance.__v_cache = cache;
|
|
}
|
|
const parentSuspense = instance.suspense;
|
|
const { renderer: { p: patch, m: move, um: _unmount, o: { createElement } } } = sharedContext;
|
|
const storageContainer = createElement('div');
|
|
sharedContext.activate = (vnode, container, anchor, isSVG, optimized) => {
|
|
const instance = vnode.component;
|
|
move(vnode, container, anchor, 0 /* ENTER */, parentSuspense);
|
|
// in case props have changed
|
|
patch(instance.vnode, vnode, container, anchor, instance, parentSuspense, isSVG, vnode.slotScopeIds, optimized);
|
|
queuePostRenderEffect(() => {
|
|
instance.isDeactivated = false;
|
|
if (instance.a) {
|
|
(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.invokeArrayFns)(instance.a);
|
|
}
|
|
const vnodeHook = vnode.props && vnode.props.onVnodeMounted;
|
|
if (vnodeHook) {
|
|
invokeVNodeHook(vnodeHook, instance.parent, vnode);
|
|
}
|
|
}, parentSuspense);
|
|
if (true) {
|
|
// Update components tree
|
|
devtoolsComponentAdded(instance);
|
|
}
|
|
};
|
|
sharedContext.deactivate = (vnode) => {
|
|
const instance = vnode.component;
|
|
move(vnode, storageContainer, null, 1 /* LEAVE */, parentSuspense);
|
|
queuePostRenderEffect(() => {
|
|
if (instance.da) {
|
|
(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.invokeArrayFns)(instance.da);
|
|
}
|
|
const vnodeHook = vnode.props && vnode.props.onVnodeUnmounted;
|
|
if (vnodeHook) {
|
|
invokeVNodeHook(vnodeHook, instance.parent, vnode);
|
|
}
|
|
instance.isDeactivated = true;
|
|
}, parentSuspense);
|
|
if (true) {
|
|
// Update components tree
|
|
devtoolsComponentAdded(instance);
|
|
}
|
|
};
|
|
function unmount(vnode) {
|
|
// reset the shapeFlag so it can be properly unmounted
|
|
resetShapeFlag(vnode);
|
|
_unmount(vnode, instance, parentSuspense);
|
|
}
|
|
function pruneCache(filter) {
|
|
cache.forEach((vnode, key) => {
|
|
const name = getComponentName(vnode.type);
|
|
if (name && (!filter || !filter(name))) {
|
|
pruneCacheEntry(key);
|
|
}
|
|
});
|
|
}
|
|
function pruneCacheEntry(key) {
|
|
const cached = cache.get(key);
|
|
if (!current || cached.type !== current.type) {
|
|
unmount(cached);
|
|
}
|
|
else if (current) {
|
|
// current active instance should no longer be kept-alive.
|
|
// we can't unmount it now but it might be later, so reset its flag now.
|
|
resetShapeFlag(current);
|
|
}
|
|
cache.delete(key);
|
|
keys.delete(key);
|
|
}
|
|
// prune cache on include/exclude prop change
|
|
watch(() => [props.include, props.exclude], ([include, exclude]) => {
|
|
include && pruneCache(name => matches(include, name));
|
|
exclude && pruneCache(name => !matches(exclude, name));
|
|
},
|
|
// prune post-render after `current` has been updated
|
|
{ flush: 'post', deep: true });
|
|
// cache sub tree after render
|
|
let pendingCacheKey = null;
|
|
const cacheSubtree = () => {
|
|
// fix #1621, the pendingCacheKey could be 0
|
|
if (pendingCacheKey != null) {
|
|
cache.set(pendingCacheKey, getInnerChild(instance.subTree));
|
|
}
|
|
};
|
|
onMounted(cacheSubtree);
|
|
onUpdated(cacheSubtree);
|
|
onBeforeUnmount(() => {
|
|
cache.forEach(cached => {
|
|
const { subTree, suspense } = instance;
|
|
const vnode = getInnerChild(subTree);
|
|
if (cached.type === vnode.type) {
|
|
// current instance will be unmounted as part of keep-alive's unmount
|
|
resetShapeFlag(vnode);
|
|
// but invoke its deactivated hook here
|
|
const da = vnode.component.da;
|
|
da && queuePostRenderEffect(da, suspense);
|
|
return;
|
|
}
|
|
unmount(cached);
|
|
});
|
|
});
|
|
return () => {
|
|
pendingCacheKey = null;
|
|
if (!slots.default) {
|
|
return null;
|
|
}
|
|
const children = slots.default();
|
|
const rawVNode = children[0];
|
|
if (children.length > 1) {
|
|
if ((true)) {
|
|
warn(`KeepAlive should contain exactly one component child.`);
|
|
}
|
|
current = null;
|
|
return children;
|
|
}
|
|
else if (!isVNode(rawVNode) ||
|
|
(!(rawVNode.shapeFlag & 4 /* STATEFUL_COMPONENT */) &&
|
|
!(rawVNode.shapeFlag & 128 /* SUSPENSE */))) {
|
|
current = null;
|
|
return rawVNode;
|
|
}
|
|
let vnode = getInnerChild(rawVNode);
|
|
const comp = vnode.type;
|
|
// for async components, name check should be based in its loaded
|
|
// inner component if available
|
|
const name = getComponentName(isAsyncWrapper(vnode)
|
|
? vnode.type.__asyncResolved || {}
|
|
: comp);
|
|
const { include, exclude, max } = props;
|
|
if ((include && (!name || !matches(include, name))) ||
|
|
(exclude && name && matches(exclude, name))) {
|
|
current = vnode;
|
|
return rawVNode;
|
|
}
|
|
const key = vnode.key == null ? comp : vnode.key;
|
|
const cachedVNode = cache.get(key);
|
|
// clone vnode if it's reused because we are going to mutate it
|
|
if (vnode.el) {
|
|
vnode = cloneVNode(vnode);
|
|
if (rawVNode.shapeFlag & 128 /* SUSPENSE */) {
|
|
rawVNode.ssContent = vnode;
|
|
}
|
|
}
|
|
// #1513 it's possible for the returned vnode to be cloned due to attr
|
|
// fallthrough or scopeId, so the vnode here may not be the final vnode
|
|
// that is mounted. Instead of caching it directly, we store the pending
|
|
// key and cache `instance.subTree` (the normalized vnode) in
|
|
// beforeMount/beforeUpdate hooks.
|
|
pendingCacheKey = key;
|
|
if (cachedVNode) {
|
|
// copy over mounted state
|
|
vnode.el = cachedVNode.el;
|
|
vnode.component = cachedVNode.component;
|
|
if (vnode.transition) {
|
|
// recursively update transition hooks on subTree
|
|
setTransitionHooks(vnode, vnode.transition);
|
|
}
|
|
// avoid vnode being mounted as fresh
|
|
vnode.shapeFlag |= 512 /* COMPONENT_KEPT_ALIVE */;
|
|
// make this key the freshest
|
|
keys.delete(key);
|
|
keys.add(key);
|
|
}
|
|
else {
|
|
keys.add(key);
|
|
// prune oldest entry
|
|
if (max && keys.size > parseInt(max, 10)) {
|
|
pruneCacheEntry(keys.values().next().value);
|
|
}
|
|
}
|
|
// avoid vnode being unmounted
|
|
vnode.shapeFlag |= 256 /* COMPONENT_SHOULD_KEEP_ALIVE */;
|
|
current = vnode;
|
|
return rawVNode;
|
|
};
|
|
}
|
|
};
|
|
// export the public type for h/tsx inference
|
|
// also to avoid inline import() in generated d.ts files
|
|
const KeepAlive = KeepAliveImpl;
|
|
function matches(pattern, name) {
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isArray)(pattern)) {
|
|
return pattern.some((p) => matches(p, name));
|
|
}
|
|
else if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isString)(pattern)) {
|
|
return pattern.split(',').indexOf(name) > -1;
|
|
}
|
|
else if (pattern.test) {
|
|
return pattern.test(name);
|
|
}
|
|
/* istanbul ignore next */
|
|
return false;
|
|
}
|
|
function onActivated(hook, target) {
|
|
registerKeepAliveHook(hook, "a" /* ACTIVATED */, target);
|
|
}
|
|
function onDeactivated(hook, target) {
|
|
registerKeepAliveHook(hook, "da" /* DEACTIVATED */, target);
|
|
}
|
|
function registerKeepAliveHook(hook, type, target = currentInstance) {
|
|
// cache the deactivate branch check wrapper for injected hooks so the same
|
|
// hook can be properly deduped by the scheduler. "__wdc" stands for "with
|
|
// deactivation check".
|
|
const wrappedHook = hook.__wdc ||
|
|
(hook.__wdc = () => {
|
|
// only fire the hook if the target instance is NOT in a deactivated branch.
|
|
let current = target;
|
|
while (current) {
|
|
if (current.isDeactivated) {
|
|
return;
|
|
}
|
|
current = current.parent;
|
|
}
|
|
hook();
|
|
});
|
|
injectHook(type, wrappedHook, target);
|
|
// In addition to registering it on the target instance, we walk up the parent
|
|
// chain and register it on all ancestor instances that are keep-alive roots.
|
|
// This avoids the need to walk the entire component tree when invoking these
|
|
// hooks, and more importantly, avoids the need to track child components in
|
|
// arrays.
|
|
if (target) {
|
|
let current = target.parent;
|
|
while (current && current.parent) {
|
|
if (isKeepAlive(current.parent.vnode)) {
|
|
injectToKeepAliveRoot(wrappedHook, type, target, current);
|
|
}
|
|
current = current.parent;
|
|
}
|
|
}
|
|
}
|
|
function injectToKeepAliveRoot(hook, type, target, keepAliveRoot) {
|
|
// injectHook wraps the original for error handling, so make sure to remove
|
|
// the wrapped version.
|
|
const injected = injectHook(type, hook, keepAliveRoot, true /* prepend */);
|
|
onUnmounted(() => {
|
|
(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.remove)(keepAliveRoot[type], injected);
|
|
}, target);
|
|
}
|
|
function resetShapeFlag(vnode) {
|
|
let shapeFlag = vnode.shapeFlag;
|
|
if (shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */) {
|
|
shapeFlag -= 256 /* COMPONENT_SHOULD_KEEP_ALIVE */;
|
|
}
|
|
if (shapeFlag & 512 /* COMPONENT_KEPT_ALIVE */) {
|
|
shapeFlag -= 512 /* COMPONENT_KEPT_ALIVE */;
|
|
}
|
|
vnode.shapeFlag = shapeFlag;
|
|
}
|
|
function getInnerChild(vnode) {
|
|
return vnode.shapeFlag & 128 /* SUSPENSE */ ? vnode.ssContent : vnode;
|
|
}
|
|
|
|
function injectHook(type, hook, target = currentInstance, prepend = false) {
|
|
if (target) {
|
|
const hooks = target[type] || (target[type] = []);
|
|
// cache the error handling wrapper for injected hooks so the same hook
|
|
// can be properly deduped by the scheduler. "__weh" stands for "with error
|
|
// handling".
|
|
const wrappedHook = hook.__weh ||
|
|
(hook.__weh = (...args) => {
|
|
if (target.isUnmounted) {
|
|
return;
|
|
}
|
|
// disable tracking inside all lifecycle hooks
|
|
// since they can potentially be called inside effects.
|
|
(0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.pauseTracking)();
|
|
// Set currentInstance during hook invocation.
|
|
// This assumes the hook does not synchronously trigger other hooks, which
|
|
// can only be false when the user does something really funky.
|
|
setCurrentInstance(target);
|
|
const res = callWithAsyncErrorHandling(hook, target, type, args);
|
|
unsetCurrentInstance();
|
|
(0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.resetTracking)();
|
|
return res;
|
|
});
|
|
if (prepend) {
|
|
hooks.unshift(wrappedHook);
|
|
}
|
|
else {
|
|
hooks.push(wrappedHook);
|
|
}
|
|
return wrappedHook;
|
|
}
|
|
else if ((true)) {
|
|
const apiName = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.toHandlerKey)(ErrorTypeStrings[type].replace(/ hook$/, ''));
|
|
warn(`${apiName} is called when there is no active component instance to be ` +
|
|
`associated with. ` +
|
|
`Lifecycle injection APIs can only be used during execution of setup().` +
|
|
(` If you are using async setup(), make sure to register lifecycle ` +
|
|
`hooks before the first await statement.`
|
|
));
|
|
}
|
|
}
|
|
const createHook = (lifecycle) => (hook, target = currentInstance) =>
|
|
// post-create lifecycle registrations are noops during SSR (except for serverPrefetch)
|
|
(!isInSSRComponentSetup || lifecycle === "sp" /* SERVER_PREFETCH */) &&
|
|
injectHook(lifecycle, hook, target);
|
|
const onBeforeMount = createHook("bm" /* BEFORE_MOUNT */);
|
|
const onMounted = createHook("m" /* MOUNTED */);
|
|
const onBeforeUpdate = createHook("bu" /* BEFORE_UPDATE */);
|
|
const onUpdated = createHook("u" /* UPDATED */);
|
|
const onBeforeUnmount = createHook("bum" /* BEFORE_UNMOUNT */);
|
|
const onUnmounted = createHook("um" /* UNMOUNTED */);
|
|
const onServerPrefetch = createHook("sp" /* SERVER_PREFETCH */);
|
|
const onRenderTriggered = createHook("rtg" /* RENDER_TRIGGERED */);
|
|
const onRenderTracked = createHook("rtc" /* RENDER_TRACKED */);
|
|
function onErrorCaptured(hook, target = currentInstance) {
|
|
injectHook("ec" /* ERROR_CAPTURED */, hook, target);
|
|
}
|
|
|
|
function createDuplicateChecker() {
|
|
const cache = Object.create(null);
|
|
return (type, key) => {
|
|
if (cache[key]) {
|
|
warn(`${type} property "${key}" is already defined in ${cache[key]}.`);
|
|
}
|
|
else {
|
|
cache[key] = type;
|
|
}
|
|
};
|
|
}
|
|
let shouldCacheAccess = true;
|
|
function applyOptions(instance) {
|
|
const options = resolveMergedOptions(instance);
|
|
const publicThis = instance.proxy;
|
|
const ctx = instance.ctx;
|
|
// do not cache property access on public proxy during state initialization
|
|
shouldCacheAccess = false;
|
|
// call beforeCreate first before accessing other options since
|
|
// the hook may mutate resolved options (#2791)
|
|
if (options.beforeCreate) {
|
|
callHook(options.beforeCreate, instance, "bc" /* BEFORE_CREATE */);
|
|
}
|
|
const {
|
|
// state
|
|
data: dataOptions, computed: computedOptions, methods, watch: watchOptions, provide: provideOptions, inject: injectOptions,
|
|
// lifecycle
|
|
created, beforeMount, mounted, beforeUpdate, updated, activated, deactivated, beforeDestroy, beforeUnmount, destroyed, unmounted, render, renderTracked, renderTriggered, errorCaptured, serverPrefetch,
|
|
// public API
|
|
expose, inheritAttrs,
|
|
// assets
|
|
components, directives, filters } = options;
|
|
const checkDuplicateProperties = ( true) ? createDuplicateChecker() : 0;
|
|
if ((true)) {
|
|
const [propsOptions] = instance.propsOptions;
|
|
if (propsOptions) {
|
|
for (const key in propsOptions) {
|
|
checkDuplicateProperties("Props" /* PROPS */, key);
|
|
}
|
|
}
|
|
}
|
|
// options initialization order (to be consistent with Vue 2):
|
|
// - props (already done outside of this function)
|
|
// - inject
|
|
// - methods
|
|
// - data (deferred since it relies on `this` access)
|
|
// - computed
|
|
// - watch (deferred since it relies on `this` access)
|
|
if (injectOptions) {
|
|
resolveInjections(injectOptions, ctx, checkDuplicateProperties, instance.appContext.config.unwrapInjectedRef);
|
|
}
|
|
if (methods) {
|
|
for (const key in methods) {
|
|
const methodHandler = methods[key];
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isFunction)(methodHandler)) {
|
|
// In dev mode, we use the `createRenderContext` function to define
|
|
// methods to the proxy target, and those are read-only but
|
|
// reconfigurable, so it needs to be redefined here
|
|
if ((true)) {
|
|
Object.defineProperty(ctx, key, {
|
|
value: methodHandler.bind(publicThis),
|
|
configurable: true,
|
|
enumerable: true,
|
|
writable: true
|
|
});
|
|
}
|
|
else {}
|
|
if ((true)) {
|
|
checkDuplicateProperties("Methods" /* METHODS */, key);
|
|
}
|
|
}
|
|
else if ((true)) {
|
|
warn(`Method "${key}" has type "${typeof methodHandler}" in the component definition. ` +
|
|
`Did you reference the function correctly?`);
|
|
}
|
|
}
|
|
}
|
|
if (dataOptions) {
|
|
if (( true) && !(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isFunction)(dataOptions)) {
|
|
warn(`The data option must be a function. ` +
|
|
`Plain object usage is no longer supported.`);
|
|
}
|
|
const data = dataOptions.call(publicThis, publicThis);
|
|
if (( true) && (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isPromise)(data)) {
|
|
warn(`data() returned a Promise - note data() cannot be async; If you ` +
|
|
`intend to perform data fetching before component renders, use ` +
|
|
`async setup() + <Suspense>.`);
|
|
}
|
|
if (!(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isObject)(data)) {
|
|
( true) && warn(`data() should return an object.`);
|
|
}
|
|
else {
|
|
instance.data = (0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.reactive)(data);
|
|
if ((true)) {
|
|
for (const key in data) {
|
|
checkDuplicateProperties("Data" /* DATA */, key);
|
|
// expose data on ctx during dev
|
|
if (key[0] !== '$' && key[0] !== '_') {
|
|
Object.defineProperty(ctx, key, {
|
|
configurable: true,
|
|
enumerable: true,
|
|
get: () => data[key],
|
|
set: _vue_shared__WEBPACK_IMPORTED_MODULE_1__.NOOP
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// state initialization complete at this point - start caching access
|
|
shouldCacheAccess = true;
|
|
if (computedOptions) {
|
|
for (const key in computedOptions) {
|
|
const opt = computedOptions[key];
|
|
const get = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isFunction)(opt)
|
|
? opt.bind(publicThis, publicThis)
|
|
: (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isFunction)(opt.get)
|
|
? opt.get.bind(publicThis, publicThis)
|
|
: _vue_shared__WEBPACK_IMPORTED_MODULE_1__.NOOP;
|
|
if (( true) && get === _vue_shared__WEBPACK_IMPORTED_MODULE_1__.NOOP) {
|
|
warn(`Computed property "${key}" has no getter.`);
|
|
}
|
|
const set = !(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isFunction)(opt) && (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isFunction)(opt.set)
|
|
? opt.set.bind(publicThis)
|
|
: ( true)
|
|
? () => {
|
|
warn(`Write operation failed: computed property "${key}" is readonly.`);
|
|
}
|
|
: 0;
|
|
const c = (0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.computed)({
|
|
get,
|
|
set
|
|
});
|
|
Object.defineProperty(ctx, key, {
|
|
enumerable: true,
|
|
configurable: true,
|
|
get: () => c.value,
|
|
set: v => (c.value = v)
|
|
});
|
|
if ((true)) {
|
|
checkDuplicateProperties("Computed" /* COMPUTED */, key);
|
|
}
|
|
}
|
|
}
|
|
if (watchOptions) {
|
|
for (const key in watchOptions) {
|
|
createWatcher(watchOptions[key], ctx, publicThis, key);
|
|
}
|
|
}
|
|
if (provideOptions) {
|
|
const provides = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isFunction)(provideOptions)
|
|
? provideOptions.call(publicThis)
|
|
: provideOptions;
|
|
Reflect.ownKeys(provides).forEach(key => {
|
|
provide(key, provides[key]);
|
|
});
|
|
}
|
|
if (created) {
|
|
callHook(created, instance, "c" /* CREATED */);
|
|
}
|
|
function registerLifecycleHook(register, hook) {
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isArray)(hook)) {
|
|
hook.forEach(_hook => register(_hook.bind(publicThis)));
|
|
}
|
|
else if (hook) {
|
|
register(hook.bind(publicThis));
|
|
}
|
|
}
|
|
registerLifecycleHook(onBeforeMount, beforeMount);
|
|
registerLifecycleHook(onMounted, mounted);
|
|
registerLifecycleHook(onBeforeUpdate, beforeUpdate);
|
|
registerLifecycleHook(onUpdated, updated);
|
|
registerLifecycleHook(onActivated, activated);
|
|
registerLifecycleHook(onDeactivated, deactivated);
|
|
registerLifecycleHook(onErrorCaptured, errorCaptured);
|
|
registerLifecycleHook(onRenderTracked, renderTracked);
|
|
registerLifecycleHook(onRenderTriggered, renderTriggered);
|
|
registerLifecycleHook(onBeforeUnmount, beforeUnmount);
|
|
registerLifecycleHook(onUnmounted, unmounted);
|
|
registerLifecycleHook(onServerPrefetch, serverPrefetch);
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isArray)(expose)) {
|
|
if (expose.length) {
|
|
const exposed = instance.exposed || (instance.exposed = {});
|
|
expose.forEach(key => {
|
|
Object.defineProperty(exposed, key, {
|
|
get: () => publicThis[key],
|
|
set: val => (publicThis[key] = val)
|
|
});
|
|
});
|
|
}
|
|
else if (!instance.exposed) {
|
|
instance.exposed = {};
|
|
}
|
|
}
|
|
// options that are handled when creating the instance but also need to be
|
|
// applied from mixins
|
|
if (render && instance.render === _vue_shared__WEBPACK_IMPORTED_MODULE_1__.NOOP) {
|
|
instance.render = render;
|
|
}
|
|
if (inheritAttrs != null) {
|
|
instance.inheritAttrs = inheritAttrs;
|
|
}
|
|
// asset options.
|
|
if (components)
|
|
instance.components = components;
|
|
if (directives)
|
|
instance.directives = directives;
|
|
}
|
|
function resolveInjections(injectOptions, ctx, checkDuplicateProperties = _vue_shared__WEBPACK_IMPORTED_MODULE_1__.NOOP, unwrapRef = false) {
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isArray)(injectOptions)) {
|
|
injectOptions = normalizeInject(injectOptions);
|
|
}
|
|
for (const key in injectOptions) {
|
|
const opt = injectOptions[key];
|
|
let injected;
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isObject)(opt)) {
|
|
if ('default' in opt) {
|
|
injected = inject(opt.from || key, opt.default, true /* treat default function as factory */);
|
|
}
|
|
else {
|
|
injected = inject(opt.from || key);
|
|
}
|
|
}
|
|
else {
|
|
injected = inject(opt);
|
|
}
|
|
if ((0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.isRef)(injected)) {
|
|
// TODO remove the check in 3.3
|
|
if (unwrapRef) {
|
|
Object.defineProperty(ctx, key, {
|
|
enumerable: true,
|
|
configurable: true,
|
|
get: () => injected.value,
|
|
set: v => (injected.value = v)
|
|
});
|
|
}
|
|
else {
|
|
if ((true)) {
|
|
warn(`injected property "${key}" is a ref and will be auto-unwrapped ` +
|
|
`and no longer needs \`.value\` in the next minor release. ` +
|
|
`To opt-in to the new behavior now, ` +
|
|
`set \`app.config.unwrapInjectedRef = true\` (this config is ` +
|
|
`temporary and will not be needed in the future.)`);
|
|
}
|
|
ctx[key] = injected;
|
|
}
|
|
}
|
|
else {
|
|
ctx[key] = injected;
|
|
}
|
|
if ((true)) {
|
|
checkDuplicateProperties("Inject" /* INJECT */, key);
|
|
}
|
|
}
|
|
}
|
|
function callHook(hook, instance, type) {
|
|
callWithAsyncErrorHandling((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isArray)(hook)
|
|
? hook.map(h => h.bind(instance.proxy))
|
|
: hook.bind(instance.proxy), instance, type);
|
|
}
|
|
function createWatcher(raw, ctx, publicThis, key) {
|
|
const getter = key.includes('.')
|
|
? createPathGetter(publicThis, key)
|
|
: () => publicThis[key];
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isString)(raw)) {
|
|
const handler = ctx[raw];
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isFunction)(handler)) {
|
|
watch(getter, handler);
|
|
}
|
|
else if ((true)) {
|
|
warn(`Invalid watch handler specified by key "${raw}"`, handler);
|
|
}
|
|
}
|
|
else if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isFunction)(raw)) {
|
|
watch(getter, raw.bind(publicThis));
|
|
}
|
|
else if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isObject)(raw)) {
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isArray)(raw)) {
|
|
raw.forEach(r => createWatcher(r, ctx, publicThis, key));
|
|
}
|
|
else {
|
|
const handler = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isFunction)(raw.handler)
|
|
? raw.handler.bind(publicThis)
|
|
: ctx[raw.handler];
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isFunction)(handler)) {
|
|
watch(getter, handler, raw);
|
|
}
|
|
else if ((true)) {
|
|
warn(`Invalid watch handler specified by key "${raw.handler}"`, handler);
|
|
}
|
|
}
|
|
}
|
|
else if ((true)) {
|
|
warn(`Invalid watch option: "${key}"`, raw);
|
|
}
|
|
}
|
|
/**
|
|
* Resolve merged options and cache it on the component.
|
|
* This is done only once per-component since the merging does not involve
|
|
* instances.
|
|
*/
|
|
function resolveMergedOptions(instance) {
|
|
const base = instance.type;
|
|
const { mixins, extends: extendsOptions } = base;
|
|
const { mixins: globalMixins, optionsCache: cache, config: { optionMergeStrategies } } = instance.appContext;
|
|
const cached = cache.get(base);
|
|
let resolved;
|
|
if (cached) {
|
|
resolved = cached;
|
|
}
|
|
else if (!globalMixins.length && !mixins && !extendsOptions) {
|
|
{
|
|
resolved = base;
|
|
}
|
|
}
|
|
else {
|
|
resolved = {};
|
|
if (globalMixins.length) {
|
|
globalMixins.forEach(m => mergeOptions(resolved, m, optionMergeStrategies, true));
|
|
}
|
|
mergeOptions(resolved, base, optionMergeStrategies);
|
|
}
|
|
cache.set(base, resolved);
|
|
return resolved;
|
|
}
|
|
function mergeOptions(to, from, strats, asMixin = false) {
|
|
const { mixins, extends: extendsOptions } = from;
|
|
if (extendsOptions) {
|
|
mergeOptions(to, extendsOptions, strats, true);
|
|
}
|
|
if (mixins) {
|
|
mixins.forEach((m) => mergeOptions(to, m, strats, true));
|
|
}
|
|
for (const key in from) {
|
|
if (asMixin && key === 'expose') {
|
|
( true) &&
|
|
warn(`"expose" option is ignored when declared in mixins or extends. ` +
|
|
`It should only be declared in the base component itself.`);
|
|
}
|
|
else {
|
|
const strat = internalOptionMergeStrats[key] || (strats && strats[key]);
|
|
to[key] = strat ? strat(to[key], from[key]) : from[key];
|
|
}
|
|
}
|
|
return to;
|
|
}
|
|
const internalOptionMergeStrats = {
|
|
data: mergeDataFn,
|
|
props: mergeObjectOptions,
|
|
emits: mergeObjectOptions,
|
|
// objects
|
|
methods: mergeObjectOptions,
|
|
computed: mergeObjectOptions,
|
|
// lifecycle
|
|
beforeCreate: mergeAsArray,
|
|
created: mergeAsArray,
|
|
beforeMount: mergeAsArray,
|
|
mounted: mergeAsArray,
|
|
beforeUpdate: mergeAsArray,
|
|
updated: mergeAsArray,
|
|
beforeDestroy: mergeAsArray,
|
|
destroyed: mergeAsArray,
|
|
activated: mergeAsArray,
|
|
deactivated: mergeAsArray,
|
|
errorCaptured: mergeAsArray,
|
|
serverPrefetch: mergeAsArray,
|
|
// assets
|
|
components: mergeObjectOptions,
|
|
directives: mergeObjectOptions,
|
|
// watch
|
|
watch: mergeWatchOptions,
|
|
// provide / inject
|
|
provide: mergeDataFn,
|
|
inject: mergeInject
|
|
};
|
|
function mergeDataFn(to, from) {
|
|
if (!from) {
|
|
return to;
|
|
}
|
|
if (!to) {
|
|
return from;
|
|
}
|
|
return function mergedDataFn() {
|
|
return ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.extend))((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isFunction)(to) ? to.call(this, this) : to, (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isFunction)(from) ? from.call(this, this) : from);
|
|
};
|
|
}
|
|
function mergeInject(to, from) {
|
|
return mergeObjectOptions(normalizeInject(to), normalizeInject(from));
|
|
}
|
|
function normalizeInject(raw) {
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isArray)(raw)) {
|
|
const res = {};
|
|
for (let i = 0; i < raw.length; i++) {
|
|
res[raw[i]] = raw[i];
|
|
}
|
|
return res;
|
|
}
|
|
return raw;
|
|
}
|
|
function mergeAsArray(to, from) {
|
|
return to ? [...new Set([].concat(to, from))] : from;
|
|
}
|
|
function mergeObjectOptions(to, from) {
|
|
return to ? (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.extend)((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.extend)(Object.create(null), to), from) : from;
|
|
}
|
|
function mergeWatchOptions(to, from) {
|
|
if (!to)
|
|
return from;
|
|
if (!from)
|
|
return to;
|
|
const merged = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.extend)(Object.create(null), to);
|
|
for (const key in from) {
|
|
merged[key] = mergeAsArray(to[key], from[key]);
|
|
}
|
|
return merged;
|
|
}
|
|
|
|
function initProps(instance, rawProps, isStateful, // result of bitwise flag comparison
|
|
isSSR = false) {
|
|
const props = {};
|
|
const attrs = {};
|
|
(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.def)(attrs, InternalObjectKey, 1);
|
|
instance.propsDefaults = Object.create(null);
|
|
setFullProps(instance, rawProps, props, attrs);
|
|
// ensure all declared prop keys are present
|
|
for (const key in instance.propsOptions[0]) {
|
|
if (!(key in props)) {
|
|
props[key] = undefined;
|
|
}
|
|
}
|
|
// validation
|
|
if ((true)) {
|
|
validateProps(rawProps || {}, props, instance);
|
|
}
|
|
if (isStateful) {
|
|
// stateful
|
|
instance.props = isSSR ? props : (0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.shallowReactive)(props);
|
|
}
|
|
else {
|
|
if (!instance.type.props) {
|
|
// functional w/ optional props, props === attrs
|
|
instance.props = attrs;
|
|
}
|
|
else {
|
|
// functional w/ declared props
|
|
instance.props = props;
|
|
}
|
|
}
|
|
instance.attrs = attrs;
|
|
}
|
|
function updateProps(instance, rawProps, rawPrevProps, optimized) {
|
|
const { props, attrs, vnode: { patchFlag } } = instance;
|
|
const rawCurrentProps = (0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.toRaw)(props);
|
|
const [options] = instance.propsOptions;
|
|
let hasAttrsChanged = false;
|
|
if (
|
|
// always force full diff in dev
|
|
// - #1942 if hmr is enabled with sfc component
|
|
// - vite#872 non-sfc component used by sfc component
|
|
!(( true) &&
|
|
(instance.type.__hmrId ||
|
|
(instance.parent && instance.parent.type.__hmrId))) &&
|
|
(optimized || patchFlag > 0) &&
|
|
!(patchFlag & 16 /* FULL_PROPS */)) {
|
|
if (patchFlag & 8 /* PROPS */) {
|
|
// Compiler-generated props & no keys change, just set the updated
|
|
// the props.
|
|
const propsToUpdate = instance.vnode.dynamicProps;
|
|
for (let i = 0; i < propsToUpdate.length; i++) {
|
|
let key = propsToUpdate[i];
|
|
// PROPS flag guarantees rawProps to be non-null
|
|
const value = rawProps[key];
|
|
if (options) {
|
|
// attr / props separation was done on init and will be consistent
|
|
// in this code path, so just check if attrs have it.
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.hasOwn)(attrs, key)) {
|
|
if (value !== attrs[key]) {
|
|
attrs[key] = value;
|
|
hasAttrsChanged = true;
|
|
}
|
|
}
|
|
else {
|
|
const camelizedKey = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.camelize)(key);
|
|
props[camelizedKey] = resolvePropValue(options, rawCurrentProps, camelizedKey, value, instance, false /* isAbsent */);
|
|
}
|
|
}
|
|
else {
|
|
if (value !== attrs[key]) {
|
|
attrs[key] = value;
|
|
hasAttrsChanged = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
// full props update.
|
|
if (setFullProps(instance, rawProps, props, attrs)) {
|
|
hasAttrsChanged = true;
|
|
}
|
|
// in case of dynamic props, check if we need to delete keys from
|
|
// the props object
|
|
let kebabKey;
|
|
for (const key in rawCurrentProps) {
|
|
if (!rawProps ||
|
|
// for camelCase
|
|
(!(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.hasOwn)(rawProps, key) &&
|
|
// it's possible the original props was passed in as kebab-case
|
|
// and converted to camelCase (#955)
|
|
((kebabKey = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.hyphenate)(key)) === key || !(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.hasOwn)(rawProps, kebabKey)))) {
|
|
if (options) {
|
|
if (rawPrevProps &&
|
|
// for camelCase
|
|
(rawPrevProps[key] !== undefined ||
|
|
// for kebab-case
|
|
rawPrevProps[kebabKey] !== undefined)) {
|
|
props[key] = resolvePropValue(options, rawCurrentProps, key, undefined, instance, true /* isAbsent */);
|
|
}
|
|
}
|
|
else {
|
|
delete props[key];
|
|
}
|
|
}
|
|
}
|
|
// in the case of functional component w/o props declaration, props and
|
|
// attrs point to the same object so it should already have been updated.
|
|
if (attrs !== rawCurrentProps) {
|
|
for (const key in attrs) {
|
|
if (!rawProps || !(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.hasOwn)(rawProps, key)) {
|
|
delete attrs[key];
|
|
hasAttrsChanged = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// trigger updates for $attrs in case it's used in component slots
|
|
if (hasAttrsChanged) {
|
|
(0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.trigger)(instance, "set" /* SET */, '$attrs');
|
|
}
|
|
if ((true)) {
|
|
validateProps(rawProps || {}, props, instance);
|
|
}
|
|
}
|
|
function setFullProps(instance, rawProps, props, attrs) {
|
|
const [options, needCastKeys] = instance.propsOptions;
|
|
let hasAttrsChanged = false;
|
|
let rawCastValues;
|
|
if (rawProps) {
|
|
for (let key in rawProps) {
|
|
// key, ref are reserved and never passed down
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isReservedProp)(key)) {
|
|
continue;
|
|
}
|
|
const value = rawProps[key];
|
|
// prop option names are camelized during normalization, so to support
|
|
// kebab -> camel conversion here we need to camelize the key.
|
|
let camelKey;
|
|
if (options && (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.hasOwn)(options, (camelKey = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.camelize)(key)))) {
|
|
if (!needCastKeys || !needCastKeys.includes(camelKey)) {
|
|
props[camelKey] = value;
|
|
}
|
|
else {
|
|
(rawCastValues || (rawCastValues = {}))[camelKey] = value;
|
|
}
|
|
}
|
|
else if (!isEmitListener(instance.emitsOptions, key)) {
|
|
if (value !== attrs[key]) {
|
|
attrs[key] = value;
|
|
hasAttrsChanged = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (needCastKeys) {
|
|
const rawCurrentProps = (0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.toRaw)(props);
|
|
const castValues = rawCastValues || _vue_shared__WEBPACK_IMPORTED_MODULE_1__.EMPTY_OBJ;
|
|
for (let i = 0; i < needCastKeys.length; i++) {
|
|
const key = needCastKeys[i];
|
|
props[key] = resolvePropValue(options, rawCurrentProps, key, castValues[key], instance, !(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.hasOwn)(castValues, key));
|
|
}
|
|
}
|
|
return hasAttrsChanged;
|
|
}
|
|
function resolvePropValue(options, props, key, value, instance, isAbsent) {
|
|
const opt = options[key];
|
|
if (opt != null) {
|
|
const hasDefault = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.hasOwn)(opt, 'default');
|
|
// default values
|
|
if (hasDefault && value === undefined) {
|
|
const defaultValue = opt.default;
|
|
if (opt.type !== Function && (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isFunction)(defaultValue)) {
|
|
const { propsDefaults } = instance;
|
|
if (key in propsDefaults) {
|
|
value = propsDefaults[key];
|
|
}
|
|
else {
|
|
setCurrentInstance(instance);
|
|
value = propsDefaults[key] = defaultValue.call(null, props);
|
|
unsetCurrentInstance();
|
|
}
|
|
}
|
|
else {
|
|
value = defaultValue;
|
|
}
|
|
}
|
|
// boolean casting
|
|
if (opt[0 /* shouldCast */]) {
|
|
if (isAbsent && !hasDefault) {
|
|
value = false;
|
|
}
|
|
else if (opt[1 /* shouldCastTrue */] &&
|
|
(value === '' || value === (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.hyphenate)(key))) {
|
|
value = true;
|
|
}
|
|
}
|
|
}
|
|
return value;
|
|
}
|
|
function normalizePropsOptions(comp, appContext, asMixin = false) {
|
|
const cache = appContext.propsCache;
|
|
const cached = cache.get(comp);
|
|
if (cached) {
|
|
return cached;
|
|
}
|
|
const raw = comp.props;
|
|
const normalized = {};
|
|
const needCastKeys = [];
|
|
// apply mixin/extends props
|
|
let hasExtends = false;
|
|
if (__VUE_OPTIONS_API__ && !(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isFunction)(comp)) {
|
|
const extendProps = (raw) => {
|
|
hasExtends = true;
|
|
const [props, keys] = normalizePropsOptions(raw, appContext, true);
|
|
(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.extend)(normalized, props);
|
|
if (keys)
|
|
needCastKeys.push(...keys);
|
|
};
|
|
if (!asMixin && appContext.mixins.length) {
|
|
appContext.mixins.forEach(extendProps);
|
|
}
|
|
if (comp.extends) {
|
|
extendProps(comp.extends);
|
|
}
|
|
if (comp.mixins) {
|
|
comp.mixins.forEach(extendProps);
|
|
}
|
|
}
|
|
if (!raw && !hasExtends) {
|
|
cache.set(comp, _vue_shared__WEBPACK_IMPORTED_MODULE_1__.EMPTY_ARR);
|
|
return _vue_shared__WEBPACK_IMPORTED_MODULE_1__.EMPTY_ARR;
|
|
}
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isArray)(raw)) {
|
|
for (let i = 0; i < raw.length; i++) {
|
|
if (( true) && !(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isString)(raw[i])) {
|
|
warn(`props must be strings when using array syntax.`, raw[i]);
|
|
}
|
|
const normalizedKey = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.camelize)(raw[i]);
|
|
if (validatePropName(normalizedKey)) {
|
|
normalized[normalizedKey] = _vue_shared__WEBPACK_IMPORTED_MODULE_1__.EMPTY_OBJ;
|
|
}
|
|
}
|
|
}
|
|
else if (raw) {
|
|
if (( true) && !(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isObject)(raw)) {
|
|
warn(`invalid props options`, raw);
|
|
}
|
|
for (const key in raw) {
|
|
const normalizedKey = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.camelize)(key);
|
|
if (validatePropName(normalizedKey)) {
|
|
const opt = raw[key];
|
|
const prop = (normalized[normalizedKey] =
|
|
(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isArray)(opt) || (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isFunction)(opt) ? { type: opt } : opt);
|
|
if (prop) {
|
|
const booleanIndex = getTypeIndex(Boolean, prop.type);
|
|
const stringIndex = getTypeIndex(String, prop.type);
|
|
prop[0 /* shouldCast */] = booleanIndex > -1;
|
|
prop[1 /* shouldCastTrue */] =
|
|
stringIndex < 0 || booleanIndex < stringIndex;
|
|
// if the prop needs boolean casting or default value
|
|
if (booleanIndex > -1 || (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.hasOwn)(prop, 'default')) {
|
|
needCastKeys.push(normalizedKey);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
const res = [normalized, needCastKeys];
|
|
cache.set(comp, res);
|
|
return res;
|
|
}
|
|
function validatePropName(key) {
|
|
if (key[0] !== '$') {
|
|
return true;
|
|
}
|
|
else if ((true)) {
|
|
warn(`Invalid prop name: "${key}" is a reserved property.`);
|
|
}
|
|
return false;
|
|
}
|
|
// use function string name to check type constructors
|
|
// so that it works across vms / iframes.
|
|
function getType(ctor) {
|
|
const match = ctor && ctor.toString().match(/^\s*function (\w+)/);
|
|
return match ? match[1] : ctor === null ? 'null' : '';
|
|
}
|
|
function isSameType(a, b) {
|
|
return getType(a) === getType(b);
|
|
}
|
|
function getTypeIndex(type, expectedTypes) {
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isArray)(expectedTypes)) {
|
|
return expectedTypes.findIndex(t => isSameType(t, type));
|
|
}
|
|
else if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isFunction)(expectedTypes)) {
|
|
return isSameType(expectedTypes, type) ? 0 : -1;
|
|
}
|
|
return -1;
|
|
}
|
|
/**
|
|
* dev only
|
|
*/
|
|
function validateProps(rawProps, props, instance) {
|
|
const resolvedValues = (0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.toRaw)(props);
|
|
const options = instance.propsOptions[0];
|
|
for (const key in options) {
|
|
let opt = options[key];
|
|
if (opt == null)
|
|
continue;
|
|
validateProp(key, resolvedValues[key], opt, !(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.hasOwn)(rawProps, key) && !(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.hasOwn)(rawProps, (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.hyphenate)(key)));
|
|
}
|
|
}
|
|
/**
|
|
* dev only
|
|
*/
|
|
function validateProp(name, value, prop, isAbsent) {
|
|
const { type, required, validator } = prop;
|
|
// required!
|
|
if (required && isAbsent) {
|
|
warn('Missing required prop: "' + name + '"');
|
|
return;
|
|
}
|
|
// missing but optional
|
|
if (value == null && !prop.required) {
|
|
return;
|
|
}
|
|
// type check
|
|
if (type != null && type !== true) {
|
|
let isValid = false;
|
|
const types = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isArray)(type) ? type : [type];
|
|
const expectedTypes = [];
|
|
// value is valid as long as one of the specified types match
|
|
for (let i = 0; i < types.length && !isValid; i++) {
|
|
const { valid, expectedType } = assertType(value, types[i]);
|
|
expectedTypes.push(expectedType || '');
|
|
isValid = valid;
|
|
}
|
|
if (!isValid) {
|
|
warn(getInvalidTypeMessage(name, value, expectedTypes));
|
|
return;
|
|
}
|
|
}
|
|
// custom validator
|
|
if (validator && !validator(value)) {
|
|
warn('Invalid prop: custom validator check failed for prop "' + name + '".');
|
|
}
|
|
}
|
|
const isSimpleType = /*#__PURE__*/ (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.makeMap)('String,Number,Boolean,Function,Symbol,BigInt');
|
|
/**
|
|
* dev only
|
|
*/
|
|
function assertType(value, type) {
|
|
let valid;
|
|
const expectedType = getType(type);
|
|
if (isSimpleType(expectedType)) {
|
|
const t = typeof value;
|
|
valid = t === expectedType.toLowerCase();
|
|
// for primitive wrapper objects
|
|
if (!valid && t === 'object') {
|
|
valid = value instanceof type;
|
|
}
|
|
}
|
|
else if (expectedType === 'Object') {
|
|
valid = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isObject)(value);
|
|
}
|
|
else if (expectedType === 'Array') {
|
|
valid = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isArray)(value);
|
|
}
|
|
else if (expectedType === 'null') {
|
|
valid = value === null;
|
|
}
|
|
else {
|
|
valid = value instanceof type;
|
|
}
|
|
return {
|
|
valid,
|
|
expectedType
|
|
};
|
|
}
|
|
/**
|
|
* dev only
|
|
*/
|
|
function getInvalidTypeMessage(name, value, expectedTypes) {
|
|
let message = `Invalid prop: type check failed for prop "${name}".` +
|
|
` Expected ${expectedTypes.map(_vue_shared__WEBPACK_IMPORTED_MODULE_1__.capitalize).join(' | ')}`;
|
|
const expectedType = expectedTypes[0];
|
|
const receivedType = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.toRawType)(value);
|
|
const expectedValue = styleValue(value, expectedType);
|
|
const receivedValue = styleValue(value, receivedType);
|
|
// check if we need to specify expected value
|
|
if (expectedTypes.length === 1 &&
|
|
isExplicable(expectedType) &&
|
|
!isBoolean(expectedType, receivedType)) {
|
|
message += ` with value ${expectedValue}`;
|
|
}
|
|
message += `, got ${receivedType} `;
|
|
// check if we need to specify received value
|
|
if (isExplicable(receivedType)) {
|
|
message += `with value ${receivedValue}.`;
|
|
}
|
|
return message;
|
|
}
|
|
/**
|
|
* dev only
|
|
*/
|
|
function styleValue(value, type) {
|
|
if (type === 'String') {
|
|
return `"${value}"`;
|
|
}
|
|
else if (type === 'Number') {
|
|
return `${Number(value)}`;
|
|
}
|
|
else {
|
|
return `${value}`;
|
|
}
|
|
}
|
|
/**
|
|
* dev only
|
|
*/
|
|
function isExplicable(type) {
|
|
const explicitTypes = ['string', 'number', 'boolean'];
|
|
return explicitTypes.some(elem => type.toLowerCase() === elem);
|
|
}
|
|
/**
|
|
* dev only
|
|
*/
|
|
function isBoolean(...args) {
|
|
return args.some(elem => elem.toLowerCase() === 'boolean');
|
|
}
|
|
|
|
const isInternalKey = (key) => key[0] === '_' || key === '$stable';
|
|
const normalizeSlotValue = (value) => (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isArray)(value)
|
|
? value.map(normalizeVNode)
|
|
: [normalizeVNode(value)];
|
|
const normalizeSlot = (key, rawSlot, ctx) => {
|
|
const normalized = withCtx((...args) => {
|
|
if (( true) && currentInstance) {
|
|
warn(`Slot "${key}" invoked outside of the render function: ` +
|
|
`this will not track dependencies used in the slot. ` +
|
|
`Invoke the slot function inside the render function instead.`);
|
|
}
|
|
return normalizeSlotValue(rawSlot(...args));
|
|
}, ctx);
|
|
normalized._c = false;
|
|
return normalized;
|
|
};
|
|
const normalizeObjectSlots = (rawSlots, slots, instance) => {
|
|
const ctx = rawSlots._ctx;
|
|
for (const key in rawSlots) {
|
|
if (isInternalKey(key))
|
|
continue;
|
|
const value = rawSlots[key];
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isFunction)(value)) {
|
|
slots[key] = normalizeSlot(key, value, ctx);
|
|
}
|
|
else if (value != null) {
|
|
if (true) {
|
|
warn(`Non-function value encountered for slot "${key}". ` +
|
|
`Prefer function slots for better performance.`);
|
|
}
|
|
const normalized = normalizeSlotValue(value);
|
|
slots[key] = () => normalized;
|
|
}
|
|
}
|
|
};
|
|
const normalizeVNodeSlots = (instance, children) => {
|
|
if (( true) &&
|
|
!isKeepAlive(instance.vnode) &&
|
|
!(false )) {
|
|
warn(`Non-function value encountered for default slot. ` +
|
|
`Prefer function slots for better performance.`);
|
|
}
|
|
const normalized = normalizeSlotValue(children);
|
|
instance.slots.default = () => normalized;
|
|
};
|
|
const initSlots = (instance, children) => {
|
|
if (instance.vnode.shapeFlag & 32 /* SLOTS_CHILDREN */) {
|
|
const type = children._;
|
|
if (type) {
|
|
// users can get the shallow readonly version of the slots object through `this.$slots`,
|
|
// we should avoid the proxy object polluting the slots of the internal instance
|
|
instance.slots = (0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.toRaw)(children);
|
|
// make compiler marker non-enumerable
|
|
(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.def)(children, '_', type);
|
|
}
|
|
else {
|
|
normalizeObjectSlots(children, (instance.slots = {}));
|
|
}
|
|
}
|
|
else {
|
|
instance.slots = {};
|
|
if (children) {
|
|
normalizeVNodeSlots(instance, children);
|
|
}
|
|
}
|
|
(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.def)(instance.slots, InternalObjectKey, 1);
|
|
};
|
|
const updateSlots = (instance, children, optimized) => {
|
|
const { vnode, slots } = instance;
|
|
let needDeletionCheck = true;
|
|
let deletionComparisonTarget = _vue_shared__WEBPACK_IMPORTED_MODULE_1__.EMPTY_OBJ;
|
|
if (vnode.shapeFlag & 32 /* SLOTS_CHILDREN */) {
|
|
const type = children._;
|
|
if (type) {
|
|
// compiled slots.
|
|
if (( true) && isHmrUpdating) {
|
|
// Parent was HMR updated so slot content may have changed.
|
|
// force update slots and mark instance for hmr as well
|
|
(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.extend)(slots, children);
|
|
}
|
|
else if (optimized && type === 1 /* STABLE */) {
|
|
// compiled AND stable.
|
|
// no need to update, and skip stale slots removal.
|
|
needDeletionCheck = false;
|
|
}
|
|
else {
|
|
// compiled but dynamic (v-if/v-for on slots) - update slots, but skip
|
|
// normalization.
|
|
(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.extend)(slots, children);
|
|
// #2893
|
|
// when rendering the optimized slots by manually written render function,
|
|
// we need to delete the `slots._` flag if necessary to make subsequent updates reliable,
|
|
// i.e. let the `renderSlot` create the bailed Fragment
|
|
if (!optimized && type === 1 /* STABLE */) {
|
|
delete slots._;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
needDeletionCheck = !children.$stable;
|
|
normalizeObjectSlots(children, slots);
|
|
}
|
|
deletionComparisonTarget = children;
|
|
}
|
|
else if (children) {
|
|
// non slot object children (direct value) passed to a component
|
|
normalizeVNodeSlots(instance, children);
|
|
deletionComparisonTarget = { default: 1 };
|
|
}
|
|
// delete stale slots
|
|
if (needDeletionCheck) {
|
|
for (const key in slots) {
|
|
if (!isInternalKey(key) && !(key in deletionComparisonTarget)) {
|
|
delete slots[key];
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
/**
|
|
Runtime helper for applying directives to a vnode. Example usage:
|
|
|
|
const comp = resolveComponent('comp')
|
|
const foo = resolveDirective('foo')
|
|
const bar = resolveDirective('bar')
|
|
|
|
return withDirectives(h(comp), [
|
|
[foo, this.x],
|
|
[bar, this.y]
|
|
])
|
|
*/
|
|
const isBuiltInDirective = /*#__PURE__*/ (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.makeMap)('bind,cloak,else-if,else,for,html,if,model,on,once,pre,show,slot,text');
|
|
function validateDirectiveName(name) {
|
|
if (isBuiltInDirective(name)) {
|
|
warn('Do not use built-in directive ids as custom directive id: ' + name);
|
|
}
|
|
}
|
|
/**
|
|
* Adds directives to a VNode.
|
|
*/
|
|
function withDirectives(vnode, directives) {
|
|
const internalInstance = currentRenderingInstance;
|
|
if (internalInstance === null) {
|
|
( true) && warn(`withDirectives can only be used inside render functions.`);
|
|
return vnode;
|
|
}
|
|
const instance = internalInstance.proxy;
|
|
const bindings = vnode.dirs || (vnode.dirs = []);
|
|
for (let i = 0; i < directives.length; i++) {
|
|
let [dir, value, arg, modifiers = _vue_shared__WEBPACK_IMPORTED_MODULE_1__.EMPTY_OBJ] = directives[i];
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isFunction)(dir)) {
|
|
dir = {
|
|
mounted: dir,
|
|
updated: dir
|
|
};
|
|
}
|
|
if (dir.deep) {
|
|
traverse(value);
|
|
}
|
|
bindings.push({
|
|
dir,
|
|
instance,
|
|
value,
|
|
oldValue: void 0,
|
|
arg,
|
|
modifiers
|
|
});
|
|
}
|
|
return vnode;
|
|
}
|
|
function invokeDirectiveHook(vnode, prevVNode, instance, name) {
|
|
const bindings = vnode.dirs;
|
|
const oldBindings = prevVNode && prevVNode.dirs;
|
|
for (let i = 0; i < bindings.length; i++) {
|
|
const binding = bindings[i];
|
|
if (oldBindings) {
|
|
binding.oldValue = oldBindings[i].value;
|
|
}
|
|
let hook = binding.dir[name];
|
|
if (hook) {
|
|
// disable tracking inside all lifecycle hooks
|
|
// since they can potentially be called inside effects.
|
|
(0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.pauseTracking)();
|
|
callWithAsyncErrorHandling(hook, instance, 8 /* DIRECTIVE_HOOK */, [
|
|
vnode.el,
|
|
binding,
|
|
vnode,
|
|
prevVNode
|
|
]);
|
|
(0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.resetTracking)();
|
|
}
|
|
}
|
|
}
|
|
|
|
function createAppContext() {
|
|
return {
|
|
app: null,
|
|
config: {
|
|
isNativeTag: _vue_shared__WEBPACK_IMPORTED_MODULE_1__.NO,
|
|
performance: false,
|
|
globalProperties: {},
|
|
optionMergeStrategies: {},
|
|
errorHandler: undefined,
|
|
warnHandler: undefined,
|
|
compilerOptions: {}
|
|
},
|
|
mixins: [],
|
|
components: {},
|
|
directives: {},
|
|
provides: Object.create(null),
|
|
optionsCache: new WeakMap(),
|
|
propsCache: new WeakMap(),
|
|
emitsCache: new WeakMap()
|
|
};
|
|
}
|
|
let uid = 0;
|
|
function createAppAPI(render, hydrate) {
|
|
return function createApp(rootComponent, rootProps = null) {
|
|
if (rootProps != null && !(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isObject)(rootProps)) {
|
|
( true) && warn(`root props passed to app.mount() must be an object.`);
|
|
rootProps = null;
|
|
}
|
|
const context = createAppContext();
|
|
const installedPlugins = new Set();
|
|
let isMounted = false;
|
|
const app = (context.app = {
|
|
_uid: uid++,
|
|
_component: rootComponent,
|
|
_props: rootProps,
|
|
_container: null,
|
|
_context: context,
|
|
_instance: null,
|
|
version,
|
|
get config() {
|
|
return context.config;
|
|
},
|
|
set config(v) {
|
|
if ((true)) {
|
|
warn(`app.config cannot be replaced. Modify individual options instead.`);
|
|
}
|
|
},
|
|
use(plugin, ...options) {
|
|
if (installedPlugins.has(plugin)) {
|
|
( true) && warn(`Plugin has already been applied to target app.`);
|
|
}
|
|
else if (plugin && (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isFunction)(plugin.install)) {
|
|
installedPlugins.add(plugin);
|
|
plugin.install(app, ...options);
|
|
}
|
|
else if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isFunction)(plugin)) {
|
|
installedPlugins.add(plugin);
|
|
plugin(app, ...options);
|
|
}
|
|
else if ((true)) {
|
|
warn(`A plugin must either be a function or an object with an "install" ` +
|
|
`function.`);
|
|
}
|
|
return app;
|
|
},
|
|
mixin(mixin) {
|
|
if (__VUE_OPTIONS_API__) {
|
|
if (!context.mixins.includes(mixin)) {
|
|
context.mixins.push(mixin);
|
|
}
|
|
else if ((true)) {
|
|
warn('Mixin has already been applied to target app' +
|
|
(mixin.name ? `: ${mixin.name}` : ''));
|
|
}
|
|
}
|
|
else if ((true)) {
|
|
warn('Mixins are only available in builds supporting Options API');
|
|
}
|
|
return app;
|
|
},
|
|
component(name, component) {
|
|
if ((true)) {
|
|
validateComponentName(name, context.config);
|
|
}
|
|
if (!component) {
|
|
return context.components[name];
|
|
}
|
|
if (( true) && context.components[name]) {
|
|
warn(`Component "${name}" has already been registered in target app.`);
|
|
}
|
|
context.components[name] = component;
|
|
return app;
|
|
},
|
|
directive(name, directive) {
|
|
if ((true)) {
|
|
validateDirectiveName(name);
|
|
}
|
|
if (!directive) {
|
|
return context.directives[name];
|
|
}
|
|
if (( true) && context.directives[name]) {
|
|
warn(`Directive "${name}" has already been registered in target app.`);
|
|
}
|
|
context.directives[name] = directive;
|
|
return app;
|
|
},
|
|
mount(rootContainer, isHydrate, isSVG) {
|
|
if (!isMounted) {
|
|
const vnode = createVNode(rootComponent, rootProps);
|
|
// store app context on the root VNode.
|
|
// this will be set on the root instance on initial mount.
|
|
vnode.appContext = context;
|
|
// HMR root reload
|
|
if ((true)) {
|
|
context.reload = () => {
|
|
render(cloneVNode(vnode), rootContainer, isSVG);
|
|
};
|
|
}
|
|
if (isHydrate && hydrate) {
|
|
hydrate(vnode, rootContainer);
|
|
}
|
|
else {
|
|
render(vnode, rootContainer, isSVG);
|
|
}
|
|
isMounted = true;
|
|
app._container = rootContainer;
|
|
rootContainer.__vue_app__ = app;
|
|
if (true) {
|
|
app._instance = vnode.component;
|
|
devtoolsInitApp(app, version);
|
|
}
|
|
return vnode.component.proxy;
|
|
}
|
|
else if ((true)) {
|
|
warn(`App has already been mounted.\n` +
|
|
`If you want to remount the same app, move your app creation logic ` +
|
|
`into a factory function and create fresh app instances for each ` +
|
|
`mount - e.g. \`const createMyApp = () => createApp(App)\``);
|
|
}
|
|
},
|
|
unmount() {
|
|
if (isMounted) {
|
|
render(null, app._container);
|
|
if (true) {
|
|
app._instance = null;
|
|
devtoolsUnmountApp(app);
|
|
}
|
|
delete app._container.__vue_app__;
|
|
}
|
|
else if ((true)) {
|
|
warn(`Cannot unmount an app that is not mounted.`);
|
|
}
|
|
},
|
|
provide(key, value) {
|
|
if (( true) && key in context.provides) {
|
|
warn(`App already provides property with key "${String(key)}". ` +
|
|
`It will be overwritten with the new value.`);
|
|
}
|
|
// TypeScript doesn't allow symbols as index type
|
|
// https://github.com/Microsoft/TypeScript/issues/24587
|
|
context.provides[key] = value;
|
|
return app;
|
|
}
|
|
});
|
|
return app;
|
|
};
|
|
}
|
|
|
|
let hasMismatch = false;
|
|
const isSVGContainer = (container) => /svg/.test(container.namespaceURI) && container.tagName !== 'foreignObject';
|
|
const isComment = (node) => node.nodeType === 8 /* COMMENT */;
|
|
// Note: hydration is DOM-specific
|
|
// But we have to place it in core due to tight coupling with core - splitting
|
|
// it out creates a ton of unnecessary complexity.
|
|
// Hydration also depends on some renderer internal logic which needs to be
|
|
// passed in via arguments.
|
|
function createHydrationFunctions(rendererInternals) {
|
|
const { mt: mountComponent, p: patch, o: { patchProp, nextSibling, parentNode, remove, insert, createComment } } = rendererInternals;
|
|
const hydrate = (vnode, container) => {
|
|
if (!container.hasChildNodes()) {
|
|
( true) &&
|
|
warn(`Attempting to hydrate existing markup but container is empty. ` +
|
|
`Performing full mount instead.`);
|
|
patch(null, vnode, container);
|
|
flushPostFlushCbs();
|
|
return;
|
|
}
|
|
hasMismatch = false;
|
|
hydrateNode(container.firstChild, vnode, null, null, null);
|
|
flushPostFlushCbs();
|
|
if (hasMismatch && !false) {
|
|
// this error should show up in production
|
|
console.error(`Hydration completed but contains mismatches.`);
|
|
}
|
|
};
|
|
const hydrateNode = (node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized = false) => {
|
|
const isFragmentStart = isComment(node) && node.data === '[';
|
|
const onMismatch = () => handleMismatch(node, vnode, parentComponent, parentSuspense, slotScopeIds, isFragmentStart);
|
|
const { type, ref, shapeFlag } = vnode;
|
|
const domType = node.nodeType;
|
|
vnode.el = node;
|
|
let nextNode = null;
|
|
switch (type) {
|
|
case Text:
|
|
if (domType !== 3 /* TEXT */) {
|
|
nextNode = onMismatch();
|
|
}
|
|
else {
|
|
if (node.data !== vnode.children) {
|
|
hasMismatch = true;
|
|
( true) &&
|
|
warn(`Hydration text mismatch:` +
|
|
`\n- Client: ${JSON.stringify(node.data)}` +
|
|
`\n- Server: ${JSON.stringify(vnode.children)}`);
|
|
node.data = vnode.children;
|
|
}
|
|
nextNode = nextSibling(node);
|
|
}
|
|
break;
|
|
case Comment$1:
|
|
if (domType !== 8 /* COMMENT */ || isFragmentStart) {
|
|
nextNode = onMismatch();
|
|
}
|
|
else {
|
|
nextNode = nextSibling(node);
|
|
}
|
|
break;
|
|
case Static:
|
|
if (domType !== 1 /* ELEMENT */) {
|
|
nextNode = onMismatch();
|
|
}
|
|
else {
|
|
// determine anchor, adopt content
|
|
nextNode = node;
|
|
// if the static vnode has its content stripped during build,
|
|
// adopt it from the server-rendered HTML.
|
|
const needToAdoptContent = !vnode.children.length;
|
|
for (let i = 0; i < vnode.staticCount; i++) {
|
|
if (needToAdoptContent)
|
|
vnode.children += nextNode.outerHTML;
|
|
if (i === vnode.staticCount - 1) {
|
|
vnode.anchor = nextNode;
|
|
}
|
|
nextNode = nextSibling(nextNode);
|
|
}
|
|
return nextNode;
|
|
}
|
|
break;
|
|
case Fragment:
|
|
if (!isFragmentStart) {
|
|
nextNode = onMismatch();
|
|
}
|
|
else {
|
|
nextNode = hydrateFragment(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized);
|
|
}
|
|
break;
|
|
default:
|
|
if (shapeFlag & 1 /* ELEMENT */) {
|
|
if (domType !== 1 /* ELEMENT */ ||
|
|
vnode.type.toLowerCase() !==
|
|
node.tagName.toLowerCase()) {
|
|
nextNode = onMismatch();
|
|
}
|
|
else {
|
|
nextNode = hydrateElement(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized);
|
|
}
|
|
}
|
|
else if (shapeFlag & 6 /* COMPONENT */) {
|
|
// when setting up the render effect, if the initial vnode already
|
|
// has .el set, the component will perform hydration instead of mount
|
|
// on its sub-tree.
|
|
vnode.slotScopeIds = slotScopeIds;
|
|
const container = parentNode(node);
|
|
mountComponent(vnode, container, null, parentComponent, parentSuspense, isSVGContainer(container), optimized);
|
|
// component may be async, so in the case of fragments we cannot rely
|
|
// on component's rendered output to determine the end of the fragment
|
|
// instead, we do a lookahead to find the end anchor node.
|
|
nextNode = isFragmentStart
|
|
? locateClosingAsyncAnchor(node)
|
|
: nextSibling(node);
|
|
// #3787
|
|
// if component is async, it may get moved / unmounted before its
|
|
// inner component is loaded, so we need to give it a placeholder
|
|
// vnode that matches its adopted DOM.
|
|
if (isAsyncWrapper(vnode)) {
|
|
let subTree;
|
|
if (isFragmentStart) {
|
|
subTree = createVNode(Fragment);
|
|
subTree.anchor = nextNode
|
|
? nextNode.previousSibling
|
|
: container.lastChild;
|
|
}
|
|
else {
|
|
subTree =
|
|
node.nodeType === 3 ? createTextVNode('') : createVNode('div');
|
|
}
|
|
subTree.el = node;
|
|
vnode.component.subTree = subTree;
|
|
}
|
|
}
|
|
else if (shapeFlag & 64 /* TELEPORT */) {
|
|
if (domType !== 8 /* COMMENT */) {
|
|
nextNode = onMismatch();
|
|
}
|
|
else {
|
|
nextNode = vnode.type.hydrate(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized, rendererInternals, hydrateChildren);
|
|
}
|
|
}
|
|
else if (shapeFlag & 128 /* SUSPENSE */) {
|
|
nextNode = vnode.type.hydrate(node, vnode, parentComponent, parentSuspense, isSVGContainer(parentNode(node)), slotScopeIds, optimized, rendererInternals, hydrateNode);
|
|
}
|
|
else if ((true)) {
|
|
warn('Invalid HostVNode type:', type, `(${typeof type})`);
|
|
}
|
|
}
|
|
if (ref != null) {
|
|
setRef(ref, null, parentSuspense, vnode);
|
|
}
|
|
return nextNode;
|
|
};
|
|
const hydrateElement = (el, vnode, parentComponent, parentSuspense, slotScopeIds, optimized) => {
|
|
optimized = optimized || !!vnode.dynamicChildren;
|
|
const { type, props, patchFlag, shapeFlag, dirs } = vnode;
|
|
// #4006 for form elements with non-string v-model value bindings
|
|
// e.g. <option :value="obj">, <input type="checkbox" :true-value="1">
|
|
const forcePatchValue = (type === 'input' && dirs) || type === 'option';
|
|
// skip props & children if this is hoisted static nodes
|
|
if (forcePatchValue || patchFlag !== -1 /* HOISTED */) {
|
|
if (dirs) {
|
|
invokeDirectiveHook(vnode, null, parentComponent, 'created');
|
|
}
|
|
// props
|
|
if (props) {
|
|
if (forcePatchValue ||
|
|
!optimized ||
|
|
patchFlag & (16 /* FULL_PROPS */ | 32 /* HYDRATE_EVENTS */)) {
|
|
for (const key in props) {
|
|
if ((forcePatchValue && key.endsWith('value')) ||
|
|
((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isOn)(key) && !(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isReservedProp)(key))) {
|
|
patchProp(el, key, null, props[key]);
|
|
}
|
|
}
|
|
}
|
|
else if (props.onClick) {
|
|
// Fast path for click listeners (which is most often) to avoid
|
|
// iterating through props.
|
|
patchProp(el, 'onClick', null, props.onClick);
|
|
}
|
|
}
|
|
// vnode / directive hooks
|
|
let vnodeHooks;
|
|
if ((vnodeHooks = props && props.onVnodeBeforeMount)) {
|
|
invokeVNodeHook(vnodeHooks, parentComponent, vnode);
|
|
}
|
|
if (dirs) {
|
|
invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount');
|
|
}
|
|
if ((vnodeHooks = props && props.onVnodeMounted) || dirs) {
|
|
queueEffectWithSuspense(() => {
|
|
vnodeHooks && invokeVNodeHook(vnodeHooks, parentComponent, vnode);
|
|
dirs && invokeDirectiveHook(vnode, null, parentComponent, 'mounted');
|
|
}, parentSuspense);
|
|
}
|
|
// children
|
|
if (shapeFlag & 16 /* ARRAY_CHILDREN */ &&
|
|
// skip if element has innerHTML / textContent
|
|
!(props && (props.innerHTML || props.textContent))) {
|
|
let next = hydrateChildren(el.firstChild, vnode, el, parentComponent, parentSuspense, slotScopeIds, optimized);
|
|
let hasWarned = false;
|
|
while (next) {
|
|
hasMismatch = true;
|
|
if (( true) && !hasWarned) {
|
|
warn(`Hydration children mismatch in <${vnode.type}>: ` +
|
|
`server rendered element contains more child nodes than client vdom.`);
|
|
hasWarned = true;
|
|
}
|
|
// The SSRed DOM contains more nodes than it should. Remove them.
|
|
const cur = next;
|
|
next = next.nextSibling;
|
|
remove(cur);
|
|
}
|
|
}
|
|
else if (shapeFlag & 8 /* TEXT_CHILDREN */) {
|
|
if (el.textContent !== vnode.children) {
|
|
hasMismatch = true;
|
|
( true) &&
|
|
warn(`Hydration text content mismatch in <${vnode.type}>:\n` +
|
|
`- Client: ${el.textContent}\n` +
|
|
`- Server: ${vnode.children}`);
|
|
el.textContent = vnode.children;
|
|
}
|
|
}
|
|
}
|
|
return el.nextSibling;
|
|
};
|
|
const hydrateChildren = (node, parentVNode, container, parentComponent, parentSuspense, slotScopeIds, optimized) => {
|
|
optimized = optimized || !!parentVNode.dynamicChildren;
|
|
const children = parentVNode.children;
|
|
const l = children.length;
|
|
let hasWarned = false;
|
|
for (let i = 0; i < l; i++) {
|
|
const vnode = optimized
|
|
? children[i]
|
|
: (children[i] = normalizeVNode(children[i]));
|
|
if (node) {
|
|
node = hydrateNode(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized);
|
|
}
|
|
else if (vnode.type === Text && !vnode.children) {
|
|
continue;
|
|
}
|
|
else {
|
|
hasMismatch = true;
|
|
if (( true) && !hasWarned) {
|
|
warn(`Hydration children mismatch in <${container.tagName.toLowerCase()}>: ` +
|
|
`server rendered element contains fewer child nodes than client vdom.`);
|
|
hasWarned = true;
|
|
}
|
|
// the SSRed DOM didn't contain enough nodes. Mount the missing ones.
|
|
patch(null, vnode, container, null, parentComponent, parentSuspense, isSVGContainer(container), slotScopeIds);
|
|
}
|
|
}
|
|
return node;
|
|
};
|
|
const hydrateFragment = (node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized) => {
|
|
const { slotScopeIds: fragmentSlotScopeIds } = vnode;
|
|
if (fragmentSlotScopeIds) {
|
|
slotScopeIds = slotScopeIds
|
|
? slotScopeIds.concat(fragmentSlotScopeIds)
|
|
: fragmentSlotScopeIds;
|
|
}
|
|
const container = parentNode(node);
|
|
const next = hydrateChildren(nextSibling(node), vnode, container, parentComponent, parentSuspense, slotScopeIds, optimized);
|
|
if (next && isComment(next) && next.data === ']') {
|
|
return nextSibling((vnode.anchor = next));
|
|
}
|
|
else {
|
|
// fragment didn't hydrate successfully, since we didn't get a end anchor
|
|
// back. This should have led to node/children mismatch warnings.
|
|
hasMismatch = true;
|
|
// since the anchor is missing, we need to create one and insert it
|
|
insert((vnode.anchor = createComment(`]`)), container, next);
|
|
return next;
|
|
}
|
|
};
|
|
const handleMismatch = (node, vnode, parentComponent, parentSuspense, slotScopeIds, isFragment) => {
|
|
hasMismatch = true;
|
|
( true) &&
|
|
warn(`Hydration node mismatch:\n- Client vnode:`, vnode.type, `\n- Server rendered DOM:`, node, node.nodeType === 3 /* TEXT */
|
|
? `(text)`
|
|
: isComment(node) && node.data === '['
|
|
? `(start of fragment)`
|
|
: ``);
|
|
vnode.el = null;
|
|
if (isFragment) {
|
|
// remove excessive fragment nodes
|
|
const end = locateClosingAsyncAnchor(node);
|
|
while (true) {
|
|
const next = nextSibling(node);
|
|
if (next && next !== end) {
|
|
remove(next);
|
|
}
|
|
else {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
const next = nextSibling(node);
|
|
const container = parentNode(node);
|
|
remove(node);
|
|
patch(null, vnode, container, next, parentComponent, parentSuspense, isSVGContainer(container), slotScopeIds);
|
|
return next;
|
|
};
|
|
const locateClosingAsyncAnchor = (node) => {
|
|
let match = 0;
|
|
while (node) {
|
|
node = nextSibling(node);
|
|
if (node && isComment(node)) {
|
|
if (node.data === '[')
|
|
match++;
|
|
if (node.data === ']') {
|
|
if (match === 0) {
|
|
return nextSibling(node);
|
|
}
|
|
else {
|
|
match--;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return node;
|
|
};
|
|
return [hydrate, hydrateNode];
|
|
}
|
|
|
|
let supported;
|
|
let perf;
|
|
function startMeasure(instance, type) {
|
|
if (instance.appContext.config.performance && isSupported()) {
|
|
perf.mark(`vue-${type}-${instance.uid}`);
|
|
}
|
|
if (true) {
|
|
devtoolsPerfStart(instance, type, supported ? perf.now() : Date.now());
|
|
}
|
|
}
|
|
function endMeasure(instance, type) {
|
|
if (instance.appContext.config.performance && isSupported()) {
|
|
const startTag = `vue-${type}-${instance.uid}`;
|
|
const endTag = startTag + `:end`;
|
|
perf.mark(endTag);
|
|
perf.measure(`<${formatComponentName(instance, instance.type)}> ${type}`, startTag, endTag);
|
|
perf.clearMarks(startTag);
|
|
perf.clearMarks(endTag);
|
|
}
|
|
if (true) {
|
|
devtoolsPerfEnd(instance, type, supported ? perf.now() : Date.now());
|
|
}
|
|
}
|
|
function isSupported() {
|
|
if (supported !== undefined) {
|
|
return supported;
|
|
}
|
|
/* eslint-disable no-restricted-globals */
|
|
if (typeof window !== 'undefined' && window.performance) {
|
|
supported = true;
|
|
perf = window.performance;
|
|
}
|
|
else {
|
|
supported = false;
|
|
}
|
|
/* eslint-enable no-restricted-globals */
|
|
return supported;
|
|
}
|
|
|
|
/**
|
|
* This is only called in esm-bundler builds.
|
|
* It is called when a renderer is created, in `baseCreateRenderer` so that
|
|
* importing runtime-core is side-effects free.
|
|
*
|
|
* istanbul-ignore-next
|
|
*/
|
|
function initFeatureFlags() {
|
|
let needWarn = false;
|
|
if (typeof __VUE_OPTIONS_API__ !== 'boolean') {
|
|
needWarn = true;
|
|
(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.getGlobalThis)().__VUE_OPTIONS_API__ = true;
|
|
}
|
|
if (typeof __VUE_PROD_DEVTOOLS__ !== 'boolean') {
|
|
needWarn = true;
|
|
(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.getGlobalThis)().__VUE_PROD_DEVTOOLS__ = false;
|
|
}
|
|
if (( true) && needWarn) {
|
|
console.warn(`You are running the esm-bundler build of Vue. It is recommended to ` +
|
|
`configure your bundler to explicitly replace feature flag globals ` +
|
|
`with boolean literals to get proper tree-shaking in the final bundle. ` +
|
|
`See http://link.vuejs.org/feature-flags for more details.`);
|
|
}
|
|
}
|
|
|
|
const queuePostRenderEffect = queueEffectWithSuspense
|
|
;
|
|
/**
|
|
* The createRenderer function accepts two generic arguments:
|
|
* HostNode and HostElement, corresponding to Node and Element types in the
|
|
* host environment. For example, for runtime-dom, HostNode would be the DOM
|
|
* `Node` interface and HostElement would be the DOM `Element` interface.
|
|
*
|
|
* Custom renderers can pass in the platform specific types like this:
|
|
*
|
|
* ``` js
|
|
* const { render, createApp } = createRenderer<Node, Element>({
|
|
* patchProp,
|
|
* ...nodeOps
|
|
* })
|
|
* ```
|
|
*/
|
|
function createRenderer(options) {
|
|
return baseCreateRenderer(options);
|
|
}
|
|
// Separate API for creating hydration-enabled renderer.
|
|
// Hydration logic is only used when calling this function, making it
|
|
// tree-shakable.
|
|
function createHydrationRenderer(options) {
|
|
return baseCreateRenderer(options, createHydrationFunctions);
|
|
}
|
|
// implementation
|
|
function baseCreateRenderer(options, createHydrationFns) {
|
|
// compile-time feature flags check
|
|
{
|
|
initFeatureFlags();
|
|
}
|
|
if (true) {
|
|
const target = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.getGlobalThis)();
|
|
target.__VUE__ = true;
|
|
setDevtoolsHook(target.__VUE_DEVTOOLS_GLOBAL_HOOK__);
|
|
}
|
|
const { insert: hostInsert, remove: hostRemove, patchProp: hostPatchProp, createElement: hostCreateElement, createText: hostCreateText, createComment: hostCreateComment, setText: hostSetText, setElementText: hostSetElementText, parentNode: hostParentNode, nextSibling: hostNextSibling, setScopeId: hostSetScopeId = _vue_shared__WEBPACK_IMPORTED_MODULE_1__.NOOP, cloneNode: hostCloneNode, insertStaticContent: hostInsertStaticContent } = options;
|
|
// Note: functions inside this closure should use `const xxx = () => {}`
|
|
// style in order to prevent being inlined by minifiers.
|
|
const patch = (n1, n2, container, anchor = null, parentComponent = null, parentSuspense = null, isSVG = false, slotScopeIds = null, optimized = ( true) && isHmrUpdating ? false : !!n2.dynamicChildren) => {
|
|
if (n1 === n2) {
|
|
return;
|
|
}
|
|
// patching & not same type, unmount old tree
|
|
if (n1 && !isSameVNodeType(n1, n2)) {
|
|
anchor = getNextHostNode(n1);
|
|
unmount(n1, parentComponent, parentSuspense, true);
|
|
n1 = null;
|
|
}
|
|
if (n2.patchFlag === -2 /* BAIL */) {
|
|
optimized = false;
|
|
n2.dynamicChildren = null;
|
|
}
|
|
const { type, ref, shapeFlag } = n2;
|
|
switch (type) {
|
|
case Text:
|
|
processText(n1, n2, container, anchor);
|
|
break;
|
|
case Comment$1:
|
|
processCommentNode(n1, n2, container, anchor);
|
|
break;
|
|
case Static:
|
|
if (n1 == null) {
|
|
mountStaticNode(n2, container, anchor, isSVG);
|
|
}
|
|
else if ((true)) {
|
|
patchStaticNode(n1, n2, container, isSVG);
|
|
}
|
|
break;
|
|
case Fragment:
|
|
processFragment(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
|
|
break;
|
|
default:
|
|
if (shapeFlag & 1 /* ELEMENT */) {
|
|
processElement(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
|
|
}
|
|
else if (shapeFlag & 6 /* COMPONENT */) {
|
|
processComponent(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
|
|
}
|
|
else if (shapeFlag & 64 /* TELEPORT */) {
|
|
type.process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, internals);
|
|
}
|
|
else if (shapeFlag & 128 /* SUSPENSE */) {
|
|
type.process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, internals);
|
|
}
|
|
else if ((true)) {
|
|
warn('Invalid VNode type:', type, `(${typeof type})`);
|
|
}
|
|
}
|
|
// set ref
|
|
if (ref != null && parentComponent) {
|
|
setRef(ref, n1 && n1.ref, parentSuspense, n2 || n1, !n2);
|
|
}
|
|
};
|
|
const processText = (n1, n2, container, anchor) => {
|
|
if (n1 == null) {
|
|
hostInsert((n2.el = hostCreateText(n2.children)), container, anchor);
|
|
}
|
|
else {
|
|
const el = (n2.el = n1.el);
|
|
if (n2.children !== n1.children) {
|
|
hostSetText(el, n2.children);
|
|
}
|
|
}
|
|
};
|
|
const processCommentNode = (n1, n2, container, anchor) => {
|
|
if (n1 == null) {
|
|
hostInsert((n2.el = hostCreateComment(n2.children || '')), container, anchor);
|
|
}
|
|
else {
|
|
// there's no support for dynamic comments
|
|
n2.el = n1.el;
|
|
}
|
|
};
|
|
const mountStaticNode = (n2, container, anchor, isSVG) => {
|
|
[n2.el, n2.anchor] = hostInsertStaticContent(n2.children, container, anchor, isSVG);
|
|
};
|
|
/**
|
|
* Dev / HMR only
|
|
*/
|
|
const patchStaticNode = (n1, n2, container, isSVG) => {
|
|
// static nodes are only patched during dev for HMR
|
|
if (n2.children !== n1.children) {
|
|
const anchor = hostNextSibling(n1.anchor);
|
|
// remove existing
|
|
removeStaticNode(n1);
|
|
[n2.el, n2.anchor] = hostInsertStaticContent(n2.children, container, anchor, isSVG);
|
|
}
|
|
else {
|
|
n2.el = n1.el;
|
|
n2.anchor = n1.anchor;
|
|
}
|
|
};
|
|
const moveStaticNode = ({ el, anchor }, container, nextSibling) => {
|
|
let next;
|
|
while (el && el !== anchor) {
|
|
next = hostNextSibling(el);
|
|
hostInsert(el, container, nextSibling);
|
|
el = next;
|
|
}
|
|
hostInsert(anchor, container, nextSibling);
|
|
};
|
|
const removeStaticNode = ({ el, anchor }) => {
|
|
let next;
|
|
while (el && el !== anchor) {
|
|
next = hostNextSibling(el);
|
|
hostRemove(el);
|
|
el = next;
|
|
}
|
|
hostRemove(anchor);
|
|
};
|
|
const processElement = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
|
|
isSVG = isSVG || n2.type === 'svg';
|
|
if (n1 == null) {
|
|
mountElement(n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
|
|
}
|
|
else {
|
|
patchElement(n1, n2, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
|
|
}
|
|
};
|
|
const mountElement = (vnode, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
|
|
let el;
|
|
let vnodeHook;
|
|
const { type, props, shapeFlag, transition, patchFlag, dirs } = vnode;
|
|
if (false /* HOISTED */) {}
|
|
else {
|
|
el = vnode.el = hostCreateElement(vnode.type, isSVG, props && props.is, props);
|
|
// mount children first, since some props may rely on child content
|
|
// being already rendered, e.g. `<select value>`
|
|
if (shapeFlag & 8 /* TEXT_CHILDREN */) {
|
|
hostSetElementText(el, vnode.children);
|
|
}
|
|
else if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
|
|
mountChildren(vnode.children, el, null, parentComponent, parentSuspense, isSVG && type !== 'foreignObject', slotScopeIds, optimized);
|
|
}
|
|
if (dirs) {
|
|
invokeDirectiveHook(vnode, null, parentComponent, 'created');
|
|
}
|
|
// props
|
|
if (props) {
|
|
for (const key in props) {
|
|
if (key !== 'value' && !(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isReservedProp)(key)) {
|
|
hostPatchProp(el, key, null, props[key], isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);
|
|
}
|
|
}
|
|
/**
|
|
* Special case for setting value on DOM elements:
|
|
* - it can be order-sensitive (e.g. should be set *after* min/max, #2325, #4024)
|
|
* - it needs to be forced (#1471)
|
|
* #2353 proposes adding another renderer option to configure this, but
|
|
* the properties affects are so finite it is worth special casing it
|
|
* here to reduce the complexity. (Special casing it also should not
|
|
* affect non-DOM renderers)
|
|
*/
|
|
if ('value' in props) {
|
|
hostPatchProp(el, 'value', null, props.value);
|
|
}
|
|
if ((vnodeHook = props.onVnodeBeforeMount)) {
|
|
invokeVNodeHook(vnodeHook, parentComponent, vnode);
|
|
}
|
|
}
|
|
// scopeId
|
|
setScopeId(el, vnode, vnode.scopeId, slotScopeIds, parentComponent);
|
|
}
|
|
if (true) {
|
|
Object.defineProperty(el, '__vnode', {
|
|
value: vnode,
|
|
enumerable: false
|
|
});
|
|
Object.defineProperty(el, '__vueParentComponent', {
|
|
value: parentComponent,
|
|
enumerable: false
|
|
});
|
|
}
|
|
if (dirs) {
|
|
invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount');
|
|
}
|
|
// #1583 For inside suspense + suspense not resolved case, enter hook should call when suspense resolved
|
|
// #1689 For inside suspense + suspense resolved case, just call it
|
|
const needCallTransitionHooks = (!parentSuspense || (parentSuspense && !parentSuspense.pendingBranch)) &&
|
|
transition &&
|
|
!transition.persisted;
|
|
if (needCallTransitionHooks) {
|
|
transition.beforeEnter(el);
|
|
}
|
|
hostInsert(el, container, anchor);
|
|
if ((vnodeHook = props && props.onVnodeMounted) ||
|
|
needCallTransitionHooks ||
|
|
dirs) {
|
|
queuePostRenderEffect(() => {
|
|
vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, vnode);
|
|
needCallTransitionHooks && transition.enter(el);
|
|
dirs && invokeDirectiveHook(vnode, null, parentComponent, 'mounted');
|
|
}, parentSuspense);
|
|
}
|
|
};
|
|
const setScopeId = (el, vnode, scopeId, slotScopeIds, parentComponent) => {
|
|
if (scopeId) {
|
|
hostSetScopeId(el, scopeId);
|
|
}
|
|
if (slotScopeIds) {
|
|
for (let i = 0; i < slotScopeIds.length; i++) {
|
|
hostSetScopeId(el, slotScopeIds[i]);
|
|
}
|
|
}
|
|
if (parentComponent) {
|
|
let subTree = parentComponent.subTree;
|
|
if (( true) &&
|
|
subTree.patchFlag > 0 &&
|
|
subTree.patchFlag & 2048 /* DEV_ROOT_FRAGMENT */) {
|
|
subTree =
|
|
filterSingleRoot(subTree.children) || subTree;
|
|
}
|
|
if (vnode === subTree) {
|
|
const parentVNode = parentComponent.vnode;
|
|
setScopeId(el, parentVNode, parentVNode.scopeId, parentVNode.slotScopeIds, parentComponent.parent);
|
|
}
|
|
}
|
|
};
|
|
const mountChildren = (children, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, start = 0) => {
|
|
for (let i = start; i < children.length; i++) {
|
|
const child = (children[i] = optimized
|
|
? cloneIfMounted(children[i])
|
|
: normalizeVNode(children[i]));
|
|
patch(null, child, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
|
|
}
|
|
};
|
|
const patchElement = (n1, n2, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
|
|
const el = (n2.el = n1.el);
|
|
let { patchFlag, dynamicChildren, dirs } = n2;
|
|
// #1426 take the old vnode's patch flag into account since user may clone a
|
|
// compiler-generated vnode, which de-opts to FULL_PROPS
|
|
patchFlag |= n1.patchFlag & 16 /* FULL_PROPS */;
|
|
const oldProps = n1.props || _vue_shared__WEBPACK_IMPORTED_MODULE_1__.EMPTY_OBJ;
|
|
const newProps = n2.props || _vue_shared__WEBPACK_IMPORTED_MODULE_1__.EMPTY_OBJ;
|
|
let vnodeHook;
|
|
if ((vnodeHook = newProps.onVnodeBeforeUpdate)) {
|
|
invokeVNodeHook(vnodeHook, parentComponent, n2, n1);
|
|
}
|
|
if (dirs) {
|
|
invokeDirectiveHook(n2, n1, parentComponent, 'beforeUpdate');
|
|
}
|
|
if (( true) && isHmrUpdating) {
|
|
// HMR updated, force full diff
|
|
patchFlag = 0;
|
|
optimized = false;
|
|
dynamicChildren = null;
|
|
}
|
|
const areChildrenSVG = isSVG && n2.type !== 'foreignObject';
|
|
if (dynamicChildren) {
|
|
patchBlockChildren(n1.dynamicChildren, dynamicChildren, el, parentComponent, parentSuspense, areChildrenSVG, slotScopeIds);
|
|
if (( true) && parentComponent && parentComponent.type.__hmrId) {
|
|
traverseStaticChildren(n1, n2);
|
|
}
|
|
}
|
|
else if (!optimized) {
|
|
// full diff
|
|
patchChildren(n1, n2, el, null, parentComponent, parentSuspense, areChildrenSVG, slotScopeIds, false);
|
|
}
|
|
if (patchFlag > 0) {
|
|
// the presence of a patchFlag means this element's render code was
|
|
// generated by the compiler and can take the fast path.
|
|
// in this path old node and new node are guaranteed to have the same shape
|
|
// (i.e. at the exact same position in the source template)
|
|
if (patchFlag & 16 /* FULL_PROPS */) {
|
|
// element props contain dynamic keys, full diff needed
|
|
patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG);
|
|
}
|
|
else {
|
|
// class
|
|
// this flag is matched when the element has dynamic class bindings.
|
|
if (patchFlag & 2 /* CLASS */) {
|
|
if (oldProps.class !== newProps.class) {
|
|
hostPatchProp(el, 'class', null, newProps.class, isSVG);
|
|
}
|
|
}
|
|
// style
|
|
// this flag is matched when the element has dynamic style bindings
|
|
if (patchFlag & 4 /* STYLE */) {
|
|
hostPatchProp(el, 'style', oldProps.style, newProps.style, isSVG);
|
|
}
|
|
// props
|
|
// This flag is matched when the element has dynamic prop/attr bindings
|
|
// other than class and style. The keys of dynamic prop/attrs are saved for
|
|
// faster iteration.
|
|
// Note dynamic keys like :[foo]="bar" will cause this optimization to
|
|
// bail out and go through a full diff because we need to unset the old key
|
|
if (patchFlag & 8 /* PROPS */) {
|
|
// if the flag is present then dynamicProps must be non-null
|
|
const propsToUpdate = n2.dynamicProps;
|
|
for (let i = 0; i < propsToUpdate.length; i++) {
|
|
const key = propsToUpdate[i];
|
|
const prev = oldProps[key];
|
|
const next = newProps[key];
|
|
// #1471 force patch value
|
|
if (next !== prev || key === 'value') {
|
|
hostPatchProp(el, key, prev, next, isSVG, n1.children, parentComponent, parentSuspense, unmountChildren);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// text
|
|
// This flag is matched when the element has only dynamic text children.
|
|
if (patchFlag & 1 /* TEXT */) {
|
|
if (n1.children !== n2.children) {
|
|
hostSetElementText(el, n2.children);
|
|
}
|
|
}
|
|
}
|
|
else if (!optimized && dynamicChildren == null) {
|
|
// unoptimized, full diff
|
|
patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG);
|
|
}
|
|
if ((vnodeHook = newProps.onVnodeUpdated) || dirs) {
|
|
queuePostRenderEffect(() => {
|
|
vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, n2, n1);
|
|
dirs && invokeDirectiveHook(n2, n1, parentComponent, 'updated');
|
|
}, parentSuspense);
|
|
}
|
|
};
|
|
// The fast path for blocks.
|
|
const patchBlockChildren = (oldChildren, newChildren, fallbackContainer, parentComponent, parentSuspense, isSVG, slotScopeIds) => {
|
|
for (let i = 0; i < newChildren.length; i++) {
|
|
const oldVNode = oldChildren[i];
|
|
const newVNode = newChildren[i];
|
|
// Determine the container (parent element) for the patch.
|
|
const container =
|
|
// oldVNode may be an errored async setup() component inside Suspense
|
|
// which will not have a mounted element
|
|
oldVNode.el &&
|
|
// - In the case of a Fragment, we need to provide the actual parent
|
|
// of the Fragment itself so it can move its children.
|
|
(oldVNode.type === Fragment ||
|
|
// - In the case of different nodes, there is going to be a replacement
|
|
// which also requires the correct parent container
|
|
!isSameVNodeType(oldVNode, newVNode) ||
|
|
// - In the case of a component, it could contain anything.
|
|
oldVNode.shapeFlag & (6 /* COMPONENT */ | 64 /* TELEPORT */))
|
|
? hostParentNode(oldVNode.el)
|
|
: // In other cases, the parent container is not actually used so we
|
|
// just pass the block element here to avoid a DOM parentNode call.
|
|
fallbackContainer;
|
|
patch(oldVNode, newVNode, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, true);
|
|
}
|
|
};
|
|
const patchProps = (el, vnode, oldProps, newProps, parentComponent, parentSuspense, isSVG) => {
|
|
if (oldProps !== newProps) {
|
|
for (const key in newProps) {
|
|
// empty string is not valid prop
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isReservedProp)(key))
|
|
continue;
|
|
const next = newProps[key];
|
|
const prev = oldProps[key];
|
|
// defer patching value
|
|
if (next !== prev && key !== 'value') {
|
|
hostPatchProp(el, key, prev, next, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);
|
|
}
|
|
}
|
|
if (oldProps !== _vue_shared__WEBPACK_IMPORTED_MODULE_1__.EMPTY_OBJ) {
|
|
for (const key in oldProps) {
|
|
if (!(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isReservedProp)(key) && !(key in newProps)) {
|
|
hostPatchProp(el, key, oldProps[key], null, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);
|
|
}
|
|
}
|
|
}
|
|
if ('value' in newProps) {
|
|
hostPatchProp(el, 'value', oldProps.value, newProps.value);
|
|
}
|
|
}
|
|
};
|
|
const processFragment = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
|
|
const fragmentStartAnchor = (n2.el = n1 ? n1.el : hostCreateText(''));
|
|
const fragmentEndAnchor = (n2.anchor = n1 ? n1.anchor : hostCreateText(''));
|
|
let { patchFlag, dynamicChildren, slotScopeIds: fragmentSlotScopeIds } = n2;
|
|
if (( true) && isHmrUpdating) {
|
|
// HMR updated, force full diff
|
|
patchFlag = 0;
|
|
optimized = false;
|
|
dynamicChildren = null;
|
|
}
|
|
// check if this is a slot fragment with :slotted scope ids
|
|
if (fragmentSlotScopeIds) {
|
|
slotScopeIds = slotScopeIds
|
|
? slotScopeIds.concat(fragmentSlotScopeIds)
|
|
: fragmentSlotScopeIds;
|
|
}
|
|
if (n1 == null) {
|
|
hostInsert(fragmentStartAnchor, container, anchor);
|
|
hostInsert(fragmentEndAnchor, container, anchor);
|
|
// a fragment can only have array children
|
|
// since they are either generated by the compiler, or implicitly created
|
|
// from arrays.
|
|
mountChildren(n2.children, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
|
|
}
|
|
else {
|
|
if (patchFlag > 0 &&
|
|
patchFlag & 64 /* STABLE_FRAGMENT */ &&
|
|
dynamicChildren &&
|
|
// #2715 the previous fragment could've been a BAILed one as a result
|
|
// of renderSlot() with no valid children
|
|
n1.dynamicChildren) {
|
|
// a stable fragment (template root or <template v-for>) doesn't need to
|
|
// patch children order, but it may contain dynamicChildren.
|
|
patchBlockChildren(n1.dynamicChildren, dynamicChildren, container, parentComponent, parentSuspense, isSVG, slotScopeIds);
|
|
if (( true) && parentComponent && parentComponent.type.__hmrId) {
|
|
traverseStaticChildren(n1, n2);
|
|
}
|
|
else if (
|
|
// #2080 if the stable fragment has a key, it's a <template v-for> that may
|
|
// get moved around. Make sure all root level vnodes inherit el.
|
|
// #2134 or if it's a component root, it may also get moved around
|
|
// as the component is being moved.
|
|
n2.key != null ||
|
|
(parentComponent && n2 === parentComponent.subTree)) {
|
|
traverseStaticChildren(n1, n2, true /* shallow */);
|
|
}
|
|
}
|
|
else {
|
|
// keyed / unkeyed, or manual fragments.
|
|
// for keyed & unkeyed, since they are compiler generated from v-for,
|
|
// each child is guaranteed to be a block so the fragment will never
|
|
// have dynamicChildren.
|
|
patchChildren(n1, n2, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
|
|
}
|
|
}
|
|
};
|
|
const processComponent = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
|
|
n2.slotScopeIds = slotScopeIds;
|
|
if (n1 == null) {
|
|
if (n2.shapeFlag & 512 /* COMPONENT_KEPT_ALIVE */) {
|
|
parentComponent.ctx.activate(n2, container, anchor, isSVG, optimized);
|
|
}
|
|
else {
|
|
mountComponent(n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized);
|
|
}
|
|
}
|
|
else {
|
|
updateComponent(n1, n2, optimized);
|
|
}
|
|
};
|
|
const mountComponent = (initialVNode, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => {
|
|
const instance = (initialVNode.component = createComponentInstance(initialVNode, parentComponent, parentSuspense));
|
|
if (( true) && instance.type.__hmrId) {
|
|
registerHMR(instance);
|
|
}
|
|
if ((true)) {
|
|
pushWarningContext(initialVNode);
|
|
startMeasure(instance, `mount`);
|
|
}
|
|
// inject renderer internals for keepAlive
|
|
if (isKeepAlive(initialVNode)) {
|
|
instance.ctx.renderer = internals;
|
|
}
|
|
// resolve props and slots for setup context
|
|
{
|
|
if ((true)) {
|
|
startMeasure(instance, `init`);
|
|
}
|
|
setupComponent(instance);
|
|
if ((true)) {
|
|
endMeasure(instance, `init`);
|
|
}
|
|
}
|
|
// setup() is async. This component relies on async logic to be resolved
|
|
// before proceeding
|
|
if (instance.asyncDep) {
|
|
parentSuspense && parentSuspense.registerDep(instance, setupRenderEffect);
|
|
// Give it a placeholder if this is not hydration
|
|
// TODO handle self-defined fallback
|
|
if (!initialVNode.el) {
|
|
const placeholder = (instance.subTree = createVNode(Comment$1));
|
|
processCommentNode(null, placeholder, container, anchor);
|
|
}
|
|
return;
|
|
}
|
|
setupRenderEffect(instance, initialVNode, container, anchor, parentSuspense, isSVG, optimized);
|
|
if ((true)) {
|
|
popWarningContext();
|
|
endMeasure(instance, `mount`);
|
|
}
|
|
};
|
|
const updateComponent = (n1, n2, optimized) => {
|
|
const instance = (n2.component = n1.component);
|
|
if (shouldUpdateComponent(n1, n2, optimized)) {
|
|
if (instance.asyncDep &&
|
|
!instance.asyncResolved) {
|
|
// async & still pending - just update props and slots
|
|
// since the component's reactive effect for render isn't set-up yet
|
|
if ((true)) {
|
|
pushWarningContext(n2);
|
|
}
|
|
updateComponentPreRender(instance, n2, optimized);
|
|
if ((true)) {
|
|
popWarningContext();
|
|
}
|
|
return;
|
|
}
|
|
else {
|
|
// normal update
|
|
instance.next = n2;
|
|
// in case the child component is also queued, remove it to avoid
|
|
// double updating the same child component in the same flush.
|
|
invalidateJob(instance.update);
|
|
// instance.update is the reactive effect.
|
|
instance.update();
|
|
}
|
|
}
|
|
else {
|
|
// no update needed. just copy over properties
|
|
n2.component = n1.component;
|
|
n2.el = n1.el;
|
|
instance.vnode = n2;
|
|
}
|
|
};
|
|
const setupRenderEffect = (instance, initialVNode, container, anchor, parentSuspense, isSVG, optimized) => {
|
|
const componentUpdateFn = () => {
|
|
if (!instance.isMounted) {
|
|
let vnodeHook;
|
|
const { el, props } = initialVNode;
|
|
const { bm, m, parent } = instance;
|
|
const isAsyncWrapperVNode = isAsyncWrapper(initialVNode);
|
|
effect.allowRecurse = false;
|
|
// beforeMount hook
|
|
if (bm) {
|
|
(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.invokeArrayFns)(bm);
|
|
}
|
|
// onVnodeBeforeMount
|
|
if (!isAsyncWrapperVNode &&
|
|
(vnodeHook = props && props.onVnodeBeforeMount)) {
|
|
invokeVNodeHook(vnodeHook, parent, initialVNode);
|
|
}
|
|
effect.allowRecurse = true;
|
|
if (el && hydrateNode) {
|
|
// vnode has adopted host node - perform hydration instead of mount.
|
|
const hydrateSubTree = () => {
|
|
if ((true)) {
|
|
startMeasure(instance, `render`);
|
|
}
|
|
instance.subTree = renderComponentRoot(instance);
|
|
if ((true)) {
|
|
endMeasure(instance, `render`);
|
|
}
|
|
if ((true)) {
|
|
startMeasure(instance, `hydrate`);
|
|
}
|
|
hydrateNode(el, instance.subTree, instance, parentSuspense, null);
|
|
if ((true)) {
|
|
endMeasure(instance, `hydrate`);
|
|
}
|
|
};
|
|
if (isAsyncWrapperVNode) {
|
|
initialVNode.type.__asyncLoader().then(
|
|
// note: we are moving the render call into an async callback,
|
|
// which means it won't track dependencies - but it's ok because
|
|
// a server-rendered async wrapper is already in resolved state
|
|
// and it will never need to change.
|
|
() => !instance.isUnmounted && hydrateSubTree());
|
|
}
|
|
else {
|
|
hydrateSubTree();
|
|
}
|
|
}
|
|
else {
|
|
if ((true)) {
|
|
startMeasure(instance, `render`);
|
|
}
|
|
const subTree = (instance.subTree = renderComponentRoot(instance));
|
|
if ((true)) {
|
|
endMeasure(instance, `render`);
|
|
}
|
|
if ((true)) {
|
|
startMeasure(instance, `patch`);
|
|
}
|
|
patch(null, subTree, container, anchor, instance, parentSuspense, isSVG);
|
|
if ((true)) {
|
|
endMeasure(instance, `patch`);
|
|
}
|
|
initialVNode.el = subTree.el;
|
|
}
|
|
// mounted hook
|
|
if (m) {
|
|
queuePostRenderEffect(m, parentSuspense);
|
|
}
|
|
// onVnodeMounted
|
|
if (!isAsyncWrapperVNode &&
|
|
(vnodeHook = props && props.onVnodeMounted)) {
|
|
const scopedInitialVNode = initialVNode;
|
|
queuePostRenderEffect(() => invokeVNodeHook(vnodeHook, parent, scopedInitialVNode), parentSuspense);
|
|
}
|
|
// activated hook for keep-alive roots.
|
|
// #1742 activated hook must be accessed after first render
|
|
// since the hook may be injected by a child keep-alive
|
|
if (initialVNode.shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */) {
|
|
instance.a && queuePostRenderEffect(instance.a, parentSuspense);
|
|
}
|
|
instance.isMounted = true;
|
|
if (true) {
|
|
devtoolsComponentAdded(instance);
|
|
}
|
|
// #2458: deference mount-only object parameters to prevent memleaks
|
|
initialVNode = container = anchor = null;
|
|
}
|
|
else {
|
|
// updateComponent
|
|
// This is triggered by mutation of component's own state (next: null)
|
|
// OR parent calling processComponent (next: VNode)
|
|
let { next, bu, u, parent, vnode } = instance;
|
|
let originNext = next;
|
|
let vnodeHook;
|
|
if ((true)) {
|
|
pushWarningContext(next || instance.vnode);
|
|
}
|
|
// Disallow component effect recursion during pre-lifecycle hooks.
|
|
effect.allowRecurse = false;
|
|
if (next) {
|
|
next.el = vnode.el;
|
|
updateComponentPreRender(instance, next, optimized);
|
|
}
|
|
else {
|
|
next = vnode;
|
|
}
|
|
// beforeUpdate hook
|
|
if (bu) {
|
|
(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.invokeArrayFns)(bu);
|
|
}
|
|
// onVnodeBeforeUpdate
|
|
if ((vnodeHook = next.props && next.props.onVnodeBeforeUpdate)) {
|
|
invokeVNodeHook(vnodeHook, parent, next, vnode);
|
|
}
|
|
effect.allowRecurse = true;
|
|
// render
|
|
if ((true)) {
|
|
startMeasure(instance, `render`);
|
|
}
|
|
const nextTree = renderComponentRoot(instance);
|
|
if ((true)) {
|
|
endMeasure(instance, `render`);
|
|
}
|
|
const prevTree = instance.subTree;
|
|
instance.subTree = nextTree;
|
|
if ((true)) {
|
|
startMeasure(instance, `patch`);
|
|
}
|
|
patch(prevTree, nextTree,
|
|
// parent may have changed if it's in a teleport
|
|
hostParentNode(prevTree.el),
|
|
// anchor may have changed if it's in a fragment
|
|
getNextHostNode(prevTree), instance, parentSuspense, isSVG);
|
|
if ((true)) {
|
|
endMeasure(instance, `patch`);
|
|
}
|
|
next.el = nextTree.el;
|
|
if (originNext === null) {
|
|
// self-triggered update. In case of HOC, update parent component
|
|
// vnode el. HOC is indicated by parent instance's subTree pointing
|
|
// to child component's vnode
|
|
updateHOCHostEl(instance, nextTree.el);
|
|
}
|
|
// updated hook
|
|
if (u) {
|
|
queuePostRenderEffect(u, parentSuspense);
|
|
}
|
|
// onVnodeUpdated
|
|
if ((vnodeHook = next.props && next.props.onVnodeUpdated)) {
|
|
queuePostRenderEffect(() => invokeVNodeHook(vnodeHook, parent, next, vnode), parentSuspense);
|
|
}
|
|
if (true) {
|
|
devtoolsComponentUpdated(instance);
|
|
}
|
|
if ((true)) {
|
|
popWarningContext();
|
|
}
|
|
}
|
|
};
|
|
// create reactive effect for rendering
|
|
const effect = new _vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.ReactiveEffect(componentUpdateFn, () => queueJob(instance.update), instance.scope // track it in component's effect scope
|
|
);
|
|
const update = (instance.update = effect.run.bind(effect));
|
|
update.id = instance.uid;
|
|
// allowRecurse
|
|
// #1801, #2043 component render effects should allow recursive updates
|
|
effect.allowRecurse = update.allowRecurse = true;
|
|
if ((true)) {
|
|
effect.onTrack = instance.rtc
|
|
? e => (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.invokeArrayFns)(instance.rtc, e)
|
|
: void 0;
|
|
effect.onTrigger = instance.rtg
|
|
? e => (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.invokeArrayFns)(instance.rtg, e)
|
|
: void 0;
|
|
// @ts-ignore (for scheduler)
|
|
update.ownerInstance = instance;
|
|
}
|
|
update();
|
|
};
|
|
const updateComponentPreRender = (instance, nextVNode, optimized) => {
|
|
nextVNode.component = instance;
|
|
const prevProps = instance.vnode.props;
|
|
instance.vnode = nextVNode;
|
|
instance.next = null;
|
|
updateProps(instance, nextVNode.props, prevProps, optimized);
|
|
updateSlots(instance, nextVNode.children, optimized);
|
|
(0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.pauseTracking)();
|
|
// props update may have triggered pre-flush watchers.
|
|
// flush them before the render update.
|
|
flushPreFlushCbs(undefined, instance.update);
|
|
(0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.resetTracking)();
|
|
};
|
|
const patchChildren = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized = false) => {
|
|
const c1 = n1 && n1.children;
|
|
const prevShapeFlag = n1 ? n1.shapeFlag : 0;
|
|
const c2 = n2.children;
|
|
const { patchFlag, shapeFlag } = n2;
|
|
// fast path
|
|
if (patchFlag > 0) {
|
|
if (patchFlag & 128 /* KEYED_FRAGMENT */) {
|
|
// this could be either fully-keyed or mixed (some keyed some not)
|
|
// presence of patchFlag means children are guaranteed to be arrays
|
|
patchKeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
|
|
return;
|
|
}
|
|
else if (patchFlag & 256 /* UNKEYED_FRAGMENT */) {
|
|
// unkeyed
|
|
patchUnkeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
|
|
return;
|
|
}
|
|
}
|
|
// children has 3 possibilities: text, array or no children.
|
|
if (shapeFlag & 8 /* TEXT_CHILDREN */) {
|
|
// text children fast path
|
|
if (prevShapeFlag & 16 /* ARRAY_CHILDREN */) {
|
|
unmountChildren(c1, parentComponent, parentSuspense);
|
|
}
|
|
if (c2 !== c1) {
|
|
hostSetElementText(container, c2);
|
|
}
|
|
}
|
|
else {
|
|
if (prevShapeFlag & 16 /* ARRAY_CHILDREN */) {
|
|
// prev children was array
|
|
if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
|
|
// two arrays, cannot assume anything, do full diff
|
|
patchKeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
|
|
}
|
|
else {
|
|
// no new children, just unmount old
|
|
unmountChildren(c1, parentComponent, parentSuspense, true);
|
|
}
|
|
}
|
|
else {
|
|
// prev children was text OR null
|
|
// new children is array OR null
|
|
if (prevShapeFlag & 8 /* TEXT_CHILDREN */) {
|
|
hostSetElementText(container, '');
|
|
}
|
|
// mount new if array
|
|
if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
|
|
mountChildren(c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
const patchUnkeyedChildren = (c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
|
|
c1 = c1 || _vue_shared__WEBPACK_IMPORTED_MODULE_1__.EMPTY_ARR;
|
|
c2 = c2 || _vue_shared__WEBPACK_IMPORTED_MODULE_1__.EMPTY_ARR;
|
|
const oldLength = c1.length;
|
|
const newLength = c2.length;
|
|
const commonLength = Math.min(oldLength, newLength);
|
|
let i;
|
|
for (i = 0; i < commonLength; i++) {
|
|
const nextChild = (c2[i] = optimized
|
|
? cloneIfMounted(c2[i])
|
|
: normalizeVNode(c2[i]));
|
|
patch(c1[i], nextChild, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
|
|
}
|
|
if (oldLength > newLength) {
|
|
// remove old
|
|
unmountChildren(c1, parentComponent, parentSuspense, true, false, commonLength);
|
|
}
|
|
else {
|
|
// mount new
|
|
mountChildren(c2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, commonLength);
|
|
}
|
|
};
|
|
// can be all-keyed or mixed
|
|
const patchKeyedChildren = (c1, c2, container, parentAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
|
|
let i = 0;
|
|
const l2 = c2.length;
|
|
let e1 = c1.length - 1; // prev ending index
|
|
let e2 = l2 - 1; // next ending index
|
|
// 1. sync from start
|
|
// (a b) c
|
|
// (a b) d e
|
|
while (i <= e1 && i <= e2) {
|
|
const n1 = c1[i];
|
|
const n2 = (c2[i] = optimized
|
|
? cloneIfMounted(c2[i])
|
|
: normalizeVNode(c2[i]));
|
|
if (isSameVNodeType(n1, n2)) {
|
|
patch(n1, n2, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
|
|
}
|
|
else {
|
|
break;
|
|
}
|
|
i++;
|
|
}
|
|
// 2. sync from end
|
|
// a (b c)
|
|
// d e (b c)
|
|
while (i <= e1 && i <= e2) {
|
|
const n1 = c1[e1];
|
|
const n2 = (c2[e2] = optimized
|
|
? cloneIfMounted(c2[e2])
|
|
: normalizeVNode(c2[e2]));
|
|
if (isSameVNodeType(n1, n2)) {
|
|
patch(n1, n2, container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
|
|
}
|
|
else {
|
|
break;
|
|
}
|
|
e1--;
|
|
e2--;
|
|
}
|
|
// 3. common sequence + mount
|
|
// (a b)
|
|
// (a b) c
|
|
// i = 2, e1 = 1, e2 = 2
|
|
// (a b)
|
|
// c (a b)
|
|
// i = 0, e1 = -1, e2 = 0
|
|
if (i > e1) {
|
|
if (i <= e2) {
|
|
const nextPos = e2 + 1;
|
|
const anchor = nextPos < l2 ? c2[nextPos].el : parentAnchor;
|
|
while (i <= e2) {
|
|
patch(null, (c2[i] = optimized
|
|
? cloneIfMounted(c2[i])
|
|
: normalizeVNode(c2[i])), container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
|
|
i++;
|
|
}
|
|
}
|
|
}
|
|
// 4. common sequence + unmount
|
|
// (a b) c
|
|
// (a b)
|
|
// i = 2, e1 = 2, e2 = 1
|
|
// a (b c)
|
|
// (b c)
|
|
// i = 0, e1 = 0, e2 = -1
|
|
else if (i > e2) {
|
|
while (i <= e1) {
|
|
unmount(c1[i], parentComponent, parentSuspense, true);
|
|
i++;
|
|
}
|
|
}
|
|
// 5. unknown sequence
|
|
// [i ... e1 + 1]: a b [c d e] f g
|
|
// [i ... e2 + 1]: a b [e d c h] f g
|
|
// i = 2, e1 = 4, e2 = 5
|
|
else {
|
|
const s1 = i; // prev starting index
|
|
const s2 = i; // next starting index
|
|
// 5.1 build key:index map for newChildren
|
|
const keyToNewIndexMap = new Map();
|
|
for (i = s2; i <= e2; i++) {
|
|
const nextChild = (c2[i] = optimized
|
|
? cloneIfMounted(c2[i])
|
|
: normalizeVNode(c2[i]));
|
|
if (nextChild.key != null) {
|
|
if (( true) && keyToNewIndexMap.has(nextChild.key)) {
|
|
warn(`Duplicate keys found during update:`, JSON.stringify(nextChild.key), `Make sure keys are unique.`);
|
|
}
|
|
keyToNewIndexMap.set(nextChild.key, i);
|
|
}
|
|
}
|
|
// 5.2 loop through old children left to be patched and try to patch
|
|
// matching nodes & remove nodes that are no longer present
|
|
let j;
|
|
let patched = 0;
|
|
const toBePatched = e2 - s2 + 1;
|
|
let moved = false;
|
|
// used to track whether any node has moved
|
|
let maxNewIndexSoFar = 0;
|
|
// works as Map<newIndex, oldIndex>
|
|
// Note that oldIndex is offset by +1
|
|
// and oldIndex = 0 is a special value indicating the new node has
|
|
// no corresponding old node.
|
|
// used for determining longest stable subsequence
|
|
const newIndexToOldIndexMap = new Array(toBePatched);
|
|
for (i = 0; i < toBePatched; i++)
|
|
newIndexToOldIndexMap[i] = 0;
|
|
for (i = s1; i <= e1; i++) {
|
|
const prevChild = c1[i];
|
|
if (patched >= toBePatched) {
|
|
// all new children have been patched so this can only be a removal
|
|
unmount(prevChild, parentComponent, parentSuspense, true);
|
|
continue;
|
|
}
|
|
let newIndex;
|
|
if (prevChild.key != null) {
|
|
newIndex = keyToNewIndexMap.get(prevChild.key);
|
|
}
|
|
else {
|
|
// key-less node, try to locate a key-less node of the same type
|
|
for (j = s2; j <= e2; j++) {
|
|
if (newIndexToOldIndexMap[j - s2] === 0 &&
|
|
isSameVNodeType(prevChild, c2[j])) {
|
|
newIndex = j;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (newIndex === undefined) {
|
|
unmount(prevChild, parentComponent, parentSuspense, true);
|
|
}
|
|
else {
|
|
newIndexToOldIndexMap[newIndex - s2] = i + 1;
|
|
if (newIndex >= maxNewIndexSoFar) {
|
|
maxNewIndexSoFar = newIndex;
|
|
}
|
|
else {
|
|
moved = true;
|
|
}
|
|
patch(prevChild, c2[newIndex], container, null, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
|
|
patched++;
|
|
}
|
|
}
|
|
// 5.3 move and mount
|
|
// generate longest stable subsequence only when nodes have moved
|
|
const increasingNewIndexSequence = moved
|
|
? getSequence(newIndexToOldIndexMap)
|
|
: _vue_shared__WEBPACK_IMPORTED_MODULE_1__.EMPTY_ARR;
|
|
j = increasingNewIndexSequence.length - 1;
|
|
// looping backwards so that we can use last patched node as anchor
|
|
for (i = toBePatched - 1; i >= 0; i--) {
|
|
const nextIndex = s2 + i;
|
|
const nextChild = c2[nextIndex];
|
|
const anchor = nextIndex + 1 < l2 ? c2[nextIndex + 1].el : parentAnchor;
|
|
if (newIndexToOldIndexMap[i] === 0) {
|
|
// mount new
|
|
patch(null, nextChild, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
|
|
}
|
|
else if (moved) {
|
|
// move if:
|
|
// There is no stable subsequence (e.g. a reverse)
|
|
// OR current node is not among the stable sequence
|
|
if (j < 0 || i !== increasingNewIndexSequence[j]) {
|
|
move(nextChild, container, anchor, 2 /* REORDER */);
|
|
}
|
|
else {
|
|
j--;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
const move = (vnode, container, anchor, moveType, parentSuspense = null) => {
|
|
const { el, type, transition, children, shapeFlag } = vnode;
|
|
if (shapeFlag & 6 /* COMPONENT */) {
|
|
move(vnode.component.subTree, container, anchor, moveType);
|
|
return;
|
|
}
|
|
if (shapeFlag & 128 /* SUSPENSE */) {
|
|
vnode.suspense.move(container, anchor, moveType);
|
|
return;
|
|
}
|
|
if (shapeFlag & 64 /* TELEPORT */) {
|
|
type.move(vnode, container, anchor, internals);
|
|
return;
|
|
}
|
|
if (type === Fragment) {
|
|
hostInsert(el, container, anchor);
|
|
for (let i = 0; i < children.length; i++) {
|
|
move(children[i], container, anchor, moveType);
|
|
}
|
|
hostInsert(vnode.anchor, container, anchor);
|
|
return;
|
|
}
|
|
if (type === Static) {
|
|
moveStaticNode(vnode, container, anchor);
|
|
return;
|
|
}
|
|
// single nodes
|
|
const needTransition = moveType !== 2 /* REORDER */ &&
|
|
shapeFlag & 1 /* ELEMENT */ &&
|
|
transition;
|
|
if (needTransition) {
|
|
if (moveType === 0 /* ENTER */) {
|
|
transition.beforeEnter(el);
|
|
hostInsert(el, container, anchor);
|
|
queuePostRenderEffect(() => transition.enter(el), parentSuspense);
|
|
}
|
|
else {
|
|
const { leave, delayLeave, afterLeave } = transition;
|
|
const remove = () => hostInsert(el, container, anchor);
|
|
const performLeave = () => {
|
|
leave(el, () => {
|
|
remove();
|
|
afterLeave && afterLeave();
|
|
});
|
|
};
|
|
if (delayLeave) {
|
|
delayLeave(el, remove, performLeave);
|
|
}
|
|
else {
|
|
performLeave();
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
hostInsert(el, container, anchor);
|
|
}
|
|
};
|
|
const unmount = (vnode, parentComponent, parentSuspense, doRemove = false, optimized = false) => {
|
|
const { type, props, ref, children, dynamicChildren, shapeFlag, patchFlag, dirs } = vnode;
|
|
// unset ref
|
|
if (ref != null) {
|
|
setRef(ref, null, parentSuspense, vnode, true);
|
|
}
|
|
if (shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */) {
|
|
parentComponent.ctx.deactivate(vnode);
|
|
return;
|
|
}
|
|
const shouldInvokeDirs = shapeFlag & 1 /* ELEMENT */ && dirs;
|
|
const shouldInvokeVnodeHook = !isAsyncWrapper(vnode);
|
|
let vnodeHook;
|
|
if (shouldInvokeVnodeHook &&
|
|
(vnodeHook = props && props.onVnodeBeforeUnmount)) {
|
|
invokeVNodeHook(vnodeHook, parentComponent, vnode);
|
|
}
|
|
if (shapeFlag & 6 /* COMPONENT */) {
|
|
unmountComponent(vnode.component, parentSuspense, doRemove);
|
|
}
|
|
else {
|
|
if (shapeFlag & 128 /* SUSPENSE */) {
|
|
vnode.suspense.unmount(parentSuspense, doRemove);
|
|
return;
|
|
}
|
|
if (shouldInvokeDirs) {
|
|
invokeDirectiveHook(vnode, null, parentComponent, 'beforeUnmount');
|
|
}
|
|
if (shapeFlag & 64 /* TELEPORT */) {
|
|
vnode.type.remove(vnode, parentComponent, parentSuspense, optimized, internals, doRemove);
|
|
}
|
|
else if (dynamicChildren &&
|
|
// #1153: fast path should not be taken for non-stable (v-for) fragments
|
|
(type !== Fragment ||
|
|
(patchFlag > 0 && patchFlag & 64 /* STABLE_FRAGMENT */))) {
|
|
// fast path for block nodes: only need to unmount dynamic children.
|
|
unmountChildren(dynamicChildren, parentComponent, parentSuspense, false, true);
|
|
}
|
|
else if ((type === Fragment &&
|
|
patchFlag &
|
|
(128 /* KEYED_FRAGMENT */ | 256 /* UNKEYED_FRAGMENT */)) ||
|
|
(!optimized && shapeFlag & 16 /* ARRAY_CHILDREN */)) {
|
|
unmountChildren(children, parentComponent, parentSuspense);
|
|
}
|
|
if (doRemove) {
|
|
remove(vnode);
|
|
}
|
|
}
|
|
if ((shouldInvokeVnodeHook &&
|
|
(vnodeHook = props && props.onVnodeUnmounted)) ||
|
|
shouldInvokeDirs) {
|
|
queuePostRenderEffect(() => {
|
|
vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, vnode);
|
|
shouldInvokeDirs &&
|
|
invokeDirectiveHook(vnode, null, parentComponent, 'unmounted');
|
|
}, parentSuspense);
|
|
}
|
|
};
|
|
const remove = vnode => {
|
|
const { type, el, anchor, transition } = vnode;
|
|
if (type === Fragment) {
|
|
removeFragment(el, anchor);
|
|
return;
|
|
}
|
|
if (type === Static) {
|
|
removeStaticNode(vnode);
|
|
return;
|
|
}
|
|
const performRemove = () => {
|
|
hostRemove(el);
|
|
if (transition && !transition.persisted && transition.afterLeave) {
|
|
transition.afterLeave();
|
|
}
|
|
};
|
|
if (vnode.shapeFlag & 1 /* ELEMENT */ &&
|
|
transition &&
|
|
!transition.persisted) {
|
|
const { leave, delayLeave } = transition;
|
|
const performLeave = () => leave(el, performRemove);
|
|
if (delayLeave) {
|
|
delayLeave(vnode.el, performRemove, performLeave);
|
|
}
|
|
else {
|
|
performLeave();
|
|
}
|
|
}
|
|
else {
|
|
performRemove();
|
|
}
|
|
};
|
|
const removeFragment = (cur, end) => {
|
|
// For fragments, directly remove all contained DOM nodes.
|
|
// (fragment child nodes cannot have transition)
|
|
let next;
|
|
while (cur !== end) {
|
|
next = hostNextSibling(cur);
|
|
hostRemove(cur);
|
|
cur = next;
|
|
}
|
|
hostRemove(end);
|
|
};
|
|
const unmountComponent = (instance, parentSuspense, doRemove) => {
|
|
if (( true) && instance.type.__hmrId) {
|
|
unregisterHMR(instance);
|
|
}
|
|
const { bum, scope, update, subTree, um } = instance;
|
|
// beforeUnmount hook
|
|
if (bum) {
|
|
(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.invokeArrayFns)(bum);
|
|
}
|
|
// stop effects in component scope
|
|
scope.stop();
|
|
// update may be null if a component is unmounted before its async
|
|
// setup has resolved.
|
|
if (update) {
|
|
// so that scheduler will no longer invoke it
|
|
update.active = false;
|
|
unmount(subTree, instance, parentSuspense, doRemove);
|
|
}
|
|
// unmounted hook
|
|
if (um) {
|
|
queuePostRenderEffect(um, parentSuspense);
|
|
}
|
|
queuePostRenderEffect(() => {
|
|
instance.isUnmounted = true;
|
|
}, parentSuspense);
|
|
// A component with async dep inside a pending suspense is unmounted before
|
|
// its async dep resolves. This should remove the dep from the suspense, and
|
|
// cause the suspense to resolve immediately if that was the last dep.
|
|
if (parentSuspense &&
|
|
parentSuspense.pendingBranch &&
|
|
!parentSuspense.isUnmounted &&
|
|
instance.asyncDep &&
|
|
!instance.asyncResolved &&
|
|
instance.suspenseId === parentSuspense.pendingId) {
|
|
parentSuspense.deps--;
|
|
if (parentSuspense.deps === 0) {
|
|
parentSuspense.resolve();
|
|
}
|
|
}
|
|
if (true) {
|
|
devtoolsComponentRemoved(instance);
|
|
}
|
|
};
|
|
const unmountChildren = (children, parentComponent, parentSuspense, doRemove = false, optimized = false, start = 0) => {
|
|
for (let i = start; i < children.length; i++) {
|
|
unmount(children[i], parentComponent, parentSuspense, doRemove, optimized);
|
|
}
|
|
};
|
|
const getNextHostNode = vnode => {
|
|
if (vnode.shapeFlag & 6 /* COMPONENT */) {
|
|
return getNextHostNode(vnode.component.subTree);
|
|
}
|
|
if (vnode.shapeFlag & 128 /* SUSPENSE */) {
|
|
return vnode.suspense.next();
|
|
}
|
|
return hostNextSibling((vnode.anchor || vnode.el));
|
|
};
|
|
const render = (vnode, container, isSVG) => {
|
|
if (vnode == null) {
|
|
if (container._vnode) {
|
|
unmount(container._vnode, null, null, true);
|
|
}
|
|
}
|
|
else {
|
|
patch(container._vnode || null, vnode, container, null, null, null, isSVG);
|
|
}
|
|
flushPostFlushCbs();
|
|
container._vnode = vnode;
|
|
};
|
|
const internals = {
|
|
p: patch,
|
|
um: unmount,
|
|
m: move,
|
|
r: remove,
|
|
mt: mountComponent,
|
|
mc: mountChildren,
|
|
pc: patchChildren,
|
|
pbc: patchBlockChildren,
|
|
n: getNextHostNode,
|
|
o: options
|
|
};
|
|
let hydrate;
|
|
let hydrateNode;
|
|
if (createHydrationFns) {
|
|
[hydrate, hydrateNode] = createHydrationFns(internals);
|
|
}
|
|
return {
|
|
render,
|
|
hydrate,
|
|
createApp: createAppAPI(render, hydrate)
|
|
};
|
|
}
|
|
function setRef(rawRef, oldRawRef, parentSuspense, vnode, isUnmount = false) {
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isArray)(rawRef)) {
|
|
rawRef.forEach((r, i) => setRef(r, oldRawRef && ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isArray)(oldRawRef) ? oldRawRef[i] : oldRawRef), parentSuspense, vnode, isUnmount));
|
|
return;
|
|
}
|
|
if (isAsyncWrapper(vnode) && !isUnmount) {
|
|
// when mounting async components, nothing needs to be done,
|
|
// because the template ref is forwarded to inner component
|
|
return;
|
|
}
|
|
const refValue = vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */
|
|
? getExposeProxy(vnode.component) || vnode.component.proxy
|
|
: vnode.el;
|
|
const value = isUnmount ? null : refValue;
|
|
const { i: owner, r: ref } = rawRef;
|
|
if (( true) && !owner) {
|
|
warn(`Missing ref owner context. ref cannot be used on hoisted vnodes. ` +
|
|
`A vnode with ref must be created inside the render function.`);
|
|
return;
|
|
}
|
|
const oldRef = oldRawRef && oldRawRef.r;
|
|
const refs = owner.refs === _vue_shared__WEBPACK_IMPORTED_MODULE_1__.EMPTY_OBJ ? (owner.refs = {}) : owner.refs;
|
|
const setupState = owner.setupState;
|
|
// dynamic ref changed. unset old ref
|
|
if (oldRef != null && oldRef !== ref) {
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isString)(oldRef)) {
|
|
refs[oldRef] = null;
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.hasOwn)(setupState, oldRef)) {
|
|
setupState[oldRef] = null;
|
|
}
|
|
}
|
|
else if ((0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.isRef)(oldRef)) {
|
|
oldRef.value = null;
|
|
}
|
|
}
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isString)(ref)) {
|
|
const doSet = () => {
|
|
{
|
|
refs[ref] = value;
|
|
}
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.hasOwn)(setupState, ref)) {
|
|
setupState[ref] = value;
|
|
}
|
|
};
|
|
// #1789: for non-null values, set them after render
|
|
// null values means this is unmount and it should not overwrite another
|
|
// ref with the same key
|
|
if (value) {
|
|
doSet.id = -1;
|
|
queuePostRenderEffect(doSet, parentSuspense);
|
|
}
|
|
else {
|
|
doSet();
|
|
}
|
|
}
|
|
else if ((0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.isRef)(ref)) {
|
|
const doSet = () => {
|
|
ref.value = value;
|
|
};
|
|
if (value) {
|
|
doSet.id = -1;
|
|
queuePostRenderEffect(doSet, parentSuspense);
|
|
}
|
|
else {
|
|
doSet();
|
|
}
|
|
}
|
|
else if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isFunction)(ref)) {
|
|
callWithErrorHandling(ref, owner, 12 /* FUNCTION_REF */, [value, refs]);
|
|
}
|
|
else if ((true)) {
|
|
warn('Invalid template ref type:', value, `(${typeof value})`);
|
|
}
|
|
}
|
|
function invokeVNodeHook(hook, instance, vnode, prevVNode = null) {
|
|
callWithAsyncErrorHandling(hook, instance, 7 /* VNODE_HOOK */, [
|
|
vnode,
|
|
prevVNode
|
|
]);
|
|
}
|
|
/**
|
|
* #1156
|
|
* When a component is HMR-enabled, we need to make sure that all static nodes
|
|
* inside a block also inherit the DOM element from the previous tree so that
|
|
* HMR updates (which are full updates) can retrieve the element for patching.
|
|
*
|
|
* #2080
|
|
* Inside keyed `template` fragment static children, if a fragment is moved,
|
|
* the children will always moved so that need inherit el form previous nodes
|
|
* to ensure correct moved position.
|
|
*/
|
|
function traverseStaticChildren(n1, n2, shallow = false) {
|
|
const ch1 = n1.children;
|
|
const ch2 = n2.children;
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isArray)(ch1) && (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isArray)(ch2)) {
|
|
for (let i = 0; i < ch1.length; i++) {
|
|
// this is only called in the optimized path so array children are
|
|
// guaranteed to be vnodes
|
|
const c1 = ch1[i];
|
|
let c2 = ch2[i];
|
|
if (c2.shapeFlag & 1 /* ELEMENT */ && !c2.dynamicChildren) {
|
|
if (c2.patchFlag <= 0 || c2.patchFlag === 32 /* HYDRATE_EVENTS */) {
|
|
c2 = ch2[i] = cloneIfMounted(ch2[i]);
|
|
c2.el = c1.el;
|
|
}
|
|
if (!shallow)
|
|
traverseStaticChildren(c1, c2);
|
|
}
|
|
// also inherit for comment nodes, but not placeholders (e.g. v-if which
|
|
// would have received .el during block patch)
|
|
if (( true) && c2.type === Comment$1 && !c2.el) {
|
|
c2.el = c1.el;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// https://en.wikipedia.org/wiki/Longest_increasing_subsequence
|
|
function getSequence(arr) {
|
|
const p = arr.slice();
|
|
const result = [0];
|
|
let i, j, u, v, c;
|
|
const len = arr.length;
|
|
for (i = 0; i < len; i++) {
|
|
const arrI = arr[i];
|
|
if (arrI !== 0) {
|
|
j = result[result.length - 1];
|
|
if (arr[j] < arrI) {
|
|
p[i] = j;
|
|
result.push(i);
|
|
continue;
|
|
}
|
|
u = 0;
|
|
v = result.length - 1;
|
|
while (u < v) {
|
|
c = (u + v) >> 1;
|
|
if (arr[result[c]] < arrI) {
|
|
u = c + 1;
|
|
}
|
|
else {
|
|
v = c;
|
|
}
|
|
}
|
|
if (arrI < arr[result[u]]) {
|
|
if (u > 0) {
|
|
p[i] = result[u - 1];
|
|
}
|
|
result[u] = i;
|
|
}
|
|
}
|
|
}
|
|
u = result.length;
|
|
v = result[u - 1];
|
|
while (u-- > 0) {
|
|
result[u] = v;
|
|
v = p[v];
|
|
}
|
|
return result;
|
|
}
|
|
|
|
const isTeleport = (type) => type.__isTeleport;
|
|
const isTeleportDisabled = (props) => props && (props.disabled || props.disabled === '');
|
|
const isTargetSVG = (target) => typeof SVGElement !== 'undefined' && target instanceof SVGElement;
|
|
const resolveTarget = (props, select) => {
|
|
const targetSelector = props && props.to;
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isString)(targetSelector)) {
|
|
if (!select) {
|
|
( true) &&
|
|
warn(`Current renderer does not support string target for Teleports. ` +
|
|
`(missing querySelector renderer option)`);
|
|
return null;
|
|
}
|
|
else {
|
|
const target = select(targetSelector);
|
|
if (!target) {
|
|
( true) &&
|
|
warn(`Failed to locate Teleport target with selector "${targetSelector}". ` +
|
|
`Note the target element must exist before the component is mounted - ` +
|
|
`i.e. the target cannot be rendered by the component itself, and ` +
|
|
`ideally should be outside of the entire Vue component tree.`);
|
|
}
|
|
return target;
|
|
}
|
|
}
|
|
else {
|
|
if (( true) && !targetSelector && !isTeleportDisabled(props)) {
|
|
warn(`Invalid Teleport target: ${targetSelector}`);
|
|
}
|
|
return targetSelector;
|
|
}
|
|
};
|
|
const TeleportImpl = {
|
|
__isTeleport: true,
|
|
process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, internals) {
|
|
const { mc: mountChildren, pc: patchChildren, pbc: patchBlockChildren, o: { insert, querySelector, createText, createComment } } = internals;
|
|
const disabled = isTeleportDisabled(n2.props);
|
|
let { shapeFlag, children, dynamicChildren } = n2;
|
|
// #3302
|
|
// HMR updated, force full diff
|
|
if (( true) && isHmrUpdating) {
|
|
optimized = false;
|
|
dynamicChildren = null;
|
|
}
|
|
if (n1 == null) {
|
|
// insert anchors in the main view
|
|
const placeholder = (n2.el = ( true)
|
|
? createComment('teleport start')
|
|
: 0);
|
|
const mainAnchor = (n2.anchor = ( true)
|
|
? createComment('teleport end')
|
|
: 0);
|
|
insert(placeholder, container, anchor);
|
|
insert(mainAnchor, container, anchor);
|
|
const target = (n2.target = resolveTarget(n2.props, querySelector));
|
|
const targetAnchor = (n2.targetAnchor = createText(''));
|
|
if (target) {
|
|
insert(targetAnchor, target);
|
|
// #2652 we could be teleporting from a non-SVG tree into an SVG tree
|
|
isSVG = isSVG || isTargetSVG(target);
|
|
}
|
|
else if (( true) && !disabled) {
|
|
warn('Invalid Teleport target on mount:', target, `(${typeof target})`);
|
|
}
|
|
const mount = (container, anchor) => {
|
|
// Teleport *always* has Array children. This is enforced in both the
|
|
// compiler and vnode children normalization.
|
|
if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
|
|
mountChildren(children, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized);
|
|
}
|
|
};
|
|
if (disabled) {
|
|
mount(container, mainAnchor);
|
|
}
|
|
else if (target) {
|
|
mount(target, targetAnchor);
|
|
}
|
|
}
|
|
else {
|
|
// update content
|
|
n2.el = n1.el;
|
|
const mainAnchor = (n2.anchor = n1.anchor);
|
|
const target = (n2.target = n1.target);
|
|
const targetAnchor = (n2.targetAnchor = n1.targetAnchor);
|
|
const wasDisabled = isTeleportDisabled(n1.props);
|
|
const currentContainer = wasDisabled ? container : target;
|
|
const currentAnchor = wasDisabled ? mainAnchor : targetAnchor;
|
|
isSVG = isSVG || isTargetSVG(target);
|
|
if (dynamicChildren) {
|
|
// fast path when the teleport happens to be a block root
|
|
patchBlockChildren(n1.dynamicChildren, dynamicChildren, currentContainer, parentComponent, parentSuspense, isSVG, slotScopeIds);
|
|
// even in block tree mode we need to make sure all root-level nodes
|
|
// in the teleport inherit previous DOM references so that they can
|
|
// be moved in future patches.
|
|
traverseStaticChildren(n1, n2, true);
|
|
}
|
|
else if (!optimized) {
|
|
patchChildren(n1, n2, currentContainer, currentAnchor, parentComponent, parentSuspense, isSVG, slotScopeIds, false);
|
|
}
|
|
if (disabled) {
|
|
if (!wasDisabled) {
|
|
// enabled -> disabled
|
|
// move into main container
|
|
moveTeleport(n2, container, mainAnchor, internals, 1 /* TOGGLE */);
|
|
}
|
|
}
|
|
else {
|
|
// target changed
|
|
if ((n2.props && n2.props.to) !== (n1.props && n1.props.to)) {
|
|
const nextTarget = (n2.target = resolveTarget(n2.props, querySelector));
|
|
if (nextTarget) {
|
|
moveTeleport(n2, nextTarget, null, internals, 0 /* TARGET_CHANGE */);
|
|
}
|
|
else if ((true)) {
|
|
warn('Invalid Teleport target on update:', target, `(${typeof target})`);
|
|
}
|
|
}
|
|
else if (wasDisabled) {
|
|
// disabled -> enabled
|
|
// move into teleport target
|
|
moveTeleport(n2, target, targetAnchor, internals, 1 /* TOGGLE */);
|
|
}
|
|
}
|
|
}
|
|
},
|
|
remove(vnode, parentComponent, parentSuspense, optimized, { um: unmount, o: { remove: hostRemove } }, doRemove) {
|
|
const { shapeFlag, children, anchor, targetAnchor, target, props } = vnode;
|
|
if (target) {
|
|
hostRemove(targetAnchor);
|
|
}
|
|
// an unmounted teleport should always remove its children if not disabled
|
|
if (doRemove || !isTeleportDisabled(props)) {
|
|
hostRemove(anchor);
|
|
if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
|
|
for (let i = 0; i < children.length; i++) {
|
|
const child = children[i];
|
|
unmount(child, parentComponent, parentSuspense, true, !!child.dynamicChildren);
|
|
}
|
|
}
|
|
}
|
|
},
|
|
move: moveTeleport,
|
|
hydrate: hydrateTeleport
|
|
};
|
|
function moveTeleport(vnode, container, parentAnchor, { o: { insert }, m: move }, moveType = 2 /* REORDER */) {
|
|
// move target anchor if this is a target change.
|
|
if (moveType === 0 /* TARGET_CHANGE */) {
|
|
insert(vnode.targetAnchor, container, parentAnchor);
|
|
}
|
|
const { el, anchor, shapeFlag, children, props } = vnode;
|
|
const isReorder = moveType === 2 /* REORDER */;
|
|
// move main view anchor if this is a re-order.
|
|
if (isReorder) {
|
|
insert(el, container, parentAnchor);
|
|
}
|
|
// if this is a re-order and teleport is enabled (content is in target)
|
|
// do not move children. So the opposite is: only move children if this
|
|
// is not a reorder, or the teleport is disabled
|
|
if (!isReorder || isTeleportDisabled(props)) {
|
|
// Teleport has either Array children or no children.
|
|
if (shapeFlag & 16 /* ARRAY_CHILDREN */) {
|
|
for (let i = 0; i < children.length; i++) {
|
|
move(children[i], container, parentAnchor, 2 /* REORDER */);
|
|
}
|
|
}
|
|
}
|
|
// move main view anchor if this is a re-order.
|
|
if (isReorder) {
|
|
insert(anchor, container, parentAnchor);
|
|
}
|
|
}
|
|
function hydrateTeleport(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized, { o: { nextSibling, parentNode, querySelector } }, hydrateChildren) {
|
|
const target = (vnode.target = resolveTarget(vnode.props, querySelector));
|
|
if (target) {
|
|
// if multiple teleports rendered to the same target element, we need to
|
|
// pick up from where the last teleport finished instead of the first node
|
|
const targetNode = target._lpa || target.firstChild;
|
|
if (vnode.shapeFlag & 16 /* ARRAY_CHILDREN */) {
|
|
if (isTeleportDisabled(vnode.props)) {
|
|
vnode.anchor = hydrateChildren(nextSibling(node), vnode, parentNode(node), parentComponent, parentSuspense, slotScopeIds, optimized);
|
|
vnode.targetAnchor = targetNode;
|
|
}
|
|
else {
|
|
vnode.anchor = nextSibling(node);
|
|
vnode.targetAnchor = hydrateChildren(targetNode, vnode, target, parentComponent, parentSuspense, slotScopeIds, optimized);
|
|
}
|
|
target._lpa =
|
|
vnode.targetAnchor && nextSibling(vnode.targetAnchor);
|
|
}
|
|
}
|
|
return vnode.anchor && nextSibling(vnode.anchor);
|
|
}
|
|
// Force-casted public typing for h and TSX props inference
|
|
const Teleport = TeleportImpl;
|
|
|
|
const COMPONENTS = 'components';
|
|
const DIRECTIVES = 'directives';
|
|
/**
|
|
* @private
|
|
*/
|
|
function resolveComponent(name, maybeSelfReference) {
|
|
return resolveAsset(COMPONENTS, name, true, maybeSelfReference) || name;
|
|
}
|
|
const NULL_DYNAMIC_COMPONENT = Symbol();
|
|
/**
|
|
* @private
|
|
*/
|
|
function resolveDynamicComponent(component) {
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isString)(component)) {
|
|
return resolveAsset(COMPONENTS, component, false) || component;
|
|
}
|
|
else {
|
|
// invalid types will fallthrough to createVNode and raise warning
|
|
return (component || NULL_DYNAMIC_COMPONENT);
|
|
}
|
|
}
|
|
/**
|
|
* @private
|
|
*/
|
|
function resolveDirective(name) {
|
|
return resolveAsset(DIRECTIVES, name);
|
|
}
|
|
// implementation
|
|
function resolveAsset(type, name, warnMissing = true, maybeSelfReference = false) {
|
|
const instance = currentRenderingInstance || currentInstance;
|
|
if (instance) {
|
|
const Component = instance.type;
|
|
// explicit self name has highest priority
|
|
if (type === COMPONENTS) {
|
|
const selfName = getComponentName(Component);
|
|
if (selfName &&
|
|
(selfName === name ||
|
|
selfName === (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.camelize)(name) ||
|
|
selfName === (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.capitalize)((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.camelize)(name)))) {
|
|
return Component;
|
|
}
|
|
}
|
|
const res =
|
|
// local registration
|
|
// check instance[type] first which is resolved for options API
|
|
resolve(instance[type] || Component[type], name) ||
|
|
// global registration
|
|
resolve(instance.appContext[type], name);
|
|
if (!res && maybeSelfReference) {
|
|
// fallback to implicit self-reference
|
|
return Component;
|
|
}
|
|
if (( true) && warnMissing && !res) {
|
|
warn(`Failed to resolve ${type.slice(0, -1)}: ${name}`);
|
|
}
|
|
return res;
|
|
}
|
|
else if ((true)) {
|
|
warn(`resolve${(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.capitalize)(type.slice(0, -1))} ` +
|
|
`can only be used in render() or setup().`);
|
|
}
|
|
}
|
|
function resolve(registry, name) {
|
|
return (registry &&
|
|
(registry[name] ||
|
|
registry[(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.camelize)(name)] ||
|
|
registry[(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.capitalize)((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.camelize)(name))]));
|
|
}
|
|
|
|
const Fragment = Symbol(( true) ? 'Fragment' : 0);
|
|
const Text = Symbol(( true) ? 'Text' : 0);
|
|
const Comment$1 = Symbol(( true) ? 'Comment' : 0);
|
|
const Static = Symbol(( true) ? 'Static' : 0);
|
|
// Since v-if and v-for are the two possible ways node structure can dynamically
|
|
// change, once we consider v-if branches and each v-for fragment a block, we
|
|
// can divide a template into nested blocks, and within each block the node
|
|
// structure would be stable. This allows us to skip most children diffing
|
|
// and only worry about the dynamic nodes (indicated by patch flags).
|
|
const blockStack = [];
|
|
let currentBlock = null;
|
|
/**
|
|
* Open a block.
|
|
* This must be called before `createBlock`. It cannot be part of `createBlock`
|
|
* because the children of the block are evaluated before `createBlock` itself
|
|
* is called. The generated code typically looks like this:
|
|
*
|
|
* ```js
|
|
* function render() {
|
|
* return (openBlock(),createBlock('div', null, [...]))
|
|
* }
|
|
* ```
|
|
* disableTracking is true when creating a v-for fragment block, since a v-for
|
|
* fragment always diffs its children.
|
|
*
|
|
* @private
|
|
*/
|
|
function openBlock(disableTracking = false) {
|
|
blockStack.push((currentBlock = disableTracking ? null : []));
|
|
}
|
|
function closeBlock() {
|
|
blockStack.pop();
|
|
currentBlock = blockStack[blockStack.length - 1] || null;
|
|
}
|
|
// Whether we should be tracking dynamic child nodes inside a block.
|
|
// Only tracks when this value is > 0
|
|
// We are not using a simple boolean because this value may need to be
|
|
// incremented/decremented by nested usage of v-once (see below)
|
|
let isBlockTreeEnabled = 1;
|
|
/**
|
|
* Block tracking sometimes needs to be disabled, for example during the
|
|
* creation of a tree that needs to be cached by v-once. The compiler generates
|
|
* code like this:
|
|
*
|
|
* ``` js
|
|
* _cache[1] || (
|
|
* setBlockTracking(-1),
|
|
* _cache[1] = createVNode(...),
|
|
* setBlockTracking(1),
|
|
* _cache[1]
|
|
* )
|
|
* ```
|
|
*
|
|
* @private
|
|
*/
|
|
function setBlockTracking(value) {
|
|
isBlockTreeEnabled += value;
|
|
}
|
|
function setupBlock(vnode) {
|
|
// save current block children on the block vnode
|
|
vnode.dynamicChildren =
|
|
isBlockTreeEnabled > 0 ? currentBlock || _vue_shared__WEBPACK_IMPORTED_MODULE_1__.EMPTY_ARR : null;
|
|
// close block
|
|
closeBlock();
|
|
// a block is always going to be patched, so track it as a child of its
|
|
// parent block
|
|
if (isBlockTreeEnabled > 0 && currentBlock) {
|
|
currentBlock.push(vnode);
|
|
}
|
|
return vnode;
|
|
}
|
|
/**
|
|
* @private
|
|
*/
|
|
function createElementBlock(type, props, children, patchFlag, dynamicProps, shapeFlag) {
|
|
return setupBlock(createBaseVNode(type, props, children, patchFlag, dynamicProps, shapeFlag, true /* isBlock */));
|
|
}
|
|
/**
|
|
* Create a block root vnode. Takes the same exact arguments as `createVNode`.
|
|
* A block root keeps track of dynamic nodes within the block in the
|
|
* `dynamicChildren` array.
|
|
*
|
|
* @private
|
|
*/
|
|
function createBlock(type, props, children, patchFlag, dynamicProps) {
|
|
return setupBlock(createVNode(type, props, children, patchFlag, dynamicProps, true /* isBlock: prevent a block from tracking itself */));
|
|
}
|
|
function isVNode(value) {
|
|
return value ? value.__v_isVNode === true : false;
|
|
}
|
|
function isSameVNodeType(n1, n2) {
|
|
if (( true) &&
|
|
n2.shapeFlag & 6 /* COMPONENT */ &&
|
|
hmrDirtyComponents.has(n2.type)) {
|
|
// HMR only: if the component has been hot-updated, force a reload.
|
|
return false;
|
|
}
|
|
return n1.type === n2.type && n1.key === n2.key;
|
|
}
|
|
let vnodeArgsTransformer;
|
|
/**
|
|
* Internal API for registering an arguments transform for createVNode
|
|
* used for creating stubs in the test-utils
|
|
* It is *internal* but needs to be exposed for test-utils to pick up proper
|
|
* typings
|
|
*/
|
|
function transformVNodeArgs(transformer) {
|
|
vnodeArgsTransformer = transformer;
|
|
}
|
|
const createVNodeWithArgsTransform = (...args) => {
|
|
return _createVNode(...(vnodeArgsTransformer
|
|
? vnodeArgsTransformer(args, currentRenderingInstance)
|
|
: args));
|
|
};
|
|
const InternalObjectKey = `__vInternal`;
|
|
const normalizeKey = ({ key }) => key != null ? key : null;
|
|
const normalizeRef = ({ ref }) => {
|
|
return (ref != null
|
|
? (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isString)(ref) || (0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.isRef)(ref) || (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isFunction)(ref)
|
|
? { i: currentRenderingInstance, r: ref }
|
|
: ref
|
|
: null);
|
|
};
|
|
function createBaseVNode(type, props = null, children = null, patchFlag = 0, dynamicProps = null, shapeFlag = type === Fragment ? 0 : 1 /* ELEMENT */, isBlockNode = false, needFullChildrenNormalization = false) {
|
|
const vnode = {
|
|
__v_isVNode: true,
|
|
__v_skip: true,
|
|
type,
|
|
props,
|
|
key: props && normalizeKey(props),
|
|
ref: props && normalizeRef(props),
|
|
scopeId: currentScopeId,
|
|
slotScopeIds: null,
|
|
children,
|
|
component: null,
|
|
suspense: null,
|
|
ssContent: null,
|
|
ssFallback: null,
|
|
dirs: null,
|
|
transition: null,
|
|
el: null,
|
|
anchor: null,
|
|
target: null,
|
|
targetAnchor: null,
|
|
staticCount: 0,
|
|
shapeFlag,
|
|
patchFlag,
|
|
dynamicProps,
|
|
dynamicChildren: null,
|
|
appContext: null
|
|
};
|
|
if (needFullChildrenNormalization) {
|
|
normalizeChildren(vnode, children);
|
|
// normalize suspense children
|
|
if (shapeFlag & 128 /* SUSPENSE */) {
|
|
type.normalize(vnode);
|
|
}
|
|
}
|
|
else if (children) {
|
|
// compiled element vnode - if children is passed, only possible types are
|
|
// string or Array.
|
|
vnode.shapeFlag |= (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isString)(children)
|
|
? 8 /* TEXT_CHILDREN */
|
|
: 16 /* ARRAY_CHILDREN */;
|
|
}
|
|
// validate key
|
|
if (( true) && vnode.key !== vnode.key) {
|
|
warn(`VNode created with invalid key (NaN). VNode type:`, vnode.type);
|
|
}
|
|
// track vnode for block tree
|
|
if (isBlockTreeEnabled > 0 &&
|
|
// avoid a block node from tracking itself
|
|
!isBlockNode &&
|
|
// has current parent block
|
|
currentBlock &&
|
|
// presence of a patch flag indicates this node needs patching on updates.
|
|
// component nodes also should always be patched, because even if the
|
|
// component doesn't need to update, it needs to persist the instance on to
|
|
// the next vnode so that it can be properly unmounted later.
|
|
(vnode.patchFlag > 0 || shapeFlag & 6 /* COMPONENT */) &&
|
|
// the EVENTS flag is only for hydration and if it is the only flag, the
|
|
// vnode should not be considered dynamic due to handler caching.
|
|
vnode.patchFlag !== 32 /* HYDRATE_EVENTS */) {
|
|
currentBlock.push(vnode);
|
|
}
|
|
return vnode;
|
|
}
|
|
const createVNode = (( true) ? createVNodeWithArgsTransform : 0);
|
|
function _createVNode(type, props = null, children = null, patchFlag = 0, dynamicProps = null, isBlockNode = false) {
|
|
if (!type || type === NULL_DYNAMIC_COMPONENT) {
|
|
if (( true) && !type) {
|
|
warn(`Invalid vnode type when creating vnode: ${type}.`);
|
|
}
|
|
type = Comment$1;
|
|
}
|
|
if (isVNode(type)) {
|
|
// createVNode receiving an existing vnode. This happens in cases like
|
|
// <component :is="vnode"/>
|
|
// #2078 make sure to merge refs during the clone instead of overwriting it
|
|
const cloned = cloneVNode(type, props, true /* mergeRef: true */);
|
|
if (children) {
|
|
normalizeChildren(cloned, children);
|
|
}
|
|
return cloned;
|
|
}
|
|
// class component normalization.
|
|
if (isClassComponent(type)) {
|
|
type = type.__vccOpts;
|
|
}
|
|
// class & style normalization.
|
|
if (props) {
|
|
// for reactive or proxy objects, we need to clone it to enable mutation.
|
|
props = guardReactiveProps(props);
|
|
let { class: klass, style } = props;
|
|
if (klass && !(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isString)(klass)) {
|
|
props.class = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.normalizeClass)(klass);
|
|
}
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isObject)(style)) {
|
|
// reactive state objects need to be cloned since they are likely to be
|
|
// mutated
|
|
if ((0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.isProxy)(style) && !(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isArray)(style)) {
|
|
style = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.extend)({}, style);
|
|
}
|
|
props.style = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.normalizeStyle)(style);
|
|
}
|
|
}
|
|
// encode the vnode type information into a bitmap
|
|
const shapeFlag = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isString)(type)
|
|
? 1 /* ELEMENT */
|
|
: isSuspense(type)
|
|
? 128 /* SUSPENSE */
|
|
: isTeleport(type)
|
|
? 64 /* TELEPORT */
|
|
: (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isObject)(type)
|
|
? 4 /* STATEFUL_COMPONENT */
|
|
: (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isFunction)(type)
|
|
? 2 /* FUNCTIONAL_COMPONENT */
|
|
: 0;
|
|
if (( true) && shapeFlag & 4 /* STATEFUL_COMPONENT */ && (0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.isProxy)(type)) {
|
|
type = (0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.toRaw)(type);
|
|
warn(`Vue received a Component which was made a reactive object. This can ` +
|
|
`lead to unnecessary performance overhead, and should be avoided by ` +
|
|
`marking the component with \`markRaw\` or using \`shallowRef\` ` +
|
|
`instead of \`ref\`.`, `\nComponent that was made reactive: `, type);
|
|
}
|
|
return createBaseVNode(type, props, children, patchFlag, dynamicProps, shapeFlag, isBlockNode, true);
|
|
}
|
|
function guardReactiveProps(props) {
|
|
if (!props)
|
|
return null;
|
|
return (0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.isProxy)(props) || InternalObjectKey in props
|
|
? (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.extend)({}, props)
|
|
: props;
|
|
}
|
|
function cloneVNode(vnode, extraProps, mergeRef = false) {
|
|
// This is intentionally NOT using spread or extend to avoid the runtime
|
|
// key enumeration cost.
|
|
const { props, ref, patchFlag, children } = vnode;
|
|
const mergedProps = extraProps ? mergeProps(props || {}, extraProps) : props;
|
|
const cloned = {
|
|
__v_isVNode: true,
|
|
__v_skip: true,
|
|
type: vnode.type,
|
|
props: mergedProps,
|
|
key: mergedProps && normalizeKey(mergedProps),
|
|
ref: extraProps && extraProps.ref
|
|
? // #2078 in the case of <component :is="vnode" ref="extra"/>
|
|
// if the vnode itself already has a ref, cloneVNode will need to merge
|
|
// the refs so the single vnode can be set on multiple refs
|
|
mergeRef && ref
|
|
? (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isArray)(ref)
|
|
? ref.concat(normalizeRef(extraProps))
|
|
: [ref, normalizeRef(extraProps)]
|
|
: normalizeRef(extraProps)
|
|
: ref,
|
|
scopeId: vnode.scopeId,
|
|
slotScopeIds: vnode.slotScopeIds,
|
|
children: ( true) && patchFlag === -1 /* HOISTED */ && (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isArray)(children)
|
|
? children.map(deepCloneVNode)
|
|
: children,
|
|
target: vnode.target,
|
|
targetAnchor: vnode.targetAnchor,
|
|
staticCount: vnode.staticCount,
|
|
shapeFlag: vnode.shapeFlag,
|
|
// if the vnode is cloned with extra props, we can no longer assume its
|
|
// existing patch flag to be reliable and need to add the FULL_PROPS flag.
|
|
// note: perserve flag for fragments since they use the flag for children
|
|
// fast paths only.
|
|
patchFlag: extraProps && vnode.type !== Fragment
|
|
? patchFlag === -1 // hoisted node
|
|
? 16 /* FULL_PROPS */
|
|
: patchFlag | 16 /* FULL_PROPS */
|
|
: patchFlag,
|
|
dynamicProps: vnode.dynamicProps,
|
|
dynamicChildren: vnode.dynamicChildren,
|
|
appContext: vnode.appContext,
|
|
dirs: vnode.dirs,
|
|
transition: vnode.transition,
|
|
// These should technically only be non-null on mounted VNodes. However,
|
|
// they *should* be copied for kept-alive vnodes. So we just always copy
|
|
// them since them being non-null during a mount doesn't affect the logic as
|
|
// they will simply be overwritten.
|
|
component: vnode.component,
|
|
suspense: vnode.suspense,
|
|
ssContent: vnode.ssContent && cloneVNode(vnode.ssContent),
|
|
ssFallback: vnode.ssFallback && cloneVNode(vnode.ssFallback),
|
|
el: vnode.el,
|
|
anchor: vnode.anchor
|
|
};
|
|
return cloned;
|
|
}
|
|
/**
|
|
* Dev only, for HMR of hoisted vnodes reused in v-for
|
|
* https://github.com/vitejs/vite/issues/2022
|
|
*/
|
|
function deepCloneVNode(vnode) {
|
|
const cloned = cloneVNode(vnode);
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isArray)(vnode.children)) {
|
|
cloned.children = vnode.children.map(deepCloneVNode);
|
|
}
|
|
return cloned;
|
|
}
|
|
/**
|
|
* @private
|
|
*/
|
|
function createTextVNode(text = ' ', flag = 0) {
|
|
return createVNode(Text, null, text, flag);
|
|
}
|
|
/**
|
|
* @private
|
|
*/
|
|
function createStaticVNode(content, numberOfNodes) {
|
|
// A static vnode can contain multiple stringified elements, and the number
|
|
// of elements is necessary for hydration.
|
|
const vnode = createVNode(Static, null, content);
|
|
vnode.staticCount = numberOfNodes;
|
|
return vnode;
|
|
}
|
|
/**
|
|
* @private
|
|
*/
|
|
function createCommentVNode(text = '',
|
|
// when used as the v-else branch, the comment node must be created as a
|
|
// block to ensure correct updates.
|
|
asBlock = false) {
|
|
return asBlock
|
|
? (openBlock(), createBlock(Comment$1, null, text))
|
|
: createVNode(Comment$1, null, text);
|
|
}
|
|
function normalizeVNode(child) {
|
|
if (child == null || typeof child === 'boolean') {
|
|
// empty placeholder
|
|
return createVNode(Comment$1);
|
|
}
|
|
else if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isArray)(child)) {
|
|
// fragment
|
|
return createVNode(Fragment, null,
|
|
// #3666, avoid reference pollution when reusing vnode
|
|
child.slice());
|
|
}
|
|
else if (typeof child === 'object') {
|
|
// already vnode, this should be the most common since compiled templates
|
|
// always produce all-vnode children arrays
|
|
return cloneIfMounted(child);
|
|
}
|
|
else {
|
|
// strings and numbers
|
|
return createVNode(Text, null, String(child));
|
|
}
|
|
}
|
|
// optimized normalization for template-compiled render fns
|
|
function cloneIfMounted(child) {
|
|
return child.el === null || child.memo ? child : cloneVNode(child);
|
|
}
|
|
function normalizeChildren(vnode, children) {
|
|
let type = 0;
|
|
const { shapeFlag } = vnode;
|
|
if (children == null) {
|
|
children = null;
|
|
}
|
|
else if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isArray)(children)) {
|
|
type = 16 /* ARRAY_CHILDREN */;
|
|
}
|
|
else if (typeof children === 'object') {
|
|
if (shapeFlag & (1 /* ELEMENT */ | 64 /* TELEPORT */)) {
|
|
// Normalize slot to plain children for plain element and Teleport
|
|
const slot = children.default;
|
|
if (slot) {
|
|
// _c marker is added by withCtx() indicating this is a compiled slot
|
|
slot._c && (slot._d = false);
|
|
normalizeChildren(vnode, slot());
|
|
slot._c && (slot._d = true);
|
|
}
|
|
return;
|
|
}
|
|
else {
|
|
type = 32 /* SLOTS_CHILDREN */;
|
|
const slotFlag = children._;
|
|
if (!slotFlag && !(InternalObjectKey in children)) {
|
|
children._ctx = currentRenderingInstance;
|
|
}
|
|
else if (slotFlag === 3 /* FORWARDED */ && currentRenderingInstance) {
|
|
// a child component receives forwarded slots from the parent.
|
|
// its slot type is determined by its parent's slot type.
|
|
if (currentRenderingInstance.slots._ === 1 /* STABLE */) {
|
|
children._ = 1 /* STABLE */;
|
|
}
|
|
else {
|
|
children._ = 2 /* DYNAMIC */;
|
|
vnode.patchFlag |= 1024 /* DYNAMIC_SLOTS */;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isFunction)(children)) {
|
|
children = { default: children, _ctx: currentRenderingInstance };
|
|
type = 32 /* SLOTS_CHILDREN */;
|
|
}
|
|
else {
|
|
children = String(children);
|
|
// force teleport children to array so it can be moved around
|
|
if (shapeFlag & 64 /* TELEPORT */) {
|
|
type = 16 /* ARRAY_CHILDREN */;
|
|
children = [createTextVNode(children)];
|
|
}
|
|
else {
|
|
type = 8 /* TEXT_CHILDREN */;
|
|
}
|
|
}
|
|
vnode.children = children;
|
|
vnode.shapeFlag |= type;
|
|
}
|
|
function mergeProps(...args) {
|
|
const ret = {};
|
|
for (let i = 0; i < args.length; i++) {
|
|
const toMerge = args[i];
|
|
for (const key in toMerge) {
|
|
if (key === 'class') {
|
|
if (ret.class !== toMerge.class) {
|
|
ret.class = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.normalizeClass)([ret.class, toMerge.class]);
|
|
}
|
|
}
|
|
else if (key === 'style') {
|
|
ret.style = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.normalizeStyle)([ret.style, toMerge.style]);
|
|
}
|
|
else if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isOn)(key)) {
|
|
const existing = ret[key];
|
|
const incoming = toMerge[key];
|
|
if (existing !== incoming) {
|
|
ret[key] = existing
|
|
? [].concat(existing, incoming)
|
|
: incoming;
|
|
}
|
|
}
|
|
else if (key !== '') {
|
|
ret[key] = toMerge[key];
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* Actual implementation
|
|
*/
|
|
function renderList(source, renderItem, cache, index) {
|
|
let ret;
|
|
const cached = (cache && cache[index]);
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isArray)(source) || (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isString)(source)) {
|
|
ret = new Array(source.length);
|
|
for (let i = 0, l = source.length; i < l; i++) {
|
|
ret[i] = renderItem(source[i], i, undefined, cached && cached[i]);
|
|
}
|
|
}
|
|
else if (typeof source === 'number') {
|
|
if (( true) && !Number.isInteger(source)) {
|
|
warn(`The v-for range expect an integer value but got ${source}.`);
|
|
return [];
|
|
}
|
|
ret = new Array(source);
|
|
for (let i = 0; i < source; i++) {
|
|
ret[i] = renderItem(i + 1, i, undefined, cached && cached[i]);
|
|
}
|
|
}
|
|
else if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isObject)(source)) {
|
|
if (source[Symbol.iterator]) {
|
|
ret = Array.from(source, (item, i) => renderItem(item, i, undefined, cached && cached[i]));
|
|
}
|
|
else {
|
|
const keys = Object.keys(source);
|
|
ret = new Array(keys.length);
|
|
for (let i = 0, l = keys.length; i < l; i++) {
|
|
const key = keys[i];
|
|
ret[i] = renderItem(source[key], key, i, cached && cached[i]);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
ret = [];
|
|
}
|
|
if (cache) {
|
|
cache[index] = ret;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* Compiler runtime helper for creating dynamic slots object
|
|
* @private
|
|
*/
|
|
function createSlots(slots, dynamicSlots) {
|
|
for (let i = 0; i < dynamicSlots.length; i++) {
|
|
const slot = dynamicSlots[i];
|
|
// array of dynamic slot generated by <template v-for="..." #[...]>
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isArray)(slot)) {
|
|
for (let j = 0; j < slot.length; j++) {
|
|
slots[slot[j].name] = slot[j].fn;
|
|
}
|
|
}
|
|
else if (slot) {
|
|
// conditional single slot generated by <template v-if="..." #foo>
|
|
slots[slot.name] = slot.fn;
|
|
}
|
|
}
|
|
return slots;
|
|
}
|
|
|
|
/**
|
|
* Compiler runtime helper for rendering `<slot/>`
|
|
* @private
|
|
*/
|
|
function renderSlot(slots, name, props = {},
|
|
// this is not a user-facing function, so the fallback is always generated by
|
|
// the compiler and guaranteed to be a function returning an array
|
|
fallback, noSlotted) {
|
|
if (currentRenderingInstance.isCE) {
|
|
return createVNode('slot', name === 'default' ? null : { name }, fallback && fallback());
|
|
}
|
|
let slot = slots[name];
|
|
if (( true) && slot && slot.length > 1) {
|
|
warn(`SSR-optimized slot function detected in a non-SSR-optimized render ` +
|
|
`function. You need to mark this component with $dynamic-slots in the ` +
|
|
`parent template.`);
|
|
slot = () => [];
|
|
}
|
|
// a compiled slot disables block tracking by default to avoid manual
|
|
// invocation interfering with template-based block tracking, but in
|
|
// `renderSlot` we can be sure that it's template-based so we can force
|
|
// enable it.
|
|
if (slot && slot._c) {
|
|
slot._d = false;
|
|
}
|
|
openBlock();
|
|
const validSlotContent = slot && ensureValidVNode(slot(props));
|
|
const rendered = createBlock(Fragment, { key: props.key || `_${name}` }, validSlotContent || (fallback ? fallback() : []), validSlotContent && slots._ === 1 /* STABLE */
|
|
? 64 /* STABLE_FRAGMENT */
|
|
: -2 /* BAIL */);
|
|
if (!noSlotted && rendered.scopeId) {
|
|
rendered.slotScopeIds = [rendered.scopeId + '-s'];
|
|
}
|
|
if (slot && slot._c) {
|
|
slot._d = true;
|
|
}
|
|
return rendered;
|
|
}
|
|
function ensureValidVNode(vnodes) {
|
|
return vnodes.some(child => {
|
|
if (!isVNode(child))
|
|
return true;
|
|
if (child.type === Comment$1)
|
|
return false;
|
|
if (child.type === Fragment &&
|
|
!ensureValidVNode(child.children))
|
|
return false;
|
|
return true;
|
|
})
|
|
? vnodes
|
|
: null;
|
|
}
|
|
|
|
/**
|
|
* For prefixing keys in v-on="obj" with "on"
|
|
* @private
|
|
*/
|
|
function toHandlers(obj) {
|
|
const ret = {};
|
|
if (( true) && !(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isObject)(obj)) {
|
|
warn(`v-on with no argument expects an object value.`);
|
|
return ret;
|
|
}
|
|
for (const key in obj) {
|
|
ret[(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.toHandlerKey)(key)] = obj[key];
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* #2437 In Vue 3, functional components do not have a public instance proxy but
|
|
* they exist in the internal parent chain. For code that relies on traversing
|
|
* public $parent chains, skip functional ones and go to the parent instead.
|
|
*/
|
|
const getPublicInstance = (i) => {
|
|
if (!i)
|
|
return null;
|
|
if (isStatefulComponent(i))
|
|
return getExposeProxy(i) || i.proxy;
|
|
return getPublicInstance(i.parent);
|
|
};
|
|
const publicPropertiesMap = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.extend)(Object.create(null), {
|
|
$: i => i,
|
|
$el: i => i.vnode.el,
|
|
$data: i => i.data,
|
|
$props: i => (( true) ? (0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.shallowReadonly)(i.props) : 0),
|
|
$attrs: i => (( true) ? (0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.shallowReadonly)(i.attrs) : 0),
|
|
$slots: i => (( true) ? (0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.shallowReadonly)(i.slots) : 0),
|
|
$refs: i => (( true) ? (0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.shallowReadonly)(i.refs) : 0),
|
|
$parent: i => getPublicInstance(i.parent),
|
|
$root: i => getPublicInstance(i.root),
|
|
$emit: i => i.emit,
|
|
$options: i => (__VUE_OPTIONS_API__ ? resolveMergedOptions(i) : i.type),
|
|
$forceUpdate: i => () => queueJob(i.update),
|
|
$nextTick: i => nextTick.bind(i.proxy),
|
|
$watch: i => (__VUE_OPTIONS_API__ ? instanceWatch.bind(i) : _vue_shared__WEBPACK_IMPORTED_MODULE_1__.NOOP)
|
|
});
|
|
const PublicInstanceProxyHandlers = {
|
|
get({ _: instance }, key) {
|
|
const { ctx, setupState, data, props, accessCache, type, appContext } = instance;
|
|
// for internal formatters to know that this is a Vue instance
|
|
if (( true) && key === '__isVue') {
|
|
return true;
|
|
}
|
|
// prioritize <script setup> bindings during dev.
|
|
// this allows even properties that start with _ or $ to be used - so that
|
|
// it aligns with the production behavior where the render fn is inlined and
|
|
// indeed has access to all declared variables.
|
|
if (( true) &&
|
|
setupState !== _vue_shared__WEBPACK_IMPORTED_MODULE_1__.EMPTY_OBJ &&
|
|
setupState.__isScriptSetup &&
|
|
(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.hasOwn)(setupState, key)) {
|
|
return setupState[key];
|
|
}
|
|
// data / props / ctx
|
|
// This getter gets called for every property access on the render context
|
|
// during render and is a major hotspot. The most expensive part of this
|
|
// is the multiple hasOwn() calls. It's much faster to do a simple property
|
|
// access on a plain object, so we use an accessCache object (with null
|
|
// prototype) to memoize what access type a key corresponds to.
|
|
let normalizedProps;
|
|
if (key[0] !== '$') {
|
|
const n = accessCache[key];
|
|
if (n !== undefined) {
|
|
switch (n) {
|
|
case 0 /* SETUP */:
|
|
return setupState[key];
|
|
case 1 /* DATA */:
|
|
return data[key];
|
|
case 3 /* CONTEXT */:
|
|
return ctx[key];
|
|
case 2 /* PROPS */:
|
|
return props[key];
|
|
// default: just fallthrough
|
|
}
|
|
}
|
|
else if (setupState !== _vue_shared__WEBPACK_IMPORTED_MODULE_1__.EMPTY_OBJ && (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.hasOwn)(setupState, key)) {
|
|
accessCache[key] = 0 /* SETUP */;
|
|
return setupState[key];
|
|
}
|
|
else if (data !== _vue_shared__WEBPACK_IMPORTED_MODULE_1__.EMPTY_OBJ && (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.hasOwn)(data, key)) {
|
|
accessCache[key] = 1 /* DATA */;
|
|
return data[key];
|
|
}
|
|
else if (
|
|
// only cache other properties when instance has declared (thus stable)
|
|
// props
|
|
(normalizedProps = instance.propsOptions[0]) &&
|
|
(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.hasOwn)(normalizedProps, key)) {
|
|
accessCache[key] = 2 /* PROPS */;
|
|
return props[key];
|
|
}
|
|
else if (ctx !== _vue_shared__WEBPACK_IMPORTED_MODULE_1__.EMPTY_OBJ && (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.hasOwn)(ctx, key)) {
|
|
accessCache[key] = 3 /* CONTEXT */;
|
|
return ctx[key];
|
|
}
|
|
else if (!__VUE_OPTIONS_API__ || shouldCacheAccess) {
|
|
accessCache[key] = 4 /* OTHER */;
|
|
}
|
|
}
|
|
const publicGetter = publicPropertiesMap[key];
|
|
let cssModule, globalProperties;
|
|
// public $xxx properties
|
|
if (publicGetter) {
|
|
if (key === '$attrs') {
|
|
(0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.track)(instance, "get" /* GET */, key);
|
|
( true) && markAttrsAccessed();
|
|
}
|
|
return publicGetter(instance);
|
|
}
|
|
else if (
|
|
// css module (injected by vue-loader)
|
|
(cssModule = type.__cssModules) &&
|
|
(cssModule = cssModule[key])) {
|
|
return cssModule;
|
|
}
|
|
else if (ctx !== _vue_shared__WEBPACK_IMPORTED_MODULE_1__.EMPTY_OBJ && (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.hasOwn)(ctx, key)) {
|
|
// user may set custom properties to `this` that start with `$`
|
|
accessCache[key] = 3 /* CONTEXT */;
|
|
return ctx[key];
|
|
}
|
|
else if (
|
|
// global properties
|
|
((globalProperties = appContext.config.globalProperties),
|
|
(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.hasOwn)(globalProperties, key))) {
|
|
{
|
|
return globalProperties[key];
|
|
}
|
|
}
|
|
else if (( true) &&
|
|
currentRenderingInstance &&
|
|
(!(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isString)(key) ||
|
|
// #1091 avoid internal isRef/isVNode checks on component instance leading
|
|
// to infinite warning loop
|
|
key.indexOf('__v') !== 0)) {
|
|
if (data !== _vue_shared__WEBPACK_IMPORTED_MODULE_1__.EMPTY_OBJ &&
|
|
(key[0] === '$' || key[0] === '_') &&
|
|
(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.hasOwn)(data, key)) {
|
|
warn(`Property ${JSON.stringify(key)} must be accessed via $data because it starts with a reserved ` +
|
|
`character ("$" or "_") and is not proxied on the render context.`);
|
|
}
|
|
else if (instance === currentRenderingInstance) {
|
|
warn(`Property ${JSON.stringify(key)} was accessed during render ` +
|
|
`but is not defined on instance.`);
|
|
}
|
|
}
|
|
},
|
|
set({ _: instance }, key, value) {
|
|
const { data, setupState, ctx } = instance;
|
|
if (setupState !== _vue_shared__WEBPACK_IMPORTED_MODULE_1__.EMPTY_OBJ && (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.hasOwn)(setupState, key)) {
|
|
setupState[key] = value;
|
|
}
|
|
else if (data !== _vue_shared__WEBPACK_IMPORTED_MODULE_1__.EMPTY_OBJ && (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.hasOwn)(data, key)) {
|
|
data[key] = value;
|
|
}
|
|
else if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.hasOwn)(instance.props, key)) {
|
|
( true) &&
|
|
warn(`Attempting to mutate prop "${key}". Props are readonly.`, instance);
|
|
return false;
|
|
}
|
|
if (key[0] === '$' && key.slice(1) in instance) {
|
|
( true) &&
|
|
warn(`Attempting to mutate public property "${key}". ` +
|
|
`Properties starting with $ are reserved and readonly.`, instance);
|
|
return false;
|
|
}
|
|
else {
|
|
if (( true) && key in instance.appContext.config.globalProperties) {
|
|
Object.defineProperty(ctx, key, {
|
|
enumerable: true,
|
|
configurable: true,
|
|
value
|
|
});
|
|
}
|
|
else {
|
|
ctx[key] = value;
|
|
}
|
|
}
|
|
return true;
|
|
},
|
|
has({ _: { data, setupState, accessCache, ctx, appContext, propsOptions } }, key) {
|
|
let normalizedProps;
|
|
return (accessCache[key] !== undefined ||
|
|
(data !== _vue_shared__WEBPACK_IMPORTED_MODULE_1__.EMPTY_OBJ && (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.hasOwn)(data, key)) ||
|
|
(setupState !== _vue_shared__WEBPACK_IMPORTED_MODULE_1__.EMPTY_OBJ && (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.hasOwn)(setupState, key)) ||
|
|
((normalizedProps = propsOptions[0]) && (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.hasOwn)(normalizedProps, key)) ||
|
|
(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.hasOwn)(ctx, key) ||
|
|
(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.hasOwn)(publicPropertiesMap, key) ||
|
|
(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.hasOwn)(appContext.config.globalProperties, key));
|
|
}
|
|
};
|
|
if (true) {
|
|
PublicInstanceProxyHandlers.ownKeys = (target) => {
|
|
warn(`Avoid app logic that relies on enumerating keys on a component instance. ` +
|
|
`The keys will be empty in production mode to avoid performance overhead.`);
|
|
return Reflect.ownKeys(target);
|
|
};
|
|
}
|
|
const RuntimeCompiledPublicInstanceProxyHandlers = /*#__PURE__*/ (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.extend)({}, PublicInstanceProxyHandlers, {
|
|
get(target, key) {
|
|
// fast path for unscopables when using `with` block
|
|
if (key === Symbol.unscopables) {
|
|
return;
|
|
}
|
|
return PublicInstanceProxyHandlers.get(target, key, target);
|
|
},
|
|
has(_, key) {
|
|
const has = key[0] !== '_' && !(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isGloballyWhitelisted)(key);
|
|
if (( true) && !has && PublicInstanceProxyHandlers.has(_, key)) {
|
|
warn(`Property ${JSON.stringify(key)} should not start with _ which is a reserved prefix for Vue internals.`);
|
|
}
|
|
return has;
|
|
}
|
|
});
|
|
// dev only
|
|
// In dev mode, the proxy target exposes the same properties as seen on `this`
|
|
// for easier console inspection. In prod mode it will be an empty object so
|
|
// these properties definitions can be skipped.
|
|
function createDevRenderContext(instance) {
|
|
const target = {};
|
|
// expose internal instance for proxy handlers
|
|
Object.defineProperty(target, `_`, {
|
|
configurable: true,
|
|
enumerable: false,
|
|
get: () => instance
|
|
});
|
|
// expose public properties
|
|
Object.keys(publicPropertiesMap).forEach(key => {
|
|
Object.defineProperty(target, key, {
|
|
configurable: true,
|
|
enumerable: false,
|
|
get: () => publicPropertiesMap[key](instance),
|
|
// intercepted by the proxy so no need for implementation,
|
|
// but needed to prevent set errors
|
|
set: _vue_shared__WEBPACK_IMPORTED_MODULE_1__.NOOP
|
|
});
|
|
});
|
|
return target;
|
|
}
|
|
// dev only
|
|
function exposePropsOnRenderContext(instance) {
|
|
const { ctx, propsOptions: [propsOptions] } = instance;
|
|
if (propsOptions) {
|
|
Object.keys(propsOptions).forEach(key => {
|
|
Object.defineProperty(ctx, key, {
|
|
enumerable: true,
|
|
configurable: true,
|
|
get: () => instance.props[key],
|
|
set: _vue_shared__WEBPACK_IMPORTED_MODULE_1__.NOOP
|
|
});
|
|
});
|
|
}
|
|
}
|
|
// dev only
|
|
function exposeSetupStateOnRenderContext(instance) {
|
|
const { ctx, setupState } = instance;
|
|
Object.keys((0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.toRaw)(setupState)).forEach(key => {
|
|
if (!setupState.__isScriptSetup && (key[0] === '$' || key[0] === '_')) {
|
|
warn(`setup() return property ${JSON.stringify(key)} should not start with "$" or "_" ` +
|
|
`which are reserved prefixes for Vue internals.`);
|
|
return;
|
|
}
|
|
Object.defineProperty(ctx, key, {
|
|
enumerable: true,
|
|
configurable: true,
|
|
get: () => setupState[key],
|
|
set: _vue_shared__WEBPACK_IMPORTED_MODULE_1__.NOOP
|
|
});
|
|
});
|
|
}
|
|
|
|
const emptyAppContext = createAppContext();
|
|
let uid$1 = 0;
|
|
function createComponentInstance(vnode, parent, suspense) {
|
|
const type = vnode.type;
|
|
// inherit parent app context - or - if root, adopt from root vnode
|
|
const appContext = (parent ? parent.appContext : vnode.appContext) || emptyAppContext;
|
|
const instance = {
|
|
uid: uid$1++,
|
|
vnode,
|
|
type,
|
|
parent,
|
|
appContext,
|
|
root: null,
|
|
next: null,
|
|
subTree: null,
|
|
update: null,
|
|
scope: new _vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.EffectScope(true /* detached */),
|
|
render: null,
|
|
proxy: null,
|
|
exposed: null,
|
|
exposeProxy: null,
|
|
withProxy: null,
|
|
provides: parent ? parent.provides : Object.create(appContext.provides),
|
|
accessCache: null,
|
|
renderCache: [],
|
|
// local resovled assets
|
|
components: null,
|
|
directives: null,
|
|
// resolved props and emits options
|
|
propsOptions: normalizePropsOptions(type, appContext),
|
|
emitsOptions: normalizeEmitsOptions(type, appContext),
|
|
// emit
|
|
emit: null,
|
|
emitted: null,
|
|
// props default value
|
|
propsDefaults: _vue_shared__WEBPACK_IMPORTED_MODULE_1__.EMPTY_OBJ,
|
|
// inheritAttrs
|
|
inheritAttrs: type.inheritAttrs,
|
|
// state
|
|
ctx: _vue_shared__WEBPACK_IMPORTED_MODULE_1__.EMPTY_OBJ,
|
|
data: _vue_shared__WEBPACK_IMPORTED_MODULE_1__.EMPTY_OBJ,
|
|
props: _vue_shared__WEBPACK_IMPORTED_MODULE_1__.EMPTY_OBJ,
|
|
attrs: _vue_shared__WEBPACK_IMPORTED_MODULE_1__.EMPTY_OBJ,
|
|
slots: _vue_shared__WEBPACK_IMPORTED_MODULE_1__.EMPTY_OBJ,
|
|
refs: _vue_shared__WEBPACK_IMPORTED_MODULE_1__.EMPTY_OBJ,
|
|
setupState: _vue_shared__WEBPACK_IMPORTED_MODULE_1__.EMPTY_OBJ,
|
|
setupContext: null,
|
|
// suspense related
|
|
suspense,
|
|
suspenseId: suspense ? suspense.pendingId : 0,
|
|
asyncDep: null,
|
|
asyncResolved: false,
|
|
// lifecycle hooks
|
|
// not using enums here because it results in computed properties
|
|
isMounted: false,
|
|
isUnmounted: false,
|
|
isDeactivated: false,
|
|
bc: null,
|
|
c: null,
|
|
bm: null,
|
|
m: null,
|
|
bu: null,
|
|
u: null,
|
|
um: null,
|
|
bum: null,
|
|
da: null,
|
|
a: null,
|
|
rtg: null,
|
|
rtc: null,
|
|
ec: null,
|
|
sp: null
|
|
};
|
|
if ((true)) {
|
|
instance.ctx = createDevRenderContext(instance);
|
|
}
|
|
else {}
|
|
instance.root = parent ? parent.root : instance;
|
|
instance.emit = emit.bind(null, instance);
|
|
// apply custom element special handling
|
|
if (vnode.ce) {
|
|
vnode.ce(instance);
|
|
}
|
|
return instance;
|
|
}
|
|
let currentInstance = null;
|
|
const getCurrentInstance = () => currentInstance || currentRenderingInstance;
|
|
const setCurrentInstance = (instance) => {
|
|
currentInstance = instance;
|
|
instance.scope.on();
|
|
};
|
|
const unsetCurrentInstance = () => {
|
|
currentInstance && currentInstance.scope.off();
|
|
currentInstance = null;
|
|
};
|
|
const isBuiltInTag = /*#__PURE__*/ (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.makeMap)('slot,component');
|
|
function validateComponentName(name, config) {
|
|
const appIsNativeTag = config.isNativeTag || _vue_shared__WEBPACK_IMPORTED_MODULE_1__.NO;
|
|
if (isBuiltInTag(name) || appIsNativeTag(name)) {
|
|
warn('Do not use built-in or reserved HTML elements as component id: ' + name);
|
|
}
|
|
}
|
|
function isStatefulComponent(instance) {
|
|
return instance.vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */;
|
|
}
|
|
let isInSSRComponentSetup = false;
|
|
function setupComponent(instance, isSSR = false) {
|
|
isInSSRComponentSetup = isSSR;
|
|
const { props, children } = instance.vnode;
|
|
const isStateful = isStatefulComponent(instance);
|
|
initProps(instance, props, isStateful, isSSR);
|
|
initSlots(instance, children);
|
|
const setupResult = isStateful
|
|
? setupStatefulComponent(instance, isSSR)
|
|
: undefined;
|
|
isInSSRComponentSetup = false;
|
|
return setupResult;
|
|
}
|
|
function setupStatefulComponent(instance, isSSR) {
|
|
const Component = instance.type;
|
|
if ((true)) {
|
|
if (Component.name) {
|
|
validateComponentName(Component.name, instance.appContext.config);
|
|
}
|
|
if (Component.components) {
|
|
const names = Object.keys(Component.components);
|
|
for (let i = 0; i < names.length; i++) {
|
|
validateComponentName(names[i], instance.appContext.config);
|
|
}
|
|
}
|
|
if (Component.directives) {
|
|
const names = Object.keys(Component.directives);
|
|
for (let i = 0; i < names.length; i++) {
|
|
validateDirectiveName(names[i]);
|
|
}
|
|
}
|
|
if (Component.compilerOptions && isRuntimeOnly()) {
|
|
warn(`"compilerOptions" is only supported when using a build of Vue that ` +
|
|
`includes the runtime compiler. Since you are using a runtime-only ` +
|
|
`build, the options should be passed via your build tool config instead.`);
|
|
}
|
|
}
|
|
// 0. create render proxy property access cache
|
|
instance.accessCache = Object.create(null);
|
|
// 1. create public instance / render proxy
|
|
// also mark it raw so it's never observed
|
|
instance.proxy = (0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.markRaw)(new Proxy(instance.ctx, PublicInstanceProxyHandlers));
|
|
if ((true)) {
|
|
exposePropsOnRenderContext(instance);
|
|
}
|
|
// 2. call setup()
|
|
const { setup } = Component;
|
|
if (setup) {
|
|
const setupContext = (instance.setupContext =
|
|
setup.length > 1 ? createSetupContext(instance) : null);
|
|
setCurrentInstance(instance);
|
|
(0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.pauseTracking)();
|
|
const setupResult = callWithErrorHandling(setup, instance, 0 /* SETUP_FUNCTION */, [( true) ? (0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.shallowReadonly)(instance.props) : 0, setupContext]);
|
|
(0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.resetTracking)();
|
|
unsetCurrentInstance();
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isPromise)(setupResult)) {
|
|
setupResult.then(unsetCurrentInstance, unsetCurrentInstance);
|
|
if (isSSR) {
|
|
// return the promise so server-renderer can wait on it
|
|
return setupResult
|
|
.then((resolvedResult) => {
|
|
handleSetupResult(instance, resolvedResult, isSSR);
|
|
})
|
|
.catch(e => {
|
|
handleError(e, instance, 0 /* SETUP_FUNCTION */);
|
|
});
|
|
}
|
|
else {
|
|
// async setup returned Promise.
|
|
// bail here and wait for re-entry.
|
|
instance.asyncDep = setupResult;
|
|
}
|
|
}
|
|
else {
|
|
handleSetupResult(instance, setupResult, isSSR);
|
|
}
|
|
}
|
|
else {
|
|
finishComponentSetup(instance, isSSR);
|
|
}
|
|
}
|
|
function handleSetupResult(instance, setupResult, isSSR) {
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isFunction)(setupResult)) {
|
|
// setup returned an inline render function
|
|
{
|
|
instance.render = setupResult;
|
|
}
|
|
}
|
|
else if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isObject)(setupResult)) {
|
|
if (( true) && isVNode(setupResult)) {
|
|
warn(`setup() should not return VNodes directly - ` +
|
|
`return a render function instead.`);
|
|
}
|
|
// setup returned bindings.
|
|
// assuming a render function compiled from template is present.
|
|
if (true) {
|
|
instance.devtoolsRawSetupState = setupResult;
|
|
}
|
|
instance.setupState = (0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.proxyRefs)(setupResult);
|
|
if ((true)) {
|
|
exposeSetupStateOnRenderContext(instance);
|
|
}
|
|
}
|
|
else if (( true) && setupResult !== undefined) {
|
|
warn(`setup() should return an object. Received: ${setupResult === null ? 'null' : typeof setupResult}`);
|
|
}
|
|
finishComponentSetup(instance, isSSR);
|
|
}
|
|
let compile;
|
|
let installWithProxy;
|
|
/**
|
|
* For runtime-dom to register the compiler.
|
|
* Note the exported method uses any to avoid d.ts relying on the compiler types.
|
|
*/
|
|
function registerRuntimeCompiler(_compile) {
|
|
compile = _compile;
|
|
installWithProxy = i => {
|
|
if (i.render._rc) {
|
|
i.withProxy = new Proxy(i.ctx, RuntimeCompiledPublicInstanceProxyHandlers);
|
|
}
|
|
};
|
|
}
|
|
// dev only
|
|
const isRuntimeOnly = () => !compile;
|
|
function finishComponentSetup(instance, isSSR, skipOptions) {
|
|
const Component = instance.type;
|
|
// template / render function normalization
|
|
if (!instance.render) {
|
|
// could be set from setup()
|
|
if (compile && !Component.render) {
|
|
const template = Component.template;
|
|
if (template) {
|
|
if ((true)) {
|
|
startMeasure(instance, `compile`);
|
|
}
|
|
const { isCustomElement, compilerOptions } = instance.appContext.config;
|
|
const { delimiters, compilerOptions: componentCompilerOptions } = Component;
|
|
const finalCompilerOptions = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.extend)((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.extend)({
|
|
isCustomElement,
|
|
delimiters
|
|
}, compilerOptions), componentCompilerOptions);
|
|
Component.render = compile(template, finalCompilerOptions);
|
|
if ((true)) {
|
|
endMeasure(instance, `compile`);
|
|
}
|
|
}
|
|
}
|
|
instance.render = (Component.render || _vue_shared__WEBPACK_IMPORTED_MODULE_1__.NOOP);
|
|
// for runtime-compiled render functions using `with` blocks, the render
|
|
// proxy used needs a different `has` handler which is more performant and
|
|
// also only allows a whitelist of globals to fallthrough.
|
|
if (installWithProxy) {
|
|
installWithProxy(instance);
|
|
}
|
|
}
|
|
// support for 2.x options
|
|
if (__VUE_OPTIONS_API__ && !(false )) {
|
|
setCurrentInstance(instance);
|
|
(0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.pauseTracking)();
|
|
applyOptions(instance);
|
|
(0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.resetTracking)();
|
|
unsetCurrentInstance();
|
|
}
|
|
// warn missing template/render
|
|
// the runtime compilation of template in SSR is done by server-render
|
|
if (( true) && !Component.render && instance.render === _vue_shared__WEBPACK_IMPORTED_MODULE_1__.NOOP && !isSSR) {
|
|
/* istanbul ignore if */
|
|
if (!compile && Component.template) {
|
|
warn(`Component provided template option but ` +
|
|
`runtime compilation is not supported in this build of Vue.` +
|
|
(` Configure your bundler to alias "vue" to "vue/dist/vue.esm-bundler.js".`
|
|
) /* should not happen */);
|
|
}
|
|
else {
|
|
warn(`Component is missing template or render function.`);
|
|
}
|
|
}
|
|
}
|
|
function createAttrsProxy(instance) {
|
|
return new Proxy(instance.attrs, ( true)
|
|
? {
|
|
get(target, key) {
|
|
markAttrsAccessed();
|
|
(0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.track)(instance, "get" /* GET */, '$attrs');
|
|
return target[key];
|
|
},
|
|
set() {
|
|
warn(`setupContext.attrs is readonly.`);
|
|
return false;
|
|
},
|
|
deleteProperty() {
|
|
warn(`setupContext.attrs is readonly.`);
|
|
return false;
|
|
}
|
|
}
|
|
: 0);
|
|
}
|
|
function createSetupContext(instance) {
|
|
const expose = exposed => {
|
|
if (( true) && instance.exposed) {
|
|
warn(`expose() should be called only once per setup().`);
|
|
}
|
|
instance.exposed = exposed || {};
|
|
};
|
|
let attrs;
|
|
if ((true)) {
|
|
// We use getters in dev in case libs like test-utils overwrite instance
|
|
// properties (overwrites should not be done in prod)
|
|
return Object.freeze({
|
|
get attrs() {
|
|
return attrs || (attrs = createAttrsProxy(instance));
|
|
},
|
|
get slots() {
|
|
return (0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.shallowReadonly)(instance.slots);
|
|
},
|
|
get emit() {
|
|
return (event, ...args) => instance.emit(event, ...args);
|
|
},
|
|
expose
|
|
});
|
|
}
|
|
else {}
|
|
}
|
|
function getExposeProxy(instance) {
|
|
if (instance.exposed) {
|
|
return (instance.exposeProxy ||
|
|
(instance.exposeProxy = new Proxy((0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.proxyRefs)((0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.markRaw)(instance.exposed)), {
|
|
get(target, key) {
|
|
if (key in target) {
|
|
return target[key];
|
|
}
|
|
else if (key in publicPropertiesMap) {
|
|
return publicPropertiesMap[key](instance);
|
|
}
|
|
}
|
|
})));
|
|
}
|
|
}
|
|
const classifyRE = /(?:^|[-_])(\w)/g;
|
|
const classify = (str) => str.replace(classifyRE, c => c.toUpperCase()).replace(/[-_]/g, '');
|
|
function getComponentName(Component) {
|
|
return (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isFunction)(Component)
|
|
? Component.displayName || Component.name
|
|
: Component.name;
|
|
}
|
|
/* istanbul ignore next */
|
|
function formatComponentName(instance, Component, isRoot = false) {
|
|
let name = getComponentName(Component);
|
|
if (!name && Component.__file) {
|
|
const match = Component.__file.match(/([^/\\]+)\.\w+$/);
|
|
if (match) {
|
|
name = match[1];
|
|
}
|
|
}
|
|
if (!name && instance && instance.parent) {
|
|
// try to infer the name based on reverse resolution
|
|
const inferFromRegistry = (registry) => {
|
|
for (const key in registry) {
|
|
if (registry[key] === Component) {
|
|
return key;
|
|
}
|
|
}
|
|
};
|
|
name =
|
|
inferFromRegistry(instance.components ||
|
|
instance.parent.type.components) || inferFromRegistry(instance.appContext.components);
|
|
}
|
|
return name ? classify(name) : isRoot ? `App` : `Anonymous`;
|
|
}
|
|
function isClassComponent(value) {
|
|
return (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isFunction)(value) && '__vccOpts' in value;
|
|
}
|
|
|
|
const stack = [];
|
|
function pushWarningContext(vnode) {
|
|
stack.push(vnode);
|
|
}
|
|
function popWarningContext() {
|
|
stack.pop();
|
|
}
|
|
function warn(msg, ...args) {
|
|
// avoid props formatting or warn handler tracking deps that might be mutated
|
|
// during patch, leading to infinite recursion.
|
|
(0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.pauseTracking)();
|
|
const instance = stack.length ? stack[stack.length - 1].component : null;
|
|
const appWarnHandler = instance && instance.appContext.config.warnHandler;
|
|
const trace = getComponentTrace();
|
|
if (appWarnHandler) {
|
|
callWithErrorHandling(appWarnHandler, instance, 11 /* APP_WARN_HANDLER */, [
|
|
msg + args.join(''),
|
|
instance && instance.proxy,
|
|
trace
|
|
.map(({ vnode }) => `at <${formatComponentName(instance, vnode.type)}>`)
|
|
.join('\n'),
|
|
trace
|
|
]);
|
|
}
|
|
else {
|
|
const warnArgs = [`[Vue warn]: ${msg}`, ...args];
|
|
/* istanbul ignore if */
|
|
if (trace.length &&
|
|
// avoid spamming console during tests
|
|
!false) {
|
|
warnArgs.push(`\n`, ...formatTrace(trace));
|
|
}
|
|
console.warn(...warnArgs);
|
|
}
|
|
(0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.resetTracking)();
|
|
}
|
|
function getComponentTrace() {
|
|
let currentVNode = stack[stack.length - 1];
|
|
if (!currentVNode) {
|
|
return [];
|
|
}
|
|
// we can't just use the stack because it will be incomplete during updates
|
|
// that did not start from the root. Re-construct the parent chain using
|
|
// instance parent pointers.
|
|
const normalizedStack = [];
|
|
while (currentVNode) {
|
|
const last = normalizedStack[0];
|
|
if (last && last.vnode === currentVNode) {
|
|
last.recurseCount++;
|
|
}
|
|
else {
|
|
normalizedStack.push({
|
|
vnode: currentVNode,
|
|
recurseCount: 0
|
|
});
|
|
}
|
|
const parentInstance = currentVNode.component && currentVNode.component.parent;
|
|
currentVNode = parentInstance && parentInstance.vnode;
|
|
}
|
|
return normalizedStack;
|
|
}
|
|
/* istanbul ignore next */
|
|
function formatTrace(trace) {
|
|
const logs = [];
|
|
trace.forEach((entry, i) => {
|
|
logs.push(...(i === 0 ? [] : [`\n`]), ...formatTraceEntry(entry));
|
|
});
|
|
return logs;
|
|
}
|
|
function formatTraceEntry({ vnode, recurseCount }) {
|
|
const postfix = recurseCount > 0 ? `... (${recurseCount} recursive calls)` : ``;
|
|
const isRoot = vnode.component ? vnode.component.parent == null : false;
|
|
const open = ` at <${formatComponentName(vnode.component, vnode.type, isRoot)}`;
|
|
const close = `>` + postfix;
|
|
return vnode.props
|
|
? [open, ...formatProps(vnode.props), close]
|
|
: [open + close];
|
|
}
|
|
/* istanbul ignore next */
|
|
function formatProps(props) {
|
|
const res = [];
|
|
const keys = Object.keys(props);
|
|
keys.slice(0, 3).forEach(key => {
|
|
res.push(...formatProp(key, props[key]));
|
|
});
|
|
if (keys.length > 3) {
|
|
res.push(` ...`);
|
|
}
|
|
return res;
|
|
}
|
|
/* istanbul ignore next */
|
|
function formatProp(key, value, raw) {
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isString)(value)) {
|
|
value = JSON.stringify(value);
|
|
return raw ? value : [`${key}=${value}`];
|
|
}
|
|
else if (typeof value === 'number' ||
|
|
typeof value === 'boolean' ||
|
|
value == null) {
|
|
return raw ? value : [`${key}=${value}`];
|
|
}
|
|
else if ((0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.isRef)(value)) {
|
|
value = formatProp(key, (0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.toRaw)(value.value), true);
|
|
return raw ? value : [`${key}=Ref<`, value, `>`];
|
|
}
|
|
else if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isFunction)(value)) {
|
|
return [`${key}=fn${value.name ? `<${value.name}>` : ``}`];
|
|
}
|
|
else {
|
|
value = (0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.toRaw)(value);
|
|
return raw ? value : [`${key}=`, value];
|
|
}
|
|
}
|
|
|
|
const ErrorTypeStrings = {
|
|
["sp" /* SERVER_PREFETCH */]: 'serverPrefetch hook',
|
|
["bc" /* BEFORE_CREATE */]: 'beforeCreate hook',
|
|
["c" /* CREATED */]: 'created hook',
|
|
["bm" /* BEFORE_MOUNT */]: 'beforeMount hook',
|
|
["m" /* MOUNTED */]: 'mounted hook',
|
|
["bu" /* BEFORE_UPDATE */]: 'beforeUpdate hook',
|
|
["u" /* UPDATED */]: 'updated',
|
|
["bum" /* BEFORE_UNMOUNT */]: 'beforeUnmount hook',
|
|
["um" /* UNMOUNTED */]: 'unmounted hook',
|
|
["a" /* ACTIVATED */]: 'activated hook',
|
|
["da" /* DEACTIVATED */]: 'deactivated hook',
|
|
["ec" /* ERROR_CAPTURED */]: 'errorCaptured hook',
|
|
["rtc" /* RENDER_TRACKED */]: 'renderTracked hook',
|
|
["rtg" /* RENDER_TRIGGERED */]: 'renderTriggered hook',
|
|
[0 /* SETUP_FUNCTION */]: 'setup function',
|
|
[1 /* RENDER_FUNCTION */]: 'render function',
|
|
[2 /* WATCH_GETTER */]: 'watcher getter',
|
|
[3 /* WATCH_CALLBACK */]: 'watcher callback',
|
|
[4 /* WATCH_CLEANUP */]: 'watcher cleanup function',
|
|
[5 /* NATIVE_EVENT_HANDLER */]: 'native event handler',
|
|
[6 /* COMPONENT_EVENT_HANDLER */]: 'component event handler',
|
|
[7 /* VNODE_HOOK */]: 'vnode hook',
|
|
[8 /* DIRECTIVE_HOOK */]: 'directive hook',
|
|
[9 /* TRANSITION_HOOK */]: 'transition hook',
|
|
[10 /* APP_ERROR_HANDLER */]: 'app errorHandler',
|
|
[11 /* APP_WARN_HANDLER */]: 'app warnHandler',
|
|
[12 /* FUNCTION_REF */]: 'ref function',
|
|
[13 /* ASYNC_COMPONENT_LOADER */]: 'async component loader',
|
|
[14 /* SCHEDULER */]: 'scheduler flush. This is likely a Vue internals bug. ' +
|
|
'Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/vue-next'
|
|
};
|
|
function callWithErrorHandling(fn, instance, type, args) {
|
|
let res;
|
|
try {
|
|
res = args ? fn(...args) : fn();
|
|
}
|
|
catch (err) {
|
|
handleError(err, instance, type);
|
|
}
|
|
return res;
|
|
}
|
|
function callWithAsyncErrorHandling(fn, instance, type, args) {
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isFunction)(fn)) {
|
|
const res = callWithErrorHandling(fn, instance, type, args);
|
|
if (res && (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isPromise)(res)) {
|
|
res.catch(err => {
|
|
handleError(err, instance, type);
|
|
});
|
|
}
|
|
return res;
|
|
}
|
|
const values = [];
|
|
for (let i = 0; i < fn.length; i++) {
|
|
values.push(callWithAsyncErrorHandling(fn[i], instance, type, args));
|
|
}
|
|
return values;
|
|
}
|
|
function handleError(err, instance, type, throwInDev = true) {
|
|
const contextVNode = instance ? instance.vnode : null;
|
|
if (instance) {
|
|
let cur = instance.parent;
|
|
// the exposed instance is the render proxy to keep it consistent with 2.x
|
|
const exposedInstance = instance.proxy;
|
|
// in production the hook receives only the error code
|
|
const errorInfo = ( true) ? ErrorTypeStrings[type] : 0;
|
|
while (cur) {
|
|
const errorCapturedHooks = cur.ec;
|
|
if (errorCapturedHooks) {
|
|
for (let i = 0; i < errorCapturedHooks.length; i++) {
|
|
if (errorCapturedHooks[i](err, exposedInstance, errorInfo) === false) {
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
cur = cur.parent;
|
|
}
|
|
// app-level handling
|
|
const appErrorHandler = instance.appContext.config.errorHandler;
|
|
if (appErrorHandler) {
|
|
callWithErrorHandling(appErrorHandler, null, 10 /* APP_ERROR_HANDLER */, [err, exposedInstance, errorInfo]);
|
|
return;
|
|
}
|
|
}
|
|
logError(err, type, contextVNode, throwInDev);
|
|
}
|
|
function logError(err, type, contextVNode, throwInDev = true) {
|
|
if ((true)) {
|
|
const info = ErrorTypeStrings[type];
|
|
if (contextVNode) {
|
|
pushWarningContext(contextVNode);
|
|
}
|
|
warn(`Unhandled error${info ? ` during execution of ${info}` : ``}`);
|
|
if (contextVNode) {
|
|
popWarningContext();
|
|
}
|
|
// crash in dev by default so it's more noticeable
|
|
if (throwInDev) {
|
|
throw err;
|
|
}
|
|
else {
|
|
console.error(err);
|
|
}
|
|
}
|
|
else {}
|
|
}
|
|
|
|
let isFlushing = false;
|
|
let isFlushPending = false;
|
|
const queue = [];
|
|
let flushIndex = 0;
|
|
const pendingPreFlushCbs = [];
|
|
let activePreFlushCbs = null;
|
|
let preFlushIndex = 0;
|
|
const pendingPostFlushCbs = [];
|
|
let activePostFlushCbs = null;
|
|
let postFlushIndex = 0;
|
|
const resolvedPromise = Promise.resolve();
|
|
let currentFlushPromise = null;
|
|
let currentPreFlushParentJob = null;
|
|
const RECURSION_LIMIT = 100;
|
|
function nextTick(fn) {
|
|
const p = currentFlushPromise || resolvedPromise;
|
|
return fn ? p.then(this ? fn.bind(this) : fn) : p;
|
|
}
|
|
// #2768
|
|
// Use binary-search to find a suitable position in the queue,
|
|
// so that the queue maintains the increasing order of job's id,
|
|
// which can prevent the job from being skipped and also can avoid repeated patching.
|
|
function findInsertionIndex(id) {
|
|
// the start index should be `flushIndex + 1`
|
|
let start = flushIndex + 1;
|
|
let end = queue.length;
|
|
while (start < end) {
|
|
const middle = (start + end) >>> 1;
|
|
const middleJobId = getId(queue[middle]);
|
|
middleJobId < id ? (start = middle + 1) : (end = middle);
|
|
}
|
|
return start;
|
|
}
|
|
function queueJob(job) {
|
|
// the dedupe search uses the startIndex argument of Array.includes()
|
|
// by default the search index includes the current job that is being run
|
|
// so it cannot recursively trigger itself again.
|
|
// if the job is a watch() callback, the search will start with a +1 index to
|
|
// allow it recursively trigger itself - it is the user's responsibility to
|
|
// ensure it doesn't end up in an infinite loop.
|
|
if ((!queue.length ||
|
|
!queue.includes(job, isFlushing && job.allowRecurse ? flushIndex + 1 : flushIndex)) &&
|
|
job !== currentPreFlushParentJob) {
|
|
if (job.id == null) {
|
|
queue.push(job);
|
|
}
|
|
else {
|
|
queue.splice(findInsertionIndex(job.id), 0, job);
|
|
}
|
|
queueFlush();
|
|
}
|
|
}
|
|
function queueFlush() {
|
|
if (!isFlushing && !isFlushPending) {
|
|
isFlushPending = true;
|
|
currentFlushPromise = resolvedPromise.then(flushJobs);
|
|
}
|
|
}
|
|
function invalidateJob(job) {
|
|
const i = queue.indexOf(job);
|
|
if (i > flushIndex) {
|
|
queue.splice(i, 1);
|
|
}
|
|
}
|
|
function queueCb(cb, activeQueue, pendingQueue, index) {
|
|
if (!(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isArray)(cb)) {
|
|
if (!activeQueue ||
|
|
!activeQueue.includes(cb, cb.allowRecurse ? index + 1 : index)) {
|
|
pendingQueue.push(cb);
|
|
}
|
|
}
|
|
else {
|
|
// if cb is an array, it is a component lifecycle hook which can only be
|
|
// triggered by a job, which is already deduped in the main queue, so
|
|
// we can skip duplicate check here to improve perf
|
|
pendingQueue.push(...cb);
|
|
}
|
|
queueFlush();
|
|
}
|
|
function queuePreFlushCb(cb) {
|
|
queueCb(cb, activePreFlushCbs, pendingPreFlushCbs, preFlushIndex);
|
|
}
|
|
function queuePostFlushCb(cb) {
|
|
queueCb(cb, activePostFlushCbs, pendingPostFlushCbs, postFlushIndex);
|
|
}
|
|
function flushPreFlushCbs(seen, parentJob = null) {
|
|
if (pendingPreFlushCbs.length) {
|
|
currentPreFlushParentJob = parentJob;
|
|
activePreFlushCbs = [...new Set(pendingPreFlushCbs)];
|
|
pendingPreFlushCbs.length = 0;
|
|
if ((true)) {
|
|
seen = seen || new Map();
|
|
}
|
|
for (preFlushIndex = 0; preFlushIndex < activePreFlushCbs.length; preFlushIndex++) {
|
|
if (( true) &&
|
|
checkRecursiveUpdates(seen, activePreFlushCbs[preFlushIndex])) {
|
|
continue;
|
|
}
|
|
activePreFlushCbs[preFlushIndex]();
|
|
}
|
|
activePreFlushCbs = null;
|
|
preFlushIndex = 0;
|
|
currentPreFlushParentJob = null;
|
|
// recursively flush until it drains
|
|
flushPreFlushCbs(seen, parentJob);
|
|
}
|
|
}
|
|
function flushPostFlushCbs(seen) {
|
|
if (pendingPostFlushCbs.length) {
|
|
const deduped = [...new Set(pendingPostFlushCbs)];
|
|
pendingPostFlushCbs.length = 0;
|
|
// #1947 already has active queue, nested flushPostFlushCbs call
|
|
if (activePostFlushCbs) {
|
|
activePostFlushCbs.push(...deduped);
|
|
return;
|
|
}
|
|
activePostFlushCbs = deduped;
|
|
if ((true)) {
|
|
seen = seen || new Map();
|
|
}
|
|
activePostFlushCbs.sort((a, b) => getId(a) - getId(b));
|
|
for (postFlushIndex = 0; postFlushIndex < activePostFlushCbs.length; postFlushIndex++) {
|
|
if (( true) &&
|
|
checkRecursiveUpdates(seen, activePostFlushCbs[postFlushIndex])) {
|
|
continue;
|
|
}
|
|
activePostFlushCbs[postFlushIndex]();
|
|
}
|
|
activePostFlushCbs = null;
|
|
postFlushIndex = 0;
|
|
}
|
|
}
|
|
const getId = (job) => job.id == null ? Infinity : job.id;
|
|
function flushJobs(seen) {
|
|
isFlushPending = false;
|
|
isFlushing = true;
|
|
if ((true)) {
|
|
seen = seen || new Map();
|
|
}
|
|
flushPreFlushCbs(seen);
|
|
// Sort queue before flush.
|
|
// This ensures that:
|
|
// 1. Components are updated from parent to child. (because parent is always
|
|
// created before the child so its render effect will have smaller
|
|
// priority number)
|
|
// 2. If a component is unmounted during a parent component's update,
|
|
// its update can be skipped.
|
|
queue.sort((a, b) => getId(a) - getId(b));
|
|
try {
|
|
for (flushIndex = 0; flushIndex < queue.length; flushIndex++) {
|
|
const job = queue[flushIndex];
|
|
if (job && job.active !== false) {
|
|
if (( true) && checkRecursiveUpdates(seen, job)) {
|
|
continue;
|
|
}
|
|
// console.log(`running:`, job.id)
|
|
callWithErrorHandling(job, null, 14 /* SCHEDULER */);
|
|
}
|
|
}
|
|
}
|
|
finally {
|
|
flushIndex = 0;
|
|
queue.length = 0;
|
|
flushPostFlushCbs(seen);
|
|
isFlushing = false;
|
|
currentFlushPromise = null;
|
|
// some postFlushCb queued jobs!
|
|
// keep flushing until it drains.
|
|
if (queue.length ||
|
|
pendingPreFlushCbs.length ||
|
|
pendingPostFlushCbs.length) {
|
|
flushJobs(seen);
|
|
}
|
|
}
|
|
}
|
|
function checkRecursiveUpdates(seen, fn) {
|
|
if (!seen.has(fn)) {
|
|
seen.set(fn, 1);
|
|
}
|
|
else {
|
|
const count = seen.get(fn);
|
|
if (count > RECURSION_LIMIT) {
|
|
const instance = fn.ownerInstance;
|
|
const componentName = instance && getComponentName(instance.type);
|
|
warn(`Maximum recursive updates exceeded${componentName ? ` in component <${componentName}>` : ``}. ` +
|
|
`This means you have a reactive effect that is mutating its own ` +
|
|
`dependencies and thus recursively triggering itself. Possible sources ` +
|
|
`include component template, render function, updated hook or ` +
|
|
`watcher source function.`);
|
|
return true;
|
|
}
|
|
else {
|
|
seen.set(fn, count + 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Simple effect.
|
|
function watchEffect(effect, options) {
|
|
return doWatch(effect, null, options);
|
|
}
|
|
function watchPostEffect(effect, options) {
|
|
return doWatch(effect, null, (( true)
|
|
? Object.assign(options || {}, { flush: 'post' })
|
|
: 0));
|
|
}
|
|
function watchSyncEffect(effect, options) {
|
|
return doWatch(effect, null, (( true)
|
|
? Object.assign(options || {}, { flush: 'sync' })
|
|
: 0));
|
|
}
|
|
// initial value for watchers to trigger on undefined initial values
|
|
const INITIAL_WATCHER_VALUE = {};
|
|
// implementation
|
|
function watch(source, cb, options) {
|
|
if (( true) && !(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isFunction)(cb)) {
|
|
warn(`\`watch(fn, options?)\` signature has been moved to a separate API. ` +
|
|
`Use \`watchEffect(fn, options?)\` instead. \`watch\` now only ` +
|
|
`supports \`watch(source, cb, options?) signature.`);
|
|
}
|
|
return doWatch(source, cb, options);
|
|
}
|
|
function doWatch(source, cb, { immediate, deep, flush, onTrack, onTrigger } = _vue_shared__WEBPACK_IMPORTED_MODULE_1__.EMPTY_OBJ) {
|
|
if (( true) && !cb) {
|
|
if (immediate !== undefined) {
|
|
warn(`watch() "immediate" option is only respected when using the ` +
|
|
`watch(source, callback, options?) signature.`);
|
|
}
|
|
if (deep !== undefined) {
|
|
warn(`watch() "deep" option is only respected when using the ` +
|
|
`watch(source, callback, options?) signature.`);
|
|
}
|
|
}
|
|
const warnInvalidSource = (s) => {
|
|
warn(`Invalid watch source: `, s, `A watch source can only be a getter/effect function, a ref, ` +
|
|
`a reactive object, or an array of these types.`);
|
|
};
|
|
const instance = currentInstance;
|
|
let getter;
|
|
let forceTrigger = false;
|
|
let isMultiSource = false;
|
|
if ((0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.isRef)(source)) {
|
|
getter = () => source.value;
|
|
forceTrigger = !!source._shallow;
|
|
}
|
|
else if ((0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.isReactive)(source)) {
|
|
getter = () => source;
|
|
deep = true;
|
|
}
|
|
else if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isArray)(source)) {
|
|
isMultiSource = true;
|
|
forceTrigger = source.some(_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.isReactive);
|
|
getter = () => source.map(s => {
|
|
if ((0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.isRef)(s)) {
|
|
return s.value;
|
|
}
|
|
else if ((0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.isReactive)(s)) {
|
|
return traverse(s);
|
|
}
|
|
else if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isFunction)(s)) {
|
|
return callWithErrorHandling(s, instance, 2 /* WATCH_GETTER */);
|
|
}
|
|
else {
|
|
( true) && warnInvalidSource(s);
|
|
}
|
|
});
|
|
}
|
|
else if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isFunction)(source)) {
|
|
if (cb) {
|
|
// getter with cb
|
|
getter = () => callWithErrorHandling(source, instance, 2 /* WATCH_GETTER */);
|
|
}
|
|
else {
|
|
// no cb -> simple effect
|
|
getter = () => {
|
|
if (instance && instance.isUnmounted) {
|
|
return;
|
|
}
|
|
if (cleanup) {
|
|
cleanup();
|
|
}
|
|
return callWithAsyncErrorHandling(source, instance, 3 /* WATCH_CALLBACK */, [onInvalidate]);
|
|
};
|
|
}
|
|
}
|
|
else {
|
|
getter = _vue_shared__WEBPACK_IMPORTED_MODULE_1__.NOOP;
|
|
( true) && warnInvalidSource(source);
|
|
}
|
|
if (cb && deep) {
|
|
const baseGetter = getter;
|
|
getter = () => traverse(baseGetter());
|
|
}
|
|
let cleanup;
|
|
let onInvalidate = (fn) => {
|
|
cleanup = effect.onStop = () => {
|
|
callWithErrorHandling(fn, instance, 4 /* WATCH_CLEANUP */);
|
|
};
|
|
};
|
|
let oldValue = isMultiSource ? [] : INITIAL_WATCHER_VALUE;
|
|
const job = () => {
|
|
if (!effect.active) {
|
|
return;
|
|
}
|
|
if (cb) {
|
|
// watch(source, cb)
|
|
const newValue = effect.run();
|
|
if (deep ||
|
|
forceTrigger ||
|
|
(isMultiSource
|
|
? newValue.some((v, i) => (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.hasChanged)(v, oldValue[i]))
|
|
: (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.hasChanged)(newValue, oldValue)) ||
|
|
(false )) {
|
|
// cleanup before running cb again
|
|
if (cleanup) {
|
|
cleanup();
|
|
}
|
|
callWithAsyncErrorHandling(cb, instance, 3 /* WATCH_CALLBACK */, [
|
|
newValue,
|
|
// pass undefined as the old value when it's changed for the first time
|
|
oldValue === INITIAL_WATCHER_VALUE ? undefined : oldValue,
|
|
onInvalidate
|
|
]);
|
|
oldValue = newValue;
|
|
}
|
|
}
|
|
else {
|
|
// watchEffect
|
|
effect.run();
|
|
}
|
|
};
|
|
// important: mark the job as a watcher callback so that scheduler knows
|
|
// it is allowed to self-trigger (#1727)
|
|
job.allowRecurse = !!cb;
|
|
let scheduler;
|
|
if (flush === 'sync') {
|
|
scheduler = job; // the scheduler function gets called directly
|
|
}
|
|
else if (flush === 'post') {
|
|
scheduler = () => queuePostRenderEffect(job, instance && instance.suspense);
|
|
}
|
|
else {
|
|
// default: 'pre'
|
|
scheduler = () => {
|
|
if (!instance || instance.isMounted) {
|
|
queuePreFlushCb(job);
|
|
}
|
|
else {
|
|
// with 'pre' option, the first call must happen before
|
|
// the component is mounted so it is called synchronously.
|
|
job();
|
|
}
|
|
};
|
|
}
|
|
const effect = new _vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.ReactiveEffect(getter, scheduler);
|
|
if ((true)) {
|
|
effect.onTrack = onTrack;
|
|
effect.onTrigger = onTrigger;
|
|
}
|
|
// initial run
|
|
if (cb) {
|
|
if (immediate) {
|
|
job();
|
|
}
|
|
else {
|
|
oldValue = effect.run();
|
|
}
|
|
}
|
|
else if (flush === 'post') {
|
|
queuePostRenderEffect(effect.run.bind(effect), instance && instance.suspense);
|
|
}
|
|
else {
|
|
effect.run();
|
|
}
|
|
return () => {
|
|
effect.stop();
|
|
if (instance && instance.scope) {
|
|
(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.remove)(instance.scope.effects, effect);
|
|
}
|
|
};
|
|
}
|
|
// this.$watch
|
|
function instanceWatch(source, value, options) {
|
|
const publicThis = this.proxy;
|
|
const getter = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isString)(source)
|
|
? source.includes('.')
|
|
? createPathGetter(publicThis, source)
|
|
: () => publicThis[source]
|
|
: source.bind(publicThis, publicThis);
|
|
let cb;
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isFunction)(value)) {
|
|
cb = value;
|
|
}
|
|
else {
|
|
cb = value.handler;
|
|
options = value;
|
|
}
|
|
const cur = currentInstance;
|
|
setCurrentInstance(this);
|
|
const res = doWatch(getter, cb.bind(publicThis), options);
|
|
if (cur) {
|
|
setCurrentInstance(cur);
|
|
}
|
|
else {
|
|
unsetCurrentInstance();
|
|
}
|
|
return res;
|
|
}
|
|
function createPathGetter(ctx, path) {
|
|
const segments = path.split('.');
|
|
return () => {
|
|
let cur = ctx;
|
|
for (let i = 0; i < segments.length && cur; i++) {
|
|
cur = cur[segments[i]];
|
|
}
|
|
return cur;
|
|
};
|
|
}
|
|
function traverse(value, seen = new Set()) {
|
|
if (!(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isObject)(value) || value["__v_skip" /* SKIP */]) {
|
|
return value;
|
|
}
|
|
seen = seen || new Set();
|
|
if (seen.has(value)) {
|
|
return value;
|
|
}
|
|
seen.add(value);
|
|
if ((0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.isRef)(value)) {
|
|
traverse(value.value, seen);
|
|
}
|
|
else if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isArray)(value)) {
|
|
for (let i = 0; i < value.length; i++) {
|
|
traverse(value[i], seen);
|
|
}
|
|
}
|
|
else if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isSet)(value) || (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isMap)(value)) {
|
|
value.forEach((v) => {
|
|
traverse(v, seen);
|
|
});
|
|
}
|
|
else if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isPlainObject)(value)) {
|
|
for (const key in value) {
|
|
traverse(value[key], seen);
|
|
}
|
|
}
|
|
return value;
|
|
}
|
|
|
|
( true)
|
|
? Object.freeze({})
|
|
: 0;
|
|
( true) ? Object.freeze([]) : 0;
|
|
const isFunction = (val) => typeof val === 'function';
|
|
const isObject = (val) => val !== null && typeof val === 'object';
|
|
const isPromise = (val) => {
|
|
return isObject(val) && isFunction(val.then) && isFunction(val.catch);
|
|
};
|
|
|
|
// dev only
|
|
const warnRuntimeUsage = (method) => warn(`${method}() is a compiler-hint helper that is only usable inside ` +
|
|
`<script setup> of a single file component. Its arguments should be ` +
|
|
`compiled away and passing it at runtime has no effect.`);
|
|
// implementation
|
|
function defineProps() {
|
|
if ((true)) {
|
|
warnRuntimeUsage(`defineProps`);
|
|
}
|
|
return null;
|
|
}
|
|
// implementation
|
|
function defineEmits() {
|
|
if ((true)) {
|
|
warnRuntimeUsage(`defineEmits`);
|
|
}
|
|
return null;
|
|
}
|
|
/**
|
|
* Vue `<script setup>` compiler macro for declaring a component's exposed
|
|
* instance properties when it is accessed by a parent component via template
|
|
* refs.
|
|
*
|
|
* `<script setup>` components are closed by default - i.e. varaibles inside
|
|
* the `<script setup>` scope is not exposed to parent unless explicitly exposed
|
|
* via `defineExpose`.
|
|
*
|
|
* This is only usable inside `<script setup>`, is compiled away in the
|
|
* output and should **not** be actually called at runtime.
|
|
*/
|
|
function defineExpose(exposed) {
|
|
if ((true)) {
|
|
warnRuntimeUsage(`defineExpose`);
|
|
}
|
|
}
|
|
/**
|
|
* Vue `<script setup>` compiler macro for providing props default values when
|
|
* using type-based `defineProps` decalration.
|
|
*
|
|
* Example usage:
|
|
* ```ts
|
|
* withDefaults(defineProps<{
|
|
* size?: number
|
|
* labels?: string[]
|
|
* }>(), {
|
|
* size: 3,
|
|
* labels: () => ['default label']
|
|
* })
|
|
* ```
|
|
*
|
|
* This is only usable inside `<script setup>`, is compiled away in the output
|
|
* and should **not** be actually called at runtime.
|
|
*/
|
|
function withDefaults(props, defaults) {
|
|
if ((true)) {
|
|
warnRuntimeUsage(`withDefaults`);
|
|
}
|
|
return null;
|
|
}
|
|
function useSlots() {
|
|
return getContext().slots;
|
|
}
|
|
function useAttrs() {
|
|
return getContext().attrs;
|
|
}
|
|
function getContext() {
|
|
const i = getCurrentInstance();
|
|
if (( true) && !i) {
|
|
warn(`useContext() called without active instance.`);
|
|
}
|
|
return i.setupContext || (i.setupContext = createSetupContext(i));
|
|
}
|
|
/**
|
|
* Runtime helper for merging default declarations. Imported by compiled code
|
|
* only.
|
|
* @internal
|
|
*/
|
|
function mergeDefaults(
|
|
// the base props is compiler-generated and guaranteed to be in this shape.
|
|
props, defaults) {
|
|
for (const key in defaults) {
|
|
const val = props[key];
|
|
if (val) {
|
|
val.default = defaults[key];
|
|
}
|
|
else if (val === null) {
|
|
props[key] = { default: defaults[key] };
|
|
}
|
|
else if ((true)) {
|
|
warn(`props default key "${key}" has no corresponding declaration.`);
|
|
}
|
|
}
|
|
return props;
|
|
}
|
|
/**
|
|
* `<script setup>` helper for persisting the current instance context over
|
|
* async/await flows.
|
|
*
|
|
* `@vue/compiler-sfc` converts the following:
|
|
*
|
|
* ```ts
|
|
* const x = await foo()
|
|
* ```
|
|
*
|
|
* into:
|
|
*
|
|
* ```ts
|
|
* let __temp, __restore
|
|
* const x = (([__temp, __restore] = withAsyncContext(() => foo())),__temp=await __temp,__restore(),__temp)
|
|
* ```
|
|
* @internal
|
|
*/
|
|
function withAsyncContext(getAwaitable) {
|
|
const ctx = getCurrentInstance();
|
|
if (( true) && !ctx) {
|
|
warn(`withAsyncContext called without active current instance. ` +
|
|
`This is likely a bug.`);
|
|
}
|
|
let awaitable = getAwaitable();
|
|
unsetCurrentInstance();
|
|
if (isPromise(awaitable)) {
|
|
awaitable = awaitable.catch(e => {
|
|
setCurrentInstance(ctx);
|
|
throw e;
|
|
});
|
|
}
|
|
return [awaitable, () => setCurrentInstance(ctx)];
|
|
}
|
|
|
|
// Actual implementation
|
|
function h(type, propsOrChildren, children) {
|
|
const l = arguments.length;
|
|
if (l === 2) {
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isObject)(propsOrChildren) && !(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isArray)(propsOrChildren)) {
|
|
// single vnode without props
|
|
if (isVNode(propsOrChildren)) {
|
|
return createVNode(type, null, [propsOrChildren]);
|
|
}
|
|
// props without children
|
|
return createVNode(type, propsOrChildren);
|
|
}
|
|
else {
|
|
// omit props
|
|
return createVNode(type, null, propsOrChildren);
|
|
}
|
|
}
|
|
else {
|
|
if (l > 3) {
|
|
children = Array.prototype.slice.call(arguments, 2);
|
|
}
|
|
else if (l === 3 && isVNode(children)) {
|
|
children = [children];
|
|
}
|
|
return createVNode(type, propsOrChildren, children);
|
|
}
|
|
}
|
|
|
|
const ssrContextKey = Symbol(( true) ? `ssrContext` : 0);
|
|
const useSSRContext = () => {
|
|
{
|
|
const ctx = inject(ssrContextKey);
|
|
if (!ctx) {
|
|
warn(`Server rendering context not provided. Make sure to only call ` +
|
|
`useSSRContext() conditionally in the server build.`);
|
|
}
|
|
return ctx;
|
|
}
|
|
};
|
|
|
|
function initCustomFormatter() {
|
|
/* eslint-disable no-restricted-globals */
|
|
if ( false || typeof window === 'undefined') {
|
|
return;
|
|
}
|
|
const vueStyle = { style: 'color:#3ba776' };
|
|
const numberStyle = { style: 'color:#0b1bc9' };
|
|
const stringStyle = { style: 'color:#b62e24' };
|
|
const keywordStyle = { style: 'color:#9d288c' };
|
|
// custom formatter for Chrome
|
|
// https://www.mattzeunert.com/2016/02/19/custom-chrome-devtools-object-formatters.html
|
|
const formatter = {
|
|
header(obj) {
|
|
// TODO also format ComponentPublicInstance & ctx.slots/attrs in setup
|
|
if (!(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isObject)(obj)) {
|
|
return null;
|
|
}
|
|
if (obj.__isVue) {
|
|
return ['div', vueStyle, `VueInstance`];
|
|
}
|
|
else if ((0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.isRef)(obj)) {
|
|
return [
|
|
'div',
|
|
{},
|
|
['span', vueStyle, genRefFlag(obj)],
|
|
'<',
|
|
formatValue(obj.value),
|
|
`>`
|
|
];
|
|
}
|
|
else if ((0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.isReactive)(obj)) {
|
|
return [
|
|
'div',
|
|
{},
|
|
['span', vueStyle, 'Reactive'],
|
|
'<',
|
|
formatValue(obj),
|
|
`>${(0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.isReadonly)(obj) ? ` (readonly)` : ``}`
|
|
];
|
|
}
|
|
else if ((0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.isReadonly)(obj)) {
|
|
return [
|
|
'div',
|
|
{},
|
|
['span', vueStyle, 'Readonly'],
|
|
'<',
|
|
formatValue(obj),
|
|
'>'
|
|
];
|
|
}
|
|
return null;
|
|
},
|
|
hasBody(obj) {
|
|
return obj && obj.__isVue;
|
|
},
|
|
body(obj) {
|
|
if (obj && obj.__isVue) {
|
|
return [
|
|
'div',
|
|
{},
|
|
...formatInstance(obj.$)
|
|
];
|
|
}
|
|
}
|
|
};
|
|
function formatInstance(instance) {
|
|
const blocks = [];
|
|
if (instance.type.props && instance.props) {
|
|
blocks.push(createInstanceBlock('props', (0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.toRaw)(instance.props)));
|
|
}
|
|
if (instance.setupState !== _vue_shared__WEBPACK_IMPORTED_MODULE_1__.EMPTY_OBJ) {
|
|
blocks.push(createInstanceBlock('setup', instance.setupState));
|
|
}
|
|
if (instance.data !== _vue_shared__WEBPACK_IMPORTED_MODULE_1__.EMPTY_OBJ) {
|
|
blocks.push(createInstanceBlock('data', (0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.toRaw)(instance.data)));
|
|
}
|
|
const computed = extractKeys(instance, 'computed');
|
|
if (computed) {
|
|
blocks.push(createInstanceBlock('computed', computed));
|
|
}
|
|
const injected = extractKeys(instance, 'inject');
|
|
if (injected) {
|
|
blocks.push(createInstanceBlock('injected', injected));
|
|
}
|
|
blocks.push([
|
|
'div',
|
|
{},
|
|
[
|
|
'span',
|
|
{
|
|
style: keywordStyle.style + ';opacity:0.66'
|
|
},
|
|
'$ (internal): '
|
|
],
|
|
['object', { object: instance }]
|
|
]);
|
|
return blocks;
|
|
}
|
|
function createInstanceBlock(type, target) {
|
|
target = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.extend)({}, target);
|
|
if (!Object.keys(target).length) {
|
|
return ['span', {}];
|
|
}
|
|
return [
|
|
'div',
|
|
{ style: 'line-height:1.25em;margin-bottom:0.6em' },
|
|
[
|
|
'div',
|
|
{
|
|
style: 'color:#476582'
|
|
},
|
|
type
|
|
],
|
|
[
|
|
'div',
|
|
{
|
|
style: 'padding-left:1.25em'
|
|
},
|
|
...Object.keys(target).map(key => {
|
|
return [
|
|
'div',
|
|
{},
|
|
['span', keywordStyle, key + ': '],
|
|
formatValue(target[key], false)
|
|
];
|
|
})
|
|
]
|
|
];
|
|
}
|
|
function formatValue(v, asRaw = true) {
|
|
if (typeof v === 'number') {
|
|
return ['span', numberStyle, v];
|
|
}
|
|
else if (typeof v === 'string') {
|
|
return ['span', stringStyle, JSON.stringify(v)];
|
|
}
|
|
else if (typeof v === 'boolean') {
|
|
return ['span', keywordStyle, v];
|
|
}
|
|
else if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isObject)(v)) {
|
|
return ['object', { object: asRaw ? (0,_vue_reactivity__WEBPACK_IMPORTED_MODULE_0__.toRaw)(v) : v }];
|
|
}
|
|
else {
|
|
return ['span', stringStyle, String(v)];
|
|
}
|
|
}
|
|
function extractKeys(instance, type) {
|
|
const Comp = instance.type;
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isFunction)(Comp)) {
|
|
return;
|
|
}
|
|
const extracted = {};
|
|
for (const key in instance.ctx) {
|
|
if (isKeyOfType(Comp, key, type)) {
|
|
extracted[key] = instance.ctx[key];
|
|
}
|
|
}
|
|
return extracted;
|
|
}
|
|
function isKeyOfType(Comp, key, type) {
|
|
const opts = Comp[type];
|
|
if (((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isArray)(opts) && opts.includes(key)) ||
|
|
((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isObject)(opts) && key in opts)) {
|
|
return true;
|
|
}
|
|
if (Comp.extends && isKeyOfType(Comp.extends, key, type)) {
|
|
return true;
|
|
}
|
|
if (Comp.mixins && Comp.mixins.some(m => isKeyOfType(m, key, type))) {
|
|
return true;
|
|
}
|
|
}
|
|
function genRefFlag(v) {
|
|
if (v._shallow) {
|
|
return `ShallowRef`;
|
|
}
|
|
if (v.effect) {
|
|
return `ComputedRef`;
|
|
}
|
|
return `Ref`;
|
|
}
|
|
if (window.devtoolsFormatters) {
|
|
window.devtoolsFormatters.push(formatter);
|
|
}
|
|
else {
|
|
window.devtoolsFormatters = [formatter];
|
|
}
|
|
}
|
|
|
|
function withMemo(memo, render, cache, index) {
|
|
const cached = cache[index];
|
|
if (cached && isMemoSame(cached, memo)) {
|
|
return cached;
|
|
}
|
|
const ret = render();
|
|
// shallow clone
|
|
ret.memo = memo.slice();
|
|
return (cache[index] = ret);
|
|
}
|
|
function isMemoSame(cached, memo) {
|
|
const prev = cached.memo;
|
|
if (prev.length != memo.length) {
|
|
return false;
|
|
}
|
|
for (let i = 0; i < prev.length; i++) {
|
|
if (prev[i] !== memo[i]) {
|
|
return false;
|
|
}
|
|
}
|
|
// make sure to let parent block track it when returning cached
|
|
if (isBlockTreeEnabled > 0 && currentBlock) {
|
|
currentBlock.push(cached);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// Core API ------------------------------------------------------------------
|
|
const version = "3.2.6";
|
|
const _ssrUtils = {
|
|
createComponentInstance,
|
|
setupComponent,
|
|
renderComponentRoot,
|
|
setCurrentRenderingInstance,
|
|
isVNode,
|
|
normalizeVNode
|
|
};
|
|
/**
|
|
* SSR utils for \@vue/server-renderer. Only exposed in cjs builds.
|
|
* @internal
|
|
*/
|
|
const ssrUtils = (_ssrUtils );
|
|
/**
|
|
* @internal only exposed in compat builds
|
|
*/
|
|
const resolveFilter = null;
|
|
/**
|
|
* @internal only exposed in compat builds.
|
|
*/
|
|
const compatUtils = (null);
|
|
|
|
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/@vue/runtime-dom/dist/runtime-dom.esm-bundler.js":
|
|
/*!***********************************************************************!*\
|
|
!*** ./node_modules/@vue/runtime-dom/dist/runtime-dom.esm-bundler.js ***!
|
|
\***********************************************************************/
|
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ "BaseTransition": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.BaseTransition),
|
|
/* harmony export */ "Comment": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.Comment),
|
|
/* harmony export */ "EffectScope": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.EffectScope),
|
|
/* harmony export */ "Fragment": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.Fragment),
|
|
/* harmony export */ "KeepAlive": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.KeepAlive),
|
|
/* harmony export */ "ReactiveEffect": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.ReactiveEffect),
|
|
/* harmony export */ "Static": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.Static),
|
|
/* harmony export */ "Suspense": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.Suspense),
|
|
/* harmony export */ "Teleport": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.Teleport),
|
|
/* harmony export */ "Text": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.Text),
|
|
/* harmony export */ "callWithAsyncErrorHandling": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.callWithAsyncErrorHandling),
|
|
/* harmony export */ "callWithErrorHandling": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.callWithErrorHandling),
|
|
/* harmony export */ "camelize": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.camelize),
|
|
/* harmony export */ "capitalize": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.capitalize),
|
|
/* harmony export */ "cloneVNode": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.cloneVNode),
|
|
/* harmony export */ "compatUtils": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.compatUtils),
|
|
/* harmony export */ "computed": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.computed),
|
|
/* harmony export */ "createBlock": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.createBlock),
|
|
/* harmony export */ "createCommentVNode": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode),
|
|
/* harmony export */ "createElementBlock": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.createElementBlock),
|
|
/* harmony export */ "createElementVNode": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.createElementVNode),
|
|
/* harmony export */ "createHydrationRenderer": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.createHydrationRenderer),
|
|
/* harmony export */ "createRenderer": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.createRenderer),
|
|
/* harmony export */ "createSlots": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.createSlots),
|
|
/* harmony export */ "createStaticVNode": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.createStaticVNode),
|
|
/* harmony export */ "createTextVNode": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.createTextVNode),
|
|
/* harmony export */ "createVNode": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.createVNode),
|
|
/* harmony export */ "customRef": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.customRef),
|
|
/* harmony export */ "defineAsyncComponent": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.defineAsyncComponent),
|
|
/* harmony export */ "defineComponent": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.defineComponent),
|
|
/* harmony export */ "defineEmits": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.defineEmits),
|
|
/* harmony export */ "defineExpose": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.defineExpose),
|
|
/* harmony export */ "defineProps": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.defineProps),
|
|
/* harmony export */ "devtools": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.devtools),
|
|
/* harmony export */ "effect": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.effect),
|
|
/* harmony export */ "effectScope": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.effectScope),
|
|
/* harmony export */ "getCurrentInstance": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.getCurrentInstance),
|
|
/* harmony export */ "getCurrentScope": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.getCurrentScope),
|
|
/* harmony export */ "getTransitionRawChildren": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.getTransitionRawChildren),
|
|
/* harmony export */ "guardReactiveProps": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.guardReactiveProps),
|
|
/* harmony export */ "h": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.h),
|
|
/* harmony export */ "handleError": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.handleError),
|
|
/* harmony export */ "initCustomFormatter": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.initCustomFormatter),
|
|
/* harmony export */ "inject": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.inject),
|
|
/* harmony export */ "isMemoSame": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.isMemoSame),
|
|
/* harmony export */ "isProxy": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.isProxy),
|
|
/* harmony export */ "isReactive": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.isReactive),
|
|
/* harmony export */ "isReadonly": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.isReadonly),
|
|
/* harmony export */ "isRef": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.isRef),
|
|
/* harmony export */ "isRuntimeOnly": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.isRuntimeOnly),
|
|
/* harmony export */ "isVNode": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.isVNode),
|
|
/* harmony export */ "markRaw": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.markRaw),
|
|
/* harmony export */ "mergeDefaults": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.mergeDefaults),
|
|
/* harmony export */ "mergeProps": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.mergeProps),
|
|
/* harmony export */ "nextTick": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.nextTick),
|
|
/* harmony export */ "normalizeClass": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.normalizeClass),
|
|
/* harmony export */ "normalizeProps": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.normalizeProps),
|
|
/* harmony export */ "normalizeStyle": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.normalizeStyle),
|
|
/* harmony export */ "onActivated": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.onActivated),
|
|
/* harmony export */ "onBeforeMount": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.onBeforeMount),
|
|
/* harmony export */ "onBeforeUnmount": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.onBeforeUnmount),
|
|
/* harmony export */ "onBeforeUpdate": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.onBeforeUpdate),
|
|
/* harmony export */ "onDeactivated": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.onDeactivated),
|
|
/* harmony export */ "onErrorCaptured": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.onErrorCaptured),
|
|
/* harmony export */ "onMounted": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.onMounted),
|
|
/* harmony export */ "onRenderTracked": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.onRenderTracked),
|
|
/* harmony export */ "onRenderTriggered": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.onRenderTriggered),
|
|
/* harmony export */ "onScopeDispose": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.onScopeDispose),
|
|
/* harmony export */ "onServerPrefetch": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.onServerPrefetch),
|
|
/* harmony export */ "onUnmounted": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.onUnmounted),
|
|
/* harmony export */ "onUpdated": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.onUpdated),
|
|
/* harmony export */ "openBlock": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.openBlock),
|
|
/* harmony export */ "popScopeId": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.popScopeId),
|
|
/* harmony export */ "provide": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.provide),
|
|
/* harmony export */ "proxyRefs": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.proxyRefs),
|
|
/* harmony export */ "pushScopeId": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.pushScopeId),
|
|
/* harmony export */ "queuePostFlushCb": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.queuePostFlushCb),
|
|
/* harmony export */ "reactive": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.reactive),
|
|
/* harmony export */ "readonly": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.readonly),
|
|
/* harmony export */ "ref": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.ref),
|
|
/* harmony export */ "registerRuntimeCompiler": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.registerRuntimeCompiler),
|
|
/* harmony export */ "renderList": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.renderList),
|
|
/* harmony export */ "renderSlot": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.renderSlot),
|
|
/* harmony export */ "resolveComponent": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.resolveComponent),
|
|
/* harmony export */ "resolveDirective": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.resolveDirective),
|
|
/* harmony export */ "resolveDynamicComponent": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.resolveDynamicComponent),
|
|
/* harmony export */ "resolveFilter": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.resolveFilter),
|
|
/* harmony export */ "resolveTransitionHooks": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.resolveTransitionHooks),
|
|
/* harmony export */ "setBlockTracking": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.setBlockTracking),
|
|
/* harmony export */ "setDevtoolsHook": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.setDevtoolsHook),
|
|
/* harmony export */ "setTransitionHooks": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.setTransitionHooks),
|
|
/* harmony export */ "shallowReactive": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.shallowReactive),
|
|
/* harmony export */ "shallowReadonly": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.shallowReadonly),
|
|
/* harmony export */ "shallowRef": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.shallowRef),
|
|
/* harmony export */ "ssrContextKey": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.ssrContextKey),
|
|
/* harmony export */ "ssrUtils": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.ssrUtils),
|
|
/* harmony export */ "stop": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.stop),
|
|
/* harmony export */ "toDisplayString": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.toDisplayString),
|
|
/* harmony export */ "toHandlerKey": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.toHandlerKey),
|
|
/* harmony export */ "toHandlers": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.toHandlers),
|
|
/* harmony export */ "toRaw": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.toRaw),
|
|
/* harmony export */ "toRef": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.toRef),
|
|
/* harmony export */ "toRefs": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.toRefs),
|
|
/* harmony export */ "transformVNodeArgs": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.transformVNodeArgs),
|
|
/* harmony export */ "triggerRef": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.triggerRef),
|
|
/* harmony export */ "unref": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.unref),
|
|
/* harmony export */ "useAttrs": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.useAttrs),
|
|
/* harmony export */ "useSSRContext": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.useSSRContext),
|
|
/* harmony export */ "useSlots": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.useSlots),
|
|
/* harmony export */ "useTransitionState": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.useTransitionState),
|
|
/* harmony export */ "version": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.version),
|
|
/* harmony export */ "warn": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.warn),
|
|
/* harmony export */ "watch": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.watch),
|
|
/* harmony export */ "watchEffect": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.watchEffect),
|
|
/* harmony export */ "watchPostEffect": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.watchPostEffect),
|
|
/* harmony export */ "watchSyncEffect": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.watchSyncEffect),
|
|
/* harmony export */ "withAsyncContext": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.withAsyncContext),
|
|
/* harmony export */ "withCtx": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.withCtx),
|
|
/* harmony export */ "withDefaults": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.withDefaults),
|
|
/* harmony export */ "withDirectives": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.withDirectives),
|
|
/* harmony export */ "withMemo": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.withMemo),
|
|
/* harmony export */ "withScopeId": () => (/* reexport safe */ _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.withScopeId),
|
|
/* harmony export */ "Transition": () => (/* binding */ Transition),
|
|
/* harmony export */ "TransitionGroup": () => (/* binding */ TransitionGroup),
|
|
/* harmony export */ "VueElement": () => (/* binding */ VueElement),
|
|
/* harmony export */ "createApp": () => (/* binding */ createApp),
|
|
/* harmony export */ "createSSRApp": () => (/* binding */ createSSRApp),
|
|
/* harmony export */ "defineCustomElement": () => (/* binding */ defineCustomElement),
|
|
/* harmony export */ "defineSSRCustomElement": () => (/* binding */ defineSSRCustomElement),
|
|
/* harmony export */ "hydrate": () => (/* binding */ hydrate),
|
|
/* harmony export */ "render": () => (/* binding */ render),
|
|
/* harmony export */ "useCssModule": () => (/* binding */ useCssModule),
|
|
/* harmony export */ "useCssVars": () => (/* binding */ useCssVars),
|
|
/* harmony export */ "vModelCheckbox": () => (/* binding */ vModelCheckbox),
|
|
/* harmony export */ "vModelDynamic": () => (/* binding */ vModelDynamic),
|
|
/* harmony export */ "vModelRadio": () => (/* binding */ vModelRadio),
|
|
/* harmony export */ "vModelSelect": () => (/* binding */ vModelSelect),
|
|
/* harmony export */ "vModelText": () => (/* binding */ vModelText),
|
|
/* harmony export */ "vShow": () => (/* binding */ vShow),
|
|
/* harmony export */ "withKeys": () => (/* binding */ withKeys),
|
|
/* harmony export */ "withModifiers": () => (/* binding */ withModifiers)
|
|
/* harmony export */ });
|
|
/* harmony import */ var _vue_shared__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @vue/shared */ "./node_modules/@vue/shared/dist/shared.esm-bundler.js");
|
|
/* harmony import */ var _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @vue/runtime-core */ "./node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js");
|
|
/* harmony import */ var _vue_runtime_core__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @vue/runtime-core */ "./node_modules/@vue/reactivity/dist/reactivity.esm-bundler.js");
|
|
|
|
|
|
|
|
|
|
const svgNS = 'http://www.w3.org/2000/svg';
|
|
const doc = (typeof document !== 'undefined' ? document : null);
|
|
const staticTemplateCache = new Map();
|
|
const nodeOps = {
|
|
insert: (child, parent, anchor) => {
|
|
parent.insertBefore(child, anchor || null);
|
|
},
|
|
remove: child => {
|
|
const parent = child.parentNode;
|
|
if (parent) {
|
|
parent.removeChild(child);
|
|
}
|
|
},
|
|
createElement: (tag, isSVG, is, props) => {
|
|
const el = isSVG
|
|
? doc.createElementNS(svgNS, tag)
|
|
: doc.createElement(tag, is ? { is } : undefined);
|
|
if (tag === 'select' && props && props.multiple != null) {
|
|
el.setAttribute('multiple', props.multiple);
|
|
}
|
|
return el;
|
|
},
|
|
createText: text => doc.createTextNode(text),
|
|
createComment: text => doc.createComment(text),
|
|
setText: (node, text) => {
|
|
node.nodeValue = text;
|
|
},
|
|
setElementText: (el, text) => {
|
|
el.textContent = text;
|
|
},
|
|
parentNode: node => node.parentNode,
|
|
nextSibling: node => node.nextSibling,
|
|
querySelector: selector => doc.querySelector(selector),
|
|
setScopeId(el, id) {
|
|
el.setAttribute(id, '');
|
|
},
|
|
cloneNode(el) {
|
|
const cloned = el.cloneNode(true);
|
|
// #3072
|
|
// - in `patchDOMProp`, we store the actual value in the `el._value` property.
|
|
// - normally, elements using `:value` bindings will not be hoisted, but if
|
|
// the bound value is a constant, e.g. `:value="true"` - they do get
|
|
// hoisted.
|
|
// - in production, hoisted nodes are cloned when subsequent inserts, but
|
|
// cloneNode() does not copy the custom property we attached.
|
|
// - This may need to account for other custom DOM properties we attach to
|
|
// elements in addition to `_value` in the future.
|
|
if (`_value` in el) {
|
|
cloned._value = el._value;
|
|
}
|
|
return cloned;
|
|
},
|
|
// __UNSAFE__
|
|
// Reason: innerHTML.
|
|
// Static content here can only come from compiled templates.
|
|
// As long as the user only uses trusted templates, this is safe.
|
|
insertStaticContent(content, parent, anchor, isSVG) {
|
|
// <parent> before | first ... last | anchor </parent>
|
|
const before = anchor ? anchor.previousSibling : parent.lastChild;
|
|
let template = staticTemplateCache.get(content);
|
|
if (!template) {
|
|
const t = doc.createElement('template');
|
|
t.innerHTML = isSVG ? `<svg>${content}</svg>` : content;
|
|
template = t.content;
|
|
if (isSVG) {
|
|
// remove outer svg wrapper
|
|
const wrapper = template.firstChild;
|
|
while (wrapper.firstChild) {
|
|
template.appendChild(wrapper.firstChild);
|
|
}
|
|
template.removeChild(wrapper);
|
|
}
|
|
staticTemplateCache.set(content, template);
|
|
}
|
|
parent.insertBefore(template.cloneNode(true), anchor);
|
|
return [
|
|
// first
|
|
before ? before.nextSibling : parent.firstChild,
|
|
// last
|
|
anchor ? anchor.previousSibling : parent.lastChild
|
|
];
|
|
}
|
|
};
|
|
|
|
// compiler should normalize class + :class bindings on the same element
|
|
// into a single binding ['staticClass', dynamic]
|
|
function patchClass(el, value, isSVG) {
|
|
// directly setting className should be faster than setAttribute in theory
|
|
// if this is an element during a transition, take the temporary transition
|
|
// classes into account.
|
|
const transitionClasses = el._vtc;
|
|
if (transitionClasses) {
|
|
value = (value ? [value, ...transitionClasses] : [...transitionClasses]).join(' ');
|
|
}
|
|
if (value == null) {
|
|
el.removeAttribute('class');
|
|
}
|
|
else if (isSVG) {
|
|
el.setAttribute('class', value);
|
|
}
|
|
else {
|
|
el.className = value;
|
|
}
|
|
}
|
|
|
|
function patchStyle(el, prev, next) {
|
|
const style = el.style;
|
|
if (!next) {
|
|
el.removeAttribute('style');
|
|
}
|
|
else if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isString)(next)) {
|
|
if (prev !== next) {
|
|
const current = style.display;
|
|
style.cssText = next;
|
|
// indicates that the `display` of the element is controlled by `v-show`,
|
|
// so we always keep the current `display` value regardless of the `style` value,
|
|
// thus handing over control to `v-show`.
|
|
if ('_vod' in el) {
|
|
style.display = current;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
for (const key in next) {
|
|
setStyle(style, key, next[key]);
|
|
}
|
|
if (prev && !(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isString)(prev)) {
|
|
for (const key in prev) {
|
|
if (next[key] == null) {
|
|
setStyle(style, key, '');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
const importantRE = /\s*!important$/;
|
|
function setStyle(style, name, val) {
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isArray)(val)) {
|
|
val.forEach(v => setStyle(style, name, v));
|
|
}
|
|
else {
|
|
if (name.startsWith('--')) {
|
|
// custom property definition
|
|
style.setProperty(name, val);
|
|
}
|
|
else {
|
|
const prefixed = autoPrefix(style, name);
|
|
if (importantRE.test(val)) {
|
|
// !important
|
|
style.setProperty((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.hyphenate)(prefixed), val.replace(importantRE, ''), 'important');
|
|
}
|
|
else {
|
|
style[prefixed] = val;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
const prefixes = ['Webkit', 'Moz', 'ms'];
|
|
const prefixCache = {};
|
|
function autoPrefix(style, rawName) {
|
|
const cached = prefixCache[rawName];
|
|
if (cached) {
|
|
return cached;
|
|
}
|
|
let name = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.camelize)(rawName);
|
|
if (name !== 'filter' && name in style) {
|
|
return (prefixCache[rawName] = name);
|
|
}
|
|
name = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.capitalize)(name);
|
|
for (let i = 0; i < prefixes.length; i++) {
|
|
const prefixed = prefixes[i] + name;
|
|
if (prefixed in style) {
|
|
return (prefixCache[rawName] = prefixed);
|
|
}
|
|
}
|
|
return rawName;
|
|
}
|
|
|
|
const xlinkNS = 'http://www.w3.org/1999/xlink';
|
|
function patchAttr(el, key, value, isSVG, instance) {
|
|
if (isSVG && key.startsWith('xlink:')) {
|
|
if (value == null) {
|
|
el.removeAttributeNS(xlinkNS, key.slice(6, key.length));
|
|
}
|
|
else {
|
|
el.setAttributeNS(xlinkNS, key, value);
|
|
}
|
|
}
|
|
else {
|
|
// note we are only checking boolean attributes that don't have a
|
|
// corresponding dom prop of the same name here.
|
|
const isBoolean = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isSpecialBooleanAttr)(key);
|
|
if (value == null || (isBoolean && !(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.includeBooleanAttr)(value))) {
|
|
el.removeAttribute(key);
|
|
}
|
|
else {
|
|
el.setAttribute(key, isBoolean ? '' : value);
|
|
}
|
|
}
|
|
}
|
|
|
|
// __UNSAFE__
|
|
// functions. The user is responsible for using them with only trusted content.
|
|
function patchDOMProp(el, key, value,
|
|
// the following args are passed only due to potential innerHTML/textContent
|
|
// overriding existing VNodes, in which case the old tree must be properly
|
|
// unmounted.
|
|
prevChildren, parentComponent, parentSuspense, unmountChildren) {
|
|
if (key === 'innerHTML' || key === 'textContent') {
|
|
if (prevChildren) {
|
|
unmountChildren(prevChildren, parentComponent, parentSuspense);
|
|
}
|
|
el[key] = value == null ? '' : value;
|
|
return;
|
|
}
|
|
if (key === 'value' && el.tagName !== 'PROGRESS') {
|
|
// store value as _value as well since
|
|
// non-string values will be stringified.
|
|
el._value = value;
|
|
const newValue = value == null ? '' : value;
|
|
if (el.value !== newValue) {
|
|
el.value = newValue;
|
|
}
|
|
if (value == null) {
|
|
el.removeAttribute(key);
|
|
}
|
|
return;
|
|
}
|
|
if (value === '' || value == null) {
|
|
const type = typeof el[key];
|
|
if (type === 'boolean') {
|
|
// e.g. <select multiple> compiles to { multiple: '' }
|
|
el[key] = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.includeBooleanAttr)(value);
|
|
return;
|
|
}
|
|
else if (value == null && type === 'string') {
|
|
// e.g. <div :id="null">
|
|
el[key] = '';
|
|
el.removeAttribute(key);
|
|
return;
|
|
}
|
|
else if (type === 'number') {
|
|
// e.g. <img :width="null">
|
|
// the value of some IDL attr must be greater than 0, e.g. input.size = 0 -> error
|
|
try {
|
|
el[key] = 0;
|
|
}
|
|
catch (_a) { }
|
|
el.removeAttribute(key);
|
|
return;
|
|
}
|
|
}
|
|
// some properties perform value validation and throw
|
|
try {
|
|
el[key] = value;
|
|
}
|
|
catch (e) {
|
|
if ((true)) {
|
|
(0,_vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.warn)(`Failed setting prop "${key}" on <${el.tagName.toLowerCase()}>: ` +
|
|
`value ${value} is invalid.`, e);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Async edge case fix requires storing an event listener's attach timestamp.
|
|
let _getNow = Date.now;
|
|
let skipTimestampCheck = false;
|
|
if (typeof window !== 'undefined') {
|
|
// Determine what event timestamp the browser is using. Annoyingly, the
|
|
// timestamp can either be hi-res (relative to page load) or low-res
|
|
// (relative to UNIX epoch), so in order to compare time we have to use the
|
|
// same timestamp type when saving the flush timestamp.
|
|
if (_getNow() > document.createEvent('Event').timeStamp) {
|
|
// if the low-res timestamp which is bigger than the event timestamp
|
|
// (which is evaluated AFTER) it means the event is using a hi-res timestamp,
|
|
// and we need to use the hi-res version for event listeners as well.
|
|
_getNow = () => performance.now();
|
|
}
|
|
// #3485: Firefox <= 53 has incorrect Event.timeStamp implementation
|
|
// and does not fire microtasks in between event propagation, so safe to exclude.
|
|
const ffMatch = navigator.userAgent.match(/firefox\/(\d+)/i);
|
|
skipTimestampCheck = !!(ffMatch && Number(ffMatch[1]) <= 53);
|
|
}
|
|
// To avoid the overhead of repeatedly calling performance.now(), we cache
|
|
// and use the same timestamp for all event listeners attached in the same tick.
|
|
let cachedNow = 0;
|
|
const p = Promise.resolve();
|
|
const reset = () => {
|
|
cachedNow = 0;
|
|
};
|
|
const getNow = () => cachedNow || (p.then(reset), (cachedNow = _getNow()));
|
|
function addEventListener(el, event, handler, options) {
|
|
el.addEventListener(event, handler, options);
|
|
}
|
|
function removeEventListener(el, event, handler, options) {
|
|
el.removeEventListener(event, handler, options);
|
|
}
|
|
function patchEvent(el, rawName, prevValue, nextValue, instance = null) {
|
|
// vei = vue event invokers
|
|
const invokers = el._vei || (el._vei = {});
|
|
const existingInvoker = invokers[rawName];
|
|
if (nextValue && existingInvoker) {
|
|
// patch
|
|
existingInvoker.value = nextValue;
|
|
}
|
|
else {
|
|
const [name, options] = parseName(rawName);
|
|
if (nextValue) {
|
|
// add
|
|
const invoker = (invokers[rawName] = createInvoker(nextValue, instance));
|
|
addEventListener(el, name, invoker, options);
|
|
}
|
|
else if (existingInvoker) {
|
|
// remove
|
|
removeEventListener(el, name, existingInvoker, options);
|
|
invokers[rawName] = undefined;
|
|
}
|
|
}
|
|
}
|
|
const optionsModifierRE = /(?:Once|Passive|Capture)$/;
|
|
function parseName(name) {
|
|
let options;
|
|
if (optionsModifierRE.test(name)) {
|
|
options = {};
|
|
let m;
|
|
while ((m = name.match(optionsModifierRE))) {
|
|
name = name.slice(0, name.length - m[0].length);
|
|
options[m[0].toLowerCase()] = true;
|
|
}
|
|
}
|
|
return [(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.hyphenate)(name.slice(2)), options];
|
|
}
|
|
function createInvoker(initialValue, instance) {
|
|
const invoker = (e) => {
|
|
// async edge case #6566: inner click event triggers patch, event handler
|
|
// attached to outer element during patch, and triggered again. This
|
|
// happens because browsers fire microtask ticks between event propagation.
|
|
// the solution is simple: we save the timestamp when a handler is attached,
|
|
// and the handler would only fire if the event passed to it was fired
|
|
// AFTER it was attached.
|
|
const timeStamp = e.timeStamp || _getNow();
|
|
if (skipTimestampCheck || timeStamp >= invoker.attached - 1) {
|
|
(0,_vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.callWithAsyncErrorHandling)(patchStopImmediatePropagation(e, invoker.value), instance, 5 /* NATIVE_EVENT_HANDLER */, [e]);
|
|
}
|
|
};
|
|
invoker.value = initialValue;
|
|
invoker.attached = getNow();
|
|
return invoker;
|
|
}
|
|
function patchStopImmediatePropagation(e, value) {
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isArray)(value)) {
|
|
const originalStop = e.stopImmediatePropagation;
|
|
e.stopImmediatePropagation = () => {
|
|
originalStop.call(e);
|
|
e._stopped = true;
|
|
};
|
|
return value.map(fn => (e) => !e._stopped && fn(e));
|
|
}
|
|
else {
|
|
return value;
|
|
}
|
|
}
|
|
|
|
const nativeOnRE = /^on[a-z]/;
|
|
const patchProp = (el, key, prevValue, nextValue, isSVG = false, prevChildren, parentComponent, parentSuspense, unmountChildren) => {
|
|
if (key === 'class') {
|
|
patchClass(el, nextValue, isSVG);
|
|
}
|
|
else if (key === 'style') {
|
|
patchStyle(el, prevValue, nextValue);
|
|
}
|
|
else if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isOn)(key)) {
|
|
// ignore v-model listeners
|
|
if (!(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isModelListener)(key)) {
|
|
patchEvent(el, key, prevValue, nextValue, parentComponent);
|
|
}
|
|
}
|
|
else if (key[0] === '.'
|
|
? ((key = key.slice(1)), true)
|
|
: key[0] === '^'
|
|
? ((key = key.slice(1)), false)
|
|
: shouldSetAsProp(el, key, nextValue, isSVG)) {
|
|
patchDOMProp(el, key, nextValue, prevChildren, parentComponent, parentSuspense, unmountChildren);
|
|
}
|
|
else {
|
|
// special case for <input v-model type="checkbox"> with
|
|
// :true-value & :false-value
|
|
// store value as dom properties since non-string values will be
|
|
// stringified.
|
|
if (key === 'true-value') {
|
|
el._trueValue = nextValue;
|
|
}
|
|
else if (key === 'false-value') {
|
|
el._falseValue = nextValue;
|
|
}
|
|
patchAttr(el, key, nextValue, isSVG);
|
|
}
|
|
};
|
|
function shouldSetAsProp(el, key, value, isSVG) {
|
|
if (isSVG) {
|
|
// most keys must be set as attribute on svg elements to work
|
|
// ...except innerHTML & textContent
|
|
if (key === 'innerHTML' || key === 'textContent') {
|
|
return true;
|
|
}
|
|
// or native onclick with function values
|
|
if (key in el && nativeOnRE.test(key) && (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isFunction)(value)) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
// spellcheck and draggable are numerated attrs, however their
|
|
// corresponding DOM properties are actually booleans - this leads to
|
|
// setting it with a string "false" value leading it to be coerced to
|
|
// `true`, so we need to always treat them as attributes.
|
|
// Note that `contentEditable` doesn't have this problem: its DOM
|
|
// property is also enumerated string values.
|
|
if (key === 'spellcheck' || key === 'draggable') {
|
|
return false;
|
|
}
|
|
// #1787, #2840 form property on form elements is readonly and must be set as
|
|
// attribute.
|
|
if (key === 'form') {
|
|
return false;
|
|
}
|
|
// #1526 <input list> must be set as attribute
|
|
if (key === 'list' && el.tagName === 'INPUT') {
|
|
return false;
|
|
}
|
|
// #2766 <textarea type> must be set as attribute
|
|
if (key === 'type' && el.tagName === 'TEXTAREA') {
|
|
return false;
|
|
}
|
|
// native onclick with string value, must be set as attribute
|
|
if (nativeOnRE.test(key) && (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isString)(value)) {
|
|
return false;
|
|
}
|
|
return key in el;
|
|
}
|
|
|
|
function defineCustomElement(options, hydate) {
|
|
const Comp = (0,_vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.defineComponent)(options);
|
|
class VueCustomElement extends VueElement {
|
|
constructor(initialProps) {
|
|
super(Comp, initialProps, hydate);
|
|
}
|
|
}
|
|
VueCustomElement.def = Comp;
|
|
return VueCustomElement;
|
|
}
|
|
const defineSSRCustomElement = ((options) => {
|
|
// @ts-ignore
|
|
return defineCustomElement(options, hydrate);
|
|
});
|
|
const BaseClass = (typeof HTMLElement !== 'undefined' ? HTMLElement : class {
|
|
});
|
|
class VueElement extends BaseClass {
|
|
constructor(_def, _props = {}, hydrate) {
|
|
super();
|
|
this._def = _def;
|
|
this._props = _props;
|
|
/**
|
|
* @internal
|
|
*/
|
|
this._instance = null;
|
|
this._connected = false;
|
|
this._resolved = false;
|
|
if (this.shadowRoot && hydrate) {
|
|
hydrate(this._createVNode(), this.shadowRoot);
|
|
}
|
|
else {
|
|
if (( true) && this.shadowRoot) {
|
|
(0,_vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.warn)(`Custom element has pre-rendered declarative shadow root but is not ` +
|
|
`defined as hydratable. Use \`defineSSRCustomElement\`.`);
|
|
}
|
|
this.attachShadow({ mode: 'open' });
|
|
}
|
|
// set initial attrs
|
|
for (let i = 0; i < this.attributes.length; i++) {
|
|
this._setAttr(this.attributes[i].name);
|
|
}
|
|
// watch future attr changes
|
|
const observer = new MutationObserver(mutations => {
|
|
for (const m of mutations) {
|
|
this._setAttr(m.attributeName);
|
|
}
|
|
});
|
|
observer.observe(this, { attributes: true });
|
|
}
|
|
connectedCallback() {
|
|
this._connected = true;
|
|
if (!this._instance) {
|
|
this._resolveDef();
|
|
render(this._createVNode(), this.shadowRoot);
|
|
}
|
|
}
|
|
disconnectedCallback() {
|
|
this._connected = false;
|
|
(0,_vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.nextTick)(() => {
|
|
if (!this._connected) {
|
|
render(null, this.shadowRoot);
|
|
this._instance = null;
|
|
}
|
|
});
|
|
}
|
|
/**
|
|
* resolve inner component definition (handle possible async component)
|
|
*/
|
|
_resolveDef() {
|
|
if (this._resolved) {
|
|
return;
|
|
}
|
|
const resolve = (def) => {
|
|
this._resolved = true;
|
|
// check if there are props set pre-upgrade or connect
|
|
for (const key of Object.keys(this)) {
|
|
if (key[0] !== '_') {
|
|
this._setProp(key, this[key]);
|
|
}
|
|
}
|
|
const { props, styles } = def;
|
|
// defining getter/setters on prototype
|
|
const rawKeys = props ? ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isArray)(props) ? props : Object.keys(props)) : [];
|
|
for (const key of rawKeys.map(_vue_shared__WEBPACK_IMPORTED_MODULE_1__.camelize)) {
|
|
Object.defineProperty(this, key, {
|
|
get() {
|
|
return this._getProp(key);
|
|
},
|
|
set(val) {
|
|
this._setProp(key, val);
|
|
}
|
|
});
|
|
}
|
|
this._applyStyles(styles);
|
|
};
|
|
const asyncDef = this._def.__asyncLoader;
|
|
if (asyncDef) {
|
|
asyncDef().then(resolve);
|
|
}
|
|
else {
|
|
resolve(this._def);
|
|
}
|
|
}
|
|
_setAttr(key) {
|
|
this._setProp((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.camelize)(key), (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.toNumber)(this.getAttribute(key)), false);
|
|
}
|
|
/**
|
|
* @internal
|
|
*/
|
|
_getProp(key) {
|
|
return this._props[key];
|
|
}
|
|
/**
|
|
* @internal
|
|
*/
|
|
_setProp(key, val, shouldReflect = true) {
|
|
if (val !== this._props[key]) {
|
|
this._props[key] = val;
|
|
if (this._instance) {
|
|
render(this._createVNode(), this.shadowRoot);
|
|
}
|
|
// reflect
|
|
if (shouldReflect) {
|
|
if (val === true) {
|
|
this.setAttribute((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.hyphenate)(key), '');
|
|
}
|
|
else if (typeof val === 'string' || typeof val === 'number') {
|
|
this.setAttribute((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.hyphenate)(key), val + '');
|
|
}
|
|
else if (!val) {
|
|
this.removeAttribute((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.hyphenate)(key));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
_createVNode() {
|
|
const vnode = (0,_vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.createVNode)(this._def, (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.extend)({}, this._props));
|
|
if (!this._instance) {
|
|
vnode.ce = instance => {
|
|
this._instance = instance;
|
|
instance.isCE = true;
|
|
// HMR
|
|
if ((true)) {
|
|
instance.ceReload = newStyles => {
|
|
// alawys reset styles
|
|
if (this._styles) {
|
|
this._styles.forEach(s => this.shadowRoot.removeChild(s));
|
|
this._styles.length = 0;
|
|
}
|
|
this._applyStyles(newStyles);
|
|
// if this is an async component, ceReload is called from the inner
|
|
// component so no need to reload the async wrapper
|
|
if (!this._def.__asyncLoader) {
|
|
// reload
|
|
this._instance = null;
|
|
render(this._createVNode(), this.shadowRoot);
|
|
}
|
|
};
|
|
}
|
|
// intercept emit
|
|
instance.emit = (event, ...args) => {
|
|
this.dispatchEvent(new CustomEvent(event, {
|
|
detail: args
|
|
}));
|
|
};
|
|
// locate nearest Vue custom element parent for provide/inject
|
|
let parent = this;
|
|
while ((parent =
|
|
parent && (parent.parentNode || parent.host))) {
|
|
if (parent instanceof VueElement) {
|
|
instance.parent = parent._instance;
|
|
break;
|
|
}
|
|
}
|
|
};
|
|
}
|
|
return vnode;
|
|
}
|
|
_applyStyles(styles) {
|
|
if (styles) {
|
|
styles.forEach(css => {
|
|
const s = document.createElement('style');
|
|
s.textContent = css;
|
|
this.shadowRoot.appendChild(s);
|
|
// record for HMR
|
|
if ((true)) {
|
|
(this._styles || (this._styles = [])).push(s);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
function useCssModule(name = '$style') {
|
|
/* istanbul ignore else */
|
|
{
|
|
const instance = (0,_vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.getCurrentInstance)();
|
|
if (!instance) {
|
|
( true) && (0,_vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.warn)(`useCssModule must be called inside setup()`);
|
|
return _vue_shared__WEBPACK_IMPORTED_MODULE_1__.EMPTY_OBJ;
|
|
}
|
|
const modules = instance.type.__cssModules;
|
|
if (!modules) {
|
|
( true) && (0,_vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.warn)(`Current instance does not have CSS modules injected.`);
|
|
return _vue_shared__WEBPACK_IMPORTED_MODULE_1__.EMPTY_OBJ;
|
|
}
|
|
const mod = modules[name];
|
|
if (!mod) {
|
|
( true) &&
|
|
(0,_vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.warn)(`Current instance does not have CSS module named "${name}".`);
|
|
return _vue_shared__WEBPACK_IMPORTED_MODULE_1__.EMPTY_OBJ;
|
|
}
|
|
return mod;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Runtime helper for SFC's CSS variable injection feature.
|
|
* @private
|
|
*/
|
|
function useCssVars(getter) {
|
|
const instance = (0,_vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.getCurrentInstance)();
|
|
/* istanbul ignore next */
|
|
if (!instance) {
|
|
( true) &&
|
|
(0,_vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.warn)(`useCssVars is called without current active component instance.`);
|
|
return;
|
|
}
|
|
const setVars = () => setVarsOnVNode(instance.subTree, getter(instance.proxy));
|
|
(0,_vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.watchPostEffect)(setVars);
|
|
(0,_vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.onMounted)(() => {
|
|
const ob = new MutationObserver(setVars);
|
|
ob.observe(instance.subTree.el.parentNode, { childList: true });
|
|
(0,_vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.onUnmounted)(() => ob.disconnect());
|
|
});
|
|
}
|
|
function setVarsOnVNode(vnode, vars) {
|
|
if (vnode.shapeFlag & 128 /* SUSPENSE */) {
|
|
const suspense = vnode.suspense;
|
|
vnode = suspense.activeBranch;
|
|
if (suspense.pendingBranch && !suspense.isHydrating) {
|
|
suspense.effects.push(() => {
|
|
setVarsOnVNode(suspense.activeBranch, vars);
|
|
});
|
|
}
|
|
}
|
|
// drill down HOCs until it's a non-component vnode
|
|
while (vnode.component) {
|
|
vnode = vnode.component.subTree;
|
|
}
|
|
if (vnode.shapeFlag & 1 /* ELEMENT */ && vnode.el) {
|
|
setVarsOnNode(vnode.el, vars);
|
|
}
|
|
else if (vnode.type === _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.Fragment) {
|
|
vnode.children.forEach(c => setVarsOnVNode(c, vars));
|
|
}
|
|
else if (vnode.type === _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.Static) {
|
|
let { el, anchor } = vnode;
|
|
while (el) {
|
|
setVarsOnNode(el, vars);
|
|
if (el === anchor)
|
|
break;
|
|
el = el.nextSibling;
|
|
}
|
|
}
|
|
}
|
|
function setVarsOnNode(el, vars) {
|
|
if (el.nodeType === 1) {
|
|
const style = el.style;
|
|
for (const key in vars) {
|
|
style.setProperty(`--${key}`, vars[key]);
|
|
}
|
|
}
|
|
}
|
|
|
|
const TRANSITION = 'transition';
|
|
const ANIMATION = 'animation';
|
|
// DOM Transition is a higher-order-component based on the platform-agnostic
|
|
// base Transition component, with DOM-specific logic.
|
|
const Transition = (props, { slots }) => (0,_vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.h)(_vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.BaseTransition, resolveTransitionProps(props), slots);
|
|
Transition.displayName = 'Transition';
|
|
const DOMTransitionPropsValidators = {
|
|
name: String,
|
|
type: String,
|
|
css: {
|
|
type: Boolean,
|
|
default: true
|
|
},
|
|
duration: [String, Number, Object],
|
|
enterFromClass: String,
|
|
enterActiveClass: String,
|
|
enterToClass: String,
|
|
appearFromClass: String,
|
|
appearActiveClass: String,
|
|
appearToClass: String,
|
|
leaveFromClass: String,
|
|
leaveActiveClass: String,
|
|
leaveToClass: String
|
|
};
|
|
const TransitionPropsValidators = (Transition.props =
|
|
/*#__PURE__*/ (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.extend)({}, _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.BaseTransition.props, DOMTransitionPropsValidators));
|
|
/**
|
|
* #3227 Incoming hooks may be merged into arrays when wrapping Transition
|
|
* with custom HOCs.
|
|
*/
|
|
const callHook = (hook, args = []) => {
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isArray)(hook)) {
|
|
hook.forEach(h => h(...args));
|
|
}
|
|
else if (hook) {
|
|
hook(...args);
|
|
}
|
|
};
|
|
/**
|
|
* Check if a hook expects a callback (2nd arg), which means the user
|
|
* intends to explicitly control the end of the transition.
|
|
*/
|
|
const hasExplicitCallback = (hook) => {
|
|
return hook
|
|
? (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isArray)(hook)
|
|
? hook.some(h => h.length > 1)
|
|
: hook.length > 1
|
|
: false;
|
|
};
|
|
function resolveTransitionProps(rawProps) {
|
|
const baseProps = {};
|
|
for (const key in rawProps) {
|
|
if (!(key in DOMTransitionPropsValidators)) {
|
|
baseProps[key] = rawProps[key];
|
|
}
|
|
}
|
|
if (rawProps.css === false) {
|
|
return baseProps;
|
|
}
|
|
const { name = 'v', type, duration, enterFromClass = `${name}-enter-from`, enterActiveClass = `${name}-enter-active`, enterToClass = `${name}-enter-to`, appearFromClass = enterFromClass, appearActiveClass = enterActiveClass, appearToClass = enterToClass, leaveFromClass = `${name}-leave-from`, leaveActiveClass = `${name}-leave-active`, leaveToClass = `${name}-leave-to` } = rawProps;
|
|
const durations = normalizeDuration(duration);
|
|
const enterDuration = durations && durations[0];
|
|
const leaveDuration = durations && durations[1];
|
|
const { onBeforeEnter, onEnter, onEnterCancelled, onLeave, onLeaveCancelled, onBeforeAppear = onBeforeEnter, onAppear = onEnter, onAppearCancelled = onEnterCancelled } = baseProps;
|
|
const finishEnter = (el, isAppear, done) => {
|
|
removeTransitionClass(el, isAppear ? appearToClass : enterToClass);
|
|
removeTransitionClass(el, isAppear ? appearActiveClass : enterActiveClass);
|
|
done && done();
|
|
};
|
|
const finishLeave = (el, done) => {
|
|
removeTransitionClass(el, leaveToClass);
|
|
removeTransitionClass(el, leaveActiveClass);
|
|
done && done();
|
|
};
|
|
const makeEnterHook = (isAppear) => {
|
|
return (el, done) => {
|
|
const hook = isAppear ? onAppear : onEnter;
|
|
const resolve = () => finishEnter(el, isAppear, done);
|
|
callHook(hook, [el, resolve]);
|
|
nextFrame(() => {
|
|
removeTransitionClass(el, isAppear ? appearFromClass : enterFromClass);
|
|
addTransitionClass(el, isAppear ? appearToClass : enterToClass);
|
|
if (!hasExplicitCallback(hook)) {
|
|
whenTransitionEnds(el, type, enterDuration, resolve);
|
|
}
|
|
});
|
|
};
|
|
};
|
|
return (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.extend)(baseProps, {
|
|
onBeforeEnter(el) {
|
|
callHook(onBeforeEnter, [el]);
|
|
addTransitionClass(el, enterFromClass);
|
|
addTransitionClass(el, enterActiveClass);
|
|
},
|
|
onBeforeAppear(el) {
|
|
callHook(onBeforeAppear, [el]);
|
|
addTransitionClass(el, appearFromClass);
|
|
addTransitionClass(el, appearActiveClass);
|
|
},
|
|
onEnter: makeEnterHook(false),
|
|
onAppear: makeEnterHook(true),
|
|
onLeave(el, done) {
|
|
const resolve = () => finishLeave(el, done);
|
|
addTransitionClass(el, leaveFromClass);
|
|
// force reflow so *-leave-from classes immediately take effect (#2593)
|
|
forceReflow();
|
|
addTransitionClass(el, leaveActiveClass);
|
|
nextFrame(() => {
|
|
removeTransitionClass(el, leaveFromClass);
|
|
addTransitionClass(el, leaveToClass);
|
|
if (!hasExplicitCallback(onLeave)) {
|
|
whenTransitionEnds(el, type, leaveDuration, resolve);
|
|
}
|
|
});
|
|
callHook(onLeave, [el, resolve]);
|
|
},
|
|
onEnterCancelled(el) {
|
|
finishEnter(el, false);
|
|
callHook(onEnterCancelled, [el]);
|
|
},
|
|
onAppearCancelled(el) {
|
|
finishEnter(el, true);
|
|
callHook(onAppearCancelled, [el]);
|
|
},
|
|
onLeaveCancelled(el) {
|
|
finishLeave(el);
|
|
callHook(onLeaveCancelled, [el]);
|
|
}
|
|
});
|
|
}
|
|
function normalizeDuration(duration) {
|
|
if (duration == null) {
|
|
return null;
|
|
}
|
|
else if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isObject)(duration)) {
|
|
return [NumberOf(duration.enter), NumberOf(duration.leave)];
|
|
}
|
|
else {
|
|
const n = NumberOf(duration);
|
|
return [n, n];
|
|
}
|
|
}
|
|
function NumberOf(val) {
|
|
const res = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.toNumber)(val);
|
|
if ((true))
|
|
validateDuration(res);
|
|
return res;
|
|
}
|
|
function validateDuration(val) {
|
|
if (typeof val !== 'number') {
|
|
(0,_vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.warn)(`<transition> explicit duration is not a valid number - ` +
|
|
`got ${JSON.stringify(val)}.`);
|
|
}
|
|
else if (isNaN(val)) {
|
|
(0,_vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.warn)(`<transition> explicit duration is NaN - ` +
|
|
'the duration expression might be incorrect.');
|
|
}
|
|
}
|
|
function addTransitionClass(el, cls) {
|
|
cls.split(/\s+/).forEach(c => c && el.classList.add(c));
|
|
(el._vtc ||
|
|
(el._vtc = new Set())).add(cls);
|
|
}
|
|
function removeTransitionClass(el, cls) {
|
|
cls.split(/\s+/).forEach(c => c && el.classList.remove(c));
|
|
const { _vtc } = el;
|
|
if (_vtc) {
|
|
_vtc.delete(cls);
|
|
if (!_vtc.size) {
|
|
el._vtc = undefined;
|
|
}
|
|
}
|
|
}
|
|
function nextFrame(cb) {
|
|
requestAnimationFrame(() => {
|
|
requestAnimationFrame(cb);
|
|
});
|
|
}
|
|
let endId = 0;
|
|
function whenTransitionEnds(el, expectedType, explicitTimeout, resolve) {
|
|
const id = (el._endId = ++endId);
|
|
const resolveIfNotStale = () => {
|
|
if (id === el._endId) {
|
|
resolve();
|
|
}
|
|
};
|
|
if (explicitTimeout) {
|
|
return setTimeout(resolveIfNotStale, explicitTimeout);
|
|
}
|
|
const { type, timeout, propCount } = getTransitionInfo(el, expectedType);
|
|
if (!type) {
|
|
return resolve();
|
|
}
|
|
const endEvent = type + 'end';
|
|
let ended = 0;
|
|
const end = () => {
|
|
el.removeEventListener(endEvent, onEnd);
|
|
resolveIfNotStale();
|
|
};
|
|
const onEnd = (e) => {
|
|
if (e.target === el && ++ended >= propCount) {
|
|
end();
|
|
}
|
|
};
|
|
setTimeout(() => {
|
|
if (ended < propCount) {
|
|
end();
|
|
}
|
|
}, timeout + 1);
|
|
el.addEventListener(endEvent, onEnd);
|
|
}
|
|
function getTransitionInfo(el, expectedType) {
|
|
const styles = window.getComputedStyle(el);
|
|
// JSDOM may return undefined for transition properties
|
|
const getStyleProperties = (key) => (styles[key] || '').split(', ');
|
|
const transitionDelays = getStyleProperties(TRANSITION + 'Delay');
|
|
const transitionDurations = getStyleProperties(TRANSITION + 'Duration');
|
|
const transitionTimeout = getTimeout(transitionDelays, transitionDurations);
|
|
const animationDelays = getStyleProperties(ANIMATION + 'Delay');
|
|
const animationDurations = getStyleProperties(ANIMATION + 'Duration');
|
|
const animationTimeout = getTimeout(animationDelays, animationDurations);
|
|
let type = null;
|
|
let timeout = 0;
|
|
let propCount = 0;
|
|
/* istanbul ignore if */
|
|
if (expectedType === TRANSITION) {
|
|
if (transitionTimeout > 0) {
|
|
type = TRANSITION;
|
|
timeout = transitionTimeout;
|
|
propCount = transitionDurations.length;
|
|
}
|
|
}
|
|
else if (expectedType === ANIMATION) {
|
|
if (animationTimeout > 0) {
|
|
type = ANIMATION;
|
|
timeout = animationTimeout;
|
|
propCount = animationDurations.length;
|
|
}
|
|
}
|
|
else {
|
|
timeout = Math.max(transitionTimeout, animationTimeout);
|
|
type =
|
|
timeout > 0
|
|
? transitionTimeout > animationTimeout
|
|
? TRANSITION
|
|
: ANIMATION
|
|
: null;
|
|
propCount = type
|
|
? type === TRANSITION
|
|
? transitionDurations.length
|
|
: animationDurations.length
|
|
: 0;
|
|
}
|
|
const hasTransform = type === TRANSITION &&
|
|
/\b(transform|all)(,|$)/.test(styles[TRANSITION + 'Property']);
|
|
return {
|
|
type,
|
|
timeout,
|
|
propCount,
|
|
hasTransform
|
|
};
|
|
}
|
|
function getTimeout(delays, durations) {
|
|
while (delays.length < durations.length) {
|
|
delays = delays.concat(delays);
|
|
}
|
|
return Math.max(...durations.map((d, i) => toMs(d) + toMs(delays[i])));
|
|
}
|
|
// Old versions of Chromium (below 61.0.3163.100) formats floating pointer
|
|
// numbers in a locale-dependent way, using a comma instead of a dot.
|
|
// If comma is not replaced with a dot, the input will be rounded down
|
|
// (i.e. acting as a floor function) causing unexpected behaviors
|
|
function toMs(s) {
|
|
return Number(s.slice(0, -1).replace(',', '.')) * 1000;
|
|
}
|
|
// synchronously force layout to put elements into a certain state
|
|
function forceReflow() {
|
|
return document.body.offsetHeight;
|
|
}
|
|
|
|
const positionMap = new WeakMap();
|
|
const newPositionMap = new WeakMap();
|
|
const TransitionGroupImpl = {
|
|
name: 'TransitionGroup',
|
|
props: /*#__PURE__*/ (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.extend)({}, TransitionPropsValidators, {
|
|
tag: String,
|
|
moveClass: String
|
|
}),
|
|
setup(props, { slots }) {
|
|
const instance = (0,_vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.getCurrentInstance)();
|
|
const state = (0,_vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.useTransitionState)();
|
|
let prevChildren;
|
|
let children;
|
|
(0,_vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.onUpdated)(() => {
|
|
// children is guaranteed to exist after initial render
|
|
if (!prevChildren.length) {
|
|
return;
|
|
}
|
|
const moveClass = props.moveClass || `${props.name || 'v'}-move`;
|
|
if (!hasCSSTransform(prevChildren[0].el, instance.vnode.el, moveClass)) {
|
|
return;
|
|
}
|
|
// we divide the work into three loops to avoid mixing DOM reads and writes
|
|
// in each iteration - which helps prevent layout thrashing.
|
|
prevChildren.forEach(callPendingCbs);
|
|
prevChildren.forEach(recordPosition);
|
|
const movedChildren = prevChildren.filter(applyTranslation);
|
|
// force reflow to put everything in position
|
|
forceReflow();
|
|
movedChildren.forEach(c => {
|
|
const el = c.el;
|
|
const style = el.style;
|
|
addTransitionClass(el, moveClass);
|
|
style.transform = style.webkitTransform = style.transitionDuration = '';
|
|
const cb = (el._moveCb = (e) => {
|
|
if (e && e.target !== el) {
|
|
return;
|
|
}
|
|
if (!e || /transform$/.test(e.propertyName)) {
|
|
el.removeEventListener('transitionend', cb);
|
|
el._moveCb = null;
|
|
removeTransitionClass(el, moveClass);
|
|
}
|
|
});
|
|
el.addEventListener('transitionend', cb);
|
|
});
|
|
});
|
|
return () => {
|
|
const rawProps = (0,_vue_runtime_core__WEBPACK_IMPORTED_MODULE_2__.toRaw)(props);
|
|
const cssTransitionProps = resolveTransitionProps(rawProps);
|
|
let tag = rawProps.tag || _vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.Fragment;
|
|
prevChildren = children;
|
|
children = slots.default ? (0,_vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.getTransitionRawChildren)(slots.default()) : [];
|
|
for (let i = 0; i < children.length; i++) {
|
|
const child = children[i];
|
|
if (child.key != null) {
|
|
(0,_vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.setTransitionHooks)(child, (0,_vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.resolveTransitionHooks)(child, cssTransitionProps, state, instance));
|
|
}
|
|
else if ((true)) {
|
|
(0,_vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.warn)(`<TransitionGroup> children must be keyed.`);
|
|
}
|
|
}
|
|
if (prevChildren) {
|
|
for (let i = 0; i < prevChildren.length; i++) {
|
|
const child = prevChildren[i];
|
|
(0,_vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.setTransitionHooks)(child, (0,_vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.resolveTransitionHooks)(child, cssTransitionProps, state, instance));
|
|
positionMap.set(child, child.el.getBoundingClientRect());
|
|
}
|
|
}
|
|
return (0,_vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.createVNode)(tag, null, children);
|
|
};
|
|
}
|
|
};
|
|
const TransitionGroup = TransitionGroupImpl;
|
|
function callPendingCbs(c) {
|
|
const el = c.el;
|
|
if (el._moveCb) {
|
|
el._moveCb();
|
|
}
|
|
if (el._enterCb) {
|
|
el._enterCb();
|
|
}
|
|
}
|
|
function recordPosition(c) {
|
|
newPositionMap.set(c, c.el.getBoundingClientRect());
|
|
}
|
|
function applyTranslation(c) {
|
|
const oldPos = positionMap.get(c);
|
|
const newPos = newPositionMap.get(c);
|
|
const dx = oldPos.left - newPos.left;
|
|
const dy = oldPos.top - newPos.top;
|
|
if (dx || dy) {
|
|
const s = c.el.style;
|
|
s.transform = s.webkitTransform = `translate(${dx}px,${dy}px)`;
|
|
s.transitionDuration = '0s';
|
|
return c;
|
|
}
|
|
}
|
|
function hasCSSTransform(el, root, moveClass) {
|
|
// Detect whether an element with the move class applied has
|
|
// CSS transitions. Since the element may be inside an entering
|
|
// transition at this very moment, we make a clone of it and remove
|
|
// all other transition classes applied to ensure only the move class
|
|
// is applied.
|
|
const clone = el.cloneNode();
|
|
if (el._vtc) {
|
|
el._vtc.forEach(cls => {
|
|
cls.split(/\s+/).forEach(c => c && clone.classList.remove(c));
|
|
});
|
|
}
|
|
moveClass.split(/\s+/).forEach(c => c && clone.classList.add(c));
|
|
clone.style.display = 'none';
|
|
const container = (root.nodeType === 1 ? root : root.parentNode);
|
|
container.appendChild(clone);
|
|
const { hasTransform } = getTransitionInfo(clone);
|
|
container.removeChild(clone);
|
|
return hasTransform;
|
|
}
|
|
|
|
const getModelAssigner = (vnode) => {
|
|
const fn = vnode.props['onUpdate:modelValue'];
|
|
return (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isArray)(fn) ? value => (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.invokeArrayFns)(fn, value) : fn;
|
|
};
|
|
function onCompositionStart(e) {
|
|
e.target.composing = true;
|
|
}
|
|
function onCompositionEnd(e) {
|
|
const target = e.target;
|
|
if (target.composing) {
|
|
target.composing = false;
|
|
trigger(target, 'input');
|
|
}
|
|
}
|
|
function trigger(el, type) {
|
|
const e = document.createEvent('HTMLEvents');
|
|
e.initEvent(type, true, true);
|
|
el.dispatchEvent(e);
|
|
}
|
|
// We are exporting the v-model runtime directly as vnode hooks so that it can
|
|
// be tree-shaken in case v-model is never used.
|
|
const vModelText = {
|
|
created(el, { modifiers: { lazy, trim, number } }, vnode) {
|
|
el._assign = getModelAssigner(vnode);
|
|
const castToNumber = number || (vnode.props && vnode.props.type === 'number');
|
|
addEventListener(el, lazy ? 'change' : 'input', e => {
|
|
if (e.target.composing)
|
|
return;
|
|
let domValue = el.value;
|
|
if (trim) {
|
|
domValue = domValue.trim();
|
|
}
|
|
else if (castToNumber) {
|
|
domValue = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.toNumber)(domValue);
|
|
}
|
|
el._assign(domValue);
|
|
});
|
|
if (trim) {
|
|
addEventListener(el, 'change', () => {
|
|
el.value = el.value.trim();
|
|
});
|
|
}
|
|
if (!lazy) {
|
|
addEventListener(el, 'compositionstart', onCompositionStart);
|
|
addEventListener(el, 'compositionend', onCompositionEnd);
|
|
// Safari < 10.2 & UIWebView doesn't fire compositionend when
|
|
// switching focus before confirming composition choice
|
|
// this also fixes the issue where some browsers e.g. iOS Chrome
|
|
// fires "change" instead of "input" on autocomplete.
|
|
addEventListener(el, 'change', onCompositionEnd);
|
|
}
|
|
},
|
|
// set value on mounted so it's after min/max for type="range"
|
|
mounted(el, { value }) {
|
|
el.value = value == null ? '' : value;
|
|
},
|
|
beforeUpdate(el, { value, modifiers: { lazy, trim, number } }, vnode) {
|
|
el._assign = getModelAssigner(vnode);
|
|
// avoid clearing unresolved text. #2302
|
|
if (el.composing)
|
|
return;
|
|
if (document.activeElement === el) {
|
|
if (lazy) {
|
|
return;
|
|
}
|
|
if (trim && el.value.trim() === value) {
|
|
return;
|
|
}
|
|
if ((number || el.type === 'number') && (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.toNumber)(el.value) === value) {
|
|
return;
|
|
}
|
|
}
|
|
const newValue = value == null ? '' : value;
|
|
if (el.value !== newValue) {
|
|
el.value = newValue;
|
|
}
|
|
}
|
|
};
|
|
const vModelCheckbox = {
|
|
// #4096 array checkboxes need to be deep traversed
|
|
deep: true,
|
|
created(el, _, vnode) {
|
|
el._assign = getModelAssigner(vnode);
|
|
addEventListener(el, 'change', () => {
|
|
const modelValue = el._modelValue;
|
|
const elementValue = getValue(el);
|
|
const checked = el.checked;
|
|
const assign = el._assign;
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isArray)(modelValue)) {
|
|
const index = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.looseIndexOf)(modelValue, elementValue);
|
|
const found = index !== -1;
|
|
if (checked && !found) {
|
|
assign(modelValue.concat(elementValue));
|
|
}
|
|
else if (!checked && found) {
|
|
const filtered = [...modelValue];
|
|
filtered.splice(index, 1);
|
|
assign(filtered);
|
|
}
|
|
}
|
|
else if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isSet)(modelValue)) {
|
|
const cloned = new Set(modelValue);
|
|
if (checked) {
|
|
cloned.add(elementValue);
|
|
}
|
|
else {
|
|
cloned.delete(elementValue);
|
|
}
|
|
assign(cloned);
|
|
}
|
|
else {
|
|
assign(getCheckboxValue(el, checked));
|
|
}
|
|
});
|
|
},
|
|
// set initial checked on mount to wait for true-value/false-value
|
|
mounted: setChecked,
|
|
beforeUpdate(el, binding, vnode) {
|
|
el._assign = getModelAssigner(vnode);
|
|
setChecked(el, binding, vnode);
|
|
}
|
|
};
|
|
function setChecked(el, { value, oldValue }, vnode) {
|
|
el._modelValue = value;
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isArray)(value)) {
|
|
el.checked = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.looseIndexOf)(value, vnode.props.value) > -1;
|
|
}
|
|
else if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isSet)(value)) {
|
|
el.checked = value.has(vnode.props.value);
|
|
}
|
|
else if (value !== oldValue) {
|
|
el.checked = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.looseEqual)(value, getCheckboxValue(el, true));
|
|
}
|
|
}
|
|
const vModelRadio = {
|
|
created(el, { value }, vnode) {
|
|
el.checked = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.looseEqual)(value, vnode.props.value);
|
|
el._assign = getModelAssigner(vnode);
|
|
addEventListener(el, 'change', () => {
|
|
el._assign(getValue(el));
|
|
});
|
|
},
|
|
beforeUpdate(el, { value, oldValue }, vnode) {
|
|
el._assign = getModelAssigner(vnode);
|
|
if (value !== oldValue) {
|
|
el.checked = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.looseEqual)(value, vnode.props.value);
|
|
}
|
|
}
|
|
};
|
|
const vModelSelect = {
|
|
// <select multiple> value need to be deep traversed
|
|
deep: true,
|
|
created(el, { value, modifiers: { number } }, vnode) {
|
|
const isSetModel = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isSet)(value);
|
|
addEventListener(el, 'change', () => {
|
|
const selectedVal = Array.prototype.filter
|
|
.call(el.options, (o) => o.selected)
|
|
.map((o) => number ? (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.toNumber)(getValue(o)) : getValue(o));
|
|
el._assign(el.multiple
|
|
? isSetModel
|
|
? new Set(selectedVal)
|
|
: selectedVal
|
|
: selectedVal[0]);
|
|
});
|
|
el._assign = getModelAssigner(vnode);
|
|
},
|
|
// set value in mounted & updated because <select> relies on its children
|
|
// <option>s.
|
|
mounted(el, { value }) {
|
|
setSelected(el, value);
|
|
},
|
|
beforeUpdate(el, _binding, vnode) {
|
|
el._assign = getModelAssigner(vnode);
|
|
},
|
|
updated(el, { value }) {
|
|
setSelected(el, value);
|
|
}
|
|
};
|
|
function setSelected(el, value) {
|
|
const isMultiple = el.multiple;
|
|
if (isMultiple && !(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isArray)(value) && !(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isSet)(value)) {
|
|
( true) &&
|
|
(0,_vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.warn)(`<select multiple v-model> expects an Array or Set value for its binding, ` +
|
|
`but got ${Object.prototype.toString.call(value).slice(8, -1)}.`);
|
|
return;
|
|
}
|
|
for (let i = 0, l = el.options.length; i < l; i++) {
|
|
const option = el.options[i];
|
|
const optionValue = getValue(option);
|
|
if (isMultiple) {
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isArray)(value)) {
|
|
option.selected = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.looseIndexOf)(value, optionValue) > -1;
|
|
}
|
|
else {
|
|
option.selected = value.has(optionValue);
|
|
}
|
|
}
|
|
else {
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.looseEqual)(getValue(option), value)) {
|
|
if (el.selectedIndex !== i)
|
|
el.selectedIndex = i;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
if (!isMultiple && el.selectedIndex !== -1) {
|
|
el.selectedIndex = -1;
|
|
}
|
|
}
|
|
// retrieve raw value set via :value bindings
|
|
function getValue(el) {
|
|
return '_value' in el ? el._value : el.value;
|
|
}
|
|
// retrieve raw value for true-value and false-value set via :true-value or :false-value bindings
|
|
function getCheckboxValue(el, checked) {
|
|
const key = checked ? '_trueValue' : '_falseValue';
|
|
return key in el ? el[key] : checked;
|
|
}
|
|
const vModelDynamic = {
|
|
created(el, binding, vnode) {
|
|
callModelHook(el, binding, vnode, null, 'created');
|
|
},
|
|
mounted(el, binding, vnode) {
|
|
callModelHook(el, binding, vnode, null, 'mounted');
|
|
},
|
|
beforeUpdate(el, binding, vnode, prevVNode) {
|
|
callModelHook(el, binding, vnode, prevVNode, 'beforeUpdate');
|
|
},
|
|
updated(el, binding, vnode, prevVNode) {
|
|
callModelHook(el, binding, vnode, prevVNode, 'updated');
|
|
}
|
|
};
|
|
function callModelHook(el, binding, vnode, prevVNode, hook) {
|
|
let modelToUse;
|
|
switch (el.tagName) {
|
|
case 'SELECT':
|
|
modelToUse = vModelSelect;
|
|
break;
|
|
case 'TEXTAREA':
|
|
modelToUse = vModelText;
|
|
break;
|
|
default:
|
|
switch (vnode.props && vnode.props.type) {
|
|
case 'checkbox':
|
|
modelToUse = vModelCheckbox;
|
|
break;
|
|
case 'radio':
|
|
modelToUse = vModelRadio;
|
|
break;
|
|
default:
|
|
modelToUse = vModelText;
|
|
}
|
|
}
|
|
const fn = modelToUse[hook];
|
|
fn && fn(el, binding, vnode, prevVNode);
|
|
}
|
|
|
|
const systemModifiers = ['ctrl', 'shift', 'alt', 'meta'];
|
|
const modifierGuards = {
|
|
stop: e => e.stopPropagation(),
|
|
prevent: e => e.preventDefault(),
|
|
self: e => e.target !== e.currentTarget,
|
|
ctrl: e => !e.ctrlKey,
|
|
shift: e => !e.shiftKey,
|
|
alt: e => !e.altKey,
|
|
meta: e => !e.metaKey,
|
|
left: e => 'button' in e && e.button !== 0,
|
|
middle: e => 'button' in e && e.button !== 1,
|
|
right: e => 'button' in e && e.button !== 2,
|
|
exact: (e, modifiers) => systemModifiers.some(m => e[`${m}Key`] && !modifiers.includes(m))
|
|
};
|
|
/**
|
|
* @private
|
|
*/
|
|
const withModifiers = (fn, modifiers) => {
|
|
return (event, ...args) => {
|
|
for (let i = 0; i < modifiers.length; i++) {
|
|
const guard = modifierGuards[modifiers[i]];
|
|
if (guard && guard(event, modifiers))
|
|
return;
|
|
}
|
|
return fn(event, ...args);
|
|
};
|
|
};
|
|
// Kept for 2.x compat.
|
|
// Note: IE11 compat for `spacebar` and `del` is removed for now.
|
|
const keyNames = {
|
|
esc: 'escape',
|
|
space: ' ',
|
|
up: 'arrow-up',
|
|
left: 'arrow-left',
|
|
right: 'arrow-right',
|
|
down: 'arrow-down',
|
|
delete: 'backspace'
|
|
};
|
|
/**
|
|
* @private
|
|
*/
|
|
const withKeys = (fn, modifiers) => {
|
|
return (event) => {
|
|
if (!('key' in event)) {
|
|
return;
|
|
}
|
|
const eventKey = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.hyphenate)(event.key);
|
|
if (modifiers.some(k => k === eventKey || keyNames[k] === eventKey)) {
|
|
return fn(event);
|
|
}
|
|
};
|
|
};
|
|
|
|
const vShow = {
|
|
beforeMount(el, { value }, { transition }) {
|
|
el._vod = el.style.display === 'none' ? '' : el.style.display;
|
|
if (transition && value) {
|
|
transition.beforeEnter(el);
|
|
}
|
|
else {
|
|
setDisplay(el, value);
|
|
}
|
|
},
|
|
mounted(el, { value }, { transition }) {
|
|
if (transition && value) {
|
|
transition.enter(el);
|
|
}
|
|
},
|
|
updated(el, { value, oldValue }, { transition }) {
|
|
if (!value === !oldValue)
|
|
return;
|
|
if (transition) {
|
|
if (value) {
|
|
transition.beforeEnter(el);
|
|
setDisplay(el, true);
|
|
transition.enter(el);
|
|
}
|
|
else {
|
|
transition.leave(el, () => {
|
|
setDisplay(el, false);
|
|
});
|
|
}
|
|
}
|
|
else {
|
|
setDisplay(el, value);
|
|
}
|
|
},
|
|
beforeUnmount(el, { value }) {
|
|
setDisplay(el, value);
|
|
}
|
|
};
|
|
function setDisplay(el, value) {
|
|
el.style.display = value ? el._vod : 'none';
|
|
}
|
|
|
|
const rendererOptions = (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.extend)({ patchProp }, nodeOps);
|
|
// lazy create the renderer - this makes core renderer logic tree-shakable
|
|
// in case the user only imports reactivity utilities from Vue.
|
|
let renderer;
|
|
let enabledHydration = false;
|
|
function ensureRenderer() {
|
|
return (renderer ||
|
|
(renderer = (0,_vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.createRenderer)(rendererOptions)));
|
|
}
|
|
function ensureHydrationRenderer() {
|
|
renderer = enabledHydration
|
|
? renderer
|
|
: (0,_vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.createHydrationRenderer)(rendererOptions);
|
|
enabledHydration = true;
|
|
return renderer;
|
|
}
|
|
// use explicit type casts here to avoid import() calls in rolled-up d.ts
|
|
const render = ((...args) => {
|
|
ensureRenderer().render(...args);
|
|
});
|
|
const hydrate = ((...args) => {
|
|
ensureHydrationRenderer().hydrate(...args);
|
|
});
|
|
const createApp = ((...args) => {
|
|
const app = ensureRenderer().createApp(...args);
|
|
if ((true)) {
|
|
injectNativeTagCheck(app);
|
|
injectCompilerOptionsCheck(app);
|
|
}
|
|
const { mount } = app;
|
|
app.mount = (containerOrSelector) => {
|
|
const container = normalizeContainer(containerOrSelector);
|
|
if (!container)
|
|
return;
|
|
const component = app._component;
|
|
if (!(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isFunction)(component) && !component.render && !component.template) {
|
|
// __UNSAFE__
|
|
// Reason: potential execution of JS expressions in in-DOM template.
|
|
// The user must make sure the in-DOM template is trusted. If it's
|
|
// rendered by the server, the template should not contain any user data.
|
|
component.template = container.innerHTML;
|
|
}
|
|
// clear content before mounting
|
|
container.innerHTML = '';
|
|
const proxy = mount(container, false, container instanceof SVGElement);
|
|
if (container instanceof Element) {
|
|
container.removeAttribute('v-cloak');
|
|
container.setAttribute('data-v-app', '');
|
|
}
|
|
return proxy;
|
|
};
|
|
return app;
|
|
});
|
|
const createSSRApp = ((...args) => {
|
|
const app = ensureHydrationRenderer().createApp(...args);
|
|
if ((true)) {
|
|
injectNativeTagCheck(app);
|
|
injectCompilerOptionsCheck(app);
|
|
}
|
|
const { mount } = app;
|
|
app.mount = (containerOrSelector) => {
|
|
const container = normalizeContainer(containerOrSelector);
|
|
if (container) {
|
|
return mount(container, true, container instanceof SVGElement);
|
|
}
|
|
};
|
|
return app;
|
|
});
|
|
function injectNativeTagCheck(app) {
|
|
// Inject `isNativeTag`
|
|
// this is used for component name validation (dev only)
|
|
Object.defineProperty(app.config, 'isNativeTag', {
|
|
value: (tag) => (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isHTMLTag)(tag) || (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isSVGTag)(tag),
|
|
writable: false
|
|
});
|
|
}
|
|
// dev only
|
|
function injectCompilerOptionsCheck(app) {
|
|
if ((0,_vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.isRuntimeOnly)()) {
|
|
const isCustomElement = app.config.isCustomElement;
|
|
Object.defineProperty(app.config, 'isCustomElement', {
|
|
get() {
|
|
return isCustomElement;
|
|
},
|
|
set() {
|
|
(0,_vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.warn)(`The \`isCustomElement\` config option is deprecated. Use ` +
|
|
`\`compilerOptions.isCustomElement\` instead.`);
|
|
}
|
|
});
|
|
const compilerOptions = app.config.compilerOptions;
|
|
const msg = `The \`compilerOptions\` config option is only respected when using ` +
|
|
`a build of Vue.js that includes the runtime compiler (aka "full build"). ` +
|
|
`Since you are using the runtime-only build, \`compilerOptions\` ` +
|
|
`must be passed to \`@vue/compiler-dom\` in the build setup instead.\n` +
|
|
`- For vue-loader: pass it via vue-loader's \`compilerOptions\` loader option.\n` +
|
|
`- For vue-cli: see https://cli.vuejs.org/guide/webpack.html#modifying-options-of-a-loader\n` +
|
|
`- For vite: pass it via @vitejs/plugin-vue options. See https://github.com/vitejs/vite/tree/main/packages/plugin-vue#example-for-passing-options-to-vuecompiler-dom`;
|
|
Object.defineProperty(app.config, 'compilerOptions', {
|
|
get() {
|
|
(0,_vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.warn)(msg);
|
|
return compilerOptions;
|
|
},
|
|
set() {
|
|
(0,_vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.warn)(msg);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
function normalizeContainer(container) {
|
|
if ((0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isString)(container)) {
|
|
const res = document.querySelector(container);
|
|
if (( true) && !res) {
|
|
(0,_vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.warn)(`Failed to mount app: mount target selector "${container}" returned null.`);
|
|
}
|
|
return res;
|
|
}
|
|
if (( true) &&
|
|
window.ShadowRoot &&
|
|
container instanceof window.ShadowRoot &&
|
|
container.mode === 'closed') {
|
|
(0,_vue_runtime_core__WEBPACK_IMPORTED_MODULE_0__.warn)(`mounting on a ShadowRoot with \`{mode: "closed"}\` may lead to unpredictable bugs`);
|
|
}
|
|
return container;
|
|
}
|
|
|
|
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/@vue/shared/dist/shared.esm-bundler.js":
|
|
/*!*************************************************************!*\
|
|
!*** ./node_modules/@vue/shared/dist/shared.esm-bundler.js ***!
|
|
\*************************************************************/
|
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ "EMPTY_ARR": () => (/* binding */ EMPTY_ARR),
|
|
/* harmony export */ "EMPTY_OBJ": () => (/* binding */ EMPTY_OBJ),
|
|
/* harmony export */ "NO": () => (/* binding */ NO),
|
|
/* harmony export */ "NOOP": () => (/* binding */ NOOP),
|
|
/* harmony export */ "PatchFlagNames": () => (/* binding */ PatchFlagNames),
|
|
/* harmony export */ "babelParserDefaultPlugins": () => (/* binding */ babelParserDefaultPlugins),
|
|
/* harmony export */ "camelize": () => (/* binding */ camelize),
|
|
/* harmony export */ "capitalize": () => (/* binding */ capitalize),
|
|
/* harmony export */ "def": () => (/* binding */ def),
|
|
/* harmony export */ "escapeHtml": () => (/* binding */ escapeHtml),
|
|
/* harmony export */ "escapeHtmlComment": () => (/* binding */ escapeHtmlComment),
|
|
/* harmony export */ "extend": () => (/* binding */ extend),
|
|
/* harmony export */ "generateCodeFrame": () => (/* binding */ generateCodeFrame),
|
|
/* harmony export */ "getGlobalThis": () => (/* binding */ getGlobalThis),
|
|
/* harmony export */ "hasChanged": () => (/* binding */ hasChanged),
|
|
/* harmony export */ "hasOwn": () => (/* binding */ hasOwn),
|
|
/* harmony export */ "hyphenate": () => (/* binding */ hyphenate),
|
|
/* harmony export */ "includeBooleanAttr": () => (/* binding */ includeBooleanAttr),
|
|
/* harmony export */ "invokeArrayFns": () => (/* binding */ invokeArrayFns),
|
|
/* harmony export */ "isArray": () => (/* binding */ isArray),
|
|
/* harmony export */ "isBooleanAttr": () => (/* binding */ isBooleanAttr),
|
|
/* harmony export */ "isDate": () => (/* binding */ isDate),
|
|
/* harmony export */ "isFunction": () => (/* binding */ isFunction),
|
|
/* harmony export */ "isGloballyWhitelisted": () => (/* binding */ isGloballyWhitelisted),
|
|
/* harmony export */ "isHTMLTag": () => (/* binding */ isHTMLTag),
|
|
/* harmony export */ "isIntegerKey": () => (/* binding */ isIntegerKey),
|
|
/* harmony export */ "isKnownHtmlAttr": () => (/* binding */ isKnownHtmlAttr),
|
|
/* harmony export */ "isKnownSvgAttr": () => (/* binding */ isKnownSvgAttr),
|
|
/* harmony export */ "isMap": () => (/* binding */ isMap),
|
|
/* harmony export */ "isModelListener": () => (/* binding */ isModelListener),
|
|
/* harmony export */ "isNoUnitNumericStyleProp": () => (/* binding */ isNoUnitNumericStyleProp),
|
|
/* harmony export */ "isObject": () => (/* binding */ isObject),
|
|
/* harmony export */ "isOn": () => (/* binding */ isOn),
|
|
/* harmony export */ "isPlainObject": () => (/* binding */ isPlainObject),
|
|
/* harmony export */ "isPromise": () => (/* binding */ isPromise),
|
|
/* harmony export */ "isReservedProp": () => (/* binding */ isReservedProp),
|
|
/* harmony export */ "isSSRSafeAttrName": () => (/* binding */ isSSRSafeAttrName),
|
|
/* harmony export */ "isSVGTag": () => (/* binding */ isSVGTag),
|
|
/* harmony export */ "isSet": () => (/* binding */ isSet),
|
|
/* harmony export */ "isSpecialBooleanAttr": () => (/* binding */ isSpecialBooleanAttr),
|
|
/* harmony export */ "isString": () => (/* binding */ isString),
|
|
/* harmony export */ "isSymbol": () => (/* binding */ isSymbol),
|
|
/* harmony export */ "isVoidTag": () => (/* binding */ isVoidTag),
|
|
/* harmony export */ "looseEqual": () => (/* binding */ looseEqual),
|
|
/* harmony export */ "looseIndexOf": () => (/* binding */ looseIndexOf),
|
|
/* harmony export */ "makeMap": () => (/* binding */ makeMap),
|
|
/* harmony export */ "normalizeClass": () => (/* binding */ normalizeClass),
|
|
/* harmony export */ "normalizeProps": () => (/* binding */ normalizeProps),
|
|
/* harmony export */ "normalizeStyle": () => (/* binding */ normalizeStyle),
|
|
/* harmony export */ "objectToString": () => (/* binding */ objectToString),
|
|
/* harmony export */ "parseStringStyle": () => (/* binding */ parseStringStyle),
|
|
/* harmony export */ "propsToAttrMap": () => (/* binding */ propsToAttrMap),
|
|
/* harmony export */ "remove": () => (/* binding */ remove),
|
|
/* harmony export */ "slotFlagsText": () => (/* binding */ slotFlagsText),
|
|
/* harmony export */ "stringifyStyle": () => (/* binding */ stringifyStyle),
|
|
/* harmony export */ "toDisplayString": () => (/* binding */ toDisplayString),
|
|
/* harmony export */ "toHandlerKey": () => (/* binding */ toHandlerKey),
|
|
/* harmony export */ "toNumber": () => (/* binding */ toNumber),
|
|
/* harmony export */ "toRawType": () => (/* binding */ toRawType),
|
|
/* harmony export */ "toTypeString": () => (/* binding */ toTypeString)
|
|
/* harmony export */ });
|
|
/**
|
|
* Make a map and return a function for checking if a key
|
|
* is in that map.
|
|
* IMPORTANT: all calls of this function must be prefixed with
|
|
* \/\*#\_\_PURE\_\_\*\/
|
|
* So that rollup can tree-shake them if necessary.
|
|
*/
|
|
function makeMap(str, expectsLowerCase) {
|
|
const map = Object.create(null);
|
|
const list = str.split(',');
|
|
for (let i = 0; i < list.length; i++) {
|
|
map[list[i]] = true;
|
|
}
|
|
return expectsLowerCase ? val => !!map[val.toLowerCase()] : val => !!map[val];
|
|
}
|
|
|
|
/**
|
|
* dev only flag -> name mapping
|
|
*/
|
|
const PatchFlagNames = {
|
|
[1 /* TEXT */]: `TEXT`,
|
|
[2 /* CLASS */]: `CLASS`,
|
|
[4 /* STYLE */]: `STYLE`,
|
|
[8 /* PROPS */]: `PROPS`,
|
|
[16 /* FULL_PROPS */]: `FULL_PROPS`,
|
|
[32 /* HYDRATE_EVENTS */]: `HYDRATE_EVENTS`,
|
|
[64 /* STABLE_FRAGMENT */]: `STABLE_FRAGMENT`,
|
|
[128 /* KEYED_FRAGMENT */]: `KEYED_FRAGMENT`,
|
|
[256 /* UNKEYED_FRAGMENT */]: `UNKEYED_FRAGMENT`,
|
|
[512 /* NEED_PATCH */]: `NEED_PATCH`,
|
|
[1024 /* DYNAMIC_SLOTS */]: `DYNAMIC_SLOTS`,
|
|
[2048 /* DEV_ROOT_FRAGMENT */]: `DEV_ROOT_FRAGMENT`,
|
|
[-1 /* HOISTED */]: `HOISTED`,
|
|
[-2 /* BAIL */]: `BAIL`
|
|
};
|
|
|
|
/**
|
|
* Dev only
|
|
*/
|
|
const slotFlagsText = {
|
|
[1 /* STABLE */]: 'STABLE',
|
|
[2 /* DYNAMIC */]: 'DYNAMIC',
|
|
[3 /* FORWARDED */]: 'FORWARDED'
|
|
};
|
|
|
|
const GLOBALS_WHITE_LISTED = 'Infinity,undefined,NaN,isFinite,isNaN,parseFloat,parseInt,decodeURI,' +
|
|
'decodeURIComponent,encodeURI,encodeURIComponent,Math,Number,Date,Array,' +
|
|
'Object,Boolean,String,RegExp,Map,Set,JSON,Intl,BigInt';
|
|
const isGloballyWhitelisted = /*#__PURE__*/ makeMap(GLOBALS_WHITE_LISTED);
|
|
|
|
const range = 2;
|
|
function generateCodeFrame(source, start = 0, end = source.length) {
|
|
// Split the content into individual lines but capture the newline sequence
|
|
// that separated each line. This is important because the actual sequence is
|
|
// needed to properly take into account the full line length for offset
|
|
// comparison
|
|
let lines = source.split(/(\r?\n)/);
|
|
// Separate the lines and newline sequences into separate arrays for easier referencing
|
|
const newlineSequences = lines.filter((_, idx) => idx % 2 === 1);
|
|
lines = lines.filter((_, idx) => idx % 2 === 0);
|
|
let count = 0;
|
|
const res = [];
|
|
for (let i = 0; i < lines.length; i++) {
|
|
count +=
|
|
lines[i].length +
|
|
((newlineSequences[i] && newlineSequences[i].length) || 0);
|
|
if (count >= start) {
|
|
for (let j = i - range; j <= i + range || end > count; j++) {
|
|
if (j < 0 || j >= lines.length)
|
|
continue;
|
|
const line = j + 1;
|
|
res.push(`${line}${' '.repeat(Math.max(3 - String(line).length, 0))}| ${lines[j]}`);
|
|
const lineLength = lines[j].length;
|
|
const newLineSeqLength = (newlineSequences[j] && newlineSequences[j].length) || 0;
|
|
if (j === i) {
|
|
// push underline
|
|
const pad = start - (count - (lineLength + newLineSeqLength));
|
|
const length = Math.max(1, end > count ? lineLength - pad : end - start);
|
|
res.push(` | ` + ' '.repeat(pad) + '^'.repeat(length));
|
|
}
|
|
else if (j > i) {
|
|
if (end > count) {
|
|
const length = Math.max(Math.min(end - count, lineLength), 1);
|
|
res.push(` | ` + '^'.repeat(length));
|
|
}
|
|
count += lineLength + newLineSeqLength;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
return res.join('\n');
|
|
}
|
|
|
|
/**
|
|
* On the client we only need to offer special cases for boolean attributes that
|
|
* have different names from their corresponding dom properties:
|
|
* - itemscope -> N/A
|
|
* - allowfullscreen -> allowFullscreen
|
|
* - formnovalidate -> formNoValidate
|
|
* - ismap -> isMap
|
|
* - nomodule -> noModule
|
|
* - novalidate -> noValidate
|
|
* - readonly -> readOnly
|
|
*/
|
|
const specialBooleanAttrs = `itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly`;
|
|
const isSpecialBooleanAttr = /*#__PURE__*/ makeMap(specialBooleanAttrs);
|
|
/**
|
|
* The full list is needed during SSR to produce the correct initial markup.
|
|
*/
|
|
const isBooleanAttr = /*#__PURE__*/ makeMap(specialBooleanAttrs +
|
|
`,async,autofocus,autoplay,controls,default,defer,disabled,hidden,` +
|
|
`loop,open,required,reversed,scoped,seamless,` +
|
|
`checked,muted,multiple,selected`);
|
|
/**
|
|
* Boolean attributes should be included if the value is truthy or ''.
|
|
* e.g. <select multiple> compiles to { multiple: '' }
|
|
*/
|
|
function includeBooleanAttr(value) {
|
|
return !!value || value === '';
|
|
}
|
|
const unsafeAttrCharRE = /[>/="'\u0009\u000a\u000c\u0020]/;
|
|
const attrValidationCache = {};
|
|
function isSSRSafeAttrName(name) {
|
|
if (attrValidationCache.hasOwnProperty(name)) {
|
|
return attrValidationCache[name];
|
|
}
|
|
const isUnsafe = unsafeAttrCharRE.test(name);
|
|
if (isUnsafe) {
|
|
console.error(`unsafe attribute name: ${name}`);
|
|
}
|
|
return (attrValidationCache[name] = !isUnsafe);
|
|
}
|
|
const propsToAttrMap = {
|
|
acceptCharset: 'accept-charset',
|
|
className: 'class',
|
|
htmlFor: 'for',
|
|
httpEquiv: 'http-equiv'
|
|
};
|
|
/**
|
|
* CSS properties that accept plain numbers
|
|
*/
|
|
const isNoUnitNumericStyleProp = /*#__PURE__*/ makeMap(`animation-iteration-count,border-image-outset,border-image-slice,` +
|
|
`border-image-width,box-flex,box-flex-group,box-ordinal-group,column-count,` +
|
|
`columns,flex,flex-grow,flex-positive,flex-shrink,flex-negative,flex-order,` +
|
|
`grid-row,grid-row-end,grid-row-span,grid-row-start,grid-column,` +
|
|
`grid-column-end,grid-column-span,grid-column-start,font-weight,line-clamp,` +
|
|
`line-height,opacity,order,orphans,tab-size,widows,z-index,zoom,` +
|
|
// SVG
|
|
`fill-opacity,flood-opacity,stop-opacity,stroke-dasharray,stroke-dashoffset,` +
|
|
`stroke-miterlimit,stroke-opacity,stroke-width`);
|
|
/**
|
|
* Known attributes, this is used for stringification of runtime static nodes
|
|
* so that we don't stringify bindings that cannot be set from HTML.
|
|
* Don't also forget to allow `data-*` and `aria-*`!
|
|
* Generated from https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes
|
|
*/
|
|
const isKnownHtmlAttr = /*#__PURE__*/ makeMap(`accept,accept-charset,accesskey,action,align,allow,alt,async,` +
|
|
`autocapitalize,autocomplete,autofocus,autoplay,background,bgcolor,` +
|
|
`border,buffered,capture,challenge,charset,checked,cite,class,code,` +
|
|
`codebase,color,cols,colspan,content,contenteditable,contextmenu,controls,` +
|
|
`coords,crossorigin,csp,data,datetime,decoding,default,defer,dir,dirname,` +
|
|
`disabled,download,draggable,dropzone,enctype,enterkeyhint,for,form,` +
|
|
`formaction,formenctype,formmethod,formnovalidate,formtarget,headers,` +
|
|
`height,hidden,high,href,hreflang,http-equiv,icon,id,importance,integrity,` +
|
|
`ismap,itemprop,keytype,kind,label,lang,language,loading,list,loop,low,` +
|
|
`manifest,max,maxlength,minlength,media,min,multiple,muted,name,novalidate,` +
|
|
`open,optimum,pattern,ping,placeholder,poster,preload,radiogroup,readonly,` +
|
|
`referrerpolicy,rel,required,reversed,rows,rowspan,sandbox,scope,scoped,` +
|
|
`selected,shape,size,sizes,slot,span,spellcheck,src,srcdoc,srclang,srcset,` +
|
|
`start,step,style,summary,tabindex,target,title,translate,type,usemap,` +
|
|
`value,width,wrap`);
|
|
/**
|
|
* Generated from https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute
|
|
*/
|
|
const isKnownSvgAttr = /*#__PURE__*/ makeMap(`xmlns,accent-height,accumulate,additive,alignment-baseline,alphabetic,amplitude,` +
|
|
`arabic-form,ascent,attributeName,attributeType,azimuth,baseFrequency,` +
|
|
`baseline-shift,baseProfile,bbox,begin,bias,by,calcMode,cap-height,class,` +
|
|
`clip,clipPathUnits,clip-path,clip-rule,color,color-interpolation,` +
|
|
`color-interpolation-filters,color-profile,color-rendering,` +
|
|
`contentScriptType,contentStyleType,crossorigin,cursor,cx,cy,d,decelerate,` +
|
|
`descent,diffuseConstant,direction,display,divisor,dominant-baseline,dur,dx,` +
|
|
`dy,edgeMode,elevation,enable-background,end,exponent,fill,fill-opacity,` +
|
|
`fill-rule,filter,filterRes,filterUnits,flood-color,flood-opacity,` +
|
|
`font-family,font-size,font-size-adjust,font-stretch,font-style,` +
|
|
`font-variant,font-weight,format,from,fr,fx,fy,g1,g2,glyph-name,` +
|
|
`glyph-orientation-horizontal,glyph-orientation-vertical,glyphRef,` +
|
|
`gradientTransform,gradientUnits,hanging,height,href,hreflang,horiz-adv-x,` +
|
|
`horiz-origin-x,id,ideographic,image-rendering,in,in2,intercept,k,k1,k2,k3,` +
|
|
`k4,kernelMatrix,kernelUnitLength,kerning,keyPoints,keySplines,keyTimes,` +
|
|
`lang,lengthAdjust,letter-spacing,lighting-color,limitingConeAngle,local,` +
|
|
`marker-end,marker-mid,marker-start,markerHeight,markerUnits,markerWidth,` +
|
|
`mask,maskContentUnits,maskUnits,mathematical,max,media,method,min,mode,` +
|
|
`name,numOctaves,offset,opacity,operator,order,orient,orientation,origin,` +
|
|
`overflow,overline-position,overline-thickness,panose-1,paint-order,path,` +
|
|
`pathLength,patternContentUnits,patternTransform,patternUnits,ping,` +
|
|
`pointer-events,points,pointsAtX,pointsAtY,pointsAtZ,preserveAlpha,` +
|
|
`preserveAspectRatio,primitiveUnits,r,radius,referrerPolicy,refX,refY,rel,` +
|
|
`rendering-intent,repeatCount,repeatDur,requiredExtensions,requiredFeatures,` +
|
|
`restart,result,rotate,rx,ry,scale,seed,shape-rendering,slope,spacing,` +
|
|
`specularConstant,specularExponent,speed,spreadMethod,startOffset,` +
|
|
`stdDeviation,stemh,stemv,stitchTiles,stop-color,stop-opacity,` +
|
|
`strikethrough-position,strikethrough-thickness,string,stroke,` +
|
|
`stroke-dasharray,stroke-dashoffset,stroke-linecap,stroke-linejoin,` +
|
|
`stroke-miterlimit,stroke-opacity,stroke-width,style,surfaceScale,` +
|
|
`systemLanguage,tabindex,tableValues,target,targetX,targetY,text-anchor,` +
|
|
`text-decoration,text-rendering,textLength,to,transform,transform-origin,` +
|
|
`type,u1,u2,underline-position,underline-thickness,unicode,unicode-bidi,` +
|
|
`unicode-range,units-per-em,v-alphabetic,v-hanging,v-ideographic,` +
|
|
`v-mathematical,values,vector-effect,version,vert-adv-y,vert-origin-x,` +
|
|
`vert-origin-y,viewBox,viewTarget,visibility,width,widths,word-spacing,` +
|
|
`writing-mode,x,x-height,x1,x2,xChannelSelector,xlink:actuate,xlink:arcrole,` +
|
|
`xlink:href,xlink:role,xlink:show,xlink:title,xlink:type,xml:base,xml:lang,` +
|
|
`xml:space,y,y1,y2,yChannelSelector,z,zoomAndPan`);
|
|
|
|
function normalizeStyle(value) {
|
|
if (isArray(value)) {
|
|
const res = {};
|
|
for (let i = 0; i < value.length; i++) {
|
|
const item = value[i];
|
|
const normalized = isString(item)
|
|
? parseStringStyle(item)
|
|
: normalizeStyle(item);
|
|
if (normalized) {
|
|
for (const key in normalized) {
|
|
res[key] = normalized[key];
|
|
}
|
|
}
|
|
}
|
|
return res;
|
|
}
|
|
else if (isString(value)) {
|
|
return value;
|
|
}
|
|
else if (isObject(value)) {
|
|
return value;
|
|
}
|
|
}
|
|
const listDelimiterRE = /;(?![^(]*\))/g;
|
|
const propertyDelimiterRE = /:(.+)/;
|
|
function parseStringStyle(cssText) {
|
|
const ret = {};
|
|
cssText.split(listDelimiterRE).forEach(item => {
|
|
if (item) {
|
|
const tmp = item.split(propertyDelimiterRE);
|
|
tmp.length > 1 && (ret[tmp[0].trim()] = tmp[1].trim());
|
|
}
|
|
});
|
|
return ret;
|
|
}
|
|
function stringifyStyle(styles) {
|
|
let ret = '';
|
|
if (!styles || isString(styles)) {
|
|
return ret;
|
|
}
|
|
for (const key in styles) {
|
|
const value = styles[key];
|
|
const normalizedKey = key.startsWith(`--`) ? key : hyphenate(key);
|
|
if (isString(value) ||
|
|
(typeof value === 'number' && isNoUnitNumericStyleProp(normalizedKey))) {
|
|
// only render valid values
|
|
ret += `${normalizedKey}:${value};`;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
function normalizeClass(value) {
|
|
let res = '';
|
|
if (isString(value)) {
|
|
res = value;
|
|
}
|
|
else if (isArray(value)) {
|
|
for (let i = 0; i < value.length; i++) {
|
|
const normalized = normalizeClass(value[i]);
|
|
if (normalized) {
|
|
res += normalized + ' ';
|
|
}
|
|
}
|
|
}
|
|
else if (isObject(value)) {
|
|
for (const name in value) {
|
|
if (value[name]) {
|
|
res += name + ' ';
|
|
}
|
|
}
|
|
}
|
|
return res.trim();
|
|
}
|
|
function normalizeProps(props) {
|
|
if (!props)
|
|
return null;
|
|
let { class: klass, style } = props;
|
|
if (klass && !isString(klass)) {
|
|
props.class = normalizeClass(klass);
|
|
}
|
|
if (style) {
|
|
props.style = normalizeStyle(style);
|
|
}
|
|
return props;
|
|
}
|
|
|
|
// These tag configs are shared between compiler-dom and runtime-dom, so they
|
|
// https://developer.mozilla.org/en-US/docs/Web/HTML/Element
|
|
const HTML_TAGS = 'html,body,base,head,link,meta,style,title,address,article,aside,footer,' +
|
|
'header,h1,h2,h3,h4,h5,h6,nav,section,div,dd,dl,dt,figcaption,' +
|
|
'figure,picture,hr,img,li,main,ol,p,pre,ul,a,b,abbr,bdi,bdo,br,cite,code,' +
|
|
'data,dfn,em,i,kbd,mark,q,rp,rt,ruby,s,samp,small,span,strong,sub,sup,' +
|
|
'time,u,var,wbr,area,audio,map,track,video,embed,object,param,source,' +
|
|
'canvas,script,noscript,del,ins,caption,col,colgroup,table,thead,tbody,td,' +
|
|
'th,tr,button,datalist,fieldset,form,input,label,legend,meter,optgroup,' +
|
|
'option,output,progress,select,textarea,details,dialog,menu,' +
|
|
'summary,template,blockquote,iframe,tfoot';
|
|
// https://developer.mozilla.org/en-US/docs/Web/SVG/Element
|
|
const SVG_TAGS = 'svg,animate,animateMotion,animateTransform,circle,clipPath,color-profile,' +
|
|
'defs,desc,discard,ellipse,feBlend,feColorMatrix,feComponentTransfer,' +
|
|
'feComposite,feConvolveMatrix,feDiffuseLighting,feDisplacementMap,' +
|
|
'feDistanceLight,feDropShadow,feFlood,feFuncA,feFuncB,feFuncG,feFuncR,' +
|
|
'feGaussianBlur,feImage,feMerge,feMergeNode,feMorphology,feOffset,' +
|
|
'fePointLight,feSpecularLighting,feSpotLight,feTile,feTurbulence,filter,' +
|
|
'foreignObject,g,hatch,hatchpath,image,line,linearGradient,marker,mask,' +
|
|
'mesh,meshgradient,meshpatch,meshrow,metadata,mpath,path,pattern,' +
|
|
'polygon,polyline,radialGradient,rect,set,solidcolor,stop,switch,symbol,' +
|
|
'text,textPath,title,tspan,unknown,use,view';
|
|
const VOID_TAGS = 'area,base,br,col,embed,hr,img,input,link,meta,param,source,track,wbr';
|
|
const isHTMLTag = /*#__PURE__*/ makeMap(HTML_TAGS);
|
|
const isSVGTag = /*#__PURE__*/ makeMap(SVG_TAGS);
|
|
const isVoidTag = /*#__PURE__*/ makeMap(VOID_TAGS);
|
|
|
|
const escapeRE = /["'&<>]/;
|
|
function escapeHtml(string) {
|
|
const str = '' + string;
|
|
const match = escapeRE.exec(str);
|
|
if (!match) {
|
|
return str;
|
|
}
|
|
let html = '';
|
|
let escaped;
|
|
let index;
|
|
let lastIndex = 0;
|
|
for (index = match.index; index < str.length; index++) {
|
|
switch (str.charCodeAt(index)) {
|
|
case 34: // "
|
|
escaped = '"';
|
|
break;
|
|
case 38: // &
|
|
escaped = '&';
|
|
break;
|
|
case 39: // '
|
|
escaped = ''';
|
|
break;
|
|
case 60: // <
|
|
escaped = '<';
|
|
break;
|
|
case 62: // >
|
|
escaped = '>';
|
|
break;
|
|
default:
|
|
continue;
|
|
}
|
|
if (lastIndex !== index) {
|
|
html += str.substring(lastIndex, index);
|
|
}
|
|
lastIndex = index + 1;
|
|
html += escaped;
|
|
}
|
|
return lastIndex !== index ? html + str.substring(lastIndex, index) : html;
|
|
}
|
|
// https://www.w3.org/TR/html52/syntax.html#comments
|
|
const commentStripRE = /^-?>|<!--|-->|--!>|<!-$/g;
|
|
function escapeHtmlComment(src) {
|
|
return src.replace(commentStripRE, '');
|
|
}
|
|
|
|
function looseCompareArrays(a, b) {
|
|
if (a.length !== b.length)
|
|
return false;
|
|
let equal = true;
|
|
for (let i = 0; equal && i < a.length; i++) {
|
|
equal = looseEqual(a[i], b[i]);
|
|
}
|
|
return equal;
|
|
}
|
|
function looseEqual(a, b) {
|
|
if (a === b)
|
|
return true;
|
|
let aValidType = isDate(a);
|
|
let bValidType = isDate(b);
|
|
if (aValidType || bValidType) {
|
|
return aValidType && bValidType ? a.getTime() === b.getTime() : false;
|
|
}
|
|
aValidType = isArray(a);
|
|
bValidType = isArray(b);
|
|
if (aValidType || bValidType) {
|
|
return aValidType && bValidType ? looseCompareArrays(a, b) : false;
|
|
}
|
|
aValidType = isObject(a);
|
|
bValidType = isObject(b);
|
|
if (aValidType || bValidType) {
|
|
/* istanbul ignore if: this if will probably never be called */
|
|
if (!aValidType || !bValidType) {
|
|
return false;
|
|
}
|
|
const aKeysCount = Object.keys(a).length;
|
|
const bKeysCount = Object.keys(b).length;
|
|
if (aKeysCount !== bKeysCount) {
|
|
return false;
|
|
}
|
|
for (const key in a) {
|
|
const aHasKey = a.hasOwnProperty(key);
|
|
const bHasKey = b.hasOwnProperty(key);
|
|
if ((aHasKey && !bHasKey) ||
|
|
(!aHasKey && bHasKey) ||
|
|
!looseEqual(a[key], b[key])) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
return String(a) === String(b);
|
|
}
|
|
function looseIndexOf(arr, val) {
|
|
return arr.findIndex(item => looseEqual(item, val));
|
|
}
|
|
|
|
/**
|
|
* For converting {{ interpolation }} values to displayed strings.
|
|
* @private
|
|
*/
|
|
const toDisplayString = (val) => {
|
|
return val == null
|
|
? ''
|
|
: isArray(val) ||
|
|
(isObject(val) &&
|
|
(val.toString === objectToString || !isFunction(val.toString)))
|
|
? JSON.stringify(val, replacer, 2)
|
|
: String(val);
|
|
};
|
|
const replacer = (_key, val) => {
|
|
// can't use isRef here since @vue/shared has no deps
|
|
if (val && val.__v_isRef) {
|
|
return replacer(_key, val.value);
|
|
}
|
|
else if (isMap(val)) {
|
|
return {
|
|
[`Map(${val.size})`]: [...val.entries()].reduce((entries, [key, val]) => {
|
|
entries[`${key} =>`] = val;
|
|
return entries;
|
|
}, {})
|
|
};
|
|
}
|
|
else if (isSet(val)) {
|
|
return {
|
|
[`Set(${val.size})`]: [...val.values()]
|
|
};
|
|
}
|
|
else if (isObject(val) && !isArray(val) && !isPlainObject(val)) {
|
|
return String(val);
|
|
}
|
|
return val;
|
|
};
|
|
|
|
/**
|
|
* List of @babel/parser plugins that are used for template expression
|
|
* transforms and SFC script transforms. By default we enable proposals slated
|
|
* for ES2020. This will need to be updated as the spec moves forward.
|
|
* Full list at https://babeljs.io/docs/en/next/babel-parser#plugins
|
|
*/
|
|
const babelParserDefaultPlugins = [
|
|
'bigInt',
|
|
'optionalChaining',
|
|
'nullishCoalescingOperator'
|
|
];
|
|
const EMPTY_OBJ = ( true)
|
|
? Object.freeze({})
|
|
: 0;
|
|
const EMPTY_ARR = ( true) ? Object.freeze([]) : 0;
|
|
const NOOP = () => { };
|
|
/**
|
|
* Always return false.
|
|
*/
|
|
const NO = () => false;
|
|
const onRE = /^on[^a-z]/;
|
|
const isOn = (key) => onRE.test(key);
|
|
const isModelListener = (key) => key.startsWith('onUpdate:');
|
|
const extend = Object.assign;
|
|
const remove = (arr, el) => {
|
|
const i = arr.indexOf(el);
|
|
if (i > -1) {
|
|
arr.splice(i, 1);
|
|
}
|
|
};
|
|
const hasOwnProperty = Object.prototype.hasOwnProperty;
|
|
const hasOwn = (val, key) => hasOwnProperty.call(val, key);
|
|
const isArray = Array.isArray;
|
|
const isMap = (val) => toTypeString(val) === '[object Map]';
|
|
const isSet = (val) => toTypeString(val) === '[object Set]';
|
|
const isDate = (val) => val instanceof Date;
|
|
const isFunction = (val) => typeof val === 'function';
|
|
const isString = (val) => typeof val === 'string';
|
|
const isSymbol = (val) => typeof val === 'symbol';
|
|
const isObject = (val) => val !== null && typeof val === 'object';
|
|
const isPromise = (val) => {
|
|
return isObject(val) && isFunction(val.then) && isFunction(val.catch);
|
|
};
|
|
const objectToString = Object.prototype.toString;
|
|
const toTypeString = (value) => objectToString.call(value);
|
|
const toRawType = (value) => {
|
|
// extract "RawType" from strings like "[object RawType]"
|
|
return toTypeString(value).slice(8, -1);
|
|
};
|
|
const isPlainObject = (val) => toTypeString(val) === '[object Object]';
|
|
const isIntegerKey = (key) => isString(key) &&
|
|
key !== 'NaN' &&
|
|
key[0] !== '-' &&
|
|
'' + parseInt(key, 10) === key;
|
|
const isReservedProp = /*#__PURE__*/ makeMap(
|
|
// the leading comma is intentional so empty string "" is also included
|
|
',key,ref,' +
|
|
'onVnodeBeforeMount,onVnodeMounted,' +
|
|
'onVnodeBeforeUpdate,onVnodeUpdated,' +
|
|
'onVnodeBeforeUnmount,onVnodeUnmounted');
|
|
const cacheStringFunction = (fn) => {
|
|
const cache = Object.create(null);
|
|
return ((str) => {
|
|
const hit = cache[str];
|
|
return hit || (cache[str] = fn(str));
|
|
});
|
|
};
|
|
const camelizeRE = /-(\w)/g;
|
|
/**
|
|
* @private
|
|
*/
|
|
const camelize = cacheStringFunction((str) => {
|
|
return str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : ''));
|
|
});
|
|
const hyphenateRE = /\B([A-Z])/g;
|
|
/**
|
|
* @private
|
|
*/
|
|
const hyphenate = cacheStringFunction((str) => str.replace(hyphenateRE, '-$1').toLowerCase());
|
|
/**
|
|
* @private
|
|
*/
|
|
const capitalize = cacheStringFunction((str) => str.charAt(0).toUpperCase() + str.slice(1));
|
|
/**
|
|
* @private
|
|
*/
|
|
const toHandlerKey = cacheStringFunction((str) => str ? `on${capitalize(str)}` : ``);
|
|
// compare whether a value has changed, accounting for NaN.
|
|
const hasChanged = (value, oldValue) => !Object.is(value, oldValue);
|
|
const invokeArrayFns = (fns, arg) => {
|
|
for (let i = 0; i < fns.length; i++) {
|
|
fns[i](arg);
|
|
}
|
|
};
|
|
const def = (obj, key, value) => {
|
|
Object.defineProperty(obj, key, {
|
|
configurable: true,
|
|
enumerable: false,
|
|
value
|
|
});
|
|
};
|
|
const toNumber = (val) => {
|
|
const n = parseFloat(val);
|
|
return isNaN(n) ? val : n;
|
|
};
|
|
let _globalThis;
|
|
const getGlobalThis = () => {
|
|
return (_globalThis ||
|
|
(_globalThis =
|
|
typeof globalThis !== 'undefined'
|
|
? globalThis
|
|
: typeof self !== 'undefined'
|
|
? self
|
|
: typeof window !== 'undefined'
|
|
? window
|
|
: typeof __webpack_require__.g !== 'undefined'
|
|
? __webpack_require__.g
|
|
: {}));
|
|
};
|
|
|
|
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/axios/index.js":
|
|
/*!*************************************!*\
|
|
!*** ./node_modules/axios/index.js ***!
|
|
\*************************************/
|
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
|
|
module.exports = __webpack_require__(/*! ./lib/axios */ "./node_modules/axios/lib/axios.js");
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/axios/lib/adapters/xhr.js":
|
|
/*!************************************************!*\
|
|
!*** ./node_modules/axios/lib/adapters/xhr.js ***!
|
|
\************************************************/
|
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
|
|
|
|
var utils = __webpack_require__(/*! ./../utils */ "./node_modules/axios/lib/utils.js");
|
|
var settle = __webpack_require__(/*! ./../core/settle */ "./node_modules/axios/lib/core/settle.js");
|
|
var cookies = __webpack_require__(/*! ./../helpers/cookies */ "./node_modules/axios/lib/helpers/cookies.js");
|
|
var buildURL = __webpack_require__(/*! ./../helpers/buildURL */ "./node_modules/axios/lib/helpers/buildURL.js");
|
|
var buildFullPath = __webpack_require__(/*! ../core/buildFullPath */ "./node_modules/axios/lib/core/buildFullPath.js");
|
|
var parseHeaders = __webpack_require__(/*! ./../helpers/parseHeaders */ "./node_modules/axios/lib/helpers/parseHeaders.js");
|
|
var isURLSameOrigin = __webpack_require__(/*! ./../helpers/isURLSameOrigin */ "./node_modules/axios/lib/helpers/isURLSameOrigin.js");
|
|
var createError = __webpack_require__(/*! ../core/createError */ "./node_modules/axios/lib/core/createError.js");
|
|
|
|
module.exports = function xhrAdapter(config) {
|
|
return new Promise(function dispatchXhrRequest(resolve, reject) {
|
|
var requestData = config.data;
|
|
var requestHeaders = config.headers;
|
|
|
|
if (utils.isFormData(requestData)) {
|
|
delete requestHeaders['Content-Type']; // Let the browser set it
|
|
}
|
|
|
|
var request = new XMLHttpRequest();
|
|
|
|
// HTTP basic authentication
|
|
if (config.auth) {
|
|
var username = config.auth.username || '';
|
|
var password = config.auth.password ? unescape(encodeURIComponent(config.auth.password)) : '';
|
|
requestHeaders.Authorization = 'Basic ' + btoa(username + ':' + password);
|
|
}
|
|
|
|
var fullPath = buildFullPath(config.baseURL, config.url);
|
|
request.open(config.method.toUpperCase(), buildURL(fullPath, config.params, config.paramsSerializer), true);
|
|
|
|
// Set the request timeout in MS
|
|
request.timeout = config.timeout;
|
|
|
|
// Listen for ready state
|
|
request.onreadystatechange = function handleLoad() {
|
|
if (!request || request.readyState !== 4) {
|
|
return;
|
|
}
|
|
|
|
// The request errored out and we didn't get a response, this will be
|
|
// handled by onerror instead
|
|
// With one exception: request that using file: protocol, most browsers
|
|
// will return status as 0 even though it's a successful request
|
|
if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf('file:') === 0)) {
|
|
return;
|
|
}
|
|
|
|
// Prepare the response
|
|
var responseHeaders = 'getAllResponseHeaders' in request ? parseHeaders(request.getAllResponseHeaders()) : null;
|
|
var responseData = !config.responseType || config.responseType === 'text' ? request.responseText : request.response;
|
|
var response = {
|
|
data: responseData,
|
|
status: request.status,
|
|
statusText: request.statusText,
|
|
headers: responseHeaders,
|
|
config: config,
|
|
request: request
|
|
};
|
|
|
|
settle(resolve, reject, response);
|
|
|
|
// Clean up request
|
|
request = null;
|
|
};
|
|
|
|
// Handle browser request cancellation (as opposed to a manual cancellation)
|
|
request.onabort = function handleAbort() {
|
|
if (!request) {
|
|
return;
|
|
}
|
|
|
|
reject(createError('Request aborted', config, 'ECONNABORTED', request));
|
|
|
|
// Clean up request
|
|
request = null;
|
|
};
|
|
|
|
// Handle low level network errors
|
|
request.onerror = function handleError() {
|
|
// Real errors are hidden from us by the browser
|
|
// onerror should only fire if it's a network error
|
|
reject(createError('Network Error', config, null, request));
|
|
|
|
// Clean up request
|
|
request = null;
|
|
};
|
|
|
|
// Handle timeout
|
|
request.ontimeout = function handleTimeout() {
|
|
var timeoutErrorMessage = 'timeout of ' + config.timeout + 'ms exceeded';
|
|
if (config.timeoutErrorMessage) {
|
|
timeoutErrorMessage = config.timeoutErrorMessage;
|
|
}
|
|
reject(createError(timeoutErrorMessage, config, 'ECONNABORTED',
|
|
request));
|
|
|
|
// Clean up request
|
|
request = null;
|
|
};
|
|
|
|
// Add xsrf header
|
|
// This is only done if running in a standard browser environment.
|
|
// Specifically not if we're in a web worker, or react-native.
|
|
if (utils.isStandardBrowserEnv()) {
|
|
// Add xsrf header
|
|
var xsrfValue = (config.withCredentials || isURLSameOrigin(fullPath)) && config.xsrfCookieName ?
|
|
cookies.read(config.xsrfCookieName) :
|
|
undefined;
|
|
|
|
if (xsrfValue) {
|
|
requestHeaders[config.xsrfHeaderName] = xsrfValue;
|
|
}
|
|
}
|
|
|
|
// Add headers to the request
|
|
if ('setRequestHeader' in request) {
|
|
utils.forEach(requestHeaders, function setRequestHeader(val, key) {
|
|
if (typeof requestData === 'undefined' && key.toLowerCase() === 'content-type') {
|
|
// Remove Content-Type if data is undefined
|
|
delete requestHeaders[key];
|
|
} else {
|
|
// Otherwise add header to the request
|
|
request.setRequestHeader(key, val);
|
|
}
|
|
});
|
|
}
|
|
|
|
// Add withCredentials to request if needed
|
|
if (!utils.isUndefined(config.withCredentials)) {
|
|
request.withCredentials = !!config.withCredentials;
|
|
}
|
|
|
|
// Add responseType to request if needed
|
|
if (config.responseType) {
|
|
try {
|
|
request.responseType = config.responseType;
|
|
} catch (e) {
|
|
// Expected DOMException thrown by browsers not compatible XMLHttpRequest Level 2.
|
|
// But, this can be suppressed for 'json' type as it can be parsed by default 'transformResponse' function.
|
|
if (config.responseType !== 'json') {
|
|
throw e;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Handle progress if needed
|
|
if (typeof config.onDownloadProgress === 'function') {
|
|
request.addEventListener('progress', config.onDownloadProgress);
|
|
}
|
|
|
|
// Not all browsers support upload events
|
|
if (typeof config.onUploadProgress === 'function' && request.upload) {
|
|
request.upload.addEventListener('progress', config.onUploadProgress);
|
|
}
|
|
|
|
if (config.cancelToken) {
|
|
// Handle cancellation
|
|
config.cancelToken.promise.then(function onCanceled(cancel) {
|
|
if (!request) {
|
|
return;
|
|
}
|
|
|
|
request.abort();
|
|
reject(cancel);
|
|
// Clean up request
|
|
request = null;
|
|
});
|
|
}
|
|
|
|
if (!requestData) {
|
|
requestData = null;
|
|
}
|
|
|
|
// Send the request
|
|
request.send(requestData);
|
|
});
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/axios/lib/axios.js":
|
|
/*!*****************************************!*\
|
|
!*** ./node_modules/axios/lib/axios.js ***!
|
|
\*****************************************/
|
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
|
|
|
|
var utils = __webpack_require__(/*! ./utils */ "./node_modules/axios/lib/utils.js");
|
|
var bind = __webpack_require__(/*! ./helpers/bind */ "./node_modules/axios/lib/helpers/bind.js");
|
|
var Axios = __webpack_require__(/*! ./core/Axios */ "./node_modules/axios/lib/core/Axios.js");
|
|
var mergeConfig = __webpack_require__(/*! ./core/mergeConfig */ "./node_modules/axios/lib/core/mergeConfig.js");
|
|
var defaults = __webpack_require__(/*! ./defaults */ "./node_modules/axios/lib/defaults.js");
|
|
|
|
/**
|
|
* Create an instance of Axios
|
|
*
|
|
* @param {Object} defaultConfig The default config for the instance
|
|
* @return {Axios} A new instance of Axios
|
|
*/
|
|
function createInstance(defaultConfig) {
|
|
var context = new Axios(defaultConfig);
|
|
var instance = bind(Axios.prototype.request, context);
|
|
|
|
// Copy axios.prototype to instance
|
|
utils.extend(instance, Axios.prototype, context);
|
|
|
|
// Copy context to instance
|
|
utils.extend(instance, context);
|
|
|
|
return instance;
|
|
}
|
|
|
|
// Create the default instance to be exported
|
|
var axios = createInstance(defaults);
|
|
|
|
// Expose Axios class to allow class inheritance
|
|
axios.Axios = Axios;
|
|
|
|
// Factory for creating new instances
|
|
axios.create = function create(instanceConfig) {
|
|
return createInstance(mergeConfig(axios.defaults, instanceConfig));
|
|
};
|
|
|
|
// Expose Cancel & CancelToken
|
|
axios.Cancel = __webpack_require__(/*! ./cancel/Cancel */ "./node_modules/axios/lib/cancel/Cancel.js");
|
|
axios.CancelToken = __webpack_require__(/*! ./cancel/CancelToken */ "./node_modules/axios/lib/cancel/CancelToken.js");
|
|
axios.isCancel = __webpack_require__(/*! ./cancel/isCancel */ "./node_modules/axios/lib/cancel/isCancel.js");
|
|
|
|
// Expose all/spread
|
|
axios.all = function all(promises) {
|
|
return Promise.all(promises);
|
|
};
|
|
axios.spread = __webpack_require__(/*! ./helpers/spread */ "./node_modules/axios/lib/helpers/spread.js");
|
|
|
|
// Expose isAxiosError
|
|
axios.isAxiosError = __webpack_require__(/*! ./helpers/isAxiosError */ "./node_modules/axios/lib/helpers/isAxiosError.js");
|
|
|
|
module.exports = axios;
|
|
|
|
// Allow use of default import syntax in TypeScript
|
|
module.exports.default = axios;
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/axios/lib/cancel/Cancel.js":
|
|
/*!*************************************************!*\
|
|
!*** ./node_modules/axios/lib/cancel/Cancel.js ***!
|
|
\*************************************************/
|
|
/***/ ((module) => {
|
|
|
|
"use strict";
|
|
|
|
|
|
/**
|
|
* A `Cancel` is an object that is thrown when an operation is canceled.
|
|
*
|
|
* @class
|
|
* @param {string=} message The message.
|
|
*/
|
|
function Cancel(message) {
|
|
this.message = message;
|
|
}
|
|
|
|
Cancel.prototype.toString = function toString() {
|
|
return 'Cancel' + (this.message ? ': ' + this.message : '');
|
|
};
|
|
|
|
Cancel.prototype.__CANCEL__ = true;
|
|
|
|
module.exports = Cancel;
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/axios/lib/cancel/CancelToken.js":
|
|
/*!******************************************************!*\
|
|
!*** ./node_modules/axios/lib/cancel/CancelToken.js ***!
|
|
\******************************************************/
|
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
|
|
|
|
var Cancel = __webpack_require__(/*! ./Cancel */ "./node_modules/axios/lib/cancel/Cancel.js");
|
|
|
|
/**
|
|
* A `CancelToken` is an object that can be used to request cancellation of an operation.
|
|
*
|
|
* @class
|
|
* @param {Function} executor The executor function.
|
|
*/
|
|
function CancelToken(executor) {
|
|
if (typeof executor !== 'function') {
|
|
throw new TypeError('executor must be a function.');
|
|
}
|
|
|
|
var resolvePromise;
|
|
this.promise = new Promise(function promiseExecutor(resolve) {
|
|
resolvePromise = resolve;
|
|
});
|
|
|
|
var token = this;
|
|
executor(function cancel(message) {
|
|
if (token.reason) {
|
|
// Cancellation has already been requested
|
|
return;
|
|
}
|
|
|
|
token.reason = new Cancel(message);
|
|
resolvePromise(token.reason);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Throws a `Cancel` if cancellation has been requested.
|
|
*/
|
|
CancelToken.prototype.throwIfRequested = function throwIfRequested() {
|
|
if (this.reason) {
|
|
throw this.reason;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Returns an object that contains a new `CancelToken` and a function that, when called,
|
|
* cancels the `CancelToken`.
|
|
*/
|
|
CancelToken.source = function source() {
|
|
var cancel;
|
|
var token = new CancelToken(function executor(c) {
|
|
cancel = c;
|
|
});
|
|
return {
|
|
token: token,
|
|
cancel: cancel
|
|
};
|
|
};
|
|
|
|
module.exports = CancelToken;
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/axios/lib/cancel/isCancel.js":
|
|
/*!***************************************************!*\
|
|
!*** ./node_modules/axios/lib/cancel/isCancel.js ***!
|
|
\***************************************************/
|
|
/***/ ((module) => {
|
|
|
|
"use strict";
|
|
|
|
|
|
module.exports = function isCancel(value) {
|
|
return !!(value && value.__CANCEL__);
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/axios/lib/core/Axios.js":
|
|
/*!**********************************************!*\
|
|
!*** ./node_modules/axios/lib/core/Axios.js ***!
|
|
\**********************************************/
|
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
|
|
|
|
var utils = __webpack_require__(/*! ./../utils */ "./node_modules/axios/lib/utils.js");
|
|
var buildURL = __webpack_require__(/*! ../helpers/buildURL */ "./node_modules/axios/lib/helpers/buildURL.js");
|
|
var InterceptorManager = __webpack_require__(/*! ./InterceptorManager */ "./node_modules/axios/lib/core/InterceptorManager.js");
|
|
var dispatchRequest = __webpack_require__(/*! ./dispatchRequest */ "./node_modules/axios/lib/core/dispatchRequest.js");
|
|
var mergeConfig = __webpack_require__(/*! ./mergeConfig */ "./node_modules/axios/lib/core/mergeConfig.js");
|
|
|
|
/**
|
|
* Create a new instance of Axios
|
|
*
|
|
* @param {Object} instanceConfig The default config for the instance
|
|
*/
|
|
function Axios(instanceConfig) {
|
|
this.defaults = instanceConfig;
|
|
this.interceptors = {
|
|
request: new InterceptorManager(),
|
|
response: new InterceptorManager()
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Dispatch a request
|
|
*
|
|
* @param {Object} config The config specific for this request (merged with this.defaults)
|
|
*/
|
|
Axios.prototype.request = function request(config) {
|
|
/*eslint no-param-reassign:0*/
|
|
// Allow for axios('example/url'[, config]) a la fetch API
|
|
if (typeof config === 'string') {
|
|
config = arguments[1] || {};
|
|
config.url = arguments[0];
|
|
} else {
|
|
config = config || {};
|
|
}
|
|
|
|
config = mergeConfig(this.defaults, config);
|
|
|
|
// Set config.method
|
|
if (config.method) {
|
|
config.method = config.method.toLowerCase();
|
|
} else if (this.defaults.method) {
|
|
config.method = this.defaults.method.toLowerCase();
|
|
} else {
|
|
config.method = 'get';
|
|
}
|
|
|
|
// Hook up interceptors middleware
|
|
var chain = [dispatchRequest, undefined];
|
|
var promise = Promise.resolve(config);
|
|
|
|
this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {
|
|
chain.unshift(interceptor.fulfilled, interceptor.rejected);
|
|
});
|
|
|
|
this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) {
|
|
chain.push(interceptor.fulfilled, interceptor.rejected);
|
|
});
|
|
|
|
while (chain.length) {
|
|
promise = promise.then(chain.shift(), chain.shift());
|
|
}
|
|
|
|
return promise;
|
|
};
|
|
|
|
Axios.prototype.getUri = function getUri(config) {
|
|
config = mergeConfig(this.defaults, config);
|
|
return buildURL(config.url, config.params, config.paramsSerializer).replace(/^\?/, '');
|
|
};
|
|
|
|
// Provide aliases for supported request methods
|
|
utils.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData(method) {
|
|
/*eslint func-names:0*/
|
|
Axios.prototype[method] = function(url, config) {
|
|
return this.request(mergeConfig(config || {}, {
|
|
method: method,
|
|
url: url,
|
|
data: (config || {}).data
|
|
}));
|
|
};
|
|
});
|
|
|
|
utils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {
|
|
/*eslint func-names:0*/
|
|
Axios.prototype[method] = function(url, data, config) {
|
|
return this.request(mergeConfig(config || {}, {
|
|
method: method,
|
|
url: url,
|
|
data: data
|
|
}));
|
|
};
|
|
});
|
|
|
|
module.exports = Axios;
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/axios/lib/core/InterceptorManager.js":
|
|
/*!***********************************************************!*\
|
|
!*** ./node_modules/axios/lib/core/InterceptorManager.js ***!
|
|
\***********************************************************/
|
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
|
|
|
|
var utils = __webpack_require__(/*! ./../utils */ "./node_modules/axios/lib/utils.js");
|
|
|
|
function InterceptorManager() {
|
|
this.handlers = [];
|
|
}
|
|
|
|
/**
|
|
* Add a new interceptor to the stack
|
|
*
|
|
* @param {Function} fulfilled The function to handle `then` for a `Promise`
|
|
* @param {Function} rejected The function to handle `reject` for a `Promise`
|
|
*
|
|
* @return {Number} An ID used to remove interceptor later
|
|
*/
|
|
InterceptorManager.prototype.use = function use(fulfilled, rejected) {
|
|
this.handlers.push({
|
|
fulfilled: fulfilled,
|
|
rejected: rejected
|
|
});
|
|
return this.handlers.length - 1;
|
|
};
|
|
|
|
/**
|
|
* Remove an interceptor from the stack
|
|
*
|
|
* @param {Number} id The ID that was returned by `use`
|
|
*/
|
|
InterceptorManager.prototype.eject = function eject(id) {
|
|
if (this.handlers[id]) {
|
|
this.handlers[id] = null;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Iterate over all the registered interceptors
|
|
*
|
|
* This method is particularly useful for skipping over any
|
|
* interceptors that may have become `null` calling `eject`.
|
|
*
|
|
* @param {Function} fn The function to call for each interceptor
|
|
*/
|
|
InterceptorManager.prototype.forEach = function forEach(fn) {
|
|
utils.forEach(this.handlers, function forEachHandler(h) {
|
|
if (h !== null) {
|
|
fn(h);
|
|
}
|
|
});
|
|
};
|
|
|
|
module.exports = InterceptorManager;
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/axios/lib/core/buildFullPath.js":
|
|
/*!******************************************************!*\
|
|
!*** ./node_modules/axios/lib/core/buildFullPath.js ***!
|
|
\******************************************************/
|
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
|
|
|
|
var isAbsoluteURL = __webpack_require__(/*! ../helpers/isAbsoluteURL */ "./node_modules/axios/lib/helpers/isAbsoluteURL.js");
|
|
var combineURLs = __webpack_require__(/*! ../helpers/combineURLs */ "./node_modules/axios/lib/helpers/combineURLs.js");
|
|
|
|
/**
|
|
* Creates a new URL by combining the baseURL with the requestedURL,
|
|
* only when the requestedURL is not already an absolute URL.
|
|
* If the requestURL is absolute, this function returns the requestedURL untouched.
|
|
*
|
|
* @param {string} baseURL The base URL
|
|
* @param {string} requestedURL Absolute or relative URL to combine
|
|
* @returns {string} The combined full path
|
|
*/
|
|
module.exports = function buildFullPath(baseURL, requestedURL) {
|
|
if (baseURL && !isAbsoluteURL(requestedURL)) {
|
|
return combineURLs(baseURL, requestedURL);
|
|
}
|
|
return requestedURL;
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/axios/lib/core/createError.js":
|
|
/*!****************************************************!*\
|
|
!*** ./node_modules/axios/lib/core/createError.js ***!
|
|
\****************************************************/
|
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
|
|
|
|
var enhanceError = __webpack_require__(/*! ./enhanceError */ "./node_modules/axios/lib/core/enhanceError.js");
|
|
|
|
/**
|
|
* Create an Error with the specified message, config, error code, request and response.
|
|
*
|
|
* @param {string} message The error message.
|
|
* @param {Object} config The config.
|
|
* @param {string} [code] The error code (for example, 'ECONNABORTED').
|
|
* @param {Object} [request] The request.
|
|
* @param {Object} [response] The response.
|
|
* @returns {Error} The created error.
|
|
*/
|
|
module.exports = function createError(message, config, code, request, response) {
|
|
var error = new Error(message);
|
|
return enhanceError(error, config, code, request, response);
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/axios/lib/core/dispatchRequest.js":
|
|
/*!********************************************************!*\
|
|
!*** ./node_modules/axios/lib/core/dispatchRequest.js ***!
|
|
\********************************************************/
|
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
|
|
|
|
var utils = __webpack_require__(/*! ./../utils */ "./node_modules/axios/lib/utils.js");
|
|
var transformData = __webpack_require__(/*! ./transformData */ "./node_modules/axios/lib/core/transformData.js");
|
|
var isCancel = __webpack_require__(/*! ../cancel/isCancel */ "./node_modules/axios/lib/cancel/isCancel.js");
|
|
var defaults = __webpack_require__(/*! ../defaults */ "./node_modules/axios/lib/defaults.js");
|
|
|
|
/**
|
|
* Throws a `Cancel` if cancellation has been requested.
|
|
*/
|
|
function throwIfCancellationRequested(config) {
|
|
if (config.cancelToken) {
|
|
config.cancelToken.throwIfRequested();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Dispatch a request to the server using the configured adapter.
|
|
*
|
|
* @param {object} config The config that is to be used for the request
|
|
* @returns {Promise} The Promise to be fulfilled
|
|
*/
|
|
module.exports = function dispatchRequest(config) {
|
|
throwIfCancellationRequested(config);
|
|
|
|
// Ensure headers exist
|
|
config.headers = config.headers || {};
|
|
|
|
// Transform request data
|
|
config.data = transformData(
|
|
config.data,
|
|
config.headers,
|
|
config.transformRequest
|
|
);
|
|
|
|
// Flatten headers
|
|
config.headers = utils.merge(
|
|
config.headers.common || {},
|
|
config.headers[config.method] || {},
|
|
config.headers
|
|
);
|
|
|
|
utils.forEach(
|
|
['delete', 'get', 'head', 'post', 'put', 'patch', 'common'],
|
|
function cleanHeaderConfig(method) {
|
|
delete config.headers[method];
|
|
}
|
|
);
|
|
|
|
var adapter = config.adapter || defaults.adapter;
|
|
|
|
return adapter(config).then(function onAdapterResolution(response) {
|
|
throwIfCancellationRequested(config);
|
|
|
|
// Transform response data
|
|
response.data = transformData(
|
|
response.data,
|
|
response.headers,
|
|
config.transformResponse
|
|
);
|
|
|
|
return response;
|
|
}, function onAdapterRejection(reason) {
|
|
if (!isCancel(reason)) {
|
|
throwIfCancellationRequested(config);
|
|
|
|
// Transform response data
|
|
if (reason && reason.response) {
|
|
reason.response.data = transformData(
|
|
reason.response.data,
|
|
reason.response.headers,
|
|
config.transformResponse
|
|
);
|
|
}
|
|
}
|
|
|
|
return Promise.reject(reason);
|
|
});
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/axios/lib/core/enhanceError.js":
|
|
/*!*****************************************************!*\
|
|
!*** ./node_modules/axios/lib/core/enhanceError.js ***!
|
|
\*****************************************************/
|
|
/***/ ((module) => {
|
|
|
|
"use strict";
|
|
|
|
|
|
/**
|
|
* Update an Error with the specified config, error code, and response.
|
|
*
|
|
* @param {Error} error The error to update.
|
|
* @param {Object} config The config.
|
|
* @param {string} [code] The error code (for example, 'ECONNABORTED').
|
|
* @param {Object} [request] The request.
|
|
* @param {Object} [response] The response.
|
|
* @returns {Error} The error.
|
|
*/
|
|
module.exports = function enhanceError(error, config, code, request, response) {
|
|
error.config = config;
|
|
if (code) {
|
|
error.code = code;
|
|
}
|
|
|
|
error.request = request;
|
|
error.response = response;
|
|
error.isAxiosError = true;
|
|
|
|
error.toJSON = function toJSON() {
|
|
return {
|
|
// Standard
|
|
message: this.message,
|
|
name: this.name,
|
|
// Microsoft
|
|
description: this.description,
|
|
number: this.number,
|
|
// Mozilla
|
|
fileName: this.fileName,
|
|
lineNumber: this.lineNumber,
|
|
columnNumber: this.columnNumber,
|
|
stack: this.stack,
|
|
// Axios
|
|
config: this.config,
|
|
code: this.code
|
|
};
|
|
};
|
|
return error;
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/axios/lib/core/mergeConfig.js":
|
|
/*!****************************************************!*\
|
|
!*** ./node_modules/axios/lib/core/mergeConfig.js ***!
|
|
\****************************************************/
|
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
|
|
|
|
var utils = __webpack_require__(/*! ../utils */ "./node_modules/axios/lib/utils.js");
|
|
|
|
/**
|
|
* Config-specific merge-function which creates a new config-object
|
|
* by merging two configuration objects together.
|
|
*
|
|
* @param {Object} config1
|
|
* @param {Object} config2
|
|
* @returns {Object} New object resulting from merging config2 to config1
|
|
*/
|
|
module.exports = function mergeConfig(config1, config2) {
|
|
// eslint-disable-next-line no-param-reassign
|
|
config2 = config2 || {};
|
|
var config = {};
|
|
|
|
var valueFromConfig2Keys = ['url', 'method', 'data'];
|
|
var mergeDeepPropertiesKeys = ['headers', 'auth', 'proxy', 'params'];
|
|
var defaultToConfig2Keys = [
|
|
'baseURL', 'transformRequest', 'transformResponse', 'paramsSerializer',
|
|
'timeout', 'timeoutMessage', 'withCredentials', 'adapter', 'responseType', 'xsrfCookieName',
|
|
'xsrfHeaderName', 'onUploadProgress', 'onDownloadProgress', 'decompress',
|
|
'maxContentLength', 'maxBodyLength', 'maxRedirects', 'transport', 'httpAgent',
|
|
'httpsAgent', 'cancelToken', 'socketPath', 'responseEncoding'
|
|
];
|
|
var directMergeKeys = ['validateStatus'];
|
|
|
|
function getMergedValue(target, source) {
|
|
if (utils.isPlainObject(target) && utils.isPlainObject(source)) {
|
|
return utils.merge(target, source);
|
|
} else if (utils.isPlainObject(source)) {
|
|
return utils.merge({}, source);
|
|
} else if (utils.isArray(source)) {
|
|
return source.slice();
|
|
}
|
|
return source;
|
|
}
|
|
|
|
function mergeDeepProperties(prop) {
|
|
if (!utils.isUndefined(config2[prop])) {
|
|
config[prop] = getMergedValue(config1[prop], config2[prop]);
|
|
} else if (!utils.isUndefined(config1[prop])) {
|
|
config[prop] = getMergedValue(undefined, config1[prop]);
|
|
}
|
|
}
|
|
|
|
utils.forEach(valueFromConfig2Keys, function valueFromConfig2(prop) {
|
|
if (!utils.isUndefined(config2[prop])) {
|
|
config[prop] = getMergedValue(undefined, config2[prop]);
|
|
}
|
|
});
|
|
|
|
utils.forEach(mergeDeepPropertiesKeys, mergeDeepProperties);
|
|
|
|
utils.forEach(defaultToConfig2Keys, function defaultToConfig2(prop) {
|
|
if (!utils.isUndefined(config2[prop])) {
|
|
config[prop] = getMergedValue(undefined, config2[prop]);
|
|
} else if (!utils.isUndefined(config1[prop])) {
|
|
config[prop] = getMergedValue(undefined, config1[prop]);
|
|
}
|
|
});
|
|
|
|
utils.forEach(directMergeKeys, function merge(prop) {
|
|
if (prop in config2) {
|
|
config[prop] = getMergedValue(config1[prop], config2[prop]);
|
|
} else if (prop in config1) {
|
|
config[prop] = getMergedValue(undefined, config1[prop]);
|
|
}
|
|
});
|
|
|
|
var axiosKeys = valueFromConfig2Keys
|
|
.concat(mergeDeepPropertiesKeys)
|
|
.concat(defaultToConfig2Keys)
|
|
.concat(directMergeKeys);
|
|
|
|
var otherKeys = Object
|
|
.keys(config1)
|
|
.concat(Object.keys(config2))
|
|
.filter(function filterAxiosKeys(key) {
|
|
return axiosKeys.indexOf(key) === -1;
|
|
});
|
|
|
|
utils.forEach(otherKeys, mergeDeepProperties);
|
|
|
|
return config;
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/axios/lib/core/settle.js":
|
|
/*!***********************************************!*\
|
|
!*** ./node_modules/axios/lib/core/settle.js ***!
|
|
\***********************************************/
|
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
|
|
|
|
var createError = __webpack_require__(/*! ./createError */ "./node_modules/axios/lib/core/createError.js");
|
|
|
|
/**
|
|
* Resolve or reject a Promise based on response status.
|
|
*
|
|
* @param {Function} resolve A function that resolves the promise.
|
|
* @param {Function} reject A function that rejects the promise.
|
|
* @param {object} response The response.
|
|
*/
|
|
module.exports = function settle(resolve, reject, response) {
|
|
var validateStatus = response.config.validateStatus;
|
|
if (!response.status || !validateStatus || validateStatus(response.status)) {
|
|
resolve(response);
|
|
} else {
|
|
reject(createError(
|
|
'Request failed with status code ' + response.status,
|
|
response.config,
|
|
null,
|
|
response.request,
|
|
response
|
|
));
|
|
}
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/axios/lib/core/transformData.js":
|
|
/*!******************************************************!*\
|
|
!*** ./node_modules/axios/lib/core/transformData.js ***!
|
|
\******************************************************/
|
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
|
|
|
|
var utils = __webpack_require__(/*! ./../utils */ "./node_modules/axios/lib/utils.js");
|
|
|
|
/**
|
|
* Transform the data for a request or a response
|
|
*
|
|
* @param {Object|String} data The data to be transformed
|
|
* @param {Array} headers The headers for the request or response
|
|
* @param {Array|Function} fns A single function or Array of functions
|
|
* @returns {*} The resulting transformed data
|
|
*/
|
|
module.exports = function transformData(data, headers, fns) {
|
|
/*eslint no-param-reassign:0*/
|
|
utils.forEach(fns, function transform(fn) {
|
|
data = fn(data, headers);
|
|
});
|
|
|
|
return data;
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/axios/lib/defaults.js":
|
|
/*!********************************************!*\
|
|
!*** ./node_modules/axios/lib/defaults.js ***!
|
|
\********************************************/
|
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
/* provided dependency */ var process = __webpack_require__(/*! process/browser */ "./node_modules/process/browser.js");
|
|
|
|
|
|
var utils = __webpack_require__(/*! ./utils */ "./node_modules/axios/lib/utils.js");
|
|
var normalizeHeaderName = __webpack_require__(/*! ./helpers/normalizeHeaderName */ "./node_modules/axios/lib/helpers/normalizeHeaderName.js");
|
|
|
|
var DEFAULT_CONTENT_TYPE = {
|
|
'Content-Type': 'application/x-www-form-urlencoded'
|
|
};
|
|
|
|
function setContentTypeIfUnset(headers, value) {
|
|
if (!utils.isUndefined(headers) && utils.isUndefined(headers['Content-Type'])) {
|
|
headers['Content-Type'] = value;
|
|
}
|
|
}
|
|
|
|
function getDefaultAdapter() {
|
|
var adapter;
|
|
if (typeof XMLHttpRequest !== 'undefined') {
|
|
// For browsers use XHR adapter
|
|
adapter = __webpack_require__(/*! ./adapters/xhr */ "./node_modules/axios/lib/adapters/xhr.js");
|
|
} else if (typeof process !== 'undefined' && Object.prototype.toString.call(process) === '[object process]') {
|
|
// For node use HTTP adapter
|
|
adapter = __webpack_require__(/*! ./adapters/http */ "./node_modules/axios/lib/adapters/xhr.js");
|
|
}
|
|
return adapter;
|
|
}
|
|
|
|
var defaults = {
|
|
adapter: getDefaultAdapter(),
|
|
|
|
transformRequest: [function transformRequest(data, headers) {
|
|
normalizeHeaderName(headers, 'Accept');
|
|
normalizeHeaderName(headers, 'Content-Type');
|
|
if (utils.isFormData(data) ||
|
|
utils.isArrayBuffer(data) ||
|
|
utils.isBuffer(data) ||
|
|
utils.isStream(data) ||
|
|
utils.isFile(data) ||
|
|
utils.isBlob(data)
|
|
) {
|
|
return data;
|
|
}
|
|
if (utils.isArrayBufferView(data)) {
|
|
return data.buffer;
|
|
}
|
|
if (utils.isURLSearchParams(data)) {
|
|
setContentTypeIfUnset(headers, 'application/x-www-form-urlencoded;charset=utf-8');
|
|
return data.toString();
|
|
}
|
|
if (utils.isObject(data)) {
|
|
setContentTypeIfUnset(headers, 'application/json;charset=utf-8');
|
|
return JSON.stringify(data);
|
|
}
|
|
return data;
|
|
}],
|
|
|
|
transformResponse: [function transformResponse(data) {
|
|
/*eslint no-param-reassign:0*/
|
|
if (typeof data === 'string') {
|
|
try {
|
|
data = JSON.parse(data);
|
|
} catch (e) { /* Ignore */ }
|
|
}
|
|
return data;
|
|
}],
|
|
|
|
/**
|
|
* A timeout in milliseconds to abort a request. If set to 0 (default) a
|
|
* timeout is not created.
|
|
*/
|
|
timeout: 0,
|
|
|
|
xsrfCookieName: 'XSRF-TOKEN',
|
|
xsrfHeaderName: 'X-XSRF-TOKEN',
|
|
|
|
maxContentLength: -1,
|
|
maxBodyLength: -1,
|
|
|
|
validateStatus: function validateStatus(status) {
|
|
return status >= 200 && status < 300;
|
|
}
|
|
};
|
|
|
|
defaults.headers = {
|
|
common: {
|
|
'Accept': 'application/json, text/plain, */*'
|
|
}
|
|
};
|
|
|
|
utils.forEach(['delete', 'get', 'head'], function forEachMethodNoData(method) {
|
|
defaults.headers[method] = {};
|
|
});
|
|
|
|
utils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {
|
|
defaults.headers[method] = utils.merge(DEFAULT_CONTENT_TYPE);
|
|
});
|
|
|
|
module.exports = defaults;
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/axios/lib/helpers/bind.js":
|
|
/*!************************************************!*\
|
|
!*** ./node_modules/axios/lib/helpers/bind.js ***!
|
|
\************************************************/
|
|
/***/ ((module) => {
|
|
|
|
"use strict";
|
|
|
|
|
|
module.exports = function bind(fn, thisArg) {
|
|
return function wrap() {
|
|
var args = new Array(arguments.length);
|
|
for (var i = 0; i < args.length; i++) {
|
|
args[i] = arguments[i];
|
|
}
|
|
return fn.apply(thisArg, args);
|
|
};
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/axios/lib/helpers/buildURL.js":
|
|
/*!****************************************************!*\
|
|
!*** ./node_modules/axios/lib/helpers/buildURL.js ***!
|
|
\****************************************************/
|
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
|
|
|
|
var utils = __webpack_require__(/*! ./../utils */ "./node_modules/axios/lib/utils.js");
|
|
|
|
function encode(val) {
|
|
return encodeURIComponent(val).
|
|
replace(/%3A/gi, ':').
|
|
replace(/%24/g, '$').
|
|
replace(/%2C/gi, ',').
|
|
replace(/%20/g, '+').
|
|
replace(/%5B/gi, '[').
|
|
replace(/%5D/gi, ']');
|
|
}
|
|
|
|
/**
|
|
* Build a URL by appending params to the end
|
|
*
|
|
* @param {string} url The base of the url (e.g., http://www.google.com)
|
|
* @param {object} [params] The params to be appended
|
|
* @returns {string} The formatted url
|
|
*/
|
|
module.exports = function buildURL(url, params, paramsSerializer) {
|
|
/*eslint no-param-reassign:0*/
|
|
if (!params) {
|
|
return url;
|
|
}
|
|
|
|
var serializedParams;
|
|
if (paramsSerializer) {
|
|
serializedParams = paramsSerializer(params);
|
|
} else if (utils.isURLSearchParams(params)) {
|
|
serializedParams = params.toString();
|
|
} else {
|
|
var parts = [];
|
|
|
|
utils.forEach(params, function serialize(val, key) {
|
|
if (val === null || typeof val === 'undefined') {
|
|
return;
|
|
}
|
|
|
|
if (utils.isArray(val)) {
|
|
key = key + '[]';
|
|
} else {
|
|
val = [val];
|
|
}
|
|
|
|
utils.forEach(val, function parseValue(v) {
|
|
if (utils.isDate(v)) {
|
|
v = v.toISOString();
|
|
} else if (utils.isObject(v)) {
|
|
v = JSON.stringify(v);
|
|
}
|
|
parts.push(encode(key) + '=' + encode(v));
|
|
});
|
|
});
|
|
|
|
serializedParams = parts.join('&');
|
|
}
|
|
|
|
if (serializedParams) {
|
|
var hashmarkIndex = url.indexOf('#');
|
|
if (hashmarkIndex !== -1) {
|
|
url = url.slice(0, hashmarkIndex);
|
|
}
|
|
|
|
url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams;
|
|
}
|
|
|
|
return url;
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/axios/lib/helpers/combineURLs.js":
|
|
/*!*******************************************************!*\
|
|
!*** ./node_modules/axios/lib/helpers/combineURLs.js ***!
|
|
\*******************************************************/
|
|
/***/ ((module) => {
|
|
|
|
"use strict";
|
|
|
|
|
|
/**
|
|
* Creates a new URL by combining the specified URLs
|
|
*
|
|
* @param {string} baseURL The base URL
|
|
* @param {string} relativeURL The relative URL
|
|
* @returns {string} The combined URL
|
|
*/
|
|
module.exports = function combineURLs(baseURL, relativeURL) {
|
|
return relativeURL
|
|
? baseURL.replace(/\/+$/, '') + '/' + relativeURL.replace(/^\/+/, '')
|
|
: baseURL;
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/axios/lib/helpers/cookies.js":
|
|
/*!***************************************************!*\
|
|
!*** ./node_modules/axios/lib/helpers/cookies.js ***!
|
|
\***************************************************/
|
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
|
|
|
|
var utils = __webpack_require__(/*! ./../utils */ "./node_modules/axios/lib/utils.js");
|
|
|
|
module.exports = (
|
|
utils.isStandardBrowserEnv() ?
|
|
|
|
// Standard browser envs support document.cookie
|
|
(function standardBrowserEnv() {
|
|
return {
|
|
write: function write(name, value, expires, path, domain, secure) {
|
|
var cookie = [];
|
|
cookie.push(name + '=' + encodeURIComponent(value));
|
|
|
|
if (utils.isNumber(expires)) {
|
|
cookie.push('expires=' + new Date(expires).toGMTString());
|
|
}
|
|
|
|
if (utils.isString(path)) {
|
|
cookie.push('path=' + path);
|
|
}
|
|
|
|
if (utils.isString(domain)) {
|
|
cookie.push('domain=' + domain);
|
|
}
|
|
|
|
if (secure === true) {
|
|
cookie.push('secure');
|
|
}
|
|
|
|
document.cookie = cookie.join('; ');
|
|
},
|
|
|
|
read: function read(name) {
|
|
var match = document.cookie.match(new RegExp('(^|;\\s*)(' + name + ')=([^;]*)'));
|
|
return (match ? decodeURIComponent(match[3]) : null);
|
|
},
|
|
|
|
remove: function remove(name) {
|
|
this.write(name, '', Date.now() - 86400000);
|
|
}
|
|
};
|
|
})() :
|
|
|
|
// Non standard browser env (web workers, react-native) lack needed support.
|
|
(function nonStandardBrowserEnv() {
|
|
return {
|
|
write: function write() {},
|
|
read: function read() { return null; },
|
|
remove: function remove() {}
|
|
};
|
|
})()
|
|
);
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/axios/lib/helpers/isAbsoluteURL.js":
|
|
/*!*********************************************************!*\
|
|
!*** ./node_modules/axios/lib/helpers/isAbsoluteURL.js ***!
|
|
\*********************************************************/
|
|
/***/ ((module) => {
|
|
|
|
"use strict";
|
|
|
|
|
|
/**
|
|
* Determines whether the specified URL is absolute
|
|
*
|
|
* @param {string} url The URL to test
|
|
* @returns {boolean} True if the specified URL is absolute, otherwise false
|
|
*/
|
|
module.exports = function isAbsoluteURL(url) {
|
|
// A URL is considered absolute if it begins with "<scheme>://" or "//" (protocol-relative URL).
|
|
// RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed
|
|
// by any combination of letters, digits, plus, period, or hyphen.
|
|
return /^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(url);
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/axios/lib/helpers/isAxiosError.js":
|
|
/*!********************************************************!*\
|
|
!*** ./node_modules/axios/lib/helpers/isAxiosError.js ***!
|
|
\********************************************************/
|
|
/***/ ((module) => {
|
|
|
|
"use strict";
|
|
|
|
|
|
/**
|
|
* Determines whether the payload is an error thrown by Axios
|
|
*
|
|
* @param {*} payload The value to test
|
|
* @returns {boolean} True if the payload is an error thrown by Axios, otherwise false
|
|
*/
|
|
module.exports = function isAxiosError(payload) {
|
|
return (typeof payload === 'object') && (payload.isAxiosError === true);
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/axios/lib/helpers/isURLSameOrigin.js":
|
|
/*!***********************************************************!*\
|
|
!*** ./node_modules/axios/lib/helpers/isURLSameOrigin.js ***!
|
|
\***********************************************************/
|
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
|
|
|
|
var utils = __webpack_require__(/*! ./../utils */ "./node_modules/axios/lib/utils.js");
|
|
|
|
module.exports = (
|
|
utils.isStandardBrowserEnv() ?
|
|
|
|
// Standard browser envs have full support of the APIs needed to test
|
|
// whether the request URL is of the same origin as current location.
|
|
(function standardBrowserEnv() {
|
|
var msie = /(msie|trident)/i.test(navigator.userAgent);
|
|
var urlParsingNode = document.createElement('a');
|
|
var originURL;
|
|
|
|
/**
|
|
* Parse a URL to discover it's components
|
|
*
|
|
* @param {String} url The URL to be parsed
|
|
* @returns {Object}
|
|
*/
|
|
function resolveURL(url) {
|
|
var href = url;
|
|
|
|
if (msie) {
|
|
// IE needs attribute set twice to normalize properties
|
|
urlParsingNode.setAttribute('href', href);
|
|
href = urlParsingNode.href;
|
|
}
|
|
|
|
urlParsingNode.setAttribute('href', href);
|
|
|
|
// urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils
|
|
return {
|
|
href: urlParsingNode.href,
|
|
protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '',
|
|
host: urlParsingNode.host,
|
|
search: urlParsingNode.search ? urlParsingNode.search.replace(/^\?/, '') : '',
|
|
hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '',
|
|
hostname: urlParsingNode.hostname,
|
|
port: urlParsingNode.port,
|
|
pathname: (urlParsingNode.pathname.charAt(0) === '/') ?
|
|
urlParsingNode.pathname :
|
|
'/' + urlParsingNode.pathname
|
|
};
|
|
}
|
|
|
|
originURL = resolveURL(window.location.href);
|
|
|
|
/**
|
|
* Determine if a URL shares the same origin as the current location
|
|
*
|
|
* @param {String} requestURL The URL to test
|
|
* @returns {boolean} True if URL shares the same origin, otherwise false
|
|
*/
|
|
return function isURLSameOrigin(requestURL) {
|
|
var parsed = (utils.isString(requestURL)) ? resolveURL(requestURL) : requestURL;
|
|
return (parsed.protocol === originURL.protocol &&
|
|
parsed.host === originURL.host);
|
|
};
|
|
})() :
|
|
|
|
// Non standard browser envs (web workers, react-native) lack needed support.
|
|
(function nonStandardBrowserEnv() {
|
|
return function isURLSameOrigin() {
|
|
return true;
|
|
};
|
|
})()
|
|
);
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/axios/lib/helpers/normalizeHeaderName.js":
|
|
/*!***************************************************************!*\
|
|
!*** ./node_modules/axios/lib/helpers/normalizeHeaderName.js ***!
|
|
\***************************************************************/
|
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
|
|
|
|
var utils = __webpack_require__(/*! ../utils */ "./node_modules/axios/lib/utils.js");
|
|
|
|
module.exports = function normalizeHeaderName(headers, normalizedName) {
|
|
utils.forEach(headers, function processHeader(value, name) {
|
|
if (name !== normalizedName && name.toUpperCase() === normalizedName.toUpperCase()) {
|
|
headers[normalizedName] = value;
|
|
delete headers[name];
|
|
}
|
|
});
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/axios/lib/helpers/parseHeaders.js":
|
|
/*!********************************************************!*\
|
|
!*** ./node_modules/axios/lib/helpers/parseHeaders.js ***!
|
|
\********************************************************/
|
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
|
|
|
|
var utils = __webpack_require__(/*! ./../utils */ "./node_modules/axios/lib/utils.js");
|
|
|
|
// Headers whose duplicates are ignored by node
|
|
// c.f. https://nodejs.org/api/http.html#http_message_headers
|
|
var ignoreDuplicateOf = [
|
|
'age', 'authorization', 'content-length', 'content-type', 'etag',
|
|
'expires', 'from', 'host', 'if-modified-since', 'if-unmodified-since',
|
|
'last-modified', 'location', 'max-forwards', 'proxy-authorization',
|
|
'referer', 'retry-after', 'user-agent'
|
|
];
|
|
|
|
/**
|
|
* Parse headers into an object
|
|
*
|
|
* ```
|
|
* Date: Wed, 27 Aug 2014 08:58:49 GMT
|
|
* Content-Type: application/json
|
|
* Connection: keep-alive
|
|
* Transfer-Encoding: chunked
|
|
* ```
|
|
*
|
|
* @param {String} headers Headers needing to be parsed
|
|
* @returns {Object} Headers parsed into an object
|
|
*/
|
|
module.exports = function parseHeaders(headers) {
|
|
var parsed = {};
|
|
var key;
|
|
var val;
|
|
var i;
|
|
|
|
if (!headers) { return parsed; }
|
|
|
|
utils.forEach(headers.split('\n'), function parser(line) {
|
|
i = line.indexOf(':');
|
|
key = utils.trim(line.substr(0, i)).toLowerCase();
|
|
val = utils.trim(line.substr(i + 1));
|
|
|
|
if (key) {
|
|
if (parsed[key] && ignoreDuplicateOf.indexOf(key) >= 0) {
|
|
return;
|
|
}
|
|
if (key === 'set-cookie') {
|
|
parsed[key] = (parsed[key] ? parsed[key] : []).concat([val]);
|
|
} else {
|
|
parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;
|
|
}
|
|
}
|
|
});
|
|
|
|
return parsed;
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/axios/lib/helpers/spread.js":
|
|
/*!**************************************************!*\
|
|
!*** ./node_modules/axios/lib/helpers/spread.js ***!
|
|
\**************************************************/
|
|
/***/ ((module) => {
|
|
|
|
"use strict";
|
|
|
|
|
|
/**
|
|
* Syntactic sugar for invoking a function and expanding an array for arguments.
|
|
*
|
|
* Common use case would be to use `Function.prototype.apply`.
|
|
*
|
|
* ```js
|
|
* function f(x, y, z) {}
|
|
* var args = [1, 2, 3];
|
|
* f.apply(null, args);
|
|
* ```
|
|
*
|
|
* With `spread` this example can be re-written.
|
|
*
|
|
* ```js
|
|
* spread(function(x, y, z) {})([1, 2, 3]);
|
|
* ```
|
|
*
|
|
* @param {Function} callback
|
|
* @returns {Function}
|
|
*/
|
|
module.exports = function spread(callback) {
|
|
return function wrap(arr) {
|
|
return callback.apply(null, arr);
|
|
};
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/axios/lib/utils.js":
|
|
/*!*****************************************!*\
|
|
!*** ./node_modules/axios/lib/utils.js ***!
|
|
\*****************************************/
|
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
|
|
|
|
var bind = __webpack_require__(/*! ./helpers/bind */ "./node_modules/axios/lib/helpers/bind.js");
|
|
|
|
/*global toString:true*/
|
|
|
|
// utils is a library of generic helper functions non-specific to axios
|
|
|
|
var toString = Object.prototype.toString;
|
|
|
|
/**
|
|
* Determine if a value is an Array
|
|
*
|
|
* @param {Object} val The value to test
|
|
* @returns {boolean} True if value is an Array, otherwise false
|
|
*/
|
|
function isArray(val) {
|
|
return toString.call(val) === '[object Array]';
|
|
}
|
|
|
|
/**
|
|
* Determine if a value is undefined
|
|
*
|
|
* @param {Object} val The value to test
|
|
* @returns {boolean} True if the value is undefined, otherwise false
|
|
*/
|
|
function isUndefined(val) {
|
|
return typeof val === 'undefined';
|
|
}
|
|
|
|
/**
|
|
* Determine if a value is a Buffer
|
|
*
|
|
* @param {Object} val The value to test
|
|
* @returns {boolean} True if value is a Buffer, otherwise false
|
|
*/
|
|
function isBuffer(val) {
|
|
return val !== null && !isUndefined(val) && val.constructor !== null && !isUndefined(val.constructor)
|
|
&& typeof val.constructor.isBuffer === 'function' && val.constructor.isBuffer(val);
|
|
}
|
|
|
|
/**
|
|
* Determine if a value is an ArrayBuffer
|
|
*
|
|
* @param {Object} val The value to test
|
|
* @returns {boolean} True if value is an ArrayBuffer, otherwise false
|
|
*/
|
|
function isArrayBuffer(val) {
|
|
return toString.call(val) === '[object ArrayBuffer]';
|
|
}
|
|
|
|
/**
|
|
* Determine if a value is a FormData
|
|
*
|
|
* @param {Object} val The value to test
|
|
* @returns {boolean} True if value is an FormData, otherwise false
|
|
*/
|
|
function isFormData(val) {
|
|
return (typeof FormData !== 'undefined') && (val instanceof FormData);
|
|
}
|
|
|
|
/**
|
|
* Determine if a value is a view on an ArrayBuffer
|
|
*
|
|
* @param {Object} val The value to test
|
|
* @returns {boolean} True if value is a view on an ArrayBuffer, otherwise false
|
|
*/
|
|
function isArrayBufferView(val) {
|
|
var result;
|
|
if ((typeof ArrayBuffer !== 'undefined') && (ArrayBuffer.isView)) {
|
|
result = ArrayBuffer.isView(val);
|
|
} else {
|
|
result = (val) && (val.buffer) && (val.buffer instanceof ArrayBuffer);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Determine if a value is a String
|
|
*
|
|
* @param {Object} val The value to test
|
|
* @returns {boolean} True if value is a String, otherwise false
|
|
*/
|
|
function isString(val) {
|
|
return typeof val === 'string';
|
|
}
|
|
|
|
/**
|
|
* Determine if a value is a Number
|
|
*
|
|
* @param {Object} val The value to test
|
|
* @returns {boolean} True if value is a Number, otherwise false
|
|
*/
|
|
function isNumber(val) {
|
|
return typeof val === 'number';
|
|
}
|
|
|
|
/**
|
|
* Determine if a value is an Object
|
|
*
|
|
* @param {Object} val The value to test
|
|
* @returns {boolean} True if value is an Object, otherwise false
|
|
*/
|
|
function isObject(val) {
|
|
return val !== null && typeof val === 'object';
|
|
}
|
|
|
|
/**
|
|
* Determine if a value is a plain Object
|
|
*
|
|
* @param {Object} val The value to test
|
|
* @return {boolean} True if value is a plain Object, otherwise false
|
|
*/
|
|
function isPlainObject(val) {
|
|
if (toString.call(val) !== '[object Object]') {
|
|
return false;
|
|
}
|
|
|
|
var prototype = Object.getPrototypeOf(val);
|
|
return prototype === null || prototype === Object.prototype;
|
|
}
|
|
|
|
/**
|
|
* Determine if a value is a Date
|
|
*
|
|
* @param {Object} val The value to test
|
|
* @returns {boolean} True if value is a Date, otherwise false
|
|
*/
|
|
function isDate(val) {
|
|
return toString.call(val) === '[object Date]';
|
|
}
|
|
|
|
/**
|
|
* Determine if a value is a File
|
|
*
|
|
* @param {Object} val The value to test
|
|
* @returns {boolean} True if value is a File, otherwise false
|
|
*/
|
|
function isFile(val) {
|
|
return toString.call(val) === '[object File]';
|
|
}
|
|
|
|
/**
|
|
* Determine if a value is a Blob
|
|
*
|
|
* @param {Object} val The value to test
|
|
* @returns {boolean} True if value is a Blob, otherwise false
|
|
*/
|
|
function isBlob(val) {
|
|
return toString.call(val) === '[object Blob]';
|
|
}
|
|
|
|
/**
|
|
* Determine if a value is a Function
|
|
*
|
|
* @param {Object} val The value to test
|
|
* @returns {boolean} True if value is a Function, otherwise false
|
|
*/
|
|
function isFunction(val) {
|
|
return toString.call(val) === '[object Function]';
|
|
}
|
|
|
|
/**
|
|
* Determine if a value is a Stream
|
|
*
|
|
* @param {Object} val The value to test
|
|
* @returns {boolean} True if value is a Stream, otherwise false
|
|
*/
|
|
function isStream(val) {
|
|
return isObject(val) && isFunction(val.pipe);
|
|
}
|
|
|
|
/**
|
|
* Determine if a value is a URLSearchParams object
|
|
*
|
|
* @param {Object} val The value to test
|
|
* @returns {boolean} True if value is a URLSearchParams object, otherwise false
|
|
*/
|
|
function isURLSearchParams(val) {
|
|
return typeof URLSearchParams !== 'undefined' && val instanceof URLSearchParams;
|
|
}
|
|
|
|
/**
|
|
* Trim excess whitespace off the beginning and end of a string
|
|
*
|
|
* @param {String} str The String to trim
|
|
* @returns {String} The String freed of excess whitespace
|
|
*/
|
|
function trim(str) {
|
|
return str.replace(/^\s*/, '').replace(/\s*$/, '');
|
|
}
|
|
|
|
/**
|
|
* Determine if we're running in a standard browser environment
|
|
*
|
|
* This allows axios to run in a web worker, and react-native.
|
|
* Both environments support XMLHttpRequest, but not fully standard globals.
|
|
*
|
|
* web workers:
|
|
* typeof window -> undefined
|
|
* typeof document -> undefined
|
|
*
|
|
* react-native:
|
|
* navigator.product -> 'ReactNative'
|
|
* nativescript
|
|
* navigator.product -> 'NativeScript' or 'NS'
|
|
*/
|
|
function isStandardBrowserEnv() {
|
|
if (typeof navigator !== 'undefined' && (navigator.product === 'ReactNative' ||
|
|
navigator.product === 'NativeScript' ||
|
|
navigator.product === 'NS')) {
|
|
return false;
|
|
}
|
|
return (
|
|
typeof window !== 'undefined' &&
|
|
typeof document !== 'undefined'
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Iterate over an Array or an Object invoking a function for each item.
|
|
*
|
|
* If `obj` is an Array callback will be called passing
|
|
* the value, index, and complete array for each item.
|
|
*
|
|
* If 'obj' is an Object callback will be called passing
|
|
* the value, key, and complete object for each property.
|
|
*
|
|
* @param {Object|Array} obj The object to iterate
|
|
* @param {Function} fn The callback to invoke for each item
|
|
*/
|
|
function forEach(obj, fn) {
|
|
// Don't bother if no value provided
|
|
if (obj === null || typeof obj === 'undefined') {
|
|
return;
|
|
}
|
|
|
|
// Force an array if not already something iterable
|
|
if (typeof obj !== 'object') {
|
|
/*eslint no-param-reassign:0*/
|
|
obj = [obj];
|
|
}
|
|
|
|
if (isArray(obj)) {
|
|
// Iterate over array values
|
|
for (var i = 0, l = obj.length; i < l; i++) {
|
|
fn.call(null, obj[i], i, obj);
|
|
}
|
|
} else {
|
|
// Iterate over object keys
|
|
for (var key in obj) {
|
|
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
fn.call(null, obj[key], key, obj);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Accepts varargs expecting each argument to be an object, then
|
|
* immutably merges the properties of each object and returns result.
|
|
*
|
|
* When multiple objects contain the same key the later object in
|
|
* the arguments list will take precedence.
|
|
*
|
|
* Example:
|
|
*
|
|
* ```js
|
|
* var result = merge({foo: 123}, {foo: 456});
|
|
* console.log(result.foo); // outputs 456
|
|
* ```
|
|
*
|
|
* @param {Object} obj1 Object to merge
|
|
* @returns {Object} Result of all merge properties
|
|
*/
|
|
function merge(/* obj1, obj2, obj3, ... */) {
|
|
var result = {};
|
|
function assignValue(val, key) {
|
|
if (isPlainObject(result[key]) && isPlainObject(val)) {
|
|
result[key] = merge(result[key], val);
|
|
} else if (isPlainObject(val)) {
|
|
result[key] = merge({}, val);
|
|
} else if (isArray(val)) {
|
|
result[key] = val.slice();
|
|
} else {
|
|
result[key] = val;
|
|
}
|
|
}
|
|
|
|
for (var i = 0, l = arguments.length; i < l; i++) {
|
|
forEach(arguments[i], assignValue);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Extends object a by mutably adding to it the properties of object b.
|
|
*
|
|
* @param {Object} a The object to be extended
|
|
* @param {Object} b The object to copy properties from
|
|
* @param {Object} thisArg The object to bind function to
|
|
* @return {Object} The resulting value of object a
|
|
*/
|
|
function extend(a, b, thisArg) {
|
|
forEach(b, function assignValue(val, key) {
|
|
if (thisArg && typeof val === 'function') {
|
|
a[key] = bind(val, thisArg);
|
|
} else {
|
|
a[key] = val;
|
|
}
|
|
});
|
|
return a;
|
|
}
|
|
|
|
/**
|
|
* Remove byte order marker. This catches EF BB BF (the UTF-8 BOM)
|
|
*
|
|
* @param {string} content with BOM
|
|
* @return {string} content value without BOM
|
|
*/
|
|
function stripBOM(content) {
|
|
if (content.charCodeAt(0) === 0xFEFF) {
|
|
content = content.slice(1);
|
|
}
|
|
return content;
|
|
}
|
|
|
|
module.exports = {
|
|
isArray: isArray,
|
|
isArrayBuffer: isArrayBuffer,
|
|
isBuffer: isBuffer,
|
|
isFormData: isFormData,
|
|
isArrayBufferView: isArrayBufferView,
|
|
isString: isString,
|
|
isNumber: isNumber,
|
|
isObject: isObject,
|
|
isPlainObject: isPlainObject,
|
|
isUndefined: isUndefined,
|
|
isDate: isDate,
|
|
isFile: isFile,
|
|
isBlob: isBlob,
|
|
isFunction: isFunction,
|
|
isStream: isStream,
|
|
isURLSearchParams: isURLSearchParams,
|
|
isStandardBrowserEnv: isStandardBrowserEnv,
|
|
forEach: forEach,
|
|
merge: merge,
|
|
extend: extend,
|
|
trim: trim,
|
|
stripBOM: stripBOM
|
|
};
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/babel-loader/lib/index.js??clonedRuleSet-5.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./resources/js/views/Home.vue?vue&type=script&lang=js":
|
|
/*!*****************************************************************************************************************************************************************************************!*\
|
|
!*** ./node_modules/babel-loader/lib/index.js??clonedRuleSet-5.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./resources/js/views/Home.vue?vue&type=script&lang=js ***!
|
|
\*****************************************************************************************************************************************************************************************/
|
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
|
|
/* harmony export */ });
|
|
/* harmony import */ var _components_PageHeader_vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../components/PageHeader.vue */ "./resources/js/components/PageHeader.vue");
|
|
/* harmony import */ var _components_Container_vue__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../components/Container.vue */ "./resources/js/components/Container.vue");
|
|
/* harmony import */ var _components_SplitContent_vue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../components/SplitContent.vue */ "./resources/js/components/SplitContent.vue");
|
|
/* harmony import */ var _components_BlogRecent_vue__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../components/BlogRecent.vue */ "./resources/js/components/BlogRecent.vue");
|
|
/* harmony import */ var _components_BlogPopular_vue__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../components/BlogPopular.vue */ "./resources/js/components/BlogPopular.vue");
|
|
/* harmony import */ var _components_PageFooter_vue__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../components/PageFooter.vue */ "./resources/js/components/PageFooter.vue");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({
|
|
components: {
|
|
PageHeader: _components_PageHeader_vue__WEBPACK_IMPORTED_MODULE_0__.default,
|
|
Container: _components_Container_vue__WEBPACK_IMPORTED_MODULE_1__.default,
|
|
SplitContent: _components_SplitContent_vue__WEBPACK_IMPORTED_MODULE_2__.default,
|
|
BlogRecent: _components_BlogRecent_vue__WEBPACK_IMPORTED_MODULE_3__.default,
|
|
BlogPopular: _components_BlogPopular_vue__WEBPACK_IMPORTED_MODULE_4__.default,
|
|
PageFooter: _components_PageFooter_vue__WEBPACK_IMPORTED_MODULE_5__.default
|
|
}
|
|
});
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/babel-loader/lib/index.js??clonedRuleSet-5.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./resources/js/apps/App.vue?vue&type=template&id=2dea4962":
|
|
/*!*******************************************************************************************************************************************************************************************************************************************************************!*\
|
|
!*** ./node_modules/babel-loader/lib/index.js??clonedRuleSet-5.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./resources/js/apps/App.vue?vue&type=template&id=2dea4962 ***!
|
|
\*******************************************************************************************************************************************************************************************************************************************************************/
|
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ "render": () => (/* binding */ render)
|
|
/* harmony export */ });
|
|
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.esm-bundler.js");
|
|
|
|
function render(_ctx, _cache) {
|
|
var _component_router_view = (0,vue__WEBPACK_IMPORTED_MODULE_0__.resolveComponent)("router-view");
|
|
|
|
return (0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createBlock)(_component_router_view);
|
|
}
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/babel-loader/lib/index.js??clonedRuleSet-5.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./resources/js/components/BlogPopular.vue?vue&type=template&id=3498cf88":
|
|
/*!*********************************************************************************************************************************************************************************************************************************************************************************!*\
|
|
!*** ./node_modules/babel-loader/lib/index.js??clonedRuleSet-5.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./resources/js/components/BlogPopular.vue?vue&type=template&id=3498cf88 ***!
|
|
\*********************************************************************************************************************************************************************************************************************************************************************************/
|
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ "render": () => (/* binding */ render)
|
|
/* harmony export */ });
|
|
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.esm-bundler.js");
|
|
|
|
var _hoisted_1 = {
|
|
"class": "blog-popular"
|
|
};
|
|
|
|
var _hoisted_2 = /*#__PURE__*/(0,vue__WEBPACK_IMPORTED_MODULE_0__.createStaticVNode)("<h3>Popular content</h3><ul class=\"popular-items\"><li><span class=\"arrow\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"></line><polyline points=\"12 5 19 12 12 19\"></polyline></svg></span><a class=\"link\" href=\"#\">Lorem ipsum dolor sit, amet consectetur adipisicing.</a></li><li><span class=\"arrow\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"></line><polyline points=\"12 5 19 12 12 19\"></polyline></svg></span><a class=\"link\" href=\"#\">Lorem ipsum dolor sit.</a></li><li><span class=\"arrow\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"></line><polyline points=\"12 5 19 12 12 19\"></polyline></svg></span><a class=\"link\" href=\"#\">Lorem ipsum dolor sit, amet consectetur adipisicing.</a></li><li><span class=\"arrow\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"></line><polyline points=\"12 5 19 12 12 19\"></polyline></svg></span><a class=\"link\" href=\"#\">Lorem ipsum dolor sit, amet consectetur adipisicing.</a></li><li><span class=\"arrow\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"></line><polyline points=\"12 5 19 12 12 19\"></polyline></svg></span><a class=\"link\" href=\"#\">Lorem ipsum dolor sit, amet consectetur adipisicing.</a></li></ul>", 2);
|
|
|
|
var _hoisted_4 = [_hoisted_2];
|
|
function render(_ctx, _cache) {
|
|
return (0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("section", _hoisted_1, _hoisted_4);
|
|
}
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/babel-loader/lib/index.js??clonedRuleSet-5.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./resources/js/components/BlogRecent.vue?vue&type=template&id=6b89b6c8":
|
|
/*!********************************************************************************************************************************************************************************************************************************************************************************!*\
|
|
!*** ./node_modules/babel-loader/lib/index.js??clonedRuleSet-5.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./resources/js/components/BlogRecent.vue?vue&type=template&id=6b89b6c8 ***!
|
|
\********************************************************************************************************************************************************************************************************************************************************************************/
|
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ "render": () => (/* binding */ render)
|
|
/* harmony export */ });
|
|
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.esm-bundler.js");
|
|
|
|
var _hoisted_1 = {
|
|
"class": "blog-recent"
|
|
};
|
|
|
|
var _hoisted_2 = /*#__PURE__*/(0,vue__WEBPACK_IMPORTED_MODULE_0__.createStaticVNode)("<div class=\"header\"><h3>Latest Articles</h3><div class=\"all-articles\"><a href=\"javascript:void(0)\">All articles</a></div></div><div class=\"list\"><ul class=\"blog-items\"><li class=\"blog-item\"><img class=\"article-image\" src=\"//via.placeholder.com/128\" alt=\"Article Topic\"><div class=\"article-text\"><h4 class=\"article-title\"> Lorem ipsum dolor sit amet, consectetur adipisicing. </h4><span class=\"article-date\">March 8, 2021</span></div></li><li class=\"blog-item\"><img class=\"article-image\" src=\"//via.placeholder.com/128\" alt=\"Article Topic\"><div class=\"article-text\"><h4 class=\"article-title\"> Lorem ipsum dolor sit amet, consectetur adipisicing. </h4><span class=\"article-date\">March 8, 2021</span></div></li><li class=\"blog-item\"><img class=\"article-image\" src=\"//via.placeholder.com/128\" alt=\"Article Topic\"><div class=\"article-text\"><h4 class=\"article-title\"> Lorem ipsum dolor sit amet, consectetur adipisicing. </h4><span class=\"article-date\">March 8, 2021</span></div></li><li class=\"blog-item\"><img class=\"article-image\" src=\"//via.placeholder.com/128\" alt=\"Article Topic\"><div class=\"article-text\"><h4 class=\"article-title\"> Lorem ipsum dolor sit amet, consectetur adipisicing. </h4><span class=\"article-date\">March 8, 2021</span></div></li><li class=\"blog-item\"><img class=\"article-image\" src=\"//via.placeholder.com/128\" alt=\"Article Topic\"><div class=\"article-text\"><h4 class=\"article-title\"> Lorem ipsum dolor sit amet, consectetur adipisicing. </h4><span class=\"article-date\">March 8, 2021</span></div></li><li class=\"blog-item\"><img class=\"article-image\" src=\"//via.placeholder.com/128\" alt=\"Article Topic\"><div class=\"article-text\"><h4 class=\"article-title\"> Lorem ipsum dolor sit amet, consectetur adipisicing. </h4><span class=\"article-date\">March 8, 2021</span></div></li><li class=\"blog-item\"><img class=\"article-image\" src=\"//via.placeholder.com/128\" alt=\"Article Topic\"><div class=\"article-text\"><h4 class=\"article-title\"> Lorem ipsum dolor sit amet, consectetur adipisicing. </h4><span class=\"article-date\">March 8, 2021</span></div></li><li class=\"blog-item\"><img class=\"article-image\" src=\"//via.placeholder.com/128\" alt=\"Article Topic\"><div class=\"article-text\"><h4 class=\"article-title\"> Lorem ipsum dolor sit amet, consectetur adipisicing. </h4><span class=\"article-date\">March 8, 2021</span></div></li><li class=\"blog-item\"><img class=\"article-image\" src=\"//via.placeholder.com/128\" alt=\"Article Topic\"><div class=\"article-text\"><h4 class=\"article-title\"> Lorem ipsum dolor sit amet, consectetur adipisicing. </h4><span class=\"article-date\">March 8, 2021</span></div></li><li class=\"blog-item\"><img class=\"article-image\" src=\"//via.placeholder.com/128\" alt=\"Article Topic\"><div class=\"article-text\"><h4 class=\"article-title\"> Lorem ipsum dolor sit amet, consectetur adipisicing. </h4><span class=\"article-date\">March 8, 2021</span></div></li></ul></div>", 2);
|
|
|
|
var _hoisted_4 = [_hoisted_2];
|
|
function render(_ctx, _cache) {
|
|
return (0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("section", _hoisted_1, _hoisted_4);
|
|
}
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/babel-loader/lib/index.js??clonedRuleSet-5.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./resources/js/components/Container.vue?vue&type=template&id=ba1063b4":
|
|
/*!*******************************************************************************************************************************************************************************************************************************************************************************!*\
|
|
!*** ./node_modules/babel-loader/lib/index.js??clonedRuleSet-5.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./resources/js/components/Container.vue?vue&type=template&id=ba1063b4 ***!
|
|
\*******************************************************************************************************************************************************************************************************************************************************************************/
|
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ "render": () => (/* binding */ render)
|
|
/* harmony export */ });
|
|
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.esm-bundler.js");
|
|
|
|
var _hoisted_1 = {
|
|
"class": "container"
|
|
};
|
|
function render(_ctx, _cache) {
|
|
return (0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_1, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.renderSlot)(_ctx.$slots, "default")]);
|
|
}
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/babel-loader/lib/index.js??clonedRuleSet-5.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./resources/js/components/PageFooter.vue?vue&type=template&id=5e81b4b5":
|
|
/*!********************************************************************************************************************************************************************************************************************************************************************************!*\
|
|
!*** ./node_modules/babel-loader/lib/index.js??clonedRuleSet-5.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./resources/js/components/PageFooter.vue?vue&type=template&id=5e81b4b5 ***!
|
|
\********************************************************************************************************************************************************************************************************************************************************************************/
|
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ "render": () => (/* binding */ render)
|
|
/* harmony export */ });
|
|
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.esm-bundler.js");
|
|
|
|
|
|
var _hoisted_1 = /*#__PURE__*/(0,vue__WEBPACK_IMPORTED_MODULE_0__.createStaticVNode)("<div class=\"credits\"><p>Designed and developed by Daniel de Cloet.</p><p> Built with <a href=\"https://vuejs.org/\">Vue.js</a>. Iconset provided by <a href=\"https://fontawesome.com/\">Font Awesome</a>. </p></div><div class=\"social-links\"><ul><li><a href=\"javascript:void(0)\"><i class=\"fab fa-github\"></i></a></li><li><a href=\"javascript:void(0)\"><i class=\"fab fa-gitlab\"></i></a></li><li><a href=\"javascript:void(0)\"><i class=\"fab fa-linkedin\"></i></a></li></ul></div>", 2);
|
|
|
|
var _hoisted_3 = [_hoisted_1];
|
|
function render(_ctx, _cache) {
|
|
return (0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("footer", null, _hoisted_3);
|
|
}
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/babel-loader/lib/index.js??clonedRuleSet-5.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./resources/js/components/PageHeader.vue?vue&type=template&id=7fb418a7":
|
|
/*!********************************************************************************************************************************************************************************************************************************************************************************!*\
|
|
!*** ./node_modules/babel-loader/lib/index.js??clonedRuleSet-5.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./resources/js/components/PageHeader.vue?vue&type=template&id=7fb418a7 ***!
|
|
\********************************************************************************************************************************************************************************************************************************************************************************/
|
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ "render": () => (/* binding */ render)
|
|
/* harmony export */ });
|
|
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.esm-bundler.js");
|
|
|
|
var _hoisted_1 = {
|
|
"class": "home-header"
|
|
};
|
|
|
|
var _hoisted_2 = /*#__PURE__*/(0,vue__WEBPACK_IMPORTED_MODULE_0__.createStaticVNode)("<div class=\"container\"><header><a class=\"brand\" href=\"/\"><img class=\"brand-logo\" src=\"//via.placeholder.com/256\" alt=\"Brand Logo\"><span class=\"brand-name\">Daniel de Cloet</span></a><nav class=\"site-nav\"><ul class=\"nav-items\"><li class=\"nav-item\"><a href=\"/blog.html\">Blog</a></li><li class=\"nav-item\"><a href=\"/snippets.html\">Snippets</a></li><li class=\"nav-item\"><a href=\"/contact.html\">Contact</a></li></ul></nav></header><section class=\"hero\"><h1>I'm Daniel, junior software engineer</h1><p> Lorem ipsum dolor sit amet consectetur, adipisicing elit. Deleniti iure earum odio architecto? Tenetur in ea, animi illo non voluptatibus distinctio consequuntur ipsam adipisci officiis quod, recusandae facilis? Ut, aliquid. </p></section></div><div class=\"wave\"><svg preserveAspectRatio=\"none\" width=\"1440\" height=\"74\" viewBox=\"0 0 1440 74\"><path d=\"M456.464 0.0433865C277.158 -1.70575 0 50.0141 0 50.0141V74H1440V50.0141C1440 50.0141 1320.4 31.1925 1243.09 27.0276C1099.33 19.2816 1019.08 53.1981 875.138 50.0141C710.527 46.3727 621.108 1.64949 456.464 0.0433865Z\"></path></svg></div>", 2);
|
|
|
|
var _hoisted_4 = [_hoisted_2];
|
|
function render(_ctx, _cache) {
|
|
return (0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_1, _hoisted_4);
|
|
}
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/babel-loader/lib/index.js??clonedRuleSet-5.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./resources/js/components/SplitContent.vue?vue&type=template&id=1553872c":
|
|
/*!**********************************************************************************************************************************************************************************************************************************************************************************!*\
|
|
!*** ./node_modules/babel-loader/lib/index.js??clonedRuleSet-5.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./resources/js/components/SplitContent.vue?vue&type=template&id=1553872c ***!
|
|
\**********************************************************************************************************************************************************************************************************************************************************************************/
|
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ "render": () => (/* binding */ render)
|
|
/* harmony export */ });
|
|
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.esm-bundler.js");
|
|
|
|
var _hoisted_1 = {
|
|
"class": "container"
|
|
};
|
|
var _hoisted_2 = {
|
|
"class": "split-content"
|
|
};
|
|
function render(_ctx, _cache) {
|
|
return (0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_1, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_2, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("main", null, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.renderSlot)(_ctx.$slots, "main")]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("aside", null, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.renderSlot)(_ctx.$slots, "aside")])])]);
|
|
}
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/babel-loader/lib/index.js??clonedRuleSet-5.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./resources/js/views/Home.vue?vue&type=template&id=63cd6604":
|
|
/*!*********************************************************************************************************************************************************************************************************************************************************************!*\
|
|
!*** ./node_modules/babel-loader/lib/index.js??clonedRuleSet-5.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./resources/js/views/Home.vue?vue&type=template&id=63cd6604 ***!
|
|
\*********************************************************************************************************************************************************************************************************************************************************************/
|
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ "render": () => (/* binding */ render)
|
|
/* harmony export */ });
|
|
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.esm-bundler.js");
|
|
|
|
function render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
var _component_page_header = (0,vue__WEBPACK_IMPORTED_MODULE_0__.resolveComponent)("page-header");
|
|
|
|
var _component_blog_recent = (0,vue__WEBPACK_IMPORTED_MODULE_0__.resolveComponent)("blog-recent");
|
|
|
|
var _component_blog_popular = (0,vue__WEBPACK_IMPORTED_MODULE_0__.resolveComponent)("blog-popular");
|
|
|
|
var _component_split_content = (0,vue__WEBPACK_IMPORTED_MODULE_0__.resolveComponent)("split-content");
|
|
|
|
var _component_page_footer = (0,vue__WEBPACK_IMPORTED_MODULE_0__.resolveComponent)("page-footer");
|
|
|
|
var _component_container = (0,vue__WEBPACK_IMPORTED_MODULE_0__.resolveComponent)("container");
|
|
|
|
return (0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createVNode)(_component_page_header), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createVNode)(_component_container, null, {
|
|
"default": (0,vue__WEBPACK_IMPORTED_MODULE_0__.withCtx)(function () {
|
|
return [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createVNode)(_component_split_content, null, {
|
|
main: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withCtx)(function () {
|
|
return [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createVNode)(_component_blog_recent)];
|
|
}),
|
|
aside: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withCtx)(function () {
|
|
return [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createVNode)(_component_blog_popular)];
|
|
}),
|
|
_: 1
|
|
/* STABLE */
|
|
|
|
}), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createVNode)(_component_page_footer)];
|
|
}),
|
|
_: 1
|
|
/* STABLE */
|
|
|
|
})], 64
|
|
/* STABLE_FRAGMENT */
|
|
);
|
|
}
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./resources/js/app.js":
|
|
/*!*****************************!*\
|
|
!*** ./resources/js/app.js ***!
|
|
\*****************************/
|
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony import */ var _router_app__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./router-app */ "./resources/js/router-app.js");
|
|
/* harmony import */ var _apps_App_vue__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./apps/App.vue */ "./resources/js/apps/App.vue");
|
|
__webpack_require__(/*! ./bootstrap */ "./resources/js/bootstrap.js"); // Import Vue.js
|
|
|
|
|
|
window.Vue = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.esm-bundler.js");
|
|
|
|
// Create the Vue.js application
|
|
|
|
var app = Vue.createApp(_apps_App_vue__WEBPACK_IMPORTED_MODULE_1__.default); // Register plugins
|
|
|
|
app.use(_router_app__WEBPACK_IMPORTED_MODULE_0__.default); // Mount and start using Vue.js
|
|
|
|
app.mount('#app');
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./resources/js/bootstrap.js":
|
|
/*!***********************************!*\
|
|
!*** ./resources/js/bootstrap.js ***!
|
|
\***********************************/
|
|
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {
|
|
|
|
window._ = __webpack_require__(/*! lodash */ "./node_modules/lodash/lodash.js");
|
|
/**
|
|
* We'll load the axios HTTP library which allows us to easily issue requests
|
|
* to our Laravel back-end. This library automatically handles sending the
|
|
* CSRF token as a header based on the value of the "XSRF" token cookie.
|
|
*/
|
|
|
|
window.axios = __webpack_require__(/*! axios */ "./node_modules/axios/index.js");
|
|
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
|
|
/**
|
|
* Echo exposes an expressive API for subscribing to channels and listening
|
|
* for events that are broadcast by Laravel. Echo and event broadcasting
|
|
* allows your team to easily build robust real-time web applications.
|
|
*/
|
|
// import Echo from 'laravel-echo';
|
|
// window.Pusher = require('pusher-js');
|
|
// window.Echo = new Echo({
|
|
// broadcaster: 'pusher',
|
|
// key: process.env.MIX_PUSHER_APP_KEY,
|
|
// cluster: process.env.MIX_PUSHER_APP_CLUSTER,
|
|
// forceTLS: true
|
|
// });
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./resources/js/router-app.js":
|
|
/*!************************************!*\
|
|
!*** ./resources/js/router-app.js ***!
|
|
\************************************/
|
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
|
|
/* harmony export */ });
|
|
/* harmony import */ var _views_Home_vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./views/Home.vue */ "./resources/js/views/Home.vue");
|
|
var VueRouter = __webpack_require__(/*! vue-router */ "./node_modules/vue-router/dist/vue-router.esm-bundler.js");
|
|
|
|
|
|
var routes = [{
|
|
path: '/',
|
|
component: _views_Home_vue__WEBPACK_IMPORTED_MODULE_0__.default
|
|
}];
|
|
var router = VueRouter.createRouter({
|
|
history: VueRouter.createWebHistory(),
|
|
routes: routes
|
|
});
|
|
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (router);
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/lodash/lodash.js":
|
|
/*!***************************************!*\
|
|
!*** ./node_modules/lodash/lodash.js ***!
|
|
\***************************************/
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/* module decorator */ module = __webpack_require__.nmd(module);
|
|
var __WEBPACK_AMD_DEFINE_RESULT__;/**
|
|
* @license
|
|
* Lodash <https://lodash.com/>
|
|
* Copyright OpenJS Foundation and other contributors <https://openjsf.org/>
|
|
* Released under MIT license <https://lodash.com/license>
|
|
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
|
|
* Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
|
*/
|
|
;(function() {
|
|
|
|
/** Used as a safe reference for `undefined` in pre-ES5 environments. */
|
|
var undefined;
|
|
|
|
/** Used as the semantic version number. */
|
|
var VERSION = '4.17.21';
|
|
|
|
/** Used as the size to enable large array optimizations. */
|
|
var LARGE_ARRAY_SIZE = 200;
|
|
|
|
/** Error message constants. */
|
|
var CORE_ERROR_TEXT = 'Unsupported core-js use. Try https://npms.io/search?q=ponyfill.',
|
|
FUNC_ERROR_TEXT = 'Expected a function',
|
|
INVALID_TEMPL_VAR_ERROR_TEXT = 'Invalid `variable` option passed into `_.template`';
|
|
|
|
/** Used to stand-in for `undefined` hash values. */
|
|
var HASH_UNDEFINED = '__lodash_hash_undefined__';
|
|
|
|
/** Used as the maximum memoize cache size. */
|
|
var MAX_MEMOIZE_SIZE = 500;
|
|
|
|
/** Used as the internal argument placeholder. */
|
|
var PLACEHOLDER = '__lodash_placeholder__';
|
|
|
|
/** Used to compose bitmasks for cloning. */
|
|
var CLONE_DEEP_FLAG = 1,
|
|
CLONE_FLAT_FLAG = 2,
|
|
CLONE_SYMBOLS_FLAG = 4;
|
|
|
|
/** Used to compose bitmasks for value comparisons. */
|
|
var COMPARE_PARTIAL_FLAG = 1,
|
|
COMPARE_UNORDERED_FLAG = 2;
|
|
|
|
/** Used to compose bitmasks for function metadata. */
|
|
var WRAP_BIND_FLAG = 1,
|
|
WRAP_BIND_KEY_FLAG = 2,
|
|
WRAP_CURRY_BOUND_FLAG = 4,
|
|
WRAP_CURRY_FLAG = 8,
|
|
WRAP_CURRY_RIGHT_FLAG = 16,
|
|
WRAP_PARTIAL_FLAG = 32,
|
|
WRAP_PARTIAL_RIGHT_FLAG = 64,
|
|
WRAP_ARY_FLAG = 128,
|
|
WRAP_REARG_FLAG = 256,
|
|
WRAP_FLIP_FLAG = 512;
|
|
|
|
/** Used as default options for `_.truncate`. */
|
|
var DEFAULT_TRUNC_LENGTH = 30,
|
|
DEFAULT_TRUNC_OMISSION = '...';
|
|
|
|
/** Used to detect hot functions by number of calls within a span of milliseconds. */
|
|
var HOT_COUNT = 800,
|
|
HOT_SPAN = 16;
|
|
|
|
/** Used to indicate the type of lazy iteratees. */
|
|
var LAZY_FILTER_FLAG = 1,
|
|
LAZY_MAP_FLAG = 2,
|
|
LAZY_WHILE_FLAG = 3;
|
|
|
|
/** Used as references for various `Number` constants. */
|
|
var INFINITY = 1 / 0,
|
|
MAX_SAFE_INTEGER = 9007199254740991,
|
|
MAX_INTEGER = 1.7976931348623157e+308,
|
|
NAN = 0 / 0;
|
|
|
|
/** Used as references for the maximum length and index of an array. */
|
|
var MAX_ARRAY_LENGTH = 4294967295,
|
|
MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1,
|
|
HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;
|
|
|
|
/** Used to associate wrap methods with their bit flags. */
|
|
var wrapFlags = [
|
|
['ary', WRAP_ARY_FLAG],
|
|
['bind', WRAP_BIND_FLAG],
|
|
['bindKey', WRAP_BIND_KEY_FLAG],
|
|
['curry', WRAP_CURRY_FLAG],
|
|
['curryRight', WRAP_CURRY_RIGHT_FLAG],
|
|
['flip', WRAP_FLIP_FLAG],
|
|
['partial', WRAP_PARTIAL_FLAG],
|
|
['partialRight', WRAP_PARTIAL_RIGHT_FLAG],
|
|
['rearg', WRAP_REARG_FLAG]
|
|
];
|
|
|
|
/** `Object#toString` result references. */
|
|
var argsTag = '[object Arguments]',
|
|
arrayTag = '[object Array]',
|
|
asyncTag = '[object AsyncFunction]',
|
|
boolTag = '[object Boolean]',
|
|
dateTag = '[object Date]',
|
|
domExcTag = '[object DOMException]',
|
|
errorTag = '[object Error]',
|
|
funcTag = '[object Function]',
|
|
genTag = '[object GeneratorFunction]',
|
|
mapTag = '[object Map]',
|
|
numberTag = '[object Number]',
|
|
nullTag = '[object Null]',
|
|
objectTag = '[object Object]',
|
|
promiseTag = '[object Promise]',
|
|
proxyTag = '[object Proxy]',
|
|
regexpTag = '[object RegExp]',
|
|
setTag = '[object Set]',
|
|
stringTag = '[object String]',
|
|
symbolTag = '[object Symbol]',
|
|
undefinedTag = '[object Undefined]',
|
|
weakMapTag = '[object WeakMap]',
|
|
weakSetTag = '[object WeakSet]';
|
|
|
|
var arrayBufferTag = '[object ArrayBuffer]',
|
|
dataViewTag = '[object DataView]',
|
|
float32Tag = '[object Float32Array]',
|
|
float64Tag = '[object Float64Array]',
|
|
int8Tag = '[object Int8Array]',
|
|
int16Tag = '[object Int16Array]',
|
|
int32Tag = '[object Int32Array]',
|
|
uint8Tag = '[object Uint8Array]',
|
|
uint8ClampedTag = '[object Uint8ClampedArray]',
|
|
uint16Tag = '[object Uint16Array]',
|
|
uint32Tag = '[object Uint32Array]';
|
|
|
|
/** Used to match empty string literals in compiled template source. */
|
|
var reEmptyStringLeading = /\b__p \+= '';/g,
|
|
reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
|
|
reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
|
|
|
|
/** Used to match HTML entities and HTML characters. */
|
|
var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g,
|
|
reUnescapedHtml = /[&<>"']/g,
|
|
reHasEscapedHtml = RegExp(reEscapedHtml.source),
|
|
reHasUnescapedHtml = RegExp(reUnescapedHtml.source);
|
|
|
|
/** Used to match template delimiters. */
|
|
var reEscape = /<%-([\s\S]+?)%>/g,
|
|
reEvaluate = /<%([\s\S]+?)%>/g,
|
|
reInterpolate = /<%=([\s\S]+?)%>/g;
|
|
|
|
/** Used to match property names within property paths. */
|
|
var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
|
|
reIsPlainProp = /^\w*$/,
|
|
rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
|
|
|
|
/**
|
|
* Used to match `RegExp`
|
|
* [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
|
|
*/
|
|
var reRegExpChar = /[\\^$.*+?()[\]{}|]/g,
|
|
reHasRegExpChar = RegExp(reRegExpChar.source);
|
|
|
|
/** Used to match leading whitespace. */
|
|
var reTrimStart = /^\s+/;
|
|
|
|
/** Used to match a single whitespace character. */
|
|
var reWhitespace = /\s/;
|
|
|
|
/** Used to match wrap detail comments. */
|
|
var reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,
|
|
reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/,
|
|
reSplitDetails = /,? & /;
|
|
|
|
/** Used to match words composed of alphanumeric characters. */
|
|
var reAsciiWord = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
|
|
|
|
/**
|
|
* Used to validate the `validate` option in `_.template` variable.
|
|
*
|
|
* Forbids characters which could potentially change the meaning of the function argument definition:
|
|
* - "()," (modification of function parameters)
|
|
* - "=" (default value)
|
|
* - "[]{}" (destructuring of function parameters)
|
|
* - "/" (beginning of a comment)
|
|
* - whitespace
|
|
*/
|
|
var reForbiddenIdentifierChars = /[()=,{}\[\]\/\s]/;
|
|
|
|
/** Used to match backslashes in property paths. */
|
|
var reEscapeChar = /\\(\\)?/g;
|
|
|
|
/**
|
|
* Used to match
|
|
* [ES template delimiters](http://ecma-international.org/ecma-262/7.0/#sec-template-literal-lexical-components).
|
|
*/
|
|
var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
|
|
|
|
/** Used to match `RegExp` flags from their coerced string values. */
|
|
var reFlags = /\w*$/;
|
|
|
|
/** Used to detect bad signed hexadecimal string values. */
|
|
var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
|
|
|
|
/** Used to detect binary string values. */
|
|
var reIsBinary = /^0b[01]+$/i;
|
|
|
|
/** Used to detect host constructors (Safari). */
|
|
var reIsHostCtor = /^\[object .+?Constructor\]$/;
|
|
|
|
/** Used to detect octal string values. */
|
|
var reIsOctal = /^0o[0-7]+$/i;
|
|
|
|
/** Used to detect unsigned integer values. */
|
|
var reIsUint = /^(?:0|[1-9]\d*)$/;
|
|
|
|
/** Used to match Latin Unicode letters (excluding mathematical operators). */
|
|
var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g;
|
|
|
|
/** Used to ensure capturing order of template delimiters. */
|
|
var reNoMatch = /($^)/;
|
|
|
|
/** Used to match unescaped characters in compiled string literals. */
|
|
var reUnescapedString = /['\n\r\u2028\u2029\\]/g;
|
|
|
|
/** Used to compose unicode character classes. */
|
|
var rsAstralRange = '\\ud800-\\udfff',
|
|
rsComboMarksRange = '\\u0300-\\u036f',
|
|
reComboHalfMarksRange = '\\ufe20-\\ufe2f',
|
|
rsComboSymbolsRange = '\\u20d0-\\u20ff',
|
|
rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,
|
|
rsDingbatRange = '\\u2700-\\u27bf',
|
|
rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff',
|
|
rsMathOpRange = '\\xac\\xb1\\xd7\\xf7',
|
|
rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf',
|
|
rsPunctuationRange = '\\u2000-\\u206f',
|
|
rsSpaceRange = ' \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000',
|
|
rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde',
|
|
rsVarRange = '\\ufe0e\\ufe0f',
|
|
rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange;
|
|
|
|
/** Used to compose unicode capture groups. */
|
|
var rsApos = "['\u2019]",
|
|
rsAstral = '[' + rsAstralRange + ']',
|
|
rsBreak = '[' + rsBreakRange + ']',
|
|
rsCombo = '[' + rsComboRange + ']',
|
|
rsDigits = '\\d+',
|
|
rsDingbat = '[' + rsDingbatRange + ']',
|
|
rsLower = '[' + rsLowerRange + ']',
|
|
rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']',
|
|
rsFitz = '\\ud83c[\\udffb-\\udfff]',
|
|
rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',
|
|
rsNonAstral = '[^' + rsAstralRange + ']',
|
|
rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}',
|
|
rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]',
|
|
rsUpper = '[' + rsUpperRange + ']',
|
|
rsZWJ = '\\u200d';
|
|
|
|
/** Used to compose unicode regexes. */
|
|
var rsMiscLower = '(?:' + rsLower + '|' + rsMisc + ')',
|
|
rsMiscUpper = '(?:' + rsUpper + '|' + rsMisc + ')',
|
|
rsOptContrLower = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?',
|
|
rsOptContrUpper = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?',
|
|
reOptMod = rsModifier + '?',
|
|
rsOptVar = '[' + rsVarRange + ']?',
|
|
rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',
|
|
rsOrdLower = '\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])',
|
|
rsOrdUpper = '\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])',
|
|
rsSeq = rsOptVar + reOptMod + rsOptJoin,
|
|
rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq,
|
|
rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';
|
|
|
|
/** Used to match apostrophes. */
|
|
var reApos = RegExp(rsApos, 'g');
|
|
|
|
/**
|
|
* Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and
|
|
* [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).
|
|
*/
|
|
var reComboMark = RegExp(rsCombo, 'g');
|
|
|
|
/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
|
|
var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');
|
|
|
|
/** Used to match complex or compound words. */
|
|
var reUnicodeWord = RegExp([
|
|
rsUpper + '?' + rsLower + '+' + rsOptContrLower + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',
|
|
rsMiscUpper + '+' + rsOptContrUpper + '(?=' + [rsBreak, rsUpper + rsMiscLower, '$'].join('|') + ')',
|
|
rsUpper + '?' + rsMiscLower + '+' + rsOptContrLower,
|
|
rsUpper + '+' + rsOptContrUpper,
|
|
rsOrdUpper,
|
|
rsOrdLower,
|
|
rsDigits,
|
|
rsEmoji
|
|
].join('|'), 'g');
|
|
|
|
/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */
|
|
var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']');
|
|
|
|
/** Used to detect strings that need a more robust regexp to match words. */
|
|
var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;
|
|
|
|
/** Used to assign default `context` object properties. */
|
|
var contextProps = [
|
|
'Array', 'Buffer', 'DataView', 'Date', 'Error', 'Float32Array', 'Float64Array',
|
|
'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object',
|
|
'Promise', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array',
|
|
'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap',
|
|
'_', 'clearTimeout', 'isFinite', 'parseInt', 'setTimeout'
|
|
];
|
|
|
|
/** Used to make template sourceURLs easier to identify. */
|
|
var templateCounter = -1;
|
|
|
|
/** Used to identify `toStringTag` values of typed arrays. */
|
|
var typedArrayTags = {};
|
|
typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
|
|
typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
|
|
typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
|
|
typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
|
|
typedArrayTags[uint32Tag] = true;
|
|
typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
|
|
typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
|
|
typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =
|
|
typedArrayTags[errorTag] = typedArrayTags[funcTag] =
|
|
typedArrayTags[mapTag] = typedArrayTags[numberTag] =
|
|
typedArrayTags[objectTag] = typedArrayTags[regexpTag] =
|
|
typedArrayTags[setTag] = typedArrayTags[stringTag] =
|
|
typedArrayTags[weakMapTag] = false;
|
|
|
|
/** Used to identify `toStringTag` values supported by `_.clone`. */
|
|
var cloneableTags = {};
|
|
cloneableTags[argsTag] = cloneableTags[arrayTag] =
|
|
cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =
|
|
cloneableTags[boolTag] = cloneableTags[dateTag] =
|
|
cloneableTags[float32Tag] = cloneableTags[float64Tag] =
|
|
cloneableTags[int8Tag] = cloneableTags[int16Tag] =
|
|
cloneableTags[int32Tag] = cloneableTags[mapTag] =
|
|
cloneableTags[numberTag] = cloneableTags[objectTag] =
|
|
cloneableTags[regexpTag] = cloneableTags[setTag] =
|
|
cloneableTags[stringTag] = cloneableTags[symbolTag] =
|
|
cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
|
|
cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
|
|
cloneableTags[errorTag] = cloneableTags[funcTag] =
|
|
cloneableTags[weakMapTag] = false;
|
|
|
|
/** Used to map Latin Unicode letters to basic Latin letters. */
|
|
var deburredLetters = {
|
|
// Latin-1 Supplement block.
|
|
'\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A',
|
|
'\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a',
|
|
'\xc7': 'C', '\xe7': 'c',
|
|
'\xd0': 'D', '\xf0': 'd',
|
|
'\xc8': 'E', '\xc9': 'E', '\xca': 'E', '\xcb': 'E',
|
|
'\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e',
|
|
'\xcc': 'I', '\xcd': 'I', '\xce': 'I', '\xcf': 'I',
|
|
'\xec': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i',
|
|
'\xd1': 'N', '\xf1': 'n',
|
|
'\xd2': 'O', '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O',
|
|
'\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o',
|
|
'\xd9': 'U', '\xda': 'U', '\xdb': 'U', '\xdc': 'U',
|
|
'\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u',
|
|
'\xdd': 'Y', '\xfd': 'y', '\xff': 'y',
|
|
'\xc6': 'Ae', '\xe6': 'ae',
|
|
'\xde': 'Th', '\xfe': 'th',
|
|
'\xdf': 'ss',
|
|
// Latin Extended-A block.
|
|
'\u0100': 'A', '\u0102': 'A', '\u0104': 'A',
|
|
'\u0101': 'a', '\u0103': 'a', '\u0105': 'a',
|
|
'\u0106': 'C', '\u0108': 'C', '\u010a': 'C', '\u010c': 'C',
|
|
'\u0107': 'c', '\u0109': 'c', '\u010b': 'c', '\u010d': 'c',
|
|
'\u010e': 'D', '\u0110': 'D', '\u010f': 'd', '\u0111': 'd',
|
|
'\u0112': 'E', '\u0114': 'E', '\u0116': 'E', '\u0118': 'E', '\u011a': 'E',
|
|
'\u0113': 'e', '\u0115': 'e', '\u0117': 'e', '\u0119': 'e', '\u011b': 'e',
|
|
'\u011c': 'G', '\u011e': 'G', '\u0120': 'G', '\u0122': 'G',
|
|
'\u011d': 'g', '\u011f': 'g', '\u0121': 'g', '\u0123': 'g',
|
|
'\u0124': 'H', '\u0126': 'H', '\u0125': 'h', '\u0127': 'h',
|
|
'\u0128': 'I', '\u012a': 'I', '\u012c': 'I', '\u012e': 'I', '\u0130': 'I',
|
|
'\u0129': 'i', '\u012b': 'i', '\u012d': 'i', '\u012f': 'i', '\u0131': 'i',
|
|
'\u0134': 'J', '\u0135': 'j',
|
|
'\u0136': 'K', '\u0137': 'k', '\u0138': 'k',
|
|
'\u0139': 'L', '\u013b': 'L', '\u013d': 'L', '\u013f': 'L', '\u0141': 'L',
|
|
'\u013a': 'l', '\u013c': 'l', '\u013e': 'l', '\u0140': 'l', '\u0142': 'l',
|
|
'\u0143': 'N', '\u0145': 'N', '\u0147': 'N', '\u014a': 'N',
|
|
'\u0144': 'n', '\u0146': 'n', '\u0148': 'n', '\u014b': 'n',
|
|
'\u014c': 'O', '\u014e': 'O', '\u0150': 'O',
|
|
'\u014d': 'o', '\u014f': 'o', '\u0151': 'o',
|
|
'\u0154': 'R', '\u0156': 'R', '\u0158': 'R',
|
|
'\u0155': 'r', '\u0157': 'r', '\u0159': 'r',
|
|
'\u015a': 'S', '\u015c': 'S', '\u015e': 'S', '\u0160': 'S',
|
|
'\u015b': 's', '\u015d': 's', '\u015f': 's', '\u0161': 's',
|
|
'\u0162': 'T', '\u0164': 'T', '\u0166': 'T',
|
|
'\u0163': 't', '\u0165': 't', '\u0167': 't',
|
|
'\u0168': 'U', '\u016a': 'U', '\u016c': 'U', '\u016e': 'U', '\u0170': 'U', '\u0172': 'U',
|
|
'\u0169': 'u', '\u016b': 'u', '\u016d': 'u', '\u016f': 'u', '\u0171': 'u', '\u0173': 'u',
|
|
'\u0174': 'W', '\u0175': 'w',
|
|
'\u0176': 'Y', '\u0177': 'y', '\u0178': 'Y',
|
|
'\u0179': 'Z', '\u017b': 'Z', '\u017d': 'Z',
|
|
'\u017a': 'z', '\u017c': 'z', '\u017e': 'z',
|
|
'\u0132': 'IJ', '\u0133': 'ij',
|
|
'\u0152': 'Oe', '\u0153': 'oe',
|
|
'\u0149': "'n", '\u017f': 's'
|
|
};
|
|
|
|
/** Used to map characters to HTML entities. */
|
|
var htmlEscapes = {
|
|
'&': '&',
|
|
'<': '<',
|
|
'>': '>',
|
|
'"': '"',
|
|
"'": '''
|
|
};
|
|
|
|
/** Used to map HTML entities to characters. */
|
|
var htmlUnescapes = {
|
|
'&': '&',
|
|
'<': '<',
|
|
'>': '>',
|
|
'"': '"',
|
|
''': "'"
|
|
};
|
|
|
|
/** Used to escape characters for inclusion in compiled string literals. */
|
|
var stringEscapes = {
|
|
'\\': '\\',
|
|
"'": "'",
|
|
'\n': 'n',
|
|
'\r': 'r',
|
|
'\u2028': 'u2028',
|
|
'\u2029': 'u2029'
|
|
};
|
|
|
|
/** Built-in method references without a dependency on `root`. */
|
|
var freeParseFloat = parseFloat,
|
|
freeParseInt = parseInt;
|
|
|
|
/** Detect free variable `global` from Node.js. */
|
|
var freeGlobal = typeof __webpack_require__.g == 'object' && __webpack_require__.g && __webpack_require__.g.Object === Object && __webpack_require__.g;
|
|
|
|
/** Detect free variable `self`. */
|
|
var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
|
|
|
|
/** Used as a reference to the global object. */
|
|
var root = freeGlobal || freeSelf || Function('return this')();
|
|
|
|
/** Detect free variable `exports`. */
|
|
var freeExports = true && exports && !exports.nodeType && exports;
|
|
|
|
/** Detect free variable `module`. */
|
|
var freeModule = freeExports && "object" == 'object' && module && !module.nodeType && module;
|
|
|
|
/** Detect the popular CommonJS extension `module.exports`. */
|
|
var moduleExports = freeModule && freeModule.exports === freeExports;
|
|
|
|
/** Detect free variable `process` from Node.js. */
|
|
var freeProcess = moduleExports && freeGlobal.process;
|
|
|
|
/** Used to access faster Node.js helpers. */
|
|
var nodeUtil = (function() {
|
|
try {
|
|
// Use `util.types` for Node.js 10+.
|
|
var types = freeModule && freeModule.require && freeModule.require('util').types;
|
|
|
|
if (types) {
|
|
return types;
|
|
}
|
|
|
|
// Legacy `process.binding('util')` for Node.js < 10.
|
|
return freeProcess && freeProcess.binding && freeProcess.binding('util');
|
|
} catch (e) {}
|
|
}());
|
|
|
|
/* Node.js helper references. */
|
|
var nodeIsArrayBuffer = nodeUtil && nodeUtil.isArrayBuffer,
|
|
nodeIsDate = nodeUtil && nodeUtil.isDate,
|
|
nodeIsMap = nodeUtil && nodeUtil.isMap,
|
|
nodeIsRegExp = nodeUtil && nodeUtil.isRegExp,
|
|
nodeIsSet = nodeUtil && nodeUtil.isSet,
|
|
nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* A faster alternative to `Function#apply`, this function invokes `func`
|
|
* with the `this` binding of `thisArg` and the arguments of `args`.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to invoke.
|
|
* @param {*} thisArg The `this` binding of `func`.
|
|
* @param {Array} args The arguments to invoke `func` with.
|
|
* @returns {*} Returns the result of `func`.
|
|
*/
|
|
function apply(func, thisArg, args) {
|
|
switch (args.length) {
|
|
case 0: return func.call(thisArg);
|
|
case 1: return func.call(thisArg, args[0]);
|
|
case 2: return func.call(thisArg, args[0], args[1]);
|
|
case 3: return func.call(thisArg, args[0], args[1], args[2]);
|
|
}
|
|
return func.apply(thisArg, args);
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `baseAggregator` for arrays.
|
|
*
|
|
* @private
|
|
* @param {Array} [array] The array to iterate over.
|
|
* @param {Function} setter The function to set `accumulator` values.
|
|
* @param {Function} iteratee The iteratee to transform keys.
|
|
* @param {Object} accumulator The initial aggregated object.
|
|
* @returns {Function} Returns `accumulator`.
|
|
*/
|
|
function arrayAggregator(array, setter, iteratee, accumulator) {
|
|
var index = -1,
|
|
length = array == null ? 0 : array.length;
|
|
|
|
while (++index < length) {
|
|
var value = array[index];
|
|
setter(accumulator, value, iteratee(value), array);
|
|
}
|
|
return accumulator;
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `_.forEach` for arrays without support for
|
|
* iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Array} [array] The array to iterate over.
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|
* @returns {Array} Returns `array`.
|
|
*/
|
|
function arrayEach(array, iteratee) {
|
|
var index = -1,
|
|
length = array == null ? 0 : array.length;
|
|
|
|
while (++index < length) {
|
|
if (iteratee(array[index], index, array) === false) {
|
|
break;
|
|
}
|
|
}
|
|
return array;
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `_.forEachRight` for arrays without support for
|
|
* iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Array} [array] The array to iterate over.
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|
* @returns {Array} Returns `array`.
|
|
*/
|
|
function arrayEachRight(array, iteratee) {
|
|
var length = array == null ? 0 : array.length;
|
|
|
|
while (length--) {
|
|
if (iteratee(array[length], length, array) === false) {
|
|
break;
|
|
}
|
|
}
|
|
return array;
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `_.every` for arrays without support for
|
|
* iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Array} [array] The array to iterate over.
|
|
* @param {Function} predicate The function invoked per iteration.
|
|
* @returns {boolean} Returns `true` if all elements pass the predicate check,
|
|
* else `false`.
|
|
*/
|
|
function arrayEvery(array, predicate) {
|
|
var index = -1,
|
|
length = array == null ? 0 : array.length;
|
|
|
|
while (++index < length) {
|
|
if (!predicate(array[index], index, array)) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `_.filter` for arrays without support for
|
|
* iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Array} [array] The array to iterate over.
|
|
* @param {Function} predicate The function invoked per iteration.
|
|
* @returns {Array} Returns the new filtered array.
|
|
*/
|
|
function arrayFilter(array, predicate) {
|
|
var index = -1,
|
|
length = array == null ? 0 : array.length,
|
|
resIndex = 0,
|
|
result = [];
|
|
|
|
while (++index < length) {
|
|
var value = array[index];
|
|
if (predicate(value, index, array)) {
|
|
result[resIndex++] = value;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `_.includes` for arrays without support for
|
|
* specifying an index to search from.
|
|
*
|
|
* @private
|
|
* @param {Array} [array] The array to inspect.
|
|
* @param {*} target The value to search for.
|
|
* @returns {boolean} Returns `true` if `target` is found, else `false`.
|
|
*/
|
|
function arrayIncludes(array, value) {
|
|
var length = array == null ? 0 : array.length;
|
|
return !!length && baseIndexOf(array, value, 0) > -1;
|
|
}
|
|
|
|
/**
|
|
* This function is like `arrayIncludes` except that it accepts a comparator.
|
|
*
|
|
* @private
|
|
* @param {Array} [array] The array to inspect.
|
|
* @param {*} target The value to search for.
|
|
* @param {Function} comparator The comparator invoked per element.
|
|
* @returns {boolean} Returns `true` if `target` is found, else `false`.
|
|
*/
|
|
function arrayIncludesWith(array, value, comparator) {
|
|
var index = -1,
|
|
length = array == null ? 0 : array.length;
|
|
|
|
while (++index < length) {
|
|
if (comparator(value, array[index])) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `_.map` for arrays without support for iteratee
|
|
* shorthands.
|
|
*
|
|
* @private
|
|
* @param {Array} [array] The array to iterate over.
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|
* @returns {Array} Returns the new mapped array.
|
|
*/
|
|
function arrayMap(array, iteratee) {
|
|
var index = -1,
|
|
length = array == null ? 0 : array.length,
|
|
result = Array(length);
|
|
|
|
while (++index < length) {
|
|
result[index] = iteratee(array[index], index, array);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Appends the elements of `values` to `array`.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to modify.
|
|
* @param {Array} values The values to append.
|
|
* @returns {Array} Returns `array`.
|
|
*/
|
|
function arrayPush(array, values) {
|
|
var index = -1,
|
|
length = values.length,
|
|
offset = array.length;
|
|
|
|
while (++index < length) {
|
|
array[offset + index] = values[index];
|
|
}
|
|
return array;
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `_.reduce` for arrays without support for
|
|
* iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Array} [array] The array to iterate over.
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|
* @param {*} [accumulator] The initial value.
|
|
* @param {boolean} [initAccum] Specify using the first element of `array` as
|
|
* the initial value.
|
|
* @returns {*} Returns the accumulated value.
|
|
*/
|
|
function arrayReduce(array, iteratee, accumulator, initAccum) {
|
|
var index = -1,
|
|
length = array == null ? 0 : array.length;
|
|
|
|
if (initAccum && length) {
|
|
accumulator = array[++index];
|
|
}
|
|
while (++index < length) {
|
|
accumulator = iteratee(accumulator, array[index], index, array);
|
|
}
|
|
return accumulator;
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `_.reduceRight` for arrays without support for
|
|
* iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Array} [array] The array to iterate over.
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|
* @param {*} [accumulator] The initial value.
|
|
* @param {boolean} [initAccum] Specify using the last element of `array` as
|
|
* the initial value.
|
|
* @returns {*} Returns the accumulated value.
|
|
*/
|
|
function arrayReduceRight(array, iteratee, accumulator, initAccum) {
|
|
var length = array == null ? 0 : array.length;
|
|
if (initAccum && length) {
|
|
accumulator = array[--length];
|
|
}
|
|
while (length--) {
|
|
accumulator = iteratee(accumulator, array[length], length, array);
|
|
}
|
|
return accumulator;
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `_.some` for arrays without support for iteratee
|
|
* shorthands.
|
|
*
|
|
* @private
|
|
* @param {Array} [array] The array to iterate over.
|
|
* @param {Function} predicate The function invoked per iteration.
|
|
* @returns {boolean} Returns `true` if any element passes the predicate check,
|
|
* else `false`.
|
|
*/
|
|
function arraySome(array, predicate) {
|
|
var index = -1,
|
|
length = array == null ? 0 : array.length;
|
|
|
|
while (++index < length) {
|
|
if (predicate(array[index], index, array)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Gets the size of an ASCII `string`.
|
|
*
|
|
* @private
|
|
* @param {string} string The string inspect.
|
|
* @returns {number} Returns the string size.
|
|
*/
|
|
var asciiSize = baseProperty('length');
|
|
|
|
/**
|
|
* Converts an ASCII `string` to an array.
|
|
*
|
|
* @private
|
|
* @param {string} string The string to convert.
|
|
* @returns {Array} Returns the converted array.
|
|
*/
|
|
function asciiToArray(string) {
|
|
return string.split('');
|
|
}
|
|
|
|
/**
|
|
* Splits an ASCII `string` into an array of its words.
|
|
*
|
|
* @private
|
|
* @param {string} The string to inspect.
|
|
* @returns {Array} Returns the words of `string`.
|
|
*/
|
|
function asciiWords(string) {
|
|
return string.match(reAsciiWord) || [];
|
|
}
|
|
|
|
/**
|
|
* The base implementation of methods like `_.findKey` and `_.findLastKey`,
|
|
* without support for iteratee shorthands, which iterates over `collection`
|
|
* using `eachFunc`.
|
|
*
|
|
* @private
|
|
* @param {Array|Object} collection The collection to inspect.
|
|
* @param {Function} predicate The function invoked per iteration.
|
|
* @param {Function} eachFunc The function to iterate over `collection`.
|
|
* @returns {*} Returns the found element or its key, else `undefined`.
|
|
*/
|
|
function baseFindKey(collection, predicate, eachFunc) {
|
|
var result;
|
|
eachFunc(collection, function(value, key, collection) {
|
|
if (predicate(value, key, collection)) {
|
|
result = key;
|
|
return false;
|
|
}
|
|
});
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.findIndex` and `_.findLastIndex` without
|
|
* support for iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to inspect.
|
|
* @param {Function} predicate The function invoked per iteration.
|
|
* @param {number} fromIndex The index to search from.
|
|
* @param {boolean} [fromRight] Specify iterating from right to left.
|
|
* @returns {number} Returns the index of the matched value, else `-1`.
|
|
*/
|
|
function baseFindIndex(array, predicate, fromIndex, fromRight) {
|
|
var length = array.length,
|
|
index = fromIndex + (fromRight ? 1 : -1);
|
|
|
|
while ((fromRight ? index-- : ++index < length)) {
|
|
if (predicate(array[index], index, array)) {
|
|
return index;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.indexOf` without `fromIndex` bounds checks.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to inspect.
|
|
* @param {*} value The value to search for.
|
|
* @param {number} fromIndex The index to search from.
|
|
* @returns {number} Returns the index of the matched value, else `-1`.
|
|
*/
|
|
function baseIndexOf(array, value, fromIndex) {
|
|
return value === value
|
|
? strictIndexOf(array, value, fromIndex)
|
|
: baseFindIndex(array, baseIsNaN, fromIndex);
|
|
}
|
|
|
|
/**
|
|
* This function is like `baseIndexOf` except that it accepts a comparator.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to inspect.
|
|
* @param {*} value The value to search for.
|
|
* @param {number} fromIndex The index to search from.
|
|
* @param {Function} comparator The comparator invoked per element.
|
|
* @returns {number} Returns the index of the matched value, else `-1`.
|
|
*/
|
|
function baseIndexOfWith(array, value, fromIndex, comparator) {
|
|
var index = fromIndex - 1,
|
|
length = array.length;
|
|
|
|
while (++index < length) {
|
|
if (comparator(array[index], value)) {
|
|
return index;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.isNaN` without support for number objects.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
|
|
*/
|
|
function baseIsNaN(value) {
|
|
return value !== value;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.mean` and `_.meanBy` without support for
|
|
* iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to iterate over.
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|
* @returns {number} Returns the mean.
|
|
*/
|
|
function baseMean(array, iteratee) {
|
|
var length = array == null ? 0 : array.length;
|
|
return length ? (baseSum(array, iteratee) / length) : NAN;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.property` without support for deep paths.
|
|
*
|
|
* @private
|
|
* @param {string} key The key of the property to get.
|
|
* @returns {Function} Returns the new accessor function.
|
|
*/
|
|
function baseProperty(key) {
|
|
return function(object) {
|
|
return object == null ? undefined : object[key];
|
|
};
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.propertyOf` without support for deep paths.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @returns {Function} Returns the new accessor function.
|
|
*/
|
|
function basePropertyOf(object) {
|
|
return function(key) {
|
|
return object == null ? undefined : object[key];
|
|
};
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.reduce` and `_.reduceRight`, without support
|
|
* for iteratee shorthands, which iterates over `collection` using `eachFunc`.
|
|
*
|
|
* @private
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|
* @param {*} accumulator The initial value.
|
|
* @param {boolean} initAccum Specify using the first or last element of
|
|
* `collection` as the initial value.
|
|
* @param {Function} eachFunc The function to iterate over `collection`.
|
|
* @returns {*} Returns the accumulated value.
|
|
*/
|
|
function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {
|
|
eachFunc(collection, function(value, index, collection) {
|
|
accumulator = initAccum
|
|
? (initAccum = false, value)
|
|
: iteratee(accumulator, value, index, collection);
|
|
});
|
|
return accumulator;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.sortBy` which uses `comparer` to define the
|
|
* sort order of `array` and replaces criteria objects with their corresponding
|
|
* values.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to sort.
|
|
* @param {Function} comparer The function to define sort order.
|
|
* @returns {Array} Returns `array`.
|
|
*/
|
|
function baseSortBy(array, comparer) {
|
|
var length = array.length;
|
|
|
|
array.sort(comparer);
|
|
while (length--) {
|
|
array[length] = array[length].value;
|
|
}
|
|
return array;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.sum` and `_.sumBy` without support for
|
|
* iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to iterate over.
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|
* @returns {number} Returns the sum.
|
|
*/
|
|
function baseSum(array, iteratee) {
|
|
var result,
|
|
index = -1,
|
|
length = array.length;
|
|
|
|
while (++index < length) {
|
|
var current = iteratee(array[index]);
|
|
if (current !== undefined) {
|
|
result = result === undefined ? current : (result + current);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.times` without support for iteratee shorthands
|
|
* or max array length checks.
|
|
*
|
|
* @private
|
|
* @param {number} n The number of times to invoke `iteratee`.
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|
* @returns {Array} Returns the array of results.
|
|
*/
|
|
function baseTimes(n, iteratee) {
|
|
var index = -1,
|
|
result = Array(n);
|
|
|
|
while (++index < n) {
|
|
result[index] = iteratee(index);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array
|
|
* of key-value pairs for `object` corresponding to the property names of `props`.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @param {Array} props The property names to get values for.
|
|
* @returns {Object} Returns the key-value pairs.
|
|
*/
|
|
function baseToPairs(object, props) {
|
|
return arrayMap(props, function(key) {
|
|
return [key, object[key]];
|
|
});
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.trim`.
|
|
*
|
|
* @private
|
|
* @param {string} string The string to trim.
|
|
* @returns {string} Returns the trimmed string.
|
|
*/
|
|
function baseTrim(string) {
|
|
return string
|
|
? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, '')
|
|
: string;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.unary` without support for storing metadata.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to cap arguments for.
|
|
* @returns {Function} Returns the new capped function.
|
|
*/
|
|
function baseUnary(func) {
|
|
return function(value) {
|
|
return func(value);
|
|
};
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.values` and `_.valuesIn` which creates an
|
|
* array of `object` property values corresponding to the property names
|
|
* of `props`.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @param {Array} props The property names to get values for.
|
|
* @returns {Object} Returns the array of property values.
|
|
*/
|
|
function baseValues(object, props) {
|
|
return arrayMap(props, function(key) {
|
|
return object[key];
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Checks if a `cache` value for `key` exists.
|
|
*
|
|
* @private
|
|
* @param {Object} cache The cache to query.
|
|
* @param {string} key The key of the entry to check.
|
|
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
|
|
*/
|
|
function cacheHas(cache, key) {
|
|
return cache.has(key);
|
|
}
|
|
|
|
/**
|
|
* Used by `_.trim` and `_.trimStart` to get the index of the first string symbol
|
|
* that is not found in the character symbols.
|
|
*
|
|
* @private
|
|
* @param {Array} strSymbols The string symbols to inspect.
|
|
* @param {Array} chrSymbols The character symbols to find.
|
|
* @returns {number} Returns the index of the first unmatched string symbol.
|
|
*/
|
|
function charsStartIndex(strSymbols, chrSymbols) {
|
|
var index = -1,
|
|
length = strSymbols.length;
|
|
|
|
while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
|
|
return index;
|
|
}
|
|
|
|
/**
|
|
* Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol
|
|
* that is not found in the character symbols.
|
|
*
|
|
* @private
|
|
* @param {Array} strSymbols The string symbols to inspect.
|
|
* @param {Array} chrSymbols The character symbols to find.
|
|
* @returns {number} Returns the index of the last unmatched string symbol.
|
|
*/
|
|
function charsEndIndex(strSymbols, chrSymbols) {
|
|
var index = strSymbols.length;
|
|
|
|
while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
|
|
return index;
|
|
}
|
|
|
|
/**
|
|
* Gets the number of `placeholder` occurrences in `array`.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to inspect.
|
|
* @param {*} placeholder The placeholder to search for.
|
|
* @returns {number} Returns the placeholder count.
|
|
*/
|
|
function countHolders(array, placeholder) {
|
|
var length = array.length,
|
|
result = 0;
|
|
|
|
while (length--) {
|
|
if (array[length] === placeholder) {
|
|
++result;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A
|
|
* letters to basic Latin letters.
|
|
*
|
|
* @private
|
|
* @param {string} letter The matched letter to deburr.
|
|
* @returns {string} Returns the deburred letter.
|
|
*/
|
|
var deburrLetter = basePropertyOf(deburredLetters);
|
|
|
|
/**
|
|
* Used by `_.escape` to convert characters to HTML entities.
|
|
*
|
|
* @private
|
|
* @param {string} chr The matched character to escape.
|
|
* @returns {string} Returns the escaped character.
|
|
*/
|
|
var escapeHtmlChar = basePropertyOf(htmlEscapes);
|
|
|
|
/**
|
|
* Used by `_.template` to escape characters for inclusion in compiled string literals.
|
|
*
|
|
* @private
|
|
* @param {string} chr The matched character to escape.
|
|
* @returns {string} Returns the escaped character.
|
|
*/
|
|
function escapeStringChar(chr) {
|
|
return '\\' + stringEscapes[chr];
|
|
}
|
|
|
|
/**
|
|
* Gets the value at `key` of `object`.
|
|
*
|
|
* @private
|
|
* @param {Object} [object] The object to query.
|
|
* @param {string} key The key of the property to get.
|
|
* @returns {*} Returns the property value.
|
|
*/
|
|
function getValue(object, key) {
|
|
return object == null ? undefined : object[key];
|
|
}
|
|
|
|
/**
|
|
* Checks if `string` contains Unicode symbols.
|
|
*
|
|
* @private
|
|
* @param {string} string The string to inspect.
|
|
* @returns {boolean} Returns `true` if a symbol is found, else `false`.
|
|
*/
|
|
function hasUnicode(string) {
|
|
return reHasUnicode.test(string);
|
|
}
|
|
|
|
/**
|
|
* Checks if `string` contains a word composed of Unicode symbols.
|
|
*
|
|
* @private
|
|
* @param {string} string The string to inspect.
|
|
* @returns {boolean} Returns `true` if a word is found, else `false`.
|
|
*/
|
|
function hasUnicodeWord(string) {
|
|
return reHasUnicodeWord.test(string);
|
|
}
|
|
|
|
/**
|
|
* Converts `iterator` to an array.
|
|
*
|
|
* @private
|
|
* @param {Object} iterator The iterator to convert.
|
|
* @returns {Array} Returns the converted array.
|
|
*/
|
|
function iteratorToArray(iterator) {
|
|
var data,
|
|
result = [];
|
|
|
|
while (!(data = iterator.next()).done) {
|
|
result.push(data.value);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Converts `map` to its key-value pairs.
|
|
*
|
|
* @private
|
|
* @param {Object} map The map to convert.
|
|
* @returns {Array} Returns the key-value pairs.
|
|
*/
|
|
function mapToArray(map) {
|
|
var index = -1,
|
|
result = Array(map.size);
|
|
|
|
map.forEach(function(value, key) {
|
|
result[++index] = [key, value];
|
|
});
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Creates a unary function that invokes `func` with its argument transformed.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to wrap.
|
|
* @param {Function} transform The argument transform.
|
|
* @returns {Function} Returns the new function.
|
|
*/
|
|
function overArg(func, transform) {
|
|
return function(arg) {
|
|
return func(transform(arg));
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Replaces all `placeholder` elements in `array` with an internal placeholder
|
|
* and returns an array of their indexes.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to modify.
|
|
* @param {*} placeholder The placeholder to replace.
|
|
* @returns {Array} Returns the new array of placeholder indexes.
|
|
*/
|
|
function replaceHolders(array, placeholder) {
|
|
var index = -1,
|
|
length = array.length,
|
|
resIndex = 0,
|
|
result = [];
|
|
|
|
while (++index < length) {
|
|
var value = array[index];
|
|
if (value === placeholder || value === PLACEHOLDER) {
|
|
array[index] = PLACEHOLDER;
|
|
result[resIndex++] = index;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Converts `set` to an array of its values.
|
|
*
|
|
* @private
|
|
* @param {Object} set The set to convert.
|
|
* @returns {Array} Returns the values.
|
|
*/
|
|
function setToArray(set) {
|
|
var index = -1,
|
|
result = Array(set.size);
|
|
|
|
set.forEach(function(value) {
|
|
result[++index] = value;
|
|
});
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Converts `set` to its value-value pairs.
|
|
*
|
|
* @private
|
|
* @param {Object} set The set to convert.
|
|
* @returns {Array} Returns the value-value pairs.
|
|
*/
|
|
function setToPairs(set) {
|
|
var index = -1,
|
|
result = Array(set.size);
|
|
|
|
set.forEach(function(value) {
|
|
result[++index] = [value, value];
|
|
});
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `_.indexOf` which performs strict equality
|
|
* comparisons of values, i.e. `===`.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to inspect.
|
|
* @param {*} value The value to search for.
|
|
* @param {number} fromIndex The index to search from.
|
|
* @returns {number} Returns the index of the matched value, else `-1`.
|
|
*/
|
|
function strictIndexOf(array, value, fromIndex) {
|
|
var index = fromIndex - 1,
|
|
length = array.length;
|
|
|
|
while (++index < length) {
|
|
if (array[index] === value) {
|
|
return index;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `_.lastIndexOf` which performs strict equality
|
|
* comparisons of values, i.e. `===`.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to inspect.
|
|
* @param {*} value The value to search for.
|
|
* @param {number} fromIndex The index to search from.
|
|
* @returns {number} Returns the index of the matched value, else `-1`.
|
|
*/
|
|
function strictLastIndexOf(array, value, fromIndex) {
|
|
var index = fromIndex + 1;
|
|
while (index--) {
|
|
if (array[index] === value) {
|
|
return index;
|
|
}
|
|
}
|
|
return index;
|
|
}
|
|
|
|
/**
|
|
* Gets the number of symbols in `string`.
|
|
*
|
|
* @private
|
|
* @param {string} string The string to inspect.
|
|
* @returns {number} Returns the string size.
|
|
*/
|
|
function stringSize(string) {
|
|
return hasUnicode(string)
|
|
? unicodeSize(string)
|
|
: asciiSize(string);
|
|
}
|
|
|
|
/**
|
|
* Converts `string` to an array.
|
|
*
|
|
* @private
|
|
* @param {string} string The string to convert.
|
|
* @returns {Array} Returns the converted array.
|
|
*/
|
|
function stringToArray(string) {
|
|
return hasUnicode(string)
|
|
? unicodeToArray(string)
|
|
: asciiToArray(string);
|
|
}
|
|
|
|
/**
|
|
* Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace
|
|
* character of `string`.
|
|
*
|
|
* @private
|
|
* @param {string} string The string to inspect.
|
|
* @returns {number} Returns the index of the last non-whitespace character.
|
|
*/
|
|
function trimmedEndIndex(string) {
|
|
var index = string.length;
|
|
|
|
while (index-- && reWhitespace.test(string.charAt(index))) {}
|
|
return index;
|
|
}
|
|
|
|
/**
|
|
* Used by `_.unescape` to convert HTML entities to characters.
|
|
*
|
|
* @private
|
|
* @param {string} chr The matched character to unescape.
|
|
* @returns {string} Returns the unescaped character.
|
|
*/
|
|
var unescapeHtmlChar = basePropertyOf(htmlUnescapes);
|
|
|
|
/**
|
|
* Gets the size of a Unicode `string`.
|
|
*
|
|
* @private
|
|
* @param {string} string The string inspect.
|
|
* @returns {number} Returns the string size.
|
|
*/
|
|
function unicodeSize(string) {
|
|
var result = reUnicode.lastIndex = 0;
|
|
while (reUnicode.test(string)) {
|
|
++result;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Converts a Unicode `string` to an array.
|
|
*
|
|
* @private
|
|
* @param {string} string The string to convert.
|
|
* @returns {Array} Returns the converted array.
|
|
*/
|
|
function unicodeToArray(string) {
|
|
return string.match(reUnicode) || [];
|
|
}
|
|
|
|
/**
|
|
* Splits a Unicode `string` into an array of its words.
|
|
*
|
|
* @private
|
|
* @param {string} The string to inspect.
|
|
* @returns {Array} Returns the words of `string`.
|
|
*/
|
|
function unicodeWords(string) {
|
|
return string.match(reUnicodeWord) || [];
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* Create a new pristine `lodash` function using the `context` object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 1.1.0
|
|
* @category Util
|
|
* @param {Object} [context=root] The context object.
|
|
* @returns {Function} Returns a new `lodash` function.
|
|
* @example
|
|
*
|
|
* _.mixin({ 'foo': _.constant('foo') });
|
|
*
|
|
* var lodash = _.runInContext();
|
|
* lodash.mixin({ 'bar': lodash.constant('bar') });
|
|
*
|
|
* _.isFunction(_.foo);
|
|
* // => true
|
|
* _.isFunction(_.bar);
|
|
* // => false
|
|
*
|
|
* lodash.isFunction(lodash.foo);
|
|
* // => false
|
|
* lodash.isFunction(lodash.bar);
|
|
* // => true
|
|
*
|
|
* // Create a suped-up `defer` in Node.js.
|
|
* var defer = _.runInContext({ 'setTimeout': setImmediate }).defer;
|
|
*/
|
|
var runInContext = (function runInContext(context) {
|
|
context = context == null ? root : _.defaults(root.Object(), context, _.pick(root, contextProps));
|
|
|
|
/** Built-in constructor references. */
|
|
var Array = context.Array,
|
|
Date = context.Date,
|
|
Error = context.Error,
|
|
Function = context.Function,
|
|
Math = context.Math,
|
|
Object = context.Object,
|
|
RegExp = context.RegExp,
|
|
String = context.String,
|
|
TypeError = context.TypeError;
|
|
|
|
/** Used for built-in method references. */
|
|
var arrayProto = Array.prototype,
|
|
funcProto = Function.prototype,
|
|
objectProto = Object.prototype;
|
|
|
|
/** Used to detect overreaching core-js shims. */
|
|
var coreJsData = context['__core-js_shared__'];
|
|
|
|
/** Used to resolve the decompiled source of functions. */
|
|
var funcToString = funcProto.toString;
|
|
|
|
/** Used to check objects for own properties. */
|
|
var hasOwnProperty = objectProto.hasOwnProperty;
|
|
|
|
/** Used to generate unique IDs. */
|
|
var idCounter = 0;
|
|
|
|
/** Used to detect methods masquerading as native. */
|
|
var maskSrcKey = (function() {
|
|
var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
|
|
return uid ? ('Symbol(src)_1.' + uid) : '';
|
|
}());
|
|
|
|
/**
|
|
* Used to resolve the
|
|
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
|
|
* of values.
|
|
*/
|
|
var nativeObjectToString = objectProto.toString;
|
|
|
|
/** Used to infer the `Object` constructor. */
|
|
var objectCtorString = funcToString.call(Object);
|
|
|
|
/** Used to restore the original `_` reference in `_.noConflict`. */
|
|
var oldDash = root._;
|
|
|
|
/** Used to detect if a method is native. */
|
|
var reIsNative = RegExp('^' +
|
|
funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
|
|
.replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
|
|
);
|
|
|
|
/** Built-in value references. */
|
|
var Buffer = moduleExports ? context.Buffer : undefined,
|
|
Symbol = context.Symbol,
|
|
Uint8Array = context.Uint8Array,
|
|
allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined,
|
|
getPrototype = overArg(Object.getPrototypeOf, Object),
|
|
objectCreate = Object.create,
|
|
propertyIsEnumerable = objectProto.propertyIsEnumerable,
|
|
splice = arrayProto.splice,
|
|
spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined,
|
|
symIterator = Symbol ? Symbol.iterator : undefined,
|
|
symToStringTag = Symbol ? Symbol.toStringTag : undefined;
|
|
|
|
var defineProperty = (function() {
|
|
try {
|
|
var func = getNative(Object, 'defineProperty');
|
|
func({}, '', {});
|
|
return func;
|
|
} catch (e) {}
|
|
}());
|
|
|
|
/** Mocked built-ins. */
|
|
var ctxClearTimeout = context.clearTimeout !== root.clearTimeout && context.clearTimeout,
|
|
ctxNow = Date && Date.now !== root.Date.now && Date.now,
|
|
ctxSetTimeout = context.setTimeout !== root.setTimeout && context.setTimeout;
|
|
|
|
/* Built-in method references for those with the same name as other `lodash` methods. */
|
|
var nativeCeil = Math.ceil,
|
|
nativeFloor = Math.floor,
|
|
nativeGetSymbols = Object.getOwnPropertySymbols,
|
|
nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined,
|
|
nativeIsFinite = context.isFinite,
|
|
nativeJoin = arrayProto.join,
|
|
nativeKeys = overArg(Object.keys, Object),
|
|
nativeMax = Math.max,
|
|
nativeMin = Math.min,
|
|
nativeNow = Date.now,
|
|
nativeParseInt = context.parseInt,
|
|
nativeRandom = Math.random,
|
|
nativeReverse = arrayProto.reverse;
|
|
|
|
/* Built-in method references that are verified to be native. */
|
|
var DataView = getNative(context, 'DataView'),
|
|
Map = getNative(context, 'Map'),
|
|
Promise = getNative(context, 'Promise'),
|
|
Set = getNative(context, 'Set'),
|
|
WeakMap = getNative(context, 'WeakMap'),
|
|
nativeCreate = getNative(Object, 'create');
|
|
|
|
/** Used to store function metadata. */
|
|
var metaMap = WeakMap && new WeakMap;
|
|
|
|
/** Used to lookup unminified function names. */
|
|
var realNames = {};
|
|
|
|
/** Used to detect maps, sets, and weakmaps. */
|
|
var dataViewCtorString = toSource(DataView),
|
|
mapCtorString = toSource(Map),
|
|
promiseCtorString = toSource(Promise),
|
|
setCtorString = toSource(Set),
|
|
weakMapCtorString = toSource(WeakMap);
|
|
|
|
/** Used to convert symbols to primitives and strings. */
|
|
var symbolProto = Symbol ? Symbol.prototype : undefined,
|
|
symbolValueOf = symbolProto ? symbolProto.valueOf : undefined,
|
|
symbolToString = symbolProto ? symbolProto.toString : undefined;
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* Creates a `lodash` object which wraps `value` to enable implicit method
|
|
* chain sequences. Methods that operate on and return arrays, collections,
|
|
* and functions can be chained together. Methods that retrieve a single value
|
|
* or may return a primitive value will automatically end the chain sequence
|
|
* and return the unwrapped value. Otherwise, the value must be unwrapped
|
|
* with `_#value`.
|
|
*
|
|
* Explicit chain sequences, which must be unwrapped with `_#value`, may be
|
|
* enabled using `_.chain`.
|
|
*
|
|
* The execution of chained methods is lazy, that is, it's deferred until
|
|
* `_#value` is implicitly or explicitly called.
|
|
*
|
|
* Lazy evaluation allows several methods to support shortcut fusion.
|
|
* Shortcut fusion is an optimization to merge iteratee calls; this avoids
|
|
* the creation of intermediate arrays and can greatly reduce the number of
|
|
* iteratee executions. Sections of a chain sequence qualify for shortcut
|
|
* fusion if the section is applied to an array and iteratees accept only
|
|
* one argument. The heuristic for whether a section qualifies for shortcut
|
|
* fusion is subject to change.
|
|
*
|
|
* Chaining is supported in custom builds as long as the `_#value` method is
|
|
* directly or indirectly included in the build.
|
|
*
|
|
* In addition to lodash methods, wrappers have `Array` and `String` methods.
|
|
*
|
|
* The wrapper `Array` methods are:
|
|
* `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`
|
|
*
|
|
* The wrapper `String` methods are:
|
|
* `replace` and `split`
|
|
*
|
|
* The wrapper methods that support shortcut fusion are:
|
|
* `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,
|
|
* `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,
|
|
* `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`
|
|
*
|
|
* The chainable wrapper methods are:
|
|
* `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`,
|
|
* `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`,
|
|
* `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`,
|
|
* `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`,
|
|
* `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`,
|
|
* `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`,
|
|
* `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`,
|
|
* `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`,
|
|
* `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`,
|
|
* `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`,
|
|
* `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`,
|
|
* `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`,
|
|
* `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`,
|
|
* `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`,
|
|
* `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`,
|
|
* `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`,
|
|
* `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`,
|
|
* `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`,
|
|
* `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`,
|
|
* `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`,
|
|
* `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`,
|
|
* `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`,
|
|
* `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`,
|
|
* `zipObject`, `zipObjectDeep`, and `zipWith`
|
|
*
|
|
* The wrapper methods that are **not** chainable by default are:
|
|
* `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,
|
|
* `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`,
|
|
* `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`,
|
|
* `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`,
|
|
* `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`,
|
|
* `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`,
|
|
* `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`,
|
|
* `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`,
|
|
* `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`,
|
|
* `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`,
|
|
* `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`,
|
|
* `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`,
|
|
* `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`,
|
|
* `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`,
|
|
* `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`,
|
|
* `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`,
|
|
* `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`,
|
|
* `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`,
|
|
* `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`,
|
|
* `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`,
|
|
* `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`,
|
|
* `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`,
|
|
* `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`,
|
|
* `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`,
|
|
* `upperFirst`, `value`, and `words`
|
|
*
|
|
* @name _
|
|
* @constructor
|
|
* @category Seq
|
|
* @param {*} value The value to wrap in a `lodash` instance.
|
|
* @returns {Object} Returns the new `lodash` wrapper instance.
|
|
* @example
|
|
*
|
|
* function square(n) {
|
|
* return n * n;
|
|
* }
|
|
*
|
|
* var wrapped = _([1, 2, 3]);
|
|
*
|
|
* // Returns an unwrapped value.
|
|
* wrapped.reduce(_.add);
|
|
* // => 6
|
|
*
|
|
* // Returns a wrapped value.
|
|
* var squares = wrapped.map(square);
|
|
*
|
|
* _.isArray(squares);
|
|
* // => false
|
|
*
|
|
* _.isArray(squares.value());
|
|
* // => true
|
|
*/
|
|
function lodash(value) {
|
|
if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
|
|
if (value instanceof LodashWrapper) {
|
|
return value;
|
|
}
|
|
if (hasOwnProperty.call(value, '__wrapped__')) {
|
|
return wrapperClone(value);
|
|
}
|
|
}
|
|
return new LodashWrapper(value);
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.create` without support for assigning
|
|
* properties to the created object.
|
|
*
|
|
* @private
|
|
* @param {Object} proto The object to inherit from.
|
|
* @returns {Object} Returns the new object.
|
|
*/
|
|
var baseCreate = (function() {
|
|
function object() {}
|
|
return function(proto) {
|
|
if (!isObject(proto)) {
|
|
return {};
|
|
}
|
|
if (objectCreate) {
|
|
return objectCreate(proto);
|
|
}
|
|
object.prototype = proto;
|
|
var result = new object;
|
|
object.prototype = undefined;
|
|
return result;
|
|
};
|
|
}());
|
|
|
|
/**
|
|
* The function whose prototype chain sequence wrappers inherit from.
|
|
*
|
|
* @private
|
|
*/
|
|
function baseLodash() {
|
|
// No operation performed.
|
|
}
|
|
|
|
/**
|
|
* The base constructor for creating `lodash` wrapper objects.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to wrap.
|
|
* @param {boolean} [chainAll] Enable explicit method chain sequences.
|
|
*/
|
|
function LodashWrapper(value, chainAll) {
|
|
this.__wrapped__ = value;
|
|
this.__actions__ = [];
|
|
this.__chain__ = !!chainAll;
|
|
this.__index__ = 0;
|
|
this.__values__ = undefined;
|
|
}
|
|
|
|
/**
|
|
* By default, the template delimiters used by lodash are like those in
|
|
* embedded Ruby (ERB) as well as ES2015 template strings. Change the
|
|
* following template settings to use alternative delimiters.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @type {Object}
|
|
*/
|
|
lodash.templateSettings = {
|
|
|
|
/**
|
|
* Used to detect `data` property values to be HTML-escaped.
|
|
*
|
|
* @memberOf _.templateSettings
|
|
* @type {RegExp}
|
|
*/
|
|
'escape': reEscape,
|
|
|
|
/**
|
|
* Used to detect code to be evaluated.
|
|
*
|
|
* @memberOf _.templateSettings
|
|
* @type {RegExp}
|
|
*/
|
|
'evaluate': reEvaluate,
|
|
|
|
/**
|
|
* Used to detect `data` property values to inject.
|
|
*
|
|
* @memberOf _.templateSettings
|
|
* @type {RegExp}
|
|
*/
|
|
'interpolate': reInterpolate,
|
|
|
|
/**
|
|
* Used to reference the data object in the template text.
|
|
*
|
|
* @memberOf _.templateSettings
|
|
* @type {string}
|
|
*/
|
|
'variable': '',
|
|
|
|
/**
|
|
* Used to import variables into the compiled template.
|
|
*
|
|
* @memberOf _.templateSettings
|
|
* @type {Object}
|
|
*/
|
|
'imports': {
|
|
|
|
/**
|
|
* A reference to the `lodash` function.
|
|
*
|
|
* @memberOf _.templateSettings.imports
|
|
* @type {Function}
|
|
*/
|
|
'_': lodash
|
|
}
|
|
};
|
|
|
|
// Ensure wrappers are instances of `baseLodash`.
|
|
lodash.prototype = baseLodash.prototype;
|
|
lodash.prototype.constructor = lodash;
|
|
|
|
LodashWrapper.prototype = baseCreate(baseLodash.prototype);
|
|
LodashWrapper.prototype.constructor = LodashWrapper;
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
|
|
*
|
|
* @private
|
|
* @constructor
|
|
* @param {*} value The value to wrap.
|
|
*/
|
|
function LazyWrapper(value) {
|
|
this.__wrapped__ = value;
|
|
this.__actions__ = [];
|
|
this.__dir__ = 1;
|
|
this.__filtered__ = false;
|
|
this.__iteratees__ = [];
|
|
this.__takeCount__ = MAX_ARRAY_LENGTH;
|
|
this.__views__ = [];
|
|
}
|
|
|
|
/**
|
|
* Creates a clone of the lazy wrapper object.
|
|
*
|
|
* @private
|
|
* @name clone
|
|
* @memberOf LazyWrapper
|
|
* @returns {Object} Returns the cloned `LazyWrapper` object.
|
|
*/
|
|
function lazyClone() {
|
|
var result = new LazyWrapper(this.__wrapped__);
|
|
result.__actions__ = copyArray(this.__actions__);
|
|
result.__dir__ = this.__dir__;
|
|
result.__filtered__ = this.__filtered__;
|
|
result.__iteratees__ = copyArray(this.__iteratees__);
|
|
result.__takeCount__ = this.__takeCount__;
|
|
result.__views__ = copyArray(this.__views__);
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Reverses the direction of lazy iteration.
|
|
*
|
|
* @private
|
|
* @name reverse
|
|
* @memberOf LazyWrapper
|
|
* @returns {Object} Returns the new reversed `LazyWrapper` object.
|
|
*/
|
|
function lazyReverse() {
|
|
if (this.__filtered__) {
|
|
var result = new LazyWrapper(this);
|
|
result.__dir__ = -1;
|
|
result.__filtered__ = true;
|
|
} else {
|
|
result = this.clone();
|
|
result.__dir__ *= -1;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Extracts the unwrapped value from its lazy wrapper.
|
|
*
|
|
* @private
|
|
* @name value
|
|
* @memberOf LazyWrapper
|
|
* @returns {*} Returns the unwrapped value.
|
|
*/
|
|
function lazyValue() {
|
|
var array = this.__wrapped__.value(),
|
|
dir = this.__dir__,
|
|
isArr = isArray(array),
|
|
isRight = dir < 0,
|
|
arrLength = isArr ? array.length : 0,
|
|
view = getView(0, arrLength, this.__views__),
|
|
start = view.start,
|
|
end = view.end,
|
|
length = end - start,
|
|
index = isRight ? end : (start - 1),
|
|
iteratees = this.__iteratees__,
|
|
iterLength = iteratees.length,
|
|
resIndex = 0,
|
|
takeCount = nativeMin(length, this.__takeCount__);
|
|
|
|
if (!isArr || (!isRight && arrLength == length && takeCount == length)) {
|
|
return baseWrapperValue(array, this.__actions__);
|
|
}
|
|
var result = [];
|
|
|
|
outer:
|
|
while (length-- && resIndex < takeCount) {
|
|
index += dir;
|
|
|
|
var iterIndex = -1,
|
|
value = array[index];
|
|
|
|
while (++iterIndex < iterLength) {
|
|
var data = iteratees[iterIndex],
|
|
iteratee = data.iteratee,
|
|
type = data.type,
|
|
computed = iteratee(value);
|
|
|
|
if (type == LAZY_MAP_FLAG) {
|
|
value = computed;
|
|
} else if (!computed) {
|
|
if (type == LAZY_FILTER_FLAG) {
|
|
continue outer;
|
|
} else {
|
|
break outer;
|
|
}
|
|
}
|
|
}
|
|
result[resIndex++] = value;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
// Ensure `LazyWrapper` is an instance of `baseLodash`.
|
|
LazyWrapper.prototype = baseCreate(baseLodash.prototype);
|
|
LazyWrapper.prototype.constructor = LazyWrapper;
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* Creates a hash object.
|
|
*
|
|
* @private
|
|
* @constructor
|
|
* @param {Array} [entries] The key-value pairs to cache.
|
|
*/
|
|
function Hash(entries) {
|
|
var index = -1,
|
|
length = entries == null ? 0 : entries.length;
|
|
|
|
this.clear();
|
|
while (++index < length) {
|
|
var entry = entries[index];
|
|
this.set(entry[0], entry[1]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Removes all key-value entries from the hash.
|
|
*
|
|
* @private
|
|
* @name clear
|
|
* @memberOf Hash
|
|
*/
|
|
function hashClear() {
|
|
this.__data__ = nativeCreate ? nativeCreate(null) : {};
|
|
this.size = 0;
|
|
}
|
|
|
|
/**
|
|
* Removes `key` and its value from the hash.
|
|
*
|
|
* @private
|
|
* @name delete
|
|
* @memberOf Hash
|
|
* @param {Object} hash The hash to modify.
|
|
* @param {string} key The key of the value to remove.
|
|
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
|
|
*/
|
|
function hashDelete(key) {
|
|
var result = this.has(key) && delete this.__data__[key];
|
|
this.size -= result ? 1 : 0;
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Gets the hash value for `key`.
|
|
*
|
|
* @private
|
|
* @name get
|
|
* @memberOf Hash
|
|
* @param {string} key The key of the value to get.
|
|
* @returns {*} Returns the entry value.
|
|
*/
|
|
function hashGet(key) {
|
|
var data = this.__data__;
|
|
if (nativeCreate) {
|
|
var result = data[key];
|
|
return result === HASH_UNDEFINED ? undefined : result;
|
|
}
|
|
return hasOwnProperty.call(data, key) ? data[key] : undefined;
|
|
}
|
|
|
|
/**
|
|
* Checks if a hash value for `key` exists.
|
|
*
|
|
* @private
|
|
* @name has
|
|
* @memberOf Hash
|
|
* @param {string} key The key of the entry to check.
|
|
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
|
|
*/
|
|
function hashHas(key) {
|
|
var data = this.__data__;
|
|
return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);
|
|
}
|
|
|
|
/**
|
|
* Sets the hash `key` to `value`.
|
|
*
|
|
* @private
|
|
* @name set
|
|
* @memberOf Hash
|
|
* @param {string} key The key of the value to set.
|
|
* @param {*} value The value to set.
|
|
* @returns {Object} Returns the hash instance.
|
|
*/
|
|
function hashSet(key, value) {
|
|
var data = this.__data__;
|
|
this.size += this.has(key) ? 0 : 1;
|
|
data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
|
|
return this;
|
|
}
|
|
|
|
// Add methods to `Hash`.
|
|
Hash.prototype.clear = hashClear;
|
|
Hash.prototype['delete'] = hashDelete;
|
|
Hash.prototype.get = hashGet;
|
|
Hash.prototype.has = hashHas;
|
|
Hash.prototype.set = hashSet;
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* Creates an list cache object.
|
|
*
|
|
* @private
|
|
* @constructor
|
|
* @param {Array} [entries] The key-value pairs to cache.
|
|
*/
|
|
function ListCache(entries) {
|
|
var index = -1,
|
|
length = entries == null ? 0 : entries.length;
|
|
|
|
this.clear();
|
|
while (++index < length) {
|
|
var entry = entries[index];
|
|
this.set(entry[0], entry[1]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Removes all key-value entries from the list cache.
|
|
*
|
|
* @private
|
|
* @name clear
|
|
* @memberOf ListCache
|
|
*/
|
|
function listCacheClear() {
|
|
this.__data__ = [];
|
|
this.size = 0;
|
|
}
|
|
|
|
/**
|
|
* Removes `key` and its value from the list cache.
|
|
*
|
|
* @private
|
|
* @name delete
|
|
* @memberOf ListCache
|
|
* @param {string} key The key of the value to remove.
|
|
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
|
|
*/
|
|
function listCacheDelete(key) {
|
|
var data = this.__data__,
|
|
index = assocIndexOf(data, key);
|
|
|
|
if (index < 0) {
|
|
return false;
|
|
}
|
|
var lastIndex = data.length - 1;
|
|
if (index == lastIndex) {
|
|
data.pop();
|
|
} else {
|
|
splice.call(data, index, 1);
|
|
}
|
|
--this.size;
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Gets the list cache value for `key`.
|
|
*
|
|
* @private
|
|
* @name get
|
|
* @memberOf ListCache
|
|
* @param {string} key The key of the value to get.
|
|
* @returns {*} Returns the entry value.
|
|
*/
|
|
function listCacheGet(key) {
|
|
var data = this.__data__,
|
|
index = assocIndexOf(data, key);
|
|
|
|
return index < 0 ? undefined : data[index][1];
|
|
}
|
|
|
|
/**
|
|
* Checks if a list cache value for `key` exists.
|
|
*
|
|
* @private
|
|
* @name has
|
|
* @memberOf ListCache
|
|
* @param {string} key The key of the entry to check.
|
|
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
|
|
*/
|
|
function listCacheHas(key) {
|
|
return assocIndexOf(this.__data__, key) > -1;
|
|
}
|
|
|
|
/**
|
|
* Sets the list cache `key` to `value`.
|
|
*
|
|
* @private
|
|
* @name set
|
|
* @memberOf ListCache
|
|
* @param {string} key The key of the value to set.
|
|
* @param {*} value The value to set.
|
|
* @returns {Object} Returns the list cache instance.
|
|
*/
|
|
function listCacheSet(key, value) {
|
|
var data = this.__data__,
|
|
index = assocIndexOf(data, key);
|
|
|
|
if (index < 0) {
|
|
++this.size;
|
|
data.push([key, value]);
|
|
} else {
|
|
data[index][1] = value;
|
|
}
|
|
return this;
|
|
}
|
|
|
|
// Add methods to `ListCache`.
|
|
ListCache.prototype.clear = listCacheClear;
|
|
ListCache.prototype['delete'] = listCacheDelete;
|
|
ListCache.prototype.get = listCacheGet;
|
|
ListCache.prototype.has = listCacheHas;
|
|
ListCache.prototype.set = listCacheSet;
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* Creates a map cache object to store key-value pairs.
|
|
*
|
|
* @private
|
|
* @constructor
|
|
* @param {Array} [entries] The key-value pairs to cache.
|
|
*/
|
|
function MapCache(entries) {
|
|
var index = -1,
|
|
length = entries == null ? 0 : entries.length;
|
|
|
|
this.clear();
|
|
while (++index < length) {
|
|
var entry = entries[index];
|
|
this.set(entry[0], entry[1]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Removes all key-value entries from the map.
|
|
*
|
|
* @private
|
|
* @name clear
|
|
* @memberOf MapCache
|
|
*/
|
|
function mapCacheClear() {
|
|
this.size = 0;
|
|
this.__data__ = {
|
|
'hash': new Hash,
|
|
'map': new (Map || ListCache),
|
|
'string': new Hash
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Removes `key` and its value from the map.
|
|
*
|
|
* @private
|
|
* @name delete
|
|
* @memberOf MapCache
|
|
* @param {string} key The key of the value to remove.
|
|
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
|
|
*/
|
|
function mapCacheDelete(key) {
|
|
var result = getMapData(this, key)['delete'](key);
|
|
this.size -= result ? 1 : 0;
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Gets the map value for `key`.
|
|
*
|
|
* @private
|
|
* @name get
|
|
* @memberOf MapCache
|
|
* @param {string} key The key of the value to get.
|
|
* @returns {*} Returns the entry value.
|
|
*/
|
|
function mapCacheGet(key) {
|
|
return getMapData(this, key).get(key);
|
|
}
|
|
|
|
/**
|
|
* Checks if a map value for `key` exists.
|
|
*
|
|
* @private
|
|
* @name has
|
|
* @memberOf MapCache
|
|
* @param {string} key The key of the entry to check.
|
|
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
|
|
*/
|
|
function mapCacheHas(key) {
|
|
return getMapData(this, key).has(key);
|
|
}
|
|
|
|
/**
|
|
* Sets the map `key` to `value`.
|
|
*
|
|
* @private
|
|
* @name set
|
|
* @memberOf MapCache
|
|
* @param {string} key The key of the value to set.
|
|
* @param {*} value The value to set.
|
|
* @returns {Object} Returns the map cache instance.
|
|
*/
|
|
function mapCacheSet(key, value) {
|
|
var data = getMapData(this, key),
|
|
size = data.size;
|
|
|
|
data.set(key, value);
|
|
this.size += data.size == size ? 0 : 1;
|
|
return this;
|
|
}
|
|
|
|
// Add methods to `MapCache`.
|
|
MapCache.prototype.clear = mapCacheClear;
|
|
MapCache.prototype['delete'] = mapCacheDelete;
|
|
MapCache.prototype.get = mapCacheGet;
|
|
MapCache.prototype.has = mapCacheHas;
|
|
MapCache.prototype.set = mapCacheSet;
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
*
|
|
* Creates an array cache object to store unique values.
|
|
*
|
|
* @private
|
|
* @constructor
|
|
* @param {Array} [values] The values to cache.
|
|
*/
|
|
function SetCache(values) {
|
|
var index = -1,
|
|
length = values == null ? 0 : values.length;
|
|
|
|
this.__data__ = new MapCache;
|
|
while (++index < length) {
|
|
this.add(values[index]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Adds `value` to the array cache.
|
|
*
|
|
* @private
|
|
* @name add
|
|
* @memberOf SetCache
|
|
* @alias push
|
|
* @param {*} value The value to cache.
|
|
* @returns {Object} Returns the cache instance.
|
|
*/
|
|
function setCacheAdd(value) {
|
|
this.__data__.set(value, HASH_UNDEFINED);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is in the array cache.
|
|
*
|
|
* @private
|
|
* @name has
|
|
* @memberOf SetCache
|
|
* @param {*} value The value to search for.
|
|
* @returns {number} Returns `true` if `value` is found, else `false`.
|
|
*/
|
|
function setCacheHas(value) {
|
|
return this.__data__.has(value);
|
|
}
|
|
|
|
// Add methods to `SetCache`.
|
|
SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;
|
|
SetCache.prototype.has = setCacheHas;
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* Creates a stack cache object to store key-value pairs.
|
|
*
|
|
* @private
|
|
* @constructor
|
|
* @param {Array} [entries] The key-value pairs to cache.
|
|
*/
|
|
function Stack(entries) {
|
|
var data = this.__data__ = new ListCache(entries);
|
|
this.size = data.size;
|
|
}
|
|
|
|
/**
|
|
* Removes all key-value entries from the stack.
|
|
*
|
|
* @private
|
|
* @name clear
|
|
* @memberOf Stack
|
|
*/
|
|
function stackClear() {
|
|
this.__data__ = new ListCache;
|
|
this.size = 0;
|
|
}
|
|
|
|
/**
|
|
* Removes `key` and its value from the stack.
|
|
*
|
|
* @private
|
|
* @name delete
|
|
* @memberOf Stack
|
|
* @param {string} key The key of the value to remove.
|
|
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
|
|
*/
|
|
function stackDelete(key) {
|
|
var data = this.__data__,
|
|
result = data['delete'](key);
|
|
|
|
this.size = data.size;
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Gets the stack value for `key`.
|
|
*
|
|
* @private
|
|
* @name get
|
|
* @memberOf Stack
|
|
* @param {string} key The key of the value to get.
|
|
* @returns {*} Returns the entry value.
|
|
*/
|
|
function stackGet(key) {
|
|
return this.__data__.get(key);
|
|
}
|
|
|
|
/**
|
|
* Checks if a stack value for `key` exists.
|
|
*
|
|
* @private
|
|
* @name has
|
|
* @memberOf Stack
|
|
* @param {string} key The key of the entry to check.
|
|
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
|
|
*/
|
|
function stackHas(key) {
|
|
return this.__data__.has(key);
|
|
}
|
|
|
|
/**
|
|
* Sets the stack `key` to `value`.
|
|
*
|
|
* @private
|
|
* @name set
|
|
* @memberOf Stack
|
|
* @param {string} key The key of the value to set.
|
|
* @param {*} value The value to set.
|
|
* @returns {Object} Returns the stack cache instance.
|
|
*/
|
|
function stackSet(key, value) {
|
|
var data = this.__data__;
|
|
if (data instanceof ListCache) {
|
|
var pairs = data.__data__;
|
|
if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
|
|
pairs.push([key, value]);
|
|
this.size = ++data.size;
|
|
return this;
|
|
}
|
|
data = this.__data__ = new MapCache(pairs);
|
|
}
|
|
data.set(key, value);
|
|
this.size = data.size;
|
|
return this;
|
|
}
|
|
|
|
// Add methods to `Stack`.
|
|
Stack.prototype.clear = stackClear;
|
|
Stack.prototype['delete'] = stackDelete;
|
|
Stack.prototype.get = stackGet;
|
|
Stack.prototype.has = stackHas;
|
|
Stack.prototype.set = stackSet;
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* Creates an array of the enumerable property names of the array-like `value`.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to query.
|
|
* @param {boolean} inherited Specify returning inherited property names.
|
|
* @returns {Array} Returns the array of property names.
|
|
*/
|
|
function arrayLikeKeys(value, inherited) {
|
|
var isArr = isArray(value),
|
|
isArg = !isArr && isArguments(value),
|
|
isBuff = !isArr && !isArg && isBuffer(value),
|
|
isType = !isArr && !isArg && !isBuff && isTypedArray(value),
|
|
skipIndexes = isArr || isArg || isBuff || isType,
|
|
result = skipIndexes ? baseTimes(value.length, String) : [],
|
|
length = result.length;
|
|
|
|
for (var key in value) {
|
|
if ((inherited || hasOwnProperty.call(value, key)) &&
|
|
!(skipIndexes && (
|
|
// Safari 9 has enumerable `arguments.length` in strict mode.
|
|
key == 'length' ||
|
|
// Node.js 0.10 has enumerable non-index properties on buffers.
|
|
(isBuff && (key == 'offset' || key == 'parent')) ||
|
|
// PhantomJS 2 has enumerable non-index properties on typed arrays.
|
|
(isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||
|
|
// Skip index properties.
|
|
isIndex(key, length)
|
|
))) {
|
|
result.push(key);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `_.sample` for arrays.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to sample.
|
|
* @returns {*} Returns the random element.
|
|
*/
|
|
function arraySample(array) {
|
|
var length = array.length;
|
|
return length ? array[baseRandom(0, length - 1)] : undefined;
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `_.sampleSize` for arrays.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to sample.
|
|
* @param {number} n The number of elements to sample.
|
|
* @returns {Array} Returns the random elements.
|
|
*/
|
|
function arraySampleSize(array, n) {
|
|
return shuffleSelf(copyArray(array), baseClamp(n, 0, array.length));
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `_.shuffle` for arrays.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to shuffle.
|
|
* @returns {Array} Returns the new shuffled array.
|
|
*/
|
|
function arrayShuffle(array) {
|
|
return shuffleSelf(copyArray(array));
|
|
}
|
|
|
|
/**
|
|
* This function is like `assignValue` except that it doesn't assign
|
|
* `undefined` values.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to modify.
|
|
* @param {string} key The key of the property to assign.
|
|
* @param {*} value The value to assign.
|
|
*/
|
|
function assignMergeValue(object, key, value) {
|
|
if ((value !== undefined && !eq(object[key], value)) ||
|
|
(value === undefined && !(key in object))) {
|
|
baseAssignValue(object, key, value);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Assigns `value` to `key` of `object` if the existing value is not equivalent
|
|
* using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
|
|
* for equality comparisons.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to modify.
|
|
* @param {string} key The key of the property to assign.
|
|
* @param {*} value The value to assign.
|
|
*/
|
|
function assignValue(object, key, value) {
|
|
var objValue = object[key];
|
|
if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||
|
|
(value === undefined && !(key in object))) {
|
|
baseAssignValue(object, key, value);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets the index at which the `key` is found in `array` of key-value pairs.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to inspect.
|
|
* @param {*} key The key to search for.
|
|
* @returns {number} Returns the index of the matched value, else `-1`.
|
|
*/
|
|
function assocIndexOf(array, key) {
|
|
var length = array.length;
|
|
while (length--) {
|
|
if (eq(array[length][0], key)) {
|
|
return length;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* Aggregates elements of `collection` on `accumulator` with keys transformed
|
|
* by `iteratee` and values set by `setter`.
|
|
*
|
|
* @private
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function} setter The function to set `accumulator` values.
|
|
* @param {Function} iteratee The iteratee to transform keys.
|
|
* @param {Object} accumulator The initial aggregated object.
|
|
* @returns {Function} Returns `accumulator`.
|
|
*/
|
|
function baseAggregator(collection, setter, iteratee, accumulator) {
|
|
baseEach(collection, function(value, key, collection) {
|
|
setter(accumulator, value, iteratee(value), collection);
|
|
});
|
|
return accumulator;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.assign` without support for multiple sources
|
|
* or `customizer` functions.
|
|
*
|
|
* @private
|
|
* @param {Object} object The destination object.
|
|
* @param {Object} source The source object.
|
|
* @returns {Object} Returns `object`.
|
|
*/
|
|
function baseAssign(object, source) {
|
|
return object && copyObject(source, keys(source), object);
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.assignIn` without support for multiple sources
|
|
* or `customizer` functions.
|
|
*
|
|
* @private
|
|
* @param {Object} object The destination object.
|
|
* @param {Object} source The source object.
|
|
* @returns {Object} Returns `object`.
|
|
*/
|
|
function baseAssignIn(object, source) {
|
|
return object && copyObject(source, keysIn(source), object);
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `assignValue` and `assignMergeValue` without
|
|
* value checks.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to modify.
|
|
* @param {string} key The key of the property to assign.
|
|
* @param {*} value The value to assign.
|
|
*/
|
|
function baseAssignValue(object, key, value) {
|
|
if (key == '__proto__' && defineProperty) {
|
|
defineProperty(object, key, {
|
|
'configurable': true,
|
|
'enumerable': true,
|
|
'value': value,
|
|
'writable': true
|
|
});
|
|
} else {
|
|
object[key] = value;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.at` without support for individual paths.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to iterate over.
|
|
* @param {string[]} paths The property paths to pick.
|
|
* @returns {Array} Returns the picked elements.
|
|
*/
|
|
function baseAt(object, paths) {
|
|
var index = -1,
|
|
length = paths.length,
|
|
result = Array(length),
|
|
skip = object == null;
|
|
|
|
while (++index < length) {
|
|
result[index] = skip ? undefined : get(object, paths[index]);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.clamp` which doesn't coerce arguments.
|
|
*
|
|
* @private
|
|
* @param {number} number The number to clamp.
|
|
* @param {number} [lower] The lower bound.
|
|
* @param {number} upper The upper bound.
|
|
* @returns {number} Returns the clamped number.
|
|
*/
|
|
function baseClamp(number, lower, upper) {
|
|
if (number === number) {
|
|
if (upper !== undefined) {
|
|
number = number <= upper ? number : upper;
|
|
}
|
|
if (lower !== undefined) {
|
|
number = number >= lower ? number : lower;
|
|
}
|
|
}
|
|
return number;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.clone` and `_.cloneDeep` which tracks
|
|
* traversed objects.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to clone.
|
|
* @param {boolean} bitmask The bitmask flags.
|
|
* 1 - Deep clone
|
|
* 2 - Flatten inherited properties
|
|
* 4 - Clone symbols
|
|
* @param {Function} [customizer] The function to customize cloning.
|
|
* @param {string} [key] The key of `value`.
|
|
* @param {Object} [object] The parent object of `value`.
|
|
* @param {Object} [stack] Tracks traversed objects and their clone counterparts.
|
|
* @returns {*} Returns the cloned value.
|
|
*/
|
|
function baseClone(value, bitmask, customizer, key, object, stack) {
|
|
var result,
|
|
isDeep = bitmask & CLONE_DEEP_FLAG,
|
|
isFlat = bitmask & CLONE_FLAT_FLAG,
|
|
isFull = bitmask & CLONE_SYMBOLS_FLAG;
|
|
|
|
if (customizer) {
|
|
result = object ? customizer(value, key, object, stack) : customizer(value);
|
|
}
|
|
if (result !== undefined) {
|
|
return result;
|
|
}
|
|
if (!isObject(value)) {
|
|
return value;
|
|
}
|
|
var isArr = isArray(value);
|
|
if (isArr) {
|
|
result = initCloneArray(value);
|
|
if (!isDeep) {
|
|
return copyArray(value, result);
|
|
}
|
|
} else {
|
|
var tag = getTag(value),
|
|
isFunc = tag == funcTag || tag == genTag;
|
|
|
|
if (isBuffer(value)) {
|
|
return cloneBuffer(value, isDeep);
|
|
}
|
|
if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
|
|
result = (isFlat || isFunc) ? {} : initCloneObject(value);
|
|
if (!isDeep) {
|
|
return isFlat
|
|
? copySymbolsIn(value, baseAssignIn(result, value))
|
|
: copySymbols(value, baseAssign(result, value));
|
|
}
|
|
} else {
|
|
if (!cloneableTags[tag]) {
|
|
return object ? value : {};
|
|
}
|
|
result = initCloneByTag(value, tag, isDeep);
|
|
}
|
|
}
|
|
// Check for circular references and return its corresponding clone.
|
|
stack || (stack = new Stack);
|
|
var stacked = stack.get(value);
|
|
if (stacked) {
|
|
return stacked;
|
|
}
|
|
stack.set(value, result);
|
|
|
|
if (isSet(value)) {
|
|
value.forEach(function(subValue) {
|
|
result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack));
|
|
});
|
|
} else if (isMap(value)) {
|
|
value.forEach(function(subValue, key) {
|
|
result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack));
|
|
});
|
|
}
|
|
|
|
var keysFunc = isFull
|
|
? (isFlat ? getAllKeysIn : getAllKeys)
|
|
: (isFlat ? keysIn : keys);
|
|
|
|
var props = isArr ? undefined : keysFunc(value);
|
|
arrayEach(props || value, function(subValue, key) {
|
|
if (props) {
|
|
key = subValue;
|
|
subValue = value[key];
|
|
}
|
|
// Recursively populate clone (susceptible to call stack limits).
|
|
assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));
|
|
});
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.conforms` which doesn't clone `source`.
|
|
*
|
|
* @private
|
|
* @param {Object} source The object of property predicates to conform to.
|
|
* @returns {Function} Returns the new spec function.
|
|
*/
|
|
function baseConforms(source) {
|
|
var props = keys(source);
|
|
return function(object) {
|
|
return baseConformsTo(object, source, props);
|
|
};
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.conformsTo` which accepts `props` to check.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to inspect.
|
|
* @param {Object} source The object of property predicates to conform to.
|
|
* @returns {boolean} Returns `true` if `object` conforms, else `false`.
|
|
*/
|
|
function baseConformsTo(object, source, props) {
|
|
var length = props.length;
|
|
if (object == null) {
|
|
return !length;
|
|
}
|
|
object = Object(object);
|
|
while (length--) {
|
|
var key = props[length],
|
|
predicate = source[key],
|
|
value = object[key];
|
|
|
|
if ((value === undefined && !(key in object)) || !predicate(value)) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.delay` and `_.defer` which accepts `args`
|
|
* to provide to `func`.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to delay.
|
|
* @param {number} wait The number of milliseconds to delay invocation.
|
|
* @param {Array} args The arguments to provide to `func`.
|
|
* @returns {number|Object} Returns the timer id or timeout object.
|
|
*/
|
|
function baseDelay(func, wait, args) {
|
|
if (typeof func != 'function') {
|
|
throw new TypeError(FUNC_ERROR_TEXT);
|
|
}
|
|
return setTimeout(function() { func.apply(undefined, args); }, wait);
|
|
}
|
|
|
|
/**
|
|
* The base implementation of methods like `_.difference` without support
|
|
* for excluding multiple arrays or iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to inspect.
|
|
* @param {Array} values The values to exclude.
|
|
* @param {Function} [iteratee] The iteratee invoked per element.
|
|
* @param {Function} [comparator] The comparator invoked per element.
|
|
* @returns {Array} Returns the new array of filtered values.
|
|
*/
|
|
function baseDifference(array, values, iteratee, comparator) {
|
|
var index = -1,
|
|
includes = arrayIncludes,
|
|
isCommon = true,
|
|
length = array.length,
|
|
result = [],
|
|
valuesLength = values.length;
|
|
|
|
if (!length) {
|
|
return result;
|
|
}
|
|
if (iteratee) {
|
|
values = arrayMap(values, baseUnary(iteratee));
|
|
}
|
|
if (comparator) {
|
|
includes = arrayIncludesWith;
|
|
isCommon = false;
|
|
}
|
|
else if (values.length >= LARGE_ARRAY_SIZE) {
|
|
includes = cacheHas;
|
|
isCommon = false;
|
|
values = new SetCache(values);
|
|
}
|
|
outer:
|
|
while (++index < length) {
|
|
var value = array[index],
|
|
computed = iteratee == null ? value : iteratee(value);
|
|
|
|
value = (comparator || value !== 0) ? value : 0;
|
|
if (isCommon && computed === computed) {
|
|
var valuesIndex = valuesLength;
|
|
while (valuesIndex--) {
|
|
if (values[valuesIndex] === computed) {
|
|
continue outer;
|
|
}
|
|
}
|
|
result.push(value);
|
|
}
|
|
else if (!includes(values, computed, comparator)) {
|
|
result.push(value);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.forEach` without support for iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|
* @returns {Array|Object} Returns `collection`.
|
|
*/
|
|
var baseEach = createBaseEach(baseForOwn);
|
|
|
|
/**
|
|
* The base implementation of `_.forEachRight` without support for iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|
* @returns {Array|Object} Returns `collection`.
|
|
*/
|
|
var baseEachRight = createBaseEach(baseForOwnRight, true);
|
|
|
|
/**
|
|
* The base implementation of `_.every` without support for iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function} predicate The function invoked per iteration.
|
|
* @returns {boolean} Returns `true` if all elements pass the predicate check,
|
|
* else `false`
|
|
*/
|
|
function baseEvery(collection, predicate) {
|
|
var result = true;
|
|
baseEach(collection, function(value, index, collection) {
|
|
result = !!predicate(value, index, collection);
|
|
return result;
|
|
});
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of methods like `_.max` and `_.min` which accepts a
|
|
* `comparator` to determine the extremum value.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to iterate over.
|
|
* @param {Function} iteratee The iteratee invoked per iteration.
|
|
* @param {Function} comparator The comparator used to compare values.
|
|
* @returns {*} Returns the extremum value.
|
|
*/
|
|
function baseExtremum(array, iteratee, comparator) {
|
|
var index = -1,
|
|
length = array.length;
|
|
|
|
while (++index < length) {
|
|
var value = array[index],
|
|
current = iteratee(value);
|
|
|
|
if (current != null && (computed === undefined
|
|
? (current === current && !isSymbol(current))
|
|
: comparator(current, computed)
|
|
)) {
|
|
var computed = current,
|
|
result = value;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.fill` without an iteratee call guard.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to fill.
|
|
* @param {*} value The value to fill `array` with.
|
|
* @param {number} [start=0] The start position.
|
|
* @param {number} [end=array.length] The end position.
|
|
* @returns {Array} Returns `array`.
|
|
*/
|
|
function baseFill(array, value, start, end) {
|
|
var length = array.length;
|
|
|
|
start = toInteger(start);
|
|
if (start < 0) {
|
|
start = -start > length ? 0 : (length + start);
|
|
}
|
|
end = (end === undefined || end > length) ? length : toInteger(end);
|
|
if (end < 0) {
|
|
end += length;
|
|
}
|
|
end = start > end ? 0 : toLength(end);
|
|
while (start < end) {
|
|
array[start++] = value;
|
|
}
|
|
return array;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.filter` without support for iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function} predicate The function invoked per iteration.
|
|
* @returns {Array} Returns the new filtered array.
|
|
*/
|
|
function baseFilter(collection, predicate) {
|
|
var result = [];
|
|
baseEach(collection, function(value, index, collection) {
|
|
if (predicate(value, index, collection)) {
|
|
result.push(value);
|
|
}
|
|
});
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.flatten` with support for restricting flattening.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to flatten.
|
|
* @param {number} depth The maximum recursion depth.
|
|
* @param {boolean} [predicate=isFlattenable] The function invoked per iteration.
|
|
* @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.
|
|
* @param {Array} [result=[]] The initial result value.
|
|
* @returns {Array} Returns the new flattened array.
|
|
*/
|
|
function baseFlatten(array, depth, predicate, isStrict, result) {
|
|
var index = -1,
|
|
length = array.length;
|
|
|
|
predicate || (predicate = isFlattenable);
|
|
result || (result = []);
|
|
|
|
while (++index < length) {
|
|
var value = array[index];
|
|
if (depth > 0 && predicate(value)) {
|
|
if (depth > 1) {
|
|
// Recursively flatten arrays (susceptible to call stack limits).
|
|
baseFlatten(value, depth - 1, predicate, isStrict, result);
|
|
} else {
|
|
arrayPush(result, value);
|
|
}
|
|
} else if (!isStrict) {
|
|
result[result.length] = value;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `baseForOwn` which iterates over `object`
|
|
* properties returned by `keysFunc` and invokes `iteratee` for each property.
|
|
* Iteratee functions may exit iteration early by explicitly returning `false`.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to iterate over.
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|
* @param {Function} keysFunc The function to get the keys of `object`.
|
|
* @returns {Object} Returns `object`.
|
|
*/
|
|
var baseFor = createBaseFor();
|
|
|
|
/**
|
|
* This function is like `baseFor` except that it iterates over properties
|
|
* in the opposite order.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to iterate over.
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|
* @param {Function} keysFunc The function to get the keys of `object`.
|
|
* @returns {Object} Returns `object`.
|
|
*/
|
|
var baseForRight = createBaseFor(true);
|
|
|
|
/**
|
|
* The base implementation of `_.forOwn` without support for iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to iterate over.
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|
* @returns {Object} Returns `object`.
|
|
*/
|
|
function baseForOwn(object, iteratee) {
|
|
return object && baseFor(object, iteratee, keys);
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.forOwnRight` without support for iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to iterate over.
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|
* @returns {Object} Returns `object`.
|
|
*/
|
|
function baseForOwnRight(object, iteratee) {
|
|
return object && baseForRight(object, iteratee, keys);
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.functions` which creates an array of
|
|
* `object` function property names filtered from `props`.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to inspect.
|
|
* @param {Array} props The property names to filter.
|
|
* @returns {Array} Returns the function names.
|
|
*/
|
|
function baseFunctions(object, props) {
|
|
return arrayFilter(props, function(key) {
|
|
return isFunction(object[key]);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.get` without support for default values.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @param {Array|string} path The path of the property to get.
|
|
* @returns {*} Returns the resolved value.
|
|
*/
|
|
function baseGet(object, path) {
|
|
path = castPath(path, object);
|
|
|
|
var index = 0,
|
|
length = path.length;
|
|
|
|
while (object != null && index < length) {
|
|
object = object[toKey(path[index++])];
|
|
}
|
|
return (index && index == length) ? object : undefined;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `getAllKeys` and `getAllKeysIn` which uses
|
|
* `keysFunc` and `symbolsFunc` to get the enumerable property names and
|
|
* symbols of `object`.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @param {Function} keysFunc The function to get the keys of `object`.
|
|
* @param {Function} symbolsFunc The function to get the symbols of `object`.
|
|
* @returns {Array} Returns the array of property names and symbols.
|
|
*/
|
|
function baseGetAllKeys(object, keysFunc, symbolsFunc) {
|
|
var result = keysFunc(object);
|
|
return isArray(object) ? result : arrayPush(result, symbolsFunc(object));
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `getTag` without fallbacks for buggy environments.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to query.
|
|
* @returns {string} Returns the `toStringTag`.
|
|
*/
|
|
function baseGetTag(value) {
|
|
if (value == null) {
|
|
return value === undefined ? undefinedTag : nullTag;
|
|
}
|
|
return (symToStringTag && symToStringTag in Object(value))
|
|
? getRawTag(value)
|
|
: objectToString(value);
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.gt` which doesn't coerce arguments.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to compare.
|
|
* @param {*} other The other value to compare.
|
|
* @returns {boolean} Returns `true` if `value` is greater than `other`,
|
|
* else `false`.
|
|
*/
|
|
function baseGt(value, other) {
|
|
return value > other;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.has` without support for deep paths.
|
|
*
|
|
* @private
|
|
* @param {Object} [object] The object to query.
|
|
* @param {Array|string} key The key to check.
|
|
* @returns {boolean} Returns `true` if `key` exists, else `false`.
|
|
*/
|
|
function baseHas(object, key) {
|
|
return object != null && hasOwnProperty.call(object, key);
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.hasIn` without support for deep paths.
|
|
*
|
|
* @private
|
|
* @param {Object} [object] The object to query.
|
|
* @param {Array|string} key The key to check.
|
|
* @returns {boolean} Returns `true` if `key` exists, else `false`.
|
|
*/
|
|
function baseHasIn(object, key) {
|
|
return object != null && key in Object(object);
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.inRange` which doesn't coerce arguments.
|
|
*
|
|
* @private
|
|
* @param {number} number The number to check.
|
|
* @param {number} start The start of the range.
|
|
* @param {number} end The end of the range.
|
|
* @returns {boolean} Returns `true` if `number` is in the range, else `false`.
|
|
*/
|
|
function baseInRange(number, start, end) {
|
|
return number >= nativeMin(start, end) && number < nativeMax(start, end);
|
|
}
|
|
|
|
/**
|
|
* The base implementation of methods like `_.intersection`, without support
|
|
* for iteratee shorthands, that accepts an array of arrays to inspect.
|
|
*
|
|
* @private
|
|
* @param {Array} arrays The arrays to inspect.
|
|
* @param {Function} [iteratee] The iteratee invoked per element.
|
|
* @param {Function} [comparator] The comparator invoked per element.
|
|
* @returns {Array} Returns the new array of shared values.
|
|
*/
|
|
function baseIntersection(arrays, iteratee, comparator) {
|
|
var includes = comparator ? arrayIncludesWith : arrayIncludes,
|
|
length = arrays[0].length,
|
|
othLength = arrays.length,
|
|
othIndex = othLength,
|
|
caches = Array(othLength),
|
|
maxLength = Infinity,
|
|
result = [];
|
|
|
|
while (othIndex--) {
|
|
var array = arrays[othIndex];
|
|
if (othIndex && iteratee) {
|
|
array = arrayMap(array, baseUnary(iteratee));
|
|
}
|
|
maxLength = nativeMin(array.length, maxLength);
|
|
caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120))
|
|
? new SetCache(othIndex && array)
|
|
: undefined;
|
|
}
|
|
array = arrays[0];
|
|
|
|
var index = -1,
|
|
seen = caches[0];
|
|
|
|
outer:
|
|
while (++index < length && result.length < maxLength) {
|
|
var value = array[index],
|
|
computed = iteratee ? iteratee(value) : value;
|
|
|
|
value = (comparator || value !== 0) ? value : 0;
|
|
if (!(seen
|
|
? cacheHas(seen, computed)
|
|
: includes(result, computed, comparator)
|
|
)) {
|
|
othIndex = othLength;
|
|
while (--othIndex) {
|
|
var cache = caches[othIndex];
|
|
if (!(cache
|
|
? cacheHas(cache, computed)
|
|
: includes(arrays[othIndex], computed, comparator))
|
|
) {
|
|
continue outer;
|
|
}
|
|
}
|
|
if (seen) {
|
|
seen.push(computed);
|
|
}
|
|
result.push(value);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.invert` and `_.invertBy` which inverts
|
|
* `object` with values transformed by `iteratee` and set by `setter`.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to iterate over.
|
|
* @param {Function} setter The function to set `accumulator` values.
|
|
* @param {Function} iteratee The iteratee to transform values.
|
|
* @param {Object} accumulator The initial inverted object.
|
|
* @returns {Function} Returns `accumulator`.
|
|
*/
|
|
function baseInverter(object, setter, iteratee, accumulator) {
|
|
baseForOwn(object, function(value, key, object) {
|
|
setter(accumulator, iteratee(value), key, object);
|
|
});
|
|
return accumulator;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.invoke` without support for individual
|
|
* method arguments.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @param {Array|string} path The path of the method to invoke.
|
|
* @param {Array} args The arguments to invoke the method with.
|
|
* @returns {*} Returns the result of the invoked method.
|
|
*/
|
|
function baseInvoke(object, path, args) {
|
|
path = castPath(path, object);
|
|
object = parent(object, path);
|
|
var func = object == null ? object : object[toKey(last(path))];
|
|
return func == null ? undefined : apply(func, object, args);
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.isArguments`.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is an `arguments` object,
|
|
*/
|
|
function baseIsArguments(value) {
|
|
return isObjectLike(value) && baseGetTag(value) == argsTag;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.isArrayBuffer` without Node.js optimizations.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.
|
|
*/
|
|
function baseIsArrayBuffer(value) {
|
|
return isObjectLike(value) && baseGetTag(value) == arrayBufferTag;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.isDate` without Node.js optimizations.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a date object, else `false`.
|
|
*/
|
|
function baseIsDate(value) {
|
|
return isObjectLike(value) && baseGetTag(value) == dateTag;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.isEqual` which supports partial comparisons
|
|
* and tracks traversed objects.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to compare.
|
|
* @param {*} other The other value to compare.
|
|
* @param {boolean} bitmask The bitmask flags.
|
|
* 1 - Unordered comparison
|
|
* 2 - Partial comparison
|
|
* @param {Function} [customizer] The function to customize comparisons.
|
|
* @param {Object} [stack] Tracks traversed `value` and `other` objects.
|
|
* @returns {boolean} Returns `true` if the values are equivalent, else `false`.
|
|
*/
|
|
function baseIsEqual(value, other, bitmask, customizer, stack) {
|
|
if (value === other) {
|
|
return true;
|
|
}
|
|
if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {
|
|
return value !== value && other !== other;
|
|
}
|
|
return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `baseIsEqual` for arrays and objects which performs
|
|
* deep comparisons and tracks traversed objects enabling objects with circular
|
|
* references to be compared.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to compare.
|
|
* @param {Object} other The other object to compare.
|
|
* @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
|
|
* @param {Function} customizer The function to customize comparisons.
|
|
* @param {Function} equalFunc The function to determine equivalents of values.
|
|
* @param {Object} [stack] Tracks traversed `object` and `other` objects.
|
|
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
|
|
*/
|
|
function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {
|
|
var objIsArr = isArray(object),
|
|
othIsArr = isArray(other),
|
|
objTag = objIsArr ? arrayTag : getTag(object),
|
|
othTag = othIsArr ? arrayTag : getTag(other);
|
|
|
|
objTag = objTag == argsTag ? objectTag : objTag;
|
|
othTag = othTag == argsTag ? objectTag : othTag;
|
|
|
|
var objIsObj = objTag == objectTag,
|
|
othIsObj = othTag == objectTag,
|
|
isSameTag = objTag == othTag;
|
|
|
|
if (isSameTag && isBuffer(object)) {
|
|
if (!isBuffer(other)) {
|
|
return false;
|
|
}
|
|
objIsArr = true;
|
|
objIsObj = false;
|
|
}
|
|
if (isSameTag && !objIsObj) {
|
|
stack || (stack = new Stack);
|
|
return (objIsArr || isTypedArray(object))
|
|
? equalArrays(object, other, bitmask, customizer, equalFunc, stack)
|
|
: equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);
|
|
}
|
|
if (!(bitmask & COMPARE_PARTIAL_FLAG)) {
|
|
var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
|
|
othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
|
|
|
|
if (objIsWrapped || othIsWrapped) {
|
|
var objUnwrapped = objIsWrapped ? object.value() : object,
|
|
othUnwrapped = othIsWrapped ? other.value() : other;
|
|
|
|
stack || (stack = new Stack);
|
|
return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);
|
|
}
|
|
}
|
|
if (!isSameTag) {
|
|
return false;
|
|
}
|
|
stack || (stack = new Stack);
|
|
return equalObjects(object, other, bitmask, customizer, equalFunc, stack);
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.isMap` without Node.js optimizations.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a map, else `false`.
|
|
*/
|
|
function baseIsMap(value) {
|
|
return isObjectLike(value) && getTag(value) == mapTag;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.isMatch` without support for iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to inspect.
|
|
* @param {Object} source The object of property values to match.
|
|
* @param {Array} matchData The property names, values, and compare flags to match.
|
|
* @param {Function} [customizer] The function to customize comparisons.
|
|
* @returns {boolean} Returns `true` if `object` is a match, else `false`.
|
|
*/
|
|
function baseIsMatch(object, source, matchData, customizer) {
|
|
var index = matchData.length,
|
|
length = index,
|
|
noCustomizer = !customizer;
|
|
|
|
if (object == null) {
|
|
return !length;
|
|
}
|
|
object = Object(object);
|
|
while (index--) {
|
|
var data = matchData[index];
|
|
if ((noCustomizer && data[2])
|
|
? data[1] !== object[data[0]]
|
|
: !(data[0] in object)
|
|
) {
|
|
return false;
|
|
}
|
|
}
|
|
while (++index < length) {
|
|
data = matchData[index];
|
|
var key = data[0],
|
|
objValue = object[key],
|
|
srcValue = data[1];
|
|
|
|
if (noCustomizer && data[2]) {
|
|
if (objValue === undefined && !(key in object)) {
|
|
return false;
|
|
}
|
|
} else {
|
|
var stack = new Stack;
|
|
if (customizer) {
|
|
var result = customizer(objValue, srcValue, key, object, source, stack);
|
|
}
|
|
if (!(result === undefined
|
|
? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack)
|
|
: result
|
|
)) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.isNative` without bad shim checks.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a native function,
|
|
* else `false`.
|
|
*/
|
|
function baseIsNative(value) {
|
|
if (!isObject(value) || isMasked(value)) {
|
|
return false;
|
|
}
|
|
var pattern = isFunction(value) ? reIsNative : reIsHostCtor;
|
|
return pattern.test(toSource(value));
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.isRegExp` without Node.js optimizations.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a regexp, else `false`.
|
|
*/
|
|
function baseIsRegExp(value) {
|
|
return isObjectLike(value) && baseGetTag(value) == regexpTag;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.isSet` without Node.js optimizations.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a set, else `false`.
|
|
*/
|
|
function baseIsSet(value) {
|
|
return isObjectLike(value) && getTag(value) == setTag;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.isTypedArray` without Node.js optimizations.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
|
|
*/
|
|
function baseIsTypedArray(value) {
|
|
return isObjectLike(value) &&
|
|
isLength(value.length) && !!typedArrayTags[baseGetTag(value)];
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.iteratee`.
|
|
*
|
|
* @private
|
|
* @param {*} [value=_.identity] The value to convert to an iteratee.
|
|
* @returns {Function} Returns the iteratee.
|
|
*/
|
|
function baseIteratee(value) {
|
|
// Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.
|
|
// See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.
|
|
if (typeof value == 'function') {
|
|
return value;
|
|
}
|
|
if (value == null) {
|
|
return identity;
|
|
}
|
|
if (typeof value == 'object') {
|
|
return isArray(value)
|
|
? baseMatchesProperty(value[0], value[1])
|
|
: baseMatches(value);
|
|
}
|
|
return property(value);
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @returns {Array} Returns the array of property names.
|
|
*/
|
|
function baseKeys(object) {
|
|
if (!isPrototype(object)) {
|
|
return nativeKeys(object);
|
|
}
|
|
var result = [];
|
|
for (var key in Object(object)) {
|
|
if (hasOwnProperty.call(object, key) && key != 'constructor') {
|
|
result.push(key);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @returns {Array} Returns the array of property names.
|
|
*/
|
|
function baseKeysIn(object) {
|
|
if (!isObject(object)) {
|
|
return nativeKeysIn(object);
|
|
}
|
|
var isProto = isPrototype(object),
|
|
result = [];
|
|
|
|
for (var key in object) {
|
|
if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
|
|
result.push(key);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.lt` which doesn't coerce arguments.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to compare.
|
|
* @param {*} other The other value to compare.
|
|
* @returns {boolean} Returns `true` if `value` is less than `other`,
|
|
* else `false`.
|
|
*/
|
|
function baseLt(value, other) {
|
|
return value < other;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.map` without support for iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function} iteratee The function invoked per iteration.
|
|
* @returns {Array} Returns the new mapped array.
|
|
*/
|
|
function baseMap(collection, iteratee) {
|
|
var index = -1,
|
|
result = isArrayLike(collection) ? Array(collection.length) : [];
|
|
|
|
baseEach(collection, function(value, key, collection) {
|
|
result[++index] = iteratee(value, key, collection);
|
|
});
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.matches` which doesn't clone `source`.
|
|
*
|
|
* @private
|
|
* @param {Object} source The object of property values to match.
|
|
* @returns {Function} Returns the new spec function.
|
|
*/
|
|
function baseMatches(source) {
|
|
var matchData = getMatchData(source);
|
|
if (matchData.length == 1 && matchData[0][2]) {
|
|
return matchesStrictComparable(matchData[0][0], matchData[0][1]);
|
|
}
|
|
return function(object) {
|
|
return object === source || baseIsMatch(object, source, matchData);
|
|
};
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
|
|
*
|
|
* @private
|
|
* @param {string} path The path of the property to get.
|
|
* @param {*} srcValue The value to match.
|
|
* @returns {Function} Returns the new spec function.
|
|
*/
|
|
function baseMatchesProperty(path, srcValue) {
|
|
if (isKey(path) && isStrictComparable(srcValue)) {
|
|
return matchesStrictComparable(toKey(path), srcValue);
|
|
}
|
|
return function(object) {
|
|
var objValue = get(object, path);
|
|
return (objValue === undefined && objValue === srcValue)
|
|
? hasIn(object, path)
|
|
: baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);
|
|
};
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.merge` without support for multiple sources.
|
|
*
|
|
* @private
|
|
* @param {Object} object The destination object.
|
|
* @param {Object} source The source object.
|
|
* @param {number} srcIndex The index of `source`.
|
|
* @param {Function} [customizer] The function to customize merged values.
|
|
* @param {Object} [stack] Tracks traversed source values and their merged
|
|
* counterparts.
|
|
*/
|
|
function baseMerge(object, source, srcIndex, customizer, stack) {
|
|
if (object === source) {
|
|
return;
|
|
}
|
|
baseFor(source, function(srcValue, key) {
|
|
stack || (stack = new Stack);
|
|
if (isObject(srcValue)) {
|
|
baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
|
|
}
|
|
else {
|
|
var newValue = customizer
|
|
? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack)
|
|
: undefined;
|
|
|
|
if (newValue === undefined) {
|
|
newValue = srcValue;
|
|
}
|
|
assignMergeValue(object, key, newValue);
|
|
}
|
|
}, keysIn);
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `baseMerge` for arrays and objects which performs
|
|
* deep merges and tracks traversed objects enabling objects with circular
|
|
* references to be merged.
|
|
*
|
|
* @private
|
|
* @param {Object} object The destination object.
|
|
* @param {Object} source The source object.
|
|
* @param {string} key The key of the value to merge.
|
|
* @param {number} srcIndex The index of `source`.
|
|
* @param {Function} mergeFunc The function to merge values.
|
|
* @param {Function} [customizer] The function to customize assigned values.
|
|
* @param {Object} [stack] Tracks traversed source values and their merged
|
|
* counterparts.
|
|
*/
|
|
function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
|
|
var objValue = safeGet(object, key),
|
|
srcValue = safeGet(source, key),
|
|
stacked = stack.get(srcValue);
|
|
|
|
if (stacked) {
|
|
assignMergeValue(object, key, stacked);
|
|
return;
|
|
}
|
|
var newValue = customizer
|
|
? customizer(objValue, srcValue, (key + ''), object, source, stack)
|
|
: undefined;
|
|
|
|
var isCommon = newValue === undefined;
|
|
|
|
if (isCommon) {
|
|
var isArr = isArray(srcValue),
|
|
isBuff = !isArr && isBuffer(srcValue),
|
|
isTyped = !isArr && !isBuff && isTypedArray(srcValue);
|
|
|
|
newValue = srcValue;
|
|
if (isArr || isBuff || isTyped) {
|
|
if (isArray(objValue)) {
|
|
newValue = objValue;
|
|
}
|
|
else if (isArrayLikeObject(objValue)) {
|
|
newValue = copyArray(objValue);
|
|
}
|
|
else if (isBuff) {
|
|
isCommon = false;
|
|
newValue = cloneBuffer(srcValue, true);
|
|
}
|
|
else if (isTyped) {
|
|
isCommon = false;
|
|
newValue = cloneTypedArray(srcValue, true);
|
|
}
|
|
else {
|
|
newValue = [];
|
|
}
|
|
}
|
|
else if (isPlainObject(srcValue) || isArguments(srcValue)) {
|
|
newValue = objValue;
|
|
if (isArguments(objValue)) {
|
|
newValue = toPlainObject(objValue);
|
|
}
|
|
else if (!isObject(objValue) || isFunction(objValue)) {
|
|
newValue = initCloneObject(srcValue);
|
|
}
|
|
}
|
|
else {
|
|
isCommon = false;
|
|
}
|
|
}
|
|
if (isCommon) {
|
|
// Recursively merge objects and arrays (susceptible to call stack limits).
|
|
stack.set(srcValue, newValue);
|
|
mergeFunc(newValue, srcValue, srcIndex, customizer, stack);
|
|
stack['delete'](srcValue);
|
|
}
|
|
assignMergeValue(object, key, newValue);
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.nth` which doesn't coerce arguments.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to query.
|
|
* @param {number} n The index of the element to return.
|
|
* @returns {*} Returns the nth element of `array`.
|
|
*/
|
|
function baseNth(array, n) {
|
|
var length = array.length;
|
|
if (!length) {
|
|
return;
|
|
}
|
|
n += n < 0 ? length : 0;
|
|
return isIndex(n, length) ? array[n] : undefined;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.orderBy` without param guards.
|
|
*
|
|
* @private
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.
|
|
* @param {string[]} orders The sort orders of `iteratees`.
|
|
* @returns {Array} Returns the new sorted array.
|
|
*/
|
|
function baseOrderBy(collection, iteratees, orders) {
|
|
if (iteratees.length) {
|
|
iteratees = arrayMap(iteratees, function(iteratee) {
|
|
if (isArray(iteratee)) {
|
|
return function(value) {
|
|
return baseGet(value, iteratee.length === 1 ? iteratee[0] : iteratee);
|
|
}
|
|
}
|
|
return iteratee;
|
|
});
|
|
} else {
|
|
iteratees = [identity];
|
|
}
|
|
|
|
var index = -1;
|
|
iteratees = arrayMap(iteratees, baseUnary(getIteratee()));
|
|
|
|
var result = baseMap(collection, function(value, key, collection) {
|
|
var criteria = arrayMap(iteratees, function(iteratee) {
|
|
return iteratee(value);
|
|
});
|
|
return { 'criteria': criteria, 'index': ++index, 'value': value };
|
|
});
|
|
|
|
return baseSortBy(result, function(object, other) {
|
|
return compareMultiple(object, other, orders);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.pick` without support for individual
|
|
* property identifiers.
|
|
*
|
|
* @private
|
|
* @param {Object} object The source object.
|
|
* @param {string[]} paths The property paths to pick.
|
|
* @returns {Object} Returns the new object.
|
|
*/
|
|
function basePick(object, paths) {
|
|
return basePickBy(object, paths, function(value, path) {
|
|
return hasIn(object, path);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.pickBy` without support for iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Object} object The source object.
|
|
* @param {string[]} paths The property paths to pick.
|
|
* @param {Function} predicate The function invoked per property.
|
|
* @returns {Object} Returns the new object.
|
|
*/
|
|
function basePickBy(object, paths, predicate) {
|
|
var index = -1,
|
|
length = paths.length,
|
|
result = {};
|
|
|
|
while (++index < length) {
|
|
var path = paths[index],
|
|
value = baseGet(object, path);
|
|
|
|
if (predicate(value, path)) {
|
|
baseSet(result, castPath(path, object), value);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `baseProperty` which supports deep paths.
|
|
*
|
|
* @private
|
|
* @param {Array|string} path The path of the property to get.
|
|
* @returns {Function} Returns the new accessor function.
|
|
*/
|
|
function basePropertyDeep(path) {
|
|
return function(object) {
|
|
return baseGet(object, path);
|
|
};
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.pullAllBy` without support for iteratee
|
|
* shorthands.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to modify.
|
|
* @param {Array} values The values to remove.
|
|
* @param {Function} [iteratee] The iteratee invoked per element.
|
|
* @param {Function} [comparator] The comparator invoked per element.
|
|
* @returns {Array} Returns `array`.
|
|
*/
|
|
function basePullAll(array, values, iteratee, comparator) {
|
|
var indexOf = comparator ? baseIndexOfWith : baseIndexOf,
|
|
index = -1,
|
|
length = values.length,
|
|
seen = array;
|
|
|
|
if (array === values) {
|
|
values = copyArray(values);
|
|
}
|
|
if (iteratee) {
|
|
seen = arrayMap(array, baseUnary(iteratee));
|
|
}
|
|
while (++index < length) {
|
|
var fromIndex = 0,
|
|
value = values[index],
|
|
computed = iteratee ? iteratee(value) : value;
|
|
|
|
while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) {
|
|
if (seen !== array) {
|
|
splice.call(seen, fromIndex, 1);
|
|
}
|
|
splice.call(array, fromIndex, 1);
|
|
}
|
|
}
|
|
return array;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.pullAt` without support for individual
|
|
* indexes or capturing the removed elements.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to modify.
|
|
* @param {number[]} indexes The indexes of elements to remove.
|
|
* @returns {Array} Returns `array`.
|
|
*/
|
|
function basePullAt(array, indexes) {
|
|
var length = array ? indexes.length : 0,
|
|
lastIndex = length - 1;
|
|
|
|
while (length--) {
|
|
var index = indexes[length];
|
|
if (length == lastIndex || index !== previous) {
|
|
var previous = index;
|
|
if (isIndex(index)) {
|
|
splice.call(array, index, 1);
|
|
} else {
|
|
baseUnset(array, index);
|
|
}
|
|
}
|
|
}
|
|
return array;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.random` without support for returning
|
|
* floating-point numbers.
|
|
*
|
|
* @private
|
|
* @param {number} lower The lower bound.
|
|
* @param {number} upper The upper bound.
|
|
* @returns {number} Returns the random number.
|
|
*/
|
|
function baseRandom(lower, upper) {
|
|
return lower + nativeFloor(nativeRandom() * (upper - lower + 1));
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.range` and `_.rangeRight` which doesn't
|
|
* coerce arguments.
|
|
*
|
|
* @private
|
|
* @param {number} start The start of the range.
|
|
* @param {number} end The end of the range.
|
|
* @param {number} step The value to increment or decrement by.
|
|
* @param {boolean} [fromRight] Specify iterating from right to left.
|
|
* @returns {Array} Returns the range of numbers.
|
|
*/
|
|
function baseRange(start, end, step, fromRight) {
|
|
var index = -1,
|
|
length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),
|
|
result = Array(length);
|
|
|
|
while (length--) {
|
|
result[fromRight ? length : ++index] = start;
|
|
start += step;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.repeat` which doesn't coerce arguments.
|
|
*
|
|
* @private
|
|
* @param {string} string The string to repeat.
|
|
* @param {number} n The number of times to repeat the string.
|
|
* @returns {string} Returns the repeated string.
|
|
*/
|
|
function baseRepeat(string, n) {
|
|
var result = '';
|
|
if (!string || n < 1 || n > MAX_SAFE_INTEGER) {
|
|
return result;
|
|
}
|
|
// Leverage the exponentiation by squaring algorithm for a faster repeat.
|
|
// See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.
|
|
do {
|
|
if (n % 2) {
|
|
result += string;
|
|
}
|
|
n = nativeFloor(n / 2);
|
|
if (n) {
|
|
string += string;
|
|
}
|
|
} while (n);
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.rest` which doesn't validate or coerce arguments.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to apply a rest parameter to.
|
|
* @param {number} [start=func.length-1] The start position of the rest parameter.
|
|
* @returns {Function} Returns the new function.
|
|
*/
|
|
function baseRest(func, start) {
|
|
return setToString(overRest(func, start, identity), func + '');
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.sample`.
|
|
*
|
|
* @private
|
|
* @param {Array|Object} collection The collection to sample.
|
|
* @returns {*} Returns the random element.
|
|
*/
|
|
function baseSample(collection) {
|
|
return arraySample(values(collection));
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.sampleSize` without param guards.
|
|
*
|
|
* @private
|
|
* @param {Array|Object} collection The collection to sample.
|
|
* @param {number} n The number of elements to sample.
|
|
* @returns {Array} Returns the random elements.
|
|
*/
|
|
function baseSampleSize(collection, n) {
|
|
var array = values(collection);
|
|
return shuffleSelf(array, baseClamp(n, 0, array.length));
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.set`.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to modify.
|
|
* @param {Array|string} path The path of the property to set.
|
|
* @param {*} value The value to set.
|
|
* @param {Function} [customizer] The function to customize path creation.
|
|
* @returns {Object} Returns `object`.
|
|
*/
|
|
function baseSet(object, path, value, customizer) {
|
|
if (!isObject(object)) {
|
|
return object;
|
|
}
|
|
path = castPath(path, object);
|
|
|
|
var index = -1,
|
|
length = path.length,
|
|
lastIndex = length - 1,
|
|
nested = object;
|
|
|
|
while (nested != null && ++index < length) {
|
|
var key = toKey(path[index]),
|
|
newValue = value;
|
|
|
|
if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
|
|
return object;
|
|
}
|
|
|
|
if (index != lastIndex) {
|
|
var objValue = nested[key];
|
|
newValue = customizer ? customizer(objValue, key, nested) : undefined;
|
|
if (newValue === undefined) {
|
|
newValue = isObject(objValue)
|
|
? objValue
|
|
: (isIndex(path[index + 1]) ? [] : {});
|
|
}
|
|
}
|
|
assignValue(nested, key, newValue);
|
|
nested = nested[key];
|
|
}
|
|
return object;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `setData` without support for hot loop shorting.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to associate metadata with.
|
|
* @param {*} data The metadata.
|
|
* @returns {Function} Returns `func`.
|
|
*/
|
|
var baseSetData = !metaMap ? identity : function(func, data) {
|
|
metaMap.set(func, data);
|
|
return func;
|
|
};
|
|
|
|
/**
|
|
* The base implementation of `setToString` without support for hot loop shorting.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to modify.
|
|
* @param {Function} string The `toString` result.
|
|
* @returns {Function} Returns `func`.
|
|
*/
|
|
var baseSetToString = !defineProperty ? identity : function(func, string) {
|
|
return defineProperty(func, 'toString', {
|
|
'configurable': true,
|
|
'enumerable': false,
|
|
'value': constant(string),
|
|
'writable': true
|
|
});
|
|
};
|
|
|
|
/**
|
|
* The base implementation of `_.shuffle`.
|
|
*
|
|
* @private
|
|
* @param {Array|Object} collection The collection to shuffle.
|
|
* @returns {Array} Returns the new shuffled array.
|
|
*/
|
|
function baseShuffle(collection) {
|
|
return shuffleSelf(values(collection));
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.slice` without an iteratee call guard.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to slice.
|
|
* @param {number} [start=0] The start position.
|
|
* @param {number} [end=array.length] The end position.
|
|
* @returns {Array} Returns the slice of `array`.
|
|
*/
|
|
function baseSlice(array, start, end) {
|
|
var index = -1,
|
|
length = array.length;
|
|
|
|
if (start < 0) {
|
|
start = -start > length ? 0 : (length + start);
|
|
}
|
|
end = end > length ? length : end;
|
|
if (end < 0) {
|
|
end += length;
|
|
}
|
|
length = start > end ? 0 : ((end - start) >>> 0);
|
|
start >>>= 0;
|
|
|
|
var result = Array(length);
|
|
while (++index < length) {
|
|
result[index] = array[index + start];
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.some` without support for iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function} predicate The function invoked per iteration.
|
|
* @returns {boolean} Returns `true` if any element passes the predicate check,
|
|
* else `false`.
|
|
*/
|
|
function baseSome(collection, predicate) {
|
|
var result;
|
|
|
|
baseEach(collection, function(value, index, collection) {
|
|
result = predicate(value, index, collection);
|
|
return !result;
|
|
});
|
|
return !!result;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which
|
|
* performs a binary search of `array` to determine the index at which `value`
|
|
* should be inserted into `array` in order to maintain its sort order.
|
|
*
|
|
* @private
|
|
* @param {Array} array The sorted array to inspect.
|
|
* @param {*} value The value to evaluate.
|
|
* @param {boolean} [retHighest] Specify returning the highest qualified index.
|
|
* @returns {number} Returns the index at which `value` should be inserted
|
|
* into `array`.
|
|
*/
|
|
function baseSortedIndex(array, value, retHighest) {
|
|
var low = 0,
|
|
high = array == null ? low : array.length;
|
|
|
|
if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {
|
|
while (low < high) {
|
|
var mid = (low + high) >>> 1,
|
|
computed = array[mid];
|
|
|
|
if (computed !== null && !isSymbol(computed) &&
|
|
(retHighest ? (computed <= value) : (computed < value))) {
|
|
low = mid + 1;
|
|
} else {
|
|
high = mid;
|
|
}
|
|
}
|
|
return high;
|
|
}
|
|
return baseSortedIndexBy(array, value, identity, retHighest);
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy`
|
|
* which invokes `iteratee` for `value` and each element of `array` to compute
|
|
* their sort ranking. The iteratee is invoked with one argument; (value).
|
|
*
|
|
* @private
|
|
* @param {Array} array The sorted array to inspect.
|
|
* @param {*} value The value to evaluate.
|
|
* @param {Function} iteratee The iteratee invoked per element.
|
|
* @param {boolean} [retHighest] Specify returning the highest qualified index.
|
|
* @returns {number} Returns the index at which `value` should be inserted
|
|
* into `array`.
|
|
*/
|
|
function baseSortedIndexBy(array, value, iteratee, retHighest) {
|
|
var low = 0,
|
|
high = array == null ? 0 : array.length;
|
|
if (high === 0) {
|
|
return 0;
|
|
}
|
|
|
|
value = iteratee(value);
|
|
var valIsNaN = value !== value,
|
|
valIsNull = value === null,
|
|
valIsSymbol = isSymbol(value),
|
|
valIsUndefined = value === undefined;
|
|
|
|
while (low < high) {
|
|
var mid = nativeFloor((low + high) / 2),
|
|
computed = iteratee(array[mid]),
|
|
othIsDefined = computed !== undefined,
|
|
othIsNull = computed === null,
|
|
othIsReflexive = computed === computed,
|
|
othIsSymbol = isSymbol(computed);
|
|
|
|
if (valIsNaN) {
|
|
var setLow = retHighest || othIsReflexive;
|
|
} else if (valIsUndefined) {
|
|
setLow = othIsReflexive && (retHighest || othIsDefined);
|
|
} else if (valIsNull) {
|
|
setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull);
|
|
} else if (valIsSymbol) {
|
|
setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol);
|
|
} else if (othIsNull || othIsSymbol) {
|
|
setLow = false;
|
|
} else {
|
|
setLow = retHighest ? (computed <= value) : (computed < value);
|
|
}
|
|
if (setLow) {
|
|
low = mid + 1;
|
|
} else {
|
|
high = mid;
|
|
}
|
|
}
|
|
return nativeMin(high, MAX_ARRAY_INDEX);
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.sortedUniq` and `_.sortedUniqBy` without
|
|
* support for iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to inspect.
|
|
* @param {Function} [iteratee] The iteratee invoked per element.
|
|
* @returns {Array} Returns the new duplicate free array.
|
|
*/
|
|
function baseSortedUniq(array, iteratee) {
|
|
var index = -1,
|
|
length = array.length,
|
|
resIndex = 0,
|
|
result = [];
|
|
|
|
while (++index < length) {
|
|
var value = array[index],
|
|
computed = iteratee ? iteratee(value) : value;
|
|
|
|
if (!index || !eq(computed, seen)) {
|
|
var seen = computed;
|
|
result[resIndex++] = value === 0 ? 0 : value;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.toNumber` which doesn't ensure correct
|
|
* conversions of binary, hexadecimal, or octal string values.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to process.
|
|
* @returns {number} Returns the number.
|
|
*/
|
|
function baseToNumber(value) {
|
|
if (typeof value == 'number') {
|
|
return value;
|
|
}
|
|
if (isSymbol(value)) {
|
|
return NAN;
|
|
}
|
|
return +value;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.toString` which doesn't convert nullish
|
|
* values to empty strings.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to process.
|
|
* @returns {string} Returns the string.
|
|
*/
|
|
function baseToString(value) {
|
|
// Exit early for strings to avoid a performance hit in some environments.
|
|
if (typeof value == 'string') {
|
|
return value;
|
|
}
|
|
if (isArray(value)) {
|
|
// Recursively convert values (susceptible to call stack limits).
|
|
return arrayMap(value, baseToString) + '';
|
|
}
|
|
if (isSymbol(value)) {
|
|
return symbolToString ? symbolToString.call(value) : '';
|
|
}
|
|
var result = (value + '');
|
|
return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.uniqBy` without support for iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to inspect.
|
|
* @param {Function} [iteratee] The iteratee invoked per element.
|
|
* @param {Function} [comparator] The comparator invoked per element.
|
|
* @returns {Array} Returns the new duplicate free array.
|
|
*/
|
|
function baseUniq(array, iteratee, comparator) {
|
|
var index = -1,
|
|
includes = arrayIncludes,
|
|
length = array.length,
|
|
isCommon = true,
|
|
result = [],
|
|
seen = result;
|
|
|
|
if (comparator) {
|
|
isCommon = false;
|
|
includes = arrayIncludesWith;
|
|
}
|
|
else if (length >= LARGE_ARRAY_SIZE) {
|
|
var set = iteratee ? null : createSet(array);
|
|
if (set) {
|
|
return setToArray(set);
|
|
}
|
|
isCommon = false;
|
|
includes = cacheHas;
|
|
seen = new SetCache;
|
|
}
|
|
else {
|
|
seen = iteratee ? [] : result;
|
|
}
|
|
outer:
|
|
while (++index < length) {
|
|
var value = array[index],
|
|
computed = iteratee ? iteratee(value) : value;
|
|
|
|
value = (comparator || value !== 0) ? value : 0;
|
|
if (isCommon && computed === computed) {
|
|
var seenIndex = seen.length;
|
|
while (seenIndex--) {
|
|
if (seen[seenIndex] === computed) {
|
|
continue outer;
|
|
}
|
|
}
|
|
if (iteratee) {
|
|
seen.push(computed);
|
|
}
|
|
result.push(value);
|
|
}
|
|
else if (!includes(seen, computed, comparator)) {
|
|
if (seen !== result) {
|
|
seen.push(computed);
|
|
}
|
|
result.push(value);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.unset`.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to modify.
|
|
* @param {Array|string} path The property path to unset.
|
|
* @returns {boolean} Returns `true` if the property is deleted, else `false`.
|
|
*/
|
|
function baseUnset(object, path) {
|
|
path = castPath(path, object);
|
|
object = parent(object, path);
|
|
return object == null || delete object[toKey(last(path))];
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `_.update`.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to modify.
|
|
* @param {Array|string} path The path of the property to update.
|
|
* @param {Function} updater The function to produce the updated value.
|
|
* @param {Function} [customizer] The function to customize path creation.
|
|
* @returns {Object} Returns `object`.
|
|
*/
|
|
function baseUpdate(object, path, updater, customizer) {
|
|
return baseSet(object, path, updater(baseGet(object, path)), customizer);
|
|
}
|
|
|
|
/**
|
|
* The base implementation of methods like `_.dropWhile` and `_.takeWhile`
|
|
* without support for iteratee shorthands.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to query.
|
|
* @param {Function} predicate The function invoked per iteration.
|
|
* @param {boolean} [isDrop] Specify dropping elements instead of taking them.
|
|
* @param {boolean} [fromRight] Specify iterating from right to left.
|
|
* @returns {Array} Returns the slice of `array`.
|
|
*/
|
|
function baseWhile(array, predicate, isDrop, fromRight) {
|
|
var length = array.length,
|
|
index = fromRight ? length : -1;
|
|
|
|
while ((fromRight ? index-- : ++index < length) &&
|
|
predicate(array[index], index, array)) {}
|
|
|
|
return isDrop
|
|
? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))
|
|
: baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));
|
|
}
|
|
|
|
/**
|
|
* The base implementation of `wrapperValue` which returns the result of
|
|
* performing a sequence of actions on the unwrapped `value`, where each
|
|
* successive action is supplied the return value of the previous.
|
|
*
|
|
* @private
|
|
* @param {*} value The unwrapped value.
|
|
* @param {Array} actions Actions to perform to resolve the unwrapped value.
|
|
* @returns {*} Returns the resolved value.
|
|
*/
|
|
function baseWrapperValue(value, actions) {
|
|
var result = value;
|
|
if (result instanceof LazyWrapper) {
|
|
result = result.value();
|
|
}
|
|
return arrayReduce(actions, function(result, action) {
|
|
return action.func.apply(action.thisArg, arrayPush([result], action.args));
|
|
}, result);
|
|
}
|
|
|
|
/**
|
|
* The base implementation of methods like `_.xor`, without support for
|
|
* iteratee shorthands, that accepts an array of arrays to inspect.
|
|
*
|
|
* @private
|
|
* @param {Array} arrays The arrays to inspect.
|
|
* @param {Function} [iteratee] The iteratee invoked per element.
|
|
* @param {Function} [comparator] The comparator invoked per element.
|
|
* @returns {Array} Returns the new array of values.
|
|
*/
|
|
function baseXor(arrays, iteratee, comparator) {
|
|
var length = arrays.length;
|
|
if (length < 2) {
|
|
return length ? baseUniq(arrays[0]) : [];
|
|
}
|
|
var index = -1,
|
|
result = Array(length);
|
|
|
|
while (++index < length) {
|
|
var array = arrays[index],
|
|
othIndex = -1;
|
|
|
|
while (++othIndex < length) {
|
|
if (othIndex != index) {
|
|
result[index] = baseDifference(result[index] || array, arrays[othIndex], iteratee, comparator);
|
|
}
|
|
}
|
|
}
|
|
return baseUniq(baseFlatten(result, 1), iteratee, comparator);
|
|
}
|
|
|
|
/**
|
|
* This base implementation of `_.zipObject` which assigns values using `assignFunc`.
|
|
*
|
|
* @private
|
|
* @param {Array} props The property identifiers.
|
|
* @param {Array} values The property values.
|
|
* @param {Function} assignFunc The function to assign values.
|
|
* @returns {Object} Returns the new object.
|
|
*/
|
|
function baseZipObject(props, values, assignFunc) {
|
|
var index = -1,
|
|
length = props.length,
|
|
valsLength = values.length,
|
|
result = {};
|
|
|
|
while (++index < length) {
|
|
var value = index < valsLength ? values[index] : undefined;
|
|
assignFunc(result, props[index], value);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Casts `value` to an empty array if it's not an array like object.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to inspect.
|
|
* @returns {Array|Object} Returns the cast array-like object.
|
|
*/
|
|
function castArrayLikeObject(value) {
|
|
return isArrayLikeObject(value) ? value : [];
|
|
}
|
|
|
|
/**
|
|
* Casts `value` to `identity` if it's not a function.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to inspect.
|
|
* @returns {Function} Returns cast function.
|
|
*/
|
|
function castFunction(value) {
|
|
return typeof value == 'function' ? value : identity;
|
|
}
|
|
|
|
/**
|
|
* Casts `value` to a path array if it's not one.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to inspect.
|
|
* @param {Object} [object] The object to query keys on.
|
|
* @returns {Array} Returns the cast property path array.
|
|
*/
|
|
function castPath(value, object) {
|
|
if (isArray(value)) {
|
|
return value;
|
|
}
|
|
return isKey(value, object) ? [value] : stringToPath(toString(value));
|
|
}
|
|
|
|
/**
|
|
* A `baseRest` alias which can be replaced with `identity` by module
|
|
* replacement plugins.
|
|
*
|
|
* @private
|
|
* @type {Function}
|
|
* @param {Function} func The function to apply a rest parameter to.
|
|
* @returns {Function} Returns the new function.
|
|
*/
|
|
var castRest = baseRest;
|
|
|
|
/**
|
|
* Casts `array` to a slice if it's needed.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to inspect.
|
|
* @param {number} start The start position.
|
|
* @param {number} [end=array.length] The end position.
|
|
* @returns {Array} Returns the cast slice.
|
|
*/
|
|
function castSlice(array, start, end) {
|
|
var length = array.length;
|
|
end = end === undefined ? length : end;
|
|
return (!start && end >= length) ? array : baseSlice(array, start, end);
|
|
}
|
|
|
|
/**
|
|
* A simple wrapper around the global [`clearTimeout`](https://mdn.io/clearTimeout).
|
|
*
|
|
* @private
|
|
* @param {number|Object} id The timer id or timeout object of the timer to clear.
|
|
*/
|
|
var clearTimeout = ctxClearTimeout || function(id) {
|
|
return root.clearTimeout(id);
|
|
};
|
|
|
|
/**
|
|
* Creates a clone of `buffer`.
|
|
*
|
|
* @private
|
|
* @param {Buffer} buffer The buffer to clone.
|
|
* @param {boolean} [isDeep] Specify a deep clone.
|
|
* @returns {Buffer} Returns the cloned buffer.
|
|
*/
|
|
function cloneBuffer(buffer, isDeep) {
|
|
if (isDeep) {
|
|
return buffer.slice();
|
|
}
|
|
var length = buffer.length,
|
|
result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);
|
|
|
|
buffer.copy(result);
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Creates a clone of `arrayBuffer`.
|
|
*
|
|
* @private
|
|
* @param {ArrayBuffer} arrayBuffer The array buffer to clone.
|
|
* @returns {ArrayBuffer} Returns the cloned array buffer.
|
|
*/
|
|
function cloneArrayBuffer(arrayBuffer) {
|
|
var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
|
|
new Uint8Array(result).set(new Uint8Array(arrayBuffer));
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Creates a clone of `dataView`.
|
|
*
|
|
* @private
|
|
* @param {Object} dataView The data view to clone.
|
|
* @param {boolean} [isDeep] Specify a deep clone.
|
|
* @returns {Object} Returns the cloned data view.
|
|
*/
|
|
function cloneDataView(dataView, isDeep) {
|
|
var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;
|
|
return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);
|
|
}
|
|
|
|
/**
|
|
* Creates a clone of `regexp`.
|
|
*
|
|
* @private
|
|
* @param {Object} regexp The regexp to clone.
|
|
* @returns {Object} Returns the cloned regexp.
|
|
*/
|
|
function cloneRegExp(regexp) {
|
|
var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));
|
|
result.lastIndex = regexp.lastIndex;
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Creates a clone of the `symbol` object.
|
|
*
|
|
* @private
|
|
* @param {Object} symbol The symbol object to clone.
|
|
* @returns {Object} Returns the cloned symbol object.
|
|
*/
|
|
function cloneSymbol(symbol) {
|
|
return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};
|
|
}
|
|
|
|
/**
|
|
* Creates a clone of `typedArray`.
|
|
*
|
|
* @private
|
|
* @param {Object} typedArray The typed array to clone.
|
|
* @param {boolean} [isDeep] Specify a deep clone.
|
|
* @returns {Object} Returns the cloned typed array.
|
|
*/
|
|
function cloneTypedArray(typedArray, isDeep) {
|
|
var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;
|
|
return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
|
|
}
|
|
|
|
/**
|
|
* Compares values to sort them in ascending order.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to compare.
|
|
* @param {*} other The other value to compare.
|
|
* @returns {number} Returns the sort order indicator for `value`.
|
|
*/
|
|
function compareAscending(value, other) {
|
|
if (value !== other) {
|
|
var valIsDefined = value !== undefined,
|
|
valIsNull = value === null,
|
|
valIsReflexive = value === value,
|
|
valIsSymbol = isSymbol(value);
|
|
|
|
var othIsDefined = other !== undefined,
|
|
othIsNull = other === null,
|
|
othIsReflexive = other === other,
|
|
othIsSymbol = isSymbol(other);
|
|
|
|
if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) ||
|
|
(valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) ||
|
|
(valIsNull && othIsDefined && othIsReflexive) ||
|
|
(!valIsDefined && othIsReflexive) ||
|
|
!valIsReflexive) {
|
|
return 1;
|
|
}
|
|
if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) ||
|
|
(othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) ||
|
|
(othIsNull && valIsDefined && valIsReflexive) ||
|
|
(!othIsDefined && valIsReflexive) ||
|
|
!othIsReflexive) {
|
|
return -1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* Used by `_.orderBy` to compare multiple properties of a value to another
|
|
* and stable sort them.
|
|
*
|
|
* If `orders` is unspecified, all values are sorted in ascending order. Otherwise,
|
|
* specify an order of "desc" for descending or "asc" for ascending sort order
|
|
* of corresponding values.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to compare.
|
|
* @param {Object} other The other object to compare.
|
|
* @param {boolean[]|string[]} orders The order to sort by for each property.
|
|
* @returns {number} Returns the sort order indicator for `object`.
|
|
*/
|
|
function compareMultiple(object, other, orders) {
|
|
var index = -1,
|
|
objCriteria = object.criteria,
|
|
othCriteria = other.criteria,
|
|
length = objCriteria.length,
|
|
ordersLength = orders.length;
|
|
|
|
while (++index < length) {
|
|
var result = compareAscending(objCriteria[index], othCriteria[index]);
|
|
if (result) {
|
|
if (index >= ordersLength) {
|
|
return result;
|
|
}
|
|
var order = orders[index];
|
|
return result * (order == 'desc' ? -1 : 1);
|
|
}
|
|
}
|
|
// Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
|
|
// that causes it, under certain circumstances, to provide the same value for
|
|
// `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247
|
|
// for more details.
|
|
//
|
|
// This also ensures a stable sort in V8 and other engines.
|
|
// See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details.
|
|
return object.index - other.index;
|
|
}
|
|
|
|
/**
|
|
* Creates an array that is the composition of partially applied arguments,
|
|
* placeholders, and provided arguments into a single array of arguments.
|
|
*
|
|
* @private
|
|
* @param {Array} args The provided arguments.
|
|
* @param {Array} partials The arguments to prepend to those provided.
|
|
* @param {Array} holders The `partials` placeholder indexes.
|
|
* @params {boolean} [isCurried] Specify composing for a curried function.
|
|
* @returns {Array} Returns the new array of composed arguments.
|
|
*/
|
|
function composeArgs(args, partials, holders, isCurried) {
|
|
var argsIndex = -1,
|
|
argsLength = args.length,
|
|
holdersLength = holders.length,
|
|
leftIndex = -1,
|
|
leftLength = partials.length,
|
|
rangeLength = nativeMax(argsLength - holdersLength, 0),
|
|
result = Array(leftLength + rangeLength),
|
|
isUncurried = !isCurried;
|
|
|
|
while (++leftIndex < leftLength) {
|
|
result[leftIndex] = partials[leftIndex];
|
|
}
|
|
while (++argsIndex < holdersLength) {
|
|
if (isUncurried || argsIndex < argsLength) {
|
|
result[holders[argsIndex]] = args[argsIndex];
|
|
}
|
|
}
|
|
while (rangeLength--) {
|
|
result[leftIndex++] = args[argsIndex++];
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* This function is like `composeArgs` except that the arguments composition
|
|
* is tailored for `_.partialRight`.
|
|
*
|
|
* @private
|
|
* @param {Array} args The provided arguments.
|
|
* @param {Array} partials The arguments to append to those provided.
|
|
* @param {Array} holders The `partials` placeholder indexes.
|
|
* @params {boolean} [isCurried] Specify composing for a curried function.
|
|
* @returns {Array} Returns the new array of composed arguments.
|
|
*/
|
|
function composeArgsRight(args, partials, holders, isCurried) {
|
|
var argsIndex = -1,
|
|
argsLength = args.length,
|
|
holdersIndex = -1,
|
|
holdersLength = holders.length,
|
|
rightIndex = -1,
|
|
rightLength = partials.length,
|
|
rangeLength = nativeMax(argsLength - holdersLength, 0),
|
|
result = Array(rangeLength + rightLength),
|
|
isUncurried = !isCurried;
|
|
|
|
while (++argsIndex < rangeLength) {
|
|
result[argsIndex] = args[argsIndex];
|
|
}
|
|
var offset = argsIndex;
|
|
while (++rightIndex < rightLength) {
|
|
result[offset + rightIndex] = partials[rightIndex];
|
|
}
|
|
while (++holdersIndex < holdersLength) {
|
|
if (isUncurried || argsIndex < argsLength) {
|
|
result[offset + holders[holdersIndex]] = args[argsIndex++];
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Copies the values of `source` to `array`.
|
|
*
|
|
* @private
|
|
* @param {Array} source The array to copy values from.
|
|
* @param {Array} [array=[]] The array to copy values to.
|
|
* @returns {Array} Returns `array`.
|
|
*/
|
|
function copyArray(source, array) {
|
|
var index = -1,
|
|
length = source.length;
|
|
|
|
array || (array = Array(length));
|
|
while (++index < length) {
|
|
array[index] = source[index];
|
|
}
|
|
return array;
|
|
}
|
|
|
|
/**
|
|
* Copies properties of `source` to `object`.
|
|
*
|
|
* @private
|
|
* @param {Object} source The object to copy properties from.
|
|
* @param {Array} props The property identifiers to copy.
|
|
* @param {Object} [object={}] The object to copy properties to.
|
|
* @param {Function} [customizer] The function to customize copied values.
|
|
* @returns {Object} Returns `object`.
|
|
*/
|
|
function copyObject(source, props, object, customizer) {
|
|
var isNew = !object;
|
|
object || (object = {});
|
|
|
|
var index = -1,
|
|
length = props.length;
|
|
|
|
while (++index < length) {
|
|
var key = props[index];
|
|
|
|
var newValue = customizer
|
|
? customizer(object[key], source[key], key, object, source)
|
|
: undefined;
|
|
|
|
if (newValue === undefined) {
|
|
newValue = source[key];
|
|
}
|
|
if (isNew) {
|
|
baseAssignValue(object, key, newValue);
|
|
} else {
|
|
assignValue(object, key, newValue);
|
|
}
|
|
}
|
|
return object;
|
|
}
|
|
|
|
/**
|
|
* Copies own symbols of `source` to `object`.
|
|
*
|
|
* @private
|
|
* @param {Object} source The object to copy symbols from.
|
|
* @param {Object} [object={}] The object to copy symbols to.
|
|
* @returns {Object} Returns `object`.
|
|
*/
|
|
function copySymbols(source, object) {
|
|
return copyObject(source, getSymbols(source), object);
|
|
}
|
|
|
|
/**
|
|
* Copies own and inherited symbols of `source` to `object`.
|
|
*
|
|
* @private
|
|
* @param {Object} source The object to copy symbols from.
|
|
* @param {Object} [object={}] The object to copy symbols to.
|
|
* @returns {Object} Returns `object`.
|
|
*/
|
|
function copySymbolsIn(source, object) {
|
|
return copyObject(source, getSymbolsIn(source), object);
|
|
}
|
|
|
|
/**
|
|
* Creates a function like `_.groupBy`.
|
|
*
|
|
* @private
|
|
* @param {Function} setter The function to set accumulator values.
|
|
* @param {Function} [initializer] The accumulator object initializer.
|
|
* @returns {Function} Returns the new aggregator function.
|
|
*/
|
|
function createAggregator(setter, initializer) {
|
|
return function(collection, iteratee) {
|
|
var func = isArray(collection) ? arrayAggregator : baseAggregator,
|
|
accumulator = initializer ? initializer() : {};
|
|
|
|
return func(collection, setter, getIteratee(iteratee, 2), accumulator);
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Creates a function like `_.assign`.
|
|
*
|
|
* @private
|
|
* @param {Function} assigner The function to assign values.
|
|
* @returns {Function} Returns the new assigner function.
|
|
*/
|
|
function createAssigner(assigner) {
|
|
return baseRest(function(object, sources) {
|
|
var index = -1,
|
|
length = sources.length,
|
|
customizer = length > 1 ? sources[length - 1] : undefined,
|
|
guard = length > 2 ? sources[2] : undefined;
|
|
|
|
customizer = (assigner.length > 3 && typeof customizer == 'function')
|
|
? (length--, customizer)
|
|
: undefined;
|
|
|
|
if (guard && isIterateeCall(sources[0], sources[1], guard)) {
|
|
customizer = length < 3 ? undefined : customizer;
|
|
length = 1;
|
|
}
|
|
object = Object(object);
|
|
while (++index < length) {
|
|
var source = sources[index];
|
|
if (source) {
|
|
assigner(object, source, index, customizer);
|
|
}
|
|
}
|
|
return object;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Creates a `baseEach` or `baseEachRight` function.
|
|
*
|
|
* @private
|
|
* @param {Function} eachFunc The function to iterate over a collection.
|
|
* @param {boolean} [fromRight] Specify iterating from right to left.
|
|
* @returns {Function} Returns the new base function.
|
|
*/
|
|
function createBaseEach(eachFunc, fromRight) {
|
|
return function(collection, iteratee) {
|
|
if (collection == null) {
|
|
return collection;
|
|
}
|
|
if (!isArrayLike(collection)) {
|
|
return eachFunc(collection, iteratee);
|
|
}
|
|
var length = collection.length,
|
|
index = fromRight ? length : -1,
|
|
iterable = Object(collection);
|
|
|
|
while ((fromRight ? index-- : ++index < length)) {
|
|
if (iteratee(iterable[index], index, iterable) === false) {
|
|
break;
|
|
}
|
|
}
|
|
return collection;
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Creates a base function for methods like `_.forIn` and `_.forOwn`.
|
|
*
|
|
* @private
|
|
* @param {boolean} [fromRight] Specify iterating from right to left.
|
|
* @returns {Function} Returns the new base function.
|
|
*/
|
|
function createBaseFor(fromRight) {
|
|
return function(object, iteratee, keysFunc) {
|
|
var index = -1,
|
|
iterable = Object(object),
|
|
props = keysFunc(object),
|
|
length = props.length;
|
|
|
|
while (length--) {
|
|
var key = props[fromRight ? length : ++index];
|
|
if (iteratee(iterable[key], key, iterable) === false) {
|
|
break;
|
|
}
|
|
}
|
|
return object;
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Creates a function that wraps `func` to invoke it with the optional `this`
|
|
* binding of `thisArg`.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to wrap.
|
|
* @param {number} bitmask The bitmask flags. See `createWrap` for more details.
|
|
* @param {*} [thisArg] The `this` binding of `func`.
|
|
* @returns {Function} Returns the new wrapped function.
|
|
*/
|
|
function createBind(func, bitmask, thisArg) {
|
|
var isBind = bitmask & WRAP_BIND_FLAG,
|
|
Ctor = createCtor(func);
|
|
|
|
function wrapper() {
|
|
var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
|
|
return fn.apply(isBind ? thisArg : this, arguments);
|
|
}
|
|
return wrapper;
|
|
}
|
|
|
|
/**
|
|
* Creates a function like `_.lowerFirst`.
|
|
*
|
|
* @private
|
|
* @param {string} methodName The name of the `String` case method to use.
|
|
* @returns {Function} Returns the new case function.
|
|
*/
|
|
function createCaseFirst(methodName) {
|
|
return function(string) {
|
|
string = toString(string);
|
|
|
|
var strSymbols = hasUnicode(string)
|
|
? stringToArray(string)
|
|
: undefined;
|
|
|
|
var chr = strSymbols
|
|
? strSymbols[0]
|
|
: string.charAt(0);
|
|
|
|
var trailing = strSymbols
|
|
? castSlice(strSymbols, 1).join('')
|
|
: string.slice(1);
|
|
|
|
return chr[methodName]() + trailing;
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Creates a function like `_.camelCase`.
|
|
*
|
|
* @private
|
|
* @param {Function} callback The function to combine each word.
|
|
* @returns {Function} Returns the new compounder function.
|
|
*/
|
|
function createCompounder(callback) {
|
|
return function(string) {
|
|
return arrayReduce(words(deburr(string).replace(reApos, '')), callback, '');
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Creates a function that produces an instance of `Ctor` regardless of
|
|
* whether it was invoked as part of a `new` expression or by `call` or `apply`.
|
|
*
|
|
* @private
|
|
* @param {Function} Ctor The constructor to wrap.
|
|
* @returns {Function} Returns the new wrapped function.
|
|
*/
|
|
function createCtor(Ctor) {
|
|
return function() {
|
|
// Use a `switch` statement to work with class constructors. See
|
|
// http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
|
|
// for more details.
|
|
var args = arguments;
|
|
switch (args.length) {
|
|
case 0: return new Ctor;
|
|
case 1: return new Ctor(args[0]);
|
|
case 2: return new Ctor(args[0], args[1]);
|
|
case 3: return new Ctor(args[0], args[1], args[2]);
|
|
case 4: return new Ctor(args[0], args[1], args[2], args[3]);
|
|
case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);
|
|
case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
|
|
case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
|
|
}
|
|
var thisBinding = baseCreate(Ctor.prototype),
|
|
result = Ctor.apply(thisBinding, args);
|
|
|
|
// Mimic the constructor's `return` behavior.
|
|
// See https://es5.github.io/#x13.2.2 for more details.
|
|
return isObject(result) ? result : thisBinding;
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Creates a function that wraps `func` to enable currying.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to wrap.
|
|
* @param {number} bitmask The bitmask flags. See `createWrap` for more details.
|
|
* @param {number} arity The arity of `func`.
|
|
* @returns {Function} Returns the new wrapped function.
|
|
*/
|
|
function createCurry(func, bitmask, arity) {
|
|
var Ctor = createCtor(func);
|
|
|
|
function wrapper() {
|
|
var length = arguments.length,
|
|
args = Array(length),
|
|
index = length,
|
|
placeholder = getHolder(wrapper);
|
|
|
|
while (index--) {
|
|
args[index] = arguments[index];
|
|
}
|
|
var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)
|
|
? []
|
|
: replaceHolders(args, placeholder);
|
|
|
|
length -= holders.length;
|
|
if (length < arity) {
|
|
return createRecurry(
|
|
func, bitmask, createHybrid, wrapper.placeholder, undefined,
|
|
args, holders, undefined, undefined, arity - length);
|
|
}
|
|
var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
|
|
return apply(fn, this, args);
|
|
}
|
|
return wrapper;
|
|
}
|
|
|
|
/**
|
|
* Creates a `_.find` or `_.findLast` function.
|
|
*
|
|
* @private
|
|
* @param {Function} findIndexFunc The function to find the collection index.
|
|
* @returns {Function} Returns the new find function.
|
|
*/
|
|
function createFind(findIndexFunc) {
|
|
return function(collection, predicate, fromIndex) {
|
|
var iterable = Object(collection);
|
|
if (!isArrayLike(collection)) {
|
|
var iteratee = getIteratee(predicate, 3);
|
|
collection = keys(collection);
|
|
predicate = function(key) { return iteratee(iterable[key], key, iterable); };
|
|
}
|
|
var index = findIndexFunc(collection, predicate, fromIndex);
|
|
return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined;
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Creates a `_.flow` or `_.flowRight` function.
|
|
*
|
|
* @private
|
|
* @param {boolean} [fromRight] Specify iterating from right to left.
|
|
* @returns {Function} Returns the new flow function.
|
|
*/
|
|
function createFlow(fromRight) {
|
|
return flatRest(function(funcs) {
|
|
var length = funcs.length,
|
|
index = length,
|
|
prereq = LodashWrapper.prototype.thru;
|
|
|
|
if (fromRight) {
|
|
funcs.reverse();
|
|
}
|
|
while (index--) {
|
|
var func = funcs[index];
|
|
if (typeof func != 'function') {
|
|
throw new TypeError(FUNC_ERROR_TEXT);
|
|
}
|
|
if (prereq && !wrapper && getFuncName(func) == 'wrapper') {
|
|
var wrapper = new LodashWrapper([], true);
|
|
}
|
|
}
|
|
index = wrapper ? index : length;
|
|
while (++index < length) {
|
|
func = funcs[index];
|
|
|
|
var funcName = getFuncName(func),
|
|
data = funcName == 'wrapper' ? getData(func) : undefined;
|
|
|
|
if (data && isLaziable(data[0]) &&
|
|
data[1] == (WRAP_ARY_FLAG | WRAP_CURRY_FLAG | WRAP_PARTIAL_FLAG | WRAP_REARG_FLAG) &&
|
|
!data[4].length && data[9] == 1
|
|
) {
|
|
wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);
|
|
} else {
|
|
wrapper = (func.length == 1 && isLaziable(func))
|
|
? wrapper[funcName]()
|
|
: wrapper.thru(func);
|
|
}
|
|
}
|
|
return function() {
|
|
var args = arguments,
|
|
value = args[0];
|
|
|
|
if (wrapper && args.length == 1 && isArray(value)) {
|
|
return wrapper.plant(value).value();
|
|
}
|
|
var index = 0,
|
|
result = length ? funcs[index].apply(this, args) : value;
|
|
|
|
while (++index < length) {
|
|
result = funcs[index].call(this, result);
|
|
}
|
|
return result;
|
|
};
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Creates a function that wraps `func` to invoke it with optional `this`
|
|
* binding of `thisArg`, partial application, and currying.
|
|
*
|
|
* @private
|
|
* @param {Function|string} func The function or method name to wrap.
|
|
* @param {number} bitmask The bitmask flags. See `createWrap` for more details.
|
|
* @param {*} [thisArg] The `this` binding of `func`.
|
|
* @param {Array} [partials] The arguments to prepend to those provided to
|
|
* the new function.
|
|
* @param {Array} [holders] The `partials` placeholder indexes.
|
|
* @param {Array} [partialsRight] The arguments to append to those provided
|
|
* to the new function.
|
|
* @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
|
|
* @param {Array} [argPos] The argument positions of the new function.
|
|
* @param {number} [ary] The arity cap of `func`.
|
|
* @param {number} [arity] The arity of `func`.
|
|
* @returns {Function} Returns the new wrapped function.
|
|
*/
|
|
function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
|
|
var isAry = bitmask & WRAP_ARY_FLAG,
|
|
isBind = bitmask & WRAP_BIND_FLAG,
|
|
isBindKey = bitmask & WRAP_BIND_KEY_FLAG,
|
|
isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG),
|
|
isFlip = bitmask & WRAP_FLIP_FLAG,
|
|
Ctor = isBindKey ? undefined : createCtor(func);
|
|
|
|
function wrapper() {
|
|
var length = arguments.length,
|
|
args = Array(length),
|
|
index = length;
|
|
|
|
while (index--) {
|
|
args[index] = arguments[index];
|
|
}
|
|
if (isCurried) {
|
|
var placeholder = getHolder(wrapper),
|
|
holdersCount = countHolders(args, placeholder);
|
|
}
|
|
if (partials) {
|
|
args = composeArgs(args, partials, holders, isCurried);
|
|
}
|
|
if (partialsRight) {
|
|
args = composeArgsRight(args, partialsRight, holdersRight, isCurried);
|
|
}
|
|
length -= holdersCount;
|
|
if (isCurried && length < arity) {
|
|
var newHolders = replaceHolders(args, placeholder);
|
|
return createRecurry(
|
|
func, bitmask, createHybrid, wrapper.placeholder, thisArg,
|
|
args, newHolders, argPos, ary, arity - length
|
|
);
|
|
}
|
|
var thisBinding = isBind ? thisArg : this,
|
|
fn = isBindKey ? thisBinding[func] : func;
|
|
|
|
length = args.length;
|
|
if (argPos) {
|
|
args = reorder(args, argPos);
|
|
} else if (isFlip && length > 1) {
|
|
args.reverse();
|
|
}
|
|
if (isAry && ary < length) {
|
|
args.length = ary;
|
|
}
|
|
if (this && this !== root && this instanceof wrapper) {
|
|
fn = Ctor || createCtor(fn);
|
|
}
|
|
return fn.apply(thisBinding, args);
|
|
}
|
|
return wrapper;
|
|
}
|
|
|
|
/**
|
|
* Creates a function like `_.invertBy`.
|
|
*
|
|
* @private
|
|
* @param {Function} setter The function to set accumulator values.
|
|
* @param {Function} toIteratee The function to resolve iteratees.
|
|
* @returns {Function} Returns the new inverter function.
|
|
*/
|
|
function createInverter(setter, toIteratee) {
|
|
return function(object, iteratee) {
|
|
return baseInverter(object, setter, toIteratee(iteratee), {});
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Creates a function that performs a mathematical operation on two values.
|
|
*
|
|
* @private
|
|
* @param {Function} operator The function to perform the operation.
|
|
* @param {number} [defaultValue] The value used for `undefined` arguments.
|
|
* @returns {Function} Returns the new mathematical operation function.
|
|
*/
|
|
function createMathOperation(operator, defaultValue) {
|
|
return function(value, other) {
|
|
var result;
|
|
if (value === undefined && other === undefined) {
|
|
return defaultValue;
|
|
}
|
|
if (value !== undefined) {
|
|
result = value;
|
|
}
|
|
if (other !== undefined) {
|
|
if (result === undefined) {
|
|
return other;
|
|
}
|
|
if (typeof value == 'string' || typeof other == 'string') {
|
|
value = baseToString(value);
|
|
other = baseToString(other);
|
|
} else {
|
|
value = baseToNumber(value);
|
|
other = baseToNumber(other);
|
|
}
|
|
result = operator(value, other);
|
|
}
|
|
return result;
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Creates a function like `_.over`.
|
|
*
|
|
* @private
|
|
* @param {Function} arrayFunc The function to iterate over iteratees.
|
|
* @returns {Function} Returns the new over function.
|
|
*/
|
|
function createOver(arrayFunc) {
|
|
return flatRest(function(iteratees) {
|
|
iteratees = arrayMap(iteratees, baseUnary(getIteratee()));
|
|
return baseRest(function(args) {
|
|
var thisArg = this;
|
|
return arrayFunc(iteratees, function(iteratee) {
|
|
return apply(iteratee, thisArg, args);
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Creates the padding for `string` based on `length`. The `chars` string
|
|
* is truncated if the number of characters exceeds `length`.
|
|
*
|
|
* @private
|
|
* @param {number} length The padding length.
|
|
* @param {string} [chars=' '] The string used as padding.
|
|
* @returns {string} Returns the padding for `string`.
|
|
*/
|
|
function createPadding(length, chars) {
|
|
chars = chars === undefined ? ' ' : baseToString(chars);
|
|
|
|
var charsLength = chars.length;
|
|
if (charsLength < 2) {
|
|
return charsLength ? baseRepeat(chars, length) : chars;
|
|
}
|
|
var result = baseRepeat(chars, nativeCeil(length / stringSize(chars)));
|
|
return hasUnicode(chars)
|
|
? castSlice(stringToArray(result), 0, length).join('')
|
|
: result.slice(0, length);
|
|
}
|
|
|
|
/**
|
|
* Creates a function that wraps `func` to invoke it with the `this` binding
|
|
* of `thisArg` and `partials` prepended to the arguments it receives.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to wrap.
|
|
* @param {number} bitmask The bitmask flags. See `createWrap` for more details.
|
|
* @param {*} thisArg The `this` binding of `func`.
|
|
* @param {Array} partials The arguments to prepend to those provided to
|
|
* the new function.
|
|
* @returns {Function} Returns the new wrapped function.
|
|
*/
|
|
function createPartial(func, bitmask, thisArg, partials) {
|
|
var isBind = bitmask & WRAP_BIND_FLAG,
|
|
Ctor = createCtor(func);
|
|
|
|
function wrapper() {
|
|
var argsIndex = -1,
|
|
argsLength = arguments.length,
|
|
leftIndex = -1,
|
|
leftLength = partials.length,
|
|
args = Array(leftLength + argsLength),
|
|
fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
|
|
|
|
while (++leftIndex < leftLength) {
|
|
args[leftIndex] = partials[leftIndex];
|
|
}
|
|
while (argsLength--) {
|
|
args[leftIndex++] = arguments[++argsIndex];
|
|
}
|
|
return apply(fn, isBind ? thisArg : this, args);
|
|
}
|
|
return wrapper;
|
|
}
|
|
|
|
/**
|
|
* Creates a `_.range` or `_.rangeRight` function.
|
|
*
|
|
* @private
|
|
* @param {boolean} [fromRight] Specify iterating from right to left.
|
|
* @returns {Function} Returns the new range function.
|
|
*/
|
|
function createRange(fromRight) {
|
|
return function(start, end, step) {
|
|
if (step && typeof step != 'number' && isIterateeCall(start, end, step)) {
|
|
end = step = undefined;
|
|
}
|
|
// Ensure the sign of `-0` is preserved.
|
|
start = toFinite(start);
|
|
if (end === undefined) {
|
|
end = start;
|
|
start = 0;
|
|
} else {
|
|
end = toFinite(end);
|
|
}
|
|
step = step === undefined ? (start < end ? 1 : -1) : toFinite(step);
|
|
return baseRange(start, end, step, fromRight);
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Creates a function that performs a relational operation on two values.
|
|
*
|
|
* @private
|
|
* @param {Function} operator The function to perform the operation.
|
|
* @returns {Function} Returns the new relational operation function.
|
|
*/
|
|
function createRelationalOperation(operator) {
|
|
return function(value, other) {
|
|
if (!(typeof value == 'string' && typeof other == 'string')) {
|
|
value = toNumber(value);
|
|
other = toNumber(other);
|
|
}
|
|
return operator(value, other);
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Creates a function that wraps `func` to continue currying.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to wrap.
|
|
* @param {number} bitmask The bitmask flags. See `createWrap` for more details.
|
|
* @param {Function} wrapFunc The function to create the `func` wrapper.
|
|
* @param {*} placeholder The placeholder value.
|
|
* @param {*} [thisArg] The `this` binding of `func`.
|
|
* @param {Array} [partials] The arguments to prepend to those provided to
|
|
* the new function.
|
|
* @param {Array} [holders] The `partials` placeholder indexes.
|
|
* @param {Array} [argPos] The argument positions of the new function.
|
|
* @param {number} [ary] The arity cap of `func`.
|
|
* @param {number} [arity] The arity of `func`.
|
|
* @returns {Function} Returns the new wrapped function.
|
|
*/
|
|
function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {
|
|
var isCurry = bitmask & WRAP_CURRY_FLAG,
|
|
newHolders = isCurry ? holders : undefined,
|
|
newHoldersRight = isCurry ? undefined : holders,
|
|
newPartials = isCurry ? partials : undefined,
|
|
newPartialsRight = isCurry ? undefined : partials;
|
|
|
|
bitmask |= (isCurry ? WRAP_PARTIAL_FLAG : WRAP_PARTIAL_RIGHT_FLAG);
|
|
bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG : WRAP_PARTIAL_FLAG);
|
|
|
|
if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) {
|
|
bitmask &= ~(WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG);
|
|
}
|
|
var newData = [
|
|
func, bitmask, thisArg, newPartials, newHolders, newPartialsRight,
|
|
newHoldersRight, argPos, ary, arity
|
|
];
|
|
|
|
var result = wrapFunc.apply(undefined, newData);
|
|
if (isLaziable(func)) {
|
|
setData(result, newData);
|
|
}
|
|
result.placeholder = placeholder;
|
|
return setWrapToString(result, func, bitmask);
|
|
}
|
|
|
|
/**
|
|
* Creates a function like `_.round`.
|
|
*
|
|
* @private
|
|
* @param {string} methodName The name of the `Math` method to use when rounding.
|
|
* @returns {Function} Returns the new round function.
|
|
*/
|
|
function createRound(methodName) {
|
|
var func = Math[methodName];
|
|
return function(number, precision) {
|
|
number = toNumber(number);
|
|
precision = precision == null ? 0 : nativeMin(toInteger(precision), 292);
|
|
if (precision && nativeIsFinite(number)) {
|
|
// Shift with exponential notation to avoid floating-point issues.
|
|
// See [MDN](https://mdn.io/round#Examples) for more details.
|
|
var pair = (toString(number) + 'e').split('e'),
|
|
value = func(pair[0] + 'e' + (+pair[1] + precision));
|
|
|
|
pair = (toString(value) + 'e').split('e');
|
|
return +(pair[0] + 'e' + (+pair[1] - precision));
|
|
}
|
|
return func(number);
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Creates a set object of `values`.
|
|
*
|
|
* @private
|
|
* @param {Array} values The values to add to the set.
|
|
* @returns {Object} Returns the new set.
|
|
*/
|
|
var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) {
|
|
return new Set(values);
|
|
};
|
|
|
|
/**
|
|
* Creates a `_.toPairs` or `_.toPairsIn` function.
|
|
*
|
|
* @private
|
|
* @param {Function} keysFunc The function to get the keys of a given object.
|
|
* @returns {Function} Returns the new pairs function.
|
|
*/
|
|
function createToPairs(keysFunc) {
|
|
return function(object) {
|
|
var tag = getTag(object);
|
|
if (tag == mapTag) {
|
|
return mapToArray(object);
|
|
}
|
|
if (tag == setTag) {
|
|
return setToPairs(object);
|
|
}
|
|
return baseToPairs(object, keysFunc(object));
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Creates a function that either curries or invokes `func` with optional
|
|
* `this` binding and partially applied arguments.
|
|
*
|
|
* @private
|
|
* @param {Function|string} func The function or method name to wrap.
|
|
* @param {number} bitmask The bitmask flags.
|
|
* 1 - `_.bind`
|
|
* 2 - `_.bindKey`
|
|
* 4 - `_.curry` or `_.curryRight` of a bound function
|
|
* 8 - `_.curry`
|
|
* 16 - `_.curryRight`
|
|
* 32 - `_.partial`
|
|
* 64 - `_.partialRight`
|
|
* 128 - `_.rearg`
|
|
* 256 - `_.ary`
|
|
* 512 - `_.flip`
|
|
* @param {*} [thisArg] The `this` binding of `func`.
|
|
* @param {Array} [partials] The arguments to be partially applied.
|
|
* @param {Array} [holders] The `partials` placeholder indexes.
|
|
* @param {Array} [argPos] The argument positions of the new function.
|
|
* @param {number} [ary] The arity cap of `func`.
|
|
* @param {number} [arity] The arity of `func`.
|
|
* @returns {Function} Returns the new wrapped function.
|
|
*/
|
|
function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
|
|
var isBindKey = bitmask & WRAP_BIND_KEY_FLAG;
|
|
if (!isBindKey && typeof func != 'function') {
|
|
throw new TypeError(FUNC_ERROR_TEXT);
|
|
}
|
|
var length = partials ? partials.length : 0;
|
|
if (!length) {
|
|
bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_PARTIAL_RIGHT_FLAG);
|
|
partials = holders = undefined;
|
|
}
|
|
ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0);
|
|
arity = arity === undefined ? arity : toInteger(arity);
|
|
length -= holders ? holders.length : 0;
|
|
|
|
if (bitmask & WRAP_PARTIAL_RIGHT_FLAG) {
|
|
var partialsRight = partials,
|
|
holdersRight = holders;
|
|
|
|
partials = holders = undefined;
|
|
}
|
|
var data = isBindKey ? undefined : getData(func);
|
|
|
|
var newData = [
|
|
func, bitmask, thisArg, partials, holders, partialsRight, holdersRight,
|
|
argPos, ary, arity
|
|
];
|
|
|
|
if (data) {
|
|
mergeData(newData, data);
|
|
}
|
|
func = newData[0];
|
|
bitmask = newData[1];
|
|
thisArg = newData[2];
|
|
partials = newData[3];
|
|
holders = newData[4];
|
|
arity = newData[9] = newData[9] === undefined
|
|
? (isBindKey ? 0 : func.length)
|
|
: nativeMax(newData[9] - length, 0);
|
|
|
|
if (!arity && bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG)) {
|
|
bitmask &= ~(WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG);
|
|
}
|
|
if (!bitmask || bitmask == WRAP_BIND_FLAG) {
|
|
var result = createBind(func, bitmask, thisArg);
|
|
} else if (bitmask == WRAP_CURRY_FLAG || bitmask == WRAP_CURRY_RIGHT_FLAG) {
|
|
result = createCurry(func, bitmask, arity);
|
|
} else if ((bitmask == WRAP_PARTIAL_FLAG || bitmask == (WRAP_BIND_FLAG | WRAP_PARTIAL_FLAG)) && !holders.length) {
|
|
result = createPartial(func, bitmask, thisArg, partials);
|
|
} else {
|
|
result = createHybrid.apply(undefined, newData);
|
|
}
|
|
var setter = data ? baseSetData : setData;
|
|
return setWrapToString(setter(result, newData), func, bitmask);
|
|
}
|
|
|
|
/**
|
|
* Used by `_.defaults` to customize its `_.assignIn` use to assign properties
|
|
* of source objects to the destination object for all destination properties
|
|
* that resolve to `undefined`.
|
|
*
|
|
* @private
|
|
* @param {*} objValue The destination value.
|
|
* @param {*} srcValue The source value.
|
|
* @param {string} key The key of the property to assign.
|
|
* @param {Object} object The parent object of `objValue`.
|
|
* @returns {*} Returns the value to assign.
|
|
*/
|
|
function customDefaultsAssignIn(objValue, srcValue, key, object) {
|
|
if (objValue === undefined ||
|
|
(eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {
|
|
return srcValue;
|
|
}
|
|
return objValue;
|
|
}
|
|
|
|
/**
|
|
* Used by `_.defaultsDeep` to customize its `_.merge` use to merge source
|
|
* objects into destination objects that are passed thru.
|
|
*
|
|
* @private
|
|
* @param {*} objValue The destination value.
|
|
* @param {*} srcValue The source value.
|
|
* @param {string} key The key of the property to merge.
|
|
* @param {Object} object The parent object of `objValue`.
|
|
* @param {Object} source The parent object of `srcValue`.
|
|
* @param {Object} [stack] Tracks traversed source values and their merged
|
|
* counterparts.
|
|
* @returns {*} Returns the value to assign.
|
|
*/
|
|
function customDefaultsMerge(objValue, srcValue, key, object, source, stack) {
|
|
if (isObject(objValue) && isObject(srcValue)) {
|
|
// Recursively merge objects and arrays (susceptible to call stack limits).
|
|
stack.set(srcValue, objValue);
|
|
baseMerge(objValue, srcValue, undefined, customDefaultsMerge, stack);
|
|
stack['delete'](srcValue);
|
|
}
|
|
return objValue;
|
|
}
|
|
|
|
/**
|
|
* Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain
|
|
* objects.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to inspect.
|
|
* @param {string} key The key of the property to inspect.
|
|
* @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`.
|
|
*/
|
|
function customOmitClone(value) {
|
|
return isPlainObject(value) ? undefined : value;
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `baseIsEqualDeep` for arrays with support for
|
|
* partial deep comparisons.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to compare.
|
|
* @param {Array} other The other array to compare.
|
|
* @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
|
|
* @param {Function} customizer The function to customize comparisons.
|
|
* @param {Function} equalFunc The function to determine equivalents of values.
|
|
* @param {Object} stack Tracks traversed `array` and `other` objects.
|
|
* @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
|
|
*/
|
|
function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {
|
|
var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
|
|
arrLength = array.length,
|
|
othLength = other.length;
|
|
|
|
if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
|
|
return false;
|
|
}
|
|
// Check that cyclic values are equal.
|
|
var arrStacked = stack.get(array);
|
|
var othStacked = stack.get(other);
|
|
if (arrStacked && othStacked) {
|
|
return arrStacked == other && othStacked == array;
|
|
}
|
|
var index = -1,
|
|
result = true,
|
|
seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;
|
|
|
|
stack.set(array, other);
|
|
stack.set(other, array);
|
|
|
|
// Ignore non-index properties.
|
|
while (++index < arrLength) {
|
|
var arrValue = array[index],
|
|
othValue = other[index];
|
|
|
|
if (customizer) {
|
|
var compared = isPartial
|
|
? customizer(othValue, arrValue, index, other, array, stack)
|
|
: customizer(arrValue, othValue, index, array, other, stack);
|
|
}
|
|
if (compared !== undefined) {
|
|
if (compared) {
|
|
continue;
|
|
}
|
|
result = false;
|
|
break;
|
|
}
|
|
// Recursively compare arrays (susceptible to call stack limits).
|
|
if (seen) {
|
|
if (!arraySome(other, function(othValue, othIndex) {
|
|
if (!cacheHas(seen, othIndex) &&
|
|
(arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {
|
|
return seen.push(othIndex);
|
|
}
|
|
})) {
|
|
result = false;
|
|
break;
|
|
}
|
|
} else if (!(
|
|
arrValue === othValue ||
|
|
equalFunc(arrValue, othValue, bitmask, customizer, stack)
|
|
)) {
|
|
result = false;
|
|
break;
|
|
}
|
|
}
|
|
stack['delete'](array);
|
|
stack['delete'](other);
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `baseIsEqualDeep` for comparing objects of
|
|
* the same `toStringTag`.
|
|
*
|
|
* **Note:** This function only supports comparing values with tags of
|
|
* `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to compare.
|
|
* @param {Object} other The other object to compare.
|
|
* @param {string} tag The `toStringTag` of the objects to compare.
|
|
* @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
|
|
* @param {Function} customizer The function to customize comparisons.
|
|
* @param {Function} equalFunc The function to determine equivalents of values.
|
|
* @param {Object} stack Tracks traversed `object` and `other` objects.
|
|
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
|
|
*/
|
|
function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {
|
|
switch (tag) {
|
|
case dataViewTag:
|
|
if ((object.byteLength != other.byteLength) ||
|
|
(object.byteOffset != other.byteOffset)) {
|
|
return false;
|
|
}
|
|
object = object.buffer;
|
|
other = other.buffer;
|
|
|
|
case arrayBufferTag:
|
|
if ((object.byteLength != other.byteLength) ||
|
|
!equalFunc(new Uint8Array(object), new Uint8Array(other))) {
|
|
return false;
|
|
}
|
|
return true;
|
|
|
|
case boolTag:
|
|
case dateTag:
|
|
case numberTag:
|
|
// Coerce booleans to `1` or `0` and dates to milliseconds.
|
|
// Invalid dates are coerced to `NaN`.
|
|
return eq(+object, +other);
|
|
|
|
case errorTag:
|
|
return object.name == other.name && object.message == other.message;
|
|
|
|
case regexpTag:
|
|
case stringTag:
|
|
// Coerce regexes to strings and treat strings, primitives and objects,
|
|
// as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring
|
|
// for more details.
|
|
return object == (other + '');
|
|
|
|
case mapTag:
|
|
var convert = mapToArray;
|
|
|
|
case setTag:
|
|
var isPartial = bitmask & COMPARE_PARTIAL_FLAG;
|
|
convert || (convert = setToArray);
|
|
|
|
if (object.size != other.size && !isPartial) {
|
|
return false;
|
|
}
|
|
// Assume cyclic values are equal.
|
|
var stacked = stack.get(object);
|
|
if (stacked) {
|
|
return stacked == other;
|
|
}
|
|
bitmask |= COMPARE_UNORDERED_FLAG;
|
|
|
|
// Recursively compare objects (susceptible to call stack limits).
|
|
stack.set(object, other);
|
|
var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);
|
|
stack['delete'](object);
|
|
return result;
|
|
|
|
case symbolTag:
|
|
if (symbolValueOf) {
|
|
return symbolValueOf.call(object) == symbolValueOf.call(other);
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `baseIsEqualDeep` for objects with support for
|
|
* partial deep comparisons.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to compare.
|
|
* @param {Object} other The other object to compare.
|
|
* @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
|
|
* @param {Function} customizer The function to customize comparisons.
|
|
* @param {Function} equalFunc The function to determine equivalents of values.
|
|
* @param {Object} stack Tracks traversed `object` and `other` objects.
|
|
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
|
|
*/
|
|
function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {
|
|
var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
|
|
objProps = getAllKeys(object),
|
|
objLength = objProps.length,
|
|
othProps = getAllKeys(other),
|
|
othLength = othProps.length;
|
|
|
|
if (objLength != othLength && !isPartial) {
|
|
return false;
|
|
}
|
|
var index = objLength;
|
|
while (index--) {
|
|
var key = objProps[index];
|
|
if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {
|
|
return false;
|
|
}
|
|
}
|
|
// Check that cyclic values are equal.
|
|
var objStacked = stack.get(object);
|
|
var othStacked = stack.get(other);
|
|
if (objStacked && othStacked) {
|
|
return objStacked == other && othStacked == object;
|
|
}
|
|
var result = true;
|
|
stack.set(object, other);
|
|
stack.set(other, object);
|
|
|
|
var skipCtor = isPartial;
|
|
while (++index < objLength) {
|
|
key = objProps[index];
|
|
var objValue = object[key],
|
|
othValue = other[key];
|
|
|
|
if (customizer) {
|
|
var compared = isPartial
|
|
? customizer(othValue, objValue, key, other, object, stack)
|
|
: customizer(objValue, othValue, key, object, other, stack);
|
|
}
|
|
// Recursively compare objects (susceptible to call stack limits).
|
|
if (!(compared === undefined
|
|
? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))
|
|
: compared
|
|
)) {
|
|
result = false;
|
|
break;
|
|
}
|
|
skipCtor || (skipCtor = key == 'constructor');
|
|
}
|
|
if (result && !skipCtor) {
|
|
var objCtor = object.constructor,
|
|
othCtor = other.constructor;
|
|
|
|
// Non `Object` object instances with different constructors are not equal.
|
|
if (objCtor != othCtor &&
|
|
('constructor' in object && 'constructor' in other) &&
|
|
!(typeof objCtor == 'function' && objCtor instanceof objCtor &&
|
|
typeof othCtor == 'function' && othCtor instanceof othCtor)) {
|
|
result = false;
|
|
}
|
|
}
|
|
stack['delete'](object);
|
|
stack['delete'](other);
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `baseRest` which flattens the rest array.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to apply a rest parameter to.
|
|
* @returns {Function} Returns the new function.
|
|
*/
|
|
function flatRest(func) {
|
|
return setToString(overRest(func, undefined, flatten), func + '');
|
|
}
|
|
|
|
/**
|
|
* Creates an array of own enumerable property names and symbols of `object`.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @returns {Array} Returns the array of property names and symbols.
|
|
*/
|
|
function getAllKeys(object) {
|
|
return baseGetAllKeys(object, keys, getSymbols);
|
|
}
|
|
|
|
/**
|
|
* Creates an array of own and inherited enumerable property names and
|
|
* symbols of `object`.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @returns {Array} Returns the array of property names and symbols.
|
|
*/
|
|
function getAllKeysIn(object) {
|
|
return baseGetAllKeys(object, keysIn, getSymbolsIn);
|
|
}
|
|
|
|
/**
|
|
* Gets metadata for `func`.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to query.
|
|
* @returns {*} Returns the metadata for `func`.
|
|
*/
|
|
var getData = !metaMap ? noop : function(func) {
|
|
return metaMap.get(func);
|
|
};
|
|
|
|
/**
|
|
* Gets the name of `func`.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to query.
|
|
* @returns {string} Returns the function name.
|
|
*/
|
|
function getFuncName(func) {
|
|
var result = (func.name + ''),
|
|
array = realNames[result],
|
|
length = hasOwnProperty.call(realNames, result) ? array.length : 0;
|
|
|
|
while (length--) {
|
|
var data = array[length],
|
|
otherFunc = data.func;
|
|
if (otherFunc == null || otherFunc == func) {
|
|
return data.name;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Gets the argument placeholder value for `func`.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to inspect.
|
|
* @returns {*} Returns the placeholder value.
|
|
*/
|
|
function getHolder(func) {
|
|
var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func;
|
|
return object.placeholder;
|
|
}
|
|
|
|
/**
|
|
* Gets the appropriate "iteratee" function. If `_.iteratee` is customized,
|
|
* this function returns the custom method, otherwise it returns `baseIteratee`.
|
|
* If arguments are provided, the chosen function is invoked with them and
|
|
* its result is returned.
|
|
*
|
|
* @private
|
|
* @param {*} [value] The value to convert to an iteratee.
|
|
* @param {number} [arity] The arity of the created iteratee.
|
|
* @returns {Function} Returns the chosen function or its result.
|
|
*/
|
|
function getIteratee() {
|
|
var result = lodash.iteratee || iteratee;
|
|
result = result === iteratee ? baseIteratee : result;
|
|
return arguments.length ? result(arguments[0], arguments[1]) : result;
|
|
}
|
|
|
|
/**
|
|
* Gets the data for `map`.
|
|
*
|
|
* @private
|
|
* @param {Object} map The map to query.
|
|
* @param {string} key The reference key.
|
|
* @returns {*} Returns the map data.
|
|
*/
|
|
function getMapData(map, key) {
|
|
var data = map.__data__;
|
|
return isKeyable(key)
|
|
? data[typeof key == 'string' ? 'string' : 'hash']
|
|
: data.map;
|
|
}
|
|
|
|
/**
|
|
* Gets the property names, values, and compare flags of `object`.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @returns {Array} Returns the match data of `object`.
|
|
*/
|
|
function getMatchData(object) {
|
|
var result = keys(object),
|
|
length = result.length;
|
|
|
|
while (length--) {
|
|
var key = result[length],
|
|
value = object[key];
|
|
|
|
result[length] = [key, value, isStrictComparable(value)];
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Gets the native function at `key` of `object`.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @param {string} key The key of the method to get.
|
|
* @returns {*} Returns the function if it's native, else `undefined`.
|
|
*/
|
|
function getNative(object, key) {
|
|
var value = getValue(object, key);
|
|
return baseIsNative(value) ? value : undefined;
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to query.
|
|
* @returns {string} Returns the raw `toStringTag`.
|
|
*/
|
|
function getRawTag(value) {
|
|
var isOwn = hasOwnProperty.call(value, symToStringTag),
|
|
tag = value[symToStringTag];
|
|
|
|
try {
|
|
value[symToStringTag] = undefined;
|
|
var unmasked = true;
|
|
} catch (e) {}
|
|
|
|
var result = nativeObjectToString.call(value);
|
|
if (unmasked) {
|
|
if (isOwn) {
|
|
value[symToStringTag] = tag;
|
|
} else {
|
|
delete value[symToStringTag];
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Creates an array of the own enumerable symbols of `object`.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @returns {Array} Returns the array of symbols.
|
|
*/
|
|
var getSymbols = !nativeGetSymbols ? stubArray : function(object) {
|
|
if (object == null) {
|
|
return [];
|
|
}
|
|
object = Object(object);
|
|
return arrayFilter(nativeGetSymbols(object), function(symbol) {
|
|
return propertyIsEnumerable.call(object, symbol);
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Creates an array of the own and inherited enumerable symbols of `object`.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @returns {Array} Returns the array of symbols.
|
|
*/
|
|
var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) {
|
|
var result = [];
|
|
while (object) {
|
|
arrayPush(result, getSymbols(object));
|
|
object = getPrototype(object);
|
|
}
|
|
return result;
|
|
};
|
|
|
|
/**
|
|
* Gets the `toStringTag` of `value`.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to query.
|
|
* @returns {string} Returns the `toStringTag`.
|
|
*/
|
|
var getTag = baseGetTag;
|
|
|
|
// Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.
|
|
if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||
|
|
(Map && getTag(new Map) != mapTag) ||
|
|
(Promise && getTag(Promise.resolve()) != promiseTag) ||
|
|
(Set && getTag(new Set) != setTag) ||
|
|
(WeakMap && getTag(new WeakMap) != weakMapTag)) {
|
|
getTag = function(value) {
|
|
var result = baseGetTag(value),
|
|
Ctor = result == objectTag ? value.constructor : undefined,
|
|
ctorString = Ctor ? toSource(Ctor) : '';
|
|
|
|
if (ctorString) {
|
|
switch (ctorString) {
|
|
case dataViewCtorString: return dataViewTag;
|
|
case mapCtorString: return mapTag;
|
|
case promiseCtorString: return promiseTag;
|
|
case setCtorString: return setTag;
|
|
case weakMapCtorString: return weakMapTag;
|
|
}
|
|
}
|
|
return result;
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Gets the view, applying any `transforms` to the `start` and `end` positions.
|
|
*
|
|
* @private
|
|
* @param {number} start The start of the view.
|
|
* @param {number} end The end of the view.
|
|
* @param {Array} transforms The transformations to apply to the view.
|
|
* @returns {Object} Returns an object containing the `start` and `end`
|
|
* positions of the view.
|
|
*/
|
|
function getView(start, end, transforms) {
|
|
var index = -1,
|
|
length = transforms.length;
|
|
|
|
while (++index < length) {
|
|
var data = transforms[index],
|
|
size = data.size;
|
|
|
|
switch (data.type) {
|
|
case 'drop': start += size; break;
|
|
case 'dropRight': end -= size; break;
|
|
case 'take': end = nativeMin(end, start + size); break;
|
|
case 'takeRight': start = nativeMax(start, end - size); break;
|
|
}
|
|
}
|
|
return { 'start': start, 'end': end };
|
|
}
|
|
|
|
/**
|
|
* Extracts wrapper details from the `source` body comment.
|
|
*
|
|
* @private
|
|
* @param {string} source The source to inspect.
|
|
* @returns {Array} Returns the wrapper details.
|
|
*/
|
|
function getWrapDetails(source) {
|
|
var match = source.match(reWrapDetails);
|
|
return match ? match[1].split(reSplitDetails) : [];
|
|
}
|
|
|
|
/**
|
|
* Checks if `path` exists on `object`.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @param {Array|string} path The path to check.
|
|
* @param {Function} hasFunc The function to check properties.
|
|
* @returns {boolean} Returns `true` if `path` exists, else `false`.
|
|
*/
|
|
function hasPath(object, path, hasFunc) {
|
|
path = castPath(path, object);
|
|
|
|
var index = -1,
|
|
length = path.length,
|
|
result = false;
|
|
|
|
while (++index < length) {
|
|
var key = toKey(path[index]);
|
|
if (!(result = object != null && hasFunc(object, key))) {
|
|
break;
|
|
}
|
|
object = object[key];
|
|
}
|
|
if (result || ++index != length) {
|
|
return result;
|
|
}
|
|
length = object == null ? 0 : object.length;
|
|
return !!length && isLength(length) && isIndex(key, length) &&
|
|
(isArray(object) || isArguments(object));
|
|
}
|
|
|
|
/**
|
|
* Initializes an array clone.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to clone.
|
|
* @returns {Array} Returns the initialized clone.
|
|
*/
|
|
function initCloneArray(array) {
|
|
var length = array.length,
|
|
result = new array.constructor(length);
|
|
|
|
// Add properties assigned by `RegExp#exec`.
|
|
if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
|
|
result.index = array.index;
|
|
result.input = array.input;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Initializes an object clone.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to clone.
|
|
* @returns {Object} Returns the initialized clone.
|
|
*/
|
|
function initCloneObject(object) {
|
|
return (typeof object.constructor == 'function' && !isPrototype(object))
|
|
? baseCreate(getPrototype(object))
|
|
: {};
|
|
}
|
|
|
|
/**
|
|
* Initializes an object clone based on its `toStringTag`.
|
|
*
|
|
* **Note:** This function only supports cloning values with tags of
|
|
* `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to clone.
|
|
* @param {string} tag The `toStringTag` of the object to clone.
|
|
* @param {boolean} [isDeep] Specify a deep clone.
|
|
* @returns {Object} Returns the initialized clone.
|
|
*/
|
|
function initCloneByTag(object, tag, isDeep) {
|
|
var Ctor = object.constructor;
|
|
switch (tag) {
|
|
case arrayBufferTag:
|
|
return cloneArrayBuffer(object);
|
|
|
|
case boolTag:
|
|
case dateTag:
|
|
return new Ctor(+object);
|
|
|
|
case dataViewTag:
|
|
return cloneDataView(object, isDeep);
|
|
|
|
case float32Tag: case float64Tag:
|
|
case int8Tag: case int16Tag: case int32Tag:
|
|
case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
|
|
return cloneTypedArray(object, isDeep);
|
|
|
|
case mapTag:
|
|
return new Ctor;
|
|
|
|
case numberTag:
|
|
case stringTag:
|
|
return new Ctor(object);
|
|
|
|
case regexpTag:
|
|
return cloneRegExp(object);
|
|
|
|
case setTag:
|
|
return new Ctor;
|
|
|
|
case symbolTag:
|
|
return cloneSymbol(object);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Inserts wrapper `details` in a comment at the top of the `source` body.
|
|
*
|
|
* @private
|
|
* @param {string} source The source to modify.
|
|
* @returns {Array} details The details to insert.
|
|
* @returns {string} Returns the modified source.
|
|
*/
|
|
function insertWrapDetails(source, details) {
|
|
var length = details.length;
|
|
if (!length) {
|
|
return source;
|
|
}
|
|
var lastIndex = length - 1;
|
|
details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex];
|
|
details = details.join(length > 2 ? ', ' : ' ');
|
|
return source.replace(reWrapComment, '{\n/* [wrapped with ' + details + '] */\n');
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is a flattenable `arguments` object or array.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
|
|
*/
|
|
function isFlattenable(value) {
|
|
return isArray(value) || isArguments(value) ||
|
|
!!(spreadableSymbol && value && value[spreadableSymbol]);
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is a valid array-like index.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
|
|
* @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
|
|
*/
|
|
function isIndex(value, length) {
|
|
var type = typeof value;
|
|
length = length == null ? MAX_SAFE_INTEGER : length;
|
|
|
|
return !!length &&
|
|
(type == 'number' ||
|
|
(type != 'symbol' && reIsUint.test(value))) &&
|
|
(value > -1 && value % 1 == 0 && value < length);
|
|
}
|
|
|
|
/**
|
|
* Checks if the given arguments are from an iteratee call.
|
|
*
|
|
* @private
|
|
* @param {*} value The potential iteratee value argument.
|
|
* @param {*} index The potential iteratee index or key argument.
|
|
* @param {*} object The potential iteratee object argument.
|
|
* @returns {boolean} Returns `true` if the arguments are from an iteratee call,
|
|
* else `false`.
|
|
*/
|
|
function isIterateeCall(value, index, object) {
|
|
if (!isObject(object)) {
|
|
return false;
|
|
}
|
|
var type = typeof index;
|
|
if (type == 'number'
|
|
? (isArrayLike(object) && isIndex(index, object.length))
|
|
: (type == 'string' && index in object)
|
|
) {
|
|
return eq(object[index], value);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is a property name and not a property path.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @param {Object} [object] The object to query keys on.
|
|
* @returns {boolean} Returns `true` if `value` is a property name, else `false`.
|
|
*/
|
|
function isKey(value, object) {
|
|
if (isArray(value)) {
|
|
return false;
|
|
}
|
|
var type = typeof value;
|
|
if (type == 'number' || type == 'symbol' || type == 'boolean' ||
|
|
value == null || isSymbol(value)) {
|
|
return true;
|
|
}
|
|
return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
|
|
(object != null && value in Object(object));
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is suitable for use as unique object key.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is suitable, else `false`.
|
|
*/
|
|
function isKeyable(value) {
|
|
var type = typeof value;
|
|
return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
|
|
? (value !== '__proto__')
|
|
: (value === null);
|
|
}
|
|
|
|
/**
|
|
* Checks if `func` has a lazy counterpart.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to check.
|
|
* @returns {boolean} Returns `true` if `func` has a lazy counterpart,
|
|
* else `false`.
|
|
*/
|
|
function isLaziable(func) {
|
|
var funcName = getFuncName(func),
|
|
other = lodash[funcName];
|
|
|
|
if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {
|
|
return false;
|
|
}
|
|
if (func === other) {
|
|
return true;
|
|
}
|
|
var data = getData(other);
|
|
return !!data && func === data[0];
|
|
}
|
|
|
|
/**
|
|
* Checks if `func` has its source masked.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to check.
|
|
* @returns {boolean} Returns `true` if `func` is masked, else `false`.
|
|
*/
|
|
function isMasked(func) {
|
|
return !!maskSrcKey && (maskSrcKey in func);
|
|
}
|
|
|
|
/**
|
|
* Checks if `func` is capable of being masked.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `func` is maskable, else `false`.
|
|
*/
|
|
var isMaskable = coreJsData ? isFunction : stubFalse;
|
|
|
|
/**
|
|
* Checks if `value` is likely a prototype object.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
|
|
*/
|
|
function isPrototype(value) {
|
|
var Ctor = value && value.constructor,
|
|
proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
|
|
|
|
return value === proto;
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` if suitable for strict
|
|
* equality comparisons, else `false`.
|
|
*/
|
|
function isStrictComparable(value) {
|
|
return value === value && !isObject(value);
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `matchesProperty` for source values suitable
|
|
* for strict equality comparisons, i.e. `===`.
|
|
*
|
|
* @private
|
|
* @param {string} key The key of the property to get.
|
|
* @param {*} srcValue The value to match.
|
|
* @returns {Function} Returns the new spec function.
|
|
*/
|
|
function matchesStrictComparable(key, srcValue) {
|
|
return function(object) {
|
|
if (object == null) {
|
|
return false;
|
|
}
|
|
return object[key] === srcValue &&
|
|
(srcValue !== undefined || (key in Object(object)));
|
|
};
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `_.memoize` which clears the memoized function's
|
|
* cache when it exceeds `MAX_MEMOIZE_SIZE`.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to have its output memoized.
|
|
* @returns {Function} Returns the new memoized function.
|
|
*/
|
|
function memoizeCapped(func) {
|
|
var result = memoize(func, function(key) {
|
|
if (cache.size === MAX_MEMOIZE_SIZE) {
|
|
cache.clear();
|
|
}
|
|
return key;
|
|
});
|
|
|
|
var cache = result.cache;
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Merges the function metadata of `source` into `data`.
|
|
*
|
|
* Merging metadata reduces the number of wrappers used to invoke a function.
|
|
* This is possible because methods like `_.bind`, `_.curry`, and `_.partial`
|
|
* may be applied regardless of execution order. Methods like `_.ary` and
|
|
* `_.rearg` modify function arguments, making the order in which they are
|
|
* executed important, preventing the merging of metadata. However, we make
|
|
* an exception for a safe combined case where curried functions have `_.ary`
|
|
* and or `_.rearg` applied.
|
|
*
|
|
* @private
|
|
* @param {Array} data The destination metadata.
|
|
* @param {Array} source The source metadata.
|
|
* @returns {Array} Returns `data`.
|
|
*/
|
|
function mergeData(data, source) {
|
|
var bitmask = data[1],
|
|
srcBitmask = source[1],
|
|
newBitmask = bitmask | srcBitmask,
|
|
isCommon = newBitmask < (WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG | WRAP_ARY_FLAG);
|
|
|
|
var isCombo =
|
|
((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_CURRY_FLAG)) ||
|
|
((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_REARG_FLAG) && (data[7].length <= source[8])) ||
|
|
((srcBitmask == (WRAP_ARY_FLAG | WRAP_REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == WRAP_CURRY_FLAG));
|
|
|
|
// Exit early if metadata can't be merged.
|
|
if (!(isCommon || isCombo)) {
|
|
return data;
|
|
}
|
|
// Use source `thisArg` if available.
|
|
if (srcBitmask & WRAP_BIND_FLAG) {
|
|
data[2] = source[2];
|
|
// Set when currying a bound function.
|
|
newBitmask |= bitmask & WRAP_BIND_FLAG ? 0 : WRAP_CURRY_BOUND_FLAG;
|
|
}
|
|
// Compose partial arguments.
|
|
var value = source[3];
|
|
if (value) {
|
|
var partials = data[3];
|
|
data[3] = partials ? composeArgs(partials, value, source[4]) : value;
|
|
data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4];
|
|
}
|
|
// Compose partial right arguments.
|
|
value = source[5];
|
|
if (value) {
|
|
partials = data[5];
|
|
data[5] = partials ? composeArgsRight(partials, value, source[6]) : value;
|
|
data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6];
|
|
}
|
|
// Use source `argPos` if available.
|
|
value = source[7];
|
|
if (value) {
|
|
data[7] = value;
|
|
}
|
|
// Use source `ary` if it's smaller.
|
|
if (srcBitmask & WRAP_ARY_FLAG) {
|
|
data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);
|
|
}
|
|
// Use source `arity` if one is not provided.
|
|
if (data[9] == null) {
|
|
data[9] = source[9];
|
|
}
|
|
// Use source `func` and merge bitmasks.
|
|
data[0] = source[0];
|
|
data[1] = newBitmask;
|
|
|
|
return data;
|
|
}
|
|
|
|
/**
|
|
* This function is like
|
|
* [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
|
|
* except that it includes inherited enumerable properties.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @returns {Array} Returns the array of property names.
|
|
*/
|
|
function nativeKeysIn(object) {
|
|
var result = [];
|
|
if (object != null) {
|
|
for (var key in Object(object)) {
|
|
result.push(key);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Converts `value` to a string using `Object.prototype.toString`.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to convert.
|
|
* @returns {string} Returns the converted string.
|
|
*/
|
|
function objectToString(value) {
|
|
return nativeObjectToString.call(value);
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `baseRest` which transforms the rest array.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to apply a rest parameter to.
|
|
* @param {number} [start=func.length-1] The start position of the rest parameter.
|
|
* @param {Function} transform The rest array transform.
|
|
* @returns {Function} Returns the new function.
|
|
*/
|
|
function overRest(func, start, transform) {
|
|
start = nativeMax(start === undefined ? (func.length - 1) : start, 0);
|
|
return function() {
|
|
var args = arguments,
|
|
index = -1,
|
|
length = nativeMax(args.length - start, 0),
|
|
array = Array(length);
|
|
|
|
while (++index < length) {
|
|
array[index] = args[start + index];
|
|
}
|
|
index = -1;
|
|
var otherArgs = Array(start + 1);
|
|
while (++index < start) {
|
|
otherArgs[index] = args[index];
|
|
}
|
|
otherArgs[start] = transform(array);
|
|
return apply(func, this, otherArgs);
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Gets the parent value at `path` of `object`.
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @param {Array} path The path to get the parent value of.
|
|
* @returns {*} Returns the parent value.
|
|
*/
|
|
function parent(object, path) {
|
|
return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1));
|
|
}
|
|
|
|
/**
|
|
* Reorder `array` according to the specified indexes where the element at
|
|
* the first index is assigned as the first element, the element at
|
|
* the second index is assigned as the second element, and so on.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to reorder.
|
|
* @param {Array} indexes The arranged array indexes.
|
|
* @returns {Array} Returns `array`.
|
|
*/
|
|
function reorder(array, indexes) {
|
|
var arrLength = array.length,
|
|
length = nativeMin(indexes.length, arrLength),
|
|
oldArray = copyArray(array);
|
|
|
|
while (length--) {
|
|
var index = indexes[length];
|
|
array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;
|
|
}
|
|
return array;
|
|
}
|
|
|
|
/**
|
|
* Gets the value at `key`, unless `key` is "__proto__" or "constructor".
|
|
*
|
|
* @private
|
|
* @param {Object} object The object to query.
|
|
* @param {string} key The key of the property to get.
|
|
* @returns {*} Returns the property value.
|
|
*/
|
|
function safeGet(object, key) {
|
|
if (key === 'constructor' && typeof object[key] === 'function') {
|
|
return;
|
|
}
|
|
|
|
if (key == '__proto__') {
|
|
return;
|
|
}
|
|
|
|
return object[key];
|
|
}
|
|
|
|
/**
|
|
* Sets metadata for `func`.
|
|
*
|
|
* **Note:** If this function becomes hot, i.e. is invoked a lot in a short
|
|
* period of time, it will trip its breaker and transition to an identity
|
|
* function to avoid garbage collection pauses in V8. See
|
|
* [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070)
|
|
* for more details.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to associate metadata with.
|
|
* @param {*} data The metadata.
|
|
* @returns {Function} Returns `func`.
|
|
*/
|
|
var setData = shortOut(baseSetData);
|
|
|
|
/**
|
|
* A simple wrapper around the global [`setTimeout`](https://mdn.io/setTimeout).
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to delay.
|
|
* @param {number} wait The number of milliseconds to delay invocation.
|
|
* @returns {number|Object} Returns the timer id or timeout object.
|
|
*/
|
|
var setTimeout = ctxSetTimeout || function(func, wait) {
|
|
return root.setTimeout(func, wait);
|
|
};
|
|
|
|
/**
|
|
* Sets the `toString` method of `func` to return `string`.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to modify.
|
|
* @param {Function} string The `toString` result.
|
|
* @returns {Function} Returns `func`.
|
|
*/
|
|
var setToString = shortOut(baseSetToString);
|
|
|
|
/**
|
|
* Sets the `toString` method of `wrapper` to mimic the source of `reference`
|
|
* with wrapper details in a comment at the top of the source body.
|
|
*
|
|
* @private
|
|
* @param {Function} wrapper The function to modify.
|
|
* @param {Function} reference The reference function.
|
|
* @param {number} bitmask The bitmask flags. See `createWrap` for more details.
|
|
* @returns {Function} Returns `wrapper`.
|
|
*/
|
|
function setWrapToString(wrapper, reference, bitmask) {
|
|
var source = (reference + '');
|
|
return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask)));
|
|
}
|
|
|
|
/**
|
|
* Creates a function that'll short out and invoke `identity` instead
|
|
* of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`
|
|
* milliseconds.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to restrict.
|
|
* @returns {Function} Returns the new shortable function.
|
|
*/
|
|
function shortOut(func) {
|
|
var count = 0,
|
|
lastCalled = 0;
|
|
|
|
return function() {
|
|
var stamp = nativeNow(),
|
|
remaining = HOT_SPAN - (stamp - lastCalled);
|
|
|
|
lastCalled = stamp;
|
|
if (remaining > 0) {
|
|
if (++count >= HOT_COUNT) {
|
|
return arguments[0];
|
|
}
|
|
} else {
|
|
count = 0;
|
|
}
|
|
return func.apply(undefined, arguments);
|
|
};
|
|
}
|
|
|
|
/**
|
|
* A specialized version of `_.shuffle` which mutates and sets the size of `array`.
|
|
*
|
|
* @private
|
|
* @param {Array} array The array to shuffle.
|
|
* @param {number} [size=array.length] The size of `array`.
|
|
* @returns {Array} Returns `array`.
|
|
*/
|
|
function shuffleSelf(array, size) {
|
|
var index = -1,
|
|
length = array.length,
|
|
lastIndex = length - 1;
|
|
|
|
size = size === undefined ? length : size;
|
|
while (++index < size) {
|
|
var rand = baseRandom(index, lastIndex),
|
|
value = array[rand];
|
|
|
|
array[rand] = array[index];
|
|
array[index] = value;
|
|
}
|
|
array.length = size;
|
|
return array;
|
|
}
|
|
|
|
/**
|
|
* Converts `string` to a property path array.
|
|
*
|
|
* @private
|
|
* @param {string} string The string to convert.
|
|
* @returns {Array} Returns the property path array.
|
|
*/
|
|
var stringToPath = memoizeCapped(function(string) {
|
|
var result = [];
|
|
if (string.charCodeAt(0) === 46 /* . */) {
|
|
result.push('');
|
|
}
|
|
string.replace(rePropName, function(match, number, quote, subString) {
|
|
result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match));
|
|
});
|
|
return result;
|
|
});
|
|
|
|
/**
|
|
* Converts `value` to a string key if it's not a string or symbol.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to inspect.
|
|
* @returns {string|symbol} Returns the key.
|
|
*/
|
|
function toKey(value) {
|
|
if (typeof value == 'string' || isSymbol(value)) {
|
|
return value;
|
|
}
|
|
var result = (value + '');
|
|
return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
|
|
}
|
|
|
|
/**
|
|
* Converts `func` to its source code.
|
|
*
|
|
* @private
|
|
* @param {Function} func The function to convert.
|
|
* @returns {string} Returns the source code.
|
|
*/
|
|
function toSource(func) {
|
|
if (func != null) {
|
|
try {
|
|
return funcToString.call(func);
|
|
} catch (e) {}
|
|
try {
|
|
return (func + '');
|
|
} catch (e) {}
|
|
}
|
|
return '';
|
|
}
|
|
|
|
/**
|
|
* Updates wrapper `details` based on `bitmask` flags.
|
|
*
|
|
* @private
|
|
* @returns {Array} details The details to modify.
|
|
* @param {number} bitmask The bitmask flags. See `createWrap` for more details.
|
|
* @returns {Array} Returns `details`.
|
|
*/
|
|
function updateWrapDetails(details, bitmask) {
|
|
arrayEach(wrapFlags, function(pair) {
|
|
var value = '_.' + pair[0];
|
|
if ((bitmask & pair[1]) && !arrayIncludes(details, value)) {
|
|
details.push(value);
|
|
}
|
|
});
|
|
return details.sort();
|
|
}
|
|
|
|
/**
|
|
* Creates a clone of `wrapper`.
|
|
*
|
|
* @private
|
|
* @param {Object} wrapper The wrapper to clone.
|
|
* @returns {Object} Returns the cloned wrapper.
|
|
*/
|
|
function wrapperClone(wrapper) {
|
|
if (wrapper instanceof LazyWrapper) {
|
|
return wrapper.clone();
|
|
}
|
|
var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);
|
|
result.__actions__ = copyArray(wrapper.__actions__);
|
|
result.__index__ = wrapper.__index__;
|
|
result.__values__ = wrapper.__values__;
|
|
return result;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* Creates an array of elements split into groups the length of `size`.
|
|
* If `array` can't be split evenly, the final chunk will be the remaining
|
|
* elements.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to process.
|
|
* @param {number} [size=1] The length of each chunk
|
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
|
* @returns {Array} Returns the new array of chunks.
|
|
* @example
|
|
*
|
|
* _.chunk(['a', 'b', 'c', 'd'], 2);
|
|
* // => [['a', 'b'], ['c', 'd']]
|
|
*
|
|
* _.chunk(['a', 'b', 'c', 'd'], 3);
|
|
* // => [['a', 'b', 'c'], ['d']]
|
|
*/
|
|
function chunk(array, size, guard) {
|
|
if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) {
|
|
size = 1;
|
|
} else {
|
|
size = nativeMax(toInteger(size), 0);
|
|
}
|
|
var length = array == null ? 0 : array.length;
|
|
if (!length || size < 1) {
|
|
return [];
|
|
}
|
|
var index = 0,
|
|
resIndex = 0,
|
|
result = Array(nativeCeil(length / size));
|
|
|
|
while (index < length) {
|
|
result[resIndex++] = baseSlice(array, index, (index += size));
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Creates an array with all falsey values removed. The values `false`, `null`,
|
|
* `0`, `""`, `undefined`, and `NaN` are falsey.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Array
|
|
* @param {Array} array The array to compact.
|
|
* @returns {Array} Returns the new array of filtered values.
|
|
* @example
|
|
*
|
|
* _.compact([0, 1, false, 2, '', 3]);
|
|
* // => [1, 2, 3]
|
|
*/
|
|
function compact(array) {
|
|
var index = -1,
|
|
length = array == null ? 0 : array.length,
|
|
resIndex = 0,
|
|
result = [];
|
|
|
|
while (++index < length) {
|
|
var value = array[index];
|
|
if (value) {
|
|
result[resIndex++] = value;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Creates a new array concatenating `array` with any additional arrays
|
|
* and/or values.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to concatenate.
|
|
* @param {...*} [values] The values to concatenate.
|
|
* @returns {Array} Returns the new concatenated array.
|
|
* @example
|
|
*
|
|
* var array = [1];
|
|
* var other = _.concat(array, 2, [3], [[4]]);
|
|
*
|
|
* console.log(other);
|
|
* // => [1, 2, 3, [4]]
|
|
*
|
|
* console.log(array);
|
|
* // => [1]
|
|
*/
|
|
function concat() {
|
|
var length = arguments.length;
|
|
if (!length) {
|
|
return [];
|
|
}
|
|
var args = Array(length - 1),
|
|
array = arguments[0],
|
|
index = length;
|
|
|
|
while (index--) {
|
|
args[index - 1] = arguments[index];
|
|
}
|
|
return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1));
|
|
}
|
|
|
|
/**
|
|
* Creates an array of `array` values not included in the other given arrays
|
|
* using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
|
|
* for equality comparisons. The order and references of result values are
|
|
* determined by the first array.
|
|
*
|
|
* **Note:** Unlike `_.pullAll`, this method returns a new array.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Array
|
|
* @param {Array} array The array to inspect.
|
|
* @param {...Array} [values] The values to exclude.
|
|
* @returns {Array} Returns the new array of filtered values.
|
|
* @see _.without, _.xor
|
|
* @example
|
|
*
|
|
* _.difference([2, 1], [2, 3]);
|
|
* // => [1]
|
|
*/
|
|
var difference = baseRest(function(array, values) {
|
|
return isArrayLikeObject(array)
|
|
? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))
|
|
: [];
|
|
});
|
|
|
|
/**
|
|
* This method is like `_.difference` except that it accepts `iteratee` which
|
|
* is invoked for each element of `array` and `values` to generate the criterion
|
|
* by which they're compared. The order and references of result values are
|
|
* determined by the first array. The iteratee is invoked with one argument:
|
|
* (value).
|
|
*
|
|
* **Note:** Unlike `_.pullAllBy`, this method returns a new array.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to inspect.
|
|
* @param {...Array} [values] The values to exclude.
|
|
* @param {Function} [iteratee=_.identity] The iteratee invoked per element.
|
|
* @returns {Array} Returns the new array of filtered values.
|
|
* @example
|
|
*
|
|
* _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor);
|
|
* // => [1.2]
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
|
|
* // => [{ 'x': 2 }]
|
|
*/
|
|
var differenceBy = baseRest(function(array, values) {
|
|
var iteratee = last(values);
|
|
if (isArrayLikeObject(iteratee)) {
|
|
iteratee = undefined;
|
|
}
|
|
return isArrayLikeObject(array)
|
|
? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), getIteratee(iteratee, 2))
|
|
: [];
|
|
});
|
|
|
|
/**
|
|
* This method is like `_.difference` except that it accepts `comparator`
|
|
* which is invoked to compare elements of `array` to `values`. The order and
|
|
* references of result values are determined by the first array. The comparator
|
|
* is invoked with two arguments: (arrVal, othVal).
|
|
*
|
|
* **Note:** Unlike `_.pullAllWith`, this method returns a new array.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to inspect.
|
|
* @param {...Array} [values] The values to exclude.
|
|
* @param {Function} [comparator] The comparator invoked per element.
|
|
* @returns {Array} Returns the new array of filtered values.
|
|
* @example
|
|
*
|
|
* var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
|
|
*
|
|
* _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);
|
|
* // => [{ 'x': 2, 'y': 1 }]
|
|
*/
|
|
var differenceWith = baseRest(function(array, values) {
|
|
var comparator = last(values);
|
|
if (isArrayLikeObject(comparator)) {
|
|
comparator = undefined;
|
|
}
|
|
return isArrayLikeObject(array)
|
|
? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined, comparator)
|
|
: [];
|
|
});
|
|
|
|
/**
|
|
* Creates a slice of `array` with `n` elements dropped from the beginning.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.5.0
|
|
* @category Array
|
|
* @param {Array} array The array to query.
|
|
* @param {number} [n=1] The number of elements to drop.
|
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
|
* @returns {Array} Returns the slice of `array`.
|
|
* @example
|
|
*
|
|
* _.drop([1, 2, 3]);
|
|
* // => [2, 3]
|
|
*
|
|
* _.drop([1, 2, 3], 2);
|
|
* // => [3]
|
|
*
|
|
* _.drop([1, 2, 3], 5);
|
|
* // => []
|
|
*
|
|
* _.drop([1, 2, 3], 0);
|
|
* // => [1, 2, 3]
|
|
*/
|
|
function drop(array, n, guard) {
|
|
var length = array == null ? 0 : array.length;
|
|
if (!length) {
|
|
return [];
|
|
}
|
|
n = (guard || n === undefined) ? 1 : toInteger(n);
|
|
return baseSlice(array, n < 0 ? 0 : n, length);
|
|
}
|
|
|
|
/**
|
|
* Creates a slice of `array` with `n` elements dropped from the end.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to query.
|
|
* @param {number} [n=1] The number of elements to drop.
|
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
|
* @returns {Array} Returns the slice of `array`.
|
|
* @example
|
|
*
|
|
* _.dropRight([1, 2, 3]);
|
|
* // => [1, 2]
|
|
*
|
|
* _.dropRight([1, 2, 3], 2);
|
|
* // => [1]
|
|
*
|
|
* _.dropRight([1, 2, 3], 5);
|
|
* // => []
|
|
*
|
|
* _.dropRight([1, 2, 3], 0);
|
|
* // => [1, 2, 3]
|
|
*/
|
|
function dropRight(array, n, guard) {
|
|
var length = array == null ? 0 : array.length;
|
|
if (!length) {
|
|
return [];
|
|
}
|
|
n = (guard || n === undefined) ? 1 : toInteger(n);
|
|
n = length - n;
|
|
return baseSlice(array, 0, n < 0 ? 0 : n);
|
|
}
|
|
|
|
/**
|
|
* Creates a slice of `array` excluding elements dropped from the end.
|
|
* Elements are dropped until `predicate` returns falsey. The predicate is
|
|
* invoked with three arguments: (value, index, array).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to query.
|
|
* @param {Function} [predicate=_.identity] The function invoked per iteration.
|
|
* @returns {Array} Returns the slice of `array`.
|
|
* @example
|
|
*
|
|
* var users = [
|
|
* { 'user': 'barney', 'active': true },
|
|
* { 'user': 'fred', 'active': false },
|
|
* { 'user': 'pebbles', 'active': false }
|
|
* ];
|
|
*
|
|
* _.dropRightWhile(users, function(o) { return !o.active; });
|
|
* // => objects for ['barney']
|
|
*
|
|
* // The `_.matches` iteratee shorthand.
|
|
* _.dropRightWhile(users, { 'user': 'pebbles', 'active': false });
|
|
* // => objects for ['barney', 'fred']
|
|
*
|
|
* // The `_.matchesProperty` iteratee shorthand.
|
|
* _.dropRightWhile(users, ['active', false]);
|
|
* // => objects for ['barney']
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.dropRightWhile(users, 'active');
|
|
* // => objects for ['barney', 'fred', 'pebbles']
|
|
*/
|
|
function dropRightWhile(array, predicate) {
|
|
return (array && array.length)
|
|
? baseWhile(array, getIteratee(predicate, 3), true, true)
|
|
: [];
|
|
}
|
|
|
|
/**
|
|
* Creates a slice of `array` excluding elements dropped from the beginning.
|
|
* Elements are dropped until `predicate` returns falsey. The predicate is
|
|
* invoked with three arguments: (value, index, array).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to query.
|
|
* @param {Function} [predicate=_.identity] The function invoked per iteration.
|
|
* @returns {Array} Returns the slice of `array`.
|
|
* @example
|
|
*
|
|
* var users = [
|
|
* { 'user': 'barney', 'active': false },
|
|
* { 'user': 'fred', 'active': false },
|
|
* { 'user': 'pebbles', 'active': true }
|
|
* ];
|
|
*
|
|
* _.dropWhile(users, function(o) { return !o.active; });
|
|
* // => objects for ['pebbles']
|
|
*
|
|
* // The `_.matches` iteratee shorthand.
|
|
* _.dropWhile(users, { 'user': 'barney', 'active': false });
|
|
* // => objects for ['fred', 'pebbles']
|
|
*
|
|
* // The `_.matchesProperty` iteratee shorthand.
|
|
* _.dropWhile(users, ['active', false]);
|
|
* // => objects for ['pebbles']
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.dropWhile(users, 'active');
|
|
* // => objects for ['barney', 'fred', 'pebbles']
|
|
*/
|
|
function dropWhile(array, predicate) {
|
|
return (array && array.length)
|
|
? baseWhile(array, getIteratee(predicate, 3), true)
|
|
: [];
|
|
}
|
|
|
|
/**
|
|
* Fills elements of `array` with `value` from `start` up to, but not
|
|
* including, `end`.
|
|
*
|
|
* **Note:** This method mutates `array`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.2.0
|
|
* @category Array
|
|
* @param {Array} array The array to fill.
|
|
* @param {*} value The value to fill `array` with.
|
|
* @param {number} [start=0] The start position.
|
|
* @param {number} [end=array.length] The end position.
|
|
* @returns {Array} Returns `array`.
|
|
* @example
|
|
*
|
|
* var array = [1, 2, 3];
|
|
*
|
|
* _.fill(array, 'a');
|
|
* console.log(array);
|
|
* // => ['a', 'a', 'a']
|
|
*
|
|
* _.fill(Array(3), 2);
|
|
* // => [2, 2, 2]
|
|
*
|
|
* _.fill([4, 6, 8, 10], '*', 1, 3);
|
|
* // => [4, '*', '*', 10]
|
|
*/
|
|
function fill(array, value, start, end) {
|
|
var length = array == null ? 0 : array.length;
|
|
if (!length) {
|
|
return [];
|
|
}
|
|
if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {
|
|
start = 0;
|
|
end = length;
|
|
}
|
|
return baseFill(array, value, start, end);
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.find` except that it returns the index of the first
|
|
* element `predicate` returns truthy for instead of the element itself.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 1.1.0
|
|
* @category Array
|
|
* @param {Array} array The array to inspect.
|
|
* @param {Function} [predicate=_.identity] The function invoked per iteration.
|
|
* @param {number} [fromIndex=0] The index to search from.
|
|
* @returns {number} Returns the index of the found element, else `-1`.
|
|
* @example
|
|
*
|
|
* var users = [
|
|
* { 'user': 'barney', 'active': false },
|
|
* { 'user': 'fred', 'active': false },
|
|
* { 'user': 'pebbles', 'active': true }
|
|
* ];
|
|
*
|
|
* _.findIndex(users, function(o) { return o.user == 'barney'; });
|
|
* // => 0
|
|
*
|
|
* // The `_.matches` iteratee shorthand.
|
|
* _.findIndex(users, { 'user': 'fred', 'active': false });
|
|
* // => 1
|
|
*
|
|
* // The `_.matchesProperty` iteratee shorthand.
|
|
* _.findIndex(users, ['active', false]);
|
|
* // => 0
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.findIndex(users, 'active');
|
|
* // => 2
|
|
*/
|
|
function findIndex(array, predicate, fromIndex) {
|
|
var length = array == null ? 0 : array.length;
|
|
if (!length) {
|
|
return -1;
|
|
}
|
|
var index = fromIndex == null ? 0 : toInteger(fromIndex);
|
|
if (index < 0) {
|
|
index = nativeMax(length + index, 0);
|
|
}
|
|
return baseFindIndex(array, getIteratee(predicate, 3), index);
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.findIndex` except that it iterates over elements
|
|
* of `collection` from right to left.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 2.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to inspect.
|
|
* @param {Function} [predicate=_.identity] The function invoked per iteration.
|
|
* @param {number} [fromIndex=array.length-1] The index to search from.
|
|
* @returns {number} Returns the index of the found element, else `-1`.
|
|
* @example
|
|
*
|
|
* var users = [
|
|
* { 'user': 'barney', 'active': true },
|
|
* { 'user': 'fred', 'active': false },
|
|
* { 'user': 'pebbles', 'active': false }
|
|
* ];
|
|
*
|
|
* _.findLastIndex(users, function(o) { return o.user == 'pebbles'; });
|
|
* // => 2
|
|
*
|
|
* // The `_.matches` iteratee shorthand.
|
|
* _.findLastIndex(users, { 'user': 'barney', 'active': true });
|
|
* // => 0
|
|
*
|
|
* // The `_.matchesProperty` iteratee shorthand.
|
|
* _.findLastIndex(users, ['active', false]);
|
|
* // => 2
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.findLastIndex(users, 'active');
|
|
* // => 0
|
|
*/
|
|
function findLastIndex(array, predicate, fromIndex) {
|
|
var length = array == null ? 0 : array.length;
|
|
if (!length) {
|
|
return -1;
|
|
}
|
|
var index = length - 1;
|
|
if (fromIndex !== undefined) {
|
|
index = toInteger(fromIndex);
|
|
index = fromIndex < 0
|
|
? nativeMax(length + index, 0)
|
|
: nativeMin(index, length - 1);
|
|
}
|
|
return baseFindIndex(array, getIteratee(predicate, 3), index, true);
|
|
}
|
|
|
|
/**
|
|
* Flattens `array` a single level deep.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Array
|
|
* @param {Array} array The array to flatten.
|
|
* @returns {Array} Returns the new flattened array.
|
|
* @example
|
|
*
|
|
* _.flatten([1, [2, [3, [4]], 5]]);
|
|
* // => [1, 2, [3, [4]], 5]
|
|
*/
|
|
function flatten(array) {
|
|
var length = array == null ? 0 : array.length;
|
|
return length ? baseFlatten(array, 1) : [];
|
|
}
|
|
|
|
/**
|
|
* Recursively flattens `array`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to flatten.
|
|
* @returns {Array} Returns the new flattened array.
|
|
* @example
|
|
*
|
|
* _.flattenDeep([1, [2, [3, [4]], 5]]);
|
|
* // => [1, 2, 3, 4, 5]
|
|
*/
|
|
function flattenDeep(array) {
|
|
var length = array == null ? 0 : array.length;
|
|
return length ? baseFlatten(array, INFINITY) : [];
|
|
}
|
|
|
|
/**
|
|
* Recursively flatten `array` up to `depth` times.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.4.0
|
|
* @category Array
|
|
* @param {Array} array The array to flatten.
|
|
* @param {number} [depth=1] The maximum recursion depth.
|
|
* @returns {Array} Returns the new flattened array.
|
|
* @example
|
|
*
|
|
* var array = [1, [2, [3, [4]], 5]];
|
|
*
|
|
* _.flattenDepth(array, 1);
|
|
* // => [1, 2, [3, [4]], 5]
|
|
*
|
|
* _.flattenDepth(array, 2);
|
|
* // => [1, 2, 3, [4], 5]
|
|
*/
|
|
function flattenDepth(array, depth) {
|
|
var length = array == null ? 0 : array.length;
|
|
if (!length) {
|
|
return [];
|
|
}
|
|
depth = depth === undefined ? 1 : toInteger(depth);
|
|
return baseFlatten(array, depth);
|
|
}
|
|
|
|
/**
|
|
* The inverse of `_.toPairs`; this method returns an object composed
|
|
* from key-value `pairs`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Array
|
|
* @param {Array} pairs The key-value pairs.
|
|
* @returns {Object} Returns the new object.
|
|
* @example
|
|
*
|
|
* _.fromPairs([['a', 1], ['b', 2]]);
|
|
* // => { 'a': 1, 'b': 2 }
|
|
*/
|
|
function fromPairs(pairs) {
|
|
var index = -1,
|
|
length = pairs == null ? 0 : pairs.length,
|
|
result = {};
|
|
|
|
while (++index < length) {
|
|
var pair = pairs[index];
|
|
result[pair[0]] = pair[1];
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Gets the first element of `array`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @alias first
|
|
* @category Array
|
|
* @param {Array} array The array to query.
|
|
* @returns {*} Returns the first element of `array`.
|
|
* @example
|
|
*
|
|
* _.head([1, 2, 3]);
|
|
* // => 1
|
|
*
|
|
* _.head([]);
|
|
* // => undefined
|
|
*/
|
|
function head(array) {
|
|
return (array && array.length) ? array[0] : undefined;
|
|
}
|
|
|
|
/**
|
|
* Gets the index at which the first occurrence of `value` is found in `array`
|
|
* using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
|
|
* for equality comparisons. If `fromIndex` is negative, it's used as the
|
|
* offset from the end of `array`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Array
|
|
* @param {Array} array The array to inspect.
|
|
* @param {*} value The value to search for.
|
|
* @param {number} [fromIndex=0] The index to search from.
|
|
* @returns {number} Returns the index of the matched value, else `-1`.
|
|
* @example
|
|
*
|
|
* _.indexOf([1, 2, 1, 2], 2);
|
|
* // => 1
|
|
*
|
|
* // Search from the `fromIndex`.
|
|
* _.indexOf([1, 2, 1, 2], 2, 2);
|
|
* // => 3
|
|
*/
|
|
function indexOf(array, value, fromIndex) {
|
|
var length = array == null ? 0 : array.length;
|
|
if (!length) {
|
|
return -1;
|
|
}
|
|
var index = fromIndex == null ? 0 : toInteger(fromIndex);
|
|
if (index < 0) {
|
|
index = nativeMax(length + index, 0);
|
|
}
|
|
return baseIndexOf(array, value, index);
|
|
}
|
|
|
|
/**
|
|
* Gets all but the last element of `array`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Array
|
|
* @param {Array} array The array to query.
|
|
* @returns {Array} Returns the slice of `array`.
|
|
* @example
|
|
*
|
|
* _.initial([1, 2, 3]);
|
|
* // => [1, 2]
|
|
*/
|
|
function initial(array) {
|
|
var length = array == null ? 0 : array.length;
|
|
return length ? baseSlice(array, 0, -1) : [];
|
|
}
|
|
|
|
/**
|
|
* Creates an array of unique values that are included in all given arrays
|
|
* using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
|
|
* for equality comparisons. The order and references of result values are
|
|
* determined by the first array.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Array
|
|
* @param {...Array} [arrays] The arrays to inspect.
|
|
* @returns {Array} Returns the new array of intersecting values.
|
|
* @example
|
|
*
|
|
* _.intersection([2, 1], [2, 3]);
|
|
* // => [2]
|
|
*/
|
|
var intersection = baseRest(function(arrays) {
|
|
var mapped = arrayMap(arrays, castArrayLikeObject);
|
|
return (mapped.length && mapped[0] === arrays[0])
|
|
? baseIntersection(mapped)
|
|
: [];
|
|
});
|
|
|
|
/**
|
|
* This method is like `_.intersection` except that it accepts `iteratee`
|
|
* which is invoked for each element of each `arrays` to generate the criterion
|
|
* by which they're compared. The order and references of result values are
|
|
* determined by the first array. The iteratee is invoked with one argument:
|
|
* (value).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Array
|
|
* @param {...Array} [arrays] The arrays to inspect.
|
|
* @param {Function} [iteratee=_.identity] The iteratee invoked per element.
|
|
* @returns {Array} Returns the new array of intersecting values.
|
|
* @example
|
|
*
|
|
* _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor);
|
|
* // => [2.1]
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
|
|
* // => [{ 'x': 1 }]
|
|
*/
|
|
var intersectionBy = baseRest(function(arrays) {
|
|
var iteratee = last(arrays),
|
|
mapped = arrayMap(arrays, castArrayLikeObject);
|
|
|
|
if (iteratee === last(mapped)) {
|
|
iteratee = undefined;
|
|
} else {
|
|
mapped.pop();
|
|
}
|
|
return (mapped.length && mapped[0] === arrays[0])
|
|
? baseIntersection(mapped, getIteratee(iteratee, 2))
|
|
: [];
|
|
});
|
|
|
|
/**
|
|
* This method is like `_.intersection` except that it accepts `comparator`
|
|
* which is invoked to compare elements of `arrays`. The order and references
|
|
* of result values are determined by the first array. The comparator is
|
|
* invoked with two arguments: (arrVal, othVal).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Array
|
|
* @param {...Array} [arrays] The arrays to inspect.
|
|
* @param {Function} [comparator] The comparator invoked per element.
|
|
* @returns {Array} Returns the new array of intersecting values.
|
|
* @example
|
|
*
|
|
* var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
|
|
* var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
|
|
*
|
|
* _.intersectionWith(objects, others, _.isEqual);
|
|
* // => [{ 'x': 1, 'y': 2 }]
|
|
*/
|
|
var intersectionWith = baseRest(function(arrays) {
|
|
var comparator = last(arrays),
|
|
mapped = arrayMap(arrays, castArrayLikeObject);
|
|
|
|
comparator = typeof comparator == 'function' ? comparator : undefined;
|
|
if (comparator) {
|
|
mapped.pop();
|
|
}
|
|
return (mapped.length && mapped[0] === arrays[0])
|
|
? baseIntersection(mapped, undefined, comparator)
|
|
: [];
|
|
});
|
|
|
|
/**
|
|
* Converts all elements in `array` into a string separated by `separator`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to convert.
|
|
* @param {string} [separator=','] The element separator.
|
|
* @returns {string} Returns the joined string.
|
|
* @example
|
|
*
|
|
* _.join(['a', 'b', 'c'], '~');
|
|
* // => 'a~b~c'
|
|
*/
|
|
function join(array, separator) {
|
|
return array == null ? '' : nativeJoin.call(array, separator);
|
|
}
|
|
|
|
/**
|
|
* Gets the last element of `array`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Array
|
|
* @param {Array} array The array to query.
|
|
* @returns {*} Returns the last element of `array`.
|
|
* @example
|
|
*
|
|
* _.last([1, 2, 3]);
|
|
* // => 3
|
|
*/
|
|
function last(array) {
|
|
var length = array == null ? 0 : array.length;
|
|
return length ? array[length - 1] : undefined;
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.indexOf` except that it iterates over elements of
|
|
* `array` from right to left.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Array
|
|
* @param {Array} array The array to inspect.
|
|
* @param {*} value The value to search for.
|
|
* @param {number} [fromIndex=array.length-1] The index to search from.
|
|
* @returns {number} Returns the index of the matched value, else `-1`.
|
|
* @example
|
|
*
|
|
* _.lastIndexOf([1, 2, 1, 2], 2);
|
|
* // => 3
|
|
*
|
|
* // Search from the `fromIndex`.
|
|
* _.lastIndexOf([1, 2, 1, 2], 2, 2);
|
|
* // => 1
|
|
*/
|
|
function lastIndexOf(array, value, fromIndex) {
|
|
var length = array == null ? 0 : array.length;
|
|
if (!length) {
|
|
return -1;
|
|
}
|
|
var index = length;
|
|
if (fromIndex !== undefined) {
|
|
index = toInteger(fromIndex);
|
|
index = index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1);
|
|
}
|
|
return value === value
|
|
? strictLastIndexOf(array, value, index)
|
|
: baseFindIndex(array, baseIsNaN, index, true);
|
|
}
|
|
|
|
/**
|
|
* Gets the element at index `n` of `array`. If `n` is negative, the nth
|
|
* element from the end is returned.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.11.0
|
|
* @category Array
|
|
* @param {Array} array The array to query.
|
|
* @param {number} [n=0] The index of the element to return.
|
|
* @returns {*} Returns the nth element of `array`.
|
|
* @example
|
|
*
|
|
* var array = ['a', 'b', 'c', 'd'];
|
|
*
|
|
* _.nth(array, 1);
|
|
* // => 'b'
|
|
*
|
|
* _.nth(array, -2);
|
|
* // => 'c';
|
|
*/
|
|
function nth(array, n) {
|
|
return (array && array.length) ? baseNth(array, toInteger(n)) : undefined;
|
|
}
|
|
|
|
/**
|
|
* Removes all given values from `array` using
|
|
* [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
|
|
* for equality comparisons.
|
|
*
|
|
* **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove`
|
|
* to remove elements from an array by predicate.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 2.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to modify.
|
|
* @param {...*} [values] The values to remove.
|
|
* @returns {Array} Returns `array`.
|
|
* @example
|
|
*
|
|
* var array = ['a', 'b', 'c', 'a', 'b', 'c'];
|
|
*
|
|
* _.pull(array, 'a', 'c');
|
|
* console.log(array);
|
|
* // => ['b', 'b']
|
|
*/
|
|
var pull = baseRest(pullAll);
|
|
|
|
/**
|
|
* This method is like `_.pull` except that it accepts an array of values to remove.
|
|
*
|
|
* **Note:** Unlike `_.difference`, this method mutates `array`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to modify.
|
|
* @param {Array} values The values to remove.
|
|
* @returns {Array} Returns `array`.
|
|
* @example
|
|
*
|
|
* var array = ['a', 'b', 'c', 'a', 'b', 'c'];
|
|
*
|
|
* _.pullAll(array, ['a', 'c']);
|
|
* console.log(array);
|
|
* // => ['b', 'b']
|
|
*/
|
|
function pullAll(array, values) {
|
|
return (array && array.length && values && values.length)
|
|
? basePullAll(array, values)
|
|
: array;
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.pullAll` except that it accepts `iteratee` which is
|
|
* invoked for each element of `array` and `values` to generate the criterion
|
|
* by which they're compared. The iteratee is invoked with one argument: (value).
|
|
*
|
|
* **Note:** Unlike `_.differenceBy`, this method mutates `array`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to modify.
|
|
* @param {Array} values The values to remove.
|
|
* @param {Function} [iteratee=_.identity] The iteratee invoked per element.
|
|
* @returns {Array} Returns `array`.
|
|
* @example
|
|
*
|
|
* var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
|
|
*
|
|
* _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x');
|
|
* console.log(array);
|
|
* // => [{ 'x': 2 }]
|
|
*/
|
|
function pullAllBy(array, values, iteratee) {
|
|
return (array && array.length && values && values.length)
|
|
? basePullAll(array, values, getIteratee(iteratee, 2))
|
|
: array;
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.pullAll` except that it accepts `comparator` which
|
|
* is invoked to compare elements of `array` to `values`. The comparator is
|
|
* invoked with two arguments: (arrVal, othVal).
|
|
*
|
|
* **Note:** Unlike `_.differenceWith`, this method mutates `array`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.6.0
|
|
* @category Array
|
|
* @param {Array} array The array to modify.
|
|
* @param {Array} values The values to remove.
|
|
* @param {Function} [comparator] The comparator invoked per element.
|
|
* @returns {Array} Returns `array`.
|
|
* @example
|
|
*
|
|
* var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }];
|
|
*
|
|
* _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual);
|
|
* console.log(array);
|
|
* // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }]
|
|
*/
|
|
function pullAllWith(array, values, comparator) {
|
|
return (array && array.length && values && values.length)
|
|
? basePullAll(array, values, undefined, comparator)
|
|
: array;
|
|
}
|
|
|
|
/**
|
|
* Removes elements from `array` corresponding to `indexes` and returns an
|
|
* array of removed elements.
|
|
*
|
|
* **Note:** Unlike `_.at`, this method mutates `array`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to modify.
|
|
* @param {...(number|number[])} [indexes] The indexes of elements to remove.
|
|
* @returns {Array} Returns the new array of removed elements.
|
|
* @example
|
|
*
|
|
* var array = ['a', 'b', 'c', 'd'];
|
|
* var pulled = _.pullAt(array, [1, 3]);
|
|
*
|
|
* console.log(array);
|
|
* // => ['a', 'c']
|
|
*
|
|
* console.log(pulled);
|
|
* // => ['b', 'd']
|
|
*/
|
|
var pullAt = flatRest(function(array, indexes) {
|
|
var length = array == null ? 0 : array.length,
|
|
result = baseAt(array, indexes);
|
|
|
|
basePullAt(array, arrayMap(indexes, function(index) {
|
|
return isIndex(index, length) ? +index : index;
|
|
}).sort(compareAscending));
|
|
|
|
return result;
|
|
});
|
|
|
|
/**
|
|
* Removes all elements from `array` that `predicate` returns truthy for
|
|
* and returns an array of the removed elements. The predicate is invoked
|
|
* with three arguments: (value, index, array).
|
|
*
|
|
* **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`
|
|
* to pull elements from an array by value.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 2.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to modify.
|
|
* @param {Function} [predicate=_.identity] The function invoked per iteration.
|
|
* @returns {Array} Returns the new array of removed elements.
|
|
* @example
|
|
*
|
|
* var array = [1, 2, 3, 4];
|
|
* var evens = _.remove(array, function(n) {
|
|
* return n % 2 == 0;
|
|
* });
|
|
*
|
|
* console.log(array);
|
|
* // => [1, 3]
|
|
*
|
|
* console.log(evens);
|
|
* // => [2, 4]
|
|
*/
|
|
function remove(array, predicate) {
|
|
var result = [];
|
|
if (!(array && array.length)) {
|
|
return result;
|
|
}
|
|
var index = -1,
|
|
indexes = [],
|
|
length = array.length;
|
|
|
|
predicate = getIteratee(predicate, 3);
|
|
while (++index < length) {
|
|
var value = array[index];
|
|
if (predicate(value, index, array)) {
|
|
result.push(value);
|
|
indexes.push(index);
|
|
}
|
|
}
|
|
basePullAt(array, indexes);
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Reverses `array` so that the first element becomes the last, the second
|
|
* element becomes the second to last, and so on.
|
|
*
|
|
* **Note:** This method mutates `array` and is based on
|
|
* [`Array#reverse`](https://mdn.io/Array/reverse).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to modify.
|
|
* @returns {Array} Returns `array`.
|
|
* @example
|
|
*
|
|
* var array = [1, 2, 3];
|
|
*
|
|
* _.reverse(array);
|
|
* // => [3, 2, 1]
|
|
*
|
|
* console.log(array);
|
|
* // => [3, 2, 1]
|
|
*/
|
|
function reverse(array) {
|
|
return array == null ? array : nativeReverse.call(array);
|
|
}
|
|
|
|
/**
|
|
* Creates a slice of `array` from `start` up to, but not including, `end`.
|
|
*
|
|
* **Note:** This method is used instead of
|
|
* [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are
|
|
* returned.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to slice.
|
|
* @param {number} [start=0] The start position.
|
|
* @param {number} [end=array.length] The end position.
|
|
* @returns {Array} Returns the slice of `array`.
|
|
*/
|
|
function slice(array, start, end) {
|
|
var length = array == null ? 0 : array.length;
|
|
if (!length) {
|
|
return [];
|
|
}
|
|
if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {
|
|
start = 0;
|
|
end = length;
|
|
}
|
|
else {
|
|
start = start == null ? 0 : toInteger(start);
|
|
end = end === undefined ? length : toInteger(end);
|
|
}
|
|
return baseSlice(array, start, end);
|
|
}
|
|
|
|
/**
|
|
* Uses a binary search to determine the lowest index at which `value`
|
|
* should be inserted into `array` in order to maintain its sort order.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Array
|
|
* @param {Array} array The sorted array to inspect.
|
|
* @param {*} value The value to evaluate.
|
|
* @returns {number} Returns the index at which `value` should be inserted
|
|
* into `array`.
|
|
* @example
|
|
*
|
|
* _.sortedIndex([30, 50], 40);
|
|
* // => 1
|
|
*/
|
|
function sortedIndex(array, value) {
|
|
return baseSortedIndex(array, value);
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.sortedIndex` except that it accepts `iteratee`
|
|
* which is invoked for `value` and each element of `array` to compute their
|
|
* sort ranking. The iteratee is invoked with one argument: (value).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Array
|
|
* @param {Array} array The sorted array to inspect.
|
|
* @param {*} value The value to evaluate.
|
|
* @param {Function} [iteratee=_.identity] The iteratee invoked per element.
|
|
* @returns {number} Returns the index at which `value` should be inserted
|
|
* into `array`.
|
|
* @example
|
|
*
|
|
* var objects = [{ 'x': 4 }, { 'x': 5 }];
|
|
*
|
|
* _.sortedIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
|
|
* // => 0
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.sortedIndexBy(objects, { 'x': 4 }, 'x');
|
|
* // => 0
|
|
*/
|
|
function sortedIndexBy(array, value, iteratee) {
|
|
return baseSortedIndexBy(array, value, getIteratee(iteratee, 2));
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.indexOf` except that it performs a binary
|
|
* search on a sorted `array`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to inspect.
|
|
* @param {*} value The value to search for.
|
|
* @returns {number} Returns the index of the matched value, else `-1`.
|
|
* @example
|
|
*
|
|
* _.sortedIndexOf([4, 5, 5, 5, 6], 5);
|
|
* // => 1
|
|
*/
|
|
function sortedIndexOf(array, value) {
|
|
var length = array == null ? 0 : array.length;
|
|
if (length) {
|
|
var index = baseSortedIndex(array, value);
|
|
if (index < length && eq(array[index], value)) {
|
|
return index;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.sortedIndex` except that it returns the highest
|
|
* index at which `value` should be inserted into `array` in order to
|
|
* maintain its sort order.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Array
|
|
* @param {Array} array The sorted array to inspect.
|
|
* @param {*} value The value to evaluate.
|
|
* @returns {number} Returns the index at which `value` should be inserted
|
|
* into `array`.
|
|
* @example
|
|
*
|
|
* _.sortedLastIndex([4, 5, 5, 5, 6], 5);
|
|
* // => 4
|
|
*/
|
|
function sortedLastIndex(array, value) {
|
|
return baseSortedIndex(array, value, true);
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.sortedLastIndex` except that it accepts `iteratee`
|
|
* which is invoked for `value` and each element of `array` to compute their
|
|
* sort ranking. The iteratee is invoked with one argument: (value).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Array
|
|
* @param {Array} array The sorted array to inspect.
|
|
* @param {*} value The value to evaluate.
|
|
* @param {Function} [iteratee=_.identity] The iteratee invoked per element.
|
|
* @returns {number} Returns the index at which `value` should be inserted
|
|
* into `array`.
|
|
* @example
|
|
*
|
|
* var objects = [{ 'x': 4 }, { 'x': 5 }];
|
|
*
|
|
* _.sortedLastIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
|
|
* // => 1
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.sortedLastIndexBy(objects, { 'x': 4 }, 'x');
|
|
* // => 1
|
|
*/
|
|
function sortedLastIndexBy(array, value, iteratee) {
|
|
return baseSortedIndexBy(array, value, getIteratee(iteratee, 2), true);
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.lastIndexOf` except that it performs a binary
|
|
* search on a sorted `array`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to inspect.
|
|
* @param {*} value The value to search for.
|
|
* @returns {number} Returns the index of the matched value, else `-1`.
|
|
* @example
|
|
*
|
|
* _.sortedLastIndexOf([4, 5, 5, 5, 6], 5);
|
|
* // => 3
|
|
*/
|
|
function sortedLastIndexOf(array, value) {
|
|
var length = array == null ? 0 : array.length;
|
|
if (length) {
|
|
var index = baseSortedIndex(array, value, true) - 1;
|
|
if (eq(array[index], value)) {
|
|
return index;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.uniq` except that it's designed and optimized
|
|
* for sorted arrays.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to inspect.
|
|
* @returns {Array} Returns the new duplicate free array.
|
|
* @example
|
|
*
|
|
* _.sortedUniq([1, 1, 2]);
|
|
* // => [1, 2]
|
|
*/
|
|
function sortedUniq(array) {
|
|
return (array && array.length)
|
|
? baseSortedUniq(array)
|
|
: [];
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.uniqBy` except that it's designed and optimized
|
|
* for sorted arrays.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to inspect.
|
|
* @param {Function} [iteratee] The iteratee invoked per element.
|
|
* @returns {Array} Returns the new duplicate free array.
|
|
* @example
|
|
*
|
|
* _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor);
|
|
* // => [1.1, 2.3]
|
|
*/
|
|
function sortedUniqBy(array, iteratee) {
|
|
return (array && array.length)
|
|
? baseSortedUniq(array, getIteratee(iteratee, 2))
|
|
: [];
|
|
}
|
|
|
|
/**
|
|
* Gets all but the first element of `array`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to query.
|
|
* @returns {Array} Returns the slice of `array`.
|
|
* @example
|
|
*
|
|
* _.tail([1, 2, 3]);
|
|
* // => [2, 3]
|
|
*/
|
|
function tail(array) {
|
|
var length = array == null ? 0 : array.length;
|
|
return length ? baseSlice(array, 1, length) : [];
|
|
}
|
|
|
|
/**
|
|
* Creates a slice of `array` with `n` elements taken from the beginning.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Array
|
|
* @param {Array} array The array to query.
|
|
* @param {number} [n=1] The number of elements to take.
|
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
|
* @returns {Array} Returns the slice of `array`.
|
|
* @example
|
|
*
|
|
* _.take([1, 2, 3]);
|
|
* // => [1]
|
|
*
|
|
* _.take([1, 2, 3], 2);
|
|
* // => [1, 2]
|
|
*
|
|
* _.take([1, 2, 3], 5);
|
|
* // => [1, 2, 3]
|
|
*
|
|
* _.take([1, 2, 3], 0);
|
|
* // => []
|
|
*/
|
|
function take(array, n, guard) {
|
|
if (!(array && array.length)) {
|
|
return [];
|
|
}
|
|
n = (guard || n === undefined) ? 1 : toInteger(n);
|
|
return baseSlice(array, 0, n < 0 ? 0 : n);
|
|
}
|
|
|
|
/**
|
|
* Creates a slice of `array` with `n` elements taken from the end.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to query.
|
|
* @param {number} [n=1] The number of elements to take.
|
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
|
* @returns {Array} Returns the slice of `array`.
|
|
* @example
|
|
*
|
|
* _.takeRight([1, 2, 3]);
|
|
* // => [3]
|
|
*
|
|
* _.takeRight([1, 2, 3], 2);
|
|
* // => [2, 3]
|
|
*
|
|
* _.takeRight([1, 2, 3], 5);
|
|
* // => [1, 2, 3]
|
|
*
|
|
* _.takeRight([1, 2, 3], 0);
|
|
* // => []
|
|
*/
|
|
function takeRight(array, n, guard) {
|
|
var length = array == null ? 0 : array.length;
|
|
if (!length) {
|
|
return [];
|
|
}
|
|
n = (guard || n === undefined) ? 1 : toInteger(n);
|
|
n = length - n;
|
|
return baseSlice(array, n < 0 ? 0 : n, length);
|
|
}
|
|
|
|
/**
|
|
* Creates a slice of `array` with elements taken from the end. Elements are
|
|
* taken until `predicate` returns falsey. The predicate is invoked with
|
|
* three arguments: (value, index, array).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to query.
|
|
* @param {Function} [predicate=_.identity] The function invoked per iteration.
|
|
* @returns {Array} Returns the slice of `array`.
|
|
* @example
|
|
*
|
|
* var users = [
|
|
* { 'user': 'barney', 'active': true },
|
|
* { 'user': 'fred', 'active': false },
|
|
* { 'user': 'pebbles', 'active': false }
|
|
* ];
|
|
*
|
|
* _.takeRightWhile(users, function(o) { return !o.active; });
|
|
* // => objects for ['fred', 'pebbles']
|
|
*
|
|
* // The `_.matches` iteratee shorthand.
|
|
* _.takeRightWhile(users, { 'user': 'pebbles', 'active': false });
|
|
* // => objects for ['pebbles']
|
|
*
|
|
* // The `_.matchesProperty` iteratee shorthand.
|
|
* _.takeRightWhile(users, ['active', false]);
|
|
* // => objects for ['fred', 'pebbles']
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.takeRightWhile(users, 'active');
|
|
* // => []
|
|
*/
|
|
function takeRightWhile(array, predicate) {
|
|
return (array && array.length)
|
|
? baseWhile(array, getIteratee(predicate, 3), false, true)
|
|
: [];
|
|
}
|
|
|
|
/**
|
|
* Creates a slice of `array` with elements taken from the beginning. Elements
|
|
* are taken until `predicate` returns falsey. The predicate is invoked with
|
|
* three arguments: (value, index, array).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to query.
|
|
* @param {Function} [predicate=_.identity] The function invoked per iteration.
|
|
* @returns {Array} Returns the slice of `array`.
|
|
* @example
|
|
*
|
|
* var users = [
|
|
* { 'user': 'barney', 'active': false },
|
|
* { 'user': 'fred', 'active': false },
|
|
* { 'user': 'pebbles', 'active': true }
|
|
* ];
|
|
*
|
|
* _.takeWhile(users, function(o) { return !o.active; });
|
|
* // => objects for ['barney', 'fred']
|
|
*
|
|
* // The `_.matches` iteratee shorthand.
|
|
* _.takeWhile(users, { 'user': 'barney', 'active': false });
|
|
* // => objects for ['barney']
|
|
*
|
|
* // The `_.matchesProperty` iteratee shorthand.
|
|
* _.takeWhile(users, ['active', false]);
|
|
* // => objects for ['barney', 'fred']
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.takeWhile(users, 'active');
|
|
* // => []
|
|
*/
|
|
function takeWhile(array, predicate) {
|
|
return (array && array.length)
|
|
? baseWhile(array, getIteratee(predicate, 3))
|
|
: [];
|
|
}
|
|
|
|
/**
|
|
* Creates an array of unique values, in order, from all given arrays using
|
|
* [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
|
|
* for equality comparisons.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Array
|
|
* @param {...Array} [arrays] The arrays to inspect.
|
|
* @returns {Array} Returns the new array of combined values.
|
|
* @example
|
|
*
|
|
* _.union([2], [1, 2]);
|
|
* // => [2, 1]
|
|
*/
|
|
var union = baseRest(function(arrays) {
|
|
return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true));
|
|
});
|
|
|
|
/**
|
|
* This method is like `_.union` except that it accepts `iteratee` which is
|
|
* invoked for each element of each `arrays` to generate the criterion by
|
|
* which uniqueness is computed. Result values are chosen from the first
|
|
* array in which the value occurs. The iteratee is invoked with one argument:
|
|
* (value).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Array
|
|
* @param {...Array} [arrays] The arrays to inspect.
|
|
* @param {Function} [iteratee=_.identity] The iteratee invoked per element.
|
|
* @returns {Array} Returns the new array of combined values.
|
|
* @example
|
|
*
|
|
* _.unionBy([2.1], [1.2, 2.3], Math.floor);
|
|
* // => [2.1, 1.2]
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
|
|
* // => [{ 'x': 1 }, { 'x': 2 }]
|
|
*/
|
|
var unionBy = baseRest(function(arrays) {
|
|
var iteratee = last(arrays);
|
|
if (isArrayLikeObject(iteratee)) {
|
|
iteratee = undefined;
|
|
}
|
|
return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), getIteratee(iteratee, 2));
|
|
});
|
|
|
|
/**
|
|
* This method is like `_.union` except that it accepts `comparator` which
|
|
* is invoked to compare elements of `arrays`. Result values are chosen from
|
|
* the first array in which the value occurs. The comparator is invoked
|
|
* with two arguments: (arrVal, othVal).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Array
|
|
* @param {...Array} [arrays] The arrays to inspect.
|
|
* @param {Function} [comparator] The comparator invoked per element.
|
|
* @returns {Array} Returns the new array of combined values.
|
|
* @example
|
|
*
|
|
* var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
|
|
* var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
|
|
*
|
|
* _.unionWith(objects, others, _.isEqual);
|
|
* // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
|
|
*/
|
|
var unionWith = baseRest(function(arrays) {
|
|
var comparator = last(arrays);
|
|
comparator = typeof comparator == 'function' ? comparator : undefined;
|
|
return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), undefined, comparator);
|
|
});
|
|
|
|
/**
|
|
* Creates a duplicate-free version of an array, using
|
|
* [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
|
|
* for equality comparisons, in which only the first occurrence of each element
|
|
* is kept. The order of result values is determined by the order they occur
|
|
* in the array.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Array
|
|
* @param {Array} array The array to inspect.
|
|
* @returns {Array} Returns the new duplicate free array.
|
|
* @example
|
|
*
|
|
* _.uniq([2, 1, 2]);
|
|
* // => [2, 1]
|
|
*/
|
|
function uniq(array) {
|
|
return (array && array.length) ? baseUniq(array) : [];
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.uniq` except that it accepts `iteratee` which is
|
|
* invoked for each element in `array` to generate the criterion by which
|
|
* uniqueness is computed. The order of result values is determined by the
|
|
* order they occur in the array. The iteratee is invoked with one argument:
|
|
* (value).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to inspect.
|
|
* @param {Function} [iteratee=_.identity] The iteratee invoked per element.
|
|
* @returns {Array} Returns the new duplicate free array.
|
|
* @example
|
|
*
|
|
* _.uniqBy([2.1, 1.2, 2.3], Math.floor);
|
|
* // => [2.1, 1.2]
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
|
|
* // => [{ 'x': 1 }, { 'x': 2 }]
|
|
*/
|
|
function uniqBy(array, iteratee) {
|
|
return (array && array.length) ? baseUniq(array, getIteratee(iteratee, 2)) : [];
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.uniq` except that it accepts `comparator` which
|
|
* is invoked to compare elements of `array`. The order of result values is
|
|
* determined by the order they occur in the array.The comparator is invoked
|
|
* with two arguments: (arrVal, othVal).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Array
|
|
* @param {Array} array The array to inspect.
|
|
* @param {Function} [comparator] The comparator invoked per element.
|
|
* @returns {Array} Returns the new duplicate free array.
|
|
* @example
|
|
*
|
|
* var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];
|
|
*
|
|
* _.uniqWith(objects, _.isEqual);
|
|
* // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]
|
|
*/
|
|
function uniqWith(array, comparator) {
|
|
comparator = typeof comparator == 'function' ? comparator : undefined;
|
|
return (array && array.length) ? baseUniq(array, undefined, comparator) : [];
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.zip` except that it accepts an array of grouped
|
|
* elements and creates an array regrouping the elements to their pre-zip
|
|
* configuration.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 1.2.0
|
|
* @category Array
|
|
* @param {Array} array The array of grouped elements to process.
|
|
* @returns {Array} Returns the new array of regrouped elements.
|
|
* @example
|
|
*
|
|
* var zipped = _.zip(['a', 'b'], [1, 2], [true, false]);
|
|
* // => [['a', 1, true], ['b', 2, false]]
|
|
*
|
|
* _.unzip(zipped);
|
|
* // => [['a', 'b'], [1, 2], [true, false]]
|
|
*/
|
|
function unzip(array) {
|
|
if (!(array && array.length)) {
|
|
return [];
|
|
}
|
|
var length = 0;
|
|
array = arrayFilter(array, function(group) {
|
|
if (isArrayLikeObject(group)) {
|
|
length = nativeMax(group.length, length);
|
|
return true;
|
|
}
|
|
});
|
|
return baseTimes(length, function(index) {
|
|
return arrayMap(array, baseProperty(index));
|
|
});
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.unzip` except that it accepts `iteratee` to specify
|
|
* how regrouped values should be combined. The iteratee is invoked with the
|
|
* elements of each group: (...group).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.8.0
|
|
* @category Array
|
|
* @param {Array} array The array of grouped elements to process.
|
|
* @param {Function} [iteratee=_.identity] The function to combine
|
|
* regrouped values.
|
|
* @returns {Array} Returns the new array of regrouped elements.
|
|
* @example
|
|
*
|
|
* var zipped = _.zip([1, 2], [10, 20], [100, 200]);
|
|
* // => [[1, 10, 100], [2, 20, 200]]
|
|
*
|
|
* _.unzipWith(zipped, _.add);
|
|
* // => [3, 30, 300]
|
|
*/
|
|
function unzipWith(array, iteratee) {
|
|
if (!(array && array.length)) {
|
|
return [];
|
|
}
|
|
var result = unzip(array);
|
|
if (iteratee == null) {
|
|
return result;
|
|
}
|
|
return arrayMap(result, function(group) {
|
|
return apply(iteratee, undefined, group);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Creates an array excluding all given values using
|
|
* [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
|
|
* for equality comparisons.
|
|
*
|
|
* **Note:** Unlike `_.pull`, this method returns a new array.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Array
|
|
* @param {Array} array The array to inspect.
|
|
* @param {...*} [values] The values to exclude.
|
|
* @returns {Array} Returns the new array of filtered values.
|
|
* @see _.difference, _.xor
|
|
* @example
|
|
*
|
|
* _.without([2, 1, 2, 3], 1, 2);
|
|
* // => [3]
|
|
*/
|
|
var without = baseRest(function(array, values) {
|
|
return isArrayLikeObject(array)
|
|
? baseDifference(array, values)
|
|
: [];
|
|
});
|
|
|
|
/**
|
|
* Creates an array of unique values that is the
|
|
* [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)
|
|
* of the given arrays. The order of result values is determined by the order
|
|
* they occur in the arrays.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 2.4.0
|
|
* @category Array
|
|
* @param {...Array} [arrays] The arrays to inspect.
|
|
* @returns {Array} Returns the new array of filtered values.
|
|
* @see _.difference, _.without
|
|
* @example
|
|
*
|
|
* _.xor([2, 1], [2, 3]);
|
|
* // => [1, 3]
|
|
*/
|
|
var xor = baseRest(function(arrays) {
|
|
return baseXor(arrayFilter(arrays, isArrayLikeObject));
|
|
});
|
|
|
|
/**
|
|
* This method is like `_.xor` except that it accepts `iteratee` which is
|
|
* invoked for each element of each `arrays` to generate the criterion by
|
|
* which by which they're compared. The order of result values is determined
|
|
* by the order they occur in the arrays. The iteratee is invoked with one
|
|
* argument: (value).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Array
|
|
* @param {...Array} [arrays] The arrays to inspect.
|
|
* @param {Function} [iteratee=_.identity] The iteratee invoked per element.
|
|
* @returns {Array} Returns the new array of filtered values.
|
|
* @example
|
|
*
|
|
* _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor);
|
|
* // => [1.2, 3.4]
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
|
|
* // => [{ 'x': 2 }]
|
|
*/
|
|
var xorBy = baseRest(function(arrays) {
|
|
var iteratee = last(arrays);
|
|
if (isArrayLikeObject(iteratee)) {
|
|
iteratee = undefined;
|
|
}
|
|
return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee, 2));
|
|
});
|
|
|
|
/**
|
|
* This method is like `_.xor` except that it accepts `comparator` which is
|
|
* invoked to compare elements of `arrays`. The order of result values is
|
|
* determined by the order they occur in the arrays. The comparator is invoked
|
|
* with two arguments: (arrVal, othVal).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Array
|
|
* @param {...Array} [arrays] The arrays to inspect.
|
|
* @param {Function} [comparator] The comparator invoked per element.
|
|
* @returns {Array} Returns the new array of filtered values.
|
|
* @example
|
|
*
|
|
* var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
|
|
* var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
|
|
*
|
|
* _.xorWith(objects, others, _.isEqual);
|
|
* // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
|
|
*/
|
|
var xorWith = baseRest(function(arrays) {
|
|
var comparator = last(arrays);
|
|
comparator = typeof comparator == 'function' ? comparator : undefined;
|
|
return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator);
|
|
});
|
|
|
|
/**
|
|
* Creates an array of grouped elements, the first of which contains the
|
|
* first elements of the given arrays, the second of which contains the
|
|
* second elements of the given arrays, and so on.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Array
|
|
* @param {...Array} [arrays] The arrays to process.
|
|
* @returns {Array} Returns the new array of grouped elements.
|
|
* @example
|
|
*
|
|
* _.zip(['a', 'b'], [1, 2], [true, false]);
|
|
* // => [['a', 1, true], ['b', 2, false]]
|
|
*/
|
|
var zip = baseRest(unzip);
|
|
|
|
/**
|
|
* This method is like `_.fromPairs` except that it accepts two arrays,
|
|
* one of property identifiers and one of corresponding values.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.4.0
|
|
* @category Array
|
|
* @param {Array} [props=[]] The property identifiers.
|
|
* @param {Array} [values=[]] The property values.
|
|
* @returns {Object} Returns the new object.
|
|
* @example
|
|
*
|
|
* _.zipObject(['a', 'b'], [1, 2]);
|
|
* // => { 'a': 1, 'b': 2 }
|
|
*/
|
|
function zipObject(props, values) {
|
|
return baseZipObject(props || [], values || [], assignValue);
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.zipObject` except that it supports property paths.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.1.0
|
|
* @category Array
|
|
* @param {Array} [props=[]] The property identifiers.
|
|
* @param {Array} [values=[]] The property values.
|
|
* @returns {Object} Returns the new object.
|
|
* @example
|
|
*
|
|
* _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]);
|
|
* // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } }
|
|
*/
|
|
function zipObjectDeep(props, values) {
|
|
return baseZipObject(props || [], values || [], baseSet);
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.zip` except that it accepts `iteratee` to specify
|
|
* how grouped values should be combined. The iteratee is invoked with the
|
|
* elements of each group: (...group).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.8.0
|
|
* @category Array
|
|
* @param {...Array} [arrays] The arrays to process.
|
|
* @param {Function} [iteratee=_.identity] The function to combine
|
|
* grouped values.
|
|
* @returns {Array} Returns the new array of grouped elements.
|
|
* @example
|
|
*
|
|
* _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) {
|
|
* return a + b + c;
|
|
* });
|
|
* // => [111, 222]
|
|
*/
|
|
var zipWith = baseRest(function(arrays) {
|
|
var length = arrays.length,
|
|
iteratee = length > 1 ? arrays[length - 1] : undefined;
|
|
|
|
iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined;
|
|
return unzipWith(arrays, iteratee);
|
|
});
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* Creates a `lodash` wrapper instance that wraps `value` with explicit method
|
|
* chain sequences enabled. The result of such sequences must be unwrapped
|
|
* with `_#value`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 1.3.0
|
|
* @category Seq
|
|
* @param {*} value The value to wrap.
|
|
* @returns {Object} Returns the new `lodash` wrapper instance.
|
|
* @example
|
|
*
|
|
* var users = [
|
|
* { 'user': 'barney', 'age': 36 },
|
|
* { 'user': 'fred', 'age': 40 },
|
|
* { 'user': 'pebbles', 'age': 1 }
|
|
* ];
|
|
*
|
|
* var youngest = _
|
|
* .chain(users)
|
|
* .sortBy('age')
|
|
* .map(function(o) {
|
|
* return o.user + ' is ' + o.age;
|
|
* })
|
|
* .head()
|
|
* .value();
|
|
* // => 'pebbles is 1'
|
|
*/
|
|
function chain(value) {
|
|
var result = lodash(value);
|
|
result.__chain__ = true;
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* This method invokes `interceptor` and returns `value`. The interceptor
|
|
* is invoked with one argument; (value). The purpose of this method is to
|
|
* "tap into" a method chain sequence in order to modify intermediate results.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Seq
|
|
* @param {*} value The value to provide to `interceptor`.
|
|
* @param {Function} interceptor The function to invoke.
|
|
* @returns {*} Returns `value`.
|
|
* @example
|
|
*
|
|
* _([1, 2, 3])
|
|
* .tap(function(array) {
|
|
* // Mutate input array.
|
|
* array.pop();
|
|
* })
|
|
* .reverse()
|
|
* .value();
|
|
* // => [2, 1]
|
|
*/
|
|
function tap(value, interceptor) {
|
|
interceptor(value);
|
|
return value;
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.tap` except that it returns the result of `interceptor`.
|
|
* The purpose of this method is to "pass thru" values replacing intermediate
|
|
* results in a method chain sequence.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Seq
|
|
* @param {*} value The value to provide to `interceptor`.
|
|
* @param {Function} interceptor The function to invoke.
|
|
* @returns {*} Returns the result of `interceptor`.
|
|
* @example
|
|
*
|
|
* _(' abc ')
|
|
* .chain()
|
|
* .trim()
|
|
* .thru(function(value) {
|
|
* return [value];
|
|
* })
|
|
* .value();
|
|
* // => ['abc']
|
|
*/
|
|
function thru(value, interceptor) {
|
|
return interceptor(value);
|
|
}
|
|
|
|
/**
|
|
* This method is the wrapper version of `_.at`.
|
|
*
|
|
* @name at
|
|
* @memberOf _
|
|
* @since 1.0.0
|
|
* @category Seq
|
|
* @param {...(string|string[])} [paths] The property paths to pick.
|
|
* @returns {Object} Returns the new `lodash` wrapper instance.
|
|
* @example
|
|
*
|
|
* var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
|
|
*
|
|
* _(object).at(['a[0].b.c', 'a[1]']).value();
|
|
* // => [3, 4]
|
|
*/
|
|
var wrapperAt = flatRest(function(paths) {
|
|
var length = paths.length,
|
|
start = length ? paths[0] : 0,
|
|
value = this.__wrapped__,
|
|
interceptor = function(object) { return baseAt(object, paths); };
|
|
|
|
if (length > 1 || this.__actions__.length ||
|
|
!(value instanceof LazyWrapper) || !isIndex(start)) {
|
|
return this.thru(interceptor);
|
|
}
|
|
value = value.slice(start, +start + (length ? 1 : 0));
|
|
value.__actions__.push({
|
|
'func': thru,
|
|
'args': [interceptor],
|
|
'thisArg': undefined
|
|
});
|
|
return new LodashWrapper(value, this.__chain__).thru(function(array) {
|
|
if (length && !array.length) {
|
|
array.push(undefined);
|
|
}
|
|
return array;
|
|
});
|
|
});
|
|
|
|
/**
|
|
* Creates a `lodash` wrapper instance with explicit method chain sequences enabled.
|
|
*
|
|
* @name chain
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Seq
|
|
* @returns {Object} Returns the new `lodash` wrapper instance.
|
|
* @example
|
|
*
|
|
* var users = [
|
|
* { 'user': 'barney', 'age': 36 },
|
|
* { 'user': 'fred', 'age': 40 }
|
|
* ];
|
|
*
|
|
* // A sequence without explicit chaining.
|
|
* _(users).head();
|
|
* // => { 'user': 'barney', 'age': 36 }
|
|
*
|
|
* // A sequence with explicit chaining.
|
|
* _(users)
|
|
* .chain()
|
|
* .head()
|
|
* .pick('user')
|
|
* .value();
|
|
* // => { 'user': 'barney' }
|
|
*/
|
|
function wrapperChain() {
|
|
return chain(this);
|
|
}
|
|
|
|
/**
|
|
* Executes the chain sequence and returns the wrapped result.
|
|
*
|
|
* @name commit
|
|
* @memberOf _
|
|
* @since 3.2.0
|
|
* @category Seq
|
|
* @returns {Object} Returns the new `lodash` wrapper instance.
|
|
* @example
|
|
*
|
|
* var array = [1, 2];
|
|
* var wrapped = _(array).push(3);
|
|
*
|
|
* console.log(array);
|
|
* // => [1, 2]
|
|
*
|
|
* wrapped = wrapped.commit();
|
|
* console.log(array);
|
|
* // => [1, 2, 3]
|
|
*
|
|
* wrapped.last();
|
|
* // => 3
|
|
*
|
|
* console.log(array);
|
|
* // => [1, 2, 3]
|
|
*/
|
|
function wrapperCommit() {
|
|
return new LodashWrapper(this.value(), this.__chain__);
|
|
}
|
|
|
|
/**
|
|
* Gets the next value on a wrapped object following the
|
|
* [iterator protocol](https://mdn.io/iteration_protocols#iterator).
|
|
*
|
|
* @name next
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Seq
|
|
* @returns {Object} Returns the next iterator value.
|
|
* @example
|
|
*
|
|
* var wrapped = _([1, 2]);
|
|
*
|
|
* wrapped.next();
|
|
* // => { 'done': false, 'value': 1 }
|
|
*
|
|
* wrapped.next();
|
|
* // => { 'done': false, 'value': 2 }
|
|
*
|
|
* wrapped.next();
|
|
* // => { 'done': true, 'value': undefined }
|
|
*/
|
|
function wrapperNext() {
|
|
if (this.__values__ === undefined) {
|
|
this.__values__ = toArray(this.value());
|
|
}
|
|
var done = this.__index__ >= this.__values__.length,
|
|
value = done ? undefined : this.__values__[this.__index__++];
|
|
|
|
return { 'done': done, 'value': value };
|
|
}
|
|
|
|
/**
|
|
* Enables the wrapper to be iterable.
|
|
*
|
|
* @name Symbol.iterator
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Seq
|
|
* @returns {Object} Returns the wrapper object.
|
|
* @example
|
|
*
|
|
* var wrapped = _([1, 2]);
|
|
*
|
|
* wrapped[Symbol.iterator]() === wrapped;
|
|
* // => true
|
|
*
|
|
* Array.from(wrapped);
|
|
* // => [1, 2]
|
|
*/
|
|
function wrapperToIterator() {
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Creates a clone of the chain sequence planting `value` as the wrapped value.
|
|
*
|
|
* @name plant
|
|
* @memberOf _
|
|
* @since 3.2.0
|
|
* @category Seq
|
|
* @param {*} value The value to plant.
|
|
* @returns {Object} Returns the new `lodash` wrapper instance.
|
|
* @example
|
|
*
|
|
* function square(n) {
|
|
* return n * n;
|
|
* }
|
|
*
|
|
* var wrapped = _([1, 2]).map(square);
|
|
* var other = wrapped.plant([3, 4]);
|
|
*
|
|
* other.value();
|
|
* // => [9, 16]
|
|
*
|
|
* wrapped.value();
|
|
* // => [1, 4]
|
|
*/
|
|
function wrapperPlant(value) {
|
|
var result,
|
|
parent = this;
|
|
|
|
while (parent instanceof baseLodash) {
|
|
var clone = wrapperClone(parent);
|
|
clone.__index__ = 0;
|
|
clone.__values__ = undefined;
|
|
if (result) {
|
|
previous.__wrapped__ = clone;
|
|
} else {
|
|
result = clone;
|
|
}
|
|
var previous = clone;
|
|
parent = parent.__wrapped__;
|
|
}
|
|
previous.__wrapped__ = value;
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* This method is the wrapper version of `_.reverse`.
|
|
*
|
|
* **Note:** This method mutates the wrapped array.
|
|
*
|
|
* @name reverse
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Seq
|
|
* @returns {Object} Returns the new `lodash` wrapper instance.
|
|
* @example
|
|
*
|
|
* var array = [1, 2, 3];
|
|
*
|
|
* _(array).reverse().value()
|
|
* // => [3, 2, 1]
|
|
*
|
|
* console.log(array);
|
|
* // => [3, 2, 1]
|
|
*/
|
|
function wrapperReverse() {
|
|
var value = this.__wrapped__;
|
|
if (value instanceof LazyWrapper) {
|
|
var wrapped = value;
|
|
if (this.__actions__.length) {
|
|
wrapped = new LazyWrapper(this);
|
|
}
|
|
wrapped = wrapped.reverse();
|
|
wrapped.__actions__.push({
|
|
'func': thru,
|
|
'args': [reverse],
|
|
'thisArg': undefined
|
|
});
|
|
return new LodashWrapper(wrapped, this.__chain__);
|
|
}
|
|
return this.thru(reverse);
|
|
}
|
|
|
|
/**
|
|
* Executes the chain sequence to resolve the unwrapped value.
|
|
*
|
|
* @name value
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @alias toJSON, valueOf
|
|
* @category Seq
|
|
* @returns {*} Returns the resolved unwrapped value.
|
|
* @example
|
|
*
|
|
* _([1, 2, 3]).value();
|
|
* // => [1, 2, 3]
|
|
*/
|
|
function wrapperValue() {
|
|
return baseWrapperValue(this.__wrapped__, this.__actions__);
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* Creates an object composed of keys generated from the results of running
|
|
* each element of `collection` thru `iteratee`. The corresponding value of
|
|
* each key is the number of times the key was returned by `iteratee`. The
|
|
* iteratee is invoked with one argument: (value).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.5.0
|
|
* @category Collection
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function} [iteratee=_.identity] The iteratee to transform keys.
|
|
* @returns {Object} Returns the composed aggregate object.
|
|
* @example
|
|
*
|
|
* _.countBy([6.1, 4.2, 6.3], Math.floor);
|
|
* // => { '4': 1, '6': 2 }
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.countBy(['one', 'two', 'three'], 'length');
|
|
* // => { '3': 2, '5': 1 }
|
|
*/
|
|
var countBy = createAggregator(function(result, value, key) {
|
|
if (hasOwnProperty.call(result, key)) {
|
|
++result[key];
|
|
} else {
|
|
baseAssignValue(result, key, 1);
|
|
}
|
|
});
|
|
|
|
/**
|
|
* Checks if `predicate` returns truthy for **all** elements of `collection`.
|
|
* Iteration is stopped once `predicate` returns falsey. The predicate is
|
|
* invoked with three arguments: (value, index|key, collection).
|
|
*
|
|
* **Note:** This method returns `true` for
|
|
* [empty collections](https://en.wikipedia.org/wiki/Empty_set) because
|
|
* [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of
|
|
* elements of empty collections.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Collection
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function} [predicate=_.identity] The function invoked per iteration.
|
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
|
* @returns {boolean} Returns `true` if all elements pass the predicate check,
|
|
* else `false`.
|
|
* @example
|
|
*
|
|
* _.every([true, 1, null, 'yes'], Boolean);
|
|
* // => false
|
|
*
|
|
* var users = [
|
|
* { 'user': 'barney', 'age': 36, 'active': false },
|
|
* { 'user': 'fred', 'age': 40, 'active': false }
|
|
* ];
|
|
*
|
|
* // The `_.matches` iteratee shorthand.
|
|
* _.every(users, { 'user': 'barney', 'active': false });
|
|
* // => false
|
|
*
|
|
* // The `_.matchesProperty` iteratee shorthand.
|
|
* _.every(users, ['active', false]);
|
|
* // => true
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.every(users, 'active');
|
|
* // => false
|
|
*/
|
|
function every(collection, predicate, guard) {
|
|
var func = isArray(collection) ? arrayEvery : baseEvery;
|
|
if (guard && isIterateeCall(collection, predicate, guard)) {
|
|
predicate = undefined;
|
|
}
|
|
return func(collection, getIteratee(predicate, 3));
|
|
}
|
|
|
|
/**
|
|
* Iterates over elements of `collection`, returning an array of all elements
|
|
* `predicate` returns truthy for. The predicate is invoked with three
|
|
* arguments: (value, index|key, collection).
|
|
*
|
|
* **Note:** Unlike `_.remove`, this method returns a new array.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Collection
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function} [predicate=_.identity] The function invoked per iteration.
|
|
* @returns {Array} Returns the new filtered array.
|
|
* @see _.reject
|
|
* @example
|
|
*
|
|
* var users = [
|
|
* { 'user': 'barney', 'age': 36, 'active': true },
|
|
* { 'user': 'fred', 'age': 40, 'active': false }
|
|
* ];
|
|
*
|
|
* _.filter(users, function(o) { return !o.active; });
|
|
* // => objects for ['fred']
|
|
*
|
|
* // The `_.matches` iteratee shorthand.
|
|
* _.filter(users, { 'age': 36, 'active': true });
|
|
* // => objects for ['barney']
|
|
*
|
|
* // The `_.matchesProperty` iteratee shorthand.
|
|
* _.filter(users, ['active', false]);
|
|
* // => objects for ['fred']
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.filter(users, 'active');
|
|
* // => objects for ['barney']
|
|
*
|
|
* // Combining several predicates using `_.overEvery` or `_.overSome`.
|
|
* _.filter(users, _.overSome([{ 'age': 36 }, ['age', 40]]));
|
|
* // => objects for ['fred', 'barney']
|
|
*/
|
|
function filter(collection, predicate) {
|
|
var func = isArray(collection) ? arrayFilter : baseFilter;
|
|
return func(collection, getIteratee(predicate, 3));
|
|
}
|
|
|
|
/**
|
|
* Iterates over elements of `collection`, returning the first element
|
|
* `predicate` returns truthy for. The predicate is invoked with three
|
|
* arguments: (value, index|key, collection).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Collection
|
|
* @param {Array|Object} collection The collection to inspect.
|
|
* @param {Function} [predicate=_.identity] The function invoked per iteration.
|
|
* @param {number} [fromIndex=0] The index to search from.
|
|
* @returns {*} Returns the matched element, else `undefined`.
|
|
* @example
|
|
*
|
|
* var users = [
|
|
* { 'user': 'barney', 'age': 36, 'active': true },
|
|
* { 'user': 'fred', 'age': 40, 'active': false },
|
|
* { 'user': 'pebbles', 'age': 1, 'active': true }
|
|
* ];
|
|
*
|
|
* _.find(users, function(o) { return o.age < 40; });
|
|
* // => object for 'barney'
|
|
*
|
|
* // The `_.matches` iteratee shorthand.
|
|
* _.find(users, { 'age': 1, 'active': true });
|
|
* // => object for 'pebbles'
|
|
*
|
|
* // The `_.matchesProperty` iteratee shorthand.
|
|
* _.find(users, ['active', false]);
|
|
* // => object for 'fred'
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.find(users, 'active');
|
|
* // => object for 'barney'
|
|
*/
|
|
var find = createFind(findIndex);
|
|
|
|
/**
|
|
* This method is like `_.find` except that it iterates over elements of
|
|
* `collection` from right to left.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 2.0.0
|
|
* @category Collection
|
|
* @param {Array|Object} collection The collection to inspect.
|
|
* @param {Function} [predicate=_.identity] The function invoked per iteration.
|
|
* @param {number} [fromIndex=collection.length-1] The index to search from.
|
|
* @returns {*} Returns the matched element, else `undefined`.
|
|
* @example
|
|
*
|
|
* _.findLast([1, 2, 3, 4], function(n) {
|
|
* return n % 2 == 1;
|
|
* });
|
|
* // => 3
|
|
*/
|
|
var findLast = createFind(findLastIndex);
|
|
|
|
/**
|
|
* Creates a flattened array of values by running each element in `collection`
|
|
* thru `iteratee` and flattening the mapped results. The iteratee is invoked
|
|
* with three arguments: (value, index|key, collection).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Collection
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
|
* @returns {Array} Returns the new flattened array.
|
|
* @example
|
|
*
|
|
* function duplicate(n) {
|
|
* return [n, n];
|
|
* }
|
|
*
|
|
* _.flatMap([1, 2], duplicate);
|
|
* // => [1, 1, 2, 2]
|
|
*/
|
|
function flatMap(collection, iteratee) {
|
|
return baseFlatten(map(collection, iteratee), 1);
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.flatMap` except that it recursively flattens the
|
|
* mapped results.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.7.0
|
|
* @category Collection
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
|
* @returns {Array} Returns the new flattened array.
|
|
* @example
|
|
*
|
|
* function duplicate(n) {
|
|
* return [[[n, n]]];
|
|
* }
|
|
*
|
|
* _.flatMapDeep([1, 2], duplicate);
|
|
* // => [1, 1, 2, 2]
|
|
*/
|
|
function flatMapDeep(collection, iteratee) {
|
|
return baseFlatten(map(collection, iteratee), INFINITY);
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.flatMap` except that it recursively flattens the
|
|
* mapped results up to `depth` times.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.7.0
|
|
* @category Collection
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
|
* @param {number} [depth=1] The maximum recursion depth.
|
|
* @returns {Array} Returns the new flattened array.
|
|
* @example
|
|
*
|
|
* function duplicate(n) {
|
|
* return [[[n, n]]];
|
|
* }
|
|
*
|
|
* _.flatMapDepth([1, 2], duplicate, 2);
|
|
* // => [[1, 1], [2, 2]]
|
|
*/
|
|
function flatMapDepth(collection, iteratee, depth) {
|
|
depth = depth === undefined ? 1 : toInteger(depth);
|
|
return baseFlatten(map(collection, iteratee), depth);
|
|
}
|
|
|
|
/**
|
|
* Iterates over elements of `collection` and invokes `iteratee` for each element.
|
|
* The iteratee is invoked with three arguments: (value, index|key, collection).
|
|
* Iteratee functions may exit iteration early by explicitly returning `false`.
|
|
*
|
|
* **Note:** As with other "Collections" methods, objects with a "length"
|
|
* property are iterated like arrays. To avoid this behavior use `_.forIn`
|
|
* or `_.forOwn` for object iteration.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @alias each
|
|
* @category Collection
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
|
* @returns {Array|Object} Returns `collection`.
|
|
* @see _.forEachRight
|
|
* @example
|
|
*
|
|
* _.forEach([1, 2], function(value) {
|
|
* console.log(value);
|
|
* });
|
|
* // => Logs `1` then `2`.
|
|
*
|
|
* _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
|
|
* console.log(key);
|
|
* });
|
|
* // => Logs 'a' then 'b' (iteration order is not guaranteed).
|
|
*/
|
|
function forEach(collection, iteratee) {
|
|
var func = isArray(collection) ? arrayEach : baseEach;
|
|
return func(collection, getIteratee(iteratee, 3));
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.forEach` except that it iterates over elements of
|
|
* `collection` from right to left.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 2.0.0
|
|
* @alias eachRight
|
|
* @category Collection
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
|
* @returns {Array|Object} Returns `collection`.
|
|
* @see _.forEach
|
|
* @example
|
|
*
|
|
* _.forEachRight([1, 2], function(value) {
|
|
* console.log(value);
|
|
* });
|
|
* // => Logs `2` then `1`.
|
|
*/
|
|
function forEachRight(collection, iteratee) {
|
|
var func = isArray(collection) ? arrayEachRight : baseEachRight;
|
|
return func(collection, getIteratee(iteratee, 3));
|
|
}
|
|
|
|
/**
|
|
* Creates an object composed of keys generated from the results of running
|
|
* each element of `collection` thru `iteratee`. The order of grouped values
|
|
* is determined by the order they occur in `collection`. The corresponding
|
|
* value of each key is an array of elements responsible for generating the
|
|
* key. The iteratee is invoked with one argument: (value).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Collection
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function} [iteratee=_.identity] The iteratee to transform keys.
|
|
* @returns {Object} Returns the composed aggregate object.
|
|
* @example
|
|
*
|
|
* _.groupBy([6.1, 4.2, 6.3], Math.floor);
|
|
* // => { '4': [4.2], '6': [6.1, 6.3] }
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.groupBy(['one', 'two', 'three'], 'length');
|
|
* // => { '3': ['one', 'two'], '5': ['three'] }
|
|
*/
|
|
var groupBy = createAggregator(function(result, value, key) {
|
|
if (hasOwnProperty.call(result, key)) {
|
|
result[key].push(value);
|
|
} else {
|
|
baseAssignValue(result, key, [value]);
|
|
}
|
|
});
|
|
|
|
/**
|
|
* Checks if `value` is in `collection`. If `collection` is a string, it's
|
|
* checked for a substring of `value`, otherwise
|
|
* [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
|
|
* is used for equality comparisons. If `fromIndex` is negative, it's used as
|
|
* the offset from the end of `collection`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Collection
|
|
* @param {Array|Object|string} collection The collection to inspect.
|
|
* @param {*} value The value to search for.
|
|
* @param {number} [fromIndex=0] The index to search from.
|
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
|
|
* @returns {boolean} Returns `true` if `value` is found, else `false`.
|
|
* @example
|
|
*
|
|
* _.includes([1, 2, 3], 1);
|
|
* // => true
|
|
*
|
|
* _.includes([1, 2, 3], 1, 2);
|
|
* // => false
|
|
*
|
|
* _.includes({ 'a': 1, 'b': 2 }, 1);
|
|
* // => true
|
|
*
|
|
* _.includes('abcd', 'bc');
|
|
* // => true
|
|
*/
|
|
function includes(collection, value, fromIndex, guard) {
|
|
collection = isArrayLike(collection) ? collection : values(collection);
|
|
fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0;
|
|
|
|
var length = collection.length;
|
|
if (fromIndex < 0) {
|
|
fromIndex = nativeMax(length + fromIndex, 0);
|
|
}
|
|
return isString(collection)
|
|
? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1)
|
|
: (!!length && baseIndexOf(collection, value, fromIndex) > -1);
|
|
}
|
|
|
|
/**
|
|
* Invokes the method at `path` of each element in `collection`, returning
|
|
* an array of the results of each invoked method. Any additional arguments
|
|
* are provided to each invoked method. If `path` is a function, it's invoked
|
|
* for, and `this` bound to, each element in `collection`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Collection
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Array|Function|string} path The path of the method to invoke or
|
|
* the function invoked per iteration.
|
|
* @param {...*} [args] The arguments to invoke each method with.
|
|
* @returns {Array} Returns the array of results.
|
|
* @example
|
|
*
|
|
* _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort');
|
|
* // => [[1, 5, 7], [1, 2, 3]]
|
|
*
|
|
* _.invokeMap([123, 456], String.prototype.split, '');
|
|
* // => [['1', '2', '3'], ['4', '5', '6']]
|
|
*/
|
|
var invokeMap = baseRest(function(collection, path, args) {
|
|
var index = -1,
|
|
isFunc = typeof path == 'function',
|
|
result = isArrayLike(collection) ? Array(collection.length) : [];
|
|
|
|
baseEach(collection, function(value) {
|
|
result[++index] = isFunc ? apply(path, value, args) : baseInvoke(value, path, args);
|
|
});
|
|
return result;
|
|
});
|
|
|
|
/**
|
|
* Creates an object composed of keys generated from the results of running
|
|
* each element of `collection` thru `iteratee`. The corresponding value of
|
|
* each key is the last element responsible for generating the key. The
|
|
* iteratee is invoked with one argument: (value).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Collection
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function} [iteratee=_.identity] The iteratee to transform keys.
|
|
* @returns {Object} Returns the composed aggregate object.
|
|
* @example
|
|
*
|
|
* var array = [
|
|
* { 'dir': 'left', 'code': 97 },
|
|
* { 'dir': 'right', 'code': 100 }
|
|
* ];
|
|
*
|
|
* _.keyBy(array, function(o) {
|
|
* return String.fromCharCode(o.code);
|
|
* });
|
|
* // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
|
|
*
|
|
* _.keyBy(array, 'dir');
|
|
* // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
|
|
*/
|
|
var keyBy = createAggregator(function(result, value, key) {
|
|
baseAssignValue(result, key, value);
|
|
});
|
|
|
|
/**
|
|
* Creates an array of values by running each element in `collection` thru
|
|
* `iteratee`. The iteratee is invoked with three arguments:
|
|
* (value, index|key, collection).
|
|
*
|
|
* Many lodash methods are guarded to work as iteratees for methods like
|
|
* `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
|
|
*
|
|
* The guarded methods are:
|
|
* `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`,
|
|
* `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`,
|
|
* `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`,
|
|
* `template`, `trim`, `trimEnd`, `trimStart`, and `words`
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Collection
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
|
* @returns {Array} Returns the new mapped array.
|
|
* @example
|
|
*
|
|
* function square(n) {
|
|
* return n * n;
|
|
* }
|
|
*
|
|
* _.map([4, 8], square);
|
|
* // => [16, 64]
|
|
*
|
|
* _.map({ 'a': 4, 'b': 8 }, square);
|
|
* // => [16, 64] (iteration order is not guaranteed)
|
|
*
|
|
* var users = [
|
|
* { 'user': 'barney' },
|
|
* { 'user': 'fred' }
|
|
* ];
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.map(users, 'user');
|
|
* // => ['barney', 'fred']
|
|
*/
|
|
function map(collection, iteratee) {
|
|
var func = isArray(collection) ? arrayMap : baseMap;
|
|
return func(collection, getIteratee(iteratee, 3));
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.sortBy` except that it allows specifying the sort
|
|
* orders of the iteratees to sort by. If `orders` is unspecified, all values
|
|
* are sorted in ascending order. Otherwise, specify an order of "desc" for
|
|
* descending or "asc" for ascending sort order of corresponding values.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Collection
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]]
|
|
* The iteratees to sort by.
|
|
* @param {string[]} [orders] The sort orders of `iteratees`.
|
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
|
|
* @returns {Array} Returns the new sorted array.
|
|
* @example
|
|
*
|
|
* var users = [
|
|
* { 'user': 'fred', 'age': 48 },
|
|
* { 'user': 'barney', 'age': 34 },
|
|
* { 'user': 'fred', 'age': 40 },
|
|
* { 'user': 'barney', 'age': 36 }
|
|
* ];
|
|
*
|
|
* // Sort by `user` in ascending order and by `age` in descending order.
|
|
* _.orderBy(users, ['user', 'age'], ['asc', 'desc']);
|
|
* // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
|
|
*/
|
|
function orderBy(collection, iteratees, orders, guard) {
|
|
if (collection == null) {
|
|
return [];
|
|
}
|
|
if (!isArray(iteratees)) {
|
|
iteratees = iteratees == null ? [] : [iteratees];
|
|
}
|
|
orders = guard ? undefined : orders;
|
|
if (!isArray(orders)) {
|
|
orders = orders == null ? [] : [orders];
|
|
}
|
|
return baseOrderBy(collection, iteratees, orders);
|
|
}
|
|
|
|
/**
|
|
* Creates an array of elements split into two groups, the first of which
|
|
* contains elements `predicate` returns truthy for, the second of which
|
|
* contains elements `predicate` returns falsey for. The predicate is
|
|
* invoked with one argument: (value).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Collection
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function} [predicate=_.identity] The function invoked per iteration.
|
|
* @returns {Array} Returns the array of grouped elements.
|
|
* @example
|
|
*
|
|
* var users = [
|
|
* { 'user': 'barney', 'age': 36, 'active': false },
|
|
* { 'user': 'fred', 'age': 40, 'active': true },
|
|
* { 'user': 'pebbles', 'age': 1, 'active': false }
|
|
* ];
|
|
*
|
|
* _.partition(users, function(o) { return o.active; });
|
|
* // => objects for [['fred'], ['barney', 'pebbles']]
|
|
*
|
|
* // The `_.matches` iteratee shorthand.
|
|
* _.partition(users, { 'age': 1, 'active': false });
|
|
* // => objects for [['pebbles'], ['barney', 'fred']]
|
|
*
|
|
* // The `_.matchesProperty` iteratee shorthand.
|
|
* _.partition(users, ['active', false]);
|
|
* // => objects for [['barney', 'pebbles'], ['fred']]
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.partition(users, 'active');
|
|
* // => objects for [['fred'], ['barney', 'pebbles']]
|
|
*/
|
|
var partition = createAggregator(function(result, value, key) {
|
|
result[key ? 0 : 1].push(value);
|
|
}, function() { return [[], []]; });
|
|
|
|
/**
|
|
* Reduces `collection` to a value which is the accumulated result of running
|
|
* each element in `collection` thru `iteratee`, where each successive
|
|
* invocation is supplied the return value of the previous. If `accumulator`
|
|
* is not given, the first element of `collection` is used as the initial
|
|
* value. The iteratee is invoked with four arguments:
|
|
* (accumulator, value, index|key, collection).
|
|
*
|
|
* Many lodash methods are guarded to work as iteratees for methods like
|
|
* `_.reduce`, `_.reduceRight`, and `_.transform`.
|
|
*
|
|
* The guarded methods are:
|
|
* `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,
|
|
* and `sortBy`
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Collection
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
|
* @param {*} [accumulator] The initial value.
|
|
* @returns {*} Returns the accumulated value.
|
|
* @see _.reduceRight
|
|
* @example
|
|
*
|
|
* _.reduce([1, 2], function(sum, n) {
|
|
* return sum + n;
|
|
* }, 0);
|
|
* // => 3
|
|
*
|
|
* _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
|
|
* (result[value] || (result[value] = [])).push(key);
|
|
* return result;
|
|
* }, {});
|
|
* // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)
|
|
*/
|
|
function reduce(collection, iteratee, accumulator) {
|
|
var func = isArray(collection) ? arrayReduce : baseReduce,
|
|
initAccum = arguments.length < 3;
|
|
|
|
return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach);
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.reduce` except that it iterates over elements of
|
|
* `collection` from right to left.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Collection
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
|
* @param {*} [accumulator] The initial value.
|
|
* @returns {*} Returns the accumulated value.
|
|
* @see _.reduce
|
|
* @example
|
|
*
|
|
* var array = [[0, 1], [2, 3], [4, 5]];
|
|
*
|
|
* _.reduceRight(array, function(flattened, other) {
|
|
* return flattened.concat(other);
|
|
* }, []);
|
|
* // => [4, 5, 2, 3, 0, 1]
|
|
*/
|
|
function reduceRight(collection, iteratee, accumulator) {
|
|
var func = isArray(collection) ? arrayReduceRight : baseReduce,
|
|
initAccum = arguments.length < 3;
|
|
|
|
return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight);
|
|
}
|
|
|
|
/**
|
|
* The opposite of `_.filter`; this method returns the elements of `collection`
|
|
* that `predicate` does **not** return truthy for.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Collection
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function} [predicate=_.identity] The function invoked per iteration.
|
|
* @returns {Array} Returns the new filtered array.
|
|
* @see _.filter
|
|
* @example
|
|
*
|
|
* var users = [
|
|
* { 'user': 'barney', 'age': 36, 'active': false },
|
|
* { 'user': 'fred', 'age': 40, 'active': true }
|
|
* ];
|
|
*
|
|
* _.reject(users, function(o) { return !o.active; });
|
|
* // => objects for ['fred']
|
|
*
|
|
* // The `_.matches` iteratee shorthand.
|
|
* _.reject(users, { 'age': 40, 'active': true });
|
|
* // => objects for ['barney']
|
|
*
|
|
* // The `_.matchesProperty` iteratee shorthand.
|
|
* _.reject(users, ['active', false]);
|
|
* // => objects for ['fred']
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.reject(users, 'active');
|
|
* // => objects for ['barney']
|
|
*/
|
|
function reject(collection, predicate) {
|
|
var func = isArray(collection) ? arrayFilter : baseFilter;
|
|
return func(collection, negate(getIteratee(predicate, 3)));
|
|
}
|
|
|
|
/**
|
|
* Gets a random element from `collection`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 2.0.0
|
|
* @category Collection
|
|
* @param {Array|Object} collection The collection to sample.
|
|
* @returns {*} Returns the random element.
|
|
* @example
|
|
*
|
|
* _.sample([1, 2, 3, 4]);
|
|
* // => 2
|
|
*/
|
|
function sample(collection) {
|
|
var func = isArray(collection) ? arraySample : baseSample;
|
|
return func(collection);
|
|
}
|
|
|
|
/**
|
|
* Gets `n` random elements at unique keys from `collection` up to the
|
|
* size of `collection`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Collection
|
|
* @param {Array|Object} collection The collection to sample.
|
|
* @param {number} [n=1] The number of elements to sample.
|
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
|
* @returns {Array} Returns the random elements.
|
|
* @example
|
|
*
|
|
* _.sampleSize([1, 2, 3], 2);
|
|
* // => [3, 1]
|
|
*
|
|
* _.sampleSize([1, 2, 3], 4);
|
|
* // => [2, 3, 1]
|
|
*/
|
|
function sampleSize(collection, n, guard) {
|
|
if ((guard ? isIterateeCall(collection, n, guard) : n === undefined)) {
|
|
n = 1;
|
|
} else {
|
|
n = toInteger(n);
|
|
}
|
|
var func = isArray(collection) ? arraySampleSize : baseSampleSize;
|
|
return func(collection, n);
|
|
}
|
|
|
|
/**
|
|
* Creates an array of shuffled values, using a version of the
|
|
* [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Collection
|
|
* @param {Array|Object} collection The collection to shuffle.
|
|
* @returns {Array} Returns the new shuffled array.
|
|
* @example
|
|
*
|
|
* _.shuffle([1, 2, 3, 4]);
|
|
* // => [4, 1, 3, 2]
|
|
*/
|
|
function shuffle(collection) {
|
|
var func = isArray(collection) ? arrayShuffle : baseShuffle;
|
|
return func(collection);
|
|
}
|
|
|
|
/**
|
|
* Gets the size of `collection` by returning its length for array-like
|
|
* values or the number of own enumerable string keyed properties for objects.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Collection
|
|
* @param {Array|Object|string} collection The collection to inspect.
|
|
* @returns {number} Returns the collection size.
|
|
* @example
|
|
*
|
|
* _.size([1, 2, 3]);
|
|
* // => 3
|
|
*
|
|
* _.size({ 'a': 1, 'b': 2 });
|
|
* // => 2
|
|
*
|
|
* _.size('pebbles');
|
|
* // => 7
|
|
*/
|
|
function size(collection) {
|
|
if (collection == null) {
|
|
return 0;
|
|
}
|
|
if (isArrayLike(collection)) {
|
|
return isString(collection) ? stringSize(collection) : collection.length;
|
|
}
|
|
var tag = getTag(collection);
|
|
if (tag == mapTag || tag == setTag) {
|
|
return collection.size;
|
|
}
|
|
return baseKeys(collection).length;
|
|
}
|
|
|
|
/**
|
|
* Checks if `predicate` returns truthy for **any** element of `collection`.
|
|
* Iteration is stopped once `predicate` returns truthy. The predicate is
|
|
* invoked with three arguments: (value, index|key, collection).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Collection
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {Function} [predicate=_.identity] The function invoked per iteration.
|
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
|
* @returns {boolean} Returns `true` if any element passes the predicate check,
|
|
* else `false`.
|
|
* @example
|
|
*
|
|
* _.some([null, 0, 'yes', false], Boolean);
|
|
* // => true
|
|
*
|
|
* var users = [
|
|
* { 'user': 'barney', 'active': true },
|
|
* { 'user': 'fred', 'active': false }
|
|
* ];
|
|
*
|
|
* // The `_.matches` iteratee shorthand.
|
|
* _.some(users, { 'user': 'barney', 'active': false });
|
|
* // => false
|
|
*
|
|
* // The `_.matchesProperty` iteratee shorthand.
|
|
* _.some(users, ['active', false]);
|
|
* // => true
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.some(users, 'active');
|
|
* // => true
|
|
*/
|
|
function some(collection, predicate, guard) {
|
|
var func = isArray(collection) ? arraySome : baseSome;
|
|
if (guard && isIterateeCall(collection, predicate, guard)) {
|
|
predicate = undefined;
|
|
}
|
|
return func(collection, getIteratee(predicate, 3));
|
|
}
|
|
|
|
/**
|
|
* Creates an array of elements, sorted in ascending order by the results of
|
|
* running each element in a collection thru each iteratee. This method
|
|
* performs a stable sort, that is, it preserves the original sort order of
|
|
* equal elements. The iteratees are invoked with one argument: (value).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Collection
|
|
* @param {Array|Object} collection The collection to iterate over.
|
|
* @param {...(Function|Function[])} [iteratees=[_.identity]]
|
|
* The iteratees to sort by.
|
|
* @returns {Array} Returns the new sorted array.
|
|
* @example
|
|
*
|
|
* var users = [
|
|
* { 'user': 'fred', 'age': 48 },
|
|
* { 'user': 'barney', 'age': 36 },
|
|
* { 'user': 'fred', 'age': 30 },
|
|
* { 'user': 'barney', 'age': 34 }
|
|
* ];
|
|
*
|
|
* _.sortBy(users, [function(o) { return o.user; }]);
|
|
* // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 30]]
|
|
*
|
|
* _.sortBy(users, ['user', 'age']);
|
|
* // => objects for [['barney', 34], ['barney', 36], ['fred', 30], ['fred', 48]]
|
|
*/
|
|
var sortBy = baseRest(function(collection, iteratees) {
|
|
if (collection == null) {
|
|
return [];
|
|
}
|
|
var length = iteratees.length;
|
|
if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) {
|
|
iteratees = [];
|
|
} else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) {
|
|
iteratees = [iteratees[0]];
|
|
}
|
|
return baseOrderBy(collection, baseFlatten(iteratees, 1), []);
|
|
});
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* Gets the timestamp of the number of milliseconds that have elapsed since
|
|
* the Unix epoch (1 January 1970 00:00:00 UTC).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 2.4.0
|
|
* @category Date
|
|
* @returns {number} Returns the timestamp.
|
|
* @example
|
|
*
|
|
* _.defer(function(stamp) {
|
|
* console.log(_.now() - stamp);
|
|
* }, _.now());
|
|
* // => Logs the number of milliseconds it took for the deferred invocation.
|
|
*/
|
|
var now = ctxNow || function() {
|
|
return root.Date.now();
|
|
};
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* The opposite of `_.before`; this method creates a function that invokes
|
|
* `func` once it's called `n` or more times.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Function
|
|
* @param {number} n The number of calls before `func` is invoked.
|
|
* @param {Function} func The function to restrict.
|
|
* @returns {Function} Returns the new restricted function.
|
|
* @example
|
|
*
|
|
* var saves = ['profile', 'settings'];
|
|
*
|
|
* var done = _.after(saves.length, function() {
|
|
* console.log('done saving!');
|
|
* });
|
|
*
|
|
* _.forEach(saves, function(type) {
|
|
* asyncSave({ 'type': type, 'complete': done });
|
|
* });
|
|
* // => Logs 'done saving!' after the two async saves have completed.
|
|
*/
|
|
function after(n, func) {
|
|
if (typeof func != 'function') {
|
|
throw new TypeError(FUNC_ERROR_TEXT);
|
|
}
|
|
n = toInteger(n);
|
|
return function() {
|
|
if (--n < 1) {
|
|
return func.apply(this, arguments);
|
|
}
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Creates a function that invokes `func`, with up to `n` arguments,
|
|
* ignoring any additional arguments.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Function
|
|
* @param {Function} func The function to cap arguments for.
|
|
* @param {number} [n=func.length] The arity cap.
|
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
|
* @returns {Function} Returns the new capped function.
|
|
* @example
|
|
*
|
|
* _.map(['6', '8', '10'], _.ary(parseInt, 1));
|
|
* // => [6, 8, 10]
|
|
*/
|
|
function ary(func, n, guard) {
|
|
n = guard ? undefined : n;
|
|
n = (func && n == null) ? func.length : n;
|
|
return createWrap(func, WRAP_ARY_FLAG, undefined, undefined, undefined, undefined, n);
|
|
}
|
|
|
|
/**
|
|
* Creates a function that invokes `func`, with the `this` binding and arguments
|
|
* of the created function, while it's called less than `n` times. Subsequent
|
|
* calls to the created function return the result of the last `func` invocation.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Function
|
|
* @param {number} n The number of calls at which `func` is no longer invoked.
|
|
* @param {Function} func The function to restrict.
|
|
* @returns {Function} Returns the new restricted function.
|
|
* @example
|
|
*
|
|
* jQuery(element).on('click', _.before(5, addContactToList));
|
|
* // => Allows adding up to 4 contacts to the list.
|
|
*/
|
|
function before(n, func) {
|
|
var result;
|
|
if (typeof func != 'function') {
|
|
throw new TypeError(FUNC_ERROR_TEXT);
|
|
}
|
|
n = toInteger(n);
|
|
return function() {
|
|
if (--n > 0) {
|
|
result = func.apply(this, arguments);
|
|
}
|
|
if (n <= 1) {
|
|
func = undefined;
|
|
}
|
|
return result;
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Creates a function that invokes `func` with the `this` binding of `thisArg`
|
|
* and `partials` prepended to the arguments it receives.
|
|
*
|
|
* The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
|
|
* may be used as a placeholder for partially applied arguments.
|
|
*
|
|
* **Note:** Unlike native `Function#bind`, this method doesn't set the "length"
|
|
* property of bound functions.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Function
|
|
* @param {Function} func The function to bind.
|
|
* @param {*} thisArg The `this` binding of `func`.
|
|
* @param {...*} [partials] The arguments to be partially applied.
|
|
* @returns {Function} Returns the new bound function.
|
|
* @example
|
|
*
|
|
* function greet(greeting, punctuation) {
|
|
* return greeting + ' ' + this.user + punctuation;
|
|
* }
|
|
*
|
|
* var object = { 'user': 'fred' };
|
|
*
|
|
* var bound = _.bind(greet, object, 'hi');
|
|
* bound('!');
|
|
* // => 'hi fred!'
|
|
*
|
|
* // Bound with placeholders.
|
|
* var bound = _.bind(greet, object, _, '!');
|
|
* bound('hi');
|
|
* // => 'hi fred!'
|
|
*/
|
|
var bind = baseRest(function(func, thisArg, partials) {
|
|
var bitmask = WRAP_BIND_FLAG;
|
|
if (partials.length) {
|
|
var holders = replaceHolders(partials, getHolder(bind));
|
|
bitmask |= WRAP_PARTIAL_FLAG;
|
|
}
|
|
return createWrap(func, bitmask, thisArg, partials, holders);
|
|
});
|
|
|
|
/**
|
|
* Creates a function that invokes the method at `object[key]` with `partials`
|
|
* prepended to the arguments it receives.
|
|
*
|
|
* This method differs from `_.bind` by allowing bound functions to reference
|
|
* methods that may be redefined or don't yet exist. See
|
|
* [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern)
|
|
* for more details.
|
|
*
|
|
* The `_.bindKey.placeholder` value, which defaults to `_` in monolithic
|
|
* builds, may be used as a placeholder for partially applied arguments.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.10.0
|
|
* @category Function
|
|
* @param {Object} object The object to invoke the method on.
|
|
* @param {string} key The key of the method.
|
|
* @param {...*} [partials] The arguments to be partially applied.
|
|
* @returns {Function} Returns the new bound function.
|
|
* @example
|
|
*
|
|
* var object = {
|
|
* 'user': 'fred',
|
|
* 'greet': function(greeting, punctuation) {
|
|
* return greeting + ' ' + this.user + punctuation;
|
|
* }
|
|
* };
|
|
*
|
|
* var bound = _.bindKey(object, 'greet', 'hi');
|
|
* bound('!');
|
|
* // => 'hi fred!'
|
|
*
|
|
* object.greet = function(greeting, punctuation) {
|
|
* return greeting + 'ya ' + this.user + punctuation;
|
|
* };
|
|
*
|
|
* bound('!');
|
|
* // => 'hiya fred!'
|
|
*
|
|
* // Bound with placeholders.
|
|
* var bound = _.bindKey(object, 'greet', _, '!');
|
|
* bound('hi');
|
|
* // => 'hiya fred!'
|
|
*/
|
|
var bindKey = baseRest(function(object, key, partials) {
|
|
var bitmask = WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG;
|
|
if (partials.length) {
|
|
var holders = replaceHolders(partials, getHolder(bindKey));
|
|
bitmask |= WRAP_PARTIAL_FLAG;
|
|
}
|
|
return createWrap(key, bitmask, object, partials, holders);
|
|
});
|
|
|
|
/**
|
|
* Creates a function that accepts arguments of `func` and either invokes
|
|
* `func` returning its result, if at least `arity` number of arguments have
|
|
* been provided, or returns a function that accepts the remaining `func`
|
|
* arguments, and so on. The arity of `func` may be specified if `func.length`
|
|
* is not sufficient.
|
|
*
|
|
* The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,
|
|
* may be used as a placeholder for provided arguments.
|
|
*
|
|
* **Note:** This method doesn't set the "length" property of curried functions.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 2.0.0
|
|
* @category Function
|
|
* @param {Function} func The function to curry.
|
|
* @param {number} [arity=func.length] The arity of `func`.
|
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
|
* @returns {Function} Returns the new curried function.
|
|
* @example
|
|
*
|
|
* var abc = function(a, b, c) {
|
|
* return [a, b, c];
|
|
* };
|
|
*
|
|
* var curried = _.curry(abc);
|
|
*
|
|
* curried(1)(2)(3);
|
|
* // => [1, 2, 3]
|
|
*
|
|
* curried(1, 2)(3);
|
|
* // => [1, 2, 3]
|
|
*
|
|
* curried(1, 2, 3);
|
|
* // => [1, 2, 3]
|
|
*
|
|
* // Curried with placeholders.
|
|
* curried(1)(_, 3)(2);
|
|
* // => [1, 2, 3]
|
|
*/
|
|
function curry(func, arity, guard) {
|
|
arity = guard ? undefined : arity;
|
|
var result = createWrap(func, WRAP_CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
|
|
result.placeholder = curry.placeholder;
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.curry` except that arguments are applied to `func`
|
|
* in the manner of `_.partialRight` instead of `_.partial`.
|
|
*
|
|
* The `_.curryRight.placeholder` value, which defaults to `_` in monolithic
|
|
* builds, may be used as a placeholder for provided arguments.
|
|
*
|
|
* **Note:** This method doesn't set the "length" property of curried functions.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Function
|
|
* @param {Function} func The function to curry.
|
|
* @param {number} [arity=func.length] The arity of `func`.
|
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
|
* @returns {Function} Returns the new curried function.
|
|
* @example
|
|
*
|
|
* var abc = function(a, b, c) {
|
|
* return [a, b, c];
|
|
* };
|
|
*
|
|
* var curried = _.curryRight(abc);
|
|
*
|
|
* curried(3)(2)(1);
|
|
* // => [1, 2, 3]
|
|
*
|
|
* curried(2, 3)(1);
|
|
* // => [1, 2, 3]
|
|
*
|
|
* curried(1, 2, 3);
|
|
* // => [1, 2, 3]
|
|
*
|
|
* // Curried with placeholders.
|
|
* curried(3)(1, _)(2);
|
|
* // => [1, 2, 3]
|
|
*/
|
|
function curryRight(func, arity, guard) {
|
|
arity = guard ? undefined : arity;
|
|
var result = createWrap(func, WRAP_CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
|
|
result.placeholder = curryRight.placeholder;
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Creates a debounced function that delays invoking `func` until after `wait`
|
|
* milliseconds have elapsed since the last time the debounced function was
|
|
* invoked. The debounced function comes with a `cancel` method to cancel
|
|
* delayed `func` invocations and a `flush` method to immediately invoke them.
|
|
* Provide `options` to indicate whether `func` should be invoked on the
|
|
* leading and/or trailing edge of the `wait` timeout. The `func` is invoked
|
|
* with the last arguments provided to the debounced function. Subsequent
|
|
* calls to the debounced function return the result of the last `func`
|
|
* invocation.
|
|
*
|
|
* **Note:** If `leading` and `trailing` options are `true`, `func` is
|
|
* invoked on the trailing edge of the timeout only if the debounced function
|
|
* is invoked more than once during the `wait` timeout.
|
|
*
|
|
* If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
|
|
* until to the next tick, similar to `setTimeout` with a timeout of `0`.
|
|
*
|
|
* See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
|
|
* for details over the differences between `_.debounce` and `_.throttle`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Function
|
|
* @param {Function} func The function to debounce.
|
|
* @param {number} [wait=0] The number of milliseconds to delay.
|
|
* @param {Object} [options={}] The options object.
|
|
* @param {boolean} [options.leading=false]
|
|
* Specify invoking on the leading edge of the timeout.
|
|
* @param {number} [options.maxWait]
|
|
* The maximum time `func` is allowed to be delayed before it's invoked.
|
|
* @param {boolean} [options.trailing=true]
|
|
* Specify invoking on the trailing edge of the timeout.
|
|
* @returns {Function} Returns the new debounced function.
|
|
* @example
|
|
*
|
|
* // Avoid costly calculations while the window size is in flux.
|
|
* jQuery(window).on('resize', _.debounce(calculateLayout, 150));
|
|
*
|
|
* // Invoke `sendMail` when clicked, debouncing subsequent calls.
|
|
* jQuery(element).on('click', _.debounce(sendMail, 300, {
|
|
* 'leading': true,
|
|
* 'trailing': false
|
|
* }));
|
|
*
|
|
* // Ensure `batchLog` is invoked once after 1 second of debounced calls.
|
|
* var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
|
|
* var source = new EventSource('/stream');
|
|
* jQuery(source).on('message', debounced);
|
|
*
|
|
* // Cancel the trailing debounced invocation.
|
|
* jQuery(window).on('popstate', debounced.cancel);
|
|
*/
|
|
function debounce(func, wait, options) {
|
|
var lastArgs,
|
|
lastThis,
|
|
maxWait,
|
|
result,
|
|
timerId,
|
|
lastCallTime,
|
|
lastInvokeTime = 0,
|
|
leading = false,
|
|
maxing = false,
|
|
trailing = true;
|
|
|
|
if (typeof func != 'function') {
|
|
throw new TypeError(FUNC_ERROR_TEXT);
|
|
}
|
|
wait = toNumber(wait) || 0;
|
|
if (isObject(options)) {
|
|
leading = !!options.leading;
|
|
maxing = 'maxWait' in options;
|
|
maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
|
|
trailing = 'trailing' in options ? !!options.trailing : trailing;
|
|
}
|
|
|
|
function invokeFunc(time) {
|
|
var args = lastArgs,
|
|
thisArg = lastThis;
|
|
|
|
lastArgs = lastThis = undefined;
|
|
lastInvokeTime = time;
|
|
result = func.apply(thisArg, args);
|
|
return result;
|
|
}
|
|
|
|
function leadingEdge(time) {
|
|
// Reset any `maxWait` timer.
|
|
lastInvokeTime = time;
|
|
// Start the timer for the trailing edge.
|
|
timerId = setTimeout(timerExpired, wait);
|
|
// Invoke the leading edge.
|
|
return leading ? invokeFunc(time) : result;
|
|
}
|
|
|
|
function remainingWait(time) {
|
|
var timeSinceLastCall = time - lastCallTime,
|
|
timeSinceLastInvoke = time - lastInvokeTime,
|
|
timeWaiting = wait - timeSinceLastCall;
|
|
|
|
return maxing
|
|
? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke)
|
|
: timeWaiting;
|
|
}
|
|
|
|
function shouldInvoke(time) {
|
|
var timeSinceLastCall = time - lastCallTime,
|
|
timeSinceLastInvoke = time - lastInvokeTime;
|
|
|
|
// Either this is the first call, activity has stopped and we're at the
|
|
// trailing edge, the system time has gone backwards and we're treating
|
|
// it as the trailing edge, or we've hit the `maxWait` limit.
|
|
return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
|
|
(timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
|
|
}
|
|
|
|
function timerExpired() {
|
|
var time = now();
|
|
if (shouldInvoke(time)) {
|
|
return trailingEdge(time);
|
|
}
|
|
// Restart the timer.
|
|
timerId = setTimeout(timerExpired, remainingWait(time));
|
|
}
|
|
|
|
function trailingEdge(time) {
|
|
timerId = undefined;
|
|
|
|
// Only invoke if we have `lastArgs` which means `func` has been
|
|
// debounced at least once.
|
|
if (trailing && lastArgs) {
|
|
return invokeFunc(time);
|
|
}
|
|
lastArgs = lastThis = undefined;
|
|
return result;
|
|
}
|
|
|
|
function cancel() {
|
|
if (timerId !== undefined) {
|
|
clearTimeout(timerId);
|
|
}
|
|
lastInvokeTime = 0;
|
|
lastArgs = lastCallTime = lastThis = timerId = undefined;
|
|
}
|
|
|
|
function flush() {
|
|
return timerId === undefined ? result : trailingEdge(now());
|
|
}
|
|
|
|
function debounced() {
|
|
var time = now(),
|
|
isInvoking = shouldInvoke(time);
|
|
|
|
lastArgs = arguments;
|
|
lastThis = this;
|
|
lastCallTime = time;
|
|
|
|
if (isInvoking) {
|
|
if (timerId === undefined) {
|
|
return leadingEdge(lastCallTime);
|
|
}
|
|
if (maxing) {
|
|
// Handle invocations in a tight loop.
|
|
clearTimeout(timerId);
|
|
timerId = setTimeout(timerExpired, wait);
|
|
return invokeFunc(lastCallTime);
|
|
}
|
|
}
|
|
if (timerId === undefined) {
|
|
timerId = setTimeout(timerExpired, wait);
|
|
}
|
|
return result;
|
|
}
|
|
debounced.cancel = cancel;
|
|
debounced.flush = flush;
|
|
return debounced;
|
|
}
|
|
|
|
/**
|
|
* Defers invoking the `func` until the current call stack has cleared. Any
|
|
* additional arguments are provided to `func` when it's invoked.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Function
|
|
* @param {Function} func The function to defer.
|
|
* @param {...*} [args] The arguments to invoke `func` with.
|
|
* @returns {number} Returns the timer id.
|
|
* @example
|
|
*
|
|
* _.defer(function(text) {
|
|
* console.log(text);
|
|
* }, 'deferred');
|
|
* // => Logs 'deferred' after one millisecond.
|
|
*/
|
|
var defer = baseRest(function(func, args) {
|
|
return baseDelay(func, 1, args);
|
|
});
|
|
|
|
/**
|
|
* Invokes `func` after `wait` milliseconds. Any additional arguments are
|
|
* provided to `func` when it's invoked.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Function
|
|
* @param {Function} func The function to delay.
|
|
* @param {number} wait The number of milliseconds to delay invocation.
|
|
* @param {...*} [args] The arguments to invoke `func` with.
|
|
* @returns {number} Returns the timer id.
|
|
* @example
|
|
*
|
|
* _.delay(function(text) {
|
|
* console.log(text);
|
|
* }, 1000, 'later');
|
|
* // => Logs 'later' after one second.
|
|
*/
|
|
var delay = baseRest(function(func, wait, args) {
|
|
return baseDelay(func, toNumber(wait) || 0, args);
|
|
});
|
|
|
|
/**
|
|
* Creates a function that invokes `func` with arguments reversed.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Function
|
|
* @param {Function} func The function to flip arguments for.
|
|
* @returns {Function} Returns the new flipped function.
|
|
* @example
|
|
*
|
|
* var flipped = _.flip(function() {
|
|
* return _.toArray(arguments);
|
|
* });
|
|
*
|
|
* flipped('a', 'b', 'c', 'd');
|
|
* // => ['d', 'c', 'b', 'a']
|
|
*/
|
|
function flip(func) {
|
|
return createWrap(func, WRAP_FLIP_FLAG);
|
|
}
|
|
|
|
/**
|
|
* Creates a function that memoizes the result of `func`. If `resolver` is
|
|
* provided, it determines the cache key for storing the result based on the
|
|
* arguments provided to the memoized function. By default, the first argument
|
|
* provided to the memoized function is used as the map cache key. The `func`
|
|
* is invoked with the `this` binding of the memoized function.
|
|
*
|
|
* **Note:** The cache is exposed as the `cache` property on the memoized
|
|
* function. Its creation may be customized by replacing the `_.memoize.Cache`
|
|
* constructor with one whose instances implement the
|
|
* [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
|
|
* method interface of `clear`, `delete`, `get`, `has`, and `set`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Function
|
|
* @param {Function} func The function to have its output memoized.
|
|
* @param {Function} [resolver] The function to resolve the cache key.
|
|
* @returns {Function} Returns the new memoized function.
|
|
* @example
|
|
*
|
|
* var object = { 'a': 1, 'b': 2 };
|
|
* var other = { 'c': 3, 'd': 4 };
|
|
*
|
|
* var values = _.memoize(_.values);
|
|
* values(object);
|
|
* // => [1, 2]
|
|
*
|
|
* values(other);
|
|
* // => [3, 4]
|
|
*
|
|
* object.a = 2;
|
|
* values(object);
|
|
* // => [1, 2]
|
|
*
|
|
* // Modify the result cache.
|
|
* values.cache.set(object, ['a', 'b']);
|
|
* values(object);
|
|
* // => ['a', 'b']
|
|
*
|
|
* // Replace `_.memoize.Cache`.
|
|
* _.memoize.Cache = WeakMap;
|
|
*/
|
|
function memoize(func, resolver) {
|
|
if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {
|
|
throw new TypeError(FUNC_ERROR_TEXT);
|
|
}
|
|
var memoized = function() {
|
|
var args = arguments,
|
|
key = resolver ? resolver.apply(this, args) : args[0],
|
|
cache = memoized.cache;
|
|
|
|
if (cache.has(key)) {
|
|
return cache.get(key);
|
|
}
|
|
var result = func.apply(this, args);
|
|
memoized.cache = cache.set(key, result) || cache;
|
|
return result;
|
|
};
|
|
memoized.cache = new (memoize.Cache || MapCache);
|
|
return memoized;
|
|
}
|
|
|
|
// Expose `MapCache`.
|
|
memoize.Cache = MapCache;
|
|
|
|
/**
|
|
* Creates a function that negates the result of the predicate `func`. The
|
|
* `func` predicate is invoked with the `this` binding and arguments of the
|
|
* created function.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Function
|
|
* @param {Function} predicate The predicate to negate.
|
|
* @returns {Function} Returns the new negated function.
|
|
* @example
|
|
*
|
|
* function isEven(n) {
|
|
* return n % 2 == 0;
|
|
* }
|
|
*
|
|
* _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));
|
|
* // => [1, 3, 5]
|
|
*/
|
|
function negate(predicate) {
|
|
if (typeof predicate != 'function') {
|
|
throw new TypeError(FUNC_ERROR_TEXT);
|
|
}
|
|
return function() {
|
|
var args = arguments;
|
|
switch (args.length) {
|
|
case 0: return !predicate.call(this);
|
|
case 1: return !predicate.call(this, args[0]);
|
|
case 2: return !predicate.call(this, args[0], args[1]);
|
|
case 3: return !predicate.call(this, args[0], args[1], args[2]);
|
|
}
|
|
return !predicate.apply(this, args);
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Creates a function that is restricted to invoking `func` once. Repeat calls
|
|
* to the function return the value of the first invocation. The `func` is
|
|
* invoked with the `this` binding and arguments of the created function.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Function
|
|
* @param {Function} func The function to restrict.
|
|
* @returns {Function} Returns the new restricted function.
|
|
* @example
|
|
*
|
|
* var initialize = _.once(createApplication);
|
|
* initialize();
|
|
* initialize();
|
|
* // => `createApplication` is invoked once
|
|
*/
|
|
function once(func) {
|
|
return before(2, func);
|
|
}
|
|
|
|
/**
|
|
* Creates a function that invokes `func` with its arguments transformed.
|
|
*
|
|
* @static
|
|
* @since 4.0.0
|
|
* @memberOf _
|
|
* @category Function
|
|
* @param {Function} func The function to wrap.
|
|
* @param {...(Function|Function[])} [transforms=[_.identity]]
|
|
* The argument transforms.
|
|
* @returns {Function} Returns the new function.
|
|
* @example
|
|
*
|
|
* function doubled(n) {
|
|
* return n * 2;
|
|
* }
|
|
*
|
|
* function square(n) {
|
|
* return n * n;
|
|
* }
|
|
*
|
|
* var func = _.overArgs(function(x, y) {
|
|
* return [x, y];
|
|
* }, [square, doubled]);
|
|
*
|
|
* func(9, 3);
|
|
* // => [81, 6]
|
|
*
|
|
* func(10, 5);
|
|
* // => [100, 10]
|
|
*/
|
|
var overArgs = castRest(function(func, transforms) {
|
|
transforms = (transforms.length == 1 && isArray(transforms[0]))
|
|
? arrayMap(transforms[0], baseUnary(getIteratee()))
|
|
: arrayMap(baseFlatten(transforms, 1), baseUnary(getIteratee()));
|
|
|
|
var funcsLength = transforms.length;
|
|
return baseRest(function(args) {
|
|
var index = -1,
|
|
length = nativeMin(args.length, funcsLength);
|
|
|
|
while (++index < length) {
|
|
args[index] = transforms[index].call(this, args[index]);
|
|
}
|
|
return apply(func, this, args);
|
|
});
|
|
});
|
|
|
|
/**
|
|
* Creates a function that invokes `func` with `partials` prepended to the
|
|
* arguments it receives. This method is like `_.bind` except it does **not**
|
|
* alter the `this` binding.
|
|
*
|
|
* The `_.partial.placeholder` value, which defaults to `_` in monolithic
|
|
* builds, may be used as a placeholder for partially applied arguments.
|
|
*
|
|
* **Note:** This method doesn't set the "length" property of partially
|
|
* applied functions.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.2.0
|
|
* @category Function
|
|
* @param {Function} func The function to partially apply arguments to.
|
|
* @param {...*} [partials] The arguments to be partially applied.
|
|
* @returns {Function} Returns the new partially applied function.
|
|
* @example
|
|
*
|
|
* function greet(greeting, name) {
|
|
* return greeting + ' ' + name;
|
|
* }
|
|
*
|
|
* var sayHelloTo = _.partial(greet, 'hello');
|
|
* sayHelloTo('fred');
|
|
* // => 'hello fred'
|
|
*
|
|
* // Partially applied with placeholders.
|
|
* var greetFred = _.partial(greet, _, 'fred');
|
|
* greetFred('hi');
|
|
* // => 'hi fred'
|
|
*/
|
|
var partial = baseRest(function(func, partials) {
|
|
var holders = replaceHolders(partials, getHolder(partial));
|
|
return createWrap(func, WRAP_PARTIAL_FLAG, undefined, partials, holders);
|
|
});
|
|
|
|
/**
|
|
* This method is like `_.partial` except that partially applied arguments
|
|
* are appended to the arguments it receives.
|
|
*
|
|
* The `_.partialRight.placeholder` value, which defaults to `_` in monolithic
|
|
* builds, may be used as a placeholder for partially applied arguments.
|
|
*
|
|
* **Note:** This method doesn't set the "length" property of partially
|
|
* applied functions.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 1.0.0
|
|
* @category Function
|
|
* @param {Function} func The function to partially apply arguments to.
|
|
* @param {...*} [partials] The arguments to be partially applied.
|
|
* @returns {Function} Returns the new partially applied function.
|
|
* @example
|
|
*
|
|
* function greet(greeting, name) {
|
|
* return greeting + ' ' + name;
|
|
* }
|
|
*
|
|
* var greetFred = _.partialRight(greet, 'fred');
|
|
* greetFred('hi');
|
|
* // => 'hi fred'
|
|
*
|
|
* // Partially applied with placeholders.
|
|
* var sayHelloTo = _.partialRight(greet, 'hello', _);
|
|
* sayHelloTo('fred');
|
|
* // => 'hello fred'
|
|
*/
|
|
var partialRight = baseRest(function(func, partials) {
|
|
var holders = replaceHolders(partials, getHolder(partialRight));
|
|
return createWrap(func, WRAP_PARTIAL_RIGHT_FLAG, undefined, partials, holders);
|
|
});
|
|
|
|
/**
|
|
* Creates a function that invokes `func` with arguments arranged according
|
|
* to the specified `indexes` where the argument value at the first index is
|
|
* provided as the first argument, the argument value at the second index is
|
|
* provided as the second argument, and so on.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Function
|
|
* @param {Function} func The function to rearrange arguments for.
|
|
* @param {...(number|number[])} indexes The arranged argument indexes.
|
|
* @returns {Function} Returns the new function.
|
|
* @example
|
|
*
|
|
* var rearged = _.rearg(function(a, b, c) {
|
|
* return [a, b, c];
|
|
* }, [2, 0, 1]);
|
|
*
|
|
* rearged('b', 'c', 'a')
|
|
* // => ['a', 'b', 'c']
|
|
*/
|
|
var rearg = flatRest(function(func, indexes) {
|
|
return createWrap(func, WRAP_REARG_FLAG, undefined, undefined, undefined, indexes);
|
|
});
|
|
|
|
/**
|
|
* Creates a function that invokes `func` with the `this` binding of the
|
|
* created function and arguments from `start` and beyond provided as
|
|
* an array.
|
|
*
|
|
* **Note:** This method is based on the
|
|
* [rest parameter](https://mdn.io/rest_parameters).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Function
|
|
* @param {Function} func The function to apply a rest parameter to.
|
|
* @param {number} [start=func.length-1] The start position of the rest parameter.
|
|
* @returns {Function} Returns the new function.
|
|
* @example
|
|
*
|
|
* var say = _.rest(function(what, names) {
|
|
* return what + ' ' + _.initial(names).join(', ') +
|
|
* (_.size(names) > 1 ? ', & ' : '') + _.last(names);
|
|
* });
|
|
*
|
|
* say('hello', 'fred', 'barney', 'pebbles');
|
|
* // => 'hello fred, barney, & pebbles'
|
|
*/
|
|
function rest(func, start) {
|
|
if (typeof func != 'function') {
|
|
throw new TypeError(FUNC_ERROR_TEXT);
|
|
}
|
|
start = start === undefined ? start : toInteger(start);
|
|
return baseRest(func, start);
|
|
}
|
|
|
|
/**
|
|
* Creates a function that invokes `func` with the `this` binding of the
|
|
* create function and an array of arguments much like
|
|
* [`Function#apply`](http://www.ecma-international.org/ecma-262/7.0/#sec-function.prototype.apply).
|
|
*
|
|
* **Note:** This method is based on the
|
|
* [spread operator](https://mdn.io/spread_operator).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.2.0
|
|
* @category Function
|
|
* @param {Function} func The function to spread arguments over.
|
|
* @param {number} [start=0] The start position of the spread.
|
|
* @returns {Function} Returns the new function.
|
|
* @example
|
|
*
|
|
* var say = _.spread(function(who, what) {
|
|
* return who + ' says ' + what;
|
|
* });
|
|
*
|
|
* say(['fred', 'hello']);
|
|
* // => 'fred says hello'
|
|
*
|
|
* var numbers = Promise.all([
|
|
* Promise.resolve(40),
|
|
* Promise.resolve(36)
|
|
* ]);
|
|
*
|
|
* numbers.then(_.spread(function(x, y) {
|
|
* return x + y;
|
|
* }));
|
|
* // => a Promise of 76
|
|
*/
|
|
function spread(func, start) {
|
|
if (typeof func != 'function') {
|
|
throw new TypeError(FUNC_ERROR_TEXT);
|
|
}
|
|
start = start == null ? 0 : nativeMax(toInteger(start), 0);
|
|
return baseRest(function(args) {
|
|
var array = args[start],
|
|
otherArgs = castSlice(args, 0, start);
|
|
|
|
if (array) {
|
|
arrayPush(otherArgs, array);
|
|
}
|
|
return apply(func, this, otherArgs);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Creates a throttled function that only invokes `func` at most once per
|
|
* every `wait` milliseconds. The throttled function comes with a `cancel`
|
|
* method to cancel delayed `func` invocations and a `flush` method to
|
|
* immediately invoke them. Provide `options` to indicate whether `func`
|
|
* should be invoked on the leading and/or trailing edge of the `wait`
|
|
* timeout. The `func` is invoked with the last arguments provided to the
|
|
* throttled function. Subsequent calls to the throttled function return the
|
|
* result of the last `func` invocation.
|
|
*
|
|
* **Note:** If `leading` and `trailing` options are `true`, `func` is
|
|
* invoked on the trailing edge of the timeout only if the throttled function
|
|
* is invoked more than once during the `wait` timeout.
|
|
*
|
|
* If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
|
|
* until to the next tick, similar to `setTimeout` with a timeout of `0`.
|
|
*
|
|
* See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
|
|
* for details over the differences between `_.throttle` and `_.debounce`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Function
|
|
* @param {Function} func The function to throttle.
|
|
* @param {number} [wait=0] The number of milliseconds to throttle invocations to.
|
|
* @param {Object} [options={}] The options object.
|
|
* @param {boolean} [options.leading=true]
|
|
* Specify invoking on the leading edge of the timeout.
|
|
* @param {boolean} [options.trailing=true]
|
|
* Specify invoking on the trailing edge of the timeout.
|
|
* @returns {Function} Returns the new throttled function.
|
|
* @example
|
|
*
|
|
* // Avoid excessively updating the position while scrolling.
|
|
* jQuery(window).on('scroll', _.throttle(updatePosition, 100));
|
|
*
|
|
* // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
|
|
* var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
|
|
* jQuery(element).on('click', throttled);
|
|
*
|
|
* // Cancel the trailing throttled invocation.
|
|
* jQuery(window).on('popstate', throttled.cancel);
|
|
*/
|
|
function throttle(func, wait, options) {
|
|
var leading = true,
|
|
trailing = true;
|
|
|
|
if (typeof func != 'function') {
|
|
throw new TypeError(FUNC_ERROR_TEXT);
|
|
}
|
|
if (isObject(options)) {
|
|
leading = 'leading' in options ? !!options.leading : leading;
|
|
trailing = 'trailing' in options ? !!options.trailing : trailing;
|
|
}
|
|
return debounce(func, wait, {
|
|
'leading': leading,
|
|
'maxWait': wait,
|
|
'trailing': trailing
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Creates a function that accepts up to one argument, ignoring any
|
|
* additional arguments.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Function
|
|
* @param {Function} func The function to cap arguments for.
|
|
* @returns {Function} Returns the new capped function.
|
|
* @example
|
|
*
|
|
* _.map(['6', '8', '10'], _.unary(parseInt));
|
|
* // => [6, 8, 10]
|
|
*/
|
|
function unary(func) {
|
|
return ary(func, 1);
|
|
}
|
|
|
|
/**
|
|
* Creates a function that provides `value` to `wrapper` as its first
|
|
* argument. Any additional arguments provided to the function are appended
|
|
* to those provided to the `wrapper`. The wrapper is invoked with the `this`
|
|
* binding of the created function.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Function
|
|
* @param {*} value The value to wrap.
|
|
* @param {Function} [wrapper=identity] The wrapper function.
|
|
* @returns {Function} Returns the new function.
|
|
* @example
|
|
*
|
|
* var p = _.wrap(_.escape, function(func, text) {
|
|
* return '<p>' + func(text) + '</p>';
|
|
* });
|
|
*
|
|
* p('fred, barney, & pebbles');
|
|
* // => '<p>fred, barney, & pebbles</p>'
|
|
*/
|
|
function wrap(value, wrapper) {
|
|
return partial(castFunction(wrapper), value);
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* Casts `value` as an array if it's not one.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.4.0
|
|
* @category Lang
|
|
* @param {*} value The value to inspect.
|
|
* @returns {Array} Returns the cast array.
|
|
* @example
|
|
*
|
|
* _.castArray(1);
|
|
* // => [1]
|
|
*
|
|
* _.castArray({ 'a': 1 });
|
|
* // => [{ 'a': 1 }]
|
|
*
|
|
* _.castArray('abc');
|
|
* // => ['abc']
|
|
*
|
|
* _.castArray(null);
|
|
* // => [null]
|
|
*
|
|
* _.castArray(undefined);
|
|
* // => [undefined]
|
|
*
|
|
* _.castArray();
|
|
* // => []
|
|
*
|
|
* var array = [1, 2, 3];
|
|
* console.log(_.castArray(array) === array);
|
|
* // => true
|
|
*/
|
|
function castArray() {
|
|
if (!arguments.length) {
|
|
return [];
|
|
}
|
|
var value = arguments[0];
|
|
return isArray(value) ? value : [value];
|
|
}
|
|
|
|
/**
|
|
* Creates a shallow clone of `value`.
|
|
*
|
|
* **Note:** This method is loosely based on the
|
|
* [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)
|
|
* and supports cloning arrays, array buffers, booleans, date objects, maps,
|
|
* numbers, `Object` objects, regexes, sets, strings, symbols, and typed
|
|
* arrays. The own enumerable properties of `arguments` objects are cloned
|
|
* as plain objects. An empty object is returned for uncloneable values such
|
|
* as error objects, functions, DOM nodes, and WeakMaps.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Lang
|
|
* @param {*} value The value to clone.
|
|
* @returns {*} Returns the cloned value.
|
|
* @see _.cloneDeep
|
|
* @example
|
|
*
|
|
* var objects = [{ 'a': 1 }, { 'b': 2 }];
|
|
*
|
|
* var shallow = _.clone(objects);
|
|
* console.log(shallow[0] === objects[0]);
|
|
* // => true
|
|
*/
|
|
function clone(value) {
|
|
return baseClone(value, CLONE_SYMBOLS_FLAG);
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.clone` except that it accepts `customizer` which
|
|
* is invoked to produce the cloned value. If `customizer` returns `undefined`,
|
|
* cloning is handled by the method instead. The `customizer` is invoked with
|
|
* up to four arguments; (value [, index|key, object, stack]).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Lang
|
|
* @param {*} value The value to clone.
|
|
* @param {Function} [customizer] The function to customize cloning.
|
|
* @returns {*} Returns the cloned value.
|
|
* @see _.cloneDeepWith
|
|
* @example
|
|
*
|
|
* function customizer(value) {
|
|
* if (_.isElement(value)) {
|
|
* return value.cloneNode(false);
|
|
* }
|
|
* }
|
|
*
|
|
* var el = _.cloneWith(document.body, customizer);
|
|
*
|
|
* console.log(el === document.body);
|
|
* // => false
|
|
* console.log(el.nodeName);
|
|
* // => 'BODY'
|
|
* console.log(el.childNodes.length);
|
|
* // => 0
|
|
*/
|
|
function cloneWith(value, customizer) {
|
|
customizer = typeof customizer == 'function' ? customizer : undefined;
|
|
return baseClone(value, CLONE_SYMBOLS_FLAG, customizer);
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.clone` except that it recursively clones `value`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 1.0.0
|
|
* @category Lang
|
|
* @param {*} value The value to recursively clone.
|
|
* @returns {*} Returns the deep cloned value.
|
|
* @see _.clone
|
|
* @example
|
|
*
|
|
* var objects = [{ 'a': 1 }, { 'b': 2 }];
|
|
*
|
|
* var deep = _.cloneDeep(objects);
|
|
* console.log(deep[0] === objects[0]);
|
|
* // => false
|
|
*/
|
|
function cloneDeep(value) {
|
|
return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG);
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.cloneWith` except that it recursively clones `value`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Lang
|
|
* @param {*} value The value to recursively clone.
|
|
* @param {Function} [customizer] The function to customize cloning.
|
|
* @returns {*} Returns the deep cloned value.
|
|
* @see _.cloneWith
|
|
* @example
|
|
*
|
|
* function customizer(value) {
|
|
* if (_.isElement(value)) {
|
|
* return value.cloneNode(true);
|
|
* }
|
|
* }
|
|
*
|
|
* var el = _.cloneDeepWith(document.body, customizer);
|
|
*
|
|
* console.log(el === document.body);
|
|
* // => false
|
|
* console.log(el.nodeName);
|
|
* // => 'BODY'
|
|
* console.log(el.childNodes.length);
|
|
* // => 20
|
|
*/
|
|
function cloneDeepWith(value, customizer) {
|
|
customizer = typeof customizer == 'function' ? customizer : undefined;
|
|
return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG, customizer);
|
|
}
|
|
|
|
/**
|
|
* Checks if `object` conforms to `source` by invoking the predicate
|
|
* properties of `source` with the corresponding property values of `object`.
|
|
*
|
|
* **Note:** This method is equivalent to `_.conforms` when `source` is
|
|
* partially applied.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.14.0
|
|
* @category Lang
|
|
* @param {Object} object The object to inspect.
|
|
* @param {Object} source The object of property predicates to conform to.
|
|
* @returns {boolean} Returns `true` if `object` conforms, else `false`.
|
|
* @example
|
|
*
|
|
* var object = { 'a': 1, 'b': 2 };
|
|
*
|
|
* _.conformsTo(object, { 'b': function(n) { return n > 1; } });
|
|
* // => true
|
|
*
|
|
* _.conformsTo(object, { 'b': function(n) { return n > 2; } });
|
|
* // => false
|
|
*/
|
|
function conformsTo(object, source) {
|
|
return source == null || baseConformsTo(object, source, keys(source));
|
|
}
|
|
|
|
/**
|
|
* Performs a
|
|
* [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
|
|
* comparison between two values to determine if they are equivalent.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Lang
|
|
* @param {*} value The value to compare.
|
|
* @param {*} other The other value to compare.
|
|
* @returns {boolean} Returns `true` if the values are equivalent, else `false`.
|
|
* @example
|
|
*
|
|
* var object = { 'a': 1 };
|
|
* var other = { 'a': 1 };
|
|
*
|
|
* _.eq(object, object);
|
|
* // => true
|
|
*
|
|
* _.eq(object, other);
|
|
* // => false
|
|
*
|
|
* _.eq('a', 'a');
|
|
* // => true
|
|
*
|
|
* _.eq('a', Object('a'));
|
|
* // => false
|
|
*
|
|
* _.eq(NaN, NaN);
|
|
* // => true
|
|
*/
|
|
function eq(value, other) {
|
|
return value === other || (value !== value && other !== other);
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is greater than `other`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.9.0
|
|
* @category Lang
|
|
* @param {*} value The value to compare.
|
|
* @param {*} other The other value to compare.
|
|
* @returns {boolean} Returns `true` if `value` is greater than `other`,
|
|
* else `false`.
|
|
* @see _.lt
|
|
* @example
|
|
*
|
|
* _.gt(3, 1);
|
|
* // => true
|
|
*
|
|
* _.gt(3, 3);
|
|
* // => false
|
|
*
|
|
* _.gt(1, 3);
|
|
* // => false
|
|
*/
|
|
var gt = createRelationalOperation(baseGt);
|
|
|
|
/**
|
|
* Checks if `value` is greater than or equal to `other`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.9.0
|
|
* @category Lang
|
|
* @param {*} value The value to compare.
|
|
* @param {*} other The other value to compare.
|
|
* @returns {boolean} Returns `true` if `value` is greater than or equal to
|
|
* `other`, else `false`.
|
|
* @see _.lte
|
|
* @example
|
|
*
|
|
* _.gte(3, 1);
|
|
* // => true
|
|
*
|
|
* _.gte(3, 3);
|
|
* // => true
|
|
*
|
|
* _.gte(1, 3);
|
|
* // => false
|
|
*/
|
|
var gte = createRelationalOperation(function(value, other) {
|
|
return value >= other;
|
|
});
|
|
|
|
/**
|
|
* Checks if `value` is likely an `arguments` object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is an `arguments` object,
|
|
* else `false`.
|
|
* @example
|
|
*
|
|
* _.isArguments(function() { return arguments; }());
|
|
* // => true
|
|
*
|
|
* _.isArguments([1, 2, 3]);
|
|
* // => false
|
|
*/
|
|
var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {
|
|
return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&
|
|
!propertyIsEnumerable.call(value, 'callee');
|
|
};
|
|
|
|
/**
|
|
* Checks if `value` is classified as an `Array` object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is an array, else `false`.
|
|
* @example
|
|
*
|
|
* _.isArray([1, 2, 3]);
|
|
* // => true
|
|
*
|
|
* _.isArray(document.body.children);
|
|
* // => false
|
|
*
|
|
* _.isArray('abc');
|
|
* // => false
|
|
*
|
|
* _.isArray(_.noop);
|
|
* // => false
|
|
*/
|
|
var isArray = Array.isArray;
|
|
|
|
/**
|
|
* Checks if `value` is classified as an `ArrayBuffer` object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.3.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.
|
|
* @example
|
|
*
|
|
* _.isArrayBuffer(new ArrayBuffer(2));
|
|
* // => true
|
|
*
|
|
* _.isArrayBuffer(new Array(2));
|
|
* // => false
|
|
*/
|
|
var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer;
|
|
|
|
/**
|
|
* Checks if `value` is array-like. A value is considered array-like if it's
|
|
* not a function and has a `value.length` that's an integer greater than or
|
|
* equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is array-like, else `false`.
|
|
* @example
|
|
*
|
|
* _.isArrayLike([1, 2, 3]);
|
|
* // => true
|
|
*
|
|
* _.isArrayLike(document.body.children);
|
|
* // => true
|
|
*
|
|
* _.isArrayLike('abc');
|
|
* // => true
|
|
*
|
|
* _.isArrayLike(_.noop);
|
|
* // => false
|
|
*/
|
|
function isArrayLike(value) {
|
|
return value != null && isLength(value.length) && !isFunction(value);
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.isArrayLike` except that it also checks if `value`
|
|
* is an object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is an array-like object,
|
|
* else `false`.
|
|
* @example
|
|
*
|
|
* _.isArrayLikeObject([1, 2, 3]);
|
|
* // => true
|
|
*
|
|
* _.isArrayLikeObject(document.body.children);
|
|
* // => true
|
|
*
|
|
* _.isArrayLikeObject('abc');
|
|
* // => false
|
|
*
|
|
* _.isArrayLikeObject(_.noop);
|
|
* // => false
|
|
*/
|
|
function isArrayLikeObject(value) {
|
|
return isObjectLike(value) && isArrayLike(value);
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is classified as a boolean primitive or object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a boolean, else `false`.
|
|
* @example
|
|
*
|
|
* _.isBoolean(false);
|
|
* // => true
|
|
*
|
|
* _.isBoolean(null);
|
|
* // => false
|
|
*/
|
|
function isBoolean(value) {
|
|
return value === true || value === false ||
|
|
(isObjectLike(value) && baseGetTag(value) == boolTag);
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is a buffer.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.3.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
|
|
* @example
|
|
*
|
|
* _.isBuffer(new Buffer(2));
|
|
* // => true
|
|
*
|
|
* _.isBuffer(new Uint8Array(2));
|
|
* // => false
|
|
*/
|
|
var isBuffer = nativeIsBuffer || stubFalse;
|
|
|
|
/**
|
|
* Checks if `value` is classified as a `Date` object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a date object, else `false`.
|
|
* @example
|
|
*
|
|
* _.isDate(new Date);
|
|
* // => true
|
|
*
|
|
* _.isDate('Mon April 23 2012');
|
|
* // => false
|
|
*/
|
|
var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate;
|
|
|
|
/**
|
|
* Checks if `value` is likely a DOM element.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a DOM element, else `false`.
|
|
* @example
|
|
*
|
|
* _.isElement(document.body);
|
|
* // => true
|
|
*
|
|
* _.isElement('<body>');
|
|
* // => false
|
|
*/
|
|
function isElement(value) {
|
|
return isObjectLike(value) && value.nodeType === 1 && !isPlainObject(value);
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is an empty object, collection, map, or set.
|
|
*
|
|
* Objects are considered empty if they have no own enumerable string keyed
|
|
* properties.
|
|
*
|
|
* Array-like values such as `arguments` objects, arrays, buffers, strings, or
|
|
* jQuery-like collections are considered empty if they have a `length` of `0`.
|
|
* Similarly, maps and sets are considered empty if they have a `size` of `0`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is empty, else `false`.
|
|
* @example
|
|
*
|
|
* _.isEmpty(null);
|
|
* // => true
|
|
*
|
|
* _.isEmpty(true);
|
|
* // => true
|
|
*
|
|
* _.isEmpty(1);
|
|
* // => true
|
|
*
|
|
* _.isEmpty([1, 2, 3]);
|
|
* // => false
|
|
*
|
|
* _.isEmpty({ 'a': 1 });
|
|
* // => false
|
|
*/
|
|
function isEmpty(value) {
|
|
if (value == null) {
|
|
return true;
|
|
}
|
|
if (isArrayLike(value) &&
|
|
(isArray(value) || typeof value == 'string' || typeof value.splice == 'function' ||
|
|
isBuffer(value) || isTypedArray(value) || isArguments(value))) {
|
|
return !value.length;
|
|
}
|
|
var tag = getTag(value);
|
|
if (tag == mapTag || tag == setTag) {
|
|
return !value.size;
|
|
}
|
|
if (isPrototype(value)) {
|
|
return !baseKeys(value).length;
|
|
}
|
|
for (var key in value) {
|
|
if (hasOwnProperty.call(value, key)) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Performs a deep comparison between two values to determine if they are
|
|
* equivalent.
|
|
*
|
|
* **Note:** This method supports comparing arrays, array buffers, booleans,
|
|
* date objects, error objects, maps, numbers, `Object` objects, regexes,
|
|
* sets, strings, symbols, and typed arrays. `Object` objects are compared
|
|
* by their own, not inherited, enumerable properties. Functions and DOM
|
|
* nodes are compared by strict equality, i.e. `===`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Lang
|
|
* @param {*} value The value to compare.
|
|
* @param {*} other The other value to compare.
|
|
* @returns {boolean} Returns `true` if the values are equivalent, else `false`.
|
|
* @example
|
|
*
|
|
* var object = { 'a': 1 };
|
|
* var other = { 'a': 1 };
|
|
*
|
|
* _.isEqual(object, other);
|
|
* // => true
|
|
*
|
|
* object === other;
|
|
* // => false
|
|
*/
|
|
function isEqual(value, other) {
|
|
return baseIsEqual(value, other);
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.isEqual` except that it accepts `customizer` which
|
|
* is invoked to compare values. If `customizer` returns `undefined`, comparisons
|
|
* are handled by the method instead. The `customizer` is invoked with up to
|
|
* six arguments: (objValue, othValue [, index|key, object, other, stack]).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Lang
|
|
* @param {*} value The value to compare.
|
|
* @param {*} other The other value to compare.
|
|
* @param {Function} [customizer] The function to customize comparisons.
|
|
* @returns {boolean} Returns `true` if the values are equivalent, else `false`.
|
|
* @example
|
|
*
|
|
* function isGreeting(value) {
|
|
* return /^h(?:i|ello)$/.test(value);
|
|
* }
|
|
*
|
|
* function customizer(objValue, othValue) {
|
|
* if (isGreeting(objValue) && isGreeting(othValue)) {
|
|
* return true;
|
|
* }
|
|
* }
|
|
*
|
|
* var array = ['hello', 'goodbye'];
|
|
* var other = ['hi', 'goodbye'];
|
|
*
|
|
* _.isEqualWith(array, other, customizer);
|
|
* // => true
|
|
*/
|
|
function isEqualWith(value, other, customizer) {
|
|
customizer = typeof customizer == 'function' ? customizer : undefined;
|
|
var result = customizer ? customizer(value, other) : undefined;
|
|
return result === undefined ? baseIsEqual(value, other, undefined, customizer) : !!result;
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,
|
|
* `SyntaxError`, `TypeError`, or `URIError` object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is an error object, else `false`.
|
|
* @example
|
|
*
|
|
* _.isError(new Error);
|
|
* // => true
|
|
*
|
|
* _.isError(Error);
|
|
* // => false
|
|
*/
|
|
function isError(value) {
|
|
if (!isObjectLike(value)) {
|
|
return false;
|
|
}
|
|
var tag = baseGetTag(value);
|
|
return tag == errorTag || tag == domExcTag ||
|
|
(typeof value.message == 'string' && typeof value.name == 'string' && !isPlainObject(value));
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is a finite primitive number.
|
|
*
|
|
* **Note:** This method is based on
|
|
* [`Number.isFinite`](https://mdn.io/Number/isFinite).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a finite number, else `false`.
|
|
* @example
|
|
*
|
|
* _.isFinite(3);
|
|
* // => true
|
|
*
|
|
* _.isFinite(Number.MIN_VALUE);
|
|
* // => true
|
|
*
|
|
* _.isFinite(Infinity);
|
|
* // => false
|
|
*
|
|
* _.isFinite('3');
|
|
* // => false
|
|
*/
|
|
function isFinite(value) {
|
|
return typeof value == 'number' && nativeIsFinite(value);
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is classified as a `Function` object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a function, else `false`.
|
|
* @example
|
|
*
|
|
* _.isFunction(_);
|
|
* // => true
|
|
*
|
|
* _.isFunction(/abc/);
|
|
* // => false
|
|
*/
|
|
function isFunction(value) {
|
|
if (!isObject(value)) {
|
|
return false;
|
|
}
|
|
// The use of `Object#toString` avoids issues with the `typeof` operator
|
|
// in Safari 9 which returns 'object' for typed arrays and other constructors.
|
|
var tag = baseGetTag(value);
|
|
return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is an integer.
|
|
*
|
|
* **Note:** This method is based on
|
|
* [`Number.isInteger`](https://mdn.io/Number/isInteger).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is an integer, else `false`.
|
|
* @example
|
|
*
|
|
* _.isInteger(3);
|
|
* // => true
|
|
*
|
|
* _.isInteger(Number.MIN_VALUE);
|
|
* // => false
|
|
*
|
|
* _.isInteger(Infinity);
|
|
* // => false
|
|
*
|
|
* _.isInteger('3');
|
|
* // => false
|
|
*/
|
|
function isInteger(value) {
|
|
return typeof value == 'number' && value == toInteger(value);
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is a valid array-like length.
|
|
*
|
|
* **Note:** This method is loosely based on
|
|
* [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
|
|
* @example
|
|
*
|
|
* _.isLength(3);
|
|
* // => true
|
|
*
|
|
* _.isLength(Number.MIN_VALUE);
|
|
* // => false
|
|
*
|
|
* _.isLength(Infinity);
|
|
* // => false
|
|
*
|
|
* _.isLength('3');
|
|
* // => false
|
|
*/
|
|
function isLength(value) {
|
|
return typeof value == 'number' &&
|
|
value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is the
|
|
* [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
|
|
* of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is an object, else `false`.
|
|
* @example
|
|
*
|
|
* _.isObject({});
|
|
* // => true
|
|
*
|
|
* _.isObject([1, 2, 3]);
|
|
* // => true
|
|
*
|
|
* _.isObject(_.noop);
|
|
* // => true
|
|
*
|
|
* _.isObject(null);
|
|
* // => false
|
|
*/
|
|
function isObject(value) {
|
|
var type = typeof value;
|
|
return value != null && (type == 'object' || type == 'function');
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is object-like. A value is object-like if it's not `null`
|
|
* and has a `typeof` result of "object".
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
|
|
* @example
|
|
*
|
|
* _.isObjectLike({});
|
|
* // => true
|
|
*
|
|
* _.isObjectLike([1, 2, 3]);
|
|
* // => true
|
|
*
|
|
* _.isObjectLike(_.noop);
|
|
* // => false
|
|
*
|
|
* _.isObjectLike(null);
|
|
* // => false
|
|
*/
|
|
function isObjectLike(value) {
|
|
return value != null && typeof value == 'object';
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is classified as a `Map` object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.3.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a map, else `false`.
|
|
* @example
|
|
*
|
|
* _.isMap(new Map);
|
|
* // => true
|
|
*
|
|
* _.isMap(new WeakMap);
|
|
* // => false
|
|
*/
|
|
var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap;
|
|
|
|
/**
|
|
* Performs a partial deep comparison between `object` and `source` to
|
|
* determine if `object` contains equivalent property values.
|
|
*
|
|
* **Note:** This method is equivalent to `_.matches` when `source` is
|
|
* partially applied.
|
|
*
|
|
* Partial comparisons will match empty array and empty object `source`
|
|
* values against any array or object value, respectively. See `_.isEqual`
|
|
* for a list of supported value comparisons.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Lang
|
|
* @param {Object} object The object to inspect.
|
|
* @param {Object} source The object of property values to match.
|
|
* @returns {boolean} Returns `true` if `object` is a match, else `false`.
|
|
* @example
|
|
*
|
|
* var object = { 'a': 1, 'b': 2 };
|
|
*
|
|
* _.isMatch(object, { 'b': 2 });
|
|
* // => true
|
|
*
|
|
* _.isMatch(object, { 'b': 1 });
|
|
* // => false
|
|
*/
|
|
function isMatch(object, source) {
|
|
return object === source || baseIsMatch(object, source, getMatchData(source));
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.isMatch` except that it accepts `customizer` which
|
|
* is invoked to compare values. If `customizer` returns `undefined`, comparisons
|
|
* are handled by the method instead. The `customizer` is invoked with five
|
|
* arguments: (objValue, srcValue, index|key, object, source).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Lang
|
|
* @param {Object} object The object to inspect.
|
|
* @param {Object} source The object of property values to match.
|
|
* @param {Function} [customizer] The function to customize comparisons.
|
|
* @returns {boolean} Returns `true` if `object` is a match, else `false`.
|
|
* @example
|
|
*
|
|
* function isGreeting(value) {
|
|
* return /^h(?:i|ello)$/.test(value);
|
|
* }
|
|
*
|
|
* function customizer(objValue, srcValue) {
|
|
* if (isGreeting(objValue) && isGreeting(srcValue)) {
|
|
* return true;
|
|
* }
|
|
* }
|
|
*
|
|
* var object = { 'greeting': 'hello' };
|
|
* var source = { 'greeting': 'hi' };
|
|
*
|
|
* _.isMatchWith(object, source, customizer);
|
|
* // => true
|
|
*/
|
|
function isMatchWith(object, source, customizer) {
|
|
customizer = typeof customizer == 'function' ? customizer : undefined;
|
|
return baseIsMatch(object, source, getMatchData(source), customizer);
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is `NaN`.
|
|
*
|
|
* **Note:** This method is based on
|
|
* [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as
|
|
* global [`isNaN`](https://mdn.io/isNaN) which returns `true` for
|
|
* `undefined` and other non-number values.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
|
|
* @example
|
|
*
|
|
* _.isNaN(NaN);
|
|
* // => true
|
|
*
|
|
* _.isNaN(new Number(NaN));
|
|
* // => true
|
|
*
|
|
* isNaN(undefined);
|
|
* // => true
|
|
*
|
|
* _.isNaN(undefined);
|
|
* // => false
|
|
*/
|
|
function isNaN(value) {
|
|
// An `NaN` primitive is the only value that is not equal to itself.
|
|
// Perform the `toStringTag` check first to avoid errors with some
|
|
// ActiveX objects in IE.
|
|
return isNumber(value) && value != +value;
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is a pristine native function.
|
|
*
|
|
* **Note:** This method can't reliably detect native functions in the presence
|
|
* of the core-js package because core-js circumvents this kind of detection.
|
|
* Despite multiple requests, the core-js maintainer has made it clear: any
|
|
* attempt to fix the detection will be obstructed. As a result, we're left
|
|
* with little choice but to throw an error. Unfortunately, this also affects
|
|
* packages, like [babel-polyfill](https://www.npmjs.com/package/babel-polyfill),
|
|
* which rely on core-js.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a native function,
|
|
* else `false`.
|
|
* @example
|
|
*
|
|
* _.isNative(Array.prototype.push);
|
|
* // => true
|
|
*
|
|
* _.isNative(_);
|
|
* // => false
|
|
*/
|
|
function isNative(value) {
|
|
if (isMaskable(value)) {
|
|
throw new Error(CORE_ERROR_TEXT);
|
|
}
|
|
return baseIsNative(value);
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is `null`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is `null`, else `false`.
|
|
* @example
|
|
*
|
|
* _.isNull(null);
|
|
* // => true
|
|
*
|
|
* _.isNull(void 0);
|
|
* // => false
|
|
*/
|
|
function isNull(value) {
|
|
return value === null;
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is `null` or `undefined`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is nullish, else `false`.
|
|
* @example
|
|
*
|
|
* _.isNil(null);
|
|
* // => true
|
|
*
|
|
* _.isNil(void 0);
|
|
* // => true
|
|
*
|
|
* _.isNil(NaN);
|
|
* // => false
|
|
*/
|
|
function isNil(value) {
|
|
return value == null;
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is classified as a `Number` primitive or object.
|
|
*
|
|
* **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are
|
|
* classified as numbers, use the `_.isFinite` method.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a number, else `false`.
|
|
* @example
|
|
*
|
|
* _.isNumber(3);
|
|
* // => true
|
|
*
|
|
* _.isNumber(Number.MIN_VALUE);
|
|
* // => true
|
|
*
|
|
* _.isNumber(Infinity);
|
|
* // => true
|
|
*
|
|
* _.isNumber('3');
|
|
* // => false
|
|
*/
|
|
function isNumber(value) {
|
|
return typeof value == 'number' ||
|
|
(isObjectLike(value) && baseGetTag(value) == numberTag);
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is a plain object, that is, an object created by the
|
|
* `Object` constructor or one with a `[[Prototype]]` of `null`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.8.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
|
|
* @example
|
|
*
|
|
* function Foo() {
|
|
* this.a = 1;
|
|
* }
|
|
*
|
|
* _.isPlainObject(new Foo);
|
|
* // => false
|
|
*
|
|
* _.isPlainObject([1, 2, 3]);
|
|
* // => false
|
|
*
|
|
* _.isPlainObject({ 'x': 0, 'y': 0 });
|
|
* // => true
|
|
*
|
|
* _.isPlainObject(Object.create(null));
|
|
* // => true
|
|
*/
|
|
function isPlainObject(value) {
|
|
if (!isObjectLike(value) || baseGetTag(value) != objectTag) {
|
|
return false;
|
|
}
|
|
var proto = getPrototype(value);
|
|
if (proto === null) {
|
|
return true;
|
|
}
|
|
var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;
|
|
return typeof Ctor == 'function' && Ctor instanceof Ctor &&
|
|
funcToString.call(Ctor) == objectCtorString;
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is classified as a `RegExp` object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.1.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a regexp, else `false`.
|
|
* @example
|
|
*
|
|
* _.isRegExp(/abc/);
|
|
* // => true
|
|
*
|
|
* _.isRegExp('/abc/');
|
|
* // => false
|
|
*/
|
|
var isRegExp = nodeIsRegExp ? baseUnary(nodeIsRegExp) : baseIsRegExp;
|
|
|
|
/**
|
|
* Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754
|
|
* double precision number which isn't the result of a rounded unsafe integer.
|
|
*
|
|
* **Note:** This method is based on
|
|
* [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a safe integer, else `false`.
|
|
* @example
|
|
*
|
|
* _.isSafeInteger(3);
|
|
* // => true
|
|
*
|
|
* _.isSafeInteger(Number.MIN_VALUE);
|
|
* // => false
|
|
*
|
|
* _.isSafeInteger(Infinity);
|
|
* // => false
|
|
*
|
|
* _.isSafeInteger('3');
|
|
* // => false
|
|
*/
|
|
function isSafeInteger(value) {
|
|
return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER;
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is classified as a `Set` object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.3.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a set, else `false`.
|
|
* @example
|
|
*
|
|
* _.isSet(new Set);
|
|
* // => true
|
|
*
|
|
* _.isSet(new WeakSet);
|
|
* // => false
|
|
*/
|
|
var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet;
|
|
|
|
/**
|
|
* Checks if `value` is classified as a `String` primitive or object.
|
|
*
|
|
* @static
|
|
* @since 0.1.0
|
|
* @memberOf _
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a string, else `false`.
|
|
* @example
|
|
*
|
|
* _.isString('abc');
|
|
* // => true
|
|
*
|
|
* _.isString(1);
|
|
* // => false
|
|
*/
|
|
function isString(value) {
|
|
return typeof value == 'string' ||
|
|
(!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag);
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is classified as a `Symbol` primitive or object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
|
|
* @example
|
|
*
|
|
* _.isSymbol(Symbol.iterator);
|
|
* // => true
|
|
*
|
|
* _.isSymbol('abc');
|
|
* // => false
|
|
*/
|
|
function isSymbol(value) {
|
|
return typeof value == 'symbol' ||
|
|
(isObjectLike(value) && baseGetTag(value) == symbolTag);
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is classified as a typed array.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
|
|
* @example
|
|
*
|
|
* _.isTypedArray(new Uint8Array);
|
|
* // => true
|
|
*
|
|
* _.isTypedArray([]);
|
|
* // => false
|
|
*/
|
|
var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;
|
|
|
|
/**
|
|
* Checks if `value` is `undefined`.
|
|
*
|
|
* @static
|
|
* @since 0.1.0
|
|
* @memberOf _
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
|
|
* @example
|
|
*
|
|
* _.isUndefined(void 0);
|
|
* // => true
|
|
*
|
|
* _.isUndefined(null);
|
|
* // => false
|
|
*/
|
|
function isUndefined(value) {
|
|
return value === undefined;
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is classified as a `WeakMap` object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.3.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a weak map, else `false`.
|
|
* @example
|
|
*
|
|
* _.isWeakMap(new WeakMap);
|
|
* // => true
|
|
*
|
|
* _.isWeakMap(new Map);
|
|
* // => false
|
|
*/
|
|
function isWeakMap(value) {
|
|
return isObjectLike(value) && getTag(value) == weakMapTag;
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is classified as a `WeakSet` object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.3.0
|
|
* @category Lang
|
|
* @param {*} value The value to check.
|
|
* @returns {boolean} Returns `true` if `value` is a weak set, else `false`.
|
|
* @example
|
|
*
|
|
* _.isWeakSet(new WeakSet);
|
|
* // => true
|
|
*
|
|
* _.isWeakSet(new Set);
|
|
* // => false
|
|
*/
|
|
function isWeakSet(value) {
|
|
return isObjectLike(value) && baseGetTag(value) == weakSetTag;
|
|
}
|
|
|
|
/**
|
|
* Checks if `value` is less than `other`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.9.0
|
|
* @category Lang
|
|
* @param {*} value The value to compare.
|
|
* @param {*} other The other value to compare.
|
|
* @returns {boolean} Returns `true` if `value` is less than `other`,
|
|
* else `false`.
|
|
* @see _.gt
|
|
* @example
|
|
*
|
|
* _.lt(1, 3);
|
|
* // => true
|
|
*
|
|
* _.lt(3, 3);
|
|
* // => false
|
|
*
|
|
* _.lt(3, 1);
|
|
* // => false
|
|
*/
|
|
var lt = createRelationalOperation(baseLt);
|
|
|
|
/**
|
|
* Checks if `value` is less than or equal to `other`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.9.0
|
|
* @category Lang
|
|
* @param {*} value The value to compare.
|
|
* @param {*} other The other value to compare.
|
|
* @returns {boolean} Returns `true` if `value` is less than or equal to
|
|
* `other`, else `false`.
|
|
* @see _.gte
|
|
* @example
|
|
*
|
|
* _.lte(1, 3);
|
|
* // => true
|
|
*
|
|
* _.lte(3, 3);
|
|
* // => true
|
|
*
|
|
* _.lte(3, 1);
|
|
* // => false
|
|
*/
|
|
var lte = createRelationalOperation(function(value, other) {
|
|
return value <= other;
|
|
});
|
|
|
|
/**
|
|
* Converts `value` to an array.
|
|
*
|
|
* @static
|
|
* @since 0.1.0
|
|
* @memberOf _
|
|
* @category Lang
|
|
* @param {*} value The value to convert.
|
|
* @returns {Array} Returns the converted array.
|
|
* @example
|
|
*
|
|
* _.toArray({ 'a': 1, 'b': 2 });
|
|
* // => [1, 2]
|
|
*
|
|
* _.toArray('abc');
|
|
* // => ['a', 'b', 'c']
|
|
*
|
|
* _.toArray(1);
|
|
* // => []
|
|
*
|
|
* _.toArray(null);
|
|
* // => []
|
|
*/
|
|
function toArray(value) {
|
|
if (!value) {
|
|
return [];
|
|
}
|
|
if (isArrayLike(value)) {
|
|
return isString(value) ? stringToArray(value) : copyArray(value);
|
|
}
|
|
if (symIterator && value[symIterator]) {
|
|
return iteratorToArray(value[symIterator]());
|
|
}
|
|
var tag = getTag(value),
|
|
func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values);
|
|
|
|
return func(value);
|
|
}
|
|
|
|
/**
|
|
* Converts `value` to a finite number.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.12.0
|
|
* @category Lang
|
|
* @param {*} value The value to convert.
|
|
* @returns {number} Returns the converted number.
|
|
* @example
|
|
*
|
|
* _.toFinite(3.2);
|
|
* // => 3.2
|
|
*
|
|
* _.toFinite(Number.MIN_VALUE);
|
|
* // => 5e-324
|
|
*
|
|
* _.toFinite(Infinity);
|
|
* // => 1.7976931348623157e+308
|
|
*
|
|
* _.toFinite('3.2');
|
|
* // => 3.2
|
|
*/
|
|
function toFinite(value) {
|
|
if (!value) {
|
|
return value === 0 ? value : 0;
|
|
}
|
|
value = toNumber(value);
|
|
if (value === INFINITY || value === -INFINITY) {
|
|
var sign = (value < 0 ? -1 : 1);
|
|
return sign * MAX_INTEGER;
|
|
}
|
|
return value === value ? value : 0;
|
|
}
|
|
|
|
/**
|
|
* Converts `value` to an integer.
|
|
*
|
|
* **Note:** This method is loosely based on
|
|
* [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Lang
|
|
* @param {*} value The value to convert.
|
|
* @returns {number} Returns the converted integer.
|
|
* @example
|
|
*
|
|
* _.toInteger(3.2);
|
|
* // => 3
|
|
*
|
|
* _.toInteger(Number.MIN_VALUE);
|
|
* // => 0
|
|
*
|
|
* _.toInteger(Infinity);
|
|
* // => 1.7976931348623157e+308
|
|
*
|
|
* _.toInteger('3.2');
|
|
* // => 3
|
|
*/
|
|
function toInteger(value) {
|
|
var result = toFinite(value),
|
|
remainder = result % 1;
|
|
|
|
return result === result ? (remainder ? result - remainder : result) : 0;
|
|
}
|
|
|
|
/**
|
|
* Converts `value` to an integer suitable for use as the length of an
|
|
* array-like object.
|
|
*
|
|
* **Note:** This method is based on
|
|
* [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Lang
|
|
* @param {*} value The value to convert.
|
|
* @returns {number} Returns the converted integer.
|
|
* @example
|
|
*
|
|
* _.toLength(3.2);
|
|
* // => 3
|
|
*
|
|
* _.toLength(Number.MIN_VALUE);
|
|
* // => 0
|
|
*
|
|
* _.toLength(Infinity);
|
|
* // => 4294967295
|
|
*
|
|
* _.toLength('3.2');
|
|
* // => 3
|
|
*/
|
|
function toLength(value) {
|
|
return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0;
|
|
}
|
|
|
|
/**
|
|
* Converts `value` to a number.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Lang
|
|
* @param {*} value The value to process.
|
|
* @returns {number} Returns the number.
|
|
* @example
|
|
*
|
|
* _.toNumber(3.2);
|
|
* // => 3.2
|
|
*
|
|
* _.toNumber(Number.MIN_VALUE);
|
|
* // => 5e-324
|
|
*
|
|
* _.toNumber(Infinity);
|
|
* // => Infinity
|
|
*
|
|
* _.toNumber('3.2');
|
|
* // => 3.2
|
|
*/
|
|
function toNumber(value) {
|
|
if (typeof value == 'number') {
|
|
return value;
|
|
}
|
|
if (isSymbol(value)) {
|
|
return NAN;
|
|
}
|
|
if (isObject(value)) {
|
|
var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
|
|
value = isObject(other) ? (other + '') : other;
|
|
}
|
|
if (typeof value != 'string') {
|
|
return value === 0 ? value : +value;
|
|
}
|
|
value = baseTrim(value);
|
|
var isBinary = reIsBinary.test(value);
|
|
return (isBinary || reIsOctal.test(value))
|
|
? freeParseInt(value.slice(2), isBinary ? 2 : 8)
|
|
: (reIsBadHex.test(value) ? NAN : +value);
|
|
}
|
|
|
|
/**
|
|
* Converts `value` to a plain object flattening inherited enumerable string
|
|
* keyed properties of `value` to own properties of the plain object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Lang
|
|
* @param {*} value The value to convert.
|
|
* @returns {Object} Returns the converted plain object.
|
|
* @example
|
|
*
|
|
* function Foo() {
|
|
* this.b = 2;
|
|
* }
|
|
*
|
|
* Foo.prototype.c = 3;
|
|
*
|
|
* _.assign({ 'a': 1 }, new Foo);
|
|
* // => { 'a': 1, 'b': 2 }
|
|
*
|
|
* _.assign({ 'a': 1 }, _.toPlainObject(new Foo));
|
|
* // => { 'a': 1, 'b': 2, 'c': 3 }
|
|
*/
|
|
function toPlainObject(value) {
|
|
return copyObject(value, keysIn(value));
|
|
}
|
|
|
|
/**
|
|
* Converts `value` to a safe integer. A safe integer can be compared and
|
|
* represented correctly.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Lang
|
|
* @param {*} value The value to convert.
|
|
* @returns {number} Returns the converted integer.
|
|
* @example
|
|
*
|
|
* _.toSafeInteger(3.2);
|
|
* // => 3
|
|
*
|
|
* _.toSafeInteger(Number.MIN_VALUE);
|
|
* // => 0
|
|
*
|
|
* _.toSafeInteger(Infinity);
|
|
* // => 9007199254740991
|
|
*
|
|
* _.toSafeInteger('3.2');
|
|
* // => 3
|
|
*/
|
|
function toSafeInteger(value) {
|
|
return value
|
|
? baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER)
|
|
: (value === 0 ? value : 0);
|
|
}
|
|
|
|
/**
|
|
* Converts `value` to a string. An empty string is returned for `null`
|
|
* and `undefined` values. The sign of `-0` is preserved.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Lang
|
|
* @param {*} value The value to convert.
|
|
* @returns {string} Returns the converted string.
|
|
* @example
|
|
*
|
|
* _.toString(null);
|
|
* // => ''
|
|
*
|
|
* _.toString(-0);
|
|
* // => '-0'
|
|
*
|
|
* _.toString([1, 2, 3]);
|
|
* // => '1,2,3'
|
|
*/
|
|
function toString(value) {
|
|
return value == null ? '' : baseToString(value);
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* Assigns own enumerable string keyed properties of source objects to the
|
|
* destination object. Source objects are applied from left to right.
|
|
* Subsequent sources overwrite property assignments of previous sources.
|
|
*
|
|
* **Note:** This method mutates `object` and is loosely based on
|
|
* [`Object.assign`](https://mdn.io/Object/assign).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.10.0
|
|
* @category Object
|
|
* @param {Object} object The destination object.
|
|
* @param {...Object} [sources] The source objects.
|
|
* @returns {Object} Returns `object`.
|
|
* @see _.assignIn
|
|
* @example
|
|
*
|
|
* function Foo() {
|
|
* this.a = 1;
|
|
* }
|
|
*
|
|
* function Bar() {
|
|
* this.c = 3;
|
|
* }
|
|
*
|
|
* Foo.prototype.b = 2;
|
|
* Bar.prototype.d = 4;
|
|
*
|
|
* _.assign({ 'a': 0 }, new Foo, new Bar);
|
|
* // => { 'a': 1, 'c': 3 }
|
|
*/
|
|
var assign = createAssigner(function(object, source) {
|
|
if (isPrototype(source) || isArrayLike(source)) {
|
|
copyObject(source, keys(source), object);
|
|
return;
|
|
}
|
|
for (var key in source) {
|
|
if (hasOwnProperty.call(source, key)) {
|
|
assignValue(object, key, source[key]);
|
|
}
|
|
}
|
|
});
|
|
|
|
/**
|
|
* This method is like `_.assign` except that it iterates over own and
|
|
* inherited source properties.
|
|
*
|
|
* **Note:** This method mutates `object`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @alias extend
|
|
* @category Object
|
|
* @param {Object} object The destination object.
|
|
* @param {...Object} [sources] The source objects.
|
|
* @returns {Object} Returns `object`.
|
|
* @see _.assign
|
|
* @example
|
|
*
|
|
* function Foo() {
|
|
* this.a = 1;
|
|
* }
|
|
*
|
|
* function Bar() {
|
|
* this.c = 3;
|
|
* }
|
|
*
|
|
* Foo.prototype.b = 2;
|
|
* Bar.prototype.d = 4;
|
|
*
|
|
* _.assignIn({ 'a': 0 }, new Foo, new Bar);
|
|
* // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 }
|
|
*/
|
|
var assignIn = createAssigner(function(object, source) {
|
|
copyObject(source, keysIn(source), object);
|
|
});
|
|
|
|
/**
|
|
* This method is like `_.assignIn` except that it accepts `customizer`
|
|
* which is invoked to produce the assigned values. If `customizer` returns
|
|
* `undefined`, assignment is handled by the method instead. The `customizer`
|
|
* is invoked with five arguments: (objValue, srcValue, key, object, source).
|
|
*
|
|
* **Note:** This method mutates `object`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @alias extendWith
|
|
* @category Object
|
|
* @param {Object} object The destination object.
|
|
* @param {...Object} sources The source objects.
|
|
* @param {Function} [customizer] The function to customize assigned values.
|
|
* @returns {Object} Returns `object`.
|
|
* @see _.assignWith
|
|
* @example
|
|
*
|
|
* function customizer(objValue, srcValue) {
|
|
* return _.isUndefined(objValue) ? srcValue : objValue;
|
|
* }
|
|
*
|
|
* var defaults = _.partialRight(_.assignInWith, customizer);
|
|
*
|
|
* defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
|
|
* // => { 'a': 1, 'b': 2 }
|
|
*/
|
|
var assignInWith = createAssigner(function(object, source, srcIndex, customizer) {
|
|
copyObject(source, keysIn(source), object, customizer);
|
|
});
|
|
|
|
/**
|
|
* This method is like `_.assign` except that it accepts `customizer`
|
|
* which is invoked to produce the assigned values. If `customizer` returns
|
|
* `undefined`, assignment is handled by the method instead. The `customizer`
|
|
* is invoked with five arguments: (objValue, srcValue, key, object, source).
|
|
*
|
|
* **Note:** This method mutates `object`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Object
|
|
* @param {Object} object The destination object.
|
|
* @param {...Object} sources The source objects.
|
|
* @param {Function} [customizer] The function to customize assigned values.
|
|
* @returns {Object} Returns `object`.
|
|
* @see _.assignInWith
|
|
* @example
|
|
*
|
|
* function customizer(objValue, srcValue) {
|
|
* return _.isUndefined(objValue) ? srcValue : objValue;
|
|
* }
|
|
*
|
|
* var defaults = _.partialRight(_.assignWith, customizer);
|
|
*
|
|
* defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
|
|
* // => { 'a': 1, 'b': 2 }
|
|
*/
|
|
var assignWith = createAssigner(function(object, source, srcIndex, customizer) {
|
|
copyObject(source, keys(source), object, customizer);
|
|
});
|
|
|
|
/**
|
|
* Creates an array of values corresponding to `paths` of `object`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 1.0.0
|
|
* @category Object
|
|
* @param {Object} object The object to iterate over.
|
|
* @param {...(string|string[])} [paths] The property paths to pick.
|
|
* @returns {Array} Returns the picked values.
|
|
* @example
|
|
*
|
|
* var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
|
|
*
|
|
* _.at(object, ['a[0].b.c', 'a[1]']);
|
|
* // => [3, 4]
|
|
*/
|
|
var at = flatRest(baseAt);
|
|
|
|
/**
|
|
* Creates an object that inherits from the `prototype` object. If a
|
|
* `properties` object is given, its own enumerable string keyed properties
|
|
* are assigned to the created object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 2.3.0
|
|
* @category Object
|
|
* @param {Object} prototype The object to inherit from.
|
|
* @param {Object} [properties] The properties to assign to the object.
|
|
* @returns {Object} Returns the new object.
|
|
* @example
|
|
*
|
|
* function Shape() {
|
|
* this.x = 0;
|
|
* this.y = 0;
|
|
* }
|
|
*
|
|
* function Circle() {
|
|
* Shape.call(this);
|
|
* }
|
|
*
|
|
* Circle.prototype = _.create(Shape.prototype, {
|
|
* 'constructor': Circle
|
|
* });
|
|
*
|
|
* var circle = new Circle;
|
|
* circle instanceof Circle;
|
|
* // => true
|
|
*
|
|
* circle instanceof Shape;
|
|
* // => true
|
|
*/
|
|
function create(prototype, properties) {
|
|
var result = baseCreate(prototype);
|
|
return properties == null ? result : baseAssign(result, properties);
|
|
}
|
|
|
|
/**
|
|
* Assigns own and inherited enumerable string keyed properties of source
|
|
* objects to the destination object for all destination properties that
|
|
* resolve to `undefined`. Source objects are applied from left to right.
|
|
* Once a property is set, additional values of the same property are ignored.
|
|
*
|
|
* **Note:** This method mutates `object`.
|
|
*
|
|
* @static
|
|
* @since 0.1.0
|
|
* @memberOf _
|
|
* @category Object
|
|
* @param {Object} object The destination object.
|
|
* @param {...Object} [sources] The source objects.
|
|
* @returns {Object} Returns `object`.
|
|
* @see _.defaultsDeep
|
|
* @example
|
|
*
|
|
* _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
|
|
* // => { 'a': 1, 'b': 2 }
|
|
*/
|
|
var defaults = baseRest(function(object, sources) {
|
|
object = Object(object);
|
|
|
|
var index = -1;
|
|
var length = sources.length;
|
|
var guard = length > 2 ? sources[2] : undefined;
|
|
|
|
if (guard && isIterateeCall(sources[0], sources[1], guard)) {
|
|
length = 1;
|
|
}
|
|
|
|
while (++index < length) {
|
|
var source = sources[index];
|
|
var props = keysIn(source);
|
|
var propsIndex = -1;
|
|
var propsLength = props.length;
|
|
|
|
while (++propsIndex < propsLength) {
|
|
var key = props[propsIndex];
|
|
var value = object[key];
|
|
|
|
if (value === undefined ||
|
|
(eq(value, objectProto[key]) && !hasOwnProperty.call(object, key))) {
|
|
object[key] = source[key];
|
|
}
|
|
}
|
|
}
|
|
|
|
return object;
|
|
});
|
|
|
|
/**
|
|
* This method is like `_.defaults` except that it recursively assigns
|
|
* default properties.
|
|
*
|
|
* **Note:** This method mutates `object`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.10.0
|
|
* @category Object
|
|
* @param {Object} object The destination object.
|
|
* @param {...Object} [sources] The source objects.
|
|
* @returns {Object} Returns `object`.
|
|
* @see _.defaults
|
|
* @example
|
|
*
|
|
* _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } });
|
|
* // => { 'a': { 'b': 2, 'c': 3 } }
|
|
*/
|
|
var defaultsDeep = baseRest(function(args) {
|
|
args.push(undefined, customDefaultsMerge);
|
|
return apply(mergeWith, undefined, args);
|
|
});
|
|
|
|
/**
|
|
* This method is like `_.find` except that it returns the key of the first
|
|
* element `predicate` returns truthy for instead of the element itself.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 1.1.0
|
|
* @category Object
|
|
* @param {Object} object The object to inspect.
|
|
* @param {Function} [predicate=_.identity] The function invoked per iteration.
|
|
* @returns {string|undefined} Returns the key of the matched element,
|
|
* else `undefined`.
|
|
* @example
|
|
*
|
|
* var users = {
|
|
* 'barney': { 'age': 36, 'active': true },
|
|
* 'fred': { 'age': 40, 'active': false },
|
|
* 'pebbles': { 'age': 1, 'active': true }
|
|
* };
|
|
*
|
|
* _.findKey(users, function(o) { return o.age < 40; });
|
|
* // => 'barney' (iteration order is not guaranteed)
|
|
*
|
|
* // The `_.matches` iteratee shorthand.
|
|
* _.findKey(users, { 'age': 1, 'active': true });
|
|
* // => 'pebbles'
|
|
*
|
|
* // The `_.matchesProperty` iteratee shorthand.
|
|
* _.findKey(users, ['active', false]);
|
|
* // => 'fred'
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.findKey(users, 'active');
|
|
* // => 'barney'
|
|
*/
|
|
function findKey(object, predicate) {
|
|
return baseFindKey(object, getIteratee(predicate, 3), baseForOwn);
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.findKey` except that it iterates over elements of
|
|
* a collection in the opposite order.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 2.0.0
|
|
* @category Object
|
|
* @param {Object} object The object to inspect.
|
|
* @param {Function} [predicate=_.identity] The function invoked per iteration.
|
|
* @returns {string|undefined} Returns the key of the matched element,
|
|
* else `undefined`.
|
|
* @example
|
|
*
|
|
* var users = {
|
|
* 'barney': { 'age': 36, 'active': true },
|
|
* 'fred': { 'age': 40, 'active': false },
|
|
* 'pebbles': { 'age': 1, 'active': true }
|
|
* };
|
|
*
|
|
* _.findLastKey(users, function(o) { return o.age < 40; });
|
|
* // => returns 'pebbles' assuming `_.findKey` returns 'barney'
|
|
*
|
|
* // The `_.matches` iteratee shorthand.
|
|
* _.findLastKey(users, { 'age': 36, 'active': true });
|
|
* // => 'barney'
|
|
*
|
|
* // The `_.matchesProperty` iteratee shorthand.
|
|
* _.findLastKey(users, ['active', false]);
|
|
* // => 'fred'
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.findLastKey(users, 'active');
|
|
* // => 'pebbles'
|
|
*/
|
|
function findLastKey(object, predicate) {
|
|
return baseFindKey(object, getIteratee(predicate, 3), baseForOwnRight);
|
|
}
|
|
|
|
/**
|
|
* Iterates over own and inherited enumerable string keyed properties of an
|
|
* object and invokes `iteratee` for each property. The iteratee is invoked
|
|
* with three arguments: (value, key, object). Iteratee functions may exit
|
|
* iteration early by explicitly returning `false`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.3.0
|
|
* @category Object
|
|
* @param {Object} object The object to iterate over.
|
|
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
|
* @returns {Object} Returns `object`.
|
|
* @see _.forInRight
|
|
* @example
|
|
*
|
|
* function Foo() {
|
|
* this.a = 1;
|
|
* this.b = 2;
|
|
* }
|
|
*
|
|
* Foo.prototype.c = 3;
|
|
*
|
|
* _.forIn(new Foo, function(value, key) {
|
|
* console.log(key);
|
|
* });
|
|
* // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed).
|
|
*/
|
|
function forIn(object, iteratee) {
|
|
return object == null
|
|
? object
|
|
: baseFor(object, getIteratee(iteratee, 3), keysIn);
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.forIn` except that it iterates over properties of
|
|
* `object` in the opposite order.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 2.0.0
|
|
* @category Object
|
|
* @param {Object} object The object to iterate over.
|
|
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
|
* @returns {Object} Returns `object`.
|
|
* @see _.forIn
|
|
* @example
|
|
*
|
|
* function Foo() {
|
|
* this.a = 1;
|
|
* this.b = 2;
|
|
* }
|
|
*
|
|
* Foo.prototype.c = 3;
|
|
*
|
|
* _.forInRight(new Foo, function(value, key) {
|
|
* console.log(key);
|
|
* });
|
|
* // => Logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'.
|
|
*/
|
|
function forInRight(object, iteratee) {
|
|
return object == null
|
|
? object
|
|
: baseForRight(object, getIteratee(iteratee, 3), keysIn);
|
|
}
|
|
|
|
/**
|
|
* Iterates over own enumerable string keyed properties of an object and
|
|
* invokes `iteratee` for each property. The iteratee is invoked with three
|
|
* arguments: (value, key, object). Iteratee functions may exit iteration
|
|
* early by explicitly returning `false`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.3.0
|
|
* @category Object
|
|
* @param {Object} object The object to iterate over.
|
|
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
|
* @returns {Object} Returns `object`.
|
|
* @see _.forOwnRight
|
|
* @example
|
|
*
|
|
* function Foo() {
|
|
* this.a = 1;
|
|
* this.b = 2;
|
|
* }
|
|
*
|
|
* Foo.prototype.c = 3;
|
|
*
|
|
* _.forOwn(new Foo, function(value, key) {
|
|
* console.log(key);
|
|
* });
|
|
* // => Logs 'a' then 'b' (iteration order is not guaranteed).
|
|
*/
|
|
function forOwn(object, iteratee) {
|
|
return object && baseForOwn(object, getIteratee(iteratee, 3));
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.forOwn` except that it iterates over properties of
|
|
* `object` in the opposite order.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 2.0.0
|
|
* @category Object
|
|
* @param {Object} object The object to iterate over.
|
|
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
|
* @returns {Object} Returns `object`.
|
|
* @see _.forOwn
|
|
* @example
|
|
*
|
|
* function Foo() {
|
|
* this.a = 1;
|
|
* this.b = 2;
|
|
* }
|
|
*
|
|
* Foo.prototype.c = 3;
|
|
*
|
|
* _.forOwnRight(new Foo, function(value, key) {
|
|
* console.log(key);
|
|
* });
|
|
* // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'.
|
|
*/
|
|
function forOwnRight(object, iteratee) {
|
|
return object && baseForOwnRight(object, getIteratee(iteratee, 3));
|
|
}
|
|
|
|
/**
|
|
* Creates an array of function property names from own enumerable properties
|
|
* of `object`.
|
|
*
|
|
* @static
|
|
* @since 0.1.0
|
|
* @memberOf _
|
|
* @category Object
|
|
* @param {Object} object The object to inspect.
|
|
* @returns {Array} Returns the function names.
|
|
* @see _.functionsIn
|
|
* @example
|
|
*
|
|
* function Foo() {
|
|
* this.a = _.constant('a');
|
|
* this.b = _.constant('b');
|
|
* }
|
|
*
|
|
* Foo.prototype.c = _.constant('c');
|
|
*
|
|
* _.functions(new Foo);
|
|
* // => ['a', 'b']
|
|
*/
|
|
function functions(object) {
|
|
return object == null ? [] : baseFunctions(object, keys(object));
|
|
}
|
|
|
|
/**
|
|
* Creates an array of function property names from own and inherited
|
|
* enumerable properties of `object`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Object
|
|
* @param {Object} object The object to inspect.
|
|
* @returns {Array} Returns the function names.
|
|
* @see _.functions
|
|
* @example
|
|
*
|
|
* function Foo() {
|
|
* this.a = _.constant('a');
|
|
* this.b = _.constant('b');
|
|
* }
|
|
*
|
|
* Foo.prototype.c = _.constant('c');
|
|
*
|
|
* _.functionsIn(new Foo);
|
|
* // => ['a', 'b', 'c']
|
|
*/
|
|
function functionsIn(object) {
|
|
return object == null ? [] : baseFunctions(object, keysIn(object));
|
|
}
|
|
|
|
/**
|
|
* Gets the value at `path` of `object`. If the resolved value is
|
|
* `undefined`, the `defaultValue` is returned in its place.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.7.0
|
|
* @category Object
|
|
* @param {Object} object The object to query.
|
|
* @param {Array|string} path The path of the property to get.
|
|
* @param {*} [defaultValue] The value returned for `undefined` resolved values.
|
|
* @returns {*} Returns the resolved value.
|
|
* @example
|
|
*
|
|
* var object = { 'a': [{ 'b': { 'c': 3 } }] };
|
|
*
|
|
* _.get(object, 'a[0].b.c');
|
|
* // => 3
|
|
*
|
|
* _.get(object, ['a', '0', 'b', 'c']);
|
|
* // => 3
|
|
*
|
|
* _.get(object, 'a.b.c', 'default');
|
|
* // => 'default'
|
|
*/
|
|
function get(object, path, defaultValue) {
|
|
var result = object == null ? undefined : baseGet(object, path);
|
|
return result === undefined ? defaultValue : result;
|
|
}
|
|
|
|
/**
|
|
* Checks if `path` is a direct property of `object`.
|
|
*
|
|
* @static
|
|
* @since 0.1.0
|
|
* @memberOf _
|
|
* @category Object
|
|
* @param {Object} object The object to query.
|
|
* @param {Array|string} path The path to check.
|
|
* @returns {boolean} Returns `true` if `path` exists, else `false`.
|
|
* @example
|
|
*
|
|
* var object = { 'a': { 'b': 2 } };
|
|
* var other = _.create({ 'a': _.create({ 'b': 2 }) });
|
|
*
|
|
* _.has(object, 'a');
|
|
* // => true
|
|
*
|
|
* _.has(object, 'a.b');
|
|
* // => true
|
|
*
|
|
* _.has(object, ['a', 'b']);
|
|
* // => true
|
|
*
|
|
* _.has(other, 'a');
|
|
* // => false
|
|
*/
|
|
function has(object, path) {
|
|
return object != null && hasPath(object, path, baseHas);
|
|
}
|
|
|
|
/**
|
|
* Checks if `path` is a direct or inherited property of `object`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Object
|
|
* @param {Object} object The object to query.
|
|
* @param {Array|string} path The path to check.
|
|
* @returns {boolean} Returns `true` if `path` exists, else `false`.
|
|
* @example
|
|
*
|
|
* var object = _.create({ 'a': _.create({ 'b': 2 }) });
|
|
*
|
|
* _.hasIn(object, 'a');
|
|
* // => true
|
|
*
|
|
* _.hasIn(object, 'a.b');
|
|
* // => true
|
|
*
|
|
* _.hasIn(object, ['a', 'b']);
|
|
* // => true
|
|
*
|
|
* _.hasIn(object, 'b');
|
|
* // => false
|
|
*/
|
|
function hasIn(object, path) {
|
|
return object != null && hasPath(object, path, baseHasIn);
|
|
}
|
|
|
|
/**
|
|
* Creates an object composed of the inverted keys and values of `object`.
|
|
* If `object` contains duplicate values, subsequent values overwrite
|
|
* property assignments of previous values.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.7.0
|
|
* @category Object
|
|
* @param {Object} object The object to invert.
|
|
* @returns {Object} Returns the new inverted object.
|
|
* @example
|
|
*
|
|
* var object = { 'a': 1, 'b': 2, 'c': 1 };
|
|
*
|
|
* _.invert(object);
|
|
* // => { '1': 'c', '2': 'b' }
|
|
*/
|
|
var invert = createInverter(function(result, value, key) {
|
|
if (value != null &&
|
|
typeof value.toString != 'function') {
|
|
value = nativeObjectToString.call(value);
|
|
}
|
|
|
|
result[value] = key;
|
|
}, constant(identity));
|
|
|
|
/**
|
|
* This method is like `_.invert` except that the inverted object is generated
|
|
* from the results of running each element of `object` thru `iteratee`. The
|
|
* corresponding inverted value of each inverted key is an array of keys
|
|
* responsible for generating the inverted value. The iteratee is invoked
|
|
* with one argument: (value).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.1.0
|
|
* @category Object
|
|
* @param {Object} object The object to invert.
|
|
* @param {Function} [iteratee=_.identity] The iteratee invoked per element.
|
|
* @returns {Object} Returns the new inverted object.
|
|
* @example
|
|
*
|
|
* var object = { 'a': 1, 'b': 2, 'c': 1 };
|
|
*
|
|
* _.invertBy(object);
|
|
* // => { '1': ['a', 'c'], '2': ['b'] }
|
|
*
|
|
* _.invertBy(object, function(value) {
|
|
* return 'group' + value;
|
|
* });
|
|
* // => { 'group1': ['a', 'c'], 'group2': ['b'] }
|
|
*/
|
|
var invertBy = createInverter(function(result, value, key) {
|
|
if (value != null &&
|
|
typeof value.toString != 'function') {
|
|
value = nativeObjectToString.call(value);
|
|
}
|
|
|
|
if (hasOwnProperty.call(result, value)) {
|
|
result[value].push(key);
|
|
} else {
|
|
result[value] = [key];
|
|
}
|
|
}, getIteratee);
|
|
|
|
/**
|
|
* Invokes the method at `path` of `object`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Object
|
|
* @param {Object} object The object to query.
|
|
* @param {Array|string} path The path of the method to invoke.
|
|
* @param {...*} [args] The arguments to invoke the method with.
|
|
* @returns {*} Returns the result of the invoked method.
|
|
* @example
|
|
*
|
|
* var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };
|
|
*
|
|
* _.invoke(object, 'a[0].b.c.slice', 1, 3);
|
|
* // => [2, 3]
|
|
*/
|
|
var invoke = baseRest(baseInvoke);
|
|
|
|
/**
|
|
* Creates an array of the own enumerable property names of `object`.
|
|
*
|
|
* **Note:** Non-object values are coerced to objects. See the
|
|
* [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
|
|
* for more details.
|
|
*
|
|
* @static
|
|
* @since 0.1.0
|
|
* @memberOf _
|
|
* @category Object
|
|
* @param {Object} object The object to query.
|
|
* @returns {Array} Returns the array of property names.
|
|
* @example
|
|
*
|
|
* function Foo() {
|
|
* this.a = 1;
|
|
* this.b = 2;
|
|
* }
|
|
*
|
|
* Foo.prototype.c = 3;
|
|
*
|
|
* _.keys(new Foo);
|
|
* // => ['a', 'b'] (iteration order is not guaranteed)
|
|
*
|
|
* _.keys('hi');
|
|
* // => ['0', '1']
|
|
*/
|
|
function keys(object) {
|
|
return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);
|
|
}
|
|
|
|
/**
|
|
* Creates an array of the own and inherited enumerable property names of `object`.
|
|
*
|
|
* **Note:** Non-object values are coerced to objects.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Object
|
|
* @param {Object} object The object to query.
|
|
* @returns {Array} Returns the array of property names.
|
|
* @example
|
|
*
|
|
* function Foo() {
|
|
* this.a = 1;
|
|
* this.b = 2;
|
|
* }
|
|
*
|
|
* Foo.prototype.c = 3;
|
|
*
|
|
* _.keysIn(new Foo);
|
|
* // => ['a', 'b', 'c'] (iteration order is not guaranteed)
|
|
*/
|
|
function keysIn(object) {
|
|
return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);
|
|
}
|
|
|
|
/**
|
|
* The opposite of `_.mapValues`; this method creates an object with the
|
|
* same values as `object` and keys generated by running each own enumerable
|
|
* string keyed property of `object` thru `iteratee`. The iteratee is invoked
|
|
* with three arguments: (value, key, object).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.8.0
|
|
* @category Object
|
|
* @param {Object} object The object to iterate over.
|
|
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
|
* @returns {Object} Returns the new mapped object.
|
|
* @see _.mapValues
|
|
* @example
|
|
*
|
|
* _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) {
|
|
* return key + value;
|
|
* });
|
|
* // => { 'a1': 1, 'b2': 2 }
|
|
*/
|
|
function mapKeys(object, iteratee) {
|
|
var result = {};
|
|
iteratee = getIteratee(iteratee, 3);
|
|
|
|
baseForOwn(object, function(value, key, object) {
|
|
baseAssignValue(result, iteratee(value, key, object), value);
|
|
});
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Creates an object with the same keys as `object` and values generated
|
|
* by running each own enumerable string keyed property of `object` thru
|
|
* `iteratee`. The iteratee is invoked with three arguments:
|
|
* (value, key, object).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 2.4.0
|
|
* @category Object
|
|
* @param {Object} object The object to iterate over.
|
|
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
|
* @returns {Object} Returns the new mapped object.
|
|
* @see _.mapKeys
|
|
* @example
|
|
*
|
|
* var users = {
|
|
* 'fred': { 'user': 'fred', 'age': 40 },
|
|
* 'pebbles': { 'user': 'pebbles', 'age': 1 }
|
|
* };
|
|
*
|
|
* _.mapValues(users, function(o) { return o.age; });
|
|
* // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.mapValues(users, 'age');
|
|
* // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
|
|
*/
|
|
function mapValues(object, iteratee) {
|
|
var result = {};
|
|
iteratee = getIteratee(iteratee, 3);
|
|
|
|
baseForOwn(object, function(value, key, object) {
|
|
baseAssignValue(result, key, iteratee(value, key, object));
|
|
});
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.assign` except that it recursively merges own and
|
|
* inherited enumerable string keyed properties of source objects into the
|
|
* destination object. Source properties that resolve to `undefined` are
|
|
* skipped if a destination value exists. Array and plain object properties
|
|
* are merged recursively. Other objects and value types are overridden by
|
|
* assignment. Source objects are applied from left to right. Subsequent
|
|
* sources overwrite property assignments of previous sources.
|
|
*
|
|
* **Note:** This method mutates `object`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.5.0
|
|
* @category Object
|
|
* @param {Object} object The destination object.
|
|
* @param {...Object} [sources] The source objects.
|
|
* @returns {Object} Returns `object`.
|
|
* @example
|
|
*
|
|
* var object = {
|
|
* 'a': [{ 'b': 2 }, { 'd': 4 }]
|
|
* };
|
|
*
|
|
* var other = {
|
|
* 'a': [{ 'c': 3 }, { 'e': 5 }]
|
|
* };
|
|
*
|
|
* _.merge(object, other);
|
|
* // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }
|
|
*/
|
|
var merge = createAssigner(function(object, source, srcIndex) {
|
|
baseMerge(object, source, srcIndex);
|
|
});
|
|
|
|
/**
|
|
* This method is like `_.merge` except that it accepts `customizer` which
|
|
* is invoked to produce the merged values of the destination and source
|
|
* properties. If `customizer` returns `undefined`, merging is handled by the
|
|
* method instead. The `customizer` is invoked with six arguments:
|
|
* (objValue, srcValue, key, object, source, stack).
|
|
*
|
|
* **Note:** This method mutates `object`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Object
|
|
* @param {Object} object The destination object.
|
|
* @param {...Object} sources The source objects.
|
|
* @param {Function} customizer The function to customize assigned values.
|
|
* @returns {Object} Returns `object`.
|
|
* @example
|
|
*
|
|
* function customizer(objValue, srcValue) {
|
|
* if (_.isArray(objValue)) {
|
|
* return objValue.concat(srcValue);
|
|
* }
|
|
* }
|
|
*
|
|
* var object = { 'a': [1], 'b': [2] };
|
|
* var other = { 'a': [3], 'b': [4] };
|
|
*
|
|
* _.mergeWith(object, other, customizer);
|
|
* // => { 'a': [1, 3], 'b': [2, 4] }
|
|
*/
|
|
var mergeWith = createAssigner(function(object, source, srcIndex, customizer) {
|
|
baseMerge(object, source, srcIndex, customizer);
|
|
});
|
|
|
|
/**
|
|
* The opposite of `_.pick`; this method creates an object composed of the
|
|
* own and inherited enumerable property paths of `object` that are not omitted.
|
|
*
|
|
* **Note:** This method is considerably slower than `_.pick`.
|
|
*
|
|
* @static
|
|
* @since 0.1.0
|
|
* @memberOf _
|
|
* @category Object
|
|
* @param {Object} object The source object.
|
|
* @param {...(string|string[])} [paths] The property paths to omit.
|
|
* @returns {Object} Returns the new object.
|
|
* @example
|
|
*
|
|
* var object = { 'a': 1, 'b': '2', 'c': 3 };
|
|
*
|
|
* _.omit(object, ['a', 'c']);
|
|
* // => { 'b': '2' }
|
|
*/
|
|
var omit = flatRest(function(object, paths) {
|
|
var result = {};
|
|
if (object == null) {
|
|
return result;
|
|
}
|
|
var isDeep = false;
|
|
paths = arrayMap(paths, function(path) {
|
|
path = castPath(path, object);
|
|
isDeep || (isDeep = path.length > 1);
|
|
return path;
|
|
});
|
|
copyObject(object, getAllKeysIn(object), result);
|
|
if (isDeep) {
|
|
result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone);
|
|
}
|
|
var length = paths.length;
|
|
while (length--) {
|
|
baseUnset(result, paths[length]);
|
|
}
|
|
return result;
|
|
});
|
|
|
|
/**
|
|
* The opposite of `_.pickBy`; this method creates an object composed of
|
|
* the own and inherited enumerable string keyed properties of `object` that
|
|
* `predicate` doesn't return truthy for. The predicate is invoked with two
|
|
* arguments: (value, key).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Object
|
|
* @param {Object} object The source object.
|
|
* @param {Function} [predicate=_.identity] The function invoked per property.
|
|
* @returns {Object} Returns the new object.
|
|
* @example
|
|
*
|
|
* var object = { 'a': 1, 'b': '2', 'c': 3 };
|
|
*
|
|
* _.omitBy(object, _.isNumber);
|
|
* // => { 'b': '2' }
|
|
*/
|
|
function omitBy(object, predicate) {
|
|
return pickBy(object, negate(getIteratee(predicate)));
|
|
}
|
|
|
|
/**
|
|
* Creates an object composed of the picked `object` properties.
|
|
*
|
|
* @static
|
|
* @since 0.1.0
|
|
* @memberOf _
|
|
* @category Object
|
|
* @param {Object} object The source object.
|
|
* @param {...(string|string[])} [paths] The property paths to pick.
|
|
* @returns {Object} Returns the new object.
|
|
* @example
|
|
*
|
|
* var object = { 'a': 1, 'b': '2', 'c': 3 };
|
|
*
|
|
* _.pick(object, ['a', 'c']);
|
|
* // => { 'a': 1, 'c': 3 }
|
|
*/
|
|
var pick = flatRest(function(object, paths) {
|
|
return object == null ? {} : basePick(object, paths);
|
|
});
|
|
|
|
/**
|
|
* Creates an object composed of the `object` properties `predicate` returns
|
|
* truthy for. The predicate is invoked with two arguments: (value, key).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Object
|
|
* @param {Object} object The source object.
|
|
* @param {Function} [predicate=_.identity] The function invoked per property.
|
|
* @returns {Object} Returns the new object.
|
|
* @example
|
|
*
|
|
* var object = { 'a': 1, 'b': '2', 'c': 3 };
|
|
*
|
|
* _.pickBy(object, _.isNumber);
|
|
* // => { 'a': 1, 'c': 3 }
|
|
*/
|
|
function pickBy(object, predicate) {
|
|
if (object == null) {
|
|
return {};
|
|
}
|
|
var props = arrayMap(getAllKeysIn(object), function(prop) {
|
|
return [prop];
|
|
});
|
|
predicate = getIteratee(predicate);
|
|
return basePickBy(object, props, function(value, path) {
|
|
return predicate(value, path[0]);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.get` except that if the resolved value is a
|
|
* function it's invoked with the `this` binding of its parent object and
|
|
* its result is returned.
|
|
*
|
|
* @static
|
|
* @since 0.1.0
|
|
* @memberOf _
|
|
* @category Object
|
|
* @param {Object} object The object to query.
|
|
* @param {Array|string} path The path of the property to resolve.
|
|
* @param {*} [defaultValue] The value returned for `undefined` resolved values.
|
|
* @returns {*} Returns the resolved value.
|
|
* @example
|
|
*
|
|
* var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };
|
|
*
|
|
* _.result(object, 'a[0].b.c1');
|
|
* // => 3
|
|
*
|
|
* _.result(object, 'a[0].b.c2');
|
|
* // => 4
|
|
*
|
|
* _.result(object, 'a[0].b.c3', 'default');
|
|
* // => 'default'
|
|
*
|
|
* _.result(object, 'a[0].b.c3', _.constant('default'));
|
|
* // => 'default'
|
|
*/
|
|
function result(object, path, defaultValue) {
|
|
path = castPath(path, object);
|
|
|
|
var index = -1,
|
|
length = path.length;
|
|
|
|
// Ensure the loop is entered when path is empty.
|
|
if (!length) {
|
|
length = 1;
|
|
object = undefined;
|
|
}
|
|
while (++index < length) {
|
|
var value = object == null ? undefined : object[toKey(path[index])];
|
|
if (value === undefined) {
|
|
index = length;
|
|
value = defaultValue;
|
|
}
|
|
object = isFunction(value) ? value.call(object) : value;
|
|
}
|
|
return object;
|
|
}
|
|
|
|
/**
|
|
* Sets the value at `path` of `object`. If a portion of `path` doesn't exist,
|
|
* it's created. Arrays are created for missing index properties while objects
|
|
* are created for all other missing properties. Use `_.setWith` to customize
|
|
* `path` creation.
|
|
*
|
|
* **Note:** This method mutates `object`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.7.0
|
|
* @category Object
|
|
* @param {Object} object The object to modify.
|
|
* @param {Array|string} path The path of the property to set.
|
|
* @param {*} value The value to set.
|
|
* @returns {Object} Returns `object`.
|
|
* @example
|
|
*
|
|
* var object = { 'a': [{ 'b': { 'c': 3 } }] };
|
|
*
|
|
* _.set(object, 'a[0].b.c', 4);
|
|
* console.log(object.a[0].b.c);
|
|
* // => 4
|
|
*
|
|
* _.set(object, ['x', '0', 'y', 'z'], 5);
|
|
* console.log(object.x[0].y.z);
|
|
* // => 5
|
|
*/
|
|
function set(object, path, value) {
|
|
return object == null ? object : baseSet(object, path, value);
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.set` except that it accepts `customizer` which is
|
|
* invoked to produce the objects of `path`. If `customizer` returns `undefined`
|
|
* path creation is handled by the method instead. The `customizer` is invoked
|
|
* with three arguments: (nsValue, key, nsObject).
|
|
*
|
|
* **Note:** This method mutates `object`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Object
|
|
* @param {Object} object The object to modify.
|
|
* @param {Array|string} path The path of the property to set.
|
|
* @param {*} value The value to set.
|
|
* @param {Function} [customizer] The function to customize assigned values.
|
|
* @returns {Object} Returns `object`.
|
|
* @example
|
|
*
|
|
* var object = {};
|
|
*
|
|
* _.setWith(object, '[0][1]', 'a', Object);
|
|
* // => { '0': { '1': 'a' } }
|
|
*/
|
|
function setWith(object, path, value, customizer) {
|
|
customizer = typeof customizer == 'function' ? customizer : undefined;
|
|
return object == null ? object : baseSet(object, path, value, customizer);
|
|
}
|
|
|
|
/**
|
|
* Creates an array of own enumerable string keyed-value pairs for `object`
|
|
* which can be consumed by `_.fromPairs`. If `object` is a map or set, its
|
|
* entries are returned.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @alias entries
|
|
* @category Object
|
|
* @param {Object} object The object to query.
|
|
* @returns {Array} Returns the key-value pairs.
|
|
* @example
|
|
*
|
|
* function Foo() {
|
|
* this.a = 1;
|
|
* this.b = 2;
|
|
* }
|
|
*
|
|
* Foo.prototype.c = 3;
|
|
*
|
|
* _.toPairs(new Foo);
|
|
* // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)
|
|
*/
|
|
var toPairs = createToPairs(keys);
|
|
|
|
/**
|
|
* Creates an array of own and inherited enumerable string keyed-value pairs
|
|
* for `object` which can be consumed by `_.fromPairs`. If `object` is a map
|
|
* or set, its entries are returned.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @alias entriesIn
|
|
* @category Object
|
|
* @param {Object} object The object to query.
|
|
* @returns {Array} Returns the key-value pairs.
|
|
* @example
|
|
*
|
|
* function Foo() {
|
|
* this.a = 1;
|
|
* this.b = 2;
|
|
* }
|
|
*
|
|
* Foo.prototype.c = 3;
|
|
*
|
|
* _.toPairsIn(new Foo);
|
|
* // => [['a', 1], ['b', 2], ['c', 3]] (iteration order is not guaranteed)
|
|
*/
|
|
var toPairsIn = createToPairs(keysIn);
|
|
|
|
/**
|
|
* An alternative to `_.reduce`; this method transforms `object` to a new
|
|
* `accumulator` object which is the result of running each of its own
|
|
* enumerable string keyed properties thru `iteratee`, with each invocation
|
|
* potentially mutating the `accumulator` object. If `accumulator` is not
|
|
* provided, a new object with the same `[[Prototype]]` will be used. The
|
|
* iteratee is invoked with four arguments: (accumulator, value, key, object).
|
|
* Iteratee functions may exit iteration early by explicitly returning `false`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 1.3.0
|
|
* @category Object
|
|
* @param {Object} object The object to iterate over.
|
|
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
|
* @param {*} [accumulator] The custom accumulator value.
|
|
* @returns {*} Returns the accumulated value.
|
|
* @example
|
|
*
|
|
* _.transform([2, 3, 4], function(result, n) {
|
|
* result.push(n *= n);
|
|
* return n % 2 == 0;
|
|
* }, []);
|
|
* // => [4, 9]
|
|
*
|
|
* _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
|
|
* (result[value] || (result[value] = [])).push(key);
|
|
* }, {});
|
|
* // => { '1': ['a', 'c'], '2': ['b'] }
|
|
*/
|
|
function transform(object, iteratee, accumulator) {
|
|
var isArr = isArray(object),
|
|
isArrLike = isArr || isBuffer(object) || isTypedArray(object);
|
|
|
|
iteratee = getIteratee(iteratee, 4);
|
|
if (accumulator == null) {
|
|
var Ctor = object && object.constructor;
|
|
if (isArrLike) {
|
|
accumulator = isArr ? new Ctor : [];
|
|
}
|
|
else if (isObject(object)) {
|
|
accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {};
|
|
}
|
|
else {
|
|
accumulator = {};
|
|
}
|
|
}
|
|
(isArrLike ? arrayEach : baseForOwn)(object, function(value, index, object) {
|
|
return iteratee(accumulator, value, index, object);
|
|
});
|
|
return accumulator;
|
|
}
|
|
|
|
/**
|
|
* Removes the property at `path` of `object`.
|
|
*
|
|
* **Note:** This method mutates `object`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Object
|
|
* @param {Object} object The object to modify.
|
|
* @param {Array|string} path The path of the property to unset.
|
|
* @returns {boolean} Returns `true` if the property is deleted, else `false`.
|
|
* @example
|
|
*
|
|
* var object = { 'a': [{ 'b': { 'c': 7 } }] };
|
|
* _.unset(object, 'a[0].b.c');
|
|
* // => true
|
|
*
|
|
* console.log(object);
|
|
* // => { 'a': [{ 'b': {} }] };
|
|
*
|
|
* _.unset(object, ['a', '0', 'b', 'c']);
|
|
* // => true
|
|
*
|
|
* console.log(object);
|
|
* // => { 'a': [{ 'b': {} }] };
|
|
*/
|
|
function unset(object, path) {
|
|
return object == null ? true : baseUnset(object, path);
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.set` except that accepts `updater` to produce the
|
|
* value to set. Use `_.updateWith` to customize `path` creation. The `updater`
|
|
* is invoked with one argument: (value).
|
|
*
|
|
* **Note:** This method mutates `object`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.6.0
|
|
* @category Object
|
|
* @param {Object} object The object to modify.
|
|
* @param {Array|string} path The path of the property to set.
|
|
* @param {Function} updater The function to produce the updated value.
|
|
* @returns {Object} Returns `object`.
|
|
* @example
|
|
*
|
|
* var object = { 'a': [{ 'b': { 'c': 3 } }] };
|
|
*
|
|
* _.update(object, 'a[0].b.c', function(n) { return n * n; });
|
|
* console.log(object.a[0].b.c);
|
|
* // => 9
|
|
*
|
|
* _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; });
|
|
* console.log(object.x[0].y.z);
|
|
* // => 0
|
|
*/
|
|
function update(object, path, updater) {
|
|
return object == null ? object : baseUpdate(object, path, castFunction(updater));
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.update` except that it accepts `customizer` which is
|
|
* invoked to produce the objects of `path`. If `customizer` returns `undefined`
|
|
* path creation is handled by the method instead. The `customizer` is invoked
|
|
* with three arguments: (nsValue, key, nsObject).
|
|
*
|
|
* **Note:** This method mutates `object`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.6.0
|
|
* @category Object
|
|
* @param {Object} object The object to modify.
|
|
* @param {Array|string} path The path of the property to set.
|
|
* @param {Function} updater The function to produce the updated value.
|
|
* @param {Function} [customizer] The function to customize assigned values.
|
|
* @returns {Object} Returns `object`.
|
|
* @example
|
|
*
|
|
* var object = {};
|
|
*
|
|
* _.updateWith(object, '[0][1]', _.constant('a'), Object);
|
|
* // => { '0': { '1': 'a' } }
|
|
*/
|
|
function updateWith(object, path, updater, customizer) {
|
|
customizer = typeof customizer == 'function' ? customizer : undefined;
|
|
return object == null ? object : baseUpdate(object, path, castFunction(updater), customizer);
|
|
}
|
|
|
|
/**
|
|
* Creates an array of the own enumerable string keyed property values of `object`.
|
|
*
|
|
* **Note:** Non-object values are coerced to objects.
|
|
*
|
|
* @static
|
|
* @since 0.1.0
|
|
* @memberOf _
|
|
* @category Object
|
|
* @param {Object} object The object to query.
|
|
* @returns {Array} Returns the array of property values.
|
|
* @example
|
|
*
|
|
* function Foo() {
|
|
* this.a = 1;
|
|
* this.b = 2;
|
|
* }
|
|
*
|
|
* Foo.prototype.c = 3;
|
|
*
|
|
* _.values(new Foo);
|
|
* // => [1, 2] (iteration order is not guaranteed)
|
|
*
|
|
* _.values('hi');
|
|
* // => ['h', 'i']
|
|
*/
|
|
function values(object) {
|
|
return object == null ? [] : baseValues(object, keys(object));
|
|
}
|
|
|
|
/**
|
|
* Creates an array of the own and inherited enumerable string keyed property
|
|
* values of `object`.
|
|
*
|
|
* **Note:** Non-object values are coerced to objects.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Object
|
|
* @param {Object} object The object to query.
|
|
* @returns {Array} Returns the array of property values.
|
|
* @example
|
|
*
|
|
* function Foo() {
|
|
* this.a = 1;
|
|
* this.b = 2;
|
|
* }
|
|
*
|
|
* Foo.prototype.c = 3;
|
|
*
|
|
* _.valuesIn(new Foo);
|
|
* // => [1, 2, 3] (iteration order is not guaranteed)
|
|
*/
|
|
function valuesIn(object) {
|
|
return object == null ? [] : baseValues(object, keysIn(object));
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* Clamps `number` within the inclusive `lower` and `upper` bounds.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Number
|
|
* @param {number} number The number to clamp.
|
|
* @param {number} [lower] The lower bound.
|
|
* @param {number} upper The upper bound.
|
|
* @returns {number} Returns the clamped number.
|
|
* @example
|
|
*
|
|
* _.clamp(-10, -5, 5);
|
|
* // => -5
|
|
*
|
|
* _.clamp(10, -5, 5);
|
|
* // => 5
|
|
*/
|
|
function clamp(number, lower, upper) {
|
|
if (upper === undefined) {
|
|
upper = lower;
|
|
lower = undefined;
|
|
}
|
|
if (upper !== undefined) {
|
|
upper = toNumber(upper);
|
|
upper = upper === upper ? upper : 0;
|
|
}
|
|
if (lower !== undefined) {
|
|
lower = toNumber(lower);
|
|
lower = lower === lower ? lower : 0;
|
|
}
|
|
return baseClamp(toNumber(number), lower, upper);
|
|
}
|
|
|
|
/**
|
|
* Checks if `n` is between `start` and up to, but not including, `end`. If
|
|
* `end` is not specified, it's set to `start` with `start` then set to `0`.
|
|
* If `start` is greater than `end` the params are swapped to support
|
|
* negative ranges.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.3.0
|
|
* @category Number
|
|
* @param {number} number The number to check.
|
|
* @param {number} [start=0] The start of the range.
|
|
* @param {number} end The end of the range.
|
|
* @returns {boolean} Returns `true` if `number` is in the range, else `false`.
|
|
* @see _.range, _.rangeRight
|
|
* @example
|
|
*
|
|
* _.inRange(3, 2, 4);
|
|
* // => true
|
|
*
|
|
* _.inRange(4, 8);
|
|
* // => true
|
|
*
|
|
* _.inRange(4, 2);
|
|
* // => false
|
|
*
|
|
* _.inRange(2, 2);
|
|
* // => false
|
|
*
|
|
* _.inRange(1.2, 2);
|
|
* // => true
|
|
*
|
|
* _.inRange(5.2, 4);
|
|
* // => false
|
|
*
|
|
* _.inRange(-3, -2, -6);
|
|
* // => true
|
|
*/
|
|
function inRange(number, start, end) {
|
|
start = toFinite(start);
|
|
if (end === undefined) {
|
|
end = start;
|
|
start = 0;
|
|
} else {
|
|
end = toFinite(end);
|
|
}
|
|
number = toNumber(number);
|
|
return baseInRange(number, start, end);
|
|
}
|
|
|
|
/**
|
|
* Produces a random number between the inclusive `lower` and `upper` bounds.
|
|
* If only one argument is provided a number between `0` and the given number
|
|
* is returned. If `floating` is `true`, or either `lower` or `upper` are
|
|
* floats, a floating-point number is returned instead of an integer.
|
|
*
|
|
* **Note:** JavaScript follows the IEEE-754 standard for resolving
|
|
* floating-point values which can produce unexpected results.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.7.0
|
|
* @category Number
|
|
* @param {number} [lower=0] The lower bound.
|
|
* @param {number} [upper=1] The upper bound.
|
|
* @param {boolean} [floating] Specify returning a floating-point number.
|
|
* @returns {number} Returns the random number.
|
|
* @example
|
|
*
|
|
* _.random(0, 5);
|
|
* // => an integer between 0 and 5
|
|
*
|
|
* _.random(5);
|
|
* // => also an integer between 0 and 5
|
|
*
|
|
* _.random(5, true);
|
|
* // => a floating-point number between 0 and 5
|
|
*
|
|
* _.random(1.2, 5.2);
|
|
* // => a floating-point number between 1.2 and 5.2
|
|
*/
|
|
function random(lower, upper, floating) {
|
|
if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) {
|
|
upper = floating = undefined;
|
|
}
|
|
if (floating === undefined) {
|
|
if (typeof upper == 'boolean') {
|
|
floating = upper;
|
|
upper = undefined;
|
|
}
|
|
else if (typeof lower == 'boolean') {
|
|
floating = lower;
|
|
lower = undefined;
|
|
}
|
|
}
|
|
if (lower === undefined && upper === undefined) {
|
|
lower = 0;
|
|
upper = 1;
|
|
}
|
|
else {
|
|
lower = toFinite(lower);
|
|
if (upper === undefined) {
|
|
upper = lower;
|
|
lower = 0;
|
|
} else {
|
|
upper = toFinite(upper);
|
|
}
|
|
}
|
|
if (lower > upper) {
|
|
var temp = lower;
|
|
lower = upper;
|
|
upper = temp;
|
|
}
|
|
if (floating || lower % 1 || upper % 1) {
|
|
var rand = nativeRandom();
|
|
return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper);
|
|
}
|
|
return baseRandom(lower, upper);
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to convert.
|
|
* @returns {string} Returns the camel cased string.
|
|
* @example
|
|
*
|
|
* _.camelCase('Foo Bar');
|
|
* // => 'fooBar'
|
|
*
|
|
* _.camelCase('--foo-bar--');
|
|
* // => 'fooBar'
|
|
*
|
|
* _.camelCase('__FOO_BAR__');
|
|
* // => 'fooBar'
|
|
*/
|
|
var camelCase = createCompounder(function(result, word, index) {
|
|
word = word.toLowerCase();
|
|
return result + (index ? capitalize(word) : word);
|
|
});
|
|
|
|
/**
|
|
* Converts the first character of `string` to upper case and the remaining
|
|
* to lower case.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to capitalize.
|
|
* @returns {string} Returns the capitalized string.
|
|
* @example
|
|
*
|
|
* _.capitalize('FRED');
|
|
* // => 'Fred'
|
|
*/
|
|
function capitalize(string) {
|
|
return upperFirst(toString(string).toLowerCase());
|
|
}
|
|
|
|
/**
|
|
* Deburrs `string` by converting
|
|
* [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)
|
|
* and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A)
|
|
* letters to basic Latin letters and removing
|
|
* [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to deburr.
|
|
* @returns {string} Returns the deburred string.
|
|
* @example
|
|
*
|
|
* _.deburr('déjà vu');
|
|
* // => 'deja vu'
|
|
*/
|
|
function deburr(string) {
|
|
string = toString(string);
|
|
return string && string.replace(reLatin, deburrLetter).replace(reComboMark, '');
|
|
}
|
|
|
|
/**
|
|
* Checks if `string` ends with the given target string.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to inspect.
|
|
* @param {string} [target] The string to search for.
|
|
* @param {number} [position=string.length] The position to search up to.
|
|
* @returns {boolean} Returns `true` if `string` ends with `target`,
|
|
* else `false`.
|
|
* @example
|
|
*
|
|
* _.endsWith('abc', 'c');
|
|
* // => true
|
|
*
|
|
* _.endsWith('abc', 'b');
|
|
* // => false
|
|
*
|
|
* _.endsWith('abc', 'b', 2);
|
|
* // => true
|
|
*/
|
|
function endsWith(string, target, position) {
|
|
string = toString(string);
|
|
target = baseToString(target);
|
|
|
|
var length = string.length;
|
|
position = position === undefined
|
|
? length
|
|
: baseClamp(toInteger(position), 0, length);
|
|
|
|
var end = position;
|
|
position -= target.length;
|
|
return position >= 0 && string.slice(position, end) == target;
|
|
}
|
|
|
|
/**
|
|
* Converts the characters "&", "<", ">", '"', and "'" in `string` to their
|
|
* corresponding HTML entities.
|
|
*
|
|
* **Note:** No other characters are escaped. To escape additional
|
|
* characters use a third-party library like [_he_](https://mths.be/he).
|
|
*
|
|
* Though the ">" character is escaped for symmetry, characters like
|
|
* ">" and "/" don't need escaping in HTML and have no special meaning
|
|
* unless they're part of a tag or unquoted attribute value. See
|
|
* [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)
|
|
* (under "semi-related fun fact") for more details.
|
|
*
|
|
* When working with HTML you should always
|
|
* [quote attribute values](http://wonko.com/post/html-escaping) to reduce
|
|
* XSS vectors.
|
|
*
|
|
* @static
|
|
* @since 0.1.0
|
|
* @memberOf _
|
|
* @category String
|
|
* @param {string} [string=''] The string to escape.
|
|
* @returns {string} Returns the escaped string.
|
|
* @example
|
|
*
|
|
* _.escape('fred, barney, & pebbles');
|
|
* // => 'fred, barney, & pebbles'
|
|
*/
|
|
function escape(string) {
|
|
string = toString(string);
|
|
return (string && reHasUnescapedHtml.test(string))
|
|
? string.replace(reUnescapedHtml, escapeHtmlChar)
|
|
: string;
|
|
}
|
|
|
|
/**
|
|
* Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+",
|
|
* "?", "(", ")", "[", "]", "{", "}", and "|" in `string`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to escape.
|
|
* @returns {string} Returns the escaped string.
|
|
* @example
|
|
*
|
|
* _.escapeRegExp('[lodash](https://lodash.com/)');
|
|
* // => '\[lodash\]\(https://lodash\.com/\)'
|
|
*/
|
|
function escapeRegExp(string) {
|
|
string = toString(string);
|
|
return (string && reHasRegExpChar.test(string))
|
|
? string.replace(reRegExpChar, '\\$&')
|
|
: string;
|
|
}
|
|
|
|
/**
|
|
* Converts `string` to
|
|
* [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to convert.
|
|
* @returns {string} Returns the kebab cased string.
|
|
* @example
|
|
*
|
|
* _.kebabCase('Foo Bar');
|
|
* // => 'foo-bar'
|
|
*
|
|
* _.kebabCase('fooBar');
|
|
* // => 'foo-bar'
|
|
*
|
|
* _.kebabCase('__FOO_BAR__');
|
|
* // => 'foo-bar'
|
|
*/
|
|
var kebabCase = createCompounder(function(result, word, index) {
|
|
return result + (index ? '-' : '') + word.toLowerCase();
|
|
});
|
|
|
|
/**
|
|
* Converts `string`, as space separated words, to lower case.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to convert.
|
|
* @returns {string} Returns the lower cased string.
|
|
* @example
|
|
*
|
|
* _.lowerCase('--Foo-Bar--');
|
|
* // => 'foo bar'
|
|
*
|
|
* _.lowerCase('fooBar');
|
|
* // => 'foo bar'
|
|
*
|
|
* _.lowerCase('__FOO_BAR__');
|
|
* // => 'foo bar'
|
|
*/
|
|
var lowerCase = createCompounder(function(result, word, index) {
|
|
return result + (index ? ' ' : '') + word.toLowerCase();
|
|
});
|
|
|
|
/**
|
|
* Converts the first character of `string` to lower case.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to convert.
|
|
* @returns {string} Returns the converted string.
|
|
* @example
|
|
*
|
|
* _.lowerFirst('Fred');
|
|
* // => 'fred'
|
|
*
|
|
* _.lowerFirst('FRED');
|
|
* // => 'fRED'
|
|
*/
|
|
var lowerFirst = createCaseFirst('toLowerCase');
|
|
|
|
/**
|
|
* Pads `string` on the left and right sides if it's shorter than `length`.
|
|
* Padding characters are truncated if they can't be evenly divided by `length`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to pad.
|
|
* @param {number} [length=0] The padding length.
|
|
* @param {string} [chars=' '] The string used as padding.
|
|
* @returns {string} Returns the padded string.
|
|
* @example
|
|
*
|
|
* _.pad('abc', 8);
|
|
* // => ' abc '
|
|
*
|
|
* _.pad('abc', 8, '_-');
|
|
* // => '_-abc_-_'
|
|
*
|
|
* _.pad('abc', 3);
|
|
* // => 'abc'
|
|
*/
|
|
function pad(string, length, chars) {
|
|
string = toString(string);
|
|
length = toInteger(length);
|
|
|
|
var strLength = length ? stringSize(string) : 0;
|
|
if (!length || strLength >= length) {
|
|
return string;
|
|
}
|
|
var mid = (length - strLength) / 2;
|
|
return (
|
|
createPadding(nativeFloor(mid), chars) +
|
|
string +
|
|
createPadding(nativeCeil(mid), chars)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Pads `string` on the right side if it's shorter than `length`. Padding
|
|
* characters are truncated if they exceed `length`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to pad.
|
|
* @param {number} [length=0] The padding length.
|
|
* @param {string} [chars=' '] The string used as padding.
|
|
* @returns {string} Returns the padded string.
|
|
* @example
|
|
*
|
|
* _.padEnd('abc', 6);
|
|
* // => 'abc '
|
|
*
|
|
* _.padEnd('abc', 6, '_-');
|
|
* // => 'abc_-_'
|
|
*
|
|
* _.padEnd('abc', 3);
|
|
* // => 'abc'
|
|
*/
|
|
function padEnd(string, length, chars) {
|
|
string = toString(string);
|
|
length = toInteger(length);
|
|
|
|
var strLength = length ? stringSize(string) : 0;
|
|
return (length && strLength < length)
|
|
? (string + createPadding(length - strLength, chars))
|
|
: string;
|
|
}
|
|
|
|
/**
|
|
* Pads `string` on the left side if it's shorter than `length`. Padding
|
|
* characters are truncated if they exceed `length`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to pad.
|
|
* @param {number} [length=0] The padding length.
|
|
* @param {string} [chars=' '] The string used as padding.
|
|
* @returns {string} Returns the padded string.
|
|
* @example
|
|
*
|
|
* _.padStart('abc', 6);
|
|
* // => ' abc'
|
|
*
|
|
* _.padStart('abc', 6, '_-');
|
|
* // => '_-_abc'
|
|
*
|
|
* _.padStart('abc', 3);
|
|
* // => 'abc'
|
|
*/
|
|
function padStart(string, length, chars) {
|
|
string = toString(string);
|
|
length = toInteger(length);
|
|
|
|
var strLength = length ? stringSize(string) : 0;
|
|
return (length && strLength < length)
|
|
? (createPadding(length - strLength, chars) + string)
|
|
: string;
|
|
}
|
|
|
|
/**
|
|
* Converts `string` to an integer of the specified radix. If `radix` is
|
|
* `undefined` or `0`, a `radix` of `10` is used unless `value` is a
|
|
* hexadecimal, in which case a `radix` of `16` is used.
|
|
*
|
|
* **Note:** This method aligns with the
|
|
* [ES5 implementation](https://es5.github.io/#x15.1.2.2) of `parseInt`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 1.1.0
|
|
* @category String
|
|
* @param {string} string The string to convert.
|
|
* @param {number} [radix=10] The radix to interpret `value` by.
|
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
|
* @returns {number} Returns the converted integer.
|
|
* @example
|
|
*
|
|
* _.parseInt('08');
|
|
* // => 8
|
|
*
|
|
* _.map(['6', '08', '10'], _.parseInt);
|
|
* // => [6, 8, 10]
|
|
*/
|
|
function parseInt(string, radix, guard) {
|
|
if (guard || radix == null) {
|
|
radix = 0;
|
|
} else if (radix) {
|
|
radix = +radix;
|
|
}
|
|
return nativeParseInt(toString(string).replace(reTrimStart, ''), radix || 0);
|
|
}
|
|
|
|
/**
|
|
* Repeats the given string `n` times.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to repeat.
|
|
* @param {number} [n=1] The number of times to repeat the string.
|
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
|
* @returns {string} Returns the repeated string.
|
|
* @example
|
|
*
|
|
* _.repeat('*', 3);
|
|
* // => '***'
|
|
*
|
|
* _.repeat('abc', 2);
|
|
* // => 'abcabc'
|
|
*
|
|
* _.repeat('abc', 0);
|
|
* // => ''
|
|
*/
|
|
function repeat(string, n, guard) {
|
|
if ((guard ? isIterateeCall(string, n, guard) : n === undefined)) {
|
|
n = 1;
|
|
} else {
|
|
n = toInteger(n);
|
|
}
|
|
return baseRepeat(toString(string), n);
|
|
}
|
|
|
|
/**
|
|
* Replaces matches for `pattern` in `string` with `replacement`.
|
|
*
|
|
* **Note:** This method is based on
|
|
* [`String#replace`](https://mdn.io/String/replace).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to modify.
|
|
* @param {RegExp|string} pattern The pattern to replace.
|
|
* @param {Function|string} replacement The match replacement.
|
|
* @returns {string} Returns the modified string.
|
|
* @example
|
|
*
|
|
* _.replace('Hi Fred', 'Fred', 'Barney');
|
|
* // => 'Hi Barney'
|
|
*/
|
|
function replace() {
|
|
var args = arguments,
|
|
string = toString(args[0]);
|
|
|
|
return args.length < 3 ? string : string.replace(args[1], args[2]);
|
|
}
|
|
|
|
/**
|
|
* Converts `string` to
|
|
* [snake case](https://en.wikipedia.org/wiki/Snake_case).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to convert.
|
|
* @returns {string} Returns the snake cased string.
|
|
* @example
|
|
*
|
|
* _.snakeCase('Foo Bar');
|
|
* // => 'foo_bar'
|
|
*
|
|
* _.snakeCase('fooBar');
|
|
* // => 'foo_bar'
|
|
*
|
|
* _.snakeCase('--FOO-BAR--');
|
|
* // => 'foo_bar'
|
|
*/
|
|
var snakeCase = createCompounder(function(result, word, index) {
|
|
return result + (index ? '_' : '') + word.toLowerCase();
|
|
});
|
|
|
|
/**
|
|
* Splits `string` by `separator`.
|
|
*
|
|
* **Note:** This method is based on
|
|
* [`String#split`](https://mdn.io/String/split).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to split.
|
|
* @param {RegExp|string} separator The separator pattern to split by.
|
|
* @param {number} [limit] The length to truncate results to.
|
|
* @returns {Array} Returns the string segments.
|
|
* @example
|
|
*
|
|
* _.split('a-b-c', '-', 2);
|
|
* // => ['a', 'b']
|
|
*/
|
|
function split(string, separator, limit) {
|
|
if (limit && typeof limit != 'number' && isIterateeCall(string, separator, limit)) {
|
|
separator = limit = undefined;
|
|
}
|
|
limit = limit === undefined ? MAX_ARRAY_LENGTH : limit >>> 0;
|
|
if (!limit) {
|
|
return [];
|
|
}
|
|
string = toString(string);
|
|
if (string && (
|
|
typeof separator == 'string' ||
|
|
(separator != null && !isRegExp(separator))
|
|
)) {
|
|
separator = baseToString(separator);
|
|
if (!separator && hasUnicode(string)) {
|
|
return castSlice(stringToArray(string), 0, limit);
|
|
}
|
|
}
|
|
return string.split(separator, limit);
|
|
}
|
|
|
|
/**
|
|
* Converts `string` to
|
|
* [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.1.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to convert.
|
|
* @returns {string} Returns the start cased string.
|
|
* @example
|
|
*
|
|
* _.startCase('--foo-bar--');
|
|
* // => 'Foo Bar'
|
|
*
|
|
* _.startCase('fooBar');
|
|
* // => 'Foo Bar'
|
|
*
|
|
* _.startCase('__FOO_BAR__');
|
|
* // => 'FOO BAR'
|
|
*/
|
|
var startCase = createCompounder(function(result, word, index) {
|
|
return result + (index ? ' ' : '') + upperFirst(word);
|
|
});
|
|
|
|
/**
|
|
* Checks if `string` starts with the given target string.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to inspect.
|
|
* @param {string} [target] The string to search for.
|
|
* @param {number} [position=0] The position to search from.
|
|
* @returns {boolean} Returns `true` if `string` starts with `target`,
|
|
* else `false`.
|
|
* @example
|
|
*
|
|
* _.startsWith('abc', 'a');
|
|
* // => true
|
|
*
|
|
* _.startsWith('abc', 'b');
|
|
* // => false
|
|
*
|
|
* _.startsWith('abc', 'b', 1);
|
|
* // => true
|
|
*/
|
|
function startsWith(string, target, position) {
|
|
string = toString(string);
|
|
position = position == null
|
|
? 0
|
|
: baseClamp(toInteger(position), 0, string.length);
|
|
|
|
target = baseToString(target);
|
|
return string.slice(position, position + target.length) == target;
|
|
}
|
|
|
|
/**
|
|
* Creates a compiled template function that can interpolate data properties
|
|
* in "interpolate" delimiters, HTML-escape interpolated data properties in
|
|
* "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data
|
|
* properties may be accessed as free variables in the template. If a setting
|
|
* object is given, it takes precedence over `_.templateSettings` values.
|
|
*
|
|
* **Note:** In the development build `_.template` utilizes
|
|
* [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)
|
|
* for easier debugging.
|
|
*
|
|
* For more information on precompiling templates see
|
|
* [lodash's custom builds documentation](https://lodash.com/custom-builds).
|
|
*
|
|
* For more information on Chrome extension sandboxes see
|
|
* [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval).
|
|
*
|
|
* @static
|
|
* @since 0.1.0
|
|
* @memberOf _
|
|
* @category String
|
|
* @param {string} [string=''] The template string.
|
|
* @param {Object} [options={}] The options object.
|
|
* @param {RegExp} [options.escape=_.templateSettings.escape]
|
|
* The HTML "escape" delimiter.
|
|
* @param {RegExp} [options.evaluate=_.templateSettings.evaluate]
|
|
* The "evaluate" delimiter.
|
|
* @param {Object} [options.imports=_.templateSettings.imports]
|
|
* An object to import into the template as free variables.
|
|
* @param {RegExp} [options.interpolate=_.templateSettings.interpolate]
|
|
* The "interpolate" delimiter.
|
|
* @param {string} [options.sourceURL='lodash.templateSources[n]']
|
|
* The sourceURL of the compiled template.
|
|
* @param {string} [options.variable='obj']
|
|
* The data object variable name.
|
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
|
* @returns {Function} Returns the compiled template function.
|
|
* @example
|
|
*
|
|
* // Use the "interpolate" delimiter to create a compiled template.
|
|
* var compiled = _.template('hello <%= user %>!');
|
|
* compiled({ 'user': 'fred' });
|
|
* // => 'hello fred!'
|
|
*
|
|
* // Use the HTML "escape" delimiter to escape data property values.
|
|
* var compiled = _.template('<b><%- value %></b>');
|
|
* compiled({ 'value': '<script>' });
|
|
* // => '<b><script></b>'
|
|
*
|
|
* // Use the "evaluate" delimiter to execute JavaScript and generate HTML.
|
|
* var compiled = _.template('<% _.forEach(users, function(user) { %><li><%- user %></li><% }); %>');
|
|
* compiled({ 'users': ['fred', 'barney'] });
|
|
* // => '<li>fred</li><li>barney</li>'
|
|
*
|
|
* // Use the internal `print` function in "evaluate" delimiters.
|
|
* var compiled = _.template('<% print("hello " + user); %>!');
|
|
* compiled({ 'user': 'barney' });
|
|
* // => 'hello barney!'
|
|
*
|
|
* // Use the ES template literal delimiter as an "interpolate" delimiter.
|
|
* // Disable support by replacing the "interpolate" delimiter.
|
|
* var compiled = _.template('hello ${ user }!');
|
|
* compiled({ 'user': 'pebbles' });
|
|
* // => 'hello pebbles!'
|
|
*
|
|
* // Use backslashes to treat delimiters as plain text.
|
|
* var compiled = _.template('<%= "\\<%- value %\\>" %>');
|
|
* compiled({ 'value': 'ignored' });
|
|
* // => '<%- value %>'
|
|
*
|
|
* // Use the `imports` option to import `jQuery` as `jq`.
|
|
* var text = '<% jq.each(users, function(user) { %><li><%- user %></li><% }); %>';
|
|
* var compiled = _.template(text, { 'imports': { 'jq': jQuery } });
|
|
* compiled({ 'users': ['fred', 'barney'] });
|
|
* // => '<li>fred</li><li>barney</li>'
|
|
*
|
|
* // Use the `sourceURL` option to specify a custom sourceURL for the template.
|
|
* var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' });
|
|
* compiled(data);
|
|
* // => Find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector.
|
|
*
|
|
* // Use the `variable` option to ensure a with-statement isn't used in the compiled template.
|
|
* var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' });
|
|
* compiled.source;
|
|
* // => function(data) {
|
|
* // var __t, __p = '';
|
|
* // __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!';
|
|
* // return __p;
|
|
* // }
|
|
*
|
|
* // Use custom template delimiters.
|
|
* _.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
|
|
* var compiled = _.template('hello {{ user }}!');
|
|
* compiled({ 'user': 'mustache' });
|
|
* // => 'hello mustache!'
|
|
*
|
|
* // Use the `source` property to inline compiled templates for meaningful
|
|
* // line numbers in error messages and stack traces.
|
|
* fs.writeFileSync(path.join(process.cwd(), 'jst.js'), '\
|
|
* var JST = {\
|
|
* "main": ' + _.template(mainText).source + '\
|
|
* };\
|
|
* ');
|
|
*/
|
|
function template(string, options, guard) {
|
|
// Based on John Resig's `tmpl` implementation
|
|
// (http://ejohn.org/blog/javascript-micro-templating/)
|
|
// and Laura Doktorova's doT.js (https://github.com/olado/doT).
|
|
var settings = lodash.templateSettings;
|
|
|
|
if (guard && isIterateeCall(string, options, guard)) {
|
|
options = undefined;
|
|
}
|
|
string = toString(string);
|
|
options = assignInWith({}, options, settings, customDefaultsAssignIn);
|
|
|
|
var imports = assignInWith({}, options.imports, settings.imports, customDefaultsAssignIn),
|
|
importsKeys = keys(imports),
|
|
importsValues = baseValues(imports, importsKeys);
|
|
|
|
var isEscaping,
|
|
isEvaluating,
|
|
index = 0,
|
|
interpolate = options.interpolate || reNoMatch,
|
|
source = "__p += '";
|
|
|
|
// Compile the regexp to match each delimiter.
|
|
var reDelimiters = RegExp(
|
|
(options.escape || reNoMatch).source + '|' +
|
|
interpolate.source + '|' +
|
|
(interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
|
|
(options.evaluate || reNoMatch).source + '|$'
|
|
, 'g');
|
|
|
|
// Use a sourceURL for easier debugging.
|
|
// The sourceURL gets injected into the source that's eval-ed, so be careful
|
|
// to normalize all kinds of whitespace, so e.g. newlines (and unicode versions of it) can't sneak in
|
|
// and escape the comment, thus injecting code that gets evaled.
|
|
var sourceURL = '//# sourceURL=' +
|
|
(hasOwnProperty.call(options, 'sourceURL')
|
|
? (options.sourceURL + '').replace(/\s/g, ' ')
|
|
: ('lodash.templateSources[' + (++templateCounter) + ']')
|
|
) + '\n';
|
|
|
|
string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
|
|
interpolateValue || (interpolateValue = esTemplateValue);
|
|
|
|
// Escape characters that can't be included in string literals.
|
|
source += string.slice(index, offset).replace(reUnescapedString, escapeStringChar);
|
|
|
|
// Replace delimiters with snippets.
|
|
if (escapeValue) {
|
|
isEscaping = true;
|
|
source += "' +\n__e(" + escapeValue + ") +\n'";
|
|
}
|
|
if (evaluateValue) {
|
|
isEvaluating = true;
|
|
source += "';\n" + evaluateValue + ";\n__p += '";
|
|
}
|
|
if (interpolateValue) {
|
|
source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
|
|
}
|
|
index = offset + match.length;
|
|
|
|
// The JS engine embedded in Adobe products needs `match` returned in
|
|
// order to produce the correct `offset` value.
|
|
return match;
|
|
});
|
|
|
|
source += "';\n";
|
|
|
|
// If `variable` is not specified wrap a with-statement around the generated
|
|
// code to add the data object to the top of the scope chain.
|
|
var variable = hasOwnProperty.call(options, 'variable') && options.variable;
|
|
if (!variable) {
|
|
source = 'with (obj) {\n' + source + '\n}\n';
|
|
}
|
|
// Throw an error if a forbidden character was found in `variable`, to prevent
|
|
// potential command injection attacks.
|
|
else if (reForbiddenIdentifierChars.test(variable)) {
|
|
throw new Error(INVALID_TEMPL_VAR_ERROR_TEXT);
|
|
}
|
|
|
|
// Cleanup code by stripping empty strings.
|
|
source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
|
|
.replace(reEmptyStringMiddle, '$1')
|
|
.replace(reEmptyStringTrailing, '$1;');
|
|
|
|
// Frame code as the function body.
|
|
source = 'function(' + (variable || 'obj') + ') {\n' +
|
|
(variable
|
|
? ''
|
|
: 'obj || (obj = {});\n'
|
|
) +
|
|
"var __t, __p = ''" +
|
|
(isEscaping
|
|
? ', __e = _.escape'
|
|
: ''
|
|
) +
|
|
(isEvaluating
|
|
? ', __j = Array.prototype.join;\n' +
|
|
"function print() { __p += __j.call(arguments, '') }\n"
|
|
: ';\n'
|
|
) +
|
|
source +
|
|
'return __p\n}';
|
|
|
|
var result = attempt(function() {
|
|
return Function(importsKeys, sourceURL + 'return ' + source)
|
|
.apply(undefined, importsValues);
|
|
});
|
|
|
|
// Provide the compiled function's source by its `toString` method or
|
|
// the `source` property as a convenience for inlining compiled templates.
|
|
result.source = source;
|
|
if (isError(result)) {
|
|
throw result;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Converts `string`, as a whole, to lower case just like
|
|
* [String#toLowerCase](https://mdn.io/toLowerCase).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to convert.
|
|
* @returns {string} Returns the lower cased string.
|
|
* @example
|
|
*
|
|
* _.toLower('--Foo-Bar--');
|
|
* // => '--foo-bar--'
|
|
*
|
|
* _.toLower('fooBar');
|
|
* // => 'foobar'
|
|
*
|
|
* _.toLower('__FOO_BAR__');
|
|
* // => '__foo_bar__'
|
|
*/
|
|
function toLower(value) {
|
|
return toString(value).toLowerCase();
|
|
}
|
|
|
|
/**
|
|
* Converts `string`, as a whole, to upper case just like
|
|
* [String#toUpperCase](https://mdn.io/toUpperCase).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to convert.
|
|
* @returns {string} Returns the upper cased string.
|
|
* @example
|
|
*
|
|
* _.toUpper('--foo-bar--');
|
|
* // => '--FOO-BAR--'
|
|
*
|
|
* _.toUpper('fooBar');
|
|
* // => 'FOOBAR'
|
|
*
|
|
* _.toUpper('__foo_bar__');
|
|
* // => '__FOO_BAR__'
|
|
*/
|
|
function toUpper(value) {
|
|
return toString(value).toUpperCase();
|
|
}
|
|
|
|
/**
|
|
* Removes leading and trailing whitespace or specified characters from `string`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to trim.
|
|
* @param {string} [chars=whitespace] The characters to trim.
|
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
|
* @returns {string} Returns the trimmed string.
|
|
* @example
|
|
*
|
|
* _.trim(' abc ');
|
|
* // => 'abc'
|
|
*
|
|
* _.trim('-_-abc-_-', '_-');
|
|
* // => 'abc'
|
|
*
|
|
* _.map([' foo ', ' bar '], _.trim);
|
|
* // => ['foo', 'bar']
|
|
*/
|
|
function trim(string, chars, guard) {
|
|
string = toString(string);
|
|
if (string && (guard || chars === undefined)) {
|
|
return baseTrim(string);
|
|
}
|
|
if (!string || !(chars = baseToString(chars))) {
|
|
return string;
|
|
}
|
|
var strSymbols = stringToArray(string),
|
|
chrSymbols = stringToArray(chars),
|
|
start = charsStartIndex(strSymbols, chrSymbols),
|
|
end = charsEndIndex(strSymbols, chrSymbols) + 1;
|
|
|
|
return castSlice(strSymbols, start, end).join('');
|
|
}
|
|
|
|
/**
|
|
* Removes trailing whitespace or specified characters from `string`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to trim.
|
|
* @param {string} [chars=whitespace] The characters to trim.
|
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
|
* @returns {string} Returns the trimmed string.
|
|
* @example
|
|
*
|
|
* _.trimEnd(' abc ');
|
|
* // => ' abc'
|
|
*
|
|
* _.trimEnd('-_-abc-_-', '_-');
|
|
* // => '-_-abc'
|
|
*/
|
|
function trimEnd(string, chars, guard) {
|
|
string = toString(string);
|
|
if (string && (guard || chars === undefined)) {
|
|
return string.slice(0, trimmedEndIndex(string) + 1);
|
|
}
|
|
if (!string || !(chars = baseToString(chars))) {
|
|
return string;
|
|
}
|
|
var strSymbols = stringToArray(string),
|
|
end = charsEndIndex(strSymbols, stringToArray(chars)) + 1;
|
|
|
|
return castSlice(strSymbols, 0, end).join('');
|
|
}
|
|
|
|
/**
|
|
* Removes leading whitespace or specified characters from `string`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to trim.
|
|
* @param {string} [chars=whitespace] The characters to trim.
|
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
|
* @returns {string} Returns the trimmed string.
|
|
* @example
|
|
*
|
|
* _.trimStart(' abc ');
|
|
* // => 'abc '
|
|
*
|
|
* _.trimStart('-_-abc-_-', '_-');
|
|
* // => 'abc-_-'
|
|
*/
|
|
function trimStart(string, chars, guard) {
|
|
string = toString(string);
|
|
if (string && (guard || chars === undefined)) {
|
|
return string.replace(reTrimStart, '');
|
|
}
|
|
if (!string || !(chars = baseToString(chars))) {
|
|
return string;
|
|
}
|
|
var strSymbols = stringToArray(string),
|
|
start = charsStartIndex(strSymbols, stringToArray(chars));
|
|
|
|
return castSlice(strSymbols, start).join('');
|
|
}
|
|
|
|
/**
|
|
* Truncates `string` if it's longer than the given maximum string length.
|
|
* The last characters of the truncated string are replaced with the omission
|
|
* string which defaults to "...".
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to truncate.
|
|
* @param {Object} [options={}] The options object.
|
|
* @param {number} [options.length=30] The maximum string length.
|
|
* @param {string} [options.omission='...'] The string to indicate text is omitted.
|
|
* @param {RegExp|string} [options.separator] The separator pattern to truncate to.
|
|
* @returns {string} Returns the truncated string.
|
|
* @example
|
|
*
|
|
* _.truncate('hi-diddly-ho there, neighborino');
|
|
* // => 'hi-diddly-ho there, neighbo...'
|
|
*
|
|
* _.truncate('hi-diddly-ho there, neighborino', {
|
|
* 'length': 24,
|
|
* 'separator': ' '
|
|
* });
|
|
* // => 'hi-diddly-ho there,...'
|
|
*
|
|
* _.truncate('hi-diddly-ho there, neighborino', {
|
|
* 'length': 24,
|
|
* 'separator': /,? +/
|
|
* });
|
|
* // => 'hi-diddly-ho there...'
|
|
*
|
|
* _.truncate('hi-diddly-ho there, neighborino', {
|
|
* 'omission': ' [...]'
|
|
* });
|
|
* // => 'hi-diddly-ho there, neig [...]'
|
|
*/
|
|
function truncate(string, options) {
|
|
var length = DEFAULT_TRUNC_LENGTH,
|
|
omission = DEFAULT_TRUNC_OMISSION;
|
|
|
|
if (isObject(options)) {
|
|
var separator = 'separator' in options ? options.separator : separator;
|
|
length = 'length' in options ? toInteger(options.length) : length;
|
|
omission = 'omission' in options ? baseToString(options.omission) : omission;
|
|
}
|
|
string = toString(string);
|
|
|
|
var strLength = string.length;
|
|
if (hasUnicode(string)) {
|
|
var strSymbols = stringToArray(string);
|
|
strLength = strSymbols.length;
|
|
}
|
|
if (length >= strLength) {
|
|
return string;
|
|
}
|
|
var end = length - stringSize(omission);
|
|
if (end < 1) {
|
|
return omission;
|
|
}
|
|
var result = strSymbols
|
|
? castSlice(strSymbols, 0, end).join('')
|
|
: string.slice(0, end);
|
|
|
|
if (separator === undefined) {
|
|
return result + omission;
|
|
}
|
|
if (strSymbols) {
|
|
end += (result.length - end);
|
|
}
|
|
if (isRegExp(separator)) {
|
|
if (string.slice(end).search(separator)) {
|
|
var match,
|
|
substring = result;
|
|
|
|
if (!separator.global) {
|
|
separator = RegExp(separator.source, toString(reFlags.exec(separator)) + 'g');
|
|
}
|
|
separator.lastIndex = 0;
|
|
while ((match = separator.exec(substring))) {
|
|
var newEnd = match.index;
|
|
}
|
|
result = result.slice(0, newEnd === undefined ? end : newEnd);
|
|
}
|
|
} else if (string.indexOf(baseToString(separator), end) != end) {
|
|
var index = result.lastIndexOf(separator);
|
|
if (index > -1) {
|
|
result = result.slice(0, index);
|
|
}
|
|
}
|
|
return result + omission;
|
|
}
|
|
|
|
/**
|
|
* The inverse of `_.escape`; this method converts the HTML entities
|
|
* `&`, `<`, `>`, `"`, and `'` in `string` to
|
|
* their corresponding characters.
|
|
*
|
|
* **Note:** No other HTML entities are unescaped. To unescape additional
|
|
* HTML entities use a third-party library like [_he_](https://mths.be/he).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 0.6.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to unescape.
|
|
* @returns {string} Returns the unescaped string.
|
|
* @example
|
|
*
|
|
* _.unescape('fred, barney, & pebbles');
|
|
* // => 'fred, barney, & pebbles'
|
|
*/
|
|
function unescape(string) {
|
|
string = toString(string);
|
|
return (string && reHasEscapedHtml.test(string))
|
|
? string.replace(reEscapedHtml, unescapeHtmlChar)
|
|
: string;
|
|
}
|
|
|
|
/**
|
|
* Converts `string`, as space separated words, to upper case.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to convert.
|
|
* @returns {string} Returns the upper cased string.
|
|
* @example
|
|
*
|
|
* _.upperCase('--foo-bar');
|
|
* // => 'FOO BAR'
|
|
*
|
|
* _.upperCase('fooBar');
|
|
* // => 'FOO BAR'
|
|
*
|
|
* _.upperCase('__foo_bar__');
|
|
* // => 'FOO BAR'
|
|
*/
|
|
var upperCase = createCompounder(function(result, word, index) {
|
|
return result + (index ? ' ' : '') + word.toUpperCase();
|
|
});
|
|
|
|
/**
|
|
* Converts the first character of `string` to upper case.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to convert.
|
|
* @returns {string} Returns the converted string.
|
|
* @example
|
|
*
|
|
* _.upperFirst('fred');
|
|
* // => 'Fred'
|
|
*
|
|
* _.upperFirst('FRED');
|
|
* // => 'FRED'
|
|
*/
|
|
var upperFirst = createCaseFirst('toUpperCase');
|
|
|
|
/**
|
|
* Splits `string` into an array of its words.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category String
|
|
* @param {string} [string=''] The string to inspect.
|
|
* @param {RegExp|string} [pattern] The pattern to match words.
|
|
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
|
|
* @returns {Array} Returns the words of `string`.
|
|
* @example
|
|
*
|
|
* _.words('fred, barney, & pebbles');
|
|
* // => ['fred', 'barney', 'pebbles']
|
|
*
|
|
* _.words('fred, barney, & pebbles', /[^, ]+/g);
|
|
* // => ['fred', 'barney', '&', 'pebbles']
|
|
*/
|
|
function words(string, pattern, guard) {
|
|
string = toString(string);
|
|
pattern = guard ? undefined : pattern;
|
|
|
|
if (pattern === undefined) {
|
|
return hasUnicodeWord(string) ? unicodeWords(string) : asciiWords(string);
|
|
}
|
|
return string.match(pattern) || [];
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* Attempts to invoke `func`, returning either the result or the caught error
|
|
* object. Any additional arguments are provided to `func` when it's invoked.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Util
|
|
* @param {Function} func The function to attempt.
|
|
* @param {...*} [args] The arguments to invoke `func` with.
|
|
* @returns {*} Returns the `func` result or error object.
|
|
* @example
|
|
*
|
|
* // Avoid throwing errors for invalid selectors.
|
|
* var elements = _.attempt(function(selector) {
|
|
* return document.querySelectorAll(selector);
|
|
* }, '>_>');
|
|
*
|
|
* if (_.isError(elements)) {
|
|
* elements = [];
|
|
* }
|
|
*/
|
|
var attempt = baseRest(function(func, args) {
|
|
try {
|
|
return apply(func, undefined, args);
|
|
} catch (e) {
|
|
return isError(e) ? e : new Error(e);
|
|
}
|
|
});
|
|
|
|
/**
|
|
* Binds methods of an object to the object itself, overwriting the existing
|
|
* method.
|
|
*
|
|
* **Note:** This method doesn't set the "length" property of bound functions.
|
|
*
|
|
* @static
|
|
* @since 0.1.0
|
|
* @memberOf _
|
|
* @category Util
|
|
* @param {Object} object The object to bind and assign the bound methods to.
|
|
* @param {...(string|string[])} methodNames The object method names to bind.
|
|
* @returns {Object} Returns `object`.
|
|
* @example
|
|
*
|
|
* var view = {
|
|
* 'label': 'docs',
|
|
* 'click': function() {
|
|
* console.log('clicked ' + this.label);
|
|
* }
|
|
* };
|
|
*
|
|
* _.bindAll(view, ['click']);
|
|
* jQuery(element).on('click', view.click);
|
|
* // => Logs 'clicked docs' when clicked.
|
|
*/
|
|
var bindAll = flatRest(function(object, methodNames) {
|
|
arrayEach(methodNames, function(key) {
|
|
key = toKey(key);
|
|
baseAssignValue(object, key, bind(object[key], object));
|
|
});
|
|
return object;
|
|
});
|
|
|
|
/**
|
|
* Creates a function that iterates over `pairs` and invokes the corresponding
|
|
* function of the first predicate to return truthy. The predicate-function
|
|
* pairs are invoked with the `this` binding and arguments of the created
|
|
* function.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Util
|
|
* @param {Array} pairs The predicate-function pairs.
|
|
* @returns {Function} Returns the new composite function.
|
|
* @example
|
|
*
|
|
* var func = _.cond([
|
|
* [_.matches({ 'a': 1 }), _.constant('matches A')],
|
|
* [_.conforms({ 'b': _.isNumber }), _.constant('matches B')],
|
|
* [_.stubTrue, _.constant('no match')]
|
|
* ]);
|
|
*
|
|
* func({ 'a': 1, 'b': 2 });
|
|
* // => 'matches A'
|
|
*
|
|
* func({ 'a': 0, 'b': 1 });
|
|
* // => 'matches B'
|
|
*
|
|
* func({ 'a': '1', 'b': '2' });
|
|
* // => 'no match'
|
|
*/
|
|
function cond(pairs) {
|
|
var length = pairs == null ? 0 : pairs.length,
|
|
toIteratee = getIteratee();
|
|
|
|
pairs = !length ? [] : arrayMap(pairs, function(pair) {
|
|
if (typeof pair[1] != 'function') {
|
|
throw new TypeError(FUNC_ERROR_TEXT);
|
|
}
|
|
return [toIteratee(pair[0]), pair[1]];
|
|
});
|
|
|
|
return baseRest(function(args) {
|
|
var index = -1;
|
|
while (++index < length) {
|
|
var pair = pairs[index];
|
|
if (apply(pair[0], this, args)) {
|
|
return apply(pair[1], this, args);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Creates a function that invokes the predicate properties of `source` with
|
|
* the corresponding property values of a given object, returning `true` if
|
|
* all predicates return truthy, else `false`.
|
|
*
|
|
* **Note:** The created function is equivalent to `_.conformsTo` with
|
|
* `source` partially applied.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Util
|
|
* @param {Object} source The object of property predicates to conform to.
|
|
* @returns {Function} Returns the new spec function.
|
|
* @example
|
|
*
|
|
* var objects = [
|
|
* { 'a': 2, 'b': 1 },
|
|
* { 'a': 1, 'b': 2 }
|
|
* ];
|
|
*
|
|
* _.filter(objects, _.conforms({ 'b': function(n) { return n > 1; } }));
|
|
* // => [{ 'a': 1, 'b': 2 }]
|
|
*/
|
|
function conforms(source) {
|
|
return baseConforms(baseClone(source, CLONE_DEEP_FLAG));
|
|
}
|
|
|
|
/**
|
|
* Creates a function that returns `value`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 2.4.0
|
|
* @category Util
|
|
* @param {*} value The value to return from the new function.
|
|
* @returns {Function} Returns the new constant function.
|
|
* @example
|
|
*
|
|
* var objects = _.times(2, _.constant({ 'a': 1 }));
|
|
*
|
|
* console.log(objects);
|
|
* // => [{ 'a': 1 }, { 'a': 1 }]
|
|
*
|
|
* console.log(objects[0] === objects[1]);
|
|
* // => true
|
|
*/
|
|
function constant(value) {
|
|
return function() {
|
|
return value;
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Checks `value` to determine whether a default value should be returned in
|
|
* its place. The `defaultValue` is returned if `value` is `NaN`, `null`,
|
|
* or `undefined`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.14.0
|
|
* @category Util
|
|
* @param {*} value The value to check.
|
|
* @param {*} defaultValue The default value.
|
|
* @returns {*} Returns the resolved value.
|
|
* @example
|
|
*
|
|
* _.defaultTo(1, 10);
|
|
* // => 1
|
|
*
|
|
* _.defaultTo(undefined, 10);
|
|
* // => 10
|
|
*/
|
|
function defaultTo(value, defaultValue) {
|
|
return (value == null || value !== value) ? defaultValue : value;
|
|
}
|
|
|
|
/**
|
|
* Creates a function that returns the result of invoking the given functions
|
|
* with the `this` binding of the created function, where each successive
|
|
* invocation is supplied the return value of the previous.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Util
|
|
* @param {...(Function|Function[])} [funcs] The functions to invoke.
|
|
* @returns {Function} Returns the new composite function.
|
|
* @see _.flowRight
|
|
* @example
|
|
*
|
|
* function square(n) {
|
|
* return n * n;
|
|
* }
|
|
*
|
|
* var addSquare = _.flow([_.add, square]);
|
|
* addSquare(1, 2);
|
|
* // => 9
|
|
*/
|
|
var flow = createFlow();
|
|
|
|
/**
|
|
* This method is like `_.flow` except that it creates a function that
|
|
* invokes the given functions from right to left.
|
|
*
|
|
* @static
|
|
* @since 3.0.0
|
|
* @memberOf _
|
|
* @category Util
|
|
* @param {...(Function|Function[])} [funcs] The functions to invoke.
|
|
* @returns {Function} Returns the new composite function.
|
|
* @see _.flow
|
|
* @example
|
|
*
|
|
* function square(n) {
|
|
* return n * n;
|
|
* }
|
|
*
|
|
* var addSquare = _.flowRight([square, _.add]);
|
|
* addSquare(1, 2);
|
|
* // => 9
|
|
*/
|
|
var flowRight = createFlow(true);
|
|
|
|
/**
|
|
* This method returns the first argument it receives.
|
|
*
|
|
* @static
|
|
* @since 0.1.0
|
|
* @memberOf _
|
|
* @category Util
|
|
* @param {*} value Any value.
|
|
* @returns {*} Returns `value`.
|
|
* @example
|
|
*
|
|
* var object = { 'a': 1 };
|
|
*
|
|
* console.log(_.identity(object) === object);
|
|
* // => true
|
|
*/
|
|
function identity(value) {
|
|
return value;
|
|
}
|
|
|
|
/**
|
|
* Creates a function that invokes `func` with the arguments of the created
|
|
* function. If `func` is a property name, the created function returns the
|
|
* property value for a given element. If `func` is an array or object, the
|
|
* created function returns `true` for elements that contain the equivalent
|
|
* source properties, otherwise it returns `false`.
|
|
*
|
|
* @static
|
|
* @since 4.0.0
|
|
* @memberOf _
|
|
* @category Util
|
|
* @param {*} [func=_.identity] The value to convert to a callback.
|
|
* @returns {Function} Returns the callback.
|
|
* @example
|
|
*
|
|
* var users = [
|
|
* { 'user': 'barney', 'age': 36, 'active': true },
|
|
* { 'user': 'fred', 'age': 40, 'active': false }
|
|
* ];
|
|
*
|
|
* // The `_.matches` iteratee shorthand.
|
|
* _.filter(users, _.iteratee({ 'user': 'barney', 'active': true }));
|
|
* // => [{ 'user': 'barney', 'age': 36, 'active': true }]
|
|
*
|
|
* // The `_.matchesProperty` iteratee shorthand.
|
|
* _.filter(users, _.iteratee(['user', 'fred']));
|
|
* // => [{ 'user': 'fred', 'age': 40 }]
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.map(users, _.iteratee('user'));
|
|
* // => ['barney', 'fred']
|
|
*
|
|
* // Create custom iteratee shorthands.
|
|
* _.iteratee = _.wrap(_.iteratee, function(iteratee, func) {
|
|
* return !_.isRegExp(func) ? iteratee(func) : function(string) {
|
|
* return func.test(string);
|
|
* };
|
|
* });
|
|
*
|
|
* _.filter(['abc', 'def'], /ef/);
|
|
* // => ['def']
|
|
*/
|
|
function iteratee(func) {
|
|
return baseIteratee(typeof func == 'function' ? func : baseClone(func, CLONE_DEEP_FLAG));
|
|
}
|
|
|
|
/**
|
|
* Creates a function that performs a partial deep comparison between a given
|
|
* object and `source`, returning `true` if the given object has equivalent
|
|
* property values, else `false`.
|
|
*
|
|
* **Note:** The created function is equivalent to `_.isMatch` with `source`
|
|
* partially applied.
|
|
*
|
|
* Partial comparisons will match empty array and empty object `source`
|
|
* values against any array or object value, respectively. See `_.isEqual`
|
|
* for a list of supported value comparisons.
|
|
*
|
|
* **Note:** Multiple values can be checked by combining several matchers
|
|
* using `_.overSome`
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Util
|
|
* @param {Object} source The object of property values to match.
|
|
* @returns {Function} Returns the new spec function.
|
|
* @example
|
|
*
|
|
* var objects = [
|
|
* { 'a': 1, 'b': 2, 'c': 3 },
|
|
* { 'a': 4, 'b': 5, 'c': 6 }
|
|
* ];
|
|
*
|
|
* _.filter(objects, _.matches({ 'a': 4, 'c': 6 }));
|
|
* // => [{ 'a': 4, 'b': 5, 'c': 6 }]
|
|
*
|
|
* // Checking for several possible values
|
|
* _.filter(objects, _.overSome([_.matches({ 'a': 1 }), _.matches({ 'a': 4 })]));
|
|
* // => [{ 'a': 1, 'b': 2, 'c': 3 }, { 'a': 4, 'b': 5, 'c': 6 }]
|
|
*/
|
|
function matches(source) {
|
|
return baseMatches(baseClone(source, CLONE_DEEP_FLAG));
|
|
}
|
|
|
|
/**
|
|
* Creates a function that performs a partial deep comparison between the
|
|
* value at `path` of a given object to `srcValue`, returning `true` if the
|
|
* object value is equivalent, else `false`.
|
|
*
|
|
* **Note:** Partial comparisons will match empty array and empty object
|
|
* `srcValue` values against any array or object value, respectively. See
|
|
* `_.isEqual` for a list of supported value comparisons.
|
|
*
|
|
* **Note:** Multiple values can be checked by combining several matchers
|
|
* using `_.overSome`
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.2.0
|
|
* @category Util
|
|
* @param {Array|string} path The path of the property to get.
|
|
* @param {*} srcValue The value to match.
|
|
* @returns {Function} Returns the new spec function.
|
|
* @example
|
|
*
|
|
* var objects = [
|
|
* { 'a': 1, 'b': 2, 'c': 3 },
|
|
* { 'a': 4, 'b': 5, 'c': 6 }
|
|
* ];
|
|
*
|
|
* _.find(objects, _.matchesProperty('a', 4));
|
|
* // => { 'a': 4, 'b': 5, 'c': 6 }
|
|
*
|
|
* // Checking for several possible values
|
|
* _.filter(objects, _.overSome([_.matchesProperty('a', 1), _.matchesProperty('a', 4)]));
|
|
* // => [{ 'a': 1, 'b': 2, 'c': 3 }, { 'a': 4, 'b': 5, 'c': 6 }]
|
|
*/
|
|
function matchesProperty(path, srcValue) {
|
|
return baseMatchesProperty(path, baseClone(srcValue, CLONE_DEEP_FLAG));
|
|
}
|
|
|
|
/**
|
|
* Creates a function that invokes the method at `path` of a given object.
|
|
* Any additional arguments are provided to the invoked method.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.7.0
|
|
* @category Util
|
|
* @param {Array|string} path The path of the method to invoke.
|
|
* @param {...*} [args] The arguments to invoke the method with.
|
|
* @returns {Function} Returns the new invoker function.
|
|
* @example
|
|
*
|
|
* var objects = [
|
|
* { 'a': { 'b': _.constant(2) } },
|
|
* { 'a': { 'b': _.constant(1) } }
|
|
* ];
|
|
*
|
|
* _.map(objects, _.method('a.b'));
|
|
* // => [2, 1]
|
|
*
|
|
* _.map(objects, _.method(['a', 'b']));
|
|
* // => [2, 1]
|
|
*/
|
|
var method = baseRest(function(path, args) {
|
|
return function(object) {
|
|
return baseInvoke(object, path, args);
|
|
};
|
|
});
|
|
|
|
/**
|
|
* The opposite of `_.method`; this method creates a function that invokes
|
|
* the method at a given path of `object`. Any additional arguments are
|
|
* provided to the invoked method.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.7.0
|
|
* @category Util
|
|
* @param {Object} object The object to query.
|
|
* @param {...*} [args] The arguments to invoke the method with.
|
|
* @returns {Function} Returns the new invoker function.
|
|
* @example
|
|
*
|
|
* var array = _.times(3, _.constant),
|
|
* object = { 'a': array, 'b': array, 'c': array };
|
|
*
|
|
* _.map(['a[2]', 'c[0]'], _.methodOf(object));
|
|
* // => [2, 0]
|
|
*
|
|
* _.map([['a', '2'], ['c', '0']], _.methodOf(object));
|
|
* // => [2, 0]
|
|
*/
|
|
var methodOf = baseRest(function(object, args) {
|
|
return function(path) {
|
|
return baseInvoke(object, path, args);
|
|
};
|
|
});
|
|
|
|
/**
|
|
* Adds all own enumerable string keyed function properties of a source
|
|
* object to the destination object. If `object` is a function, then methods
|
|
* are added to its prototype as well.
|
|
*
|
|
* **Note:** Use `_.runInContext` to create a pristine `lodash` function to
|
|
* avoid conflicts caused by modifying the original.
|
|
*
|
|
* @static
|
|
* @since 0.1.0
|
|
* @memberOf _
|
|
* @category Util
|
|
* @param {Function|Object} [object=lodash] The destination object.
|
|
* @param {Object} source The object of functions to add.
|
|
* @param {Object} [options={}] The options object.
|
|
* @param {boolean} [options.chain=true] Specify whether mixins are chainable.
|
|
* @returns {Function|Object} Returns `object`.
|
|
* @example
|
|
*
|
|
* function vowels(string) {
|
|
* return _.filter(string, function(v) {
|
|
* return /[aeiou]/i.test(v);
|
|
* });
|
|
* }
|
|
*
|
|
* _.mixin({ 'vowels': vowels });
|
|
* _.vowels('fred');
|
|
* // => ['e']
|
|
*
|
|
* _('fred').vowels().value();
|
|
* // => ['e']
|
|
*
|
|
* _.mixin({ 'vowels': vowels }, { 'chain': false });
|
|
* _('fred').vowels();
|
|
* // => ['e']
|
|
*/
|
|
function mixin(object, source, options) {
|
|
var props = keys(source),
|
|
methodNames = baseFunctions(source, props);
|
|
|
|
if (options == null &&
|
|
!(isObject(source) && (methodNames.length || !props.length))) {
|
|
options = source;
|
|
source = object;
|
|
object = this;
|
|
methodNames = baseFunctions(source, keys(source));
|
|
}
|
|
var chain = !(isObject(options) && 'chain' in options) || !!options.chain,
|
|
isFunc = isFunction(object);
|
|
|
|
arrayEach(methodNames, function(methodName) {
|
|
var func = source[methodName];
|
|
object[methodName] = func;
|
|
if (isFunc) {
|
|
object.prototype[methodName] = function() {
|
|
var chainAll = this.__chain__;
|
|
if (chain || chainAll) {
|
|
var result = object(this.__wrapped__),
|
|
actions = result.__actions__ = copyArray(this.__actions__);
|
|
|
|
actions.push({ 'func': func, 'args': arguments, 'thisArg': object });
|
|
result.__chain__ = chainAll;
|
|
return result;
|
|
}
|
|
return func.apply(object, arrayPush([this.value()], arguments));
|
|
};
|
|
}
|
|
});
|
|
|
|
return object;
|
|
}
|
|
|
|
/**
|
|
* Reverts the `_` variable to its previous value and returns a reference to
|
|
* the `lodash` function.
|
|
*
|
|
* @static
|
|
* @since 0.1.0
|
|
* @memberOf _
|
|
* @category Util
|
|
* @returns {Function} Returns the `lodash` function.
|
|
* @example
|
|
*
|
|
* var lodash = _.noConflict();
|
|
*/
|
|
function noConflict() {
|
|
if (root._ === this) {
|
|
root._ = oldDash;
|
|
}
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* This method returns `undefined`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 2.3.0
|
|
* @category Util
|
|
* @example
|
|
*
|
|
* _.times(2, _.noop);
|
|
* // => [undefined, undefined]
|
|
*/
|
|
function noop() {
|
|
// No operation performed.
|
|
}
|
|
|
|
/**
|
|
* Creates a function that gets the argument at index `n`. If `n` is negative,
|
|
* the nth argument from the end is returned.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Util
|
|
* @param {number} [n=0] The index of the argument to return.
|
|
* @returns {Function} Returns the new pass-thru function.
|
|
* @example
|
|
*
|
|
* var func = _.nthArg(1);
|
|
* func('a', 'b', 'c', 'd');
|
|
* // => 'b'
|
|
*
|
|
* var func = _.nthArg(-2);
|
|
* func('a', 'b', 'c', 'd');
|
|
* // => 'c'
|
|
*/
|
|
function nthArg(n) {
|
|
n = toInteger(n);
|
|
return baseRest(function(args) {
|
|
return baseNth(args, n);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Creates a function that invokes `iteratees` with the arguments it receives
|
|
* and returns their results.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Util
|
|
* @param {...(Function|Function[])} [iteratees=[_.identity]]
|
|
* The iteratees to invoke.
|
|
* @returns {Function} Returns the new function.
|
|
* @example
|
|
*
|
|
* var func = _.over([Math.max, Math.min]);
|
|
*
|
|
* func(1, 2, 3, 4);
|
|
* // => [4, 1]
|
|
*/
|
|
var over = createOver(arrayMap);
|
|
|
|
/**
|
|
* Creates a function that checks if **all** of the `predicates` return
|
|
* truthy when invoked with the arguments it receives.
|
|
*
|
|
* Following shorthands are possible for providing predicates.
|
|
* Pass an `Object` and it will be used as an parameter for `_.matches` to create the predicate.
|
|
* Pass an `Array` of parameters for `_.matchesProperty` and the predicate will be created using them.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Util
|
|
* @param {...(Function|Function[])} [predicates=[_.identity]]
|
|
* The predicates to check.
|
|
* @returns {Function} Returns the new function.
|
|
* @example
|
|
*
|
|
* var func = _.overEvery([Boolean, isFinite]);
|
|
*
|
|
* func('1');
|
|
* // => true
|
|
*
|
|
* func(null);
|
|
* // => false
|
|
*
|
|
* func(NaN);
|
|
* // => false
|
|
*/
|
|
var overEvery = createOver(arrayEvery);
|
|
|
|
/**
|
|
* Creates a function that checks if **any** of the `predicates` return
|
|
* truthy when invoked with the arguments it receives.
|
|
*
|
|
* Following shorthands are possible for providing predicates.
|
|
* Pass an `Object` and it will be used as an parameter for `_.matches` to create the predicate.
|
|
* Pass an `Array` of parameters for `_.matchesProperty` and the predicate will be created using them.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Util
|
|
* @param {...(Function|Function[])} [predicates=[_.identity]]
|
|
* The predicates to check.
|
|
* @returns {Function} Returns the new function.
|
|
* @example
|
|
*
|
|
* var func = _.overSome([Boolean, isFinite]);
|
|
*
|
|
* func('1');
|
|
* // => true
|
|
*
|
|
* func(null);
|
|
* // => true
|
|
*
|
|
* func(NaN);
|
|
* // => false
|
|
*
|
|
* var matchesFunc = _.overSome([{ 'a': 1 }, { 'a': 2 }])
|
|
* var matchesPropertyFunc = _.overSome([['a', 1], ['a', 2]])
|
|
*/
|
|
var overSome = createOver(arraySome);
|
|
|
|
/**
|
|
* Creates a function that returns the value at `path` of a given object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 2.4.0
|
|
* @category Util
|
|
* @param {Array|string} path The path of the property to get.
|
|
* @returns {Function} Returns the new accessor function.
|
|
* @example
|
|
*
|
|
* var objects = [
|
|
* { 'a': { 'b': 2 } },
|
|
* { 'a': { 'b': 1 } }
|
|
* ];
|
|
*
|
|
* _.map(objects, _.property('a.b'));
|
|
* // => [2, 1]
|
|
*
|
|
* _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');
|
|
* // => [1, 2]
|
|
*/
|
|
function property(path) {
|
|
return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);
|
|
}
|
|
|
|
/**
|
|
* The opposite of `_.property`; this method creates a function that returns
|
|
* the value at a given path of `object`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.0.0
|
|
* @category Util
|
|
* @param {Object} object The object to query.
|
|
* @returns {Function} Returns the new accessor function.
|
|
* @example
|
|
*
|
|
* var array = [0, 1, 2],
|
|
* object = { 'a': array, 'b': array, 'c': array };
|
|
*
|
|
* _.map(['a[2]', 'c[0]'], _.propertyOf(object));
|
|
* // => [2, 0]
|
|
*
|
|
* _.map([['a', '2'], ['c', '0']], _.propertyOf(object));
|
|
* // => [2, 0]
|
|
*/
|
|
function propertyOf(object) {
|
|
return function(path) {
|
|
return object == null ? undefined : baseGet(object, path);
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Creates an array of numbers (positive and/or negative) progressing from
|
|
* `start` up to, but not including, `end`. A step of `-1` is used if a negative
|
|
* `start` is specified without an `end` or `step`. If `end` is not specified,
|
|
* it's set to `start` with `start` then set to `0`.
|
|
*
|
|
* **Note:** JavaScript follows the IEEE-754 standard for resolving
|
|
* floating-point values which can produce unexpected results.
|
|
*
|
|
* @static
|
|
* @since 0.1.0
|
|
* @memberOf _
|
|
* @category Util
|
|
* @param {number} [start=0] The start of the range.
|
|
* @param {number} end The end of the range.
|
|
* @param {number} [step=1] The value to increment or decrement by.
|
|
* @returns {Array} Returns the range of numbers.
|
|
* @see _.inRange, _.rangeRight
|
|
* @example
|
|
*
|
|
* _.range(4);
|
|
* // => [0, 1, 2, 3]
|
|
*
|
|
* _.range(-4);
|
|
* // => [0, -1, -2, -3]
|
|
*
|
|
* _.range(1, 5);
|
|
* // => [1, 2, 3, 4]
|
|
*
|
|
* _.range(0, 20, 5);
|
|
* // => [0, 5, 10, 15]
|
|
*
|
|
* _.range(0, -4, -1);
|
|
* // => [0, -1, -2, -3]
|
|
*
|
|
* _.range(1, 4, 0);
|
|
* // => [1, 1, 1]
|
|
*
|
|
* _.range(0);
|
|
* // => []
|
|
*/
|
|
var range = createRange();
|
|
|
|
/**
|
|
* This method is like `_.range` except that it populates values in
|
|
* descending order.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Util
|
|
* @param {number} [start=0] The start of the range.
|
|
* @param {number} end The end of the range.
|
|
* @param {number} [step=1] The value to increment or decrement by.
|
|
* @returns {Array} Returns the range of numbers.
|
|
* @see _.inRange, _.range
|
|
* @example
|
|
*
|
|
* _.rangeRight(4);
|
|
* // => [3, 2, 1, 0]
|
|
*
|
|
* _.rangeRight(-4);
|
|
* // => [-3, -2, -1, 0]
|
|
*
|
|
* _.rangeRight(1, 5);
|
|
* // => [4, 3, 2, 1]
|
|
*
|
|
* _.rangeRight(0, 20, 5);
|
|
* // => [15, 10, 5, 0]
|
|
*
|
|
* _.rangeRight(0, -4, -1);
|
|
* // => [-3, -2, -1, 0]
|
|
*
|
|
* _.rangeRight(1, 4, 0);
|
|
* // => [1, 1, 1]
|
|
*
|
|
* _.rangeRight(0);
|
|
* // => []
|
|
*/
|
|
var rangeRight = createRange(true);
|
|
|
|
/**
|
|
* This method returns a new empty array.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.13.0
|
|
* @category Util
|
|
* @returns {Array} Returns the new empty array.
|
|
* @example
|
|
*
|
|
* var arrays = _.times(2, _.stubArray);
|
|
*
|
|
* console.log(arrays);
|
|
* // => [[], []]
|
|
*
|
|
* console.log(arrays[0] === arrays[1]);
|
|
* // => false
|
|
*/
|
|
function stubArray() {
|
|
return [];
|
|
}
|
|
|
|
/**
|
|
* This method returns `false`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.13.0
|
|
* @category Util
|
|
* @returns {boolean} Returns `false`.
|
|
* @example
|
|
*
|
|
* _.times(2, _.stubFalse);
|
|
* // => [false, false]
|
|
*/
|
|
function stubFalse() {
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* This method returns a new empty object.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.13.0
|
|
* @category Util
|
|
* @returns {Object} Returns the new empty object.
|
|
* @example
|
|
*
|
|
* var objects = _.times(2, _.stubObject);
|
|
*
|
|
* console.log(objects);
|
|
* // => [{}, {}]
|
|
*
|
|
* console.log(objects[0] === objects[1]);
|
|
* // => false
|
|
*/
|
|
function stubObject() {
|
|
return {};
|
|
}
|
|
|
|
/**
|
|
* This method returns an empty string.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.13.0
|
|
* @category Util
|
|
* @returns {string} Returns the empty string.
|
|
* @example
|
|
*
|
|
* _.times(2, _.stubString);
|
|
* // => ['', '']
|
|
*/
|
|
function stubString() {
|
|
return '';
|
|
}
|
|
|
|
/**
|
|
* This method returns `true`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.13.0
|
|
* @category Util
|
|
* @returns {boolean} Returns `true`.
|
|
* @example
|
|
*
|
|
* _.times(2, _.stubTrue);
|
|
* // => [true, true]
|
|
*/
|
|
function stubTrue() {
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Invokes the iteratee `n` times, returning an array of the results of
|
|
* each invocation. The iteratee is invoked with one argument; (index).
|
|
*
|
|
* @static
|
|
* @since 0.1.0
|
|
* @memberOf _
|
|
* @category Util
|
|
* @param {number} n The number of times to invoke `iteratee`.
|
|
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
|
* @returns {Array} Returns the array of results.
|
|
* @example
|
|
*
|
|
* _.times(3, String);
|
|
* // => ['0', '1', '2']
|
|
*
|
|
* _.times(4, _.constant(0));
|
|
* // => [0, 0, 0, 0]
|
|
*/
|
|
function times(n, iteratee) {
|
|
n = toInteger(n);
|
|
if (n < 1 || n > MAX_SAFE_INTEGER) {
|
|
return [];
|
|
}
|
|
var index = MAX_ARRAY_LENGTH,
|
|
length = nativeMin(n, MAX_ARRAY_LENGTH);
|
|
|
|
iteratee = getIteratee(iteratee);
|
|
n -= MAX_ARRAY_LENGTH;
|
|
|
|
var result = baseTimes(length, iteratee);
|
|
while (++index < n) {
|
|
iteratee(index);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Converts `value` to a property path array.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Util
|
|
* @param {*} value The value to convert.
|
|
* @returns {Array} Returns the new property path array.
|
|
* @example
|
|
*
|
|
* _.toPath('a.b.c');
|
|
* // => ['a', 'b', 'c']
|
|
*
|
|
* _.toPath('a[0].b.c');
|
|
* // => ['a', '0', 'b', 'c']
|
|
*/
|
|
function toPath(value) {
|
|
if (isArray(value)) {
|
|
return arrayMap(value, toKey);
|
|
}
|
|
return isSymbol(value) ? [value] : copyArray(stringToPath(toString(value)));
|
|
}
|
|
|
|
/**
|
|
* Generates a unique ID. If `prefix` is given, the ID is appended to it.
|
|
*
|
|
* @static
|
|
* @since 0.1.0
|
|
* @memberOf _
|
|
* @category Util
|
|
* @param {string} [prefix=''] The value to prefix the ID with.
|
|
* @returns {string} Returns the unique ID.
|
|
* @example
|
|
*
|
|
* _.uniqueId('contact_');
|
|
* // => 'contact_104'
|
|
*
|
|
* _.uniqueId();
|
|
* // => '105'
|
|
*/
|
|
function uniqueId(prefix) {
|
|
var id = ++idCounter;
|
|
return toString(prefix) + id;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* Adds two numbers.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.4.0
|
|
* @category Math
|
|
* @param {number} augend The first number in an addition.
|
|
* @param {number} addend The second number in an addition.
|
|
* @returns {number} Returns the total.
|
|
* @example
|
|
*
|
|
* _.add(6, 4);
|
|
* // => 10
|
|
*/
|
|
var add = createMathOperation(function(augend, addend) {
|
|
return augend + addend;
|
|
}, 0);
|
|
|
|
/**
|
|
* Computes `number` rounded up to `precision`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.10.0
|
|
* @category Math
|
|
* @param {number} number The number to round up.
|
|
* @param {number} [precision=0] The precision to round up to.
|
|
* @returns {number} Returns the rounded up number.
|
|
* @example
|
|
*
|
|
* _.ceil(4.006);
|
|
* // => 5
|
|
*
|
|
* _.ceil(6.004, 2);
|
|
* // => 6.01
|
|
*
|
|
* _.ceil(6040, -2);
|
|
* // => 6100
|
|
*/
|
|
var ceil = createRound('ceil');
|
|
|
|
/**
|
|
* Divide two numbers.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.7.0
|
|
* @category Math
|
|
* @param {number} dividend The first number in a division.
|
|
* @param {number} divisor The second number in a division.
|
|
* @returns {number} Returns the quotient.
|
|
* @example
|
|
*
|
|
* _.divide(6, 4);
|
|
* // => 1.5
|
|
*/
|
|
var divide = createMathOperation(function(dividend, divisor) {
|
|
return dividend / divisor;
|
|
}, 1);
|
|
|
|
/**
|
|
* Computes `number` rounded down to `precision`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.10.0
|
|
* @category Math
|
|
* @param {number} number The number to round down.
|
|
* @param {number} [precision=0] The precision to round down to.
|
|
* @returns {number} Returns the rounded down number.
|
|
* @example
|
|
*
|
|
* _.floor(4.006);
|
|
* // => 4
|
|
*
|
|
* _.floor(0.046, 2);
|
|
* // => 0.04
|
|
*
|
|
* _.floor(4060, -2);
|
|
* // => 4000
|
|
*/
|
|
var floor = createRound('floor');
|
|
|
|
/**
|
|
* Computes the maximum value of `array`. If `array` is empty or falsey,
|
|
* `undefined` is returned.
|
|
*
|
|
* @static
|
|
* @since 0.1.0
|
|
* @memberOf _
|
|
* @category Math
|
|
* @param {Array} array The array to iterate over.
|
|
* @returns {*} Returns the maximum value.
|
|
* @example
|
|
*
|
|
* _.max([4, 2, 8, 6]);
|
|
* // => 8
|
|
*
|
|
* _.max([]);
|
|
* // => undefined
|
|
*/
|
|
function max(array) {
|
|
return (array && array.length)
|
|
? baseExtremum(array, identity, baseGt)
|
|
: undefined;
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.max` except that it accepts `iteratee` which is
|
|
* invoked for each element in `array` to generate the criterion by which
|
|
* the value is ranked. The iteratee is invoked with one argument: (value).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Math
|
|
* @param {Array} array The array to iterate over.
|
|
* @param {Function} [iteratee=_.identity] The iteratee invoked per element.
|
|
* @returns {*} Returns the maximum value.
|
|
* @example
|
|
*
|
|
* var objects = [{ 'n': 1 }, { 'n': 2 }];
|
|
*
|
|
* _.maxBy(objects, function(o) { return o.n; });
|
|
* // => { 'n': 2 }
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.maxBy(objects, 'n');
|
|
* // => { 'n': 2 }
|
|
*/
|
|
function maxBy(array, iteratee) {
|
|
return (array && array.length)
|
|
? baseExtremum(array, getIteratee(iteratee, 2), baseGt)
|
|
: undefined;
|
|
}
|
|
|
|
/**
|
|
* Computes the mean of the values in `array`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Math
|
|
* @param {Array} array The array to iterate over.
|
|
* @returns {number} Returns the mean.
|
|
* @example
|
|
*
|
|
* _.mean([4, 2, 8, 6]);
|
|
* // => 5
|
|
*/
|
|
function mean(array) {
|
|
return baseMean(array, identity);
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.mean` except that it accepts `iteratee` which is
|
|
* invoked for each element in `array` to generate the value to be averaged.
|
|
* The iteratee is invoked with one argument: (value).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.7.0
|
|
* @category Math
|
|
* @param {Array} array The array to iterate over.
|
|
* @param {Function} [iteratee=_.identity] The iteratee invoked per element.
|
|
* @returns {number} Returns the mean.
|
|
* @example
|
|
*
|
|
* var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
|
|
*
|
|
* _.meanBy(objects, function(o) { return o.n; });
|
|
* // => 5
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.meanBy(objects, 'n');
|
|
* // => 5
|
|
*/
|
|
function meanBy(array, iteratee) {
|
|
return baseMean(array, getIteratee(iteratee, 2));
|
|
}
|
|
|
|
/**
|
|
* Computes the minimum value of `array`. If `array` is empty or falsey,
|
|
* `undefined` is returned.
|
|
*
|
|
* @static
|
|
* @since 0.1.0
|
|
* @memberOf _
|
|
* @category Math
|
|
* @param {Array} array The array to iterate over.
|
|
* @returns {*} Returns the minimum value.
|
|
* @example
|
|
*
|
|
* _.min([4, 2, 8, 6]);
|
|
* // => 2
|
|
*
|
|
* _.min([]);
|
|
* // => undefined
|
|
*/
|
|
function min(array) {
|
|
return (array && array.length)
|
|
? baseExtremum(array, identity, baseLt)
|
|
: undefined;
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.min` except that it accepts `iteratee` which is
|
|
* invoked for each element in `array` to generate the criterion by which
|
|
* the value is ranked. The iteratee is invoked with one argument: (value).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Math
|
|
* @param {Array} array The array to iterate over.
|
|
* @param {Function} [iteratee=_.identity] The iteratee invoked per element.
|
|
* @returns {*} Returns the minimum value.
|
|
* @example
|
|
*
|
|
* var objects = [{ 'n': 1 }, { 'n': 2 }];
|
|
*
|
|
* _.minBy(objects, function(o) { return o.n; });
|
|
* // => { 'n': 1 }
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.minBy(objects, 'n');
|
|
* // => { 'n': 1 }
|
|
*/
|
|
function minBy(array, iteratee) {
|
|
return (array && array.length)
|
|
? baseExtremum(array, getIteratee(iteratee, 2), baseLt)
|
|
: undefined;
|
|
}
|
|
|
|
/**
|
|
* Multiply two numbers.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.7.0
|
|
* @category Math
|
|
* @param {number} multiplier The first number in a multiplication.
|
|
* @param {number} multiplicand The second number in a multiplication.
|
|
* @returns {number} Returns the product.
|
|
* @example
|
|
*
|
|
* _.multiply(6, 4);
|
|
* // => 24
|
|
*/
|
|
var multiply = createMathOperation(function(multiplier, multiplicand) {
|
|
return multiplier * multiplicand;
|
|
}, 1);
|
|
|
|
/**
|
|
* Computes `number` rounded to `precision`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.10.0
|
|
* @category Math
|
|
* @param {number} number The number to round.
|
|
* @param {number} [precision=0] The precision to round to.
|
|
* @returns {number} Returns the rounded number.
|
|
* @example
|
|
*
|
|
* _.round(4.006);
|
|
* // => 4
|
|
*
|
|
* _.round(4.006, 2);
|
|
* // => 4.01
|
|
*
|
|
* _.round(4060, -2);
|
|
* // => 4100
|
|
*/
|
|
var round = createRound('round');
|
|
|
|
/**
|
|
* Subtract two numbers.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Math
|
|
* @param {number} minuend The first number in a subtraction.
|
|
* @param {number} subtrahend The second number in a subtraction.
|
|
* @returns {number} Returns the difference.
|
|
* @example
|
|
*
|
|
* _.subtract(6, 4);
|
|
* // => 2
|
|
*/
|
|
var subtract = createMathOperation(function(minuend, subtrahend) {
|
|
return minuend - subtrahend;
|
|
}, 0);
|
|
|
|
/**
|
|
* Computes the sum of the values in `array`.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 3.4.0
|
|
* @category Math
|
|
* @param {Array} array The array to iterate over.
|
|
* @returns {number} Returns the sum.
|
|
* @example
|
|
*
|
|
* _.sum([4, 2, 8, 6]);
|
|
* // => 20
|
|
*/
|
|
function sum(array) {
|
|
return (array && array.length)
|
|
? baseSum(array, identity)
|
|
: 0;
|
|
}
|
|
|
|
/**
|
|
* This method is like `_.sum` except that it accepts `iteratee` which is
|
|
* invoked for each element in `array` to generate the value to be summed.
|
|
* The iteratee is invoked with one argument: (value).
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @since 4.0.0
|
|
* @category Math
|
|
* @param {Array} array The array to iterate over.
|
|
* @param {Function} [iteratee=_.identity] The iteratee invoked per element.
|
|
* @returns {number} Returns the sum.
|
|
* @example
|
|
*
|
|
* var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
|
|
*
|
|
* _.sumBy(objects, function(o) { return o.n; });
|
|
* // => 20
|
|
*
|
|
* // The `_.property` iteratee shorthand.
|
|
* _.sumBy(objects, 'n');
|
|
* // => 20
|
|
*/
|
|
function sumBy(array, iteratee) {
|
|
return (array && array.length)
|
|
? baseSum(array, getIteratee(iteratee, 2))
|
|
: 0;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
// Add methods that return wrapped values in chain sequences.
|
|
lodash.after = after;
|
|
lodash.ary = ary;
|
|
lodash.assign = assign;
|
|
lodash.assignIn = assignIn;
|
|
lodash.assignInWith = assignInWith;
|
|
lodash.assignWith = assignWith;
|
|
lodash.at = at;
|
|
lodash.before = before;
|
|
lodash.bind = bind;
|
|
lodash.bindAll = bindAll;
|
|
lodash.bindKey = bindKey;
|
|
lodash.castArray = castArray;
|
|
lodash.chain = chain;
|
|
lodash.chunk = chunk;
|
|
lodash.compact = compact;
|
|
lodash.concat = concat;
|
|
lodash.cond = cond;
|
|
lodash.conforms = conforms;
|
|
lodash.constant = constant;
|
|
lodash.countBy = countBy;
|
|
lodash.create = create;
|
|
lodash.curry = curry;
|
|
lodash.curryRight = curryRight;
|
|
lodash.debounce = debounce;
|
|
lodash.defaults = defaults;
|
|
lodash.defaultsDeep = defaultsDeep;
|
|
lodash.defer = defer;
|
|
lodash.delay = delay;
|
|
lodash.difference = difference;
|
|
lodash.differenceBy = differenceBy;
|
|
lodash.differenceWith = differenceWith;
|
|
lodash.drop = drop;
|
|
lodash.dropRight = dropRight;
|
|
lodash.dropRightWhile = dropRightWhile;
|
|
lodash.dropWhile = dropWhile;
|
|
lodash.fill = fill;
|
|
lodash.filter = filter;
|
|
lodash.flatMap = flatMap;
|
|
lodash.flatMapDeep = flatMapDeep;
|
|
lodash.flatMapDepth = flatMapDepth;
|
|
lodash.flatten = flatten;
|
|
lodash.flattenDeep = flattenDeep;
|
|
lodash.flattenDepth = flattenDepth;
|
|
lodash.flip = flip;
|
|
lodash.flow = flow;
|
|
lodash.flowRight = flowRight;
|
|
lodash.fromPairs = fromPairs;
|
|
lodash.functions = functions;
|
|
lodash.functionsIn = functionsIn;
|
|
lodash.groupBy = groupBy;
|
|
lodash.initial = initial;
|
|
lodash.intersection = intersection;
|
|
lodash.intersectionBy = intersectionBy;
|
|
lodash.intersectionWith = intersectionWith;
|
|
lodash.invert = invert;
|
|
lodash.invertBy = invertBy;
|
|
lodash.invokeMap = invokeMap;
|
|
lodash.iteratee = iteratee;
|
|
lodash.keyBy = keyBy;
|
|
lodash.keys = keys;
|
|
lodash.keysIn = keysIn;
|
|
lodash.map = map;
|
|
lodash.mapKeys = mapKeys;
|
|
lodash.mapValues = mapValues;
|
|
lodash.matches = matches;
|
|
lodash.matchesProperty = matchesProperty;
|
|
lodash.memoize = memoize;
|
|
lodash.merge = merge;
|
|
lodash.mergeWith = mergeWith;
|
|
lodash.method = method;
|
|
lodash.methodOf = methodOf;
|
|
lodash.mixin = mixin;
|
|
lodash.negate = negate;
|
|
lodash.nthArg = nthArg;
|
|
lodash.omit = omit;
|
|
lodash.omitBy = omitBy;
|
|
lodash.once = once;
|
|
lodash.orderBy = orderBy;
|
|
lodash.over = over;
|
|
lodash.overArgs = overArgs;
|
|
lodash.overEvery = overEvery;
|
|
lodash.overSome = overSome;
|
|
lodash.partial = partial;
|
|
lodash.partialRight = partialRight;
|
|
lodash.partition = partition;
|
|
lodash.pick = pick;
|
|
lodash.pickBy = pickBy;
|
|
lodash.property = property;
|
|
lodash.propertyOf = propertyOf;
|
|
lodash.pull = pull;
|
|
lodash.pullAll = pullAll;
|
|
lodash.pullAllBy = pullAllBy;
|
|
lodash.pullAllWith = pullAllWith;
|
|
lodash.pullAt = pullAt;
|
|
lodash.range = range;
|
|
lodash.rangeRight = rangeRight;
|
|
lodash.rearg = rearg;
|
|
lodash.reject = reject;
|
|
lodash.remove = remove;
|
|
lodash.rest = rest;
|
|
lodash.reverse = reverse;
|
|
lodash.sampleSize = sampleSize;
|
|
lodash.set = set;
|
|
lodash.setWith = setWith;
|
|
lodash.shuffle = shuffle;
|
|
lodash.slice = slice;
|
|
lodash.sortBy = sortBy;
|
|
lodash.sortedUniq = sortedUniq;
|
|
lodash.sortedUniqBy = sortedUniqBy;
|
|
lodash.split = split;
|
|
lodash.spread = spread;
|
|
lodash.tail = tail;
|
|
lodash.take = take;
|
|
lodash.takeRight = takeRight;
|
|
lodash.takeRightWhile = takeRightWhile;
|
|
lodash.takeWhile = takeWhile;
|
|
lodash.tap = tap;
|
|
lodash.throttle = throttle;
|
|
lodash.thru = thru;
|
|
lodash.toArray = toArray;
|
|
lodash.toPairs = toPairs;
|
|
lodash.toPairsIn = toPairsIn;
|
|
lodash.toPath = toPath;
|
|
lodash.toPlainObject = toPlainObject;
|
|
lodash.transform = transform;
|
|
lodash.unary = unary;
|
|
lodash.union = union;
|
|
lodash.unionBy = unionBy;
|
|
lodash.unionWith = unionWith;
|
|
lodash.uniq = uniq;
|
|
lodash.uniqBy = uniqBy;
|
|
lodash.uniqWith = uniqWith;
|
|
lodash.unset = unset;
|
|
lodash.unzip = unzip;
|
|
lodash.unzipWith = unzipWith;
|
|
lodash.update = update;
|
|
lodash.updateWith = updateWith;
|
|
lodash.values = values;
|
|
lodash.valuesIn = valuesIn;
|
|
lodash.without = without;
|
|
lodash.words = words;
|
|
lodash.wrap = wrap;
|
|
lodash.xor = xor;
|
|
lodash.xorBy = xorBy;
|
|
lodash.xorWith = xorWith;
|
|
lodash.zip = zip;
|
|
lodash.zipObject = zipObject;
|
|
lodash.zipObjectDeep = zipObjectDeep;
|
|
lodash.zipWith = zipWith;
|
|
|
|
// Add aliases.
|
|
lodash.entries = toPairs;
|
|
lodash.entriesIn = toPairsIn;
|
|
lodash.extend = assignIn;
|
|
lodash.extendWith = assignInWith;
|
|
|
|
// Add methods to `lodash.prototype`.
|
|
mixin(lodash, lodash);
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
// Add methods that return unwrapped values in chain sequences.
|
|
lodash.add = add;
|
|
lodash.attempt = attempt;
|
|
lodash.camelCase = camelCase;
|
|
lodash.capitalize = capitalize;
|
|
lodash.ceil = ceil;
|
|
lodash.clamp = clamp;
|
|
lodash.clone = clone;
|
|
lodash.cloneDeep = cloneDeep;
|
|
lodash.cloneDeepWith = cloneDeepWith;
|
|
lodash.cloneWith = cloneWith;
|
|
lodash.conformsTo = conformsTo;
|
|
lodash.deburr = deburr;
|
|
lodash.defaultTo = defaultTo;
|
|
lodash.divide = divide;
|
|
lodash.endsWith = endsWith;
|
|
lodash.eq = eq;
|
|
lodash.escape = escape;
|
|
lodash.escapeRegExp = escapeRegExp;
|
|
lodash.every = every;
|
|
lodash.find = find;
|
|
lodash.findIndex = findIndex;
|
|
lodash.findKey = findKey;
|
|
lodash.findLast = findLast;
|
|
lodash.findLastIndex = findLastIndex;
|
|
lodash.findLastKey = findLastKey;
|
|
lodash.floor = floor;
|
|
lodash.forEach = forEach;
|
|
lodash.forEachRight = forEachRight;
|
|
lodash.forIn = forIn;
|
|
lodash.forInRight = forInRight;
|
|
lodash.forOwn = forOwn;
|
|
lodash.forOwnRight = forOwnRight;
|
|
lodash.get = get;
|
|
lodash.gt = gt;
|
|
lodash.gte = gte;
|
|
lodash.has = has;
|
|
lodash.hasIn = hasIn;
|
|
lodash.head = head;
|
|
lodash.identity = identity;
|
|
lodash.includes = includes;
|
|
lodash.indexOf = indexOf;
|
|
lodash.inRange = inRange;
|
|
lodash.invoke = invoke;
|
|
lodash.isArguments = isArguments;
|
|
lodash.isArray = isArray;
|
|
lodash.isArrayBuffer = isArrayBuffer;
|
|
lodash.isArrayLike = isArrayLike;
|
|
lodash.isArrayLikeObject = isArrayLikeObject;
|
|
lodash.isBoolean = isBoolean;
|
|
lodash.isBuffer = isBuffer;
|
|
lodash.isDate = isDate;
|
|
lodash.isElement = isElement;
|
|
lodash.isEmpty = isEmpty;
|
|
lodash.isEqual = isEqual;
|
|
lodash.isEqualWith = isEqualWith;
|
|
lodash.isError = isError;
|
|
lodash.isFinite = isFinite;
|
|
lodash.isFunction = isFunction;
|
|
lodash.isInteger = isInteger;
|
|
lodash.isLength = isLength;
|
|
lodash.isMap = isMap;
|
|
lodash.isMatch = isMatch;
|
|
lodash.isMatchWith = isMatchWith;
|
|
lodash.isNaN = isNaN;
|
|
lodash.isNative = isNative;
|
|
lodash.isNil = isNil;
|
|
lodash.isNull = isNull;
|
|
lodash.isNumber = isNumber;
|
|
lodash.isObject = isObject;
|
|
lodash.isObjectLike = isObjectLike;
|
|
lodash.isPlainObject = isPlainObject;
|
|
lodash.isRegExp = isRegExp;
|
|
lodash.isSafeInteger = isSafeInteger;
|
|
lodash.isSet = isSet;
|
|
lodash.isString = isString;
|
|
lodash.isSymbol = isSymbol;
|
|
lodash.isTypedArray = isTypedArray;
|
|
lodash.isUndefined = isUndefined;
|
|
lodash.isWeakMap = isWeakMap;
|
|
lodash.isWeakSet = isWeakSet;
|
|
lodash.join = join;
|
|
lodash.kebabCase = kebabCase;
|
|
lodash.last = last;
|
|
lodash.lastIndexOf = lastIndexOf;
|
|
lodash.lowerCase = lowerCase;
|
|
lodash.lowerFirst = lowerFirst;
|
|
lodash.lt = lt;
|
|
lodash.lte = lte;
|
|
lodash.max = max;
|
|
lodash.maxBy = maxBy;
|
|
lodash.mean = mean;
|
|
lodash.meanBy = meanBy;
|
|
lodash.min = min;
|
|
lodash.minBy = minBy;
|
|
lodash.stubArray = stubArray;
|
|
lodash.stubFalse = stubFalse;
|
|
lodash.stubObject = stubObject;
|
|
lodash.stubString = stubString;
|
|
lodash.stubTrue = stubTrue;
|
|
lodash.multiply = multiply;
|
|
lodash.nth = nth;
|
|
lodash.noConflict = noConflict;
|
|
lodash.noop = noop;
|
|
lodash.now = now;
|
|
lodash.pad = pad;
|
|
lodash.padEnd = padEnd;
|
|
lodash.padStart = padStart;
|
|
lodash.parseInt = parseInt;
|
|
lodash.random = random;
|
|
lodash.reduce = reduce;
|
|
lodash.reduceRight = reduceRight;
|
|
lodash.repeat = repeat;
|
|
lodash.replace = replace;
|
|
lodash.result = result;
|
|
lodash.round = round;
|
|
lodash.runInContext = runInContext;
|
|
lodash.sample = sample;
|
|
lodash.size = size;
|
|
lodash.snakeCase = snakeCase;
|
|
lodash.some = some;
|
|
lodash.sortedIndex = sortedIndex;
|
|
lodash.sortedIndexBy = sortedIndexBy;
|
|
lodash.sortedIndexOf = sortedIndexOf;
|
|
lodash.sortedLastIndex = sortedLastIndex;
|
|
lodash.sortedLastIndexBy = sortedLastIndexBy;
|
|
lodash.sortedLastIndexOf = sortedLastIndexOf;
|
|
lodash.startCase = startCase;
|
|
lodash.startsWith = startsWith;
|
|
lodash.subtract = subtract;
|
|
lodash.sum = sum;
|
|
lodash.sumBy = sumBy;
|
|
lodash.template = template;
|
|
lodash.times = times;
|
|
lodash.toFinite = toFinite;
|
|
lodash.toInteger = toInteger;
|
|
lodash.toLength = toLength;
|
|
lodash.toLower = toLower;
|
|
lodash.toNumber = toNumber;
|
|
lodash.toSafeInteger = toSafeInteger;
|
|
lodash.toString = toString;
|
|
lodash.toUpper = toUpper;
|
|
lodash.trim = trim;
|
|
lodash.trimEnd = trimEnd;
|
|
lodash.trimStart = trimStart;
|
|
lodash.truncate = truncate;
|
|
lodash.unescape = unescape;
|
|
lodash.uniqueId = uniqueId;
|
|
lodash.upperCase = upperCase;
|
|
lodash.upperFirst = upperFirst;
|
|
|
|
// Add aliases.
|
|
lodash.each = forEach;
|
|
lodash.eachRight = forEachRight;
|
|
lodash.first = head;
|
|
|
|
mixin(lodash, (function() {
|
|
var source = {};
|
|
baseForOwn(lodash, function(func, methodName) {
|
|
if (!hasOwnProperty.call(lodash.prototype, methodName)) {
|
|
source[methodName] = func;
|
|
}
|
|
});
|
|
return source;
|
|
}()), { 'chain': false });
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
|
|
/**
|
|
* The semantic version number.
|
|
*
|
|
* @static
|
|
* @memberOf _
|
|
* @type {string}
|
|
*/
|
|
lodash.VERSION = VERSION;
|
|
|
|
// Assign default placeholders.
|
|
arrayEach(['bind', 'bindKey', 'curry', 'curryRight', 'partial', 'partialRight'], function(methodName) {
|
|
lodash[methodName].placeholder = lodash;
|
|
});
|
|
|
|
// Add `LazyWrapper` methods for `_.drop` and `_.take` variants.
|
|
arrayEach(['drop', 'take'], function(methodName, index) {
|
|
LazyWrapper.prototype[methodName] = function(n) {
|
|
n = n === undefined ? 1 : nativeMax(toInteger(n), 0);
|
|
|
|
var result = (this.__filtered__ && !index)
|
|
? new LazyWrapper(this)
|
|
: this.clone();
|
|
|
|
if (result.__filtered__) {
|
|
result.__takeCount__ = nativeMin(n, result.__takeCount__);
|
|
} else {
|
|
result.__views__.push({
|
|
'size': nativeMin(n, MAX_ARRAY_LENGTH),
|
|
'type': methodName + (result.__dir__ < 0 ? 'Right' : '')
|
|
});
|
|
}
|
|
return result;
|
|
};
|
|
|
|
LazyWrapper.prototype[methodName + 'Right'] = function(n) {
|
|
return this.reverse()[methodName](n).reverse();
|
|
};
|
|
});
|
|
|
|
// Add `LazyWrapper` methods that accept an `iteratee` value.
|
|
arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) {
|
|
var type = index + 1,
|
|
isFilter = type == LAZY_FILTER_FLAG || type == LAZY_WHILE_FLAG;
|
|
|
|
LazyWrapper.prototype[methodName] = function(iteratee) {
|
|
var result = this.clone();
|
|
result.__iteratees__.push({
|
|
'iteratee': getIteratee(iteratee, 3),
|
|
'type': type
|
|
});
|
|
result.__filtered__ = result.__filtered__ || isFilter;
|
|
return result;
|
|
};
|
|
});
|
|
|
|
// Add `LazyWrapper` methods for `_.head` and `_.last`.
|
|
arrayEach(['head', 'last'], function(methodName, index) {
|
|
var takeName = 'take' + (index ? 'Right' : '');
|
|
|
|
LazyWrapper.prototype[methodName] = function() {
|
|
return this[takeName](1).value()[0];
|
|
};
|
|
});
|
|
|
|
// Add `LazyWrapper` methods for `_.initial` and `_.tail`.
|
|
arrayEach(['initial', 'tail'], function(methodName, index) {
|
|
var dropName = 'drop' + (index ? '' : 'Right');
|
|
|
|
LazyWrapper.prototype[methodName] = function() {
|
|
return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1);
|
|
};
|
|
});
|
|
|
|
LazyWrapper.prototype.compact = function() {
|
|
return this.filter(identity);
|
|
};
|
|
|
|
LazyWrapper.prototype.find = function(predicate) {
|
|
return this.filter(predicate).head();
|
|
};
|
|
|
|
LazyWrapper.prototype.findLast = function(predicate) {
|
|
return this.reverse().find(predicate);
|
|
};
|
|
|
|
LazyWrapper.prototype.invokeMap = baseRest(function(path, args) {
|
|
if (typeof path == 'function') {
|
|
return new LazyWrapper(this);
|
|
}
|
|
return this.map(function(value) {
|
|
return baseInvoke(value, path, args);
|
|
});
|
|
});
|
|
|
|
LazyWrapper.prototype.reject = function(predicate) {
|
|
return this.filter(negate(getIteratee(predicate)));
|
|
};
|
|
|
|
LazyWrapper.prototype.slice = function(start, end) {
|
|
start = toInteger(start);
|
|
|
|
var result = this;
|
|
if (result.__filtered__ && (start > 0 || end < 0)) {
|
|
return new LazyWrapper(result);
|
|
}
|
|
if (start < 0) {
|
|
result = result.takeRight(-start);
|
|
} else if (start) {
|
|
result = result.drop(start);
|
|
}
|
|
if (end !== undefined) {
|
|
end = toInteger(end);
|
|
result = end < 0 ? result.dropRight(-end) : result.take(end - start);
|
|
}
|
|
return result;
|
|
};
|
|
|
|
LazyWrapper.prototype.takeRightWhile = function(predicate) {
|
|
return this.reverse().takeWhile(predicate).reverse();
|
|
};
|
|
|
|
LazyWrapper.prototype.toArray = function() {
|
|
return this.take(MAX_ARRAY_LENGTH);
|
|
};
|
|
|
|
// Add `LazyWrapper` methods to `lodash.prototype`.
|
|
baseForOwn(LazyWrapper.prototype, function(func, methodName) {
|
|
var checkIteratee = /^(?:filter|find|map|reject)|While$/.test(methodName),
|
|
isTaker = /^(?:head|last)$/.test(methodName),
|
|
lodashFunc = lodash[isTaker ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName],
|
|
retUnwrapped = isTaker || /^find/.test(methodName);
|
|
|
|
if (!lodashFunc) {
|
|
return;
|
|
}
|
|
lodash.prototype[methodName] = function() {
|
|
var value = this.__wrapped__,
|
|
args = isTaker ? [1] : arguments,
|
|
isLazy = value instanceof LazyWrapper,
|
|
iteratee = args[0],
|
|
useLazy = isLazy || isArray(value);
|
|
|
|
var interceptor = function(value) {
|
|
var result = lodashFunc.apply(lodash, arrayPush([value], args));
|
|
return (isTaker && chainAll) ? result[0] : result;
|
|
};
|
|
|
|
if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) {
|
|
// Avoid lazy use if the iteratee has a "length" value other than `1`.
|
|
isLazy = useLazy = false;
|
|
}
|
|
var chainAll = this.__chain__,
|
|
isHybrid = !!this.__actions__.length,
|
|
isUnwrapped = retUnwrapped && !chainAll,
|
|
onlyLazy = isLazy && !isHybrid;
|
|
|
|
if (!retUnwrapped && useLazy) {
|
|
value = onlyLazy ? value : new LazyWrapper(this);
|
|
var result = func.apply(value, args);
|
|
result.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });
|
|
return new LodashWrapper(result, chainAll);
|
|
}
|
|
if (isUnwrapped && onlyLazy) {
|
|
return func.apply(this, args);
|
|
}
|
|
result = this.thru(interceptor);
|
|
return isUnwrapped ? (isTaker ? result.value()[0] : result.value()) : result;
|
|
};
|
|
});
|
|
|
|
// Add `Array` methods to `lodash.prototype`.
|
|
arrayEach(['pop', 'push', 'shift', 'sort', 'splice', 'unshift'], function(methodName) {
|
|
var func = arrayProto[methodName],
|
|
chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru',
|
|
retUnwrapped = /^(?:pop|shift)$/.test(methodName);
|
|
|
|
lodash.prototype[methodName] = function() {
|
|
var args = arguments;
|
|
if (retUnwrapped && !this.__chain__) {
|
|
var value = this.value();
|
|
return func.apply(isArray(value) ? value : [], args);
|
|
}
|
|
return this[chainName](function(value) {
|
|
return func.apply(isArray(value) ? value : [], args);
|
|
});
|
|
};
|
|
});
|
|
|
|
// Map minified method names to their real names.
|
|
baseForOwn(LazyWrapper.prototype, function(func, methodName) {
|
|
var lodashFunc = lodash[methodName];
|
|
if (lodashFunc) {
|
|
var key = lodashFunc.name + '';
|
|
if (!hasOwnProperty.call(realNames, key)) {
|
|
realNames[key] = [];
|
|
}
|
|
realNames[key].push({ 'name': methodName, 'func': lodashFunc });
|
|
}
|
|
});
|
|
|
|
realNames[createHybrid(undefined, WRAP_BIND_KEY_FLAG).name] = [{
|
|
'name': 'wrapper',
|
|
'func': undefined
|
|
}];
|
|
|
|
// Add methods to `LazyWrapper`.
|
|
LazyWrapper.prototype.clone = lazyClone;
|
|
LazyWrapper.prototype.reverse = lazyReverse;
|
|
LazyWrapper.prototype.value = lazyValue;
|
|
|
|
// Add chain sequence methods to the `lodash` wrapper.
|
|
lodash.prototype.at = wrapperAt;
|
|
lodash.prototype.chain = wrapperChain;
|
|
lodash.prototype.commit = wrapperCommit;
|
|
lodash.prototype.next = wrapperNext;
|
|
lodash.prototype.plant = wrapperPlant;
|
|
lodash.prototype.reverse = wrapperReverse;
|
|
lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue;
|
|
|
|
// Add lazy aliases.
|
|
lodash.prototype.first = lodash.prototype.head;
|
|
|
|
if (symIterator) {
|
|
lodash.prototype[symIterator] = wrapperToIterator;
|
|
}
|
|
return lodash;
|
|
});
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
// Export lodash.
|
|
var _ = runInContext();
|
|
|
|
// Some AMD build optimizers, like r.js, check for condition patterns like:
|
|
if (true) {
|
|
// Expose Lodash on the global object to prevent errors when Lodash is
|
|
// loaded by a script tag in the presence of an AMD loader.
|
|
// See http://requirejs.org/docs/errors.html#mismatch for more details.
|
|
// Use `_.noConflict` to remove Lodash from the global object.
|
|
root._ = _;
|
|
|
|
// Define as an anonymous module so, through path mapping, it can be
|
|
// referenced as the "underscore" module.
|
|
!(__WEBPACK_AMD_DEFINE_RESULT__ = (function() {
|
|
return _;
|
|
}).call(exports, __webpack_require__, exports, module),
|
|
__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
|
|
}
|
|
// Check for `exports` after `define` in case a build optimizer adds it.
|
|
else {}
|
|
}.call(this));
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./resources/scss/app.scss":
|
|
/*!*********************************!*\
|
|
!*** ./resources/scss/app.scss ***!
|
|
\*********************************/
|
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
__webpack_require__.r(__webpack_exports__);
|
|
// extracted by mini-css-extract-plugin
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/process/browser.js":
|
|
/*!*****************************************!*\
|
|
!*** ./node_modules/process/browser.js ***!
|
|
\*****************************************/
|
|
/***/ ((module) => {
|
|
|
|
// shim for using process in browser
|
|
var process = module.exports = {};
|
|
|
|
// cached from whatever global is present so that test runners that stub it
|
|
// don't break things. But we need to wrap it in a try catch in case it is
|
|
// wrapped in strict mode code which doesn't define any globals. It's inside a
|
|
// function because try/catches deoptimize in certain engines.
|
|
|
|
var cachedSetTimeout;
|
|
var cachedClearTimeout;
|
|
|
|
function defaultSetTimout() {
|
|
throw new Error('setTimeout has not been defined');
|
|
}
|
|
function defaultClearTimeout () {
|
|
throw new Error('clearTimeout has not been defined');
|
|
}
|
|
(function () {
|
|
try {
|
|
if (typeof setTimeout === 'function') {
|
|
cachedSetTimeout = setTimeout;
|
|
} else {
|
|
cachedSetTimeout = defaultSetTimout;
|
|
}
|
|
} catch (e) {
|
|
cachedSetTimeout = defaultSetTimout;
|
|
}
|
|
try {
|
|
if (typeof clearTimeout === 'function') {
|
|
cachedClearTimeout = clearTimeout;
|
|
} else {
|
|
cachedClearTimeout = defaultClearTimeout;
|
|
}
|
|
} catch (e) {
|
|
cachedClearTimeout = defaultClearTimeout;
|
|
}
|
|
} ())
|
|
function runTimeout(fun) {
|
|
if (cachedSetTimeout === setTimeout) {
|
|
//normal enviroments in sane situations
|
|
return setTimeout(fun, 0);
|
|
}
|
|
// if setTimeout wasn't available but was latter defined
|
|
if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
|
|
cachedSetTimeout = setTimeout;
|
|
return setTimeout(fun, 0);
|
|
}
|
|
try {
|
|
// when when somebody has screwed with setTimeout but no I.E. maddness
|
|
return cachedSetTimeout(fun, 0);
|
|
} catch(e){
|
|
try {
|
|
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
|
|
return cachedSetTimeout.call(null, fun, 0);
|
|
} catch(e){
|
|
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
|
|
return cachedSetTimeout.call(this, fun, 0);
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
function runClearTimeout(marker) {
|
|
if (cachedClearTimeout === clearTimeout) {
|
|
//normal enviroments in sane situations
|
|
return clearTimeout(marker);
|
|
}
|
|
// if clearTimeout wasn't available but was latter defined
|
|
if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
|
|
cachedClearTimeout = clearTimeout;
|
|
return clearTimeout(marker);
|
|
}
|
|
try {
|
|
// when when somebody has screwed with setTimeout but no I.E. maddness
|
|
return cachedClearTimeout(marker);
|
|
} catch (e){
|
|
try {
|
|
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
|
|
return cachedClearTimeout.call(null, marker);
|
|
} catch (e){
|
|
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
|
|
// Some versions of I.E. have different rules for clearTimeout vs setTimeout
|
|
return cachedClearTimeout.call(this, marker);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
}
|
|
var queue = [];
|
|
var draining = false;
|
|
var currentQueue;
|
|
var queueIndex = -1;
|
|
|
|
function cleanUpNextTick() {
|
|
if (!draining || !currentQueue) {
|
|
return;
|
|
}
|
|
draining = false;
|
|
if (currentQueue.length) {
|
|
queue = currentQueue.concat(queue);
|
|
} else {
|
|
queueIndex = -1;
|
|
}
|
|
if (queue.length) {
|
|
drainQueue();
|
|
}
|
|
}
|
|
|
|
function drainQueue() {
|
|
if (draining) {
|
|
return;
|
|
}
|
|
var timeout = runTimeout(cleanUpNextTick);
|
|
draining = true;
|
|
|
|
var len = queue.length;
|
|
while(len) {
|
|
currentQueue = queue;
|
|
queue = [];
|
|
while (++queueIndex < len) {
|
|
if (currentQueue) {
|
|
currentQueue[queueIndex].run();
|
|
}
|
|
}
|
|
queueIndex = -1;
|
|
len = queue.length;
|
|
}
|
|
currentQueue = null;
|
|
draining = false;
|
|
runClearTimeout(timeout);
|
|
}
|
|
|
|
process.nextTick = function (fun) {
|
|
var args = new Array(arguments.length - 1);
|
|
if (arguments.length > 1) {
|
|
for (var i = 1; i < arguments.length; i++) {
|
|
args[i - 1] = arguments[i];
|
|
}
|
|
}
|
|
queue.push(new Item(fun, args));
|
|
if (queue.length === 1 && !draining) {
|
|
runTimeout(drainQueue);
|
|
}
|
|
};
|
|
|
|
// v8 likes predictible objects
|
|
function Item(fun, array) {
|
|
this.fun = fun;
|
|
this.array = array;
|
|
}
|
|
Item.prototype.run = function () {
|
|
this.fun.apply(null, this.array);
|
|
};
|
|
process.title = 'browser';
|
|
process.browser = true;
|
|
process.env = {};
|
|
process.argv = [];
|
|
process.version = ''; // empty string to avoid regexp issues
|
|
process.versions = {};
|
|
|
|
function noop() {}
|
|
|
|
process.on = noop;
|
|
process.addListener = noop;
|
|
process.once = noop;
|
|
process.off = noop;
|
|
process.removeListener = noop;
|
|
process.removeAllListeners = noop;
|
|
process.emit = noop;
|
|
process.prependListener = noop;
|
|
process.prependOnceListener = noop;
|
|
|
|
process.listeners = function (name) { return [] }
|
|
|
|
process.binding = function (name) {
|
|
throw new Error('process.binding is not supported');
|
|
};
|
|
|
|
process.cwd = function () { return '/' };
|
|
process.chdir = function (dir) {
|
|
throw new Error('process.chdir is not supported');
|
|
};
|
|
process.umask = function() { return 0; };
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./resources/js/apps/App.vue":
|
|
/*!***********************************!*\
|
|
!*** ./resources/js/apps/App.vue ***!
|
|
\***********************************/
|
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
|
|
/* harmony export */ });
|
|
/* harmony import */ var _App_vue_vue_type_template_id_2dea4962__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./App.vue?vue&type=template&id=2dea4962 */ "./resources/js/apps/App.vue?vue&type=template&id=2dea4962");
|
|
|
|
const script = {}
|
|
script.render = _App_vue_vue_type_template_id_2dea4962__WEBPACK_IMPORTED_MODULE_0__.render
|
|
/* hot reload */
|
|
if (false) {}
|
|
|
|
script.__file = "resources/js/apps/App.vue"
|
|
|
|
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (script);
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./resources/js/components/BlogPopular.vue":
|
|
/*!*************************************************!*\
|
|
!*** ./resources/js/components/BlogPopular.vue ***!
|
|
\*************************************************/
|
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
|
|
/* harmony export */ });
|
|
/* harmony import */ var _BlogPopular_vue_vue_type_template_id_3498cf88__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./BlogPopular.vue?vue&type=template&id=3498cf88 */ "./resources/js/components/BlogPopular.vue?vue&type=template&id=3498cf88");
|
|
|
|
const script = {}
|
|
script.render = _BlogPopular_vue_vue_type_template_id_3498cf88__WEBPACK_IMPORTED_MODULE_0__.render
|
|
/* hot reload */
|
|
if (false) {}
|
|
|
|
script.__file = "resources/js/components/BlogPopular.vue"
|
|
|
|
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (script);
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./resources/js/components/BlogRecent.vue":
|
|
/*!************************************************!*\
|
|
!*** ./resources/js/components/BlogRecent.vue ***!
|
|
\************************************************/
|
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
|
|
/* harmony export */ });
|
|
/* harmony import */ var _BlogRecent_vue_vue_type_template_id_6b89b6c8__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./BlogRecent.vue?vue&type=template&id=6b89b6c8 */ "./resources/js/components/BlogRecent.vue?vue&type=template&id=6b89b6c8");
|
|
|
|
const script = {}
|
|
script.render = _BlogRecent_vue_vue_type_template_id_6b89b6c8__WEBPACK_IMPORTED_MODULE_0__.render
|
|
/* hot reload */
|
|
if (false) {}
|
|
|
|
script.__file = "resources/js/components/BlogRecent.vue"
|
|
|
|
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (script);
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./resources/js/components/Container.vue":
|
|
/*!***********************************************!*\
|
|
!*** ./resources/js/components/Container.vue ***!
|
|
\***********************************************/
|
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
|
|
/* harmony export */ });
|
|
/* harmony import */ var _Container_vue_vue_type_template_id_ba1063b4__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Container.vue?vue&type=template&id=ba1063b4 */ "./resources/js/components/Container.vue?vue&type=template&id=ba1063b4");
|
|
|
|
const script = {}
|
|
script.render = _Container_vue_vue_type_template_id_ba1063b4__WEBPACK_IMPORTED_MODULE_0__.render
|
|
/* hot reload */
|
|
if (false) {}
|
|
|
|
script.__file = "resources/js/components/Container.vue"
|
|
|
|
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (script);
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./resources/js/components/PageFooter.vue":
|
|
/*!************************************************!*\
|
|
!*** ./resources/js/components/PageFooter.vue ***!
|
|
\************************************************/
|
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
|
|
/* harmony export */ });
|
|
/* harmony import */ var _PageFooter_vue_vue_type_template_id_5e81b4b5__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./PageFooter.vue?vue&type=template&id=5e81b4b5 */ "./resources/js/components/PageFooter.vue?vue&type=template&id=5e81b4b5");
|
|
|
|
const script = {}
|
|
script.render = _PageFooter_vue_vue_type_template_id_5e81b4b5__WEBPACK_IMPORTED_MODULE_0__.render
|
|
/* hot reload */
|
|
if (false) {}
|
|
|
|
script.__file = "resources/js/components/PageFooter.vue"
|
|
|
|
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (script);
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./resources/js/components/PageHeader.vue":
|
|
/*!************************************************!*\
|
|
!*** ./resources/js/components/PageHeader.vue ***!
|
|
\************************************************/
|
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
|
|
/* harmony export */ });
|
|
/* harmony import */ var _PageHeader_vue_vue_type_template_id_7fb418a7__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./PageHeader.vue?vue&type=template&id=7fb418a7 */ "./resources/js/components/PageHeader.vue?vue&type=template&id=7fb418a7");
|
|
|
|
const script = {}
|
|
script.render = _PageHeader_vue_vue_type_template_id_7fb418a7__WEBPACK_IMPORTED_MODULE_0__.render
|
|
/* hot reload */
|
|
if (false) {}
|
|
|
|
script.__file = "resources/js/components/PageHeader.vue"
|
|
|
|
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (script);
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./resources/js/components/SplitContent.vue":
|
|
/*!**************************************************!*\
|
|
!*** ./resources/js/components/SplitContent.vue ***!
|
|
\**************************************************/
|
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
|
|
/* harmony export */ });
|
|
/* harmony import */ var _SplitContent_vue_vue_type_template_id_1553872c__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./SplitContent.vue?vue&type=template&id=1553872c */ "./resources/js/components/SplitContent.vue?vue&type=template&id=1553872c");
|
|
|
|
const script = {}
|
|
script.render = _SplitContent_vue_vue_type_template_id_1553872c__WEBPACK_IMPORTED_MODULE_0__.render
|
|
/* hot reload */
|
|
if (false) {}
|
|
|
|
script.__file = "resources/js/components/SplitContent.vue"
|
|
|
|
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (script);
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./resources/js/views/Home.vue":
|
|
/*!*************************************!*\
|
|
!*** ./resources/js/views/Home.vue ***!
|
|
\*************************************/
|
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
|
|
/* harmony export */ });
|
|
/* harmony import */ var _Home_vue_vue_type_template_id_63cd6604__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Home.vue?vue&type=template&id=63cd6604 */ "./resources/js/views/Home.vue?vue&type=template&id=63cd6604");
|
|
/* harmony import */ var _Home_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Home.vue?vue&type=script&lang=js */ "./resources/js/views/Home.vue?vue&type=script&lang=js");
|
|
|
|
|
|
|
|
_Home_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__.default.render = _Home_vue_vue_type_template_id_63cd6604__WEBPACK_IMPORTED_MODULE_0__.render
|
|
/* hot reload */
|
|
if (false) {}
|
|
|
|
_Home_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__.default.__file = "resources/js/views/Home.vue"
|
|
|
|
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (_Home_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_1__.default);
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./resources/js/views/Home.vue?vue&type=script&lang=js":
|
|
/*!*************************************************************!*\
|
|
!*** ./resources/js/views/Home.vue?vue&type=script&lang=js ***!
|
|
\*************************************************************/
|
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ "default": () => (/* reexport safe */ _node_modules_babel_loader_lib_index_js_clonedRuleSet_5_use_0_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_Home_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_0__.default)
|
|
/* harmony export */ });
|
|
/* harmony import */ var _node_modules_babel_loader_lib_index_js_clonedRuleSet_5_use_0_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_Home_vue_vue_type_script_lang_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../node_modules/babel-loader/lib/index.js??clonedRuleSet-5.use[0]!../../../node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./Home.vue?vue&type=script&lang=js */ "./node_modules/babel-loader/lib/index.js??clonedRuleSet-5.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./resources/js/views/Home.vue?vue&type=script&lang=js");
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./resources/js/apps/App.vue?vue&type=template&id=2dea4962":
|
|
/*!*****************************************************************!*\
|
|
!*** ./resources/js/apps/App.vue?vue&type=template&id=2dea4962 ***!
|
|
\*****************************************************************/
|
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ "render": () => (/* reexport safe */ _node_modules_babel_loader_lib_index_js_clonedRuleSet_5_use_0_node_modules_vue_loader_dist_templateLoader_js_ruleSet_1_rules_2_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_App_vue_vue_type_template_id_2dea4962__WEBPACK_IMPORTED_MODULE_0__.render)
|
|
/* harmony export */ });
|
|
/* harmony import */ var _node_modules_babel_loader_lib_index_js_clonedRuleSet_5_use_0_node_modules_vue_loader_dist_templateLoader_js_ruleSet_1_rules_2_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_App_vue_vue_type_template_id_2dea4962__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../node_modules/babel-loader/lib/index.js??clonedRuleSet-5.use[0]!../../../node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!../../../node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./App.vue?vue&type=template&id=2dea4962 */ "./node_modules/babel-loader/lib/index.js??clonedRuleSet-5.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./resources/js/apps/App.vue?vue&type=template&id=2dea4962");
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./resources/js/components/BlogPopular.vue?vue&type=template&id=3498cf88":
|
|
/*!*******************************************************************************!*\
|
|
!*** ./resources/js/components/BlogPopular.vue?vue&type=template&id=3498cf88 ***!
|
|
\*******************************************************************************/
|
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ "render": () => (/* reexport safe */ _node_modules_babel_loader_lib_index_js_clonedRuleSet_5_use_0_node_modules_vue_loader_dist_templateLoader_js_ruleSet_1_rules_2_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_BlogPopular_vue_vue_type_template_id_3498cf88__WEBPACK_IMPORTED_MODULE_0__.render)
|
|
/* harmony export */ });
|
|
/* harmony import */ var _node_modules_babel_loader_lib_index_js_clonedRuleSet_5_use_0_node_modules_vue_loader_dist_templateLoader_js_ruleSet_1_rules_2_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_BlogPopular_vue_vue_type_template_id_3498cf88__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../node_modules/babel-loader/lib/index.js??clonedRuleSet-5.use[0]!../../../node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!../../../node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./BlogPopular.vue?vue&type=template&id=3498cf88 */ "./node_modules/babel-loader/lib/index.js??clonedRuleSet-5.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./resources/js/components/BlogPopular.vue?vue&type=template&id=3498cf88");
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./resources/js/components/BlogRecent.vue?vue&type=template&id=6b89b6c8":
|
|
/*!******************************************************************************!*\
|
|
!*** ./resources/js/components/BlogRecent.vue?vue&type=template&id=6b89b6c8 ***!
|
|
\******************************************************************************/
|
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ "render": () => (/* reexport safe */ _node_modules_babel_loader_lib_index_js_clonedRuleSet_5_use_0_node_modules_vue_loader_dist_templateLoader_js_ruleSet_1_rules_2_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_BlogRecent_vue_vue_type_template_id_6b89b6c8__WEBPACK_IMPORTED_MODULE_0__.render)
|
|
/* harmony export */ });
|
|
/* harmony import */ var _node_modules_babel_loader_lib_index_js_clonedRuleSet_5_use_0_node_modules_vue_loader_dist_templateLoader_js_ruleSet_1_rules_2_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_BlogRecent_vue_vue_type_template_id_6b89b6c8__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../node_modules/babel-loader/lib/index.js??clonedRuleSet-5.use[0]!../../../node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!../../../node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./BlogRecent.vue?vue&type=template&id=6b89b6c8 */ "./node_modules/babel-loader/lib/index.js??clonedRuleSet-5.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./resources/js/components/BlogRecent.vue?vue&type=template&id=6b89b6c8");
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./resources/js/components/Container.vue?vue&type=template&id=ba1063b4":
|
|
/*!*****************************************************************************!*\
|
|
!*** ./resources/js/components/Container.vue?vue&type=template&id=ba1063b4 ***!
|
|
\*****************************************************************************/
|
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ "render": () => (/* reexport safe */ _node_modules_babel_loader_lib_index_js_clonedRuleSet_5_use_0_node_modules_vue_loader_dist_templateLoader_js_ruleSet_1_rules_2_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_Container_vue_vue_type_template_id_ba1063b4__WEBPACK_IMPORTED_MODULE_0__.render)
|
|
/* harmony export */ });
|
|
/* harmony import */ var _node_modules_babel_loader_lib_index_js_clonedRuleSet_5_use_0_node_modules_vue_loader_dist_templateLoader_js_ruleSet_1_rules_2_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_Container_vue_vue_type_template_id_ba1063b4__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../node_modules/babel-loader/lib/index.js??clonedRuleSet-5.use[0]!../../../node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!../../../node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./Container.vue?vue&type=template&id=ba1063b4 */ "./node_modules/babel-loader/lib/index.js??clonedRuleSet-5.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./resources/js/components/Container.vue?vue&type=template&id=ba1063b4");
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./resources/js/components/PageFooter.vue?vue&type=template&id=5e81b4b5":
|
|
/*!******************************************************************************!*\
|
|
!*** ./resources/js/components/PageFooter.vue?vue&type=template&id=5e81b4b5 ***!
|
|
\******************************************************************************/
|
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ "render": () => (/* reexport safe */ _node_modules_babel_loader_lib_index_js_clonedRuleSet_5_use_0_node_modules_vue_loader_dist_templateLoader_js_ruleSet_1_rules_2_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_PageFooter_vue_vue_type_template_id_5e81b4b5__WEBPACK_IMPORTED_MODULE_0__.render)
|
|
/* harmony export */ });
|
|
/* harmony import */ var _node_modules_babel_loader_lib_index_js_clonedRuleSet_5_use_0_node_modules_vue_loader_dist_templateLoader_js_ruleSet_1_rules_2_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_PageFooter_vue_vue_type_template_id_5e81b4b5__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../node_modules/babel-loader/lib/index.js??clonedRuleSet-5.use[0]!../../../node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!../../../node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./PageFooter.vue?vue&type=template&id=5e81b4b5 */ "./node_modules/babel-loader/lib/index.js??clonedRuleSet-5.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./resources/js/components/PageFooter.vue?vue&type=template&id=5e81b4b5");
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./resources/js/components/PageHeader.vue?vue&type=template&id=7fb418a7":
|
|
/*!******************************************************************************!*\
|
|
!*** ./resources/js/components/PageHeader.vue?vue&type=template&id=7fb418a7 ***!
|
|
\******************************************************************************/
|
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ "render": () => (/* reexport safe */ _node_modules_babel_loader_lib_index_js_clonedRuleSet_5_use_0_node_modules_vue_loader_dist_templateLoader_js_ruleSet_1_rules_2_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_PageHeader_vue_vue_type_template_id_7fb418a7__WEBPACK_IMPORTED_MODULE_0__.render)
|
|
/* harmony export */ });
|
|
/* harmony import */ var _node_modules_babel_loader_lib_index_js_clonedRuleSet_5_use_0_node_modules_vue_loader_dist_templateLoader_js_ruleSet_1_rules_2_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_PageHeader_vue_vue_type_template_id_7fb418a7__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../node_modules/babel-loader/lib/index.js??clonedRuleSet-5.use[0]!../../../node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!../../../node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./PageHeader.vue?vue&type=template&id=7fb418a7 */ "./node_modules/babel-loader/lib/index.js??clonedRuleSet-5.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./resources/js/components/PageHeader.vue?vue&type=template&id=7fb418a7");
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./resources/js/components/SplitContent.vue?vue&type=template&id=1553872c":
|
|
/*!********************************************************************************!*\
|
|
!*** ./resources/js/components/SplitContent.vue?vue&type=template&id=1553872c ***!
|
|
\********************************************************************************/
|
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ "render": () => (/* reexport safe */ _node_modules_babel_loader_lib_index_js_clonedRuleSet_5_use_0_node_modules_vue_loader_dist_templateLoader_js_ruleSet_1_rules_2_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_SplitContent_vue_vue_type_template_id_1553872c__WEBPACK_IMPORTED_MODULE_0__.render)
|
|
/* harmony export */ });
|
|
/* harmony import */ var _node_modules_babel_loader_lib_index_js_clonedRuleSet_5_use_0_node_modules_vue_loader_dist_templateLoader_js_ruleSet_1_rules_2_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_SplitContent_vue_vue_type_template_id_1553872c__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../node_modules/babel-loader/lib/index.js??clonedRuleSet-5.use[0]!../../../node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!../../../node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./SplitContent.vue?vue&type=template&id=1553872c */ "./node_modules/babel-loader/lib/index.js??clonedRuleSet-5.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./resources/js/components/SplitContent.vue?vue&type=template&id=1553872c");
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./resources/js/views/Home.vue?vue&type=template&id=63cd6604":
|
|
/*!*******************************************************************!*\
|
|
!*** ./resources/js/views/Home.vue?vue&type=template&id=63cd6604 ***!
|
|
\*******************************************************************/
|
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ "render": () => (/* reexport safe */ _node_modules_babel_loader_lib_index_js_clonedRuleSet_5_use_0_node_modules_vue_loader_dist_templateLoader_js_ruleSet_1_rules_2_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_Home_vue_vue_type_template_id_63cd6604__WEBPACK_IMPORTED_MODULE_0__.render)
|
|
/* harmony export */ });
|
|
/* harmony import */ var _node_modules_babel_loader_lib_index_js_clonedRuleSet_5_use_0_node_modules_vue_loader_dist_templateLoader_js_ruleSet_1_rules_2_node_modules_vue_loader_dist_index_js_ruleSet_0_use_0_Home_vue_vue_type_template_id_63cd6604__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../../node_modules/babel-loader/lib/index.js??clonedRuleSet-5.use[0]!../../../node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!../../../node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./Home.vue?vue&type=template&id=63cd6604 */ "./node_modules/babel-loader/lib/index.js??clonedRuleSet-5.use[0]!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./resources/js/views/Home.vue?vue&type=template&id=63cd6604");
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/vue-router/dist/vue-router.esm-bundler.js":
|
|
/*!****************************************************************!*\
|
|
!*** ./node_modules/vue-router/dist/vue-router.esm-bundler.js ***!
|
|
\****************************************************************/
|
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ "NavigationFailureType": () => (/* binding */ NavigationFailureType),
|
|
/* harmony export */ "RouterLink": () => (/* binding */ RouterLink),
|
|
/* harmony export */ "RouterView": () => (/* binding */ RouterView),
|
|
/* harmony export */ "START_LOCATION": () => (/* binding */ START_LOCATION_NORMALIZED),
|
|
/* harmony export */ "createMemoryHistory": () => (/* binding */ createMemoryHistory),
|
|
/* harmony export */ "createRouter": () => (/* binding */ createRouter),
|
|
/* harmony export */ "createRouterMatcher": () => (/* binding */ createRouterMatcher),
|
|
/* harmony export */ "createWebHashHistory": () => (/* binding */ createWebHashHistory),
|
|
/* harmony export */ "createWebHistory": () => (/* binding */ createWebHistory),
|
|
/* harmony export */ "isNavigationFailure": () => (/* binding */ isNavigationFailure),
|
|
/* harmony export */ "matchedRouteKey": () => (/* binding */ matchedRouteKey),
|
|
/* harmony export */ "onBeforeRouteLeave": () => (/* binding */ onBeforeRouteLeave),
|
|
/* harmony export */ "onBeforeRouteUpdate": () => (/* binding */ onBeforeRouteUpdate),
|
|
/* harmony export */ "parseQuery": () => (/* binding */ parseQuery),
|
|
/* harmony export */ "routeLocationKey": () => (/* binding */ routeLocationKey),
|
|
/* harmony export */ "routerKey": () => (/* binding */ routerKey),
|
|
/* harmony export */ "routerViewLocationKey": () => (/* binding */ routerViewLocationKey),
|
|
/* harmony export */ "stringifyQuery": () => (/* binding */ stringifyQuery),
|
|
/* harmony export */ "useLink": () => (/* binding */ useLink),
|
|
/* harmony export */ "useRoute": () => (/* binding */ useRoute),
|
|
/* harmony export */ "useRouter": () => (/* binding */ useRouter),
|
|
/* harmony export */ "viewDepthKey": () => (/* binding */ viewDepthKey)
|
|
/* harmony export */ });
|
|
/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.esm-bundler.js");
|
|
/* harmony import */ var _vue_devtools_api__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @vue/devtools-api */ "./node_modules/@vue/devtools-api/lib/esm/index.js");
|
|
/*!
|
|
* vue-router v4.0.11
|
|
* (c) 2021 Eduardo San Martin Morote
|
|
* @license MIT
|
|
*/
|
|
|
|
|
|
|
|
const hasSymbol = typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol';
|
|
const PolySymbol = (name) =>
|
|
// vr = vue router
|
|
hasSymbol
|
|
? Symbol(( true) ? '[vue-router]: ' + name : 0)
|
|
: (( true) ? '[vue-router]: ' : 0) + name;
|
|
// rvlm = Router View Location Matched
|
|
/**
|
|
* RouteRecord being rendered by the closest ancestor Router View. Used for
|
|
* `onBeforeRouteUpdate` and `onBeforeRouteLeave`. rvlm stands for Router View
|
|
* Location Matched
|
|
*
|
|
* @internal
|
|
*/
|
|
const matchedRouteKey = /*#__PURE__*/ PolySymbol(( true) ? 'router view location matched' : 0);
|
|
/**
|
|
* Allows overriding the router view depth to control which component in
|
|
* `matched` is rendered. rvd stands for Router View Depth
|
|
*
|
|
* @internal
|
|
*/
|
|
const viewDepthKey = /*#__PURE__*/ PolySymbol(( true) ? 'router view depth' : 0);
|
|
/**
|
|
* Allows overriding the router instance returned by `useRouter` in tests. r
|
|
* stands for router
|
|
*
|
|
* @internal
|
|
*/
|
|
const routerKey = /*#__PURE__*/ PolySymbol(( true) ? 'router' : 0);
|
|
/**
|
|
* Allows overriding the current route returned by `useRoute` in tests. rl
|
|
* stands for route location
|
|
*
|
|
* @internal
|
|
*/
|
|
const routeLocationKey = /*#__PURE__*/ PolySymbol(( true) ? 'route location' : 0);
|
|
/**
|
|
* Allows overriding the current route used by router-view. Internally this is
|
|
* used when the `route` prop is passed.
|
|
*
|
|
* @internal
|
|
*/
|
|
const routerViewLocationKey = /*#__PURE__*/ PolySymbol(( true) ? 'router view location' : 0);
|
|
|
|
const isBrowser = typeof window !== 'undefined';
|
|
|
|
function isESModule(obj) {
|
|
return obj.__esModule || (hasSymbol && obj[Symbol.toStringTag] === 'Module');
|
|
}
|
|
const assign = Object.assign;
|
|
function applyToParams(fn, params) {
|
|
const newParams = {};
|
|
for (const key in params) {
|
|
const value = params[key];
|
|
newParams[key] = Array.isArray(value) ? value.map(fn) : fn(value);
|
|
}
|
|
return newParams;
|
|
}
|
|
const noop = () => { };
|
|
|
|
function warn(msg) {
|
|
// avoid using ...args as it breaks in older Edge builds
|
|
const args = Array.from(arguments).slice(1);
|
|
console.warn.apply(console, ['[Vue Router warn]: ' + msg].concat(args));
|
|
}
|
|
|
|
const TRAILING_SLASH_RE = /\/$/;
|
|
const removeTrailingSlash = (path) => path.replace(TRAILING_SLASH_RE, '');
|
|
/**
|
|
* Transforms an URI into a normalized history location
|
|
*
|
|
* @param parseQuery
|
|
* @param location - URI to normalize
|
|
* @param currentLocation - current absolute location. Allows resolving relative
|
|
* paths. Must start with `/`. Defaults to `/`
|
|
* @returns a normalized history location
|
|
*/
|
|
function parseURL(parseQuery, location, currentLocation = '/') {
|
|
let path, query = {}, searchString = '', hash = '';
|
|
// Could use URL and URLSearchParams but IE 11 doesn't support it
|
|
const searchPos = location.indexOf('?');
|
|
const hashPos = location.indexOf('#', searchPos > -1 ? searchPos : 0);
|
|
if (searchPos > -1) {
|
|
path = location.slice(0, searchPos);
|
|
searchString = location.slice(searchPos + 1, hashPos > -1 ? hashPos : location.length);
|
|
query = parseQuery(searchString);
|
|
}
|
|
if (hashPos > -1) {
|
|
path = path || location.slice(0, hashPos);
|
|
// keep the # character
|
|
hash = location.slice(hashPos, location.length);
|
|
}
|
|
// no search and no query
|
|
path = resolveRelativePath(path != null ? path : location, currentLocation);
|
|
// empty path means a relative query or hash `?foo=f`, `#thing`
|
|
return {
|
|
fullPath: path + (searchString && '?') + searchString + hash,
|
|
path,
|
|
query,
|
|
hash,
|
|
};
|
|
}
|
|
/**
|
|
* Stringifies a URL object
|
|
*
|
|
* @param stringifyQuery
|
|
* @param location
|
|
*/
|
|
function stringifyURL(stringifyQuery, location) {
|
|
const query = location.query ? stringifyQuery(location.query) : '';
|
|
return location.path + (query && '?') + query + (location.hash || '');
|
|
}
|
|
/**
|
|
* Strips off the base from the beginning of a location.pathname in a non
|
|
* case-sensitive way.
|
|
*
|
|
* @param pathname - location.pathname
|
|
* @param base - base to strip off
|
|
*/
|
|
function stripBase(pathname, base) {
|
|
// no base or base is not found at the beginning
|
|
if (!base || !pathname.toLowerCase().startsWith(base.toLowerCase()))
|
|
return pathname;
|
|
return pathname.slice(base.length) || '/';
|
|
}
|
|
/**
|
|
* Checks if two RouteLocation are equal. This means that both locations are
|
|
* pointing towards the same {@link RouteRecord} and that all `params`, `query`
|
|
* parameters and `hash` are the same
|
|
*
|
|
* @param a - first {@link RouteLocation}
|
|
* @param b - second {@link RouteLocation}
|
|
*/
|
|
function isSameRouteLocation(stringifyQuery, a, b) {
|
|
const aLastIndex = a.matched.length - 1;
|
|
const bLastIndex = b.matched.length - 1;
|
|
return (aLastIndex > -1 &&
|
|
aLastIndex === bLastIndex &&
|
|
isSameRouteRecord(a.matched[aLastIndex], b.matched[bLastIndex]) &&
|
|
isSameRouteLocationParams(a.params, b.params) &&
|
|
stringifyQuery(a.query) === stringifyQuery(b.query) &&
|
|
a.hash === b.hash);
|
|
}
|
|
/**
|
|
* Check if two `RouteRecords` are equal. Takes into account aliases: they are
|
|
* considered equal to the `RouteRecord` they are aliasing.
|
|
*
|
|
* @param a - first {@link RouteRecord}
|
|
* @param b - second {@link RouteRecord}
|
|
*/
|
|
function isSameRouteRecord(a, b) {
|
|
// since the original record has an undefined value for aliasOf
|
|
// but all aliases point to the original record, this will always compare
|
|
// the original record
|
|
return (a.aliasOf || a) === (b.aliasOf || b);
|
|
}
|
|
function isSameRouteLocationParams(a, b) {
|
|
if (Object.keys(a).length !== Object.keys(b).length)
|
|
return false;
|
|
for (const key in a) {
|
|
if (!isSameRouteLocationParamsValue(a[key], b[key]))
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
function isSameRouteLocationParamsValue(a, b) {
|
|
return Array.isArray(a)
|
|
? isEquivalentArray(a, b)
|
|
: Array.isArray(b)
|
|
? isEquivalentArray(b, a)
|
|
: a === b;
|
|
}
|
|
/**
|
|
* Check if two arrays are the same or if an array with one single entry is the
|
|
* same as another primitive value. Used to check query and parameters
|
|
*
|
|
* @param a - array of values
|
|
* @param b - array of values or a single value
|
|
*/
|
|
function isEquivalentArray(a, b) {
|
|
return Array.isArray(b)
|
|
? a.length === b.length && a.every((value, i) => value === b[i])
|
|
: a.length === 1 && a[0] === b;
|
|
}
|
|
/**
|
|
* Resolves a relative path that starts with `.`.
|
|
*
|
|
* @param to - path location we are resolving
|
|
* @param from - currentLocation.path, should start with `/`
|
|
*/
|
|
function resolveRelativePath(to, from) {
|
|
if (to.startsWith('/'))
|
|
return to;
|
|
if (( true) && !from.startsWith('/')) {
|
|
warn(`Cannot resolve a relative location without an absolute path. Trying to resolve "${to}" from "${from}". It should look like "/${from}".`);
|
|
return to;
|
|
}
|
|
if (!to)
|
|
return from;
|
|
const fromSegments = from.split('/');
|
|
const toSegments = to.split('/');
|
|
let position = fromSegments.length - 1;
|
|
let toPosition;
|
|
let segment;
|
|
for (toPosition = 0; toPosition < toSegments.length; toPosition++) {
|
|
segment = toSegments[toPosition];
|
|
// can't go below zero
|
|
if (position === 1 || segment === '.')
|
|
continue;
|
|
if (segment === '..')
|
|
position--;
|
|
// found something that is not relative path
|
|
else
|
|
break;
|
|
}
|
|
return (fromSegments.slice(0, position).join('/') +
|
|
'/' +
|
|
toSegments
|
|
.slice(toPosition - (toPosition === toSegments.length ? 1 : 0))
|
|
.join('/'));
|
|
}
|
|
|
|
var NavigationType;
|
|
(function (NavigationType) {
|
|
NavigationType["pop"] = "pop";
|
|
NavigationType["push"] = "push";
|
|
})(NavigationType || (NavigationType = {}));
|
|
var NavigationDirection;
|
|
(function (NavigationDirection) {
|
|
NavigationDirection["back"] = "back";
|
|
NavigationDirection["forward"] = "forward";
|
|
NavigationDirection["unknown"] = "";
|
|
})(NavigationDirection || (NavigationDirection = {}));
|
|
/**
|
|
* Starting location for Histories
|
|
*/
|
|
const START = '';
|
|
// Generic utils
|
|
/**
|
|
* Normalizes a base by removing any trailing slash and reading the base tag if
|
|
* present.
|
|
*
|
|
* @param base - base to normalize
|
|
*/
|
|
function normalizeBase(base) {
|
|
if (!base) {
|
|
if (isBrowser) {
|
|
// respect <base> tag
|
|
const baseEl = document.querySelector('base');
|
|
base = (baseEl && baseEl.getAttribute('href')) || '/';
|
|
// strip full URL origin
|
|
base = base.replace(/^\w+:\/\/[^\/]+/, '');
|
|
}
|
|
else {
|
|
base = '/';
|
|
}
|
|
}
|
|
// ensure leading slash when it was removed by the regex above avoid leading
|
|
// slash with hash because the file could be read from the disk like file://
|
|
// and the leading slash would cause problems
|
|
if (base[0] !== '/' && base[0] !== '#')
|
|
base = '/' + base;
|
|
// remove the trailing slash so all other method can just do `base + fullPath`
|
|
// to build an href
|
|
return removeTrailingSlash(base);
|
|
}
|
|
// remove any character before the hash
|
|
const BEFORE_HASH_RE = /^[^#]+#/;
|
|
function createHref(base, location) {
|
|
return base.replace(BEFORE_HASH_RE, '#') + location;
|
|
}
|
|
|
|
function getElementPosition(el, offset) {
|
|
const docRect = document.documentElement.getBoundingClientRect();
|
|
const elRect = el.getBoundingClientRect();
|
|
return {
|
|
behavior: offset.behavior,
|
|
left: elRect.left - docRect.left - (offset.left || 0),
|
|
top: elRect.top - docRect.top - (offset.top || 0),
|
|
};
|
|
}
|
|
const computeScrollPosition = () => ({
|
|
left: window.pageXOffset,
|
|
top: window.pageYOffset,
|
|
});
|
|
function scrollToPosition(position) {
|
|
let scrollToOptions;
|
|
if ('el' in position) {
|
|
const positionEl = position.el;
|
|
const isIdSelector = typeof positionEl === 'string' && positionEl.startsWith('#');
|
|
/**
|
|
* `id`s can accept pretty much any characters, including CSS combinators
|
|
* like `>` or `~`. It's still possible to retrieve elements using
|
|
* `document.getElementById('~')` but it needs to be escaped when using
|
|
* `document.querySelector('#\\~')` for it to be valid. The only
|
|
* requirements for `id`s are them to be unique on the page and to not be
|
|
* empty (`id=""`). Because of that, when passing an id selector, it should
|
|
* be properly escaped for it to work with `querySelector`. We could check
|
|
* for the id selector to be simple (no CSS combinators `+ >~`) but that
|
|
* would make things inconsistent since they are valid characters for an
|
|
* `id` but would need to be escaped when using `querySelector`, breaking
|
|
* their usage and ending up in no selector returned. Selectors need to be
|
|
* escaped:
|
|
*
|
|
* - `#1-thing` becomes `#\31 -thing`
|
|
* - `#with~symbols` becomes `#with\\~symbols`
|
|
*
|
|
* - More information about the topic can be found at
|
|
* https://mathiasbynens.be/notes/html5-id-class.
|
|
* - Practical example: https://mathiasbynens.be/demo/html5-id
|
|
*/
|
|
if (( true) && typeof position.el === 'string') {
|
|
if (!isIdSelector || !document.getElementById(position.el.slice(1))) {
|
|
try {
|
|
const foundEl = document.querySelector(position.el);
|
|
if (isIdSelector && foundEl) {
|
|
warn(`The selector "${position.el}" should be passed as "el: document.querySelector('${position.el}')" because it starts with "#".`);
|
|
// return to avoid other warnings
|
|
return;
|
|
}
|
|
}
|
|
catch (err) {
|
|
warn(`The selector "${position.el}" is invalid. If you are using an id selector, make sure to escape it. You can find more information about escaping characters in selectors at https://mathiasbynens.be/notes/css-escapes or use CSS.escape (https://developer.mozilla.org/en-US/docs/Web/API/CSS/escape).`);
|
|
// return to avoid other warnings
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
const el = typeof positionEl === 'string'
|
|
? isIdSelector
|
|
? document.getElementById(positionEl.slice(1))
|
|
: document.querySelector(positionEl)
|
|
: positionEl;
|
|
if (!el) {
|
|
( true) &&
|
|
warn(`Couldn't find element using selector "${position.el}" returned by scrollBehavior.`);
|
|
return;
|
|
}
|
|
scrollToOptions = getElementPosition(el, position);
|
|
}
|
|
else {
|
|
scrollToOptions = position;
|
|
}
|
|
if ('scrollBehavior' in document.documentElement.style)
|
|
window.scrollTo(scrollToOptions);
|
|
else {
|
|
window.scrollTo(scrollToOptions.left != null ? scrollToOptions.left : window.pageXOffset, scrollToOptions.top != null ? scrollToOptions.top : window.pageYOffset);
|
|
}
|
|
}
|
|
function getScrollKey(path, delta) {
|
|
const position = history.state ? history.state.position - delta : -1;
|
|
return position + path;
|
|
}
|
|
const scrollPositions = new Map();
|
|
function saveScrollPosition(key, scrollPosition) {
|
|
scrollPositions.set(key, scrollPosition);
|
|
}
|
|
function getSavedScrollPosition(key) {
|
|
const scroll = scrollPositions.get(key);
|
|
// consume it so it's not used again
|
|
scrollPositions.delete(key);
|
|
return scroll;
|
|
}
|
|
// TODO: RFC about how to save scroll position
|
|
/**
|
|
* ScrollBehavior instance used by the router to compute and restore the scroll
|
|
* position when navigating.
|
|
*/
|
|
// export interface ScrollHandler<ScrollPositionEntry extends HistoryStateValue, ScrollPosition extends ScrollPositionEntry> {
|
|
// // returns a scroll position that can be saved in history
|
|
// compute(): ScrollPositionEntry
|
|
// // can take an extended ScrollPositionEntry
|
|
// scroll(position: ScrollPosition): void
|
|
// }
|
|
// export const scrollHandler: ScrollHandler<ScrollPosition> = {
|
|
// compute: computeScroll,
|
|
// scroll: scrollToPosition,
|
|
// }
|
|
|
|
let createBaseLocation = () => location.protocol + '//' + location.host;
|
|
/**
|
|
* Creates a normalized history location from a window.location object
|
|
* @param location -
|
|
*/
|
|
function createCurrentLocation(base, location) {
|
|
const { pathname, search, hash } = location;
|
|
// allows hash bases like #, /#, #/, #!, #!/, /#!/, or even /folder#end
|
|
const hashPos = base.indexOf('#');
|
|
if (hashPos > -1) {
|
|
let slicePos = hash.includes(base.slice(hashPos))
|
|
? base.slice(hashPos).length
|
|
: 1;
|
|
let pathFromHash = hash.slice(slicePos);
|
|
// prepend the starting slash to hash so the url starts with /#
|
|
if (pathFromHash[0] !== '/')
|
|
pathFromHash = '/' + pathFromHash;
|
|
return stripBase(pathFromHash, '');
|
|
}
|
|
const path = stripBase(pathname, base);
|
|
return path + search + hash;
|
|
}
|
|
function useHistoryListeners(base, historyState, currentLocation, replace) {
|
|
let listeners = [];
|
|
let teardowns = [];
|
|
// TODO: should it be a stack? a Dict. Check if the popstate listener
|
|
// can trigger twice
|
|
let pauseState = null;
|
|
const popStateHandler = ({ state, }) => {
|
|
const to = createCurrentLocation(base, location);
|
|
const from = currentLocation.value;
|
|
const fromState = historyState.value;
|
|
let delta = 0;
|
|
if (state) {
|
|
currentLocation.value = to;
|
|
historyState.value = state;
|
|
// ignore the popstate and reset the pauseState
|
|
if (pauseState && pauseState === from) {
|
|
pauseState = null;
|
|
return;
|
|
}
|
|
delta = fromState ? state.position - fromState.position : 0;
|
|
}
|
|
else {
|
|
replace(to);
|
|
}
|
|
// console.log({ deltaFromCurrent })
|
|
// Here we could also revert the navigation by calling history.go(-delta)
|
|
// this listener will have to be adapted to not trigger again and to wait for the url
|
|
// to be updated before triggering the listeners. Some kind of validation function would also
|
|
// need to be passed to the listeners so the navigation can be accepted
|
|
// call all listeners
|
|
listeners.forEach(listener => {
|
|
listener(currentLocation.value, from, {
|
|
delta,
|
|
type: NavigationType.pop,
|
|
direction: delta
|
|
? delta > 0
|
|
? NavigationDirection.forward
|
|
: NavigationDirection.back
|
|
: NavigationDirection.unknown,
|
|
});
|
|
});
|
|
};
|
|
function pauseListeners() {
|
|
pauseState = currentLocation.value;
|
|
}
|
|
function listen(callback) {
|
|
// setup the listener and prepare teardown callbacks
|
|
listeners.push(callback);
|
|
const teardown = () => {
|
|
const index = listeners.indexOf(callback);
|
|
if (index > -1)
|
|
listeners.splice(index, 1);
|
|
};
|
|
teardowns.push(teardown);
|
|
return teardown;
|
|
}
|
|
function beforeUnloadListener() {
|
|
const { history } = window;
|
|
if (!history.state)
|
|
return;
|
|
history.replaceState(assign({}, history.state, { scroll: computeScrollPosition() }), '');
|
|
}
|
|
function destroy() {
|
|
for (const teardown of teardowns)
|
|
teardown();
|
|
teardowns = [];
|
|
window.removeEventListener('popstate', popStateHandler);
|
|
window.removeEventListener('beforeunload', beforeUnloadListener);
|
|
}
|
|
// setup the listeners and prepare teardown callbacks
|
|
window.addEventListener('popstate', popStateHandler);
|
|
window.addEventListener('beforeunload', beforeUnloadListener);
|
|
return {
|
|
pauseListeners,
|
|
listen,
|
|
destroy,
|
|
};
|
|
}
|
|
/**
|
|
* Creates a state object
|
|
*/
|
|
function buildState(back, current, forward, replaced = false, computeScroll = false) {
|
|
return {
|
|
back,
|
|
current,
|
|
forward,
|
|
replaced,
|
|
position: window.history.length,
|
|
scroll: computeScroll ? computeScrollPosition() : null,
|
|
};
|
|
}
|
|
function useHistoryStateNavigation(base) {
|
|
const { history, location } = window;
|
|
// private variables
|
|
const currentLocation = {
|
|
value: createCurrentLocation(base, location),
|
|
};
|
|
const historyState = { value: history.state };
|
|
// build current history entry as this is a fresh navigation
|
|
if (!historyState.value) {
|
|
changeLocation(currentLocation.value, {
|
|
back: null,
|
|
current: currentLocation.value,
|
|
forward: null,
|
|
// the length is off by one, we need to decrease it
|
|
position: history.length - 1,
|
|
replaced: true,
|
|
// don't add a scroll as the user may have an anchor and we want
|
|
// scrollBehavior to be triggered without a saved position
|
|
scroll: null,
|
|
}, true);
|
|
}
|
|
function changeLocation(to, state, replace) {
|
|
/**
|
|
* if a base tag is provided and we are on a normal domain, we have to
|
|
* respect the provided `base` attribute because pushState() will use it and
|
|
* potentially erase anything before the `#` like at
|
|
* https://github.com/vuejs/vue-router-next/issues/685 where a base of
|
|
* `/folder/#` but a base of `/` would erase the `/folder/` section. If
|
|
* there is no host, the `<base>` tag makes no sense and if there isn't a
|
|
* base tag we can just use everything after the `#`.
|
|
*/
|
|
const hashIndex = base.indexOf('#');
|
|
const url = hashIndex > -1
|
|
? (location.host && document.querySelector('base')
|
|
? base
|
|
: base.slice(hashIndex)) + to
|
|
: createBaseLocation() + base + to;
|
|
try {
|
|
// BROWSER QUIRK
|
|
// NOTE: Safari throws a SecurityError when calling this function 100 times in 30 seconds
|
|
history[replace ? 'replaceState' : 'pushState'](state, '', url);
|
|
historyState.value = state;
|
|
}
|
|
catch (err) {
|
|
if ((true)) {
|
|
warn('Error with push/replace State', err);
|
|
}
|
|
else {}
|
|
// Force the navigation, this also resets the call count
|
|
location[replace ? 'replace' : 'assign'](url);
|
|
}
|
|
}
|
|
function replace(to, data) {
|
|
const state = assign({}, history.state, buildState(historyState.value.back,
|
|
// keep back and forward entries but override current position
|
|
to, historyState.value.forward, true), data, { position: historyState.value.position });
|
|
changeLocation(to, state, true);
|
|
currentLocation.value = to;
|
|
}
|
|
function push(to, data) {
|
|
// Add to current entry the information of where we are going
|
|
// as well as saving the current position
|
|
const currentState = assign({},
|
|
// use current history state to gracefully handle a wrong call to
|
|
// history.replaceState
|
|
// https://github.com/vuejs/vue-router-next/issues/366
|
|
historyState.value, history.state, {
|
|
forward: to,
|
|
scroll: computeScrollPosition(),
|
|
});
|
|
if (( true) && !history.state) {
|
|
warn(`history.state seems to have been manually replaced without preserving the necessary values. Make sure to preserve existing history state if you are manually calling history.replaceState:\n\n` +
|
|
`history.replaceState(history.state, '', url)\n\n` +
|
|
`You can find more information at https://next.router.vuejs.org/guide/migration/#usage-of-history-state.`);
|
|
}
|
|
changeLocation(currentState.current, currentState, true);
|
|
const state = assign({}, buildState(currentLocation.value, to, null), { position: currentState.position + 1 }, data);
|
|
changeLocation(to, state, false);
|
|
currentLocation.value = to;
|
|
}
|
|
return {
|
|
location: currentLocation,
|
|
state: historyState,
|
|
push,
|
|
replace,
|
|
};
|
|
}
|
|
/**
|
|
* Creates an HTML5 history. Most common history for single page applications.
|
|
*
|
|
* @param base -
|
|
*/
|
|
function createWebHistory(base) {
|
|
base = normalizeBase(base);
|
|
const historyNavigation = useHistoryStateNavigation(base);
|
|
const historyListeners = useHistoryListeners(base, historyNavigation.state, historyNavigation.location, historyNavigation.replace);
|
|
function go(delta, triggerListeners = true) {
|
|
if (!triggerListeners)
|
|
historyListeners.pauseListeners();
|
|
history.go(delta);
|
|
}
|
|
const routerHistory = assign({
|
|
// it's overridden right after
|
|
location: '',
|
|
base,
|
|
go,
|
|
createHref: createHref.bind(null, base),
|
|
}, historyNavigation, historyListeners);
|
|
Object.defineProperty(routerHistory, 'location', {
|
|
enumerable: true,
|
|
get: () => historyNavigation.location.value,
|
|
});
|
|
Object.defineProperty(routerHistory, 'state', {
|
|
enumerable: true,
|
|
get: () => historyNavigation.state.value,
|
|
});
|
|
return routerHistory;
|
|
}
|
|
|
|
/**
|
|
* Creates a in-memory based history. The main purpose of this history is to handle SSR. It starts in a special location that is nowhere.
|
|
* It's up to the user to replace that location with the starter location by either calling `router.push` or `router.replace`.
|
|
*
|
|
* @param base - Base applied to all urls, defaults to '/'
|
|
* @returns a history object that can be passed to the router constructor
|
|
*/
|
|
function createMemoryHistory(base = '') {
|
|
let listeners = [];
|
|
let queue = [START];
|
|
let position = 0;
|
|
function setLocation(location) {
|
|
position++;
|
|
if (position === queue.length) {
|
|
// we are at the end, we can simply append a new entry
|
|
queue.push(location);
|
|
}
|
|
else {
|
|
// we are in the middle, we remove everything from here in the queue
|
|
queue.splice(position);
|
|
queue.push(location);
|
|
}
|
|
}
|
|
function triggerListeners(to, from, { direction, delta }) {
|
|
const info = {
|
|
direction,
|
|
delta,
|
|
type: NavigationType.pop,
|
|
};
|
|
for (const callback of listeners) {
|
|
callback(to, from, info);
|
|
}
|
|
}
|
|
const routerHistory = {
|
|
// rewritten by Object.defineProperty
|
|
location: START,
|
|
// TODO: should be kept in queue
|
|
state: {},
|
|
base,
|
|
createHref: createHref.bind(null, base),
|
|
replace(to) {
|
|
// remove current entry and decrement position
|
|
queue.splice(position--, 1);
|
|
setLocation(to);
|
|
},
|
|
push(to, data) {
|
|
setLocation(to);
|
|
},
|
|
listen(callback) {
|
|
listeners.push(callback);
|
|
return () => {
|
|
const index = listeners.indexOf(callback);
|
|
if (index > -1)
|
|
listeners.splice(index, 1);
|
|
};
|
|
},
|
|
destroy() {
|
|
listeners = [];
|
|
queue = [START];
|
|
position = 0;
|
|
},
|
|
go(delta, shouldTrigger = true) {
|
|
const from = this.location;
|
|
const direction =
|
|
// we are considering delta === 0 going forward, but in abstract mode
|
|
// using 0 for the delta doesn't make sense like it does in html5 where
|
|
// it reloads the page
|
|
delta < 0 ? NavigationDirection.back : NavigationDirection.forward;
|
|
position = Math.max(0, Math.min(position + delta, queue.length - 1));
|
|
if (shouldTrigger) {
|
|
triggerListeners(this.location, from, {
|
|
direction,
|
|
delta,
|
|
});
|
|
}
|
|
},
|
|
};
|
|
Object.defineProperty(routerHistory, 'location', {
|
|
enumerable: true,
|
|
get: () => queue[position],
|
|
});
|
|
return routerHistory;
|
|
}
|
|
|
|
/**
|
|
* Creates a hash history. Useful for web applications with no host (e.g.
|
|
* `file://`) or when configuring a server to handle any URL is not possible.
|
|
*
|
|
* @param base - optional base to provide. Defaults to `location.pathname +
|
|
* location.search` If there is a `<base>` tag in the `head`, its value will be
|
|
* ignored in favor of this parameter **but note it affects all the
|
|
* history.pushState() calls**, meaning that if you use a `<base>` tag, it's
|
|
* `href` value **has to match this parameter** (ignoring anything after the
|
|
* `#`).
|
|
*
|
|
* @example
|
|
* ```js
|
|
* // at https://example.com/folder
|
|
* createWebHashHistory() // gives a url of `https://example.com/folder#`
|
|
* createWebHashHistory('/folder/') // gives a url of `https://example.com/folder/#`
|
|
* // if the `#` is provided in the base, it won't be added by `createWebHashHistory`
|
|
* createWebHashHistory('/folder/#/app/') // gives a url of `https://example.com/folder/#/app/`
|
|
* // you should avoid doing this because it changes the original url and breaks copying urls
|
|
* createWebHashHistory('/other-folder/') // gives a url of `https://example.com/other-folder/#`
|
|
*
|
|
* // at file:///usr/etc/folder/index.html
|
|
* // for locations with no `host`, the base is ignored
|
|
* createWebHashHistory('/iAmIgnored') // gives a url of `file:///usr/etc/folder/index.html#`
|
|
* ```
|
|
*/
|
|
function createWebHashHistory(base) {
|
|
// Make sure this implementation is fine in terms of encoding, specially for IE11
|
|
// for `file://`, directly use the pathname and ignore the base
|
|
// location.pathname contains an initial `/` even at the root: `https://example.com`
|
|
base = location.host ? base || location.pathname + location.search : '';
|
|
// allow the user to provide a `#` in the middle: `/base/#/app`
|
|
if (!base.includes('#'))
|
|
base += '#';
|
|
if (( true) && !base.endsWith('#/') && !base.endsWith('#')) {
|
|
warn(`A hash base must end with a "#":\n"${base}" should be "${base.replace(/#.*$/, '#')}".`);
|
|
}
|
|
return createWebHistory(base);
|
|
}
|
|
|
|
function isRouteLocation(route) {
|
|
return typeof route === 'string' || (route && typeof route === 'object');
|
|
}
|
|
function isRouteName(name) {
|
|
return typeof name === 'string' || typeof name === 'symbol';
|
|
}
|
|
|
|
/**
|
|
* Initial route location where the router is. Can be used in navigation guards
|
|
* to differentiate the initial navigation.
|
|
*
|
|
* @example
|
|
* ```js
|
|
* import { START_LOCATION } from 'vue-router'
|
|
*
|
|
* router.beforeEach((to, from) => {
|
|
* if (from === START_LOCATION) {
|
|
* // initial navigation
|
|
* }
|
|
* })
|
|
* ```
|
|
*/
|
|
const START_LOCATION_NORMALIZED = {
|
|
path: '/',
|
|
name: undefined,
|
|
params: {},
|
|
query: {},
|
|
hash: '',
|
|
fullPath: '/',
|
|
matched: [],
|
|
meta: {},
|
|
redirectedFrom: undefined,
|
|
};
|
|
|
|
const NavigationFailureSymbol = /*#__PURE__*/ PolySymbol(( true) ? 'navigation failure' : 0);
|
|
/**
|
|
* Enumeration with all possible types for navigation failures. Can be passed to
|
|
* {@link isNavigationFailure} to check for specific failures.
|
|
*/
|
|
var NavigationFailureType;
|
|
(function (NavigationFailureType) {
|
|
/**
|
|
* An aborted navigation is a navigation that failed because a navigation
|
|
* guard returned `false` or called `next(false)`
|
|
*/
|
|
NavigationFailureType[NavigationFailureType["aborted"] = 4] = "aborted";
|
|
/**
|
|
* A cancelled navigation is a navigation that failed because a more recent
|
|
* navigation finished started (not necessarily finished).
|
|
*/
|
|
NavigationFailureType[NavigationFailureType["cancelled"] = 8] = "cancelled";
|
|
/**
|
|
* A duplicated navigation is a navigation that failed because it was
|
|
* initiated while already being at the exact same location.
|
|
*/
|
|
NavigationFailureType[NavigationFailureType["duplicated"] = 16] = "duplicated";
|
|
})(NavigationFailureType || (NavigationFailureType = {}));
|
|
// DEV only debug messages
|
|
const ErrorTypeMessages = {
|
|
[1 /* MATCHER_NOT_FOUND */]({ location, currentLocation }) {
|
|
return `No match for\n ${JSON.stringify(location)}${currentLocation
|
|
? '\nwhile being at\n' + JSON.stringify(currentLocation)
|
|
: ''}`;
|
|
},
|
|
[2 /* NAVIGATION_GUARD_REDIRECT */]({ from, to, }) {
|
|
return `Redirected from "${from.fullPath}" to "${stringifyRoute(to)}" via a navigation guard.`;
|
|
},
|
|
[4 /* NAVIGATION_ABORTED */]({ from, to }) {
|
|
return `Navigation aborted from "${from.fullPath}" to "${to.fullPath}" via a navigation guard.`;
|
|
},
|
|
[8 /* NAVIGATION_CANCELLED */]({ from, to }) {
|
|
return `Navigation cancelled from "${from.fullPath}" to "${to.fullPath}" with a new navigation.`;
|
|
},
|
|
[16 /* NAVIGATION_DUPLICATED */]({ from, to }) {
|
|
return `Avoided redundant navigation to current location: "${from.fullPath}".`;
|
|
},
|
|
};
|
|
function createRouterError(type, params) {
|
|
// keep full error messages in cjs versions
|
|
if (true) {
|
|
return assign(new Error(ErrorTypeMessages[type](params)), {
|
|
type,
|
|
[NavigationFailureSymbol]: true,
|
|
}, params);
|
|
}
|
|
else {}
|
|
}
|
|
function isNavigationFailure(error, type) {
|
|
return (error instanceof Error &&
|
|
NavigationFailureSymbol in error &&
|
|
(type == null || !!(error.type & type)));
|
|
}
|
|
const propertiesToLog = ['params', 'query', 'hash'];
|
|
function stringifyRoute(to) {
|
|
if (typeof to === 'string')
|
|
return to;
|
|
if ('path' in to)
|
|
return to.path;
|
|
const location = {};
|
|
for (const key of propertiesToLog) {
|
|
if (key in to)
|
|
location[key] = to[key];
|
|
}
|
|
return JSON.stringify(location, null, 2);
|
|
}
|
|
|
|
// default pattern for a param: non greedy everything but /
|
|
const BASE_PARAM_PATTERN = '[^/]+?';
|
|
const BASE_PATH_PARSER_OPTIONS = {
|
|
sensitive: false,
|
|
strict: false,
|
|
start: true,
|
|
end: true,
|
|
};
|
|
// Special Regex characters that must be escaped in static tokens
|
|
const REGEX_CHARS_RE = /[.+*?^${}()[\]/\\]/g;
|
|
/**
|
|
* Creates a path parser from an array of Segments (a segment is an array of Tokens)
|
|
*
|
|
* @param segments - array of segments returned by tokenizePath
|
|
* @param extraOptions - optional options for the regexp
|
|
* @returns a PathParser
|
|
*/
|
|
function tokensToParser(segments, extraOptions) {
|
|
const options = assign({}, BASE_PATH_PARSER_OPTIONS, extraOptions);
|
|
// the amount of scores is the same as the length of segments except for the root segment "/"
|
|
const score = [];
|
|
// the regexp as a string
|
|
let pattern = options.start ? '^' : '';
|
|
// extracted keys
|
|
const keys = [];
|
|
for (const segment of segments) {
|
|
// the root segment needs special treatment
|
|
const segmentScores = segment.length ? [] : [90 /* Root */];
|
|
// allow trailing slash
|
|
if (options.strict && !segment.length)
|
|
pattern += '/';
|
|
for (let tokenIndex = 0; tokenIndex < segment.length; tokenIndex++) {
|
|
const token = segment[tokenIndex];
|
|
// resets the score if we are inside a sub segment /:a-other-:b
|
|
let subSegmentScore = 40 /* Segment */ +
|
|
(options.sensitive ? 0.25 /* BonusCaseSensitive */ : 0);
|
|
if (token.type === 0 /* Static */) {
|
|
// prepend the slash if we are starting a new segment
|
|
if (!tokenIndex)
|
|
pattern += '/';
|
|
pattern += token.value.replace(REGEX_CHARS_RE, '\\$&');
|
|
subSegmentScore += 40 /* Static */;
|
|
}
|
|
else if (token.type === 1 /* Param */) {
|
|
const { value, repeatable, optional, regexp } = token;
|
|
keys.push({
|
|
name: value,
|
|
repeatable,
|
|
optional,
|
|
});
|
|
const re = regexp ? regexp : BASE_PARAM_PATTERN;
|
|
// the user provided a custom regexp /:id(\\d+)
|
|
if (re !== BASE_PARAM_PATTERN) {
|
|
subSegmentScore += 10 /* BonusCustomRegExp */;
|
|
// make sure the regexp is valid before using it
|
|
try {
|
|
new RegExp(`(${re})`);
|
|
}
|
|
catch (err) {
|
|
throw new Error(`Invalid custom RegExp for param "${value}" (${re}): ` +
|
|
err.message);
|
|
}
|
|
}
|
|
// when we repeat we must take care of the repeating leading slash
|
|
let subPattern = repeatable ? `((?:${re})(?:/(?:${re}))*)` : `(${re})`;
|
|
// prepend the slash if we are starting a new segment
|
|
if (!tokenIndex)
|
|
subPattern =
|
|
// avoid an optional / if there are more segments e.g. /:p?-static
|
|
// or /:p?-:p2
|
|
optional && segment.length < 2
|
|
? `(?:/${subPattern})`
|
|
: '/' + subPattern;
|
|
if (optional)
|
|
subPattern += '?';
|
|
pattern += subPattern;
|
|
subSegmentScore += 20 /* Dynamic */;
|
|
if (optional)
|
|
subSegmentScore += -8 /* BonusOptional */;
|
|
if (repeatable)
|
|
subSegmentScore += -20 /* BonusRepeatable */;
|
|
if (re === '.*')
|
|
subSegmentScore += -50 /* BonusWildcard */;
|
|
}
|
|
segmentScores.push(subSegmentScore);
|
|
}
|
|
// an empty array like /home/ -> [[{home}], []]
|
|
// if (!segment.length) pattern += '/'
|
|
score.push(segmentScores);
|
|
}
|
|
// only apply the strict bonus to the last score
|
|
if (options.strict && options.end) {
|
|
const i = score.length - 1;
|
|
score[i][score[i].length - 1] += 0.7000000000000001 /* BonusStrict */;
|
|
}
|
|
// TODO: dev only warn double trailing slash
|
|
if (!options.strict)
|
|
pattern += '/?';
|
|
if (options.end)
|
|
pattern += '$';
|
|
// allow paths like /dynamic to only match dynamic or dynamic/... but not dynamic_something_else
|
|
else if (options.strict)
|
|
pattern += '(?:/|$)';
|
|
const re = new RegExp(pattern, options.sensitive ? '' : 'i');
|
|
function parse(path) {
|
|
const match = path.match(re);
|
|
const params = {};
|
|
if (!match)
|
|
return null;
|
|
for (let i = 1; i < match.length; i++) {
|
|
const value = match[i] || '';
|
|
const key = keys[i - 1];
|
|
params[key.name] = value && key.repeatable ? value.split('/') : value;
|
|
}
|
|
return params;
|
|
}
|
|
function stringify(params) {
|
|
let path = '';
|
|
// for optional parameters to allow to be empty
|
|
let avoidDuplicatedSlash = false;
|
|
for (const segment of segments) {
|
|
if (!avoidDuplicatedSlash || !path.endsWith('/'))
|
|
path += '/';
|
|
avoidDuplicatedSlash = false;
|
|
for (const token of segment) {
|
|
if (token.type === 0 /* Static */) {
|
|
path += token.value;
|
|
}
|
|
else if (token.type === 1 /* Param */) {
|
|
const { value, repeatable, optional } = token;
|
|
const param = value in params ? params[value] : '';
|
|
if (Array.isArray(param) && !repeatable)
|
|
throw new Error(`Provided param "${value}" is an array but it is not repeatable (* or + modifiers)`);
|
|
const text = Array.isArray(param) ? param.join('/') : param;
|
|
if (!text) {
|
|
if (optional) {
|
|
// if we have more than one optional param like /:a?-static we
|
|
// don't need to care about the optional param
|
|
if (segment.length < 2) {
|
|
// remove the last slash as we could be at the end
|
|
if (path.endsWith('/'))
|
|
path = path.slice(0, -1);
|
|
// do not append a slash on the next iteration
|
|
else
|
|
avoidDuplicatedSlash = true;
|
|
}
|
|
}
|
|
else
|
|
throw new Error(`Missing required param "${value}"`);
|
|
}
|
|
path += text;
|
|
}
|
|
}
|
|
}
|
|
return path;
|
|
}
|
|
return {
|
|
re,
|
|
score,
|
|
keys,
|
|
parse,
|
|
stringify,
|
|
};
|
|
}
|
|
/**
|
|
* Compares an array of numbers as used in PathParser.score and returns a
|
|
* number. This function can be used to `sort` an array
|
|
*
|
|
* @param a - first array of numbers
|
|
* @param b - second array of numbers
|
|
* @returns 0 if both are equal, < 0 if a should be sorted first, > 0 if b
|
|
* should be sorted first
|
|
*/
|
|
function compareScoreArray(a, b) {
|
|
let i = 0;
|
|
while (i < a.length && i < b.length) {
|
|
const diff = b[i] - a[i];
|
|
// only keep going if diff === 0
|
|
if (diff)
|
|
return diff;
|
|
i++;
|
|
}
|
|
// if the last subsegment was Static, the shorter segments should be sorted first
|
|
// otherwise sort the longest segment first
|
|
if (a.length < b.length) {
|
|
return a.length === 1 && a[0] === 40 /* Static */ + 40 /* Segment */
|
|
? -1
|
|
: 1;
|
|
}
|
|
else if (a.length > b.length) {
|
|
return b.length === 1 && b[0] === 40 /* Static */ + 40 /* Segment */
|
|
? 1
|
|
: -1;
|
|
}
|
|
return 0;
|
|
}
|
|
/**
|
|
* Compare function that can be used with `sort` to sort an array of PathParser
|
|
*
|
|
* @param a - first PathParser
|
|
* @param b - second PathParser
|
|
* @returns 0 if both are equal, < 0 if a should be sorted first, > 0 if b
|
|
*/
|
|
function comparePathParserScore(a, b) {
|
|
let i = 0;
|
|
const aScore = a.score;
|
|
const bScore = b.score;
|
|
while (i < aScore.length && i < bScore.length) {
|
|
const comp = compareScoreArray(aScore[i], bScore[i]);
|
|
// do not return if both are equal
|
|
if (comp)
|
|
return comp;
|
|
i++;
|
|
}
|
|
// if a and b share the same score entries but b has more, sort b first
|
|
return bScore.length - aScore.length;
|
|
// this is the ternary version
|
|
// return aScore.length < bScore.length
|
|
// ? 1
|
|
// : aScore.length > bScore.length
|
|
// ? -1
|
|
// : 0
|
|
}
|
|
|
|
const ROOT_TOKEN = {
|
|
type: 0 /* Static */,
|
|
value: '',
|
|
};
|
|
const VALID_PARAM_RE = /[a-zA-Z0-9_]/;
|
|
// After some profiling, the cache seems to be unnecessary because tokenizePath
|
|
// (the slowest part of adding a route) is very fast
|
|
// const tokenCache = new Map<string, Token[][]>()
|
|
function tokenizePath(path) {
|
|
if (!path)
|
|
return [[]];
|
|
if (path === '/')
|
|
return [[ROOT_TOKEN]];
|
|
if (!path.startsWith('/')) {
|
|
throw new Error(( true)
|
|
? `Route paths should start with a "/": "${path}" should be "/${path}".`
|
|
: 0);
|
|
}
|
|
// if (tokenCache.has(path)) return tokenCache.get(path)!
|
|
function crash(message) {
|
|
throw new Error(`ERR (${state})/"${buffer}": ${message}`);
|
|
}
|
|
let state = 0 /* Static */;
|
|
let previousState = state;
|
|
const tokens = [];
|
|
// the segment will always be valid because we get into the initial state
|
|
// with the leading /
|
|
let segment;
|
|
function finalizeSegment() {
|
|
if (segment)
|
|
tokens.push(segment);
|
|
segment = [];
|
|
}
|
|
// index on the path
|
|
let i = 0;
|
|
// char at index
|
|
let char;
|
|
// buffer of the value read
|
|
let buffer = '';
|
|
// custom regexp for a param
|
|
let customRe = '';
|
|
function consumeBuffer() {
|
|
if (!buffer)
|
|
return;
|
|
if (state === 0 /* Static */) {
|
|
segment.push({
|
|
type: 0 /* Static */,
|
|
value: buffer,
|
|
});
|
|
}
|
|
else if (state === 1 /* Param */ ||
|
|
state === 2 /* ParamRegExp */ ||
|
|
state === 3 /* ParamRegExpEnd */) {
|
|
if (segment.length > 1 && (char === '*' || char === '+'))
|
|
crash(`A repeatable param (${buffer}) must be alone in its segment. eg: '/:ids+.`);
|
|
segment.push({
|
|
type: 1 /* Param */,
|
|
value: buffer,
|
|
regexp: customRe,
|
|
repeatable: char === '*' || char === '+',
|
|
optional: char === '*' || char === '?',
|
|
});
|
|
}
|
|
else {
|
|
crash('Invalid state to consume buffer');
|
|
}
|
|
buffer = '';
|
|
}
|
|
function addCharToBuffer() {
|
|
buffer += char;
|
|
}
|
|
while (i < path.length) {
|
|
char = path[i++];
|
|
if (char === '\\' && state !== 2 /* ParamRegExp */) {
|
|
previousState = state;
|
|
state = 4 /* EscapeNext */;
|
|
continue;
|
|
}
|
|
switch (state) {
|
|
case 0 /* Static */:
|
|
if (char === '/') {
|
|
if (buffer) {
|
|
consumeBuffer();
|
|
}
|
|
finalizeSegment();
|
|
}
|
|
else if (char === ':') {
|
|
consumeBuffer();
|
|
state = 1 /* Param */;
|
|
}
|
|
else {
|
|
addCharToBuffer();
|
|
}
|
|
break;
|
|
case 4 /* EscapeNext */:
|
|
addCharToBuffer();
|
|
state = previousState;
|
|
break;
|
|
case 1 /* Param */:
|
|
if (char === '(') {
|
|
state = 2 /* ParamRegExp */;
|
|
}
|
|
else if (VALID_PARAM_RE.test(char)) {
|
|
addCharToBuffer();
|
|
}
|
|
else {
|
|
consumeBuffer();
|
|
state = 0 /* Static */;
|
|
// go back one character if we were not modifying
|
|
if (char !== '*' && char !== '?' && char !== '+')
|
|
i--;
|
|
}
|
|
break;
|
|
case 2 /* ParamRegExp */:
|
|
// TODO: is it worth handling nested regexp? like :p(?:prefix_([^/]+)_suffix)
|
|
// it already works by escaping the closing )
|
|
// https://paths.esm.dev/?p=AAMeJbiAwQEcDKbAoAAkP60PG2R6QAvgNaA6AFACM2ABuQBB#
|
|
// is this really something people need since you can also write
|
|
// /prefix_:p()_suffix
|
|
if (char === ')') {
|
|
// handle the escaped )
|
|
if (customRe[customRe.length - 1] == '\\')
|
|
customRe = customRe.slice(0, -1) + char;
|
|
else
|
|
state = 3 /* ParamRegExpEnd */;
|
|
}
|
|
else {
|
|
customRe += char;
|
|
}
|
|
break;
|
|
case 3 /* ParamRegExpEnd */:
|
|
// same as finalizing a param
|
|
consumeBuffer();
|
|
state = 0 /* Static */;
|
|
// go back one character if we were not modifying
|
|
if (char !== '*' && char !== '?' && char !== '+')
|
|
i--;
|
|
customRe = '';
|
|
break;
|
|
default:
|
|
crash('Unknown state');
|
|
break;
|
|
}
|
|
}
|
|
if (state === 2 /* ParamRegExp */)
|
|
crash(`Unfinished custom RegExp for param "${buffer}"`);
|
|
consumeBuffer();
|
|
finalizeSegment();
|
|
// tokenCache.set(path, tokens)
|
|
return tokens;
|
|
}
|
|
|
|
function createRouteRecordMatcher(record, parent, options) {
|
|
const parser = tokensToParser(tokenizePath(record.path), options);
|
|
// warn against params with the same name
|
|
if ((true)) {
|
|
const existingKeys = new Set();
|
|
for (const key of parser.keys) {
|
|
if (existingKeys.has(key.name))
|
|
warn(`Found duplicated params with name "${key.name}" for path "${record.path}". Only the last one will be available on "$route.params".`);
|
|
existingKeys.add(key.name);
|
|
}
|
|
}
|
|
const matcher = assign(parser, {
|
|
record,
|
|
parent,
|
|
// these needs to be populated by the parent
|
|
children: [],
|
|
alias: [],
|
|
});
|
|
if (parent) {
|
|
// both are aliases or both are not aliases
|
|
// we don't want to mix them because the order is used when
|
|
// passing originalRecord in Matcher.addRoute
|
|
if (!matcher.record.aliasOf === !parent.record.aliasOf)
|
|
parent.children.push(matcher);
|
|
}
|
|
return matcher;
|
|
}
|
|
|
|
/**
|
|
* Creates a Router Matcher.
|
|
*
|
|
* @internal
|
|
* @param routes - array of initial routes
|
|
* @param globalOptions - global route options
|
|
*/
|
|
function createRouterMatcher(routes, globalOptions) {
|
|
// normalized ordered array of matchers
|
|
const matchers = [];
|
|
const matcherMap = new Map();
|
|
globalOptions = mergeOptions({ strict: false, end: true, sensitive: false }, globalOptions);
|
|
function getRecordMatcher(name) {
|
|
return matcherMap.get(name);
|
|
}
|
|
function addRoute(record, parent, originalRecord) {
|
|
// used later on to remove by name
|
|
const isRootAdd = !originalRecord;
|
|
const mainNormalizedRecord = normalizeRouteRecord(record);
|
|
// we might be the child of an alias
|
|
mainNormalizedRecord.aliasOf = originalRecord && originalRecord.record;
|
|
const options = mergeOptions(globalOptions, record);
|
|
// generate an array of records to correctly handle aliases
|
|
const normalizedRecords = [
|
|
mainNormalizedRecord,
|
|
];
|
|
if ('alias' in record) {
|
|
const aliases = typeof record.alias === 'string' ? [record.alias] : record.alias;
|
|
for (const alias of aliases) {
|
|
normalizedRecords.push(assign({}, mainNormalizedRecord, {
|
|
// this allows us to hold a copy of the `components` option
|
|
// so that async components cache is hold on the original record
|
|
components: originalRecord
|
|
? originalRecord.record.components
|
|
: mainNormalizedRecord.components,
|
|
path: alias,
|
|
// we might be the child of an alias
|
|
aliasOf: originalRecord
|
|
? originalRecord.record
|
|
: mainNormalizedRecord,
|
|
// the aliases are always of the same kind as the original since they
|
|
// are defined on the same record
|
|
}));
|
|
}
|
|
}
|
|
let matcher;
|
|
let originalMatcher;
|
|
for (const normalizedRecord of normalizedRecords) {
|
|
const { path } = normalizedRecord;
|
|
// Build up the path for nested routes if the child isn't an absolute
|
|
// route. Only add the / delimiter if the child path isn't empty and if the
|
|
// parent path doesn't have a trailing slash
|
|
if (parent && path[0] !== '/') {
|
|
const parentPath = parent.record.path;
|
|
const connectingSlash = parentPath[parentPath.length - 1] === '/' ? '' : '/';
|
|
normalizedRecord.path =
|
|
parent.record.path + (path && connectingSlash + path);
|
|
}
|
|
if (( true) && normalizedRecord.path === '*') {
|
|
throw new Error('Catch all routes ("*") must now be defined using a param with a custom regexp.\n' +
|
|
'See more at https://next.router.vuejs.org/guide/migration/#removed-star-or-catch-all-routes.');
|
|
}
|
|
// create the object before hand so it can be passed to children
|
|
matcher = createRouteRecordMatcher(normalizedRecord, parent, options);
|
|
if (( true) && parent && path[0] === '/')
|
|
checkMissingParamsInAbsolutePath(matcher, parent);
|
|
// if we are an alias we must tell the original record that we exist
|
|
// so we can be removed
|
|
if (originalRecord) {
|
|
originalRecord.alias.push(matcher);
|
|
if ((true)) {
|
|
checkSameParams(originalRecord, matcher);
|
|
}
|
|
}
|
|
else {
|
|
// otherwise, the first record is the original and others are aliases
|
|
originalMatcher = originalMatcher || matcher;
|
|
if (originalMatcher !== matcher)
|
|
originalMatcher.alias.push(matcher);
|
|
// remove the route if named and only for the top record (avoid in nested calls)
|
|
// this works because the original record is the first one
|
|
if (isRootAdd && record.name && !isAliasRecord(matcher))
|
|
removeRoute(record.name);
|
|
}
|
|
if ('children' in mainNormalizedRecord) {
|
|
const children = mainNormalizedRecord.children;
|
|
for (let i = 0; i < children.length; i++) {
|
|
addRoute(children[i], matcher, originalRecord && originalRecord.children[i]);
|
|
}
|
|
}
|
|
// if there was no original record, then the first one was not an alias and all
|
|
// other alias (if any) need to reference this record when adding children
|
|
originalRecord = originalRecord || matcher;
|
|
// TODO: add normalized records for more flexibility
|
|
// if (parent && isAliasRecord(originalRecord)) {
|
|
// parent.children.push(originalRecord)
|
|
// }
|
|
insertMatcher(matcher);
|
|
}
|
|
return originalMatcher
|
|
? () => {
|
|
// since other matchers are aliases, they should be removed by the original matcher
|
|
removeRoute(originalMatcher);
|
|
}
|
|
: noop;
|
|
}
|
|
function removeRoute(matcherRef) {
|
|
if (isRouteName(matcherRef)) {
|
|
const matcher = matcherMap.get(matcherRef);
|
|
if (matcher) {
|
|
matcherMap.delete(matcherRef);
|
|
matchers.splice(matchers.indexOf(matcher), 1);
|
|
matcher.children.forEach(removeRoute);
|
|
matcher.alias.forEach(removeRoute);
|
|
}
|
|
}
|
|
else {
|
|
const index = matchers.indexOf(matcherRef);
|
|
if (index > -1) {
|
|
matchers.splice(index, 1);
|
|
if (matcherRef.record.name)
|
|
matcherMap.delete(matcherRef.record.name);
|
|
matcherRef.children.forEach(removeRoute);
|
|
matcherRef.alias.forEach(removeRoute);
|
|
}
|
|
}
|
|
}
|
|
function getRoutes() {
|
|
return matchers;
|
|
}
|
|
function insertMatcher(matcher) {
|
|
let i = 0;
|
|
// console.log('i is', { i })
|
|
while (i < matchers.length &&
|
|
comparePathParserScore(matcher, matchers[i]) >= 0)
|
|
i++;
|
|
// console.log('END i is', { i })
|
|
// while (i < matchers.length && matcher.score <= matchers[i].score) i++
|
|
matchers.splice(i, 0, matcher);
|
|
// only add the original record to the name map
|
|
if (matcher.record.name && !isAliasRecord(matcher))
|
|
matcherMap.set(matcher.record.name, matcher);
|
|
}
|
|
function resolve(location, currentLocation) {
|
|
let matcher;
|
|
let params = {};
|
|
let path;
|
|
let name;
|
|
if ('name' in location && location.name) {
|
|
matcher = matcherMap.get(location.name);
|
|
if (!matcher)
|
|
throw createRouterError(1 /* MATCHER_NOT_FOUND */, {
|
|
location,
|
|
});
|
|
name = matcher.record.name;
|
|
params = assign(
|
|
// paramsFromLocation is a new object
|
|
paramsFromLocation(currentLocation.params,
|
|
// only keep params that exist in the resolved location
|
|
// TODO: only keep optional params coming from a parent record
|
|
matcher.keys.filter(k => !k.optional).map(k => k.name)), location.params);
|
|
// throws if cannot be stringified
|
|
path = matcher.stringify(params);
|
|
}
|
|
else if ('path' in location) {
|
|
// no need to resolve the path with the matcher as it was provided
|
|
// this also allows the user to control the encoding
|
|
path = location.path;
|
|
if (( true) && !path.startsWith('/')) {
|
|
warn(`The Matcher cannot resolve relative paths but received "${path}". Unless you directly called \`matcher.resolve("${path}")\`, this is probably a bug in vue-router. Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/vue-router-next.`);
|
|
}
|
|
matcher = matchers.find(m => m.re.test(path));
|
|
// matcher should have a value after the loop
|
|
if (matcher) {
|
|
// TODO: dev warning of unused params if provided
|
|
// we know the matcher works because we tested the regexp
|
|
params = matcher.parse(path);
|
|
name = matcher.record.name;
|
|
}
|
|
// location is a relative path
|
|
}
|
|
else {
|
|
// match by name or path of current route
|
|
matcher = currentLocation.name
|
|
? matcherMap.get(currentLocation.name)
|
|
: matchers.find(m => m.re.test(currentLocation.path));
|
|
if (!matcher)
|
|
throw createRouterError(1 /* MATCHER_NOT_FOUND */, {
|
|
location,
|
|
currentLocation,
|
|
});
|
|
name = matcher.record.name;
|
|
// since we are navigating to the same location, we don't need to pick the
|
|
// params like when `name` is provided
|
|
params = assign({}, currentLocation.params, location.params);
|
|
path = matcher.stringify(params);
|
|
}
|
|
const matched = [];
|
|
let parentMatcher = matcher;
|
|
while (parentMatcher) {
|
|
// reversed order so parents are at the beginning
|
|
matched.unshift(parentMatcher.record);
|
|
parentMatcher = parentMatcher.parent;
|
|
}
|
|
return {
|
|
name,
|
|
path,
|
|
params,
|
|
matched,
|
|
meta: mergeMetaFields(matched),
|
|
};
|
|
}
|
|
// add initial routes
|
|
routes.forEach(route => addRoute(route));
|
|
return { addRoute, resolve, removeRoute, getRoutes, getRecordMatcher };
|
|
}
|
|
function paramsFromLocation(params, keys) {
|
|
const newParams = {};
|
|
for (const key of keys) {
|
|
if (key in params)
|
|
newParams[key] = params[key];
|
|
}
|
|
return newParams;
|
|
}
|
|
/**
|
|
* Normalizes a RouteRecordRaw. Creates a copy
|
|
*
|
|
* @param record
|
|
* @returns the normalized version
|
|
*/
|
|
function normalizeRouteRecord(record) {
|
|
return {
|
|
path: record.path,
|
|
redirect: record.redirect,
|
|
name: record.name,
|
|
meta: record.meta || {},
|
|
aliasOf: undefined,
|
|
beforeEnter: record.beforeEnter,
|
|
props: normalizeRecordProps(record),
|
|
children: record.children || [],
|
|
instances: {},
|
|
leaveGuards: new Set(),
|
|
updateGuards: new Set(),
|
|
enterCallbacks: {},
|
|
components: 'components' in record
|
|
? record.components || {}
|
|
: { default: record.component },
|
|
};
|
|
}
|
|
/**
|
|
* Normalize the optional `props` in a record to always be an object similar to
|
|
* components. Also accept a boolean for components.
|
|
* @param record
|
|
*/
|
|
function normalizeRecordProps(record) {
|
|
const propsObject = {};
|
|
// props does not exist on redirect records but we can set false directly
|
|
const props = record.props || false;
|
|
if ('component' in record) {
|
|
propsObject.default = props;
|
|
}
|
|
else {
|
|
// NOTE: we could also allow a function to be applied to every component.
|
|
// Would need user feedback for use cases
|
|
for (const name in record.components)
|
|
propsObject[name] = typeof props === 'boolean' ? props : props[name];
|
|
}
|
|
return propsObject;
|
|
}
|
|
/**
|
|
* Checks if a record or any of its parent is an alias
|
|
* @param record
|
|
*/
|
|
function isAliasRecord(record) {
|
|
while (record) {
|
|
if (record.record.aliasOf)
|
|
return true;
|
|
record = record.parent;
|
|
}
|
|
return false;
|
|
}
|
|
/**
|
|
* Merge meta fields of an array of records
|
|
*
|
|
* @param matched - array of matched records
|
|
*/
|
|
function mergeMetaFields(matched) {
|
|
return matched.reduce((meta, record) => assign(meta, record.meta), {});
|
|
}
|
|
function mergeOptions(defaults, partialOptions) {
|
|
const options = {};
|
|
for (const key in defaults) {
|
|
options[key] = key in partialOptions ? partialOptions[key] : defaults[key];
|
|
}
|
|
return options;
|
|
}
|
|
function isSameParam(a, b) {
|
|
return (a.name === b.name &&
|
|
a.optional === b.optional &&
|
|
a.repeatable === b.repeatable);
|
|
}
|
|
/**
|
|
* Check if a path and its alias have the same required params
|
|
*
|
|
* @param a - original record
|
|
* @param b - alias record
|
|
*/
|
|
function checkSameParams(a, b) {
|
|
for (const key of a.keys) {
|
|
if (!key.optional && !b.keys.find(isSameParam.bind(null, key)))
|
|
return warn(`Alias "${b.record.path}" and the original record: "${a.record.path}" should have the exact same param named "${key.name}"`);
|
|
}
|
|
for (const key of b.keys) {
|
|
if (!key.optional && !a.keys.find(isSameParam.bind(null, key)))
|
|
return warn(`Alias "${b.record.path}" and the original record: "${a.record.path}" should have the exact same param named "${key.name}"`);
|
|
}
|
|
}
|
|
function checkMissingParamsInAbsolutePath(record, parent) {
|
|
for (const key of parent.keys) {
|
|
if (!record.keys.find(isSameParam.bind(null, key)))
|
|
return warn(`Absolute path "${record.record.path}" should have the exact same param named "${key.name}" as its parent "${parent.record.path}".`);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Encoding Rules ␣ = Space Path: ␣ " < > # ? { } Query: ␣ " < > # & = Hash: ␣ "
|
|
* < > `
|
|
*
|
|
* On top of that, the RFC3986 (https://tools.ietf.org/html/rfc3986#section-2.2)
|
|
* defines some extra characters to be encoded. Most browsers do not encode them
|
|
* in encodeURI https://github.com/whatwg/url/issues/369, so it may be safer to
|
|
* also encode `!'()*`. Leaving unencoded only ASCII alphanumeric(`a-zA-Z0-9`)
|
|
* plus `-._~`. This extra safety should be applied to query by patching the
|
|
* string returned by encodeURIComponent encodeURI also encodes `[\]^`. `\`
|
|
* should be encoded to avoid ambiguity. Browsers (IE, FF, C) transform a `\`
|
|
* into a `/` if directly typed in. The _backtick_ (`````) should also be
|
|
* encoded everywhere because some browsers like FF encode it when directly
|
|
* written while others don't. Safari and IE don't encode ``"<>{}``` in hash.
|
|
*/
|
|
// const EXTRA_RESERVED_RE = /[!'()*]/g
|
|
// const encodeReservedReplacer = (c: string) => '%' + c.charCodeAt(0).toString(16)
|
|
const HASH_RE = /#/g; // %23
|
|
const AMPERSAND_RE = /&/g; // %26
|
|
const SLASH_RE = /\//g; // %2F
|
|
const EQUAL_RE = /=/g; // %3D
|
|
const IM_RE = /\?/g; // %3F
|
|
const PLUS_RE = /\+/g; // %2B
|
|
/**
|
|
* NOTE: It's not clear to me if we should encode the + symbol in queries, it
|
|
* seems to be less flexible than not doing so and I can't find out the legacy
|
|
* systems requiring this for regular requests like text/html. In the standard,
|
|
* the encoding of the plus character is only mentioned for
|
|
* application/x-www-form-urlencoded
|
|
* (https://url.spec.whatwg.org/#urlencoded-parsing) and most browsers seems lo
|
|
* leave the plus character as is in queries. To be more flexible, we allow the
|
|
* plus character on the query but it can also be manually encoded by the user.
|
|
*
|
|
* Resources:
|
|
* - https://url.spec.whatwg.org/#urlencoded-parsing
|
|
* - https://stackoverflow.com/questions/1634271/url-encoding-the-space-character-or-20
|
|
*/
|
|
const ENC_BRACKET_OPEN_RE = /%5B/g; // [
|
|
const ENC_BRACKET_CLOSE_RE = /%5D/g; // ]
|
|
const ENC_CARET_RE = /%5E/g; // ^
|
|
const ENC_BACKTICK_RE = /%60/g; // `
|
|
const ENC_CURLY_OPEN_RE = /%7B/g; // {
|
|
const ENC_PIPE_RE = /%7C/g; // |
|
|
const ENC_CURLY_CLOSE_RE = /%7D/g; // }
|
|
const ENC_SPACE_RE = /%20/g; // }
|
|
/**
|
|
* Encode characters that need to be encoded on the path, search and hash
|
|
* sections of the URL.
|
|
*
|
|
* @internal
|
|
* @param text - string to encode
|
|
* @returns encoded string
|
|
*/
|
|
function commonEncode(text) {
|
|
return encodeURI('' + text)
|
|
.replace(ENC_PIPE_RE, '|')
|
|
.replace(ENC_BRACKET_OPEN_RE, '[')
|
|
.replace(ENC_BRACKET_CLOSE_RE, ']');
|
|
}
|
|
/**
|
|
* Encode characters that need to be encoded on the hash section of the URL.
|
|
*
|
|
* @param text - string to encode
|
|
* @returns encoded string
|
|
*/
|
|
function encodeHash(text) {
|
|
return commonEncode(text)
|
|
.replace(ENC_CURLY_OPEN_RE, '{')
|
|
.replace(ENC_CURLY_CLOSE_RE, '}')
|
|
.replace(ENC_CARET_RE, '^');
|
|
}
|
|
/**
|
|
* Encode characters that need to be encoded query values on the query
|
|
* section of the URL.
|
|
*
|
|
* @param text - string to encode
|
|
* @returns encoded string
|
|
*/
|
|
function encodeQueryValue(text) {
|
|
return (commonEncode(text)
|
|
// Encode the space as +, encode the + to differentiate it from the space
|
|
.replace(PLUS_RE, '%2B')
|
|
.replace(ENC_SPACE_RE, '+')
|
|
.replace(HASH_RE, '%23')
|
|
.replace(AMPERSAND_RE, '%26')
|
|
.replace(ENC_BACKTICK_RE, '`')
|
|
.replace(ENC_CURLY_OPEN_RE, '{')
|
|
.replace(ENC_CURLY_CLOSE_RE, '}')
|
|
.replace(ENC_CARET_RE, '^'));
|
|
}
|
|
/**
|
|
* Like `encodeQueryValue` but also encodes the `=` character.
|
|
*
|
|
* @param text - string to encode
|
|
*/
|
|
function encodeQueryKey(text) {
|
|
return encodeQueryValue(text).replace(EQUAL_RE, '%3D');
|
|
}
|
|
/**
|
|
* Encode characters that need to be encoded on the path section of the URL.
|
|
*
|
|
* @param text - string to encode
|
|
* @returns encoded string
|
|
*/
|
|
function encodePath(text) {
|
|
return commonEncode(text).replace(HASH_RE, '%23').replace(IM_RE, '%3F');
|
|
}
|
|
/**
|
|
* Encode characters that need to be encoded on the path section of the URL as a
|
|
* param. This function encodes everything {@link encodePath} does plus the
|
|
* slash (`/`) character. If `text` is `null` or `undefined`, returns an empty
|
|
* string instead.
|
|
*
|
|
* @param text - string to encode
|
|
* @returns encoded string
|
|
*/
|
|
function encodeParam(text) {
|
|
return text == null ? '' : encodePath(text).replace(SLASH_RE, '%2F');
|
|
}
|
|
/**
|
|
* Decode text using `decodeURIComponent`. Returns the original text if it
|
|
* fails.
|
|
*
|
|
* @param text - string to decode
|
|
* @returns decoded string
|
|
*/
|
|
function decode(text) {
|
|
try {
|
|
return decodeURIComponent('' + text);
|
|
}
|
|
catch (err) {
|
|
( true) && warn(`Error decoding "${text}". Using original value`);
|
|
}
|
|
return '' + text;
|
|
}
|
|
|
|
/**
|
|
* Transforms a queryString into a {@link LocationQuery} object. Accept both, a
|
|
* version with the leading `?` and without Should work as URLSearchParams
|
|
|
|
* @internal
|
|
*
|
|
* @param search - search string to parse
|
|
* @returns a query object
|
|
*/
|
|
function parseQuery(search) {
|
|
const query = {};
|
|
// avoid creating an object with an empty key and empty value
|
|
// because of split('&')
|
|
if (search === '' || search === '?')
|
|
return query;
|
|
const hasLeadingIM = search[0] === '?';
|
|
const searchParams = (hasLeadingIM ? search.slice(1) : search).split('&');
|
|
for (let i = 0; i < searchParams.length; ++i) {
|
|
// pre decode the + into space
|
|
const searchParam = searchParams[i].replace(PLUS_RE, ' ');
|
|
// allow the = character
|
|
const eqPos = searchParam.indexOf('=');
|
|
const key = decode(eqPos < 0 ? searchParam : searchParam.slice(0, eqPos));
|
|
const value = eqPos < 0 ? null : decode(searchParam.slice(eqPos + 1));
|
|
if (key in query) {
|
|
// an extra variable for ts types
|
|
let currentValue = query[key];
|
|
if (!Array.isArray(currentValue)) {
|
|
currentValue = query[key] = [currentValue];
|
|
}
|
|
currentValue.push(value);
|
|
}
|
|
else {
|
|
query[key] = value;
|
|
}
|
|
}
|
|
return query;
|
|
}
|
|
/**
|
|
* Stringifies a {@link LocationQueryRaw} object. Like `URLSearchParams`, it
|
|
* doesn't prepend a `?`
|
|
*
|
|
* @internal
|
|
*
|
|
* @param query - query object to stringify
|
|
* @returns string version of the query without the leading `?`
|
|
*/
|
|
function stringifyQuery(query) {
|
|
let search = '';
|
|
for (let key in query) {
|
|
const value = query[key];
|
|
key = encodeQueryKey(key);
|
|
if (value == null) {
|
|
// only null adds the value
|
|
if (value !== undefined) {
|
|
search += (search.length ? '&' : '') + key;
|
|
}
|
|
continue;
|
|
}
|
|
// keep null values
|
|
const values = Array.isArray(value)
|
|
? value.map(v => v && encodeQueryValue(v))
|
|
: [value && encodeQueryValue(value)];
|
|
values.forEach(value => {
|
|
// skip undefined values in arrays as if they were not present
|
|
// smaller code than using filter
|
|
if (value !== undefined) {
|
|
// only append & with non-empty search
|
|
search += (search.length ? '&' : '') + key;
|
|
if (value != null)
|
|
search += '=' + value;
|
|
}
|
|
});
|
|
}
|
|
return search;
|
|
}
|
|
/**
|
|
* Transforms a {@link LocationQueryRaw} into a {@link LocationQuery} by casting
|
|
* numbers into strings, removing keys with an undefined value and replacing
|
|
* undefined with null in arrays
|
|
*
|
|
* @param query - query object to normalize
|
|
* @returns a normalized query object
|
|
*/
|
|
function normalizeQuery(query) {
|
|
const normalizedQuery = {};
|
|
for (const key in query) {
|
|
const value = query[key];
|
|
if (value !== undefined) {
|
|
normalizedQuery[key] = Array.isArray(value)
|
|
? value.map(v => (v == null ? null : '' + v))
|
|
: value == null
|
|
? value
|
|
: '' + value;
|
|
}
|
|
}
|
|
return normalizedQuery;
|
|
}
|
|
|
|
/**
|
|
* Create a list of callbacks that can be reset. Used to create before and after navigation guards list
|
|
*/
|
|
function useCallbacks() {
|
|
let handlers = [];
|
|
function add(handler) {
|
|
handlers.push(handler);
|
|
return () => {
|
|
const i = handlers.indexOf(handler);
|
|
if (i > -1)
|
|
handlers.splice(i, 1);
|
|
};
|
|
}
|
|
function reset() {
|
|
handlers = [];
|
|
}
|
|
return {
|
|
add,
|
|
list: () => handlers,
|
|
reset,
|
|
};
|
|
}
|
|
|
|
function registerGuard(record, name, guard) {
|
|
const removeFromList = () => {
|
|
record[name].delete(guard);
|
|
};
|
|
(0,vue__WEBPACK_IMPORTED_MODULE_0__.onUnmounted)(removeFromList);
|
|
(0,vue__WEBPACK_IMPORTED_MODULE_0__.onDeactivated)(removeFromList);
|
|
(0,vue__WEBPACK_IMPORTED_MODULE_0__.onActivated)(() => {
|
|
record[name].add(guard);
|
|
});
|
|
record[name].add(guard);
|
|
}
|
|
/**
|
|
* Add a navigation guard that triggers whenever the component for the current
|
|
* location is about to be left. Similar to {@link beforeRouteLeave} but can be
|
|
* used in any component. The guard is removed when the component is unmounted.
|
|
*
|
|
* @param leaveGuard - {@link NavigationGuard}
|
|
*/
|
|
function onBeforeRouteLeave(leaveGuard) {
|
|
if (( true) && !(0,vue__WEBPACK_IMPORTED_MODULE_0__.getCurrentInstance)()) {
|
|
warn('getCurrentInstance() returned null. onBeforeRouteLeave() must be called at the top of a setup function');
|
|
return;
|
|
}
|
|
const activeRecord = (0,vue__WEBPACK_IMPORTED_MODULE_0__.inject)(matchedRouteKey,
|
|
// to avoid warning
|
|
{}).value;
|
|
if (!activeRecord) {
|
|
( true) &&
|
|
warn('No active route record was found. Are you missing a <router-view> component?');
|
|
return;
|
|
}
|
|
registerGuard(activeRecord, 'leaveGuards', leaveGuard);
|
|
}
|
|
/**
|
|
* Add a navigation guard that triggers whenever the current location is about
|
|
* to be updated. Similar to {@link beforeRouteUpdate} but can be used in any
|
|
* component. The guard is removed when the component is unmounted.
|
|
*
|
|
* @param updateGuard - {@link NavigationGuard}
|
|
*/
|
|
function onBeforeRouteUpdate(updateGuard) {
|
|
if (( true) && !(0,vue__WEBPACK_IMPORTED_MODULE_0__.getCurrentInstance)()) {
|
|
warn('getCurrentInstance() returned null. onBeforeRouteUpdate() must be called at the top of a setup function');
|
|
return;
|
|
}
|
|
const activeRecord = (0,vue__WEBPACK_IMPORTED_MODULE_0__.inject)(matchedRouteKey,
|
|
// to avoid warning
|
|
{}).value;
|
|
if (!activeRecord) {
|
|
( true) &&
|
|
warn('No active route record was found. Are you missing a <router-view> component?');
|
|
return;
|
|
}
|
|
registerGuard(activeRecord, 'updateGuards', updateGuard);
|
|
}
|
|
function guardToPromiseFn(guard, to, from, record, name) {
|
|
// keep a reference to the enterCallbackArray to prevent pushing callbacks if a new navigation took place
|
|
const enterCallbackArray = record &&
|
|
// name is defined if record is because of the function overload
|
|
(record.enterCallbacks[name] = record.enterCallbacks[name] || []);
|
|
return () => new Promise((resolve, reject) => {
|
|
const next = (valid) => {
|
|
if (valid === false)
|
|
reject(createRouterError(4 /* NAVIGATION_ABORTED */, {
|
|
from,
|
|
to,
|
|
}));
|
|
else if (valid instanceof Error) {
|
|
reject(valid);
|
|
}
|
|
else if (isRouteLocation(valid)) {
|
|
reject(createRouterError(2 /* NAVIGATION_GUARD_REDIRECT */, {
|
|
from: to,
|
|
to: valid,
|
|
}));
|
|
}
|
|
else {
|
|
if (enterCallbackArray &&
|
|
// since enterCallbackArray is truthy, both record and name also are
|
|
record.enterCallbacks[name] === enterCallbackArray &&
|
|
typeof valid === 'function')
|
|
enterCallbackArray.push(valid);
|
|
resolve();
|
|
}
|
|
};
|
|
// wrapping with Promise.resolve allows it to work with both async and sync guards
|
|
const guardReturn = guard.call(record && record.instances[name], to, from, ( true) ? canOnlyBeCalledOnce(next, to, from) : 0);
|
|
let guardCall = Promise.resolve(guardReturn);
|
|
if (guard.length < 3)
|
|
guardCall = guardCall.then(next);
|
|
if (( true) && guard.length > 2) {
|
|
const message = `The "next" callback was never called inside of ${guard.name ? '"' + guard.name + '"' : ''}:\n${guard.toString()}\n. If you are returning a value instead of calling "next", make sure to remove the "next" parameter from your function.`;
|
|
if (typeof guardReturn === 'object' && 'then' in guardReturn) {
|
|
guardCall = guardCall.then(resolvedValue => {
|
|
// @ts-expect-error: _called is added at canOnlyBeCalledOnce
|
|
if (!next._called) {
|
|
warn(message);
|
|
return Promise.reject(new Error('Invalid navigation guard'));
|
|
}
|
|
return resolvedValue;
|
|
});
|
|
// TODO: test me!
|
|
}
|
|
else if (guardReturn !== undefined) {
|
|
// @ts-expect-error: _called is added at canOnlyBeCalledOnce
|
|
if (!next._called) {
|
|
warn(message);
|
|
reject(new Error('Invalid navigation guard'));
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
guardCall.catch(err => reject(err));
|
|
});
|
|
}
|
|
function canOnlyBeCalledOnce(next, to, from) {
|
|
let called = 0;
|
|
return function () {
|
|
if (called++ === 1)
|
|
warn(`The "next" callback was called more than once in one navigation guard when going from "${from.fullPath}" to "${to.fullPath}". It should be called exactly one time in each navigation guard. This will fail in production.`);
|
|
// @ts-expect-error: we put it in the original one because it's easier to check
|
|
next._called = true;
|
|
if (called === 1)
|
|
next.apply(null, arguments);
|
|
};
|
|
}
|
|
function extractComponentsGuards(matched, guardType, to, from) {
|
|
const guards = [];
|
|
for (const record of matched) {
|
|
for (const name in record.components) {
|
|
let rawComponent = record.components[name];
|
|
if ((true)) {
|
|
if (!rawComponent ||
|
|
(typeof rawComponent !== 'object' &&
|
|
typeof rawComponent !== 'function')) {
|
|
warn(`Component "${name}" in record with path "${record.path}" is not` +
|
|
` a valid component. Received "${String(rawComponent)}".`);
|
|
// throw to ensure we stop here but warn to ensure the message isn't
|
|
// missed by the user
|
|
throw new Error('Invalid route component');
|
|
}
|
|
else if ('then' in rawComponent) {
|
|
// warn if user wrote import('/component.vue') instead of () =>
|
|
// import('./component.vue')
|
|
warn(`Component "${name}" in record with path "${record.path}" is a ` +
|
|
`Promise instead of a function that returns a Promise. Did you ` +
|
|
`write "import('./MyPage.vue')" instead of ` +
|
|
`"() => import('./MyPage.vue')" ? This will break in ` +
|
|
`production if not fixed.`);
|
|
const promise = rawComponent;
|
|
rawComponent = () => promise;
|
|
}
|
|
else if (rawComponent.__asyncLoader &&
|
|
// warn only once per component
|
|
!rawComponent.__warnedDefineAsync) {
|
|
rawComponent.__warnedDefineAsync = true;
|
|
warn(`Component "${name}" in record with path "${record.path}" is defined ` +
|
|
`using "defineAsyncComponent()". ` +
|
|
`Write "() => import('./MyPage.vue')" instead of ` +
|
|
`"defineAsyncComponent(() => import('./MyPage.vue'))".`);
|
|
}
|
|
}
|
|
// skip update and leave guards if the route component is not mounted
|
|
if (guardType !== 'beforeRouteEnter' && !record.instances[name])
|
|
continue;
|
|
if (isRouteComponent(rawComponent)) {
|
|
// __vccOpts is added by vue-class-component and contain the regular options
|
|
const options = rawComponent.__vccOpts || rawComponent;
|
|
const guard = options[guardType];
|
|
guard && guards.push(guardToPromiseFn(guard, to, from, record, name));
|
|
}
|
|
else {
|
|
// start requesting the chunk already
|
|
let componentPromise = rawComponent();
|
|
if (( true) && !('catch' in componentPromise)) {
|
|
warn(`Component "${name}" in record with path "${record.path}" is a function that does not return a Promise. If you were passing a functional component, make sure to add a "displayName" to the component. This will break in production if not fixed.`);
|
|
componentPromise = Promise.resolve(componentPromise);
|
|
}
|
|
guards.push(() => componentPromise.then(resolved => {
|
|
if (!resolved)
|
|
return Promise.reject(new Error(`Couldn't resolve component "${name}" at "${record.path}"`));
|
|
const resolvedComponent = isESModule(resolved)
|
|
? resolved.default
|
|
: resolved;
|
|
// replace the function with the resolved component
|
|
record.components[name] = resolvedComponent;
|
|
// __vccOpts is added by vue-class-component and contain the regular options
|
|
const options = resolvedComponent.__vccOpts || resolvedComponent;
|
|
const guard = options[guardType];
|
|
return guard && guardToPromiseFn(guard, to, from, record, name)();
|
|
}));
|
|
}
|
|
}
|
|
}
|
|
return guards;
|
|
}
|
|
/**
|
|
* Allows differentiating lazy components from functional components and vue-class-component
|
|
*
|
|
* @param component
|
|
*/
|
|
function isRouteComponent(component) {
|
|
return (typeof component === 'object' ||
|
|
'displayName' in component ||
|
|
'props' in component ||
|
|
'__vccOpts' in component);
|
|
}
|
|
|
|
// TODO: we could allow currentRoute as a prop to expose `isActive` and
|
|
// `isExactActive` behavior should go through an RFC
|
|
function useLink(props) {
|
|
const router = (0,vue__WEBPACK_IMPORTED_MODULE_0__.inject)(routerKey);
|
|
const currentRoute = (0,vue__WEBPACK_IMPORTED_MODULE_0__.inject)(routeLocationKey);
|
|
const route = (0,vue__WEBPACK_IMPORTED_MODULE_0__.computed)(() => router.resolve((0,vue__WEBPACK_IMPORTED_MODULE_0__.unref)(props.to)));
|
|
const activeRecordIndex = (0,vue__WEBPACK_IMPORTED_MODULE_0__.computed)(() => {
|
|
const { matched } = route.value;
|
|
const { length } = matched;
|
|
const routeMatched = matched[length - 1];
|
|
const currentMatched = currentRoute.matched;
|
|
if (!routeMatched || !currentMatched.length)
|
|
return -1;
|
|
const index = currentMatched.findIndex(isSameRouteRecord.bind(null, routeMatched));
|
|
if (index > -1)
|
|
return index;
|
|
// possible parent record
|
|
const parentRecordPath = getOriginalPath(matched[length - 2]);
|
|
return (
|
|
// we are dealing with nested routes
|
|
length > 1 &&
|
|
// if the parent and matched route have the same path, this link is
|
|
// referring to the empty child. Or we currently are on a different
|
|
// child of the same parent
|
|
getOriginalPath(routeMatched) === parentRecordPath &&
|
|
// avoid comparing the child with its parent
|
|
currentMatched[currentMatched.length - 1].path !== parentRecordPath
|
|
? currentMatched.findIndex(isSameRouteRecord.bind(null, matched[length - 2]))
|
|
: index);
|
|
});
|
|
const isActive = (0,vue__WEBPACK_IMPORTED_MODULE_0__.computed)(() => activeRecordIndex.value > -1 &&
|
|
includesParams(currentRoute.params, route.value.params));
|
|
const isExactActive = (0,vue__WEBPACK_IMPORTED_MODULE_0__.computed)(() => activeRecordIndex.value > -1 &&
|
|
activeRecordIndex.value === currentRoute.matched.length - 1 &&
|
|
isSameRouteLocationParams(currentRoute.params, route.value.params));
|
|
function navigate(e = {}) {
|
|
if (guardEvent(e)) {
|
|
return router[(0,vue__WEBPACK_IMPORTED_MODULE_0__.unref)(props.replace) ? 'replace' : 'push']((0,vue__WEBPACK_IMPORTED_MODULE_0__.unref)(props.to)
|
|
// avoid uncaught errors are they are logged anyway
|
|
).catch(noop);
|
|
}
|
|
return Promise.resolve();
|
|
}
|
|
// devtools only
|
|
if (( true) && isBrowser) {
|
|
const instance = (0,vue__WEBPACK_IMPORTED_MODULE_0__.getCurrentInstance)();
|
|
if (instance) {
|
|
const linkContextDevtools = {
|
|
route: route.value,
|
|
isActive: isActive.value,
|
|
isExactActive: isExactActive.value,
|
|
};
|
|
// @ts-expect-error: this is internal
|
|
instance.__vrl_devtools = instance.__vrl_devtools || [];
|
|
// @ts-expect-error: this is internal
|
|
instance.__vrl_devtools.push(linkContextDevtools);
|
|
(0,vue__WEBPACK_IMPORTED_MODULE_0__.watchEffect)(() => {
|
|
linkContextDevtools.route = route.value;
|
|
linkContextDevtools.isActive = isActive.value;
|
|
linkContextDevtools.isExactActive = isExactActive.value;
|
|
}, { flush: 'post' });
|
|
}
|
|
}
|
|
return {
|
|
route,
|
|
href: (0,vue__WEBPACK_IMPORTED_MODULE_0__.computed)(() => route.value.href),
|
|
isActive,
|
|
isExactActive,
|
|
navigate,
|
|
};
|
|
}
|
|
const RouterLinkImpl = /*#__PURE__*/ (0,vue__WEBPACK_IMPORTED_MODULE_0__.defineComponent)({
|
|
name: 'RouterLink',
|
|
props: {
|
|
to: {
|
|
type: [String, Object],
|
|
required: true,
|
|
},
|
|
replace: Boolean,
|
|
activeClass: String,
|
|
// inactiveClass: String,
|
|
exactActiveClass: String,
|
|
custom: Boolean,
|
|
ariaCurrentValue: {
|
|
type: String,
|
|
default: 'page',
|
|
},
|
|
},
|
|
useLink,
|
|
setup(props, { slots }) {
|
|
const link = (0,vue__WEBPACK_IMPORTED_MODULE_0__.reactive)(useLink(props));
|
|
const { options } = (0,vue__WEBPACK_IMPORTED_MODULE_0__.inject)(routerKey);
|
|
const elClass = (0,vue__WEBPACK_IMPORTED_MODULE_0__.computed)(() => ({
|
|
[getLinkClass(props.activeClass, options.linkActiveClass, 'router-link-active')]: link.isActive,
|
|
// [getLinkClass(
|
|
// props.inactiveClass,
|
|
// options.linkInactiveClass,
|
|
// 'router-link-inactive'
|
|
// )]: !link.isExactActive,
|
|
[getLinkClass(props.exactActiveClass, options.linkExactActiveClass, 'router-link-exact-active')]: link.isExactActive,
|
|
}));
|
|
return () => {
|
|
const children = slots.default && slots.default(link);
|
|
return props.custom
|
|
? children
|
|
: (0,vue__WEBPACK_IMPORTED_MODULE_0__.h)('a', {
|
|
'aria-current': link.isExactActive
|
|
? props.ariaCurrentValue
|
|
: null,
|
|
href: link.href,
|
|
// this would override user added attrs but Vue will still add
|
|
// the listener so we end up triggering both
|
|
onClick: link.navigate,
|
|
class: elClass.value,
|
|
}, children);
|
|
};
|
|
},
|
|
});
|
|
// export the public type for h/tsx inference
|
|
// also to avoid inline import() in generated d.ts files
|
|
/**
|
|
* Component to render a link that triggers a navigation on click.
|
|
*/
|
|
const RouterLink = RouterLinkImpl;
|
|
function guardEvent(e) {
|
|
// don't redirect with control keys
|
|
if (e.metaKey || e.altKey || e.ctrlKey || e.shiftKey)
|
|
return;
|
|
// don't redirect when preventDefault called
|
|
if (e.defaultPrevented)
|
|
return;
|
|
// don't redirect on right click
|
|
if (e.button !== undefined && e.button !== 0)
|
|
return;
|
|
// don't redirect if `target="_blank"`
|
|
// @ts-expect-error getAttribute does exist
|
|
if (e.currentTarget && e.currentTarget.getAttribute) {
|
|
// @ts-expect-error getAttribute exists
|
|
const target = e.currentTarget.getAttribute('target');
|
|
if (/\b_blank\b/i.test(target))
|
|
return;
|
|
}
|
|
// this may be a Weex event which doesn't have this method
|
|
if (e.preventDefault)
|
|
e.preventDefault();
|
|
return true;
|
|
}
|
|
function includesParams(outer, inner) {
|
|
for (const key in inner) {
|
|
const innerValue = inner[key];
|
|
const outerValue = outer[key];
|
|
if (typeof innerValue === 'string') {
|
|
if (innerValue !== outerValue)
|
|
return false;
|
|
}
|
|
else {
|
|
if (!Array.isArray(outerValue) ||
|
|
outerValue.length !== innerValue.length ||
|
|
innerValue.some((value, i) => value !== outerValue[i]))
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
/**
|
|
* Get the original path value of a record by following its aliasOf
|
|
* @param record
|
|
*/
|
|
function getOriginalPath(record) {
|
|
return record ? (record.aliasOf ? record.aliasOf.path : record.path) : '';
|
|
}
|
|
/**
|
|
* Utility class to get the active class based on defaults.
|
|
* @param propClass
|
|
* @param globalClass
|
|
* @param defaultClass
|
|
*/
|
|
const getLinkClass = (propClass, globalClass, defaultClass) => propClass != null
|
|
? propClass
|
|
: globalClass != null
|
|
? globalClass
|
|
: defaultClass;
|
|
|
|
const RouterViewImpl = /*#__PURE__*/ (0,vue__WEBPACK_IMPORTED_MODULE_0__.defineComponent)({
|
|
name: 'RouterView',
|
|
// #674 we manually inherit them
|
|
inheritAttrs: false,
|
|
props: {
|
|
name: {
|
|
type: String,
|
|
default: 'default',
|
|
},
|
|
route: Object,
|
|
},
|
|
setup(props, { attrs, slots }) {
|
|
( true) && warnDeprecatedUsage();
|
|
const injectedRoute = (0,vue__WEBPACK_IMPORTED_MODULE_0__.inject)(routerViewLocationKey);
|
|
const routeToDisplay = (0,vue__WEBPACK_IMPORTED_MODULE_0__.computed)(() => props.route || injectedRoute.value);
|
|
const depth = (0,vue__WEBPACK_IMPORTED_MODULE_0__.inject)(viewDepthKey, 0);
|
|
const matchedRouteRef = (0,vue__WEBPACK_IMPORTED_MODULE_0__.computed)(() => routeToDisplay.value.matched[depth]);
|
|
(0,vue__WEBPACK_IMPORTED_MODULE_0__.provide)(viewDepthKey, depth + 1);
|
|
(0,vue__WEBPACK_IMPORTED_MODULE_0__.provide)(matchedRouteKey, matchedRouteRef);
|
|
(0,vue__WEBPACK_IMPORTED_MODULE_0__.provide)(routerViewLocationKey, routeToDisplay);
|
|
const viewRef = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)();
|
|
// watch at the same time the component instance, the route record we are
|
|
// rendering, and the name
|
|
(0,vue__WEBPACK_IMPORTED_MODULE_0__.watch)(() => [viewRef.value, matchedRouteRef.value, props.name], ([instance, to, name], [oldInstance, from, oldName]) => {
|
|
// copy reused instances
|
|
if (to) {
|
|
// this will update the instance for new instances as well as reused
|
|
// instances when navigating to a new route
|
|
to.instances[name] = instance;
|
|
// the component instance is reused for a different route or name so
|
|
// we copy any saved update or leave guards. With async setup, the
|
|
// mounting component will mount before the matchedRoute changes,
|
|
// making instance === oldInstance, so we check if guards have been
|
|
// added before. This works because we remove guards when
|
|
// unmounting/deactivating components
|
|
if (from && from !== to && instance && instance === oldInstance) {
|
|
if (!to.leaveGuards.size) {
|
|
to.leaveGuards = from.leaveGuards;
|
|
}
|
|
if (!to.updateGuards.size) {
|
|
to.updateGuards = from.updateGuards;
|
|
}
|
|
}
|
|
}
|
|
// trigger beforeRouteEnter next callbacks
|
|
if (instance &&
|
|
to &&
|
|
// if there is no instance but to and from are the same this might be
|
|
// the first visit
|
|
(!from || !isSameRouteRecord(to, from) || !oldInstance)) {
|
|
(to.enterCallbacks[name] || []).forEach(callback => callback(instance));
|
|
}
|
|
}, { flush: 'post' });
|
|
return () => {
|
|
const route = routeToDisplay.value;
|
|
const matchedRoute = matchedRouteRef.value;
|
|
const ViewComponent = matchedRoute && matchedRoute.components[props.name];
|
|
// we need the value at the time we render because when we unmount, we
|
|
// navigated to a different location so the value is different
|
|
const currentName = props.name;
|
|
if (!ViewComponent) {
|
|
return normalizeSlot(slots.default, { Component: ViewComponent, route });
|
|
}
|
|
// props from route configuration
|
|
const routePropsOption = matchedRoute.props[props.name];
|
|
const routeProps = routePropsOption
|
|
? routePropsOption === true
|
|
? route.params
|
|
: typeof routePropsOption === 'function'
|
|
? routePropsOption(route)
|
|
: routePropsOption
|
|
: null;
|
|
const onVnodeUnmounted = vnode => {
|
|
// remove the instance reference to prevent leak
|
|
if (vnode.component.isUnmounted) {
|
|
matchedRoute.instances[currentName] = null;
|
|
}
|
|
};
|
|
const component = (0,vue__WEBPACK_IMPORTED_MODULE_0__.h)(ViewComponent, assign({}, routeProps, attrs, {
|
|
onVnodeUnmounted,
|
|
ref: viewRef,
|
|
}));
|
|
return (
|
|
// pass the vnode to the slot as a prop.
|
|
// h and <component :is="..."> both accept vnodes
|
|
normalizeSlot(slots.default, { Component: component, route }) ||
|
|
component);
|
|
};
|
|
},
|
|
});
|
|
function normalizeSlot(slot, data) {
|
|
if (!slot)
|
|
return null;
|
|
const slotContent = slot(data);
|
|
return slotContent.length === 1 ? slotContent[0] : slotContent;
|
|
}
|
|
// export the public type for h/tsx inference
|
|
// also to avoid inline import() in generated d.ts files
|
|
/**
|
|
* Component to display the current route the user is at.
|
|
*/
|
|
const RouterView = RouterViewImpl;
|
|
// warn against deprecated usage with <transition> & <keep-alive>
|
|
// due to functional component being no longer eager in Vue 3
|
|
function warnDeprecatedUsage() {
|
|
const instance = (0,vue__WEBPACK_IMPORTED_MODULE_0__.getCurrentInstance)();
|
|
const parentName = instance.parent && instance.parent.type.name;
|
|
if (parentName &&
|
|
(parentName === 'KeepAlive' || parentName.includes('Transition'))) {
|
|
const comp = parentName === 'KeepAlive' ? 'keep-alive' : 'transition';
|
|
warn(`<router-view> can no longer be used directly inside <transition> or <keep-alive>.\n` +
|
|
`Use slot props instead:\n\n` +
|
|
`<router-view v-slot="{ Component }">\n` +
|
|
` <${comp}>\n` +
|
|
` <component :is="Component" />\n` +
|
|
` </${comp}>\n` +
|
|
`</router-view>`);
|
|
}
|
|
}
|
|
|
|
function formatRouteLocation(routeLocation, tooltip) {
|
|
const copy = assign({}, routeLocation, {
|
|
// remove variables that can contain vue instances
|
|
matched: routeLocation.matched.map(matched => omit(matched, ['instances', 'children', 'aliasOf'])),
|
|
});
|
|
return {
|
|
_custom: {
|
|
type: null,
|
|
readOnly: true,
|
|
display: routeLocation.fullPath,
|
|
tooltip,
|
|
value: copy,
|
|
},
|
|
};
|
|
}
|
|
function formatDisplay(display) {
|
|
return {
|
|
_custom: {
|
|
display,
|
|
},
|
|
};
|
|
}
|
|
// to support multiple router instances
|
|
let routerId = 0;
|
|
function addDevtools(app, router, matcher) {
|
|
// Take over router.beforeEach and afterEach
|
|
// make sure we are not registering the devtool twice
|
|
if (router.__hasDevtools)
|
|
return;
|
|
router.__hasDevtools = true;
|
|
// increment to support multiple router instances
|
|
const id = routerId++;
|
|
(0,_vue_devtools_api__WEBPACK_IMPORTED_MODULE_1__.setupDevtoolsPlugin)({
|
|
id: 'org.vuejs.router' + (id ? '.' + id : ''),
|
|
label: 'Vue Router',
|
|
packageName: 'vue-router',
|
|
homepage: 'https://next.router.vuejs.org/',
|
|
logo: 'https://vuejs.org/images/icons/favicon-96x96.png',
|
|
componentStateTypes: ['Routing'],
|
|
app,
|
|
}, api => {
|
|
// display state added by the router
|
|
api.on.inspectComponent((payload, ctx) => {
|
|
if (payload.instanceData) {
|
|
payload.instanceData.state.push({
|
|
type: 'Routing',
|
|
key: '$route',
|
|
editable: false,
|
|
value: formatRouteLocation(router.currentRoute.value, 'Current Route'),
|
|
});
|
|
}
|
|
});
|
|
// mark router-link as active
|
|
api.on.visitComponentTree(({ treeNode: node, componentInstance }) => {
|
|
// if multiple useLink are used
|
|
if (Array.isArray(componentInstance.__vrl_devtools)) {
|
|
componentInstance.__devtoolsApi = api;
|
|
componentInstance.__vrl_devtools.forEach(devtoolsData => {
|
|
let backgroundColor = ORANGE_400;
|
|
let tooltip = '';
|
|
if (devtoolsData.isExactActive) {
|
|
backgroundColor = LIME_500;
|
|
tooltip = 'This is exactly active';
|
|
}
|
|
else if (devtoolsData.isActive) {
|
|
backgroundColor = BLUE_600;
|
|
tooltip = 'This link is active';
|
|
}
|
|
node.tags.push({
|
|
label: devtoolsData.route.path,
|
|
textColor: 0,
|
|
tooltip,
|
|
backgroundColor,
|
|
});
|
|
});
|
|
}
|
|
});
|
|
(0,vue__WEBPACK_IMPORTED_MODULE_0__.watch)(router.currentRoute, () => {
|
|
// refresh active state
|
|
refreshRoutesView();
|
|
api.notifyComponentUpdate();
|
|
api.sendInspectorTree(routerInspectorId);
|
|
api.sendInspectorState(routerInspectorId);
|
|
});
|
|
const navigationsLayerId = 'router:navigations:' + id;
|
|
api.addTimelineLayer({
|
|
id: navigationsLayerId,
|
|
label: `Router${id ? ' ' + id : ''} Navigations`,
|
|
color: 0x40a8c4,
|
|
});
|
|
// const errorsLayerId = 'router:errors'
|
|
// api.addTimelineLayer({
|
|
// id: errorsLayerId,
|
|
// label: 'Router Errors',
|
|
// color: 0xea5455,
|
|
// })
|
|
router.onError((error, to) => {
|
|
api.addTimelineEvent({
|
|
layerId: navigationsLayerId,
|
|
event: {
|
|
title: 'Error during Navigation',
|
|
subtitle: to.fullPath,
|
|
logType: 'error',
|
|
time: Date.now(),
|
|
data: { error },
|
|
groupId: to.meta.__navigationId,
|
|
},
|
|
});
|
|
});
|
|
// attached to `meta` and used to group events
|
|
let navigationId = 0;
|
|
router.beforeEach((to, from) => {
|
|
const data = {
|
|
guard: formatDisplay('beforeEach'),
|
|
from: formatRouteLocation(from, 'Current Location during this navigation'),
|
|
to: formatRouteLocation(to, 'Target location'),
|
|
};
|
|
// Used to group navigations together, hide from devtools
|
|
Object.defineProperty(to.meta, '__navigationId', {
|
|
value: navigationId++,
|
|
});
|
|
api.addTimelineEvent({
|
|
layerId: navigationsLayerId,
|
|
event: {
|
|
time: Date.now(),
|
|
title: 'Start of navigation',
|
|
subtitle: to.fullPath,
|
|
data,
|
|
groupId: to.meta.__navigationId,
|
|
},
|
|
});
|
|
});
|
|
router.afterEach((to, from, failure) => {
|
|
const data = {
|
|
guard: formatDisplay('afterEach'),
|
|
};
|
|
if (failure) {
|
|
data.failure = {
|
|
_custom: {
|
|
type: Error,
|
|
readOnly: true,
|
|
display: failure ? failure.message : '',
|
|
tooltip: 'Navigation Failure',
|
|
value: failure,
|
|
},
|
|
};
|
|
data.status = formatDisplay('❌');
|
|
}
|
|
else {
|
|
data.status = formatDisplay('✅');
|
|
}
|
|
// we set here to have the right order
|
|
data.from = formatRouteLocation(from, 'Current Location during this navigation');
|
|
data.to = formatRouteLocation(to, 'Target location');
|
|
api.addTimelineEvent({
|
|
layerId: navigationsLayerId,
|
|
event: {
|
|
title: 'End of navigation',
|
|
subtitle: to.fullPath,
|
|
time: Date.now(),
|
|
data,
|
|
logType: failure ? 'warning' : 'default',
|
|
groupId: to.meta.__navigationId,
|
|
},
|
|
});
|
|
});
|
|
/**
|
|
* Inspector of Existing routes
|
|
*/
|
|
const routerInspectorId = 'router-inspector:' + id;
|
|
api.addInspector({
|
|
id: routerInspectorId,
|
|
label: 'Routes' + (id ? ' ' + id : ''),
|
|
icon: 'book',
|
|
treeFilterPlaceholder: 'Search routes',
|
|
});
|
|
function refreshRoutesView() {
|
|
// the routes view isn't active
|
|
if (!activeRoutesPayload)
|
|
return;
|
|
const payload = activeRoutesPayload;
|
|
// children routes will appear as nested
|
|
let routes = matcher.getRoutes().filter(route => !route.parent);
|
|
// reset match state to false
|
|
routes.forEach(resetMatchStateOnRouteRecord);
|
|
// apply a match state if there is a payload
|
|
if (payload.filter) {
|
|
routes = routes.filter(route =>
|
|
// save matches state based on the payload
|
|
isRouteMatching(route, payload.filter.toLowerCase()));
|
|
}
|
|
// mark active routes
|
|
routes.forEach(route => markRouteRecordActive(route, router.currentRoute.value));
|
|
payload.rootNodes = routes.map(formatRouteRecordForInspector);
|
|
}
|
|
let activeRoutesPayload;
|
|
api.on.getInspectorTree(payload => {
|
|
activeRoutesPayload = payload;
|
|
if (payload.app === app && payload.inspectorId === routerInspectorId) {
|
|
refreshRoutesView();
|
|
}
|
|
});
|
|
/**
|
|
* Display information about the currently selected route record
|
|
*/
|
|
api.on.getInspectorState(payload => {
|
|
if (payload.app === app && payload.inspectorId === routerInspectorId) {
|
|
const routes = matcher.getRoutes();
|
|
const route = routes.find(route => route.record.__vd_id === payload.nodeId);
|
|
if (route) {
|
|
payload.state = {
|
|
options: formatRouteRecordMatcherForStateInspector(route),
|
|
};
|
|
}
|
|
}
|
|
});
|
|
api.sendInspectorTree(routerInspectorId);
|
|
api.sendInspectorState(routerInspectorId);
|
|
});
|
|
}
|
|
function modifierForKey(key) {
|
|
if (key.optional) {
|
|
return key.repeatable ? '*' : '?';
|
|
}
|
|
else {
|
|
return key.repeatable ? '+' : '';
|
|
}
|
|
}
|
|
function formatRouteRecordMatcherForStateInspector(route) {
|
|
const { record } = route;
|
|
const fields = [
|
|
{ editable: false, key: 'path', value: record.path },
|
|
];
|
|
if (record.name != null) {
|
|
fields.push({
|
|
editable: false,
|
|
key: 'name',
|
|
value: record.name,
|
|
});
|
|
}
|
|
fields.push({ editable: false, key: 'regexp', value: route.re });
|
|
if (route.keys.length) {
|
|
fields.push({
|
|
editable: false,
|
|
key: 'keys',
|
|
value: {
|
|
_custom: {
|
|
type: null,
|
|
readOnly: true,
|
|
display: route.keys
|
|
.map(key => `${key.name}${modifierForKey(key)}`)
|
|
.join(' '),
|
|
tooltip: 'Param keys',
|
|
value: route.keys,
|
|
},
|
|
},
|
|
});
|
|
}
|
|
if (record.redirect != null) {
|
|
fields.push({
|
|
editable: false,
|
|
key: 'redirect',
|
|
value: record.redirect,
|
|
});
|
|
}
|
|
if (route.alias.length) {
|
|
fields.push({
|
|
editable: false,
|
|
key: 'aliases',
|
|
value: route.alias.map(alias => alias.record.path),
|
|
});
|
|
}
|
|
fields.push({
|
|
key: 'score',
|
|
editable: false,
|
|
value: {
|
|
_custom: {
|
|
type: null,
|
|
readOnly: true,
|
|
display: route.score.map(score => score.join(', ')).join(' | '),
|
|
tooltip: 'Score used to sort routes',
|
|
value: route.score,
|
|
},
|
|
},
|
|
});
|
|
return fields;
|
|
}
|
|
/**
|
|
* Extracted from tailwind palette
|
|
*/
|
|
const PINK_500 = 0xec4899;
|
|
const BLUE_600 = 0x2563eb;
|
|
const LIME_500 = 0x84cc16;
|
|
const CYAN_400 = 0x22d3ee;
|
|
const ORANGE_400 = 0xfb923c;
|
|
// const GRAY_100 = 0xf4f4f5
|
|
const DARK = 0x666666;
|
|
function formatRouteRecordForInspector(route) {
|
|
const tags = [];
|
|
const { record } = route;
|
|
if (record.name != null) {
|
|
tags.push({
|
|
label: String(record.name),
|
|
textColor: 0,
|
|
backgroundColor: CYAN_400,
|
|
});
|
|
}
|
|
if (record.aliasOf) {
|
|
tags.push({
|
|
label: 'alias',
|
|
textColor: 0,
|
|
backgroundColor: ORANGE_400,
|
|
});
|
|
}
|
|
if (route.__vd_match) {
|
|
tags.push({
|
|
label: 'matches',
|
|
textColor: 0,
|
|
backgroundColor: PINK_500,
|
|
});
|
|
}
|
|
if (route.__vd_exactActive) {
|
|
tags.push({
|
|
label: 'exact',
|
|
textColor: 0,
|
|
backgroundColor: LIME_500,
|
|
});
|
|
}
|
|
if (route.__vd_active) {
|
|
tags.push({
|
|
label: 'active',
|
|
textColor: 0,
|
|
backgroundColor: BLUE_600,
|
|
});
|
|
}
|
|
if (record.redirect) {
|
|
tags.push({
|
|
label: 'redirect: ' +
|
|
(typeof record.redirect === 'string' ? record.redirect : 'Object'),
|
|
textColor: 0xffffff,
|
|
backgroundColor: DARK,
|
|
});
|
|
}
|
|
// add an id to be able to select it. Using the `path` is not possible because
|
|
// empty path children would collide with their parents
|
|
let id = record.__vd_id;
|
|
if (id == null) {
|
|
id = String(routeRecordId++);
|
|
record.__vd_id = id;
|
|
}
|
|
return {
|
|
id,
|
|
label: record.path,
|
|
tags,
|
|
children: route.children.map(formatRouteRecordForInspector),
|
|
};
|
|
}
|
|
// incremental id for route records and inspector state
|
|
let routeRecordId = 0;
|
|
const EXTRACT_REGEXP_RE = /^\/(.*)\/([a-z]*)$/;
|
|
function markRouteRecordActive(route, currentRoute) {
|
|
// no route will be active if matched is empty
|
|
// reset the matching state
|
|
const isExactActive = currentRoute.matched.length &&
|
|
isSameRouteRecord(currentRoute.matched[currentRoute.matched.length - 1], route.record);
|
|
route.__vd_exactActive = route.__vd_active = isExactActive;
|
|
if (!isExactActive) {
|
|
route.__vd_active = currentRoute.matched.some(match => isSameRouteRecord(match, route.record));
|
|
}
|
|
route.children.forEach(childRoute => markRouteRecordActive(childRoute, currentRoute));
|
|
}
|
|
function resetMatchStateOnRouteRecord(route) {
|
|
route.__vd_match = false;
|
|
route.children.forEach(resetMatchStateOnRouteRecord);
|
|
}
|
|
function isRouteMatching(route, filter) {
|
|
const found = String(route.re).match(EXTRACT_REGEXP_RE);
|
|
route.__vd_match = false;
|
|
if (!found || found.length < 3) {
|
|
return false;
|
|
}
|
|
// use a regexp without $ at the end to match nested routes better
|
|
const nonEndingRE = new RegExp(found[1].replace(/\$$/, ''), found[2]);
|
|
if (nonEndingRE.test(filter)) {
|
|
// mark children as matches
|
|
route.children.forEach(child => isRouteMatching(child, filter));
|
|
// exception case: `/`
|
|
if (route.record.path !== '/' || filter === '/') {
|
|
route.__vd_match = route.re.test(filter);
|
|
return true;
|
|
}
|
|
// hide the / route
|
|
return false;
|
|
}
|
|
const path = route.record.path.toLowerCase();
|
|
const decodedPath = decode(path);
|
|
// also allow partial matching on the path
|
|
if (!filter.startsWith('/') &&
|
|
(decodedPath.includes(filter) || path.includes(filter)))
|
|
return true;
|
|
if (decodedPath.startsWith(filter) || path.startsWith(filter))
|
|
return true;
|
|
if (route.record.name && String(route.record.name).includes(filter))
|
|
return true;
|
|
return route.children.some(child => isRouteMatching(child, filter));
|
|
}
|
|
function omit(obj, keys) {
|
|
const ret = {};
|
|
for (const key in obj) {
|
|
if (!keys.includes(key)) {
|
|
// @ts-expect-error
|
|
ret[key] = obj[key];
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* Creates a Router instance that can be used by a Vue app.
|
|
*
|
|
* @param options - {@link RouterOptions}
|
|
*/
|
|
function createRouter(options) {
|
|
const matcher = createRouterMatcher(options.routes, options);
|
|
const parseQuery$1 = options.parseQuery || parseQuery;
|
|
const stringifyQuery$1 = options.stringifyQuery || stringifyQuery;
|
|
const routerHistory = options.history;
|
|
if (( true) && !routerHistory)
|
|
throw new Error('Provide the "history" option when calling "createRouter()":' +
|
|
' https://next.router.vuejs.org/api/#history.');
|
|
const beforeGuards = useCallbacks();
|
|
const beforeResolveGuards = useCallbacks();
|
|
const afterGuards = useCallbacks();
|
|
const currentRoute = (0,vue__WEBPACK_IMPORTED_MODULE_0__.shallowRef)(START_LOCATION_NORMALIZED);
|
|
let pendingLocation = START_LOCATION_NORMALIZED;
|
|
// leave the scrollRestoration if no scrollBehavior is provided
|
|
if (isBrowser && options.scrollBehavior && 'scrollRestoration' in history) {
|
|
history.scrollRestoration = 'manual';
|
|
}
|
|
const normalizeParams = applyToParams.bind(null, paramValue => '' + paramValue);
|
|
const encodeParams = applyToParams.bind(null, encodeParam);
|
|
const decodeParams =
|
|
// @ts-expect-error: intentionally avoid the type check
|
|
applyToParams.bind(null, decode);
|
|
function addRoute(parentOrRoute, route) {
|
|
let parent;
|
|
let record;
|
|
if (isRouteName(parentOrRoute)) {
|
|
parent = matcher.getRecordMatcher(parentOrRoute);
|
|
record = route;
|
|
}
|
|
else {
|
|
record = parentOrRoute;
|
|
}
|
|
return matcher.addRoute(record, parent);
|
|
}
|
|
function removeRoute(name) {
|
|
const recordMatcher = matcher.getRecordMatcher(name);
|
|
if (recordMatcher) {
|
|
matcher.removeRoute(recordMatcher);
|
|
}
|
|
else if ((true)) {
|
|
warn(`Cannot remove non-existent route "${String(name)}"`);
|
|
}
|
|
}
|
|
function getRoutes() {
|
|
return matcher.getRoutes().map(routeMatcher => routeMatcher.record);
|
|
}
|
|
function hasRoute(name) {
|
|
return !!matcher.getRecordMatcher(name);
|
|
}
|
|
function resolve(rawLocation, currentLocation) {
|
|
// const objectLocation = routerLocationAsObject(rawLocation)
|
|
// we create a copy to modify it later
|
|
currentLocation = assign({}, currentLocation || currentRoute.value);
|
|
if (typeof rawLocation === 'string') {
|
|
const locationNormalized = parseURL(parseQuery$1, rawLocation, currentLocation.path);
|
|
const matchedRoute = matcher.resolve({ path: locationNormalized.path }, currentLocation);
|
|
const href = routerHistory.createHref(locationNormalized.fullPath);
|
|
if ((true)) {
|
|
if (href.startsWith('//'))
|
|
warn(`Location "${rawLocation}" resolved to "${href}". A resolved location cannot start with multiple slashes.`);
|
|
else if (!matchedRoute.matched.length) {
|
|
warn(`No match found for location with path "${rawLocation}"`);
|
|
}
|
|
}
|
|
// locationNormalized is always a new object
|
|
return assign(locationNormalized, matchedRoute, {
|
|
params: decodeParams(matchedRoute.params),
|
|
hash: decode(locationNormalized.hash),
|
|
redirectedFrom: undefined,
|
|
href,
|
|
});
|
|
}
|
|
let matcherLocation;
|
|
// path could be relative in object as well
|
|
if ('path' in rawLocation) {
|
|
if (( true) &&
|
|
'params' in rawLocation &&
|
|
!('name' in rawLocation) &&
|
|
Object.keys(rawLocation.params).length) {
|
|
warn(`Path "${rawLocation.path}" was passed with params but they will be ignored. Use a named route alongside params instead.`);
|
|
}
|
|
matcherLocation = assign({}, rawLocation, {
|
|
path: parseURL(parseQuery$1, rawLocation.path, currentLocation.path).path,
|
|
});
|
|
}
|
|
else {
|
|
// remove any nullish param
|
|
const targetParams = assign({}, rawLocation.params);
|
|
for (const key in targetParams) {
|
|
if (targetParams[key] == null) {
|
|
delete targetParams[key];
|
|
}
|
|
}
|
|
// pass encoded values to the matcher so it can produce encoded path and fullPath
|
|
matcherLocation = assign({}, rawLocation, {
|
|
params: encodeParams(rawLocation.params),
|
|
});
|
|
// current location params are decoded, we need to encode them in case the
|
|
// matcher merges the params
|
|
currentLocation.params = encodeParams(currentLocation.params);
|
|
}
|
|
const matchedRoute = matcher.resolve(matcherLocation, currentLocation);
|
|
const hash = rawLocation.hash || '';
|
|
if (( true) && hash && !hash.startsWith('#')) {
|
|
warn(`A \`hash\` should always start with the character "#". Replace "${hash}" with "#${hash}".`);
|
|
}
|
|
// decoding them) the matcher might have merged current location params so
|
|
// we need to run the decoding again
|
|
matchedRoute.params = normalizeParams(decodeParams(matchedRoute.params));
|
|
const fullPath = stringifyURL(stringifyQuery$1, assign({}, rawLocation, {
|
|
hash: encodeHash(hash),
|
|
path: matchedRoute.path,
|
|
}));
|
|
const href = routerHistory.createHref(fullPath);
|
|
if ((true)) {
|
|
if (href.startsWith('//')) {
|
|
warn(`Location "${rawLocation}" resolved to "${href}". A resolved location cannot start with multiple slashes.`);
|
|
}
|
|
else if (!matchedRoute.matched.length) {
|
|
warn(`No match found for location with path "${'path' in rawLocation ? rawLocation.path : rawLocation}"`);
|
|
}
|
|
}
|
|
return assign({
|
|
fullPath,
|
|
// keep the hash encoded so fullPath is effectively path + encodedQuery +
|
|
// hash
|
|
hash,
|
|
query:
|
|
// if the user is using a custom query lib like qs, we might have
|
|
// nested objects, so we keep the query as is, meaning it can contain
|
|
// numbers at `$route.query`, but at the point, the user will have to
|
|
// use their own type anyway.
|
|
// https://github.com/vuejs/vue-router-next/issues/328#issuecomment-649481567
|
|
stringifyQuery$1 === stringifyQuery
|
|
? normalizeQuery(rawLocation.query)
|
|
: (rawLocation.query || {}),
|
|
}, matchedRoute, {
|
|
redirectedFrom: undefined,
|
|
href,
|
|
});
|
|
}
|
|
function locationAsObject(to) {
|
|
return typeof to === 'string'
|
|
? parseURL(parseQuery$1, to, currentRoute.value.path)
|
|
: assign({}, to);
|
|
}
|
|
function checkCanceledNavigation(to, from) {
|
|
if (pendingLocation !== to) {
|
|
return createRouterError(8 /* NAVIGATION_CANCELLED */, {
|
|
from,
|
|
to,
|
|
});
|
|
}
|
|
}
|
|
function push(to) {
|
|
return pushWithRedirect(to);
|
|
}
|
|
function replace(to) {
|
|
return push(assign(locationAsObject(to), { replace: true }));
|
|
}
|
|
function handleRedirectRecord(to) {
|
|
const lastMatched = to.matched[to.matched.length - 1];
|
|
if (lastMatched && lastMatched.redirect) {
|
|
const { redirect } = lastMatched;
|
|
let newTargetLocation = typeof redirect === 'function' ? redirect(to) : redirect;
|
|
if (typeof newTargetLocation === 'string') {
|
|
newTargetLocation =
|
|
newTargetLocation.includes('?') || newTargetLocation.includes('#')
|
|
? (newTargetLocation = locationAsObject(newTargetLocation))
|
|
: // force empty params
|
|
{ path: newTargetLocation };
|
|
// @ts-expect-error: force empty params when a string is passed to let
|
|
// the router parse them again
|
|
newTargetLocation.params = {};
|
|
}
|
|
if (( true) &&
|
|
!('path' in newTargetLocation) &&
|
|
!('name' in newTargetLocation)) {
|
|
warn(`Invalid redirect found:\n${JSON.stringify(newTargetLocation, null, 2)}\n when navigating to "${to.fullPath}". A redirect must contain a name or path. This will break in production.`);
|
|
throw new Error('Invalid redirect');
|
|
}
|
|
return assign({
|
|
query: to.query,
|
|
hash: to.hash,
|
|
params: to.params,
|
|
}, newTargetLocation);
|
|
}
|
|
}
|
|
function pushWithRedirect(to, redirectedFrom) {
|
|
const targetLocation = (pendingLocation = resolve(to));
|
|
const from = currentRoute.value;
|
|
const data = to.state;
|
|
const force = to.force;
|
|
// to could be a string where `replace` is a function
|
|
const replace = to.replace === true;
|
|
const shouldRedirect = handleRedirectRecord(targetLocation);
|
|
if (shouldRedirect)
|
|
return pushWithRedirect(assign(locationAsObject(shouldRedirect), {
|
|
state: data,
|
|
force,
|
|
replace,
|
|
}),
|
|
// keep original redirectedFrom if it exists
|
|
redirectedFrom || targetLocation);
|
|
// if it was a redirect we already called `pushWithRedirect` above
|
|
const toLocation = targetLocation;
|
|
toLocation.redirectedFrom = redirectedFrom;
|
|
let failure;
|
|
if (!force && isSameRouteLocation(stringifyQuery$1, from, targetLocation)) {
|
|
failure = createRouterError(16 /* NAVIGATION_DUPLICATED */, { to: toLocation, from });
|
|
// trigger scroll to allow scrolling to the same anchor
|
|
handleScroll(from, from,
|
|
// this is a push, the only way for it to be triggered from a
|
|
// history.listen is with a redirect, which makes it become a push
|
|
true,
|
|
// This cannot be the first navigation because the initial location
|
|
// cannot be manually navigated to
|
|
false);
|
|
}
|
|
return (failure ? Promise.resolve(failure) : navigate(toLocation, from))
|
|
.catch((error) => isNavigationFailure(error)
|
|
? error
|
|
: // reject any unknown error
|
|
triggerError(error, toLocation, from))
|
|
.then((failure) => {
|
|
if (failure) {
|
|
if (isNavigationFailure(failure, 2 /* NAVIGATION_GUARD_REDIRECT */)) {
|
|
if (( true) &&
|
|
// we are redirecting to the same location we were already at
|
|
isSameRouteLocation(stringifyQuery$1, resolve(failure.to), toLocation) &&
|
|
// and we have done it a couple of times
|
|
redirectedFrom &&
|
|
// @ts-expect-error: added only in dev
|
|
(redirectedFrom._count = redirectedFrom._count
|
|
? // @ts-expect-error
|
|
redirectedFrom._count + 1
|
|
: 1) > 10) {
|
|
warn(`Detected an infinite redirection in a navigation guard when going from "${from.fullPath}" to "${toLocation.fullPath}". Aborting to avoid a Stack Overflow. This will break in production if not fixed.`);
|
|
return Promise.reject(new Error('Infinite redirect in navigation guard'));
|
|
}
|
|
return pushWithRedirect(
|
|
// keep options
|
|
assign(locationAsObject(failure.to), {
|
|
state: data,
|
|
force,
|
|
replace,
|
|
}),
|
|
// preserve the original redirectedFrom if any
|
|
redirectedFrom || toLocation);
|
|
}
|
|
}
|
|
else {
|
|
// if we fail we don't finalize the navigation
|
|
failure = finalizeNavigation(toLocation, from, true, replace, data);
|
|
}
|
|
triggerAfterEach(toLocation, from, failure);
|
|
return failure;
|
|
});
|
|
}
|
|
/**
|
|
* Helper to reject and skip all navigation guards if a new navigation happened
|
|
* @param to
|
|
* @param from
|
|
*/
|
|
function checkCanceledNavigationAndReject(to, from) {
|
|
const error = checkCanceledNavigation(to, from);
|
|
return error ? Promise.reject(error) : Promise.resolve();
|
|
}
|
|
// TODO: refactor the whole before guards by internally using router.beforeEach
|
|
function navigate(to, from) {
|
|
let guards;
|
|
const [leavingRecords, updatingRecords, enteringRecords] = extractChangingRecords(to, from);
|
|
// all components here have been resolved once because we are leaving
|
|
guards = extractComponentsGuards(leavingRecords.reverse(), 'beforeRouteLeave', to, from);
|
|
// leavingRecords is already reversed
|
|
for (const record of leavingRecords) {
|
|
record.leaveGuards.forEach(guard => {
|
|
guards.push(guardToPromiseFn(guard, to, from));
|
|
});
|
|
}
|
|
const canceledNavigationCheck = checkCanceledNavigationAndReject.bind(null, to, from);
|
|
guards.push(canceledNavigationCheck);
|
|
// run the queue of per route beforeRouteLeave guards
|
|
return (runGuardQueue(guards)
|
|
.then(() => {
|
|
// check global guards beforeEach
|
|
guards = [];
|
|
for (const guard of beforeGuards.list()) {
|
|
guards.push(guardToPromiseFn(guard, to, from));
|
|
}
|
|
guards.push(canceledNavigationCheck);
|
|
return runGuardQueue(guards);
|
|
})
|
|
.then(() => {
|
|
// check in components beforeRouteUpdate
|
|
guards = extractComponentsGuards(updatingRecords, 'beforeRouteUpdate', to, from);
|
|
for (const record of updatingRecords) {
|
|
record.updateGuards.forEach(guard => {
|
|
guards.push(guardToPromiseFn(guard, to, from));
|
|
});
|
|
}
|
|
guards.push(canceledNavigationCheck);
|
|
// run the queue of per route beforeEnter guards
|
|
return runGuardQueue(guards);
|
|
})
|
|
.then(() => {
|
|
// check the route beforeEnter
|
|
guards = [];
|
|
for (const record of to.matched) {
|
|
// do not trigger beforeEnter on reused views
|
|
if (record.beforeEnter && !from.matched.includes(record)) {
|
|
if (Array.isArray(record.beforeEnter)) {
|
|
for (const beforeEnter of record.beforeEnter)
|
|
guards.push(guardToPromiseFn(beforeEnter, to, from));
|
|
}
|
|
else {
|
|
guards.push(guardToPromiseFn(record.beforeEnter, to, from));
|
|
}
|
|
}
|
|
}
|
|
guards.push(canceledNavigationCheck);
|
|
// run the queue of per route beforeEnter guards
|
|
return runGuardQueue(guards);
|
|
})
|
|
.then(() => {
|
|
// NOTE: at this point to.matched is normalized and does not contain any () => Promise<Component>
|
|
// clear existing enterCallbacks, these are added by extractComponentsGuards
|
|
to.matched.forEach(record => (record.enterCallbacks = {}));
|
|
// check in-component beforeRouteEnter
|
|
guards = extractComponentsGuards(enteringRecords, 'beforeRouteEnter', to, from);
|
|
guards.push(canceledNavigationCheck);
|
|
// run the queue of per route beforeEnter guards
|
|
return runGuardQueue(guards);
|
|
})
|
|
.then(() => {
|
|
// check global guards beforeResolve
|
|
guards = [];
|
|
for (const guard of beforeResolveGuards.list()) {
|
|
guards.push(guardToPromiseFn(guard, to, from));
|
|
}
|
|
guards.push(canceledNavigationCheck);
|
|
return runGuardQueue(guards);
|
|
})
|
|
// catch any navigation canceled
|
|
.catch(err => isNavigationFailure(err, 8 /* NAVIGATION_CANCELLED */)
|
|
? err
|
|
: Promise.reject(err)));
|
|
}
|
|
function triggerAfterEach(to, from, failure) {
|
|
// navigation is confirmed, call afterGuards
|
|
// TODO: wrap with error handlers
|
|
for (const guard of afterGuards.list())
|
|
guard(to, from, failure);
|
|
}
|
|
/**
|
|
* - Cleans up any navigation guards
|
|
* - Changes the url if necessary
|
|
* - Calls the scrollBehavior
|
|
*/
|
|
function finalizeNavigation(toLocation, from, isPush, replace, data) {
|
|
// a more recent navigation took place
|
|
const error = checkCanceledNavigation(toLocation, from);
|
|
if (error)
|
|
return error;
|
|
// only consider as push if it's not the first navigation
|
|
const isFirstNavigation = from === START_LOCATION_NORMALIZED;
|
|
const state = !isBrowser ? {} : history.state;
|
|
// change URL only if the user did a push/replace and if it's not the initial navigation because
|
|
// it's just reflecting the url
|
|
if (isPush) {
|
|
// on the initial navigation, we want to reuse the scroll position from
|
|
// history state if it exists
|
|
if (replace || isFirstNavigation)
|
|
routerHistory.replace(toLocation.fullPath, assign({
|
|
scroll: isFirstNavigation && state && state.scroll,
|
|
}, data));
|
|
else
|
|
routerHistory.push(toLocation.fullPath, data);
|
|
}
|
|
// accept current navigation
|
|
currentRoute.value = toLocation;
|
|
handleScroll(toLocation, from, isPush, isFirstNavigation);
|
|
markAsReady();
|
|
}
|
|
let removeHistoryListener;
|
|
// attach listener to history to trigger navigations
|
|
function setupListeners() {
|
|
removeHistoryListener = routerHistory.listen((to, _from, info) => {
|
|
// cannot be a redirect route because it was in history
|
|
const toLocation = resolve(to);
|
|
// due to dynamic routing, and to hash history with manual navigation
|
|
// (manually changing the url or calling history.hash = '#/somewhere'),
|
|
// there could be a redirect record in history
|
|
const shouldRedirect = handleRedirectRecord(toLocation);
|
|
if (shouldRedirect) {
|
|
pushWithRedirect(assign(shouldRedirect, { replace: true }), toLocation).catch(noop);
|
|
return;
|
|
}
|
|
pendingLocation = toLocation;
|
|
const from = currentRoute.value;
|
|
// TODO: should be moved to web history?
|
|
if (isBrowser) {
|
|
saveScrollPosition(getScrollKey(from.fullPath, info.delta), computeScrollPosition());
|
|
}
|
|
navigate(toLocation, from)
|
|
.catch((error) => {
|
|
if (isNavigationFailure(error, 4 /* NAVIGATION_ABORTED */ | 8 /* NAVIGATION_CANCELLED */)) {
|
|
return error;
|
|
}
|
|
if (isNavigationFailure(error, 2 /* NAVIGATION_GUARD_REDIRECT */)) {
|
|
// Here we could call if (info.delta) routerHistory.go(-info.delta,
|
|
// false) but this is bug prone as we have no way to wait the
|
|
// navigation to be finished before calling pushWithRedirect. Using
|
|
// a setTimeout of 16ms seems to work but there is not guarantee for
|
|
// it to work on every browser. So Instead we do not restore the
|
|
// history entry and trigger a new navigation as requested by the
|
|
// navigation guard.
|
|
// the error is already handled by router.push we just want to avoid
|
|
// logging the error
|
|
pushWithRedirect(error.to, toLocation
|
|
// avoid an uncaught rejection, let push call triggerError
|
|
)
|
|
.then(failure => {
|
|
// manual change in hash history #916 ending up in the URL not
|
|
// changing but it was changed by the manual url change, so we
|
|
// need to manually change it ourselves
|
|
if (isNavigationFailure(failure, 4 /* NAVIGATION_ABORTED */ |
|
|
16 /* NAVIGATION_DUPLICATED */) &&
|
|
!info.delta &&
|
|
info.type === NavigationType.pop) {
|
|
routerHistory.go(-1, false);
|
|
}
|
|
})
|
|
.catch(noop);
|
|
// avoid the then branch
|
|
return Promise.reject();
|
|
}
|
|
// do not restore history on unknown direction
|
|
if (info.delta)
|
|
routerHistory.go(-info.delta, false);
|
|
// unrecognized error, transfer to the global handler
|
|
return triggerError(error, toLocation, from);
|
|
})
|
|
.then((failure) => {
|
|
failure =
|
|
failure ||
|
|
finalizeNavigation(
|
|
// after navigation, all matched components are resolved
|
|
toLocation, from, false);
|
|
// revert the navigation
|
|
if (failure) {
|
|
if (info.delta) {
|
|
routerHistory.go(-info.delta, false);
|
|
}
|
|
else if (info.type === NavigationType.pop &&
|
|
isNavigationFailure(failure, 4 /* NAVIGATION_ABORTED */ | 16 /* NAVIGATION_DUPLICATED */)) {
|
|
// manual change in hash history #916
|
|
// it's like a push but lacks the information of the direction
|
|
routerHistory.go(-1, false);
|
|
}
|
|
}
|
|
triggerAfterEach(toLocation, from, failure);
|
|
})
|
|
.catch(noop);
|
|
});
|
|
}
|
|
// Initialization and Errors
|
|
let readyHandlers = useCallbacks();
|
|
let errorHandlers = useCallbacks();
|
|
let ready;
|
|
/**
|
|
* Trigger errorHandlers added via onError and throws the error as well
|
|
*
|
|
* @param error - error to throw
|
|
* @param to - location we were navigating to when the error happened
|
|
* @param from - location we were navigating from when the error happened
|
|
* @returns the error as a rejected promise
|
|
*/
|
|
function triggerError(error, to, from) {
|
|
markAsReady(error);
|
|
const list = errorHandlers.list();
|
|
if (list.length) {
|
|
list.forEach(handler => handler(error, to, from));
|
|
}
|
|
else {
|
|
if ((true)) {
|
|
warn('uncaught error during route navigation:');
|
|
}
|
|
console.error(error);
|
|
}
|
|
return Promise.reject(error);
|
|
}
|
|
function isReady() {
|
|
if (ready && currentRoute.value !== START_LOCATION_NORMALIZED)
|
|
return Promise.resolve();
|
|
return new Promise((resolve, reject) => {
|
|
readyHandlers.add([resolve, reject]);
|
|
});
|
|
}
|
|
/**
|
|
* Mark the router as ready, resolving the promised returned by isReady(). Can
|
|
* only be called once, otherwise does nothing.
|
|
* @param err - optional error
|
|
*/
|
|
function markAsReady(err) {
|
|
if (ready)
|
|
return;
|
|
ready = true;
|
|
setupListeners();
|
|
readyHandlers
|
|
.list()
|
|
.forEach(([resolve, reject]) => (err ? reject(err) : resolve()));
|
|
readyHandlers.reset();
|
|
}
|
|
// Scroll behavior
|
|
function handleScroll(to, from, isPush, isFirstNavigation) {
|
|
const { scrollBehavior } = options;
|
|
if (!isBrowser || !scrollBehavior)
|
|
return Promise.resolve();
|
|
const scrollPosition = (!isPush && getSavedScrollPosition(getScrollKey(to.fullPath, 0))) ||
|
|
((isFirstNavigation || !isPush) &&
|
|
history.state &&
|
|
history.state.scroll) ||
|
|
null;
|
|
return (0,vue__WEBPACK_IMPORTED_MODULE_0__.nextTick)()
|
|
.then(() => scrollBehavior(to, from, scrollPosition))
|
|
.then(position => position && scrollToPosition(position))
|
|
.catch(err => triggerError(err, to, from));
|
|
}
|
|
const go = (delta) => routerHistory.go(delta);
|
|
let started;
|
|
const installedApps = new Set();
|
|
const router = {
|
|
currentRoute,
|
|
addRoute,
|
|
removeRoute,
|
|
hasRoute,
|
|
getRoutes,
|
|
resolve,
|
|
options,
|
|
push,
|
|
replace,
|
|
go,
|
|
back: () => go(-1),
|
|
forward: () => go(1),
|
|
beforeEach: beforeGuards.add,
|
|
beforeResolve: beforeResolveGuards.add,
|
|
afterEach: afterGuards.add,
|
|
onError: errorHandlers.add,
|
|
isReady,
|
|
install(app) {
|
|
const router = this;
|
|
app.component('RouterLink', RouterLink);
|
|
app.component('RouterView', RouterView);
|
|
app.config.globalProperties.$router = router;
|
|
Object.defineProperty(app.config.globalProperties, '$route', {
|
|
enumerable: true,
|
|
get: () => (0,vue__WEBPACK_IMPORTED_MODULE_0__.unref)(currentRoute),
|
|
});
|
|
// this initial navigation is only necessary on client, on server it doesn't
|
|
// make sense because it will create an extra unnecessary navigation and could
|
|
// lead to problems
|
|
if (isBrowser &&
|
|
// used for the initial navigation client side to avoid pushing
|
|
// multiple times when the router is used in multiple apps
|
|
!started &&
|
|
currentRoute.value === START_LOCATION_NORMALIZED) {
|
|
// see above
|
|
started = true;
|
|
push(routerHistory.location).catch(err => {
|
|
if ((true))
|
|
warn('Unexpected error when starting the router:', err);
|
|
});
|
|
}
|
|
const reactiveRoute = {};
|
|
for (const key in START_LOCATION_NORMALIZED) {
|
|
// @ts-expect-error: the key matches
|
|
reactiveRoute[key] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.computed)(() => currentRoute.value[key]);
|
|
}
|
|
app.provide(routerKey, router);
|
|
app.provide(routeLocationKey, (0,vue__WEBPACK_IMPORTED_MODULE_0__.reactive)(reactiveRoute));
|
|
app.provide(routerViewLocationKey, currentRoute);
|
|
const unmountApp = app.unmount;
|
|
installedApps.add(app);
|
|
app.unmount = function () {
|
|
installedApps.delete(app);
|
|
// the router is not attached to an app anymore
|
|
if (installedApps.size < 1) {
|
|
// invalidate the current navigation
|
|
pendingLocation = START_LOCATION_NORMALIZED;
|
|
removeHistoryListener && removeHistoryListener();
|
|
currentRoute.value = START_LOCATION_NORMALIZED;
|
|
started = false;
|
|
ready = false;
|
|
}
|
|
unmountApp();
|
|
};
|
|
if (( true) && isBrowser) {
|
|
addDevtools(app, router, matcher);
|
|
}
|
|
},
|
|
};
|
|
return router;
|
|
}
|
|
function runGuardQueue(guards) {
|
|
return guards.reduce((promise, guard) => promise.then(() => guard()), Promise.resolve());
|
|
}
|
|
function extractChangingRecords(to, from) {
|
|
const leavingRecords = [];
|
|
const updatingRecords = [];
|
|
const enteringRecords = [];
|
|
const len = Math.max(from.matched.length, to.matched.length);
|
|
for (let i = 0; i < len; i++) {
|
|
const recordFrom = from.matched[i];
|
|
if (recordFrom) {
|
|
if (to.matched.find(record => isSameRouteRecord(record, recordFrom)))
|
|
updatingRecords.push(recordFrom);
|
|
else
|
|
leavingRecords.push(recordFrom);
|
|
}
|
|
const recordTo = to.matched[i];
|
|
if (recordTo) {
|
|
// the type doesn't matter because we are comparing per reference
|
|
if (!from.matched.find(record => isSameRouteRecord(record, recordTo))) {
|
|
enteringRecords.push(recordTo);
|
|
}
|
|
}
|
|
}
|
|
return [leavingRecords, updatingRecords, enteringRecords];
|
|
}
|
|
|
|
/**
|
|
* Returns the router instance. Equivalent to using `$router` inside
|
|
* templates.
|
|
*/
|
|
function useRouter() {
|
|
return (0,vue__WEBPACK_IMPORTED_MODULE_0__.inject)(routerKey);
|
|
}
|
|
/**
|
|
* Returns the current route location. Equivalent to using `$route` inside
|
|
* templates.
|
|
*/
|
|
function useRoute() {
|
|
return (0,vue__WEBPACK_IMPORTED_MODULE_0__.inject)(routeLocationKey);
|
|
}
|
|
|
|
|
|
|
|
|
|
/***/ }),
|
|
|
|
/***/ "./node_modules/vue/dist/vue.esm-bundler.js":
|
|
/*!**************************************************!*\
|
|
!*** ./node_modules/vue/dist/vue.esm-bundler.js ***!
|
|
\**************************************************/
|
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
|
|
"use strict";
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
/* harmony export */ "BaseTransition": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.BaseTransition),
|
|
/* harmony export */ "Comment": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.Comment),
|
|
/* harmony export */ "EffectScope": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.EffectScope),
|
|
/* harmony export */ "Fragment": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.Fragment),
|
|
/* harmony export */ "KeepAlive": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.KeepAlive),
|
|
/* harmony export */ "ReactiveEffect": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.ReactiveEffect),
|
|
/* harmony export */ "Static": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.Static),
|
|
/* harmony export */ "Suspense": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.Suspense),
|
|
/* harmony export */ "Teleport": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.Teleport),
|
|
/* harmony export */ "Text": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.Text),
|
|
/* harmony export */ "Transition": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.Transition),
|
|
/* harmony export */ "TransitionGroup": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.TransitionGroup),
|
|
/* harmony export */ "VueElement": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.VueElement),
|
|
/* harmony export */ "callWithAsyncErrorHandling": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.callWithAsyncErrorHandling),
|
|
/* harmony export */ "callWithErrorHandling": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.callWithErrorHandling),
|
|
/* harmony export */ "camelize": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.camelize),
|
|
/* harmony export */ "capitalize": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.capitalize),
|
|
/* harmony export */ "cloneVNode": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.cloneVNode),
|
|
/* harmony export */ "compatUtils": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.compatUtils),
|
|
/* harmony export */ "computed": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.computed),
|
|
/* harmony export */ "createApp": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.createApp),
|
|
/* harmony export */ "createBlock": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.createBlock),
|
|
/* harmony export */ "createCommentVNode": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode),
|
|
/* harmony export */ "createElementBlock": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.createElementBlock),
|
|
/* harmony export */ "createElementVNode": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.createElementVNode),
|
|
/* harmony export */ "createHydrationRenderer": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.createHydrationRenderer),
|
|
/* harmony export */ "createRenderer": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.createRenderer),
|
|
/* harmony export */ "createSSRApp": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.createSSRApp),
|
|
/* harmony export */ "createSlots": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.createSlots),
|
|
/* harmony export */ "createStaticVNode": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.createStaticVNode),
|
|
/* harmony export */ "createTextVNode": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.createTextVNode),
|
|
/* harmony export */ "createVNode": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.createVNode),
|
|
/* harmony export */ "customRef": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.customRef),
|
|
/* harmony export */ "defineAsyncComponent": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.defineAsyncComponent),
|
|
/* harmony export */ "defineComponent": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.defineComponent),
|
|
/* harmony export */ "defineCustomElement": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.defineCustomElement),
|
|
/* harmony export */ "defineEmits": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.defineEmits),
|
|
/* harmony export */ "defineExpose": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.defineExpose),
|
|
/* harmony export */ "defineProps": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.defineProps),
|
|
/* harmony export */ "defineSSRCustomElement": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.defineSSRCustomElement),
|
|
/* harmony export */ "devtools": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.devtools),
|
|
/* harmony export */ "effect": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.effect),
|
|
/* harmony export */ "effectScope": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.effectScope),
|
|
/* harmony export */ "getCurrentInstance": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.getCurrentInstance),
|
|
/* harmony export */ "getCurrentScope": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.getCurrentScope),
|
|
/* harmony export */ "getTransitionRawChildren": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.getTransitionRawChildren),
|
|
/* harmony export */ "guardReactiveProps": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.guardReactiveProps),
|
|
/* harmony export */ "h": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.h),
|
|
/* harmony export */ "handleError": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.handleError),
|
|
/* harmony export */ "hydrate": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.hydrate),
|
|
/* harmony export */ "initCustomFormatter": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.initCustomFormatter),
|
|
/* harmony export */ "inject": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.inject),
|
|
/* harmony export */ "isMemoSame": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.isMemoSame),
|
|
/* harmony export */ "isProxy": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.isProxy),
|
|
/* harmony export */ "isReactive": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.isReactive),
|
|
/* harmony export */ "isReadonly": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.isReadonly),
|
|
/* harmony export */ "isRef": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.isRef),
|
|
/* harmony export */ "isRuntimeOnly": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.isRuntimeOnly),
|
|
/* harmony export */ "isVNode": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.isVNode),
|
|
/* harmony export */ "markRaw": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.markRaw),
|
|
/* harmony export */ "mergeDefaults": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.mergeDefaults),
|
|
/* harmony export */ "mergeProps": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.mergeProps),
|
|
/* harmony export */ "nextTick": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.nextTick),
|
|
/* harmony export */ "normalizeClass": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.normalizeClass),
|
|
/* harmony export */ "normalizeProps": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.normalizeProps),
|
|
/* harmony export */ "normalizeStyle": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.normalizeStyle),
|
|
/* harmony export */ "onActivated": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.onActivated),
|
|
/* harmony export */ "onBeforeMount": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.onBeforeMount),
|
|
/* harmony export */ "onBeforeUnmount": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.onBeforeUnmount),
|
|
/* harmony export */ "onBeforeUpdate": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.onBeforeUpdate),
|
|
/* harmony export */ "onDeactivated": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.onDeactivated),
|
|
/* harmony export */ "onErrorCaptured": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.onErrorCaptured),
|
|
/* harmony export */ "onMounted": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.onMounted),
|
|
/* harmony export */ "onRenderTracked": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.onRenderTracked),
|
|
/* harmony export */ "onRenderTriggered": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.onRenderTriggered),
|
|
/* harmony export */ "onScopeDispose": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.onScopeDispose),
|
|
/* harmony export */ "onServerPrefetch": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.onServerPrefetch),
|
|
/* harmony export */ "onUnmounted": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.onUnmounted),
|
|
/* harmony export */ "onUpdated": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.onUpdated),
|
|
/* harmony export */ "openBlock": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.openBlock),
|
|
/* harmony export */ "popScopeId": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.popScopeId),
|
|
/* harmony export */ "provide": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.provide),
|
|
/* harmony export */ "proxyRefs": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.proxyRefs),
|
|
/* harmony export */ "pushScopeId": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.pushScopeId),
|
|
/* harmony export */ "queuePostFlushCb": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.queuePostFlushCb),
|
|
/* harmony export */ "reactive": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.reactive),
|
|
/* harmony export */ "readonly": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.readonly),
|
|
/* harmony export */ "ref": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.ref),
|
|
/* harmony export */ "registerRuntimeCompiler": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.registerRuntimeCompiler),
|
|
/* harmony export */ "render": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.render),
|
|
/* harmony export */ "renderList": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.renderList),
|
|
/* harmony export */ "renderSlot": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.renderSlot),
|
|
/* harmony export */ "resolveComponent": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.resolveComponent),
|
|
/* harmony export */ "resolveDirective": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.resolveDirective),
|
|
/* harmony export */ "resolveDynamicComponent": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.resolveDynamicComponent),
|
|
/* harmony export */ "resolveFilter": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.resolveFilter),
|
|
/* harmony export */ "resolveTransitionHooks": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.resolveTransitionHooks),
|
|
/* harmony export */ "setBlockTracking": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.setBlockTracking),
|
|
/* harmony export */ "setDevtoolsHook": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.setDevtoolsHook),
|
|
/* harmony export */ "setTransitionHooks": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.setTransitionHooks),
|
|
/* harmony export */ "shallowReactive": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.shallowReactive),
|
|
/* harmony export */ "shallowReadonly": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.shallowReadonly),
|
|
/* harmony export */ "shallowRef": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.shallowRef),
|
|
/* harmony export */ "ssrContextKey": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.ssrContextKey),
|
|
/* harmony export */ "ssrUtils": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.ssrUtils),
|
|
/* harmony export */ "stop": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.stop),
|
|
/* harmony export */ "toDisplayString": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.toDisplayString),
|
|
/* harmony export */ "toHandlerKey": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.toHandlerKey),
|
|
/* harmony export */ "toHandlers": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.toHandlers),
|
|
/* harmony export */ "toRaw": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.toRaw),
|
|
/* harmony export */ "toRef": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.toRef),
|
|
/* harmony export */ "toRefs": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.toRefs),
|
|
/* harmony export */ "transformVNodeArgs": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.transformVNodeArgs),
|
|
/* harmony export */ "triggerRef": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.triggerRef),
|
|
/* harmony export */ "unref": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.unref),
|
|
/* harmony export */ "useAttrs": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.useAttrs),
|
|
/* harmony export */ "useCssModule": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.useCssModule),
|
|
/* harmony export */ "useCssVars": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.useCssVars),
|
|
/* harmony export */ "useSSRContext": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.useSSRContext),
|
|
/* harmony export */ "useSlots": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.useSlots),
|
|
/* harmony export */ "useTransitionState": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.useTransitionState),
|
|
/* harmony export */ "vModelCheckbox": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.vModelCheckbox),
|
|
/* harmony export */ "vModelDynamic": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.vModelDynamic),
|
|
/* harmony export */ "vModelRadio": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.vModelRadio),
|
|
/* harmony export */ "vModelSelect": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.vModelSelect),
|
|
/* harmony export */ "vModelText": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.vModelText),
|
|
/* harmony export */ "vShow": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.vShow),
|
|
/* harmony export */ "version": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.version),
|
|
/* harmony export */ "warn": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.warn),
|
|
/* harmony export */ "watch": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.watch),
|
|
/* harmony export */ "watchEffect": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.watchEffect),
|
|
/* harmony export */ "watchPostEffect": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.watchPostEffect),
|
|
/* harmony export */ "watchSyncEffect": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.watchSyncEffect),
|
|
/* harmony export */ "withAsyncContext": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.withAsyncContext),
|
|
/* harmony export */ "withCtx": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.withCtx),
|
|
/* harmony export */ "withDefaults": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.withDefaults),
|
|
/* harmony export */ "withDirectives": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.withDirectives),
|
|
/* harmony export */ "withKeys": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.withKeys),
|
|
/* harmony export */ "withMemo": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.withMemo),
|
|
/* harmony export */ "withModifiers": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.withModifiers),
|
|
/* harmony export */ "withScopeId": () => (/* reexport safe */ _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__.withScopeId),
|
|
/* harmony export */ "compile": () => (/* binding */ compileToFunction)
|
|
/* harmony export */ });
|
|
/* harmony import */ var _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @vue/runtime-dom */ "./node_modules/@vue/runtime-dom/dist/runtime-dom.esm-bundler.js");
|
|
/* harmony import */ var _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @vue/runtime-dom */ "./node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js");
|
|
/* harmony import */ var _vue_compiler_dom__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @vue/compiler-dom */ "./node_modules/@vue/compiler-dom/dist/compiler-dom.esm-bundler.js");
|
|
/* harmony import */ var _vue_shared__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @vue/shared */ "./node_modules/@vue/shared/dist/shared.esm-bundler.js");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function initDev() {
|
|
{
|
|
(0,_vue_runtime_dom__WEBPACK_IMPORTED_MODULE_2__.initCustomFormatter)();
|
|
}
|
|
}
|
|
|
|
// This entry is the "full-build" that includes both the runtime
|
|
if ((true)) {
|
|
initDev();
|
|
}
|
|
const compileCache = Object.create(null);
|
|
function compileToFunction(template, options) {
|
|
if (!(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.isString)(template)) {
|
|
if (template.nodeType) {
|
|
template = template.innerHTML;
|
|
}
|
|
else {
|
|
( true) && (0,_vue_runtime_dom__WEBPACK_IMPORTED_MODULE_2__.warn)(`invalid template option: `, template);
|
|
return _vue_shared__WEBPACK_IMPORTED_MODULE_1__.NOOP;
|
|
}
|
|
}
|
|
const key = template;
|
|
const cached = compileCache[key];
|
|
if (cached) {
|
|
return cached;
|
|
}
|
|
if (template[0] === '#') {
|
|
const el = document.querySelector(template);
|
|
if (( true) && !el) {
|
|
(0,_vue_runtime_dom__WEBPACK_IMPORTED_MODULE_2__.warn)(`Template element not found or is empty: ${template}`);
|
|
}
|
|
// __UNSAFE__
|
|
// Reason: potential execution of JS expressions in in-DOM template.
|
|
// The user must make sure the in-DOM template is trusted. If it's rendered
|
|
// by the server, the template should not contain any user data.
|
|
template = el ? el.innerHTML : ``;
|
|
}
|
|
const { code } = (0,_vue_compiler_dom__WEBPACK_IMPORTED_MODULE_3__.compile)(template, (0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.extend)({
|
|
hoistStatic: true,
|
|
onError: ( true) ? onError : 0,
|
|
onWarn: ( true) ? e => onError(e, true) : 0
|
|
}, options));
|
|
function onError(err, asWarning = false) {
|
|
const message = asWarning
|
|
? err.message
|
|
: `Template compilation error: ${err.message}`;
|
|
const codeFrame = err.loc &&
|
|
(0,_vue_shared__WEBPACK_IMPORTED_MODULE_1__.generateCodeFrame)(template, err.loc.start.offset, err.loc.end.offset);
|
|
(0,_vue_runtime_dom__WEBPACK_IMPORTED_MODULE_2__.warn)(codeFrame ? `${message}\n${codeFrame}` : message);
|
|
}
|
|
// The wildcard import results in a huge object with every export
|
|
// with keys that cannot be mangled, and can be quite heavy size-wise.
|
|
// In the global build we know `Vue` is available globally so we can avoid
|
|
// the wildcard object.
|
|
const render = (new Function('Vue', code)(_vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__));
|
|
render._rc = true;
|
|
return (compileCache[key] = render);
|
|
}
|
|
(0,_vue_runtime_dom__WEBPACK_IMPORTED_MODULE_2__.registerRuntimeCompiler)(compileToFunction);
|
|
|
|
|
|
|
|
|
|
/***/ })
|
|
|
|
/******/ });
|
|
/************************************************************************/
|
|
/******/ // The module cache
|
|
/******/ var __webpack_module_cache__ = {};
|
|
/******/
|
|
/******/ // The require function
|
|
/******/ function __webpack_require__(moduleId) {
|
|
/******/ // Check if module is in cache
|
|
/******/ var cachedModule = __webpack_module_cache__[moduleId];
|
|
/******/ if (cachedModule !== undefined) {
|
|
/******/ return cachedModule.exports;
|
|
/******/ }
|
|
/******/ // Create a new module (and put it into the cache)
|
|
/******/ var module = __webpack_module_cache__[moduleId] = {
|
|
/******/ id: moduleId,
|
|
/******/ loaded: false,
|
|
/******/ exports: {}
|
|
/******/ };
|
|
/******/
|
|
/******/ // Execute the module function
|
|
/******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
|
/******/
|
|
/******/ // Flag the module as loaded
|
|
/******/ module.loaded = true;
|
|
/******/
|
|
/******/ // Return the exports of the module
|
|
/******/ return module.exports;
|
|
/******/ }
|
|
/******/
|
|
/******/ // expose the modules object (__webpack_modules__)
|
|
/******/ __webpack_require__.m = __webpack_modules__;
|
|
/******/
|
|
/************************************************************************/
|
|
/******/ /* webpack/runtime/chunk loaded */
|
|
/******/ (() => {
|
|
/******/ var deferred = [];
|
|
/******/ __webpack_require__.O = (result, chunkIds, fn, priority) => {
|
|
/******/ if(chunkIds) {
|
|
/******/ priority = priority || 0;
|
|
/******/ for(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];
|
|
/******/ deferred[i] = [chunkIds, fn, priority];
|
|
/******/ return;
|
|
/******/ }
|
|
/******/ var notFulfilled = Infinity;
|
|
/******/ for (var i = 0; i < deferred.length; i++) {
|
|
/******/ var [chunkIds, fn, priority] = deferred[i];
|
|
/******/ var fulfilled = true;
|
|
/******/ for (var j = 0; j < chunkIds.length; j++) {
|
|
/******/ if ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every((key) => (__webpack_require__.O[key](chunkIds[j])))) {
|
|
/******/ chunkIds.splice(j--, 1);
|
|
/******/ } else {
|
|
/******/ fulfilled = false;
|
|
/******/ if(priority < notFulfilled) notFulfilled = priority;
|
|
/******/ }
|
|
/******/ }
|
|
/******/ if(fulfilled) {
|
|
/******/ deferred.splice(i--, 1)
|
|
/******/ var r = fn();
|
|
/******/ if (r !== undefined) result = r;
|
|
/******/ }
|
|
/******/ }
|
|
/******/ return result;
|
|
/******/ };
|
|
/******/ })();
|
|
/******/
|
|
/******/ /* webpack/runtime/compat get default export */
|
|
/******/ (() => {
|
|
/******/ // getDefaultExport function for compatibility with non-harmony modules
|
|
/******/ __webpack_require__.n = (module) => {
|
|
/******/ var getter = module && module.__esModule ?
|
|
/******/ () => (module['default']) :
|
|
/******/ () => (module);
|
|
/******/ __webpack_require__.d(getter, { a: getter });
|
|
/******/ return getter;
|
|
/******/ };
|
|
/******/ })();
|
|
/******/
|
|
/******/ /* webpack/runtime/define property getters */
|
|
/******/ (() => {
|
|
/******/ // define getter functions for harmony exports
|
|
/******/ __webpack_require__.d = (exports, definition) => {
|
|
/******/ for(var key in definition) {
|
|
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
|
|
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
|
|
/******/ }
|
|
/******/ }
|
|
/******/ };
|
|
/******/ })();
|
|
/******/
|
|
/******/ /* webpack/runtime/global */
|
|
/******/ (() => {
|
|
/******/ __webpack_require__.g = (function() {
|
|
/******/ if (typeof globalThis === 'object') return globalThis;
|
|
/******/ try {
|
|
/******/ return this || new Function('return this')();
|
|
/******/ } catch (e) {
|
|
/******/ if (typeof window === 'object') return window;
|
|
/******/ }
|
|
/******/ })();
|
|
/******/ })();
|
|
/******/
|
|
/******/ /* webpack/runtime/hasOwnProperty shorthand */
|
|
/******/ (() => {
|
|
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
|
|
/******/ })();
|
|
/******/
|
|
/******/ /* webpack/runtime/make namespace object */
|
|
/******/ (() => {
|
|
/******/ // define __esModule on exports
|
|
/******/ __webpack_require__.r = (exports) => {
|
|
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
|
|
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
/******/ }
|
|
/******/ Object.defineProperty(exports, '__esModule', { value: true });
|
|
/******/ };
|
|
/******/ })();
|
|
/******/
|
|
/******/ /* webpack/runtime/node module decorator */
|
|
/******/ (() => {
|
|
/******/ __webpack_require__.nmd = (module) => {
|
|
/******/ module.paths = [];
|
|
/******/ if (!module.children) module.children = [];
|
|
/******/ return module;
|
|
/******/ };
|
|
/******/ })();
|
|
/******/
|
|
/******/ /* webpack/runtime/jsonp chunk loading */
|
|
/******/ (() => {
|
|
/******/ // no baseURI
|
|
/******/
|
|
/******/ // object to store loaded and loading chunks
|
|
/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched
|
|
/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded
|
|
/******/ var installedChunks = {
|
|
/******/ "/js/app": 0,
|
|
/******/ "css/app": 0
|
|
/******/ };
|
|
/******/
|
|
/******/ // no chunk on demand loading
|
|
/******/
|
|
/******/ // no prefetching
|
|
/******/
|
|
/******/ // no preloaded
|
|
/******/
|
|
/******/ // no HMR
|
|
/******/
|
|
/******/ // no HMR manifest
|
|
/******/
|
|
/******/ __webpack_require__.O.j = (chunkId) => (installedChunks[chunkId] === 0);
|
|
/******/
|
|
/******/ // install a JSONP callback for chunk loading
|
|
/******/ var webpackJsonpCallback = (parentChunkLoadingFunction, data) => {
|
|
/******/ var [chunkIds, moreModules, runtime] = data;
|
|
/******/ // add "moreModules" to the modules object,
|
|
/******/ // then flag all "chunkIds" as loaded and fire callback
|
|
/******/ var moduleId, chunkId, i = 0;
|
|
/******/ if(chunkIds.some((id) => (installedChunks[id] !== 0))) {
|
|
/******/ for(moduleId in moreModules) {
|
|
/******/ if(__webpack_require__.o(moreModules, moduleId)) {
|
|
/******/ __webpack_require__.m[moduleId] = moreModules[moduleId];
|
|
/******/ }
|
|
/******/ }
|
|
/******/ if(runtime) var result = runtime(__webpack_require__);
|
|
/******/ }
|
|
/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data);
|
|
/******/ for(;i < chunkIds.length; i++) {
|
|
/******/ chunkId = chunkIds[i];
|
|
/******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {
|
|
/******/ installedChunks[chunkId][0]();
|
|
/******/ }
|
|
/******/ installedChunks[chunkIds[i]] = 0;
|
|
/******/ }
|
|
/******/ return __webpack_require__.O(result);
|
|
/******/ }
|
|
/******/
|
|
/******/ var chunkLoadingGlobal = self["webpackChunk"] = self["webpackChunk"] || [];
|
|
/******/ chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));
|
|
/******/ chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));
|
|
/******/ })();
|
|
/******/
|
|
/************************************************************************/
|
|
/******/
|
|
/******/ // startup
|
|
/******/ // Load entry module and return exports
|
|
/******/ // This entry module depends on other loaded chunks and execution need to be delayed
|
|
/******/ __webpack_require__.O(undefined, ["css/app"], () => (__webpack_require__("./resources/js/app.js")))
|
|
/******/ var __webpack_exports__ = __webpack_require__.O(undefined, ["css/app"], () => (__webpack_require__("./resources/scss/app.scss")))
|
|
/******/ __webpack_exports__ = __webpack_require__.O(__webpack_exports__);
|
|
/******/
|
|
/******/ })()
|
|
; |