From 5d914f18ea23782ebaf05997b3b2a19cdba1a04f Mon Sep 17 00:00:00 2001 From: Jakub Trzebiatowski Date: Sat, 19 Aug 2023 14:27:10 +0200 Subject: [PATCH 001/212] Refactor comment message rendering ...so the logic for rendering attachments is clearly separated from the logic for rendering textual comments. This fixes #25415 --- .../home/report/ReportActionItemFragment.js | 81 ++++++---------- .../home/report/ReportActionItemMessage.js | 8 +- .../comment/AttachmentCommentFragment.js | 32 ++++++ .../home/report/comment/RenderCommentHTML.js | 22 +++++ .../report/comment/TextCommentFragment.js | 97 +++++++++++++++++++ 5 files changed, 184 insertions(+), 56 deletions(-) create mode 100644 src/pages/home/report/comment/AttachmentCommentFragment.js create mode 100644 src/pages/home/report/comment/RenderCommentHTML.js create mode 100644 src/pages/home/report/comment/TextCommentFragment.js diff --git a/src/pages/home/report/ReportActionItemFragment.js b/src/pages/home/report/ReportActionItemFragment.js index 24501e307759..b50592c20af7 100644 --- a/src/pages/home/report/ReportActionItemFragment.js +++ b/src/pages/home/report/ReportActionItemFragment.js @@ -1,23 +1,19 @@ import React, {memo} from 'react'; import PropTypes from 'prop-types'; -import Str from 'expensify-common/lib/str'; import reportActionFragmentPropTypes from './reportActionFragmentPropTypes'; import styles from '../../../styles/styles'; -import variables from '../../../styles/variables'; -import themeColors from '../../../styles/themes/default'; import RenderHTML from '../../../components/RenderHTML'; import Text from '../../../components/Text'; -import * as EmojiUtils from '../../../libs/EmojiUtils'; import withWindowDimensions, {windowDimensionsPropTypes} from '../../../components/withWindowDimensions'; import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize'; -import * as DeviceCapabilities from '../../../libs/DeviceCapabilities'; import compose from '../../../libs/compose'; -import convertToLTR from '../../../libs/convertToLTR'; import {withNetwork} from '../../../components/OnyxProvider'; import CONST from '../../../CONST'; -import editedLabelStyles from '../../../styles/editedLabelStyles'; import UserDetailsTooltip from '../../../components/UserDetailsTooltip'; import avatarPropTypes from '../../../components/avatarPropTypes'; +import * as ReportUtils from '../../../libs/ReportUtils'; +import AttachmentCommentFragment from './comment/AttachmentCommentFragment'; +import TextCommentFragment from './comment/TextCommentFragment'; const propTypes = { /** Users accountID */ @@ -62,6 +58,9 @@ const propTypes = { /** Whether the comment is a thread parent message/the first message in a thread */ isThreadParentMessage: PropTypes.bool, + /** Should the comment have the appearance of being grouped with the previous comment? */ + displayAsGroup: PropTypes.bool.isRequired, + ...windowDimensionsPropTypes, /** localization props */ @@ -85,62 +84,40 @@ const defaultProps = { }; function ReportActionItemFragment(props) { - switch (props.fragment.type) { + const fragment = props.fragment; + + switch (fragment.type) { case 'COMMENT': { - const {html, text} = props.fragment; - const isPendingDelete = props.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE && props.network.isOffline; + const isPendingDelete = props.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE; // Threaded messages display "[Deleted message]" instead of being hidden altogether. // While offline we display the previous message with a strikethrough style. Once online we want to // immediately display "[Deleted message]" while the delete action is pending. - if ((!props.network.isOffline && props.isThreadParentMessage && props.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE) || props.fragment.isDeletedParentAction) { + if ((!props.network.isOffline && props.isThreadParentMessage && isPendingDelete) || props.fragment.isDeletedParentAction) { return ${props.translate('parentReportAction.deletedMessage')}`} />; } - // If the only difference between fragment.text and fragment.html is
tags - // we render it as text, not as html. - // This is done to render emojis with line breaks between them as text. - const differByLineBreaksOnly = Str.replaceAll(html, '
', '\n') === text; - - // Only render HTML if we have html in the fragment - if (!differByLineBreaksOnly) { - const editedTag = props.fragment.isEdited ? `` : ''; - const htmlContent = isPendingDelete ? `${html}` : html; - - const htmlWithTag = editedTag ? `${htmlContent}${editedTag}` : htmlContent; - - return ${htmlWithTag}` : `${htmlWithTag}`} />; + // Does the fragment content represent an attachment? + const isFragmentAttachment = ReportUtils.isReportMessageAttachment(fragment); + + if (isFragmentAttachment) { + return ( + + ); } - const containsOnlyEmojis = EmojiUtils.containsOnlyEmojis(text); return ( - - - {convertToLTR(props.iouMessage || text)} - - {Boolean(props.fragment.isEdited) && ( - <> - - {' '} - - - {props.translate('reportActionCompose.edited')} - - - )} - + ); } case 'TEXT': @@ -154,7 +131,7 @@ function ReportActionItemFragment(props) { numberOfLines={props.isSingleLine ? 1 : undefined} style={[styles.chatItemMessageHeaderSender, props.isSingleLine ? styles.pre : styles.preWrap]} > - {props.fragment.text} + {fragment.text} ); diff --git a/src/pages/home/report/ReportActionItemMessage.js b/src/pages/home/report/ReportActionItemMessage.js index a3d8494c38de..024ba9a9388f 100644 --- a/src/pages/home/report/ReportActionItemMessage.js +++ b/src/pages/home/report/ReportActionItemMessage.js @@ -36,8 +36,7 @@ const defaultProps = { }; function ReportActionItemMessage(props) { - const messages = _.compact(props.action.previousMessage || props.action.message); - const isAttachment = ReportUtils.isReportMessageAttachment(_.last(messages)); + const fragments = _.compact(props.action.previousMessage || props.action.message); const isIOUReport = ReportActionsUtils.isMoneyRequestAction(props.action); let iouMessage; if (isIOUReport) { @@ -48,9 +47,9 @@ function ReportActionItemMessage(props) { } return ( - + {!props.isHidden ? ( - _.map(messages, (fragment, index) => ( + _.map(fragments, (fragment, index) => ( )) diff --git a/src/pages/home/report/comment/AttachmentCommentFragment.js b/src/pages/home/report/comment/AttachmentCommentFragment.js new file mode 100644 index 000000000000..2d019c7d89e0 --- /dev/null +++ b/src/pages/home/report/comment/AttachmentCommentFragment.js @@ -0,0 +1,32 @@ +import React from 'react'; +import {View} from 'react-native'; +import PropTypes from 'prop-types'; +import styles from '../../../../styles/styles'; +import RenderCommentHTML from './RenderCommentHTML'; + +const propTypes = { + /** The reportAction's source */ + source: PropTypes.oneOf(['Chronos', 'email', 'ios', 'android', 'web', 'email', '']).isRequired, + + /** The message fragment's HTML */ + html: PropTypes.string.isRequired, + + /** Should extra margin be added on top of the component? */ + addExtraMargin: PropTypes.bool.isRequired, +}; + +function AttachmentCommentFragment(props) { + return ( + + + + ); +} + +AttachmentCommentFragment.propTypes = propTypes; +AttachmentCommentFragment.displayName = 'AttachmentCommentFragment'; + +export default AttachmentCommentFragment; diff --git a/src/pages/home/report/comment/RenderCommentHTML.js b/src/pages/home/report/comment/RenderCommentHTML.js new file mode 100644 index 000000000000..216fdfc58025 --- /dev/null +++ b/src/pages/home/report/comment/RenderCommentHTML.js @@ -0,0 +1,22 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import RenderHTML from '../../../../components/RenderHTML'; + +const propTypes = { + /** The reportAction's source */ + source: PropTypes.oneOf(['Chronos', 'email', 'ios', 'android', 'web', 'email', '']).isRequired, + + /** The comment's HTML */ + html: PropTypes.string.isRequired, +}; + +function RenderCommentHTML(props) { + const html = props.html; + + return ${html}` : `${html}`} />; +} + +RenderCommentHTML.propTypes = propTypes; +RenderCommentHTML.displayName = 'RenderCommentHTML'; + +export default RenderCommentHTML; diff --git a/src/pages/home/report/comment/TextCommentFragment.js b/src/pages/home/report/comment/TextCommentFragment.js new file mode 100644 index 000000000000..ef72707c317f --- /dev/null +++ b/src/pages/home/report/comment/TextCommentFragment.js @@ -0,0 +1,97 @@ +import React, {memo} from 'react'; +import PropTypes from 'prop-types'; +import Str from 'expensify-common/lib/str'; +import reportActionFragmentPropTypes from '../reportActionFragmentPropTypes'; +import styles from '../../../../styles/styles'; +import variables from '../../../../styles/variables'; +import themeColors from '../../../../styles/themes/default'; +import Text from '../../../../components/Text'; +import * as EmojiUtils from '../../../../libs/EmojiUtils'; +import withWindowDimensions, {windowDimensionsPropTypes} from '../../../../components/withWindowDimensions'; +import withLocalize, {withLocalizePropTypes} from '../../../../components/withLocalize'; +import * as DeviceCapabilities from '../../../../libs/DeviceCapabilities'; +import compose from '../../../../libs/compose'; +import convertToLTR from '../../../../libs/convertToLTR'; +import CONST from '../../../../CONST'; +import editedLabelStyles from '../../../../styles/editedLabelStyles'; +import RenderCommentHTML from './RenderCommentHTML'; + +const propTypes = { + /** The reportAction's source */ + source: PropTypes.oneOf(['Chronos', 'email', 'ios', 'android', 'web', 'email', '']).isRequired, + + /** The message fragment needing to be displayed */ + fragment: reportActionFragmentPropTypes.isRequired, + + /** Should this message fragment be styled as deleted? */ + styleAsDeleted: PropTypes.bool.isRequired, + + /** Additional styles to add after local styles. */ + style: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.object), PropTypes.object]).isRequired, + + ...windowDimensionsPropTypes, + + /** localization props */ + ...withLocalizePropTypes, +}; + +function TextCommentFragment(props) { + const {fragment, styleAsDeleted} = props; + const {html, text} = fragment; + + // If the only difference between fragment.text and fragment.html is
tags + // we render it as text, not as html. + // This is done to render emojis with line breaks between them as text. + const differByLineBreaksOnly = Str.replaceAll(html, '
', '\n') === text; + + // Only render HTML if we have html in the fragment + if (!differByLineBreaksOnly) { + const editedTag = fragment.isEdited ? `` : ''; + const htmlContent = styleAsDeleted ? `${html}` : html; + + const htmlWithTag = editedTag ? `${htmlContent}${editedTag}` : htmlContent; + + return ( + + ); + } + + const containsOnlyEmojis = EmojiUtils.containsOnlyEmojis(text); + + return ( + + + {convertToLTR(props.iouMessage || text)} + + {Boolean(fragment.isEdited) && ( + <> + + {' '} + + + {props.translate('reportActionCompose.edited')} + + + )} + + ); +} + +TextCommentFragment.propTypes = propTypes; +TextCommentFragment.displayName = 'TextCommentFragment'; + +export default compose(withWindowDimensions, withLocalize)(memo(TextCommentFragment)); From 0e218bfcb59045a6dd41c9dfa0e07a43bd7667bf Mon Sep 17 00:00:00 2001 From: Jakub Trzebiatowski Date: Mon, 2 Oct 2023 13:40:36 +0200 Subject: [PATCH 002/212] TextCommentFragment: Add iouMessage prop --- src/pages/home/report/ReportActionItemFragment.js | 1 + src/pages/home/report/comment/TextCommentFragment.js | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/src/pages/home/report/ReportActionItemFragment.js b/src/pages/home/report/ReportActionItemFragment.js index b50592c20af7..73fa448db1db 100644 --- a/src/pages/home/report/ReportActionItemFragment.js +++ b/src/pages/home/report/ReportActionItemFragment.js @@ -116,6 +116,7 @@ function ReportActionItemFragment(props) { source={props.source} fragment={fragment} styleAsDeleted={isPendingDelete && props.network.isOffline} + iouMessage={props.iouMessage} style={props.style} /> ); diff --git a/src/pages/home/report/comment/TextCommentFragment.js b/src/pages/home/report/comment/TextCommentFragment.js index ef72707c317f..c124728a49d1 100644 --- a/src/pages/home/report/comment/TextCommentFragment.js +++ b/src/pages/home/report/comment/TextCommentFragment.js @@ -26,6 +26,9 @@ const propTypes = { /** Should this message fragment be styled as deleted? */ styleAsDeleted: PropTypes.bool.isRequired, + /** Text of an IOU report action */ + iouMessage: PropTypes.string, + /** Additional styles to add after local styles. */ style: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.object), PropTypes.object]).isRequired, @@ -35,6 +38,10 @@ const propTypes = { ...withLocalizePropTypes, }; +const defaultProps = { + iouMessage: undefined, +} + function TextCommentFragment(props) { const {fragment, styleAsDeleted} = props; const {html, text} = fragment; @@ -92,6 +99,7 @@ function TextCommentFragment(props) { } TextCommentFragment.propTypes = propTypes; +TextCommentFragment.defaultProps = defaultProps; TextCommentFragment.displayName = 'TextCommentFragment'; export default compose(withWindowDimensions, withLocalize)(memo(TextCommentFragment)); From 4882e00c82b09f77ad8000bdf56752914b753f70 Mon Sep 17 00:00:00 2001 From: Jakub Trzebiatowski Date: Mon, 2 Oct 2023 14:34:27 +0200 Subject: [PATCH 003/212] Add a missing semicolon --- src/pages/home/report/comment/TextCommentFragment.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/home/report/comment/TextCommentFragment.js b/src/pages/home/report/comment/TextCommentFragment.js index c124728a49d1..aed0730b8c59 100644 --- a/src/pages/home/report/comment/TextCommentFragment.js +++ b/src/pages/home/report/comment/TextCommentFragment.js @@ -40,7 +40,7 @@ const propTypes = { const defaultProps = { iouMessage: undefined, -} +}; function TextCommentFragment(props) { const {fragment, styleAsDeleted} = props; From 65c2205df1f8acd1e2df1928db61db4708c5d039 Mon Sep 17 00:00:00 2001 From: Viktoryia Kliushun Date: Wed, 4 Oct 2023 18:00:35 +0200 Subject: [PATCH 004/212] [TS migration] Migrate 'E2E' lib --- metro.config.js | 4 +- src/CONST.ts | 70 +++++++++++++++++++ src/ONYXKEYS.ts | 4 +- src/libs/E2E/{API.mock.js => API.mock.ts} | 38 +++++----- .../E2E/actions/{e2eLogin.js => e2eLogin.ts} | 12 ++-- src/libs/E2E/apiMocks/authenticatePusher.js | 6 -- src/libs/E2E/apiMocks/authenticatePusher.ts | 11 +++ .../{beginSignin.js => beginSignin.ts} | 7 +- .../E2E/apiMocks/{openApp.js => openApp.ts} | 41 ++++++----- .../apiMocks/{openReport.js => openReport.ts} | 10 ++- .../apiMocks/{signinUser.js => signinUser.ts} | 7 +- src/libs/E2E/{client.js => client.ts} | 29 ++++---- src/libs/E2E/isE2ETestSession.js | 1 - src/libs/E2E/isE2ETestSession.native.js | 3 - src/libs/E2E/isE2ETestSession.native.ts | 6 ++ src/libs/E2E/isE2ETestSession.ts | 5 ++ ...imeTest.e2e.js => appStartTimeTest.e2e.ts} | 6 +- src/libs/E2E/types.ts | 7 ++ src/types/onyx/Currency.ts | 9 +++ src/types/onyx/FrequentlyUsedEmoji.ts | 5 +- src/types/onyx/Policy.ts | 3 + src/types/onyx/Report.ts | 24 +++++++ src/types/onyx/ReportAction.ts | 13 ++-- src/types/onyx/Response.ts | 3 + tests/e2e/README.md | 2 +- 25 files changed, 242 insertions(+), 84 deletions(-) rename src/libs/E2E/{API.mock.js => API.mock.ts} (65%) rename src/libs/E2E/actions/{e2eLogin.js => e2eLogin.ts} (80%) delete mode 100644 src/libs/E2E/apiMocks/authenticatePusher.js create mode 100644 src/libs/E2E/apiMocks/authenticatePusher.ts rename src/libs/E2E/apiMocks/{beginSignin.js => beginSignin.ts} (73%) rename src/libs/E2E/apiMocks/{openApp.js => openApp.ts} (99%) rename src/libs/E2E/apiMocks/{openReport.js => openReport.ts} (91%) rename src/libs/E2E/apiMocks/{signinUser.js => signinUser.ts} (95%) rename src/libs/E2E/{client.js => client.ts} (69%) delete mode 100644 src/libs/E2E/isE2ETestSession.js delete mode 100644 src/libs/E2E/isE2ETestSession.native.js create mode 100644 src/libs/E2E/isE2ETestSession.native.ts create mode 100644 src/libs/E2E/isE2ETestSession.ts rename src/libs/E2E/tests/{appStartTimeTest.e2e.js => appStartTimeTest.e2e.ts} (86%) create mode 100644 src/libs/E2E/types.ts diff --git a/metro.config.js b/metro.config.js index bf2ff904df70..a63cde4e0d14 100644 --- a/metro.config.js +++ b/metro.config.js @@ -27,8 +27,8 @@ const config = { if (isUsingMockAPI && moduleName.includes('/API')) { return { ...resolution, - // TODO: Change API.mock.js extension once it is migrated to TypeScript - filePath: resolution.filePath.replace(/src\/libs\/API.js/, 'src/libs/E2E/API.mock.js'), + // TODO: Change API.js extension once it is migrated to TypeScript + filePath: resolution.filePath.replace(/src\/libs\/API.js/, 'src/libs/E2E/API.mock.ts'), }; } return resolution; diff --git a/src/CONST.ts b/src/CONST.ts index 0a262d868de9..6cf6824494e8 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -240,6 +240,76 @@ const CONST = { CUSTOM_STATUS: 'customStatus', NEW_DOT_CATEGORIES: 'newDotCategories', NEW_DOT_TAGS: 'newDotTags', + PDF_META_STORE: 'pdfMetaStore', + REPORT_ACTION_CONTEXT_MENU: 'reportActionContextMenu', + SUBMIT_POLICY: 'submitPolicy', + ATTENDEES: 'attendees', + AUTO_EXPORT: 'autoExport', + AUTO_EXPORT_INTACCT: 'autoExportIntacct', + AUTO_EXPORT_QBO: 'autoExportQbo', + AUTO_EXPORT_XERO: 'autoExportXero', + AUTO_JOIN_POLICY: 'autoJoinPolicy', + AUTOMATED_TAX_EXEMPTION: 'automatedTaxExemption', + BILL_PAY: 'billPay', + CATEGORY_DEFAULT_TAX: 'categoryDefaultTax', + COLLECTABLE_DEPOSIT_ACCOUNTS: 'collectableDepositAccounts', + CONCIERGE_TRAVEL: 'conciergeTravel', + CONNECTED_CARDS: 'connectedCards', + DISCREPANCY: 'discrepancy', + DOMAIN_CONTACT_BILLING: 'domainContactBilling', + DOMAIN_TWO_FACTOR_AUTH: 'domainTwoFactorAuth', + DUPLICATE_DETECTION: 'duplicateDetection', + EMAIL_SUPPRESSION_BETA: 'emailSuppressionBeta', + EXPENSES_V2: 'expensesV2', + EXPENSIFY_CARD: 'expensifyCard', + EXPENSIFY_CARD_INTACCT_RECONCILIATION: 'expensifyCardIntacctReconciliation', + EXPENSIFY_CARD_NETSUITE_RECONCILIATION: 'expensifyCardNetSuiteReconciliation', + EXPENSIFY_CARD_QBO_RECONCILIATION: 'expensifyCardQBOReconciliation', + EXPENSIFY_CARD_RAPID_INCREASE_FRAUD: 'expensifyCardRapidIncreaseFraud', + EXPENSIFY_CARD_XERO_RECONCILIATION: 'expensifyCardXeroReconciliation', + EXPENSIFY_ORG: 'expensifyOrg', + FIX_VIOLATION_PUSH_NOTIFICATION: 'fixViolationPushNotification', + FREE_PLAN_FULL_LAUNCH: 'freePlanFullLaunch', + FREE_PLAN_SOFT_LAUNCH: 'freePlanSoftLaunch', + GUSTO: 'gusto', + INBOX_CACHE: 'inboxCache', + INBOX_HIDDEN_TASKS: 'inboxHiddenTasks', + INDIRECT_INTEGRATION_SETUP: 'indirectIntegrationSetup', + IOU: 'IOU', + JOIN_POLICY: 'joinPolicy', + LOAD_POLICY_ASYNC: 'loadPolicyAsync', + MAP_RECEIPT: 'mapReceipt', + MERGE_API: 'mergeAPI', + MOBILE_REALTIME_REPORT_COMMENTS: 'mobileRealtimeReportComments', + MOBILE_SECURE_RECEIPTS: 'mobileSecureReceipts', + MONTHLY_SETTLEMENT: 'monthlySettlement', + NAMES_AND_AVATARS: 'namesAndAvatars', + NATIVE_CHAT: 'nativeChat', + NEW_PRICING: 'newPricing', + NEWSLETTER_THREE: 'newsletterThree', + NEXT_STEPS: 'nextSteps', + OPEN_FACE_HAMBURGER: 'openFaceHamburger', + PER_DIEM: 'perDiem', + PER_DIEM_INTERNATIONAL: 'perDiemInternational', + PRICING_COPY_CHANGES: 'pricingCopyChanges', + QBO_INVOICES: 'qboInvoices', + QUICKBOOKS_DESKTOP_V2: 'quickbooksDesktopV2', + REALTIME_REPORT_COMMENTS: 'realtimeReportComments', + S2W_ANNOUNCEMENT: 's2wAnnouncement', + SCHEDULED_AUTO_REPORTING: 'scheduledAutoReporting', + SECURE_RECEIPTS: 'secureReceipts', + SECURE_RECEIPTS_REPORTS: 'secureReceiptsReports', + SELF_SERVICE_HARD_LAUNCH: 'selfServiceHardLaunch', + SEND_MONEY: 'sendMoney', + SMART_SCAN_USER_DISPUTES: 'smartScanUserDisputes', + SMS_SIGN_UP: 'smsSignUp', + STRIPE_CONNECT: 'stripeConnect', + SUMMARY_EMAIL: 'summaryEmail', + SWIPE_TO_WIN: 'swipeToWin', + TAX_FOR_MILEAGE: 'taxForMileage', + TWO_FACTOR_AUTH: 'twoFactorAuth', + VENMO_INTEGRATION: 'venmoIntegration', + ZENEFITS_INTEGRATION: 'zenefitsIntegration', }, BUTTON_STATES: { DEFAULT: 'default', diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index 0a17d3a1d2f7..3ce5271da323 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -321,7 +321,7 @@ type OnyxValues = { [ONYXKEYS.COUNTRY_CODE]: number; [ONYXKEYS.COUNTRY]: string; [ONYXKEYS.USER]: OnyxTypes.User; - [ONYXKEYS.LOGIN_LIST]: OnyxTypes.Login; + [ONYXKEYS.LOGIN_LIST]: Record; [ONYXKEYS.SESSION]: OnyxTypes.Session; [ONYXKEYS.BETAS]: OnyxTypes.Beta[]; [ONYXKEYS.NVP_PRIORITY_MODE]: ValueOf; @@ -380,7 +380,7 @@ type OnyxValues = { [ONYXKEYS.COLLECTION.WORKSPACE_INVITE_MEMBERS_DRAFT]: Record; [ONYXKEYS.COLLECTION.REPORT]: OnyxTypes.Report; [ONYXKEYS.COLLECTION.REPORT_METADATA]: OnyxTypes.ReportMetadata; - [ONYXKEYS.COLLECTION.REPORT_ACTIONS]: OnyxTypes.ReportAction; + [ONYXKEYS.COLLECTION.REPORT_ACTIONS]: Record; [ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS]: string; [ONYXKEYS.COLLECTION.REPORT_ACTIONS_REACTIONS]: OnyxTypes.ReportActionReactions; [ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT]: string; diff --git a/src/libs/E2E/API.mock.js b/src/libs/E2E/API.mock.ts similarity index 65% rename from src/libs/E2E/API.mock.js rename to src/libs/E2E/API.mock.ts index 47f445f72222..18087405596a 100644 --- a/src/libs/E2E/API.mock.js +++ b/src/libs/E2E/API.mock.ts @@ -1,7 +1,7 @@ /* eslint-disable rulesdir/no-api-in-views */ -import _ from 'underscore'; import Onyx from 'react-native-onyx'; import Log from '../Log'; +import Response from '../../types/onyx/Response'; // mock functions import mockBeginSignin from './apiMocks/beginSignin'; @@ -10,12 +10,16 @@ import mockAuthenticatePusher from './apiMocks/authenticatePusher'; import mockOpenApp from './apiMocks/openApp'; import mockOpenReport from './apiMocks/openReport'; +type ApiCommandParameters = Record; + +type Mocks = Record Response>; + /** * A dictionary which has the name of a API command as key, and a function which * receives the api command parameters as value and is expected to return a response * object. */ -const mocks = { +const mocks: Mocks = { BeginSignIn: mockBeginSignin, SigninUser: mockSigninUser, OpenApp: mockOpenApp, @@ -24,9 +28,9 @@ const mocks = { AuthenticatePusher: mockAuthenticatePusher, }; -function mockCall(command, apiCommandParameters, tag) { - const mockResponse = mocks[command] && mocks[command](apiCommandParameters); - if (!mockResponse || !_.isArray(mockResponse.onyxData)) { +function mockCall(command: string, apiCommandParameters: ApiCommandParameters, tag: string): Promise | undefined { + const mockResponse = mocks[command]?.(apiCommandParameters); + if (!mockResponse || !Array.isArray(mockResponse.onyxData)) { Log.warn(`[${tag}] for command ${command} is not mocked yet!`); return; } @@ -38,12 +42,10 @@ function mockCall(command, apiCommandParameters, tag) { * All calls to API.write() will be persisted to disk as JSON with the params, successData, and failureData. * This is so that if the network is unavailable or the app is closed, we can send the WRITE request later. * - * @param {String} command - Name of API command to call. - * @param {Object} apiCommandParameters - Parameters to send to the API. - * - * @returns {Promise} + * @param command - Name of API command to call. + * @param apiCommandParameters - Parameters to send to the API. */ -function write(command, apiCommandParameters = {}) { +function write(command: string, apiCommandParameters: ApiCommandParameters = {}): Promise | undefined { return mockCall(command, apiCommandParameters, 'API.write'); } @@ -55,24 +57,20 @@ function write(command, apiCommandParameters = {}) { * Using this method is discouraged and will throw an ESLint error. Use it sparingly and only when all other alternatives have been exhausted. * It is best to discuss it in Slack anytime you are tempted to use this method. * - * @param {String} command - Name of API command to call. - * @param {Object} apiCommandParameters - Parameters to send to the API. - * - * @returns {Promise} + * @param command - Name of API command to call. + * @param apiCommandParameters - Parameters to send to the API. */ -function makeRequestWithSideEffects(command, apiCommandParameters = {}) { +function makeRequestWithSideEffects(command: string, apiCommandParameters: ApiCommandParameters = {}): Promise | undefined { return mockCall(command, apiCommandParameters, 'API.makeRequestWithSideEffects'); } /** * Requests made with this method are not be persisted to disk. If there is no network connectivity, the request is ignored and discarded. * - * @param {String} command - Name of API command to call. - * @param {Object} apiCommandParameters - Parameters to send to the API. - * - * @returns {Promise} + * @param command - Name of API command to call. + * @param apiCommandParameters - Parameters to send to the API. */ -function read(command, apiCommandParameters) { +function read(command: string, apiCommandParameters: ApiCommandParameters): Promise | undefined { return mockCall(command, apiCommandParameters, 'API.read'); } diff --git a/src/libs/E2E/actions/e2eLogin.js b/src/libs/E2E/actions/e2eLogin.ts similarity index 80% rename from src/libs/E2E/actions/e2eLogin.js rename to src/libs/E2E/actions/e2eLogin.ts index 77576b09d88d..bc80b53a138b 100644 --- a/src/libs/E2E/actions/e2eLogin.js +++ b/src/libs/E2E/actions/e2eLogin.ts @@ -8,18 +8,16 @@ import * as Session from '../../actions/Session'; * If the user is already logged in the function will simply * resolve. * - * @param {String} email - * @param {String} password - * @return {Promise} Resolved true when the user was actually signed in. Returns false if the user was already logged in. + * @return Resolved true when the user was actually signed in. Returns false if the user was already logged in. */ -export default function (email = 'fake@email.com', password = 'Password123') { - const waitForBeginSignInToFinish = () => +export default function (email = 'fake@email.com', password = 'Password123'): Promise { + const waitForBeginSignInToFinish = (): Promise => new Promise((resolve) => { const id = Onyx.connect({ key: ONYXKEYS.CREDENTIALS, callback: (credentials) => { // beginSignUp writes to credentials.login once the API call is complete - if (!credentials.login) { + if (!credentials?.login) { return; } @@ -36,7 +34,7 @@ export default function (email = 'fake@email.com', password = 'Password123') { const connectionId = Onyx.connect({ key: ONYXKEYS.SESSION, callback: (session) => { - if (session.authToken == null || session.authToken.length === 0) { + if (session?.authToken == null || session.authToken.length === 0) { neededLogin = true; // authenticate with a predefined user diff --git a/src/libs/E2E/apiMocks/authenticatePusher.js b/src/libs/E2E/apiMocks/authenticatePusher.js deleted file mode 100644 index 3f0c724105d9..000000000000 --- a/src/libs/E2E/apiMocks/authenticatePusher.js +++ /dev/null @@ -1,6 +0,0 @@ -export default () => ({ - auth: 'auth', - shared_secret: 'secret', - jsonCode: 200, - requestID: '783ef7fc3991969a-SJC', -}); diff --git a/src/libs/E2E/apiMocks/authenticatePusher.ts b/src/libs/E2E/apiMocks/authenticatePusher.ts new file mode 100644 index 000000000000..346018df6eb2 --- /dev/null +++ b/src/libs/E2E/apiMocks/authenticatePusher.ts @@ -0,0 +1,11 @@ +import Response from '../../../types/onyx/Response'; + +const authenticatePusher = (): Response => ({ + auth: 'auth', + // eslint-disable-next-line @typescript-eslint/naming-convention + shared_secret: 'secret', + jsonCode: 200, + requestID: '783ef7fc3991969a-SJC', +}); + +export default authenticatePusher; diff --git a/src/libs/E2E/apiMocks/beginSignin.js b/src/libs/E2E/apiMocks/beginSignin.ts similarity index 73% rename from src/libs/E2E/apiMocks/beginSignin.js rename to src/libs/E2E/apiMocks/beginSignin.ts index 44e68ef58992..ea07ea7a6c08 100644 --- a/src/libs/E2E/apiMocks/beginSignin.js +++ b/src/libs/E2E/apiMocks/beginSignin.ts @@ -1,4 +1,7 @@ -export default ({email}) => ({ +import Response from '../../../types/onyx/Response'; +import {SigninParams} from '../types'; + +const beginSignin = ({email}: SigninParams): Response => ({ onyxData: [ { onyxMethod: 'merge', @@ -23,3 +26,5 @@ export default ({email}) => ({ jsonCode: 200, requestID: '783e54ef4b38cff5-SJC', }); + +export default beginSignin; diff --git a/src/libs/E2E/apiMocks/openApp.js b/src/libs/E2E/apiMocks/openApp.ts similarity index 99% rename from src/libs/E2E/apiMocks/openApp.js rename to src/libs/E2E/apiMocks/openApp.ts index d50f4462cfd9..5ef53348f293 100644 --- a/src/libs/E2E/apiMocks/openApp.js +++ b/src/libs/E2E/apiMocks/openApp.ts @@ -1,4 +1,7 @@ -export default () => ({ +/* eslint-disable @typescript-eslint/naming-convention */ +import Response from '../../../types/onyx/Response'; + +const openApp = (): Response => ({ onyxData: [ { onyxMethod: 'merge', @@ -1299,7 +1302,7 @@ export default () => ({ displayName: 'applausetester+pd1005@applause.expensifail.com', pronouns: '', timezone: { - automatic: 'true', + automatic: true, selected: 'Europe/Lisbon', }, firstName: '', @@ -1375,7 +1378,7 @@ export default () => ({ displayName: 'Applause Main Account', pronouns: '__predefined_coCos', timezone: { - automatic: 'true', + automatic: true, selected: 'Europe/Kiev', }, firstName: 'Applause', @@ -1572,7 +1575,7 @@ export default () => ({ report_98258097: { reportID: '98258097', reportName: 'Chat Report', - chatType: '', + chatType: null, ownerAccountID: 0, policyID: '_FAKE_', participantAccountIDs: [22], @@ -1620,7 +1623,7 @@ export default () => ({ report_98344717: { reportID: '98344717', reportName: 'Chat Report', - chatType: '', + chatType: null, ownerAccountID: 0, policyID: '_FAKE_', participantAccountIDs: [14], @@ -1642,7 +1645,7 @@ export default () => ({ report_98345050: { reportID: '98345050', reportName: 'Chat Report', - chatType: '', + chatType: null, ownerAccountID: 0, policyID: '_FAKE_', participantAccountIDs: [4], @@ -1664,7 +1667,7 @@ export default () => ({ report_98345315: { reportID: '98345315', reportName: 'Chat Report', - chatType: '', + chatType: null, ownerAccountID: 0, policyID: '_FAKE_', participantAccountIDs: [4, 16, 18, 19], @@ -1686,7 +1689,7 @@ export default () => ({ report_98345625: { reportID: '98345625', reportName: 'Chat Report', - chatType: '', + chatType: null, ownerAccountID: 0, policyID: '_FAKE_', participantAccountIDs: [2, 1, 4, 3, 5, 16, 18, 19], @@ -1730,7 +1733,7 @@ export default () => ({ report_98414813: { reportID: '98414813', reportName: 'Chat Report', - chatType: '', + chatType: null, ownerAccountID: 0, policyID: '_FAKE_', participantAccountIDs: [14, 16], @@ -1752,7 +1755,7 @@ export default () => ({ report_98817646: { reportID: '98817646', reportName: 'Chat Report', - chatType: '', + chatType: null, ownerAccountID: 0, policyID: '_FAKE_', participantAccountIDs: [16], @@ -1841,7 +1844,7 @@ export default () => ({ report_2242399088152511: { reportID: '2242399088152511', reportName: 'Chat Report', - chatType: '', + chatType: null, ownerAccountID: 0, policyID: '_FAKE_', participantAccountIDs: [22, 10, 6, 8, 4], @@ -1863,7 +1866,7 @@ export default () => ({ report_2576922422943214: { reportID: '2576922422943214', reportName: 'Chat Report', - chatType: '', + chatType: null, ownerAccountID: 0, policyID: '_FAKE_', participantAccountIDs: [12], @@ -1885,7 +1888,7 @@ export default () => ({ report_2752461403207161: { reportID: '2752461403207161', reportName: 'Chat Report', - chatType: '', + chatType: null, ownerAccountID: 0, policyID: '_FAKE_', participantAccountIDs: [2], @@ -1929,7 +1932,7 @@ export default () => ({ report_4867098979334014: { reportID: '4867098979334014', reportName: 'Chat Report', - chatType: '', + chatType: null, ownerAccountID: 0, policyID: '_FAKE_', participantAccountIDs: [21], @@ -1998,7 +2001,7 @@ export default () => ({ report_5654270288238256: { reportID: '5654270288238256', reportName: 'Chat Report', - chatType: '', + chatType: null, ownerAccountID: 0, policyID: '_FAKE_', participantAccountIDs: [6, 2, 9, 4, 5, 7, 100, 11], @@ -2042,7 +2045,7 @@ export default () => ({ report_6801643744224146: { reportID: '6801643744224146', reportName: 'Chat Report', - chatType: '', + chatType: null, ownerAccountID: 0, policyID: '_FAKE_', participantAccountIDs: [22, 6, 2, 23, 9, 4, 5, 7], @@ -2065,7 +2068,7 @@ export default () => ({ report_7658708888047100: { reportID: '7658708888047100', reportName: 'Chat Report', - chatType: '', + chatType: null, ownerAccountID: 0, policyID: '_FAKE_', participantAccountIDs: [22, 6, 4, 5, 24, 101], @@ -2109,7 +2112,7 @@ export default () => ({ report_7819732651025410: { reportID: '7819732651025410', reportName: 'Chat Report', - chatType: '', + chatType: null, ownerAccountID: 0, policyID: '_FAKE_', participantAccountIDs: [5], @@ -2158,3 +2161,5 @@ export default () => ({ jsonCode: 200, requestID: '783ef7fac81f969a-SJC', }); + +export default openApp; diff --git a/src/libs/E2E/apiMocks/openReport.js b/src/libs/E2E/apiMocks/openReport.ts similarity index 91% rename from src/libs/E2E/apiMocks/openReport.js rename to src/libs/E2E/apiMocks/openReport.ts index 936f9d77ef06..d55614753788 100644 --- a/src/libs/E2E/apiMocks/openReport.js +++ b/src/libs/E2E/apiMocks/openReport.ts @@ -1,4 +1,6 @@ -export default () => ({ +import Response from '../../../types/onyx/Response'; + +const openReport = (): Response => ({ onyxData: [ { onyxMethod: 'merge', @@ -6,7 +8,7 @@ export default () => ({ value: { reportID: '98345625', reportName: 'Chat Report', - chatType: '', + chatType: null, ownerAccountID: 0, policyID: '_FAKE_', participantAccountIDs: [2, 1, 4, 3, 5, 16, 18, 19], @@ -30,6 +32,7 @@ export default () => ({ onyxMethod: 'merge', key: 'reportActions_98345625', value: { + // eslint-disable-next-line @typescript-eslint/naming-convention 226245034: { reportActionID: '226245034', actionName: 'CREATED', @@ -59,6 +62,7 @@ export default () => ({ automatic: false, shouldShow: true, }, + // eslint-disable-next-line @typescript-eslint/naming-convention 1082059149: { person: [ { @@ -94,3 +98,5 @@ export default () => ({ jsonCode: 200, requestID: '783ef80a3fc5969a-SJC', }); + +export default openReport; diff --git a/src/libs/E2E/apiMocks/signinUser.js b/src/libs/E2E/apiMocks/signinUser.ts similarity index 95% rename from src/libs/E2E/apiMocks/signinUser.js rename to src/libs/E2E/apiMocks/signinUser.ts index 26203bc492cf..b65a104ac983 100644 --- a/src/libs/E2E/apiMocks/signinUser.js +++ b/src/libs/E2E/apiMocks/signinUser.ts @@ -1,4 +1,7 @@ -export default ({email}) => ({ +import Response from '../../../types/onyx/Response'; +import {SigninParams} from '../types'; + +const signinUser = ({email}: SigninParams): Response => ({ onyxData: [ { onyxMethod: 'merge', @@ -121,3 +124,5 @@ export default ({email}) => ({ jsonCode: 200, requestID: '783e5f3cadfbcfc0-SJC', }); + +export default signinUser; diff --git a/src/libs/E2E/client.js b/src/libs/E2E/client.ts similarity index 69% rename from src/libs/E2E/client.js rename to src/libs/E2E/client.ts index c948c7c2c6d2..ffafa395233b 100644 --- a/src/libs/E2E/client.js +++ b/src/libs/E2E/client.ts @@ -1,28 +1,36 @@ import Routes from '../../../tests/e2e/server/routes'; import Config from '../../../tests/e2e/config'; +type TestResult = { + name: string; + duration?: number; + error?: string; +}; + +type TestConfig = { + name: string; +}; + const SERVER_ADDRESS = `http://localhost:${Config.SERVER_PORT}`; /** * Submits a test result to the server. * Note: a test can have multiple test results. - * - * @param {TestResult} testResult - * @returns {Promise} */ -const submitTestResults = (testResult) => +const submitTestResults = (testResult: TestResult): Promise => fetch(`${SERVER_ADDRESS}${Routes.testResults}`, { method: 'POST', headers: { + // eslint-disable-next-line @typescript-eslint/naming-convention 'Content-Type': 'application/json', }, body: JSON.stringify(testResult), }).then((res) => { - if (res.statusCode === 200) { + if (res.status === 200) { console.debug(`[E2E] Test result '${testResult.name}' submitted successfully`); return; } - const errorMsg = `Test result submission failed with status code ${res.statusCode}`; + const errorMsg = `Test result submission failed with status code ${res.status}`; res.json() .then((responseText) => { throw new Error(`${errorMsg}: ${responseText}`); @@ -34,13 +42,10 @@ const submitTestResults = (testResult) => const submitTestDone = () => fetch(`${SERVER_ADDRESS}${Routes.testDone}`); -/** - * @returns {Promise} - */ -const getTestConfig = () => +const getTestConfig = (): Promise => fetch(`${SERVER_ADDRESS}${Routes.testConfig}`) - .then((res) => res.json()) - .then((config) => config); + .then((res: Response): Promise => res.json()) + .then((config: TestConfig) => config); export default { submitTestResults, diff --git a/src/libs/E2E/isE2ETestSession.js b/src/libs/E2E/isE2ETestSession.js deleted file mode 100644 index eae5767cffbc..000000000000 --- a/src/libs/E2E/isE2ETestSession.js +++ /dev/null @@ -1 +0,0 @@ -export default () => false; diff --git a/src/libs/E2E/isE2ETestSession.native.js b/src/libs/E2E/isE2ETestSession.native.js deleted file mode 100644 index 214e8241c5dc..000000000000 --- a/src/libs/E2E/isE2ETestSession.native.js +++ /dev/null @@ -1,3 +0,0 @@ -import CONFIG from '../../CONFIG'; - -export default () => CONFIG.E2E_TESTING; diff --git a/src/libs/E2E/isE2ETestSession.native.ts b/src/libs/E2E/isE2ETestSession.native.ts new file mode 100644 index 000000000000..19499c91050d --- /dev/null +++ b/src/libs/E2E/isE2ETestSession.native.ts @@ -0,0 +1,6 @@ +import CONFIG from '../../CONFIG'; +import {IsE2ETestSession} from './types'; + +const isE2ETestSession: IsE2ETestSession = () => CONFIG.E2E_TESTING; + +export default isE2ETestSession; diff --git a/src/libs/E2E/isE2ETestSession.ts b/src/libs/E2E/isE2ETestSession.ts new file mode 100644 index 000000000000..145c4336fddf --- /dev/null +++ b/src/libs/E2E/isE2ETestSession.ts @@ -0,0 +1,5 @@ +import {IsE2ETestSession} from './types'; + +const isE2ETestSession: IsE2ETestSession = () => false; + +export default isE2ETestSession; diff --git a/src/libs/E2E/tests/appStartTimeTest.e2e.js b/src/libs/E2E/tests/appStartTimeTest.e2e.ts similarity index 86% rename from src/libs/E2E/tests/appStartTimeTest.e2e.js rename to src/libs/E2E/tests/appStartTimeTest.e2e.ts index d44fd6ce1195..2a33453151e0 100644 --- a/src/libs/E2E/tests/appStartTimeTest.e2e.js +++ b/src/libs/E2E/tests/appStartTimeTest.e2e.ts @@ -1,4 +1,4 @@ -import _ from 'underscore'; +import {PerformanceEntry} from 'react-native-performance'; import E2ELogin from '../actions/e2eLogin'; import Performance from '../../Performance'; import E2EClient from '../client'; @@ -14,11 +14,11 @@ const test = () => { console.debug('[E2E] Logged in, getting metrics and submitting them…'); // collect performance metrics and submit - const metrics = Performance.getPerformanceMetrics(); + const metrics: PerformanceEntry[] = Performance.getPerformanceMetrics(); // underscore promises in sequence without for-loop Promise.all( - _.map(metrics, (metric) => + metrics.map((metric) => E2EClient.submitTestResults({ name: `App start ${metric.name}`, duration: metric.duration, diff --git a/src/libs/E2E/types.ts b/src/libs/E2E/types.ts new file mode 100644 index 000000000000..fcdfa01d7132 --- /dev/null +++ b/src/libs/E2E/types.ts @@ -0,0 +1,7 @@ +type SigninParams = { + email?: string; +}; + +type IsE2ETestSession = () => boolean; + +export type {SigninParams, IsE2ETestSession}; diff --git a/src/types/onyx/Currency.ts b/src/types/onyx/Currency.ts index 770fcc33a9a9..a4767403381f 100644 --- a/src/types/onyx/Currency.ts +++ b/src/types/onyx/Currency.ts @@ -10,6 +10,15 @@ type Currency = { /** Number of decimals the currency can have, if this is missing, we assume it has 2 decimals */ decimals?: number; + + /** If currency is retired */ + retired?: boolean; + + /** Retirement date of the currency */ + retirementDate?: string; + + /** Cache burst */ + cacheBurst?: number; }; export default Currency; diff --git a/src/types/onyx/FrequentlyUsedEmoji.ts b/src/types/onyx/FrequentlyUsedEmoji.ts index 2276095df9b5..8001ed91822a 100644 --- a/src/types/onyx/FrequentlyUsedEmoji.ts +++ b/src/types/onyx/FrequentlyUsedEmoji.ts @@ -3,7 +3,7 @@ type FrequentlyUsedEmoji = { code: string; /** The name of the emoji */ - name: string; + name?: string; /** The number of times the emoji has been used */ count: number; @@ -13,6 +13,9 @@ type FrequentlyUsedEmoji = { /** The emoji skin tone type */ types?: string[]; + + /** The emoji keywords */ + keywords?: string[]; }; export default FrequentlyUsedEmoji; diff --git a/src/types/onyx/Policy.ts b/src/types/onyx/Policy.ts index df4a1364a894..d394f467c3a6 100644 --- a/src/types/onyx/Policy.ts +++ b/src/types/onyx/Policy.ts @@ -47,6 +47,9 @@ type Policy = { /** Whether policy expense chats can be created and used on this policy. Enabled manually by CQ/JS snippet. Always true for free policies. */ isPolicyExpenseChatEnabled: boolean; + + /** The employee list of the policy */ + employeeList?: []; }; export default Policy; diff --git a/src/types/onyx/Report.ts b/src/types/onyx/Report.ts index 6b2db2912cd6..ca502c84116c 100644 --- a/src/types/onyx/Report.ts +++ b/src/types/onyx/Report.ts @@ -24,9 +24,15 @@ type Report = { /** The text of the last message on the report */ lastMessageText?: string; + /** The timestamp of the last message on the report */ + lastMessageTimestamp?: number; + /** The time of the last message on the report */ lastVisibleActionCreated?: string; + /** The time of the last read of the report */ + lastReadCreated?: string; + /** The last time the report was visited */ lastReadTime?: string; @@ -39,6 +45,9 @@ type Report = { /** The email address of the report owner */ ownerEmail?: string; + /** The email address of the manager */ + managerEmail?: string; + /** List of primarylogins of participants of the report */ participants?: string[]; @@ -51,6 +60,15 @@ type Report = { /** ID of the report */ reportID: string; + /** ID of the iou report */ + iouReportID?: number; + + /** ID of the chat report */ + chatReportID?: string; + + /** The state of the report */ + state?: ValueOf; + /** The state that the report is currently in */ stateNum?: ValueOf; @@ -63,6 +81,12 @@ type Report = { /** The report type */ type?: string; + /** The report visibility */ + visibility?: string; + + /** Report cached total */ + cachedTotal?: string; + parentReportID?: string; parentReportActionID?: string; isOptimisticReport?: boolean; diff --git a/src/types/onyx/ReportAction.ts b/src/types/onyx/ReportAction.ts index ec505a7e8d07..4ed9bc627738 100644 --- a/src/types/onyx/ReportAction.ts +++ b/src/types/onyx/ReportAction.ts @@ -8,6 +8,9 @@ type Message = { /** The text content of the fragment. */ text: string; + /** The html content of the fragment. */ + html?: string; + /** Used to apply additional styling. Style refers to a predetermined constant and not a class name. e.g. 'normal' * or 'strong' */ @@ -29,11 +32,11 @@ type Message = { iconUrl?: string; /** Fragment edited flag */ - isEdited: boolean; + isEdited?: boolean; - isDeletedParentAction: boolean; - whisperedTo: number[]; - reactions: Reaction[]; + isDeletedParentAction?: boolean; + whisperedTo?: number[]; + reactions?: Reaction[]; }; type Person = { @@ -79,6 +82,8 @@ type ReportActionBase = { childCommenterCount?: number; childLastVisibleActionCreated?: string; childVisibleActionCount?: number; + timestamp?: number; + reportActionTimestamp?: number; pendingAction?: OnyxCommon.PendingAction; }; diff --git a/src/types/onyx/Response.ts b/src/types/onyx/Response.ts index 255ac6d9bae4..b6af476db6c8 100644 --- a/src/types/onyx/Response.ts +++ b/src/types/onyx/Response.ts @@ -7,6 +7,9 @@ type Response = { onyxData?: OnyxUpdate[]; requestID?: string; message?: string; + auth?: string; + // eslint-disable-next-line @typescript-eslint/naming-convention + shared_secret?: string; }; export default Response; diff --git a/tests/e2e/README.md b/tests/e2e/README.md index 2aa9a2a84800..c31109fd01bf 100644 --- a/tests/e2e/README.md +++ b/tests/e2e/README.md @@ -85,7 +85,7 @@ components: - Client: - Client-side code (app) for communication with the test server. - - Located in `src/libs/E2E/client.js`. + - Located in `src/libs/E2E/client.ts`. ## How a test gets executed From 61aa3d8b3aaa77129426f15b08bc5878d2712d9a Mon Sep 17 00:00:00 2001 From: Viktoryia Kliushun Date: Thu, 5 Oct 2023 10:57:31 +0200 Subject: [PATCH 005/212] Add errors field to report action type --- src/types/onyx/ReportAction.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/types/onyx/ReportAction.ts b/src/types/onyx/ReportAction.ts index 4ed9bc627738..54a598d4564f 100644 --- a/src/types/onyx/ReportAction.ts +++ b/src/types/onyx/ReportAction.ts @@ -69,6 +69,9 @@ type ReportActionBase = { /** Error message that's come back from the server. */ error?: string; + /** Any additional errors */ + errors?: OnyxCommon.Errors; + /** accountIDs of the people to which the whisper was sent to (if any). Returns empty array if it is not a whisper */ whisperedToAccountIDs?: number[]; From 6fd4a81d0154b6080bbaee3f62988f403ea1640e Mon Sep 17 00:00:00 2001 From: Mahesh Date: Sat, 14 Oct 2023 00:58:14 +0530 Subject: [PATCH 006/212] update search icon & styles for search input --- docs/_sass/_search-bar.scss | 2 -- docs/assets/js/main.js | 37 ++++++++++++++++++------------------- 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/docs/_sass/_search-bar.scss b/docs/_sass/_search-bar.scss index e9c56835af50..c2185ef8f36a 100644 --- a/docs/_sass/_search-bar.scss +++ b/docs/_sass/_search-bar.scss @@ -210,9 +210,7 @@ label.search-label { width: auto; } -/* Change the path of the Google Search Button icon into Expensify icon */ .gsc-search-button.gsc-search-button-v2 svg path { - d: path('M8 1c3.9 0 7 3.1 7 7 0 1.4-.4 2.7-1.1 3.8l5.2 5.2c.6.6.6 1.5 0 2.1-.6.6-1.5.6-2.1 0l-5.2-5.2C10.7 14.6 9.4 15 8 15c-3.9 0-7-3.1-7-7s3.1-7 7-7zm0 3c2.2 0 4 1.8 4 4s-1.8 4-4 4-4-1.8-4-4 1.8-4 4-4z'); fill-rule: evenodd; clip-rule: evenodd; } diff --git a/docs/assets/js/main.js b/docs/assets/js/main.js index aebd0f5d4864..50ac9cfa7e41 100644 --- a/docs/assets/js/main.js +++ b/docs/assets/js/main.js @@ -120,25 +120,12 @@ function changeSVGViewBoxGoogle() { // Get all inline Google SVG elements on the page const svgsGoogle = document.querySelectorAll('svg'); - // Create a media query for screens wider than tablet - const mediaQuery = window.matchMedia('(min-width: 800px)'); - - // Check if the viewport is smaller than tablet - if (!mediaQuery.matches) { - Array.from(svgsGoogle).forEach((svg) => { - // Set the viewBox attribute to '0 0 13 13' to make the svg fit in the mobile view - svg.setAttribute('viewBox', '0 0 13 13'); - svg.setAttribute('height', '13'); - svg.setAttribute('width', '13'); - }); - } else { - Array.from(svgsGoogle).forEach((svg) => { - // Set the viewBox attribute to '0 0 20 20' to make the svg fit in the tablet-desktop view - svg.setAttribute('viewBox', '0 0 20 20'); - svg.setAttribute('height', '16'); - svg.setAttribute('width', '16'); - }); - } + Array.from(svgsGoogle).forEach((svg) => { + // Set the viewBox attribute to '0 0 13 13' to make the svg fit in the mobile view + svg.setAttribute('viewBox', '0 0 20 20'); + svg.setAttribute('height', '16'); + svg.setAttribute('width', '16'); + }); } // Function to insert element after another @@ -147,11 +134,23 @@ function insertElementAfter(referenceNode, newNode) { referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling); } +// Update the ICON for search input. +/* Change the path of the Google Search Button icon into Expensify icon */ +function updateGoogleSearchIcon() { + const node = document.querySelector('.gsc-search-button.gsc-search-button-v2 svg path'); + node.setAttribute( + 'd', + 'M8 1c3.9 0 7 3.1 7 7 0 1.4-.4 2.7-1.1 3.8l5.2 5.2c.6.6.6 1.5 0 2.1-.6.6-1.5.6-2.1 0l-5.2-5.2C10.7 14.6 9.4 15 8 15c-3.9 0-7-3.1-7-7s3.1-7 7-7zm0 3c2.2 0 4 1.8 4 4s-1.8 4-4 4-4-1.8-4-4 1.8-4 4-4z', + ); +} + // Need to wait up until page is load, so the svg viewBox can be changed // And the search label can be inserted window.addEventListener('load', () => { changeSVGViewBoxGoogle(); + updateGoogleSearchIcon(); + // Add required into the search input const searchInput = document.getElementById('gsc-i-id1'); searchInput.setAttribute('required', ''); From d5186d4eeedc8262c2f74037aa86d7baa5d0e6d6 Mon Sep 17 00:00:00 2001 From: Jakub Trzebiatowski Date: Mon, 16 Oct 2023 10:06:21 +0200 Subject: [PATCH 007/212] Extract the reportAction's source prop type to a separate file --- src/pages/home/report/comment/AttachmentCommentFragment.js | 3 ++- src/pages/home/report/comment/RenderCommentHTML.js | 3 ++- src/pages/home/report/comment/TextCommentFragment.js | 3 ++- src/pages/home/report/reportActionSourcePropType.js | 3 +++ 4 files changed, 9 insertions(+), 3 deletions(-) create mode 100644 src/pages/home/report/reportActionSourcePropType.js diff --git a/src/pages/home/report/comment/AttachmentCommentFragment.js b/src/pages/home/report/comment/AttachmentCommentFragment.js index 2d019c7d89e0..3b03749f113e 100644 --- a/src/pages/home/report/comment/AttachmentCommentFragment.js +++ b/src/pages/home/report/comment/AttachmentCommentFragment.js @@ -3,10 +3,11 @@ import {View} from 'react-native'; import PropTypes from 'prop-types'; import styles from '../../../../styles/styles'; import RenderCommentHTML from './RenderCommentHTML'; +import reportActionSourcePropType from '../reportActionSourcePropType'; const propTypes = { /** The reportAction's source */ - source: PropTypes.oneOf(['Chronos', 'email', 'ios', 'android', 'web', 'email', '']).isRequired, + source: reportActionSourcePropType.isRequired, /** The message fragment's HTML */ html: PropTypes.string.isRequired, diff --git a/src/pages/home/report/comment/RenderCommentHTML.js b/src/pages/home/report/comment/RenderCommentHTML.js index 216fdfc58025..ef9d3ffcb8f1 100644 --- a/src/pages/home/report/comment/RenderCommentHTML.js +++ b/src/pages/home/report/comment/RenderCommentHTML.js @@ -1,10 +1,11 @@ import React from 'react'; import PropTypes from 'prop-types'; import RenderHTML from '../../../../components/RenderHTML'; +import reportActionSourcePropType from '../reportActionSourcePropType'; const propTypes = { /** The reportAction's source */ - source: PropTypes.oneOf(['Chronos', 'email', 'ios', 'android', 'web', 'email', '']).isRequired, + source: reportActionSourcePropType.isRequired, /** The comment's HTML */ html: PropTypes.string.isRequired, diff --git a/src/pages/home/report/comment/TextCommentFragment.js b/src/pages/home/report/comment/TextCommentFragment.js index aed0730b8c59..e51eabcec720 100644 --- a/src/pages/home/report/comment/TextCommentFragment.js +++ b/src/pages/home/report/comment/TextCommentFragment.js @@ -2,6 +2,7 @@ import React, {memo} from 'react'; import PropTypes from 'prop-types'; import Str from 'expensify-common/lib/str'; import reportActionFragmentPropTypes from '../reportActionFragmentPropTypes'; +import reportActionSourcePropType from '../reportActionSourcePropType'; import styles from '../../../../styles/styles'; import variables from '../../../../styles/variables'; import themeColors from '../../../../styles/themes/default'; @@ -18,7 +19,7 @@ import RenderCommentHTML from './RenderCommentHTML'; const propTypes = { /** The reportAction's source */ - source: PropTypes.oneOf(['Chronos', 'email', 'ios', 'android', 'web', 'email', '']).isRequired, + source: reportActionSourcePropType.isRequired, /** The message fragment needing to be displayed */ fragment: reportActionFragmentPropTypes.isRequired, diff --git a/src/pages/home/report/reportActionSourcePropType.js b/src/pages/home/report/reportActionSourcePropType.js new file mode 100644 index 000000000000..0ad9662eb693 --- /dev/null +++ b/src/pages/home/report/reportActionSourcePropType.js @@ -0,0 +1,3 @@ +import PropTypes from 'prop-types'; + +export default PropTypes.oneOf(['Chronos', 'email', 'ios', 'android', 'web', 'email', '']); From 354cd4cb340c8f04f5ea0c3ff87b8b48e0a9a277 Mon Sep 17 00:00:00 2001 From: Viktoryia Kliushun Date: Mon, 16 Oct 2023 16:52:41 +0200 Subject: [PATCH 008/212] Migrate e2e files to TS --- ...iveLaunchingTest.js => reactNativeLaunchingTest.ts} | 10 ++++++---- ...SearchPageTest.e2e.js => openSearchPageTest.e2e.ts} | 2 +- src/libs/Navigation/Navigation.js | 2 +- src/libs/Performance.tsx | 4 ++-- 4 files changed, 10 insertions(+), 8 deletions(-) rename src/libs/E2E/{reactNativeLaunchingTest.js => reactNativeLaunchingTest.ts} (91%) rename src/libs/E2E/tests/{openSearchPageTest.e2e.js => openSearchPageTest.e2e.ts} (95%) diff --git a/src/libs/E2E/reactNativeLaunchingTest.js b/src/libs/E2E/reactNativeLaunchingTest.ts similarity index 91% rename from src/libs/E2E/reactNativeLaunchingTest.js rename to src/libs/E2E/reactNativeLaunchingTest.ts index 13183c1044db..f56988d2513c 100644 --- a/src/libs/E2E/reactNativeLaunchingTest.js +++ b/src/libs/E2E/reactNativeLaunchingTest.ts @@ -4,13 +4,15 @@ * By doing this, we avoid bundling any E2E testing code * into the actual release app. */ - +import {ValueOf} from 'type-fest'; import Performance from '../Performance'; import * as Metrics from '../Metrics'; import E2EConfig from '../../../tests/e2e/config'; import E2EClient from './client'; +type Tests = Record, () => void>; + console.debug('=========================='); console.debug('==== Running e2e test ===='); console.debug('=========================='); @@ -21,13 +23,13 @@ if (!Metrics.canCapturePerformanceMetrics()) { } // import your test here, define its name and config first in e2e/config.js -const tests = { +const tests: Tests = { [E2EConfig.TEST_NAMES.AppStartTime]: require('./tests/appStartTimeTest.e2e').default, [E2EConfig.TEST_NAMES.OpenSearchPage]: require('./tests/openSearchPageTest.e2e').default, }; // Once we receive the TII measurement we know that the app is initialized and ready to be used: -const appReady = new Promise((resolve) => { +const appReady = new Promise((resolve) => { Performance.subscribeToMeasurements((entry) => { if (entry.name !== 'TTI') { return; @@ -38,7 +40,7 @@ const appReady = new Promise((resolve) => { }); E2EClient.getTestConfig() - .then((config) => { + .then((config): Promise | undefined => { const test = tests[config.name]; if (!test) { // instead of throwing, report the error to the server, which is better for DX diff --git a/src/libs/E2E/tests/openSearchPageTest.e2e.js b/src/libs/E2E/tests/openSearchPageTest.e2e.ts similarity index 95% rename from src/libs/E2E/tests/openSearchPageTest.e2e.js rename to src/libs/E2E/tests/openSearchPageTest.e2e.ts index 3b2d91322cf0..5807134586d0 100644 --- a/src/libs/E2E/tests/openSearchPageTest.e2e.js +++ b/src/libs/E2E/tests/openSearchPageTest.e2e.ts @@ -9,7 +9,7 @@ const test = () => { // check for login (if already logged in the action will simply resolve) console.debug('[E2E] Logging in for search'); - E2ELogin().then((neededLogin) => { + E2ELogin().then((neededLogin: boolean): Promise | undefined => { if (neededLogin) { // we don't want to submit the first login to the results return E2EClient.submitTestDone(); diff --git a/src/libs/Navigation/Navigation.js b/src/libs/Navigation/Navigation.js index 07b12486b8b2..db806f71fab0 100644 --- a/src/libs/Navigation/Navigation.js +++ b/src/libs/Navigation/Navigation.js @@ -80,7 +80,7 @@ const getActiveRouteIndex = function (route, index) { /** * Main navigation method for redirecting to a route. * @param {String} route - * @param {String} type - Type of action to perform. Currently UP is supported. + * @param {String} [type] - Type of action to perform. Currently UP is supported. */ function navigate(route = ROUTES.HOME, type) { if (!canNavigate('navigate', {route})) { diff --git a/src/libs/Performance.tsx b/src/libs/Performance.tsx index cfb5e258c9f8..d177a6fd4ccc 100644 --- a/src/libs/Performance.tsx +++ b/src/libs/Performance.tsx @@ -27,7 +27,7 @@ type GetPerformanceMetrics = () => PerformanceEntry[]; type PrintPerformanceMetrics = () => void; type MarkStart = (name: string, detail?: Record) => PerformanceMark | void; type MarkEnd = (name: string, detail?: Record) => PerformanceMark | void; -type MeasureFailSafe = (measureName: string, startOrMeasureOptions: string, endMark: string) => void; +type MeasureFailSafe = (measureName: string, startOrMeasureOptions: string, endMark?: string) => void; type MeasureTTI = (endMark: string) => void; type TraceRender = (id: string, phase: Phase, actualDuration: number, baseDuration: number, startTime: number, commitTime: number, interactions: Set) => PerformanceMeasure | void; type WithRenderTrace = ({id}: WrappedComponentConfig) => WithRenderTraceHOC | BlankHOC; @@ -91,7 +91,7 @@ if (Metrics.canCapturePerformanceMetrics()) { perfModule.setResourceLoggingEnabled(true); rnPerformance = perfModule.default; - Performance.measureFailSafe = (measureName: string, startOrMeasureOptions: string, endMark: string) => { + Performance.measureFailSafe = (measureName: string, startOrMeasureOptions: string, endMark?: string) => { try { rnPerformance.measure(measureName, startOrMeasureOptions, endMark); } catch (error) { From af68eded83d288de722568d00db8fe4e4a9394b6 Mon Sep 17 00:00:00 2001 From: Viktoryia Kliushun Date: Tue, 17 Oct 2023 12:09:19 +0200 Subject: [PATCH 009/212] Update files extension in docs --- fastlane/Fastfile | 2 +- tests/e2e/ADDING_TESTS.md | 6 +++--- tests/e2e/README.md | 6 +++--- tests/e2e/config.js | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 78abf8074155..83a554c40a84 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -17,7 +17,7 @@ platform :android do desc "Generate a new local APK for e2e testing" lane :build_e2e do ENV["ENVFILE"]="tests/e2e/.env.e2e" - ENV["ENTRY_FILE"]="src/libs/E2E/reactNativeLaunchingTest.js" + ENV["ENTRY_FILE"]="src/libs/E2E/reactNativeLaunchingTest.ts" ENV["E2E_TESTING"]="true" gradle( diff --git a/tests/e2e/ADDING_TESTS.md b/tests/e2e/ADDING_TESTS.md index dcd08aeee441..90b84a09c972 100644 --- a/tests/e2e/ADDING_TESTS.md +++ b/tests/e2e/ADDING_TESTS.md @@ -15,9 +15,9 @@ I recommend doing the following. 1. Rename `./index.js` to `./appIndex.js` 2. Create a new `./index.js` with the following content: ```js -requrire("./src/libs/E2E/reactNativeLaunchingTest.js"); +requrire("./src/libs/E2E/reactNativeLaunchingTest.ts"); ``` -3. In `./src/libs/E2E/reactNativeLaunchingTest.js` change the main app import to the new `./appIndex.js` file: +3. In `./src/libs/E2E/reactNativeLaunchingTest.ts` change the main app import to the new `./appIndex.js` file: ```diff - import '../../../index'; + import '../../../appIndex'; @@ -92,7 +92,7 @@ anything here, like connecting to onyx, calling APIs, navigating. There are some common actions that are common among different test cases: -- `src/libs/E2E/actions/e2eLogin.js` - Log a user into the app. +- `src/libs/E2E/actions/e2eLogin.ts` - Log a user into the app. The test will be called once the app is ready, which mean you can immediately start. Your test is expected to default export its test function. diff --git a/tests/e2e/README.md b/tests/e2e/README.md index c31109fd01bf..8c7be011502d 100644 --- a/tests/e2e/README.md +++ b/tests/e2e/README.md @@ -70,7 +70,7 @@ components: - The tests themselves : - The tests are located in `src/libs/E2E/tests` - As opposed to other test frameworks, the tests are _inside the app_, and execute logic using app code (e.g. `navigationRef.navigate('Signin')`) - - For the tests there is a custom entry for react native, located in `src/libs/E2E/reactNativeLaunchingTest.js` + - For the tests there is a custom entry for react native, located in `src/libs/E2E/reactNativeLaunchingTest.ts` - The test runner: - Orchestrates the test suite. @@ -91,7 +91,7 @@ components: ## How a test gets executed There exists a custom android entry point for the app, which is used for the e2e tests. -The entry file used is `src/libs/E2E/reactNativeEntry.js`, and here we can add our test case. +The entry file used is `src/libs/E2E/reactNativeEntry.ts`, and here we can add our test case. The test case should only execute its test once. The _test runner_ is responsible for running the test multiple time to average out the results. @@ -128,7 +128,7 @@ Therefore, a customized release build type is needed, which is called `e2eReleas text traffic enabled but works otherwise just like a release build. In addition to that, another entry file will be used (instead of `index.js`). The entry file used is -`src/libs/E2E/reactNativeEntry.js`. By using a custom entry file we avoid bundling any e2e testing code +`src/libs/E2E/reactNativeEntry.ts`. By using a custom entry file we avoid bundling any e2e testing code into the actual release app. For the app to detect that it is currently running e2e tests, an environment variable called `E2E_TESTING=true` must diff --git a/tests/e2e/config.js b/tests/e2e/config.js index 4f08754cfec2..141f1eff93be 100644 --- a/tests/e2e/config.js +++ b/tests/e2e/config.js @@ -28,7 +28,7 @@ module.exports = { compare: './app-e2eRelease-compare.apk', }, - ENTRY_FILE: 'src/libs/E2E/reactNativeLaunchingTest.js', + ENTRY_FILE: 'src/libs/E2E/reactNativeLaunchingTest.ts', // The port of the testing server that communicates with the app SERVER_PORT: 4723, From bc08d2a5c2bb8ee088983267fb3dd2d41b40a569 Mon Sep 17 00:00:00 2001 From: Viktoryia Kliushun Date: Wed, 18 Oct 2023 08:25:06 +0200 Subject: [PATCH 010/212] Remove todo --- metro.config.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/metro.config.js b/metro.config.js index a63cde4e0d14..34746cdaab48 100644 --- a/metro.config.js +++ b/metro.config.js @@ -27,8 +27,7 @@ const config = { if (isUsingMockAPI && moduleName.includes('/API')) { return { ...resolution, - // TODO: Change API.js extension once it is migrated to TypeScript - filePath: resolution.filePath.replace(/src\/libs\/API.js/, 'src/libs/E2E/API.mock.ts'), + filePath: resolution.filePath.replace(/src\/libs\/API.ts/, 'src/libs/E2E/API.mock.ts'), }; } return resolution; From c0f2af25f40f3a2bbf637a07864f9064042dd76b Mon Sep 17 00:00:00 2001 From: Jakub Trzebiatowski Date: Thu, 19 Oct 2023 14:20:47 +0200 Subject: [PATCH 011/212] Remove a left-over of local testing --- src/libs/Permissions.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libs/Permissions.ts b/src/libs/Permissions.ts index 9a5a538dda6f..13489c396c3c 100644 --- a/src/libs/Permissions.ts +++ b/src/libs/Permissions.ts @@ -43,7 +43,6 @@ function canUseCustomStatus(betas: Beta[]): boolean { } function canUseCategories(betas: Beta[]): boolean { - return true; return betas?.includes(CONST.BETAS.NEW_DOT_CATEGORIES) || canUseAllBetas(betas); } From 68edae50d121af81fb6c8805af25359f58235dca Mon Sep 17 00:00:00 2001 From: David Cardoza Date: Fri, 20 Oct 2023 12:55:07 +0800 Subject: [PATCH 012/212] Create How-to-Join-the-ExpensifyApproved!-Partner-Program https://github.com/Expensify/Expensify/issues/311406 --- ...oin-the-ExpensifyApproved!-Partner-Program | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 docs/articles/expensify-classic/expensify-partner-program/How-to-Join-the-ExpensifyApproved!-Partner-Program diff --git a/docs/articles/expensify-classic/expensify-partner-program/How-to-Join-the-ExpensifyApproved!-Partner-Program b/docs/articles/expensify-classic/expensify-partner-program/How-to-Join-the-ExpensifyApproved!-Partner-Program new file mode 100644 index 000000000000..054dae5e2e14 --- /dev/null +++ b/docs/articles/expensify-classic/expensify-partner-program/How-to-Join-the-ExpensifyApproved!-Partner-Program @@ -0,0 +1,38 @@ +--- +title: ExpensifyApproved! Partner Program +description: How to Join the ExpensifyApproved! Partner Program +--- + +# Overview + +As trusted accountants and financial advisors, you strive to offer your clients the best tools available. Expensify is recognized as a leading, all-in-one expense and corporate card management platform suitable for clients of every size. By becoming an ExpensifyApproved! Partner, you unlock exclusive benefits for both you and your clientele. +## Key Benefits +Dedicated Partner Manager: Enjoy personalized assistance with an assigned Partner Manager post-course completion. +Client Onboarding Support: A dedicated Client Onboarding Manager will aid in smooth transitions. +Free Expensify Account: Complimentary access to our platform for your convenience. +Revenue share (US-only): All partners receive 0.5% revenue share on client Expensify Card transactions. Keep this as a bonus or offer it to your clients as cash back. +Exclusive CPA Card (US-only): Automated expense reconciliation from swipe to journal entry with the CPA Card. +Special Pricing Offers (US-only): Avail partner-specific discounts for your clients and a revenue share from client Expensify Card transactions. +Professional Growth (US-only): Earn 3 CPE credits after completing the ExpensifyApproved! University. +Cobranded Marketing - Collaborate with your Partner Manager to craft custom marketing materials, case studies, and more. + +# How to join the ExpensifyApproved! Partner Program + +## 1. Enroll in ExpensifyApproved! University (EA!U) +Visit university.expensify.com and enroll in the “Getting Started with Expensify” course. +This course imparts the essentials of Expensify, ensuring you follow the best practices for client setups. + +# 2. Complete the course +Grasp the core features and functionalities of Expensify. +Ensure you're equipped to serve your clients using Expensify to its fullest. +Once completed, you’ll be prompted to schedule a call with your Partner Manager. **This call is required to earn your certification.** + +# 3. Once you successfully complete the course, you'll unlock: +- A dedicated Partner Manager - assigned to you after you have completed the course! +- A dedicated Client Setup Specialist +- Membership to the ExpensifyApproved! Partner Program. +- A complimentary free Expensify account +- Access to the exclusive CPA Card (US-only). +- Partner-specific discounts to extend to your clients. +- A 0.5% revenue share on client Expensify Card expenses (US-only) +- 3 CPE credits (US-only). From eebfbf1a08cf5d2f3bf18964d5986a3404c8303a Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Fri, 20 Oct 2023 13:41:21 +0200 Subject: [PATCH 013/212] migrate withWindowDimensions directory to TypeScript --- .../{index.native.js => index.native.tsx} | 55 +++++++++---------- .../{index.js => index.tsx} | 54 +++++++++--------- src/components/withWindowDimensions/types.ts | 30 ++++++++++ 3 files changed, 82 insertions(+), 57 deletions(-) rename src/components/withWindowDimensions/{index.native.js => index.native.tsx} (65%) rename src/components/withWindowDimensions/{index.js => index.tsx} (68%) create mode 100644 src/components/withWindowDimensions/types.ts diff --git a/src/components/withWindowDimensions/index.native.js b/src/components/withWindowDimensions/index.native.tsx similarity index 65% rename from src/components/withWindowDimensions/index.native.js rename to src/components/withWindowDimensions/index.native.tsx index 363196b3fd4d..889397f2bab6 100644 --- a/src/components/withWindowDimensions/index.native.js +++ b/src/components/withWindowDimensions/index.native.tsx @@ -1,12 +1,14 @@ -import React, {forwardRef, createContext, useState, useEffect, useMemo} from 'react'; +import React, {createContext, useState, useEffect, useMemo, ComponentType, RefAttributes, ForwardedRef} from 'react'; import PropTypes from 'prop-types'; -import {Dimensions} from 'react-native'; +import {Dimensions, ScaledSize} from 'react-native'; import {useSafeAreaInsets} from 'react-native-safe-area-context'; import getComponentDisplayName from '../../libs/getComponentDisplayName'; import variables from '../../styles/variables'; import getWindowHeightAdjustment from '../../libs/getWindowHeightAdjustment'; +import {WindowDimensionsContextData, WindowDimensionsProps} from './types'; +import ChildrenProps from '../../types/utils/ChildrenProps'; -const WindowDimensionsContext = createContext(null); +const WindowDimensionsContext = createContext(null); const windowDimensionsPropTypes = { // Width of the window windowWidth: PropTypes.number.isRequired, @@ -27,12 +29,7 @@ const windowDimensionsPropTypes = { isLargeScreenWidth: PropTypes.bool.isRequired, }; -const windowDimensionsProviderPropTypes = { - /* Actual content wrapped by this component */ - children: PropTypes.node.isRequired, -}; - -function WindowDimensionsProvider(props) { +function WindowDimensionsProvider(props: ChildrenProps) { const [windowDimension, setWindowDimension] = useState(() => { const initialDimensions = Dimensions.get('window'); return { @@ -42,9 +39,8 @@ function WindowDimensionsProvider(props) { }); useEffect(() => { - const onDimensionChange = (newDimensions) => { + const onDimensionChange = (newDimensions: {window: ScaledSize}) => { const {window} = newDimensions; - setWindowDimension({ windowHeight: window.height, windowWidth: window.width, @@ -76,30 +72,31 @@ function WindowDimensionsProvider(props) { return {props.children}; } -WindowDimensionsProvider.propTypes = windowDimensionsProviderPropTypes; WindowDimensionsProvider.displayName = 'WindowDimensionsProvider'; /** - * @param {React.Component} WrappedComponent - * @returns {React.Component} + * @param WrappedComponent + * @returns */ -export default function withWindowDimensions(WrappedComponent) { - const WithWindowDimensions = forwardRef((props, ref) => ( - - {(windowDimensionsProps) => ( - - )} - - )); +export default function withWindowDimensions(WrappedComponent: ComponentType>) { + function WithWindowDimensions(props: Omit, ref: ForwardedRef) { + return ( + + {(windowDimensionsProps) => ( + + )} + + ); + } WithWindowDimensions.displayName = `withWindowDimensions(${getComponentDisplayName(WrappedComponent)})`; - return WithWindowDimensions; + return React.forwardRef(WithWindowDimensions); } export {WindowDimensionsProvider, windowDimensionsPropTypes}; diff --git a/src/components/withWindowDimensions/index.js b/src/components/withWindowDimensions/index.tsx similarity index 68% rename from src/components/withWindowDimensions/index.js rename to src/components/withWindowDimensions/index.tsx index 16e5985e0985..6a5dfadc6a49 100644 --- a/src/components/withWindowDimensions/index.js +++ b/src/components/withWindowDimensions/index.tsx @@ -1,13 +1,15 @@ -import React, {forwardRef, createContext, useState, useEffect, useMemo} from 'react'; +import React, {createContext, useState, useEffect, useMemo, RefAttributes, ComponentType, ForwardedRef} from 'react'; import PropTypes from 'prop-types'; import lodashDebounce from 'lodash/debounce'; -import {Dimensions} from 'react-native'; +import {Dimensions, ScaledSize} from 'react-native'; import {useSafeAreaInsets} from 'react-native-safe-area-context'; import getComponentDisplayName from '../../libs/getComponentDisplayName'; import variables from '../../styles/variables'; import getWindowHeightAdjustment from '../../libs/getWindowHeightAdjustment'; +import ChildrenProps from '../../types/utils/ChildrenProps'; +import {WindowDimensionsContextData, WindowDimensionsProps} from './types'; -const WindowDimensionsContext = createContext(null); +const WindowDimensionsContext = createContext(null); const windowDimensionsPropTypes = { // Width of the window windowWidth: PropTypes.number.isRequired, @@ -28,12 +30,7 @@ const windowDimensionsPropTypes = { isLargeScreenWidth: PropTypes.bool.isRequired, }; -const windowDimensionsProviderPropTypes = { - /* Actual content wrapped by this component */ - children: PropTypes.node.isRequired, -}; - -function WindowDimensionsProvider(props) { +function WindowDimensionsProvider(props: ChildrenProps) { const [windowDimension, setWindowDimension] = useState(() => { const initialDimensions = Dimensions.get('window'); return { @@ -43,7 +40,7 @@ function WindowDimensionsProvider(props) { }); useEffect(() => { - const onDimensionChange = (newDimensions) => { + const onDimensionChange = (newDimensions: {window: ScaledSize}) => { const {window} = newDimensions; setWindowDimension({ windowHeight: window.height, @@ -81,30 +78,31 @@ function WindowDimensionsProvider(props) { return {props.children}; } -WindowDimensionsProvider.propTypes = windowDimensionsProviderPropTypes; WindowDimensionsProvider.displayName = 'WindowDimensionsProvider'; /** - * @param {React.Component} WrappedComponent - * @returns {React.Component} + * @param WrappedComponent + * @returns */ -export default function withWindowDimensions(WrappedComponent) { - const WithWindowDimensions = forwardRef((props, ref) => ( - - {(windowDimensionsProps) => ( - - )} - - )); +export default function withWindowDimensions(WrappedComponent: ComponentType>) { + function WithWindowDimensions(props: Omit, ref: ForwardedRef) { + return ( + + {(windowDimensionsProps) => ( + + )} + + ); + } WithWindowDimensions.displayName = `withWindowDimensions(${getComponentDisplayName(WrappedComponent)})`; - return WithWindowDimensions; + return React.forwardRef(WithWindowDimensions); } export {WindowDimensionsProvider, windowDimensionsPropTypes}; diff --git a/src/components/withWindowDimensions/types.ts b/src/components/withWindowDimensions/types.ts new file mode 100644 index 000000000000..994c10fa4a52 --- /dev/null +++ b/src/components/withWindowDimensions/types.ts @@ -0,0 +1,30 @@ +type WindowDimensionsContextData = { + windowHeight: number; + windowWidth: number; + isExtraSmallScreenWidth: boolean; + isSmallScreenWidth: boolean; + isMediumScreenWidth: boolean; + isLargeScreenWidth: boolean; +}; + +type WindowDimensionsProps = WindowDimensionsContextData & { + // Width of the window + windowWidth: number; + + // Height of the window + windowHeight: number; + + // Is the window width extra narrow, like on a Fold mobile device? + isExtraSmallScreenWidth: boolean; + + // Is the window width narrow, like on a mobile device? + isSmallScreenWidth: boolean; + + // Is the window width medium sized, like on a tablet device? + isMediumScreenWidth: boolean; + + // Is the window width wide, like on a browser or desktop? + isLargeScreenWidth: boolean; +}; + +export type {WindowDimensionsContextData, WindowDimensionsProps}; From 8213caad111c8c59a26ccf3f92d967dc9debe2ab Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Fri, 20 Oct 2023 13:41:42 +0200 Subject: [PATCH 014/212] create types file for Modal --- src/components/Modal/types.ts | 69 +++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 src/components/Modal/types.ts diff --git a/src/components/Modal/types.ts b/src/components/Modal/types.ts new file mode 100644 index 000000000000..b17f794374e6 --- /dev/null +++ b/src/components/Modal/types.ts @@ -0,0 +1,69 @@ +import {ValueOf} from 'type-fest'; +import {ModalProps} from 'react-native-modal'; +import ChildrenProps from '../../types/utils/ChildrenProps'; +import {WindowDimensionsProps} from '../withWindowDimensions/types'; +import CONST from '../../CONST'; + +type BaseModalProps = WindowDimensionsProps & + ChildrenProps & { + /** Decides whether the modal should cover fullscreen. FullScreen modal has backdrop */ + fullscreen?: boolean; + + /** Should we close modal on outside click */ + shouldCloseOnOutsideClick?: boolean; + + /** Should we announce the Modal visibility changes? */ + shouldSetModalVisibility?: boolean; + + /** Callback method fired when the user requests to close the modal */ + onClose: () => void; + + /** State that determines whether to display the modal or not */ + isVisible: boolean; + + /** Callback method fired when the user requests to submit the modal content. */ + onSubmit?: () => void; + + /** Callback method fired when the modal is hidden */ + onModalHide?: () => void; + + /** Callback method fired when the modal is shown */ + onModalShow?: () => void; + + /** Style of modal to display */ + // type: PropTypes.oneOf(_.values(CONST.MODAL.MODAL_TYPE)), + type?: ValueOf; + + /** A react-native-animatable animation definition for the modal display animation. */ + animationIn?: Pick; + + /** A react-native-animatable animation definition for the modal hide animation. */ + animationOut?: Pick; + + /** The anchor position of a popover modal. Has no effect on other modal types. */ + popoverAnchorPosition?: { + top: number; + right: number; + bottom: number; + left: number; + }; + + /** Modal container styles */ + innerContainerStyle?: Pick; + + /** Whether the modal should go under the system statusbar */ + statusBarTranslucent?: boolean; + + /** Whether the modal should avoid the keyboard */ + avoidKeyboard?: boolean; + + /** + * Whether the modal should hide its content while animating. On iOS, set to true + * if `useNativeDriver` is also true, to avoid flashes in the UI. + * + * See: https://github.com/react-native-modal/react-native-modal/pull/116 + * */ + hideModalContentWhileAnimating?: boolean; + }; + +export default BaseModalProps; From 04476a3504a3c128241dfd38e34aee32dd03b14b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucas=20M=C3=B3rawski?= Date: Fri, 20 Oct 2023 18:32:39 +0200 Subject: [PATCH 015/212] chrome camera fix --- .../ReceiptSelector/NavigationAwareCamera.js | 48 +++++++++++++++++-- src/pages/iou/ReceiptSelector/index.js | 7 ++- 2 files changed, 48 insertions(+), 7 deletions(-) diff --git a/src/pages/iou/ReceiptSelector/NavigationAwareCamera.js b/src/pages/iou/ReceiptSelector/NavigationAwareCamera.js index e9cb81003979..2bdbbed30ede 100644 --- a/src/pages/iou/ReceiptSelector/NavigationAwareCamera.js +++ b/src/pages/iou/ReceiptSelector/NavigationAwareCamera.js @@ -1,13 +1,20 @@ -import React, {useEffect, useRef} from 'react'; +import React, {useEffect, useRef, useState} from 'react'; import Webcam from 'react-webcam'; -import {useIsFocused} from '@react-navigation/native'; +import {useIsFocused, useNavigation} from '@react-navigation/native'; import PropTypes from 'prop-types'; import {View} from 'react-native'; +import {useTabAnimation} from '@react-navigation/material-top-tabs'; const propTypes = { /* Flag to turn on/off the torch/flashlight - if available */ torchOn: PropTypes.bool, + /* The index of the tab that contains this camera */ + cameraTabIndex: PropTypes.number.isRequired, + + /* Whether we're in a tab navigator */ + isInTabNavigator: PropTypes.bool.isRequired, + /* Callback function when media stream becomes available - user granted camera permissions and camera starts to work */ onUserMedia: PropTypes.func, @@ -21,10 +28,41 @@ const defaultProps = { torchOn: false, }; +function useTabNavigatorFocus({cameraTabIndex, isInTabNavigator}) { + // Get navigation to get initial isFocused value (only needed once during init!) + const navigation = useNavigation(); + const [isTabFocused, setIsTabFocused] = useState(navigation.isFocused()); + const isPageFocused = useIsFocused(); + + // Retrieve the animation value from the tab navigator, which ranges from 0 to the total number of pages displayed. + // Even a minimal scroll towards the camera page (e.g., a value of 0.001 at start) should activate the camera for immediate responsiveness. + + // STOP!!!!!!! This is not a pattern to be followed! We are conditionally rendering this hook becase when used in the edit flow we'll never be inside a tab navigator. + // eslint-disable-next-line react-hooks/rules-of-hooks + const tabPositionAnimation = isInTabNavigator ? useTabAnimation() : null; + + useEffect(() => { + if (!isInTabNavigator) { + return; + } + + const listenerId = tabPositionAnimation.addListener(({value}) => { + // Activate camera as soon the index is animating towards the `cameraTabIndex` + setIsTabFocused(value > cameraTabIndex - 1 && value < cameraTabIndex + 1); + }); + + return () => { + tabPositionAnimation.removeListener(listenerId); + }; + }, [cameraTabIndex, tabPositionAnimation, isInTabNavigator]); + + return isTabFocused && isPageFocused; +} + // Wraps a camera that will only be active when the tab is focused or as soon as it starts to become focused. -const NavigationAwareCamera = React.forwardRef(({torchOn, onTorchAvailability, ...props}, ref) => { +const NavigationAwareCamera = React.forwardRef(({torchOn, onTorchAvailability, cameraTabIndex, isInTabNavigator, ...props}, ref) => { const trackRef = useRef(null); - const isCameraActive = useIsFocused(); + const showCamera = useTabNavigatorFocus({cameraTabIndex, isInTabNavigator}); const handleOnUserMedia = (stream) => { if (props.onUserMedia) { @@ -51,7 +89,7 @@ const NavigationAwareCamera = React.forwardRef(({torchOn, onTorchAvailability, . }); }, [torchOn]); - if (!isCameraActive) { + if (!showCamera) { return null; } return ( diff --git a/src/pages/iou/ReceiptSelector/index.js b/src/pages/iou/ReceiptSelector/index.js index ca9fe90575e7..7b7f609ea6a2 100644 --- a/src/pages/iou/ReceiptSelector/index.js +++ b/src/pages/iou/ReceiptSelector/index.js @@ -67,8 +67,9 @@ const defaultProps = { isInTabNavigator: true, }; -function ReceiptSelector({route, transactionID, iou, report}) { +function ReceiptSelector({route, transactionID, iou, report, isInTabNavigator}) { const iouType = lodashGet(route, 'params.iouType', ''); + const pageIndex = lodashGet(route, 'params.pageIndex', 1); // Grouping related states const [isAttachmentInvalid, setIsAttachmentInvalid] = useState(false); @@ -82,7 +83,7 @@ function ReceiptSelector({route, transactionID, iou, report}) { const [cameraPermissionState, setCameraPermissionState] = useState('prompt'); const [isFlashLightOn, toggleFlashlight] = useReducer((state) => !state, false); - const [isTorchAvailable, setIsTorchAvailable] = useState(true); + const [isTorchAvailable, setIsTorchAvailable] = useState(false); const cameraRef = useRef(null); const hideReciptModal = () => { @@ -201,6 +202,8 @@ function ReceiptSelector({route, transactionID, iou, report}) { torchOn={isFlashLightOn} onTorchAvailability={setIsTorchAvailable} forceScreenshotSourceSize + cameraTabIndex={pageIndex} + isInTabNavigator={isInTabNavigator} />
From c09a37cb6c80cd80470cac82d6e0388cd0dda3dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucas=20M=C3=B3rawski?= Date: Fri, 20 Oct 2023 21:01:34 +0200 Subject: [PATCH 016/212] little fix --- src/pages/iou/ReceiptSelector/NavigationAwareCamera.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/iou/ReceiptSelector/NavigationAwareCamera.js b/src/pages/iou/ReceiptSelector/NavigationAwareCamera.js index 2bdbbed30ede..7aaf5f24658d 100644 --- a/src/pages/iou/ReceiptSelector/NavigationAwareCamera.js +++ b/src/pages/iou/ReceiptSelector/NavigationAwareCamera.js @@ -31,8 +31,8 @@ const defaultProps = { function useTabNavigatorFocus({cameraTabIndex, isInTabNavigator}) { // Get navigation to get initial isFocused value (only needed once during init!) const navigation = useNavigation(); - const [isTabFocused, setIsTabFocused] = useState(navigation.isFocused()); const isPageFocused = useIsFocused(); + const [isTabFocused, setIsTabFocused] = useState(isPageFocused); // Retrieve the animation value from the tab navigator, which ranges from 0 to the total number of pages displayed. // Even a minimal scroll towards the camera page (e.g., a value of 0.001 at start) should activate the camera for immediate responsiveness. From e8664c0dc88699c336a057e23b5b4b965f6ee624 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucas=20M=C3=B3rawski?= Date: Fri, 20 Oct 2023 21:02:43 +0200 Subject: [PATCH 017/212] linting --- src/pages/iou/ReceiptSelector/NavigationAwareCamera.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/pages/iou/ReceiptSelector/NavigationAwareCamera.js b/src/pages/iou/ReceiptSelector/NavigationAwareCamera.js index 7aaf5f24658d..dc6610575820 100644 --- a/src/pages/iou/ReceiptSelector/NavigationAwareCamera.js +++ b/src/pages/iou/ReceiptSelector/NavigationAwareCamera.js @@ -1,6 +1,6 @@ import React, {useEffect, useRef, useState} from 'react'; import Webcam from 'react-webcam'; -import {useIsFocused, useNavigation} from '@react-navigation/native'; +import {useIsFocused} from '@react-navigation/native'; import PropTypes from 'prop-types'; import {View} from 'react-native'; import {useTabAnimation} from '@react-navigation/material-top-tabs'; @@ -30,7 +30,6 @@ const defaultProps = { function useTabNavigatorFocus({cameraTabIndex, isInTabNavigator}) { // Get navigation to get initial isFocused value (only needed once during init!) - const navigation = useNavigation(); const isPageFocused = useIsFocused(); const [isTabFocused, setIsTabFocused] = useState(isPageFocused); From 7307db82185f027084c84f9ba78e90f490b4997a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucas=20M=C3=B3rawski?= Date: Fri, 20 Oct 2023 21:41:51 +0200 Subject: [PATCH 018/212] default tab focused to false --- src/pages/iou/ReceiptSelector/NavigationAwareCamera.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/pages/iou/ReceiptSelector/NavigationAwareCamera.js b/src/pages/iou/ReceiptSelector/NavigationAwareCamera.js index dc6610575820..99eea31a185e 100644 --- a/src/pages/iou/ReceiptSelector/NavigationAwareCamera.js +++ b/src/pages/iou/ReceiptSelector/NavigationAwareCamera.js @@ -31,7 +31,7 @@ const defaultProps = { function useTabNavigatorFocus({cameraTabIndex, isInTabNavigator}) { // Get navigation to get initial isFocused value (only needed once during init!) const isPageFocused = useIsFocused(); - const [isTabFocused, setIsTabFocused] = useState(isPageFocused); + const [isTabFocused, setIsTabFocused] = useState(false); // Retrieve the animation value from the tab navigator, which ranges from 0 to the total number of pages displayed. // Even a minimal scroll towards the camera page (e.g., a value of 0.001 at start) should activate the camera for immediate responsiveness. @@ -84,7 +84,11 @@ const NavigationAwareCamera = React.forwardRef(({torchOn, onTorchAvailability, c } trackRef.current.applyConstraints({ - advanced: [{torch: torchOn}], + advanced: [ + { + torch: torchOn, + }, + ], }); }, [torchOn]); From 710cee10c3dbb147bf1750a2d938757de491ac0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucas=20M=C3=B3rawski?= Date: Sat, 21 Oct 2023 21:30:32 +0200 Subject: [PATCH 019/212] fixed infinite loader on scan tab refresh --- .../ReceiptSelector/NavigationAwareCamera.js | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/pages/iou/ReceiptSelector/NavigationAwareCamera.js b/src/pages/iou/ReceiptSelector/NavigationAwareCamera.js index 99eea31a185e..3f57b7a4fd21 100644 --- a/src/pages/iou/ReceiptSelector/NavigationAwareCamera.js +++ b/src/pages/iou/ReceiptSelector/NavigationAwareCamera.js @@ -41,15 +41,24 @@ function useTabNavigatorFocus({cameraTabIndex, isInTabNavigator}) { const tabPositionAnimation = isInTabNavigator ? useTabAnimation() : null; useEffect(() => { - if (!isInTabNavigator) { + if (!tabPositionAnimation) { return; } + const index = Number(cameraTabIndex); const listenerId = tabPositionAnimation.addListener(({value}) => { // Activate camera as soon the index is animating towards the `cameraTabIndex` - setIsTabFocused(value > cameraTabIndex - 1 && value < cameraTabIndex + 1); + setIsTabFocused(value > index - 1 && value < index + 1); }); + // We need to get the position animation value on component initialization to determine + // if the tab is focused or not. Since it's an Animated.Value the only synchronous way + // to retrieve the value is to use a private method. + // eslint-disable-next-line no-underscore-dangle + const initialTabPositionValue = tabPositionAnimation.__getValue(); + + setIsTabFocused(initialTabPositionValue > index - 1 && initialTabPositionValue < index + 1); + return () => { tabPositionAnimation.removeListener(listenerId); }; @@ -84,11 +93,7 @@ const NavigationAwareCamera = React.forwardRef(({torchOn, onTorchAvailability, c } trackRef.current.applyConstraints({ - advanced: [ - { - torch: torchOn, - }, - ], + advanced: [{torch: torchOn}], }); }, [torchOn]); From 9e87798a65099498e40f1b54d58e898db3b915fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucas=20M=C3=B3rawski?= Date: Sat, 21 Oct 2023 21:33:06 +0200 Subject: [PATCH 020/212] const name change --- src/pages/iou/ReceiptSelector/NavigationAwareCamera.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/pages/iou/ReceiptSelector/NavigationAwareCamera.js b/src/pages/iou/ReceiptSelector/NavigationAwareCamera.js index 3f57b7a4fd21..77ef63891f34 100644 --- a/src/pages/iou/ReceiptSelector/NavigationAwareCamera.js +++ b/src/pages/iou/ReceiptSelector/NavigationAwareCamera.js @@ -70,7 +70,10 @@ function useTabNavigatorFocus({cameraTabIndex, isInTabNavigator}) { // Wraps a camera that will only be active when the tab is focused or as soon as it starts to become focused. const NavigationAwareCamera = React.forwardRef(({torchOn, onTorchAvailability, cameraTabIndex, isInTabNavigator, ...props}, ref) => { const trackRef = useRef(null); - const showCamera = useTabNavigatorFocus({cameraTabIndex, isInTabNavigator}); + const shouldShowCamera = useTabNavigatorFocus({ + cameraTabIndex, + isInTabNavigator, + }); const handleOnUserMedia = (stream) => { if (props.onUserMedia) { @@ -97,7 +100,7 @@ const NavigationAwareCamera = React.forwardRef(({torchOn, onTorchAvailability, c }); }, [torchOn]); - if (!showCamera) { + if (!shouldShowCamera) { return null; } return ( From b068258b3f0ca69df9d0df8a7db0abcdf3eed4b9 Mon Sep 17 00:00:00 2001 From: dukenv0307 Date: Mon, 23 Oct 2023 09:49:20 +0700 Subject: [PATCH 021/212] fix: 30100 --- src/pages/workspace/WorkspaceInitialPage.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/pages/workspace/WorkspaceInitialPage.js b/src/pages/workspace/WorkspaceInitialPage.js index d275b7f0dd10..67fcfdec6328 100644 --- a/src/pages/workspace/WorkspaceInitialPage.js +++ b/src/pages/workspace/WorkspaceInitialPage.js @@ -32,6 +32,7 @@ import * as ReimbursementAccountProps from '../ReimbursementAccount/reimbursemen import * as ReportUtils from '../../libs/ReportUtils'; import withWindowDimensions from '../../components/withWindowDimensions'; import PressableWithoutFeedback from '../../components/Pressable/PressableWithoutFeedback'; +import usePrevious from '../../hooks/usePrevious'; const propTypes = { ...policyPropTypes, @@ -78,8 +79,6 @@ function WorkspaceInitialPage(props) { const policyReports = _.filter(props.reports, (report) => report && report.policyID === policy.id); Policy.deleteWorkspace(policy.id, policyReports, policy.name); setIsDeleteModalOpen(false); - // Pop the deleted workspace page before opening workspace settings. - Navigation.goBack(ROUTES.SETTINGS_WORKSPACES); }, [props.reports, policy]); useEffect(() => { @@ -193,6 +192,14 @@ function WorkspaceInitialPage(props) { }, ]; + const prevPolicy = usePrevious(policy); + + useEffect(() => { + if (PolicyUtils.isPendingDeletePolicy(policy) && !PolicyUtils.isPendingDeletePolicy(prevPolicy)) { + Navigation.goBack(ROUTES.SETTINGS_WORKSPACES); + } + }, [policy, prevPolicy]); + return ( ( Navigation.goBack(ROUTES.SETTINGS_WORKSPACES)} - shouldShow={_.isEmpty(policy) || !PolicyUtils.isPolicyAdmin(policy) || PolicyUtils.isPendingDeletePolicy(policy)} + shouldShow={_.isEmpty(policy) || !PolicyUtils.isPolicyAdmin(policy) || (PolicyUtils.isPendingDeletePolicy(policy) && PolicyUtils.isPendingDeletePolicy(prevPolicy))} subtitleKey={_.isEmpty(policy) ? undefined : 'workspace.common.notAuthorized'} > Date: Mon, 23 Oct 2023 09:34:44 +0200 Subject: [PATCH 022/212] Run Prettier --- src/pages/home/report/comment/TextCommentFragment.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/home/report/comment/TextCommentFragment.js b/src/pages/home/report/comment/TextCommentFragment.js index 4bf1b4bec86e..c176266dc12f 100644 --- a/src/pages/home/report/comment/TextCommentFragment.js +++ b/src/pages/home/report/comment/TextCommentFragment.js @@ -16,7 +16,7 @@ import convertToLTR from '../../../../libs/convertToLTR'; import CONST from '../../../../CONST'; import editedLabelStyles from '../../../../styles/editedLabelStyles'; import RenderCommentHTML from './RenderCommentHTML'; -import * as Browser from "../../../../libs/Browser"; +import * as Browser from '../../../../libs/Browser'; const propTypes = { /** The reportAction's source */ From cf613ad591c4448573fe68ab142ff4b86bfc37ea Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Mon, 23 Oct 2023 13:33:37 +0200 Subject: [PATCH 023/212] start migrating BaseModal to TypeScript --- .../Modal/{BaseModal.js => BaseModal.tsx} | 79 ++++++++----------- src/components/Modal/types.ts | 13 +++ 2 files changed, 44 insertions(+), 48 deletions(-) rename src/components/Modal/{BaseModal.js => BaseModal.tsx} (86%) diff --git a/src/components/Modal/BaseModal.js b/src/components/Modal/BaseModal.tsx similarity index 86% rename from src/components/Modal/BaseModal.js rename to src/components/Modal/BaseModal.tsx index 051c4ba3f80a..ec60b8520180 100644 --- a/src/components/Modal/BaseModal.js +++ b/src/components/Modal/BaseModal.tsx @@ -15,43 +15,34 @@ import CONST from '../../CONST'; import ComposerFocusManager from '../../libs/ComposerFocusManager'; import useNativeDriver from '../../libs/useNativeDriver'; import usePrevious from '../../hooks/usePrevious'; - -const propTypes = { - ...modalPropTypes, - - /** The ref to the modal container */ - forwardedRef: PropTypes.func, -}; - -const defaultProps = { - ...modalDefaultProps, - forwardedRef: () => {}, -}; - -function BaseModal({ - isVisible, - onClose, - shouldSetModalVisibility, - onModalHide, - type, - popoverAnchorPosition, - innerContainerStyle, - outerStyle, - onModalShow, - propagateSwipe, - fullscreen, - animationIn, - animationOut, - useNativeDriver: useNativeDriverProp, - hideModalContentWhileAnimating, - animationInTiming, - animationOutTiming, - statusBarTranslucent, - onLayout, - avoidKeyboard, - forwardedRef, - children, -}) { +import BaseModalProps from './types'; + +function BaseModal( + { + isVisible, + onClose, + shouldSetModalVisibility, + onModalHide, + type, + popoverAnchorPosition, + innerContainerStyle, + outerStyle, + onModalShow, + propagateSwipe, + fullscreen, + animationIn, + animationOut, + useNativeDriver: useNativeDriverProp, + hideModalContentWhileAnimating, + animationInTiming, + animationOutTiming, + statusBarTranslucent, + onLayout, + avoidKeyboard, + children, + }: BaseModalProps, + ref: React.ForwardedRef, +) { const {windowWidth, windowHeight, isSmallScreenWidth} = useWindowDimensions(); const safeAreaInsets = useSafeAreaInsets(); @@ -69,7 +60,7 @@ function BaseModal({ Modal.setModalVisibility(false); } if (callHideCallback) { - onModalHide(); + onModalHide?.(); } Modal.onModalDidClose(); if (!fullscreen) { @@ -207,7 +198,7 @@ function BaseModal({ > {children} @@ -215,14 +206,6 @@ function BaseModal({ ); } -BaseModal.propTypes = propTypes; -BaseModal.defaultProps = defaultProps; BaseModal.displayName = 'BaseModal'; -export default forwardRef((props, ref) => ( - -)); +export default forwardRef(BaseModal); diff --git a/src/components/Modal/types.ts b/src/components/Modal/types.ts index b17f794374e6..585df54b4b55 100644 --- a/src/components/Modal/types.ts +++ b/src/components/Modal/types.ts @@ -1,4 +1,5 @@ import {ValueOf} from 'type-fest'; +import {StyleProp, ViewStyle} from 'react-native'; import {ModalProps} from 'react-native-modal'; import ChildrenProps from '../../types/utils/ChildrenProps'; import {WindowDimensionsProps} from '../withWindowDimensions/types'; @@ -30,6 +31,8 @@ type BaseModalProps = WindowDimensionsProps & /** Callback method fired when the modal is shown */ onModalShow?: () => void; + propagateSwipe?: Pick; + /** Style of modal to display */ // type: PropTypes.oneOf(_.values(CONST.MODAL.MODAL_TYPE)), type?: ValueOf; @@ -40,6 +43,12 @@ type BaseModalProps = WindowDimensionsProps & /** A react-native-animatable animation definition for the modal hide animation. */ animationOut?: Pick; + useNativeDriver?: Pick; + + animationInTiming?: Pick; + + animationOutTiming?: Pick; + /** The anchor position of a popover modal. Has no effect on other modal types. */ popoverAnchorPosition?: { top: number; @@ -51,9 +60,13 @@ type BaseModalProps = WindowDimensionsProps & /** Modal container styles */ innerContainerStyle?: Pick; + outerStyle?: StyleProp; + /** Whether the modal should go under the system statusbar */ statusBarTranslucent?: boolean; + onLayout: Pick; + /** Whether the modal should avoid the keyboard */ avoidKeyboard?: boolean; From 21bf4259317f9af68cb9d7c8b812187bfdc3e043 Mon Sep 17 00:00:00 2001 From: Viktoryia Kliushun Date: Mon, 23 Oct 2023 14:53:55 +0200 Subject: [PATCH 024/212] Fix ts error --- src/libs/ReportActionsUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/ReportActionsUtils.ts b/src/libs/ReportActionsUtils.ts index d016e220e147..208e7d4f062b 100644 --- a/src/libs/ReportActionsUtils.ts +++ b/src/libs/ReportActionsUtils.ts @@ -362,7 +362,7 @@ function replaceBaseURL(reportAction: ReportAction): ReportAction { if (!updatedReportAction.message) { return updatedReportAction; } - updatedReportAction.message[0].html = reportAction.message[0].html.replace('%baseURL', environmentURL); + updatedReportAction.message[0].html = reportAction.message[0].html?.replace('%baseURL', environmentURL); return updatedReportAction; } From b3f0a85f2bc656d730fccb325626d58e24a65e8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucas=20M=C3=B3rawski?= Date: Mon, 23 Oct 2023 19:47:34 +0200 Subject: [PATCH 025/212] delayed show camera state --- src/pages/iou/ReceiptSelector/NavigationAwareCamera.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/pages/iou/ReceiptSelector/NavigationAwareCamera.js b/src/pages/iou/ReceiptSelector/NavigationAwareCamera.js index 77ef63891f34..c95ce48a61b8 100644 --- a/src/pages/iou/ReceiptSelector/NavigationAwareCamera.js +++ b/src/pages/iou/ReceiptSelector/NavigationAwareCamera.js @@ -48,7 +48,9 @@ function useTabNavigatorFocus({cameraTabIndex, isInTabNavigator}) { const listenerId = tabPositionAnimation.addListener(({value}) => { // Activate camera as soon the index is animating towards the `cameraTabIndex` - setIsTabFocused(value > index - 1 && value < index + 1); + requestAnimationFrame(() => { + setIsTabFocused(value > index - 1 && value < index + 1); + }); }); // We need to get the position animation value on component initialization to determine @@ -57,7 +59,9 @@ function useTabNavigatorFocus({cameraTabIndex, isInTabNavigator}) { // eslint-disable-next-line no-underscore-dangle const initialTabPositionValue = tabPositionAnimation.__getValue(); - setIsTabFocused(initialTabPositionValue > index - 1 && initialTabPositionValue < index + 1); + requestAnimationFrame(() => { + setIsTabFocused(initialTabPositionValue > index - 1 && initialTabPositionValue < index + 1); + }); return () => { tabPositionAnimation.removeListener(listenerId); From 686118c0b5b956677d378a3bd6bacc8cae370832 Mon Sep 17 00:00:00 2001 From: Jakub Trzebiatowski Date: Tue, 24 Oct 2023 10:57:00 +0200 Subject: [PATCH 026/212] ReportActionItemMessage: Remove a duplicated passed property --- src/pages/home/report/ReportActionItemMessage.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/home/report/ReportActionItemMessage.js b/src/pages/home/report/ReportActionItemMessage.js index 44c314934fba..4ecb39efc986 100644 --- a/src/pages/home/report/ReportActionItemMessage.js +++ b/src/pages/home/report/ReportActionItemMessage.js @@ -59,7 +59,6 @@ function ReportActionItemMessage(props) { pendingAction={props.action.pendingAction} source={lodashGet(props.action, 'originalMessage.source')} accountID={props.action.actorAccountID} - displayAsGroup={props.displayAsGroup} style={props.style} displayAsGroup={props.displayAsGroup} /> From 408ef25d1139445bc451b3f0f809173f95ec2379 Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Tue, 24 Oct 2023 13:53:15 +0200 Subject: [PATCH 027/212] add missing prop types --- src/components/Modal/types.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/Modal/types.ts b/src/components/Modal/types.ts index 585df54b4b55..03c6cee89fed 100644 --- a/src/components/Modal/types.ts +++ b/src/components/Modal/types.ts @@ -1,5 +1,5 @@ import {ValueOf} from 'type-fest'; -import {StyleProp, ViewStyle} from 'react-native'; +import {ViewStyle} from 'react-native'; import {ModalProps} from 'react-native-modal'; import ChildrenProps from '../../types/utils/ChildrenProps'; import {WindowDimensionsProps} from '../withWindowDimensions/types'; @@ -51,16 +51,16 @@ type BaseModalProps = WindowDimensionsProps & /** The anchor position of a popover modal. Has no effect on other modal types. */ popoverAnchorPosition?: { - top: number; - right: number; - bottom: number; - left: number; + top?: number; + right?: number; + bottom?: number; + left?: number; }; /** Modal container styles */ innerContainerStyle?: Pick; - outerStyle?: StyleProp; + outerStyle?: ViewStyle; /** Whether the modal should go under the system statusbar */ statusBarTranslucent?: boolean; From 1c1d092c1737c65138ef423d9e9e0dd3ec885513 Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Tue, 24 Oct 2023 16:17:20 +0200 Subject: [PATCH 028/212] update types, update helper function types --- src/components/Modal/types.ts | 25 ++++--------------------- src/libs/actions/Modal.ts | 4 ++-- src/styles/getModalStyles.ts | 4 +--- 3 files changed, 7 insertions(+), 26 deletions(-) diff --git a/src/components/Modal/types.ts b/src/components/Modal/types.ts index 03c6cee89fed..b1dfdaff640d 100644 --- a/src/components/Modal/types.ts +++ b/src/components/Modal/types.ts @@ -1,12 +1,11 @@ import {ValueOf} from 'type-fest'; import {ViewStyle} from 'react-native'; import {ModalProps} from 'react-native-modal'; -import ChildrenProps from '../../types/utils/ChildrenProps'; import {WindowDimensionsProps} from '../withWindowDimensions/types'; import CONST from '../../CONST'; type BaseModalProps = WindowDimensionsProps & - ChildrenProps & { + ModalProps & { /** Decides whether the modal should cover fullscreen. FullScreen modal has backdrop */ fullscreen?: boolean; @@ -31,24 +30,10 @@ type BaseModalProps = WindowDimensionsProps & /** Callback method fired when the modal is shown */ onModalShow?: () => void; - propagateSwipe?: Pick; - /** Style of modal to display */ // type: PropTypes.oneOf(_.values(CONST.MODAL.MODAL_TYPE)), type?: ValueOf; - /** A react-native-animatable animation definition for the modal display animation. */ - animationIn?: Pick; - - /** A react-native-animatable animation definition for the modal hide animation. */ - animationOut?: Pick; - - useNativeDriver?: Pick; - - animationInTiming?: Pick; - - animationOutTiming?: Pick; - /** The anchor position of a popover modal. Has no effect on other modal types. */ popoverAnchorPosition?: { top?: number; @@ -57,19 +42,17 @@ type BaseModalProps = WindowDimensionsProps & left?: number; }; - /** Modal container styles */ - innerContainerStyle?: Pick; - outerStyle?: ViewStyle; /** Whether the modal should go under the system statusbar */ statusBarTranslucent?: boolean; - onLayout: Pick; - /** Whether the modal should avoid the keyboard */ avoidKeyboard?: boolean; + /** Modal container styles */ + innerContainerStyle?: ViewStyle; + /** * Whether the modal should hide its content while animating. On iOS, set to true * if `useNativeDriver` is also true, to avoid flashes in the UI. diff --git a/src/libs/actions/Modal.ts b/src/libs/actions/Modal.ts index ff09731f59a7..7a443b94354f 100644 --- a/src/libs/actions/Modal.ts +++ b/src/libs/actions/Modal.ts @@ -1,13 +1,13 @@ import Onyx from 'react-native-onyx'; import ONYXKEYS from '../../ONYXKEYS'; -let closeModal: (isNavigating: boolean) => void; +let closeModal: ((isNavigating: boolean) => void) | null; let onModalClose: null | (() => void); /** * Allows other parts of the app to call modal close function */ -function setCloseModal(onClose: () => void) { +function setCloseModal(onClose: (() => void) | null) { closeModal = onClose; } diff --git a/src/styles/getModalStyles.ts b/src/styles/getModalStyles.ts index d52d29568c2d..e318e7b989b8 100644 --- a/src/styles/getModalStyles.ts +++ b/src/styles/getModalStyles.ts @@ -21,8 +21,6 @@ type WindowDimensions = { windowWidth: number; windowHeight: number; isSmallScreenWidth: boolean; - isMediumScreenWidth: boolean; - isLargeScreenWidth: boolean; }; type GetModalStyles = { @@ -39,7 +37,7 @@ type GetModalStyles = { }; export default function getModalStyles( - type: ModalType, + type: ModalType | undefined, windowDimensions: WindowDimensions, popoverAnchorPosition: ViewStyle = {}, innerContainerStyle: ViewStyle = {}, From 118415e0d938ad828401f6a5052beba72851b018 Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Tue, 24 Oct 2023 16:17:42 +0200 Subject: [PATCH 029/212] reorganise types in StyleUtils --- src/styles/StyleUtils.ts | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/src/styles/StyleUtils.ts b/src/styles/StyleUtils.ts index 62da2bf3be4b..68a2e61529bc 100644 --- a/src/styles/StyleUtils.ts +++ b/src/styles/StyleUtils.ts @@ -56,10 +56,10 @@ type ModalPaddingStylesParams = { safeAreaPaddingBottom: number; safeAreaPaddingLeft: number; safeAreaPaddingRight: number; - modalContainerStyleMarginTop: number; - modalContainerStyleMarginBottom: number; - modalContainerStylePaddingTop: number; - modalContainerStylePaddingBottom: number; + modalContainerStyleMarginTop: DimensionValue | undefined; + modalContainerStyleMarginBottom: DimensionValue | undefined; + modalContainerStylePaddingTop: DimensionValue | undefined; + modalContainerStylePaddingBottom: DimensionValue | undefined; insets: EdgeInsets; }; @@ -287,12 +287,19 @@ function getEReceiptColorStyles(colorCode: EReceiptColorName): EreceiptColorStyl return eReceiptColorStyles[colorCode]; } +type SafeAreaPadding = { + paddingTop: number; + paddingBottom: number; + paddingLeft: number; + paddingRight: number; +}; + /** * Takes safe area insets and returns padding to use for a View */ -function getSafeAreaPadding(insets?: EdgeInsets, insetsPercentage: number = variables.safeInsertPercentage): ViewStyle { +function getSafeAreaPadding(insets?: EdgeInsets, insetsPercentage: number = variables.safeInsertPercentage): SafeAreaPadding { return { - paddingTop: insets?.top, + paddingTop: insets?.top ?? 0, paddingBottom: (insets?.bottom ?? 0) * insetsPercentage, paddingLeft: (insets?.left ?? 0) * insetsPercentage, paddingRight: (insets?.right ?? 0) * insetsPercentage, @@ -568,6 +575,14 @@ function getWidthAndHeightStyle(width: number, height?: number): ViewStyle { }; } +function getCombinedSpacing(modalContainerValue: DimensionValue | undefined, safeAreaValue: number, shouldAddSafeAreaValue: boolean): number | DimensionValue | undefined { + if (typeof modalContainerValue === 'number') { + return (modalContainerValue ?? 0) + (shouldAddSafeAreaValue ? safeAreaValue : 0); + } + + return modalContainerValue; +} + function getModalPaddingStyles({ shouldAddBottomSafeAreaMargin, shouldAddTopSafeAreaMargin, @@ -585,12 +600,12 @@ function getModalPaddingStyles({ }: ModalPaddingStylesParams): ViewStyle { // use fallback value for safeAreaPaddingBottom to keep padding bottom consistent with padding top. // More info: issue #17376 - const safeAreaPaddingBottomWithFallback = insets.bottom === 0 ? modalContainerStylePaddingTop ?? 0 : safeAreaPaddingBottom; + const safeAreaPaddingBottomWithFallback = insets.bottom === 0 && typeof modalContainerStylePaddingTop === 'number' ? modalContainerStylePaddingTop ?? 0 : safeAreaPaddingBottom; return { - marginTop: (modalContainerStyleMarginTop ?? 0) + (shouldAddTopSafeAreaMargin ? safeAreaPaddingTop : 0), - marginBottom: (modalContainerStyleMarginBottom ?? 0) + (shouldAddBottomSafeAreaMargin ? safeAreaPaddingBottomWithFallback : 0), - paddingTop: shouldAddTopSafeAreaPadding ? (modalContainerStylePaddingTop ?? 0) + safeAreaPaddingTop : modalContainerStylePaddingTop ?? 0, - paddingBottom: shouldAddBottomSafeAreaPadding ? (modalContainerStylePaddingBottom ?? 0) + safeAreaPaddingBottomWithFallback : modalContainerStylePaddingBottom ?? 0, + marginTop: getCombinedSpacing(modalContainerStyleMarginTop, safeAreaPaddingTop, shouldAddTopSafeAreaMargin), + marginBottom: getCombinedSpacing(modalContainerStyleMarginBottom, safeAreaPaddingBottomWithFallback, shouldAddBottomSafeAreaMargin), + paddingTop: getCombinedSpacing(modalContainerStylePaddingTop, safeAreaPaddingTop, shouldAddTopSafeAreaPadding), + paddingBottom: getCombinedSpacing(modalContainerStylePaddingBottom, safeAreaPaddingBottomWithFallback, shouldAddBottomSafeAreaPadding), paddingLeft: safeAreaPaddingLeft ?? 0, paddingRight: safeAreaPaddingRight ?? 0, }; From 4c18fc0ba771b5c5f2995b97c24c9d388ae17b34 Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Tue, 24 Oct 2023 16:18:01 +0200 Subject: [PATCH 030/212] fix typings in BaseModal --- src/components/Modal/BaseModal.tsx | 32 ++++++++++++------------------ 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/src/components/Modal/BaseModal.tsx b/src/components/Modal/BaseModal.tsx index ec60b8520180..86fbbf896ac1 100644 --- a/src/components/Modal/BaseModal.tsx +++ b/src/components/Modal/BaseModal.tsx @@ -1,17 +1,14 @@ import React, {forwardRef, useCallback, useEffect, useMemo, useRef} from 'react'; import {View} from 'react-native'; -import PropTypes from 'prop-types'; import ReactNativeModal from 'react-native-modal'; import {useSafeAreaInsets} from 'react-native-safe-area-context'; import styles from '../../styles/styles'; import * as Modal from '../../libs/actions/Modal'; import * as StyleUtils from '../../styles/StyleUtils'; import themeColors from '../../styles/themes/default'; -import {propTypes as modalPropTypes, defaultProps as modalDefaultProps} from './modalPropTypes'; import getModalStyles from '../../styles/getModalStyles'; import useWindowDimensions from '../../hooks/useWindowDimensions'; import variables from '../../styles/variables'; -import CONST from '../../CONST'; import ComposerFocusManager from '../../libs/ComposerFocusManager'; import useNativeDriver from '../../libs/useNativeDriver'; import usePrevious from '../../hooks/usePrevious'; @@ -21,24 +18,24 @@ function BaseModal( { isVisible, onClose, - shouldSetModalVisibility, - onModalHide, + shouldSetModalVisibility = true, + onModalHide = () => {}, type, - popoverAnchorPosition, - innerContainerStyle, + popoverAnchorPosition = {}, + innerContainerStyle = {}, outerStyle, - onModalShow, + onModalShow = () => {}, propagateSwipe, - fullscreen, + fullscreen = true, animationIn, animationOut, useNativeDriver: useNativeDriverProp, - hideModalContentWhileAnimating, + hideModalContentWhileAnimating = false, animationInTiming, animationOutTiming, - statusBarTranslucent, + statusBarTranslucent = true, onLayout, - avoidKeyboard, + avoidKeyboard = false, children, }: BaseModalProps, ref: React.ForwardedRef, @@ -101,13 +98,10 @@ function BaseModal( if (shouldSetModalVisibility) { Modal.setModalVisibility(true); } - onModalShow(); + onModalShow?.(); }; - const handleBackdropPress = (e) => { - if (e && e.key === CONST.KEYBOARD_SHORTCUTS.ENTER.shortcutKey) { - return; - } + const handleBackdropPress = () => { onClose(); }; @@ -186,8 +180,8 @@ function BaseModal( style={modalStyle} deviceHeight={windowHeight} deviceWidth={windowWidth} - animationIn={animationIn || modalStyleAnimationIn} - animationOut={animationOut || modalStyleAnimationOut} + animationIn={animationIn ?? modalStyleAnimationIn} + animationOut={animationOut ?? modalStyleAnimationOut} useNativeDriver={useNativeDriverProp && useNativeDriver} hideModalContentWhileAnimating={hideModalContentWhileAnimating} animationInTiming={animationInTiming} From c016d8436219e39f8fd6da99d0544271c2fa393c Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Wed, 25 Oct 2023 12:27:07 +0200 Subject: [PATCH 031/212] migrate index.web.js to TypeScript --- .../Modal/{index.web.js => index.web.tsx} | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) rename src/components/Modal/{index.web.js => index.web.tsx} (63%) diff --git a/src/components/Modal/index.web.js b/src/components/Modal/index.web.tsx similarity index 63% rename from src/components/Modal/index.web.js rename to src/components/Modal/index.web.tsx index 065b3a9f210f..d5ed7e6369ba 100644 --- a/src/components/Modal/index.web.js +++ b/src/components/Modal/index.web.tsx @@ -1,14 +1,14 @@ import React, {useState} from 'react'; import withWindowDimensions from '../withWindowDimensions'; import BaseModal from './BaseModal'; -import {propTypes, defaultProps} from './modalPropTypes'; import * as StyleUtils from '../../styles/StyleUtils'; import themeColors from '../../styles/themes/default'; import StatusBar from '../../libs/StatusBar'; import CONST from '../../CONST'; +import BaseModalProps from './types'; -function Modal(props) { - const [previousStatusBarColor, setPreviousStatusBarColor] = useState(); +function Modal(props: BaseModalProps) { + const [previousStatusBarColor, setPreviousStatusBarColor] = useState(); const setStatusBarColor = (color = themeColors.appBG) => { if (!props.fullscreen) { @@ -25,12 +25,15 @@ function Modal(props) { const showModal = () => { const statusBarColor = StatusBar.getBackgroundColor(); - const isFullScreenModal = - props.type === CONST.MODAL.MODAL_TYPE.CENTERED || props.type === CONST.MODAL.MODAL_TYPE.CENTERED_UNSWIPEABLE || props.type === CONST.MODAL.MODAL_TYPE.RIGHT_DOCKED; - setPreviousStatusBarColor(statusBarColor); - // If it is a full screen modal then match it with appBG, otherwise we use the backdrop color - setStatusBarColor(isFullScreenModal ? themeColors.appBG : StyleUtils.getThemeBackgroundColor(statusBarColor)); - props.onModalShow(); + + if (statusBarColor) { + const isFullScreenModal = + props.type === CONST.MODAL.MODAL_TYPE.CENTERED || props.type === CONST.MODAL.MODAL_TYPE.CENTERED_UNSWIPEABLE || props.type === CONST.MODAL.MODAL_TYPE.RIGHT_DOCKED; + setPreviousStatusBarColor(statusBarColor); + // If it is a full screen modal then match it with appBG, otherwise we use the backdrop color + setStatusBarColor(isFullScreenModal ? themeColors.appBG : StyleUtils.getThemeBackgroundColor(statusBarColor)); + props.onModalShow(); + } }; return ( @@ -46,7 +49,5 @@ function Modal(props) { ); } -Modal.propTypes = propTypes; -Modal.defaultProps = defaultProps; Modal.displayName = 'Modal'; export default withWindowDimensions(Modal); From 5f3968d44bccd743a1b4739484771de7a52a0c5b Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Wed, 25 Oct 2023 12:35:39 +0200 Subject: [PATCH 032/212] migrate index.ios.js to TypeScript --- src/components/Modal/{index.ios.js => index.ios.tsx} | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) rename src/components/Modal/{index.ios.js => index.ios.tsx} (72%) diff --git a/src/components/Modal/index.ios.js b/src/components/Modal/index.ios.tsx similarity index 72% rename from src/components/Modal/index.ios.js rename to src/components/Modal/index.ios.tsx index d8206d12532d..8b82a67d8601 100644 --- a/src/components/Modal/index.ios.js +++ b/src/components/Modal/index.ios.tsx @@ -1,9 +1,9 @@ import React from 'react'; import withWindowDimensions from '../withWindowDimensions'; import BaseModal from './BaseModal'; -import {propTypes, defaultProps} from './modalPropTypes'; +import BaseModalProps from './types'; -function Modal(props) { +function Modal(props: BaseModalProps) { return ( Date: Wed, 25 Oct 2023 13:15:23 +0200 Subject: [PATCH 033/212] migrate index.android.js to TypeScript --- .../Modal/{index.android.js => index.android.tsx} | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) rename src/components/Modal/{index.android.js => index.android.tsx} (86%) diff --git a/src/components/Modal/index.android.js b/src/components/Modal/index.android.tsx similarity index 86% rename from src/components/Modal/index.android.js rename to src/components/Modal/index.android.tsx index b5f11a02650a..cf61452b7780 100644 --- a/src/components/Modal/index.android.js +++ b/src/components/Modal/index.android.tsx @@ -2,8 +2,8 @@ import React from 'react'; import {AppState} from 'react-native'; import withWindowDimensions from '../withWindowDimensions'; import BaseModal from './BaseModal'; -import {propTypes, defaultProps} from './modalPropTypes'; import ComposerFocusManager from '../../libs/ComposerFocusManager'; +import BaseModalProps from './types'; AppState.addEventListener('focus', () => { ComposerFocusManager.setReadyToFocus(); @@ -15,19 +15,17 @@ AppState.addEventListener('blur', () => { // Only want to use useNativeDriver on Android. It has strange flashes issue on IOS // https://github.com/react-native-modal/react-native-modal#the-modal-flashes-in-a-weird-way-when-animating -function Modal(props) { +function Modal(props: BaseModalProps) { return ( {props.children} ); } -Modal.propTypes = propTypes; -Modal.defaultProps = defaultProps; Modal.displayName = 'Modal'; export default withWindowDimensions(Modal); From a4378183f74b13825f67968607b3314f62c6bac5 Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Wed, 25 Oct 2023 14:47:54 +0200 Subject: [PATCH 034/212] fix spacing calculation --- src/styles/StyleUtils.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/styles/StyleUtils.ts b/src/styles/StyleUtils.ts index 68a2e61529bc..8d42a3810469 100644 --- a/src/styles/StyleUtils.ts +++ b/src/styles/StyleUtils.ts @@ -575,8 +575,16 @@ function getWidthAndHeightStyle(width: number, height?: number): ViewStyle { }; } +/** + * Combine margin/padding with safe area inset + * + * @param modalContainerValue - margin or padding value + * @param safeAreaValue - safe area inset + * @param shouldAddSafeAreaValue - indicator whether safe area inset should be applied + */ function getCombinedSpacing(modalContainerValue: DimensionValue | undefined, safeAreaValue: number, shouldAddSafeAreaValue: boolean): number | DimensionValue | undefined { - if (typeof modalContainerValue === 'number') { + // modalContainerValue can only be added to safe area inset if it's a number, otherwise it's returned as is + if (typeof modalContainerValue === 'number' || !modalContainerValue) { return (modalContainerValue ?? 0) + (shouldAddSafeAreaValue ? safeAreaValue : 0); } From 3084c1f9b6afc000d004d3fca0c605f21983628f Mon Sep 17 00:00:00 2001 From: David Cardoza Date: Thu, 26 Oct 2023 00:47:10 +0800 Subject: [PATCH 035/212] Rename How-to-Join-the-ExpensifyApproved!-Partner-Program to How-to-Join-the-ExpensifyApproved!-Partner-Program.md --- ...gram => How-to-Join-the-ExpensifyApproved!-Partner-Program.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/articles/expensify-classic/expensify-partner-program/{How-to-Join-the-ExpensifyApproved!-Partner-Program => How-to-Join-the-ExpensifyApproved!-Partner-Program.md} (100%) diff --git a/docs/articles/expensify-classic/expensify-partner-program/How-to-Join-the-ExpensifyApproved!-Partner-Program b/docs/articles/expensify-classic/expensify-partner-program/How-to-Join-the-ExpensifyApproved!-Partner-Program.md similarity index 100% rename from docs/articles/expensify-classic/expensify-partner-program/How-to-Join-the-ExpensifyApproved!-Partner-Program rename to docs/articles/expensify-classic/expensify-partner-program/How-to-Join-the-ExpensifyApproved!-Partner-Program.md From 73859687f0883648cfa0ac1b68f6f6508f02bddb Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Thu, 26 Oct 2023 10:20:43 +0200 Subject: [PATCH 036/212] apply finishing touches --- src/components/Modal/BaseModal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Modal/BaseModal.tsx b/src/components/Modal/BaseModal.tsx index 9074d9d9e53e..d845beb2e3a1 100644 --- a/src/components/Modal/BaseModal.tsx +++ b/src/components/Modal/BaseModal.tsx @@ -49,7 +49,7 @@ function BaseModal( /** * Hides modal - * @param {Boolean} [callHideCallback=true] Should we call the onModalHide callback + * @param callHideCallback - Should we call the onModalHide callback */ const hideModal = useCallback( (callHideCallback = true) => { From c26a716da26ed01036bd370c4a2a55b75791f9e4 Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Thu, 26 Oct 2023 10:38:26 +0200 Subject: [PATCH 037/212] remove unnecessary conditional function calls --- src/components/Modal/BaseModal.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Modal/BaseModal.tsx b/src/components/Modal/BaseModal.tsx index d845beb2e3a1..4c6532d16fb8 100644 --- a/src/components/Modal/BaseModal.tsx +++ b/src/components/Modal/BaseModal.tsx @@ -57,7 +57,7 @@ function BaseModal( Modal.setModalVisibility(false); } if (callHideCallback) { - onModalHide?.(); + onModalHide(); } Modal.onModalDidClose(); if (!fullscreen) { @@ -98,7 +98,7 @@ function BaseModal( if (shouldSetModalVisibility) { Modal.setModalVisibility(true); } - onModalShow?.(); + onModalShow(); }; const handleBackdropPress = () => { From a1adc3766af1546c69c0bb6ad1f387eb97abb5dc Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Thu, 26 Oct 2023 10:40:44 +0200 Subject: [PATCH 038/212] create common NewDimensions type --- src/components/withWindowDimensions/index.native.tsx | 6 +++--- src/components/withWindowDimensions/index.tsx | 6 +++--- src/components/withWindowDimensions/types.ts | 6 +++++- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/components/withWindowDimensions/index.native.tsx b/src/components/withWindowDimensions/index.native.tsx index 889397f2bab6..f4ce0707c83e 100644 --- a/src/components/withWindowDimensions/index.native.tsx +++ b/src/components/withWindowDimensions/index.native.tsx @@ -1,11 +1,11 @@ import React, {createContext, useState, useEffect, useMemo, ComponentType, RefAttributes, ForwardedRef} from 'react'; import PropTypes from 'prop-types'; -import {Dimensions, ScaledSize} from 'react-native'; +import {Dimensions} from 'react-native'; import {useSafeAreaInsets} from 'react-native-safe-area-context'; import getComponentDisplayName from '../../libs/getComponentDisplayName'; import variables from '../../styles/variables'; import getWindowHeightAdjustment from '../../libs/getWindowHeightAdjustment'; -import {WindowDimensionsContextData, WindowDimensionsProps} from './types'; +import {NewDimensions, WindowDimensionsContextData, WindowDimensionsProps} from './types'; import ChildrenProps from '../../types/utils/ChildrenProps'; const WindowDimensionsContext = createContext(null); @@ -39,7 +39,7 @@ function WindowDimensionsProvider(props: ChildrenProps) { }); useEffect(() => { - const onDimensionChange = (newDimensions: {window: ScaledSize}) => { + const onDimensionChange = (newDimensions: NewDimensions) => { const {window} = newDimensions; setWindowDimension({ windowHeight: window.height, diff --git a/src/components/withWindowDimensions/index.tsx b/src/components/withWindowDimensions/index.tsx index 6a5dfadc6a49..ab5c4d006751 100644 --- a/src/components/withWindowDimensions/index.tsx +++ b/src/components/withWindowDimensions/index.tsx @@ -1,13 +1,13 @@ import React, {createContext, useState, useEffect, useMemo, RefAttributes, ComponentType, ForwardedRef} from 'react'; import PropTypes from 'prop-types'; import lodashDebounce from 'lodash/debounce'; -import {Dimensions, ScaledSize} from 'react-native'; +import {Dimensions} from 'react-native'; import {useSafeAreaInsets} from 'react-native-safe-area-context'; import getComponentDisplayName from '../../libs/getComponentDisplayName'; import variables from '../../styles/variables'; import getWindowHeightAdjustment from '../../libs/getWindowHeightAdjustment'; import ChildrenProps from '../../types/utils/ChildrenProps'; -import {WindowDimensionsContextData, WindowDimensionsProps} from './types'; +import {NewDimensions, WindowDimensionsContextData, WindowDimensionsProps} from './types'; const WindowDimensionsContext = createContext(null); const windowDimensionsPropTypes = { @@ -40,7 +40,7 @@ function WindowDimensionsProvider(props: ChildrenProps) { }); useEffect(() => { - const onDimensionChange = (newDimensions: {window: ScaledSize}) => { + const onDimensionChange = (newDimensions: NewDimensions) => { const {window} = newDimensions; setWindowDimension({ windowHeight: window.height, diff --git a/src/components/withWindowDimensions/types.ts b/src/components/withWindowDimensions/types.ts index 994c10fa4a52..514c86616b87 100644 --- a/src/components/withWindowDimensions/types.ts +++ b/src/components/withWindowDimensions/types.ts @@ -1,3 +1,5 @@ +import {ScaledSize} from 'react-native'; + type WindowDimensionsContextData = { windowHeight: number; windowWidth: number; @@ -27,4 +29,6 @@ type WindowDimensionsProps = WindowDimensionsContextData & { isLargeScreenWidth: boolean; }; -export type {WindowDimensionsContextData, WindowDimensionsProps}; +type NewDimensions = {window: ScaledSize}; + +export type {WindowDimensionsContextData, WindowDimensionsProps, NewDimensions}; From bc5c041c7f016a46ff02a207bd297697ca4d822d Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Thu, 26 Oct 2023 11:20:03 +0200 Subject: [PATCH 039/212] change index.web.tsx to index.tsx to fix linting --- src/components/Modal/{index.web.tsx => index.tsx} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/components/Modal/{index.web.tsx => index.tsx} (100%) diff --git a/src/components/Modal/index.web.tsx b/src/components/Modal/index.tsx similarity index 100% rename from src/components/Modal/index.web.tsx rename to src/components/Modal/index.tsx From ac60a8e5c5eb5161e32ec6a3e8024c5cbb36b5d0 Mon Sep 17 00:00:00 2001 From: Jakub Trzebiatowski Date: Thu, 26 Oct 2023 13:42:14 +0200 Subject: [PATCH 040/212] Pass a missing displayAsGroup property --- src/pages/home/report/ReportActionItemSingle.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pages/home/report/ReportActionItemSingle.js b/src/pages/home/report/ReportActionItemSingle.js index fc189a3aef36..c35cadc805e6 100644 --- a/src/pages/home/report/ReportActionItemSingle.js +++ b/src/pages/home/report/ReportActionItemSingle.js @@ -240,6 +240,7 @@ function ReportActionItemSingle(props) { delegateAccountID={props.action.delegateAccountID} isSingleLine actorIcon={icon} + displayAsGroup={false} /> ))} From 673d1207fb1653c823fdc76edfd5d9f86cad7e1d Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Thu, 26 Oct 2023 14:14:21 +0200 Subject: [PATCH 041/212] add event to backdrop press handler --- src/components/Modal/BaseModal.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/components/Modal/BaseModal.tsx b/src/components/Modal/BaseModal.tsx index 4c6532d16fb8..7a4747718fb9 100644 --- a/src/components/Modal/BaseModal.tsx +++ b/src/components/Modal/BaseModal.tsx @@ -13,6 +13,7 @@ import ComposerFocusManager from '../../libs/ComposerFocusManager'; import useNativeDriver from '../../libs/useNativeDriver'; import usePrevious from '../../hooks/usePrevious'; import BaseModalProps from './types'; +import CONST from '../../CONST'; function BaseModal( { @@ -101,7 +102,11 @@ function BaseModal( onModalShow(); }; - const handleBackdropPress = () => { + const handleBackdropPress = (e?: KeyboardEvent) => { + if (e?.key === CONST.KEYBOARD_SHORTCUTS.ENTER.shortcutKey) { + return; + } + onClose(); }; From 2d7d45bf6e5928b8490596888255b8e8f97597e8 Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Thu, 26 Oct 2023 14:33:17 +0200 Subject: [PATCH 042/212] apply changes based on feedback from code review --- src/components/Modal/index.tsx | 8 +++++--- src/components/Modal/types.ts | 5 +++-- src/components/withWindowDimensions/index.native.tsx | 4 ---- src/components/withWindowDimensions/index.tsx | 4 ---- 4 files changed, 8 insertions(+), 13 deletions(-) diff --git a/src/components/Modal/index.tsx b/src/components/Modal/index.tsx index d5ed7e6369ba..82f2aac9bbc2 100644 --- a/src/components/Modal/index.tsx +++ b/src/components/Modal/index.tsx @@ -26,14 +26,16 @@ function Modal(props: BaseModalProps) { const showModal = () => { const statusBarColor = StatusBar.getBackgroundColor(); + const isFullScreenModal = + props.type === CONST.MODAL.MODAL_TYPE.CENTERED || props.type === CONST.MODAL.MODAL_TYPE.CENTERED_UNSWIPEABLE || props.type === CONST.MODAL.MODAL_TYPE.RIGHT_DOCKED; + if (statusBarColor) { - const isFullScreenModal = - props.type === CONST.MODAL.MODAL_TYPE.CENTERED || props.type === CONST.MODAL.MODAL_TYPE.CENTERED_UNSWIPEABLE || props.type === CONST.MODAL.MODAL_TYPE.RIGHT_DOCKED; setPreviousStatusBarColor(statusBarColor); // If it is a full screen modal then match it with appBG, otherwise we use the backdrop color setStatusBarColor(isFullScreenModal ? themeColors.appBG : StyleUtils.getThemeBackgroundColor(statusBarColor)); - props.onModalShow(); } + + props.onModalShow(); }; return ( diff --git a/src/components/Modal/types.ts b/src/components/Modal/types.ts index b1dfdaff640d..36ce5fa28781 100644 --- a/src/components/Modal/types.ts +++ b/src/components/Modal/types.ts @@ -4,6 +4,8 @@ import {ModalProps} from 'react-native-modal'; import {WindowDimensionsProps} from '../withWindowDimensions/types'; import CONST from '../../CONST'; +type ModalVariant = ValueOf; + type BaseModalProps = WindowDimensionsProps & ModalProps & { /** Decides whether the modal should cover fullscreen. FullScreen modal has backdrop */ @@ -31,8 +33,7 @@ type BaseModalProps = WindowDimensionsProps & onModalShow?: () => void; /** Style of modal to display */ - // type: PropTypes.oneOf(_.values(CONST.MODAL.MODAL_TYPE)), - type?: ValueOf; + type?: ModalVariant; /** The anchor position of a popover modal. Has no effect on other modal types. */ popoverAnchorPosition?: { diff --git a/src/components/withWindowDimensions/index.native.tsx b/src/components/withWindowDimensions/index.native.tsx index f4ce0707c83e..611efa60ee79 100644 --- a/src/components/withWindowDimensions/index.native.tsx +++ b/src/components/withWindowDimensions/index.native.tsx @@ -74,10 +74,6 @@ function WindowDimensionsProvider(props: ChildrenProps) { WindowDimensionsProvider.displayName = 'WindowDimensionsProvider'; -/** - * @param WrappedComponent - * @returns - */ export default function withWindowDimensions(WrappedComponent: ComponentType>) { function WithWindowDimensions(props: Omit, ref: ForwardedRef) { return ( diff --git a/src/components/withWindowDimensions/index.tsx b/src/components/withWindowDimensions/index.tsx index ab5c4d006751..d952f036fba0 100644 --- a/src/components/withWindowDimensions/index.tsx +++ b/src/components/withWindowDimensions/index.tsx @@ -80,10 +80,6 @@ function WindowDimensionsProvider(props: ChildrenProps) { WindowDimensionsProvider.displayName = 'WindowDimensionsProvider'; -/** - * @param WrappedComponent - * @returns - */ export default function withWindowDimensions(WrappedComponent: ComponentType>) { function WithWindowDimensions(props: Omit, ref: ForwardedRef) { return ( From a75557fcbeebdded218b6eb8752b58aa97c68ae9 Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Thu, 26 Oct 2023 16:02:48 +0200 Subject: [PATCH 043/212] extract PopoverAnchorPosition to TypeScript --- src/components/Modal/types.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/components/Modal/types.ts b/src/components/Modal/types.ts index 36ce5fa28781..68bffbb60080 100644 --- a/src/components/Modal/types.ts +++ b/src/components/Modal/types.ts @@ -4,7 +4,12 @@ import {ModalProps} from 'react-native-modal'; import {WindowDimensionsProps} from '../withWindowDimensions/types'; import CONST from '../../CONST'; -type ModalVariant = ValueOf; +type PopoverAnchorPosition = { + top?: number; + right?: number; + bottom?: number; + left?: number; +}; type BaseModalProps = WindowDimensionsProps & ModalProps & { @@ -33,15 +38,10 @@ type BaseModalProps = WindowDimensionsProps & onModalShow?: () => void; /** Style of modal to display */ - type?: ModalVariant; + type?: ValueOf; /** The anchor position of a popover modal. Has no effect on other modal types. */ - popoverAnchorPosition?: { - top?: number; - right?: number; - bottom?: number; - left?: number; - }; + popoverAnchorPosition?: PopoverAnchorPosition; outerStyle?: ViewStyle; From 5fe60ddadf95b90779907df2db70325565d95811 Mon Sep 17 00:00:00 2001 From: Yauheni Pasiukevich Date: Wed, 25 Oct 2023 15:00:05 +0200 Subject: [PATCH 044/212] Migrate 'ErrorBoundary' component to TypeScript --- ...ErrorBoundary.js => BaseErrorBoundary.tsx} | 26 +++++++---------- src/components/ErrorBoundary/index.js | 8 ----- src/components/ErrorBoundary/index.native.js | 16 ---------- src/components/ErrorBoundary/index.native.tsx | 29 +++++++++++++++++++ src/components/ErrorBoundary/index.tsx | 22 ++++++++++++++ 5 files changed, 61 insertions(+), 40 deletions(-) rename src/components/ErrorBoundary/{BaseErrorBoundary.js => BaseErrorBoundary.tsx} (72%) delete mode 100644 src/components/ErrorBoundary/index.js delete mode 100644 src/components/ErrorBoundary/index.native.js create mode 100644 src/components/ErrorBoundary/index.native.tsx create mode 100644 src/components/ErrorBoundary/index.tsx diff --git a/src/components/ErrorBoundary/BaseErrorBoundary.js b/src/components/ErrorBoundary/BaseErrorBoundary.tsx similarity index 72% rename from src/components/ErrorBoundary/BaseErrorBoundary.js rename to src/components/ErrorBoundary/BaseErrorBoundary.tsx index d626442e81dd..1ba80c6e6523 100644 --- a/src/components/ErrorBoundary/BaseErrorBoundary.js +++ b/src/components/ErrorBoundary/BaseErrorBoundary.tsx @@ -1,32 +1,28 @@ import React from 'react'; -import PropTypes from 'prop-types'; import {ErrorBoundary} from 'react-error-boundary'; import BootSplash from '../../libs/BootSplash'; import GenericErrorPage from '../../pages/ErrorPage/GenericErrorPage'; -const propTypes = { +type LogError = (message: string, error: Error, errorInfo: string) => void; + +type BaseErrorBoundaryProps = { /* A message posted to `logError` (along with error data) when this component intercepts an error */ - errorMessage: PropTypes.string.isRequired, + errorMessage: string; /* A function to perform the actual logging since different platforms support different tools */ - logError: PropTypes.func, + logError?: LogError; /* Actual content wrapped by this error boundary */ - children: PropTypes.node.isRequired, -}; - -const defaultProps = { - logError: () => {}, + children: React.ReactNode; }; - /** * This component captures an error in the child component tree and logs it to the server * It can be used to wrap the entire app as well as to wrap specific parts for more granularity * @see {@link https://reactjs.org/docs/error-boundaries.html#where-to-place-error-boundaries} - * @return {React.Component} */ -function BaseErrorBoundary({logError, errorMessage, children}) { - const catchError = (error, errorInfo) => { + +function BaseErrorBoundary({logError = () => {}, errorMessage, children}: BaseErrorBoundaryProps) { + const catchError = (error: Error, errorInfo: React.ErrorInfo) => { logError(errorMessage, error, JSON.stringify(errorInfo)); // We hide the splash screen since the error might happened during app init BootSplash.hide(); @@ -42,8 +38,6 @@ function BaseErrorBoundary({logError, errorMessage, children}) { ); } -BaseErrorBoundary.propTypes = propTypes; -BaseErrorBoundary.defaultProps = defaultProps; BaseErrorBoundary.displayName = 'BaseErrorBoundary'; - +export type {LogError, BaseErrorBoundaryProps}; export default BaseErrorBoundary; diff --git a/src/components/ErrorBoundary/index.js b/src/components/ErrorBoundary/index.js deleted file mode 100644 index 4a113fa040dd..000000000000 --- a/src/components/ErrorBoundary/index.js +++ /dev/null @@ -1,8 +0,0 @@ -import BaseErrorBoundary from './BaseErrorBoundary'; -import Log from '../../libs/Log'; - -BaseErrorBoundary.defaultProps.logError = (errorMessage, error, errorInfo) => { - // Log the error to the server - Log.alert(`${errorMessage} - ${error.message}`, {errorInfo}, false); -}; -export default BaseErrorBoundary; diff --git a/src/components/ErrorBoundary/index.native.js b/src/components/ErrorBoundary/index.native.js deleted file mode 100644 index 68815acf670f..000000000000 --- a/src/components/ErrorBoundary/index.native.js +++ /dev/null @@ -1,16 +0,0 @@ -import crashlytics from '@react-native-firebase/crashlytics'; - -import BaseErrorBoundary from './BaseErrorBoundary'; -import Log from '../../libs/Log'; - -BaseErrorBoundary.defaultProps.logError = (errorMessage, error, errorInfo) => { - // Log the error to the server - Log.alert(`${errorMessage} - ${error.message}`, {errorInfo}, false); - - /* On native we also log the error to crashlytics - * Since the error was handled we need to manually tell crashlytics about it */ - crashlytics().log(`errorInfo: ${errorInfo}`); - crashlytics().recordError(error); -}; - -export default BaseErrorBoundary; diff --git a/src/components/ErrorBoundary/index.native.tsx b/src/components/ErrorBoundary/index.native.tsx new file mode 100644 index 000000000000..8503618ba401 --- /dev/null +++ b/src/components/ErrorBoundary/index.native.tsx @@ -0,0 +1,29 @@ +import crashlytics from '@react-native-firebase/crashlytics'; + +import BaseErrorBoundary, {LogError, BaseErrorBoundaryProps} from './BaseErrorBoundary'; +import Log from '../../libs/Log'; + +const logError: LogError = (errorMessage, error, errorInfo) => { + // Log the error to the server + Log.alert(`${errorMessage} - ${error.message}`, {errorInfo}, false); + + /* On native we also log the error to crashlytics + * Since the error was handled we need to manually tell crashlytics about it */ + crashlytics().log(`errorInfo: ${errorInfo}`); + crashlytics().recordError(error); +}; + +function ErrorBoundary({errorMessage, children}: BaseErrorBoundaryProps) { + return ( + + {children} + + ); +} + +ErrorBoundary.displayName = 'ErrorBoundary'; + +export default ErrorBoundary; diff --git a/src/components/ErrorBoundary/index.tsx b/src/components/ErrorBoundary/index.tsx new file mode 100644 index 000000000000..3a1aa91aadff --- /dev/null +++ b/src/components/ErrorBoundary/index.tsx @@ -0,0 +1,22 @@ +import BaseErrorBoundary, {LogError, BaseErrorBoundaryProps} from './BaseErrorBoundary'; +import Log from '../../libs/Log'; + +const logError: LogError = (errorMessage, error, errorInfo) => { + // Log the error to the server + Log.alert(`${errorMessage} - ${error.message}`, {errorInfo}, false); +}; + +function ErrorBoundary({errorMessage, children}: BaseErrorBoundaryProps) { + return ( + + {children} + + ); +} + +ErrorBoundary.displayName = 'ErrorBoundary'; + +export default ErrorBoundary; From f806a947ede5a8c3770d46ac756f608bbc6fa0ba Mon Sep 17 00:00:00 2001 From: dukenv0307 Date: Mon, 30 Oct 2023 15:58:14 +0700 Subject: [PATCH 045/212] validate login form whever the input is changed --- src/pages/signin/LoginForm/BaseLoginForm.js | 68 +++++++++++++++------ 1 file changed, 49 insertions(+), 19 deletions(-) diff --git a/src/pages/signin/LoginForm/BaseLoginForm.js b/src/pages/signin/LoginForm/BaseLoginForm.js index 9529d7fd0d60..2fa2360430a6 100644 --- a/src/pages/signin/LoginForm/BaseLoginForm.js +++ b/src/pages/signin/LoginForm/BaseLoginForm.js @@ -98,18 +98,52 @@ function LoginForm(props) { const [login, setLogin] = useState(() => Str.removeSMSDomain(props.credentials.login || '')); const [formError, setFormError] = useState(false); const prevIsVisible = usePrevious(props.isVisible); + const firstBlurred = useRef(!canFocusInputOnScreenFocus()); const {translate} = props; /** - * Handle text input and clear formError upon text change + * Validate the input value and set the error for formError + * + * @param {String} value + */ + const validate = useCallback( + (value) => { + const loginTrim = value.trim(); + if (!loginTrim) { + setFormError('common.pleaseEnterEmailOrPhoneNumber'); + return false; + } + + const phoneLogin = LoginUtils.appendCountryCode(LoginUtils.getPhoneNumberWithoutSpecialChars(loginTrim)); + const parsedPhoneNumber = parsePhoneNumber(phoneLogin); + + if (!Str.isValidEmail(loginTrim) && !parsedPhoneNumber.possible) { + if (ValidationUtils.isNumericWithSpecialChars(loginTrim)) { + setFormError('common.error.phoneNumber'); + } else { + setFormError('loginForm.error.invalidFormatEmailLogin'); + } + return false; + } + + setFormError(null); + return true; + }, + [setFormError], + ); + + /** + * Handle text input and validate the text input if it is blurred * * @param {String} text */ const onTextInput = useCallback( (text) => { setLogin(text); - setFormError(null); + if (firstBlurred.current) { + validate(text); + } if (props.account.errors || props.account.message) { Session.clearAccountMessages(); @@ -120,7 +154,7 @@ function LoginForm(props) { CloseAccount.setDefaultData(); } }, - [props.account, props.closeAccount, input, setFormError, setLogin], + [props.account, props.closeAccount, input, setLogin, validate], ); function getSignInWithStyles() { @@ -140,23 +174,11 @@ function LoginForm(props) { CloseAccount.setDefaultData(); } - const loginTrim = login.trim(); - if (!loginTrim) { - setFormError('common.pleaseEnterEmailOrPhoneNumber'); + if (!validate(login)) { return; } - const phoneLogin = LoginUtils.appendCountryCode(LoginUtils.getPhoneNumberWithoutSpecialChars(loginTrim)); - const parsedPhoneNumber = parsePhoneNumber(phoneLogin); - - if (!Str.isValidEmail(loginTrim) && !parsedPhoneNumber.possible) { - if (ValidationUtils.isNumericWithSpecialChars(loginTrim)) { - setFormError('common.error.phoneNumber'); - } else { - setFormError('loginForm.error.invalidFormatEmailLogin'); - } - return; - } + const loginTrim = login.trim(); // If the user has entered a guide email, then we are going to enable an experimental Onyx mode to help with performance if (PolicyUtils.isExpensifyGuideTeam(loginTrim)) { @@ -164,11 +186,12 @@ function LoginForm(props) { MemoryOnlyKeys.enable(); } - setFormError(null); + const phoneLogin = LoginUtils.appendCountryCode(LoginUtils.getPhoneNumberWithoutSpecialChars(loginTrim)); + const parsedPhoneNumber = parsePhoneNumber(phoneLogin); // Check if this login has an account associated with it or not Session.beginSignIn(parsedPhoneNumber.possible ? parsedPhoneNumber.number.e164 : loginTrim); - }, [login, props.account, props.closeAccount, props.network, setFormError]); + }, [login, props.account, props.closeAccount, props.network, validate]); useEffect(() => { // Just call clearAccountMessages on the login page (home route), because when the user is in the transition route and not yet authenticated, @@ -228,6 +251,13 @@ function LoginForm(props) { textContentType="username" nativeID="username" name="username" + onBlur={() => { + if (firstBlurred.current) { + return; + } + firstBlurred.current = true; + validate(login); + }} onChangeText={onTextInput} onSubmitEditing={validateAndSubmitForm} autoCapitalize="none" From e846414b398cd6e9bcb4cdfa16974cf188d9ffe1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucas=20M=C3=B3rawski?= Date: Mon, 30 Oct 2023 11:01:59 +0100 Subject: [PATCH 046/212] prettier --- src/pages/iou/ReceiptSelector/NavigationAwareCamera.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/pages/iou/ReceiptSelector/NavigationAwareCamera.js b/src/pages/iou/ReceiptSelector/NavigationAwareCamera.js index a2f5f0b7c561..783ae36f0e07 100644 --- a/src/pages/iou/ReceiptSelector/NavigationAwareCamera.js +++ b/src/pages/iou/ReceiptSelector/NavigationAwareCamera.js @@ -1,10 +1,9 @@ -import React, {useEffect, useRef, useState} from 'react'; -import Webcam from 'react-webcam'; +import {useTabAnimation} from '@react-navigation/material-top-tabs'; import {useIsFocused} from '@react-navigation/native'; import PropTypes from 'prop-types'; -import React, {useEffect, useRef} from 'react'; +import React, {useEffect, useRef, useState} from 'react'; import {View} from 'react-native'; -import {useTabAnimation} from '@react-navigation/material-top-tabs'; +import Webcam from 'react-webcam'; const propTypes = { /* Flag to turn on/off the torch/flashlight - if available */ From 551e96a4acc865200870ca2b8353006b06f6223d Mon Sep 17 00:00:00 2001 From: Viktoryia Kliushun Date: Mon, 30 Oct 2023 11:12:04 +0100 Subject: [PATCH 047/212] Update imports after merging main, fix ts errors --- src/libs/E2E/API.mock.ts | 5 ++--- src/libs/E2E/apiMocks/authenticatePusher.ts | 2 +- src/libs/E2E/apiMocks/beginSignin.ts | 4 ++-- src/libs/E2E/apiMocks/openApp.ts | 6 +++--- src/libs/E2E/apiMocks/openReport.ts | 2 +- src/libs/E2E/apiMocks/signinUser.ts | 4 ++-- src/libs/E2E/isE2ETestSession.native.ts | 2 +- src/types/onyx/Report.ts | 3 --- 8 files changed, 12 insertions(+), 16 deletions(-) diff --git a/src/libs/E2E/API.mock.ts b/src/libs/E2E/API.mock.ts index db46e32e8d3e..8b57e99b6006 100644 --- a/src/libs/E2E/API.mock.ts +++ b/src/libs/E2E/API.mock.ts @@ -1,10 +1,9 @@ /* eslint-disable rulesdir/no-api-in-views */ import Onyx from 'react-native-onyx'; import Log from '@libs/Log'; -import mockAuthenticatePusher from './apiMocks/authenticatePusher'; -import Response from '../../types/onyx/Response'; - +import Response from '@src/types/onyx/Response'; // mock functions +import mockAuthenticatePusher from './apiMocks/authenticatePusher'; import mockBeginSignin from './apiMocks/beginSignin'; import mockOpenApp from './apiMocks/openApp'; import mockOpenReport from './apiMocks/openReport'; diff --git a/src/libs/E2E/apiMocks/authenticatePusher.ts b/src/libs/E2E/apiMocks/authenticatePusher.ts index 346018df6eb2..81191ddb8222 100644 --- a/src/libs/E2E/apiMocks/authenticatePusher.ts +++ b/src/libs/E2E/apiMocks/authenticatePusher.ts @@ -1,4 +1,4 @@ -import Response from '../../../types/onyx/Response'; +import Response from '@src/types/onyx/Response'; const authenticatePusher = (): Response => ({ auth: 'auth', diff --git a/src/libs/E2E/apiMocks/beginSignin.ts b/src/libs/E2E/apiMocks/beginSignin.ts index ea07ea7a6c08..298846250a12 100644 --- a/src/libs/E2E/apiMocks/beginSignin.ts +++ b/src/libs/E2E/apiMocks/beginSignin.ts @@ -1,5 +1,5 @@ -import Response from '../../../types/onyx/Response'; -import {SigninParams} from '../types'; +import {SigninParams} from '@libs/E2E/types'; +import Response from '@src/types/onyx/Response'; const beginSignin = ({email}: SigninParams): Response => ({ onyxData: [ diff --git a/src/libs/E2E/apiMocks/openApp.ts b/src/libs/E2E/apiMocks/openApp.ts index 5ef53348f293..795375077f5a 100644 --- a/src/libs/E2E/apiMocks/openApp.ts +++ b/src/libs/E2E/apiMocks/openApp.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/naming-convention */ -import Response from '../../../types/onyx/Response'; +import Response from '@src/types/onyx/Response'; const openApp = (): Response => ({ onyxData: [ @@ -1773,7 +1773,7 @@ const openApp = (): Response => ({ isOwnPolicyExpenseChat: false, lastMessageHtml: 'RR', hasOutstandingIOU: true, - iouReportID: 2543745284790730, + iouReportID: '2543745284790730', }, report_358751490033727: { reportID: '358751490033727', @@ -1950,7 +1950,7 @@ const openApp = (): Response => ({ isOwnPolicyExpenseChat: false, lastMessageHtml: 'Requested \u20ac200.00 from Christoph for Essen mit Kunden', hasOutstandingIOU: true, - iouReportID: 4249286573496381, + iouReportID: '4249286573496381', }, report_5277760851229035: { reportID: '5277760851229035', diff --git a/src/libs/E2E/apiMocks/openReport.ts b/src/libs/E2E/apiMocks/openReport.ts index d55614753788..cb80bc4804fd 100644 --- a/src/libs/E2E/apiMocks/openReport.ts +++ b/src/libs/E2E/apiMocks/openReport.ts @@ -1,4 +1,4 @@ -import Response from '../../../types/onyx/Response'; +import Response from '@src/types/onyx/Response'; const openReport = (): Response => ({ onyxData: [ diff --git a/src/libs/E2E/apiMocks/signinUser.ts b/src/libs/E2E/apiMocks/signinUser.ts index b65a104ac983..d94d2fda9016 100644 --- a/src/libs/E2E/apiMocks/signinUser.ts +++ b/src/libs/E2E/apiMocks/signinUser.ts @@ -1,5 +1,5 @@ -import Response from '../../../types/onyx/Response'; -import {SigninParams} from '../types'; +import {SigninParams} from '@libs/E2E/types'; +import Response from '@src/types/onyx/Response'; const signinUser = ({email}: SigninParams): Response => ({ onyxData: [ diff --git a/src/libs/E2E/isE2ETestSession.native.ts b/src/libs/E2E/isE2ETestSession.native.ts index 19499c91050d..0463d41572cf 100644 --- a/src/libs/E2E/isE2ETestSession.native.ts +++ b/src/libs/E2E/isE2ETestSession.native.ts @@ -1,4 +1,4 @@ -import CONFIG from '../../CONFIG'; +import CONFIG from '@src/CONFIG'; import {IsE2ETestSession} from './types'; const isE2ETestSession: IsE2ETestSession = () => CONFIG.E2E_TESTING; diff --git a/src/types/onyx/Report.ts b/src/types/onyx/Report.ts index dcb38ea047fb..264c4e039c69 100644 --- a/src/types/onyx/Report.ts +++ b/src/types/onyx/Report.ts @@ -54,9 +54,6 @@ type Report = { /** ID of the report */ reportID: string; - /** ID of the iou report */ - iouReportID?: number; - /** ID of the chat report */ chatReportID?: string; From 3e0627ac6d015e7eef2733183b2871cbb45c3b78 Mon Sep 17 00:00:00 2001 From: Viktoryia Kliushun Date: Mon, 30 Oct 2023 11:22:21 +0100 Subject: [PATCH 048/212] Fix prettier --- .prettierignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.prettierignore b/.prettierignore index 80888b18a317..2df776736b69 100644 --- a/.prettierignore +++ b/.prettierignore @@ -16,4 +16,4 @@ package-lock.json *.scss *.md # We need to modify the import here specifically, hence we disable prettier to get rid of the sorted imports -src/libs/E2E/reactNativeLaunchingTest.js +src/libs/E2E/reactNativeLaunchingTest.ts From 43adb91a918118d9b2b42fcb7d60a4ad7c4f42ac Mon Sep 17 00:00:00 2001 From: Yauheni Pasiukevich Date: Mon, 30 Oct 2023 15:45:15 +0100 Subject: [PATCH 049/212] update imports --- src/components/ErrorBoundary/index.native.tsx | 2 +- src/components/ErrorBoundary/index.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/ErrorBoundary/index.native.tsx b/src/components/ErrorBoundary/index.native.tsx index 8503618ba401..c340647141a8 100644 --- a/src/components/ErrorBoundary/index.native.tsx +++ b/src/components/ErrorBoundary/index.native.tsx @@ -1,7 +1,7 @@ import crashlytics from '@react-native-firebase/crashlytics'; import BaseErrorBoundary, {LogError, BaseErrorBoundaryProps} from './BaseErrorBoundary'; -import Log from '../../libs/Log'; +import Log from '@libs/Log'; const logError: LogError = (errorMessage, error, errorInfo) => { // Log the error to the server diff --git a/src/components/ErrorBoundary/index.tsx b/src/components/ErrorBoundary/index.tsx index 3a1aa91aadff..c042f0c53ab4 100644 --- a/src/components/ErrorBoundary/index.tsx +++ b/src/components/ErrorBoundary/index.tsx @@ -1,5 +1,5 @@ import BaseErrorBoundary, {LogError, BaseErrorBoundaryProps} from './BaseErrorBoundary'; -import Log from '../../libs/Log'; +import Log from '@libs//Log'; const logError: LogError = (errorMessage, error, errorInfo) => { // Log the error to the server From b67174262b517d7ac8e475eb551184d8805e2508 Mon Sep 17 00:00:00 2001 From: Yauheni Pasiukevich Date: Mon, 30 Oct 2023 15:50:42 +0100 Subject: [PATCH 050/212] fix type --- src/components/ErrorBoundary/BaseErrorBoundary.tsx | 3 +-- src/components/ErrorBoundary/index.native.tsx | 6 +++--- src/components/ErrorBoundary/index.tsx | 5 +++-- src/components/ErrorBoundary/types.ts | 3 +++ 4 files changed, 10 insertions(+), 7 deletions(-) create mode 100644 src/components/ErrorBoundary/types.ts diff --git a/src/components/ErrorBoundary/BaseErrorBoundary.tsx b/src/components/ErrorBoundary/BaseErrorBoundary.tsx index 61e0c2c0aa26..27ea79950507 100644 --- a/src/components/ErrorBoundary/BaseErrorBoundary.tsx +++ b/src/components/ErrorBoundary/BaseErrorBoundary.tsx @@ -2,8 +2,7 @@ import React from 'react'; import {ErrorBoundary} from 'react-error-boundary'; import BootSplash from '@libs/BootSplash'; import GenericErrorPage from '@pages/ErrorPage/GenericErrorPage'; - -type LogError = (message: string, error: Error, errorInfo: string) => void; +import LogError from './types'; type BaseErrorBoundaryProps = { /* A message posted to `logError` (along with error data) when this component intercepts an error */ diff --git a/src/components/ErrorBoundary/index.native.tsx b/src/components/ErrorBoundary/index.native.tsx index c340647141a8..20f90a122d25 100644 --- a/src/components/ErrorBoundary/index.native.tsx +++ b/src/components/ErrorBoundary/index.native.tsx @@ -1,7 +1,7 @@ import crashlytics from '@react-native-firebase/crashlytics'; - -import BaseErrorBoundary, {LogError, BaseErrorBoundaryProps} from './BaseErrorBoundary'; import Log from '@libs/Log'; +import BaseErrorBoundary, {BaseErrorBoundaryProps} from './BaseErrorBoundary'; +import LogError from './types'; const logError: LogError = (errorMessage, error, errorInfo) => { // Log the error to the server @@ -13,7 +13,7 @@ const logError: LogError = (errorMessage, error, errorInfo) => { crashlytics().recordError(error); }; -function ErrorBoundary({errorMessage, children}: BaseErrorBoundaryProps) { +function ErrorBoundary({errorMessage, children}: Omit) { return ( { // Log the error to the server Log.alert(`${errorMessage} - ${error.message}`, {errorInfo}, false); }; -function ErrorBoundary({errorMessage, children}: BaseErrorBoundaryProps) { +function ErrorBoundary({errorMessage, children}: Omit) { return ( void; + +export default LogError; From da8b083bd138ff6468447e173b2b559cfadddcc4 Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Mon, 30 Oct 2023 16:19:29 +0100 Subject: [PATCH 051/212] add return types to HOCs, fix linting --- src/components/Modal/BaseModal.tsx | 14 +++++++------- src/components/Modal/types.ts | 4 ++-- .../withWindowDimensions/index.native.tsx | 10 ++++++---- src/components/withWindowDimensions/index.tsx | 10 ++++++---- 4 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/components/Modal/BaseModal.tsx b/src/components/Modal/BaseModal.tsx index 71a89ddbfdf4..512ab65eb7af 100644 --- a/src/components/Modal/BaseModal.tsx +++ b/src/components/Modal/BaseModal.tsx @@ -3,18 +3,18 @@ import React, {forwardRef, useCallback, useEffect, useMemo, useRef} from 'react' import {View} from 'react-native'; import ReactNativeModal from 'react-native-modal'; import {useSafeAreaInsets} from 'react-native-safe-area-context'; -import styles from '../../styles/styles'; +import CONST from '../../CONST'; +import usePrevious from '../../hooks/usePrevious'; +import useWindowDimensions from '../../hooks/useWindowDimensions'; import * as Modal from '../../libs/actions/Modal'; +import ComposerFocusManager from '../../libs/ComposerFocusManager'; +import useNativeDriver from '../../libs/useNativeDriver'; +import getModalStyles from '../../styles/getModalStyles'; +import styles from '../../styles/styles'; import * as StyleUtils from '../../styles/StyleUtils'; import themeColors from '../../styles/themes/default'; -import getModalStyles from '../../styles/getModalStyles'; -import useWindowDimensions from '../../hooks/useWindowDimensions'; import variables from '../../styles/variables'; -import ComposerFocusManager from '../../libs/ComposerFocusManager'; -import useNativeDriver from '../../libs/useNativeDriver'; -import usePrevious from '../../hooks/usePrevious'; import BaseModalProps from './types'; -import CONST from '../../CONST'; function BaseModal( { diff --git a/src/components/Modal/types.ts b/src/components/Modal/types.ts index 68bffbb60080..dcb9edf910de 100644 --- a/src/components/Modal/types.ts +++ b/src/components/Modal/types.ts @@ -1,8 +1,8 @@ -import {ValueOf} from 'type-fest'; import {ViewStyle} from 'react-native'; import {ModalProps} from 'react-native-modal'; -import {WindowDimensionsProps} from '../withWindowDimensions/types'; +import {ValueOf} from 'type-fest'; import CONST from '../../CONST'; +import {WindowDimensionsProps} from '../withWindowDimensions/types'; type PopoverAnchorPosition = { top?: number; diff --git a/src/components/withWindowDimensions/index.native.tsx b/src/components/withWindowDimensions/index.native.tsx index 611efa60ee79..8e4611e6c5b0 100644 --- a/src/components/withWindowDimensions/index.native.tsx +++ b/src/components/withWindowDimensions/index.native.tsx @@ -1,12 +1,12 @@ -import React, {createContext, useState, useEffect, useMemo, ComponentType, RefAttributes, ForwardedRef} from 'react'; import PropTypes from 'prop-types'; +import React, {ComponentType, createContext, ForwardedRef, RefAttributes, useEffect, useMemo, useState} from 'react'; import {Dimensions} from 'react-native'; import {useSafeAreaInsets} from 'react-native-safe-area-context'; import getComponentDisplayName from '../../libs/getComponentDisplayName'; -import variables from '../../styles/variables'; import getWindowHeightAdjustment from '../../libs/getWindowHeightAdjustment'; -import {NewDimensions, WindowDimensionsContextData, WindowDimensionsProps} from './types'; +import variables from '../../styles/variables'; import ChildrenProps from '../../types/utils/ChildrenProps'; +import {NewDimensions, WindowDimensionsContextData, WindowDimensionsProps} from './types'; const WindowDimensionsContext = createContext(null); const windowDimensionsPropTypes = { @@ -74,7 +74,9 @@ function WindowDimensionsProvider(props: ChildrenProps) { WindowDimensionsProvider.displayName = 'WindowDimensionsProvider'; -export default function withWindowDimensions(WrappedComponent: ComponentType>) { +export default function withWindowDimensions( + WrappedComponent: ComponentType>, +): (props: Omit & React.RefAttributes) => React.ReactElement | null { function WithWindowDimensions(props: Omit, ref: ForwardedRef) { return ( diff --git a/src/components/withWindowDimensions/index.tsx b/src/components/withWindowDimensions/index.tsx index c1b12d6f6156..508b9e2608fc 100644 --- a/src/components/withWindowDimensions/index.tsx +++ b/src/components/withWindowDimensions/index.tsx @@ -1,13 +1,13 @@ -import React, {createContext, useState, useEffect, useMemo, RefAttributes, ComponentType, ForwardedRef} from 'react'; -import PropTypes from 'prop-types'; import lodashDebounce from 'lodash/debounce'; +import PropTypes from 'prop-types'; +import React, {ComponentType, createContext, ForwardedRef, RefAttributes, useEffect, useMemo, useState} from 'react'; import {Dimensions} from 'react-native'; import {useSafeAreaInsets} from 'react-native-safe-area-context'; +import getWindowHeightAdjustment from '@libs/getWindowHeightAdjustment'; import getComponentDisplayName from '../../libs/getComponentDisplayName'; import variables from '../../styles/variables'; import ChildrenProps from '../../types/utils/ChildrenProps'; import {NewDimensions, WindowDimensionsContextData, WindowDimensionsProps} from './types'; -import getWindowHeightAdjustment from '@libs/getWindowHeightAdjustment'; const WindowDimensionsContext = createContext(null); const windowDimensionsPropTypes = { @@ -80,7 +80,9 @@ function WindowDimensionsProvider(props: ChildrenProps) { WindowDimensionsProvider.displayName = 'WindowDimensionsProvider'; -export default function withWindowDimensions(WrappedComponent: ComponentType>) { +export default function withWindowDimensions( + WrappedComponent: ComponentType>, +): (props: Omit & React.RefAttributes) => React.ReactElement | null { function WithWindowDimensions(props: Omit, ref: ForwardedRef) { return ( From a6287edbcb47c65f6aff9cfe680f659475266dd5 Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Mon, 30 Oct 2023 16:49:36 +0100 Subject: [PATCH 052/212] fix imports --- src/components/Modal/BaseModal.tsx | 23 +++++++++---------- src/components/Modal/types.ts | 4 ++-- .../withWindowDimensions/index.native.tsx | 8 +++---- src/components/withWindowDimensions/index.tsx | 6 ++--- 4 files changed, 20 insertions(+), 21 deletions(-) diff --git a/src/components/Modal/BaseModal.tsx b/src/components/Modal/BaseModal.tsx index 512ab65eb7af..89f2a5ba2a53 100644 --- a/src/components/Modal/BaseModal.tsx +++ b/src/components/Modal/BaseModal.tsx @@ -1,19 +1,18 @@ -import PropTypes from 'prop-types'; import React, {forwardRef, useCallback, useEffect, useMemo, useRef} from 'react'; import {View} from 'react-native'; import ReactNativeModal from 'react-native-modal'; import {useSafeAreaInsets} from 'react-native-safe-area-context'; -import CONST from '../../CONST'; -import usePrevious from '../../hooks/usePrevious'; -import useWindowDimensions from '../../hooks/useWindowDimensions'; -import * as Modal from '../../libs/actions/Modal'; -import ComposerFocusManager from '../../libs/ComposerFocusManager'; -import useNativeDriver from '../../libs/useNativeDriver'; -import getModalStyles from '../../styles/getModalStyles'; -import styles from '../../styles/styles'; -import * as StyleUtils from '../../styles/StyleUtils'; -import themeColors from '../../styles/themes/default'; -import variables from '../../styles/variables'; +import usePrevious from '@hooks/usePrevious'; +import useWindowDimensions from '@hooks/useWindowDimensions'; +import ComposerFocusManager from '@libs/ComposerFocusManager'; +import useNativeDriver from '@libs/useNativeDriver'; +import getModalStyles from '@styles/getModalStyles'; +import styles from '@styles/styles'; +import * as StyleUtils from '@styles/StyleUtils'; +import themeColors from '@styles/themes/default'; +import variables from '@styles/variables'; +import * as Modal from '@userActions/Modal'; +import CONST from '@src/CONST'; import BaseModalProps from './types'; function BaseModal( diff --git a/src/components/Modal/types.ts b/src/components/Modal/types.ts index dcb9edf910de..3fa60e6ac765 100644 --- a/src/components/Modal/types.ts +++ b/src/components/Modal/types.ts @@ -1,8 +1,8 @@ import {ViewStyle} from 'react-native'; import {ModalProps} from 'react-native-modal'; import {ValueOf} from 'type-fest'; -import CONST from '../../CONST'; -import {WindowDimensionsProps} from '../withWindowDimensions/types'; +import {WindowDimensionsProps} from '@components/withWindowDimensions/types'; +import CONST from '@src/CONST'; type PopoverAnchorPosition = { top?: number; diff --git a/src/components/withWindowDimensions/index.native.tsx b/src/components/withWindowDimensions/index.native.tsx index 8e4611e6c5b0..0c9f61a45c0b 100644 --- a/src/components/withWindowDimensions/index.native.tsx +++ b/src/components/withWindowDimensions/index.native.tsx @@ -2,10 +2,10 @@ import PropTypes from 'prop-types'; import React, {ComponentType, createContext, ForwardedRef, RefAttributes, useEffect, useMemo, useState} from 'react'; import {Dimensions} from 'react-native'; import {useSafeAreaInsets} from 'react-native-safe-area-context'; -import getComponentDisplayName from '../../libs/getComponentDisplayName'; -import getWindowHeightAdjustment from '../../libs/getWindowHeightAdjustment'; -import variables from '../../styles/variables'; -import ChildrenProps from '../../types/utils/ChildrenProps'; +import getComponentDisplayName from '@libs/getComponentDisplayName'; +import getWindowHeightAdjustment from '@libs/getWindowHeightAdjustment'; +import variables from '@styles/variables'; +import ChildrenProps from '@src/types/utils/ChildrenProps'; import {NewDimensions, WindowDimensionsContextData, WindowDimensionsProps} from './types'; const WindowDimensionsContext = createContext(null); diff --git a/src/components/withWindowDimensions/index.tsx b/src/components/withWindowDimensions/index.tsx index 508b9e2608fc..1479450deec4 100644 --- a/src/components/withWindowDimensions/index.tsx +++ b/src/components/withWindowDimensions/index.tsx @@ -3,10 +3,10 @@ import PropTypes from 'prop-types'; import React, {ComponentType, createContext, ForwardedRef, RefAttributes, useEffect, useMemo, useState} from 'react'; import {Dimensions} from 'react-native'; import {useSafeAreaInsets} from 'react-native-safe-area-context'; +import getComponentDisplayName from '@libs/getComponentDisplayName'; import getWindowHeightAdjustment from '@libs/getWindowHeightAdjustment'; -import getComponentDisplayName from '../../libs/getComponentDisplayName'; -import variables from '../../styles/variables'; -import ChildrenProps from '../../types/utils/ChildrenProps'; +import variables from '@styles/variables'; +import ChildrenProps from '@src/types/utils/ChildrenProps'; import {NewDimensions, WindowDimensionsContextData, WindowDimensionsProps} from './types'; const WindowDimensionsContext = createContext(null); From 803f9f955fcfe49fedffa56a91f8bd5af71b1d88 Mon Sep 17 00:00:00 2001 From: dukenv0307 Date: Mon, 30 Oct 2023 23:43:47 +0700 Subject: [PATCH 053/212] fix validate on native --- src/pages/signin/LoginForm/BaseLoginForm.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/pages/signin/LoginForm/BaseLoginForm.js b/src/pages/signin/LoginForm/BaseLoginForm.js index 2fa2360430a6..e52389076f90 100644 --- a/src/pages/signin/LoginForm/BaseLoginForm.js +++ b/src/pages/signin/LoginForm/BaseLoginForm.js @@ -98,7 +98,7 @@ function LoginForm(props) { const [login, setLogin] = useState(() => Str.removeSMSDomain(props.credentials.login || '')); const [formError, setFormError] = useState(false); const prevIsVisible = usePrevious(props.isVisible); - const firstBlurred = useRef(!canFocusInputOnScreenFocus()); + const firstBlurred = useRef(false); const {translate} = props; @@ -174,6 +174,12 @@ function LoginForm(props) { CloseAccount.setDefaultData(); } + // For native, the single input doesn't lost focus when we click outside. + // So we need to change firstBlurred here to make the validate function is called whenever the text input is changed after the first validation. + if (!firstBlurred.current) { + firstBlurred.current = true; + } + if (!validate(login)) { return; } From 11f90d3342cc0876c6ff0a98554b21cf50b5c50d Mon Sep 17 00:00:00 2001 From: dukenv0307 Date: Tue, 31 Oct 2023 15:20:18 +0700 Subject: [PATCH 054/212] display skeleton avtar while loading --- src/components/AvatarWithIndicator.js | 20 +++++++++++++------ .../sidebar/PressableAvatarWithIndicator.js | 19 ++++++++++++++++-- src/styles/styles.ts | 4 ++++ 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/src/components/AvatarWithIndicator.js b/src/components/AvatarWithIndicator.js index c2a8d5346e13..4af8074b57da 100644 --- a/src/components/AvatarWithIndicator.js +++ b/src/components/AvatarWithIndicator.js @@ -17,22 +17,30 @@ const propTypes = { /** A fallback avatar icon to display when there is an error on loading avatar from remote URL. */ fallbackIcon: PropTypes.oneOfType([PropTypes.func, PropTypes.string]), + + /** Indicates whether the avatar is loaded or not */ + isLoading: PropTypes.bool, }; const defaultProps = { tooltipText: '', fallbackIcon: Expensicons.FallbackAvatar, + isLoading: true, }; function AvatarWithIndicator(props) { return ( - - - + + {!props.isLoading && ( + <> + + + + )} ); diff --git a/src/pages/home/sidebar/PressableAvatarWithIndicator.js b/src/pages/home/sidebar/PressableAvatarWithIndicator.js index e798bece339f..20a61c6ed869 100644 --- a/src/pages/home/sidebar/PressableAvatarWithIndicator.js +++ b/src/pages/home/sidebar/PressableAvatarWithIndicator.js @@ -2,15 +2,18 @@ import lodashGet from 'lodash/get'; import PropTypes from 'prop-types'; import React, {useCallback} from 'react'; +import {withOnyx} from 'react-native-onyx'; import AvatarWithIndicator from '@components/AvatarWithIndicator'; import OfflineWithFeedback from '@components/OfflineWithFeedback'; import PressableWithoutFeedback from '@components/Pressable/PressableWithoutFeedback'; import withCurrentUserPersonalDetails from '@components/withCurrentUserPersonalDetails'; import useLocalize from '@hooks/useLocalize'; +import compose from '@libs/compose'; import Navigation from '@libs/Navigation/Navigation'; import * as UserUtils from '@libs/UserUtils'; import personalDetailsPropType from '@pages/personalDetailsPropType'; import CONST from '@src/CONST'; +import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; const propTypes = { @@ -19,6 +22,9 @@ const propTypes = { /** The personal details of the person who is logged in */ currentUserPersonalDetails: personalDetailsPropType, + + /** Indicates whether the app is loading initial data */ + isLoading: PropTypes.bool, }; const defaultProps = { @@ -28,9 +34,10 @@ const defaultProps = { accountID: '', avatar: '', }, + isLoading: true, }; -function PressableAvatarWithIndicator({isCreateMenuOpen, currentUserPersonalDetails}) { +function PressableAvatarWithIndicator({isCreateMenuOpen, currentUserPersonalDetails, isLoading}) { const {translate} = useLocalize(); const showSettingsPage = useCallback(() => { @@ -53,6 +60,7 @@ function PressableAvatarWithIndicator({isCreateMenuOpen, currentUserPersonalDeta source={UserUtils.getAvatar(currentUserPersonalDetails.avatar, currentUserPersonalDetails.accountID)} tooltipText={translate('common.settings')} fallbackIcon={currentUserPersonalDetails.fallbackIcon} + isLoading={isLoading && !currentUserPersonalDetails.avatar} /> @@ -62,4 +70,11 @@ function PressableAvatarWithIndicator({isCreateMenuOpen, currentUserPersonalDeta PressableAvatarWithIndicator.propTypes = propTypes; PressableAvatarWithIndicator.defaultProps = defaultProps; PressableAvatarWithIndicator.displayName = 'PressableAvatarWithIndicator'; -export default withCurrentUserPersonalDetails(PressableAvatarWithIndicator); +export default compose( + withCurrentUserPersonalDetails, + withOnyx({ + isLoading: { + key: ONYXKEYS.IS_LOADING_APP, + }, + }), +)(PressableAvatarWithIndicator); diff --git a/src/styles/styles.ts b/src/styles/styles.ts index 589c3756042f..49714d23eb61 100644 --- a/src/styles/styles.ts +++ b/src/styles/styles.ts @@ -1327,6 +1327,10 @@ const styles = (theme: ThemeDefault) => width: variables.componentSizeNormal, }, + skeletonAvatar: { + backgroundColor: theme.skeletonLHNIn, + }, + statusIndicator: (backgroundColor = theme.danger) => ({ borderColor: theme.sidebar, From 52ff093865e5f7a3914da7d84cb2aa6615bf6752 Mon Sep 17 00:00:00 2001 From: Yauheni Pasiukevich Date: Fri, 27 Oct 2023 15:38:00 +0200 Subject: [PATCH 055/212] [TS migration] Migrate 'MentionSuggestions.js' component to TypeScript --- src/components/AvatarTypes.ts | 13 +++ ...nSuggestions.js => MentionSuggestions.tsx} | 103 ++++++++---------- src/styles/StyleUtils.ts | 4 +- 3 files changed, 61 insertions(+), 59 deletions(-) create mode 100644 src/components/AvatarTypes.ts rename src/components/{MentionSuggestions.js => MentionSuggestions.tsx} (56%) diff --git a/src/components/AvatarTypes.ts b/src/components/AvatarTypes.ts new file mode 100644 index 000000000000..2e94904b0d7c --- /dev/null +++ b/src/components/AvatarTypes.ts @@ -0,0 +1,13 @@ +import CONST from '@src/CONST'; + +type AvatarFunctionType = () => void; + +type AvatarType = { + source: string | AvatarFunctionType; + type: typeof CONST.ICON_TYPE_AVATAR | typeof CONST.ICON_TYPE_WORKSPACE; + name: string; + id: number | string; + fallbackIcon: string | AvatarFunctionType; +}; + +export default AvatarType; diff --git a/src/components/MentionSuggestions.js b/src/components/MentionSuggestions.tsx similarity index 56% rename from src/components/MentionSuggestions.js rename to src/components/MentionSuggestions.tsx index d18b8947e68d..fe7ce2896bfc 100644 --- a/src/components/MentionSuggestions.js +++ b/src/components/MentionSuggestions.tsx @@ -1,7 +1,5 @@ -import PropTypes from 'prop-types'; import React from 'react'; import {View} from 'react-native'; -import _ from 'underscore'; import getStyledTextArray from '@libs/GetStyledTextArray'; import styles from '@styles/styles'; import * as StyleUtils from '@styles/StyleUtils'; @@ -9,65 +7,58 @@ import themeColors from '@styles/themes/default'; import CONST from '@src/CONST'; import AutoCompleteSuggestions from './AutoCompleteSuggestions'; import Avatar from './Avatar'; -import avatarPropTypes from './avatarPropTypes'; +import AvatarTypes from './AvatarTypes'; import Text from './Text'; -const propTypes = { - /** The index of the highlighted mention */ - highlightedMentionIndex: PropTypes.number, +type Mention = { + /** Display name of the user */ + text: string; - /** Array of suggested mentions */ - mentions: PropTypes.arrayOf( - PropTypes.shape({ - /** Display name of the user */ - text: PropTypes.string, + /** Email/phone number of the user */ + alternateText: string; + + /** Array of icons of the user. We use the first element of this array */ + icons: AvatarTypes[]; +}; - /** Email/phone number of the user */ - alternateText: PropTypes.string, +type MentionSuggestionsProps = { + /** The index of the highlighted mention */ + highlightedMentionIndex?: number; - /** Array of icons of the user. We use the first element of this array */ - icons: PropTypes.arrayOf(avatarPropTypes), - }), - ).isRequired, + /** Array of suggested mentions */ + mentions: Mention[]; /** Fired when the user selects an mention */ - onSelect: PropTypes.func.isRequired, + onSelect: () => void; /** Mention prefix that follows the @ sign */ - prefix: PropTypes.string.isRequired, + prefix: string; /** Show that we can use large mention picker. * Depending on available space and whether the input is expanded, we can have a small or large mention suggester. * When this value is false, the suggester will have a height of 2.5 items. When this value is true, the height can be up to 5 items. */ - isMentionPickerLarge: PropTypes.bool.isRequired, + isMentionPickerLarge: boolean; /** Meaures the parent container's position and dimensions. */ - measureParentContainer: PropTypes.func, -}; - -const defaultProps = { - highlightedMentionIndex: 0, - measureParentContainer: () => {}, + measureParentContainer: () => void; }; /** * Create unique keys for each mention item - * @param {Object} item - * @param {Number} index - * @returns {String} + * @param item + * @param index */ -const keyExtractor = (item) => item.alternateText; +const keyExtractor = (item: Mention) => item.alternateText; -function MentionSuggestions(props) { +function MentionSuggestions({prefix, mentions, highlightedMentionIndex = 0, onSelect, isMentionPickerLarge, measureParentContainer = () => {}}: MentionSuggestionsProps) { /** * Render a suggestion menu item component. - * @param {Object} item - * @returns {JSX.Element} + * @param item */ - const renderSuggestionMenuItem = (item) => { + const renderSuggestionMenuItem = (item: Mention) => { const isIcon = item.text === CONST.AUTO_COMPLETE_SUGGESTER.HERE_TEXT; - const styledDisplayName = getStyledTextArray(item.text, props.prefix); - const styledHandle = item.text === item.alternateText ? '' : getStyledTextArray(item.alternateText, props.prefix); + const styledDisplayName = getStyledTextArray(item.text, prefix); + const styledHandle = item.text === item.alternateText ? '' : getStyledTextArray(item.alternateText, prefix); return ( @@ -85,9 +76,9 @@ function MentionSuggestions(props) { style={[styles.mentionSuggestionsText, styles.flexShrink1]} numberOfLines={1} > - {_.map(styledDisplayName, ({text, isColored}, i) => ( + {styledDisplayName.map(({text, isColored}) => ( {text} @@ -98,18 +89,18 @@ function MentionSuggestions(props) { style={[styles.mentionSuggestionsText, styles.flex1]} numberOfLines={1} > - {_.map( - styledHandle, - ({text, isColored}, i) => - text !== '' && ( - - {text} - - ), - )} + {styledHandle && + styledHandle.map( + ({text, isColored}) => + text !== '' && ( + + {text} + + ), + )} ); @@ -117,20 +108,18 @@ function MentionSuggestions(props) { return ( ); } -MentionSuggestions.propTypes = propTypes; -MentionSuggestions.defaultProps = defaultProps; MentionSuggestions.displayName = 'MentionSuggestions'; export default MentionSuggestions; diff --git a/src/styles/StyleUtils.ts b/src/styles/StyleUtils.ts index f58d2c9a236d..77fe3dea9faa 100644 --- a/src/styles/StyleUtils.ts +++ b/src/styles/StyleUtils.ts @@ -1,5 +1,5 @@ import {CSSProperties} from 'react'; -import {Animated, DimensionValue, ImageStyle, PressableStateCallbackType, TextStyle, ViewStyle} from 'react-native'; +import {Animated, DimensionValue, ImageStyle, PressableStateCallbackType, StyleProp, TextStyle, ViewStyle} from 'react-native'; import {EdgeInsets} from 'react-native-safe-area-context'; import {ValueOf} from 'type-fest'; import * as Browser from '@libs/Browser'; @@ -1012,7 +1012,7 @@ function getAutoCompleteSuggestionContainerStyle(itemsHeight: number): ViewStyle /** * Select the correct color for text. */ -function getColoredBackgroundStyle(isColored: boolean): ViewStyle { +function getColoredBackgroundStyle(isColored: boolean): StyleProp | undefined { return {backgroundColor: isColored ? themeColors.link : undefined}; } From 7ce4f40b9c50b373cc335abff22b647a879ce4fe Mon Sep 17 00:00:00 2001 From: Yauheni Pasiukevich Date: Tue, 31 Oct 2023 12:54:17 +0100 Subject: [PATCH 056/212] remove redundant styles --- src/styles/styles.ts | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/src/styles/styles.ts b/src/styles/styles.ts index 589c3756042f..51dd70e70f2e 100644 --- a/src/styles/styles.ts +++ b/src/styles/styles.ts @@ -326,10 +326,6 @@ const styles = (theme: ThemeDefault) => textAlign: 'left', }, - textUnderline: { - textDecorationLine: 'underline', - }, - label: { fontSize: variables.fontSizeLabel, lineHeight: variables.lineHeightLarge, @@ -382,10 +378,6 @@ const styles = (theme: ThemeDefault) => fontSize: variables.fontSizeLarge, }, - textXLarge: { - fontSize: variables.fontSizeXLarge, - }, - textXXLarge: { fontSize: variables.fontSizeXXLarge, }, @@ -405,11 +397,6 @@ const styles = (theme: ThemeDefault) => fontWeight: fontWeightBold, }, - textItalic: { - fontFamily: fontFamily.EXP_NEUE_ITALIC, - fontStyle: 'italic', - }, - textHeadline: { ...headlineFont, ...whiteSpace.preWrap, @@ -426,10 +413,6 @@ const styles = (theme: ThemeDefault) => lineHeight: variables.lineHeightSizeh1, }, - textDecorationNoLine: { - textDecorationLine: 'none', - }, - textWhite: { color: theme.textLight, }, @@ -438,10 +421,6 @@ const styles = (theme: ThemeDefault) => color: theme.link, }, - textUppercase: { - textTransform: 'uppercase', - }, - textNoWrap: { ...whiteSpace.noWrap, }, From 06ee840dfb68c752b50b4f967f67db1733279db5 Mon Sep 17 00:00:00 2001 From: Yauheni Pasiukevich Date: Tue, 31 Oct 2023 14:37:58 +0100 Subject: [PATCH 057/212] move prop type to types --- src/components/ErrorBoundary/BaseErrorBoundary.tsx | 12 +----------- src/components/ErrorBoundary/index.native.tsx | 4 ++-- src/components/ErrorBoundary/index.tsx | 4 ++-- src/components/ErrorBoundary/types.ts | 13 ++++++++++++- 4 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/components/ErrorBoundary/BaseErrorBoundary.tsx b/src/components/ErrorBoundary/BaseErrorBoundary.tsx index 27ea79950507..2a6524d5a993 100644 --- a/src/components/ErrorBoundary/BaseErrorBoundary.tsx +++ b/src/components/ErrorBoundary/BaseErrorBoundary.tsx @@ -2,18 +2,8 @@ import React from 'react'; import {ErrorBoundary} from 'react-error-boundary'; import BootSplash from '@libs/BootSplash'; import GenericErrorPage from '@pages/ErrorPage/GenericErrorPage'; -import LogError from './types'; +import {BaseErrorBoundaryProps, LogError} from './types'; -type BaseErrorBoundaryProps = { - /* A message posted to `logError` (along with error data) when this component intercepts an error */ - errorMessage: string; - - /* A function to perform the actual logging since different platforms support different tools */ - logError?: LogError; - - /* Actual content wrapped by this error boundary */ - children: React.ReactNode; -}; /** * This component captures an error in the child component tree and logs it to the server * It can be used to wrap the entire app as well as to wrap specific parts for more granularity diff --git a/src/components/ErrorBoundary/index.native.tsx b/src/components/ErrorBoundary/index.native.tsx index 20f90a122d25..125ff81ca110 100644 --- a/src/components/ErrorBoundary/index.native.tsx +++ b/src/components/ErrorBoundary/index.native.tsx @@ -1,7 +1,7 @@ import crashlytics from '@react-native-firebase/crashlytics'; import Log from '@libs/Log'; -import BaseErrorBoundary, {BaseErrorBoundaryProps} from './BaseErrorBoundary'; -import LogError from './types'; +import BaseErrorBoundary from './BaseErrorBoundary'; +import {BaseErrorBoundaryProps, LogError} from './types'; const logError: LogError = (errorMessage, error, errorInfo) => { // Log the error to the server diff --git a/src/components/ErrorBoundary/index.tsx b/src/components/ErrorBoundary/index.tsx index 5d54951a3838..9bc3dc748e8e 100644 --- a/src/components/ErrorBoundary/index.tsx +++ b/src/components/ErrorBoundary/index.tsx @@ -1,6 +1,6 @@ import Log from '@libs//Log'; -import BaseErrorBoundary, {BaseErrorBoundaryProps} from './BaseErrorBoundary'; -import LogError from './types'; +import BaseErrorBoundary from './BaseErrorBoundary'; +import {BaseErrorBoundaryProps, LogError} from './types'; const logError: LogError = (errorMessage, error, errorInfo) => { // Log the error to the server diff --git a/src/components/ErrorBoundary/types.ts b/src/components/ErrorBoundary/types.ts index ea534cd7b4d7..61127f3ce4e9 100644 --- a/src/components/ErrorBoundary/types.ts +++ b/src/components/ErrorBoundary/types.ts @@ -1,3 +1,14 @@ type LogError = (message: string, error: Error, errorInfo: string) => void; -export default LogError; +type BaseErrorBoundaryProps = { + /* A message posted to `logError` (along with error data) when this component intercepts an error */ + errorMessage: string; + + /* A function to perform the actual logging since different platforms support different tools */ + logError?: LogError; + + /* Actual content wrapped by this error boundary */ + children: React.ReactNode; +}; + +export type {BaseErrorBoundaryProps, LogError}; From 934b666ff33bc163e85abc14059fea0b6f351498 Mon Sep 17 00:00:00 2001 From: dukenv0307 Date: Wed, 1 Nov 2023 17:55:58 +0700 Subject: [PATCH 058/212] create skeleton avtar component --- src/components/AvatarSkeleton.js | 36 +++++++++++++++++++++++++++ src/components/AvatarWithIndicator.js | 7 ++++-- src/styles/styles.ts | 4 --- 3 files changed, 41 insertions(+), 6 deletions(-) create mode 100644 src/components/AvatarSkeleton.js diff --git a/src/components/AvatarSkeleton.js b/src/components/AvatarSkeleton.js new file mode 100644 index 000000000000..3bd940e13078 --- /dev/null +++ b/src/components/AvatarSkeleton.js @@ -0,0 +1,36 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import {Circle} from 'react-native-svg'; +import themeColors from '@styles/themes/default'; +import SkeletonViewContentLoader from './SkeletonViewContentLoader'; + +const propTypes = { + /** */ + shouldAnimate: PropTypes.bool, +}; + +const defaultTypes = { + shouldAnimate: true, +}; + +function AvatarSkeleton(props) { + return ( + + + + ); +} + +AvatarSkeleton.propTypes = propTypes; +AvatarSkeleton.defaultProps = defaultTypes; +AvatarSkeleton.displayName = 'AvatarSkeleton'; +export default AvatarSkeleton; diff --git a/src/components/AvatarWithIndicator.js b/src/components/AvatarWithIndicator.js index 4af8074b57da..0cfd618a5819 100644 --- a/src/components/AvatarWithIndicator.js +++ b/src/components/AvatarWithIndicator.js @@ -4,6 +4,7 @@ import {View} from 'react-native'; import * as UserUtils from '@libs/UserUtils'; import styles from '@styles/styles'; import Avatar from './Avatar'; +import AvatarSkeleton from './AvatarSkeleton'; import * as Expensicons from './Icon/Expensicons'; import Indicator from './Indicator'; import Tooltip from './Tooltip'; @@ -31,8 +32,8 @@ const defaultProps = { function AvatarWithIndicator(props) { return ( - - {!props.isLoading && ( + + {!props.isLoading ? ( <> + ) : ( + )} diff --git a/src/styles/styles.ts b/src/styles/styles.ts index 49714d23eb61..589c3756042f 100644 --- a/src/styles/styles.ts +++ b/src/styles/styles.ts @@ -1327,10 +1327,6 @@ const styles = (theme: ThemeDefault) => width: variables.componentSizeNormal, }, - skeletonAvatar: { - backgroundColor: theme.skeletonLHNIn, - }, - statusIndicator: (backgroundColor = theme.danger) => ({ borderColor: theme.sidebar, From d4ef364e86a07248b0d926d756a0343d810cf780 Mon Sep 17 00:00:00 2001 From: dukenv0307 Date: Thu, 2 Nov 2023 12:04:03 +0700 Subject: [PATCH 059/212] add onMounseDown for sign icon --- src/components/SignInButtons/AppleSignIn/index.website.js | 2 ++ src/components/SignInButtons/GoogleSignIn/index.website.js | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/components/SignInButtons/AppleSignIn/index.website.js b/src/components/SignInButtons/AppleSignIn/index.website.js index adae0a691e13..587b6dbec983 100644 --- a/src/components/SignInButtons/AppleSignIn/index.website.js +++ b/src/components/SignInButtons/AppleSignIn/index.website.js @@ -93,6 +93,7 @@ function AppleSignInDiv({isDesktopFlow}) { data-width={CONST.SIGN_IN_FORM_WIDTH} data-height="52" style={{cursor: 'pointer'}} + onMouseDown={(event) => event.preventDefault()} /> ) : (
event.preventDefault()} /> ); } diff --git a/src/components/SignInButtons/GoogleSignIn/index.website.js b/src/components/SignInButtons/GoogleSignIn/index.website.js index 7f3a3019c318..be4b944822dd 100644 --- a/src/components/SignInButtons/GoogleSignIn/index.website.js +++ b/src/components/SignInButtons/GoogleSignIn/index.website.js @@ -76,6 +76,7 @@ function GoogleSignIn({translate, isDesktopFlow}) { id={desktopId} role="button" aria-label={translate('common.signInWithGoogle')} + onMouseDown={(event) => event.preventDefault()} /> ) : ( @@ -84,6 +85,7 @@ function GoogleSignIn({translate, isDesktopFlow}) { id={mainId} role="button" aria-label={translate('common.signInWithGoogle')} + onMouseDown={(event) => event.preventDefault()} /> ); From 5d42500bfc78c8a03fa82dcab00b987baf44d8b4 Mon Sep 17 00:00:00 2001 From: dukenv0307 Date: Thu, 2 Nov 2023 17:12:51 +0700 Subject: [PATCH 060/212] fix bug on desktop --- src/components/SignInButtons/AppleSignIn/index.desktop.js | 7 +++++-- src/components/SignInButtons/GoogleSignIn/index.desktop.js | 2 +- src/components/SignInButtons/IconButton.js | 7 ++++++- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/components/SignInButtons/AppleSignIn/index.desktop.js b/src/components/SignInButtons/AppleSignIn/index.desktop.js index cad37d585de4..fac187c6fcc4 100644 --- a/src/components/SignInButtons/AppleSignIn/index.desktop.js +++ b/src/components/SignInButtons/AppleSignIn/index.desktop.js @@ -14,9 +14,12 @@ const appleSignInWebRouteForDesktopFlow = `${CONFIG.EXPENSIFY.NEW_EXPENSIFY_URL} */ function AppleSignIn() { return ( - + { + onPressIn={() => { window.open(appleSignInWebRouteForDesktopFlow); }} provider={CONST.SIGN_IN_METHOD.APPLE} diff --git a/src/components/SignInButtons/GoogleSignIn/index.desktop.js b/src/components/SignInButtons/GoogleSignIn/index.desktop.js index e69905dcad05..b2f3cb01a980 100644 --- a/src/components/SignInButtons/GoogleSignIn/index.desktop.js +++ b/src/components/SignInButtons/GoogleSignIn/index.desktop.js @@ -19,7 +19,7 @@ function GoogleSignIn() { return ( { + onPressIn={() => { window.open(googleSignInWebRouteForDesktopFlow); }} provider={CONST.SIGN_IN_METHOD.GOOGLE} diff --git a/src/components/SignInButtons/IconButton.js b/src/components/SignInButtons/IconButton.js index 0d18779ea9ba..49d7dccea59e 100644 --- a/src/components/SignInButtons/IconButton.js +++ b/src/components/SignInButtons/IconButton.js @@ -11,6 +11,9 @@ const propTypes = { /** The on press method */ onPress: PropTypes.func, + /** The on press in method */ + onPressIn: PropTypes.func, + /** Which provider you are using to sign in */ provider: PropTypes.string.isRequired, @@ -19,6 +22,7 @@ const propTypes = { const defaultProps = { onPress: () => {}, + onPressIn: () => {}, }; const providerData = { @@ -32,9 +36,10 @@ const providerData = { }, }; -function IconButton({onPress, translate, provider}) { +function IconButton({onPress, translate, provider, onPressIn}) { return ( Date: Thu, 2 Nov 2023 13:24:44 +0100 Subject: [PATCH 061/212] change namings, props --- src/components/AvatarType.ts | 14 ++++++++++++++ src/components/AvatarTypes.ts | 13 ------------- src/components/MentionSuggestions.tsx | 6 +++--- 3 files changed, 17 insertions(+), 16 deletions(-) create mode 100644 src/components/AvatarType.ts delete mode 100644 src/components/AvatarTypes.ts diff --git a/src/components/AvatarType.ts b/src/components/AvatarType.ts new file mode 100644 index 000000000000..dc07a638106d --- /dev/null +++ b/src/components/AvatarType.ts @@ -0,0 +1,14 @@ +import CONST from '@src/CONST'; + + +type AvatarFunction = () => void; + +type Avatar = { + source?: string | AvatarFunction; + type?: typeof CONST.ICON_TYPE_AVATAR | typeof CONST.ICON_TYPE_WORKSPACE; + name?: string; + id?: number | string; + fallbackIcon?: string | AvatarFunction; +}; + +export default Avatar; diff --git a/src/components/AvatarTypes.ts b/src/components/AvatarTypes.ts deleted file mode 100644 index 2e94904b0d7c..000000000000 --- a/src/components/AvatarTypes.ts +++ /dev/null @@ -1,13 +0,0 @@ -import CONST from '@src/CONST'; - -type AvatarFunctionType = () => void; - -type AvatarType = { - source: string | AvatarFunctionType; - type: typeof CONST.ICON_TYPE_AVATAR | typeof CONST.ICON_TYPE_WORKSPACE; - name: string; - id: number | string; - fallbackIcon: string | AvatarFunctionType; -}; - -export default AvatarType; diff --git a/src/components/MentionSuggestions.tsx b/src/components/MentionSuggestions.tsx index fe7ce2896bfc..fdff35638766 100644 --- a/src/components/MentionSuggestions.tsx +++ b/src/components/MentionSuggestions.tsx @@ -7,7 +7,7 @@ import themeColors from '@styles/themes/default'; import CONST from '@src/CONST'; import AutoCompleteSuggestions from './AutoCompleteSuggestions'; import Avatar from './Avatar'; -import AvatarTypes from './AvatarTypes'; +import AvatarType from './AvatarType'; import Text from './Text'; type Mention = { @@ -18,7 +18,7 @@ type Mention = { alternateText: string; /** Array of icons of the user. We use the first element of this array */ - icons: AvatarTypes[]; + icons: AvatarType[]; }; type MentionSuggestionsProps = { @@ -92,7 +92,7 @@ function MentionSuggestions({prefix, mentions, highlightedMentionIndex = 0, onSe {styledHandle && styledHandle.map( ({text, isColored}) => - text !== '' && ( + Boolean(text) && ( Date: Thu, 2 Nov 2023 14:18:16 +0100 Subject: [PATCH 062/212] revert to map with index key --- src/components/MentionSuggestions.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/MentionSuggestions.tsx b/src/components/MentionSuggestions.tsx index fdff35638766..74f8503881ab 100644 --- a/src/components/MentionSuggestions.tsx +++ b/src/components/MentionSuggestions.tsx @@ -76,9 +76,9 @@ function MentionSuggestions({prefix, mentions, highlightedMentionIndex = 0, onSe style={[styles.mentionSuggestionsText, styles.flexShrink1]} numberOfLines={1} > - {styledDisplayName.map(({text, isColored}) => ( + {styledDisplayName.map(({text, isColored}, i) => ( {text} @@ -91,10 +91,10 @@ function MentionSuggestions({prefix, mentions, highlightedMentionIndex = 0, onSe > {styledHandle && styledHandle.map( - ({text, isColored}) => + ({text, isColored}, i) => Boolean(text) && ( {text} From 9c256ed3f41c2b76d9568cfc9359aee6cd857a42 Mon Sep 17 00:00:00 2001 From: Yauheni Pasiukevich Date: Thu, 2 Nov 2023 14:27:43 +0100 Subject: [PATCH 063/212] change type name --- src/components/{AvatarType.ts => AvatarIconType.ts} | 4 ++-- src/components/MentionSuggestions.tsx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) rename src/components/{AvatarType.ts => AvatarIconType.ts} (85%) diff --git a/src/components/AvatarType.ts b/src/components/AvatarIconType.ts similarity index 85% rename from src/components/AvatarType.ts rename to src/components/AvatarIconType.ts index dc07a638106d..117fbd2b085a 100644 --- a/src/components/AvatarType.ts +++ b/src/components/AvatarIconType.ts @@ -3,7 +3,7 @@ import CONST from '@src/CONST'; type AvatarFunction = () => void; -type Avatar = { +type AvatarIcon = { source?: string | AvatarFunction; type?: typeof CONST.ICON_TYPE_AVATAR | typeof CONST.ICON_TYPE_WORKSPACE; name?: string; @@ -11,4 +11,4 @@ type Avatar = { fallbackIcon?: string | AvatarFunction; }; -export default Avatar; +export default AvatarIcon; diff --git a/src/components/MentionSuggestions.tsx b/src/components/MentionSuggestions.tsx index 74f8503881ab..23274fd8fa36 100644 --- a/src/components/MentionSuggestions.tsx +++ b/src/components/MentionSuggestions.tsx @@ -7,7 +7,7 @@ import themeColors from '@styles/themes/default'; import CONST from '@src/CONST'; import AutoCompleteSuggestions from './AutoCompleteSuggestions'; import Avatar from './Avatar'; -import AvatarType from './AvatarType'; +import AvatarIcon from './AvatarIconType'; import Text from './Text'; type Mention = { @@ -18,7 +18,7 @@ type Mention = { alternateText: string; /** Array of icons of the user. We use the first element of this array */ - icons: AvatarType[]; + icons: AvatarIcon[]; }; type MentionSuggestionsProps = { From 6ac09c50823b6b9de8f6f7b71b9ab1dea4b8e119 Mon Sep 17 00:00:00 2001 From: Yauheni Pasiukevich Date: Thu, 2 Nov 2023 14:29:25 +0100 Subject: [PATCH 064/212] remove optional for some props --- src/components/AvatarIconType.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/AvatarIconType.ts b/src/components/AvatarIconType.ts index 117fbd2b085a..5e05d357e2d3 100644 --- a/src/components/AvatarIconType.ts +++ b/src/components/AvatarIconType.ts @@ -4,10 +4,10 @@ import CONST from '@src/CONST'; type AvatarFunction = () => void; type AvatarIcon = { - source?: string | AvatarFunction; - type?: typeof CONST.ICON_TYPE_AVATAR | typeof CONST.ICON_TYPE_WORKSPACE; - name?: string; - id?: number | string; + source: string | AvatarFunction; + type: typeof CONST.ICON_TYPE_AVATAR | typeof CONST.ICON_TYPE_WORKSPACE; + name: string; + id: number | string; fallbackIcon?: string | AvatarFunction; }; From 4ed174463cb98a6252c241ade052d643d4c099db Mon Sep 17 00:00:00 2001 From: Yauheni Pasiukevich Date: Thu, 2 Nov 2023 15:32:11 +0100 Subject: [PATCH 065/212] fix lint --- src/components/AvatarIconType.ts | 1 - src/components/MentionSuggestions.tsx | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/AvatarIconType.ts b/src/components/AvatarIconType.ts index 5e05d357e2d3..192acabb2399 100644 --- a/src/components/AvatarIconType.ts +++ b/src/components/AvatarIconType.ts @@ -1,6 +1,5 @@ import CONST from '@src/CONST'; - type AvatarFunction = () => void; type AvatarIcon = { diff --git a/src/components/MentionSuggestions.tsx b/src/components/MentionSuggestions.tsx index 23274fd8fa36..a7a67edafff0 100644 --- a/src/components/MentionSuggestions.tsx +++ b/src/components/MentionSuggestions.tsx @@ -78,6 +78,7 @@ function MentionSuggestions({prefix, mentions, highlightedMentionIndex = 0, onSe > {styledDisplayName.map(({text, isColored}, i) => ( @@ -94,6 +95,7 @@ function MentionSuggestions({prefix, mentions, highlightedMentionIndex = 0, onSe ({text, isColored}, i) => Boolean(text) && ( From ed3bc9906da6cb90119ba653bb22946c605c034a Mon Sep 17 00:00:00 2001 From: AmjedNazzal Date: Fri, 3 Nov 2023 10:38:06 +0300 Subject: [PATCH 066/212] Fix Issue #28474 --- src/components/AddressSearch/index.js | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/components/AddressSearch/index.js b/src/components/AddressSearch/index.js index 3e122e029969..e57952c03850 100644 --- a/src/components/AddressSearch/index.js +++ b/src/components/AddressSearch/index.js @@ -1,3 +1,4 @@ +import ExpensiMark from 'expensify-common/lib/ExpensiMark'; import lodashGet from 'lodash/get'; import PropTypes from 'prop-types'; import React, {useEffect, useMemo, useRef, useState} from 'react'; @@ -254,6 +255,31 @@ function AddressSearch(props) { values.state = stateFallback; } + // Some edge-case addresses may lack both street_number and route in the API response, resulting in an empty "values.street" + // We are setting up a fallback to ensure "values.street" is populated with a relevant value + if(!values.street){ + const { adr_address } = details; + const streetAddressRegex = /(]*>[^<]*<\/span>)/; + const streetAddressHtml = adr_address.match(streetAddressRegex); + if (streetAddressHtml[1]) { + const parser = new ExpensiMark(); + const streetFallback = parser.htmlToText(streetAddressHtml[1]); + values.street = streetFallback; + } + else { + let streetFallback = ''; + const excludedTypes = ['country', 'administrative_area_level_1', 'administrative_area_level_2', 'postal_code']; + addressComponents.forEach((addressComponent) => { + if (excludedTypes.some(excludedType => addressComponent.types.includes(excludedType))) { + return; + } + const value = addressComponent['long_name'] || ''; + streetFallback += value + ' '; + }); + values.street = streetFallback.trim(); + } + } + // Not all pages define the Address Line 2 field, so in that case we append any additional address details // (e.g. Apt #) to Address Line 1 if (subpremise && typeof props.renamedInputKeys.street2 === 'undefined') { From b6803588628af1fa040bfcbb2c451cdef4a5df7f Mon Sep 17 00:00:00 2001 From: AmjedNazzal Date: Fri, 3 Nov 2023 11:24:36 +0300 Subject: [PATCH 067/212] Fix Issue #28474 small change --- src/components/AddressSearch/index.js | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/components/AddressSearch/index.js b/src/components/AddressSearch/index.js index e57952c03850..ef0535b02d2c 100644 --- a/src/components/AddressSearch/index.js +++ b/src/components/AddressSearch/index.js @@ -257,27 +257,26 @@ function AddressSearch(props) { // Some edge-case addresses may lack both street_number and route in the API response, resulting in an empty "values.street" // We are setting up a fallback to ensure "values.street" is populated with a relevant value - if(!values.street){ - const { adr_address } = details; + if (!values.street) { + const {adr_address} = details; const streetAddressRegex = /(]*>[^<]*<\/span>)/; const streetAddressHtml = adr_address.match(streetAddressRegex); if (streetAddressHtml[1]) { const parser = new ExpensiMark(); const streetFallback = parser.htmlToText(streetAddressHtml[1]); values.street = streetFallback; - } - else { + } else { let streetFallback = ''; const excludedTypes = ['country', 'administrative_area_level_1', 'administrative_area_level_2', 'postal_code']; addressComponents.forEach((addressComponent) => { - if (excludedTypes.some(excludedType => addressComponent.types.includes(excludedType))) { - return; + if (_.some(excludedTypes, (excludedType) => _.includes(addressComponent.types, excludedType))) { + return; } - const value = addressComponent['long_name'] || ''; - streetFallback += value + ' '; + const value = addressComponent.long_name || ''; + streetFallback = `${streetFallback}${value} `; }); - values.street = streetFallback.trim(); - } + values.street = streetFallback.trim(); + } } // Not all pages define the Address Line 2 field, so in that case we append any additional address details From 0138d943fc97c4576e41cb0fd937bb8b7d7bf2d0 Mon Sep 17 00:00:00 2001 From: Yauheni Pasiukevich Date: Fri, 3 Nov 2023 11:50:13 +0100 Subject: [PATCH 068/212] change types, mapping --- src/components/AvatarIconType.ts | 13 --------- src/components/MentionSuggestions.tsx | 42 +++++++++++++++------------ src/styles/StyleUtils.ts | 2 +- 3 files changed, 25 insertions(+), 32 deletions(-) delete mode 100644 src/components/AvatarIconType.ts diff --git a/src/components/AvatarIconType.ts b/src/components/AvatarIconType.ts deleted file mode 100644 index 192acabb2399..000000000000 --- a/src/components/AvatarIconType.ts +++ /dev/null @@ -1,13 +0,0 @@ -import CONST from '@src/CONST'; - -type AvatarFunction = () => void; - -type AvatarIcon = { - source: string | AvatarFunction; - type: typeof CONST.ICON_TYPE_AVATAR | typeof CONST.ICON_TYPE_WORKSPACE; - name: string; - id: number | string; - fallbackIcon?: string | AvatarFunction; -}; - -export default AvatarIcon; diff --git a/src/components/MentionSuggestions.tsx b/src/components/MentionSuggestions.tsx index a7a67edafff0..c9f7e93d173e 100644 --- a/src/components/MentionSuggestions.tsx +++ b/src/components/MentionSuggestions.tsx @@ -7,9 +7,19 @@ import themeColors from '@styles/themes/default'; import CONST from '@src/CONST'; import AutoCompleteSuggestions from './AutoCompleteSuggestions'; import Avatar from './Avatar'; -import AvatarIcon from './AvatarIconType'; import Text from './Text'; +// TODO: remove when avatarPropTypes will be migrated to TS +type AvatarFunction = () => void; + +type AvatarIcon = { + source: string | AvatarFunction; + type: typeof CONST.ICON_TYPE_AVATAR | typeof CONST.ICON_TYPE_WORKSPACE; + name: string; + id: number | string; + fallbackIcon?: string | AvatarFunction; +}; + type Mention = { /** Display name of the user */ text: string; @@ -45,20 +55,17 @@ type MentionSuggestionsProps = { /** * Create unique keys for each mention item - * @param item - * @param index */ const keyExtractor = (item: Mention) => item.alternateText; function MentionSuggestions({prefix, mentions, highlightedMentionIndex = 0, onSelect, isMentionPickerLarge, measureParentContainer = () => {}}: MentionSuggestionsProps) { /** * Render a suggestion menu item component. - * @param item */ const renderSuggestionMenuItem = (item: Mention) => { const isIcon = item.text === CONST.AUTO_COMPLETE_SUGGESTER.HERE_TEXT; const styledDisplayName = getStyledTextArray(item.text, prefix); - const styledHandle = item.text === item.alternateText ? '' : getStyledTextArray(item.alternateText, prefix); + const styledHandle = item.text === item.alternateText ? undefined : getStyledTextArray(item.alternateText, prefix); return ( @@ -90,19 +97,18 @@ function MentionSuggestions({prefix, mentions, highlightedMentionIndex = 0, onSe style={[styles.mentionSuggestionsText, styles.flex1]} numberOfLines={1} > - {styledHandle && - styledHandle.map( - ({text, isColored}, i) => - Boolean(text) && ( - - {text} - - ), - )} + {styledHandle?.map( + ({text, isColored}, i) => + Boolean(text) && ( + + {text} + + ), + )} ); diff --git a/src/styles/StyleUtils.ts b/src/styles/StyleUtils.ts index 77fe3dea9faa..393940070895 100644 --- a/src/styles/StyleUtils.ts +++ b/src/styles/StyleUtils.ts @@ -1012,7 +1012,7 @@ function getAutoCompleteSuggestionContainerStyle(itemsHeight: number): ViewStyle /** * Select the correct color for text. */ -function getColoredBackgroundStyle(isColored: boolean): StyleProp | undefined { +function getColoredBackgroundStyle(isColored: boolean): StyleProp { return {backgroundColor: isColored ? themeColors.link : undefined}; } From dab085cfab08cd6e8ccfe2d13448979064f8cf5e Mon Sep 17 00:00:00 2001 From: Yauheni Pasiukevich Date: Fri, 3 Nov 2023 14:49:26 +0100 Subject: [PATCH 069/212] reuse existed Icon type --- src/components/MentionSuggestions.tsx | 14 ++------------ src/types/onyx/OnyxCommon.ts | 7 +++++-- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/src/components/MentionSuggestions.tsx b/src/components/MentionSuggestions.tsx index c9f7e93d173e..a009364c2223 100644 --- a/src/components/MentionSuggestions.tsx +++ b/src/components/MentionSuggestions.tsx @@ -5,21 +5,11 @@ import styles from '@styles/styles'; import * as StyleUtils from '@styles/StyleUtils'; import themeColors from '@styles/themes/default'; import CONST from '@src/CONST'; +import {Icon} from '@src/types/onyx/OnyxCommon'; import AutoCompleteSuggestions from './AutoCompleteSuggestions'; import Avatar from './Avatar'; import Text from './Text'; -// TODO: remove when avatarPropTypes will be migrated to TS -type AvatarFunction = () => void; - -type AvatarIcon = { - source: string | AvatarFunction; - type: typeof CONST.ICON_TYPE_AVATAR | typeof CONST.ICON_TYPE_WORKSPACE; - name: string; - id: number | string; - fallbackIcon?: string | AvatarFunction; -}; - type Mention = { /** Display name of the user */ text: string; @@ -28,7 +18,7 @@ type Mention = { alternateText: string; /** Array of icons of the user. We use the first element of this array */ - icons: AvatarIcon[]; + icons: Icon[]; }; type MentionSuggestionsProps = { diff --git a/src/types/onyx/OnyxCommon.ts b/src/types/onyx/OnyxCommon.ts index bafd5e8cbbf0..0ab6cee0fe15 100644 --- a/src/types/onyx/OnyxCommon.ts +++ b/src/types/onyx/OnyxCommon.ts @@ -1,4 +1,5 @@ import * as React from 'react'; +import {SvgProps} from 'react-native-svg'; import {ValueOf} from 'type-fest'; import CONST from '@src/CONST'; @@ -9,9 +10,11 @@ type ErrorFields = Record | null>; type Errors = Record; type Icon = { - source: React.ReactNode | string; - type: 'avatar' | 'workspace'; + source: string | React.FC; + type: typeof CONST.ICON_TYPE_AVATAR | typeof CONST.ICON_TYPE_WORKSPACE; name: string; + id: number | string; + fallbackIcon?: string | React.FC; }; export type {Icon, PendingAction, ErrorFields, Errors}; From 2284b28478e5138a803e3a146f7bb405044365d1 Mon Sep 17 00:00:00 2001 From: AmjedNazzal Date: Fri, 3 Nov 2023 22:30:28 +0300 Subject: [PATCH 070/212] Fix issue #28474 removed the extra fallback --- src/components/AddressSearch/index.js | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/src/components/AddressSearch/index.js b/src/components/AddressSearch/index.js index ef0535b02d2c..c91c9bd9f8f9 100644 --- a/src/components/AddressSearch/index.js +++ b/src/components/AddressSearch/index.js @@ -257,25 +257,13 @@ function AddressSearch(props) { // Some edge-case addresses may lack both street_number and route in the API response, resulting in an empty "values.street" // We are setting up a fallback to ensure "values.street" is populated with a relevant value - if (!values.street) { - const {adr_address} = details; + if (!values.street && details.adr_address) { const streetAddressRegex = /(]*>[^<]*<\/span>)/; - const streetAddressHtml = adr_address.match(streetAddressRegex); - if (streetAddressHtml[1]) { + const adr_address = details.adr_address.match(streetAddressRegex); + const streetAddressHtml = _.get(adr_address, [1], null); + if (streetAddressHtml) { const parser = new ExpensiMark(); - const streetFallback = parser.htmlToText(streetAddressHtml[1]); - values.street = streetFallback; - } else { - let streetFallback = ''; - const excludedTypes = ['country', 'administrative_area_level_1', 'administrative_area_level_2', 'postal_code']; - addressComponents.forEach((addressComponent) => { - if (_.some(excludedTypes, (excludedType) => _.includes(addressComponent.types, excludedType))) { - return; - } - const value = addressComponent.long_name || ''; - streetFallback = `${streetFallback}${value} `; - }); - values.street = streetFallback.trim(); + values.street = parser.htmlToText(streetAddressHtml); } } From dec06d4f324813c1756a3df572a5494ca362578d Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Sat, 4 Nov 2023 11:13:03 +0800 Subject: [PATCH 071/212] remove flex grow --- src/components/SelectionList/BaseSelectionList.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/SelectionList/BaseSelectionList.js b/src/components/SelectionList/BaseSelectionList.js index 2a7947733a9e..a6abfe51eb84 100644 --- a/src/components/SelectionList/BaseSelectionList.js +++ b/src/components/SelectionList/BaseSelectionList.js @@ -453,7 +453,6 @@ function BaseSelectionList({ windowSize={5} viewabilityConfig={{viewAreaCoveragePercentThreshold: 95}} testID="selection-list" - style={[styles.flexGrow0]} onLayout={scrollToFocusedIndexOnFirstRender} /> {children} From efbda85415b6e47f18f6c5c859db7bae398914cf Mon Sep 17 00:00:00 2001 From: AmjedNazzal Date: Sat, 4 Nov 2023 12:56:06 +0300 Subject: [PATCH 072/212] Fix issue #28474 reverted to plain regex --- src/components/AddressSearch/index.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/components/AddressSearch/index.js b/src/components/AddressSearch/index.js index c91c9bd9f8f9..6a28217bfcf6 100644 --- a/src/components/AddressSearch/index.js +++ b/src/components/AddressSearch/index.js @@ -1,4 +1,3 @@ -import ExpensiMark from 'expensify-common/lib/ExpensiMark'; import lodashGet from 'lodash/get'; import PropTypes from 'prop-types'; import React, {useEffect, useMemo, useRef, useState} from 'react'; @@ -258,12 +257,11 @@ function AddressSearch(props) { // Some edge-case addresses may lack both street_number and route in the API response, resulting in an empty "values.street" // We are setting up a fallback to ensure "values.street" is populated with a relevant value if (!values.street && details.adr_address) { - const streetAddressRegex = /(]*>[^<]*<\/span>)/; + const streetAddressRegex = /]*>([^<]*)<\/span>/; const adr_address = details.adr_address.match(streetAddressRegex); - const streetAddressHtml = _.get(adr_address, [1], null); - if (streetAddressHtml) { - const parser = new ExpensiMark(); - values.street = parser.htmlToText(streetAddressHtml); + const streetAddressFallback = _.get(adr_address, [1], null); + if (streetAddressFallback) { + values.street = streetAddressFallback; } } From fbbd172739a81f89f4dee53e0ea0a0ee26e6111f Mon Sep 17 00:00:00 2001 From: Mahesh Vagicherla Date: Sat, 4 Nov 2023 21:14:31 +0530 Subject: [PATCH 073/212] fix: remove options props --- .../Navigation/AppNavigator/Navigators/RightModalNavigator.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/libs/Navigation/AppNavigator/Navigators/RightModalNavigator.js b/src/libs/Navigation/AppNavigator/Navigators/RightModalNavigator.js index de3fb9e79659..3fd8dec90d8d 100644 --- a/src/libs/Navigation/AppNavigator/Navigators/RightModalNavigator.js +++ b/src/libs/Navigation/AppNavigator/Navigators/RightModalNavigator.js @@ -37,10 +37,6 @@ function RightModalNavigator(props) { Date: Mon, 6 Nov 2023 13:35:27 +0700 Subject: [PATCH 074/212] fix lint --- src/components/SignInButtons/AppleSignIn/index.website.js | 2 ++ src/components/SignInButtons/GoogleSignIn/index.website.js | 2 ++ src/styles/fontFamily/multiFontFamily.ts | 4 ++-- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/SignInButtons/AppleSignIn/index.website.js b/src/components/SignInButtons/AppleSignIn/index.website.js index 587b6dbec983..f30e06a9bcab 100644 --- a/src/components/SignInButtons/AppleSignIn/index.website.js +++ b/src/components/SignInButtons/AppleSignIn/index.website.js @@ -83,6 +83,7 @@ function AppleSignInDiv({isDesktopFlow}) { }, []); return isDesktopFlow ? ( + /* eslint-disable-next-line jsx-a11y/no-static-element-interactions */
event.preventDefault()} /> ) : ( + /* eslint-disable-next-line jsx-a11y/no-static-element-interactions */
+ {/* eslint-disable-next-line jsx-a11y/interactive-supports-focus */}
) : ( + {/* eslint-disable-next-line jsx-a11y/interactive-supports-focus */}
Date: Mon, 6 Nov 2023 13:43:18 +0700 Subject: [PATCH 075/212] fix lint --- src/styles/fontFamily/multiFontFamily.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/styles/fontFamily/multiFontFamily.ts b/src/styles/fontFamily/multiFontFamily.ts index b6b74ad68dfc..5bd89e0d4bcb 100644 --- a/src/styles/fontFamily/multiFontFamily.ts +++ b/src/styles/fontFamily/multiFontFamily.ts @@ -1,5 +1,5 @@ -import CONST from '@src/CONST'; import getOperatingSystem from '@libs/getOperatingSystem'; +import CONST from '@src/CONST'; import {multiBold} from './bold'; import FontFamilyStyles from './types'; From 08c0d4c74a85887369c86a7087f68819e86ae42e Mon Sep 17 00:00:00 2001 From: Jakub Trzebiatowski Date: Mon, 6 Nov 2023 12:22:28 +0100 Subject: [PATCH 076/212] TextCommentFragment: Fix import paths --- src/pages/home/report/comment/TextCommentFragment.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/home/report/comment/TextCommentFragment.js b/src/pages/home/report/comment/TextCommentFragment.js index 10db27143012..155736e34767 100644 --- a/src/pages/home/report/comment/TextCommentFragment.js +++ b/src/pages/home/report/comment/TextCommentFragment.js @@ -14,9 +14,9 @@ import styles from '@styles/styles'; import themeColors from '@styles/themes/default'; import variables from '@styles/variables'; import CONST from '@src/CONST'; -import reportActionFragmentPropTypes from '../reportActionFragmentPropTypes'; +import reportActionFragmentPropTypes from '@pages/home/report/reportActionFragmentPropTypes'; import reportActionSourcePropType from "@pages/home/report/reportActionSourcePropType"; -import RenderCommentHTML from "@pages/home/report/comment/RenderCommentHTML"; +import RenderCommentHTML from "./RenderCommentHTML"; const propTypes = { /** The reportAction's source */ From cfaf05d106fd8c23d8e4ecc39cd7a52bb12ee69d Mon Sep 17 00:00:00 2001 From: Jakub Trzebiatowski Date: Mon, 6 Nov 2023 12:26:39 +0100 Subject: [PATCH 077/212] Fix more import paths --- src/pages/home/report/ReportActionItemFragment.js | 6 +++--- src/pages/home/report/comment/AttachmentCommentFragment.js | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pages/home/report/ReportActionItemFragment.js b/src/pages/home/report/ReportActionItemFragment.js index 42294e01abf0..33f6339c2360 100644 --- a/src/pages/home/report/ReportActionItemFragment.js +++ b/src/pages/home/report/ReportActionItemFragment.js @@ -10,10 +10,10 @@ import withWindowDimensions, {windowDimensionsPropTypes} from '@components/withW import compose from '@libs/compose'; import styles from '@styles/styles'; import CONST from '@src/CONST'; -import reportActionFragmentPropTypes from './reportActionFragmentPropTypes'; -import AttachmentCommentFragment from '@pages/home/report/comment/AttachmentCommentFragment'; -import TextCommentFragment from '@pages/home/report/comment/TextCommentFragment'; import * as ReportUtils from '@libs/ReportUtils'; +import AttachmentCommentFragment from './comment/AttachmentCommentFragment'; +import TextCommentFragment from './comment/TextCommentFragment'; +import reportActionFragmentPropTypes from './reportActionFragmentPropTypes'; const propTypes = { /** Users accountID */ diff --git a/src/pages/home/report/comment/AttachmentCommentFragment.js b/src/pages/home/report/comment/AttachmentCommentFragment.js index 9feeb3fdfc9f..db610dcb7394 100644 --- a/src/pages/home/report/comment/AttachmentCommentFragment.js +++ b/src/pages/home/report/comment/AttachmentCommentFragment.js @@ -3,7 +3,7 @@ import React from 'react'; import styles from '@styles/styles'; import reportActionSourcePropType from "@pages/home/report/reportActionSourcePropType"; import {View} from "react-native"; -import RenderCommentHTML from "@pages/home/report/comment/RenderCommentHTML"; +import RenderCommentHTML from "./RenderCommentHTML"; const propTypes = { /** The reportAction's source */ From bf943c6e4da19cd7a91f9324d157dd64e66cbf25 Mon Sep 17 00:00:00 2001 From: Jakub Trzebiatowski Date: Mon, 6 Nov 2023 12:34:43 +0100 Subject: [PATCH 078/212] Re-add the convertToLTR import --- src/pages/home/report/ReportActionItemFragment.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pages/home/report/ReportActionItemFragment.js b/src/pages/home/report/ReportActionItemFragment.js index 33f6339c2360..2efd325ff06a 100644 --- a/src/pages/home/report/ReportActionItemFragment.js +++ b/src/pages/home/report/ReportActionItemFragment.js @@ -11,6 +11,7 @@ import compose from '@libs/compose'; import styles from '@styles/styles'; import CONST from '@src/CONST'; import * as ReportUtils from '@libs/ReportUtils'; +import convertToLTR from '@libs/convertToLTR'; import AttachmentCommentFragment from './comment/AttachmentCommentFragment'; import TextCommentFragment from './comment/TextCommentFragment'; import reportActionFragmentPropTypes from './reportActionFragmentPropTypes'; From 1eaac4ce04bffd549b623b9f48cea1b8f1678dc2 Mon Sep 17 00:00:00 2001 From: Viktoryia Kliushun Date: Mon, 6 Nov 2023 13:40:23 +0100 Subject: [PATCH 079/212] Fix NaN in cooling down logs --- tests/e2e/testRunner.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/e2e/testRunner.js b/tests/e2e/testRunner.js index d8e4afd606ac..582c386e032f 100644 --- a/tests/e2e/testRunner.js +++ b/tests/e2e/testRunner.js @@ -203,8 +203,8 @@ const runTests = async () => { } } - const coolDownLogs = Logger.progressInfo(`Cooling down for ${config.COOL_DOWN / 1000}s`); - coolDownLogs.updateText(`Cooling down for ${config.COOL_DOWN / 1000}s`); + const coolDownLogs = Logger.progressInfo(`Cooling down for ${config.BOOT_COOL_DOWN / 1000}s`); + coolDownLogs.updateText(`Cooling down for ${config.BOOT_COOL_DOWN / 1000}s`); // Having the cooldown right at the beginning should hopefully lower the chances of heat // throttling from the previous run (which we have no control over and will be a From a8dd5679ba4804b8b4773acd8c2917826ae0c606 Mon Sep 17 00:00:00 2001 From: Prince Mendiratta Date: Mon, 6 Nov 2023 21:33:15 +0530 Subject: [PATCH 080/212] feat: fix system message for custom tags Signed-off-by: Prince Mendiratta --- src/libs/ReportUtils.js | 9 ++++++++- src/libs/actions/IOU.js | 5 +++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js index 1e3fc5297193..7465badcfc7d 100644 --- a/src/libs/ReportUtils.js +++ b/src/libs/ReportUtils.js @@ -11,6 +11,7 @@ import * as defaultWorkspaceAvatars from '@components/Icon/WorkspaceDefaultAvata import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; +import * as IOU from './actions/IOU'; import * as CurrencyUtils from './CurrencyUtils'; import DateUtils from './DateUtils'; import isReportMessageAttachment from './isReportMessageAttachment'; @@ -19,6 +20,7 @@ import linkingConfig from './Navigation/linkingConfig'; import Navigation from './Navigation/Navigation'; import * as NumberUtils from './NumberUtils'; import Permissions from './Permissions'; +import * as PolicyUtils from './PolicyUtils'; import * as ReportActionsUtils from './ReportActionsUtils'; import * as TransactionUtils from './TransactionUtils'; import * as Url from './Url'; @@ -1906,6 +1908,11 @@ function getModifiedExpenseMessage(reportAction) { if (_.isEmpty(reportActionOriginalMessage)) { return Localize.translateLocal('iou.changedTheRequest'); } + const reportID = lodashGet(reportAction, 'reportID', ''); + const policyID = lodashGet(getReport(reportID), 'policyID', ''); + const policyTags = IOU.getPolicyTags(policyID); + const policyTag = PolicyUtils.getTag(policyTags); + const policyTagListName = lodashGet(policyTag, 'name', Localize.translateLocal('common.tag')); const hasModifiedAmount = _.has(reportActionOriginalMessage, 'oldAmount') && @@ -1954,7 +1961,7 @@ function getModifiedExpenseMessage(reportAction) { const hasModifiedTag = _.has(reportActionOriginalMessage, 'oldTag') && _.has(reportActionOriginalMessage, 'tag'); if (hasModifiedTag) { - return getProperSchemaForModifiedExpenseMessage(reportActionOriginalMessage.tag, reportActionOriginalMessage.oldTag, Localize.translateLocal('common.tag'), true); + return getProperSchemaForModifiedExpenseMessage(reportActionOriginalMessage.tag, reportActionOriginalMessage.oldTag, policyTagListName, true); } const hasModifiedBillable = _.has(reportActionOriginalMessage, 'oldBillable') && _.has(reportActionOriginalMessage, 'billable'); diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 19ac03228753..691bbf68a88c 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -2949,6 +2949,10 @@ function getIOUReportID(iou, route) { return lodashGet(route, 'params.reportID') || lodashGet(iou, 'participants.0.reportID', ''); } +function getPolicyTags(policyID) { + return lodashGet(allPolicyTags, `${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`, {}); +} + export { createDistanceRequest, editMoneyRequest, @@ -2985,4 +2989,5 @@ export { replaceReceipt, detachReceipt, getIOUReportID, + getPolicyTags, }; From e86594f3139b543c762c37ec5de8074959b03767 Mon Sep 17 00:00:00 2001 From: Prince Mendiratta Date: Mon, 6 Nov 2023 21:48:17 +0530 Subject: [PATCH 081/212] feat: do not convert to lowercase if custom tag Signed-off-by: Prince Mendiratta --- src/libs/ReportUtils.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js index 7465badcfc7d..2f7e0308c3f8 100644 --- a/src/libs/ReportUtils.js +++ b/src/libs/ReportUtils.js @@ -1855,13 +1855,14 @@ function getReportPreviewMessage(report, reportAction = {}, shouldConsiderReceip * @param {String} oldValue * @param {String} valueName * @param {Boolean} valueInQuotes + * @param {Boolean} shouldConvertToLowercase * @returns {String} */ -function getProperSchemaForModifiedExpenseMessage(newValue, oldValue, valueName, valueInQuotes) { +function getProperSchemaForModifiedExpenseMessage(newValue, oldValue, valueName, valueInQuotes, shouldConvertToLowercase = true) { const newValueToDisplay = valueInQuotes ? `"${newValue}"` : newValue; const oldValueToDisplay = valueInQuotes ? `"${oldValue}"` : oldValue; - const displayValueName = valueName.toLowerCase(); + const displayValueName = shouldConvertToLowercase ? valueName.toLowerCase() : valueName; if (!oldValue) { return Localize.translateLocal('iou.setTheRequest', {valueName: displayValueName, newValueToDisplay}); @@ -1961,7 +1962,13 @@ function getModifiedExpenseMessage(reportAction) { const hasModifiedTag = _.has(reportActionOriginalMessage, 'oldTag') && _.has(reportActionOriginalMessage, 'tag'); if (hasModifiedTag) { - return getProperSchemaForModifiedExpenseMessage(reportActionOriginalMessage.tag, reportActionOriginalMessage.oldTag, policyTagListName, true); + return getProperSchemaForModifiedExpenseMessage( + reportActionOriginalMessage.tag, + reportActionOriginalMessage.oldTag, + policyTagListName, + true, + policyTagListName === Localize.translateLocal('common.tag'), + ); } const hasModifiedBillable = _.has(reportActionOriginalMessage, 'oldBillable') && _.has(reportActionOriginalMessage, 'billable'); From bf1be4565a20ea1d9c3025718d0d538d43faf862 Mon Sep 17 00:00:00 2001 From: Nam Le Date: Tue, 7 Nov 2023 13:53:24 +0700 Subject: [PATCH 082/212] hightlight selector when item selected --- src/components/ValuePicker/ValueSelectorModal.js | 8 ++------ src/components/ValuePicker/index.js | 1 - 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/components/ValuePicker/ValueSelectorModal.js b/src/components/ValuePicker/ValueSelectorModal.js index cd7923296eed..0187a8c59ddc 100644 --- a/src/components/ValuePicker/ValueSelectorModal.js +++ b/src/components/ValuePicker/ValueSelectorModal.js @@ -12,9 +12,6 @@ const propTypes = { /** Whether the modal is visible */ isVisible: PropTypes.bool.isRequired, - /** Current value selected */ - currentValue: PropTypes.string, - /** Items to pick from */ items: PropTypes.arrayOf(PropTypes.shape({value: PropTypes.string, label: PropTypes.string})), @@ -32,7 +29,6 @@ const propTypes = { }; const defaultProps = { - currentValue: '', items: [], selectedItem: {}, label: '', @@ -40,7 +36,7 @@ const defaultProps = { onItemSelected: () => {}, }; -function ValueSelectorModal({currentValue, items, selectedItem, label, isVisible, onClose, onItemSelected}) { +function ValueSelectorModal({items, selectedItem, label, isVisible, onClose, onItemSelected}) { const [sectionsData, setSectionsData] = useState([]); useEffect(() => { @@ -70,7 +66,7 @@ function ValueSelectorModal({currentValue, items, selectedItem, label, isVisible diff --git a/src/components/ValuePicker/index.js b/src/components/ValuePicker/index.js index e9ec200b7a7d..bfba851bc470 100644 --- a/src/components/ValuePicker/index.js +++ b/src/components/ValuePicker/index.js @@ -80,7 +80,6 @@ function ValuePicker({value, label, items, placeholder, errorText, onInputChange Date: Tue, 7 Nov 2023 16:38:30 +0800 Subject: [PATCH 083/212] set default number of lines to 0 --- src/components/Composer/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Composer/index.js b/src/components/Composer/index.js index 924705e0fd39..834c0e91dd36 100755 --- a/src/components/Composer/index.js +++ b/src/components/Composer/index.js @@ -93,7 +93,7 @@ const propTypes = { const defaultProps = { defaultValue: undefined, value: undefined, - numberOfLines: undefined, + numberOfLines: 0, onNumberOfLinesChange: () => {}, maxLines: -1, onPasteFile: () => {}, From 581dfcdea7d8dc80953b8832d820d23211b714be Mon Sep 17 00:00:00 2001 From: Viktoryia Kliushun Date: Tue, 7 Nov 2023 09:45:58 +0100 Subject: [PATCH 084/212] Migrate new files to TS; fix TS issues after merging main --- src/libs/E2E/API.mock.ts | 13 +++++----- ...{waitForKeyboard.js => waitForKeyboard.ts} | 2 +- src/libs/E2E/apiMocks/openReport.ts | 15 ++++++----- ...eadNewestAction.js => readNewestAction.ts} | 4 ++- src/libs/E2E/client.ts | 25 +++++++++++++------ ...ingTest.e2e.js => reportTypingTest.e2e.ts} | 0 src/types/onyx/OriginalMessage.ts | 1 + src/types/onyx/PersonalDetails.ts | 5 +++- src/types/onyx/Report.ts | 21 ++++++++++++++++ src/types/onyx/ReportAction.ts | 6 +++++ 10 files changed, 66 insertions(+), 26 deletions(-) rename src/libs/E2E/actions/{waitForKeyboard.js => waitForKeyboard.ts} (86%) rename src/libs/E2E/apiMocks/{readNewestAction.js => readNewestAction.ts} (76%) rename src/libs/E2E/tests/{reportTypingTest.e2e.js => reportTypingTest.e2e.ts} (100%) diff --git a/src/libs/E2E/API.mock.ts b/src/libs/E2E/API.mock.ts index 6d25612a6ed3..0568de926024 100644 --- a/src/libs/E2E/API.mock.ts +++ b/src/libs/E2E/API.mock.ts @@ -1,4 +1,3 @@ -/* eslint-disable rulesdir/no-api-in-views */ import Onyx from 'react-native-onyx'; import Log from '@libs/Log'; import Response from '@src/types/onyx/Response'; @@ -30,14 +29,14 @@ const mocks: Mocks = { ReadNewestAction: mockReadNewestAction, }; -function mockCall(command, apiCommandParameters, tag) { - const mockResponse = mocks[command] && mocks[command](apiCommandParameters); +function mockCall(command: string, apiCommandParameters: ApiCommandParameters, tag: string): Promise | Promise | undefined { + const mockResponse = mocks[command]?.(apiCommandParameters); if (!mockResponse) { Log.warn(`[${tag}] for command ${command} is not mocked yet! ⚠️`); return; } - if (_.isArray(mockResponse.onyxData)) { + if (Array.isArray(mockResponse.onyxData)) { return Onyx.update(mockResponse.onyxData); } @@ -51,7 +50,7 @@ function mockCall(command, apiCommandParameters, tag) { * @param command - Name of API command to call. * @param apiCommandParameters - Parameters to send to the API. */ -function write(command: string, apiCommandParameters: ApiCommandParameters = {}): Promise | undefined { +function write(command: string, apiCommandParameters: ApiCommandParameters = {}): Promise | Promise | undefined { return mockCall(command, apiCommandParameters, 'API.write'); } @@ -66,7 +65,7 @@ function write(command: string, apiCommandParameters: ApiCommandParameters = {}) * @param command - Name of API command to call. * @param apiCommandParameters - Parameters to send to the API. */ -function makeRequestWithSideEffects(command: string, apiCommandParameters: ApiCommandParameters = {}): Promise | undefined { +function makeRequestWithSideEffects(command: string, apiCommandParameters: ApiCommandParameters = {}): Promise | Promise | undefined { return mockCall(command, apiCommandParameters, 'API.makeRequestWithSideEffects'); } @@ -76,7 +75,7 @@ function makeRequestWithSideEffects(command: string, apiCommandParameters: ApiCo * @param command - Name of API command to call. * @param apiCommandParameters - Parameters to send to the API. */ -function read(command: string, apiCommandParameters: ApiCommandParameters): Promise | undefined { +function read(command: string, apiCommandParameters: ApiCommandParameters): Promise | Promise | undefined { return mockCall(command, apiCommandParameters, 'API.read'); } diff --git a/src/libs/E2E/actions/waitForKeyboard.js b/src/libs/E2E/actions/waitForKeyboard.ts similarity index 86% rename from src/libs/E2E/actions/waitForKeyboard.js rename to src/libs/E2E/actions/waitForKeyboard.ts index 4bc0f492e3a3..df7a9aae9651 100644 --- a/src/libs/E2E/actions/waitForKeyboard.js +++ b/src/libs/E2E/actions/waitForKeyboard.ts @@ -1,6 +1,6 @@ import {Keyboard} from 'react-native'; -export default function waitForKeyboard() { +export default function waitForKeyboard(): Promise { return new Promise((resolve) => { function checkKeyboard() { if (Keyboard.isVisible()) { diff --git a/src/libs/E2E/apiMocks/openReport.ts b/src/libs/E2E/apiMocks/openReport.ts index fd780234d768..dc3652ae0f88 100644 --- a/src/libs/E2E/apiMocks/openReport.ts +++ b/src/libs/E2E/apiMocks/openReport.ts @@ -1,6 +1,7 @@ +/* eslint-disable @typescript-eslint/naming-convention */ import Response from '@src/types/onyx/Response'; -const openReport = (): Response => ({ +export default (): Response => ({ onyxData: [ { onyxMethod: 'merge', @@ -32,7 +33,7 @@ const openReport = (): Response => ({ visibility: null, isOwnPolicyExpenseChat: false, lastMessageHtml: 'terry+hightraffic@margelo.io owes \u20ac12.00', - iouReportID: 206636935813547, + iouReportID: '206636935813547', hasOutstandingIOU: false, hasOutstandingChildRequest: false, policyName: null, @@ -157,7 +158,7 @@ const openReport = (): Response => ({ reportActionID: '6576518341807837187', previousReportActionID: '2658221912430757962', lastModified: '2023-08-29 12:38:16.070', - childReportID: 206636935813547, + childReportID: '206636935813547', childType: 'iou', childStatusNum: 1, childStateNum: 1, @@ -219,7 +220,7 @@ const openReport = (): Response => ({ reportActionID: '2658221912430757962', previousReportActionID: '6551789403725495383', lastModified: '2023-08-25 12:39:48.121', - childReportID: 1411015346900020, + childReportID: '1411015346900020', childType: 'chat', childOldestFourAccountIDs: '12883048', childCommenterCount: 1, @@ -729,7 +730,7 @@ const openReport = (): Response => ({ reportActionID: '3986429677777110818', previousReportActionID: '7317910228472011573', lastModified: '2023-07-27 17:03:11.250', - childReportID: 3338245207149134, + childReportID: '3338245207149134', childType: 'chat', whisperedToAccountIDs: [], }, @@ -1595,7 +1596,7 @@ const openReport = (): Response => ({ reportActionID: '2030060194258527427', previousReportActionID: '5540483153987237906', lastModified: '2023-07-27 07:40:49.146', - childReportID: 5860710623453234, + childReportID: '5860710623453234', childType: 'chat', childOldestFourAccountIDs: '14567013,12883048', childCommenterCount: 2, @@ -1974,5 +1975,3 @@ const openReport = (): Response => ({ jsonCode: 200, requestID: '81b8b8509a7f5b54-VIE', }); - -export default openReport; diff --git a/src/libs/E2E/apiMocks/readNewestAction.js b/src/libs/E2E/apiMocks/readNewestAction.ts similarity index 76% rename from src/libs/E2E/apiMocks/readNewestAction.js rename to src/libs/E2E/apiMocks/readNewestAction.ts index 04270a8d93f4..5db007e64a6f 100644 --- a/src/libs/E2E/apiMocks/readNewestAction.js +++ b/src/libs/E2E/apiMocks/readNewestAction.ts @@ -1,4 +1,6 @@ -export default () => ({ +import Response from '@src/types/onyx/Response'; + +export default (): Response => ({ jsonCode: 200, requestID: '81b8c48e3bfe5a84-VIE', onyxData: [ diff --git a/src/libs/E2E/client.ts b/src/libs/E2E/client.ts index e53cb86d6114..866314cda05e 100644 --- a/src/libs/E2E/client.ts +++ b/src/libs/E2E/client.ts @@ -5,12 +5,22 @@ type TestResult = { name: string; duration?: number; error?: string; + renderCount?: number; }; type TestConfig = { name: string; }; +type NativeCommandPayload = { + text: string; +}; + +type NativeCommand = { + actionName: string; + payload?: NativeCommandPayload; +}; + const SERVER_ADDRESS = `http://localhost:${Config.SERVER_PORT}`; /** @@ -44,24 +54,23 @@ const submitTestResults = (testResult: TestResult): Promise => { const submitTestDone = () => fetch(`${SERVER_ADDRESS}${Routes.testDone}`); -let currentActiveTestConfig = null; -/** - * @returns {Promise} - */ -const getTestConfig = () => +let currentActiveTestConfig: TestConfig | null = null; + +const getTestConfig = (): Promise => fetch(`${SERVER_ADDRESS}${Routes.testConfig}`) - .then((res) => res.json()) - .then((config) => { + .then((res: Response): Promise => res.json()) + .then((config: TestConfig) => { currentActiveTestConfig = config; return config; }); const getCurrentActiveTestConfig = () => currentActiveTestConfig; -const sendNativeCommand = (payload) => +const sendNativeCommand = (payload: NativeCommand) => fetch(`${SERVER_ADDRESS}${Routes.testNativeCommand}`, { method: 'POST', headers: { + // eslint-disable-next-line @typescript-eslint/naming-convention 'Content-Type': 'application/json', }, body: JSON.stringify(payload), diff --git a/src/libs/E2E/tests/reportTypingTest.e2e.js b/src/libs/E2E/tests/reportTypingTest.e2e.ts similarity index 100% rename from src/libs/E2E/tests/reportTypingTest.e2e.js rename to src/libs/E2E/tests/reportTypingTest.e2e.ts diff --git a/src/types/onyx/OriginalMessage.ts b/src/types/onyx/OriginalMessage.ts index 014cd67a9a2a..b5e4b25a6508 100644 --- a/src/types/onyx/OriginalMessage.ts +++ b/src/types/onyx/OriginalMessage.ts @@ -140,6 +140,7 @@ type OriginalMessageReportPreview = { actionName: typeof CONST.REPORT.ACTIONS.TYPE.REPORTPREVIEW; originalMessage: { linkedReportID: string; + lastModified?: string; }; }; diff --git a/src/types/onyx/PersonalDetails.ts b/src/types/onyx/PersonalDetails.ts index 5637d7e5fdcf..ffa801445e1f 100644 --- a/src/types/onyx/PersonalDetails.ts +++ b/src/types/onyx/PersonalDetails.ts @@ -61,9 +61,12 @@ type PersonalDetails = { /** A fallback avatar icon to display when there is an error on loading avatar from remote URL. */ fallbackIcon?: string; - /** Status of the current user from their personal details */ + /** Status of the current user from their personal details */ status?: string; + + /** PayPalMe address of the current user */ + payPalMeAddress?: string; }; export default PersonalDetails; diff --git a/src/types/onyx/Report.ts b/src/types/onyx/Report.ts index 56b0d2333d4a..5b6480dfb2e1 100644 --- a/src/types/onyx/Report.ts +++ b/src/types/onyx/Report.ts @@ -36,12 +36,33 @@ type Report = { /** The last time the report was visited */ lastReadTime?: string; + /** The sequence number of the last report visit */ + lastReadSequenceNumber?: number; + + /** The time of the last mention of the report */ + lastMentionedTime?: string; + /** The current user's notification preference for this report */ notificationPreference?: string | number; + /** The policy name to use */ + policyName?: string; + /** The policy name to use for an archived report */ oldPolicyName?: string; + /** Whether the report has parent access */ + hasParentAccess?: boolean; + + /** Description of the report */ + description?: string; + + /** Whether the parent action was deleted */ + isDeletedParentAction?: boolean; + + /** PayPalMe address of the submitter */ + submitterPayPalMeAddress?: string; + /** The email address of the report owner */ ownerEmail?: string; diff --git a/src/types/onyx/ReportAction.ts b/src/types/onyx/ReportAction.ts index ab2f87f400a2..2195c4e3ff0b 100644 --- a/src/types/onyx/ReportAction.ts +++ b/src/types/onyx/ReportAction.ts @@ -81,6 +81,12 @@ type ReportActionBase = { /** accountIDs of the people to which the whisper was sent to (if any). Returns empty array if it is not a whisper */ whisperedToAccountIDs?: number[]; + /** Report action child status number */ + childStatusNum?: number; + + /** Report action child status name */ + childStateNum?: number; + avatar?: string; automatic?: boolean; shouldShow?: boolean; From 7c557ac5b9105786510b4a57ce51f2953892e782 Mon Sep 17 00:00:00 2001 From: dukenv0307 Date: Tue, 7 Nov 2023 16:07:46 +0700 Subject: [PATCH 085/212] create withTabAnimation HOC --- src/libs/Navigation/withTabAnimation.js | 47 +++++++++++++++++++ .../NavigationAwareCamera.native.js | 18 +++++-- 2 files changed, 61 insertions(+), 4 deletions(-) create mode 100644 src/libs/Navigation/withTabAnimation.js diff --git a/src/libs/Navigation/withTabAnimation.js b/src/libs/Navigation/withTabAnimation.js new file mode 100644 index 000000000000..eb1520d4468e --- /dev/null +++ b/src/libs/Navigation/withTabAnimation.js @@ -0,0 +1,47 @@ +import {useTabAnimation} from '@react-navigation/material-top-tabs'; +import PropTypes from 'prop-types'; +import * as React from 'react'; +import getComponentDisplayName from '@libs/getComponentDisplayName'; + +const propTypes = { + /* Whether we're in a tab navigator */ + isInTabNavigator: PropTypes.bool.isRequired, +}; + +export default function (WrappedComponent) { + function WrappedComponentWithTabAnimation(props) { + const animation = useTabAnimation(); + + return ( + + ); + } + + function WithTabAnimation(props, ref) { + if (props.isInTabNavigator) { + return ( + + ); + } + return ( + + ); + } + + WithTabAnimation.propTypes = propTypes; + WithTabAnimation.displayName = `withTabAnimation(${getComponentDisplayName(WrappedComponent)})`; + + return React.forwardRef(WithTabAnimation); +} diff --git a/src/pages/iou/ReceiptSelector/NavigationAwareCamera.native.js b/src/pages/iou/ReceiptSelector/NavigationAwareCamera.native.js index 9d1b1723e882..58b3c991fb06 100644 --- a/src/pages/iou/ReceiptSelector/NavigationAwareCamera.native.js +++ b/src/pages/iou/ReceiptSelector/NavigationAwareCamera.native.js @@ -1,8 +1,8 @@ -import {useTabAnimation} from '@react-navigation/material-top-tabs'; import {useNavigation} from '@react-navigation/native'; import PropTypes from 'prop-types'; import React, {useEffect, useState} from 'react'; import {Camera} from 'react-native-vision-camera'; +import withTabAnimation from '@libs/Navigation/withTabAnimation'; import CONST from '@src/CONST'; const propTypes = { @@ -14,6 +14,16 @@ const propTypes = { /** Name of the selected receipt tab */ selectedTab: PropTypes.string.isRequired, + + /** */ + tabAnimation: PropTypes.shape({ + addListener: PropTypes.func, + removeListener: PropTypes.func, + }), +}; + +const defaultProps = { + tabAnimation: undefined, }; // Wraps a camera that will only be active when the tab is focused or as soon as it starts to become focused. @@ -27,8 +37,7 @@ const NavigationAwareCamera = React.forwardRef(({cameraTabIndex, isInTabNavigato // STOP!!!!!!! This is not a pattern to be followed! We are conditionally rendering this hook becase when used in the edit flow we'll never be inside a tab navigator. // eslint-disable-next-line react-hooks/rules-of-hooks - const tabPositionAnimation = isInTabNavigator ? useTabAnimation() : null; - + const tabPositionAnimation = props.tabAnimation; useEffect(() => { if (!isInTabNavigator) { return; @@ -78,6 +87,7 @@ const NavigationAwareCamera = React.forwardRef(({cameraTabIndex, isInTabNavigato }); NavigationAwareCamera.propTypes = propTypes; +NavigationAwareCamera.defaultProps = defaultProps; NavigationAwareCamera.displayName = 'NavigationAwareCamera'; -export default NavigationAwareCamera; +export default withTabAnimation(NavigationAwareCamera); From 963b7c4d11b161d06efc4c18a456c05b454fe9d3 Mon Sep 17 00:00:00 2001 From: Jakub Trzebiatowski Date: Tue, 7 Nov 2023 11:22:41 +0100 Subject: [PATCH 086/212] Run Prettier --- src/pages/home/report/ReportActionItemFragment.js | 4 ++-- src/pages/home/report/comment/AttachmentCommentFragment.js | 6 +++--- src/pages/home/report/comment/RenderCommentHTML.js | 2 +- src/pages/home/report/comment/TextCommentFragment.js | 6 +++--- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/pages/home/report/ReportActionItemFragment.js b/src/pages/home/report/ReportActionItemFragment.js index 2efd325ff06a..c569be72658e 100644 --- a/src/pages/home/report/ReportActionItemFragment.js +++ b/src/pages/home/report/ReportActionItemFragment.js @@ -8,10 +8,10 @@ import UserDetailsTooltip from '@components/UserDetailsTooltip'; import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; import withWindowDimensions, {windowDimensionsPropTypes} from '@components/withWindowDimensions'; import compose from '@libs/compose'; +import convertToLTR from '@libs/convertToLTR'; +import * as ReportUtils from '@libs/ReportUtils'; import styles from '@styles/styles'; import CONST from '@src/CONST'; -import * as ReportUtils from '@libs/ReportUtils'; -import convertToLTR from '@libs/convertToLTR'; import AttachmentCommentFragment from './comment/AttachmentCommentFragment'; import TextCommentFragment from './comment/TextCommentFragment'; import reportActionFragmentPropTypes from './reportActionFragmentPropTypes'; diff --git a/src/pages/home/report/comment/AttachmentCommentFragment.js b/src/pages/home/report/comment/AttachmentCommentFragment.js index db610dcb7394..8c04ca404f1d 100644 --- a/src/pages/home/report/comment/AttachmentCommentFragment.js +++ b/src/pages/home/report/comment/AttachmentCommentFragment.js @@ -1,9 +1,9 @@ import PropTypes from 'prop-types'; import React from 'react'; +import {View} from 'react-native'; +import reportActionSourcePropType from '@pages/home/report/reportActionSourcePropType'; import styles from '@styles/styles'; -import reportActionSourcePropType from "@pages/home/report/reportActionSourcePropType"; -import {View} from "react-native"; -import RenderCommentHTML from "./RenderCommentHTML"; +import RenderCommentHTML from './RenderCommentHTML'; const propTypes = { /** The reportAction's source */ diff --git a/src/pages/home/report/comment/RenderCommentHTML.js b/src/pages/home/report/comment/RenderCommentHTML.js index 474d87533480..dc8da2208dd5 100644 --- a/src/pages/home/report/comment/RenderCommentHTML.js +++ b/src/pages/home/report/comment/RenderCommentHTML.js @@ -1,7 +1,7 @@ import PropTypes from 'prop-types'; import React from 'react'; -import reportActionSourcePropType from '@pages/home/report/reportActionSourcePropType'; import RenderHTML from '@components/RenderHTML'; +import reportActionSourcePropType from '@pages/home/report/reportActionSourcePropType'; const propTypes = { /** The reportAction's source */ diff --git a/src/pages/home/report/comment/TextCommentFragment.js b/src/pages/home/report/comment/TextCommentFragment.js index 155736e34767..b7c1ce904595 100644 --- a/src/pages/home/report/comment/TextCommentFragment.js +++ b/src/pages/home/report/comment/TextCommentFragment.js @@ -9,14 +9,14 @@ import compose from '@libs/compose'; import convertToLTR from '@libs/convertToLTR'; import * as DeviceCapabilities from '@libs/DeviceCapabilities'; import * as EmojiUtils from '@libs/EmojiUtils'; +import reportActionFragmentPropTypes from '@pages/home/report/reportActionFragmentPropTypes'; +import reportActionSourcePropType from '@pages/home/report/reportActionSourcePropType'; import editedLabelStyles from '@styles/editedLabelStyles'; import styles from '@styles/styles'; import themeColors from '@styles/themes/default'; import variables from '@styles/variables'; import CONST from '@src/CONST'; -import reportActionFragmentPropTypes from '@pages/home/report/reportActionFragmentPropTypes'; -import reportActionSourcePropType from "@pages/home/report/reportActionSourcePropType"; -import RenderCommentHTML from "./RenderCommentHTML"; +import RenderCommentHTML from './RenderCommentHTML'; const propTypes = { /** The reportAction's source */ From 35331a58ff717a6d89a151e005c4e7b061767780 Mon Sep 17 00:00:00 2001 From: Yauheni Pasiukevich Date: Tue, 7 Nov 2023 13:20:30 +0100 Subject: [PATCH 087/212] fix missed react dependency --- src/components/ErrorBoundary/index.native.tsx | 1 + src/components/ErrorBoundary/index.tsx | 1 + 2 files changed, 2 insertions(+) diff --git a/src/components/ErrorBoundary/index.native.tsx b/src/components/ErrorBoundary/index.native.tsx index 125ff81ca110..b8e56ee528c2 100644 --- a/src/components/ErrorBoundary/index.native.tsx +++ b/src/components/ErrorBoundary/index.native.tsx @@ -1,4 +1,5 @@ import crashlytics from '@react-native-firebase/crashlytics'; +import React from 'react'; import Log from '@libs/Log'; import BaseErrorBoundary from './BaseErrorBoundary'; import {BaseErrorBoundaryProps, LogError} from './types'; diff --git a/src/components/ErrorBoundary/index.tsx b/src/components/ErrorBoundary/index.tsx index 9bc3dc748e8e..fce70674dd97 100644 --- a/src/components/ErrorBoundary/index.tsx +++ b/src/components/ErrorBoundary/index.tsx @@ -1,3 +1,4 @@ +import React from 'react'; import Log from '@libs//Log'; import BaseErrorBoundary from './BaseErrorBoundary'; import {BaseErrorBoundaryProps, LogError} from './types'; From eb58d70d9d7fdd51f5a45008d4e7542528093232 Mon Sep 17 00:00:00 2001 From: Yauheni Pasiukevich Date: Tue, 7 Nov 2023 16:19:59 +0100 Subject: [PATCH 088/212] remove redundant style --- src/styles/styles.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/styles/styles.ts b/src/styles/styles.ts index e591eb4176a2..46a7bde0dd7b 100644 --- a/src/styles/styles.ts +++ b/src/styles/styles.ts @@ -327,10 +327,6 @@ const styles = (theme: ThemeColors) => textAlign: 'left', }, - textUnderline: { - textDecorationLine: 'underline', - }, - verticalAlignMiddle: { verticalAlign: 'middle', }, From 40f0fec7df7b48cc0304a8e797c8c0a036d3fc86 Mon Sep 17 00:00:00 2001 From: Daniel Edwards Date: Tue, 7 Nov 2023 12:16:16 -0500 Subject: [PATCH 089/212] Add SVG --- assets/images/empty-state__attach-receipt.svg | 16 ++++++++++++++++ src/components/Icon/Expensicons.js | 2 ++ 2 files changed, 18 insertions(+) create mode 100644 assets/images/empty-state__attach-receipt.svg diff --git a/assets/images/empty-state__attach-receipt.svg b/assets/images/empty-state__attach-receipt.svg new file mode 100644 index 000000000000..6b50afbdbf0b --- /dev/null +++ b/assets/images/empty-state__attach-receipt.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/src/components/Icon/Expensicons.js b/src/components/Icon/Expensicons.js index a4aa6b13cb29..e5f4d158be1a 100644 --- a/src/components/Icon/Expensicons.js +++ b/src/components/Icon/Expensicons.js @@ -46,6 +46,7 @@ import DragAndDrop from '@assets/images/drag-and-drop.svg'; import DragHandles from '@assets/images/drag-handles.svg'; import Emoji from '@assets/images/emoji.svg'; import EmptyStateRoutePending from '@assets/images/emptystate__routepending.svg'; +import EmptyStateAttachReceipt from '@assets/images/empty-state__attach-receipt.svg'; import EReceiptIcon from '@assets/images/eReceiptIcon.svg'; import Exclamation from '@assets/images/exclamation.svg'; import Exit from '@assets/images/exit.svg'; @@ -176,6 +177,7 @@ export { EReceiptIcon, Emoji, EmptyStateRoutePending, + EmptyStateAttachReceipt, Exclamation, Exit, ExpensifyCard, From 561c3548eab0de370a61a4403a99dcbde28ebd81 Mon Sep 17 00:00:00 2001 From: Daniel Edwards Date: Tue, 7 Nov 2023 15:31:42 -0500 Subject: [PATCH 090/212] Adds ReceiptEmptyState Component --- src/components/ReceiptEmptyState.js | 47 +++++++++++++++++++++++++++++ src/styles/styles.ts | 5 +++ 2 files changed, 52 insertions(+) create mode 100644 src/components/ReceiptEmptyState.js diff --git a/src/components/ReceiptEmptyState.js b/src/components/ReceiptEmptyState.js new file mode 100644 index 000000000000..31edb4842389 --- /dev/null +++ b/src/components/ReceiptEmptyState.js @@ -0,0 +1,47 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { View } from 'react-native'; +import styles from '@styles/styles'; +import variables from '@styles/variables'; +import Icon from './Icon'; +import * as Expensicons from './Icon/Expensicons'; + +import PressableWithoutFeedback from './Pressable/PressableWithoutFeedback'; + +const propTypes = { + /** Whether or not there is a violation error */ + hasError: PropTypes.bool, + + /** Callback to be called on onPress */ + onPress: PropTypes.func, +} + +const defaultProps = { + hasError: false, + onPress: undefined, +} + + +// Create a component with the above instructions: + +function ReceiptEmptyState({hasError, onPress}) { + return ( + + + + + + + ) +} + +ReceiptEmptyState.displayName = 'ReceiptEmptyState'; +ReceiptEmptyState.propTypes = propTypes; +ReceiptEmptyState.defaultProps = defaultProps; + +export default ReceiptEmptyState; diff --git a/src/styles/styles.ts b/src/styles/styles.ts index da5cc8e726fd..588dba090767 100644 --- a/src/styles/styles.ts +++ b/src/styles/styles.ts @@ -3837,6 +3837,11 @@ const styles = (theme: ThemeDefault) => maxWidth: 400, }, + moneyRequestAttachReceipt: { + backgroundColor: theme.appBG, + borderColor: theme.textSupporting, + }, + mapViewContainer: { ...flex.flex1, minHeight: 300, From d8ededb712fc3adad9133e63d845d0df33e7acca Mon Sep 17 00:00:00 2001 From: Daniel Edwards Date: Tue, 7 Nov 2023 15:32:24 -0500 Subject: [PATCH 091/212] Adds EmptyStateReceipt to MoneyRequestView --- src/components/ReportActionItem/MoneyRequestView.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/components/ReportActionItem/MoneyRequestView.js b/src/components/ReportActionItem/MoneyRequestView.js index aa1813fa6e4d..97455f621421 100644 --- a/src/components/ReportActionItem/MoneyRequestView.js +++ b/src/components/ReportActionItem/MoneyRequestView.js @@ -37,6 +37,7 @@ import * as IOU from '@userActions/IOU'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; +import ReceiptEmptyState from '@components/ReceiptEmptyState'; import ReportActionItemImage from './ReportActionItemImage'; const propTypes = { @@ -175,6 +176,11 @@ function MoneyRequestView({report, betas, parentReport, policyCategories, should )} + {!hasReceipt && Permissions.canUseViolations() && ( + + Navigation.navigate(ROUTES.EDIT_REQUEST.getRoute(report.reportID, CONST.EDIT_REQUEST_FIELD.RECEIPT))} /> + + )} Date: Tue, 7 Nov 2023 15:45:32 -0500 Subject: [PATCH 092/212] prettier --- src/components/Icon/Expensicons.js | 2 +- src/components/ReceiptEmptyState.js | 19 ++++++++++--------- .../ReportActionItem/MoneyRequestView.js | 7 +++++-- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/components/Icon/Expensicons.js b/src/components/Icon/Expensicons.js index e5f4d158be1a..3d4f0edb1656 100644 --- a/src/components/Icon/Expensicons.js +++ b/src/components/Icon/Expensicons.js @@ -45,8 +45,8 @@ import Download from '@assets/images/download.svg'; import DragAndDrop from '@assets/images/drag-and-drop.svg'; import DragHandles from '@assets/images/drag-handles.svg'; import Emoji from '@assets/images/emoji.svg'; -import EmptyStateRoutePending from '@assets/images/emptystate__routepending.svg'; import EmptyStateAttachReceipt from '@assets/images/empty-state__attach-receipt.svg'; +import EmptyStateRoutePending from '@assets/images/emptystate__routepending.svg'; import EReceiptIcon from '@assets/images/eReceiptIcon.svg'; import Exclamation from '@assets/images/exclamation.svg'; import Exit from '@assets/images/exit.svg'; diff --git a/src/components/ReceiptEmptyState.js b/src/components/ReceiptEmptyState.js index 31edb4842389..f32083c650d9 100644 --- a/src/components/ReceiptEmptyState.js +++ b/src/components/ReceiptEmptyState.js @@ -1,11 +1,10 @@ -import React from 'react'; import PropTypes from 'prop-types'; -import { View } from 'react-native'; +import React from 'react'; +import {View} from 'react-native'; import styles from '@styles/styles'; import variables from '@styles/variables'; import Icon from './Icon'; import * as Expensicons from './Icon/Expensicons'; - import PressableWithoutFeedback from './Pressable/PressableWithoutFeedback'; const propTypes = { @@ -14,20 +13,22 @@ const propTypes = { /** Callback to be called on onPress */ onPress: PropTypes.func, -} +}; const defaultProps = { hasError: false, onPress: undefined, -} - +}; // Create a component with the above instructions: function ReceiptEmptyState({hasError, onPress}) { return ( - - + + - ) + ); } ReceiptEmptyState.displayName = 'ReceiptEmptyState'; diff --git a/src/components/ReportActionItem/MoneyRequestView.js b/src/components/ReportActionItem/MoneyRequestView.js index 97455f621421..a9ae4d85e426 100644 --- a/src/components/ReportActionItem/MoneyRequestView.js +++ b/src/components/ReportActionItem/MoneyRequestView.js @@ -8,6 +8,7 @@ import categoryPropTypes from '@components/categoryPropTypes'; import * as Expensicons from '@components/Icon/Expensicons'; import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription'; import OfflineWithFeedback from '@components/OfflineWithFeedback'; +import ReceiptEmptyState from '@components/ReceiptEmptyState'; import SpacerView from '@components/SpacerView'; import Switch from '@components/Switch'; import tagPropTypes from '@components/tagPropTypes'; @@ -37,7 +38,6 @@ import * as IOU from '@userActions/IOU'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; -import ReceiptEmptyState from '@components/ReceiptEmptyState'; import ReportActionItemImage from './ReportActionItemImage'; const propTypes = { @@ -178,7 +178,10 @@ function MoneyRequestView({report, betas, parentReport, policyCategories, should )} {!hasReceipt && Permissions.canUseViolations() && ( - Navigation.navigate(ROUTES.EDIT_REQUEST.getRoute(report.reportID, CONST.EDIT_REQUEST_FIELD.RECEIPT))} /> + Navigation.navigate(ROUTES.EDIT_REQUEST.getRoute(report.reportID, CONST.EDIT_REQUEST_FIELD.RECEIPT))} + /> )} From 6a50f7ff77aa8b0f281efd3159f61a766e96bc6c Mon Sep 17 00:00:00 2001 From: dukenv0307 Date: Wed, 8 Nov 2023 15:05:27 +0700 Subject: [PATCH 093/212] refactor navigation camera component --- .../Navigation => components}/withTabAnimation.js | 0 .../index.js} | 0 .../index.native.js} | 13 +++++-------- 3 files changed, 5 insertions(+), 8 deletions(-) rename src/{libs/Navigation => components}/withTabAnimation.js (100%) rename src/pages/iou/ReceiptSelector/{NavigationAwareCamera.js => NavigationAwareCamera/index.js} (100%) rename src/pages/iou/ReceiptSelector/{NavigationAwareCamera.native.js => NavigationAwareCamera/index.native.js} (82%) diff --git a/src/libs/Navigation/withTabAnimation.js b/src/components/withTabAnimation.js similarity index 100% rename from src/libs/Navigation/withTabAnimation.js rename to src/components/withTabAnimation.js diff --git a/src/pages/iou/ReceiptSelector/NavigationAwareCamera.js b/src/pages/iou/ReceiptSelector/NavigationAwareCamera/index.js similarity index 100% rename from src/pages/iou/ReceiptSelector/NavigationAwareCamera.js rename to src/pages/iou/ReceiptSelector/NavigationAwareCamera/index.js diff --git a/src/pages/iou/ReceiptSelector/NavigationAwareCamera.native.js b/src/pages/iou/ReceiptSelector/NavigationAwareCamera/index.native.js similarity index 82% rename from src/pages/iou/ReceiptSelector/NavigationAwareCamera.native.js rename to src/pages/iou/ReceiptSelector/NavigationAwareCamera/index.native.js index 58b3c991fb06..591c928f423a 100644 --- a/src/pages/iou/ReceiptSelector/NavigationAwareCamera.native.js +++ b/src/pages/iou/ReceiptSelector/NavigationAwareCamera/index.native.js @@ -2,7 +2,7 @@ import {useNavigation} from '@react-navigation/native'; import PropTypes from 'prop-types'; import React, {useEffect, useState} from 'react'; import {Camera} from 'react-native-vision-camera'; -import withTabAnimation from '@libs/Navigation/withTabAnimation'; +import withTabAnimation from '@components/withTabAnimation'; import CONST from '@src/CONST'; const propTypes = { @@ -27,7 +27,7 @@ const defaultProps = { }; // Wraps a camera that will only be active when the tab is focused or as soon as it starts to become focused. -const NavigationAwareCamera = React.forwardRef(({cameraTabIndex, isInTabNavigator, selectedTab, ...props}, ref) => { +const NavigationAwareCamera = React.forwardRef(({cameraTabIndex, isInTabNavigator, selectedTab, tabAnimation, ...props}, ref) => { // Get navigation to get initial isFocused value (only needed once during init!) const navigation = useNavigation(); const [isCameraActive, setIsCameraActive] = useState(() => navigation.isFocused()); @@ -35,15 +35,12 @@ const NavigationAwareCamera = React.forwardRef(({cameraTabIndex, isInTabNavigato // Retrieve the animation value from the tab navigator, which ranges from 0 to the total number of pages displayed. // Even a minimal scroll towards the camera page (e.g., a value of 0.001 at start) should activate the camera for immediate responsiveness. - // STOP!!!!!!! This is not a pattern to be followed! We are conditionally rendering this hook becase when used in the edit flow we'll never be inside a tab navigator. - // eslint-disable-next-line react-hooks/rules-of-hooks - const tabPositionAnimation = props.tabAnimation; useEffect(() => { if (!isInTabNavigator) { return; } - const listenerId = tabPositionAnimation.addListener(({value}) => { + const listenerId = tabAnimation.addListener(({value}) => { if (selectedTab !== CONST.TAB.SCAN) { return; } @@ -52,9 +49,9 @@ const NavigationAwareCamera = React.forwardRef(({cameraTabIndex, isInTabNavigato }); return () => { - tabPositionAnimation.removeListener(listenerId); + tabAnimation.removeListener(listenerId); }; - }, [cameraTabIndex, tabPositionAnimation, isInTabNavigator, selectedTab]); + }, [cameraTabIndex, tabAnimation, isInTabNavigator, selectedTab]); // Note: The useEffect can be removed once VisionCamera V3 is used. // Its only needed for android, because there is a native cameraX android bug. With out this flow would break the camera: From 4ee167df9e3cecece730c6bf89b8145126982ef8 Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Wed, 8 Nov 2023 09:25:37 +0100 Subject: [PATCH 094/212] bump react-native-collapsible version --- package-lock.json | 11 +++++++---- package.json | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index b9eb50615924..5c7e14208387 100644 --- a/package-lock.json +++ b/package-lock.json @@ -78,7 +78,7 @@ "react-native": "0.72.4", "react-native-android-location-enabler": "^1.2.2", "react-native-blob-util": "^0.17.3", - "react-native-collapsible": "^1.6.0", + "react-native-collapsible": "^1.6.1", "react-native-config": "^1.4.5", "react-native-dev-menu": "^4.1.1", "react-native-device-info": "^10.3.0", @@ -44560,8 +44560,9 @@ } }, "node_modules/react-native-collapsible": { - "version": "1.6.0", - "license": "MIT", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/react-native-collapsible/-/react-native-collapsible-1.6.1.tgz", + "integrity": "sha512-orF4BeiXd2hZW7fu9YcqIJXzN6TJcFcddY807D3MAOVktLuW9oQ+RIkrTJ5DR3v9ZOFfREkOjEmS79qeUTvkBQ==", "peerDependencies": { "react": "*", "react-native": "*" @@ -85276,7 +85277,9 @@ "dev": true }, "react-native-collapsible": { - "version": "1.6.0", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/react-native-collapsible/-/react-native-collapsible-1.6.1.tgz", + "integrity": "sha512-orF4BeiXd2hZW7fu9YcqIJXzN6TJcFcddY807D3MAOVktLuW9oQ+RIkrTJ5DR3v9ZOFfREkOjEmS79qeUTvkBQ==", "requires": {} }, "react-native-config": { diff --git a/package.json b/package.json index f10ec0d81ee9..0b05e0705537 100644 --- a/package.json +++ b/package.json @@ -127,7 +127,7 @@ "react-native": "0.72.4", "react-native-android-location-enabler": "^1.2.2", "react-native-blob-util": "^0.17.3", - "react-native-collapsible": "^1.6.0", + "react-native-collapsible": "^1.6.1", "react-native-config": "^1.4.5", "react-native-dev-menu": "^4.1.1", "react-native-device-info": "^10.3.0", From 6740d923d323f7885ae09971eccdec9fd9e1297e Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Wed, 8 Nov 2023 09:26:41 +0100 Subject: [PATCH 095/212] migrate Collapsible to TypeScript --- .../Collapsible/index.native.js | 24 ------------------- .../Collapsible/index.native.tsx | 15 ++++++++++++ .../Collapsible/{index.js => index.tsx} | 0 3 files changed, 15 insertions(+), 24 deletions(-) delete mode 100644 src/components/CollapsibleSection/Collapsible/index.native.js create mode 100644 src/components/CollapsibleSection/Collapsible/index.native.tsx rename src/components/CollapsibleSection/Collapsible/{index.js => index.tsx} (100%) diff --git a/src/components/CollapsibleSection/Collapsible/index.native.js b/src/components/CollapsibleSection/Collapsible/index.native.js deleted file mode 100644 index 9b800304beeb..000000000000 --- a/src/components/CollapsibleSection/Collapsible/index.native.js +++ /dev/null @@ -1,24 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import CollapsibleRN from 'react-native-collapsible'; - -const propTypes = { - /** Whether the section should start expanded. False by default */ - isOpened: PropTypes.bool, - - /** Children to display inside the Collapsible component */ - children: PropTypes.node.isRequired, -}; - -const defaultProps = { - isOpened: false, -}; - -function Collapsible(props) { - return {props.children}; -} - -Collapsible.displayName = 'Collapsible'; -Collapsible.propTypes = propTypes; -Collapsible.defaultProps = defaultProps; -export default Collapsible; diff --git a/src/components/CollapsibleSection/Collapsible/index.native.tsx b/src/components/CollapsibleSection/Collapsible/index.native.tsx new file mode 100644 index 000000000000..48f118c7a189 --- /dev/null +++ b/src/components/CollapsibleSection/Collapsible/index.native.tsx @@ -0,0 +1,15 @@ +import React from 'react'; +import CollapsibleRN from 'react-native-collapsible'; +import ChildrenProps from '@src/types/utils/ChildrenProps'; + +type CollapsibleProps = ChildrenProps & { + /** Whether the section should start expanded. False by default */ + isOpened?: boolean; +}; + +function Collapsible({isOpened = false, children}: CollapsibleProps) { + return {children}; +} + +Collapsible.displayName = 'Collapsible'; +export default Collapsible; diff --git a/src/components/CollapsibleSection/Collapsible/index.js b/src/components/CollapsibleSection/Collapsible/index.tsx similarity index 100% rename from src/components/CollapsibleSection/Collapsible/index.js rename to src/components/CollapsibleSection/Collapsible/index.tsx From 0f9ecf598c70763153918a53f445b22471150a56 Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Wed, 8 Nov 2023 09:26:56 +0100 Subject: [PATCH 096/212] start migrating CollapsibleSection to TypeScript --- src/components/CollapsibleSection/index.js | 71 --------------------- src/components/CollapsibleSection/index.tsx | 57 +++++++++++++++++ 2 files changed, 57 insertions(+), 71 deletions(-) delete mode 100644 src/components/CollapsibleSection/index.js create mode 100644 src/components/CollapsibleSection/index.tsx diff --git a/src/components/CollapsibleSection/index.js b/src/components/CollapsibleSection/index.js deleted file mode 100644 index 32d422297ca4..000000000000 --- a/src/components/CollapsibleSection/index.js +++ /dev/null @@ -1,71 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import {View} from 'react-native'; -import Icon from '@components/Icon'; -import * as Expensicons from '@components/Icon/Expensicons'; -import PressableWithFeedback from '@components/Pressable/PressableWithFeedback'; -import Text from '@components/Text'; -import styles from '@styles/styles'; -import CONST from '@src/CONST'; -import Collapsible from './Collapsible'; - -const propTypes = { - /** Title of the Collapsible section */ - title: PropTypes.string.isRequired, - - /** Children to display inside the Collapsible component */ - children: PropTypes.node.isRequired, -}; - -class CollapsibleSection extends React.Component { - constructor(props) { - super(props); - this.toggleSection = this.toggleSection.bind(this); - this.state = { - isExpanded: false, - }; - } - - /** - * Expands/collapses the section - */ - toggleSection() { - this.setState((prevState) => ({ - isExpanded: !prevState.isExpanded, - })); - } - - render() { - const src = this.state.isExpanded ? Expensicons.UpArrow : Expensicons.DownArrow; - - return ( - - - - {this.props.title} - - - - - - - {this.props.children} - - - ); - } -} - -CollapsibleSection.propTypes = propTypes; -export default CollapsibleSection; diff --git a/src/components/CollapsibleSection/index.tsx b/src/components/CollapsibleSection/index.tsx new file mode 100644 index 000000000000..1475b535cdaa --- /dev/null +++ b/src/components/CollapsibleSection/index.tsx @@ -0,0 +1,57 @@ +import React, {useState} from 'react'; +import {View} from 'react-native'; +import Icon from '@components/Icon'; +import * as Expensicons from '@components/Icon/Expensicons'; +import PressableWithFeedback from '@components/Pressable/PressableWithFeedback'; +import Text from '@components/Text'; +import styles from '@styles/styles'; +import CONST from '@src/CONST'; +import ChildrenProps from '@src/types/utils/ChildrenProps'; +import Collapsible from './Collapsible'; + +type CollapsibleSectionProps = ChildrenProps & { + /** Title of the Collapsible section */ + title: string; +}; + +function CollapsibleSection(props: CollapsibleSectionProps) { + const [isExpanded, setIsExpanded] = useState(false); + + /** + * Expands/collapses the section + */ + const toggleSection = () => { + setIsExpanded(!isExpanded); + }; + + const src = isExpanded ? Expensicons.UpArrow : Expensicons.DownArrow; + + return ( + + + + {props.title} + + + + + + + {props.children} + + + ); +} + +export default CollapsibleSection; From 280909e3327a95d775765024e4dfbf7eadee312b Mon Sep 17 00:00:00 2001 From: Viktoryia Kliushun Date: Wed, 8 Nov 2023 11:38:44 +0100 Subject: [PATCH 097/212] [TS migration] Migrate 'MultipleAvatars.js' component --- ...MultipleAvatars.js => MultipleAvatars.tsx} | 242 ++++++++++-------- src/components/Tooltip/index.js | 2 +- src/components/UserDetailsTooltip/index.js | 2 +- src/libs/UserUtils.ts | 3 + src/styles/StyleUtils.ts | 14 +- 5 files changed, 144 insertions(+), 119 deletions(-) rename src/components/{MultipleAvatars.js => MultipleAvatars.tsx} (57%) diff --git a/src/components/MultipleAvatars.js b/src/components/MultipleAvatars.tsx similarity index 57% rename from src/components/MultipleAvatars.js rename to src/components/MultipleAvatars.tsx index 209540189b69..00c591e3a580 100644 --- a/src/components/MultipleAvatars.js +++ b/src/components/MultipleAvatars.tsx @@ -1,77 +1,85 @@ -import PropTypes from 'prop-types'; import React, {memo, useMemo} from 'react'; -import {View} from 'react-native'; -import _ from 'underscore'; +import {StyleProp, View, ViewStyle} from 'react-native'; +import {ValueOf} from 'type-fest'; +import {AvatarSource} from '@libs/UserUtils'; import styles from '@styles/styles'; import * as StyleUtils from '@styles/StyleUtils'; import themeColors from '@styles/themes/default'; import variables from '@styles/variables'; import CONST from '@src/CONST'; import Avatar from './Avatar'; -import avatarPropTypes from './avatarPropTypes'; import Text from './Text'; import Tooltip from './Tooltip'; import UserDetailsTooltip from './UserDetailsTooltip'; -const propTypes = { +type AvatarType = { + /** Avatar source to display */ + source?: AvatarSource; + + /** Denotes whether it is an avatar or a workspace avatar */ + type?: typeof CONST.ICON_TYPE_AVATAR | typeof CONST.ICON_TYPE_WORKSPACE; + + /** Owner of the avatar. If user, displayName. If workspace, policy name */ + name?: string; + + /** Avatar id */ + id?: number | string; + + /** A fallback avatar icon to display when there is an error on loading avatar from remote URL. */ + fallbackIcon?: AvatarSource; +}; + +type MultipleAvatarsProps = { /** Array of avatar URLs or icons */ - icons: PropTypes.arrayOf(avatarPropTypes), + icons: AvatarType[]; /** Set the size of avatars */ - size: PropTypes.oneOf(_.values(CONST.AVATAR_SIZE)), + size: ValueOf; /** Style for Second Avatar */ - // eslint-disable-next-line react/forbid-prop-types - secondAvatarStyle: PropTypes.arrayOf(PropTypes.object), + secondAvatarStyle: StyleProp; /** A fallback avatar icon to display when there is an error on loading avatar from remote URL. */ - fallbackIcon: PropTypes.oneOfType([PropTypes.func, PropTypes.string]), + fallbackIcon?: AvatarSource; /** Prop to identify if we should load avatars vertically instead of diagonally */ - shouldStackHorizontally: PropTypes.bool, + shouldStackHorizontally?: boolean; /** Prop to identify if we should display avatars in rows */ - shouldDisplayAvatarsInRows: PropTypes.bool, + shouldDisplayAvatarsInRows?: boolean; /** Whether the avatars are hovered */ - isHovered: PropTypes.bool, + isHovered?: boolean; /** Whether the avatars are in an element being pressed */ - isPressed: PropTypes.bool, + isPressed?: boolean; /** Whether #focus mode is on */ - isFocusMode: PropTypes.bool, + isFocusMode?: boolean; /** Whether avatars are displayed within a reportAction */ - isInReportAction: PropTypes.bool, + isInReportAction?: boolean; /** Whether to show the toolip text */ - shouldShowTooltip: PropTypes.bool, + shouldShowTooltip?: boolean; /** Whether avatars are displayed with the highlighted background color instead of the app background color. This is primarily the case for IOU previews. */ - shouldUseCardBackground: PropTypes.bool, + shouldUseCardBackground?: boolean; /** Prop to limit the amount of avatars displayed horizontally */ - maxAvatarsInRow: PropTypes.number, + maxAvatarsInRow?: number; }; -const defaultProps = { - icons: [], - size: CONST.AVATAR_SIZE.DEFAULT, - secondAvatarStyle: [StyleUtils.getBackgroundAndBorderStyle(themeColors.componentBG)], - fallbackIcon: undefined, - shouldStackHorizontally: false, - shouldDisplayAvatarsInRows: false, - isHovered: false, - isPressed: false, - isFocusMode: false, - isInReportAction: false, - shouldShowTooltip: true, - shouldUseCardBackground: false, - maxAvatarsInRow: CONST.AVATAR_ROW_SIZE.DEFAULT, +type AvatarStyles = { + singleAvatarStyle: ViewStyle; + secondAvatarStyles: ViewStyle; }; -const avatarSizeToStylesMap = { +type AvatarSizeToStyles = typeof CONST.AVATAR_SIZE.SMALL | typeof CONST.AVATAR_SIZE.LARGE | typeof CONST.AVATAR_SIZE.DEFAULT; + +type AvatarSizeToStylesMap = Record; + +const avatarSizeToStylesMap: AvatarSizeToStylesMap = { [CONST.AVATAR_SIZE.SMALL]: { singleAvatarStyle: styles.singleAvatarSmall, secondAvatarStyles: styles.secondAvatarSmall, @@ -80,78 +88,93 @@ const avatarSizeToStylesMap = { singleAvatarStyle: styles.singleAvatarMedium, secondAvatarStyles: styles.secondAvatarMedium, }, - default: { + [CONST.AVATAR_SIZE.DEFAULT]: { singleAvatarStyle: styles.singleAvatar, secondAvatarStyles: styles.secondAvatar, }, }; -function MultipleAvatars(props) { - let avatarContainerStyles = StyleUtils.getContainerStyles(props.size, props.isInReportAction); - const {singleAvatarStyle, secondAvatarStyles} = useMemo(() => avatarSizeToStylesMap[props.size] || avatarSizeToStylesMap.default, [props.size]); - const tooltipTexts = props.shouldShowTooltip ? _.pluck(props.icons, 'name') : ['']; +function MultipleAvatars({ + fallbackIcon, + icons = [], + size = CONST.AVATAR_SIZE.DEFAULT, + secondAvatarStyle = [StyleUtils.getBackgroundAndBorderStyle(themeColors.componentBG)], + shouldStackHorizontally = false, + shouldDisplayAvatarsInRows = false, + isHovered = false, + isPressed = false, + isFocusMode = false, + isInReportAction = false, + shouldShowTooltip = true, + shouldUseCardBackground = false, + maxAvatarsInRow = CONST.AVATAR_ROW_SIZE.DEFAULT, +}: MultipleAvatarsProps) { + let avatarContainerStyles = StyleUtils.getContainerStyles(size, isInReportAction); + const {singleAvatarStyle, secondAvatarStyles} = useMemo(() => avatarSizeToStylesMap[size as AvatarSizeToStyles] ?? avatarSizeToStylesMap.default, [size]); + + const tooltipTexts = shouldShowTooltip ? icons.map((icon) => icon.name) : ['']; const avatarSize = useMemo(() => { - if (props.isFocusMode) { + if (isFocusMode) { return CONST.AVATAR_SIZE.MID_SUBSCRIPT; } - if (props.size === CONST.AVATAR_SIZE.LARGE) { + if (size === CONST.AVATAR_SIZE.LARGE) { return CONST.AVATAR_SIZE.MEDIUM; } return CONST.AVATAR_SIZE.SMALLER; - }, [props.isFocusMode, props.size]); + }, [isFocusMode, size]); const avatarRows = useMemo(() => { // If we're not displaying avatars in rows or the number of icons is less than or equal to the max avatars in a row, return a single row - if (!props.shouldDisplayAvatarsInRows || props.icons.length <= props.maxAvatarsInRow) { - return [props.icons]; + if (!shouldDisplayAvatarsInRows || icons.length <= maxAvatarsInRow) { + return [icons]; } // Calculate the size of each row - const rowSize = Math.min(Math.ceil(props.icons.length / 2), props.maxAvatarsInRow); + const rowSize = Math.min(Math.ceil(icons.length / 2), maxAvatarsInRow); // Slice the icons array into two rows - const firstRow = props.icons.slice(rowSize); - const secondRow = props.icons.slice(0, rowSize); + const firstRow = icons.slice(rowSize); + const secondRow = icons.slice(0, rowSize); // Update the state with the two rows as an array return [firstRow, secondRow]; - }, [props.icons, props.maxAvatarsInRow, props.shouldDisplayAvatarsInRows]); + }, [icons, maxAvatarsInRow, shouldDisplayAvatarsInRows]); - if (!props.icons.length) { + if (!icons.length) { return null; } - if (props.icons.length === 1 && !props.shouldStackHorizontally) { + if (icons.length === 1 && !shouldStackHorizontally) { return ( ); } - const oneAvatarSize = StyleUtils.getAvatarStyle(props.size); - const oneAvatarBorderWidth = StyleUtils.getAvatarBorderWidth(props.size).borderWidth; + const oneAvatarSize = StyleUtils.getAvatarStyle(size); + const oneAvatarBorderWidth = StyleUtils.getAvatarBorderWidth(size).borderWidth ?? 0; const overlapSize = oneAvatarSize.width / 3; - if (props.shouldStackHorizontally) { + if (shouldStackHorizontally) { // Height of one avatar + border space const height = oneAvatarSize.height + 2 * oneAvatarBorderWidth; avatarContainerStyles = StyleUtils.combineStyles([styles.alignItemsCenter, styles.flexRow, StyleUtils.getHeight(height)]); @@ -159,36 +182,37 @@ function MultipleAvatars(props) { return ( <> - {props.shouldStackHorizontally ? ( - _.map(avatarRows, (avatars, rowIndex) => ( + {shouldStackHorizontally ? ( + avatarRows.map((avatars, rowIndex) => ( - {_.map([...avatars].splice(0, props.maxAvatarsInRow), (icon, index) => ( + {[...avatars].splice(0, maxAvatarsInRow).map((icon, index) => ( - + ))} - {avatars.length > props.maxAvatarsInRow && ( + {avatars.length > maxAvatarsInRow && ( {`+${avatars.length - props.maxAvatarsInRow}`} + >{`+${avatars.length - maxAvatarsInRow}`} @@ -238,53 +262,47 @@ function MultipleAvatars(props) { )) ) : ( - + {/* View is necessary for tooltip to show for multiple avatars in LHN */} - - {props.icons.length === 2 ? ( + + {icons.length === 2 ? ( @@ -292,10 +310,10 @@ function MultipleAvatars(props) { - {`+${props.icons.length - 1}`} + {`+${icons.length - 1}`} @@ -308,8 +326,6 @@ function MultipleAvatars(props) { ); } -MultipleAvatars.defaultProps = defaultProps; -MultipleAvatars.propTypes = propTypes; MultipleAvatars.displayName = 'MultipleAvatars'; export default memo(MultipleAvatars); diff --git a/src/components/Tooltip/index.js b/src/components/Tooltip/index.js index 19a607220e1c..c7c4428e19a3 100644 --- a/src/components/Tooltip/index.js +++ b/src/components/Tooltip/index.js @@ -15,7 +15,7 @@ const defaultProps = { shouldRender: true, }; -function Tooltip({shouldRender, children, ...props}) { +function Tooltip({shouldRender = true, children, ...props}) { if (!shouldRender) { return children; } diff --git a/src/components/UserDetailsTooltip/index.js b/src/components/UserDetailsTooltip/index.js index ea5cd4337071..6e256ac9ba9e 100644 --- a/src/components/UserDetailsTooltip/index.js +++ b/src/components/UserDetailsTooltip/index.js @@ -15,7 +15,7 @@ const defaultProps = { shouldRender: true, }; -function UserDetailsTooltip({shouldRender, children, ...props}) { +function UserDetailsTooltip({shouldRender = true, children, ...props}) { if (!shouldRender) { return children; } diff --git a/src/libs/UserUtils.ts b/src/libs/UserUtils.ts index f7883609f625..1a5ced6c9f85 100644 --- a/src/libs/UserUtils.ts +++ b/src/libs/UserUtils.ts @@ -8,6 +8,8 @@ import hashCode from './hashCode'; type AvatarRange = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24; +type AvatarSource = React.FC | string; + type LoginListIndicator = ValueOf | ''; /** @@ -202,3 +204,4 @@ export { getFullSizeAvatar, generateAccountID, }; +export type {AvatarSource}; diff --git a/src/styles/StyleUtils.ts b/src/styles/StyleUtils.ts index 42b7860ee263..b1116b372c2f 100644 --- a/src/styles/StyleUtils.ts +++ b/src/styles/StyleUtils.ts @@ -17,6 +17,12 @@ import variables from './variables'; type AllStyles = ViewStyle | TextStyle | ImageStyle; type ParsableStyle = StyleProp | ((state: PressableStateCallbackType) => StyleProp); +type AvatarStyle = { + width: number; + height: number; + borderRadius: number; + backgroundColor: string; +}; type ColorValue = ValueOf; type AvatarSizeName = ValueOf; @@ -210,7 +216,7 @@ function getAvatarWidthStyle(size: AvatarSizeName): ViewStyle { /** * Return the style from an avatar size constant */ -function getAvatarStyle(size: AvatarSizeName): ViewStyle { +function getAvatarStyle(size: AvatarSizeName): AvatarStyle { const avatarSize = getAvatarSize(size); return { height: avatarSize, @@ -241,7 +247,7 @@ function getAvatarBorderWidth(size: AvatarSizeName): ViewStyle { /** * Return the border radius for an avatar */ -function getAvatarBorderRadius(size: AvatarSizeName, type: string): ViewStyle { +function getAvatarBorderRadius(size: AvatarSizeName, type?: string): ViewStyle { if (type === CONST.ICON_TYPE_WORKSPACE) { return {borderRadius: avatarBorderSizes[size]}; } @@ -1286,8 +1292,8 @@ function getAmountFontSizeAndLineHeight(baseFontSize: number, baseLineHeight: nu /** * Returns container styles for showing the icons in MultipleAvatars/SubscriptAvatar */ -function getContainerStyles(size: string, isInReportAction = false): Array { - let containerStyles: Array; +function getContainerStyles(size: string, isInReportAction = false): ViewStyle[] { + let containerStyles: ViewStyle[]; switch (size) { case CONST.AVATAR_SIZE.SMALL: From ab92c85b94f09b58e565ac66b15528b53affbdaf Mon Sep 17 00:00:00 2001 From: Viktoryia Kliushun Date: Wed, 8 Nov 2023 12:26:04 +0100 Subject: [PATCH 098/212] Update OnyxCommon Icon type --- src/components/MultipleAvatars.tsx | 20 ++------------------ src/types/onyx/OnyxCommon.ts | 19 +++++++++++++++---- 2 files changed, 17 insertions(+), 22 deletions(-) diff --git a/src/components/MultipleAvatars.tsx b/src/components/MultipleAvatars.tsx index 00c591e3a580..e3d871e0f888 100644 --- a/src/components/MultipleAvatars.tsx +++ b/src/components/MultipleAvatars.tsx @@ -7,31 +7,15 @@ import * as StyleUtils from '@styles/StyleUtils'; import themeColors from '@styles/themes/default'; import variables from '@styles/variables'; import CONST from '@src/CONST'; +import type {Icon} from '@src/types/onyx/OnyxCommon'; import Avatar from './Avatar'; import Text from './Text'; import Tooltip from './Tooltip'; import UserDetailsTooltip from './UserDetailsTooltip'; -type AvatarType = { - /** Avatar source to display */ - source?: AvatarSource; - - /** Denotes whether it is an avatar or a workspace avatar */ - type?: typeof CONST.ICON_TYPE_AVATAR | typeof CONST.ICON_TYPE_WORKSPACE; - - /** Owner of the avatar. If user, displayName. If workspace, policy name */ - name?: string; - - /** Avatar id */ - id?: number | string; - - /** A fallback avatar icon to display when there is an error on loading avatar from remote URL. */ - fallbackIcon?: AvatarSource; -}; - type MultipleAvatarsProps = { /** Array of avatar URLs or icons */ - icons: AvatarType[]; + icons: Icon[]; /** Set the size of avatars */ size: ValueOf; diff --git a/src/types/onyx/OnyxCommon.ts b/src/types/onyx/OnyxCommon.ts index ef2944d6af82..4d376b8b7da8 100644 --- a/src/types/onyx/OnyxCommon.ts +++ b/src/types/onyx/OnyxCommon.ts @@ -1,5 +1,5 @@ -import * as React from 'react'; import {ValueOf} from 'type-fest'; +import {AvatarSource} from '@libs/UserUtils'; import CONST from '@src/CONST'; type PendingAction = ValueOf; @@ -11,9 +11,20 @@ type ErrorFields = Record; type Icon = { - source: React.ReactNode | string; - type: 'avatar' | 'workspace'; - name: string; + /** Avatar source to display */ + source?: AvatarSource; + + /** Denotes whether it is an avatar or a workspace avatar */ + type?: typeof CONST.ICON_TYPE_AVATAR | typeof CONST.ICON_TYPE_WORKSPACE; + + /** Owner of the avatar. If user, displayName. If workspace, policy name */ + name?: string; + + /** Avatar id */ + id?: number | string; + + /** A fallback avatar icon to display when there is an error on loading avatar from remote URL. */ + fallbackIcon?: AvatarSource; }; export type {Icon, PendingAction, PendingFields, ErrorFields, Errors}; From cf6410f9128a085ef065fd3441cd352885bb799a Mon Sep 17 00:00:00 2001 From: Viktoryia Kliushun Date: Wed, 8 Nov 2023 12:39:35 +0100 Subject: [PATCH 099/212] Add useMemo for tooltipTexts --- src/components/MultipleAvatars.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/MultipleAvatars.tsx b/src/components/MultipleAvatars.tsx index e3d871e0f888..a86d4946856e 100644 --- a/src/components/MultipleAvatars.tsx +++ b/src/components/MultipleAvatars.tsx @@ -96,7 +96,7 @@ function MultipleAvatars({ let avatarContainerStyles = StyleUtils.getContainerStyles(size, isInReportAction); const {singleAvatarStyle, secondAvatarStyles} = useMemo(() => avatarSizeToStylesMap[size as AvatarSizeToStyles] ?? avatarSizeToStylesMap.default, [size]); - const tooltipTexts = shouldShowTooltip ? icons.map((icon) => icon.name) : ['']; + const tooltipTexts = useMemo(() => (shouldShowTooltip ? icons.map((icon) => icon.name) : ['']), [shouldShowTooltip, icons]); const avatarSize = useMemo(() => { if (isFocusMode) { return CONST.AVATAR_SIZE.MID_SUBSCRIPT; From d04a7338598becd085b2e6f8398ca21888fbc82e Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Wed, 8 Nov 2023 13:24:09 +0100 Subject: [PATCH 100/212] fix type errors on CollapsibleSection --- src/components/CollapsibleSection/Collapsible/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/CollapsibleSection/Collapsible/index.tsx b/src/components/CollapsibleSection/Collapsible/index.tsx index 51d650ed5748..867f0bb1228b 100644 --- a/src/components/CollapsibleSection/Collapsible/index.tsx +++ b/src/components/CollapsibleSection/Collapsible/index.tsx @@ -1,3 +1,3 @@ -import Collapsible from 'react-collapse'; +import {Collapse} from 'react-collapse'; -export default Collapsible; +export default Collapse; From 5d90cc0127907cd27859f1aad899dc8baddf25c7 Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Wed, 8 Nov 2023 13:45:48 +0100 Subject: [PATCH 101/212] create common types file for Collapsible component --- .../CollapsibleSection/Collapsible/index.native.tsx | 7 +------ src/components/CollapsibleSection/Collapsible/index.tsx | 7 ++++++- src/components/CollapsibleSection/Collapsible/types.ts | 8 ++++++++ 3 files changed, 15 insertions(+), 7 deletions(-) create mode 100644 src/components/CollapsibleSection/Collapsible/types.ts diff --git a/src/components/CollapsibleSection/Collapsible/index.native.tsx b/src/components/CollapsibleSection/Collapsible/index.native.tsx index 48f118c7a189..e8d3dc9439d0 100644 --- a/src/components/CollapsibleSection/Collapsible/index.native.tsx +++ b/src/components/CollapsibleSection/Collapsible/index.native.tsx @@ -1,11 +1,6 @@ import React from 'react'; import CollapsibleRN from 'react-native-collapsible'; -import ChildrenProps from '@src/types/utils/ChildrenProps'; - -type CollapsibleProps = ChildrenProps & { - /** Whether the section should start expanded. False by default */ - isOpened?: boolean; -}; +import CollapsibleProps from './types'; function Collapsible({isOpened = false, children}: CollapsibleProps) { return {children}; diff --git a/src/components/CollapsibleSection/Collapsible/index.tsx b/src/components/CollapsibleSection/Collapsible/index.tsx index 867f0bb1228b..2585fd92f42b 100644 --- a/src/components/CollapsibleSection/Collapsible/index.tsx +++ b/src/components/CollapsibleSection/Collapsible/index.tsx @@ -1,3 +1,8 @@ +import React from 'react'; import {Collapse} from 'react-collapse'; +import CollapsibleProps from './types'; -export default Collapse; +function Collapsible({isOpened = false, children}: CollapsibleProps) { + return {children}; +} +export default Collapsible; diff --git a/src/components/CollapsibleSection/Collapsible/types.ts b/src/components/CollapsibleSection/Collapsible/types.ts new file mode 100644 index 000000000000..8b8e8aba6860 --- /dev/null +++ b/src/components/CollapsibleSection/Collapsible/types.ts @@ -0,0 +1,8 @@ +import ChildrenProps from '@src/types/utils/ChildrenProps'; + +type CollapsibleProps = ChildrenProps & { + /** Whether the section should start expanded. False by default */ + isOpened?: boolean; +}; + +export default CollapsibleProps; From 97fde1b8f93521f395595a201ad2e42a187b7e42 Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Wed, 8 Nov 2023 15:00:47 +0100 Subject: [PATCH 102/212] remove unnecessary newline --- src/components/CollapsibleSection/index.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/CollapsibleSection/index.tsx b/src/components/CollapsibleSection/index.tsx index 9b985aea803d..3cb19a52866d 100644 --- a/src/components/CollapsibleSection/index.tsx +++ b/src/components/CollapsibleSection/index.tsx @@ -45,7 +45,6 @@ function CollapsibleSection(props: CollapsibleSectionProps) { - {props.children} From f4afdb42aae6cdd44a552454562c7be0e610836e Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Wed, 8 Nov 2023 15:53:16 +0100 Subject: [PATCH 103/212] remove redundant useNativeDriver prop --- src/components/Modal/index.android.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/Modal/index.android.tsx b/src/components/Modal/index.android.tsx index 6c7f3173fd0a..3aaf2c342634 100644 --- a/src/components/Modal/index.android.tsx +++ b/src/components/Modal/index.android.tsx @@ -20,7 +20,6 @@ function Modal(props: BaseModalProps) { {props.children} From dfa86a01e17d73cb543f15d3eb31753c3e59a7b4 Mon Sep 17 00:00:00 2001 From: Daniel Edwards Date: Wed, 8 Nov 2023 10:48:29 -0500 Subject: [PATCH 104/212] Removed extra SVG and updated fill color --- src/components/ReceiptEmptyState.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/ReceiptEmptyState.js b/src/components/ReceiptEmptyState.js index f32083c650d9..01c1b8a484f5 100644 --- a/src/components/ReceiptEmptyState.js +++ b/src/components/ReceiptEmptyState.js @@ -33,9 +33,8 @@ function ReceiptEmptyState({hasError, onPress}) { src={Expensicons.EmptyStateAttachReceipt} width={variables.iconSizeUltraLarge} height={variables.iconSizeUltraLarge} - fill="#DC80E4" + fill="transparent" /> - ); From ae53f131cb4c76d471a548f05a3bddb2c60d61cf Mon Sep 17 00:00:00 2001 From: Artem Makushov Date: Wed, 8 Nov 2023 17:59:50 +0100 Subject: [PATCH 105/212] remove moment totally --- .../createOrUpdateStagingDeploy.js | 5 +-- .github/libs/CONST.js | 1 + package-lock.json | 36 ------------------- package.json | 2 -- src/libs/actions/App.js | 2 -- tests/unit/createOrUpdateStagingDeployTest.js | 2 +- 6 files changed, 5 insertions(+), 43 deletions(-) diff --git a/.github/actions/javascript/createOrUpdateStagingDeploy/createOrUpdateStagingDeploy.js b/.github/actions/javascript/createOrUpdateStagingDeploy/createOrUpdateStagingDeploy.js index 82a79528ed09..1865da588dc0 100644 --- a/.github/actions/javascript/createOrUpdateStagingDeploy/createOrUpdateStagingDeploy.js +++ b/.github/actions/javascript/createOrUpdateStagingDeploy/createOrUpdateStagingDeploy.js @@ -1,6 +1,7 @@ +import {format} from 'date-fns'; + const _ = require('underscore'); const core = require('@actions/core'); -const moment = require('moment'); const CONST = require('../../../libs/CONST'); const GithubUtils = require('../../../libs/GithubUtils'); const GitUtils = require('../../../libs/GitUtils'); @@ -118,7 +119,7 @@ async function run() { if (shouldCreateNewDeployChecklist) { const {data: newChecklist} = await GithubUtils.octokit.issues.create({ ...defaultPayload, - title: `Deploy Checklist: New Expensify ${moment().format('YYYY-MM-DD')}`, + title: `Deploy Checklist: New Expensify ${format(new Date(), CONST.DATE_FORMAT_STRING)}`, labels: [CONST.LABELS.STAGING_DEPLOY], assignees: [CONST.APPLAUSE_BOT], }); diff --git a/.github/libs/CONST.js b/.github/libs/CONST.js index 36eeb804aa00..b3ba9bed08c1 100644 --- a/.github/libs/CONST.js +++ b/.github/libs/CONST.js @@ -8,6 +8,7 @@ const CONST = { DEPLOY_BLOCKER: 'DeployBlockerCash', INTERNAL_QA: 'InternalQA', }, + DATE_FORMAT_STRING: 'yyyy-MM-dd', }; CONST.APP_REPO_URL = `https://github.com/${CONST.GITHUB_OWNER}/${CONST.APP_REPO}`; diff --git a/package-lock.json b/package-lock.json index 997aa1d0d9e7..3203a064f22b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -60,8 +60,6 @@ "lodash": "4.17.21", "lottie-react-native": "^6.4.0", "mapbox-gl": "^2.15.0", - "moment": "^2.29.4", - "moment-timezone": "^0.5.31", "onfido-sdk-ui": "13.1.0", "patch-package": "^8.0.0", "process": "^0.11.10", @@ -41318,27 +41316,6 @@ "dev": true, "license": "MIT" }, - "node_modules/moment": { - "version": "2.29.4", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", - "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==", - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/moment-timezone": { - "version": "0.5.43", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.43.tgz", - "integrity": "sha512-72j3aNyuIsDxdF1i7CEgV2FfxM1r6aaqJyLB2vwb33mXYyoyLly+F1zbWqhA3/bVIoJ4szlUoMbUnVdid32NUQ==", - "license": "MIT", - "dependencies": { - "moment": "^2.29.4" - }, - "engines": { - "node": "*" - } - }, "node_modules/move-concurrently": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", @@ -82814,19 +82791,6 @@ "integrity": "sha512-qYvlv/exQ4+svI3UOvPUpLDF0OMX5euvUH0Ny4N5QyRyhNdgAgUrVH3iUINSzEPLvx0kbo/Bp28GJKIqvE7URw==", "dev": true }, - "moment": { - "version": "2.29.4", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", - "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==" - }, - "moment-timezone": { - "version": "0.5.43", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.43.tgz", - "integrity": "sha512-72j3aNyuIsDxdF1i7CEgV2FfxM1r6aaqJyLB2vwb33mXYyoyLly+F1zbWqhA3/bVIoJ4szlUoMbUnVdid32NUQ==", - "requires": { - "moment": "^2.29.4" - } - }, "move-concurrently": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", diff --git a/package.json b/package.json index 9f5c9d5bff73..553678001701 100644 --- a/package.json +++ b/package.json @@ -109,8 +109,6 @@ "lodash": "4.17.21", "lottie-react-native": "^6.4.0", "mapbox-gl": "^2.15.0", - "moment": "^2.29.4", - "moment-timezone": "^0.5.31", "onfido-sdk-ui": "13.1.0", "patch-package": "^8.0.0", "process": "^0.11.10", diff --git a/src/libs/actions/App.js b/src/libs/actions/App.js index 884dddf0eb0a..48b75dcb9cf5 100644 --- a/src/libs/actions/App.js +++ b/src/libs/actions/App.js @@ -1,8 +1,6 @@ -// Do not remove this import until moment package is fully removed. // Issue - https://github.com/Expensify/App/issues/26719 import Str from 'expensify-common/lib/str'; import lodashGet from 'lodash/get'; -import 'moment/locale/es'; import {AppState} from 'react-native'; import Onyx from 'react-native-onyx'; import _ from 'underscore'; diff --git a/tests/unit/createOrUpdateStagingDeployTest.js b/tests/unit/createOrUpdateStagingDeployTest.js index 9183268f15f0..6ac3d90d806d 100644 --- a/tests/unit/createOrUpdateStagingDeployTest.js +++ b/tests/unit/createOrUpdateStagingDeployTest.js @@ -6,7 +6,7 @@ const fns = require('date-fns'); const CONST = require('../../.github/libs/CONST'); const GitUtils = require('../../.github/libs/GitUtils'); const GithubUtils = require('../../.github/libs/GithubUtils'); -const run = require('../../.github/actions/javascript/createOrUpdateStagingDeploy/createOrUpdateStagingDeploy'); +const run = require('../../.github/actions/javascript/createOrUpdateStagingDeploy/createOrUpdateStagingDeploy').default; const mockGetInput = jest.fn(); const mockListIssues = jest.fn(); From ccd4b44379392357f2b8a61cac08a0453e0b9898 Mon Sep 17 00:00:00 2001 From: Artem Makushov Date: Wed, 8 Nov 2023 18:03:46 +0100 Subject: [PATCH 106/212] remove import --- .../createOrUpdateStagingDeploy/createOrUpdateStagingDeploy.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/actions/javascript/createOrUpdateStagingDeploy/createOrUpdateStagingDeploy.js b/.github/actions/javascript/createOrUpdateStagingDeploy/createOrUpdateStagingDeploy.js index 1865da588dc0..f81a181cb8d3 100644 --- a/.github/actions/javascript/createOrUpdateStagingDeploy/createOrUpdateStagingDeploy.js +++ b/.github/actions/javascript/createOrUpdateStagingDeploy/createOrUpdateStagingDeploy.js @@ -1,5 +1,4 @@ -import {format} from 'date-fns'; - +const format = require('date-fns/format'); const _ = require('underscore'); const core = require('@actions/core'); const CONST = require('../../../libs/CONST'); From bc3181ae12a98fd29add7af9e51847c6cc18a08a Mon Sep 17 00:00:00 2001 From: Viktoryia Kliushun Date: Wed, 8 Nov 2023 18:06:05 +0100 Subject: [PATCH 107/212] Make size and secondAvatarStyle to be optional --- src/components/MultipleAvatars.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/MultipleAvatars.tsx b/src/components/MultipleAvatars.tsx index a86d4946856e..4101fd381a3f 100644 --- a/src/components/MultipleAvatars.tsx +++ b/src/components/MultipleAvatars.tsx @@ -18,10 +18,10 @@ type MultipleAvatarsProps = { icons: Icon[]; /** Set the size of avatars */ - size: ValueOf; + size?: ValueOf; /** Style for Second Avatar */ - secondAvatarStyle: StyleProp; + secondAvatarStyle?: StyleProp; /** A fallback avatar icon to display when there is an error on loading avatar from remote URL. */ fallbackIcon?: AvatarSource; From 5ef4f9b94b26377ffacb6805ca7be12425bf61a3 Mon Sep 17 00:00:00 2001 From: Artem Makushov Date: Wed, 8 Nov 2023 18:07:43 +0100 Subject: [PATCH 108/212] removed accidently added default --- tests/unit/createOrUpdateStagingDeployTest.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/createOrUpdateStagingDeployTest.js b/tests/unit/createOrUpdateStagingDeployTest.js index 6ac3d90d806d..9183268f15f0 100644 --- a/tests/unit/createOrUpdateStagingDeployTest.js +++ b/tests/unit/createOrUpdateStagingDeployTest.js @@ -6,7 +6,7 @@ const fns = require('date-fns'); const CONST = require('../../.github/libs/CONST'); const GitUtils = require('../../.github/libs/GitUtils'); const GithubUtils = require('../../.github/libs/GithubUtils'); -const run = require('../../.github/actions/javascript/createOrUpdateStagingDeploy/createOrUpdateStagingDeploy').default; +const run = require('../../.github/actions/javascript/createOrUpdateStagingDeploy/createOrUpdateStagingDeploy'); const mockGetInput = jest.fn(); const mockListIssues = jest.fn(); From 22f237f122150cfa41698d19835c044e76460ea8 Mon Sep 17 00:00:00 2001 From: Viktoryia Kliushun Date: Wed, 8 Nov 2023 18:50:06 +0100 Subject: [PATCH 109/212] Remove unused avatar props --- src/components/MultipleAvatars.tsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/components/MultipleAvatars.tsx b/src/components/MultipleAvatars.tsx index 4101fd381a3f..e867de7ddb97 100644 --- a/src/components/MultipleAvatars.tsx +++ b/src/components/MultipleAvatars.tsx @@ -137,7 +137,6 @@ function MultipleAvatars({ icon={icons[0]} fallbackUserDetails={{ displayName: icons[0].name, - avatar: icons[0].source, }} > @@ -180,7 +179,6 @@ function MultipleAvatars({ icon={icon} fallbackUserDetails={{ displayName: icon.name, - avatar: icon.source, }} > @@ -252,7 +250,6 @@ function MultipleAvatars({ icon={icons[0]} fallbackUserDetails={{ displayName: icons[0].name, - avatar: icons[0].source, }} > {/* View is necessary for tooltip to show for multiple avatars in LHN */} @@ -275,7 +272,6 @@ function MultipleAvatars({ icon={icons[1]} fallbackUserDetails={{ displayName: icons[1].name, - avatar: icons[1].source, }} > From 8082b7c49407a2048faedf6cc432faa407adccab Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Thu, 9 Nov 2023 08:54:52 +0100 Subject: [PATCH 110/212] bring back default useNativeDriver prop for android --- src/components/Modal/index.android.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/components/Modal/index.android.tsx b/src/components/Modal/index.android.tsx index 3aaf2c342634..2343cb4c70a9 100644 --- a/src/components/Modal/index.android.tsx +++ b/src/components/Modal/index.android.tsx @@ -15,13 +15,14 @@ AppState.addEventListener('blur', () => { // Only want to use useNativeDriver on Android. It has strange flashes issue on IOS // https://github.com/react-native-modal/react-native-modal#the-modal-flashes-in-a-weird-way-when-animating -function Modal(props: BaseModalProps) { +function Modal({useNativeDriver = true, ...rest}: BaseModalProps) { return ( - {props.children} + {rest.children} ); } From a5e8a581860dd9e3a9d54f6cb95bc7371342f28d Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Thu, 9 Nov 2023 09:31:50 +0100 Subject: [PATCH 111/212] add optional chaining to onModalShow --- src/components/Modal/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Modal/index.tsx b/src/components/Modal/index.tsx index 47da7256abf3..3d8a30ba3e2a 100644 --- a/src/components/Modal/index.tsx +++ b/src/components/Modal/index.tsx @@ -35,7 +35,7 @@ function Modal(props: BaseModalProps) { setStatusBarColor(isFullScreenModal ? themeColors.appBG : StyleUtils.getThemeBackgroundColor(statusBarColor)); } - props.onModalShow(); + props.onModalShow?.(); }; return ( From e2d0ba1e5fee0c0f4e7024149dfc3393eb506e22 Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Thu, 9 Nov 2023 11:39:48 +0100 Subject: [PATCH 112/212] destructure props in CollapsibleSection --- src/components/CollapsibleSection/index.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/CollapsibleSection/index.tsx b/src/components/CollapsibleSection/index.tsx index 3cb19a52866d..434017f2a547 100644 --- a/src/components/CollapsibleSection/index.tsx +++ b/src/components/CollapsibleSection/index.tsx @@ -14,7 +14,7 @@ type CollapsibleSectionProps = ChildrenProps & { title: string; }; -function CollapsibleSection(props: CollapsibleSectionProps) { +function CollapsibleSection({title, children}: CollapsibleSectionProps) { const [isExpanded, setIsExpanded] = useState(false); /** @@ -32,7 +32,7 @@ function CollapsibleSection(props: CollapsibleSectionProps) { onPress={toggleSection} style={[styles.pb4, styles.flexRow]} role={CONST.ACCESSIBILITY_ROLE.BUTTON} - accessibilityLabel={props.title} + accessibilityLabel={title} hoverDimmingValue={1} pressDimmingValue={0.2} > @@ -40,13 +40,13 @@ function CollapsibleSection(props: CollapsibleSectionProps) { style={[styles.flex1, styles.textStrong, styles.userSelectNone]} dataSet={{[CONST.SELECTION_SCRAPER_HIDDEN_ELEMENT]: true}} > - {props.title} + {title} - {props.children} + {children} ); From c1ba54297a86b994c3fb6d117a3c7007aa82cdec Mon Sep 17 00:00:00 2001 From: Jakub Trzebiatowski Date: Thu, 9 Nov 2023 12:03:36 +0100 Subject: [PATCH 113/212] Apply to the PR comments --- .../home/report/ReportActionItemFragment.js | 5 +---- .../comment/AttachmentCommentFragment.js | 18 ++++++++---------- .../home/report/comment/RenderCommentHTML.js | 6 +++--- 3 files changed, 12 insertions(+), 17 deletions(-) diff --git a/src/pages/home/report/ReportActionItemFragment.js b/src/pages/home/report/ReportActionItemFragment.js index c569be72658e..fe2308afab27 100644 --- a/src/pages/home/report/ReportActionItemFragment.js +++ b/src/pages/home/report/ReportActionItemFragment.js @@ -107,10 +107,7 @@ function ReportActionItemFragment(props) { return ${props.translate('parentReportAction.deletedMessage')}`} />; } - // Does the fragment content represent an attachment? - const isFragmentAttachment = ReportUtils.isReportMessageAttachment(fragment); - - if (isFragmentAttachment) { + if (ReportUtils.isReportMessageAttachment(fragment)) { return ( - - - ); -} +const AttachmentCommentFragment = ({addExtraMargin, html, source}) => ( + + + +); AttachmentCommentFragment.propTypes = propTypes; AttachmentCommentFragment.displayName = 'AttachmentCommentFragment'; diff --git a/src/pages/home/report/comment/RenderCommentHTML.js b/src/pages/home/report/comment/RenderCommentHTML.js index dc8da2208dd5..cd2f464510e9 100644 --- a/src/pages/home/report/comment/RenderCommentHTML.js +++ b/src/pages/home/report/comment/RenderCommentHTML.js @@ -11,10 +11,10 @@ const propTypes = { html: PropTypes.string.isRequired, }; -function RenderCommentHTML(props) { - const html = props.html; +function RenderCommentHTML({html, source}) { + const commentHtml = source === 'email' ? `${html}` : `${html}`; - return ${html}` : `${html}`} />; + return ; } RenderCommentHTML.propTypes = propTypes; From c7187331f3b0cb3d1ada676d0bdcd2720acc3068 Mon Sep 17 00:00:00 2001 From: Jakub Trzebiatowski Date: Thu, 9 Nov 2023 12:07:21 +0100 Subject: [PATCH 114/212] Run Prettier --- src/pages/home/report/comment/RenderCommentHTML.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/home/report/comment/RenderCommentHTML.js b/src/pages/home/report/comment/RenderCommentHTML.js index cd2f464510e9..14039af21189 100644 --- a/src/pages/home/report/comment/RenderCommentHTML.js +++ b/src/pages/home/report/comment/RenderCommentHTML.js @@ -14,7 +14,7 @@ const propTypes = { function RenderCommentHTML({html, source}) { const commentHtml = source === 'email' ? `${html}` : `${html}`; - return ; + return ; } RenderCommentHTML.propTypes = propTypes; From b81148810c83bba7de2dcdd22dc4ac9878b0b9c5 Mon Sep 17 00:00:00 2001 From: Amjed Nazzal <74202751+AmjedNazzal@users.noreply.github.com> Date: Thu, 9 Nov 2023 16:33:32 +0300 Subject: [PATCH 115/212] Update src/components/AddressSearch/index.js Co-authored-by: Joel Davies --- src/components/AddressSearch/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/AddressSearch/index.js b/src/components/AddressSearch/index.js index 6a28217bfcf6..225ba0a9f7b1 100644 --- a/src/components/AddressSearch/index.js +++ b/src/components/AddressSearch/index.js @@ -257,7 +257,7 @@ function AddressSearch(props) { // Some edge-case addresses may lack both street_number and route in the API response, resulting in an empty "values.street" // We are setting up a fallback to ensure "values.street" is populated with a relevant value if (!values.street && details.adr_address) { - const streetAddressRegex = /]*>([^<]*)<\/span>/; + const streetAddressRegex = /([^<]*)<\/span>/; const adr_address = details.adr_address.match(streetAddressRegex); const streetAddressFallback = _.get(adr_address, [1], null); if (streetAddressFallback) { From d08e0489133018bd21e197d3c84d570b9ad9dea6 Mon Sep 17 00:00:00 2001 From: dukenv0307 Date: Thu, 9 Nov 2023 21:03:51 +0700 Subject: [PATCH 116/212] add display name --- src/components/withTabAnimation.js | 2 ++ .../iou/ReceiptSelector/NavigationAwareCamera/index.native.js | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/withTabAnimation.js b/src/components/withTabAnimation.js index eb1520d4468e..a2afdb26dc6e 100644 --- a/src/components/withTabAnimation.js +++ b/src/components/withTabAnimation.js @@ -21,6 +21,8 @@ export default function (WrappedComponent) { ); } + WrappedComponentWithTabAnimation.displayName = `withAnimation(${getComponentDisplayName(WrappedComponent)})`; + function WithTabAnimation(props, ref) { if (props.isInTabNavigator) { return ( diff --git a/src/pages/iou/ReceiptSelector/NavigationAwareCamera/index.native.js b/src/pages/iou/ReceiptSelector/NavigationAwareCamera/index.native.js index 591c928f423a..eca8042a6965 100644 --- a/src/pages/iou/ReceiptSelector/NavigationAwareCamera/index.native.js +++ b/src/pages/iou/ReceiptSelector/NavigationAwareCamera/index.native.js @@ -15,7 +15,7 @@ const propTypes = { /** Name of the selected receipt tab */ selectedTab: PropTypes.string.isRequired, - /** */ + /** The tab animation from hook */ tabAnimation: PropTypes.shape({ addListener: PropTypes.func, removeListener: PropTypes.func, From f6ef44c255fde9ab083a7f78f5d2b5a4bcc46195 Mon Sep 17 00:00:00 2001 From: Amjed Nazzal <74202751+AmjedNazzal@users.noreply.github.com> Date: Thu, 9 Nov 2023 17:13:30 +0300 Subject: [PATCH 117/212] Fix Issue #28474 switched to lodashget --- src/components/AddressSearch/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/AddressSearch/index.js b/src/components/AddressSearch/index.js index 225ba0a9f7b1..9e05bbc757c5 100644 --- a/src/components/AddressSearch/index.js +++ b/src/components/AddressSearch/index.js @@ -259,7 +259,7 @@ function AddressSearch(props) { if (!values.street && details.adr_address) { const streetAddressRegex = /([^<]*)<\/span>/; const adr_address = details.adr_address.match(streetAddressRegex); - const streetAddressFallback = _.get(adr_address, [1], null); + const streetAddressFallback = lodashGet(adr_address, [1], null); if (streetAddressFallback) { values.street = streetAddressFallback; } From 678807569b0623efe5a3b9253b56fee96563f0d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucas=20M=C3=B3rawski?= Date: Thu, 9 Nov 2023 16:58:07 +0100 Subject: [PATCH 118/212] useTabNavigationFocus hook refactoring --- src/hooks/useTabNavigatorFocus/index.js | 57 +++++++++++++++++ .../useTabNavigatorFocus/index.native.js | 52 +++++++++++++++ .../ReceiptSelector/NavigationAwareCamera.js | 64 +++---------------- .../NavigationAwareCamera.native.js | 60 ++--------------- src/pages/iou/ReceiptSelector/index.js | 8 +-- src/pages/iou/ReceiptSelector/index.native.js | 7 +- 6 files changed, 123 insertions(+), 125 deletions(-) create mode 100644 src/hooks/useTabNavigatorFocus/index.js create mode 100644 src/hooks/useTabNavigatorFocus/index.native.js diff --git a/src/hooks/useTabNavigatorFocus/index.js b/src/hooks/useTabNavigatorFocus/index.js new file mode 100644 index 000000000000..2a41809b7414 --- /dev/null +++ b/src/hooks/useTabNavigatorFocus/index.js @@ -0,0 +1,57 @@ +import {useTabAnimation} from '@react-navigation/material-top-tabs'; +import {useIsFocused} from '@react-navigation/native'; +import {useEffect, useState} from 'react'; + +function useTabNavigatorFocus({tabIndex}) { + let tabPositionAnimation = null; + try { + // Retrieve the animation value from the tab navigator, which ranges from 0 to the total number of pages displayed. + // Even a minimal scroll towards the camera page (e.g., a value of 0.001 at start) should activate the camera for immediate responsiveness. + // STOP!!!!!!! This is not a pattern to be followed! We are conditionally rendering this hook becase when used in the edit flow we'll never be inside a tab navigator. + // eslint-disable-next-line react-hooks/rules-of-hooks + tabPositionAnimation = useTabAnimation(); + } catch (error) { + tabPositionAnimation = null; + } + const isPageFocused = useIsFocused(); + // set to true if the hook is not used within the MaterialTopTabs context + // the hook will then return true if the screen is focused + const [isTabFocused, setIsTabFocused] = useState(!tabPositionAnimation); + + useEffect(() => { + if (!tabPositionAnimation) { + return; + } + const index = Number(tabIndex); + + const listenerId = tabPositionAnimation.addListener(({value}) => { + // Activate camera as soon the index is animating towards the `tabIndex` + requestAnimationFrame(() => { + setIsTabFocused(value > index - 1 && value < index + 1); + }); + }); + + // We need to get the position animation value on component initialization to determine + // if the tab is focused or not. Since it's an Animated.Value the only synchronous way + // to retrieve the value is to use a private method. + // eslint-disable-next-line no-underscore-dangle + const initialTabPositionValue = tabPositionAnimation.__getValue(); + + if (typeof initialTabPositionValue === 'number') { + requestAnimationFrame(() => { + setIsTabFocused(initialTabPositionValue > index - 1 && initialTabPositionValue < index + 1); + }); + } + + return () => { + if (!tabPositionAnimation) { + return; + } + tabPositionAnimation.removeListener(listenerId); + }; + }, [tabIndex, tabPositionAnimation]); + + return isTabFocused && isPageFocused; +} + +export default useTabNavigatorFocus; diff --git a/src/hooks/useTabNavigatorFocus/index.native.js b/src/hooks/useTabNavigatorFocus/index.native.js new file mode 100644 index 000000000000..a313e95ee0dd --- /dev/null +++ b/src/hooks/useTabNavigatorFocus/index.native.js @@ -0,0 +1,52 @@ +import {useTabAnimation} from '@react-navigation/material-top-tabs'; +import {useIsFocused} from '@react-navigation/native'; +import {useEffect, useState} from 'react'; +import CONST from '@src/CONST'; + +function useTabNavigatorFocus({tabIndex, selectedTab}) { + let tabPositionAnimation = null; + try { + // Retrieve the animation value from the tab navigator, which ranges from 0 to the total number of pages displayed. + // Even a minimal scroll towards the camera page (e.g., a value of 0.001 at start) should activate the camera for immediate responsiveness. + // STOP!!!!!!! This is not a pattern to be followed! We are conditionally rendering this hook becase when used in the edit flow we'll never be inside a tab navigator. + // eslint-disable-next-line react-hooks/rules-of-hooks + tabPositionAnimation = useTabAnimation(); + } catch (error) { + tabPositionAnimation = null; + } + const isPageFocused = useIsFocused(); + // set to true if the hook is not used within the MaterialTopTabs context + // the hook will then return true if the screen is focused + const [isTabFocused, setIsTabFocused] = useState(!tabPositionAnimation); + + // Retrieve the animation value from the tab navigator, which ranges from 0 to the total number of pages displayed. + // Even a minimal scroll towards the camera page (e.g., a value of 0.001 at start) should activate the camera for immediate responsiveness. + + // STOP!!!!!!! This is not a pattern to be followed! We are conditionally rendering this hook becase when used in the edit flow we'll never be inside a tab navigator. + // eslint-disable-next-line react-hooks/rules-of-hooks + + useEffect(() => { + if (!tabPositionAnimation) { + return; + } + + const listenerId = tabPositionAnimation.addListener(({value}) => { + if (selectedTab !== CONST.TAB.SCAN) { + return; + } + // Activate camera as soon the index is animating towards the `cameraTabIndex` + setIsTabFocused(value > tabIndex - 1 && value < tabIndex + 1); + }); + + return () => { + if (!tabPositionAnimation) { + return; + } + tabPositionAnimation.removeListener(listenerId); + }; + }, [tabIndex, tabPositionAnimation, selectedTab]); + + return isTabFocused && isPageFocused; +} + +export default useTabNavigatorFocus; diff --git a/src/pages/iou/ReceiptSelector/NavigationAwareCamera.js b/src/pages/iou/ReceiptSelector/NavigationAwareCamera.js index 783ae36f0e07..10b16da13b6e 100644 --- a/src/pages/iou/ReceiptSelector/NavigationAwareCamera.js +++ b/src/pages/iou/ReceiptSelector/NavigationAwareCamera.js @@ -1,24 +1,20 @@ -import {useTabAnimation} from '@react-navigation/material-top-tabs'; -import {useIsFocused} from '@react-navigation/native'; import PropTypes from 'prop-types'; -import React, {useEffect, useRef, useState} from 'react'; +import React, {useEffect, useRef} from 'react'; import {View} from 'react-native'; import Webcam from 'react-webcam'; +import useTabNavigatorFocus from '@hooks/useTabNavigatorFocus'; const propTypes = { - /* Flag to turn on/off the torch/flashlight - if available */ + /** Flag to turn on/off the torch/flashlight - if available */ torchOn: PropTypes.bool, - /* The index of the tab that contains this camera */ + /** The index of the tab that contains this camera */ cameraTabIndex: PropTypes.number.isRequired, - /* Whether we're in a tab navigator */ - isInTabNavigator: PropTypes.bool.isRequired, - - /* Callback function when media stream becomes available - user granted camera permissions and camera starts to work */ + /** Callback function when media stream becomes available - user granted camera permissions and camera starts to work */ onUserMedia: PropTypes.func, - /* Callback function passing torch/flashlight capability as bool param of the browser */ + /** Callback function passing torch/flashlight capability as bool param of the browser */ onTorchAvailability: PropTypes.func, }; @@ -28,55 +24,11 @@ const defaultProps = { torchOn: false, }; -function useTabNavigatorFocus({cameraTabIndex, isInTabNavigator}) { - // Get navigation to get initial isFocused value (only needed once during init!) - const isPageFocused = useIsFocused(); - const [isTabFocused, setIsTabFocused] = useState(false); - - // Retrieve the animation value from the tab navigator, which ranges from 0 to the total number of pages displayed. - // Even a minimal scroll towards the camera page (e.g., a value of 0.001 at start) should activate the camera for immediate responsiveness. - - // STOP!!!!!!! This is not a pattern to be followed! We are conditionally rendering this hook becase when used in the edit flow we'll never be inside a tab navigator. - // eslint-disable-next-line react-hooks/rules-of-hooks - const tabPositionAnimation = isInTabNavigator ? useTabAnimation() : null; - - useEffect(() => { - if (!tabPositionAnimation) { - return; - } - const index = Number(cameraTabIndex); - - const listenerId = tabPositionAnimation.addListener(({value}) => { - // Activate camera as soon the index is animating towards the `cameraTabIndex` - requestAnimationFrame(() => { - setIsTabFocused(value > index - 1 && value < index + 1); - }); - }); - - // We need to get the position animation value on component initialization to determine - // if the tab is focused or not. Since it's an Animated.Value the only synchronous way - // to retrieve the value is to use a private method. - // eslint-disable-next-line no-underscore-dangle - const initialTabPositionValue = tabPositionAnimation.__getValue(); - - requestAnimationFrame(() => { - setIsTabFocused(initialTabPositionValue > index - 1 && initialTabPositionValue < index + 1); - }); - - return () => { - tabPositionAnimation.removeListener(listenerId); - }; - }, [cameraTabIndex, tabPositionAnimation, isInTabNavigator]); - - return isTabFocused && isPageFocused; -} - // Wraps a camera that will only be active when the tab is focused or as soon as it starts to become focused. -const NavigationAwareCamera = React.forwardRef(({torchOn, onTorchAvailability, cameraTabIndex, isInTabNavigator, ...props}, ref) => { +const NavigationAwareCamera = React.forwardRef(({torchOn, onTorchAvailability, cameraTabIndex, ...props}, ref) => { const trackRef = useRef(null); const shouldShowCamera = useTabNavigatorFocus({ - cameraTabIndex, - isInTabNavigator, + tabIndex: cameraTabIndex, }); const handleOnUserMedia = (stream) => { diff --git a/src/pages/iou/ReceiptSelector/NavigationAwareCamera.native.js b/src/pages/iou/ReceiptSelector/NavigationAwareCamera.native.js index 9d1b1723e882..78d2abe1a3b3 100644 --- a/src/pages/iou/ReceiptSelector/NavigationAwareCamera.native.js +++ b/src/pages/iou/ReceiptSelector/NavigationAwareCamera.native.js @@ -1,71 +1,19 @@ -import {useTabAnimation} from '@react-navigation/material-top-tabs'; -import {useNavigation} from '@react-navigation/native'; import PropTypes from 'prop-types'; -import React, {useEffect, useState} from 'react'; +import React from 'react'; import {Camera} from 'react-native-vision-camera'; -import CONST from '@src/CONST'; +import useTabNavigatorFocus from '@hooks/useTabNavigatorFocus'; const propTypes = { /* The index of the tab that contains this camera */ cameraTabIndex: PropTypes.number.isRequired, - /* Whether we're in a tab navigator */ - isInTabNavigator: PropTypes.bool.isRequired, - /** Name of the selected receipt tab */ selectedTab: PropTypes.string.isRequired, }; // Wraps a camera that will only be active when the tab is focused or as soon as it starts to become focused. -const NavigationAwareCamera = React.forwardRef(({cameraTabIndex, isInTabNavigator, selectedTab, ...props}, ref) => { - // Get navigation to get initial isFocused value (only needed once during init!) - const navigation = useNavigation(); - const [isCameraActive, setIsCameraActive] = useState(() => navigation.isFocused()); - - // Retrieve the animation value from the tab navigator, which ranges from 0 to the total number of pages displayed. - // Even a minimal scroll towards the camera page (e.g., a value of 0.001 at start) should activate the camera for immediate responsiveness. - - // STOP!!!!!!! This is not a pattern to be followed! We are conditionally rendering this hook becase when used in the edit flow we'll never be inside a tab navigator. - // eslint-disable-next-line react-hooks/rules-of-hooks - const tabPositionAnimation = isInTabNavigator ? useTabAnimation() : null; - - useEffect(() => { - if (!isInTabNavigator) { - return; - } - - const listenerId = tabPositionAnimation.addListener(({value}) => { - if (selectedTab !== CONST.TAB.SCAN) { - return; - } - // Activate camera as soon the index is animating towards the `cameraTabIndex` - setIsCameraActive(value > cameraTabIndex - 1 && value < cameraTabIndex + 1); - }); - - return () => { - tabPositionAnimation.removeListener(listenerId); - }; - }, [cameraTabIndex, tabPositionAnimation, isInTabNavigator, selectedTab]); - - // Note: The useEffect can be removed once VisionCamera V3 is used. - // Its only needed for android, because there is a native cameraX android bug. With out this flow would break the camera: - // 1. Open camera tab - // 2. Take a picture - // 3. Go back from the opened screen - // 4. The camera is not working anymore - useEffect(() => { - const removeBlurListener = navigation.addListener('blur', () => { - setIsCameraActive(false); - }); - const removeFocusListener = navigation.addListener('focus', () => { - setIsCameraActive(true); - }); - - return () => { - removeBlurListener(); - removeFocusListener(); - }; - }, [navigation]); +const NavigationAwareCamera = React.forwardRef(({cameraTabIndex, selectedTab, ...props}, ref) => { + const isCameraActive = useTabNavigatorFocus({tabIndex: cameraTabIndex, selectedTab}); return ( diff --git a/src/pages/iou/ReceiptSelector/index.native.js b/src/pages/iou/ReceiptSelector/index.native.js index d47a2c7739a2..69f1a894d3b6 100644 --- a/src/pages/iou/ReceiptSelector/index.native.js +++ b/src/pages/iou/ReceiptSelector/index.native.js @@ -51,9 +51,6 @@ const propTypes = { /** The id of the transaction we're editing */ transactionID: PropTypes.string, - /** Whether or not the receipt selector is in a tab navigator for tab animations */ - isInTabNavigator: PropTypes.bool, - /** Name of the selected receipt tab */ selectedTab: PropTypes.string, }; @@ -62,11 +59,10 @@ const defaultProps = { report: {}, iou: iouDefaultProps, transactionID: '', - isInTabNavigator: true, selectedTab: '', }; -function ReceiptSelector({route, report, iou, transactionID, isInTabNavigator, selectedTab}) { +function ReceiptSelector({route, report, iou, transactionID, selectedTab}) { const devices = useCameraDevices('wide-angle-camera'); const device = devices.back; @@ -198,7 +194,6 @@ function ReceiptSelector({route, report, iou, transactionID, isInTabNavigator, s zoom={device.neutralZoom} photo cameraTabIndex={pageIndex} - isInTabNavigator={isInTabNavigator} selectedTab={selectedTab} /> )} From 7d0075ef86a326bbb719d54f7f43ac8e4d4ab765 Mon Sep 17 00:00:00 2001 From: Viktoryia Kliushun Date: Thu, 9 Nov 2023 17:55:24 +0100 Subject: [PATCH 119/212] Fix ts issues after main merging --- src/libs/E2E/apiMocks/openApp.ts | 6 ++++++ src/libs/E2E/client.ts | 1 + src/libs/E2E/tests/appStartTimeTest.e2e.ts | 1 + src/types/onyx/FrequentlyUsedEmoji.ts | 2 +- 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/libs/E2E/apiMocks/openApp.ts b/src/libs/E2E/apiMocks/openApp.ts index 6e0a607776ec..351aba50aeb0 100644 --- a/src/libs/E2E/apiMocks/openApp.ts +++ b/src/libs/E2E/apiMocks/openApp.ts @@ -995,6 +995,7 @@ const openApp = (): Response => ({ count: 15, keywords: ['face', 'kiss'], lastUpdatedAt: 1669639079, + name: 'kissing', }, { code: '\ud83d\ude1a', @@ -1015,18 +1016,21 @@ const openApp = (): Response => ({ count: 11, keywords: ['face', 'mouth', 'zipper'], lastUpdatedAt: 1670346432, + name: 'zipper_mouth_face', }, { code: '\ud83d\ude25', count: 11, keywords: ['disappointed', 'face', 'relieved', 'whew'], lastUpdatedAt: 1669660257, + name: 'disappointed_relieved', }, { code: '\ud83d\ude0e', count: 11, keywords: ['bright', 'cool', 'eye', 'eyewear', 'face', 'glasses', 'smile', 'sun', 'sunglasses', 'weather'], lastUpdatedAt: 1669660252, + name: 'sunglasses', }, { code: '\ud83d\ude36', @@ -1040,12 +1044,14 @@ const openApp = (): Response => ({ count: 11, keywords: ['expressionless', 'face', 'inexpressive', 'unexpressive'], lastUpdatedAt: 1669640332, + name: 'expressionless', }, { code: '\ud83d\ude0f', count: 11, keywords: ['face', 'smirk'], lastUpdatedAt: 1666207075, + name: 'smirk', }, { code: '\ud83e\udd70', diff --git a/src/libs/E2E/client.ts b/src/libs/E2E/client.ts index 866314cda05e..472567cc6c1d 100644 --- a/src/libs/E2E/client.ts +++ b/src/libs/E2E/client.ts @@ -3,6 +3,7 @@ import Routes from '../../../tests/e2e/server/routes'; type TestResult = { name: string; + branch?: string; duration?: number; error?: string; renderCount?: number; diff --git a/src/libs/E2E/tests/appStartTimeTest.e2e.ts b/src/libs/E2E/tests/appStartTimeTest.e2e.ts index bcb8bcd823bc..92e2513e0351 100644 --- a/src/libs/E2E/tests/appStartTimeTest.e2e.ts +++ b/src/libs/E2E/tests/appStartTimeTest.e2e.ts @@ -1,3 +1,4 @@ +import Config from 'react-native-config'; import {PerformanceEntry} from 'react-native-performance'; import E2ELogin from '@libs/E2E/actions/e2eLogin'; import E2EClient from '@libs/E2E/client'; diff --git a/src/types/onyx/FrequentlyUsedEmoji.ts b/src/types/onyx/FrequentlyUsedEmoji.ts index 8001ed91822a..333721b25b52 100644 --- a/src/types/onyx/FrequentlyUsedEmoji.ts +++ b/src/types/onyx/FrequentlyUsedEmoji.ts @@ -3,7 +3,7 @@ type FrequentlyUsedEmoji = { code: string; /** The name of the emoji */ - name?: string; + name: string; /** The number of times the emoji has been used */ count: number; From 6f7692817e60fc32083d0dad903ed87ffeb6216e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucas=20M=C3=B3rawski?= Date: Thu, 9 Nov 2023 18:19:43 +0100 Subject: [PATCH 120/212] added JSDocs for useTabNavigatorFocus hook --- src/hooks/useTabNavigatorFocus/index.js | 24 +++++++++++++++++++ .../useTabNavigatorFocus/index.native.js | 23 ++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/src/hooks/useTabNavigatorFocus/index.js b/src/hooks/useTabNavigatorFocus/index.js index 2a41809b7414..7af6bc5950ac 100644 --- a/src/hooks/useTabNavigatorFocus/index.js +++ b/src/hooks/useTabNavigatorFocus/index.js @@ -2,6 +2,30 @@ import {useTabAnimation} from '@react-navigation/material-top-tabs'; import {useIsFocused} from '@react-navigation/native'; import {useEffect, useState} from 'react'; +/** + * Custom React hook to determine the focus status of a tab in a Material Top Tab Navigator. + * It evaluates whether the current tab is focused based on the tab's animation position and + * the screen's focus status within a React Navigation environment. + * + * This hook is designed for use with the Material Top Tabs provided by '@react-navigation/material-top-tabs'. + * It leverages the `useTabAnimation` hook from the same package to track the animated position of tabs + * and the `useIsFocused` hook from '@react-navigation/native' to ascertain if the current screen is in focus. + * + * Note: This hook contains a conditional invocation of another hook (`useTabAnimation`), + * which is typically an anti-pattern in React. This is done to account for scenarios where the hook + * might not be used within a Material Top Tabs Navigator context. Proper usage should ensure that + * this hook is only used where appropriate. + * + * Note: This hook is almost identical to native implementation, except for the `selectedTab` parameter + * and the fact that it uses requestAnimationFrame to mitigate issues when updating the isTabFocused state. + * + * @param {Object} params - The parameters object. + * @param {number} params.tabIndex - The index of the tab for which focus status is being determined. + * @returns {boolean} Returns `true` if the tab is both animation-focused and screen-focused, otherwise `false`. + * + * @example + * const isTabFocused = useTabNavigatorFocus({ tabIndex: 1 }); + */ function useTabNavigatorFocus({tabIndex}) { let tabPositionAnimation = null; try { diff --git a/src/hooks/useTabNavigatorFocus/index.native.js b/src/hooks/useTabNavigatorFocus/index.native.js index a313e95ee0dd..7f9da7b3f841 100644 --- a/src/hooks/useTabNavigatorFocus/index.native.js +++ b/src/hooks/useTabNavigatorFocus/index.native.js @@ -3,6 +3,29 @@ import {useIsFocused} from '@react-navigation/native'; import {useEffect, useState} from 'react'; import CONST from '@src/CONST'; +/** + * Custom React hook to determine the focus status of a specific tab in a Material Top Tab Navigator, with additional + * conditions based on a selected tab state. It evaluates whether the specified tab is focused by combining the tab's + * animation position and the screen's focus status within a React Navigation environment. + * + * The hook is primarily intended for use with Material Top Tabs provided by '@react-navigation/material-top-tabs'. + * It utilizes the `useTabAnimation` hook from this package to track the animated position of the tabs and the + * `useIsFocused` hook from '@react-navigation/native' to determine if the current screen is focused. Additionally, + * it uses a `selectedTab` parameter to apply custom logic based on the currently selected tab. + * + * Note: This hook employs a conditional invocation of the `useTabAnimation` hook, which is generally against React's + * rules of hooks. This pattern is used here to handle scenarios where the hook might not be employed within a + * Material Top Tabs Navigator context. Ensure this hook is only used in appropriate scenarios to avoid potential issues. + * + * @param {Object} params - The parameters object. + * @param {number} params.tabIndex - The index of the tab for which focus status is being determined. + * @param {string} params.selectedTab - The tab identifier passed by to the component. Used only on native platform + * + * @returns {boolean} Returns `true` if the specified tab is both animation-focused and screen-focused, otherwise `false`. + * + * @example + * const isTabFocused = useTabNavigatorFocus({ tabIndex: 1, selectedTab: 'home' }); + */ function useTabNavigatorFocus({tabIndex, selectedTab}) { let tabPositionAnimation = null; try { From 1abfecf6423273146edcdf5799596a4af8e66507 Mon Sep 17 00:00:00 2001 From: Artem Makushov Date: Thu, 9 Nov 2023 18:25:22 +0100 Subject: [PATCH 121/212] github actions update --- .../javascript/authorChecklist/index.js | 1 + .../javascript/awaitStagingDeploys/index.js | 1 + .../javascript/checkDeployBlockers/index.js | 1 + .../createOrUpdateStagingDeploy/index.js | 15652 +++++++--------- .../getDeployPullRequestList/index.js | 1 + .../javascript/getPullRequestDetails/index.js | 1 + .../javascript/getReleaseBody/index.js | 1 + .../javascript/isStagingDeployLocked/index.js | 1 + .../markPullRequestsAsDeployed/index.js | 1 + .../javascript/postTestBuildComment/index.js | 1 + .../reopenIssueWithComment/index.js | 1 + .../javascript/reviewerChecklist/index.js | 1 + .../javascript/verifySignedCommits/index.js | 1 + 13 files changed, 6378 insertions(+), 9286 deletions(-) diff --git a/.github/actions/javascript/authorChecklist/index.js b/.github/actions/javascript/authorChecklist/index.js index 9459e5443a6a..dc677dcd1dea 100644 --- a/.github/actions/javascript/authorChecklist/index.js +++ b/.github/actions/javascript/authorChecklist/index.js @@ -17,6 +17,7 @@ const CONST = { DEPLOY_BLOCKER: 'DeployBlockerCash', INTERNAL_QA: 'InternalQA', }, + DATE_FORMAT_STRING: 'yyyy-MM-dd', }; CONST.APP_REPO_URL = `https://github.com/${CONST.GITHUB_OWNER}/${CONST.APP_REPO}`; diff --git a/.github/actions/javascript/awaitStagingDeploys/index.js b/.github/actions/javascript/awaitStagingDeploys/index.js index 3fd3739c81d6..08468d9a06a5 100644 --- a/.github/actions/javascript/awaitStagingDeploys/index.js +++ b/.github/actions/javascript/awaitStagingDeploys/index.js @@ -129,6 +129,7 @@ const CONST = { DEPLOY_BLOCKER: 'DeployBlockerCash', INTERNAL_QA: 'InternalQA', }, + DATE_FORMAT_STRING: 'yyyy-MM-dd', }; CONST.APP_REPO_URL = `https://github.com/${CONST.GITHUB_OWNER}/${CONST.APP_REPO}`; diff --git a/.github/actions/javascript/checkDeployBlockers/index.js b/.github/actions/javascript/checkDeployBlockers/index.js index c860977f790b..690018aa9367 100644 --- a/.github/actions/javascript/checkDeployBlockers/index.js +++ b/.github/actions/javascript/checkDeployBlockers/index.js @@ -96,6 +96,7 @@ const CONST = { DEPLOY_BLOCKER: 'DeployBlockerCash', INTERNAL_QA: 'InternalQA', }, + DATE_FORMAT_STRING: 'yyyy-MM-dd', }; CONST.APP_REPO_URL = `https://github.com/${CONST.GITHUB_OWNER}/${CONST.APP_REPO}`; diff --git a/.github/actions/javascript/createOrUpdateStagingDeploy/index.js b/.github/actions/javascript/createOrUpdateStagingDeploy/index.js index 8ea16c7d96b1..abf0712103a5 100644 --- a/.github/actions/javascript/createOrUpdateStagingDeploy/index.js +++ b/.github/actions/javascript/createOrUpdateStagingDeploy/index.js @@ -7,9 +7,9 @@ /***/ 3926: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +const format = __nccwpck_require__(2168); const _ = __nccwpck_require__(5067); const core = __nccwpck_require__(2186); -const moment = __nccwpck_require__(9623); const CONST = __nccwpck_require__(4097); const GithubUtils = __nccwpck_require__(7999); const GitUtils = __nccwpck_require__(669); @@ -127,7 +127,7 @@ async function run() { if (shouldCreateNewDeployChecklist) { const {data: newChecklist} = await GithubUtils.octokit.issues.create({ ...defaultPayload, - title: `Deploy Checklist: New Expensify ${moment().format('YYYY-MM-DD')}`, + title: `Deploy Checklist: New Expensify ${format(new Date(), CONST.DATE_FORMAT_STRING)}`, labels: [CONST.LABELS.STAGING_DEPLOY], assignees: [CONST.APPLAUSE_BOT], }); @@ -169,6 +169,7 @@ const CONST = { DEPLOY_BLOCKER: 'DeployBlockerCash', INTERNAL_QA: 'InternalQA', }, + DATE_FORMAT_STRING: 'yyyy-MM-dd', }; CONST.APP_REPO_URL = `https://github.com/${CONST.GITHUB_OWNER}/${CONST.APP_REPO}`; @@ -7457,10425 +7458,7488 @@ function removeHook(state, name, method) { /***/ }), -/***/ 8932: -/***/ ((__unused_webpack_module, exports) => { +/***/ 8620: +/***/ ((module, exports) => { "use strict"; -Object.defineProperty(exports, "__esModule", ({ value: true })); - -class Deprecation extends Error { - constructor(message) { - super(message); // Maintains proper stack trace (only available on V8) - - /* istanbul ignore next */ +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = addLeadingZeros; +function addLeadingZeros(number, targetLength) { + var sign = number < 0 ? '-' : ''; + var output = Math.abs(number).toString(); + while (output.length < targetLength) { + output = '0' + output; + } + return sign + output; +} +module.exports = exports.default; - if (Error.captureStackTrace) { - Error.captureStackTrace(this, this.constructor); - } +/***/ }), - this.name = 'Deprecation'; - } +/***/ 618: +/***/ ((module, exports, __nccwpck_require__) => { -} +"use strict"; -exports.Deprecation = Deprecation; +var _interopRequireDefault = (__nccwpck_require__(3286)["default"]); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _index = _interopRequireDefault(__nccwpck_require__(1773)); +var _default = _index.default; +exports["default"] = _default; +module.exports = exports.default; /***/ }), -/***/ 8685: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 9307: +/***/ ((__unused_webpack_module, exports) => { "use strict"; -var iconvLite = __nccwpck_require__(9032); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.getDefaultOptions = getDefaultOptions; +exports.setDefaultOptions = setDefaultOptions; +var defaultOptions = {}; +function getDefaultOptions() { + return defaultOptions; +} +function setDefaultOptions(newOptions) { + defaultOptions = newOptions; +} -// Expose to the world -module.exports.O = convert; +/***/ }), -/** - * Convert encoding of an UTF-8 string or a buffer +/***/ 9257: +/***/ ((module, exports, __nccwpck_require__) => { + +"use strict"; + + +var _interopRequireDefault = (__nccwpck_require__(3286)["default"]); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _index = _interopRequireDefault(__nccwpck_require__(2966)); +var _index2 = _interopRequireDefault(__nccwpck_require__(8493)); +var _index3 = _interopRequireDefault(__nccwpck_require__(7170)); +var _index4 = _interopRequireDefault(__nccwpck_require__(8761)); +var _index5 = _interopRequireDefault(__nccwpck_require__(8050)); +var _index6 = _interopRequireDefault(__nccwpck_require__(8620)); +var _index7 = _interopRequireDefault(__nccwpck_require__(289)); +var dayPeriodEnum = { + am: 'am', + pm: 'pm', + midnight: 'midnight', + noon: 'noon', + morning: 'morning', + afternoon: 'afternoon', + evening: 'evening', + night: 'night' +}; +/* + * | | Unit | | Unit | + * |-----|--------------------------------|-----|--------------------------------| + * | a | AM, PM | A* | Milliseconds in day | + * | b | AM, PM, noon, midnight | B | Flexible day period | + * | c | Stand-alone local day of week | C* | Localized hour w/ day period | + * | d | Day of month | D | Day of year | + * | e | Local day of week | E | Day of week | + * | f | | F* | Day of week in month | + * | g* | Modified Julian day | G | Era | + * | h | Hour [1-12] | H | Hour [0-23] | + * | i! | ISO day of week | I! | ISO week of year | + * | j* | Localized hour w/ day period | J* | Localized hour w/o day period | + * | k | Hour [1-24] | K | Hour [0-11] | + * | l* | (deprecated) | L | Stand-alone month | + * | m | Minute | M | Month | + * | n | | N | | + * | o! | Ordinal number modifier | O | Timezone (GMT) | + * | p! | Long localized time | P! | Long localized date | + * | q | Stand-alone quarter | Q | Quarter | + * | r* | Related Gregorian year | R! | ISO week-numbering year | + * | s | Second | S | Fraction of second | + * | t! | Seconds timestamp | T! | Milliseconds timestamp | + * | u | Extended year | U* | Cyclic year | + * | v* | Timezone (generic non-locat.) | V* | Timezone (location) | + * | w | Local week of year | W* | Week of month | + * | x | Timezone (ISO-8601 w/o Z) | X | Timezone (ISO-8601) | + * | y | Year (abs) | Y | Local week-numbering year | + * | z | Timezone (specific non-locat.) | Z* | Timezone (aliases) | * - * @param {String|Buffer} str String to be converted - * @param {String} to Encoding to be converted to - * @param {String} [from='UTF-8'] Encoding to be converted from - * @return {Buffer} Encoded string + * Letters marked by * are not implemented but reserved by Unicode standard. + * + * Letters marked by ! are non-standard, but implemented by date-fns: + * - `o` modifies the previous token to turn it into an ordinal (see `format` docs) + * - `i` is ISO day of week. For `i` and `ii` is returns numeric ISO week days, + * i.e. 7 for Sunday, 1 for Monday, etc. + * - `I` is ISO week of year, as opposed to `w` which is local week of year. + * - `R` is ISO week-numbering year, as opposed to `Y` which is local week-numbering year. + * `R` is supposed to be used in conjunction with `I` and `i` + * for universal ISO week-numbering date, whereas + * `Y` is supposed to be used in conjunction with `w` and `e` + * for week-numbering date specific to the locale. + * - `P` is long localized date format + * - `p` is long localized time format */ -function convert(str, to, from) { - from = checkEncoding(from || 'UTF-8'); - to = checkEncoding(to || 'UTF-8'); - str = str || ''; - - var result; - if (from !== 'UTF-8' && typeof str === 'string') { - str = Buffer.from(str, 'binary'); +var formatters = { + // Era + G: function G(date, token, localize) { + var era = date.getUTCFullYear() > 0 ? 1 : 0; + switch (token) { + // AD, BC + case 'G': + case 'GG': + case 'GGG': + return localize.era(era, { + width: 'abbreviated' + }); + // A, B + case 'GGGGG': + return localize.era(era, { + width: 'narrow' + }); + // Anno Domini, Before Christ + case 'GGGG': + default: + return localize.era(era, { + width: 'wide' + }); } - - if (from === to) { - if (typeof str === 'string') { - result = Buffer.from(str); - } else { - result = str; - } - } else { - try { - result = convertIconvLite(str, to, from); - } catch (E) { - console.error(E); - result = str; - } + }, + // Year + y: function y(date, token, localize) { + // Ordinal number + if (token === 'yo') { + var signedYear = date.getUTCFullYear(); + // Returns 1 for 1 BC (which is year 0 in JavaScript) + var year = signedYear > 0 ? signedYear : 1 - signedYear; + return localize.ordinalNumber(year, { + unit: 'year' + }); } - - if (typeof result === 'string') { - result = Buffer.from(result, 'utf-8'); + return _index7.default.y(date, token); + }, + // Local week-numbering year + Y: function Y(date, token, localize, options) { + var signedWeekYear = (0, _index5.default)(date, options); + // Returns 1 for 1 BC (which is year 0 in JavaScript) + var weekYear = signedWeekYear > 0 ? signedWeekYear : 1 - signedWeekYear; + + // Two digit year + if (token === 'YY') { + var twoDigitYear = weekYear % 100; + return (0, _index6.default)(twoDigitYear, 2); + } + + // Ordinal number + if (token === 'Yo') { + return localize.ordinalNumber(weekYear, { + unit: 'year' + }); } - return result; -} + // Padding + return (0, _index6.default)(weekYear, token.length); + }, + // ISO week-numbering year + R: function R(date, token) { + var isoWeekYear = (0, _index3.default)(date); -/** - * Convert encoding of astring with iconv-lite - * - * @param {String|Buffer} str String to be converted - * @param {String} to Encoding to be converted to - * @param {String} [from='UTF-8'] Encoding to be converted from - * @return {Buffer} Encoded string - */ -function convertIconvLite(str, to, from) { - if (to === 'UTF-8') { - return iconvLite.decode(str, from); - } else if (from === 'UTF-8') { - return iconvLite.encode(str, to); + // Padding + return (0, _index6.default)(isoWeekYear, token.length); + }, + // Extended year. This is a single number designating the year of this calendar system. + // The main difference between `y` and `u` localizers are B.C. years: + // | Year | `y` | `u` | + // |------|-----|-----| + // | AC 1 | 1 | 1 | + // | BC 1 | 1 | 0 | + // | BC 2 | 2 | -1 | + // Also `yy` always returns the last two digits of a year, + // while `uu` pads single digit years to 2 characters and returns other years unchanged. + u: function u(date, token) { + var year = date.getUTCFullYear(); + return (0, _index6.default)(year, token.length); + }, + // Quarter + Q: function Q(date, token, localize) { + var quarter = Math.ceil((date.getUTCMonth() + 1) / 3); + switch (token) { + // 1, 2, 3, 4 + case 'Q': + return String(quarter); + // 01, 02, 03, 04 + case 'QQ': + return (0, _index6.default)(quarter, 2); + // 1st, 2nd, 3rd, 4th + case 'Qo': + return localize.ordinalNumber(quarter, { + unit: 'quarter' + }); + // Q1, Q2, Q3, Q4 + case 'QQQ': + return localize.quarter(quarter, { + width: 'abbreviated', + context: 'formatting' + }); + // 1, 2, 3, 4 (narrow quarter; could be not numerical) + case 'QQQQQ': + return localize.quarter(quarter, { + width: 'narrow', + context: 'formatting' + }); + // 1st quarter, 2nd quarter, ... + case 'QQQQ': + default: + return localize.quarter(quarter, { + width: 'wide', + context: 'formatting' + }); + } + }, + // Stand-alone quarter + q: function q(date, token, localize) { + var quarter = Math.ceil((date.getUTCMonth() + 1) / 3); + switch (token) { + // 1, 2, 3, 4 + case 'q': + return String(quarter); + // 01, 02, 03, 04 + case 'qq': + return (0, _index6.default)(quarter, 2); + // 1st, 2nd, 3rd, 4th + case 'qo': + return localize.ordinalNumber(quarter, { + unit: 'quarter' + }); + // Q1, Q2, Q3, Q4 + case 'qqq': + return localize.quarter(quarter, { + width: 'abbreviated', + context: 'standalone' + }); + // 1, 2, 3, 4 (narrow quarter; could be not numerical) + case 'qqqqq': + return localize.quarter(quarter, { + width: 'narrow', + context: 'standalone' + }); + // 1st quarter, 2nd quarter, ... + case 'qqqq': + default: + return localize.quarter(quarter, { + width: 'wide', + context: 'standalone' + }); + } + }, + // Month + M: function M(date, token, localize) { + var month = date.getUTCMonth(); + switch (token) { + case 'M': + case 'MM': + return _index7.default.M(date, token); + // 1st, 2nd, ..., 12th + case 'Mo': + return localize.ordinalNumber(month + 1, { + unit: 'month' + }); + // Jan, Feb, ..., Dec + case 'MMM': + return localize.month(month, { + width: 'abbreviated', + context: 'formatting' + }); + // J, F, ..., D + case 'MMMMM': + return localize.month(month, { + width: 'narrow', + context: 'formatting' + }); + // January, February, ..., December + case 'MMMM': + default: + return localize.month(month, { + width: 'wide', + context: 'formatting' + }); + } + }, + // Stand-alone month + L: function L(date, token, localize) { + var month = date.getUTCMonth(); + switch (token) { + // 1, 2, ..., 12 + case 'L': + return String(month + 1); + // 01, 02, ..., 12 + case 'LL': + return (0, _index6.default)(month + 1, 2); + // 1st, 2nd, ..., 12th + case 'Lo': + return localize.ordinalNumber(month + 1, { + unit: 'month' + }); + // Jan, Feb, ..., Dec + case 'LLL': + return localize.month(month, { + width: 'abbreviated', + context: 'standalone' + }); + // J, F, ..., D + case 'LLLLL': + return localize.month(month, { + width: 'narrow', + context: 'standalone' + }); + // January, February, ..., December + case 'LLLL': + default: + return localize.month(month, { + width: 'wide', + context: 'standalone' + }); + } + }, + // Local week of year + w: function w(date, token, localize, options) { + var week = (0, _index4.default)(date, options); + if (token === 'wo') { + return localize.ordinalNumber(week, { + unit: 'week' + }); + } + return (0, _index6.default)(week, token.length); + }, + // ISO week of year + I: function I(date, token, localize) { + var isoWeek = (0, _index2.default)(date); + if (token === 'Io') { + return localize.ordinalNumber(isoWeek, { + unit: 'week' + }); + } + return (0, _index6.default)(isoWeek, token.length); + }, + // Day of the month + d: function d(date, token, localize) { + if (token === 'do') { + return localize.ordinalNumber(date.getUTCDate(), { + unit: 'date' + }); + } + return _index7.default.d(date, token); + }, + // Day of year + D: function D(date, token, localize) { + var dayOfYear = (0, _index.default)(date); + if (token === 'Do') { + return localize.ordinalNumber(dayOfYear, { + unit: 'dayOfYear' + }); + } + return (0, _index6.default)(dayOfYear, token.length); + }, + // Day of week + E: function E(date, token, localize) { + var dayOfWeek = date.getUTCDay(); + switch (token) { + // Tue + case 'E': + case 'EE': + case 'EEE': + return localize.day(dayOfWeek, { + width: 'abbreviated', + context: 'formatting' + }); + // T + case 'EEEEE': + return localize.day(dayOfWeek, { + width: 'narrow', + context: 'formatting' + }); + // Tu + case 'EEEEEE': + return localize.day(dayOfWeek, { + width: 'short', + context: 'formatting' + }); + // Tuesday + case 'EEEE': + default: + return localize.day(dayOfWeek, { + width: 'wide', + context: 'formatting' + }); + } + }, + // Local day of week + e: function e(date, token, localize, options) { + var dayOfWeek = date.getUTCDay(); + var localDayOfWeek = (dayOfWeek - options.weekStartsOn + 8) % 7 || 7; + switch (token) { + // Numerical value (Nth day of week with current locale or weekStartsOn) + case 'e': + return String(localDayOfWeek); + // Padded numerical value + case 'ee': + return (0, _index6.default)(localDayOfWeek, 2); + // 1st, 2nd, ..., 7th + case 'eo': + return localize.ordinalNumber(localDayOfWeek, { + unit: 'day' + }); + case 'eee': + return localize.day(dayOfWeek, { + width: 'abbreviated', + context: 'formatting' + }); + // T + case 'eeeee': + return localize.day(dayOfWeek, { + width: 'narrow', + context: 'formatting' + }); + // Tu + case 'eeeeee': + return localize.day(dayOfWeek, { + width: 'short', + context: 'formatting' + }); + // Tuesday + case 'eeee': + default: + return localize.day(dayOfWeek, { + width: 'wide', + context: 'formatting' + }); + } + }, + // Stand-alone local day of week + c: function c(date, token, localize, options) { + var dayOfWeek = date.getUTCDay(); + var localDayOfWeek = (dayOfWeek - options.weekStartsOn + 8) % 7 || 7; + switch (token) { + // Numerical value (same as in `e`) + case 'c': + return String(localDayOfWeek); + // Padded numerical value + case 'cc': + return (0, _index6.default)(localDayOfWeek, token.length); + // 1st, 2nd, ..., 7th + case 'co': + return localize.ordinalNumber(localDayOfWeek, { + unit: 'day' + }); + case 'ccc': + return localize.day(dayOfWeek, { + width: 'abbreviated', + context: 'standalone' + }); + // T + case 'ccccc': + return localize.day(dayOfWeek, { + width: 'narrow', + context: 'standalone' + }); + // Tu + case 'cccccc': + return localize.day(dayOfWeek, { + width: 'short', + context: 'standalone' + }); + // Tuesday + case 'cccc': + default: + return localize.day(dayOfWeek, { + width: 'wide', + context: 'standalone' + }); + } + }, + // ISO day of week + i: function i(date, token, localize) { + var dayOfWeek = date.getUTCDay(); + var isoDayOfWeek = dayOfWeek === 0 ? 7 : dayOfWeek; + switch (token) { + // 2 + case 'i': + return String(isoDayOfWeek); + // 02 + case 'ii': + return (0, _index6.default)(isoDayOfWeek, token.length); + // 2nd + case 'io': + return localize.ordinalNumber(isoDayOfWeek, { + unit: 'day' + }); + // Tue + case 'iii': + return localize.day(dayOfWeek, { + width: 'abbreviated', + context: 'formatting' + }); + // T + case 'iiiii': + return localize.day(dayOfWeek, { + width: 'narrow', + context: 'formatting' + }); + // Tu + case 'iiiiii': + return localize.day(dayOfWeek, { + width: 'short', + context: 'formatting' + }); + // Tuesday + case 'iiii': + default: + return localize.day(dayOfWeek, { + width: 'wide', + context: 'formatting' + }); + } + }, + // AM or PM + a: function a(date, token, localize) { + var hours = date.getUTCHours(); + var dayPeriodEnumValue = hours / 12 >= 1 ? 'pm' : 'am'; + switch (token) { + case 'a': + case 'aa': + return localize.dayPeriod(dayPeriodEnumValue, { + width: 'abbreviated', + context: 'formatting' + }); + case 'aaa': + return localize.dayPeriod(dayPeriodEnumValue, { + width: 'abbreviated', + context: 'formatting' + }).toLowerCase(); + case 'aaaaa': + return localize.dayPeriod(dayPeriodEnumValue, { + width: 'narrow', + context: 'formatting' + }); + case 'aaaa': + default: + return localize.dayPeriod(dayPeriodEnumValue, { + width: 'wide', + context: 'formatting' + }); + } + }, + // AM, PM, midnight, noon + b: function b(date, token, localize) { + var hours = date.getUTCHours(); + var dayPeriodEnumValue; + if (hours === 12) { + dayPeriodEnumValue = dayPeriodEnum.noon; + } else if (hours === 0) { + dayPeriodEnumValue = dayPeriodEnum.midnight; } else { - return iconvLite.encode(iconvLite.decode(str, from), to); + dayPeriodEnumValue = hours / 12 >= 1 ? 'pm' : 'am'; + } + switch (token) { + case 'b': + case 'bb': + return localize.dayPeriod(dayPeriodEnumValue, { + width: 'abbreviated', + context: 'formatting' + }); + case 'bbb': + return localize.dayPeriod(dayPeriodEnumValue, { + width: 'abbreviated', + context: 'formatting' + }).toLowerCase(); + case 'bbbbb': + return localize.dayPeriod(dayPeriodEnumValue, { + width: 'narrow', + context: 'formatting' + }); + case 'bbbb': + default: + return localize.dayPeriod(dayPeriodEnumValue, { + width: 'wide', + context: 'formatting' + }); + } + }, + // in the morning, in the afternoon, in the evening, at night + B: function B(date, token, localize) { + var hours = date.getUTCHours(); + var dayPeriodEnumValue; + if (hours >= 17) { + dayPeriodEnumValue = dayPeriodEnum.evening; + } else if (hours >= 12) { + dayPeriodEnumValue = dayPeriodEnum.afternoon; + } else if (hours >= 4) { + dayPeriodEnumValue = dayPeriodEnum.morning; + } else { + dayPeriodEnumValue = dayPeriodEnum.night; + } + switch (token) { + case 'B': + case 'BB': + case 'BBB': + return localize.dayPeriod(dayPeriodEnumValue, { + width: 'abbreviated', + context: 'formatting' + }); + case 'BBBBB': + return localize.dayPeriod(dayPeriodEnumValue, { + width: 'narrow', + context: 'formatting' + }); + case 'BBBB': + default: + return localize.dayPeriod(dayPeriodEnumValue, { + width: 'wide', + context: 'formatting' + }); + } + }, + // Hour [1-12] + h: function h(date, token, localize) { + if (token === 'ho') { + var hours = date.getUTCHours() % 12; + if (hours === 0) hours = 12; + return localize.ordinalNumber(hours, { + unit: 'hour' + }); + } + return _index7.default.h(date, token); + }, + // Hour [0-23] + H: function H(date, token, localize) { + if (token === 'Ho') { + return localize.ordinalNumber(date.getUTCHours(), { + unit: 'hour' + }); } + return _index7.default.H(date, token); + }, + // Hour [0-11] + K: function K(date, token, localize) { + var hours = date.getUTCHours() % 12; + if (token === 'Ko') { + return localize.ordinalNumber(hours, { + unit: 'hour' + }); + } + return (0, _index6.default)(hours, token.length); + }, + // Hour [1-24] + k: function k(date, token, localize) { + var hours = date.getUTCHours(); + if (hours === 0) hours = 24; + if (token === 'ko') { + return localize.ordinalNumber(hours, { + unit: 'hour' + }); + } + return (0, _index6.default)(hours, token.length); + }, + // Minute + m: function m(date, token, localize) { + if (token === 'mo') { + return localize.ordinalNumber(date.getUTCMinutes(), { + unit: 'minute' + }); + } + return _index7.default.m(date, token); + }, + // Second + s: function s(date, token, localize) { + if (token === 'so') { + return localize.ordinalNumber(date.getUTCSeconds(), { + unit: 'second' + }); + } + return _index7.default.s(date, token); + }, + // Fraction of second + S: function S(date, token) { + return _index7.default.S(date, token); + }, + // Timezone (ISO-8601. If offset is 0, output is always `'Z'`) + X: function X(date, token, _localize, options) { + var originalDate = options._originalDate || date; + var timezoneOffset = originalDate.getTimezoneOffset(); + if (timezoneOffset === 0) { + return 'Z'; + } + switch (token) { + // Hours and optional minutes + case 'X': + return formatTimezoneWithOptionalMinutes(timezoneOffset); + + // Hours, minutes and optional seconds without `:` delimiter + // Note: neither ISO-8601 nor JavaScript supports seconds in timezone offsets + // so this token always has the same output as `XX` + case 'XXXX': + case 'XX': + // Hours and minutes without `:` delimiter + return formatTimezone(timezoneOffset); + + // Hours, minutes and optional seconds with `:` delimiter + // Note: neither ISO-8601 nor JavaScript supports seconds in timezone offsets + // so this token always has the same output as `XXX` + case 'XXXXX': + case 'XXX': // Hours and minutes with `:` delimiter + default: + return formatTimezone(timezoneOffset, ':'); + } + }, + // Timezone (ISO-8601. If offset is 0, output is `'+00:00'` or equivalent) + x: function x(date, token, _localize, options) { + var originalDate = options._originalDate || date; + var timezoneOffset = originalDate.getTimezoneOffset(); + switch (token) { + // Hours and optional minutes + case 'x': + return formatTimezoneWithOptionalMinutes(timezoneOffset); + + // Hours, minutes and optional seconds without `:` delimiter + // Note: neither ISO-8601 nor JavaScript supports seconds in timezone offsets + // so this token always has the same output as `xx` + case 'xxxx': + case 'xx': + // Hours and minutes without `:` delimiter + return formatTimezone(timezoneOffset); + + // Hours, minutes and optional seconds with `:` delimiter + // Note: neither ISO-8601 nor JavaScript supports seconds in timezone offsets + // so this token always has the same output as `xxx` + case 'xxxxx': + case 'xxx': // Hours and minutes with `:` delimiter + default: + return formatTimezone(timezoneOffset, ':'); + } + }, + // Timezone (GMT) + O: function O(date, token, _localize, options) { + var originalDate = options._originalDate || date; + var timezoneOffset = originalDate.getTimezoneOffset(); + switch (token) { + // Short + case 'O': + case 'OO': + case 'OOO': + return 'GMT' + formatTimezoneShort(timezoneOffset, ':'); + // Long + case 'OOOO': + default: + return 'GMT' + formatTimezone(timezoneOffset, ':'); + } + }, + // Timezone (specific non-location) + z: function z(date, token, _localize, options) { + var originalDate = options._originalDate || date; + var timezoneOffset = originalDate.getTimezoneOffset(); + switch (token) { + // Short + case 'z': + case 'zz': + case 'zzz': + return 'GMT' + formatTimezoneShort(timezoneOffset, ':'); + // Long + case 'zzzz': + default: + return 'GMT' + formatTimezone(timezoneOffset, ':'); + } + }, + // Seconds timestamp + t: function t(date, token, _localize, options) { + var originalDate = options._originalDate || date; + var timestamp = Math.floor(originalDate.getTime() / 1000); + return (0, _index6.default)(timestamp, token.length); + }, + // Milliseconds timestamp + T: function T(date, token, _localize, options) { + var originalDate = options._originalDate || date; + var timestamp = originalDate.getTime(); + return (0, _index6.default)(timestamp, token.length); + } +}; +function formatTimezoneShort(offset, dirtyDelimiter) { + var sign = offset > 0 ? '-' : '+'; + var absOffset = Math.abs(offset); + var hours = Math.floor(absOffset / 60); + var minutes = absOffset % 60; + if (minutes === 0) { + return sign + String(hours); + } + var delimiter = dirtyDelimiter || ''; + return sign + String(hours) + delimiter + (0, _index6.default)(minutes, 2); } - -/** - * Converts charset name if needed - * - * @param {String} name Character set - * @return {String} Character set name - */ -function checkEncoding(name) { - return (name || '') - .toString() - .trim() - .replace(/^latin[\-_]?(\d+)$/i, 'ISO-8859-$1') - .replace(/^win(?:dows)?[\-_]?(\d+)$/i, 'WINDOWS-$1') - .replace(/^utf[\-_]?(\d+)$/i, 'UTF-$1') - .replace(/^ks_c_5601\-1987$/i, 'CP949') - .replace(/^us[\-_]?ascii$/i, 'ASCII') - .toUpperCase(); +function formatTimezoneWithOptionalMinutes(offset, dirtyDelimiter) { + if (offset % 60 === 0) { + var sign = offset > 0 ? '-' : '+'; + return sign + (0, _index6.default)(Math.abs(offset) / 60, 2); + } + return formatTimezone(offset, dirtyDelimiter); } - +function formatTimezone(offset, dirtyDelimiter) { + var delimiter = dirtyDelimiter || ''; + var sign = offset > 0 ? '-' : '+'; + var absOffset = Math.abs(offset); + var hours = (0, _index6.default)(Math.floor(absOffset / 60), 2); + var minutes = (0, _index6.default)(absOffset % 60, 2); + return sign + hours + delimiter + minutes; +} +var _default = formatters; +exports["default"] = _default; +module.exports = exports.default; /***/ }), -/***/ 9695: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +/***/ 289: +/***/ ((module, exports, __nccwpck_require__) => { "use strict"; -var Buffer = (__nccwpck_require__(5118).Buffer); - -// Multibyte codec. In this scheme, a character is represented by 1 or more bytes. -// Our codec supports UTF-16 surrogates, extensions for GB18030 and unicode sequences. -// To save memory and loading time, we read table files only when requested. -exports._dbcs = DBCSCodec; +var _interopRequireDefault = (__nccwpck_require__(3286)["default"]); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _index = _interopRequireDefault(__nccwpck_require__(8620)); +/* + * | | Unit | | Unit | + * |-----|--------------------------------|-----|--------------------------------| + * | a | AM, PM | A* | | + * | d | Day of month | D | | + * | h | Hour [1-12] | H | Hour [0-23] | + * | m | Minute | M | Month | + * | s | Second | S | Fraction of second | + * | y | Year (abs) | Y | | + * + * Letters marked by * are not implemented but reserved by Unicode standard. + */ -var UNASSIGNED = -1, - GB18030_CODE = -2, - SEQ_START = -10, - NODE_START = -1000, - UNASSIGNED_NODE = new Array(0x100), - DEF_CHAR = -1; +var formatters = { + // Year + y: function y(date, token) { + // From http://www.unicode.org/reports/tr35/tr35-31/tr35-dates.html#Date_Format_tokens + // | Year | y | yy | yyy | yyyy | yyyyy | + // |----------|-------|----|-------|-------|-------| + // | AD 1 | 1 | 01 | 001 | 0001 | 00001 | + // | AD 12 | 12 | 12 | 012 | 0012 | 00012 | + // | AD 123 | 123 | 23 | 123 | 0123 | 00123 | + // | AD 1234 | 1234 | 34 | 1234 | 1234 | 01234 | + // | AD 12345 | 12345 | 45 | 12345 | 12345 | 12345 | + + var signedYear = date.getUTCFullYear(); + // Returns 1 for 1 BC (which is year 0 in JavaScript) + var year = signedYear > 0 ? signedYear : 1 - signedYear; + return (0, _index.default)(token === 'yy' ? year % 100 : year, token.length); + }, + // Month + M: function M(date, token) { + var month = date.getUTCMonth(); + return token === 'M' ? String(month + 1) : (0, _index.default)(month + 1, 2); + }, + // Day of the month + d: function d(date, token) { + return (0, _index.default)(date.getUTCDate(), token.length); + }, + // AM or PM + a: function a(date, token) { + var dayPeriodEnumValue = date.getUTCHours() / 12 >= 1 ? 'pm' : 'am'; + switch (token) { + case 'a': + case 'aa': + return dayPeriodEnumValue.toUpperCase(); + case 'aaa': + return dayPeriodEnumValue; + case 'aaaaa': + return dayPeriodEnumValue[0]; + case 'aaaa': + default: + return dayPeriodEnumValue === 'am' ? 'a.m.' : 'p.m.'; + } + }, + // Hour [1-12] + h: function h(date, token) { + return (0, _index.default)(date.getUTCHours() % 12 || 12, token.length); + }, + // Hour [0-23] + H: function H(date, token) { + return (0, _index.default)(date.getUTCHours(), token.length); + }, + // Minute + m: function m(date, token) { + return (0, _index.default)(date.getUTCMinutes(), token.length); + }, + // Second + s: function s(date, token) { + return (0, _index.default)(date.getUTCSeconds(), token.length); + }, + // Fraction of second + S: function S(date, token) { + var numberOfDigits = token.length; + var milliseconds = date.getUTCMilliseconds(); + var fractionalSeconds = Math.floor(milliseconds * Math.pow(10, numberOfDigits - 3)); + return (0, _index.default)(fractionalSeconds, token.length); + } +}; +var _default = formatters; +exports["default"] = _default; +module.exports = exports.default; -for (var i = 0; i < 0x100; i++) - UNASSIGNED_NODE[i] = UNASSIGNED; +/***/ }), +/***/ 8387: +/***/ ((module, exports) => { -// Class DBCSCodec reads and initializes mapping tables. -function DBCSCodec(codecOptions, iconv) { - this.encodingName = codecOptions.encodingName; - if (!codecOptions) - throw new Error("DBCS codec is called without the data.") - if (!codecOptions.table) - throw new Error("Encoding '" + this.encodingName + "' has no data."); +"use strict"; - // Load tables. - var mappingTable = codecOptions.table(); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var dateLongFormatter = function dateLongFormatter(pattern, formatLong) { + switch (pattern) { + case 'P': + return formatLong.date({ + width: 'short' + }); + case 'PP': + return formatLong.date({ + width: 'medium' + }); + case 'PPP': + return formatLong.date({ + width: 'long' + }); + case 'PPPP': + default: + return formatLong.date({ + width: 'full' + }); + } +}; +var timeLongFormatter = function timeLongFormatter(pattern, formatLong) { + switch (pattern) { + case 'p': + return formatLong.time({ + width: 'short' + }); + case 'pp': + return formatLong.time({ + width: 'medium' + }); + case 'ppp': + return formatLong.time({ + width: 'long' + }); + case 'pppp': + default: + return formatLong.time({ + width: 'full' + }); + } +}; +var dateTimeLongFormatter = function dateTimeLongFormatter(pattern, formatLong) { + var matchResult = pattern.match(/(P+)(p+)?/) || []; + var datePattern = matchResult[1]; + var timePattern = matchResult[2]; + if (!timePattern) { + return dateLongFormatter(pattern, formatLong); + } + var dateTimeFormat; + switch (datePattern) { + case 'P': + dateTimeFormat = formatLong.dateTime({ + width: 'short' + }); + break; + case 'PP': + dateTimeFormat = formatLong.dateTime({ + width: 'medium' + }); + break; + case 'PPP': + dateTimeFormat = formatLong.dateTime({ + width: 'long' + }); + break; + case 'PPPP': + default: + dateTimeFormat = formatLong.dateTime({ + width: 'full' + }); + break; + } + return dateTimeFormat.replace('{{date}}', dateLongFormatter(datePattern, formatLong)).replace('{{time}}', timeLongFormatter(timePattern, formatLong)); +}; +var longFormatters = { + p: timeLongFormatter, + P: dateTimeLongFormatter +}; +var _default = longFormatters; +exports["default"] = _default; +module.exports = exports.default; - // Decode tables: MBCS -> Unicode. +/***/ }), - // decodeTables is a trie, encoded as an array of arrays of integers. Internal arrays are trie nodes and all have len = 256. - // Trie root is decodeTables[0]. - // Values: >= 0 -> unicode character code. can be > 0xFFFF - // == UNASSIGNED -> unknown/unassigned sequence. - // == GB18030_CODE -> this is the end of a GB18030 4-byte sequence. - // <= NODE_START -> index of the next node in our trie to process next byte. - // <= SEQ_START -> index of the start of a character code sequence, in decodeTableSeq. - this.decodeTables = []; - this.decodeTables[0] = UNASSIGNED_NODE.slice(0); // Create root node. +/***/ 7032: +/***/ ((module, exports) => { - // Sometimes a MBCS char corresponds to a sequence of unicode chars. We store them as arrays of integers here. - this.decodeTableSeq = []; +"use strict"; - // Actual mapping tables consist of chunks. Use them to fill up decode tables. - for (var i = 0; i < mappingTable.length; i++) - this._addDecodeChunk(mappingTable[i]); - // Load & create GB18030 tables when needed. - if (typeof codecOptions.gb18030 === 'function') { - this.gb18030 = codecOptions.gb18030(); // Load GB18030 ranges. +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = getTimezoneOffsetInMilliseconds; +/** + * Google Chrome as of 67.0.3396.87 introduced timezones with offset that includes seconds. + * They usually appear for dates that denote time before the timezones were introduced + * (e.g. for 'Europe/Prague' timezone the offset is GMT+00:57:44 before 1 October 1891 + * and GMT+01:00:00 after that date) + * + * Date#getTimezoneOffset returns the offset in minutes and would return 57 for the example above, + * which would lead to incorrect calculations. + * + * This function returns the timezone offset in milliseconds that takes seconds in account. + */ +function getTimezoneOffsetInMilliseconds(date) { + var utcDate = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds())); + utcDate.setUTCFullYear(date.getFullYear()); + return date.getTime() - utcDate.getTime(); +} +module.exports = exports.default; - // Add GB18030 common decode nodes. - var commonThirdByteNodeIdx = this.decodeTables.length; - this.decodeTables.push(UNASSIGNED_NODE.slice(0)); +/***/ }), - var commonFourthByteNodeIdx = this.decodeTables.length; - this.decodeTables.push(UNASSIGNED_NODE.slice(0)); +/***/ 2966: +/***/ ((module, exports, __nccwpck_require__) => { - // Fill out the tree - var firstByteNode = this.decodeTables[0]; - for (var i = 0x81; i <= 0xFE; i++) { - var secondByteNode = this.decodeTables[NODE_START - firstByteNode[i]]; - for (var j = 0x30; j <= 0x39; j++) { - if (secondByteNode[j] === UNASSIGNED) { - secondByteNode[j] = NODE_START - commonThirdByteNodeIdx; - } else if (secondByteNode[j] > NODE_START) { - throw new Error("gb18030 decode tables conflict at byte 2"); - } +"use strict"; - var thirdByteNode = this.decodeTables[NODE_START - secondByteNode[j]]; - for (var k = 0x81; k <= 0xFE; k++) { - if (thirdByteNode[k] === UNASSIGNED) { - thirdByteNode[k] = NODE_START - commonFourthByteNodeIdx; - } else if (thirdByteNode[k] === NODE_START - commonFourthByteNodeIdx) { - continue; - } else if (thirdByteNode[k] > NODE_START) { - throw new Error("gb18030 decode tables conflict at byte 3"); - } - var fourthByteNode = this.decodeTables[NODE_START - thirdByteNode[k]]; - for (var l = 0x30; l <= 0x39; l++) { - if (fourthByteNode[l] === UNASSIGNED) - fourthByteNode[l] = GB18030_CODE; - } - } - } - } - } +var _interopRequireDefault = (__nccwpck_require__(3286)["default"]); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = getUTCDayOfYear; +var _index = _interopRequireDefault(__nccwpck_require__(6477)); +var _index2 = _interopRequireDefault(__nccwpck_require__(2063)); +var MILLISECONDS_IN_DAY = 86400000; +function getUTCDayOfYear(dirtyDate) { + (0, _index2.default)(1, arguments); + var date = (0, _index.default)(dirtyDate); + var timestamp = date.getTime(); + date.setUTCMonth(0, 1); + date.setUTCHours(0, 0, 0, 0); + var startOfYearTimestamp = date.getTime(); + var difference = timestamp - startOfYearTimestamp; + return Math.floor(difference / MILLISECONDS_IN_DAY) + 1; +} +module.exports = exports.default; - this.defaultCharUnicode = iconv.defaultCharUnicode; +/***/ }), - - // Encode tables: Unicode -> DBCS. +/***/ 8493: +/***/ ((module, exports, __nccwpck_require__) => { - // `encodeTable` is array mapping from unicode char to encoded char. All its values are integers for performance. - // Because it can be sparse, it is represented as array of buckets by 256 chars each. Bucket can be null. - // Values: >= 0 -> it is a normal char. Write the value (if <=256 then 1 byte, if <=65536 then 2 bytes, etc.). - // == UNASSIGNED -> no conversion found. Output a default char. - // <= SEQ_START -> it's an index in encodeTableSeq, see below. The character starts a sequence. - this.encodeTable = []; - - // `encodeTableSeq` is used when a sequence of unicode characters is encoded as a single code. We use a tree of - // objects where keys correspond to characters in sequence and leafs are the encoded dbcs values. A special DEF_CHAR key - // means end of sequence (needed when one sequence is a strict subsequence of another). - // Objects are kept separately from encodeTable to increase performance. - this.encodeTableSeq = []; +"use strict"; - // Some chars can be decoded, but need not be encoded. - var skipEncodeChars = {}; - if (codecOptions.encodeSkipVals) - for (var i = 0; i < codecOptions.encodeSkipVals.length; i++) { - var val = codecOptions.encodeSkipVals[i]; - if (typeof val === 'number') - skipEncodeChars[val] = true; - else - for (var j = val.from; j <= val.to; j++) - skipEncodeChars[j] = true; - } - - // Use decode trie to recursively fill out encode tables. - this._fillEncodeTable(0, 0, skipEncodeChars); - // Add more encoding pairs when needed. - if (codecOptions.encodeAdd) { - for (var uChar in codecOptions.encodeAdd) - if (Object.prototype.hasOwnProperty.call(codecOptions.encodeAdd, uChar)) - this._setEncodeChar(uChar.charCodeAt(0), codecOptions.encodeAdd[uChar]); - } +var _interopRequireDefault = (__nccwpck_require__(3286)["default"]); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = getUTCISOWeek; +var _index = _interopRequireDefault(__nccwpck_require__(6477)); +var _index2 = _interopRequireDefault(__nccwpck_require__(3061)); +var _index3 = _interopRequireDefault(__nccwpck_require__(1478)); +var _index4 = _interopRequireDefault(__nccwpck_require__(2063)); +var MILLISECONDS_IN_WEEK = 604800000; +function getUTCISOWeek(dirtyDate) { + (0, _index4.default)(1, arguments); + var date = (0, _index.default)(dirtyDate); + var diff = (0, _index2.default)(date).getTime() - (0, _index3.default)(date).getTime(); + + // Round the number of days to the nearest integer + // because the number of milliseconds in a week is not constant + // (e.g. it's different in the week of the daylight saving time clock shift) + return Math.round(diff / MILLISECONDS_IN_WEEK) + 1; +} +module.exports = exports.default; - this.defCharSB = this.encodeTable[0][iconv.defaultCharSingleByte.charCodeAt(0)]; - if (this.defCharSB === UNASSIGNED) this.defCharSB = this.encodeTable[0]['?']; - if (this.defCharSB === UNASSIGNED) this.defCharSB = "?".charCodeAt(0); -} +/***/ }), -DBCSCodec.prototype.encoder = DBCSEncoder; -DBCSCodec.prototype.decoder = DBCSDecoder; +/***/ 7170: +/***/ ((module, exports, __nccwpck_require__) => { -// Decoder helpers -DBCSCodec.prototype._getDecodeTrieNode = function(addr) { - var bytes = []; - for (; addr > 0; addr >>>= 8) - bytes.push(addr & 0xFF); - if (bytes.length == 0) - bytes.push(0); +"use strict"; - var node = this.decodeTables[0]; - for (var i = bytes.length-1; i > 0; i--) { // Traverse nodes deeper into the trie. - var val = node[bytes[i]]; - if (val == UNASSIGNED) { // Create new node. - node[bytes[i]] = NODE_START - this.decodeTables.length; - this.decodeTables.push(node = UNASSIGNED_NODE.slice(0)); - } - else if (val <= NODE_START) { // Existing node. - node = this.decodeTables[NODE_START - val]; - } - else - throw new Error("Overwrite byte in " + this.encodingName + ", addr: " + addr.toString(16)); - } - return node; +var _interopRequireDefault = (__nccwpck_require__(3286)["default"]); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = getUTCISOWeekYear; +var _index = _interopRequireDefault(__nccwpck_require__(6477)); +var _index2 = _interopRequireDefault(__nccwpck_require__(2063)); +var _index3 = _interopRequireDefault(__nccwpck_require__(3061)); +function getUTCISOWeekYear(dirtyDate) { + (0, _index2.default)(1, arguments); + var date = (0, _index.default)(dirtyDate); + var year = date.getUTCFullYear(); + var fourthOfJanuaryOfNextYear = new Date(0); + fourthOfJanuaryOfNextYear.setUTCFullYear(year + 1, 0, 4); + fourthOfJanuaryOfNextYear.setUTCHours(0, 0, 0, 0); + var startOfNextYear = (0, _index3.default)(fourthOfJanuaryOfNextYear); + var fourthOfJanuaryOfThisYear = new Date(0); + fourthOfJanuaryOfThisYear.setUTCFullYear(year, 0, 4); + fourthOfJanuaryOfThisYear.setUTCHours(0, 0, 0, 0); + var startOfThisYear = (0, _index3.default)(fourthOfJanuaryOfThisYear); + if (date.getTime() >= startOfNextYear.getTime()) { + return year + 1; + } else if (date.getTime() >= startOfThisYear.getTime()) { + return year; + } else { + return year - 1; + } } +module.exports = exports.default; +/***/ }), -DBCSCodec.prototype._addDecodeChunk = function(chunk) { - // First element of chunk is the hex mbcs code where we start. - var curAddr = parseInt(chunk[0], 16); +/***/ 8761: +/***/ ((module, exports, __nccwpck_require__) => { - // Choose the decoding node where we'll write our chars. - var writeTable = this._getDecodeTrieNode(curAddr); - curAddr = curAddr & 0xFF; +"use strict"; - // Write all other elements of the chunk to the table. - for (var k = 1; k < chunk.length; k++) { - var part = chunk[k]; - if (typeof part === "string") { // String, write as-is. - for (var l = 0; l < part.length;) { - var code = part.charCodeAt(l++); - if (0xD800 <= code && code < 0xDC00) { // Decode surrogate - var codeTrail = part.charCodeAt(l++); - if (0xDC00 <= codeTrail && codeTrail < 0xE000) - writeTable[curAddr++] = 0x10000 + (code - 0xD800) * 0x400 + (codeTrail - 0xDC00); - else - throw new Error("Incorrect surrogate pair in " + this.encodingName + " at chunk " + chunk[0]); - } - else if (0x0FF0 < code && code <= 0x0FFF) { // Character sequence (our own encoding used) - var len = 0xFFF - code + 2; - var seq = []; - for (var m = 0; m < len; m++) - seq.push(part.charCodeAt(l++)); // Simple variation: don't support surrogates or subsequences in seq. - writeTable[curAddr++] = SEQ_START - this.decodeTableSeq.length; - this.decodeTableSeq.push(seq); - } - else - writeTable[curAddr++] = code; // Basic char - } - } - else if (typeof part === "number") { // Integer, meaning increasing sequence starting with prev character. - var charCode = writeTable[curAddr - 1] + 1; - for (var l = 0; l < part; l++) - writeTable[curAddr++] = charCode++; - } - else - throw new Error("Incorrect type '" + typeof part + "' given in " + this.encodingName + " at chunk " + chunk[0]); - } - if (curAddr > 0xFF) - throw new Error("Incorrect chunk in " + this.encodingName + " at addr " + chunk[0] + ": too long" + curAddr); -} +var _interopRequireDefault = (__nccwpck_require__(3286)["default"]); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = getUTCWeek; +var _index = _interopRequireDefault(__nccwpck_require__(6477)); +var _index2 = _interopRequireDefault(__nccwpck_require__(2258)); +var _index3 = _interopRequireDefault(__nccwpck_require__(2629)); +var _index4 = _interopRequireDefault(__nccwpck_require__(2063)); +var MILLISECONDS_IN_WEEK = 604800000; +function getUTCWeek(dirtyDate, options) { + (0, _index4.default)(1, arguments); + var date = (0, _index.default)(dirtyDate); + var diff = (0, _index2.default)(date, options).getTime() - (0, _index3.default)(date, options).getTime(); + + // Round the number of days to the nearest integer + // because the number of milliseconds in a week is not constant + // (e.g. it's different in the week of the daylight saving time clock shift) + return Math.round(diff / MILLISECONDS_IN_WEEK) + 1; +} +module.exports = exports.default; -// Encoder helpers -DBCSCodec.prototype._getEncodeBucket = function(uCode) { - var high = uCode >> 8; // This could be > 0xFF because of astral characters. - if (this.encodeTable[high] === undefined) - this.encodeTable[high] = UNASSIGNED_NODE.slice(0); // Create bucket on demand. - return this.encodeTable[high]; -} +/***/ }), -DBCSCodec.prototype._setEncodeChar = function(uCode, dbcsCode) { - var bucket = this._getEncodeBucket(uCode); - var low = uCode & 0xFF; - if (bucket[low] <= SEQ_START) - this.encodeTableSeq[SEQ_START-bucket[low]][DEF_CHAR] = dbcsCode; // There's already a sequence, set a single-char subsequence of it. - else if (bucket[low] == UNASSIGNED) - bucket[low] = dbcsCode; +/***/ 8050: +/***/ ((module, exports, __nccwpck_require__) => { + +"use strict"; + + +var _interopRequireDefault = (__nccwpck_require__(3286)["default"]); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = getUTCWeekYear; +var _index = _interopRequireDefault(__nccwpck_require__(6477)); +var _index2 = _interopRequireDefault(__nccwpck_require__(2063)); +var _index3 = _interopRequireDefault(__nccwpck_require__(2258)); +var _index4 = _interopRequireDefault(__nccwpck_require__(1985)); +var _index5 = __nccwpck_require__(9307); +function getUTCWeekYear(dirtyDate, options) { + var _ref, _ref2, _ref3, _options$firstWeekCon, _options$locale, _options$locale$optio, _defaultOptions$local, _defaultOptions$local2; + (0, _index2.default)(1, arguments); + var date = (0, _index.default)(dirtyDate); + var year = date.getUTCFullYear(); + var defaultOptions = (0, _index5.getDefaultOptions)(); + var firstWeekContainsDate = (0, _index4.default)((_ref = (_ref2 = (_ref3 = (_options$firstWeekCon = options === null || options === void 0 ? void 0 : options.firstWeekContainsDate) !== null && _options$firstWeekCon !== void 0 ? _options$firstWeekCon : options === null || options === void 0 ? void 0 : (_options$locale = options.locale) === null || _options$locale === void 0 ? void 0 : (_options$locale$optio = _options$locale.options) === null || _options$locale$optio === void 0 ? void 0 : _options$locale$optio.firstWeekContainsDate) !== null && _ref3 !== void 0 ? _ref3 : defaultOptions.firstWeekContainsDate) !== null && _ref2 !== void 0 ? _ref2 : (_defaultOptions$local = defaultOptions.locale) === null || _defaultOptions$local === void 0 ? void 0 : (_defaultOptions$local2 = _defaultOptions$local.options) === null || _defaultOptions$local2 === void 0 ? void 0 : _defaultOptions$local2.firstWeekContainsDate) !== null && _ref !== void 0 ? _ref : 1); + + // Test if weekStartsOn is between 1 and 7 _and_ is not NaN + if (!(firstWeekContainsDate >= 1 && firstWeekContainsDate <= 7)) { + throw new RangeError('firstWeekContainsDate must be between 1 and 7 inclusively'); + } + var firstWeekOfNextYear = new Date(0); + firstWeekOfNextYear.setUTCFullYear(year + 1, 0, firstWeekContainsDate); + firstWeekOfNextYear.setUTCHours(0, 0, 0, 0); + var startOfNextYear = (0, _index3.default)(firstWeekOfNextYear, options); + var firstWeekOfThisYear = new Date(0); + firstWeekOfThisYear.setUTCFullYear(year, 0, firstWeekContainsDate); + firstWeekOfThisYear.setUTCHours(0, 0, 0, 0); + var startOfThisYear = (0, _index3.default)(firstWeekOfThisYear, options); + if (date.getTime() >= startOfNextYear.getTime()) { + return year + 1; + } else if (date.getTime() >= startOfThisYear.getTime()) { + return year; + } else { + return year - 1; + } } +module.exports = exports.default; -DBCSCodec.prototype._setEncodeSequence = function(seq, dbcsCode) { - - // Get the root of character tree according to first character of the sequence. - var uCode = seq[0]; - var bucket = this._getEncodeBucket(uCode); - var low = uCode & 0xFF; +/***/ }), - var node; - if (bucket[low] <= SEQ_START) { - // There's already a sequence with - use it. - node = this.encodeTableSeq[SEQ_START-bucket[low]]; - } - else { - // There was no sequence object - allocate a new one. - node = {}; - if (bucket[low] !== UNASSIGNED) node[DEF_CHAR] = bucket[low]; // If a char was set before - make it a single-char subsequence. - bucket[low] = SEQ_START - this.encodeTableSeq.length; - this.encodeTableSeq.push(node); - } +/***/ 2509: +/***/ ((__unused_webpack_module, exports) => { - // Traverse the character tree, allocating new nodes as needed. - for (var j = 1; j < seq.length-1; j++) { - var oldVal = node[uCode]; - if (typeof oldVal === 'object') - node = oldVal; - else { - node = node[uCode] = {} - if (oldVal !== undefined) - node[DEF_CHAR] = oldVal - } - } +"use strict"; - // Set the leaf to given dbcsCode. - uCode = seq[seq.length-1]; - node[uCode] = dbcsCode; + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.isProtectedDayOfYearToken = isProtectedDayOfYearToken; +exports.isProtectedWeekYearToken = isProtectedWeekYearToken; +exports.throwProtectedError = throwProtectedError; +var protectedDayOfYearTokens = ['D', 'DD']; +var protectedWeekYearTokens = ['YY', 'YYYY']; +function isProtectedDayOfYearToken(token) { + return protectedDayOfYearTokens.indexOf(token) !== -1; +} +function isProtectedWeekYearToken(token) { + return protectedWeekYearTokens.indexOf(token) !== -1; +} +function throwProtectedError(token, format, input) { + if (token === 'YYYY') { + throw new RangeError("Use `yyyy` instead of `YYYY` (in `".concat(format, "`) for formatting years to the input `").concat(input, "`; see: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md")); + } else if (token === 'YY') { + throw new RangeError("Use `yy` instead of `YY` (in `".concat(format, "`) for formatting years to the input `").concat(input, "`; see: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md")); + } else if (token === 'D') { + throw new RangeError("Use `d` instead of `D` (in `".concat(format, "`) for formatting days of the month to the input `").concat(input, "`; see: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md")); + } else if (token === 'DD') { + throw new RangeError("Use `dd` instead of `DD` (in `".concat(format, "`) for formatting days of the month to the input `").concat(input, "`; see: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md")); + } } -DBCSCodec.prototype._fillEncodeTable = function(nodeIdx, prefix, skipEncodeChars) { - var node = this.decodeTables[nodeIdx]; - var hasValues = false; - var subNodeEmpty = {}; - for (var i = 0; i < 0x100; i++) { - var uCode = node[i]; - var mbCode = prefix + i; - if (skipEncodeChars[mbCode]) - continue; +/***/ }), - if (uCode >= 0) { - this._setEncodeChar(uCode, mbCode); - hasValues = true; - } else if (uCode <= NODE_START) { - var subNodeIdx = NODE_START - uCode; - if (!subNodeEmpty[subNodeIdx]) { // Skip empty subtrees (they are too large in gb18030). - var newPrefix = (mbCode << 8) >>> 0; // NOTE: '>>> 0' keeps 32-bit num positive. - if (this._fillEncodeTable(subNodeIdx, newPrefix, skipEncodeChars)) - hasValues = true; - else - subNodeEmpty[subNodeIdx] = true; - } - } else if (uCode <= SEQ_START) { - this._setEncodeSequence(this.decodeTableSeq[SEQ_START - uCode], mbCode); - hasValues = true; - } - } - return hasValues; +/***/ 2063: +/***/ ((module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = requiredArgs; +function requiredArgs(required, args) { + if (args.length < required) { + throw new TypeError(required + ' argument' + (required > 1 ? 's' : '') + ' required, but only ' + args.length + ' present'); + } } +module.exports = exports.default; +/***/ }), +/***/ 3061: +/***/ ((module, exports, __nccwpck_require__) => { -// == Encoder ================================================================== +"use strict"; -function DBCSEncoder(options, codec) { - // Encoder state - this.leadSurrogate = -1; - this.seqObj = undefined; - - // Static data - this.encodeTable = codec.encodeTable; - this.encodeTableSeq = codec.encodeTableSeq; - this.defaultCharSingleByte = codec.defCharSB; - this.gb18030 = codec.gb18030; -} -DBCSEncoder.prototype.write = function(str) { - var newBuf = Buffer.alloc(str.length * (this.gb18030 ? 4 : 3)), - leadSurrogate = this.leadSurrogate, - seqObj = this.seqObj, nextChar = -1, - i = 0, j = 0; +var _interopRequireDefault = (__nccwpck_require__(3286)["default"]); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = startOfUTCISOWeek; +var _index = _interopRequireDefault(__nccwpck_require__(6477)); +var _index2 = _interopRequireDefault(__nccwpck_require__(2063)); +function startOfUTCISOWeek(dirtyDate) { + (0, _index2.default)(1, arguments); + var weekStartsOn = 1; + var date = (0, _index.default)(dirtyDate); + var day = date.getUTCDay(); + var diff = (day < weekStartsOn ? 7 : 0) + day - weekStartsOn; + date.setUTCDate(date.getUTCDate() - diff); + date.setUTCHours(0, 0, 0, 0); + return date; +} +module.exports = exports.default; - while (true) { - // 0. Get next character. - if (nextChar === -1) { - if (i == str.length) break; - var uCode = str.charCodeAt(i++); - } - else { - var uCode = nextChar; - nextChar = -1; - } +/***/ }), - // 1. Handle surrogates. - if (0xD800 <= uCode && uCode < 0xE000) { // Char is one of surrogates. - if (uCode < 0xDC00) { // We've got lead surrogate. - if (leadSurrogate === -1) { - leadSurrogate = uCode; - continue; - } else { - leadSurrogate = uCode; - // Double lead surrogate found. - uCode = UNASSIGNED; - } - } else { // We've got trail surrogate. - if (leadSurrogate !== -1) { - uCode = 0x10000 + (leadSurrogate - 0xD800) * 0x400 + (uCode - 0xDC00); - leadSurrogate = -1; - } else { - // Incomplete surrogate pair - only trail surrogate found. - uCode = UNASSIGNED; - } - - } - } - else if (leadSurrogate !== -1) { - // Incomplete surrogate pair - only lead surrogate found. - nextChar = uCode; uCode = UNASSIGNED; // Write an error, then current char. - leadSurrogate = -1; - } +/***/ 1478: +/***/ ((module, exports, __nccwpck_require__) => { - // 2. Convert uCode character. - var dbcsCode = UNASSIGNED; - if (seqObj !== undefined && uCode != UNASSIGNED) { // We are in the middle of the sequence - var resCode = seqObj[uCode]; - if (typeof resCode === 'object') { // Sequence continues. - seqObj = resCode; - continue; +"use strict"; - } else if (typeof resCode == 'number') { // Sequence finished. Write it. - dbcsCode = resCode; - } else if (resCode == undefined) { // Current character is not part of the sequence. +var _interopRequireDefault = (__nccwpck_require__(3286)["default"]); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = startOfUTCISOWeekYear; +var _index = _interopRequireDefault(__nccwpck_require__(7170)); +var _index2 = _interopRequireDefault(__nccwpck_require__(3061)); +var _index3 = _interopRequireDefault(__nccwpck_require__(2063)); +function startOfUTCISOWeekYear(dirtyDate) { + (0, _index3.default)(1, arguments); + var year = (0, _index.default)(dirtyDate); + var fourthOfJanuary = new Date(0); + fourthOfJanuary.setUTCFullYear(year, 0, 4); + fourthOfJanuary.setUTCHours(0, 0, 0, 0); + var date = (0, _index2.default)(fourthOfJanuary); + return date; +} +module.exports = exports.default; - // Try default character for this sequence - resCode = seqObj[DEF_CHAR]; - if (resCode !== undefined) { - dbcsCode = resCode; // Found. Write it. - nextChar = uCode; // Current character will be written too in the next iteration. +/***/ }), - } else { - // TODO: What if we have no default? (resCode == undefined) - // Then, we should write first char of the sequence as-is and try the rest recursively. - // Didn't do it for now because no encoding has this situation yet. - // Currently, just skip the sequence and write current char. - } - } - seqObj = undefined; - } - else if (uCode >= 0) { // Regular character - var subtable = this.encodeTable[uCode >> 8]; - if (subtable !== undefined) - dbcsCode = subtable[uCode & 0xFF]; - - if (dbcsCode <= SEQ_START) { // Sequence start - seqObj = this.encodeTableSeq[SEQ_START-dbcsCode]; - continue; - } +/***/ 2258: +/***/ ((module, exports, __nccwpck_require__) => { - if (dbcsCode == UNASSIGNED && this.gb18030) { - // Use GB18030 algorithm to find character(s) to write. - var idx = findIdx(this.gb18030.uChars, uCode); - if (idx != -1) { - var dbcsCode = this.gb18030.gbChars[idx] + (uCode - this.gb18030.uChars[idx]); - newBuf[j++] = 0x81 + Math.floor(dbcsCode / 12600); dbcsCode = dbcsCode % 12600; - newBuf[j++] = 0x30 + Math.floor(dbcsCode / 1260); dbcsCode = dbcsCode % 1260; - newBuf[j++] = 0x81 + Math.floor(dbcsCode / 10); dbcsCode = dbcsCode % 10; - newBuf[j++] = 0x30 + dbcsCode; - continue; - } - } - } +"use strict"; - // 3. Write dbcsCode character. - if (dbcsCode === UNASSIGNED) - dbcsCode = this.defaultCharSingleByte; - - if (dbcsCode < 0x100) { - newBuf[j++] = dbcsCode; - } - else if (dbcsCode < 0x10000) { - newBuf[j++] = dbcsCode >> 8; // high byte - newBuf[j++] = dbcsCode & 0xFF; // low byte - } - else if (dbcsCode < 0x1000000) { - newBuf[j++] = dbcsCode >> 16; - newBuf[j++] = (dbcsCode >> 8) & 0xFF; - newBuf[j++] = dbcsCode & 0xFF; - } else { - newBuf[j++] = dbcsCode >>> 24; - newBuf[j++] = (dbcsCode >>> 16) & 0xFF; - newBuf[j++] = (dbcsCode >>> 8) & 0xFF; - newBuf[j++] = dbcsCode & 0xFF; - } - } - this.seqObj = seqObj; - this.leadSurrogate = leadSurrogate; - return newBuf.slice(0, j); +var _interopRequireDefault = (__nccwpck_require__(3286)["default"]); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = startOfUTCWeek; +var _index = _interopRequireDefault(__nccwpck_require__(6477)); +var _index2 = _interopRequireDefault(__nccwpck_require__(2063)); +var _index3 = _interopRequireDefault(__nccwpck_require__(1985)); +var _index4 = __nccwpck_require__(9307); +function startOfUTCWeek(dirtyDate, options) { + var _ref, _ref2, _ref3, _options$weekStartsOn, _options$locale, _options$locale$optio, _defaultOptions$local, _defaultOptions$local2; + (0, _index2.default)(1, arguments); + var defaultOptions = (0, _index4.getDefaultOptions)(); + var weekStartsOn = (0, _index3.default)((_ref = (_ref2 = (_ref3 = (_options$weekStartsOn = options === null || options === void 0 ? void 0 : options.weekStartsOn) !== null && _options$weekStartsOn !== void 0 ? _options$weekStartsOn : options === null || options === void 0 ? void 0 : (_options$locale = options.locale) === null || _options$locale === void 0 ? void 0 : (_options$locale$optio = _options$locale.options) === null || _options$locale$optio === void 0 ? void 0 : _options$locale$optio.weekStartsOn) !== null && _ref3 !== void 0 ? _ref3 : defaultOptions.weekStartsOn) !== null && _ref2 !== void 0 ? _ref2 : (_defaultOptions$local = defaultOptions.locale) === null || _defaultOptions$local === void 0 ? void 0 : (_defaultOptions$local2 = _defaultOptions$local.options) === null || _defaultOptions$local2 === void 0 ? void 0 : _defaultOptions$local2.weekStartsOn) !== null && _ref !== void 0 ? _ref : 0); + + // Test if weekStartsOn is between 0 and 6 _and_ is not NaN + if (!(weekStartsOn >= 0 && weekStartsOn <= 6)) { + throw new RangeError('weekStartsOn must be between 0 and 6 inclusively'); + } + var date = (0, _index.default)(dirtyDate); + var day = date.getUTCDay(); + var diff = (day < weekStartsOn ? 7 : 0) + day - weekStartsOn; + date.setUTCDate(date.getUTCDate() - diff); + date.setUTCHours(0, 0, 0, 0); + return date; } +module.exports = exports.default; -DBCSEncoder.prototype.end = function() { - if (this.leadSurrogate === -1 && this.seqObj === undefined) - return; // All clean. Most often case. +/***/ }), - var newBuf = Buffer.alloc(10), j = 0; +/***/ 2629: +/***/ ((module, exports, __nccwpck_require__) => { - if (this.seqObj) { // We're in the sequence. - var dbcsCode = this.seqObj[DEF_CHAR]; - if (dbcsCode !== undefined) { // Write beginning of the sequence. - if (dbcsCode < 0x100) { - newBuf[j++] = dbcsCode; - } - else { - newBuf[j++] = dbcsCode >> 8; // high byte - newBuf[j++] = dbcsCode & 0xFF; // low byte - } - } else { - // See todo above. - } - this.seqObj = undefined; - } +"use strict"; - if (this.leadSurrogate !== -1) { - // Incomplete surrogate pair - only lead surrogate found. - newBuf[j++] = this.defaultCharSingleByte; - this.leadSurrogate = -1; - } - - return newBuf.slice(0, j); + +var _interopRequireDefault = (__nccwpck_require__(3286)["default"]); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = startOfUTCWeekYear; +var _index = _interopRequireDefault(__nccwpck_require__(8050)); +var _index2 = _interopRequireDefault(__nccwpck_require__(2063)); +var _index3 = _interopRequireDefault(__nccwpck_require__(2258)); +var _index4 = _interopRequireDefault(__nccwpck_require__(1985)); +var _index5 = __nccwpck_require__(9307); +function startOfUTCWeekYear(dirtyDate, options) { + var _ref, _ref2, _ref3, _options$firstWeekCon, _options$locale, _options$locale$optio, _defaultOptions$local, _defaultOptions$local2; + (0, _index2.default)(1, arguments); + var defaultOptions = (0, _index5.getDefaultOptions)(); + var firstWeekContainsDate = (0, _index4.default)((_ref = (_ref2 = (_ref3 = (_options$firstWeekCon = options === null || options === void 0 ? void 0 : options.firstWeekContainsDate) !== null && _options$firstWeekCon !== void 0 ? _options$firstWeekCon : options === null || options === void 0 ? void 0 : (_options$locale = options.locale) === null || _options$locale === void 0 ? void 0 : (_options$locale$optio = _options$locale.options) === null || _options$locale$optio === void 0 ? void 0 : _options$locale$optio.firstWeekContainsDate) !== null && _ref3 !== void 0 ? _ref3 : defaultOptions.firstWeekContainsDate) !== null && _ref2 !== void 0 ? _ref2 : (_defaultOptions$local = defaultOptions.locale) === null || _defaultOptions$local === void 0 ? void 0 : (_defaultOptions$local2 = _defaultOptions$local.options) === null || _defaultOptions$local2 === void 0 ? void 0 : _defaultOptions$local2.firstWeekContainsDate) !== null && _ref !== void 0 ? _ref : 1); + var year = (0, _index.default)(dirtyDate, options); + var firstWeek = new Date(0); + firstWeek.setUTCFullYear(year, 0, firstWeekContainsDate); + firstWeek.setUTCHours(0, 0, 0, 0); + var date = (0, _index3.default)(firstWeek, options); + return date; +} +module.exports = exports.default; + +/***/ }), + +/***/ 1985: +/***/ ((module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = toInteger; +function toInteger(dirtyNumber) { + if (dirtyNumber === null || dirtyNumber === true || dirtyNumber === false) { + return NaN; + } + var number = Number(dirtyNumber); + if (isNaN(number)) { + return number; + } + return number < 0 ? Math.ceil(number) : Math.floor(number); } +module.exports = exports.default; -// Export for testing -DBCSEncoder.prototype.findIdx = findIdx; +/***/ }), +/***/ 524: +/***/ ((module, exports, __nccwpck_require__) => { -// == Decoder ================================================================== +"use strict"; -function DBCSDecoder(options, codec) { - // Decoder state - this.nodeIdx = 0; - this.prevBytes = []; - // Static data - this.decodeTables = codec.decodeTables; - this.decodeTableSeq = codec.decodeTableSeq; - this.defaultCharUnicode = codec.defaultCharUnicode; - this.gb18030 = codec.gb18030; +var _interopRequireDefault = (__nccwpck_require__(3286)["default"]); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = addMilliseconds; +var _index = _interopRequireDefault(__nccwpck_require__(1985)); +var _index2 = _interopRequireDefault(__nccwpck_require__(6477)); +var _index3 = _interopRequireDefault(__nccwpck_require__(2063)); +/** + * @name addMilliseconds + * @category Millisecond Helpers + * @summary Add the specified number of milliseconds to the given date. + * + * @description + * Add the specified number of milliseconds to the given date. + * + * @param {Date|Number} date - the date to be changed + * @param {Number} amount - the amount of milliseconds to be added. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`. + * @returns {Date} the new date with the milliseconds added + * @throws {TypeError} 2 arguments required + * + * @example + * // Add 750 milliseconds to 10 July 2014 12:45:30.000: + * const result = addMilliseconds(new Date(2014, 6, 10, 12, 45, 30, 0), 750) + * //=> Thu Jul 10 2014 12:45:30.750 + */ +function addMilliseconds(dirtyDate, dirtyAmount) { + (0, _index3.default)(2, arguments); + var timestamp = (0, _index2.default)(dirtyDate).getTime(); + var amount = (0, _index.default)(dirtyAmount); + return new Date(timestamp + amount); } +module.exports = exports.default; -DBCSDecoder.prototype.write = function(buf) { - var newBuf = Buffer.alloc(buf.length*2), - nodeIdx = this.nodeIdx, - prevBytes = this.prevBytes, prevOffset = this.prevBytes.length, - seqStart = -this.prevBytes.length, // idx of the start of current parsed sequence. - uCode; +/***/ }), - for (var i = 0, j = 0; i < buf.length; i++) { - var curByte = (i >= 0) ? buf[i] : prevBytes[i + prevOffset]; +/***/ 2168: +/***/ ((module, exports, __nccwpck_require__) => { - // Lookup in current trie node. - var uCode = this.decodeTables[nodeIdx][curByte]; +"use strict"; - if (uCode >= 0) { - // Normal character, just use it. - } - else if (uCode === UNASSIGNED) { // Unknown char. - // TODO: Callback with seq. - uCode = this.defaultCharUnicode.charCodeAt(0); - i = seqStart; // Skip one byte ('i' will be incremented by the for loop) and try to parse again. - } - else if (uCode === GB18030_CODE) { - if (i >= 3) { - var ptr = (buf[i-3]-0x81)*12600 + (buf[i-2]-0x30)*1260 + (buf[i-1]-0x81)*10 + (curByte-0x30); - } else { - var ptr = (prevBytes[i-3+prevOffset]-0x81)*12600 + - (((i-2 >= 0) ? buf[i-2] : prevBytes[i-2+prevOffset])-0x30)*1260 + - (((i-1 >= 0) ? buf[i-1] : prevBytes[i-1+prevOffset])-0x81)*10 + - (curByte-0x30); - } - var idx = findIdx(this.gb18030.gbChars, ptr); - uCode = this.gb18030.uChars[idx] + ptr - this.gb18030.gbChars[idx]; - } - else if (uCode <= NODE_START) { // Go to next trie node. - nodeIdx = NODE_START - uCode; - continue; - } - else if (uCode <= SEQ_START) { // Output a sequence of chars. - var seq = this.decodeTableSeq[SEQ_START - uCode]; - for (var k = 0; k < seq.length - 1; k++) { - uCode = seq[k]; - newBuf[j++] = uCode & 0xFF; - newBuf[j++] = uCode >> 8; - } - uCode = seq[seq.length-1]; - } - else - throw new Error("iconv-lite internal error: invalid decoding table value " + uCode + " at " + nodeIdx + "/" + curByte); - // Write the character to buffer, handling higher planes using surrogate pair. - if (uCode >= 0x10000) { - uCode -= 0x10000; - var uCodeLead = 0xD800 | (uCode >> 10); - newBuf[j++] = uCodeLead & 0xFF; - newBuf[j++] = uCodeLead >> 8; +var _interopRequireDefault = (__nccwpck_require__(3286)["default"]); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = format; +var _index = _interopRequireDefault(__nccwpck_require__(9920)); +var _index2 = _interopRequireDefault(__nccwpck_require__(7923)); +var _index3 = _interopRequireDefault(__nccwpck_require__(6477)); +var _index4 = _interopRequireDefault(__nccwpck_require__(9257)); +var _index5 = _interopRequireDefault(__nccwpck_require__(8387)); +var _index6 = _interopRequireDefault(__nccwpck_require__(7032)); +var _index7 = __nccwpck_require__(2509); +var _index8 = _interopRequireDefault(__nccwpck_require__(1985)); +var _index9 = _interopRequireDefault(__nccwpck_require__(2063)); +var _index10 = __nccwpck_require__(9307); +var _index11 = _interopRequireDefault(__nccwpck_require__(618)); +// This RegExp consists of three parts separated by `|`: +// - [yYQqMLwIdDecihHKkms]o matches any available ordinal number token +// (one of the certain letters followed by `o`) +// - (\w)\1* matches any sequences of the same letter +// - '' matches two quote characters in a row +// - '(''|[^'])+('|$) matches anything surrounded by two quote characters ('), +// except a single quote symbol, which ends the sequence. +// Two quote characters do not end the sequence. +// If there is no matching single quote +// then the sequence will continue until the end of the string. +// - . matches any single character unmatched by previous parts of the RegExps +var formattingTokensRegExp = /[yYQqMLwIdDecihHKkms]o|(\w)\1*|''|'(''|[^'])+('|$)|./g; + +// This RegExp catches symbols escaped by quotes, and also +// sequences of symbols P, p, and the combinations like `PPPPPPPppppp` +var longFormattingTokensRegExp = /P+p+|P+|p+|''|'(''|[^'])+('|$)|./g; +var escapedStringRegExp = /^'([^]*?)'?$/; +var doubleQuoteRegExp = /''/g; +var unescapedLatinCharacterRegExp = /[a-zA-Z]/; - uCode = 0xDC00 | (uCode & 0x3FF); - } - newBuf[j++] = uCode & 0xFF; - newBuf[j++] = uCode >> 8; +/** + * @name format + * @category Common Helpers + * @summary Format the date. + * + * @description + * Return the formatted date string in the given format. The result may vary by locale. + * + * > ⚠️ Please note that the `format` tokens differ from Moment.js and other libraries. + * > See: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md + * + * The characters wrapped between two single quotes characters (') are escaped. + * Two single quotes in a row, whether inside or outside a quoted sequence, represent a 'real' single quote. + * (see the last example) + * + * Format of the string is based on Unicode Technical Standard #35: + * https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table + * with a few additions (see note 7 below the table). + * + * Accepted patterns: + * | Unit | Pattern | Result examples | Notes | + * |---------------------------------|---------|-----------------------------------|-------| + * | Era | G..GGG | AD, BC | | + * | | GGGG | Anno Domini, Before Christ | 2 | + * | | GGGGG | A, B | | + * | Calendar year | y | 44, 1, 1900, 2017 | 5 | + * | | yo | 44th, 1st, 0th, 17th | 5,7 | + * | | yy | 44, 01, 00, 17 | 5 | + * | | yyy | 044, 001, 1900, 2017 | 5 | + * | | yyyy | 0044, 0001, 1900, 2017 | 5 | + * | | yyyyy | ... | 3,5 | + * | Local week-numbering year | Y | 44, 1, 1900, 2017 | 5 | + * | | Yo | 44th, 1st, 1900th, 2017th | 5,7 | + * | | YY | 44, 01, 00, 17 | 5,8 | + * | | YYY | 044, 001, 1900, 2017 | 5 | + * | | YYYY | 0044, 0001, 1900, 2017 | 5,8 | + * | | YYYYY | ... | 3,5 | + * | ISO week-numbering year | R | -43, 0, 1, 1900, 2017 | 5,7 | + * | | RR | -43, 00, 01, 1900, 2017 | 5,7 | + * | | RRR | -043, 000, 001, 1900, 2017 | 5,7 | + * | | RRRR | -0043, 0000, 0001, 1900, 2017 | 5,7 | + * | | RRRRR | ... | 3,5,7 | + * | Extended year | u | -43, 0, 1, 1900, 2017 | 5 | + * | | uu | -43, 01, 1900, 2017 | 5 | + * | | uuu | -043, 001, 1900, 2017 | 5 | + * | | uuuu | -0043, 0001, 1900, 2017 | 5 | + * | | uuuuu | ... | 3,5 | + * | Quarter (formatting) | Q | 1, 2, 3, 4 | | + * | | Qo | 1st, 2nd, 3rd, 4th | 7 | + * | | QQ | 01, 02, 03, 04 | | + * | | QQQ | Q1, Q2, Q3, Q4 | | + * | | QQQQ | 1st quarter, 2nd quarter, ... | 2 | + * | | QQQQQ | 1, 2, 3, 4 | 4 | + * | Quarter (stand-alone) | q | 1, 2, 3, 4 | | + * | | qo | 1st, 2nd, 3rd, 4th | 7 | + * | | qq | 01, 02, 03, 04 | | + * | | qqq | Q1, Q2, Q3, Q4 | | + * | | qqqq | 1st quarter, 2nd quarter, ... | 2 | + * | | qqqqq | 1, 2, 3, 4 | 4 | + * | Month (formatting) | M | 1, 2, ..., 12 | | + * | | Mo | 1st, 2nd, ..., 12th | 7 | + * | | MM | 01, 02, ..., 12 | | + * | | MMM | Jan, Feb, ..., Dec | | + * | | MMMM | January, February, ..., December | 2 | + * | | MMMMM | J, F, ..., D | | + * | Month (stand-alone) | L | 1, 2, ..., 12 | | + * | | Lo | 1st, 2nd, ..., 12th | 7 | + * | | LL | 01, 02, ..., 12 | | + * | | LLL | Jan, Feb, ..., Dec | | + * | | LLLL | January, February, ..., December | 2 | + * | | LLLLL | J, F, ..., D | | + * | Local week of year | w | 1, 2, ..., 53 | | + * | | wo | 1st, 2nd, ..., 53th | 7 | + * | | ww | 01, 02, ..., 53 | | + * | ISO week of year | I | 1, 2, ..., 53 | 7 | + * | | Io | 1st, 2nd, ..., 53th | 7 | + * | | II | 01, 02, ..., 53 | 7 | + * | Day of month | d | 1, 2, ..., 31 | | + * | | do | 1st, 2nd, ..., 31st | 7 | + * | | dd | 01, 02, ..., 31 | | + * | Day of year | D | 1, 2, ..., 365, 366 | 9 | + * | | Do | 1st, 2nd, ..., 365th, 366th | 7 | + * | | DD | 01, 02, ..., 365, 366 | 9 | + * | | DDD | 001, 002, ..., 365, 366 | | + * | | DDDD | ... | 3 | + * | Day of week (formatting) | E..EEE | Mon, Tue, Wed, ..., Sun | | + * | | EEEE | Monday, Tuesday, ..., Sunday | 2 | + * | | EEEEE | M, T, W, T, F, S, S | | + * | | EEEEEE | Mo, Tu, We, Th, Fr, Sa, Su | | + * | ISO day of week (formatting) | i | 1, 2, 3, ..., 7 | 7 | + * | | io | 1st, 2nd, ..., 7th | 7 | + * | | ii | 01, 02, ..., 07 | 7 | + * | | iii | Mon, Tue, Wed, ..., Sun | 7 | + * | | iiii | Monday, Tuesday, ..., Sunday | 2,7 | + * | | iiiii | M, T, W, T, F, S, S | 7 | + * | | iiiiii | Mo, Tu, We, Th, Fr, Sa, Su | 7 | + * | Local day of week (formatting) | e | 2, 3, 4, ..., 1 | | + * | | eo | 2nd, 3rd, ..., 1st | 7 | + * | | ee | 02, 03, ..., 01 | | + * | | eee | Mon, Tue, Wed, ..., Sun | | + * | | eeee | Monday, Tuesday, ..., Sunday | 2 | + * | | eeeee | M, T, W, T, F, S, S | | + * | | eeeeee | Mo, Tu, We, Th, Fr, Sa, Su | | + * | Local day of week (stand-alone) | c | 2, 3, 4, ..., 1 | | + * | | co | 2nd, 3rd, ..., 1st | 7 | + * | | cc | 02, 03, ..., 01 | | + * | | ccc | Mon, Tue, Wed, ..., Sun | | + * | | cccc | Monday, Tuesday, ..., Sunday | 2 | + * | | ccccc | M, T, W, T, F, S, S | | + * | | cccccc | Mo, Tu, We, Th, Fr, Sa, Su | | + * | AM, PM | a..aa | AM, PM | | + * | | aaa | am, pm | | + * | | aaaa | a.m., p.m. | 2 | + * | | aaaaa | a, p | | + * | AM, PM, noon, midnight | b..bb | AM, PM, noon, midnight | | + * | | bbb | am, pm, noon, midnight | | + * | | bbbb | a.m., p.m., noon, midnight | 2 | + * | | bbbbb | a, p, n, mi | | + * | Flexible day period | B..BBB | at night, in the morning, ... | | + * | | BBBB | at night, in the morning, ... | 2 | + * | | BBBBB | at night, in the morning, ... | | + * | Hour [1-12] | h | 1, 2, ..., 11, 12 | | + * | | ho | 1st, 2nd, ..., 11th, 12th | 7 | + * | | hh | 01, 02, ..., 11, 12 | | + * | Hour [0-23] | H | 0, 1, 2, ..., 23 | | + * | | Ho | 0th, 1st, 2nd, ..., 23rd | 7 | + * | | HH | 00, 01, 02, ..., 23 | | + * | Hour [0-11] | K | 1, 2, ..., 11, 0 | | + * | | Ko | 1st, 2nd, ..., 11th, 0th | 7 | + * | | KK | 01, 02, ..., 11, 00 | | + * | Hour [1-24] | k | 24, 1, 2, ..., 23 | | + * | | ko | 24th, 1st, 2nd, ..., 23rd | 7 | + * | | kk | 24, 01, 02, ..., 23 | | + * | Minute | m | 0, 1, ..., 59 | | + * | | mo | 0th, 1st, ..., 59th | 7 | + * | | mm | 00, 01, ..., 59 | | + * | Second | s | 0, 1, ..., 59 | | + * | | so | 0th, 1st, ..., 59th | 7 | + * | | ss | 00, 01, ..., 59 | | + * | Fraction of second | S | 0, 1, ..., 9 | | + * | | SS | 00, 01, ..., 99 | | + * | | SSS | 000, 001, ..., 999 | | + * | | SSSS | ... | 3 | + * | Timezone (ISO-8601 w/ Z) | X | -08, +0530, Z | | + * | | XX | -0800, +0530, Z | | + * | | XXX | -08:00, +05:30, Z | | + * | | XXXX | -0800, +0530, Z, +123456 | 2 | + * | | XXXXX | -08:00, +05:30, Z, +12:34:56 | | + * | Timezone (ISO-8601 w/o Z) | x | -08, +0530, +00 | | + * | | xx | -0800, +0530, +0000 | | + * | | xxx | -08:00, +05:30, +00:00 | 2 | + * | | xxxx | -0800, +0530, +0000, +123456 | | + * | | xxxxx | -08:00, +05:30, +00:00, +12:34:56 | | + * | Timezone (GMT) | O...OOO | GMT-8, GMT+5:30, GMT+0 | | + * | | OOOO | GMT-08:00, GMT+05:30, GMT+00:00 | 2 | + * | Timezone (specific non-locat.) | z...zzz | GMT-8, GMT+5:30, GMT+0 | 6 | + * | | zzzz | GMT-08:00, GMT+05:30, GMT+00:00 | 2,6 | + * | Seconds timestamp | t | 512969520 | 7 | + * | | tt | ... | 3,7 | + * | Milliseconds timestamp | T | 512969520900 | 7 | + * | | TT | ... | 3,7 | + * | Long localized date | P | 04/29/1453 | 7 | + * | | PP | Apr 29, 1453 | 7 | + * | | PPP | April 29th, 1453 | 7 | + * | | PPPP | Friday, April 29th, 1453 | 2,7 | + * | Long localized time | p | 12:00 AM | 7 | + * | | pp | 12:00:00 AM | 7 | + * | | ppp | 12:00:00 AM GMT+2 | 7 | + * | | pppp | 12:00:00 AM GMT+02:00 | 2,7 | + * | Combination of date and time | Pp | 04/29/1453, 12:00 AM | 7 | + * | | PPpp | Apr 29, 1453, 12:00:00 AM | 7 | + * | | PPPppp | April 29th, 1453 at ... | 7 | + * | | PPPPpppp| Friday, April 29th, 1453 at ... | 2,7 | + * Notes: + * 1. "Formatting" units (e.g. formatting quarter) in the default en-US locale + * are the same as "stand-alone" units, but are different in some languages. + * "Formatting" units are declined according to the rules of the language + * in the context of a date. "Stand-alone" units are always nominative singular: + * + * `format(new Date(2017, 10, 6), 'do LLLL', {locale: cs}) //=> '6. listopad'` + * + * `format(new Date(2017, 10, 6), 'do MMMM', {locale: cs}) //=> '6. listopadu'` + * + * 2. Any sequence of the identical letters is a pattern, unless it is escaped by + * the single quote characters (see below). + * If the sequence is longer than listed in table (e.g. `EEEEEEEEEEE`) + * the output will be the same as default pattern for this unit, usually + * the longest one (in case of ISO weekdays, `EEEE`). Default patterns for units + * are marked with "2" in the last column of the table. + * + * `format(new Date(2017, 10, 6), 'MMM') //=> 'Nov'` + * + * `format(new Date(2017, 10, 6), 'MMMM') //=> 'November'` + * + * `format(new Date(2017, 10, 6), 'MMMMM') //=> 'N'` + * + * `format(new Date(2017, 10, 6), 'MMMMMM') //=> 'November'` + * + * `format(new Date(2017, 10, 6), 'MMMMMMM') //=> 'November'` + * + * 3. Some patterns could be unlimited length (such as `yyyyyyyy`). + * The output will be padded with zeros to match the length of the pattern. + * + * `format(new Date(2017, 10, 6), 'yyyyyyyy') //=> '00002017'` + * + * 4. `QQQQQ` and `qqqqq` could be not strictly numerical in some locales. + * These tokens represent the shortest form of the quarter. + * + * 5. The main difference between `y` and `u` patterns are B.C. years: + * + * | Year | `y` | `u` | + * |------|-----|-----| + * | AC 1 | 1 | 1 | + * | BC 1 | 1 | 0 | + * | BC 2 | 2 | -1 | + * + * Also `yy` always returns the last two digits of a year, + * while `uu` pads single digit years to 2 characters and returns other years unchanged: + * + * | Year | `yy` | `uu` | + * |------|------|------| + * | 1 | 01 | 01 | + * | 14 | 14 | 14 | + * | 376 | 76 | 376 | + * | 1453 | 53 | 1453 | + * + * The same difference is true for local and ISO week-numbering years (`Y` and `R`), + * except local week-numbering years are dependent on `options.weekStartsOn` + * and `options.firstWeekContainsDate` (compare [getISOWeekYear]{@link https://date-fns.org/docs/getISOWeekYear} + * and [getWeekYear]{@link https://date-fns.org/docs/getWeekYear}). + * + * 6. Specific non-location timezones are currently unavailable in `date-fns`, + * so right now these tokens fall back to GMT timezones. + * + * 7. These patterns are not in the Unicode Technical Standard #35: + * - `i`: ISO day of week + * - `I`: ISO week of year + * - `R`: ISO week-numbering year + * - `t`: seconds timestamp + * - `T`: milliseconds timestamp + * - `o`: ordinal number modifier + * - `P`: long localized date + * - `p`: long localized time + * + * 8. `YY` and `YYYY` tokens represent week-numbering years but they are often confused with years. + * You should enable `options.useAdditionalWeekYearTokens` to use them. See: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md + * + * 9. `D` and `DD` tokens represent days of the year but they are often confused with days of the month. + * You should enable `options.useAdditionalDayOfYearTokens` to use them. See: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md + * + * @param {Date|Number} date - the original date + * @param {String} format - the string of tokens + * @param {Object} [options] - an object with options. + * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale} + * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday) + * @param {Number} [options.firstWeekContainsDate=1] - the day of January, which is + * @param {Boolean} [options.useAdditionalWeekYearTokens=false] - if true, allows usage of the week-numbering year tokens `YY` and `YYYY`; + * see: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md + * @param {Boolean} [options.useAdditionalDayOfYearTokens=false] - if true, allows usage of the day of year tokens `D` and `DD`; + * see: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md + * @returns {String} the formatted date string + * @throws {TypeError} 2 arguments required + * @throws {RangeError} `date` must not be Invalid Date + * @throws {RangeError} `options.locale` must contain `localize` property + * @throws {RangeError} `options.locale` must contain `formatLong` property + * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6 + * @throws {RangeError} `options.firstWeekContainsDate` must be between 1 and 7 + * @throws {RangeError} use `yyyy` instead of `YYYY` for formatting years using [format provided] to the input [input provided]; see: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md + * @throws {RangeError} use `yy` instead of `YY` for formatting years using [format provided] to the input [input provided]; see: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md + * @throws {RangeError} use `d` instead of `D` for formatting days of the month using [format provided] to the input [input provided]; see: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md + * @throws {RangeError} use `dd` instead of `DD` for formatting days of the month using [format provided] to the input [input provided]; see: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md + * @throws {RangeError} format string contains an unescaped latin alphabet character + * + * @example + * // Represent 11 February 2014 in middle-endian format: + * const result = format(new Date(2014, 1, 11), 'MM/dd/yyyy') + * //=> '02/11/2014' + * + * @example + * // Represent 2 July 2014 in Esperanto: + * import { eoLocale } from 'date-fns/locale/eo' + * const result = format(new Date(2014, 6, 2), "do 'de' MMMM yyyy", { + * locale: eoLocale + * }) + * //=> '2-a de julio 2014' + * + * @example + * // Escape string by single quote characters: + * const result = format(new Date(2014, 6, 2, 15), "h 'o''clock'") + * //=> "3 o'clock" + */ - // Reset trie node. - nodeIdx = 0; seqStart = i+1; - } +function format(dirtyDate, dirtyFormatStr, options) { + var _ref, _options$locale, _ref2, _ref3, _ref4, _options$firstWeekCon, _options$locale2, _options$locale2$opti, _defaultOptions$local, _defaultOptions$local2, _ref5, _ref6, _ref7, _options$weekStartsOn, _options$locale3, _options$locale3$opti, _defaultOptions$local3, _defaultOptions$local4; + (0, _index9.default)(2, arguments); + var formatStr = String(dirtyFormatStr); + var defaultOptions = (0, _index10.getDefaultOptions)(); + var locale = (_ref = (_options$locale = options === null || options === void 0 ? void 0 : options.locale) !== null && _options$locale !== void 0 ? _options$locale : defaultOptions.locale) !== null && _ref !== void 0 ? _ref : _index11.default; + var firstWeekContainsDate = (0, _index8.default)((_ref2 = (_ref3 = (_ref4 = (_options$firstWeekCon = options === null || options === void 0 ? void 0 : options.firstWeekContainsDate) !== null && _options$firstWeekCon !== void 0 ? _options$firstWeekCon : options === null || options === void 0 ? void 0 : (_options$locale2 = options.locale) === null || _options$locale2 === void 0 ? void 0 : (_options$locale2$opti = _options$locale2.options) === null || _options$locale2$opti === void 0 ? void 0 : _options$locale2$opti.firstWeekContainsDate) !== null && _ref4 !== void 0 ? _ref4 : defaultOptions.firstWeekContainsDate) !== null && _ref3 !== void 0 ? _ref3 : (_defaultOptions$local = defaultOptions.locale) === null || _defaultOptions$local === void 0 ? void 0 : (_defaultOptions$local2 = _defaultOptions$local.options) === null || _defaultOptions$local2 === void 0 ? void 0 : _defaultOptions$local2.firstWeekContainsDate) !== null && _ref2 !== void 0 ? _ref2 : 1); + + // Test if weekStartsOn is between 1 and 7 _and_ is not NaN + if (!(firstWeekContainsDate >= 1 && firstWeekContainsDate <= 7)) { + throw new RangeError('firstWeekContainsDate must be between 1 and 7 inclusively'); + } + var weekStartsOn = (0, _index8.default)((_ref5 = (_ref6 = (_ref7 = (_options$weekStartsOn = options === null || options === void 0 ? void 0 : options.weekStartsOn) !== null && _options$weekStartsOn !== void 0 ? _options$weekStartsOn : options === null || options === void 0 ? void 0 : (_options$locale3 = options.locale) === null || _options$locale3 === void 0 ? void 0 : (_options$locale3$opti = _options$locale3.options) === null || _options$locale3$opti === void 0 ? void 0 : _options$locale3$opti.weekStartsOn) !== null && _ref7 !== void 0 ? _ref7 : defaultOptions.weekStartsOn) !== null && _ref6 !== void 0 ? _ref6 : (_defaultOptions$local3 = defaultOptions.locale) === null || _defaultOptions$local3 === void 0 ? void 0 : (_defaultOptions$local4 = _defaultOptions$local3.options) === null || _defaultOptions$local4 === void 0 ? void 0 : _defaultOptions$local4.weekStartsOn) !== null && _ref5 !== void 0 ? _ref5 : 0); - this.nodeIdx = nodeIdx; - this.prevBytes = (seqStart >= 0) - ? Array.prototype.slice.call(buf, seqStart) - : prevBytes.slice(seqStart + prevOffset).concat(Array.prototype.slice.call(buf)); + // Test if weekStartsOn is between 0 and 6 _and_ is not NaN + if (!(weekStartsOn >= 0 && weekStartsOn <= 6)) { + throw new RangeError('weekStartsOn must be between 0 and 6 inclusively'); + } + if (!locale.localize) { + throw new RangeError('locale must contain localize property'); + } + if (!locale.formatLong) { + throw new RangeError('locale must contain formatLong property'); + } + var originalDate = (0, _index3.default)(dirtyDate); + if (!(0, _index.default)(originalDate)) { + throw new RangeError('Invalid time value'); + } - return newBuf.slice(0, j).toString('ucs2'); + // Convert the date in system timezone to the same date in UTC+00:00 timezone. + // This ensures that when UTC functions will be implemented, locales will be compatible with them. + // See an issue about UTC functions: https://github.com/date-fns/date-fns/issues/376 + var timezoneOffset = (0, _index6.default)(originalDate); + var utcDate = (0, _index2.default)(originalDate, timezoneOffset); + var formatterOptions = { + firstWeekContainsDate: firstWeekContainsDate, + weekStartsOn: weekStartsOn, + locale: locale, + _originalDate: originalDate + }; + var result = formatStr.match(longFormattingTokensRegExp).map(function (substring) { + var firstCharacter = substring[0]; + if (firstCharacter === 'p' || firstCharacter === 'P') { + var longFormatter = _index5.default[firstCharacter]; + return longFormatter(substring, locale.formatLong); + } + return substring; + }).join('').match(formattingTokensRegExp).map(function (substring) { + // Replace two single quote characters with one single quote character + if (substring === "''") { + return "'"; + } + var firstCharacter = substring[0]; + if (firstCharacter === "'") { + return cleanEscapedString(substring); + } + var formatter = _index4.default[firstCharacter]; + if (formatter) { + if (!(options !== null && options !== void 0 && options.useAdditionalWeekYearTokens) && (0, _index7.isProtectedWeekYearToken)(substring)) { + (0, _index7.throwProtectedError)(substring, dirtyFormatStr, String(dirtyDate)); + } + if (!(options !== null && options !== void 0 && options.useAdditionalDayOfYearTokens) && (0, _index7.isProtectedDayOfYearToken)(substring)) { + (0, _index7.throwProtectedError)(substring, dirtyFormatStr, String(dirtyDate)); + } + return formatter(utcDate, substring, locale.localize, formatterOptions); + } + if (firstCharacter.match(unescapedLatinCharacterRegExp)) { + throw new RangeError('Format string contains an unescaped latin alphabet character `' + firstCharacter + '`'); + } + return substring; + }).join(''); + return result; +} +function cleanEscapedString(input) { + var matched = input.match(escapedStringRegExp); + if (!matched) { + return input; + } + return matched[1].replace(doubleQuoteRegExp, "'"); } +module.exports = exports.default; -DBCSDecoder.prototype.end = function() { - var ret = ''; +/***/ }), - // Try to parse all remaining chars. - while (this.prevBytes.length > 0) { - // Skip 1 character in the buffer. - ret += this.defaultCharUnicode; - var bytesArr = this.prevBytes.slice(1); +/***/ 6801: +/***/ ((module, exports, __nccwpck_require__) => { - // Parse remaining as usual. - this.prevBytes = []; - this.nodeIdx = 0; - if (bytesArr.length > 0) - ret += this.write(bytesArr); - } +"use strict"; - this.prevBytes = []; - this.nodeIdx = 0; - return ret; + +var _interopRequireDefault = (__nccwpck_require__(3286)["default"]); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = isDate; +var _typeof2 = _interopRequireDefault(__nccwpck_require__(5605)); +var _index = _interopRequireDefault(__nccwpck_require__(2063)); +/** + * @name isDate + * @category Common Helpers + * @summary Is the given value a date? + * + * @description + * Returns true if the given value is an instance of Date. The function works for dates transferred across iframes. + * + * @param {*} value - the value to check + * @returns {boolean} true if the given value is a date + * @throws {TypeError} 1 arguments required + * + * @example + * // For a valid date: + * const result = isDate(new Date()) + * //=> true + * + * @example + * // For an invalid date: + * const result = isDate(new Date(NaN)) + * //=> true + * + * @example + * // For some value: + * const result = isDate('2014-02-31') + * //=> false + * + * @example + * // For an object: + * const result = isDate({}) + * //=> false + */ +function isDate(value) { + (0, _index.default)(1, arguments); + return value instanceof Date || (0, _typeof2.default)(value) === 'object' && Object.prototype.toString.call(value) === '[object Date]'; } +module.exports = exports.default; -// Binary search for GB18030. Returns largest i such that table[i] <= val. -function findIdx(table, val) { - if (table[0] > val) - return -1; +/***/ }), - var l = 0, r = table.length; - while (l < r-1) { // always table[l] <= val < table[r] - var mid = l + ((r-l+1) >> 1); - if (table[mid] <= val) - l = mid; - else - r = mid; - } - return l; -} +/***/ 9920: +/***/ ((module, exports, __nccwpck_require__) => { + +"use strict"; +var _interopRequireDefault = (__nccwpck_require__(3286)["default"]); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = isValid; +var _index = _interopRequireDefault(__nccwpck_require__(6801)); +var _index2 = _interopRequireDefault(__nccwpck_require__(6477)); +var _index3 = _interopRequireDefault(__nccwpck_require__(2063)); +/** + * @name isValid + * @category Common Helpers + * @summary Is the given date valid? + * + * @description + * Returns false if argument is Invalid Date and true otherwise. + * Argument is converted to Date using `toDate`. See [toDate]{@link https://date-fns.org/docs/toDate} + * Invalid Date is a Date, whose time value is NaN. + * + * Time value of Date: http://es5.github.io/#x15.9.1.1 + * + * @param {*} date - the date to check + * @returns {Boolean} the date is valid + * @throws {TypeError} 1 argument required + * + * @example + * // For the valid date: + * const result = isValid(new Date(2014, 1, 31)) + * //=> true + * + * @example + * // For the value, convertable into a date: + * const result = isValid(1393804800000) + * //=> true + * + * @example + * // For the invalid date: + * const result = isValid(new Date('')) + * //=> false + */ +function isValid(dirtyDate) { + (0, _index3.default)(1, arguments); + if (!(0, _index.default)(dirtyDate) && typeof dirtyDate !== 'number') { + return false; + } + var date = (0, _index2.default)(dirtyDate); + return !isNaN(Number(date)); +} +module.exports = exports.default; /***/ }), -/***/ 1386: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 1244: +/***/ ((module, exports) => { "use strict"; -// Description of supported double byte encodings and aliases. -// Tables are not require()-d until they are needed to speed up library load. -// require()-s are direct to support Browserify. +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = buildFormatLongFn; +function buildFormatLongFn(args) { + return function () { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + // TODO: Remove String() + var width = options.width ? String(options.width) : args.defaultWidth; + var format = args.formats[width] || args.formats[args.defaultWidth]; + return format; + }; +} +module.exports = exports.default; -module.exports = { - - // == Japanese/ShiftJIS ==================================================== - // All japanese encodings are based on JIS X set of standards: - // JIS X 0201 - Single-byte encoding of ASCII + ¥ + Kana chars at 0xA1-0xDF. - // JIS X 0208 - Main set of 6879 characters, placed in 94x94 plane, to be encoded by 2 bytes. - // Has several variations in 1978, 1983, 1990 and 1997. - // JIS X 0212 - Supplementary plane of 6067 chars in 94x94 plane. 1990. Effectively dead. - // JIS X 0213 - Extension and modern replacement of 0208 and 0212. Total chars: 11233. - // 2 planes, first is superset of 0208, second - revised 0212. - // Introduced in 2000, revised 2004. Some characters are in Unicode Plane 2 (0x2xxxx) - - // Byte encodings are: - // * Shift_JIS: Compatible with 0201, uses not defined chars in top half as lead bytes for double-byte - // encoding of 0208. Lead byte ranges: 0x81-0x9F, 0xE0-0xEF; Trail byte ranges: 0x40-0x7E, 0x80-0x9E, 0x9F-0xFC. - // Windows CP932 is a superset of Shift_JIS. Some companies added more chars, notably KDDI. - // * EUC-JP: Up to 3 bytes per character. Used mostly on *nixes. - // 0x00-0x7F - lower part of 0201 - // 0x8E, 0xA1-0xDF - upper part of 0201 - // (0xA1-0xFE)x2 - 0208 plane (94x94). - // 0x8F, (0xA1-0xFE)x2 - 0212 plane (94x94). - // * JIS X 208: 7-bit, direct encoding of 0208. Byte ranges: 0x21-0x7E (94 values). Uncommon. - // Used as-is in ISO2022 family. - // * ISO2022-JP: Stateful encoding, with escape sequences to switch between ASCII, - // 0201-1976 Roman, 0208-1978, 0208-1983. - // * ISO2022-JP-1: Adds esc seq for 0212-1990. - // * ISO2022-JP-2: Adds esc seq for GB2313-1980, KSX1001-1992, ISO8859-1, ISO8859-7. - // * ISO2022-JP-3: Adds esc seq for 0201-1976 Kana set, 0213-2000 Planes 1, 2. - // * ISO2022-JP-2004: Adds 0213-2004 Plane 1. - // - // After JIS X 0213 appeared, Shift_JIS-2004, EUC-JISX0213 and ISO2022-JP-2004 followed, with just changing the planes. - // - // Overall, it seems that it's a mess :( http://www8.plala.or.jp/tkubota1/unicode-symbols-map2.html +/***/ }), - 'shiftjis': { - type: '_dbcs', - table: function() { return __nccwpck_require__(7014) }, - encodeAdd: {'\u00a5': 0x5C, '\u203E': 0x7E}, - encodeSkipVals: [{from: 0xED40, to: 0xF940}], - }, - 'csshiftjis': 'shiftjis', - 'mskanji': 'shiftjis', - 'sjis': 'shiftjis', - 'windows31j': 'shiftjis', - 'ms31j': 'shiftjis', - 'xsjis': 'shiftjis', - 'windows932': 'shiftjis', - 'ms932': 'shiftjis', - '932': 'shiftjis', - 'cp932': 'shiftjis', +/***/ 3647: +/***/ ((module, exports) => { - 'eucjp': { - type: '_dbcs', - table: function() { return __nccwpck_require__(1532) }, - encodeAdd: {'\u00a5': 0x5C, '\u203E': 0x7E}, - }, +"use strict"; - // TODO: KDDI extension to Shift_JIS - // TODO: IBM CCSID 942 = CP932, but F0-F9 custom chars and other char changes. - // TODO: IBM CCSID 943 = Shift_JIS = CP932 with original Shift_JIS lower 128 chars. +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = buildLocalizeFn; +function buildLocalizeFn(args) { + return function (dirtyIndex, options) { + var context = options !== null && options !== void 0 && options.context ? String(options.context) : 'standalone'; + var valuesArray; + if (context === 'formatting' && args.formattingValues) { + var defaultWidth = args.defaultFormattingWidth || args.defaultWidth; + var width = options !== null && options !== void 0 && options.width ? String(options.width) : defaultWidth; + valuesArray = args.formattingValues[width] || args.formattingValues[defaultWidth]; + } else { + var _defaultWidth = args.defaultWidth; + var _width = options !== null && options !== void 0 && options.width ? String(options.width) : args.defaultWidth; + valuesArray = args.values[_width] || args.values[_defaultWidth]; + } + var index = args.argumentCallback ? args.argumentCallback(dirtyIndex) : dirtyIndex; + // @ts-ignore: For some reason TypeScript just don't want to match it, no matter how hard we try. I challenge you to try to remove it! + return valuesArray[index]; + }; +} +module.exports = exports.default; - // == Chinese/GBK ========================================================== - // http://en.wikipedia.org/wiki/GBK - // We mostly implement W3C recommendation: https://www.w3.org/TR/encoding/#gbk-encoder +/***/ }), - // Oldest GB2312 (1981, ~7600 chars) is a subset of CP936 - 'gb2312': 'cp936', - 'gb231280': 'cp936', - 'gb23121980': 'cp936', - 'csgb2312': 'cp936', - 'csiso58gb231280': 'cp936', - 'euccn': 'cp936', +/***/ 4029: +/***/ ((module, exports) => { - // Microsoft's CP936 is a subset and approximation of GBK. - 'windows936': 'cp936', - 'ms936': 'cp936', - '936': 'cp936', - 'cp936': { - type: '_dbcs', - table: function() { return __nccwpck_require__(3336) }, - }, +"use strict"; - // GBK (~22000 chars) is an extension of CP936 that added user-mapped chars and some other. - 'gbk': { - type: '_dbcs', - table: function() { return (__nccwpck_require__(3336).concat)(__nccwpck_require__(4346)) }, - }, - 'xgbk': 'gbk', - 'isoir58': 'gbk', - // GB18030 is an algorithmic extension of GBK. - // Main source: https://www.w3.org/TR/encoding/#gbk-encoder - // http://icu-project.org/docs/papers/gb18030.html - // http://source.icu-project.org/repos/icu/data/trunk/charset/data/xml/gb-18030-2000.xml - // http://www.khngai.com/chinese/charmap/tblgbk.php?page=0 - 'gb18030': { - type: '_dbcs', - table: function() { return (__nccwpck_require__(3336).concat)(__nccwpck_require__(4346)) }, - gb18030: function() { return __nccwpck_require__(6258) }, - encodeSkipVals: [0x80], - encodeAdd: {'€': 0xA2E3}, - }, +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = buildMatchFn; +function buildMatchFn(args) { + return function (string) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var width = options.width; + var matchPattern = width && args.matchPatterns[width] || args.matchPatterns[args.defaultMatchWidth]; + var matchResult = string.match(matchPattern); + if (!matchResult) { + return null; + } + var matchedString = matchResult[0]; + var parsePatterns = width && args.parsePatterns[width] || args.parsePatterns[args.defaultParseWidth]; + var key = Array.isArray(parsePatterns) ? findIndex(parsePatterns, function (pattern) { + return pattern.test(matchedString); + }) : findKey(parsePatterns, function (pattern) { + return pattern.test(matchedString); + }); + var value; + value = args.valueCallback ? args.valueCallback(key) : key; + value = options.valueCallback ? options.valueCallback(value) : value; + var rest = string.slice(matchedString.length); + return { + value: value, + rest: rest + }; + }; +} +function findKey(object, predicate) { + for (var key in object) { + if (object.hasOwnProperty(key) && predicate(object[key])) { + return key; + } + } + return undefined; +} +function findIndex(array, predicate) { + for (var key = 0; key < array.length; key++) { + if (predicate(array[key])) { + return key; + } + } + return undefined; +} +module.exports = exports.default; - 'chinese': 'gb18030', +/***/ }), +/***/ 3364: +/***/ ((module, exports) => { - // == Korean =============================================================== - // EUC-KR, KS_C_5601 and KS X 1001 are exactly the same. - 'windows949': 'cp949', - 'ms949': 'cp949', - '949': 'cp949', - 'cp949': { - type: '_dbcs', - table: function() { return __nccwpck_require__(7348) }, - }, +"use strict"; - 'cseuckr': 'cp949', - 'csksc56011987': 'cp949', - 'euckr': 'cp949', - 'isoir149': 'cp949', - 'korean': 'cp949', - 'ksc56011987': 'cp949', - 'ksc56011989': 'cp949', - 'ksc5601': 'cp949', +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = buildMatchPatternFn; +function buildMatchPatternFn(args) { + return function (string) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var matchResult = string.match(args.matchPattern); + if (!matchResult) return null; + var matchedString = matchResult[0]; + var parseResult = string.match(args.parsePattern); + if (!parseResult) return null; + var value = args.valueCallback ? args.valueCallback(parseResult[0]) : parseResult[0]; + value = options.valueCallback ? options.valueCallback(value) : value; + var rest = string.slice(matchedString.length); + return { + value: value, + rest: rest + }; + }; +} +module.exports = exports.default; - // == Big5/Taiwan/Hong Kong ================================================ - // There are lots of tables for Big5 and cp950. Please see the following links for history: - // http://moztw.org/docs/big5/ http://www.haible.de/bruno/charsets/conversion-tables/Big5.html - // Variations, in roughly number of defined chars: - // * Windows CP 950: Microsoft variant of Big5. Canonical: http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP950.TXT - // * Windows CP 951: Microsoft variant of Big5-HKSCS-2001. Seems to be never public. http://me.abelcheung.org/articles/research/what-is-cp951/ - // * Big5-2003 (Taiwan standard) almost superset of cp950. - // * Unicode-at-on (UAO) / Mozilla 1.8. Falling out of use on the Web. Not supported by other browsers. - // * Big5-HKSCS (-2001, -2004, -2008). Hong Kong standard. - // many unicode code points moved from PUA to Supplementary plane (U+2XXXX) over the years. - // Plus, it has 4 combining sequences. - // Seems that Mozilla refused to support it for 10 yrs. https://bugzilla.mozilla.org/show_bug.cgi?id=162431 https://bugzilla.mozilla.org/show_bug.cgi?id=310299 - // because big5-hkscs is the only encoding to include astral characters in non-algorithmic way. - // Implementations are not consistent within browsers; sometimes labeled as just big5. - // MS Internet Explorer switches from big5 to big5-hkscs when a patch applied. - // Great discussion & recap of what's going on https://bugzilla.mozilla.org/show_bug.cgi?id=912470#c31 - // In the encoder, it might make sense to support encoding old PUA mappings to Big5 bytes seq-s. - // Official spec: http://www.ogcio.gov.hk/en/business/tech_promotion/ccli/terms/doc/2003cmp_2008.txt - // http://www.ogcio.gov.hk/tc/business/tech_promotion/ccli/terms/doc/hkscs-2008-big5-iso.txt - // - // Current understanding of how to deal with Big5(-HKSCS) is in the Encoding Standard, http://encoding.spec.whatwg.org/#big5-encoder - // Unicode mapping (http://www.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/OTHER/BIG5.TXT) is said to be wrong. +/***/ }), - 'windows950': 'cp950', - 'ms950': 'cp950', - '950': 'cp950', - 'cp950': { - type: '_dbcs', - table: function() { return __nccwpck_require__(4284) }, - }, +/***/ 4846: +/***/ ((module, exports) => { - // Big5 has many variations and is an extension of cp950. We use Encoding Standard's as a consensus. - 'big5': 'big5hkscs', - 'big5hkscs': { - type: '_dbcs', - table: function() { return (__nccwpck_require__(4284).concat)(__nccwpck_require__(3480)) }, - encodeSkipVals: [ - // Although Encoding Standard says we should avoid encoding to HKSCS area (See Step 1 of - // https://encoding.spec.whatwg.org/#index-big5-pointer), we still do it to increase compatibility with ICU. - // But if a single unicode point can be encoded both as HKSCS and regular Big5, we prefer the latter. - 0x8e69, 0x8e6f, 0x8e7e, 0x8eab, 0x8eb4, 0x8ecd, 0x8ed0, 0x8f57, 0x8f69, 0x8f6e, 0x8fcb, 0x8ffe, - 0x906d, 0x907a, 0x90c4, 0x90dc, 0x90f1, 0x91bf, 0x92af, 0x92b0, 0x92b1, 0x92b2, 0x92d1, 0x9447, 0x94ca, - 0x95d9, 0x96fc, 0x9975, 0x9b76, 0x9b78, 0x9b7b, 0x9bc6, 0x9bde, 0x9bec, 0x9bf6, 0x9c42, 0x9c53, 0x9c62, - 0x9c68, 0x9c6b, 0x9c77, 0x9cbc, 0x9cbd, 0x9cd0, 0x9d57, 0x9d5a, 0x9dc4, 0x9def, 0x9dfb, 0x9ea9, 0x9eef, - 0x9efd, 0x9f60, 0x9fcb, 0xa077, 0xa0dc, 0xa0df, 0x8fcc, 0x92c8, 0x9644, 0x96ed, +"use strict"; - // Step 2 of https://encoding.spec.whatwg.org/#index-big5-pointer: Use last pointer for U+2550, U+255E, U+2561, U+256A, U+5341, or U+5345 - 0xa2a4, 0xa2a5, 0xa2a7, 0xa2a6, 0xa2cc, 0xa2ce, - ], - }, - 'cnbig5': 'big5hkscs', - 'csbig5': 'big5hkscs', - 'xxbig5': 'big5hkscs', +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var formatDistanceLocale = { + lessThanXSeconds: { + one: 'less than a second', + other: 'less than {{count}} seconds' + }, + xSeconds: { + one: '1 second', + other: '{{count}} seconds' + }, + halfAMinute: 'half a minute', + lessThanXMinutes: { + one: 'less than a minute', + other: 'less than {{count}} minutes' + }, + xMinutes: { + one: '1 minute', + other: '{{count}} minutes' + }, + aboutXHours: { + one: 'about 1 hour', + other: 'about {{count}} hours' + }, + xHours: { + one: '1 hour', + other: '{{count}} hours' + }, + xDays: { + one: '1 day', + other: '{{count}} days' + }, + aboutXWeeks: { + one: 'about 1 week', + other: 'about {{count}} weeks' + }, + xWeeks: { + one: '1 week', + other: '{{count}} weeks' + }, + aboutXMonths: { + one: 'about 1 month', + other: 'about {{count}} months' + }, + xMonths: { + one: '1 month', + other: '{{count}} months' + }, + aboutXYears: { + one: 'about 1 year', + other: 'about {{count}} years' + }, + xYears: { + one: '1 year', + other: '{{count}} years' + }, + overXYears: { + one: 'over 1 year', + other: 'over {{count}} years' + }, + almostXYears: { + one: 'almost 1 year', + other: 'almost {{count}} years' + } }; - +var formatDistance = function formatDistance(token, count, options) { + var result; + var tokenValue = formatDistanceLocale[token]; + if (typeof tokenValue === 'string') { + result = tokenValue; + } else if (count === 1) { + result = tokenValue.one; + } else { + result = tokenValue.other.replace('{{count}}', count.toString()); + } + if (options !== null && options !== void 0 && options.addSuffix) { + if (options.comparison && options.comparison > 0) { + return 'in ' + result; + } else { + return result + ' ago'; + } + } + return result; +}; +var _default = formatDistance; +exports["default"] = _default; +module.exports = exports.default; /***/ }), -/***/ 2733: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +/***/ 368: +/***/ ((module, exports, __nccwpck_require__) => { "use strict"; -// Update this array if you add/rename/remove files in this directory. -// We support Browserify by skipping automatic module discovery and requiring modules directly. -var modules = [ - __nccwpck_require__(2376), - __nccwpck_require__(9557), - __nccwpck_require__(1155), - __nccwpck_require__(1644), - __nccwpck_require__(373), - __nccwpck_require__(1080), - __nccwpck_require__(1012), - __nccwpck_require__(9695), - __nccwpck_require__(1386), -]; +var _interopRequireDefault = (__nccwpck_require__(3286)["default"]); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _index = _interopRequireDefault(__nccwpck_require__(1244)); +var dateFormats = { + full: 'EEEE, MMMM do, y', + long: 'MMMM do, y', + medium: 'MMM d, y', + short: 'MM/dd/yyyy' +}; +var timeFormats = { + full: 'h:mm:ss a zzzz', + long: 'h:mm:ss a z', + medium: 'h:mm:ss a', + short: 'h:mm a' +}; +var dateTimeFormats = { + full: "{{date}} 'at' {{time}}", + long: "{{date}} 'at' {{time}}", + medium: '{{date}}, {{time}}', + short: '{{date}}, {{time}}' +}; +var formatLong = { + date: (0, _index.default)({ + formats: dateFormats, + defaultWidth: 'full' + }), + time: (0, _index.default)({ + formats: timeFormats, + defaultWidth: 'full' + }), + dateTime: (0, _index.default)({ + formats: dateTimeFormats, + defaultWidth: 'full' + }) +}; +var _default = formatLong; +exports["default"] = _default; +module.exports = exports.default; -// Put all encoding/alias/codec definitions to single object and export it. -for (var i = 0; i < modules.length; i++) { - var module = modules[i]; - for (var enc in module) - if (Object.prototype.hasOwnProperty.call(module, enc)) - exports[enc] = module[enc]; -} +/***/ }), +/***/ 2430: +/***/ ((module, exports) => { -/***/ }), +"use strict"; -/***/ 2376: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var formatRelativeLocale = { + lastWeek: "'last' eeee 'at' p", + yesterday: "'yesterday at' p", + today: "'today at' p", + tomorrow: "'tomorrow at' p", + nextWeek: "eeee 'at' p", + other: 'P' +}; +var formatRelative = function formatRelative(token, _date, _baseDate, _options) { + return formatRelativeLocale[token]; +}; +var _default = formatRelative; +exports["default"] = _default; +module.exports = exports.default; + +/***/ }), + +/***/ 5474: +/***/ ((module, exports, __nccwpck_require__) => { "use strict"; -var Buffer = (__nccwpck_require__(5118).Buffer); -// Export Node.js internal encodings. +var _interopRequireDefault = (__nccwpck_require__(3286)["default"]); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _index = _interopRequireDefault(__nccwpck_require__(3647)); +var eraValues = { + narrow: ['B', 'A'], + abbreviated: ['BC', 'AD'], + wide: ['Before Christ', 'Anno Domini'] +}; +var quarterValues = { + narrow: ['1', '2', '3', '4'], + abbreviated: ['Q1', 'Q2', 'Q3', 'Q4'], + wide: ['1st quarter', '2nd quarter', '3rd quarter', '4th quarter'] +}; -module.exports = { - // Encodings - utf8: { type: "_internal", bomAware: true}, - cesu8: { type: "_internal", bomAware: true}, - unicode11utf8: "utf8", +// Note: in English, the names of days of the week and months are capitalized. +// If you are making a new locale based on this one, check if the same is true for the language you're working on. +// Generally, formatted dates should look like they are in the middle of a sentence, +// e.g. in Spanish language the weekdays and months should be in the lowercase. +var monthValues = { + narrow: ['J', 'F', 'M', 'A', 'M', 'J', 'J', 'A', 'S', 'O', 'N', 'D'], + abbreviated: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], + wide: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'] +}; +var dayValues = { + narrow: ['S', 'M', 'T', 'W', 'T', 'F', 'S'], + short: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'], + abbreviated: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], + wide: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'] +}; +var dayPeriodValues = { + narrow: { + am: 'a', + pm: 'p', + midnight: 'mi', + noon: 'n', + morning: 'morning', + afternoon: 'afternoon', + evening: 'evening', + night: 'night' + }, + abbreviated: { + am: 'AM', + pm: 'PM', + midnight: 'midnight', + noon: 'noon', + morning: 'morning', + afternoon: 'afternoon', + evening: 'evening', + night: 'night' + }, + wide: { + am: 'a.m.', + pm: 'p.m.', + midnight: 'midnight', + noon: 'noon', + morning: 'morning', + afternoon: 'afternoon', + evening: 'evening', + night: 'night' + } +}; +var formattingDayPeriodValues = { + narrow: { + am: 'a', + pm: 'p', + midnight: 'mi', + noon: 'n', + morning: 'in the morning', + afternoon: 'in the afternoon', + evening: 'in the evening', + night: 'at night' + }, + abbreviated: { + am: 'AM', + pm: 'PM', + midnight: 'midnight', + noon: 'noon', + morning: 'in the morning', + afternoon: 'in the afternoon', + evening: 'in the evening', + night: 'at night' + }, + wide: { + am: 'a.m.', + pm: 'p.m.', + midnight: 'midnight', + noon: 'noon', + morning: 'in the morning', + afternoon: 'in the afternoon', + evening: 'in the evening', + night: 'at night' + } +}; +var ordinalNumber = function ordinalNumber(dirtyNumber, _options) { + var number = Number(dirtyNumber); + + // If ordinal numbers depend on context, for example, + // if they are different for different grammatical genders, + // use `options.unit`. + // + // `unit` can be 'year', 'quarter', 'month', 'week', 'date', 'dayOfYear', + // 'day', 'hour', 'minute', 'second'. + + var rem100 = number % 100; + if (rem100 > 20 || rem100 < 10) { + switch (rem100 % 10) { + case 1: + return number + 'st'; + case 2: + return number + 'nd'; + case 3: + return number + 'rd'; + } + } + return number + 'th'; +}; +var localize = { + ordinalNumber: ordinalNumber, + era: (0, _index.default)({ + values: eraValues, + defaultWidth: 'wide' + }), + quarter: (0, _index.default)({ + values: quarterValues, + defaultWidth: 'wide', + argumentCallback: function argumentCallback(quarter) { + return quarter - 1; + } + }), + month: (0, _index.default)({ + values: monthValues, + defaultWidth: 'wide' + }), + day: (0, _index.default)({ + values: dayValues, + defaultWidth: 'wide' + }), + dayPeriod: (0, _index.default)({ + values: dayPeriodValues, + defaultWidth: 'wide', + formattingValues: formattingDayPeriodValues, + defaultFormattingWidth: 'wide' + }) +}; +var _default = localize; +exports["default"] = _default; +module.exports = exports.default; - ucs2: { type: "_internal", bomAware: true}, - utf16le: "ucs2", +/***/ }), - binary: { type: "_internal" }, - base64: { type: "_internal" }, - hex: { type: "_internal" }, +/***/ 1338: +/***/ ((module, exports, __nccwpck_require__) => { - // Codec. - _internal: InternalCodec, +"use strict"; + + +var _interopRequireDefault = (__nccwpck_require__(3286)["default"]); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _index = _interopRequireDefault(__nccwpck_require__(4029)); +var _index2 = _interopRequireDefault(__nccwpck_require__(3364)); +var matchOrdinalNumberPattern = /^(\d+)(th|st|nd|rd)?/i; +var parseOrdinalNumberPattern = /\d+/i; +var matchEraPatterns = { + narrow: /^(b|a)/i, + abbreviated: /^(b\.?\s?c\.?|b\.?\s?c\.?\s?e\.?|a\.?\s?d\.?|c\.?\s?e\.?)/i, + wide: /^(before christ|before common era|anno domini|common era)/i +}; +var parseEraPatterns = { + any: [/^b/i, /^(a|c)/i] +}; +var matchQuarterPatterns = { + narrow: /^[1234]/i, + abbreviated: /^q[1234]/i, + wide: /^[1234](th|st|nd|rd)? quarter/i +}; +var parseQuarterPatterns = { + any: [/1/i, /2/i, /3/i, /4/i] +}; +var matchMonthPatterns = { + narrow: /^[jfmasond]/i, + abbreviated: /^(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)/i, + wide: /^(january|february|march|april|may|june|july|august|september|october|november|december)/i +}; +var parseMonthPatterns = { + narrow: [/^j/i, /^f/i, /^m/i, /^a/i, /^m/i, /^j/i, /^j/i, /^a/i, /^s/i, /^o/i, /^n/i, /^d/i], + any: [/^ja/i, /^f/i, /^mar/i, /^ap/i, /^may/i, /^jun/i, /^jul/i, /^au/i, /^s/i, /^o/i, /^n/i, /^d/i] }; +var matchDayPatterns = { + narrow: /^[smtwf]/i, + short: /^(su|mo|tu|we|th|fr|sa)/i, + abbreviated: /^(sun|mon|tue|wed|thu|fri|sat)/i, + wide: /^(sunday|monday|tuesday|wednesday|thursday|friday|saturday)/i +}; +var parseDayPatterns = { + narrow: [/^s/i, /^m/i, /^t/i, /^w/i, /^t/i, /^f/i, /^s/i], + any: [/^su/i, /^m/i, /^tu/i, /^w/i, /^th/i, /^f/i, /^sa/i] +}; +var matchDayPeriodPatterns = { + narrow: /^(a|p|mi|n|(in the|at) (morning|afternoon|evening|night))/i, + any: /^([ap]\.?\s?m\.?|midnight|noon|(in the|at) (morning|afternoon|evening|night))/i +}; +var parseDayPeriodPatterns = { + any: { + am: /^a/i, + pm: /^p/i, + midnight: /^mi/i, + noon: /^no/i, + morning: /morning/i, + afternoon: /afternoon/i, + evening: /evening/i, + night: /night/i + } +}; +var match = { + ordinalNumber: (0, _index2.default)({ + matchPattern: matchOrdinalNumberPattern, + parsePattern: parseOrdinalNumberPattern, + valueCallback: function valueCallback(value) { + return parseInt(value, 10); + } + }), + era: (0, _index.default)({ + matchPatterns: matchEraPatterns, + defaultMatchWidth: 'wide', + parsePatterns: parseEraPatterns, + defaultParseWidth: 'any' + }), + quarter: (0, _index.default)({ + matchPatterns: matchQuarterPatterns, + defaultMatchWidth: 'wide', + parsePatterns: parseQuarterPatterns, + defaultParseWidth: 'any', + valueCallback: function valueCallback(index) { + return index + 1; + } + }), + month: (0, _index.default)({ + matchPatterns: matchMonthPatterns, + defaultMatchWidth: 'wide', + parsePatterns: parseMonthPatterns, + defaultParseWidth: 'any' + }), + day: (0, _index.default)({ + matchPatterns: matchDayPatterns, + defaultMatchWidth: 'wide', + parsePatterns: parseDayPatterns, + defaultParseWidth: 'any' + }), + dayPeriod: (0, _index.default)({ + matchPatterns: matchDayPeriodPatterns, + defaultMatchWidth: 'any', + parsePatterns: parseDayPeriodPatterns, + defaultParseWidth: 'any' + }) +}; +var _default = match; +exports["default"] = _default; +module.exports = exports.default; -//------------------------------------------------------------------------------ +/***/ }), -function InternalCodec(codecOptions, iconv) { - this.enc = codecOptions.encodingName; - this.bomAware = codecOptions.bomAware; +/***/ 1773: +/***/ ((module, exports, __nccwpck_require__) => { - if (this.enc === "base64") - this.encoder = InternalEncoderBase64; - else if (this.enc === "cesu8") { - this.enc = "utf8"; // Use utf8 for decoding. - this.encoder = InternalEncoderCesu8; +"use strict"; - // Add decoder for versions of Node not supporting CESU-8 - if (Buffer.from('eda0bdedb2a9', 'hex').toString() !== '💩') { - this.decoder = InternalDecoderCesu8; - this.defaultCharUnicode = iconv.defaultCharUnicode; - } - } -} -InternalCodec.prototype.encoder = InternalEncoder; -InternalCodec.prototype.decoder = InternalDecoder; +var _interopRequireDefault = (__nccwpck_require__(3286)["default"]); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _index = _interopRequireDefault(__nccwpck_require__(4846)); +var _index2 = _interopRequireDefault(__nccwpck_require__(368)); +var _index3 = _interopRequireDefault(__nccwpck_require__(2430)); +var _index4 = _interopRequireDefault(__nccwpck_require__(5474)); +var _index5 = _interopRequireDefault(__nccwpck_require__(1338)); +/** + * @type {Locale} + * @category Locales + * @summary English locale (United States). + * @language English + * @iso-639-2 eng + * @author Sasha Koss [@kossnocorp]{@link https://github.com/kossnocorp} + * @author Lesha Koss [@leshakoss]{@link https://github.com/leshakoss} + */ +var locale = { + code: 'en-US', + formatDistance: _index.default, + formatLong: _index2.default, + formatRelative: _index3.default, + localize: _index4.default, + match: _index5.default, + options: { + weekStartsOn: 0 /* Sunday */, + firstWeekContainsDate: 1 + } +}; +var _default = locale; +exports["default"] = _default; +module.exports = exports.default; -//------------------------------------------------------------------------------ +/***/ }), -// We use node.js internal decoder. Its signature is the same as ours. -var StringDecoder = (__nccwpck_require__(1576).StringDecoder); +/***/ 7923: +/***/ ((module, exports, __nccwpck_require__) => { -if (!StringDecoder.prototype.end) // Node v0.8 doesn't have this method. - StringDecoder.prototype.end = function() {}; +"use strict"; -function InternalDecoder(options, codec) { - this.decoder = new StringDecoder(codec.enc); +var _interopRequireDefault = (__nccwpck_require__(3286)["default"]); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = subMilliseconds; +var _index = _interopRequireDefault(__nccwpck_require__(524)); +var _index2 = _interopRequireDefault(__nccwpck_require__(2063)); +var _index3 = _interopRequireDefault(__nccwpck_require__(1985)); +/** + * @name subMilliseconds + * @category Millisecond Helpers + * @summary Subtract the specified number of milliseconds from the given date. + * + * @description + * Subtract the specified number of milliseconds from the given date. + * + * @param {Date|Number} date - the date to be changed + * @param {Number} amount - the amount of milliseconds to be subtracted. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`. + * @returns {Date} the new date with the milliseconds subtracted + * @throws {TypeError} 2 arguments required + * + * @example + * // Subtract 750 milliseconds from 10 July 2014 12:45:30.000: + * const result = subMilliseconds(new Date(2014, 6, 10, 12, 45, 30, 0), 750) + * //=> Thu Jul 10 2014 12:45:29.250 + */ +function subMilliseconds(dirtyDate, dirtyAmount) { + (0, _index2.default)(2, arguments); + var amount = (0, _index3.default)(dirtyAmount); + return (0, _index.default)(dirtyDate, -amount); } +module.exports = exports.default; -InternalDecoder.prototype.write = function(buf) { - if (!Buffer.isBuffer(buf)) { - buf = Buffer.from(buf); - } +/***/ }), - return this.decoder.write(buf); -} +/***/ 6477: +/***/ ((module, exports, __nccwpck_require__) => { -InternalDecoder.prototype.end = function() { - return this.decoder.end(); +"use strict"; + + +var _interopRequireDefault = (__nccwpck_require__(3286)["default"]); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = toDate; +var _typeof2 = _interopRequireDefault(__nccwpck_require__(5605)); +var _index = _interopRequireDefault(__nccwpck_require__(2063)); +/** + * @name toDate + * @category Common Helpers + * @summary Convert the given argument to an instance of Date. + * + * @description + * Convert the given argument to an instance of Date. + * + * If the argument is an instance of Date, the function returns its clone. + * + * If the argument is a number, it is treated as a timestamp. + * + * If the argument is none of the above, the function returns Invalid Date. + * + * **Note**: *all* Date arguments passed to any *date-fns* function is processed by `toDate`. + * + * @param {Date|Number} argument - the value to convert + * @returns {Date} the parsed date in the local time zone + * @throws {TypeError} 1 argument required + * + * @example + * // Clone the date: + * const result = toDate(new Date(2014, 1, 11, 11, 30, 30)) + * //=> Tue Feb 11 2014 11:30:30 + * + * @example + * // Convert the timestamp to date: + * const result = toDate(1392098430000) + * //=> Tue Feb 11 2014 11:30:30 + */ +function toDate(argument) { + (0, _index.default)(1, arguments); + var argStr = Object.prototype.toString.call(argument); + + // Clone the date + if (argument instanceof Date || (0, _typeof2.default)(argument) === 'object' && argStr === '[object Date]') { + // Prevent the date to lose the milliseconds when passed to new Date() in IE10 + return new Date(argument.getTime()); + } else if (typeof argument === 'number' || argStr === '[object Number]') { + return new Date(argument); + } else { + if ((typeof argument === 'string' || argStr === '[object String]') && typeof console !== 'undefined') { + // eslint-disable-next-line no-console + console.warn("Starting with v2.0.0-beta.1 date-fns doesn't accept strings as date arguments. Please use `parseISO` to parse strings. See: https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#string-arguments"); + // eslint-disable-next-line no-console + console.warn(new Error().stack); + } + return new Date(NaN); + } } +module.exports = exports.default; +/***/ }), -//------------------------------------------------------------------------------ -// Encoder is mostly trivial +/***/ 8932: +/***/ ((__unused_webpack_module, exports) => { -function InternalEncoder(options, codec) { - this.enc = codec.enc; -} +"use strict"; -InternalEncoder.prototype.write = function(str) { - return Buffer.from(str, this.enc); -} -InternalEncoder.prototype.end = function() { -} +Object.defineProperty(exports, "__esModule", ({ value: true })); +class Deprecation extends Error { + constructor(message) { + super(message); // Maintains proper stack trace (only available on V8) -//------------------------------------------------------------------------------ -// Except base64 encoder, which must keep its state. + /* istanbul ignore next */ -function InternalEncoderBase64(options, codec) { - this.prevStr = ''; -} + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } -InternalEncoderBase64.prototype.write = function(str) { - str = this.prevStr + str; - var completeQuads = str.length - (str.length % 4); - this.prevStr = str.slice(completeQuads); - str = str.slice(0, completeQuads); + this.name = 'Deprecation'; + } - return Buffer.from(str, "base64"); } -InternalEncoderBase64.prototype.end = function() { - return Buffer.from(this.prevStr, "base64"); -} +exports.Deprecation = Deprecation; -//------------------------------------------------------------------------------ -// CESU-8 encoder is also special. +/***/ }), -function InternalEncoderCesu8(options, codec) { -} +/***/ 8685: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -InternalEncoderCesu8.prototype.write = function(str) { - var buf = Buffer.alloc(str.length * 3), bufIdx = 0; - for (var i = 0; i < str.length; i++) { - var charCode = str.charCodeAt(i); - // Naive implementation, but it works because CESU-8 is especially easy - // to convert from UTF-16 (which all JS strings are encoded in). - if (charCode < 0x80) - buf[bufIdx++] = charCode; - else if (charCode < 0x800) { - buf[bufIdx++] = 0xC0 + (charCode >>> 6); - buf[bufIdx++] = 0x80 + (charCode & 0x3f); - } - else { // charCode will always be < 0x10000 in javascript. - buf[bufIdx++] = 0xE0 + (charCode >>> 12); - buf[bufIdx++] = 0x80 + ((charCode >>> 6) & 0x3f); - buf[bufIdx++] = 0x80 + (charCode & 0x3f); - } - } - return buf.slice(0, bufIdx); -} +"use strict"; -InternalEncoderCesu8.prototype.end = function() { -} -//------------------------------------------------------------------------------ -// CESU-8 decoder is not implemented in Node v4.0+ +var iconvLite = __nccwpck_require__(9032); -function InternalDecoderCesu8(options, codec) { - this.acc = 0; - this.contBytes = 0; - this.accBytes = 0; - this.defaultCharUnicode = codec.defaultCharUnicode; -} +// Expose to the world +module.exports.O = convert; -InternalDecoderCesu8.prototype.write = function(buf) { - var acc = this.acc, contBytes = this.contBytes, accBytes = this.accBytes, - res = ''; - for (var i = 0; i < buf.length; i++) { - var curByte = buf[i]; - if ((curByte & 0xC0) !== 0x80) { // Leading byte - if (contBytes > 0) { // Previous code is invalid - res += this.defaultCharUnicode; - contBytes = 0; - } +/** + * Convert encoding of an UTF-8 string or a buffer + * + * @param {String|Buffer} str String to be converted + * @param {String} to Encoding to be converted to + * @param {String} [from='UTF-8'] Encoding to be converted from + * @return {Buffer} Encoded string + */ +function convert(str, to, from) { + from = checkEncoding(from || 'UTF-8'); + to = checkEncoding(to || 'UTF-8'); + str = str || ''; - if (curByte < 0x80) { // Single-byte code - res += String.fromCharCode(curByte); - } else if (curByte < 0xE0) { // Two-byte code - acc = curByte & 0x1F; - contBytes = 1; accBytes = 1; - } else if (curByte < 0xF0) { // Three-byte code - acc = curByte & 0x0F; - contBytes = 2; accBytes = 1; - } else { // Four or more are not supported for CESU-8. - res += this.defaultCharUnicode; - } - } else { // Continuation byte - if (contBytes > 0) { // We're waiting for it. - acc = (acc << 6) | (curByte & 0x3f); - contBytes--; accBytes++; - if (contBytes === 0) { - // Check for overlong encoding, but support Modified UTF-8 (encoding NULL as C0 80) - if (accBytes === 2 && acc < 0x80 && acc > 0) - res += this.defaultCharUnicode; - else if (accBytes === 3 && acc < 0x800) - res += this.defaultCharUnicode; - else - // Actually add character. - res += String.fromCharCode(acc); - } - } else { // Unexpected continuation byte - res += this.defaultCharUnicode; - } + var result; + + if (from !== 'UTF-8' && typeof str === 'string') { + str = Buffer.from(str, 'binary'); + } + + if (from === to) { + if (typeof str === 'string') { + result = Buffer.from(str); + } else { + result = str; + } + } else { + try { + result = convertIconvLite(str, to, from); + } catch (E) { + console.error(E); + result = str; } } - this.acc = acc; this.contBytes = contBytes; this.accBytes = accBytes; - return res; + + if (typeof result === 'string') { + result = Buffer.from(result, 'utf-8'); + } + + return result; } -InternalDecoderCesu8.prototype.end = function() { - var res = 0; - if (this.contBytes > 0) - res += this.defaultCharUnicode; - return res; +/** + * Convert encoding of astring with iconv-lite + * + * @param {String|Buffer} str String to be converted + * @param {String} to Encoding to be converted to + * @param {String} [from='UTF-8'] Encoding to be converted from + * @return {Buffer} Encoded string + */ +function convertIconvLite(str, to, from) { + if (to === 'UTF-8') { + return iconvLite.decode(str, from); + } else if (from === 'UTF-8') { + return iconvLite.encode(str, to); + } else { + return iconvLite.encode(iconvLite.decode(str, from), to); + } +} + +/** + * Converts charset name if needed + * + * @param {String} name Character set + * @return {String} Character set name + */ +function checkEncoding(name) { + return (name || '') + .toString() + .trim() + .replace(/^latin[\-_]?(\d+)$/i, 'ISO-8859-$1') + .replace(/^win(?:dows)?[\-_]?(\d+)$/i, 'WINDOWS-$1') + .replace(/^utf[\-_]?(\d+)$/i, 'UTF-$1') + .replace(/^ks_c_5601\-1987$/i, 'CP949') + .replace(/^us[\-_]?ascii$/i, 'ASCII') + .toUpperCase(); } /***/ }), -/***/ 373: +/***/ 9695: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; var Buffer = (__nccwpck_require__(5118).Buffer); -// Single-byte codec. Needs a 'chars' string parameter that contains 256 or 128 chars that -// correspond to encoded bytes (if 128 - then lower half is ASCII). +// Multibyte codec. In this scheme, a character is represented by 1 or more bytes. +// Our codec supports UTF-16 surrogates, extensions for GB18030 and unicode sequences. +// To save memory and loading time, we read table files only when requested. -exports._sbcs = SBCSCodec; -function SBCSCodec(codecOptions, iconv) { - if (!codecOptions) - throw new Error("SBCS codec is called without the data.") - - // Prepare char buffer for decoding. - if (!codecOptions.chars || (codecOptions.chars.length !== 128 && codecOptions.chars.length !== 256)) - throw new Error("Encoding '"+codecOptions.type+"' has incorrect 'chars' (must be of len 128 or 256)"); - - if (codecOptions.chars.length === 128) { - var asciiString = ""; - for (var i = 0; i < 128; i++) - asciiString += String.fromCharCode(i); - codecOptions.chars = asciiString + codecOptions.chars; - } +exports._dbcs = DBCSCodec; - this.decodeBuf = Buffer.from(codecOptions.chars, 'ucs2'); - - // Encoding buffer. - var encodeBuf = Buffer.alloc(65536, iconv.defaultCharSingleByte.charCodeAt(0)); +var UNASSIGNED = -1, + GB18030_CODE = -2, + SEQ_START = -10, + NODE_START = -1000, + UNASSIGNED_NODE = new Array(0x100), + DEF_CHAR = -1; - for (var i = 0; i < codecOptions.chars.length; i++) - encodeBuf[codecOptions.chars.charCodeAt(i)] = i; +for (var i = 0; i < 0x100; i++) + UNASSIGNED_NODE[i] = UNASSIGNED; - this.encodeBuf = encodeBuf; -} -SBCSCodec.prototype.encoder = SBCSEncoder; -SBCSCodec.prototype.decoder = SBCSDecoder; +// Class DBCSCodec reads and initializes mapping tables. +function DBCSCodec(codecOptions, iconv) { + this.encodingName = codecOptions.encodingName; + if (!codecOptions) + throw new Error("DBCS codec is called without the data.") + if (!codecOptions.table) + throw new Error("Encoding '" + this.encodingName + "' has no data."); + // Load tables. + var mappingTable = codecOptions.table(); -function SBCSEncoder(options, codec) { - this.encodeBuf = codec.encodeBuf; -} -SBCSEncoder.prototype.write = function(str) { - var buf = Buffer.alloc(str.length); - for (var i = 0; i < str.length; i++) - buf[i] = this.encodeBuf[str.charCodeAt(i)]; - - return buf; -} + // Decode tables: MBCS -> Unicode. -SBCSEncoder.prototype.end = function() { -} + // decodeTables is a trie, encoded as an array of arrays of integers. Internal arrays are trie nodes and all have len = 256. + // Trie root is decodeTables[0]. + // Values: >= 0 -> unicode character code. can be > 0xFFFF + // == UNASSIGNED -> unknown/unassigned sequence. + // == GB18030_CODE -> this is the end of a GB18030 4-byte sequence. + // <= NODE_START -> index of the next node in our trie to process next byte. + // <= SEQ_START -> index of the start of a character code sequence, in decodeTableSeq. + this.decodeTables = []; + this.decodeTables[0] = UNASSIGNED_NODE.slice(0); // Create root node. + // Sometimes a MBCS char corresponds to a sequence of unicode chars. We store them as arrays of integers here. + this.decodeTableSeq = []; -function SBCSDecoder(options, codec) { - this.decodeBuf = codec.decodeBuf; -} + // Actual mapping tables consist of chunks. Use them to fill up decode tables. + for (var i = 0; i < mappingTable.length; i++) + this._addDecodeChunk(mappingTable[i]); -SBCSDecoder.prototype.write = function(buf) { - // Strings are immutable in JS -> we use ucs2 buffer to speed up computations. - var decodeBuf = this.decodeBuf; - var newBuf = Buffer.alloc(buf.length*2); - var idx1 = 0, idx2 = 0; - for (var i = 0; i < buf.length; i++) { - idx1 = buf[i]*2; idx2 = i*2; - newBuf[idx2] = decodeBuf[idx1]; - newBuf[idx2+1] = decodeBuf[idx1+1]; - } - return newBuf.toString('ucs2'); -} + // Load & create GB18030 tables when needed. + if (typeof codecOptions.gb18030 === 'function') { + this.gb18030 = codecOptions.gb18030(); // Load GB18030 ranges. -SBCSDecoder.prototype.end = function() { -} + // Add GB18030 common decode nodes. + var commonThirdByteNodeIdx = this.decodeTables.length; + this.decodeTables.push(UNASSIGNED_NODE.slice(0)); + var commonFourthByteNodeIdx = this.decodeTables.length; + this.decodeTables.push(UNASSIGNED_NODE.slice(0)); -/***/ }), + // Fill out the tree + var firstByteNode = this.decodeTables[0]; + for (var i = 0x81; i <= 0xFE; i++) { + var secondByteNode = this.decodeTables[NODE_START - firstByteNode[i]]; + for (var j = 0x30; j <= 0x39; j++) { + if (secondByteNode[j] === UNASSIGNED) { + secondByteNode[j] = NODE_START - commonThirdByteNodeIdx; + } else if (secondByteNode[j] > NODE_START) { + throw new Error("gb18030 decode tables conflict at byte 2"); + } -/***/ 1012: -/***/ ((module) => { + var thirdByteNode = this.decodeTables[NODE_START - secondByteNode[j]]; + for (var k = 0x81; k <= 0xFE; k++) { + if (thirdByteNode[k] === UNASSIGNED) { + thirdByteNode[k] = NODE_START - commonFourthByteNodeIdx; + } else if (thirdByteNode[k] === NODE_START - commonFourthByteNodeIdx) { + continue; + } else if (thirdByteNode[k] > NODE_START) { + throw new Error("gb18030 decode tables conflict at byte 3"); + } -"use strict"; + var fourthByteNode = this.decodeTables[NODE_START - thirdByteNode[k]]; + for (var l = 0x30; l <= 0x39; l++) { + if (fourthByteNode[l] === UNASSIGNED) + fourthByteNode[l] = GB18030_CODE; + } + } + } + } + } + this.defaultCharUnicode = iconv.defaultCharUnicode; -// Generated data for sbcs codec. Don't edit manually. Regenerate using generation/gen-sbcs.js script. -module.exports = { - "437": "cp437", - "737": "cp737", - "775": "cp775", - "850": "cp850", - "852": "cp852", - "855": "cp855", - "856": "cp856", - "857": "cp857", - "858": "cp858", - "860": "cp860", - "861": "cp861", - "862": "cp862", - "863": "cp863", - "864": "cp864", - "865": "cp865", - "866": "cp866", - "869": "cp869", - "874": "windows874", - "922": "cp922", - "1046": "cp1046", - "1124": "cp1124", - "1125": "cp1125", - "1129": "cp1129", - "1133": "cp1133", - "1161": "cp1161", - "1162": "cp1162", - "1163": "cp1163", - "1250": "windows1250", - "1251": "windows1251", - "1252": "windows1252", - "1253": "windows1253", - "1254": "windows1254", - "1255": "windows1255", - "1256": "windows1256", - "1257": "windows1257", - "1258": "windows1258", - "28591": "iso88591", - "28592": "iso88592", - "28593": "iso88593", - "28594": "iso88594", - "28595": "iso88595", - "28596": "iso88596", - "28597": "iso88597", - "28598": "iso88598", - "28599": "iso88599", - "28600": "iso885910", - "28601": "iso885911", - "28603": "iso885913", - "28604": "iso885914", - "28605": "iso885915", - "28606": "iso885916", - "windows874": { - "type": "_sbcs", - "chars": "€����…�����������‘’“”•–—�������� กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู����฿เแโใไๅๆ็่้๊๋์ํ๎๏๐๑๒๓๔๕๖๗๘๙๚๛����" - }, - "win874": "windows874", - "cp874": "windows874", - "windows1250": { - "type": "_sbcs", - "chars": "€�‚�„…†‡�‰Š‹ŚŤŽŹ�‘’“”•–—�™š›śťžź ˇ˘Ł¤Ą¦§¨©Ş«¬­®Ż°±˛ł´µ¶·¸ąş»Ľ˝ľżŔÁÂĂÄĹĆÇČÉĘËĚÍÎĎĐŃŇÓÔŐÖ×ŘŮÚŰÜÝŢßŕáâăäĺćçčéęëěíîďđńňóôőö÷řůúűüýţ˙" - }, - "win1250": "windows1250", - "cp1250": "windows1250", - "windows1251": { - "type": "_sbcs", - "chars": "ЂЃ‚ѓ„…†‡€‰Љ‹ЊЌЋЏђ‘’“”•–—�™љ›њќћџ ЎўЈ¤Ґ¦§Ё©Є«¬­®Ї°±Ііґµ¶·ё№є»јЅѕїАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя" - }, - "win1251": "windows1251", - "cp1251": "windows1251", - "windows1252": { - "type": "_sbcs", - "chars": "€�‚ƒ„…†‡ˆ‰Š‹Œ�Ž��‘’“”•–—˜™š›œ�žŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ" - }, - "win1252": "windows1252", - "cp1252": "windows1252", - "windows1253": { - "type": "_sbcs", - "chars": "€�‚ƒ„…†‡�‰�‹�����‘’“”•–—�™�›���� ΅Ά£¤¥¦§¨©�«¬­®―°±²³΄µ¶·ΈΉΊ»Ό½ΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ�ΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώ�" - }, - "win1253": "windows1253", - "cp1253": "windows1253", - "windows1254": { - "type": "_sbcs", - "chars": "€�‚ƒ„…†‡ˆ‰Š‹Œ����‘’“”•–—˜™š›œ��Ÿ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏĞÑÒÓÔÕÖ×ØÙÚÛÜİŞßàáâãäåæçèéêëìíîïğñòóôõö÷øùúûüışÿ" - }, - "win1254": "windows1254", - "cp1254": "windows1254", - "windows1255": { - "type": "_sbcs", - "chars": "€�‚ƒ„…†‡ˆ‰�‹�����‘’“”•–—˜™�›���� ¡¢£₪¥¦§¨©×«¬­®¯°±²³´µ¶·¸¹÷»¼½¾¿ְֱֲֳִֵֶַָֹֺֻּֽ־ֿ׀ׁׂ׃װױײ׳״�������אבגדהוזחטיךכלםמןנסעףפץצקרשת��‎‏�" - }, - "win1255": "windows1255", - "cp1255": "windows1255", - "windows1256": { - "type": "_sbcs", - "chars": "€پ‚ƒ„…†‡ˆ‰ٹ‹Œچژڈگ‘’“”•–—ک™ڑ›œ‌‍ں ،¢£¤¥¦§¨©ھ«¬­®¯°±²³´µ¶·¸¹؛»¼½¾؟ہءآأؤإئابةتثجحخدذرزسشصض×طظعغـفقكàلâمنهوçèéêëىيîïًٌٍَôُِ÷ّùْûü‎‏ے" - }, - "win1256": "windows1256", - "cp1256": "windows1256", - "windows1257": { - "type": "_sbcs", - "chars": "€�‚�„…†‡�‰�‹�¨ˇ¸�‘’“”•–—�™�›�¯˛� �¢£¤�¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙" - }, - "win1257": "windows1257", - "cp1257": "windows1257", - "windows1258": { - "type": "_sbcs", - "chars": "€�‚ƒ„…†‡ˆ‰�‹Œ����‘’“”•–—˜™�›œ��Ÿ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂĂÄÅÆÇÈÉÊË̀ÍÎÏĐÑ̉ÓÔƠÖ×ØÙÚÛÜỮßàáâăäåæçèéêë́íîïđṇ̃óôơö÷øùúûüư₫ÿ" - }, - "win1258": "windows1258", - "cp1258": "windows1258", - "iso88591": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ" - }, - "cp28591": "iso88591", - "iso88592": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ Ą˘Ł¤ĽŚ§¨ŠŞŤŹ­ŽŻ°ą˛ł´ľśˇ¸šşťź˝žżŔÁÂĂÄĹĆÇČÉĘËĚÍÎĎĐŃŇÓÔŐÖ×ŘŮÚŰÜÝŢßŕáâăäĺćçčéęëěíîďđńňóôőö÷řůúűüýţ˙" - }, - "cp28592": "iso88592", - "iso88593": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ Ħ˘£¤�Ĥ§¨İŞĞĴ­�Ż°ħ²³´µĥ·¸ışğĵ½�żÀÁÂ�ÄĊĈÇÈÉÊËÌÍÎÏ�ÑÒÓÔĠÖ×ĜÙÚÛÜŬŜßàáâ�äċĉçèéêëìíîï�ñòóôġö÷ĝùúûüŭŝ˙" - }, - "cp28593": "iso88593", - "iso88594": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ĄĸŖ¤ĨĻ§¨ŠĒĢŦ­Ž¯°ą˛ŗ´ĩļˇ¸šēģŧŊžŋĀÁÂÃÄÅÆĮČÉĘËĖÍÎĪĐŅŌĶÔÕÖ×ØŲÚÛÜŨŪßāáâãäåæįčéęëėíîīđņōķôõö÷øųúûüũū˙" - }, - "cp28594": "iso88594", - "iso88595": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ЁЂЃЄЅІЇЈЉЊЋЌ­ЎЏАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя№ёђѓєѕіїјљњћќ§ўџ" - }, - "cp28595": "iso88595", - "iso88596": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ���¤�������،­�������������؛���؟�ءآأؤإئابةتثجحخدذرزسشصضطظعغ�����ـفقكلمنهوىيًٌٍَُِّْ�������������" - }, - "cp28596": "iso88596", - "iso88597": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ‘’£€₯¦§¨©ͺ«¬­�―°±²³΄΅Ά·ΈΉΊ»Ό½ΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ�ΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώ�" - }, - "cp28597": "iso88597", - "iso88598": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ �¢£¤¥¦§¨©×«¬­®¯°±²³´µ¶·¸¹÷»¼½¾��������������������������������‗אבגדהוזחטיךכלםמןנסעףפץצקרשת��‎‏�" - }, - "cp28598": "iso88598", - "iso88599": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏĞÑÒÓÔÕÖ×ØÙÚÛÜİŞßàáâãäåæçèéêëìíîïğñòóôõö÷øùúûüışÿ" - }, - "cp28599": "iso88599", - "iso885910": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ĄĒĢĪĨĶ§ĻĐŠŦŽ­ŪŊ°ąēģīĩķ·ļđšŧž―ūŋĀÁÂÃÄÅÆĮČÉĘËĖÍÎÏÐŅŌÓÔÕÖŨØŲÚÛÜÝÞßāáâãäåæįčéęëėíîïðņōóôõöũøųúûüýþĸ" - }, - "cp28600": "iso885910", - "iso885911": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู����฿เแโใไๅๆ็่้๊๋์ํ๎๏๐๑๒๓๔๕๖๗๘๙๚๛����" - }, - "cp28601": "iso885911", - "iso885913": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ”¢£¤„¦§Ø©Ŗ«¬­®Æ°±²³“µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž’" - }, - "cp28603": "iso885913", - "iso885914": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ Ḃḃ£ĊċḊ§Ẁ©ẂḋỲ­®ŸḞḟĠġṀṁ¶ṖẁṗẃṠỳẄẅṡÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏŴÑÒÓÔÕÖṪØÙÚÛÜÝŶßàáâãäåæçèéêëìíîïŵñòóôõöṫøùúûüýŷÿ" - }, - "cp28604": "iso885914", - "iso885915": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£€¥Š§š©ª«¬­®¯°±²³Žµ¶·ž¹º»ŒœŸ¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ" - }, - "cp28605": "iso885915", - "iso885916": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ĄąŁ€„Š§š©Ș«Ź­źŻ°±ČłŽ”¶·žčș»ŒœŸżÀÁÂĂÄĆÆÇÈÉÊËÌÍÎÏĐŃÒÓÔŐÖŚŰÙÚÛÜĘȚßàáâăäćæçèéêëìíîïđńòóôőöśűùúûüęțÿ" - }, - "cp28606": "iso885916", - "cp437": { - "type": "_sbcs", - "chars": "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ " - }, - "ibm437": "cp437", - "csibm437": "cp437", - "cp737": { - "type": "_sbcs", - "chars": "ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρσςτυφχψ░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀ωάέήϊίόύϋώΆΈΉΊΌΎΏ±≥≤ΪΫ÷≈°∙·√ⁿ²■ " - }, - "ibm737": "cp737", - "csibm737": "cp737", - "cp775": { - "type": "_sbcs", - "chars": "ĆüéāäģåćłēŖŗīŹÄÅÉæÆōöĢ¢ŚśÖÜø£ØפĀĪóŻżź”¦©®¬½¼Ł«»░▒▓│┤ĄČĘĖ╣║╗╝ĮŠ┐└┴┬├─┼ŲŪ╚╔╩╦╠═╬Žąčęėįšųūž┘┌█▄▌▐▀ÓßŌŃõÕµńĶķĻļņĒŅ’­±“¾¶§÷„°∙·¹³²■ " - }, - "ibm775": "cp775", - "csibm775": "cp775", - "cp850": { - "type": "_sbcs", - "chars": "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø׃áíóúñѪº¿®¬½¼¡«»░▒▓│┤ÁÂÀ©╣║╗╝¢¥┐└┴┬├─┼ãÃ╚╔╩╦╠═╬¤ðÐÊËÈıÍÎÏ┘┌█▄¦Ì▀ÓßÔÒõÕµþÞÚÛÙýݯ´­±‗¾¶§÷¸°¨·¹³²■ " - }, - "ibm850": "cp850", - "csibm850": "cp850", - "cp852": { - "type": "_sbcs", - "chars": "ÇüéâäůćçłëŐőîŹÄĆÉĹĺôöĽľŚśÖÜŤťŁ×čáíóúĄąŽžĘ꬟Ⱥ«»░▒▓│┤ÁÂĚŞ╣║╗╝Żż┐└┴┬├─┼Ăă╚╔╩╦╠═╬¤đĐĎËďŇÍÎě┘┌█▄ŢŮ▀ÓßÔŃńňŠšŔÚŕŰýÝţ´­˝˛ˇ˘§÷¸°¨˙űŘř■ " - }, - "ibm852": "cp852", - "csibm852": "cp852", - "cp855": { - "type": "_sbcs", - "chars": "ђЂѓЃёЁєЄѕЅіІїЇјЈљЉњЊћЋќЌўЎџЏюЮъЪаАбБцЦдДеЕфФгГ«»░▒▓│┤хХиИ╣║╗╝йЙ┐└┴┬├─┼кК╚╔╩╦╠═╬¤лЛмМнНоОп┘┌█▄Пя▀ЯрРсСтТуУжЖвВьЬ№­ыЫзЗшШэЭщЩчЧ§■ " - }, - "ibm855": "cp855", - "csibm855": "cp855", - "cp856": { - "type": "_sbcs", - "chars": "אבגדהוזחטיךכלםמןנסעףפץצקרשת�£�×����������®¬½¼�«»░▒▓│┤���©╣║╗╝¢¥┐└┴┬├─┼��╚╔╩╦╠═╬¤���������┘┌█▄¦�▀������µ�������¯´­±‗¾¶§÷¸°¨·¹³²■ " - }, - "ibm856": "cp856", - "csibm856": "cp856", - "cp857": { - "type": "_sbcs", - "chars": "ÇüéâäàåçêëèïîıÄÅÉæÆôöòûùİÖÜø£ØŞşáíóúñÑĞ𿮬½¼¡«»░▒▓│┤ÁÂÀ©╣║╗╝¢¥┐└┴┬├─┼ãÃ╚╔╩╦╠═╬¤ºªÊËÈ�ÍÎÏ┘┌█▄¦Ì▀ÓßÔÒõÕµ�×ÚÛÙìÿ¯´­±�¾¶§÷¸°¨·¹³²■ " - }, - "ibm857": "cp857", - "csibm857": "cp857", - "cp858": { - "type": "_sbcs", - "chars": "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø׃áíóúñѪº¿®¬½¼¡«»░▒▓│┤ÁÂÀ©╣║╗╝¢¥┐└┴┬├─┼ãÃ╚╔╩╦╠═╬¤ðÐÊËÈ€ÍÎÏ┘┌█▄¦Ì▀ÓßÔÒõÕµþÞÚÛÙýݯ´­±‗¾¶§÷¸°¨·¹³²■ " - }, - "ibm858": "cp858", - "csibm858": "cp858", - "cp860": { - "type": "_sbcs", - "chars": "ÇüéâãàÁçêÊèÍÔìÃÂÉÀÈôõòÚùÌÕÜ¢£Ù₧ÓáíóúñѪº¿Ò¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ " - }, - "ibm860": "cp860", - "csibm860": "cp860", - "cp861": { - "type": "_sbcs", - "chars": "ÇüéâäàåçêëèÐðÞÄÅÉæÆôöþûÝýÖÜø£Ø₧ƒáíóúÁÍÓÚ¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ " - }, - "ibm861": "cp861", - "csibm861": "cp861", - "cp862": { - "type": "_sbcs", - "chars": "אבגדהוזחטיךכלםמןנסעףפץצקרשת¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ " - }, - "ibm862": "cp862", - "csibm862": "cp862", - "cp863": { - "type": "_sbcs", - "chars": "ÇüéâÂà¶çêëèïî‗À§ÉÈÊôËÏûù¤ÔÜ¢£ÙÛƒ¦´óú¨¸³¯Î⌐¬½¼¾«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ " - }, - "ibm863": "cp863", - "csibm863": "cp863", - "cp864": { - "type": "_sbcs", - "chars": "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$٪&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~°·∙√▒─│┼┤┬├┴┐┌└┘β∞φ±½¼≈«»ﻷﻸ��ﻻﻼ� ­ﺂ£¤ﺄ��ﺎﺏﺕﺙ،ﺝﺡﺥ٠١٢٣٤٥٦٧٨٩ﻑ؛ﺱﺵﺹ؟¢ﺀﺁﺃﺅﻊﺋﺍﺑﺓﺗﺛﺟﺣﺧﺩﺫﺭﺯﺳﺷﺻﺿﻁﻅﻋﻏ¦¬÷×ﻉـﻓﻗﻛﻟﻣﻧﻫﻭﻯﻳﺽﻌﻎﻍﻡﹽّﻥﻩﻬﻰﻲﻐﻕﻵﻶﻝﻙﻱ■�" - }, - "ibm864": "cp864", - "csibm864": "cp864", - "cp865": { - "type": "_sbcs", - "chars": "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø₧ƒáíóúñѪº¿⌐¬½¼¡«¤░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ " - }, - "ibm865": "cp865", - "csibm865": "cp865", - "cp866": { - "type": "_sbcs", - "chars": "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀рстуфхцчшщъыьэюяЁёЄєЇїЎў°∙·√№¤■ " - }, - "ibm866": "cp866", - "csibm866": "cp866", - "cp869": { - "type": "_sbcs", - "chars": "������Ά�·¬¦‘’Έ―ΉΊΪΌ��ΎΫ©Ώ²³ά£έήίϊΐόύΑΒΓΔΕΖΗ½ΘΙ«»░▒▓│┤ΚΛΜΝ╣║╗╝ΞΟ┐└┴┬├─┼ΠΡ╚╔╩╦╠═╬ΣΤΥΦΧΨΩαβγ┘┌█▄δε▀ζηθικλμνξοπρσςτ΄­±υφχ§ψ΅°¨ωϋΰώ■ " - }, - "ibm869": "cp869", - "csibm869": "cp869", - "cp922": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®‾°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏŠÑÒÓÔÕÖ×ØÙÚÛÜÝŽßàáâãäåæçèéêëìíîïšñòóôõö÷øùúûüýžÿ" - }, - "ibm922": "cp922", - "csibm922": "cp922", - "cp1046": { - "type": "_sbcs", - "chars": "ﺈ×÷ﹱˆ■│─┐┌└┘ﹹﹻﹽﹿﹷﺊﻰﻳﻲﻎﻏﻐﻶﻸﻺﻼ ¤ﺋﺑﺗﺛﺟﺣ،­ﺧﺳ٠١٢٣٤٥٦٧٨٩ﺷ؛ﺻﺿﻊ؟ﻋءآأؤإئابةتثجحخدذرزسشصضطﻇعغﻌﺂﺄﺎﻓـفقكلمنهوىيًٌٍَُِّْﻗﻛﻟﻵﻷﻹﻻﻣﻧﻬﻩ�" - }, - "ibm1046": "cp1046", - "csibm1046": "cp1046", - "cp1124": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ЁЂҐЄЅІЇЈЉЊЋЌ­ЎЏАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя№ёђґєѕіїјљњћќ§ўџ" - }, - "ibm1124": "cp1124", - "csibm1124": "cp1124", - "cp1125": { - "type": "_sbcs", - "chars": "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀рстуфхцчшщъыьэюяЁёҐґЄєІіЇї·√№¤■ " - }, - "ibm1125": "cp1125", - "csibm1125": "cp1125", - "cp1129": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§œ©ª«¬­®¯°±²³Ÿµ¶·Œ¹º»¼½¾¿ÀÁÂĂÄÅÆÇÈÉÊË̀ÍÎÏĐÑ̉ÓÔƠÖ×ØÙÚÛÜỮßàáâăäåæçèéêë́íîïđṇ̃óôơö÷øùúûüư₫ÿ" - }, - "ibm1129": "cp1129", - "csibm1129": "cp1129", - "cp1133": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ກຂຄງຈສຊຍດຕຖທນບປຜຝພຟມຢຣລວຫອຮ���ຯະາຳິີຶືຸູຼັົຽ���ເແໂໃໄ່້໊໋໌ໍໆ�ໜໝ₭����������������໐໑໒໓໔໕໖໗໘໙��¢¬¦�" - }, - "ibm1133": "cp1133", - "csibm1133": "cp1133", - "cp1161": { - "type": "_sbcs", - "chars": "��������������������������������่กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู้๊๋€฿เแโใไๅๆ็่้๊๋์ํ๎๏๐๑๒๓๔๕๖๗๘๙๚๛¢¬¦ " - }, - "ibm1161": "cp1161", - "csibm1161": "cp1161", - "cp1162": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู����฿เแโใไๅๆ็่้๊๋์ํ๎๏๐๑๒๓๔๕๖๗๘๙๚๛����" - }, - "ibm1162": "cp1162", - "csibm1162": "cp1162", - "cp1163": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£€¥¦§œ©ª«¬­®¯°±²³Ÿµ¶·Œ¹º»¼½¾¿ÀÁÂĂÄÅÆÇÈÉÊË̀ÍÎÏĐÑ̉ÓÔƠÖ×ØÙÚÛÜỮßàáâăäåæçèéêë́íîïđṇ̃óôơö÷øùúûüư₫ÿ" - }, - "ibm1163": "cp1163", - "csibm1163": "cp1163", - "maccroatian": { - "type": "_sbcs", - "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®Š™´¨≠ŽØ∞±≤≥∆µ∂∑∏š∫ªºΩžø¿¡¬√ƒ≈Ć«Č… ÀÃÕŒœĐ—“”‘’÷◊�©⁄¤‹›Æ»–·‚„‰ÂćÁčÈÍÎÏÌÓÔđÒÚÛÙıˆ˜¯πË˚¸Êæˇ" - }, - "maccyrillic": { - "type": "_sbcs", - "chars": "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ†°¢£§•¶І®©™Ђђ≠Ѓѓ∞±≤≥іµ∂ЈЄєЇїЉљЊњјЅ¬√ƒ≈∆«»… ЋћЌќѕ–—“”‘’÷„ЎўЏџ№Ёёяабвгдежзийклмнопрстуфхцчшщъыьэю¤" - }, - "macgreek": { - "type": "_sbcs", - "chars": "Ĺ²É³ÖÜ΅àâä΄¨çéèê룙î‰ôö¦­ùûü†ΓΔΘΛΞΠß®©ΣΪ§≠°·Α±≤≥¥ΒΕΖΗΙΚΜΦΫΨΩάΝ¬ΟΡ≈Τ«»… ΥΧΆΈœ–―“”‘’÷ΉΊΌΎέήίόΏύαβψδεφγηιξκλμνοπώρστθωςχυζϊϋΐΰ�" - }, - "maciceland": { - "type": "_sbcs", - "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûüÝ°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄¤ÐðÞþý·‚„‰ÂÊÁËÈÍÎÏÌÓÔ�ÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ" - }, - "macroman": { - "type": "_sbcs", - "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄¤‹›fifl‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔ�ÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ" - }, - "macromania": { - "type": "_sbcs", - "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ĂŞ∞±≤≥¥µ∂∑∏π∫ªºΩăş¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄¤‹›Ţţ‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔ�ÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ" - }, - "macthai": { - "type": "_sbcs", - "chars": "«»…“”�•‘’� กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู​–—฿เแโใไๅๆ็่้๊๋์ํ™๏๐๑๒๓๔๕๖๗๘๙®©����" - }, - "macturkish": { - "type": "_sbcs", - "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸĞğİıŞş‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔ�ÒÚÛÙ�ˆ˜¯˘˙˚¸˝˛ˇ" - }, - "macukraine": { - "type": "_sbcs", - "chars": "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ†°Ґ£§•¶І®©™Ђђ≠Ѓѓ∞±≤≥іµґЈЄєЇїЉљЊњјЅ¬√ƒ≈∆«»… ЋћЌќѕ–—“”‘’÷„ЎўЏџ№Ёёяабвгдежзийклмнопрстуфхцчшщъыьэю¤" - }, - "koi8r": { - "type": "_sbcs", - "chars": "─│┌┐└┘├┤┬┴┼▀▄█▌▐░▒▓⌠■∙√≈≤≥ ⌡°²·÷═║╒ё╓╔╕╖╗╘╙╚╛╜╝╞╟╠╡Ё╢╣╤╥╦╧╨╩╪╫╬©юабцдефгхийклмнопярстужвьызшэщчъЮАБЦДЕФГХИЙКЛМНОПЯРСТУЖВЬЫЗШЭЩЧЪ" - }, - "koi8u": { - "type": "_sbcs", - "chars": "─│┌┐└┘├┤┬┴┼▀▄█▌▐░▒▓⌠■∙√≈≤≥ ⌡°²·÷═║╒ёє╔ії╗╘╙╚╛ґ╝╞╟╠╡ЁЄ╣ІЇ╦╧╨╩╪Ґ╬©юабцдефгхийклмнопярстужвьызшэщчъЮАБЦДЕФГХИЙКЛМНОПЯРСТУЖВЬЫЗШЭЩЧЪ" - }, - "koi8ru": { - "type": "_sbcs", - "chars": "─│┌┐└┘├┤┬┴┼▀▄█▌▐░▒▓⌠■∙√≈≤≥ ⌡°²·÷═║╒ёє╔ії╗╘╙╚╛ґў╞╟╠╡ЁЄ╣ІЇ╦╧╨╩╪ҐЎ©юабцдефгхийклмнопярстужвьызшэщчъЮАБЦДЕФГХИЙКЛМНОПЯРСТУЖВЬЫЗШЭЩЧЪ" - }, - "koi8t": { - "type": "_sbcs", - "chars": "қғ‚Ғ„…†‡�‰ҳ‹ҲҷҶ�Қ‘’“”•–—�™�›�����ӯӮё¤ӣ¦§���«¬­®�°±²Ё�Ӣ¶·�№�»���©юабцдефгхийклмнопярстужвьызшэщчъЮАБЦДЕФГХИЙКЛМНОПЯРСТУЖВЬЫЗШЭЩЧЪ" - }, - "armscii8": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ �և։)(»«—.՝,-֊…՜՛՞ԱաԲբԳգԴդԵեԶզԷէԸըԹթԺժԻիԼլԽխԾծԿկՀհՁձՂղՃճՄմՅյՆնՇշՈոՉչՊպՋջՌռՍսՎվՏտՐրՑցՒւՓփՔքՕօՖֆ՚�" - }, - "rk1048": { - "type": "_sbcs", - "chars": "ЂЃ‚ѓ„…†‡€‰Љ‹ЊҚҺЏђ‘’“”•–—�™љ›њқһџ ҰұӘ¤Ө¦§Ё©Ғ«¬­®Ү°±Ііөµ¶·ё№ғ»әҢңүАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя" - }, - "tcvn": { - "type": "_sbcs", - "chars": "\u0000ÚỤ\u0003ỪỬỮ\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010ỨỰỲỶỸÝỴ\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ÀẢÃÁẠẶẬÈẺẼÉẸỆÌỈĨÍỊÒỎÕÓỌỘỜỞỠỚỢÙỦŨ ĂÂÊÔƠƯĐăâêôơưđẶ̀̀̉̃́àảãáạẲằẳẵắẴẮẦẨẪẤỀặầẩẫấậèỂẻẽéẹềểễếệìỉỄẾỒĩíịòỔỏõóọồổỗốộờởỡớợùỖủũúụừửữứựỳỷỹýỵỐ" - }, - "georgianacademy": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿აბგდევზთიკლმნოპჟრსტუფქღყშჩცძწჭხჯჰჱჲჳჴჵჶçèéêëìíîïðñòóôõö÷øùúûüýþÿ" - }, - "georgianps": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿აბგდევზჱთიკლმნჲოპჟრსტჳუფქღყშჩცძწჭხჴჯჰჵæçèéêëìíîïðñòóôõö÷øùúûüýþÿ" - }, - "pt154": { - "type": "_sbcs", - "chars": "ҖҒӮғ„…ҶҮҲүҠӢҢҚҺҸҗ‘’“”•–—ҳҷҡӣңқһҹ ЎўЈӨҘҰ§Ё©Ә«¬ӯ®Ҝ°ұІіҙө¶·ё№ә»јҪҫҝАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя" - }, - "viscii": { - "type": "_sbcs", - "chars": "\u0000\u0001Ẳ\u0003\u0004ẴẪ\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013Ỷ\u0015\u0016\u0017\u0018Ỹ\u001a\u001b\u001c\u001dỴ\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ẠẮẰẶẤẦẨẬẼẸẾỀỂỄỆỐỒỔỖỘỢỚỜỞỊỎỌỈỦŨỤỲÕắằặấầẩậẽẹếềểễệốồổỗỠƠộờởịỰỨỪỬơớƯÀÁÂÃẢĂẳẵÈÉÊẺÌÍĨỳĐứÒÓÔạỷừửÙÚỹỵÝỡưàáâãảăữẫèéêẻìíĩỉđựòóôõỏọụùúũủýợỮ" - }, - "iso646cn": { - "type": "_sbcs", - "chars": "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#¥%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}‾��������������������������������������������������������������������������������������������������������������������������������" - }, - "iso646jp": { - "type": "_sbcs", - "chars": "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[¥]^_`abcdefghijklmnopqrstuvwxyz{|}‾��������������������������������������������������������������������������������������������������������������������������������" - }, - "hproman8": { - "type": "_sbcs", - "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ÀÂÈÊËÎÏ´ˋˆ¨˜ÙÛ₤¯Ýý°ÇçÑñ¡¿¤£¥§ƒ¢âêôûáéóúàèòùäëöüÅîØÆåíøæÄìÖÜÉïßÔÁÃãÐðÍÌÓÒÕõŠšÚŸÿÞþ·µ¶¾—¼½ªº«■»±�" - }, - "macintosh": { - "type": "_sbcs", - "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄¤‹›fifl‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔ�ÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ" - }, - "ascii": { - "type": "_sbcs", - "chars": "��������������������������������������������������������������������������������������������������������������������������������" - }, - "tis620": { - "type": "_sbcs", - "chars": "���������������������������������กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู����฿เแโใไๅๆ็่้๊๋์ํ๎๏๐๑๒๓๔๕๖๗๘๙๚๛����" - } -} - -/***/ }), - -/***/ 1080: -/***/ ((module) => { - -"use strict"; - - -// Manually added data to be used by sbcs codec in addition to generated one. - -module.exports = { - // Not supported by iconv, not sure why. - "10029": "maccenteuro", - "maccenteuro": { - "type": "_sbcs", - "chars": "ÄĀāÉĄÖÜáąČäčĆć鏟ĎíďĒēĖóėôöõúĚěü†°Ę£§•¶ß®©™ę¨≠ģĮįĪ≤≥īĶ∂∑łĻļĽľĹĺŅņѬ√ńŇ∆«»… ňŐÕőŌ–—“”‘’÷◊ōŔŕŘ‹›řŖŗŠ‚„šŚśÁŤťÍŽžŪÓÔūŮÚůŰűŲųÝýķŻŁżĢˇ" - }, - - "808": "cp808", - "ibm808": "cp808", - "cp808": { - "type": "_sbcs", - "chars": "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀рстуфхцчшщъыьэюяЁёЄєЇїЎў°∙·√№€■ " - }, - - "mik": { - "type": "_sbcs", - "chars": "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя└┴┬├─┼╣║╚╔╩╦╠═╬┐░▒▓│┤№§╗╝┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ " - }, - - "cp720": { - "type": "_sbcs", - "chars": "\x80\x81éâ\x84à\x86çêëèïî\x8d\x8e\x8f\x90\u0651\u0652ô¤ـûùءآأؤ£إئابةتثجحخدذرزسشص«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀ضطظعغفµقكلمنهوىي≡\u064b\u064c\u064d\u064e\u064f\u0650≈°∙·√ⁿ²■\u00a0" - }, - - // Aliases of generated encodings. - "ascii8bit": "ascii", - "usascii": "ascii", - "ansix34": "ascii", - "ansix341968": "ascii", - "ansix341986": "ascii", - "csascii": "ascii", - "cp367": "ascii", - "ibm367": "ascii", - "isoir6": "ascii", - "iso646us": "ascii", - "iso646irv": "ascii", - "us": "ascii", - - "latin1": "iso88591", - "latin2": "iso88592", - "latin3": "iso88593", - "latin4": "iso88594", - "latin5": "iso88599", - "latin6": "iso885910", - "latin7": "iso885913", - "latin8": "iso885914", - "latin9": "iso885915", - "latin10": "iso885916", - - "csisolatin1": "iso88591", - "csisolatin2": "iso88592", - "csisolatin3": "iso88593", - "csisolatin4": "iso88594", - "csisolatincyrillic": "iso88595", - "csisolatinarabic": "iso88596", - "csisolatingreek" : "iso88597", - "csisolatinhebrew": "iso88598", - "csisolatin5": "iso88599", - "csisolatin6": "iso885910", - - "l1": "iso88591", - "l2": "iso88592", - "l3": "iso88593", - "l4": "iso88594", - "l5": "iso88599", - "l6": "iso885910", - "l7": "iso885913", - "l8": "iso885914", - "l9": "iso885915", - "l10": "iso885916", - - "isoir14": "iso646jp", - "isoir57": "iso646cn", - "isoir100": "iso88591", - "isoir101": "iso88592", - "isoir109": "iso88593", - "isoir110": "iso88594", - "isoir144": "iso88595", - "isoir127": "iso88596", - "isoir126": "iso88597", - "isoir138": "iso88598", - "isoir148": "iso88599", - "isoir157": "iso885910", - "isoir166": "tis620", - "isoir179": "iso885913", - "isoir199": "iso885914", - "isoir203": "iso885915", - "isoir226": "iso885916", - - "cp819": "iso88591", - "ibm819": "iso88591", - - "cyrillic": "iso88595", - - "arabic": "iso88596", - "arabic8": "iso88596", - "ecma114": "iso88596", - "asmo708": "iso88596", - - "greek" : "iso88597", - "greek8" : "iso88597", - "ecma118" : "iso88597", - "elot928" : "iso88597", - - "hebrew": "iso88598", - "hebrew8": "iso88598", - - "turkish": "iso88599", - "turkish8": "iso88599", - - "thai": "iso885911", - "thai8": "iso885911", - - "celtic": "iso885914", - "celtic8": "iso885914", - "isoceltic": "iso885914", - - "tis6200": "tis620", - "tis62025291": "tis620", - "tis62025330": "tis620", - - "10000": "macroman", - "10006": "macgreek", - "10007": "maccyrillic", - "10079": "maciceland", - "10081": "macturkish", - - "cspc8codepage437": "cp437", - "cspc775baltic": "cp775", - "cspc850multilingual": "cp850", - "cspcp852": "cp852", - "cspc862latinhebrew": "cp862", - "cpgr": "cp869", - - "msee": "cp1250", - "mscyrl": "cp1251", - "msansi": "cp1252", - "msgreek": "cp1253", - "msturk": "cp1254", - "mshebr": "cp1255", - "msarab": "cp1256", - "winbaltrim": "cp1257", - - "cp20866": "koi8r", - "20866": "koi8r", - "ibm878": "koi8r", - "cskoi8r": "koi8r", - - "cp21866": "koi8u", - "21866": "koi8u", - "ibm1168": "koi8u", - - "strk10482002": "rk1048", - - "tcvn5712": "tcvn", - "tcvn57121": "tcvn", - - "gb198880": "iso646cn", - "cn": "iso646cn", - - "csiso14jisc6220ro": "iso646jp", - "jisc62201969ro": "iso646jp", - "jp": "iso646jp", - - "cshproman8": "hproman8", - "r8": "hproman8", - "roman8": "hproman8", - "xroman8": "hproman8", - "ibm1051": "hproman8", - - "mac": "macintosh", - "csmacintosh": "macintosh", -}; - - - -/***/ }), - -/***/ 1155: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - -var Buffer = (__nccwpck_require__(5118).Buffer); - -// Note: UTF16-LE (or UCS2) codec is Node.js native. See encodings/internal.js - -// == UTF16-BE codec. ========================================================== - -exports.utf16be = Utf16BECodec; -function Utf16BECodec() { -} - -Utf16BECodec.prototype.encoder = Utf16BEEncoder; -Utf16BECodec.prototype.decoder = Utf16BEDecoder; -Utf16BECodec.prototype.bomAware = true; - - -// -- Encoding - -function Utf16BEEncoder() { -} - -Utf16BEEncoder.prototype.write = function(str) { - var buf = Buffer.from(str, 'ucs2'); - for (var i = 0; i < buf.length; i += 2) { - var tmp = buf[i]; buf[i] = buf[i+1]; buf[i+1] = tmp; - } - return buf; -} - -Utf16BEEncoder.prototype.end = function() { -} - - -// -- Decoding - -function Utf16BEDecoder() { - this.overflowByte = -1; -} - -Utf16BEDecoder.prototype.write = function(buf) { - if (buf.length == 0) - return ''; - - var buf2 = Buffer.alloc(buf.length + 1), - i = 0, j = 0; - - if (this.overflowByte !== -1) { - buf2[0] = buf[0]; - buf2[1] = this.overflowByte; - i = 1; j = 2; - } - - for (; i < buf.length-1; i += 2, j+= 2) { - buf2[j] = buf[i+1]; - buf2[j+1] = buf[i]; - } - - this.overflowByte = (i == buf.length-1) ? buf[buf.length-1] : -1; - - return buf2.slice(0, j).toString('ucs2'); -} - -Utf16BEDecoder.prototype.end = function() { - this.overflowByte = -1; -} - - -// == UTF-16 codec ============================================================= -// Decoder chooses automatically from UTF-16LE and UTF-16BE using BOM and space-based heuristic. -// Defaults to UTF-16LE, as it's prevalent and default in Node. -// http://en.wikipedia.org/wiki/UTF-16 and http://encoding.spec.whatwg.org/#utf-16le -// Decoder default can be changed: iconv.decode(buf, 'utf16', {defaultEncoding: 'utf-16be'}); - -// Encoder uses UTF-16LE and prepends BOM (which can be overridden with addBOM: false). - -exports.utf16 = Utf16Codec; -function Utf16Codec(codecOptions, iconv) { - this.iconv = iconv; -} - -Utf16Codec.prototype.encoder = Utf16Encoder; -Utf16Codec.prototype.decoder = Utf16Decoder; - - -// -- Encoding (pass-through) - -function Utf16Encoder(options, codec) { - options = options || {}; - if (options.addBOM === undefined) - options.addBOM = true; - this.encoder = codec.iconv.getEncoder('utf-16le', options); -} - -Utf16Encoder.prototype.write = function(str) { - return this.encoder.write(str); -} - -Utf16Encoder.prototype.end = function() { - return this.encoder.end(); -} - - -// -- Decoding - -function Utf16Decoder(options, codec) { - this.decoder = null; - this.initialBufs = []; - this.initialBufsLen = 0; - - this.options = options || {}; - this.iconv = codec.iconv; -} - -Utf16Decoder.prototype.write = function(buf) { - if (!this.decoder) { - // Codec is not chosen yet. Accumulate initial bytes. - this.initialBufs.push(buf); - this.initialBufsLen += buf.length; - - if (this.initialBufsLen < 16) // We need more bytes to use space heuristic (see below) - return ''; - - // We have enough bytes -> detect endianness. - var encoding = detectEncoding(this.initialBufs, this.options.defaultEncoding); - this.decoder = this.iconv.getDecoder(encoding, this.options); - - var resStr = ''; - for (var i = 0; i < this.initialBufs.length; i++) - resStr += this.decoder.write(this.initialBufs[i]); - - this.initialBufs.length = this.initialBufsLen = 0; - return resStr; - } - - return this.decoder.write(buf); -} - -Utf16Decoder.prototype.end = function() { - if (!this.decoder) { - var encoding = detectEncoding(this.initialBufs, this.options.defaultEncoding); - this.decoder = this.iconv.getDecoder(encoding, this.options); - - var resStr = ''; - for (var i = 0; i < this.initialBufs.length; i++) - resStr += this.decoder.write(this.initialBufs[i]); - - var trail = this.decoder.end(); - if (trail) - resStr += trail; - - this.initialBufs.length = this.initialBufsLen = 0; - return resStr; - } - return this.decoder.end(); -} - -function detectEncoding(bufs, defaultEncoding) { - var b = []; - var charsProcessed = 0; - var asciiCharsLE = 0, asciiCharsBE = 0; // Number of ASCII chars when decoded as LE or BE. - - outer_loop: - for (var i = 0; i < bufs.length; i++) { - var buf = bufs[i]; - for (var j = 0; j < buf.length; j++) { - b.push(buf[j]); - if (b.length === 2) { - if (charsProcessed === 0) { - // Check BOM first. - if (b[0] === 0xFF && b[1] === 0xFE) return 'utf-16le'; - if (b[0] === 0xFE && b[1] === 0xFF) return 'utf-16be'; - } - - if (b[0] === 0 && b[1] !== 0) asciiCharsBE++; - if (b[0] !== 0 && b[1] === 0) asciiCharsLE++; - - b.length = 0; - charsProcessed++; - - if (charsProcessed >= 100) { - break outer_loop; - } - } - } - } - - // Make decisions. - // Most of the time, the content has ASCII chars (U+00**), but the opposite (U+**00) is uncommon. - // So, we count ASCII as if it was LE or BE, and decide from that. - if (asciiCharsBE > asciiCharsLE) return 'utf-16be'; - if (asciiCharsBE < asciiCharsLE) return 'utf-16le'; - - // Couldn't decide (likely all zeros or not enough data). - return defaultEncoding || 'utf-16le'; -} - - - - -/***/ }), - -/***/ 9557: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - - -var Buffer = (__nccwpck_require__(5118).Buffer); - -// == UTF32-LE/BE codec. ========================================================== - -exports._utf32 = Utf32Codec; - -function Utf32Codec(codecOptions, iconv) { - this.iconv = iconv; - this.bomAware = true; - this.isLE = codecOptions.isLE; -} - -exports.utf32le = { type: '_utf32', isLE: true }; -exports.utf32be = { type: '_utf32', isLE: false }; - -// Aliases -exports.ucs4le = 'utf32le'; -exports.ucs4be = 'utf32be'; - -Utf32Codec.prototype.encoder = Utf32Encoder; -Utf32Codec.prototype.decoder = Utf32Decoder; - -// -- Encoding - -function Utf32Encoder(options, codec) { - this.isLE = codec.isLE; - this.highSurrogate = 0; -} - -Utf32Encoder.prototype.write = function(str) { - var src = Buffer.from(str, 'ucs2'); - var dst = Buffer.alloc(src.length * 2); - var write32 = this.isLE ? dst.writeUInt32LE : dst.writeUInt32BE; - var offset = 0; - - for (var i = 0; i < src.length; i += 2) { - var code = src.readUInt16LE(i); - var isHighSurrogate = (0xD800 <= code && code < 0xDC00); - var isLowSurrogate = (0xDC00 <= code && code < 0xE000); - - if (this.highSurrogate) { - if (isHighSurrogate || !isLowSurrogate) { - // There shouldn't be two high surrogates in a row, nor a high surrogate which isn't followed by a low - // surrogate. If this happens, keep the pending high surrogate as a stand-alone semi-invalid character - // (technically wrong, but expected by some applications, like Windows file names). - write32.call(dst, this.highSurrogate, offset); - offset += 4; - } - else { - // Create 32-bit value from high and low surrogates; - var codepoint = (((this.highSurrogate - 0xD800) << 10) | (code - 0xDC00)) + 0x10000; - - write32.call(dst, codepoint, offset); - offset += 4; - this.highSurrogate = 0; - - continue; - } - } - - if (isHighSurrogate) - this.highSurrogate = code; - else { - // Even if the current character is a low surrogate, with no previous high surrogate, we'll - // encode it as a semi-invalid stand-alone character for the same reasons expressed above for - // unpaired high surrogates. - write32.call(dst, code, offset); - offset += 4; - this.highSurrogate = 0; - } - } - - if (offset < dst.length) - dst = dst.slice(0, offset); - - return dst; -}; - -Utf32Encoder.prototype.end = function() { - // Treat any leftover high surrogate as a semi-valid independent character. - if (!this.highSurrogate) - return; - - var buf = Buffer.alloc(4); - - if (this.isLE) - buf.writeUInt32LE(this.highSurrogate, 0); - else - buf.writeUInt32BE(this.highSurrogate, 0); - - this.highSurrogate = 0; - - return buf; -}; - -// -- Decoding - -function Utf32Decoder(options, codec) { - this.isLE = codec.isLE; - this.badChar = codec.iconv.defaultCharUnicode.charCodeAt(0); - this.overflow = []; -} - -Utf32Decoder.prototype.write = function(src) { - if (src.length === 0) - return ''; - - var i = 0; - var codepoint = 0; - var dst = Buffer.alloc(src.length + 4); - var offset = 0; - var isLE = this.isLE; - var overflow = this.overflow; - var badChar = this.badChar; - - if (overflow.length > 0) { - for (; i < src.length && overflow.length < 4; i++) - overflow.push(src[i]); - - if (overflow.length === 4) { - // NOTE: codepoint is a signed int32 and can be negative. - // NOTE: We copied this block from below to help V8 optimize it (it works with array, not buffer). - if (isLE) { - codepoint = overflow[i] | (overflow[i+1] << 8) | (overflow[i+2] << 16) | (overflow[i+3] << 24); - } else { - codepoint = overflow[i+3] | (overflow[i+2] << 8) | (overflow[i+1] << 16) | (overflow[i] << 24); - } - overflow.length = 0; - - offset = _writeCodepoint(dst, offset, codepoint, badChar); - } - } - - // Main loop. Should be as optimized as possible. - for (; i < src.length - 3; i += 4) { - // NOTE: codepoint is a signed int32 and can be negative. - if (isLE) { - codepoint = src[i] | (src[i+1] << 8) | (src[i+2] << 16) | (src[i+3] << 24); - } else { - codepoint = src[i+3] | (src[i+2] << 8) | (src[i+1] << 16) | (src[i] << 24); - } - offset = _writeCodepoint(dst, offset, codepoint, badChar); - } - - // Keep overflowing bytes. - for (; i < src.length; i++) { - overflow.push(src[i]); - } - - return dst.slice(0, offset).toString('ucs2'); -}; - -function _writeCodepoint(dst, offset, codepoint, badChar) { - // NOTE: codepoint is signed int32 and can be negative. We keep it that way to help V8 with optimizations. - if (codepoint < 0 || codepoint > 0x10FFFF) { - // Not a valid Unicode codepoint - codepoint = badChar; - } - - // Ephemeral Planes: Write high surrogate. - if (codepoint >= 0x10000) { - codepoint -= 0x10000; - - var high = 0xD800 | (codepoint >> 10); - dst[offset++] = high & 0xff; - dst[offset++] = high >> 8; - - // Low surrogate is written below. - var codepoint = 0xDC00 | (codepoint & 0x3FF); - } - - // Write BMP char or low surrogate. - dst[offset++] = codepoint & 0xff; - dst[offset++] = codepoint >> 8; - - return offset; -}; - -Utf32Decoder.prototype.end = function() { - this.overflow.length = 0; -}; - -// == UTF-32 Auto codec ============================================================= -// Decoder chooses automatically from UTF-32LE and UTF-32BE using BOM and space-based heuristic. -// Defaults to UTF-32LE. http://en.wikipedia.org/wiki/UTF-32 -// Encoder/decoder default can be changed: iconv.decode(buf, 'utf32', {defaultEncoding: 'utf-32be'}); - -// Encoder prepends BOM (which can be overridden with (addBOM: false}). - -exports.utf32 = Utf32AutoCodec; -exports.ucs4 = 'utf32'; - -function Utf32AutoCodec(options, iconv) { - this.iconv = iconv; -} - -Utf32AutoCodec.prototype.encoder = Utf32AutoEncoder; -Utf32AutoCodec.prototype.decoder = Utf32AutoDecoder; - -// -- Encoding - -function Utf32AutoEncoder(options, codec) { - options = options || {}; - - if (options.addBOM === undefined) - options.addBOM = true; - - this.encoder = codec.iconv.getEncoder(options.defaultEncoding || 'utf-32le', options); -} - -Utf32AutoEncoder.prototype.write = function(str) { - return this.encoder.write(str); -}; - -Utf32AutoEncoder.prototype.end = function() { - return this.encoder.end(); -}; - -// -- Decoding - -function Utf32AutoDecoder(options, codec) { - this.decoder = null; - this.initialBufs = []; - this.initialBufsLen = 0; - this.options = options || {}; - this.iconv = codec.iconv; -} - -Utf32AutoDecoder.prototype.write = function(buf) { - if (!this.decoder) { - // Codec is not chosen yet. Accumulate initial bytes. - this.initialBufs.push(buf); - this.initialBufsLen += buf.length; - - if (this.initialBufsLen < 32) // We need more bytes to use space heuristic (see below) - return ''; - - // We have enough bytes -> detect endianness. - var encoding = detectEncoding(this.initialBufs, this.options.defaultEncoding); - this.decoder = this.iconv.getDecoder(encoding, this.options); - - var resStr = ''; - for (var i = 0; i < this.initialBufs.length; i++) - resStr += this.decoder.write(this.initialBufs[i]); - - this.initialBufs.length = this.initialBufsLen = 0; - return resStr; - } - - return this.decoder.write(buf); -}; - -Utf32AutoDecoder.prototype.end = function() { - if (!this.decoder) { - var encoding = detectEncoding(this.initialBufs, this.options.defaultEncoding); - this.decoder = this.iconv.getDecoder(encoding, this.options); - - var resStr = ''; - for (var i = 0; i < this.initialBufs.length; i++) - resStr += this.decoder.write(this.initialBufs[i]); - - var trail = this.decoder.end(); - if (trail) - resStr += trail; - - this.initialBufs.length = this.initialBufsLen = 0; - return resStr; - } - - return this.decoder.end(); -}; - -function detectEncoding(bufs, defaultEncoding) { - var b = []; - var charsProcessed = 0; - var invalidLE = 0, invalidBE = 0; // Number of invalid chars when decoded as LE or BE. - var bmpCharsLE = 0, bmpCharsBE = 0; // Number of BMP chars when decoded as LE or BE. - - outer_loop: - for (var i = 0; i < bufs.length; i++) { - var buf = bufs[i]; - for (var j = 0; j < buf.length; j++) { - b.push(buf[j]); - if (b.length === 4) { - if (charsProcessed === 0) { - // Check BOM first. - if (b[0] === 0xFF && b[1] === 0xFE && b[2] === 0 && b[3] === 0) { - return 'utf-32le'; - } - if (b[0] === 0 && b[1] === 0 && b[2] === 0xFE && b[3] === 0xFF) { - return 'utf-32be'; - } - } - - if (b[0] !== 0 || b[1] > 0x10) invalidBE++; - if (b[3] !== 0 || b[2] > 0x10) invalidLE++; - - if (b[0] === 0 && b[1] === 0 && (b[2] !== 0 || b[3] !== 0)) bmpCharsBE++; - if ((b[0] !== 0 || b[1] !== 0) && b[2] === 0 && b[3] === 0) bmpCharsLE++; - - b.length = 0; - charsProcessed++; - - if (charsProcessed >= 100) { - break outer_loop; - } - } - } - } - - // Make decisions. - if (bmpCharsBE - invalidBE > bmpCharsLE - invalidLE) return 'utf-32be'; - if (bmpCharsBE - invalidBE < bmpCharsLE - invalidLE) return 'utf-32le'; - - // Couldn't decide (likely all zeros or not enough data). - return defaultEncoding || 'utf-32le'; -} - - -/***/ }), - -/***/ 1644: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; - -var Buffer = (__nccwpck_require__(5118).Buffer); - -// UTF-7 codec, according to https://tools.ietf.org/html/rfc2152 -// See also below a UTF-7-IMAP codec, according to http://tools.ietf.org/html/rfc3501#section-5.1.3 - -exports.utf7 = Utf7Codec; -exports.unicode11utf7 = 'utf7'; // Alias UNICODE-1-1-UTF-7 -function Utf7Codec(codecOptions, iconv) { - this.iconv = iconv; -}; - -Utf7Codec.prototype.encoder = Utf7Encoder; -Utf7Codec.prototype.decoder = Utf7Decoder; -Utf7Codec.prototype.bomAware = true; - - -// -- Encoding - -var nonDirectChars = /[^A-Za-z0-9'\(\),-\.\/:\? \n\r\t]+/g; - -function Utf7Encoder(options, codec) { - this.iconv = codec.iconv; -} - -Utf7Encoder.prototype.write = function(str) { - // Naive implementation. - // Non-direct chars are encoded as "+-"; single "+" char is encoded as "+-". - return Buffer.from(str.replace(nonDirectChars, function(chunk) { - return "+" + (chunk === '+' ? '' : - this.iconv.encode(chunk, 'utf16-be').toString('base64').replace(/=+$/, '')) - + "-"; - }.bind(this))); -} - -Utf7Encoder.prototype.end = function() { -} - - -// -- Decoding - -function Utf7Decoder(options, codec) { - this.iconv = codec.iconv; - this.inBase64 = false; - this.base64Accum = ''; -} - -var base64Regex = /[A-Za-z0-9\/+]/; -var base64Chars = []; -for (var i = 0; i < 256; i++) - base64Chars[i] = base64Regex.test(String.fromCharCode(i)); - -var plusChar = '+'.charCodeAt(0), - minusChar = '-'.charCodeAt(0), - andChar = '&'.charCodeAt(0); - -Utf7Decoder.prototype.write = function(buf) { - var res = "", lastI = 0, - inBase64 = this.inBase64, - base64Accum = this.base64Accum; - - // The decoder is more involved as we must handle chunks in stream. - - for (var i = 0; i < buf.length; i++) { - if (!inBase64) { // We're in direct mode. - // Write direct chars until '+' - if (buf[i] == plusChar) { - res += this.iconv.decode(buf.slice(lastI, i), "ascii"); // Write direct chars. - lastI = i+1; - inBase64 = true; - } - } else { // We decode base64. - if (!base64Chars[buf[i]]) { // Base64 ended. - if (i == lastI && buf[i] == minusChar) {// "+-" -> "+" - res += "+"; - } else { - var b64str = base64Accum + this.iconv.decode(buf.slice(lastI, i), "ascii"); - res += this.iconv.decode(Buffer.from(b64str, 'base64'), "utf16-be"); - } - - if (buf[i] != minusChar) // Minus is absorbed after base64. - i--; - - lastI = i+1; - inBase64 = false; - base64Accum = ''; - } - } - } - - if (!inBase64) { - res += this.iconv.decode(buf.slice(lastI), "ascii"); // Write direct chars. - } else { - var b64str = base64Accum + this.iconv.decode(buf.slice(lastI), "ascii"); - - var canBeDecoded = b64str.length - (b64str.length % 8); // Minimal chunk: 2 quads -> 2x3 bytes -> 3 chars. - base64Accum = b64str.slice(canBeDecoded); // The rest will be decoded in future. - b64str = b64str.slice(0, canBeDecoded); - - res += this.iconv.decode(Buffer.from(b64str, 'base64'), "utf16-be"); - } - - this.inBase64 = inBase64; - this.base64Accum = base64Accum; - - return res; -} - -Utf7Decoder.prototype.end = function() { - var res = ""; - if (this.inBase64 && this.base64Accum.length > 0) - res = this.iconv.decode(Buffer.from(this.base64Accum, 'base64'), "utf16-be"); - - this.inBase64 = false; - this.base64Accum = ''; - return res; -} - - -// UTF-7-IMAP codec. -// RFC3501 Sec. 5.1.3 Modified UTF-7 (http://tools.ietf.org/html/rfc3501#section-5.1.3) -// Differences: -// * Base64 part is started by "&" instead of "+" -// * Direct characters are 0x20-0x7E, except "&" (0x26) -// * In Base64, "," is used instead of "/" -// * Base64 must not be used to represent direct characters. -// * No implicit shift back from Base64 (should always end with '-') -// * String must end in non-shifted position. -// * "-&" while in base64 is not allowed. - - -exports.utf7imap = Utf7IMAPCodec; -function Utf7IMAPCodec(codecOptions, iconv) { - this.iconv = iconv; -}; - -Utf7IMAPCodec.prototype.encoder = Utf7IMAPEncoder; -Utf7IMAPCodec.prototype.decoder = Utf7IMAPDecoder; -Utf7IMAPCodec.prototype.bomAware = true; - - -// -- Encoding - -function Utf7IMAPEncoder(options, codec) { - this.iconv = codec.iconv; - this.inBase64 = false; - this.base64Accum = Buffer.alloc(6); - this.base64AccumIdx = 0; -} - -Utf7IMAPEncoder.prototype.write = function(str) { - var inBase64 = this.inBase64, - base64Accum = this.base64Accum, - base64AccumIdx = this.base64AccumIdx, - buf = Buffer.alloc(str.length*5 + 10), bufIdx = 0; - - for (var i = 0; i < str.length; i++) { - var uChar = str.charCodeAt(i); - if (0x20 <= uChar && uChar <= 0x7E) { // Direct character or '&'. - if (inBase64) { - if (base64AccumIdx > 0) { - bufIdx += buf.write(base64Accum.slice(0, base64AccumIdx).toString('base64').replace(/\//g, ',').replace(/=+$/, ''), bufIdx); - base64AccumIdx = 0; - } - - buf[bufIdx++] = minusChar; // Write '-', then go to direct mode. - inBase64 = false; - } - - if (!inBase64) { - buf[bufIdx++] = uChar; // Write direct character - - if (uChar === andChar) // Ampersand -> '&-' - buf[bufIdx++] = minusChar; - } - - } else { // Non-direct character - if (!inBase64) { - buf[bufIdx++] = andChar; // Write '&', then go to base64 mode. - inBase64 = true; - } - if (inBase64) { - base64Accum[base64AccumIdx++] = uChar >> 8; - base64Accum[base64AccumIdx++] = uChar & 0xFF; - - if (base64AccumIdx == base64Accum.length) { - bufIdx += buf.write(base64Accum.toString('base64').replace(/\//g, ','), bufIdx); - base64AccumIdx = 0; - } - } - } - } - - this.inBase64 = inBase64; - this.base64AccumIdx = base64AccumIdx; - - return buf.slice(0, bufIdx); -} - -Utf7IMAPEncoder.prototype.end = function() { - var buf = Buffer.alloc(10), bufIdx = 0; - if (this.inBase64) { - if (this.base64AccumIdx > 0) { - bufIdx += buf.write(this.base64Accum.slice(0, this.base64AccumIdx).toString('base64').replace(/\//g, ',').replace(/=+$/, ''), bufIdx); - this.base64AccumIdx = 0; - } - - buf[bufIdx++] = minusChar; // Write '-', then go to direct mode. - this.inBase64 = false; - } - - return buf.slice(0, bufIdx); -} - - -// -- Decoding - -function Utf7IMAPDecoder(options, codec) { - this.iconv = codec.iconv; - this.inBase64 = false; - this.base64Accum = ''; -} - -var base64IMAPChars = base64Chars.slice(); -base64IMAPChars[','.charCodeAt(0)] = true; - -Utf7IMAPDecoder.prototype.write = function(buf) { - var res = "", lastI = 0, - inBase64 = this.inBase64, - base64Accum = this.base64Accum; - - // The decoder is more involved as we must handle chunks in stream. - // It is forgiving, closer to standard UTF-7 (for example, '-' is optional at the end). - - for (var i = 0; i < buf.length; i++) { - if (!inBase64) { // We're in direct mode. - // Write direct chars until '&' - if (buf[i] == andChar) { - res += this.iconv.decode(buf.slice(lastI, i), "ascii"); // Write direct chars. - lastI = i+1; - inBase64 = true; - } - } else { // We decode base64. - if (!base64IMAPChars[buf[i]]) { // Base64 ended. - if (i == lastI && buf[i] == minusChar) { // "&-" -> "&" - res += "&"; - } else { - var b64str = base64Accum + this.iconv.decode(buf.slice(lastI, i), "ascii").replace(/,/g, '/'); - res += this.iconv.decode(Buffer.from(b64str, 'base64'), "utf16-be"); - } - - if (buf[i] != minusChar) // Minus may be absorbed after base64. - i--; - - lastI = i+1; - inBase64 = false; - base64Accum = ''; - } - } - } - - if (!inBase64) { - res += this.iconv.decode(buf.slice(lastI), "ascii"); // Write direct chars. - } else { - var b64str = base64Accum + this.iconv.decode(buf.slice(lastI), "ascii").replace(/,/g, '/'); - - var canBeDecoded = b64str.length - (b64str.length % 8); // Minimal chunk: 2 quads -> 2x3 bytes -> 3 chars. - base64Accum = b64str.slice(canBeDecoded); // The rest will be decoded in future. - b64str = b64str.slice(0, canBeDecoded); - - res += this.iconv.decode(Buffer.from(b64str, 'base64'), "utf16-be"); - } - - this.inBase64 = inBase64; - this.base64Accum = base64Accum; - - return res; -} - -Utf7IMAPDecoder.prototype.end = function() { - var res = ""; - if (this.inBase64 && this.base64Accum.length > 0) - res = this.iconv.decode(Buffer.from(this.base64Accum, 'base64'), "utf16-be"); - - this.inBase64 = false; - this.base64Accum = ''; - return res; -} - - - - -/***/ }), - -/***/ 7961: -/***/ ((__unused_webpack_module, exports) => { - -"use strict"; - - -var BOMChar = '\uFEFF'; - -exports.PrependBOM = PrependBOMWrapper -function PrependBOMWrapper(encoder, options) { - this.encoder = encoder; - this.addBOM = true; -} - -PrependBOMWrapper.prototype.write = function(str) { - if (this.addBOM) { - str = BOMChar + str; - this.addBOM = false; - } - - return this.encoder.write(str); -} - -PrependBOMWrapper.prototype.end = function() { - return this.encoder.end(); -} - - -//------------------------------------------------------------------------------ - -exports.StripBOM = StripBOMWrapper; -function StripBOMWrapper(decoder, options) { - this.decoder = decoder; - this.pass = false; - this.options = options || {}; -} - -StripBOMWrapper.prototype.write = function(buf) { - var res = this.decoder.write(buf); - if (this.pass || !res) - return res; - - if (res[0] === BOMChar) { - res = res.slice(1); - if (typeof this.options.stripBOM === 'function') - this.options.stripBOM(); - } - - this.pass = true; - return res; -} - -StripBOMWrapper.prototype.end = function() { - return this.decoder.end(); -} - - - -/***/ }), - -/***/ 9032: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -"use strict"; - - -var Buffer = (__nccwpck_require__(5118).Buffer); - -var bomHandling = __nccwpck_require__(7961), - iconv = module.exports; - -// All codecs and aliases are kept here, keyed by encoding name/alias. -// They are lazy loaded in `iconv.getCodec` from `encodings/index.js`. -iconv.encodings = null; - -// Characters emitted in case of error. -iconv.defaultCharUnicode = '�'; -iconv.defaultCharSingleByte = '?'; - -// Public API. -iconv.encode = function encode(str, encoding, options) { - str = "" + (str || ""); // Ensure string. - - var encoder = iconv.getEncoder(encoding, options); - - var res = encoder.write(str); - var trail = encoder.end(); - - return (trail && trail.length > 0) ? Buffer.concat([res, trail]) : res; -} - -iconv.decode = function decode(buf, encoding, options) { - if (typeof buf === 'string') { - if (!iconv.skipDecodeWarning) { - console.error('Iconv-lite warning: decode()-ing strings is deprecated. Refer to https://github.com/ashtuchkin/iconv-lite/wiki/Use-Buffers-when-decoding'); - iconv.skipDecodeWarning = true; - } - - buf = Buffer.from("" + (buf || ""), "binary"); // Ensure buffer. - } - - var decoder = iconv.getDecoder(encoding, options); - - var res = decoder.write(buf); - var trail = decoder.end(); - - return trail ? (res + trail) : res; -} - -iconv.encodingExists = function encodingExists(enc) { - try { - iconv.getCodec(enc); - return true; - } catch (e) { - return false; - } -} - -// Legacy aliases to convert functions -iconv.toEncoding = iconv.encode; -iconv.fromEncoding = iconv.decode; - -// Search for a codec in iconv.encodings. Cache codec data in iconv._codecDataCache. -iconv._codecDataCache = {}; -iconv.getCodec = function getCodec(encoding) { - if (!iconv.encodings) - iconv.encodings = __nccwpck_require__(2733); // Lazy load all encoding definitions. - - // Canonicalize encoding name: strip all non-alphanumeric chars and appended year. - var enc = iconv._canonicalizeEncoding(encoding); - - // Traverse iconv.encodings to find actual codec. - var codecOptions = {}; - while (true) { - var codec = iconv._codecDataCache[enc]; - if (codec) - return codec; - - var codecDef = iconv.encodings[enc]; - - switch (typeof codecDef) { - case "string": // Direct alias to other encoding. - enc = codecDef; - break; - - case "object": // Alias with options. Can be layered. - for (var key in codecDef) - codecOptions[key] = codecDef[key]; - - if (!codecOptions.encodingName) - codecOptions.encodingName = enc; - - enc = codecDef.type; - break; - - case "function": // Codec itself. - if (!codecOptions.encodingName) - codecOptions.encodingName = enc; - - // The codec function must load all tables and return object with .encoder and .decoder methods. - // It'll be called only once (for each different options object). - codec = new codecDef(codecOptions, iconv); - - iconv._codecDataCache[codecOptions.encodingName] = codec; // Save it to be reused later. - return codec; - - default: - throw new Error("Encoding not recognized: '" + encoding + "' (searched as: '"+enc+"')"); - } - } -} - -iconv._canonicalizeEncoding = function(encoding) { - // Canonicalize encoding name: strip all non-alphanumeric chars and appended year. - return (''+encoding).toLowerCase().replace(/:\d{4}$|[^0-9a-z]/g, ""); -} - -iconv.getEncoder = function getEncoder(encoding, options) { - var codec = iconv.getCodec(encoding), - encoder = new codec.encoder(options, codec); - - if (codec.bomAware && options && options.addBOM) - encoder = new bomHandling.PrependBOM(encoder, options); - - return encoder; -} - -iconv.getDecoder = function getDecoder(encoding, options) { - var codec = iconv.getCodec(encoding), - decoder = new codec.decoder(options, codec); - - if (codec.bomAware && !(options && options.stripBOM === false)) - decoder = new bomHandling.StripBOM(decoder, options); - - return decoder; -} - -// Streaming API -// NOTE: Streaming API naturally depends on 'stream' module from Node.js. Unfortunately in browser environments this module can add -// up to 100Kb to the output bundle. To avoid unnecessary code bloat, we don't enable Streaming API in browser by default. -// If you would like to enable it explicitly, please add the following code to your app: -// > iconv.enableStreamingAPI(require('stream')); -iconv.enableStreamingAPI = function enableStreamingAPI(stream_module) { - if (iconv.supportsStreams) - return; - - // Dependency-inject stream module to create IconvLite stream classes. - var streams = __nccwpck_require__(6869)(stream_module); - - // Not public API yet, but expose the stream classes. - iconv.IconvLiteEncoderStream = streams.IconvLiteEncoderStream; - iconv.IconvLiteDecoderStream = streams.IconvLiteDecoderStream; - - // Streaming API. - iconv.encodeStream = function encodeStream(encoding, options) { - return new iconv.IconvLiteEncoderStream(iconv.getEncoder(encoding, options), options); - } - - iconv.decodeStream = function decodeStream(encoding, options) { - return new iconv.IconvLiteDecoderStream(iconv.getDecoder(encoding, options), options); - } - - iconv.supportsStreams = true; -} - -// Enable Streaming API automatically if 'stream' module is available and non-empty (the majority of environments). -var stream_module; -try { - stream_module = __nccwpck_require__(2781); -} catch (e) {} - -if (stream_module && stream_module.Transform) { - iconv.enableStreamingAPI(stream_module); - -} else { - // In rare cases where 'stream' module is not available by default, throw a helpful exception. - iconv.encodeStream = iconv.decodeStream = function() { - throw new Error("iconv-lite Streaming API is not enabled. Use iconv.enableStreamingAPI(require('stream')); to enable it."); - }; -} - -if (false) {} - - -/***/ }), - -/***/ 6869: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -"use strict"; - - -var Buffer = (__nccwpck_require__(5118).Buffer); - -// NOTE: Due to 'stream' module being pretty large (~100Kb, significant in browser environments), -// we opt to dependency-inject it instead of creating a hard dependency. -module.exports = function(stream_module) { - var Transform = stream_module.Transform; - - // == Encoder stream ======================================================= - - function IconvLiteEncoderStream(conv, options) { - this.conv = conv; - options = options || {}; - options.decodeStrings = false; // We accept only strings, so we don't need to decode them. - Transform.call(this, options); - } - - IconvLiteEncoderStream.prototype = Object.create(Transform.prototype, { - constructor: { value: IconvLiteEncoderStream } - }); - - IconvLiteEncoderStream.prototype._transform = function(chunk, encoding, done) { - if (typeof chunk != 'string') - return done(new Error("Iconv encoding stream needs strings as its input.")); - try { - var res = this.conv.write(chunk); - if (res && res.length) this.push(res); - done(); - } - catch (e) { - done(e); - } - } - - IconvLiteEncoderStream.prototype._flush = function(done) { - try { - var res = this.conv.end(); - if (res && res.length) this.push(res); - done(); - } - catch (e) { - done(e); - } - } - - IconvLiteEncoderStream.prototype.collect = function(cb) { - var chunks = []; - this.on('error', cb); - this.on('data', function(chunk) { chunks.push(chunk); }); - this.on('end', function() { - cb(null, Buffer.concat(chunks)); - }); - return this; - } - - - // == Decoder stream ======================================================= - - function IconvLiteDecoderStream(conv, options) { - this.conv = conv; - options = options || {}; - options.encoding = this.encoding = 'utf8'; // We output strings. - Transform.call(this, options); - } - - IconvLiteDecoderStream.prototype = Object.create(Transform.prototype, { - constructor: { value: IconvLiteDecoderStream } - }); - - IconvLiteDecoderStream.prototype._transform = function(chunk, encoding, done) { - if (!Buffer.isBuffer(chunk) && !(chunk instanceof Uint8Array)) - return done(new Error("Iconv decoding stream needs buffers as its input.")); - try { - var res = this.conv.write(chunk); - if (res && res.length) this.push(res, this.encoding); - done(); - } - catch (e) { - done(e); - } - } - - IconvLiteDecoderStream.prototype._flush = function(done) { - try { - var res = this.conv.end(); - if (res && res.length) this.push(res, this.encoding); - done(); - } - catch (e) { - done(e); - } - } - - IconvLiteDecoderStream.prototype.collect = function(cb) { - var res = ''; - this.on('error', cb); - this.on('data', function(chunk) { res += chunk; }); - this.on('end', function() { - cb(null, res); - }); - return this; - } - - return { - IconvLiteEncoderStream: IconvLiteEncoderStream, - IconvLiteDecoderStream: IconvLiteDecoderStream, - }; -}; - - -/***/ }), - -/***/ 3287: -/***/ ((__unused_webpack_module, exports) => { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", ({ value: true })); - -/*! - * is-plain-object - * - * Copyright (c) 2014-2017, Jon Schlinkert. - * Released under the MIT License. - */ - -function isObject(o) { - return Object.prototype.toString.call(o) === '[object Object]'; -} - -function isPlainObject(o) { - var ctor,prot; - - if (isObject(o) === false) return false; - - // If has modified constructor - ctor = o.constructor; - if (ctor === undefined) return true; - - // If has modified prototype - prot = ctor.prototype; - if (isObject(prot) === false) return false; - - // If constructor does not have an Object-specific method - if (prot.hasOwnProperty('isPrototypeOf') === false) { - return false; - } - - // Most likely a plain Object - return true; -} - -exports.isPlainObject = isPlainObject; - - -/***/ }), - -/***/ 5902: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var hashClear = __nccwpck_require__(1789), - hashDelete = __nccwpck_require__(712), - hashGet = __nccwpck_require__(5395), - hashHas = __nccwpck_require__(5232), - hashSet = __nccwpck_require__(7320); - -/** - * 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]); - } -} - -// Add methods to `Hash`. -Hash.prototype.clear = hashClear; -Hash.prototype['delete'] = hashDelete; -Hash.prototype.get = hashGet; -Hash.prototype.has = hashHas; -Hash.prototype.set = hashSet; - -module.exports = Hash; - - -/***/ }), - -/***/ 6608: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var listCacheClear = __nccwpck_require__(9792), - listCacheDelete = __nccwpck_require__(7716), - listCacheGet = __nccwpck_require__(5789), - listCacheHas = __nccwpck_require__(9386), - listCacheSet = __nccwpck_require__(7399); - -/** - * 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]); - } -} - -// Add methods to `ListCache`. -ListCache.prototype.clear = listCacheClear; -ListCache.prototype['delete'] = listCacheDelete; -ListCache.prototype.get = listCacheGet; -ListCache.prototype.has = listCacheHas; -ListCache.prototype.set = listCacheSet; - -module.exports = ListCache; - - -/***/ }), - -/***/ 881: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var getNative = __nccwpck_require__(4479), - root = __nccwpck_require__(9882); - -/* Built-in method references that are verified to be native. */ -var Map = getNative(root, 'Map'); - -module.exports = Map; - - -/***/ }), - -/***/ 938: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var mapCacheClear = __nccwpck_require__(1610), - mapCacheDelete = __nccwpck_require__(6657), - mapCacheGet = __nccwpck_require__(1372), - mapCacheHas = __nccwpck_require__(609), - mapCacheSet = __nccwpck_require__(5582); - -/** - * 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]); - } -} - -// Add methods to `MapCache`. -MapCache.prototype.clear = mapCacheClear; -MapCache.prototype['delete'] = mapCacheDelete; -MapCache.prototype.get = mapCacheGet; -MapCache.prototype.has = mapCacheHas; -MapCache.prototype.set = mapCacheSet; - -module.exports = MapCache; - - -/***/ }), - -/***/ 9213: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var root = __nccwpck_require__(9882); - -/** Built-in value references. */ -var Symbol = root.Symbol; - -module.exports = Symbol; - - -/***/ }), - -/***/ 4356: -/***/ ((module) => { - -/** - * 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; -} - -module.exports = arrayMap; - - -/***/ }), - -/***/ 6752: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var eq = __nccwpck_require__(1901); - -/** - * 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; -} - -module.exports = assocIndexOf; - - -/***/ }), - -/***/ 5758: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var castPath = __nccwpck_require__(2688), - toKey = __nccwpck_require__(9071); - -/** - * 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; -} - -module.exports = baseGet; - - -/***/ }), - -/***/ 7497: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var Symbol = __nccwpck_require__(9213), - getRawTag = __nccwpck_require__(923), - objectToString = __nccwpck_require__(4200); - -/** `Object#toString` result references. */ -var nullTag = '[object Null]', - undefinedTag = '[object Undefined]'; - -/** Built-in value references. */ -var symToStringTag = Symbol ? Symbol.toStringTag : undefined; - -/** - * 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); -} - -module.exports = baseGetTag; - - -/***/ }), - -/***/ 411: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var isFunction = __nccwpck_require__(7799), - isMasked = __nccwpck_require__(9058), - isObject = __nccwpck_require__(3334), - toSource = __nccwpck_require__(6928); - -/** - * Used to match `RegExp` - * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). - */ -var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; - -/** Used to detect host constructors (Safari). */ -var reIsHostCtor = /^\[object .+?Constructor\]$/; - -/** Used for built-in method references. */ -var funcProto = Function.prototype, - objectProto = Object.prototype; - -/** 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 detect if a method is native. */ -var reIsNative = RegExp('^' + - funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') - .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' -); - -/** - * 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)); -} - -module.exports = baseIsNative; - - -/***/ }), - -/***/ 6792: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var Symbol = __nccwpck_require__(9213), - arrayMap = __nccwpck_require__(4356), - isArray = __nccwpck_require__(4869), - isSymbol = __nccwpck_require__(6403); - -/** Used as references for various `Number` constants. */ -var INFINITY = 1 / 0; - -/** Used to convert symbols to primitives and strings. */ -var symbolProto = Symbol ? Symbol.prototype : undefined, - symbolToString = symbolProto ? symbolProto.toString : undefined; - -/** - * 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; -} - -module.exports = baseToString; - - -/***/ }), - -/***/ 2688: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var isArray = __nccwpck_require__(4869), - isKey = __nccwpck_require__(9084), - stringToPath = __nccwpck_require__(1853), - toString = __nccwpck_require__(2931); - -/** - * 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)); -} - -module.exports = castPath; - - -/***/ }), - -/***/ 8380: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var root = __nccwpck_require__(9882); - -/** Used to detect overreaching core-js shims. */ -var coreJsData = root['__core-js_shared__']; - -module.exports = coreJsData; - - -/***/ }), - -/***/ 2085: -/***/ ((module) => { - -/** Detect free variable `global` from Node.js. */ -var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; - -module.exports = freeGlobal; - - -/***/ }), - -/***/ 9980: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var isKeyable = __nccwpck_require__(3308); - -/** - * 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; -} - -module.exports = getMapData; - - -/***/ }), - -/***/ 4479: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var baseIsNative = __nccwpck_require__(411), - getValue = __nccwpck_require__(3542); - -/** - * 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; -} - -module.exports = getNative; - - -/***/ }), - -/***/ 923: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var Symbol = __nccwpck_require__(9213); - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; - -/** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. - */ -var nativeObjectToString = objectProto.toString; - -/** Built-in value references. */ -var symToStringTag = Symbol ? Symbol.toStringTag : 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; -} - -module.exports = getRawTag; - - -/***/ }), - -/***/ 3542: -/***/ ((module) => { - -/** - * 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]; -} - -module.exports = getValue; - - -/***/ }), - -/***/ 1789: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var nativeCreate = __nccwpck_require__(3041); - -/** - * Removes all key-value entries from the hash. - * - * @private - * @name clear - * @memberOf Hash - */ -function hashClear() { - this.__data__ = nativeCreate ? nativeCreate(null) : {}; - this.size = 0; -} - -module.exports = hashClear; - - -/***/ }), - -/***/ 712: -/***/ ((module) => { - -/** - * 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; -} - -module.exports = hashDelete; - - -/***/ }), - -/***/ 5395: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var nativeCreate = __nccwpck_require__(3041); - -/** Used to stand-in for `undefined` hash values. */ -var HASH_UNDEFINED = '__lodash_hash_undefined__'; - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; - -/** - * 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; -} - -module.exports = hashGet; - - -/***/ }), - -/***/ 5232: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var nativeCreate = __nccwpck_require__(3041); - -/** Used for built-in method references. */ -var objectProto = Object.prototype; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; - -/** - * 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); -} - -module.exports = hashHas; - - -/***/ }), - -/***/ 7320: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var nativeCreate = __nccwpck_require__(3041); - -/** Used to stand-in for `undefined` hash values. */ -var HASH_UNDEFINED = '__lodash_hash_undefined__'; - -/** - * 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; -} - -module.exports = hashSet; - - -/***/ }), - -/***/ 9084: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var isArray = __nccwpck_require__(4869), - isSymbol = __nccwpck_require__(6403); - -/** Used to match property names within property paths. */ -var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, - reIsPlainProp = /^\w*$/; - -/** - * 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)); -} - -module.exports = isKey; - - -/***/ }), - -/***/ 3308: -/***/ ((module) => { - -/** - * 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); -} - -module.exports = isKeyable; - - -/***/ }), + + // Encode tables: Unicode -> DBCS. -/***/ 9058: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // `encodeTable` is array mapping from unicode char to encoded char. All its values are integers for performance. + // Because it can be sparse, it is represented as array of buckets by 256 chars each. Bucket can be null. + // Values: >= 0 -> it is a normal char. Write the value (if <=256 then 1 byte, if <=65536 then 2 bytes, etc.). + // == UNASSIGNED -> no conversion found. Output a default char. + // <= SEQ_START -> it's an index in encodeTableSeq, see below. The character starts a sequence. + this.encodeTable = []; + + // `encodeTableSeq` is used when a sequence of unicode characters is encoded as a single code. We use a tree of + // objects where keys correspond to characters in sequence and leafs are the encoded dbcs values. A special DEF_CHAR key + // means end of sequence (needed when one sequence is a strict subsequence of another). + // Objects are kept separately from encodeTable to increase performance. + this.encodeTableSeq = []; -var coreJsData = __nccwpck_require__(8380); + // Some chars can be decoded, but need not be encoded. + var skipEncodeChars = {}; + if (codecOptions.encodeSkipVals) + for (var i = 0; i < codecOptions.encodeSkipVals.length; i++) { + var val = codecOptions.encodeSkipVals[i]; + if (typeof val === 'number') + skipEncodeChars[val] = true; + else + for (var j = val.from; j <= val.to; j++) + skipEncodeChars[j] = true; + } + + // Use decode trie to recursively fill out encode tables. + this._fillEncodeTable(0, 0, skipEncodeChars); -/** 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) : ''; -}()); + // Add more encoding pairs when needed. + if (codecOptions.encodeAdd) { + for (var uChar in codecOptions.encodeAdd) + if (Object.prototype.hasOwnProperty.call(codecOptions.encodeAdd, uChar)) + this._setEncodeChar(uChar.charCodeAt(0), codecOptions.encodeAdd[uChar]); + } -/** - * 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); + this.defCharSB = this.encodeTable[0][iconv.defaultCharSingleByte.charCodeAt(0)]; + if (this.defCharSB === UNASSIGNED) this.defCharSB = this.encodeTable[0]['?']; + if (this.defCharSB === UNASSIGNED) this.defCharSB = "?".charCodeAt(0); } -module.exports = isMasked; - +DBCSCodec.prototype.encoder = DBCSEncoder; +DBCSCodec.prototype.decoder = DBCSDecoder; -/***/ }), +// Decoder helpers +DBCSCodec.prototype._getDecodeTrieNode = function(addr) { + var bytes = []; + for (; addr > 0; addr >>>= 8) + bytes.push(addr & 0xFF); + if (bytes.length == 0) + bytes.push(0); -/***/ 9792: -/***/ ((module) => { + var node = this.decodeTables[0]; + for (var i = bytes.length-1; i > 0; i--) { // Traverse nodes deeper into the trie. + var val = node[bytes[i]]; -/** - * Removes all key-value entries from the list cache. - * - * @private - * @name clear - * @memberOf ListCache - */ -function listCacheClear() { - this.__data__ = []; - this.size = 0; + if (val == UNASSIGNED) { // Create new node. + node[bytes[i]] = NODE_START - this.decodeTables.length; + this.decodeTables.push(node = UNASSIGNED_NODE.slice(0)); + } + else if (val <= NODE_START) { // Existing node. + node = this.decodeTables[NODE_START - val]; + } + else + throw new Error("Overwrite byte in " + this.encodingName + ", addr: " + addr.toString(16)); + } + return node; } -module.exports = listCacheClear; - - -/***/ }), -/***/ 7716: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var assocIndexOf = __nccwpck_require__(6752); +DBCSCodec.prototype._addDecodeChunk = function(chunk) { + // First element of chunk is the hex mbcs code where we start. + var curAddr = parseInt(chunk[0], 16); -/** Used for built-in method references. */ -var arrayProto = Array.prototype; + // Choose the decoding node where we'll write our chars. + var writeTable = this._getDecodeTrieNode(curAddr); + curAddr = curAddr & 0xFF; -/** Built-in value references. */ -var splice = arrayProto.splice; + // Write all other elements of the chunk to the table. + for (var k = 1; k < chunk.length; k++) { + var part = chunk[k]; + if (typeof part === "string") { // String, write as-is. + for (var l = 0; l < part.length;) { + var code = part.charCodeAt(l++); + if (0xD800 <= code && code < 0xDC00) { // Decode surrogate + var codeTrail = part.charCodeAt(l++); + if (0xDC00 <= codeTrail && codeTrail < 0xE000) + writeTable[curAddr++] = 0x10000 + (code - 0xD800) * 0x400 + (codeTrail - 0xDC00); + else + throw new Error("Incorrect surrogate pair in " + this.encodingName + " at chunk " + chunk[0]); + } + else if (0x0FF0 < code && code <= 0x0FFF) { // Character sequence (our own encoding used) + var len = 0xFFF - code + 2; + var seq = []; + for (var m = 0; m < len; m++) + seq.push(part.charCodeAt(l++)); // Simple variation: don't support surrogates or subsequences in seq. -/** - * 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); + writeTable[curAddr++] = SEQ_START - this.decodeTableSeq.length; + this.decodeTableSeq.push(seq); + } + else + writeTable[curAddr++] = code; // Basic char + } + } + else if (typeof part === "number") { // Integer, meaning increasing sequence starting with prev character. + var charCode = writeTable[curAddr - 1] + 1; + for (var l = 0; l < part; l++) + writeTable[curAddr++] = charCode++; + } + else + throw new Error("Incorrect type '" + typeof part + "' given in " + this.encodingName + " at chunk " + chunk[0]); + } + if (curAddr > 0xFF) + throw new Error("Incorrect chunk in " + this.encodingName + " at addr " + chunk[0] + ": too long" + curAddr); +} - 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; +// Encoder helpers +DBCSCodec.prototype._getEncodeBucket = function(uCode) { + var high = uCode >> 8; // This could be > 0xFF because of astral characters. + if (this.encodeTable[high] === undefined) + this.encodeTable[high] = UNASSIGNED_NODE.slice(0); // Create bucket on demand. + return this.encodeTable[high]; } -module.exports = listCacheDelete; +DBCSCodec.prototype._setEncodeChar = function(uCode, dbcsCode) { + var bucket = this._getEncodeBucket(uCode); + var low = uCode & 0xFF; + if (bucket[low] <= SEQ_START) + this.encodeTableSeq[SEQ_START-bucket[low]][DEF_CHAR] = dbcsCode; // There's already a sequence, set a single-char subsequence of it. + else if (bucket[low] == UNASSIGNED) + bucket[low] = dbcsCode; +} +DBCSCodec.prototype._setEncodeSequence = function(seq, dbcsCode) { + + // Get the root of character tree according to first character of the sequence. + var uCode = seq[0]; + var bucket = this._getEncodeBucket(uCode); + var low = uCode & 0xFF; -/***/ }), + var node; + if (bucket[low] <= SEQ_START) { + // There's already a sequence with - use it. + node = this.encodeTableSeq[SEQ_START-bucket[low]]; + } + else { + // There was no sequence object - allocate a new one. + node = {}; + if (bucket[low] !== UNASSIGNED) node[DEF_CHAR] = bucket[low]; // If a char was set before - make it a single-char subsequence. + bucket[low] = SEQ_START - this.encodeTableSeq.length; + this.encodeTableSeq.push(node); + } -/***/ 5789: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // Traverse the character tree, allocating new nodes as needed. + for (var j = 1; j < seq.length-1; j++) { + var oldVal = node[uCode]; + if (typeof oldVal === 'object') + node = oldVal; + else { + node = node[uCode] = {} + if (oldVal !== undefined) + node[DEF_CHAR] = oldVal + } + } -var assocIndexOf = __nccwpck_require__(6752); + // Set the leaf to given dbcsCode. + uCode = seq[seq.length-1]; + node[uCode] = dbcsCode; +} -/** - * 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); +DBCSCodec.prototype._fillEncodeTable = function(nodeIdx, prefix, skipEncodeChars) { + var node = this.decodeTables[nodeIdx]; + var hasValues = false; + var subNodeEmpty = {}; + for (var i = 0; i < 0x100; i++) { + var uCode = node[i]; + var mbCode = prefix + i; + if (skipEncodeChars[mbCode]) + continue; - return index < 0 ? undefined : data[index][1]; + if (uCode >= 0) { + this._setEncodeChar(uCode, mbCode); + hasValues = true; + } else if (uCode <= NODE_START) { + var subNodeIdx = NODE_START - uCode; + if (!subNodeEmpty[subNodeIdx]) { // Skip empty subtrees (they are too large in gb18030). + var newPrefix = (mbCode << 8) >>> 0; // NOTE: '>>> 0' keeps 32-bit num positive. + if (this._fillEncodeTable(subNodeIdx, newPrefix, skipEncodeChars)) + hasValues = true; + else + subNodeEmpty[subNodeIdx] = true; + } + } else if (uCode <= SEQ_START) { + this._setEncodeSequence(this.decodeTableSeq[SEQ_START - uCode], mbCode); + hasValues = true; + } + } + return hasValues; } -module.exports = listCacheGet; -/***/ }), +// == Encoder ================================================================== -/***/ 9386: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +function DBCSEncoder(options, codec) { + // Encoder state + this.leadSurrogate = -1; + this.seqObj = undefined; + + // Static data + this.encodeTable = codec.encodeTable; + this.encodeTableSeq = codec.encodeTableSeq; + this.defaultCharSingleByte = codec.defCharSB; + this.gb18030 = codec.gb18030; +} -var assocIndexOf = __nccwpck_require__(6752); +DBCSEncoder.prototype.write = function(str) { + var newBuf = Buffer.alloc(str.length * (this.gb18030 ? 4 : 3)), + leadSurrogate = this.leadSurrogate, + seqObj = this.seqObj, nextChar = -1, + i = 0, j = 0; -/** - * 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; -} + while (true) { + // 0. Get next character. + if (nextChar === -1) { + if (i == str.length) break; + var uCode = str.charCodeAt(i++); + } + else { + var uCode = nextChar; + nextChar = -1; + } -module.exports = listCacheHas; + // 1. Handle surrogates. + if (0xD800 <= uCode && uCode < 0xE000) { // Char is one of surrogates. + if (uCode < 0xDC00) { // We've got lead surrogate. + if (leadSurrogate === -1) { + leadSurrogate = uCode; + continue; + } else { + leadSurrogate = uCode; + // Double lead surrogate found. + uCode = UNASSIGNED; + } + } else { // We've got trail surrogate. + if (leadSurrogate !== -1) { + uCode = 0x10000 + (leadSurrogate - 0xD800) * 0x400 + (uCode - 0xDC00); + leadSurrogate = -1; + } else { + // Incomplete surrogate pair - only trail surrogate found. + uCode = UNASSIGNED; + } + + } + } + else if (leadSurrogate !== -1) { + // Incomplete surrogate pair - only lead surrogate found. + nextChar = uCode; uCode = UNASSIGNED; // Write an error, then current char. + leadSurrogate = -1; + } + + // 2. Convert uCode character. + var dbcsCode = UNASSIGNED; + if (seqObj !== undefined && uCode != UNASSIGNED) { // We are in the middle of the sequence + var resCode = seqObj[uCode]; + if (typeof resCode === 'object') { // Sequence continues. + seqObj = resCode; + continue; + } else if (typeof resCode == 'number') { // Sequence finished. Write it. + dbcsCode = resCode; -/***/ }), + } else if (resCode == undefined) { // Current character is not part of the sequence. -/***/ 7399: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // Try default character for this sequence + resCode = seqObj[DEF_CHAR]; + if (resCode !== undefined) { + dbcsCode = resCode; // Found. Write it. + nextChar = uCode; // Current character will be written too in the next iteration. -var assocIndexOf = __nccwpck_require__(6752); + } else { + // TODO: What if we have no default? (resCode == undefined) + // Then, we should write first char of the sequence as-is and try the rest recursively. + // Didn't do it for now because no encoding has this situation yet. + // Currently, just skip the sequence and write current char. + } + } + seqObj = undefined; + } + else if (uCode >= 0) { // Regular character + var subtable = this.encodeTable[uCode >> 8]; + if (subtable !== undefined) + dbcsCode = subtable[uCode & 0xFF]; + + if (dbcsCode <= SEQ_START) { // Sequence start + seqObj = this.encodeTableSeq[SEQ_START-dbcsCode]; + continue; + } -/** - * 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 (dbcsCode == UNASSIGNED && this.gb18030) { + // Use GB18030 algorithm to find character(s) to write. + var idx = findIdx(this.gb18030.uChars, uCode); + if (idx != -1) { + var dbcsCode = this.gb18030.gbChars[idx] + (uCode - this.gb18030.uChars[idx]); + newBuf[j++] = 0x81 + Math.floor(dbcsCode / 12600); dbcsCode = dbcsCode % 12600; + newBuf[j++] = 0x30 + Math.floor(dbcsCode / 1260); dbcsCode = dbcsCode % 1260; + newBuf[j++] = 0x81 + Math.floor(dbcsCode / 10); dbcsCode = dbcsCode % 10; + newBuf[j++] = 0x30 + dbcsCode; + continue; + } + } + } + + // 3. Write dbcsCode character. + if (dbcsCode === UNASSIGNED) + dbcsCode = this.defaultCharSingleByte; + + if (dbcsCode < 0x100) { + newBuf[j++] = dbcsCode; + } + else if (dbcsCode < 0x10000) { + newBuf[j++] = dbcsCode >> 8; // high byte + newBuf[j++] = dbcsCode & 0xFF; // low byte + } + else if (dbcsCode < 0x1000000) { + newBuf[j++] = dbcsCode >> 16; + newBuf[j++] = (dbcsCode >> 8) & 0xFF; + newBuf[j++] = dbcsCode & 0xFF; + } else { + newBuf[j++] = dbcsCode >>> 24; + newBuf[j++] = (dbcsCode >>> 16) & 0xFF; + newBuf[j++] = (dbcsCode >>> 8) & 0xFF; + newBuf[j++] = dbcsCode & 0xFF; + } + } - if (index < 0) { - ++this.size; - data.push([key, value]); - } else { - data[index][1] = value; - } - return this; + this.seqObj = seqObj; + this.leadSurrogate = leadSurrogate; + return newBuf.slice(0, j); } -module.exports = listCacheSet; +DBCSEncoder.prototype.end = function() { + if (this.leadSurrogate === -1 && this.seqObj === undefined) + return; // All clean. Most often case. + var newBuf = Buffer.alloc(10), j = 0; -/***/ }), + if (this.seqObj) { // We're in the sequence. + var dbcsCode = this.seqObj[DEF_CHAR]; + if (dbcsCode !== undefined) { // Write beginning of the sequence. + if (dbcsCode < 0x100) { + newBuf[j++] = dbcsCode; + } + else { + newBuf[j++] = dbcsCode >> 8; // high byte + newBuf[j++] = dbcsCode & 0xFF; // low byte + } + } else { + // See todo above. + } + this.seqObj = undefined; + } -/***/ 1610: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (this.leadSurrogate !== -1) { + // Incomplete surrogate pair - only lead surrogate found. + newBuf[j++] = this.defaultCharSingleByte; + this.leadSurrogate = -1; + } + + return newBuf.slice(0, j); +} -var Hash = __nccwpck_require__(5902), - ListCache = __nccwpck_require__(6608), - Map = __nccwpck_require__(881); +// Export for testing +DBCSEncoder.prototype.findIdx = findIdx; -/** - * 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 - }; -} -module.exports = mapCacheClear; +// == Decoder ================================================================== +function DBCSDecoder(options, codec) { + // Decoder state + this.nodeIdx = 0; + this.prevBytes = []; -/***/ }), + // Static data + this.decodeTables = codec.decodeTables; + this.decodeTableSeq = codec.decodeTableSeq; + this.defaultCharUnicode = codec.defaultCharUnicode; + this.gb18030 = codec.gb18030; +} -/***/ 6657: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +DBCSDecoder.prototype.write = function(buf) { + var newBuf = Buffer.alloc(buf.length*2), + nodeIdx = this.nodeIdx, + prevBytes = this.prevBytes, prevOffset = this.prevBytes.length, + seqStart = -this.prevBytes.length, // idx of the start of current parsed sequence. + uCode; -var getMapData = __nccwpck_require__(9980); + for (var i = 0, j = 0; i < buf.length; i++) { + var curByte = (i >= 0) ? buf[i] : prevBytes[i + prevOffset]; -/** - * 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; -} + // Lookup in current trie node. + var uCode = this.decodeTables[nodeIdx][curByte]; -module.exports = mapCacheDelete; + if (uCode >= 0) { + // Normal character, just use it. + } + else if (uCode === UNASSIGNED) { // Unknown char. + // TODO: Callback with seq. + uCode = this.defaultCharUnicode.charCodeAt(0); + i = seqStart; // Skip one byte ('i' will be incremented by the for loop) and try to parse again. + } + else if (uCode === GB18030_CODE) { + if (i >= 3) { + var ptr = (buf[i-3]-0x81)*12600 + (buf[i-2]-0x30)*1260 + (buf[i-1]-0x81)*10 + (curByte-0x30); + } else { + var ptr = (prevBytes[i-3+prevOffset]-0x81)*12600 + + (((i-2 >= 0) ? buf[i-2] : prevBytes[i-2+prevOffset])-0x30)*1260 + + (((i-1 >= 0) ? buf[i-1] : prevBytes[i-1+prevOffset])-0x81)*10 + + (curByte-0x30); + } + var idx = findIdx(this.gb18030.gbChars, ptr); + uCode = this.gb18030.uChars[idx] + ptr - this.gb18030.gbChars[idx]; + } + else if (uCode <= NODE_START) { // Go to next trie node. + nodeIdx = NODE_START - uCode; + continue; + } + else if (uCode <= SEQ_START) { // Output a sequence of chars. + var seq = this.decodeTableSeq[SEQ_START - uCode]; + for (var k = 0; k < seq.length - 1; k++) { + uCode = seq[k]; + newBuf[j++] = uCode & 0xFF; + newBuf[j++] = uCode >> 8; + } + uCode = seq[seq.length-1]; + } + else + throw new Error("iconv-lite internal error: invalid decoding table value " + uCode + " at " + nodeIdx + "/" + curByte); + // Write the character to buffer, handling higher planes using surrogate pair. + if (uCode >= 0x10000) { + uCode -= 0x10000; + var uCodeLead = 0xD800 | (uCode >> 10); + newBuf[j++] = uCodeLead & 0xFF; + newBuf[j++] = uCodeLead >> 8; -/***/ }), + uCode = 0xDC00 | (uCode & 0x3FF); + } + newBuf[j++] = uCode & 0xFF; + newBuf[j++] = uCode >> 8; -/***/ 1372: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // Reset trie node. + nodeIdx = 0; seqStart = i+1; + } -var getMapData = __nccwpck_require__(9980); + this.nodeIdx = nodeIdx; + this.prevBytes = (seqStart >= 0) + ? Array.prototype.slice.call(buf, seqStart) + : prevBytes.slice(seqStart + prevOffset).concat(Array.prototype.slice.call(buf)); -/** - * 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); + return newBuf.slice(0, j).toString('ucs2'); } -module.exports = mapCacheGet; +DBCSDecoder.prototype.end = function() { + var ret = ''; + // Try to parse all remaining chars. + while (this.prevBytes.length > 0) { + // Skip 1 character in the buffer. + ret += this.defaultCharUnicode; + var bytesArr = this.prevBytes.slice(1); -/***/ }), + // Parse remaining as usual. + this.prevBytes = []; + this.nodeIdx = 0; + if (bytesArr.length > 0) + ret += this.write(bytesArr); + } -/***/ 609: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + this.prevBytes = []; + this.nodeIdx = 0; + return ret; +} -var getMapData = __nccwpck_require__(9980); +// Binary search for GB18030. Returns largest i such that table[i] <= val. +function findIdx(table, val) { + if (table[0] > val) + return -1; -/** - * 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); + var l = 0, r = table.length; + while (l < r-1) { // always table[l] <= val < table[r] + var mid = l + ((r-l+1) >> 1); + if (table[mid] <= val) + l = mid; + else + r = mid; + } + return l; } -module.exports = mapCacheHas; /***/ }), -/***/ 5582: +/***/ 1386: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -var getMapData = __nccwpck_require__(9980); - -/** - * 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; -} - -module.exports = mapCacheSet; +"use strict"; -/***/ }), +// Description of supported double byte encodings and aliases. +// Tables are not require()-d until they are needed to speed up library load. +// require()-s are direct to support Browserify. -/***/ 9422: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +module.exports = { + + // == Japanese/ShiftJIS ==================================================== + // All japanese encodings are based on JIS X set of standards: + // JIS X 0201 - Single-byte encoding of ASCII + ¥ + Kana chars at 0xA1-0xDF. + // JIS X 0208 - Main set of 6879 characters, placed in 94x94 plane, to be encoded by 2 bytes. + // Has several variations in 1978, 1983, 1990 and 1997. + // JIS X 0212 - Supplementary plane of 6067 chars in 94x94 plane. 1990. Effectively dead. + // JIS X 0213 - Extension and modern replacement of 0208 and 0212. Total chars: 11233. + // 2 planes, first is superset of 0208, second - revised 0212. + // Introduced in 2000, revised 2004. Some characters are in Unicode Plane 2 (0x2xxxx) -var memoize = __nccwpck_require__(9885); + // Byte encodings are: + // * Shift_JIS: Compatible with 0201, uses not defined chars in top half as lead bytes for double-byte + // encoding of 0208. Lead byte ranges: 0x81-0x9F, 0xE0-0xEF; Trail byte ranges: 0x40-0x7E, 0x80-0x9E, 0x9F-0xFC. + // Windows CP932 is a superset of Shift_JIS. Some companies added more chars, notably KDDI. + // * EUC-JP: Up to 3 bytes per character. Used mostly on *nixes. + // 0x00-0x7F - lower part of 0201 + // 0x8E, 0xA1-0xDF - upper part of 0201 + // (0xA1-0xFE)x2 - 0208 plane (94x94). + // 0x8F, (0xA1-0xFE)x2 - 0212 plane (94x94). + // * JIS X 208: 7-bit, direct encoding of 0208. Byte ranges: 0x21-0x7E (94 values). Uncommon. + // Used as-is in ISO2022 family. + // * ISO2022-JP: Stateful encoding, with escape sequences to switch between ASCII, + // 0201-1976 Roman, 0208-1978, 0208-1983. + // * ISO2022-JP-1: Adds esc seq for 0212-1990. + // * ISO2022-JP-2: Adds esc seq for GB2313-1980, KSX1001-1992, ISO8859-1, ISO8859-7. + // * ISO2022-JP-3: Adds esc seq for 0201-1976 Kana set, 0213-2000 Planes 1, 2. + // * ISO2022-JP-2004: Adds 0213-2004 Plane 1. + // + // After JIS X 0213 appeared, Shift_JIS-2004, EUC-JISX0213 and ISO2022-JP-2004 followed, with just changing the planes. + // + // Overall, it seems that it's a mess :( http://www8.plala.or.jp/tkubota1/unicode-symbols-map2.html -/** Used as the maximum memoize cache size. */ -var MAX_MEMOIZE_SIZE = 500; + 'shiftjis': { + type: '_dbcs', + table: function() { return __nccwpck_require__(7014) }, + encodeAdd: {'\u00a5': 0x5C, '\u203E': 0x7E}, + encodeSkipVals: [{from: 0xED40, to: 0xF940}], + }, + 'csshiftjis': 'shiftjis', + 'mskanji': 'shiftjis', + 'sjis': 'shiftjis', + 'windows31j': 'shiftjis', + 'ms31j': 'shiftjis', + 'xsjis': 'shiftjis', + 'windows932': 'shiftjis', + 'ms932': 'shiftjis', + '932': 'shiftjis', + 'cp932': 'shiftjis', -/** - * 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; - }); + 'eucjp': { + type: '_dbcs', + table: function() { return __nccwpck_require__(1532) }, + encodeAdd: {'\u00a5': 0x5C, '\u203E': 0x7E}, + }, - var cache = result.cache; - return result; -} + // TODO: KDDI extension to Shift_JIS + // TODO: IBM CCSID 942 = CP932, but F0-F9 custom chars and other char changes. + // TODO: IBM CCSID 943 = Shift_JIS = CP932 with original Shift_JIS lower 128 chars. -module.exports = memoizeCapped; + // == Chinese/GBK ========================================================== + // http://en.wikipedia.org/wiki/GBK + // We mostly implement W3C recommendation: https://www.w3.org/TR/encoding/#gbk-encoder -/***/ }), + // Oldest GB2312 (1981, ~7600 chars) is a subset of CP936 + 'gb2312': 'cp936', + 'gb231280': 'cp936', + 'gb23121980': 'cp936', + 'csgb2312': 'cp936', + 'csiso58gb231280': 'cp936', + 'euccn': 'cp936', -/***/ 3041: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // Microsoft's CP936 is a subset and approximation of GBK. + 'windows936': 'cp936', + 'ms936': 'cp936', + '936': 'cp936', + 'cp936': { + type: '_dbcs', + table: function() { return __nccwpck_require__(3336) }, + }, -var getNative = __nccwpck_require__(4479); + // GBK (~22000 chars) is an extension of CP936 that added user-mapped chars and some other. + 'gbk': { + type: '_dbcs', + table: function() { return (__nccwpck_require__(3336).concat)(__nccwpck_require__(4346)) }, + }, + 'xgbk': 'gbk', + 'isoir58': 'gbk', -/* Built-in method references that are verified to be native. */ -var nativeCreate = getNative(Object, 'create'); + // GB18030 is an algorithmic extension of GBK. + // Main source: https://www.w3.org/TR/encoding/#gbk-encoder + // http://icu-project.org/docs/papers/gb18030.html + // http://source.icu-project.org/repos/icu/data/trunk/charset/data/xml/gb-18030-2000.xml + // http://www.khngai.com/chinese/charmap/tblgbk.php?page=0 + 'gb18030': { + type: '_dbcs', + table: function() { return (__nccwpck_require__(3336).concat)(__nccwpck_require__(4346)) }, + gb18030: function() { return __nccwpck_require__(6258) }, + encodeSkipVals: [0x80], + encodeAdd: {'€': 0xA2E3}, + }, -module.exports = nativeCreate; + 'chinese': 'gb18030', -/***/ }), + // == Korean =============================================================== + // EUC-KR, KS_C_5601 and KS X 1001 are exactly the same. + 'windows949': 'cp949', + 'ms949': 'cp949', + '949': 'cp949', + 'cp949': { + type: '_dbcs', + table: function() { return __nccwpck_require__(7348) }, + }, -/***/ 4200: -/***/ ((module) => { + 'cseuckr': 'cp949', + 'csksc56011987': 'cp949', + 'euckr': 'cp949', + 'isoir149': 'cp949', + 'korean': 'cp949', + 'ksc56011987': 'cp949', + 'ksc56011989': 'cp949', + 'ksc5601': 'cp949', -/** Used for built-in method references. */ -var objectProto = Object.prototype; -/** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. - */ -var nativeObjectToString = objectProto.toString; + // == Big5/Taiwan/Hong Kong ================================================ + // There are lots of tables for Big5 and cp950. Please see the following links for history: + // http://moztw.org/docs/big5/ http://www.haible.de/bruno/charsets/conversion-tables/Big5.html + // Variations, in roughly number of defined chars: + // * Windows CP 950: Microsoft variant of Big5. Canonical: http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP950.TXT + // * Windows CP 951: Microsoft variant of Big5-HKSCS-2001. Seems to be never public. http://me.abelcheung.org/articles/research/what-is-cp951/ + // * Big5-2003 (Taiwan standard) almost superset of cp950. + // * Unicode-at-on (UAO) / Mozilla 1.8. Falling out of use on the Web. Not supported by other browsers. + // * Big5-HKSCS (-2001, -2004, -2008). Hong Kong standard. + // many unicode code points moved from PUA to Supplementary plane (U+2XXXX) over the years. + // Plus, it has 4 combining sequences. + // Seems that Mozilla refused to support it for 10 yrs. https://bugzilla.mozilla.org/show_bug.cgi?id=162431 https://bugzilla.mozilla.org/show_bug.cgi?id=310299 + // because big5-hkscs is the only encoding to include astral characters in non-algorithmic way. + // Implementations are not consistent within browsers; sometimes labeled as just big5. + // MS Internet Explorer switches from big5 to big5-hkscs when a patch applied. + // Great discussion & recap of what's going on https://bugzilla.mozilla.org/show_bug.cgi?id=912470#c31 + // In the encoder, it might make sense to support encoding old PUA mappings to Big5 bytes seq-s. + // Official spec: http://www.ogcio.gov.hk/en/business/tech_promotion/ccli/terms/doc/2003cmp_2008.txt + // http://www.ogcio.gov.hk/tc/business/tech_promotion/ccli/terms/doc/hkscs-2008-big5-iso.txt + // + // Current understanding of how to deal with Big5(-HKSCS) is in the Encoding Standard, http://encoding.spec.whatwg.org/#big5-encoder + // Unicode mapping (http://www.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/OTHER/BIG5.TXT) is said to be wrong. -/** - * 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); -} + 'windows950': 'cp950', + 'ms950': 'cp950', + '950': 'cp950', + 'cp950': { + type: '_dbcs', + table: function() { return __nccwpck_require__(4284) }, + }, -module.exports = objectToString; + // Big5 has many variations and is an extension of cp950. We use Encoding Standard's as a consensus. + 'big5': 'big5hkscs', + 'big5hkscs': { + type: '_dbcs', + table: function() { return (__nccwpck_require__(4284).concat)(__nccwpck_require__(3480)) }, + encodeSkipVals: [ + // Although Encoding Standard says we should avoid encoding to HKSCS area (See Step 1 of + // https://encoding.spec.whatwg.org/#index-big5-pointer), we still do it to increase compatibility with ICU. + // But if a single unicode point can be encoded both as HKSCS and regular Big5, we prefer the latter. + 0x8e69, 0x8e6f, 0x8e7e, 0x8eab, 0x8eb4, 0x8ecd, 0x8ed0, 0x8f57, 0x8f69, 0x8f6e, 0x8fcb, 0x8ffe, + 0x906d, 0x907a, 0x90c4, 0x90dc, 0x90f1, 0x91bf, 0x92af, 0x92b0, 0x92b1, 0x92b2, 0x92d1, 0x9447, 0x94ca, + 0x95d9, 0x96fc, 0x9975, 0x9b76, 0x9b78, 0x9b7b, 0x9bc6, 0x9bde, 0x9bec, 0x9bf6, 0x9c42, 0x9c53, 0x9c62, + 0x9c68, 0x9c6b, 0x9c77, 0x9cbc, 0x9cbd, 0x9cd0, 0x9d57, 0x9d5a, 0x9dc4, 0x9def, 0x9dfb, 0x9ea9, 0x9eef, + 0x9efd, 0x9f60, 0x9fcb, 0xa077, 0xa0dc, 0xa0df, 0x8fcc, 0x92c8, 0x9644, 0x96ed, + + // Step 2 of https://encoding.spec.whatwg.org/#index-big5-pointer: Use last pointer for U+2550, U+255E, U+2561, U+256A, U+5341, or U+5345 + 0xa2a4, 0xa2a5, 0xa2a7, 0xa2a6, 0xa2cc, 0xa2ce, + ], + }, + + 'cnbig5': 'big5hkscs', + 'csbig5': 'big5hkscs', + 'xxbig5': 'big5hkscs', +}; /***/ }), -/***/ 9882: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 2733: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -var freeGlobal = __nccwpck_require__(2085); +"use strict"; -/** 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')(); +// Update this array if you add/rename/remove files in this directory. +// We support Browserify by skipping automatic module discovery and requiring modules directly. +var modules = [ + __nccwpck_require__(2376), + __nccwpck_require__(9557), + __nccwpck_require__(1155), + __nccwpck_require__(1644), + __nccwpck_require__(373), + __nccwpck_require__(1080), + __nccwpck_require__(1012), + __nccwpck_require__(9695), + __nccwpck_require__(1386), +]; -module.exports = root; +// Put all encoding/alias/codec definitions to single object and export it. +for (var i = 0; i < modules.length; i++) { + var module = modules[i]; + for (var enc in module) + if (Object.prototype.hasOwnProperty.call(module, enc)) + exports[enc] = module[enc]; +} /***/ }), -/***/ 1853: +/***/ 2376: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -var memoizeCapped = __nccwpck_require__(9422); +"use strict"; -/** Used to match property names within property paths. */ -var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; +var Buffer = (__nccwpck_require__(5118).Buffer); -/** Used to match backslashes in property paths. */ -var reEscapeChar = /\\(\\)?/g; +// Export Node.js internal encodings. -/** - * 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; -}); +module.exports = { + // Encodings + utf8: { type: "_internal", bomAware: true}, + cesu8: { type: "_internal", bomAware: true}, + unicode11utf8: "utf8", -module.exports = stringToPath; + ucs2: { type: "_internal", bomAware: true}, + utf16le: "ucs2", + binary: { type: "_internal" }, + base64: { type: "_internal" }, + hex: { type: "_internal" }, -/***/ }), + // Codec. + _internal: InternalCodec, +}; -/***/ 9071: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +//------------------------------------------------------------------------------ -var isSymbol = __nccwpck_require__(6403); +function InternalCodec(codecOptions, iconv) { + this.enc = codecOptions.encodingName; + this.bomAware = codecOptions.bomAware; -/** Used as references for various `Number` constants. */ -var INFINITY = 1 / 0; + if (this.enc === "base64") + this.encoder = InternalEncoderBase64; + else if (this.enc === "cesu8") { + this.enc = "utf8"; // Use utf8 for decoding. + this.encoder = InternalEncoderCesu8; -/** - * 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; + // Add decoder for versions of Node not supporting CESU-8 + if (Buffer.from('eda0bdedb2a9', 'hex').toString() !== '💩') { + this.decoder = InternalDecoderCesu8; + this.defaultCharUnicode = iconv.defaultCharUnicode; + } + } } -module.exports = toKey; - +InternalCodec.prototype.encoder = InternalEncoder; +InternalCodec.prototype.decoder = InternalDecoder; -/***/ }), +//------------------------------------------------------------------------------ -/***/ 6928: -/***/ ((module) => { +// We use node.js internal decoder. Its signature is the same as ours. +var StringDecoder = (__nccwpck_require__(1576).StringDecoder); -/** Used for built-in method references. */ -var funcProto = Function.prototype; +if (!StringDecoder.prototype.end) // Node v0.8 doesn't have this method. + StringDecoder.prototype.end = function() {}; -/** Used to resolve the decompiled source of functions. */ -var funcToString = funcProto.toString; -/** - * 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 ''; +function InternalDecoder(options, codec) { + this.decoder = new StringDecoder(codec.enc); } -module.exports = toSource; +InternalDecoder.prototype.write = function(buf) { + if (!Buffer.isBuffer(buf)) { + buf = Buffer.from(buf); + } + return this.decoder.write(buf); +} -/***/ }), +InternalDecoder.prototype.end = function() { + return this.decoder.end(); +} -/***/ 1901: -/***/ ((module) => { -/** - * 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); -} +//------------------------------------------------------------------------------ +// Encoder is mostly trivial -module.exports = eq; +function InternalEncoder(options, codec) { + this.enc = codec.enc; +} +InternalEncoder.prototype.write = function(str) { + return Buffer.from(str, this.enc); +} -/***/ }), +InternalEncoder.prototype.end = function() { +} -/***/ 6908: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -var baseGet = __nccwpck_require__(5758); +//------------------------------------------------------------------------------ +// Except base64 encoder, which must keep its state. -/** - * 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; +function InternalEncoderBase64(options, codec) { + this.prevStr = ''; } -module.exports = get; +InternalEncoderBase64.prototype.write = function(str) { + str = this.prevStr + str; + var completeQuads = str.length - (str.length % 4); + this.prevStr = str.slice(completeQuads); + str = str.slice(0, completeQuads); + return Buffer.from(str, "base64"); +} -/***/ }), +InternalEncoderBase64.prototype.end = function() { + return Buffer.from(this.prevStr, "base64"); +} -/***/ 4869: -/***/ ((module) => { -/** - * 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; +//------------------------------------------------------------------------------ +// CESU-8 encoder is also special. -module.exports = isArray; +function InternalEncoderCesu8(options, codec) { +} +InternalEncoderCesu8.prototype.write = function(str) { + var buf = Buffer.alloc(str.length * 3), bufIdx = 0; + for (var i = 0; i < str.length; i++) { + var charCode = str.charCodeAt(i); + // Naive implementation, but it works because CESU-8 is especially easy + // to convert from UTF-16 (which all JS strings are encoded in). + if (charCode < 0x80) + buf[bufIdx++] = charCode; + else if (charCode < 0x800) { + buf[bufIdx++] = 0xC0 + (charCode >>> 6); + buf[bufIdx++] = 0x80 + (charCode & 0x3f); + } + else { // charCode will always be < 0x10000 in javascript. + buf[bufIdx++] = 0xE0 + (charCode >>> 12); + buf[bufIdx++] = 0x80 + ((charCode >>> 6) & 0x3f); + buf[bufIdx++] = 0x80 + (charCode & 0x3f); + } + } + return buf.slice(0, bufIdx); +} -/***/ }), +InternalEncoderCesu8.prototype.end = function() { +} -/***/ 7799: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +//------------------------------------------------------------------------------ +// CESU-8 decoder is not implemented in Node v4.0+ -var baseGetTag = __nccwpck_require__(7497), - isObject = __nccwpck_require__(3334); +function InternalDecoderCesu8(options, codec) { + this.acc = 0; + this.contBytes = 0; + this.accBytes = 0; + this.defaultCharUnicode = codec.defaultCharUnicode; +} -/** `Object#toString` result references. */ -var asyncTag = '[object AsyncFunction]', - funcTag = '[object Function]', - genTag = '[object GeneratorFunction]', - proxyTag = '[object Proxy]'; +InternalDecoderCesu8.prototype.write = function(buf) { + var acc = this.acc, contBytes = this.contBytes, accBytes = this.accBytes, + res = ''; + for (var i = 0; i < buf.length; i++) { + var curByte = buf[i]; + if ((curByte & 0xC0) !== 0x80) { // Leading byte + if (contBytes > 0) { // Previous code is invalid + res += this.defaultCharUnicode; + contBytes = 0; + } -/** - * 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; + if (curByte < 0x80) { // Single-byte code + res += String.fromCharCode(curByte); + } else if (curByte < 0xE0) { // Two-byte code + acc = curByte & 0x1F; + contBytes = 1; accBytes = 1; + } else if (curByte < 0xF0) { // Three-byte code + acc = curByte & 0x0F; + contBytes = 2; accBytes = 1; + } else { // Four or more are not supported for CESU-8. + res += this.defaultCharUnicode; + } + } else { // Continuation byte + if (contBytes > 0) { // We're waiting for it. + acc = (acc << 6) | (curByte & 0x3f); + contBytes--; accBytes++; + if (contBytes === 0) { + // Check for overlong encoding, but support Modified UTF-8 (encoding NULL as C0 80) + if (accBytes === 2 && acc < 0x80 && acc > 0) + res += this.defaultCharUnicode; + else if (accBytes === 3 && acc < 0x800) + res += this.defaultCharUnicode; + else + // Actually add character. + res += String.fromCharCode(acc); + } + } else { // Unexpected continuation byte + res += this.defaultCharUnicode; + } + } + } + this.acc = acc; this.contBytes = contBytes; this.accBytes = accBytes; + return res; } -module.exports = isFunction; +InternalDecoderCesu8.prototype.end = function() { + var res = 0; + if (this.contBytes > 0) + res += this.defaultCharUnicode; + return res; +} /***/ }), -/***/ 3334: -/***/ ((module) => { +/***/ 373: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -/** - * 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'); -} +"use strict"; -module.exports = isObject; +var Buffer = (__nccwpck_require__(5118).Buffer); +// Single-byte codec. Needs a 'chars' string parameter that contains 256 or 128 chars that +// correspond to encoded bytes (if 128 - then lower half is ASCII). -/***/ }), +exports._sbcs = SBCSCodec; +function SBCSCodec(codecOptions, iconv) { + if (!codecOptions) + throw new Error("SBCS codec is called without the data.") + + // Prepare char buffer for decoding. + if (!codecOptions.chars || (codecOptions.chars.length !== 128 && codecOptions.chars.length !== 256)) + throw new Error("Encoding '"+codecOptions.type+"' has incorrect 'chars' (must be of len 128 or 256)"); + + if (codecOptions.chars.length === 128) { + var asciiString = ""; + for (var i = 0; i < 128; i++) + asciiString += String.fromCharCode(i); + codecOptions.chars = asciiString + codecOptions.chars; + } -/***/ 5926: -/***/ ((module) => { + this.decodeBuf = Buffer.from(codecOptions.chars, 'ucs2'); + + // Encoding buffer. + var encodeBuf = Buffer.alloc(65536, iconv.defaultCharSingleByte.charCodeAt(0)); -/** - * 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'; + for (var i = 0; i < codecOptions.chars.length; i++) + encodeBuf[codecOptions.chars.charCodeAt(i)] = i; + + this.encodeBuf = encodeBuf; } -module.exports = isObjectLike; +SBCSCodec.prototype.encoder = SBCSEncoder; +SBCSCodec.prototype.decoder = SBCSDecoder; -/***/ }), +function SBCSEncoder(options, codec) { + this.encodeBuf = codec.encodeBuf; +} -/***/ 6403: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +SBCSEncoder.prototype.write = function(str) { + var buf = Buffer.alloc(str.length); + for (var i = 0; i < str.length; i++) + buf[i] = this.encodeBuf[str.charCodeAt(i)]; + + return buf; +} -var baseGetTag = __nccwpck_require__(7497), - isObjectLike = __nccwpck_require__(5926); +SBCSEncoder.prototype.end = function() { +} -/** `Object#toString` result references. */ -var symbolTag = '[object Symbol]'; -/** - * 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); +function SBCSDecoder(options, codec) { + this.decodeBuf = codec.decodeBuf; } -module.exports = isSymbol; +SBCSDecoder.prototype.write = function(buf) { + // Strings are immutable in JS -> we use ucs2 buffer to speed up computations. + var decodeBuf = this.decodeBuf; + var newBuf = Buffer.alloc(buf.length*2); + var idx1 = 0, idx2 = 0; + for (var i = 0; i < buf.length; i++) { + idx1 = buf[i]*2; idx2 = i*2; + newBuf[idx2] = decodeBuf[idx1]; + newBuf[idx2+1] = decodeBuf[idx1+1]; + } + return newBuf.toString('ucs2'); +} +SBCSDecoder.prototype.end = function() { +} -/***/ }), -/***/ 9885: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ }), -var MapCache = __nccwpck_require__(938); +/***/ 1012: +/***/ ((module) => { -/** Error message constants. */ -var FUNC_ERROR_TEXT = 'Expected a function'; +"use strict"; -/** - * 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; +// Generated data for sbcs codec. Don't edit manually. Regenerate using generation/gen-sbcs.js script. +module.exports = { + "437": "cp437", + "737": "cp737", + "775": "cp775", + "850": "cp850", + "852": "cp852", + "855": "cp855", + "856": "cp856", + "857": "cp857", + "858": "cp858", + "860": "cp860", + "861": "cp861", + "862": "cp862", + "863": "cp863", + "864": "cp864", + "865": "cp865", + "866": "cp866", + "869": "cp869", + "874": "windows874", + "922": "cp922", + "1046": "cp1046", + "1124": "cp1124", + "1125": "cp1125", + "1129": "cp1129", + "1133": "cp1133", + "1161": "cp1161", + "1162": "cp1162", + "1163": "cp1163", + "1250": "windows1250", + "1251": "windows1251", + "1252": "windows1252", + "1253": "windows1253", + "1254": "windows1254", + "1255": "windows1255", + "1256": "windows1256", + "1257": "windows1257", + "1258": "windows1258", + "28591": "iso88591", + "28592": "iso88592", + "28593": "iso88593", + "28594": "iso88594", + "28595": "iso88595", + "28596": "iso88596", + "28597": "iso88597", + "28598": "iso88598", + "28599": "iso88599", + "28600": "iso885910", + "28601": "iso885911", + "28603": "iso885913", + "28604": "iso885914", + "28605": "iso885915", + "28606": "iso885916", + "windows874": { + "type": "_sbcs", + "chars": "€����…�����������‘’“”•–—�������� กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู����฿เแโใไๅๆ็่้๊๋์ํ๎๏๐๑๒๓๔๕๖๗๘๙๚๛����" + }, + "win874": "windows874", + "cp874": "windows874", + "windows1250": { + "type": "_sbcs", + "chars": "€�‚�„…†‡�‰Š‹ŚŤŽŹ�‘’“”•–—�™š›śťžź ˇ˘Ł¤Ą¦§¨©Ş«¬­®Ż°±˛ł´µ¶·¸ąş»Ľ˝ľżŔÁÂĂÄĹĆÇČÉĘËĚÍÎĎĐŃŇÓÔŐÖ×ŘŮÚŰÜÝŢßŕáâăäĺćçčéęëěíîďđńňóôőö÷řůúűüýţ˙" + }, + "win1250": "windows1250", + "cp1250": "windows1250", + "windows1251": { + "type": "_sbcs", + "chars": "ЂЃ‚ѓ„…†‡€‰Љ‹ЊЌЋЏђ‘’“”•–—�™љ›њќћџ ЎўЈ¤Ґ¦§Ё©Є«¬­®Ї°±Ііґµ¶·ё№є»јЅѕїАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя" + }, + "win1251": "windows1251", + "cp1251": "windows1251", + "windows1252": { + "type": "_sbcs", + "chars": "€�‚ƒ„…†‡ˆ‰Š‹Œ�Ž��‘’“”•–—˜™š›œ�žŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ" + }, + "win1252": "windows1252", + "cp1252": "windows1252", + "windows1253": { + "type": "_sbcs", + "chars": "€�‚ƒ„…†‡�‰�‹�����‘’“”•–—�™�›���� ΅Ά£¤¥¦§¨©�«¬­®―°±²³΄µ¶·ΈΉΊ»Ό½ΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ�ΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώ�" + }, + "win1253": "windows1253", + "cp1253": "windows1253", + "windows1254": { + "type": "_sbcs", + "chars": "€�‚ƒ„…†‡ˆ‰Š‹Œ����‘’“”•–—˜™š›œ��Ÿ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏĞÑÒÓÔÕÖ×ØÙÚÛÜİŞßàáâãäåæçèéêëìíîïğñòóôõö÷øùúûüışÿ" + }, + "win1254": "windows1254", + "cp1254": "windows1254", + "windows1255": { + "type": "_sbcs", + "chars": "€�‚ƒ„…†‡ˆ‰�‹�����‘’“”•–—˜™�›���� ¡¢£₪¥¦§¨©×«¬­®¯°±²³´µ¶·¸¹÷»¼½¾¿ְֱֲֳִֵֶַָֹֺֻּֽ־ֿ׀ׁׂ׃װױײ׳״�������אבגדהוזחטיךכלםמןנסעףפץצקרשת��‎‏�" + }, + "win1255": "windows1255", + "cp1255": "windows1255", + "windows1256": { + "type": "_sbcs", + "chars": "€پ‚ƒ„…†‡ˆ‰ٹ‹Œچژڈگ‘’“”•–—ک™ڑ›œ‌‍ں ،¢£¤¥¦§¨©ھ«¬­®¯°±²³´µ¶·¸¹؛»¼½¾؟ہءآأؤإئابةتثجحخدذرزسشصض×طظعغـفقكàلâمنهوçèéêëىيîïًٌٍَôُِ÷ّùْûü‎‏ے" + }, + "win1256": "windows1256", + "cp1256": "windows1256", + "windows1257": { + "type": "_sbcs", + "chars": "€�‚�„…†‡�‰�‹�¨ˇ¸�‘’“”•–—�™�›�¯˛� �¢£¤�¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙" + }, + "win1257": "windows1257", + "cp1257": "windows1257", + "windows1258": { + "type": "_sbcs", + "chars": "€�‚ƒ„…†‡ˆ‰�‹Œ����‘’“”•–—˜™�›œ��Ÿ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂĂÄÅÆÇÈÉÊË̀ÍÎÏĐÑ̉ÓÔƠÖ×ØÙÚÛÜỮßàáâăäåæçèéêë́íîïđṇ̃óôơö÷øùúûüư₫ÿ" + }, + "win1258": "windows1258", + "cp1258": "windows1258", + "iso88591": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ" + }, + "cp28591": "iso88591", + "iso88592": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ Ą˘Ł¤ĽŚ§¨ŠŞŤŹ­ŽŻ°ą˛ł´ľśˇ¸šşťź˝žżŔÁÂĂÄĹĆÇČÉĘËĚÍÎĎĐŃŇÓÔŐÖ×ŘŮÚŰÜÝŢßŕáâăäĺćçčéęëěíîďđńňóôőö÷řůúűüýţ˙" + }, + "cp28592": "iso88592", + "iso88593": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ Ħ˘£¤�Ĥ§¨İŞĞĴ­�Ż°ħ²³´µĥ·¸ışğĵ½�żÀÁÂ�ÄĊĈÇÈÉÊËÌÍÎÏ�ÑÒÓÔĠÖ×ĜÙÚÛÜŬŜßàáâ�äċĉçèéêëìíîï�ñòóôġö÷ĝùúûüŭŝ˙" + }, + "cp28593": "iso88593", + "iso88594": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ĄĸŖ¤ĨĻ§¨ŠĒĢŦ­Ž¯°ą˛ŗ´ĩļˇ¸šēģŧŊžŋĀÁÂÃÄÅÆĮČÉĘËĖÍÎĪĐŅŌĶÔÕÖ×ØŲÚÛÜŨŪßāáâãäåæįčéęëėíîīđņōķôõö÷øųúûüũū˙" + }, + "cp28594": "iso88594", + "iso88595": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ЁЂЃЄЅІЇЈЉЊЋЌ­ЎЏАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя№ёђѓєѕіїјљњћќ§ўџ" + }, + "cp28595": "iso88595", + "iso88596": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ���¤�������،­�������������؛���؟�ءآأؤإئابةتثجحخدذرزسشصضطظعغ�����ـفقكلمنهوىيًٌٍَُِّْ�������������" + }, + "cp28596": "iso88596", + "iso88597": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ‘’£€₯¦§¨©ͺ«¬­�―°±²³΄΅Ά·ΈΉΊ»Ό½ΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ�ΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώ�" + }, + "cp28597": "iso88597", + "iso88598": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ �¢£¤¥¦§¨©×«¬­®¯°±²³´µ¶·¸¹÷»¼½¾��������������������������������‗אבגדהוזחטיךכלםמןנסעףפץצקרשת��‎‏�" + }, + "cp28598": "iso88598", + "iso88599": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏĞÑÒÓÔÕÖ×ØÙÚÛÜİŞßàáâãäåæçèéêëìíîïğñòóôõö÷øùúûüışÿ" + }, + "cp28599": "iso88599", + "iso885910": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ĄĒĢĪĨĶ§ĻĐŠŦŽ­ŪŊ°ąēģīĩķ·ļđšŧž―ūŋĀÁÂÃÄÅÆĮČÉĘËĖÍÎÏÐŅŌÓÔÕÖŨØŲÚÛÜÝÞßāáâãäåæįčéęëėíîïðņōóôõöũøųúûüýþĸ" + }, + "cp28600": "iso885910", + "iso885911": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู����฿เแโใไๅๆ็่้๊๋์ํ๎๏๐๑๒๓๔๕๖๗๘๙๚๛����" + }, + "cp28601": "iso885911", + "iso885913": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ”¢£¤„¦§Ø©Ŗ«¬­®Æ°±²³“µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž’" + }, + "cp28603": "iso885913", + "iso885914": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ Ḃḃ£ĊċḊ§Ẁ©ẂḋỲ­®ŸḞḟĠġṀṁ¶ṖẁṗẃṠỳẄẅṡÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏŴÑÒÓÔÕÖṪØÙÚÛÜÝŶßàáâãäåæçèéêëìíîïŵñòóôõöṫøùúûüýŷÿ" + }, + "cp28604": "iso885914", + "iso885915": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£€¥Š§š©ª«¬­®¯°±²³Žµ¶·ž¹º»ŒœŸ¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ" + }, + "cp28605": "iso885915", + "iso885916": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ĄąŁ€„Š§š©Ș«Ź­źŻ°±ČłŽ”¶·žčș»ŒœŸżÀÁÂĂÄĆÆÇÈÉÊËÌÍÎÏĐŃÒÓÔŐÖŚŰÙÚÛÜĘȚßàáâăäćæçèéêëìíîïđńòóôőöśűùúûüęțÿ" + }, + "cp28606": "iso885916", + "cp437": { + "type": "_sbcs", + "chars": "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ " + }, + "ibm437": "cp437", + "csibm437": "cp437", + "cp737": { + "type": "_sbcs", + "chars": "ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρσςτυφχψ░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀ωάέήϊίόύϋώΆΈΉΊΌΎΏ±≥≤ΪΫ÷≈°∙·√ⁿ²■ " + }, + "ibm737": "cp737", + "csibm737": "cp737", + "cp775": { + "type": "_sbcs", + "chars": "ĆüéāäģåćłēŖŗīŹÄÅÉæÆōöĢ¢ŚśÖÜø£ØפĀĪóŻżź”¦©®¬½¼Ł«»░▒▓│┤ĄČĘĖ╣║╗╝ĮŠ┐└┴┬├─┼ŲŪ╚╔╩╦╠═╬Žąčęėįšųūž┘┌█▄▌▐▀ÓßŌŃõÕµńĶķĻļņĒŅ’­±“¾¶§÷„°∙·¹³²■ " + }, + "ibm775": "cp775", + "csibm775": "cp775", + "cp850": { + "type": "_sbcs", + "chars": "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø׃áíóúñѪº¿®¬½¼¡«»░▒▓│┤ÁÂÀ©╣║╗╝¢¥┐└┴┬├─┼ãÃ╚╔╩╦╠═╬¤ðÐÊËÈıÍÎÏ┘┌█▄¦Ì▀ÓßÔÒõÕµþÞÚÛÙýݯ´­±‗¾¶§÷¸°¨·¹³²■ " + }, + "ibm850": "cp850", + "csibm850": "cp850", + "cp852": { + "type": "_sbcs", + "chars": "ÇüéâäůćçłëŐőîŹÄĆÉĹĺôöĽľŚśÖÜŤťŁ×čáíóúĄąŽžĘ꬟Ⱥ«»░▒▓│┤ÁÂĚŞ╣║╗╝Żż┐└┴┬├─┼Ăă╚╔╩╦╠═╬¤đĐĎËďŇÍÎě┘┌█▄ŢŮ▀ÓßÔŃńňŠšŔÚŕŰýÝţ´­˝˛ˇ˘§÷¸°¨˙űŘř■ " + }, + "ibm852": "cp852", + "csibm852": "cp852", + "cp855": { + "type": "_sbcs", + "chars": "ђЂѓЃёЁєЄѕЅіІїЇјЈљЉњЊћЋќЌўЎџЏюЮъЪаАбБцЦдДеЕфФгГ«»░▒▓│┤хХиИ╣║╗╝йЙ┐└┴┬├─┼кК╚╔╩╦╠═╬¤лЛмМнНоОп┘┌█▄Пя▀ЯрРсСтТуУжЖвВьЬ№­ыЫзЗшШэЭщЩчЧ§■ " + }, + "ibm855": "cp855", + "csibm855": "cp855", + "cp856": { + "type": "_sbcs", + "chars": "אבגדהוזחטיךכלםמןנסעףפץצקרשת�£�×����������®¬½¼�«»░▒▓│┤���©╣║╗╝¢¥┐└┴┬├─┼��╚╔╩╦╠═╬¤���������┘┌█▄¦�▀������µ�������¯´­±‗¾¶§÷¸°¨·¹³²■ " + }, + "ibm856": "cp856", + "csibm856": "cp856", + "cp857": { + "type": "_sbcs", + "chars": "ÇüéâäàåçêëèïîıÄÅÉæÆôöòûùİÖÜø£ØŞşáíóúñÑĞ𿮬½¼¡«»░▒▓│┤ÁÂÀ©╣║╗╝¢¥┐└┴┬├─┼ãÃ╚╔╩╦╠═╬¤ºªÊËÈ�ÍÎÏ┘┌█▄¦Ì▀ÓßÔÒõÕµ�×ÚÛÙìÿ¯´­±�¾¶§÷¸°¨·¹³²■ " + }, + "ibm857": "cp857", + "csibm857": "cp857", + "cp858": { + "type": "_sbcs", + "chars": "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø׃áíóúñѪº¿®¬½¼¡«»░▒▓│┤ÁÂÀ©╣║╗╝¢¥┐└┴┬├─┼ãÃ╚╔╩╦╠═╬¤ðÐÊËÈ€ÍÎÏ┘┌█▄¦Ì▀ÓßÔÒõÕµþÞÚÛÙýݯ´­±‗¾¶§÷¸°¨·¹³²■ " + }, + "ibm858": "cp858", + "csibm858": "cp858", + "cp860": { + "type": "_sbcs", + "chars": "ÇüéâãàÁçêÊèÍÔìÃÂÉÀÈôõòÚùÌÕÜ¢£Ù₧ÓáíóúñѪº¿Ò¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ " + }, + "ibm860": "cp860", + "csibm860": "cp860", + "cp861": { + "type": "_sbcs", + "chars": "ÇüéâäàåçêëèÐðÞÄÅÉæÆôöþûÝýÖÜø£Ø₧ƒáíóúÁÍÓÚ¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ " + }, + "ibm861": "cp861", + "csibm861": "cp861", + "cp862": { + "type": "_sbcs", + "chars": "אבגדהוזחטיךכלםמןנסעףפץצקרשת¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ " + }, + "ibm862": "cp862", + "csibm862": "cp862", + "cp863": { + "type": "_sbcs", + "chars": "ÇüéâÂà¶çêëèïî‗À§ÉÈÊôËÏûù¤ÔÜ¢£ÙÛƒ¦´óú¨¸³¯Î⌐¬½¼¾«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ " + }, + "ibm863": "cp863", + "csibm863": "cp863", + "cp864": { + "type": "_sbcs", + "chars": "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$٪&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~°·∙√▒─│┼┤┬├┴┐┌└┘β∞φ±½¼≈«»ﻷﻸ��ﻻﻼ� ­ﺂ£¤ﺄ��ﺎﺏﺕﺙ،ﺝﺡﺥ٠١٢٣٤٥٦٧٨٩ﻑ؛ﺱﺵﺹ؟¢ﺀﺁﺃﺅﻊﺋﺍﺑﺓﺗﺛﺟﺣﺧﺩﺫﺭﺯﺳﺷﺻﺿﻁﻅﻋﻏ¦¬÷×ﻉـﻓﻗﻛﻟﻣﻧﻫﻭﻯﻳﺽﻌﻎﻍﻡﹽّﻥﻩﻬﻰﻲﻐﻕﻵﻶﻝﻙﻱ■�" + }, + "ibm864": "cp864", + "csibm864": "cp864", + "cp865": { + "type": "_sbcs", + "chars": "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø₧ƒáíóúñѪº¿⌐¬½¼¡«¤░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ " + }, + "ibm865": "cp865", + "csibm865": "cp865", + "cp866": { + "type": "_sbcs", + "chars": "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀рстуфхцчшщъыьэюяЁёЄєЇїЎў°∙·√№¤■ " + }, + "ibm866": "cp866", + "csibm866": "cp866", + "cp869": { + "type": "_sbcs", + "chars": "������Ά�·¬¦‘’Έ―ΉΊΪΌ��ΎΫ©Ώ²³ά£έήίϊΐόύΑΒΓΔΕΖΗ½ΘΙ«»░▒▓│┤ΚΛΜΝ╣║╗╝ΞΟ┐└┴┬├─┼ΠΡ╚╔╩╦╠═╬ΣΤΥΦΧΨΩαβγ┘┌█▄δε▀ζηθικλμνξοπρσςτ΄­±υφχ§ψ΅°¨ωϋΰώ■ " + }, + "ibm869": "cp869", + "csibm869": "cp869", + "cp922": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®‾°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏŠÑÒÓÔÕÖ×ØÙÚÛÜÝŽßàáâãäåæçèéêëìíîïšñòóôõö÷øùúûüýžÿ" + }, + "ibm922": "cp922", + "csibm922": "cp922", + "cp1046": { + "type": "_sbcs", + "chars": "ﺈ×÷ﹱˆ■│─┐┌└┘ﹹﹻﹽﹿﹷﺊﻰﻳﻲﻎﻏﻐﻶﻸﻺﻼ ¤ﺋﺑﺗﺛﺟﺣ،­ﺧﺳ٠١٢٣٤٥٦٧٨٩ﺷ؛ﺻﺿﻊ؟ﻋءآأؤإئابةتثجحخدذرزسشصضطﻇعغﻌﺂﺄﺎﻓـفقكلمنهوىيًٌٍَُِّْﻗﻛﻟﻵﻷﻹﻻﻣﻧﻬﻩ�" + }, + "ibm1046": "cp1046", + "csibm1046": "cp1046", + "cp1124": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ЁЂҐЄЅІЇЈЉЊЋЌ­ЎЏАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя№ёђґєѕіїјљњћќ§ўџ" + }, + "ibm1124": "cp1124", + "csibm1124": "cp1124", + "cp1125": { + "type": "_sbcs", + "chars": "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀рстуфхцчшщъыьэюяЁёҐґЄєІіЇї·√№¤■ " + }, + "ibm1125": "cp1125", + "csibm1125": "cp1125", + "cp1129": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§œ©ª«¬­®¯°±²³Ÿµ¶·Œ¹º»¼½¾¿ÀÁÂĂÄÅÆÇÈÉÊË̀ÍÎÏĐÑ̉ÓÔƠÖ×ØÙÚÛÜỮßàáâăäåæçèéêë́íîïđṇ̃óôơö÷øùúûüư₫ÿ" + }, + "ibm1129": "cp1129", + "csibm1129": "cp1129", + "cp1133": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ກຂຄງຈສຊຍດຕຖທນບປຜຝພຟມຢຣລວຫອຮ���ຯະາຳິີຶືຸູຼັົຽ���ເແໂໃໄ່້໊໋໌ໍໆ�ໜໝ₭����������������໐໑໒໓໔໕໖໗໘໙��¢¬¦�" + }, + "ibm1133": "cp1133", + "csibm1133": "cp1133", + "cp1161": { + "type": "_sbcs", + "chars": "��������������������������������่กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู้๊๋€฿เแโใไๅๆ็่้๊๋์ํ๎๏๐๑๒๓๔๕๖๗๘๙๚๛¢¬¦ " + }, + "ibm1161": "cp1161", + "csibm1161": "cp1161", + "cp1162": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู����฿เแโใไๅๆ็่้๊๋์ํ๎๏๐๑๒๓๔๕๖๗๘๙๚๛����" + }, + "ibm1162": "cp1162", + "csibm1162": "cp1162", + "cp1163": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£€¥¦§œ©ª«¬­®¯°±²³Ÿµ¶·Œ¹º»¼½¾¿ÀÁÂĂÄÅÆÇÈÉÊË̀ÍÎÏĐÑ̉ÓÔƠÖ×ØÙÚÛÜỮßàáâăäåæçèéêë́íîïđṇ̃óôơö÷øùúûüư₫ÿ" + }, + "ibm1163": "cp1163", + "csibm1163": "cp1163", + "maccroatian": { + "type": "_sbcs", + "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®Š™´¨≠ŽØ∞±≤≥∆µ∂∑∏š∫ªºΩžø¿¡¬√ƒ≈Ć«Č… ÀÃÕŒœĐ—“”‘’÷◊�©⁄¤‹›Æ»–·‚„‰ÂćÁčÈÍÎÏÌÓÔđÒÚÛÙıˆ˜¯πË˚¸Êæˇ" + }, + "maccyrillic": { + "type": "_sbcs", + "chars": "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ†°¢£§•¶І®©™Ђђ≠Ѓѓ∞±≤≥іµ∂ЈЄєЇїЉљЊњјЅ¬√ƒ≈∆«»… ЋћЌќѕ–—“”‘’÷„ЎўЏџ№Ёёяабвгдежзийклмнопрстуфхцчшщъыьэю¤" + }, + "macgreek": { + "type": "_sbcs", + "chars": "Ĺ²É³ÖÜ΅àâä΄¨çéèê룙î‰ôö¦­ùûü†ΓΔΘΛΞΠß®©ΣΪ§≠°·Α±≤≥¥ΒΕΖΗΙΚΜΦΫΨΩάΝ¬ΟΡ≈Τ«»… ΥΧΆΈœ–―“”‘’÷ΉΊΌΎέήίόΏύαβψδεφγηιξκλμνοπώρστθωςχυζϊϋΐΰ�" + }, + "maciceland": { + "type": "_sbcs", + "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûüÝ°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄¤ÐðÞþý·‚„‰ÂÊÁËÈÍÎÏÌÓÔ�ÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ" + }, + "macroman": { + "type": "_sbcs", + "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄¤‹›fifl‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔ�ÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ" + }, + "macromania": { + "type": "_sbcs", + "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ĂŞ∞±≤≥¥µ∂∑∏π∫ªºΩăş¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄¤‹›Ţţ‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔ�ÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ" + }, + "macthai": { + "type": "_sbcs", + "chars": "«»…“”�•‘’� กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู​–—฿เแโใไๅๆ็่้๊๋์ํ™๏๐๑๒๓๔๕๖๗๘๙®©����" + }, + "macturkish": { + "type": "_sbcs", + "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸĞğİıŞş‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔ�ÒÚÛÙ�ˆ˜¯˘˙˚¸˝˛ˇ" + }, + "macukraine": { + "type": "_sbcs", + "chars": "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ†°Ґ£§•¶І®©™Ђђ≠Ѓѓ∞±≤≥іµґЈЄєЇїЉљЊњјЅ¬√ƒ≈∆«»… ЋћЌќѕ–—“”‘’÷„ЎўЏџ№Ёёяабвгдежзийклмнопрстуфхцчшщъыьэю¤" + }, + "koi8r": { + "type": "_sbcs", + "chars": "─│┌┐└┘├┤┬┴┼▀▄█▌▐░▒▓⌠■∙√≈≤≥ ⌡°²·÷═║╒ё╓╔╕╖╗╘╙╚╛╜╝╞╟╠╡Ё╢╣╤╥╦╧╨╩╪╫╬©юабцдефгхийклмнопярстужвьызшэщчъЮАБЦДЕФГХИЙКЛМНОПЯРСТУЖВЬЫЗШЭЩЧЪ" + }, + "koi8u": { + "type": "_sbcs", + "chars": "─│┌┐└┘├┤┬┴┼▀▄█▌▐░▒▓⌠■∙√≈≤≥ ⌡°²·÷═║╒ёє╔ії╗╘╙╚╛ґ╝╞╟╠╡ЁЄ╣ІЇ╦╧╨╩╪Ґ╬©юабцдефгхийклмнопярстужвьызшэщчъЮАБЦДЕФГХИЙКЛМНОПЯРСТУЖВЬЫЗШЭЩЧЪ" + }, + "koi8ru": { + "type": "_sbcs", + "chars": "─│┌┐└┘├┤┬┴┼▀▄█▌▐░▒▓⌠■∙√≈≤≥ ⌡°²·÷═║╒ёє╔ії╗╘╙╚╛ґў╞╟╠╡ЁЄ╣ІЇ╦╧╨╩╪ҐЎ©юабцдефгхийклмнопярстужвьызшэщчъЮАБЦДЕФГХИЙКЛМНОПЯРСТУЖВЬЫЗШЭЩЧЪ" + }, + "koi8t": { + "type": "_sbcs", + "chars": "қғ‚Ғ„…†‡�‰ҳ‹ҲҷҶ�Қ‘’“”•–—�™�›�����ӯӮё¤ӣ¦§���«¬­®�°±²Ё�Ӣ¶·�№�»���©юабцдефгхийклмнопярстужвьызшэщчъЮАБЦДЕФГХИЙКЛМНОПЯРСТУЖВЬЫЗШЭЩЧЪ" + }, + "armscii8": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ �և։)(»«—.՝,-֊…՜՛՞ԱաԲբԳգԴդԵեԶզԷէԸըԹթԺժԻիԼլԽխԾծԿկՀհՁձՂղՃճՄմՅյՆնՇշՈոՉչՊպՋջՌռՍսՎվՏտՐրՑցՒւՓփՔքՕօՖֆ՚�" + }, + "rk1048": { + "type": "_sbcs", + "chars": "ЂЃ‚ѓ„…†‡€‰Љ‹ЊҚҺЏђ‘’“”•–—�™љ›њқһџ ҰұӘ¤Ө¦§Ё©Ғ«¬­®Ү°±Ііөµ¶·ё№ғ»әҢңүАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя" + }, + "tcvn": { + "type": "_sbcs", + "chars": "\u0000ÚỤ\u0003ỪỬỮ\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010ỨỰỲỶỸÝỴ\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ÀẢÃÁẠẶẬÈẺẼÉẸỆÌỈĨÍỊÒỎÕÓỌỘỜỞỠỚỢÙỦŨ ĂÂÊÔƠƯĐăâêôơưđẶ̀̀̉̃́àảãáạẲằẳẵắẴẮẦẨẪẤỀặầẩẫấậèỂẻẽéẹềểễếệìỉỄẾỒĩíịòỔỏõóọồổỗốộờởỡớợùỖủũúụừửữứựỳỷỹýỵỐ" + }, + "georgianacademy": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿აბგდევზთიკლმნოპჟრსტუფქღყშჩცძწჭხჯჰჱჲჳჴჵჶçèéêëìíîïðñòóôõö÷øùúûüýþÿ" + }, + "georgianps": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿აბგდევზჱთიკლმნჲოპჟრსტჳუფქღყშჩცძწჭხჴჯჰჵæçèéêëìíîïðñòóôõö÷øùúûüýþÿ" + }, + "pt154": { + "type": "_sbcs", + "chars": "ҖҒӮғ„…ҶҮҲүҠӢҢҚҺҸҗ‘’“”•–—ҳҷҡӣңқһҹ ЎўЈӨҘҰ§Ё©Ә«¬ӯ®Ҝ°ұІіҙө¶·ё№ә»јҪҫҝАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя" + }, + "viscii": { + "type": "_sbcs", + "chars": "\u0000\u0001Ẳ\u0003\u0004ẴẪ\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013Ỷ\u0015\u0016\u0017\u0018Ỹ\u001a\u001b\u001c\u001dỴ\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ẠẮẰẶẤẦẨẬẼẸẾỀỂỄỆỐỒỔỖỘỢỚỜỞỊỎỌỈỦŨỤỲÕắằặấầẩậẽẹếềểễệốồổỗỠƠộờởịỰỨỪỬơớƯÀÁÂÃẢĂẳẵÈÉÊẺÌÍĨỳĐứÒÓÔạỷừửÙÚỹỵÝỡưàáâãảăữẫèéêẻìíĩỉđựòóôõỏọụùúũủýợỮ" + }, + "iso646cn": { + "type": "_sbcs", + "chars": "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#¥%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}‾��������������������������������������������������������������������������������������������������������������������������������" + }, + "iso646jp": { + "type": "_sbcs", + "chars": "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[¥]^_`abcdefghijklmnopqrstuvwxyz{|}‾��������������������������������������������������������������������������������������������������������������������������������" + }, + "hproman8": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ÀÂÈÊËÎÏ´ˋˆ¨˜ÙÛ₤¯Ýý°ÇçÑñ¡¿¤£¥§ƒ¢âêôûáéóúàèòùäëöüÅîØÆåíøæÄìÖÜÉïßÔÁÃãÐðÍÌÓÒÕõŠšÚŸÿÞþ·µ¶¾—¼½ªº«■»±�" + }, + "macintosh": { + "type": "_sbcs", + "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄¤‹›fifl‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔ�ÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ" + }, + "ascii": { + "type": "_sbcs", + "chars": "��������������������������������������������������������������������������������������������������������������������������������" + }, + "tis620": { + "type": "_sbcs", + "chars": "���������������������������������กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู����฿เแโใไๅๆ็่้๊๋์ํ๎๏๐๑๒๓๔๕๖๗๘๙๚๛����" + } } -// Expose `MapCache`. -memoize.Cache = MapCache; - -module.exports = memoize; - - /***/ }), -/***/ 2931: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -var baseToString = __nccwpck_require__(6792); - -/** - * 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); -} +/***/ 1080: +/***/ ((module) => { -module.exports = toString; +"use strict"; -/***/ }), +// Manually added data to be used by sbcs codec in addition to generated one. -/***/ 9623: -/***/ (function(module, __unused_webpack_exports, __nccwpck_require__) { +module.exports = { + // Not supported by iconv, not sure why. + "10029": "maccenteuro", + "maccenteuro": { + "type": "_sbcs", + "chars": "ÄĀāÉĄÖÜáąČäčĆć鏟ĎíďĒēĖóėôöõúĚěü†°Ę£§•¶ß®©™ę¨≠ģĮįĪ≤≥īĶ∂∑łĻļĽľĹĺŅņѬ√ńŇ∆«»… ňŐÕőŌ–—“”‘’÷◊ōŔŕŘ‹›řŖŗŠ‚„šŚśÁŤťÍŽžŪÓÔūŮÚůŰűŲųÝýķŻŁżĢˇ" + }, -/* module decorator */ module = __nccwpck_require__.nmd(module); -//! moment.js -//! version : 2.29.4 -//! authors : Tim Wood, Iskren Chernev, Moment.js contributors -//! license : MIT -//! momentjs.com + "808": "cp808", + "ibm808": "cp808", + "cp808": { + "type": "_sbcs", + "chars": "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀рстуфхцчшщъыьэюяЁёЄєЇїЎў°∙·√№€■ " + }, -;(function (global, factory) { - true ? module.exports = factory() : - 0 -}(this, (function () { 'use strict'; + "mik": { + "type": "_sbcs", + "chars": "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя└┴┬├─┼╣║╚╔╩╦╠═╬┐░▒▓│┤№§╗╝┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ " + }, - var hookCallback; + "cp720": { + "type": "_sbcs", + "chars": "\x80\x81éâ\x84à\x86çêëèïî\x8d\x8e\x8f\x90\u0651\u0652ô¤ـûùءآأؤ£إئابةتثجحخدذرزسشص«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀ضطظعغفµقكلمنهوىي≡\u064b\u064c\u064d\u064e\u064f\u0650≈°∙·√ⁿ²■\u00a0" + }, - function hooks() { - return hookCallback.apply(null, arguments); - } + // Aliases of generated encodings. + "ascii8bit": "ascii", + "usascii": "ascii", + "ansix34": "ascii", + "ansix341968": "ascii", + "ansix341986": "ascii", + "csascii": "ascii", + "cp367": "ascii", + "ibm367": "ascii", + "isoir6": "ascii", + "iso646us": "ascii", + "iso646irv": "ascii", + "us": "ascii", - // This is done to register the method called with moment() - // without creating circular dependencies. - function setHookCallback(callback) { - hookCallback = callback; - } + "latin1": "iso88591", + "latin2": "iso88592", + "latin3": "iso88593", + "latin4": "iso88594", + "latin5": "iso88599", + "latin6": "iso885910", + "latin7": "iso885913", + "latin8": "iso885914", + "latin9": "iso885915", + "latin10": "iso885916", - function isArray(input) { - return ( - input instanceof Array || - Object.prototype.toString.call(input) === '[object Array]' - ); - } + "csisolatin1": "iso88591", + "csisolatin2": "iso88592", + "csisolatin3": "iso88593", + "csisolatin4": "iso88594", + "csisolatincyrillic": "iso88595", + "csisolatinarabic": "iso88596", + "csisolatingreek" : "iso88597", + "csisolatinhebrew": "iso88598", + "csisolatin5": "iso88599", + "csisolatin6": "iso885910", - function isObject(input) { - // IE8 will treat undefined and null as object if it wasn't for - // input != null - return ( - input != null && - Object.prototype.toString.call(input) === '[object Object]' - ); - } + "l1": "iso88591", + "l2": "iso88592", + "l3": "iso88593", + "l4": "iso88594", + "l5": "iso88599", + "l6": "iso885910", + "l7": "iso885913", + "l8": "iso885914", + "l9": "iso885915", + "l10": "iso885916", - function hasOwnProp(a, b) { - return Object.prototype.hasOwnProperty.call(a, b); - } + "isoir14": "iso646jp", + "isoir57": "iso646cn", + "isoir100": "iso88591", + "isoir101": "iso88592", + "isoir109": "iso88593", + "isoir110": "iso88594", + "isoir144": "iso88595", + "isoir127": "iso88596", + "isoir126": "iso88597", + "isoir138": "iso88598", + "isoir148": "iso88599", + "isoir157": "iso885910", + "isoir166": "tis620", + "isoir179": "iso885913", + "isoir199": "iso885914", + "isoir203": "iso885915", + "isoir226": "iso885916", - function isObjectEmpty(obj) { - if (Object.getOwnPropertyNames) { - return Object.getOwnPropertyNames(obj).length === 0; - } else { - var k; - for (k in obj) { - if (hasOwnProp(obj, k)) { - return false; - } - } - return true; - } - } + "cp819": "iso88591", + "ibm819": "iso88591", - function isUndefined(input) { - return input === void 0; - } + "cyrillic": "iso88595", - function isNumber(input) { - return ( - typeof input === 'number' || - Object.prototype.toString.call(input) === '[object Number]' - ); - } + "arabic": "iso88596", + "arabic8": "iso88596", + "ecma114": "iso88596", + "asmo708": "iso88596", - function isDate(input) { - return ( - input instanceof Date || - Object.prototype.toString.call(input) === '[object Date]' - ); - } + "greek" : "iso88597", + "greek8" : "iso88597", + "ecma118" : "iso88597", + "elot928" : "iso88597", - function map(arr, fn) { - var res = [], - i, - arrLen = arr.length; - for (i = 0; i < arrLen; ++i) { - res.push(fn(arr[i], i)); - } - return res; - } + "hebrew": "iso88598", + "hebrew8": "iso88598", - function extend(a, b) { - for (var i in b) { - if (hasOwnProp(b, i)) { - a[i] = b[i]; - } - } + "turkish": "iso88599", + "turkish8": "iso88599", - if (hasOwnProp(b, 'toString')) { - a.toString = b.toString; - } + "thai": "iso885911", + "thai8": "iso885911", - if (hasOwnProp(b, 'valueOf')) { - a.valueOf = b.valueOf; - } + "celtic": "iso885914", + "celtic8": "iso885914", + "isoceltic": "iso885914", - return a; - } + "tis6200": "tis620", + "tis62025291": "tis620", + "tis62025330": "tis620", - function createUTC(input, format, locale, strict) { - return createLocalOrUTC(input, format, locale, strict, true).utc(); - } + "10000": "macroman", + "10006": "macgreek", + "10007": "maccyrillic", + "10079": "maciceland", + "10081": "macturkish", - function defaultParsingFlags() { - // We need to deep clone this object. - return { - empty: false, - unusedTokens: [], - unusedInput: [], - overflow: -2, - charsLeftOver: 0, - nullInput: false, - invalidEra: null, - invalidMonth: null, - invalidFormat: false, - userInvalidated: false, - iso: false, - parsedDateParts: [], - era: null, - meridiem: null, - rfc2822: false, - weekdayMismatch: false, - }; - } + "cspc8codepage437": "cp437", + "cspc775baltic": "cp775", + "cspc850multilingual": "cp850", + "cspcp852": "cp852", + "cspc862latinhebrew": "cp862", + "cpgr": "cp869", - function getParsingFlags(m) { - if (m._pf == null) { - m._pf = defaultParsingFlags(); - } - return m._pf; - } + "msee": "cp1250", + "mscyrl": "cp1251", + "msansi": "cp1252", + "msgreek": "cp1253", + "msturk": "cp1254", + "mshebr": "cp1255", + "msarab": "cp1256", + "winbaltrim": "cp1257", - var some; - if (Array.prototype.some) { - some = Array.prototype.some; - } else { - some = function (fun) { - var t = Object(this), - len = t.length >>> 0, - i; - - for (i = 0; i < len; i++) { - if (i in t && fun.call(this, t[i], i, t)) { - return true; - } - } + "cp20866": "koi8r", + "20866": "koi8r", + "ibm878": "koi8r", + "cskoi8r": "koi8r", - return false; - }; - } + "cp21866": "koi8u", + "21866": "koi8u", + "ibm1168": "koi8u", - function isValid(m) { - if (m._isValid == null) { - var flags = getParsingFlags(m), - parsedParts = some.call(flags.parsedDateParts, function (i) { - return i != null; - }), - isNowValid = - !isNaN(m._d.getTime()) && - flags.overflow < 0 && - !flags.empty && - !flags.invalidEra && - !flags.invalidMonth && - !flags.invalidWeekday && - !flags.weekdayMismatch && - !flags.nullInput && - !flags.invalidFormat && - !flags.userInvalidated && - (!flags.meridiem || (flags.meridiem && parsedParts)); - - if (m._strict) { - isNowValid = - isNowValid && - flags.charsLeftOver === 0 && - flags.unusedTokens.length === 0 && - flags.bigHour === undefined; - } + "strk10482002": "rk1048", - if (Object.isFrozen == null || !Object.isFrozen(m)) { - m._isValid = isNowValid; - } else { - return isNowValid; - } - } - return m._isValid; - } + "tcvn5712": "tcvn", + "tcvn57121": "tcvn", - function createInvalid(flags) { - var m = createUTC(NaN); - if (flags != null) { - extend(getParsingFlags(m), flags); - } else { - getParsingFlags(m).userInvalidated = true; - } + "gb198880": "iso646cn", + "cn": "iso646cn", - return m; - } + "csiso14jisc6220ro": "iso646jp", + "jisc62201969ro": "iso646jp", + "jp": "iso646jp", - // Plugins that add properties should also add the key here (null value), - // so we can properly clone ourselves. - var momentProperties = (hooks.momentProperties = []), - updateInProgress = false; + "cshproman8": "hproman8", + "r8": "hproman8", + "roman8": "hproman8", + "xroman8": "hproman8", + "ibm1051": "hproman8", - function copyConfig(to, from) { - var i, - prop, - val, - momentPropertiesLen = momentProperties.length; + "mac": "macintosh", + "csmacintosh": "macintosh", +}; - if (!isUndefined(from._isAMomentObject)) { - to._isAMomentObject = from._isAMomentObject; - } - if (!isUndefined(from._i)) { - to._i = from._i; - } - if (!isUndefined(from._f)) { - to._f = from._f; - } - if (!isUndefined(from._l)) { - to._l = from._l; - } - if (!isUndefined(from._strict)) { - to._strict = from._strict; - } - if (!isUndefined(from._tzm)) { - to._tzm = from._tzm; - } - if (!isUndefined(from._isUTC)) { - to._isUTC = from._isUTC; - } - if (!isUndefined(from._offset)) { - to._offset = from._offset; - } - if (!isUndefined(from._pf)) { - to._pf = getParsingFlags(from); - } - if (!isUndefined(from._locale)) { - to._locale = from._locale; - } - if (momentPropertiesLen > 0) { - for (i = 0; i < momentPropertiesLen; i++) { - prop = momentProperties[i]; - val = from[prop]; - if (!isUndefined(val)) { - to[prop] = val; - } - } - } - return to; - } +/***/ }), - // Moment prototype object - function Moment(config) { - copyConfig(this, config); - this._d = new Date(config._d != null ? config._d.getTime() : NaN); - if (!this.isValid()) { - this._d = new Date(NaN); - } - // Prevent infinite loop in case updateOffset creates new moment - // objects. - if (updateInProgress === false) { - updateInProgress = true; - hooks.updateOffset(this); - updateInProgress = false; - } - } +/***/ 1155: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - function isMoment(obj) { - return ( - obj instanceof Moment || (obj != null && obj._isAMomentObject != null) - ); - } +"use strict"; - function warn(msg) { - if ( - hooks.suppressDeprecationWarnings === false && - typeof console !== 'undefined' && - console.warn - ) { - console.warn('Deprecation warning: ' + msg); - } - } +var Buffer = (__nccwpck_require__(5118).Buffer); - function deprecate(msg, fn) { - var firstTime = true; +// Note: UTF16-LE (or UCS2) codec is Node.js native. See encodings/internal.js - return extend(function () { - if (hooks.deprecationHandler != null) { - hooks.deprecationHandler(null, msg); - } - if (firstTime) { - var args = [], - arg, - i, - key, - argLen = arguments.length; - for (i = 0; i < argLen; i++) { - arg = ''; - if (typeof arguments[i] === 'object') { - arg += '\n[' + i + '] '; - for (key in arguments[0]) { - if (hasOwnProp(arguments[0], key)) { - arg += key + ': ' + arguments[0][key] + ', '; - } - } - arg = arg.slice(0, -2); // Remove trailing comma and space - } else { - arg = arguments[i]; - } - args.push(arg); - } - warn( - msg + - '\nArguments: ' + - Array.prototype.slice.call(args).join('') + - '\n' + - new Error().stack - ); - firstTime = false; - } - return fn.apply(this, arguments); - }, fn); - } +// == UTF16-BE codec. ========================================================== - var deprecations = {}; +exports.utf16be = Utf16BECodec; +function Utf16BECodec() { +} - function deprecateSimple(name, msg) { - if (hooks.deprecationHandler != null) { - hooks.deprecationHandler(name, msg); - } - if (!deprecations[name]) { - warn(msg); - deprecations[name] = true; - } - } +Utf16BECodec.prototype.encoder = Utf16BEEncoder; +Utf16BECodec.prototype.decoder = Utf16BEDecoder; +Utf16BECodec.prototype.bomAware = true; - hooks.suppressDeprecationWarnings = false; - hooks.deprecationHandler = null; - function isFunction(input) { - return ( - (typeof Function !== 'undefined' && input instanceof Function) || - Object.prototype.toString.call(input) === '[object Function]' - ); - } +// -- Encoding - function set(config) { - var prop, i; - for (i in config) { - if (hasOwnProp(config, i)) { - prop = config[i]; - if (isFunction(prop)) { - this[i] = prop; - } else { - this['_' + i] = prop; - } - } - } - this._config = config; - // Lenient ordinal parsing accepts just a number in addition to - // number + (possibly) stuff coming from _dayOfMonthOrdinalParse. - // TODO: Remove "ordinalParse" fallback in next major release. - this._dayOfMonthOrdinalParseLenient = new RegExp( - (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) + - '|' + - /\d{1,2}/.source - ); - } +function Utf16BEEncoder() { +} - function mergeConfigs(parentConfig, childConfig) { - var res = extend({}, parentConfig), - prop; - for (prop in childConfig) { - if (hasOwnProp(childConfig, prop)) { - if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) { - res[prop] = {}; - extend(res[prop], parentConfig[prop]); - extend(res[prop], childConfig[prop]); - } else if (childConfig[prop] != null) { - res[prop] = childConfig[prop]; - } else { - delete res[prop]; - } - } - } - for (prop in parentConfig) { - if ( - hasOwnProp(parentConfig, prop) && - !hasOwnProp(childConfig, prop) && - isObject(parentConfig[prop]) - ) { - // make sure changes to properties don't modify parent config - res[prop] = extend({}, res[prop]); - } - } - return res; +Utf16BEEncoder.prototype.write = function(str) { + var buf = Buffer.from(str, 'ucs2'); + for (var i = 0; i < buf.length; i += 2) { + var tmp = buf[i]; buf[i] = buf[i+1]; buf[i+1] = tmp; } + return buf; +} - function Locale(config) { - if (config != null) { - this.set(config); - } - } +Utf16BEEncoder.prototype.end = function() { +} - var keys; - if (Object.keys) { - keys = Object.keys; - } else { - keys = function (obj) { - var i, - res = []; - for (i in obj) { - if (hasOwnProp(obj, i)) { - res.push(i); - } - } - return res; - }; - } +// -- Decoding - var defaultCalendar = { - sameDay: '[Today at] LT', - nextDay: '[Tomorrow at] LT', - nextWeek: 'dddd [at] LT', - lastDay: '[Yesterday at] LT', - lastWeek: '[Last] dddd [at] LT', - sameElse: 'L', - }; +function Utf16BEDecoder() { + this.overflowByte = -1; +} - function calendar(key, mom, now) { - var output = this._calendar[key] || this._calendar['sameElse']; - return isFunction(output) ? output.call(mom, now) : output; - } +Utf16BEDecoder.prototype.write = function(buf) { + if (buf.length == 0) + return ''; - function zeroFill(number, targetLength, forceSign) { - var absNumber = '' + Math.abs(number), - zerosToFill = targetLength - absNumber.length, - sign = number >= 0; - return ( - (sign ? (forceSign ? '+' : '') : '-') + - Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + - absNumber - ); - } + var buf2 = Buffer.alloc(buf.length + 1), + i = 0, j = 0; - var formattingTokens = - /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|N{1,5}|YYYYYY|YYYYY|YYYY|YY|y{2,4}|yo?|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g, - localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g, - formatFunctions = {}, - formatTokenFunctions = {}; - - // token: 'M' - // padded: ['MM', 2] - // ordinal: 'Mo' - // callback: function () { this.month() + 1 } - function addFormatToken(token, padded, ordinal, callback) { - var func = callback; - if (typeof callback === 'string') { - func = function () { - return this[callback](); - }; - } - if (token) { - formatTokenFunctions[token] = func; - } - if (padded) { - formatTokenFunctions[padded[0]] = function () { - return zeroFill(func.apply(this, arguments), padded[1], padded[2]); - }; - } - if (ordinal) { - formatTokenFunctions[ordinal] = function () { - return this.localeData().ordinal( - func.apply(this, arguments), - token - ); - }; - } + if (this.overflowByte !== -1) { + buf2[0] = buf[0]; + buf2[1] = this.overflowByte; + i = 1; j = 2; } - function removeFormattingTokens(input) { - if (input.match(/\[[\s\S]/)) { - return input.replace(/^\[|\]$/g, ''); - } - return input.replace(/\\/g, ''); + for (; i < buf.length-1; i += 2, j+= 2) { + buf2[j] = buf[i+1]; + buf2[j+1] = buf[i]; } - function makeFormatFunction(format) { - var array = format.match(formattingTokens), - i, - length; + this.overflowByte = (i == buf.length-1) ? buf[buf.length-1] : -1; - for (i = 0, length = array.length; i < length; i++) { - if (formatTokenFunctions[array[i]]) { - array[i] = formatTokenFunctions[array[i]]; - } else { - array[i] = removeFormattingTokens(array[i]); - } - } + return buf2.slice(0, j).toString('ucs2'); +} - return function (mom) { - var output = '', - i; - for (i = 0; i < length; i++) { - output += isFunction(array[i]) - ? array[i].call(mom, format) - : array[i]; - } - return output; - }; - } +Utf16BEDecoder.prototype.end = function() { + this.overflowByte = -1; +} - // format date using native date object - function formatMoment(m, format) { - if (!m.isValid()) { - return m.localeData().invalidDate(); - } - format = expandFormat(format, m.localeData()); - formatFunctions[format] = - formatFunctions[format] || makeFormatFunction(format); +// == UTF-16 codec ============================================================= +// Decoder chooses automatically from UTF-16LE and UTF-16BE using BOM and space-based heuristic. +// Defaults to UTF-16LE, as it's prevalent and default in Node. +// http://en.wikipedia.org/wiki/UTF-16 and http://encoding.spec.whatwg.org/#utf-16le +// Decoder default can be changed: iconv.decode(buf, 'utf16', {defaultEncoding: 'utf-16be'}); - return formatFunctions[format](m); - } +// Encoder uses UTF-16LE and prepends BOM (which can be overridden with addBOM: false). - function expandFormat(format, locale) { - var i = 5; +exports.utf16 = Utf16Codec; +function Utf16Codec(codecOptions, iconv) { + this.iconv = iconv; +} - function replaceLongDateFormatTokens(input) { - return locale.longDateFormat(input) || input; - } +Utf16Codec.prototype.encoder = Utf16Encoder; +Utf16Codec.prototype.decoder = Utf16Decoder; - localFormattingTokens.lastIndex = 0; - while (i >= 0 && localFormattingTokens.test(format)) { - format = format.replace( - localFormattingTokens, - replaceLongDateFormatTokens - ); - localFormattingTokens.lastIndex = 0; - i -= 1; - } - return format; - } +// -- Encoding (pass-through) - var defaultLongDateFormat = { - LTS: 'h:mm:ss A', - LT: 'h:mm A', - L: 'MM/DD/YYYY', - LL: 'MMMM D, YYYY', - LLL: 'MMMM D, YYYY h:mm A', - LLLL: 'dddd, MMMM D, YYYY h:mm A', - }; +function Utf16Encoder(options, codec) { + options = options || {}; + if (options.addBOM === undefined) + options.addBOM = true; + this.encoder = codec.iconv.getEncoder('utf-16le', options); +} - function longDateFormat(key) { - var format = this._longDateFormat[key], - formatUpper = this._longDateFormat[key.toUpperCase()]; +Utf16Encoder.prototype.write = function(str) { + return this.encoder.write(str); +} - if (format || !formatUpper) { - return format; - } +Utf16Encoder.prototype.end = function() { + return this.encoder.end(); +} - this._longDateFormat[key] = formatUpper - .match(formattingTokens) - .map(function (tok) { - if ( - tok === 'MMMM' || - tok === 'MM' || - tok === 'DD' || - tok === 'dddd' - ) { - return tok.slice(1); - } - return tok; - }) - .join(''); - return this._longDateFormat[key]; - } +// -- Decoding - var defaultInvalidDate = 'Invalid date'; +function Utf16Decoder(options, codec) { + this.decoder = null; + this.initialBufs = []; + this.initialBufsLen = 0; - function invalidDate() { - return this._invalidDate; - } + this.options = options || {}; + this.iconv = codec.iconv; +} - var defaultOrdinal = '%d', - defaultDayOfMonthOrdinalParse = /\d{1,2}/; +Utf16Decoder.prototype.write = function(buf) { + if (!this.decoder) { + // Codec is not chosen yet. Accumulate initial bytes. + this.initialBufs.push(buf); + this.initialBufsLen += buf.length; + + if (this.initialBufsLen < 16) // We need more bytes to use space heuristic (see below) + return ''; - function ordinal(number) { - return this._ordinal.replace('%d', number); - } + // We have enough bytes -> detect endianness. + var encoding = detectEncoding(this.initialBufs, this.options.defaultEncoding); + this.decoder = this.iconv.getDecoder(encoding, this.options); - var defaultRelativeTime = { - future: 'in %s', - past: '%s ago', - s: 'a few seconds', - ss: '%d seconds', - m: 'a minute', - mm: '%d minutes', - h: 'an hour', - hh: '%d hours', - d: 'a day', - dd: '%d days', - w: 'a week', - ww: '%d weeks', - M: 'a month', - MM: '%d months', - y: 'a year', - yy: '%d years', - }; + var resStr = ''; + for (var i = 0; i < this.initialBufs.length; i++) + resStr += this.decoder.write(this.initialBufs[i]); - function relativeTime(number, withoutSuffix, string, isFuture) { - var output = this._relativeTime[string]; - return isFunction(output) - ? output(number, withoutSuffix, string, isFuture) - : output.replace(/%d/i, number); + this.initialBufs.length = this.initialBufsLen = 0; + return resStr; } - function pastFuture(diff, output) { - var format = this._relativeTime[diff > 0 ? 'future' : 'past']; - return isFunction(format) ? format(output) : format.replace(/%s/i, output); - } + return this.decoder.write(buf); +} + +Utf16Decoder.prototype.end = function() { + if (!this.decoder) { + var encoding = detectEncoding(this.initialBufs, this.options.defaultEncoding); + this.decoder = this.iconv.getDecoder(encoding, this.options); - var aliases = {}; + var resStr = ''; + for (var i = 0; i < this.initialBufs.length; i++) + resStr += this.decoder.write(this.initialBufs[i]); - function addUnitAlias(unit, shorthand) { - var lowerCase = unit.toLowerCase(); - aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit; - } + var trail = this.decoder.end(); + if (trail) + resStr += trail; - function normalizeUnits(units) { - return typeof units === 'string' - ? aliases[units] || aliases[units.toLowerCase()] - : undefined; + this.initialBufs.length = this.initialBufsLen = 0; + return resStr; } + return this.decoder.end(); +} - function normalizeObjectUnits(inputObject) { - var normalizedInput = {}, - normalizedProp, - prop; +function detectEncoding(bufs, defaultEncoding) { + var b = []; + var charsProcessed = 0; + var asciiCharsLE = 0, asciiCharsBE = 0; // Number of ASCII chars when decoded as LE or BE. - for (prop in inputObject) { - if (hasOwnProp(inputObject, prop)) { - normalizedProp = normalizeUnits(prop); - if (normalizedProp) { - normalizedInput[normalizedProp] = inputObject[prop]; + outer_loop: + for (var i = 0; i < bufs.length; i++) { + var buf = bufs[i]; + for (var j = 0; j < buf.length; j++) { + b.push(buf[j]); + if (b.length === 2) { + if (charsProcessed === 0) { + // Check BOM first. + if (b[0] === 0xFF && b[1] === 0xFE) return 'utf-16le'; + if (b[0] === 0xFE && b[1] === 0xFF) return 'utf-16be'; } - } - } - - return normalizedInput; - } - var priorities = {}; + if (b[0] === 0 && b[1] !== 0) asciiCharsBE++; + if (b[0] !== 0 && b[1] === 0) asciiCharsLE++; - function addUnitPriority(unit, priority) { - priorities[unit] = priority; - } + b.length = 0; + charsProcessed++; - function getPrioritizedUnits(unitsObj) { - var units = [], - u; - for (u in unitsObj) { - if (hasOwnProp(unitsObj, u)) { - units.push({ unit: u, priority: priorities[u] }); + if (charsProcessed >= 100) { + break outer_loop; + } } } - units.sort(function (a, b) { - return a.priority - b.priority; - }); - return units; } - function isLeapYear(year) { - return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0; - } + // Make decisions. + // Most of the time, the content has ASCII chars (U+00**), but the opposite (U+**00) is uncommon. + // So, we count ASCII as if it was LE or BE, and decide from that. + if (asciiCharsBE > asciiCharsLE) return 'utf-16be'; + if (asciiCharsBE < asciiCharsLE) return 'utf-16le'; - function absFloor(number) { - if (number < 0) { - // -0 -> 0 - return Math.ceil(number) || 0; - } else { - return Math.floor(number); - } - } + // Couldn't decide (likely all zeros or not enough data). + return defaultEncoding || 'utf-16le'; +} - function toInt(argumentForCoercion) { - var coercedNumber = +argumentForCoercion, - value = 0; - if (coercedNumber !== 0 && isFinite(coercedNumber)) { - value = absFloor(coercedNumber); - } - return value; - } - function makeGetSet(unit, keepTime) { - return function (value) { - if (value != null) { - set$1(this, unit, value); - hooks.updateOffset(this, keepTime); - return this; - } else { - return get(this, unit); - } - }; - } +/***/ }), - function get(mom, unit) { - return mom.isValid() - ? mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() - : NaN; - } - - function set$1(mom, unit, value) { - if (mom.isValid() && !isNaN(value)) { - if ( - unit === 'FullYear' && - isLeapYear(mom.year()) && - mom.month() === 1 && - mom.date() === 29 - ) { - value = toInt(value); - mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit]( - value, - mom.month(), - daysInMonth(value, mom.month()) - ); - } else { - mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value); - } - } - } +/***/ 9557: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - // MOMENTS +"use strict"; - function stringGet(units) { - units = normalizeUnits(units); - if (isFunction(this[units])) { - return this[units](); - } - return this; - } - function stringSet(units, value) { - if (typeof units === 'object') { - units = normalizeObjectUnits(units); - var prioritized = getPrioritizedUnits(units), - i, - prioritizedLen = prioritized.length; - for (i = 0; i < prioritizedLen; i++) { - this[prioritized[i].unit](units[prioritized[i].unit]); - } - } else { - units = normalizeUnits(units); - if (isFunction(this[units])) { - return this[units](value); - } - } - return this; - } +var Buffer = (__nccwpck_require__(5118).Buffer); - var match1 = /\d/, // 0 - 9 - match2 = /\d\d/, // 00 - 99 - match3 = /\d{3}/, // 000 - 999 - match4 = /\d{4}/, // 0000 - 9999 - match6 = /[+-]?\d{6}/, // -999999 - 999999 - match1to2 = /\d\d?/, // 0 - 99 - match3to4 = /\d\d\d\d?/, // 999 - 9999 - match5to6 = /\d\d\d\d\d\d?/, // 99999 - 999999 - match1to3 = /\d{1,3}/, // 0 - 999 - match1to4 = /\d{1,4}/, // 0 - 9999 - match1to6 = /[+-]?\d{1,6}/, // -999999 - 999999 - matchUnsigned = /\d+/, // 0 - inf - matchSigned = /[+-]?\d+/, // -inf - inf - matchOffset = /Z|[+-]\d\d:?\d\d/gi, // +00:00 -00:00 +0000 -0000 or Z - matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi, // +00 -00 +00:00 -00:00 +0000 -0000 or Z - matchTimestamp = /[+-]?\d+(\.\d{1,3})?/, // 123456789 123456789.123 - // any word (or two) characters or numbers including two/three word month in arabic. - // includes scottish gaelic two word and hyphenated months - matchWord = - /[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i, - regexes; - - regexes = {}; - - function addRegexToken(token, regex, strictRegex) { - regexes[token] = isFunction(regex) - ? regex - : function (isStrict, localeData) { - return isStrict && strictRegex ? strictRegex : regex; - }; - } - - function getParseRegexForToken(token, config) { - if (!hasOwnProp(regexes, token)) { - return new RegExp(unescapeFormat(token)); - } +// == UTF32-LE/BE codec. ========================================================== - return regexes[token](config._strict, config._locale); - } +exports._utf32 = Utf32Codec; + +function Utf32Codec(codecOptions, iconv) { + this.iconv = iconv; + this.bomAware = true; + this.isLE = codecOptions.isLE; +} - // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript - function unescapeFormat(s) { - return regexEscape( - s - .replace('\\', '') - .replace( - /\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, - function (matched, p1, p2, p3, p4) { - return p1 || p2 || p3 || p4; - } - ) - ); - } +exports.utf32le = { type: '_utf32', isLE: true }; +exports.utf32be = { type: '_utf32', isLE: false }; - function regexEscape(s) { - return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); - } +// Aliases +exports.ucs4le = 'utf32le'; +exports.ucs4be = 'utf32be'; - var tokens = {}; +Utf32Codec.prototype.encoder = Utf32Encoder; +Utf32Codec.prototype.decoder = Utf32Decoder; - function addParseToken(token, callback) { - var i, - func = callback, - tokenLen; - if (typeof token === 'string') { - token = [token]; - } - if (isNumber(callback)) { - func = function (input, array) { - array[callback] = toInt(input); - }; - } - tokenLen = token.length; - for (i = 0; i < tokenLen; i++) { - tokens[token[i]] = func; - } - } +// -- Encoding - function addWeekParseToken(token, callback) { - addParseToken(token, function (input, array, config, token) { - config._w = config._w || {}; - callback(input, config._w, config, token); - }); - } +function Utf32Encoder(options, codec) { + this.isLE = codec.isLE; + this.highSurrogate = 0; +} - function addTimeToArrayFromToken(token, input, config) { - if (input != null && hasOwnProp(tokens, token)) { - tokens[token](input, config._a, config, token); - } - } +Utf32Encoder.prototype.write = function(str) { + var src = Buffer.from(str, 'ucs2'); + var dst = Buffer.alloc(src.length * 2); + var write32 = this.isLE ? dst.writeUInt32LE : dst.writeUInt32BE; + var offset = 0; - var YEAR = 0, - MONTH = 1, - DATE = 2, - HOUR = 3, - MINUTE = 4, - SECOND = 5, - MILLISECOND = 6, - WEEK = 7, - WEEKDAY = 8; + for (var i = 0; i < src.length; i += 2) { + var code = src.readUInt16LE(i); + var isHighSurrogate = (0xD800 <= code && code < 0xDC00); + var isLowSurrogate = (0xDC00 <= code && code < 0xE000); - function mod(n, x) { - return ((n % x) + x) % x; - } + if (this.highSurrogate) { + if (isHighSurrogate || !isLowSurrogate) { + // There shouldn't be two high surrogates in a row, nor a high surrogate which isn't followed by a low + // surrogate. If this happens, keep the pending high surrogate as a stand-alone semi-invalid character + // (technically wrong, but expected by some applications, like Windows file names). + write32.call(dst, this.highSurrogate, offset); + offset += 4; + } + else { + // Create 32-bit value from high and low surrogates; + var codepoint = (((this.highSurrogate - 0xD800) << 10) | (code - 0xDC00)) + 0x10000; - var indexOf; + write32.call(dst, codepoint, offset); + offset += 4; + this.highSurrogate = 0; - if (Array.prototype.indexOf) { - indexOf = Array.prototype.indexOf; - } else { - indexOf = function (o) { - // I know - var i; - for (i = 0; i < this.length; ++i) { - if (this[i] === o) { - return i; - } + continue; } - return -1; - }; - } + } - function daysInMonth(year, month) { - if (isNaN(year) || isNaN(month)) { - return NaN; + if (isHighSurrogate) + this.highSurrogate = code; + else { + // Even if the current character is a low surrogate, with no previous high surrogate, we'll + // encode it as a semi-invalid stand-alone character for the same reasons expressed above for + // unpaired high surrogates. + write32.call(dst, code, offset); + offset += 4; + this.highSurrogate = 0; } - var modMonth = mod(month, 12); - year += (month - modMonth) / 12; - return modMonth === 1 - ? isLeapYear(year) - ? 29 - : 28 - : 31 - ((modMonth % 7) % 2); } - // FORMATTING - - addFormatToken('M', ['MM', 2], 'Mo', function () { - return this.month() + 1; - }); + if (offset < dst.length) + dst = dst.slice(0, offset); - addFormatToken('MMM', 0, 0, function (format) { - return this.localeData().monthsShort(this, format); - }); + return dst; +}; - addFormatToken('MMMM', 0, 0, function (format) { - return this.localeData().months(this, format); - }); +Utf32Encoder.prototype.end = function() { + // Treat any leftover high surrogate as a semi-valid independent character. + if (!this.highSurrogate) + return; - // ALIASES + var buf = Buffer.alloc(4); - addUnitAlias('month', 'M'); + if (this.isLE) + buf.writeUInt32LE(this.highSurrogate, 0); + else + buf.writeUInt32BE(this.highSurrogate, 0); - // PRIORITY + this.highSurrogate = 0; - addUnitPriority('month', 8); + return buf; +}; - // PARSING +// -- Decoding - addRegexToken('M', match1to2); - addRegexToken('MM', match1to2, match2); - addRegexToken('MMM', function (isStrict, locale) { - return locale.monthsShortRegex(isStrict); - }); - addRegexToken('MMMM', function (isStrict, locale) { - return locale.monthsRegex(isStrict); - }); +function Utf32Decoder(options, codec) { + this.isLE = codec.isLE; + this.badChar = codec.iconv.defaultCharUnicode.charCodeAt(0); + this.overflow = []; +} - addParseToken(['M', 'MM'], function (input, array) { - array[MONTH] = toInt(input) - 1; - }); +Utf32Decoder.prototype.write = function(src) { + if (src.length === 0) + return ''; - addParseToken(['MMM', 'MMMM'], function (input, array, config, token) { - var month = config._locale.monthsParse(input, token, config._strict); - // if we didn't find a month name, mark the date as invalid. - if (month != null) { - array[MONTH] = month; - } else { - getParsingFlags(config).invalidMonth = input; - } - }); + var i = 0; + var codepoint = 0; + var dst = Buffer.alloc(src.length + 4); + var offset = 0; + var isLE = this.isLE; + var overflow = this.overflow; + var badChar = this.badChar; - // LOCALES - - var defaultLocaleMonths = - 'January_February_March_April_May_June_July_August_September_October_November_December'.split( - '_' - ), - defaultLocaleMonthsShort = - 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), - MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/, - defaultMonthsShortRegex = matchWord, - defaultMonthsRegex = matchWord; - - function localeMonths(m, format) { - if (!m) { - return isArray(this._months) - ? this._months - : this._months['standalone']; - } - return isArray(this._months) - ? this._months[m.month()] - : this._months[ - (this._months.isFormat || MONTHS_IN_FORMAT).test(format) - ? 'format' - : 'standalone' - ][m.month()]; - } - - function localeMonthsShort(m, format) { - if (!m) { - return isArray(this._monthsShort) - ? this._monthsShort - : this._monthsShort['standalone']; - } - return isArray(this._monthsShort) - ? this._monthsShort[m.month()] - : this._monthsShort[ - MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone' - ][m.month()]; - } - - function handleStrictParse(monthName, format, strict) { - var i, - ii, - mom, - llc = monthName.toLocaleLowerCase(); - if (!this._monthsParse) { - // this is not used - this._monthsParse = []; - this._longMonthsParse = []; - this._shortMonthsParse = []; - for (i = 0; i < 12; ++i) { - mom = createUTC([2000, i]); - this._shortMonthsParse[i] = this.monthsShort( - mom, - '' - ).toLocaleLowerCase(); - this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase(); + if (overflow.length > 0) { + for (; i < src.length && overflow.length < 4; i++) + overflow.push(src[i]); + + if (overflow.length === 4) { + // NOTE: codepoint is a signed int32 and can be negative. + // NOTE: We copied this block from below to help V8 optimize it (it works with array, not buffer). + if (isLE) { + codepoint = overflow[i] | (overflow[i+1] << 8) | (overflow[i+2] << 16) | (overflow[i+3] << 24); + } else { + codepoint = overflow[i+3] | (overflow[i+2] << 8) | (overflow[i+1] << 16) | (overflow[i] << 24); } + overflow.length = 0; + + offset = _writeCodepoint(dst, offset, codepoint, badChar); } + } - if (strict) { - if (format === 'MMM') { - ii = indexOf.call(this._shortMonthsParse, llc); - return ii !== -1 ? ii : null; - } else { - ii = indexOf.call(this._longMonthsParse, llc); - return ii !== -1 ? ii : null; - } + // Main loop. Should be as optimized as possible. + for (; i < src.length - 3; i += 4) { + // NOTE: codepoint is a signed int32 and can be negative. + if (isLE) { + codepoint = src[i] | (src[i+1] << 8) | (src[i+2] << 16) | (src[i+3] << 24); } else { - if (format === 'MMM') { - ii = indexOf.call(this._shortMonthsParse, llc); - if (ii !== -1) { - return ii; - } - ii = indexOf.call(this._longMonthsParse, llc); - return ii !== -1 ? ii : null; - } else { - ii = indexOf.call(this._longMonthsParse, llc); - if (ii !== -1) { - return ii; - } - ii = indexOf.call(this._shortMonthsParse, llc); - return ii !== -1 ? ii : null; - } + codepoint = src[i+3] | (src[i+2] << 8) | (src[i+1] << 16) | (src[i] << 24); } + offset = _writeCodepoint(dst, offset, codepoint, badChar); } - function localeMonthsParse(monthName, format, strict) { - var i, mom, regex; + // Keep overflowing bytes. + for (; i < src.length; i++) { + overflow.push(src[i]); + } - if (this._monthsParseExact) { - return handleStrictParse.call(this, monthName, format, strict); - } + return dst.slice(0, offset).toString('ucs2'); +}; - if (!this._monthsParse) { - this._monthsParse = []; - this._longMonthsParse = []; - this._shortMonthsParse = []; - } +function _writeCodepoint(dst, offset, codepoint, badChar) { + // NOTE: codepoint is signed int32 and can be negative. We keep it that way to help V8 with optimizations. + if (codepoint < 0 || codepoint > 0x10FFFF) { + // Not a valid Unicode codepoint + codepoint = badChar; + } - // TODO: add sorting - // Sorting makes sure if one month (or abbr) is a prefix of another - // see sorting in computeMonthsParse - for (i = 0; i < 12; i++) { - // make the regex if we don't have it already - mom = createUTC([2000, i]); - if (strict && !this._longMonthsParse[i]) { - this._longMonthsParse[i] = new RegExp( - '^' + this.months(mom, '').replace('.', '') + '$', - 'i' - ); - this._shortMonthsParse[i] = new RegExp( - '^' + this.monthsShort(mom, '').replace('.', '') + '$', - 'i' - ); - } - if (!strict && !this._monthsParse[i]) { - regex = - '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, ''); - this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i'); - } - // test the regex - if ( - strict && - format === 'MMMM' && - this._longMonthsParse[i].test(monthName) - ) { - return i; - } else if ( - strict && - format === 'MMM' && - this._shortMonthsParse[i].test(monthName) - ) { - return i; - } else if (!strict && this._monthsParse[i].test(monthName)) { - return i; - } - } + // Ephemeral Planes: Write high surrogate. + if (codepoint >= 0x10000) { + codepoint -= 0x10000; + + var high = 0xD800 | (codepoint >> 10); + dst[offset++] = high & 0xff; + dst[offset++] = high >> 8; + + // Low surrogate is written below. + var codepoint = 0xDC00 | (codepoint & 0x3FF); } - // MOMENTS + // Write BMP char or low surrogate. + dst[offset++] = codepoint & 0xff; + dst[offset++] = codepoint >> 8; - function setMonth(mom, value) { - var dayOfMonth; + return offset; +}; - if (!mom.isValid()) { - // No op - return mom; - } +Utf32Decoder.prototype.end = function() { + this.overflow.length = 0; +}; - if (typeof value === 'string') { - if (/^\d+$/.test(value)) { - value = toInt(value); - } else { - value = mom.localeData().monthsParse(value); - // TODO: Another silent failure? - if (!isNumber(value)) { - return mom; - } - } - } +// == UTF-32 Auto codec ============================================================= +// Decoder chooses automatically from UTF-32LE and UTF-32BE using BOM and space-based heuristic. +// Defaults to UTF-32LE. http://en.wikipedia.org/wiki/UTF-32 +// Encoder/decoder default can be changed: iconv.decode(buf, 'utf32', {defaultEncoding: 'utf-32be'}); - dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value)); - mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth); - return mom; - } +// Encoder prepends BOM (which can be overridden with (addBOM: false}). - function getSetMonth(value) { - if (value != null) { - setMonth(this, value); - hooks.updateOffset(this, true); - return this; - } else { - return get(this, 'Month'); - } - } +exports.utf32 = Utf32AutoCodec; +exports.ucs4 = 'utf32'; - function getDaysInMonth() { - return daysInMonth(this.year(), this.month()); - } +function Utf32AutoCodec(options, iconv) { + this.iconv = iconv; +} - function monthsShortRegex(isStrict) { - if (this._monthsParseExact) { - if (!hasOwnProp(this, '_monthsRegex')) { - computeMonthsParse.call(this); - } - if (isStrict) { - return this._monthsShortStrictRegex; - } else { - return this._monthsShortRegex; - } - } else { - if (!hasOwnProp(this, '_monthsShortRegex')) { - this._monthsShortRegex = defaultMonthsShortRegex; - } - return this._monthsShortStrictRegex && isStrict - ? this._monthsShortStrictRegex - : this._monthsShortRegex; - } - } +Utf32AutoCodec.prototype.encoder = Utf32AutoEncoder; +Utf32AutoCodec.prototype.decoder = Utf32AutoDecoder; - function monthsRegex(isStrict) { - if (this._monthsParseExact) { - if (!hasOwnProp(this, '_monthsRegex')) { - computeMonthsParse.call(this); - } - if (isStrict) { - return this._monthsStrictRegex; - } else { - return this._monthsRegex; - } - } else { - if (!hasOwnProp(this, '_monthsRegex')) { - this._monthsRegex = defaultMonthsRegex; - } - return this._monthsStrictRegex && isStrict - ? this._monthsStrictRegex - : this._monthsRegex; - } - } +// -- Encoding - function computeMonthsParse() { - function cmpLenRev(a, b) { - return b.length - a.length; - } +function Utf32AutoEncoder(options, codec) { + options = options || {}; - var shortPieces = [], - longPieces = [], - mixedPieces = [], - i, - mom; - for (i = 0; i < 12; i++) { - // make the regex if we don't have it already - mom = createUTC([2000, i]); - shortPieces.push(this.monthsShort(mom, '')); - longPieces.push(this.months(mom, '')); - mixedPieces.push(this.months(mom, '')); - mixedPieces.push(this.monthsShort(mom, '')); - } - // Sorting makes sure if one month (or abbr) is a prefix of another it - // will match the longer piece. - shortPieces.sort(cmpLenRev); - longPieces.sort(cmpLenRev); - mixedPieces.sort(cmpLenRev); - for (i = 0; i < 12; i++) { - shortPieces[i] = regexEscape(shortPieces[i]); - longPieces[i] = regexEscape(longPieces[i]); - } - for (i = 0; i < 24; i++) { - mixedPieces[i] = regexEscape(mixedPieces[i]); - } + if (options.addBOM === undefined) + options.addBOM = true; - this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i'); - this._monthsShortRegex = this._monthsRegex; - this._monthsStrictRegex = new RegExp( - '^(' + longPieces.join('|') + ')', - 'i' - ); - this._monthsShortStrictRegex = new RegExp( - '^(' + shortPieces.join('|') + ')', - 'i' - ); - } + this.encoder = codec.iconv.getEncoder(options.defaultEncoding || 'utf-32le', options); +} - // FORMATTING +Utf32AutoEncoder.prototype.write = function(str) { + return this.encoder.write(str); +}; - addFormatToken('Y', 0, 0, function () { - var y = this.year(); - return y <= 9999 ? zeroFill(y, 4) : '+' + y; - }); +Utf32AutoEncoder.prototype.end = function() { + return this.encoder.end(); +}; - addFormatToken(0, ['YY', 2], 0, function () { - return this.year() % 100; - }); +// -- Decoding + +function Utf32AutoDecoder(options, codec) { + this.decoder = null; + this.initialBufs = []; + this.initialBufsLen = 0; + this.options = options || {}; + this.iconv = codec.iconv; +} - addFormatToken(0, ['YYYY', 4], 0, 'year'); - addFormatToken(0, ['YYYYY', 5], 0, 'year'); - addFormatToken(0, ['YYYYYY', 6, true], 0, 'year'); +Utf32AutoDecoder.prototype.write = function(buf) { + if (!this.decoder) { + // Codec is not chosen yet. Accumulate initial bytes. + this.initialBufs.push(buf); + this.initialBufsLen += buf.length; - // ALIASES + if (this.initialBufsLen < 32) // We need more bytes to use space heuristic (see below) + return ''; - addUnitAlias('year', 'y'); + // We have enough bytes -> detect endianness. + var encoding = detectEncoding(this.initialBufs, this.options.defaultEncoding); + this.decoder = this.iconv.getDecoder(encoding, this.options); - // PRIORITIES + var resStr = ''; + for (var i = 0; i < this.initialBufs.length; i++) + resStr += this.decoder.write(this.initialBufs[i]); - addUnitPriority('year', 1); + this.initialBufs.length = this.initialBufsLen = 0; + return resStr; + } - // PARSING + return this.decoder.write(buf); +}; - addRegexToken('Y', matchSigned); - addRegexToken('YY', match1to2, match2); - addRegexToken('YYYY', match1to4, match4); - addRegexToken('YYYYY', match1to6, match6); - addRegexToken('YYYYYY', match1to6, match6); +Utf32AutoDecoder.prototype.end = function() { + if (!this.decoder) { + var encoding = detectEncoding(this.initialBufs, this.options.defaultEncoding); + this.decoder = this.iconv.getDecoder(encoding, this.options); - addParseToken(['YYYYY', 'YYYYYY'], YEAR); - addParseToken('YYYY', function (input, array) { - array[YEAR] = - input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input); - }); - addParseToken('YY', function (input, array) { - array[YEAR] = hooks.parseTwoDigitYear(input); - }); - addParseToken('Y', function (input, array) { - array[YEAR] = parseInt(input, 10); - }); + var resStr = ''; + for (var i = 0; i < this.initialBufs.length; i++) + resStr += this.decoder.write(this.initialBufs[i]); - // HELPERS + var trail = this.decoder.end(); + if (trail) + resStr += trail; - function daysInYear(year) { - return isLeapYear(year) ? 366 : 365; + this.initialBufs.length = this.initialBufsLen = 0; + return resStr; } - // HOOKS - - hooks.parseTwoDigitYear = function (input) { - return toInt(input) + (toInt(input) > 68 ? 1900 : 2000); - }; + return this.decoder.end(); +}; - // MOMENTS +function detectEncoding(bufs, defaultEncoding) { + var b = []; + var charsProcessed = 0; + var invalidLE = 0, invalidBE = 0; // Number of invalid chars when decoded as LE or BE. + var bmpCharsLE = 0, bmpCharsBE = 0; // Number of BMP chars when decoded as LE or BE. - var getSetYear = makeGetSet('FullYear', true); + outer_loop: + for (var i = 0; i < bufs.length; i++) { + var buf = bufs[i]; + for (var j = 0; j < buf.length; j++) { + b.push(buf[j]); + if (b.length === 4) { + if (charsProcessed === 0) { + // Check BOM first. + if (b[0] === 0xFF && b[1] === 0xFE && b[2] === 0 && b[3] === 0) { + return 'utf-32le'; + } + if (b[0] === 0 && b[1] === 0 && b[2] === 0xFE && b[3] === 0xFF) { + return 'utf-32be'; + } + } - function getIsLeapYear() { - return isLeapYear(this.year()); - } + if (b[0] !== 0 || b[1] > 0x10) invalidBE++; + if (b[3] !== 0 || b[2] > 0x10) invalidLE++; - function createDate(y, m, d, h, M, s, ms) { - // can't just apply() to create a date: - // https://stackoverflow.com/q/181348 - var date; - // the date constructor remaps years 0-99 to 1900-1999 - if (y < 100 && y >= 0) { - // preserve leap years using a full 400 year cycle, then reset - date = new Date(y + 400, m, d, h, M, s, ms); - if (isFinite(date.getFullYear())) { - date.setFullYear(y); - } - } else { - date = new Date(y, m, d, h, M, s, ms); - } + if (b[0] === 0 && b[1] === 0 && (b[2] !== 0 || b[3] !== 0)) bmpCharsBE++; + if ((b[0] !== 0 || b[1] !== 0) && b[2] === 0 && b[3] === 0) bmpCharsLE++; - return date; - } + b.length = 0; + charsProcessed++; - function createUTCDate(y) { - var date, args; - // the Date.UTC function remaps years 0-99 to 1900-1999 - if (y < 100 && y >= 0) { - args = Array.prototype.slice.call(arguments); - // preserve leap years using a full 400 year cycle, then reset - args[0] = y + 400; - date = new Date(Date.UTC.apply(null, args)); - if (isFinite(date.getUTCFullYear())) { - date.setUTCFullYear(y); + if (charsProcessed >= 100) { + break outer_loop; + } } - } else { - date = new Date(Date.UTC.apply(null, arguments)); } - - return date; } - // start-of-first-week - start-of-year - function firstWeekOffset(year, dow, doy) { - var // first-week day -- which january is always in the first week (4 for iso, 1 for other) - fwd = 7 + dow - doy, - // first-week day local weekday -- which local weekday is fwd - fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7; + // Make decisions. + if (bmpCharsBE - invalidBE > bmpCharsLE - invalidLE) return 'utf-32be'; + if (bmpCharsBE - invalidBE < bmpCharsLE - invalidLE) return 'utf-32le'; - return -fwdlw + fwd - 1; - } + // Couldn't decide (likely all zeros or not enough data). + return defaultEncoding || 'utf-32le'; +} - // https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday - function dayOfYearFromWeeks(year, week, weekday, dow, doy) { - var localWeekday = (7 + weekday - dow) % 7, - weekOffset = firstWeekOffset(year, dow, doy), - dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset, - resYear, - resDayOfYear; - if (dayOfYear <= 0) { - resYear = year - 1; - resDayOfYear = daysInYear(resYear) + dayOfYear; - } else if (dayOfYear > daysInYear(year)) { - resYear = year + 1; - resDayOfYear = dayOfYear - daysInYear(year); - } else { - resYear = year; - resDayOfYear = dayOfYear; - } +/***/ }), - return { - year: resYear, - dayOfYear: resDayOfYear, - }; - } +/***/ 1644: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - function weekOfYear(mom, dow, doy) { - var weekOffset = firstWeekOffset(mom.year(), dow, doy), - week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1, - resWeek, - resYear; +"use strict"; - if (week < 1) { - resYear = mom.year() - 1; - resWeek = week + weeksInYear(resYear, dow, doy); - } else if (week > weeksInYear(mom.year(), dow, doy)) { - resWeek = week - weeksInYear(mom.year(), dow, doy); - resYear = mom.year() + 1; - } else { - resYear = mom.year(); - resWeek = week; - } +var Buffer = (__nccwpck_require__(5118).Buffer); - return { - week: resWeek, - year: resYear, - }; - } +// UTF-7 codec, according to https://tools.ietf.org/html/rfc2152 +// See also below a UTF-7-IMAP codec, according to http://tools.ietf.org/html/rfc3501#section-5.1.3 - function weeksInYear(year, dow, doy) { - var weekOffset = firstWeekOffset(year, dow, doy), - weekOffsetNext = firstWeekOffset(year + 1, dow, doy); - return (daysInYear(year) - weekOffset + weekOffsetNext) / 7; - } +exports.utf7 = Utf7Codec; +exports.unicode11utf7 = 'utf7'; // Alias UNICODE-1-1-UTF-7 +function Utf7Codec(codecOptions, iconv) { + this.iconv = iconv; +}; - // FORMATTING +Utf7Codec.prototype.encoder = Utf7Encoder; +Utf7Codec.prototype.decoder = Utf7Decoder; +Utf7Codec.prototype.bomAware = true; - addFormatToken('w', ['ww', 2], 'wo', 'week'); - addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek'); - // ALIASES +// -- Encoding - addUnitAlias('week', 'w'); - addUnitAlias('isoWeek', 'W'); +var nonDirectChars = /[^A-Za-z0-9'\(\),-\.\/:\? \n\r\t]+/g; - // PRIORITIES +function Utf7Encoder(options, codec) { + this.iconv = codec.iconv; +} - addUnitPriority('week', 5); - addUnitPriority('isoWeek', 5); +Utf7Encoder.prototype.write = function(str) { + // Naive implementation. + // Non-direct chars are encoded as "+-"; single "+" char is encoded as "+-". + return Buffer.from(str.replace(nonDirectChars, function(chunk) { + return "+" + (chunk === '+' ? '' : + this.iconv.encode(chunk, 'utf16-be').toString('base64').replace(/=+$/, '')) + + "-"; + }.bind(this))); +} - // PARSING +Utf7Encoder.prototype.end = function() { +} - addRegexToken('w', match1to2); - addRegexToken('ww', match1to2, match2); - addRegexToken('W', match1to2); - addRegexToken('WW', match1to2, match2); - addWeekParseToken( - ['w', 'ww', 'W', 'WW'], - function (input, week, config, token) { - week[token.substr(0, 1)] = toInt(input); - } - ); +// -- Decoding - // HELPERS +function Utf7Decoder(options, codec) { + this.iconv = codec.iconv; + this.inBase64 = false; + this.base64Accum = ''; +} - // LOCALES +var base64Regex = /[A-Za-z0-9\/+]/; +var base64Chars = []; +for (var i = 0; i < 256; i++) + base64Chars[i] = base64Regex.test(String.fromCharCode(i)); - function localeWeek(mom) { - return weekOfYear(mom, this._week.dow, this._week.doy).week; - } +var plusChar = '+'.charCodeAt(0), + minusChar = '-'.charCodeAt(0), + andChar = '&'.charCodeAt(0); - var defaultLocaleWeek = { - dow: 0, // Sunday is the first day of the week. - doy: 6, // The week that contains Jan 6th is the first week of the year. - }; +Utf7Decoder.prototype.write = function(buf) { + var res = "", lastI = 0, + inBase64 = this.inBase64, + base64Accum = this.base64Accum; - function localeFirstDayOfWeek() { - return this._week.dow; - } + // The decoder is more involved as we must handle chunks in stream. - function localeFirstDayOfYear() { - return this._week.doy; - } + for (var i = 0; i < buf.length; i++) { + if (!inBase64) { // We're in direct mode. + // Write direct chars until '+' + if (buf[i] == plusChar) { + res += this.iconv.decode(buf.slice(lastI, i), "ascii"); // Write direct chars. + lastI = i+1; + inBase64 = true; + } + } else { // We decode base64. + if (!base64Chars[buf[i]]) { // Base64 ended. + if (i == lastI && buf[i] == minusChar) {// "+-" -> "+" + res += "+"; + } else { + var b64str = base64Accum + this.iconv.decode(buf.slice(lastI, i), "ascii"); + res += this.iconv.decode(Buffer.from(b64str, 'base64'), "utf16-be"); + } - // MOMENTS + if (buf[i] != minusChar) // Minus is absorbed after base64. + i--; - function getSetWeek(input) { - var week = this.localeData().week(this); - return input == null ? week : this.add((input - week) * 7, 'd'); + lastI = i+1; + inBase64 = false; + base64Accum = ''; + } + } } - function getSetISOWeek(input) { - var week = weekOfYear(this, 1, 4).week; - return input == null ? week : this.add((input - week) * 7, 'd'); - } + if (!inBase64) { + res += this.iconv.decode(buf.slice(lastI), "ascii"); // Write direct chars. + } else { + var b64str = base64Accum + this.iconv.decode(buf.slice(lastI), "ascii"); - // FORMATTING + var canBeDecoded = b64str.length - (b64str.length % 8); // Minimal chunk: 2 quads -> 2x3 bytes -> 3 chars. + base64Accum = b64str.slice(canBeDecoded); // The rest will be decoded in future. + b64str = b64str.slice(0, canBeDecoded); - addFormatToken('d', 0, 'do', 'day'); + res += this.iconv.decode(Buffer.from(b64str, 'base64'), "utf16-be"); + } - addFormatToken('dd', 0, 0, function (format) { - return this.localeData().weekdaysMin(this, format); - }); + this.inBase64 = inBase64; + this.base64Accum = base64Accum; - addFormatToken('ddd', 0, 0, function (format) { - return this.localeData().weekdaysShort(this, format); - }); + return res; +} - addFormatToken('dddd', 0, 0, function (format) { - return this.localeData().weekdays(this, format); - }); +Utf7Decoder.prototype.end = function() { + var res = ""; + if (this.inBase64 && this.base64Accum.length > 0) + res = this.iconv.decode(Buffer.from(this.base64Accum, 'base64'), "utf16-be"); - addFormatToken('e', 0, 0, 'weekday'); - addFormatToken('E', 0, 0, 'isoWeekday'); + this.inBase64 = false; + this.base64Accum = ''; + return res; +} - // ALIASES - addUnitAlias('day', 'd'); - addUnitAlias('weekday', 'e'); - addUnitAlias('isoWeekday', 'E'); +// UTF-7-IMAP codec. +// RFC3501 Sec. 5.1.3 Modified UTF-7 (http://tools.ietf.org/html/rfc3501#section-5.1.3) +// Differences: +// * Base64 part is started by "&" instead of "+" +// * Direct characters are 0x20-0x7E, except "&" (0x26) +// * In Base64, "," is used instead of "/" +// * Base64 must not be used to represent direct characters. +// * No implicit shift back from Base64 (should always end with '-') +// * String must end in non-shifted position. +// * "-&" while in base64 is not allowed. - // PRIORITY - addUnitPriority('day', 11); - addUnitPriority('weekday', 11); - addUnitPriority('isoWeekday', 11); - // PARSING +exports.utf7imap = Utf7IMAPCodec; +function Utf7IMAPCodec(codecOptions, iconv) { + this.iconv = iconv; +}; - addRegexToken('d', match1to2); - addRegexToken('e', match1to2); - addRegexToken('E', match1to2); - addRegexToken('dd', function (isStrict, locale) { - return locale.weekdaysMinRegex(isStrict); - }); - addRegexToken('ddd', function (isStrict, locale) { - return locale.weekdaysShortRegex(isStrict); - }); - addRegexToken('dddd', function (isStrict, locale) { - return locale.weekdaysRegex(isStrict); - }); +Utf7IMAPCodec.prototype.encoder = Utf7IMAPEncoder; +Utf7IMAPCodec.prototype.decoder = Utf7IMAPDecoder; +Utf7IMAPCodec.prototype.bomAware = true; - addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) { - var weekday = config._locale.weekdaysParse(input, token, config._strict); - // if we didn't get a weekday name, mark the date as invalid - if (weekday != null) { - week.d = weekday; - } else { - getParsingFlags(config).invalidWeekday = input; - } - }); - addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) { - week[token] = toInt(input); - }); +// -- Encoding - // HELPERS +function Utf7IMAPEncoder(options, codec) { + this.iconv = codec.iconv; + this.inBase64 = false; + this.base64Accum = Buffer.alloc(6); + this.base64AccumIdx = 0; +} - function parseWeekday(input, locale) { - if (typeof input !== 'string') { - return input; - } +Utf7IMAPEncoder.prototype.write = function(str) { + var inBase64 = this.inBase64, + base64Accum = this.base64Accum, + base64AccumIdx = this.base64AccumIdx, + buf = Buffer.alloc(str.length*5 + 10), bufIdx = 0; - if (!isNaN(input)) { - return parseInt(input, 10); - } + for (var i = 0; i < str.length; i++) { + var uChar = str.charCodeAt(i); + if (0x20 <= uChar && uChar <= 0x7E) { // Direct character or '&'. + if (inBase64) { + if (base64AccumIdx > 0) { + bufIdx += buf.write(base64Accum.slice(0, base64AccumIdx).toString('base64').replace(/\//g, ',').replace(/=+$/, ''), bufIdx); + base64AccumIdx = 0; + } - input = locale.weekdaysParse(input); - if (typeof input === 'number') { - return input; - } + buf[bufIdx++] = minusChar; // Write '-', then go to direct mode. + inBase64 = false; + } - return null; - } + if (!inBase64) { + buf[bufIdx++] = uChar; // Write direct character - function parseIsoWeekday(input, locale) { - if (typeof input === 'string') { - return locale.weekdaysParse(input) % 7 || 7; - } - return isNaN(input) ? null : input; - } - - // LOCALES - function shiftWeekdays(ws, n) { - return ws.slice(n, 7).concat(ws.slice(0, n)); - } - - var defaultLocaleWeekdays = - 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), - defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), - defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), - defaultWeekdaysRegex = matchWord, - defaultWeekdaysShortRegex = matchWord, - defaultWeekdaysMinRegex = matchWord; - - function localeWeekdays(m, format) { - var weekdays = isArray(this._weekdays) - ? this._weekdays - : this._weekdays[ - m && m !== true && this._weekdays.isFormat.test(format) - ? 'format' - : 'standalone' - ]; - return m === true - ? shiftWeekdays(weekdays, this._week.dow) - : m - ? weekdays[m.day()] - : weekdays; - } - - function localeWeekdaysShort(m) { - return m === true - ? shiftWeekdays(this._weekdaysShort, this._week.dow) - : m - ? this._weekdaysShort[m.day()] - : this._weekdaysShort; - } - - function localeWeekdaysMin(m) { - return m === true - ? shiftWeekdays(this._weekdaysMin, this._week.dow) - : m - ? this._weekdaysMin[m.day()] - : this._weekdaysMin; - } - - function handleStrictParse$1(weekdayName, format, strict) { - var i, - ii, - mom, - llc = weekdayName.toLocaleLowerCase(); - if (!this._weekdaysParse) { - this._weekdaysParse = []; - this._shortWeekdaysParse = []; - this._minWeekdaysParse = []; - - for (i = 0; i < 7; ++i) { - mom = createUTC([2000, 1]).day(i); - this._minWeekdaysParse[i] = this.weekdaysMin( - mom, - '' - ).toLocaleLowerCase(); - this._shortWeekdaysParse[i] = this.weekdaysShort( - mom, - '' - ).toLocaleLowerCase(); - this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase(); + if (uChar === andChar) // Ampersand -> '&-' + buf[bufIdx++] = minusChar; } - } - if (strict) { - if (format === 'dddd') { - ii = indexOf.call(this._weekdaysParse, llc); - return ii !== -1 ? ii : null; - } else if (format === 'ddd') { - ii = indexOf.call(this._shortWeekdaysParse, llc); - return ii !== -1 ? ii : null; - } else { - ii = indexOf.call(this._minWeekdaysParse, llc); - return ii !== -1 ? ii : null; + } else { // Non-direct character + if (!inBase64) { + buf[bufIdx++] = andChar; // Write '&', then go to base64 mode. + inBase64 = true; } - } else { - if (format === 'dddd') { - ii = indexOf.call(this._weekdaysParse, llc); - if (ii !== -1) { - return ii; - } - ii = indexOf.call(this._shortWeekdaysParse, llc); - if (ii !== -1) { - return ii; - } - ii = indexOf.call(this._minWeekdaysParse, llc); - return ii !== -1 ? ii : null; - } else if (format === 'ddd') { - ii = indexOf.call(this._shortWeekdaysParse, llc); - if (ii !== -1) { - return ii; - } - ii = indexOf.call(this._weekdaysParse, llc); - if (ii !== -1) { - return ii; - } - ii = indexOf.call(this._minWeekdaysParse, llc); - return ii !== -1 ? ii : null; - } else { - ii = indexOf.call(this._minWeekdaysParse, llc); - if (ii !== -1) { - return ii; - } - ii = indexOf.call(this._weekdaysParse, llc); - if (ii !== -1) { - return ii; + if (inBase64) { + base64Accum[base64AccumIdx++] = uChar >> 8; + base64Accum[base64AccumIdx++] = uChar & 0xFF; + + if (base64AccumIdx == base64Accum.length) { + bufIdx += buf.write(base64Accum.toString('base64').replace(/\//g, ','), bufIdx); + base64AccumIdx = 0; } - ii = indexOf.call(this._shortWeekdaysParse, llc); - return ii !== -1 ? ii : null; } } } - function localeWeekdaysParse(weekdayName, format, strict) { - var i, mom, regex; + this.inBase64 = inBase64; + this.base64AccumIdx = base64AccumIdx; - if (this._weekdaysParseExact) { - return handleStrictParse$1.call(this, weekdayName, format, strict); - } + return buf.slice(0, bufIdx); +} - if (!this._weekdaysParse) { - this._weekdaysParse = []; - this._minWeekdaysParse = []; - this._shortWeekdaysParse = []; - this._fullWeekdaysParse = []; +Utf7IMAPEncoder.prototype.end = function() { + var buf = Buffer.alloc(10), bufIdx = 0; + if (this.inBase64) { + if (this.base64AccumIdx > 0) { + bufIdx += buf.write(this.base64Accum.slice(0, this.base64AccumIdx).toString('base64').replace(/\//g, ',').replace(/=+$/, ''), bufIdx); + this.base64AccumIdx = 0; } - for (i = 0; i < 7; i++) { - // make the regex if we don't have it already - - mom = createUTC([2000, 1]).day(i); - if (strict && !this._fullWeekdaysParse[i]) { - this._fullWeekdaysParse[i] = new RegExp( - '^' + this.weekdays(mom, '').replace('.', '\\.?') + '$', - 'i' - ); - this._shortWeekdaysParse[i] = new RegExp( - '^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$', - 'i' - ); - this._minWeekdaysParse[i] = new RegExp( - '^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$', - 'i' - ); - } - if (!this._weekdaysParse[i]) { - regex = - '^' + - this.weekdays(mom, '') + - '|^' + - this.weekdaysShort(mom, '') + - '|^' + - this.weekdaysMin(mom, ''); - this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i'); - } - // test the regex - if ( - strict && - format === 'dddd' && - this._fullWeekdaysParse[i].test(weekdayName) - ) { - return i; - } else if ( - strict && - format === 'ddd' && - this._shortWeekdaysParse[i].test(weekdayName) - ) { - return i; - } else if ( - strict && - format === 'dd' && - this._minWeekdaysParse[i].test(weekdayName) - ) { - return i; - } else if (!strict && this._weekdaysParse[i].test(weekdayName)) { - return i; - } - } + buf[bufIdx++] = minusChar; // Write '-', then go to direct mode. + this.inBase64 = false; } - // MOMENTS + return buf.slice(0, bufIdx); +} - function getSetDayOfWeek(input) { - if (!this.isValid()) { - return input != null ? this : NaN; - } - var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay(); - if (input != null) { - input = parseWeekday(input, this.localeData()); - return this.add(input - day, 'd'); - } else { - return day; - } - } - function getSetLocaleDayOfWeek(input) { - if (!this.isValid()) { - return input != null ? this : NaN; - } - var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7; - return input == null ? weekday : this.add(input - weekday, 'd'); - } +// -- Decoding - function getSetISODayOfWeek(input) { - if (!this.isValid()) { - return input != null ? this : NaN; - } +function Utf7IMAPDecoder(options, codec) { + this.iconv = codec.iconv; + this.inBase64 = false; + this.base64Accum = ''; +} - // behaves the same as moment#day except - // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6) - // as a setter, sunday should belong to the previous week. +var base64IMAPChars = base64Chars.slice(); +base64IMAPChars[','.charCodeAt(0)] = true; - if (input != null) { - var weekday = parseIsoWeekday(input, this.localeData()); - return this.day(this.day() % 7 ? weekday : weekday - 7); - } else { - return this.day() || 7; - } - } +Utf7IMAPDecoder.prototype.write = function(buf) { + var res = "", lastI = 0, + inBase64 = this.inBase64, + base64Accum = this.base64Accum; - function weekdaysRegex(isStrict) { - if (this._weekdaysParseExact) { - if (!hasOwnProp(this, '_weekdaysRegex')) { - computeWeekdaysParse.call(this); - } - if (isStrict) { - return this._weekdaysStrictRegex; - } else { - return this._weekdaysRegex; - } - } else { - if (!hasOwnProp(this, '_weekdaysRegex')) { - this._weekdaysRegex = defaultWeekdaysRegex; - } - return this._weekdaysStrictRegex && isStrict - ? this._weekdaysStrictRegex - : this._weekdaysRegex; - } - } + // The decoder is more involved as we must handle chunks in stream. + // It is forgiving, closer to standard UTF-7 (for example, '-' is optional at the end). - function weekdaysShortRegex(isStrict) { - if (this._weekdaysParseExact) { - if (!hasOwnProp(this, '_weekdaysRegex')) { - computeWeekdaysParse.call(this); - } - if (isStrict) { - return this._weekdaysShortStrictRegex; - } else { - return this._weekdaysShortRegex; - } - } else { - if (!hasOwnProp(this, '_weekdaysShortRegex')) { - this._weekdaysShortRegex = defaultWeekdaysShortRegex; + for (var i = 0; i < buf.length; i++) { + if (!inBase64) { // We're in direct mode. + // Write direct chars until '&' + if (buf[i] == andChar) { + res += this.iconv.decode(buf.slice(lastI, i), "ascii"); // Write direct chars. + lastI = i+1; + inBase64 = true; } - return this._weekdaysShortStrictRegex && isStrict - ? this._weekdaysShortStrictRegex - : this._weekdaysShortRegex; - } - } + } else { // We decode base64. + if (!base64IMAPChars[buf[i]]) { // Base64 ended. + if (i == lastI && buf[i] == minusChar) { // "&-" -> "&" + res += "&"; + } else { + var b64str = base64Accum + this.iconv.decode(buf.slice(lastI, i), "ascii").replace(/,/g, '/'); + res += this.iconv.decode(Buffer.from(b64str, 'base64'), "utf16-be"); + } - function weekdaysMinRegex(isStrict) { - if (this._weekdaysParseExact) { - if (!hasOwnProp(this, '_weekdaysRegex')) { - computeWeekdaysParse.call(this); - } - if (isStrict) { - return this._weekdaysMinStrictRegex; - } else { - return this._weekdaysMinRegex; - } - } else { - if (!hasOwnProp(this, '_weekdaysMinRegex')) { - this._weekdaysMinRegex = defaultWeekdaysMinRegex; + if (buf[i] != minusChar) // Minus may be absorbed after base64. + i--; + + lastI = i+1; + inBase64 = false; + base64Accum = ''; } - return this._weekdaysMinStrictRegex && isStrict - ? this._weekdaysMinStrictRegex - : this._weekdaysMinRegex; } } - function computeWeekdaysParse() { - function cmpLenRev(a, b) { - return b.length - a.length; - } + if (!inBase64) { + res += this.iconv.decode(buf.slice(lastI), "ascii"); // Write direct chars. + } else { + var b64str = base64Accum + this.iconv.decode(buf.slice(lastI), "ascii").replace(/,/g, '/'); - var minPieces = [], - shortPieces = [], - longPieces = [], - mixedPieces = [], - i, - mom, - minp, - shortp, - longp; - for (i = 0; i < 7; i++) { - // make the regex if we don't have it already - mom = createUTC([2000, 1]).day(i); - minp = regexEscape(this.weekdaysMin(mom, '')); - shortp = regexEscape(this.weekdaysShort(mom, '')); - longp = regexEscape(this.weekdays(mom, '')); - minPieces.push(minp); - shortPieces.push(shortp); - longPieces.push(longp); - mixedPieces.push(minp); - mixedPieces.push(shortp); - mixedPieces.push(longp); - } - // Sorting makes sure if one weekday (or abbr) is a prefix of another it - // will match the longer piece. - minPieces.sort(cmpLenRev); - shortPieces.sort(cmpLenRev); - longPieces.sort(cmpLenRev); - mixedPieces.sort(cmpLenRev); - - this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i'); - this._weekdaysShortRegex = this._weekdaysRegex; - this._weekdaysMinRegex = this._weekdaysRegex; - - this._weekdaysStrictRegex = new RegExp( - '^(' + longPieces.join('|') + ')', - 'i' - ); - this._weekdaysShortStrictRegex = new RegExp( - '^(' + shortPieces.join('|') + ')', - 'i' - ); - this._weekdaysMinStrictRegex = new RegExp( - '^(' + minPieces.join('|') + ')', - 'i' - ); + var canBeDecoded = b64str.length - (b64str.length % 8); // Minimal chunk: 2 quads -> 2x3 bytes -> 3 chars. + base64Accum = b64str.slice(canBeDecoded); // The rest will be decoded in future. + b64str = b64str.slice(0, canBeDecoded); + + res += this.iconv.decode(Buffer.from(b64str, 'base64'), "utf16-be"); } - // FORMATTING + this.inBase64 = inBase64; + this.base64Accum = base64Accum; - function hFormat() { - return this.hours() % 12 || 12; - } + return res; +} - function kFormat() { - return this.hours() || 24; - } +Utf7IMAPDecoder.prototype.end = function() { + var res = ""; + if (this.inBase64 && this.base64Accum.length > 0) + res = this.iconv.decode(Buffer.from(this.base64Accum, 'base64'), "utf16-be"); + + this.inBase64 = false; + this.base64Accum = ''; + return res; +} - addFormatToken('H', ['HH', 2], 0, 'hour'); - addFormatToken('h', ['hh', 2], 0, hFormat); - addFormatToken('k', ['kk', 2], 0, kFormat); - addFormatToken('hmm', 0, 0, function () { - return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2); - }); - addFormatToken('hmmss', 0, 0, function () { - return ( - '' + - hFormat.apply(this) + - zeroFill(this.minutes(), 2) + - zeroFill(this.seconds(), 2) - ); - }); - addFormatToken('Hmm', 0, 0, function () { - return '' + this.hours() + zeroFill(this.minutes(), 2); - }); +/***/ }), - addFormatToken('Hmmss', 0, 0, function () { - return ( - '' + - this.hours() + - zeroFill(this.minutes(), 2) + - zeroFill(this.seconds(), 2) - ); - }); +/***/ 7961: +/***/ ((__unused_webpack_module, exports) => { - function meridiem(token, lowercase) { - addFormatToken(token, 0, 0, function () { - return this.localeData().meridiem( - this.hours(), - this.minutes(), - lowercase - ); - }); +"use strict"; + + +var BOMChar = '\uFEFF'; + +exports.PrependBOM = PrependBOMWrapper +function PrependBOMWrapper(encoder, options) { + this.encoder = encoder; + this.addBOM = true; +} + +PrependBOMWrapper.prototype.write = function(str) { + if (this.addBOM) { + str = BOMChar + str; + this.addBOM = false; } - meridiem('a', true); - meridiem('A', false); + return this.encoder.write(str); +} + +PrependBOMWrapper.prototype.end = function() { + return this.encoder.end(); +} - // ALIASES - addUnitAlias('hour', 'h'); +//------------------------------------------------------------------------------ - // PRIORITY - addUnitPriority('hour', 13); +exports.StripBOM = StripBOMWrapper; +function StripBOMWrapper(decoder, options) { + this.decoder = decoder; + this.pass = false; + this.options = options || {}; +} - // PARSING +StripBOMWrapper.prototype.write = function(buf) { + var res = this.decoder.write(buf); + if (this.pass || !res) + return res; - function matchMeridiem(isStrict, locale) { - return locale._meridiemParse; + if (res[0] === BOMChar) { + res = res.slice(1); + if (typeof this.options.stripBOM === 'function') + this.options.stripBOM(); } - addRegexToken('a', matchMeridiem); - addRegexToken('A', matchMeridiem); - addRegexToken('H', match1to2); - addRegexToken('h', match1to2); - addRegexToken('k', match1to2); - addRegexToken('HH', match1to2, match2); - addRegexToken('hh', match1to2, match2); - addRegexToken('kk', match1to2, match2); + this.pass = true; + return res; +} - addRegexToken('hmm', match3to4); - addRegexToken('hmmss', match5to6); - addRegexToken('Hmm', match3to4); - addRegexToken('Hmmss', match5to6); +StripBOMWrapper.prototype.end = function() { + return this.decoder.end(); +} - addParseToken(['H', 'HH'], HOUR); - addParseToken(['k', 'kk'], function (input, array, config) { - var kInput = toInt(input); - array[HOUR] = kInput === 24 ? 0 : kInput; - }); - addParseToken(['a', 'A'], function (input, array, config) { - config._isPm = config._locale.isPM(input); - config._meridiem = input; - }); - addParseToken(['h', 'hh'], function (input, array, config) { - array[HOUR] = toInt(input); - getParsingFlags(config).bigHour = true; - }); - addParseToken('hmm', function (input, array, config) { - var pos = input.length - 2; - array[HOUR] = toInt(input.substr(0, pos)); - array[MINUTE] = toInt(input.substr(pos)); - getParsingFlags(config).bigHour = true; - }); - addParseToken('hmmss', function (input, array, config) { - var pos1 = input.length - 4, - pos2 = input.length - 2; - array[HOUR] = toInt(input.substr(0, pos1)); - array[MINUTE] = toInt(input.substr(pos1, 2)); - array[SECOND] = toInt(input.substr(pos2)); - getParsingFlags(config).bigHour = true; - }); - addParseToken('Hmm', function (input, array, config) { - var pos = input.length - 2; - array[HOUR] = toInt(input.substr(0, pos)); - array[MINUTE] = toInt(input.substr(pos)); - }); - addParseToken('Hmmss', function (input, array, config) { - var pos1 = input.length - 4, - pos2 = input.length - 2; - array[HOUR] = toInt(input.substr(0, pos1)); - array[MINUTE] = toInt(input.substr(pos1, 2)); - array[SECOND] = toInt(input.substr(pos2)); - }); - // LOCALES - function localeIsPM(input) { - // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays - // Using charAt should be more compatible. - return (input + '').toLowerCase().charAt(0) === 'p'; - } +/***/ }), - var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i, - // Setting the hour should keep the time, because the user explicitly - // specified which hour they want. So trying to maintain the same hour (in - // a new timezone) makes sense. Adding/subtracting hours does not follow - // this rule. - getSetHour = makeGetSet('Hours', true); +/***/ 9032: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - function localeMeridiem(hours, minutes, isLower) { - if (hours > 11) { - return isLower ? 'pm' : 'PM'; - } else { - return isLower ? 'am' : 'AM'; - } - } +"use strict"; - var baseConfig = { - calendar: defaultCalendar, - longDateFormat: defaultLongDateFormat, - invalidDate: defaultInvalidDate, - ordinal: defaultOrdinal, - dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse, - relativeTime: defaultRelativeTime, - months: defaultLocaleMonths, - monthsShort: defaultLocaleMonthsShort, +var Buffer = (__nccwpck_require__(5118).Buffer); - week: defaultLocaleWeek, +var bomHandling = __nccwpck_require__(7961), + iconv = module.exports; - weekdays: defaultLocaleWeekdays, - weekdaysMin: defaultLocaleWeekdaysMin, - weekdaysShort: defaultLocaleWeekdaysShort, +// All codecs and aliases are kept here, keyed by encoding name/alias. +// They are lazy loaded in `iconv.getCodec` from `encodings/index.js`. +iconv.encodings = null; - meridiemParse: defaultLocaleMeridiemParse, - }; +// Characters emitted in case of error. +iconv.defaultCharUnicode = '�'; +iconv.defaultCharSingleByte = '?'; - // internal storage for locale config files - var locales = {}, - localeFamilies = {}, - globalLocale; - - function commonPrefix(arr1, arr2) { - var i, - minl = Math.min(arr1.length, arr2.length); - for (i = 0; i < minl; i += 1) { - if (arr1[i] !== arr2[i]) { - return i; - } - } - return minl; - } - - function normalizeLocale(key) { - return key ? key.toLowerCase().replace('_', '-') : key; - } - - // pick the locale from the array - // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each - // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root - function chooseLocale(names) { - var i = 0, - j, - next, - locale, - split; - - while (i < names.length) { - split = normalizeLocale(names[i]).split('-'); - j = split.length; - next = normalizeLocale(names[i + 1]); - next = next ? next.split('-') : null; - while (j > 0) { - locale = loadLocale(split.slice(0, j).join('-')); - if (locale) { - return locale; - } - if ( - next && - next.length >= j && - commonPrefix(split, next) >= j - 1 - ) { - //the next array item is better than a shallower substring of this one - break; - } - j--; - } - i++; +// Public API. +iconv.encode = function encode(str, encoding, options) { + str = "" + (str || ""); // Ensure string. + + var encoder = iconv.getEncoder(encoding, options); + + var res = encoder.write(str); + var trail = encoder.end(); + + return (trail && trail.length > 0) ? Buffer.concat([res, trail]) : res; +} + +iconv.decode = function decode(buf, encoding, options) { + if (typeof buf === 'string') { + if (!iconv.skipDecodeWarning) { + console.error('Iconv-lite warning: decode()-ing strings is deprecated. Refer to https://github.com/ashtuchkin/iconv-lite/wiki/Use-Buffers-when-decoding'); + iconv.skipDecodeWarning = true; } - return globalLocale; - } - function isLocaleNameSane(name) { - // Prevent names that look like filesystem paths, i.e contain '/' or '\' - return name.match('^[^/\\\\]*$') != null; + buf = Buffer.from("" + (buf || ""), "binary"); // Ensure buffer. } - function loadLocale(name) { - var oldLocale = null, - aliasedRequire; - // TODO: Find a better way to register and load all the locales in Node - if ( - locales[name] === undefined && - "object" !== 'undefined' && - module && - module.exports && - isLocaleNameSane(name) - ) { - try { - oldLocale = globalLocale._abbr; - aliasedRequire = require; - aliasedRequire('./locale/' + name); - getSetGlobalLocale(oldLocale); - } catch (e) { - // mark as not found to avoid repeating expensive file require call causing high CPU - // when trying to find en-US, en_US, en-us for every format call - locales[name] = null; // null means not found - } - } - return locales[name]; + var decoder = iconv.getDecoder(encoding, options); + + var res = decoder.write(buf); + var trail = decoder.end(); + + return trail ? (res + trail) : res; +} + +iconv.encodingExists = function encodingExists(enc) { + try { + iconv.getCodec(enc); + return true; + } catch (e) { + return false; } +} - // This function will load locale and then set the global locale. If - // no arguments are passed in, it will simply return the current global - // locale key. - function getSetGlobalLocale(key, values) { - var data; - if (key) { - if (isUndefined(values)) { - data = getLocale(key); - } else { - data = defineLocale(key, values); - } +// Legacy aliases to convert functions +iconv.toEncoding = iconv.encode; +iconv.fromEncoding = iconv.decode; - if (data) { - // moment.duration._locale = moment._locale = data; - globalLocale = data; - } else { - if (typeof console !== 'undefined' && console.warn) { - //warn user if arguments are passed but the locale could not be set - console.warn( - 'Locale ' + key + ' not found. Did you forget to load it?' - ); - } - } - } +// Search for a codec in iconv.encodings. Cache codec data in iconv._codecDataCache. +iconv._codecDataCache = {}; +iconv.getCodec = function getCodec(encoding) { + if (!iconv.encodings) + iconv.encodings = __nccwpck_require__(2733); // Lazy load all encoding definitions. + + // Canonicalize encoding name: strip all non-alphanumeric chars and appended year. + var enc = iconv._canonicalizeEncoding(encoding); + + // Traverse iconv.encodings to find actual codec. + var codecOptions = {}; + while (true) { + var codec = iconv._codecDataCache[enc]; + if (codec) + return codec; - return globalLocale._abbr; - } - - function defineLocale(name, config) { - if (config !== null) { - var locale, - parentConfig = baseConfig; - config.abbr = name; - if (locales[name] != null) { - deprecateSimple( - 'defineLocaleOverride', - 'use moment.updateLocale(localeName, config) to change ' + - 'an existing locale. moment.defineLocale(localeName, ' + - 'config) should only be used for creating a new locale ' + - 'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.' - ); - parentConfig = locales[name]._config; - } else if (config.parentLocale != null) { - if (locales[config.parentLocale] != null) { - parentConfig = locales[config.parentLocale]._config; - } else { - locale = loadLocale(config.parentLocale); - if (locale != null) { - parentConfig = locale._config; - } else { - if (!localeFamilies[config.parentLocale]) { - localeFamilies[config.parentLocale] = []; - } - localeFamilies[config.parentLocale].push({ - name: name, - config: config, - }); - return null; - } - } - } - locales[name] = new Locale(mergeConfigs(parentConfig, config)); + var codecDef = iconv.encodings[enc]; - if (localeFamilies[name]) { - localeFamilies[name].forEach(function (x) { - defineLocale(x.name, x.config); - }); - } + switch (typeof codecDef) { + case "string": // Direct alias to other encoding. + enc = codecDef; + break; - // backwards compat for now: also set the locale - // make sure we set the locale AFTER all child locales have been - // created, so we won't end up with the child locale set. - getSetGlobalLocale(name); + case "object": // Alias with options. Can be layered. + for (var key in codecDef) + codecOptions[key] = codecDef[key]; - return locales[name]; - } else { - // useful for testing - delete locales[name]; - return null; - } - } + if (!codecOptions.encodingName) + codecOptions.encodingName = enc; + + enc = codecDef.type; + break; - function updateLocale(name, config) { - if (config != null) { - var locale, - tmpLocale, - parentConfig = baseConfig; + case "function": // Codec itself. + if (!codecOptions.encodingName) + codecOptions.encodingName = enc; - if (locales[name] != null && locales[name].parentLocale != null) { - // Update existing child locale in-place to avoid memory-leaks - locales[name].set(mergeConfigs(locales[name]._config, config)); - } else { - // MERGE - tmpLocale = loadLocale(name); - if (tmpLocale != null) { - parentConfig = tmpLocale._config; - } - config = mergeConfigs(parentConfig, config); - if (tmpLocale == null) { - // updateLocale is called for creating a new locale - // Set abbr so it will have a name (getters return - // undefined otherwise). - config.abbr = name; - } - locale = new Locale(config); - locale.parentLocale = locales[name]; - locales[name] = locale; - } + // The codec function must load all tables and return object with .encoder and .decoder methods. + // It'll be called only once (for each different options object). + codec = new codecDef(codecOptions, iconv); - // backwards compat for now: also set the locale - getSetGlobalLocale(name); - } else { - // pass null for config to unupdate, useful for tests - if (locales[name] != null) { - if (locales[name].parentLocale != null) { - locales[name] = locales[name].parentLocale; - if (name === getSetGlobalLocale()) { - getSetGlobalLocale(name); - } - } else if (locales[name] != null) { - delete locales[name]; - } - } + iconv._codecDataCache[codecOptions.encodingName] = codec; // Save it to be reused later. + return codec; + + default: + throw new Error("Encoding not recognized: '" + encoding + "' (searched as: '"+enc+"')"); } - return locales[name]; } +} - // returns locale data - function getLocale(key) { - var locale; +iconv._canonicalizeEncoding = function(encoding) { + // Canonicalize encoding name: strip all non-alphanumeric chars and appended year. + return (''+encoding).toLowerCase().replace(/:\d{4}$|[^0-9a-z]/g, ""); +} - if (key && key._locale && key._locale._abbr) { - key = key._locale._abbr; - } +iconv.getEncoder = function getEncoder(encoding, options) { + var codec = iconv.getCodec(encoding), + encoder = new codec.encoder(options, codec); - if (!key) { - return globalLocale; - } + if (codec.bomAware && options && options.addBOM) + encoder = new bomHandling.PrependBOM(encoder, options); - if (!isArray(key)) { - //short-circuit everything else - locale = loadLocale(key); - if (locale) { - return locale; - } - key = [key]; - } + return encoder; +} - return chooseLocale(key); - } - - function listLocales() { - return keys(locales); - } - - function checkOverflow(m) { - var overflow, - a = m._a; - - if (a && getParsingFlags(m).overflow === -2) { - overflow = - a[MONTH] < 0 || a[MONTH] > 11 - ? MONTH - : a[DATE] < 1 || a[DATE] > daysInMonth(a[YEAR], a[MONTH]) - ? DATE - : a[HOUR] < 0 || - a[HOUR] > 24 || - (a[HOUR] === 24 && - (a[MINUTE] !== 0 || - a[SECOND] !== 0 || - a[MILLISECOND] !== 0)) - ? HOUR - : a[MINUTE] < 0 || a[MINUTE] > 59 - ? MINUTE - : a[SECOND] < 0 || a[SECOND] > 59 - ? SECOND - : a[MILLISECOND] < 0 || a[MILLISECOND] > 999 - ? MILLISECOND - : -1; - - if ( - getParsingFlags(m)._overflowDayOfYear && - (overflow < YEAR || overflow > DATE) - ) { - overflow = DATE; - } - if (getParsingFlags(m)._overflowWeeks && overflow === -1) { - overflow = WEEK; - } - if (getParsingFlags(m)._overflowWeekday && overflow === -1) { - overflow = WEEKDAY; - } +iconv.getDecoder = function getDecoder(encoding, options) { + var codec = iconv.getCodec(encoding), + decoder = new codec.decoder(options, codec); - getParsingFlags(m).overflow = overflow; - } + if (codec.bomAware && !(options && options.stripBOM === false)) + decoder = new bomHandling.StripBOM(decoder, options); - return m; - } - - // iso 8601 regex - // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00) - var extendedIsoRegex = - /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([+-]\d\d(?::?\d\d)?|\s*Z)?)?$/, - basicIsoRegex = - /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d|))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([+-]\d\d(?::?\d\d)?|\s*Z)?)?$/, - tzRegex = /Z|[+-]\d\d(?::?\d\d)?/, - isoDates = [ - ['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/], - ['YYYY-MM-DD', /\d{4}-\d\d-\d\d/], - ['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/], - ['GGGG-[W]WW', /\d{4}-W\d\d/, false], - ['YYYY-DDD', /\d{4}-\d{3}/], - ['YYYY-MM', /\d{4}-\d\d/, false], - ['YYYYYYMMDD', /[+-]\d{10}/], - ['YYYYMMDD', /\d{8}/], - ['GGGG[W]WWE', /\d{4}W\d{3}/], - ['GGGG[W]WW', /\d{4}W\d{2}/, false], - ['YYYYDDD', /\d{7}/], - ['YYYYMM', /\d{6}/, false], - ['YYYY', /\d{4}/, false], - ], - // iso time formats and regexes - isoTimes = [ - ['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/], - ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/], - ['HH:mm:ss', /\d\d:\d\d:\d\d/], - ['HH:mm', /\d\d:\d\d/], - ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/], - ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/], - ['HHmmss', /\d\d\d\d\d\d/], - ['HHmm', /\d\d\d\d/], - ['HH', /\d\d/], - ], - aspNetJsonRegex = /^\/?Date\((-?\d+)/i, - // RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3 - rfc2822 = - /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/, - obsOffsets = { - UT: 0, - GMT: 0, - EDT: -4 * 60, - EST: -5 * 60, - CDT: -5 * 60, - CST: -6 * 60, - MDT: -6 * 60, - MST: -7 * 60, - PDT: -7 * 60, - PST: -8 * 60, - }; + return decoder; +} - // date from iso format - function configFromISO(config) { - var i, - l, - string = config._i, - match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string), - allowTime, - dateFormat, - timeFormat, - tzFormat, - isoDatesLen = isoDates.length, - isoTimesLen = isoTimes.length; - - if (match) { - getParsingFlags(config).iso = true; - for (i = 0, l = isoDatesLen; i < l; i++) { - if (isoDates[i][1].exec(match[1])) { - dateFormat = isoDates[i][0]; - allowTime = isoDates[i][2] !== false; - break; - } - } - if (dateFormat == null) { - config._isValid = false; - return; - } - if (match[3]) { - for (i = 0, l = isoTimesLen; i < l; i++) { - if (isoTimes[i][1].exec(match[3])) { - // match[2] should be 'T' or space - timeFormat = (match[2] || ' ') + isoTimes[i][0]; - break; - } - } - if (timeFormat == null) { - config._isValid = false; - return; - } - } - if (!allowTime && timeFormat != null) { - config._isValid = false; - return; - } - if (match[4]) { - if (tzRegex.exec(match[4])) { - tzFormat = 'Z'; - } else { - config._isValid = false; - return; - } - } - config._f = dateFormat + (timeFormat || '') + (tzFormat || ''); - configFromStringAndFormat(config); - } else { - config._isValid = false; - } - } +// Streaming API +// NOTE: Streaming API naturally depends on 'stream' module from Node.js. Unfortunately in browser environments this module can add +// up to 100Kb to the output bundle. To avoid unnecessary code bloat, we don't enable Streaming API in browser by default. +// If you would like to enable it explicitly, please add the following code to your app: +// > iconv.enableStreamingAPI(require('stream')); +iconv.enableStreamingAPI = function enableStreamingAPI(stream_module) { + if (iconv.supportsStreams) + return; - function extractFromRFC2822Strings( - yearStr, - monthStr, - dayStr, - hourStr, - minuteStr, - secondStr - ) { - var result = [ - untruncateYear(yearStr), - defaultLocaleMonthsShort.indexOf(monthStr), - parseInt(dayStr, 10), - parseInt(hourStr, 10), - parseInt(minuteStr, 10), - ]; - - if (secondStr) { - result.push(parseInt(secondStr, 10)); - } + // Dependency-inject stream module to create IconvLite stream classes. + var streams = __nccwpck_require__(6869)(stream_module); - return result; - } + // Not public API yet, but expose the stream classes. + iconv.IconvLiteEncoderStream = streams.IconvLiteEncoderStream; + iconv.IconvLiteDecoderStream = streams.IconvLiteDecoderStream; - function untruncateYear(yearStr) { - var year = parseInt(yearStr, 10); - if (year <= 49) { - return 2000 + year; - } else if (year <= 999) { - return 1900 + year; - } - return year; - } - - function preprocessRFC2822(s) { - // Remove comments and folding whitespace and replace multiple-spaces with a single space - return s - .replace(/\([^()]*\)|[\n\t]/g, ' ') - .replace(/(\s\s+)/g, ' ') - .replace(/^\s\s*/, '') - .replace(/\s\s*$/, ''); - } - - function checkWeekday(weekdayStr, parsedInput, config) { - if (weekdayStr) { - // TODO: Replace the vanilla JS Date object with an independent day-of-week check. - var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr), - weekdayActual = new Date( - parsedInput[0], - parsedInput[1], - parsedInput[2] - ).getDay(); - if (weekdayProvided !== weekdayActual) { - getParsingFlags(config).weekdayMismatch = true; - config._isValid = false; - return false; - } - } - return true; + // Streaming API. + iconv.encodeStream = function encodeStream(encoding, options) { + return new iconv.IconvLiteEncoderStream(iconv.getEncoder(encoding, options), options); } - function calculateOffset(obsOffset, militaryOffset, numOffset) { - if (obsOffset) { - return obsOffsets[obsOffset]; - } else if (militaryOffset) { - // the only allowed military tz is Z - return 0; - } else { - var hm = parseInt(numOffset, 10), - m = hm % 100, - h = (hm - m) / 100; - return h * 60 + m; - } + iconv.decodeStream = function decodeStream(encoding, options) { + return new iconv.IconvLiteDecoderStream(iconv.getDecoder(encoding, options), options); } - // date and time from ref 2822 format - function configFromRFC2822(config) { - var match = rfc2822.exec(preprocessRFC2822(config._i)), - parsedArray; - if (match) { - parsedArray = extractFromRFC2822Strings( - match[4], - match[3], - match[2], - match[5], - match[6], - match[7] - ); - if (!checkWeekday(match[1], parsedArray, config)) { - return; - } - - config._a = parsedArray; - config._tzm = calculateOffset(match[8], match[9], match[10]); - - config._d = createUTCDate.apply(null, config._a); - config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm); + iconv.supportsStreams = true; +} - getParsingFlags(config).rfc2822 = true; - } else { - config._isValid = false; - } - } +// Enable Streaming API automatically if 'stream' module is available and non-empty (the majority of environments). +var stream_module; +try { + stream_module = __nccwpck_require__(2781); +} catch (e) {} - // date from 1) ASP.NET, 2) ISO, 3) RFC 2822 formats, or 4) optional fallback if parsing isn't strict - function configFromString(config) { - var matched = aspNetJsonRegex.exec(config._i); - if (matched !== null) { - config._d = new Date(+matched[1]); - return; - } +if (stream_module && stream_module.Transform) { + iconv.enableStreamingAPI(stream_module); - configFromISO(config); - if (config._isValid === false) { - delete config._isValid; - } else { - return; - } +} else { + // In rare cases where 'stream' module is not available by default, throw a helpful exception. + iconv.encodeStream = iconv.decodeStream = function() { + throw new Error("iconv-lite Streaming API is not enabled. Use iconv.enableStreamingAPI(require('stream')); to enable it."); + }; +} - configFromRFC2822(config); - if (config._isValid === false) { - delete config._isValid; - } else { - return; - } +if (false) {} - if (config._strict) { - config._isValid = false; - } else { - // Final attempt, use Input Fallback - hooks.createFromInputFallback(config); - } - } - hooks.createFromInputFallback = deprecate( - 'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' + - 'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' + - 'discouraged. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.', - function (config) { - config._d = new Date(config._i + (config._useUTC ? ' UTC' : '')); - } - ); +/***/ }), - // Pick the first defined of two or three arguments. - function defaults(a, b, c) { - if (a != null) { - return a; - } - if (b != null) { - return b; - } - return c; - } - - function currentDateArray(config) { - // hooks is actually the exported moment object - var nowValue = new Date(hooks.now()); - if (config._useUTC) { - return [ - nowValue.getUTCFullYear(), - nowValue.getUTCMonth(), - nowValue.getUTCDate(), - ]; - } - return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()]; - } - - // convert an array to a date. - // the array should mirror the parameters below - // note: all values past the year are optional and will default to the lowest possible value. - // [year, month, day , hour, minute, second, millisecond] - function configFromArray(config) { - var i, - date, - input = [], - currentDate, - expectedWeekday, - yearToUse; - - if (config._d) { - return; - } +/***/ 6869: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - currentDate = currentDateArray(config); +"use strict"; - //compute day of the year from weeks and weekdays - if (config._w && config._a[DATE] == null && config._a[MONTH] == null) { - dayOfYearFromWeekInfo(config); - } - //if the day of the year is set, figure out what it is - if (config._dayOfYear != null) { - yearToUse = defaults(config._a[YEAR], currentDate[YEAR]); +var Buffer = (__nccwpck_require__(5118).Buffer); - if ( - config._dayOfYear > daysInYear(yearToUse) || - config._dayOfYear === 0 - ) { - getParsingFlags(config)._overflowDayOfYear = true; - } +// NOTE: Due to 'stream' module being pretty large (~100Kb, significant in browser environments), +// we opt to dependency-inject it instead of creating a hard dependency. +module.exports = function(stream_module) { + var Transform = stream_module.Transform; - date = createUTCDate(yearToUse, 0, config._dayOfYear); - config._a[MONTH] = date.getUTCMonth(); - config._a[DATE] = date.getUTCDate(); - } + // == Encoder stream ======================================================= - // Default to current date. - // * if no year, month, day of month are given, default to today - // * if day of month is given, default month and year - // * if month is given, default only year - // * if year is given, don't default anything - for (i = 0; i < 3 && config._a[i] == null; ++i) { - config._a[i] = input[i] = currentDate[i]; - } + function IconvLiteEncoderStream(conv, options) { + this.conv = conv; + options = options || {}; + options.decodeStrings = false; // We accept only strings, so we don't need to decode them. + Transform.call(this, options); + } - // Zero out whatever was not defaulted, including time - for (; i < 7; i++) { - config._a[i] = input[i] = - config._a[i] == null ? (i === 2 ? 1 : 0) : config._a[i]; - } + IconvLiteEncoderStream.prototype = Object.create(Transform.prototype, { + constructor: { value: IconvLiteEncoderStream } + }); - // Check for 24:00:00.000 - if ( - config._a[HOUR] === 24 && - config._a[MINUTE] === 0 && - config._a[SECOND] === 0 && - config._a[MILLISECOND] === 0 - ) { - config._nextDay = true; - config._a[HOUR] = 0; + IconvLiteEncoderStream.prototype._transform = function(chunk, encoding, done) { + if (typeof chunk != 'string') + return done(new Error("Iconv encoding stream needs strings as its input.")); + try { + var res = this.conv.write(chunk); + if (res && res.length) this.push(res); + done(); } - - config._d = (config._useUTC ? createUTCDate : createDate).apply( - null, - input - ); - expectedWeekday = config._useUTC - ? config._d.getUTCDay() - : config._d.getDay(); - - // Apply timezone offset from input. The actual utcOffset can be changed - // with parseZone. - if (config._tzm != null) { - config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm); + catch (e) { + done(e); } + } - if (config._nextDay) { - config._a[HOUR] = 24; + IconvLiteEncoderStream.prototype._flush = function(done) { + try { + var res = this.conv.end(); + if (res && res.length) this.push(res); + done(); } - - // check for mismatching day of week - if ( - config._w && - typeof config._w.d !== 'undefined' && - config._w.d !== expectedWeekday - ) { - getParsingFlags(config).weekdayMismatch = true; + catch (e) { + done(e); } } - function dayOfYearFromWeekInfo(config) { - var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow, curWeek; - - w = config._w; - if (w.GG != null || w.W != null || w.E != null) { - dow = 1; - doy = 4; - - // TODO: We need to take the current isoWeekYear, but that depends on - // how we interpret now (local, utc, fixed offset). So create - // a now version of current config (take local/utc/offset flags, and - // create now). - weekYear = defaults( - w.GG, - config._a[YEAR], - weekOfYear(createLocal(), 1, 4).year - ); - week = defaults(w.W, 1); - weekday = defaults(w.E, 1); - if (weekday < 1 || weekday > 7) { - weekdayOverflow = true; - } - } else { - dow = config._locale._week.dow; - doy = config._locale._week.doy; - - curWeek = weekOfYear(createLocal(), dow, doy); - - weekYear = defaults(w.gg, config._a[YEAR], curWeek.year); - - // Default to current week. - week = defaults(w.w, curWeek.week); - - if (w.d != null) { - // weekday -- low day numbers are considered next week - weekday = w.d; - if (weekday < 0 || weekday > 6) { - weekdayOverflow = true; - } - } else if (w.e != null) { - // local weekday -- counting starts from beginning of week - weekday = w.e + dow; - if (w.e < 0 || w.e > 6) { - weekdayOverflow = true; - } - } else { - // default to beginning of week - weekday = dow; - } - } - if (week < 1 || week > weeksInYear(weekYear, dow, doy)) { - getParsingFlags(config)._overflowWeeks = true; - } else if (weekdayOverflow != null) { - getParsingFlags(config)._overflowWeekday = true; - } else { - temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy); - config._a[YEAR] = temp.year; - config._dayOfYear = temp.dayOfYear; - } + IconvLiteEncoderStream.prototype.collect = function(cb) { + var chunks = []; + this.on('error', cb); + this.on('data', function(chunk) { chunks.push(chunk); }); + this.on('end', function() { + cb(null, Buffer.concat(chunks)); + }); + return this; } - // constant that refers to the ISO standard - hooks.ISO_8601 = function () {}; - // constant that refers to the RFC 2822 form - hooks.RFC_2822 = function () {}; + // == Decoder stream ======================================================= - // date from string and format string - function configFromStringAndFormat(config) { - // TODO: Move this to another part of the creation flow to prevent circular deps - if (config._f === hooks.ISO_8601) { - configFromISO(config); - return; - } - if (config._f === hooks.RFC_2822) { - configFromRFC2822(config); - return; - } - config._a = []; - getParsingFlags(config).empty = true; - - // This array is used to make a Date, either with `new Date` or `Date.UTC` - var string = '' + config._i, - i, - parsedInput, - tokens, - token, - skipped, - stringLength = string.length, - totalParsedInputLength = 0, - era, - tokenLen; - - tokens = - expandFormat(config._f, config._locale).match(formattingTokens) || []; - tokenLen = tokens.length; - for (i = 0; i < tokenLen; i++) { - token = tokens[i]; - parsedInput = (string.match(getParseRegexForToken(token, config)) || - [])[0]; - if (parsedInput) { - skipped = string.substr(0, string.indexOf(parsedInput)); - if (skipped.length > 0) { - getParsingFlags(config).unusedInput.push(skipped); - } - string = string.slice( - string.indexOf(parsedInput) + parsedInput.length - ); - totalParsedInputLength += parsedInput.length; - } - // don't parse if it's not a known token - if (formatTokenFunctions[token]) { - if (parsedInput) { - getParsingFlags(config).empty = false; - } else { - getParsingFlags(config).unusedTokens.push(token); - } - addTimeToArrayFromToken(token, parsedInput, config); - } else if (config._strict && !parsedInput) { - getParsingFlags(config).unusedTokens.push(token); - } - } + function IconvLiteDecoderStream(conv, options) { + this.conv = conv; + options = options || {}; + options.encoding = this.encoding = 'utf8'; // We output strings. + Transform.call(this, options); + } - // add remaining unparsed input length to the string - getParsingFlags(config).charsLeftOver = - stringLength - totalParsedInputLength; - if (string.length > 0) { - getParsingFlags(config).unusedInput.push(string); - } + IconvLiteDecoderStream.prototype = Object.create(Transform.prototype, { + constructor: { value: IconvLiteDecoderStream } + }); - // clear _12h flag if hour is <= 12 - if ( - config._a[HOUR] <= 12 && - getParsingFlags(config).bigHour === true && - config._a[HOUR] > 0 - ) { - getParsingFlags(config).bigHour = undefined; + IconvLiteDecoderStream.prototype._transform = function(chunk, encoding, done) { + if (!Buffer.isBuffer(chunk) && !(chunk instanceof Uint8Array)) + return done(new Error("Iconv decoding stream needs buffers as its input.")); + try { + var res = this.conv.write(chunk); + if (res && res.length) this.push(res, this.encoding); + done(); } - - getParsingFlags(config).parsedDateParts = config._a.slice(0); - getParsingFlags(config).meridiem = config._meridiem; - // handle meridiem - config._a[HOUR] = meridiemFixWrap( - config._locale, - config._a[HOUR], - config._meridiem - ); - - // handle era - era = getParsingFlags(config).era; - if (era !== null) { - config._a[YEAR] = config._locale.erasConvertYear(era, config._a[YEAR]); + catch (e) { + done(e); } - - configFromArray(config); - checkOverflow(config); } - function meridiemFixWrap(locale, hour, meridiem) { - var isPm; - - if (meridiem == null) { - // nothing to do - return hour; + IconvLiteDecoderStream.prototype._flush = function(done) { + try { + var res = this.conv.end(); + if (res && res.length) this.push(res, this.encoding); + done(); } - if (locale.meridiemHour != null) { - return locale.meridiemHour(hour, meridiem); - } else if (locale.isPM != null) { - // Fallback - isPm = locale.isPM(meridiem); - if (isPm && hour < 12) { - hour += 12; - } - if (!isPm && hour === 12) { - hour = 0; - } - return hour; - } else { - // this is not supposed to happen - return hour; + catch (e) { + done(e); } } - // date from string and array of format strings - function configFromStringAndArray(config) { - var tempConfig, - bestMoment, - scoreToBeat, - i, - currentScore, - validFormatFound, - bestFormatIsValid = false, - configfLen = config._f.length; - - if (configfLen === 0) { - getParsingFlags(config).invalidFormat = true; - config._d = new Date(NaN); - return; - } + IconvLiteDecoderStream.prototype.collect = function(cb) { + var res = ''; + this.on('error', cb); + this.on('data', function(chunk) { res += chunk; }); + this.on('end', function() { + cb(null, res); + }); + return this; + } - for (i = 0; i < configfLen; i++) { - currentScore = 0; - validFormatFound = false; - tempConfig = copyConfig({}, config); - if (config._useUTC != null) { - tempConfig._useUTC = config._useUTC; - } - tempConfig._f = config._f[i]; - configFromStringAndFormat(tempConfig); + return { + IconvLiteEncoderStream: IconvLiteEncoderStream, + IconvLiteDecoderStream: IconvLiteDecoderStream, + }; +}; - if (isValid(tempConfig)) { - validFormatFound = true; - } - // if there is any input that was not parsed add a penalty for that format - currentScore += getParsingFlags(tempConfig).charsLeftOver; +/***/ }), - //or tokens - currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10; +/***/ 3287: +/***/ ((__unused_webpack_module, exports) => { - getParsingFlags(tempConfig).score = currentScore; +"use strict"; - if (!bestFormatIsValid) { - if ( - scoreToBeat == null || - currentScore < scoreToBeat || - validFormatFound - ) { - scoreToBeat = currentScore; - bestMoment = tempConfig; - if (validFormatFound) { - bestFormatIsValid = true; - } - } - } else { - if (currentScore < scoreToBeat) { - scoreToBeat = currentScore; - bestMoment = tempConfig; - } - } - } - extend(config, bestMoment || tempConfig); - } +Object.defineProperty(exports, "__esModule", ({ value: true })); - function configFromObject(config) { - if (config._d) { - return; - } +/*! + * is-plain-object + * + * Copyright (c) 2014-2017, Jon Schlinkert. + * Released under the MIT License. + */ - var i = normalizeObjectUnits(config._i), - dayOrDate = i.day === undefined ? i.date : i.day; - config._a = map( - [i.year, i.month, dayOrDate, i.hour, i.minute, i.second, i.millisecond], - function (obj) { - return obj && parseInt(obj, 10); - } - ); +function isObject(o) { + return Object.prototype.toString.call(o) === '[object Object]'; +} - configFromArray(config); - } +function isPlainObject(o) { + var ctor,prot; - function createFromConfig(config) { - var res = new Moment(checkOverflow(prepareConfig(config))); - if (res._nextDay) { - // Adding is smart enough around DST - res.add(1, 'd'); - res._nextDay = undefined; - } + if (isObject(o) === false) return false; - return res; - } + // If has modified constructor + ctor = o.constructor; + if (ctor === undefined) return true; - function prepareConfig(config) { - var input = config._i, - format = config._f; + // If has modified prototype + prot = ctor.prototype; + if (isObject(prot) === false) return false; - config._locale = config._locale || getLocale(config._l); + // If constructor does not have an Object-specific method + if (prot.hasOwnProperty('isPrototypeOf') === false) { + return false; + } - if (input === null || (format === undefined && input === '')) { - return createInvalid({ nullInput: true }); - } + // Most likely a plain Object + return true; +} - if (typeof input === 'string') { - config._i = input = config._locale.preparse(input); - } +exports.isPlainObject = isPlainObject; - if (isMoment(input)) { - return new Moment(checkOverflow(input)); - } else if (isDate(input)) { - config._d = input; - } else if (isArray(format)) { - configFromStringAndArray(config); - } else if (format) { - configFromStringAndFormat(config); - } else { - configFromInput(config); - } - if (!isValid(config)) { - config._d = null; - } +/***/ }), - return config; - } +/***/ 5902: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - function configFromInput(config) { - var input = config._i; - if (isUndefined(input)) { - config._d = new Date(hooks.now()); - } else if (isDate(input)) { - config._d = new Date(input.valueOf()); - } else if (typeof input === 'string') { - configFromString(config); - } else if (isArray(input)) { - config._a = map(input.slice(0), function (obj) { - return parseInt(obj, 10); - }); - configFromArray(config); - } else if (isObject(input)) { - configFromObject(config); - } else if (isNumber(input)) { - // from milliseconds - config._d = new Date(input); - } else { - hooks.createFromInputFallback(config); - } - } +var hashClear = __nccwpck_require__(1789), + hashDelete = __nccwpck_require__(712), + hashGet = __nccwpck_require__(5395), + hashHas = __nccwpck_require__(5232), + hashSet = __nccwpck_require__(7320); - function createLocalOrUTC(input, format, locale, strict, isUTC) { - var c = {}; +/** + * 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; - if (format === true || format === false) { - strict = format; - format = undefined; - } + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } +} - if (locale === true || locale === false) { - strict = locale; - locale = undefined; - } +// Add methods to `Hash`. +Hash.prototype.clear = hashClear; +Hash.prototype['delete'] = hashDelete; +Hash.prototype.get = hashGet; +Hash.prototype.has = hashHas; +Hash.prototype.set = hashSet; - if ( - (isObject(input) && isObjectEmpty(input)) || - (isArray(input) && input.length === 0) - ) { - input = undefined; - } - // object construction must be done this way. - // https://github.com/moment/moment/issues/1423 - c._isAMomentObject = true; - c._useUTC = c._isUTC = isUTC; - c._l = locale; - c._i = input; - c._f = format; - c._strict = strict; +module.exports = Hash; - return createFromConfig(c); - } - function createLocal(input, format, locale, strict) { - return createLocalOrUTC(input, format, locale, strict, false); - } +/***/ }), - var prototypeMin = deprecate( - 'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/', - function () { - var other = createLocal.apply(null, arguments); - if (this.isValid() && other.isValid()) { - return other < this ? this : other; - } else { - return createInvalid(); - } - } - ), - prototypeMax = deprecate( - 'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/', - function () { - var other = createLocal.apply(null, arguments); - if (this.isValid() && other.isValid()) { - return other > this ? this : other; - } else { - return createInvalid(); - } - } - ); +/***/ 6608: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - // Pick a moment m from moments so that m[fn](other) is true for all - // other. This relies on the function fn to be transitive. - // - // moments should either be an array of moment objects or an array, whose - // first element is an array of moment objects. - function pickBy(fn, moments) { - var res, i; - if (moments.length === 1 && isArray(moments[0])) { - moments = moments[0]; - } - if (!moments.length) { - return createLocal(); - } - res = moments[0]; - for (i = 1; i < moments.length; ++i) { - if (!moments[i].isValid() || moments[i][fn](res)) { - res = moments[i]; - } - } - return res; - } +var listCacheClear = __nccwpck_require__(9792), + listCacheDelete = __nccwpck_require__(7716), + listCacheGet = __nccwpck_require__(5789), + listCacheHas = __nccwpck_require__(9386), + listCacheSet = __nccwpck_require__(7399); - // TODO: Use [].sort instead? - function min() { - var args = [].slice.call(arguments, 0); +/** + * 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; - return pickBy('isBefore', args); - } + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } +} - function max() { - var args = [].slice.call(arguments, 0); +// Add methods to `ListCache`. +ListCache.prototype.clear = listCacheClear; +ListCache.prototype['delete'] = listCacheDelete; +ListCache.prototype.get = listCacheGet; +ListCache.prototype.has = listCacheHas; +ListCache.prototype.set = listCacheSet; - return pickBy('isAfter', args); - } +module.exports = ListCache; - var now = function () { - return Date.now ? Date.now() : +new Date(); - }; - var ordering = [ - 'year', - 'quarter', - 'month', - 'week', - 'day', - 'hour', - 'minute', - 'second', - 'millisecond', - ]; - - function isDurationValid(m) { - var key, - unitHasDecimal = false, - i, - orderLen = ordering.length; - for (key in m) { - if ( - hasOwnProp(m, key) && - !( - indexOf.call(ordering, key) !== -1 && - (m[key] == null || !isNaN(m[key])) - ) - ) { - return false; - } - } +/***/ }), - for (i = 0; i < orderLen; ++i) { - if (m[ordering[i]]) { - if (unitHasDecimal) { - return false; // only allow non-integers for smallest unit - } - if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) { - unitHasDecimal = true; - } - } - } +/***/ 881: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - return true; - } +var getNative = __nccwpck_require__(4479), + root = __nccwpck_require__(9882); - function isValid$1() { - return this._isValid; - } +/* Built-in method references that are verified to be native. */ +var Map = getNative(root, 'Map'); - function createInvalid$1() { - return createDuration(NaN); - } +module.exports = Map; - function Duration(duration) { - var normalizedInput = normalizeObjectUnits(duration), - years = normalizedInput.year || 0, - quarters = normalizedInput.quarter || 0, - months = normalizedInput.month || 0, - weeks = normalizedInput.week || normalizedInput.isoWeek || 0, - days = normalizedInput.day || 0, - hours = normalizedInput.hour || 0, - minutes = normalizedInput.minute || 0, - seconds = normalizedInput.second || 0, - milliseconds = normalizedInput.millisecond || 0; - this._isValid = isDurationValid(normalizedInput); +/***/ }), - // representation for dateAddRemove - this._milliseconds = - +milliseconds + - seconds * 1e3 + // 1000 - minutes * 6e4 + // 1000 * 60 - hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978 - // Because of dateAddRemove treats 24 hours as different from a - // day when working around DST, we need to store them separately - this._days = +days + weeks * 7; - // It is impossible to translate months into days without knowing - // which months you are are talking about, so we have to store - // it separately. - this._months = +months + quarters * 3 + years * 12; +/***/ 938: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - this._data = {}; +var mapCacheClear = __nccwpck_require__(1610), + mapCacheDelete = __nccwpck_require__(6657), + mapCacheGet = __nccwpck_require__(1372), + mapCacheHas = __nccwpck_require__(609), + mapCacheSet = __nccwpck_require__(5582); - this._locale = getLocale(); +/** + * 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._bubble(); - } + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } +} - function isDuration(obj) { - return obj instanceof Duration; - } +// Add methods to `MapCache`. +MapCache.prototype.clear = mapCacheClear; +MapCache.prototype['delete'] = mapCacheDelete; +MapCache.prototype.get = mapCacheGet; +MapCache.prototype.has = mapCacheHas; +MapCache.prototype.set = mapCacheSet; - function absRound(number) { - if (number < 0) { - return Math.round(-1 * number) * -1; - } else { - return Math.round(number); - } - } +module.exports = MapCache; - // compare two arrays, return the number of differences - function compareArrays(array1, array2, dontConvert) { - var len = Math.min(array1.length, array2.length), - lengthDiff = Math.abs(array1.length - array2.length), - diffs = 0, - i; - for (i = 0; i < len; i++) { - if ( - (dontConvert && array1[i] !== array2[i]) || - (!dontConvert && toInt(array1[i]) !== toInt(array2[i])) - ) { - diffs++; - } - } - return diffs + lengthDiff; - } - // FORMATTING +/***/ }), - function offset(token, separator) { - addFormatToken(token, 0, 0, function () { - var offset = this.utcOffset(), - sign = '+'; - if (offset < 0) { - offset = -offset; - sign = '-'; - } - return ( - sign + - zeroFill(~~(offset / 60), 2) + - separator + - zeroFill(~~offset % 60, 2) - ); - }); - } +/***/ 9213: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - offset('Z', ':'); - offset('ZZ', ''); +var root = __nccwpck_require__(9882); - // PARSING +/** Built-in value references. */ +var Symbol = root.Symbol; + +module.exports = Symbol; - addRegexToken('Z', matchShortOffset); - addRegexToken('ZZ', matchShortOffset); - addParseToken(['Z', 'ZZ'], function (input, array, config) { - config._useUTC = true; - config._tzm = offsetFromString(matchShortOffset, input); - }); - // HELPERS +/***/ }), - // timezone chunker - // '+10:00' > ['10', '00'] - // '-1530' > ['-15', '30'] - var chunkOffset = /([\+\-]|\d\d)/gi; +/***/ 4356: +/***/ ((module) => { - function offsetFromString(matcher, string) { - var matches = (string || '').match(matcher), - chunk, - parts, - minutes; +/** + * 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); - if (matches === null) { - return null; - } + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; +} - chunk = matches[matches.length - 1] || []; - parts = (chunk + '').match(chunkOffset) || ['-', 0, 0]; - minutes = +(parts[1] * 60) + toInt(parts[2]); - - return minutes === 0 ? 0 : parts[0] === '+' ? minutes : -minutes; - } - - // Return a moment from input, that is local/utc/zone equivalent to model. - function cloneWithOffset(input, model) { - var res, diff; - if (model._isUTC) { - res = model.clone(); - diff = - (isMoment(input) || isDate(input) - ? input.valueOf() - : createLocal(input).valueOf()) - res.valueOf(); - // Use low-level api, because this fn is low-level api. - res._d.setTime(res._d.valueOf() + diff); - hooks.updateOffset(res, false); - return res; - } else { - return createLocal(input).local(); - } - } +module.exports = arrayMap; - function getDateOffset(m) { - // On Firefox.24 Date#getTimezoneOffset returns a floating point. - // https://github.com/moment/moment/pull/1871 - return -Math.round(m._d.getTimezoneOffset()); - } - // HOOKS +/***/ }), - // This function will be called whenever a moment is mutated. - // It is intended to keep the offset in sync with the timezone. - hooks.updateOffset = function () {}; +/***/ 6752: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - // MOMENTS +var eq = __nccwpck_require__(1901); - // keepLocalTime = true means only change the timezone, without - // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]--> - // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset - // +0200, so we adjust the time as needed, to be valid. - // - // Keeping the time actually adds/subtracts (one hour) - // from the actual represented time. That is why we call updateOffset - // a second time. In case it wants us to change the offset again - // _changeInProgress == true case, then we have to adjust, because - // there is no such time in the given timezone. - function getSetOffset(input, keepLocalTime, keepMinutes) { - var offset = this._offset || 0, - localAdjust; - if (!this.isValid()) { - return input != null ? this : NaN; - } - if (input != null) { - if (typeof input === 'string') { - input = offsetFromString(matchShortOffset, input); - if (input === null) { - return this; - } - } else if (Math.abs(input) < 16 && !keepMinutes) { - input = input * 60; - } - if (!this._isUTC && keepLocalTime) { - localAdjust = getDateOffset(this); - } - this._offset = input; - this._isUTC = true; - if (localAdjust != null) { - this.add(localAdjust, 'm'); - } - if (offset !== input) { - if (!keepLocalTime || this._changeInProgress) { - addSubtract( - this, - createDuration(input - offset, 'm'), - 1, - false - ); - } else if (!this._changeInProgress) { - this._changeInProgress = true; - hooks.updateOffset(this, true); - this._changeInProgress = null; - } - } - return this; - } else { - return this._isUTC ? offset : getDateOffset(this); - } +/** + * 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; +} - function getSetZone(input, keepLocalTime) { - if (input != null) { - if (typeof input !== 'string') { - input = -input; - } - - this.utcOffset(input, keepLocalTime); +module.exports = assocIndexOf; - return this; - } else { - return -this.utcOffset(); - } - } - function setOffsetToUTC(keepLocalTime) { - return this.utcOffset(0, keepLocalTime); - } +/***/ }), - function setOffsetToLocal(keepLocalTime) { - if (this._isUTC) { - this.utcOffset(0, keepLocalTime); - this._isUTC = false; +/***/ 5758: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - if (keepLocalTime) { - this.subtract(getDateOffset(this), 'm'); - } - } - return this; - } +var castPath = __nccwpck_require__(2688), + toKey = __nccwpck_require__(9071); - function setOffsetToParsedOffset() { - if (this._tzm != null) { - this.utcOffset(this._tzm, false, true); - } else if (typeof this._i === 'string') { - var tZone = offsetFromString(matchOffset, this._i); - if (tZone != null) { - this.utcOffset(tZone); - } else { - this.utcOffset(0, true); - } - } - return this; - } +/** + * 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); - function hasAlignedHourOffset(input) { - if (!this.isValid()) { - return false; - } - input = input ? createLocal(input).utcOffset() : 0; + var index = 0, + length = path.length; - return (this.utcOffset() - input) % 60 === 0; - } + while (object != null && index < length) { + object = object[toKey(path[index++])]; + } + return (index && index == length) ? object : undefined; +} - function isDaylightSavingTime() { - return ( - this.utcOffset() > this.clone().month(0).utcOffset() || - this.utcOffset() > this.clone().month(5).utcOffset() - ); - } +module.exports = baseGet; - function isDaylightSavingTimeShifted() { - if (!isUndefined(this._isDSTShifted)) { - return this._isDSTShifted; - } - var c = {}, - other; +/***/ }), - copyConfig(c, this); - c = prepareConfig(c); +/***/ 7497: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - if (c._a) { - other = c._isUTC ? createUTC(c._a) : createLocal(c._a); - this._isDSTShifted = - this.isValid() && compareArrays(c._a, other.toArray()) > 0; - } else { - this._isDSTShifted = false; - } +var Symbol = __nccwpck_require__(9213), + getRawTag = __nccwpck_require__(923), + objectToString = __nccwpck_require__(4200); - return this._isDSTShifted; - } +/** `Object#toString` result references. */ +var nullTag = '[object Null]', + undefinedTag = '[object Undefined]'; - function isLocal() { - return this.isValid() ? !this._isUTC : false; - } +/** Built-in value references. */ +var symToStringTag = Symbol ? Symbol.toStringTag : undefined; - function isUtcOffset() { - return this.isValid() ? this._isUTC : false; - } +/** + * 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); +} - function isUtc() { - return this.isValid() ? this._isUTC && this._offset === 0 : false; - } +module.exports = baseGetTag; - // ASP.NET json date format regex - var aspNetRegex = /^(-|\+)?(?:(\d*)[. ])?(\d+):(\d+)(?::(\d+)(\.\d*)?)?$/, - // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html - // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere - // and further modified to allow for strings containing both week and day - isoRegex = - /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/; - function createDuration(input, key) { - var duration = input, - // matching against regexp is expensive, do it on demand - match = null, - sign, - ret, - diffRes; +/***/ }), - if (isDuration(input)) { - duration = { - ms: input._milliseconds, - d: input._days, - M: input._months, - }; - } else if (isNumber(input) || !isNaN(+input)) { - duration = {}; - if (key) { - duration[key] = +input; - } else { - duration.milliseconds = +input; - } - } else if ((match = aspNetRegex.exec(input))) { - sign = match[1] === '-' ? -1 : 1; - duration = { - y: 0, - d: toInt(match[DATE]) * sign, - h: toInt(match[HOUR]) * sign, - m: toInt(match[MINUTE]) * sign, - s: toInt(match[SECOND]) * sign, - ms: toInt(absRound(match[MILLISECOND] * 1000)) * sign, // the millisecond decimal point is included in the match - }; - } else if ((match = isoRegex.exec(input))) { - sign = match[1] === '-' ? -1 : 1; - duration = { - y: parseIso(match[2], sign), - M: parseIso(match[3], sign), - w: parseIso(match[4], sign), - d: parseIso(match[5], sign), - h: parseIso(match[6], sign), - m: parseIso(match[7], sign), - s: parseIso(match[8], sign), - }; - } else if (duration == null) { - // checks for null or undefined - duration = {}; - } else if ( - typeof duration === 'object' && - ('from' in duration || 'to' in duration) - ) { - diffRes = momentsDifference( - createLocal(duration.from), - createLocal(duration.to) - ); +/***/ 411: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - duration = {}; - duration.ms = diffRes.milliseconds; - duration.M = diffRes.months; - } +var isFunction = __nccwpck_require__(7799), + isMasked = __nccwpck_require__(9058), + isObject = __nccwpck_require__(3334), + toSource = __nccwpck_require__(6928); - ret = new Duration(duration); +/** + * Used to match `RegExp` + * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). + */ +var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; - if (isDuration(input) && hasOwnProp(input, '_locale')) { - ret._locale = input._locale; - } +/** Used to detect host constructors (Safari). */ +var reIsHostCtor = /^\[object .+?Constructor\]$/; - if (isDuration(input) && hasOwnProp(input, '_isValid')) { - ret._isValid = input._isValid; - } +/** Used for built-in method references. */ +var funcProto = Function.prototype, + objectProto = Object.prototype; - return ret; - } +/** Used to resolve the decompiled source of functions. */ +var funcToString = funcProto.toString; - createDuration.fn = Duration.prototype; - createDuration.invalid = createInvalid$1; +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; - function parseIso(inp, sign) { - // We'd normally use ~~inp for this, but unfortunately it also - // converts floats to ints. - // inp may be undefined, so careful calling replace on it. - var res = inp && parseFloat(inp.replace(',', '.')); - // apply sign while we're at it - return (isNaN(res) ? 0 : res) * sign; - } +/** Used to detect if a method is native. */ +var reIsNative = RegExp('^' + + funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' +); - function positiveMomentsDifference(base, other) { - var res = {}; +/** + * 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)); +} - res.months = - other.month() - base.month() + (other.year() - base.year()) * 12; - if (base.clone().add(res.months, 'M').isAfter(other)) { - --res.months; - } +module.exports = baseIsNative; - res.milliseconds = +other - +base.clone().add(res.months, 'M'); - return res; - } +/***/ }), - function momentsDifference(base, other) { - var res; - if (!(base.isValid() && other.isValid())) { - return { milliseconds: 0, months: 0 }; - } +/***/ 6792: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - other = cloneWithOffset(other, base); - if (base.isBefore(other)) { - res = positiveMomentsDifference(base, other); - } else { - res = positiveMomentsDifference(other, base); - res.milliseconds = -res.milliseconds; - res.months = -res.months; - } +var Symbol = __nccwpck_require__(9213), + arrayMap = __nccwpck_require__(4356), + isArray = __nccwpck_require__(4869), + isSymbol = __nccwpck_require__(6403); - return res; - } +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; - // TODO: remove 'name' arg after deprecation is removed - function createAdder(direction, name) { - return function (val, period) { - var dur, tmp; - //invert the arguments, but complain about it - if (period !== null && !isNaN(+period)) { - deprecateSimple( - name, - 'moment().' + - name + - '(period, number) is deprecated. Please use moment().' + - name + - '(number, period). ' + - 'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.' - ); - tmp = val; - val = period; - period = tmp; - } +/** Used to convert symbols to primitives and strings. */ +var symbolProto = Symbol ? Symbol.prototype : undefined, + symbolToString = symbolProto ? symbolProto.toString : undefined; - dur = createDuration(val, period); - addSubtract(this, dur, direction); - return this; - }; - } +/** + * 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; +} - function addSubtract(mom, duration, isAdding, updateOffset) { - var milliseconds = duration._milliseconds, - days = absRound(duration._days), - months = absRound(duration._months); +module.exports = baseToString; - if (!mom.isValid()) { - // No op - return; - } - updateOffset = updateOffset == null ? true : updateOffset; +/***/ }), - if (months) { - setMonth(mom, get(mom, 'Month') + months * isAdding); - } - if (days) { - set$1(mom, 'Date', get(mom, 'Date') + days * isAdding); - } - if (milliseconds) { - mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding); - } - if (updateOffset) { - hooks.updateOffset(mom, days || months); - } - } +/***/ 2688: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - var add = createAdder(1, 'add'), - subtract = createAdder(-1, 'subtract'); +var isArray = __nccwpck_require__(4869), + isKey = __nccwpck_require__(9084), + stringToPath = __nccwpck_require__(1853), + toString = __nccwpck_require__(2931); - function isString(input) { - return typeof input === 'string' || input instanceof String; - } +/** + * 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)); +} - // type MomentInput = Moment | Date | string | number | (number | string)[] | MomentInputObject | void; // null | undefined - function isMomentInput(input) { - return ( - isMoment(input) || - isDate(input) || - isString(input) || - isNumber(input) || - isNumberOrStringArray(input) || - isMomentInputObject(input) || - input === null || - input === undefined - ); - } +module.exports = castPath; - function isMomentInputObject(input) { - var objectTest = isObject(input) && !isObjectEmpty(input), - propertyTest = false, - properties = [ - 'years', - 'year', - 'y', - 'months', - 'month', - 'M', - 'days', - 'day', - 'd', - 'dates', - 'date', - 'D', - 'hours', - 'hour', - 'h', - 'minutes', - 'minute', - 'm', - 'seconds', - 'second', - 's', - 'milliseconds', - 'millisecond', - 'ms', - ], - i, - property, - propertyLen = properties.length; - - for (i = 0; i < propertyLen; i += 1) { - property = properties[i]; - propertyTest = propertyTest || hasOwnProp(input, property); - } - return objectTest && propertyTest; - } +/***/ }), - function isNumberOrStringArray(input) { - var arrayTest = isArray(input), - dataTypeTest = false; - if (arrayTest) { - dataTypeTest = - input.filter(function (item) { - return !isNumber(item) && isString(input); - }).length === 0; - } - return arrayTest && dataTypeTest; - } - - function isCalendarSpec(input) { - var objectTest = isObject(input) && !isObjectEmpty(input), - propertyTest = false, - properties = [ - 'sameDay', - 'nextDay', - 'lastDay', - 'nextWeek', - 'lastWeek', - 'sameElse', - ], - i, - property; - - for (i = 0; i < properties.length; i += 1) { - property = properties[i]; - propertyTest = propertyTest || hasOwnProp(input, property); - } +/***/ 8380: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - return objectTest && propertyTest; - } - - function getCalendarFormat(myMoment, now) { - var diff = myMoment.diff(now, 'days', true); - return diff < -6 - ? 'sameElse' - : diff < -1 - ? 'lastWeek' - : diff < 0 - ? 'lastDay' - : diff < 1 - ? 'sameDay' - : diff < 2 - ? 'nextDay' - : diff < 7 - ? 'nextWeek' - : 'sameElse'; - } - - function calendar$1(time, formats) { - // Support for single parameter, formats only overload to the calendar function - if (arguments.length === 1) { - if (!arguments[0]) { - time = undefined; - formats = undefined; - } else if (isMomentInput(arguments[0])) { - time = arguments[0]; - formats = undefined; - } else if (isCalendarSpec(arguments[0])) { - formats = arguments[0]; - time = undefined; - } - } - // We want to compare the start of today, vs this. - // Getting start-of-today depends on whether we're local/utc/offset or not. - var now = time || createLocal(), - sod = cloneWithOffset(now, this).startOf('day'), - format = hooks.calendarFormat(this, sod) || 'sameElse', - output = - formats && - (isFunction(formats[format]) - ? formats[format].call(this, now) - : formats[format]); - - return this.format( - output || this.localeData().calendar(format, this, createLocal(now)) - ); - } +var root = __nccwpck_require__(9882); - function clone() { - return new Moment(this); - } +/** Used to detect overreaching core-js shims. */ +var coreJsData = root['__core-js_shared__']; - function isAfter(input, units) { - var localInput = isMoment(input) ? input : createLocal(input); - if (!(this.isValid() && localInput.isValid())) { - return false; - } - units = normalizeUnits(units) || 'millisecond'; - if (units === 'millisecond') { - return this.valueOf() > localInput.valueOf(); - } else { - return localInput.valueOf() < this.clone().startOf(units).valueOf(); - } - } +module.exports = coreJsData; - function isBefore(input, units) { - var localInput = isMoment(input) ? input : createLocal(input); - if (!(this.isValid() && localInput.isValid())) { - return false; - } - units = normalizeUnits(units) || 'millisecond'; - if (units === 'millisecond') { - return this.valueOf() < localInput.valueOf(); - } else { - return this.clone().endOf(units).valueOf() < localInput.valueOf(); - } - } - function isBetween(from, to, units, inclusivity) { - var localFrom = isMoment(from) ? from : createLocal(from), - localTo = isMoment(to) ? to : createLocal(to); - if (!(this.isValid() && localFrom.isValid() && localTo.isValid())) { - return false; - } - inclusivity = inclusivity || '()'; - return ( - (inclusivity[0] === '(' - ? this.isAfter(localFrom, units) - : !this.isBefore(localFrom, units)) && - (inclusivity[1] === ')' - ? this.isBefore(localTo, units) - : !this.isAfter(localTo, units)) - ); - } +/***/ }), - function isSame(input, units) { - var localInput = isMoment(input) ? input : createLocal(input), - inputMs; - if (!(this.isValid() && localInput.isValid())) { - return false; - } - units = normalizeUnits(units) || 'millisecond'; - if (units === 'millisecond') { - return this.valueOf() === localInput.valueOf(); - } else { - inputMs = localInput.valueOf(); - return ( - this.clone().startOf(units).valueOf() <= inputMs && - inputMs <= this.clone().endOf(units).valueOf() - ); - } - } +/***/ 2085: +/***/ ((module) => { - function isSameOrAfter(input, units) { - return this.isSame(input, units) || this.isAfter(input, units); - } +/** Detect free variable `global` from Node.js. */ +var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; - function isSameOrBefore(input, units) { - return this.isSame(input, units) || this.isBefore(input, units); - } +module.exports = freeGlobal; - function diff(input, units, asFloat) { - var that, zoneDelta, output; - if (!this.isValid()) { - return NaN; - } +/***/ }), - that = cloneWithOffset(input, this); +/***/ 9980: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - if (!that.isValid()) { - return NaN; - } +var isKeyable = __nccwpck_require__(3308); - zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4; +/** + * 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; +} - units = normalizeUnits(units); +module.exports = getMapData; - switch (units) { - case 'year': - output = monthDiff(this, that) / 12; - break; - case 'month': - output = monthDiff(this, that); - break; - case 'quarter': - output = monthDiff(this, that) / 3; - break; - case 'second': - output = (this - that) / 1e3; - break; // 1000 - case 'minute': - output = (this - that) / 6e4; - break; // 1000 * 60 - case 'hour': - output = (this - that) / 36e5; - break; // 1000 * 60 * 60 - case 'day': - output = (this - that - zoneDelta) / 864e5; - break; // 1000 * 60 * 60 * 24, negate dst - case 'week': - output = (this - that - zoneDelta) / 6048e5; - break; // 1000 * 60 * 60 * 24 * 7, negate dst - default: - output = this - that; - } - return asFloat ? output : absFloor(output); - } +/***/ }), - function monthDiff(a, b) { - if (a.date() < b.date()) { - // end-of-month calculations work correct when the start month has more - // days than the end month. - return -monthDiff(b, a); - } - // difference in months - var wholeMonthDiff = (b.year() - a.year()) * 12 + (b.month() - a.month()), - // b is in (anchor - 1 month, anchor + 1 month) - anchor = a.clone().add(wholeMonthDiff, 'months'), - anchor2, - adjust; - - if (b - anchor < 0) { - anchor2 = a.clone().add(wholeMonthDiff - 1, 'months'); - // linear across the month - adjust = (b - anchor) / (anchor - anchor2); - } else { - anchor2 = a.clone().add(wholeMonthDiff + 1, 'months'); - // linear across the month - adjust = (b - anchor) / (anchor2 - anchor); - } +/***/ 4479: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - //check for negative zero, return zero if negative zero - return -(wholeMonthDiff + adjust) || 0; - } +var baseIsNative = __nccwpck_require__(411), + getValue = __nccwpck_require__(3542); - hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ'; - hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]'; +/** + * 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; +} - function toString() { - return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ'); - } +module.exports = getNative; - function toISOString(keepOffset) { - if (!this.isValid()) { - return null; - } - var utc = keepOffset !== true, - m = utc ? this.clone().utc() : this; - if (m.year() < 0 || m.year() > 9999) { - return formatMoment( - m, - utc - ? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]' - : 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ' - ); - } - if (isFunction(Date.prototype.toISOString)) { - // native implementation is ~50x faster, use it when we can - if (utc) { - return this.toDate().toISOString(); - } else { - return new Date(this.valueOf() + this.utcOffset() * 60 * 1000) - .toISOString() - .replace('Z', formatMoment(m, 'Z')); - } - } - return formatMoment( - m, - utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ' - ); - } - /** - * Return a human readable representation of a moment that can - * also be evaluated to get a new moment which is the same - * - * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects - */ - function inspect() { - if (!this.isValid()) { - return 'moment.invalid(/* ' + this._i + ' */)'; - } - var func = 'moment', - zone = '', - prefix, - year, - datetime, - suffix; - if (!this.isLocal()) { - func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone'; - zone = 'Z'; - } - prefix = '[' + func + '("]'; - year = 0 <= this.year() && this.year() <= 9999 ? 'YYYY' : 'YYYYYY'; - datetime = '-MM-DD[T]HH:mm:ss.SSS'; - suffix = zone + '[")]'; +/***/ }), - return this.format(prefix + year + datetime + suffix); - } +/***/ 923: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - function format(inputString) { - if (!inputString) { - inputString = this.isUtc() - ? hooks.defaultFormatUtc - : hooks.defaultFormat; - } - var output = formatMoment(this, inputString); - return this.localeData().postformat(output); - } - - function from(time, withoutSuffix) { - if ( - this.isValid() && - ((isMoment(time) && time.isValid()) || createLocal(time).isValid()) - ) { - return createDuration({ to: this, from: time }) - .locale(this.locale()) - .humanize(!withoutSuffix); - } else { - return this.localeData().invalidDate(); - } - } +var Symbol = __nccwpck_require__(9213); - function fromNow(withoutSuffix) { - return this.from(createLocal(), withoutSuffix); - } +/** Used for built-in method references. */ +var objectProto = Object.prototype; - function to(time, withoutSuffix) { - if ( - this.isValid() && - ((isMoment(time) && time.isValid()) || createLocal(time).isValid()) - ) { - return createDuration({ from: this, to: time }) - .locale(this.locale()) - .humanize(!withoutSuffix); - } else { - return this.localeData().invalidDate(); - } - } +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; - function toNow(withoutSuffix) { - return this.to(createLocal(), withoutSuffix); - } +/** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ +var nativeObjectToString = objectProto.toString; - // If passed a locale key, it will set the locale for this - // instance. Otherwise, it will return the locale configuration - // variables for this instance. - function locale(key) { - var newLocaleData; +/** Built-in value references. */ +var symToStringTag = Symbol ? Symbol.toStringTag : undefined; - if (key === undefined) { - return this._locale._abbr; - } else { - newLocaleData = getLocale(key); - if (newLocaleData != null) { - this._locale = newLocaleData; - } - return this; - } - } +/** + * 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]; - var lang = deprecate( - 'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.', - function (key) { - if (key === undefined) { - return this.localeData(); - } else { - return this.locale(key); - } - } - ); + try { + value[symToStringTag] = undefined; + var unmasked = true; + } catch (e) {} - function localeData() { - return this._locale; + var result = nativeObjectToString.call(value); + if (unmasked) { + if (isOwn) { + value[symToStringTag] = tag; + } else { + delete value[symToStringTag]; } + } + return result; +} - var MS_PER_SECOND = 1000, - MS_PER_MINUTE = 60 * MS_PER_SECOND, - MS_PER_HOUR = 60 * MS_PER_MINUTE, - MS_PER_400_YEARS = (365 * 400 + 97) * 24 * MS_PER_HOUR; +module.exports = getRawTag; - // actual modulo - handles negative numbers (for dates before 1970): - function mod$1(dividend, divisor) { - return ((dividend % divisor) + divisor) % divisor; - } - function localStartOfDate(y, m, d) { - // the date constructor remaps years 0-99 to 1900-1999 - if (y < 100 && y >= 0) { - // preserve leap years using a full 400 year cycle, then reset - return new Date(y + 400, m, d) - MS_PER_400_YEARS; - } else { - return new Date(y, m, d).valueOf(); - } - } +/***/ }), - function utcStartOfDate(y, m, d) { - // Date.UTC remaps years 0-99 to 1900-1999 - if (y < 100 && y >= 0) { - // preserve leap years using a full 400 year cycle, then reset - return Date.UTC(y + 400, m, d) - MS_PER_400_YEARS; - } else { - return Date.UTC(y, m, d); - } - } +/***/ 3542: +/***/ ((module) => { - function startOf(units) { - var time, startOfDate; - units = normalizeUnits(units); - if (units === undefined || units === 'millisecond' || !this.isValid()) { - return this; - } +/** + * 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]; +} - startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate; +module.exports = getValue; - switch (units) { - case 'year': - time = startOfDate(this.year(), 0, 1); - break; - case 'quarter': - time = startOfDate( - this.year(), - this.month() - (this.month() % 3), - 1 - ); - break; - case 'month': - time = startOfDate(this.year(), this.month(), 1); - break; - case 'week': - time = startOfDate( - this.year(), - this.month(), - this.date() - this.weekday() - ); - break; - case 'isoWeek': - time = startOfDate( - this.year(), - this.month(), - this.date() - (this.isoWeekday() - 1) - ); - break; - case 'day': - case 'date': - time = startOfDate(this.year(), this.month(), this.date()); - break; - case 'hour': - time = this._d.valueOf(); - time -= mod$1( - time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), - MS_PER_HOUR - ); - break; - case 'minute': - time = this._d.valueOf(); - time -= mod$1(time, MS_PER_MINUTE); - break; - case 'second': - time = this._d.valueOf(); - time -= mod$1(time, MS_PER_SECOND); - break; - } - this._d.setTime(time); - hooks.updateOffset(this, true); - return this; - } +/***/ }), - function endOf(units) { - var time, startOfDate; - units = normalizeUnits(units); - if (units === undefined || units === 'millisecond' || !this.isValid()) { - return this; - } +/***/ 1789: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate; +var nativeCreate = __nccwpck_require__(3041); - switch (units) { - case 'year': - time = startOfDate(this.year() + 1, 0, 1) - 1; - break; - case 'quarter': - time = - startOfDate( - this.year(), - this.month() - (this.month() % 3) + 3, - 1 - ) - 1; - break; - case 'month': - time = startOfDate(this.year(), this.month() + 1, 1) - 1; - break; - case 'week': - time = - startOfDate( - this.year(), - this.month(), - this.date() - this.weekday() + 7 - ) - 1; - break; - case 'isoWeek': - time = - startOfDate( - this.year(), - this.month(), - this.date() - (this.isoWeekday() - 1) + 7 - ) - 1; - break; - case 'day': - case 'date': - time = startOfDate(this.year(), this.month(), this.date() + 1) - 1; - break; - case 'hour': - time = this._d.valueOf(); - time += - MS_PER_HOUR - - mod$1( - time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), - MS_PER_HOUR - ) - - 1; - break; - case 'minute': - time = this._d.valueOf(); - time += MS_PER_MINUTE - mod$1(time, MS_PER_MINUTE) - 1; - break; - case 'second': - time = this._d.valueOf(); - time += MS_PER_SECOND - mod$1(time, MS_PER_SECOND) - 1; - break; - } +/** + * Removes all key-value entries from the hash. + * + * @private + * @name clear + * @memberOf Hash + */ +function hashClear() { + this.__data__ = nativeCreate ? nativeCreate(null) : {}; + this.size = 0; +} - this._d.setTime(time); - hooks.updateOffset(this, true); - return this; - } +module.exports = hashClear; - function valueOf() { - return this._d.valueOf() - (this._offset || 0) * 60000; - } - function unix() { - return Math.floor(this.valueOf() / 1000); - } +/***/ }), - function toDate() { - return new Date(this.valueOf()); - } +/***/ 712: +/***/ ((module) => { - function toArray() { - var m = this; - return [ - m.year(), - m.month(), - m.date(), - m.hour(), - m.minute(), - m.second(), - m.millisecond(), - ]; - } +/** + * 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; +} - function toObject() { - var m = this; - return { - years: m.year(), - months: m.month(), - date: m.date(), - hours: m.hours(), - minutes: m.minutes(), - seconds: m.seconds(), - milliseconds: m.milliseconds(), - }; - } +module.exports = hashDelete; - function toJSON() { - // new Date(NaN).toJSON() === null - return this.isValid() ? this.toISOString() : null; - } - function isValid$2() { - return isValid(this); - } +/***/ }), - function parsingFlags() { - return extend({}, getParsingFlags(this)); - } +/***/ 5395: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - function invalidAt() { - return getParsingFlags(this).overflow; - } +var nativeCreate = __nccwpck_require__(3041); - function creationData() { - return { - input: this._i, - format: this._f, - locale: this._locale, - isUTC: this._isUTC, - strict: this._strict, - }; - } +/** Used to stand-in for `undefined` hash values. */ +var HASH_UNDEFINED = '__lodash_hash_undefined__'; - addFormatToken('N', 0, 0, 'eraAbbr'); - addFormatToken('NN', 0, 0, 'eraAbbr'); - addFormatToken('NNN', 0, 0, 'eraAbbr'); - addFormatToken('NNNN', 0, 0, 'eraName'); - addFormatToken('NNNNN', 0, 0, 'eraNarrow'); - - addFormatToken('y', ['y', 1], 'yo', 'eraYear'); - addFormatToken('y', ['yy', 2], 0, 'eraYear'); - addFormatToken('y', ['yyy', 3], 0, 'eraYear'); - addFormatToken('y', ['yyyy', 4], 0, 'eraYear'); - - addRegexToken('N', matchEraAbbr); - addRegexToken('NN', matchEraAbbr); - addRegexToken('NNN', matchEraAbbr); - addRegexToken('NNNN', matchEraName); - addRegexToken('NNNNN', matchEraNarrow); - - addParseToken( - ['N', 'NN', 'NNN', 'NNNN', 'NNNNN'], - function (input, array, config, token) { - var era = config._locale.erasParse(input, token, config._strict); - if (era) { - getParsingFlags(config).era = era; - } else { - getParsingFlags(config).invalidEra = input; - } - } - ); +/** Used for built-in method references. */ +var objectProto = Object.prototype; - addRegexToken('y', matchUnsigned); - addRegexToken('yy', matchUnsigned); - addRegexToken('yyy', matchUnsigned); - addRegexToken('yyyy', matchUnsigned); - addRegexToken('yo', matchEraYearOrdinal); - - addParseToken(['y', 'yy', 'yyy', 'yyyy'], YEAR); - addParseToken(['yo'], function (input, array, config, token) { - var match; - if (config._locale._eraYearOrdinalRegex) { - match = input.match(config._locale._eraYearOrdinalRegex); - } +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; - if (config._locale.eraYearOrdinalParse) { - array[YEAR] = config._locale.eraYearOrdinalParse(input, match); - } else { - array[YEAR] = parseInt(input, 10); - } - }); +/** + * 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; +} - function localeEras(m, format) { - var i, - l, - date, - eras = this._eras || getLocale('en')._eras; - for (i = 0, l = eras.length; i < l; ++i) { - switch (typeof eras[i].since) { - case 'string': - // truncate time - date = hooks(eras[i].since).startOf('day'); - eras[i].since = date.valueOf(); - break; - } +module.exports = hashGet; - switch (typeof eras[i].until) { - case 'undefined': - eras[i].until = +Infinity; - break; - case 'string': - // truncate time - date = hooks(eras[i].until).startOf('day').valueOf(); - eras[i].until = date.valueOf(); - break; - } - } - return eras; - } - - function localeErasParse(eraName, format, strict) { - var i, - l, - eras = this.eras(), - name, - abbr, - narrow; - eraName = eraName.toUpperCase(); - - for (i = 0, l = eras.length; i < l; ++i) { - name = eras[i].name.toUpperCase(); - abbr = eras[i].abbr.toUpperCase(); - narrow = eras[i].narrow.toUpperCase(); - - if (strict) { - switch (format) { - case 'N': - case 'NN': - case 'NNN': - if (abbr === eraName) { - return eras[i]; - } - break; - case 'NNNN': - if (name === eraName) { - return eras[i]; - } - break; +/***/ }), - case 'NNNNN': - if (narrow === eraName) { - return eras[i]; - } - break; - } - } else if ([name, abbr, narrow].indexOf(eraName) >= 0) { - return eras[i]; - } - } - } +/***/ 5232: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - function localeErasConvertYear(era, year) { - var dir = era.since <= era.until ? +1 : -1; - if (year === undefined) { - return hooks(era.since).year(); - } else { - return hooks(era.since).year() + (year - era.offset) * dir; - } - } +var nativeCreate = __nccwpck_require__(3041); - function getEraName() { - var i, - l, - val, - eras = this.localeData().eras(); - for (i = 0, l = eras.length; i < l; ++i) { - // truncate time - val = this.clone().startOf('day').valueOf(); +/** Used for built-in method references. */ +var objectProto = Object.prototype; - if (eras[i].since <= val && val <= eras[i].until) { - return eras[i].name; - } - if (eras[i].until <= val && val <= eras[i].since) { - return eras[i].name; - } - } +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; - return ''; - } +/** + * 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); +} - function getEraNarrow() { - var i, - l, - val, - eras = this.localeData().eras(); - for (i = 0, l = eras.length; i < l; ++i) { - // truncate time - val = this.clone().startOf('day').valueOf(); +module.exports = hashHas; - if (eras[i].since <= val && val <= eras[i].until) { - return eras[i].narrow; - } - if (eras[i].until <= val && val <= eras[i].since) { - return eras[i].narrow; - } - } - return ''; - } +/***/ }), - function getEraAbbr() { - var i, - l, - val, - eras = this.localeData().eras(); - for (i = 0, l = eras.length; i < l; ++i) { - // truncate time - val = this.clone().startOf('day').valueOf(); +/***/ 7320: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - if (eras[i].since <= val && val <= eras[i].until) { - return eras[i].abbr; - } - if (eras[i].until <= val && val <= eras[i].since) { - return eras[i].abbr; - } - } +var nativeCreate = __nccwpck_require__(3041); - return ''; - } +/** Used to stand-in for `undefined` hash values. */ +var HASH_UNDEFINED = '__lodash_hash_undefined__'; - function getEraYear() { - var i, - l, - dir, - val, - eras = this.localeData().eras(); - for (i = 0, l = eras.length; i < l; ++i) { - dir = eras[i].since <= eras[i].until ? +1 : -1; - - // truncate time - val = this.clone().startOf('day').valueOf(); - - if ( - (eras[i].since <= val && val <= eras[i].until) || - (eras[i].until <= val && val <= eras[i].since) - ) { - return ( - (this.year() - hooks(eras[i].since).year()) * dir + - eras[i].offset - ); - } - } +/** + * 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; +} - return this.year(); - } +module.exports = hashSet; - function erasNameRegex(isStrict) { - if (!hasOwnProp(this, '_erasNameRegex')) { - computeErasParse.call(this); - } - return isStrict ? this._erasNameRegex : this._erasRegex; - } - function erasAbbrRegex(isStrict) { - if (!hasOwnProp(this, '_erasAbbrRegex')) { - computeErasParse.call(this); - } - return isStrict ? this._erasAbbrRegex : this._erasRegex; - } +/***/ }), - function erasNarrowRegex(isStrict) { - if (!hasOwnProp(this, '_erasNarrowRegex')) { - computeErasParse.call(this); - } - return isStrict ? this._erasNarrowRegex : this._erasRegex; - } +/***/ 9084: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - function matchEraAbbr(isStrict, locale) { - return locale.erasAbbrRegex(isStrict); - } +var isArray = __nccwpck_require__(4869), + isSymbol = __nccwpck_require__(6403); - function matchEraName(isStrict, locale) { - return locale.erasNameRegex(isStrict); - } +/** Used to match property names within property paths. */ +var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, + reIsPlainProp = /^\w*$/; - function matchEraNarrow(isStrict, locale) { - return locale.erasNarrowRegex(isStrict); - } +/** + * 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)); +} - function matchEraYearOrdinal(isStrict, locale) { - return locale._eraYearOrdinalRegex || matchUnsigned; - } +module.exports = isKey; - function computeErasParse() { - var abbrPieces = [], - namePieces = [], - narrowPieces = [], - mixedPieces = [], - i, - l, - eras = this.eras(); - for (i = 0, l = eras.length; i < l; ++i) { - namePieces.push(regexEscape(eras[i].name)); - abbrPieces.push(regexEscape(eras[i].abbr)); - narrowPieces.push(regexEscape(eras[i].narrow)); +/***/ }), - mixedPieces.push(regexEscape(eras[i].name)); - mixedPieces.push(regexEscape(eras[i].abbr)); - mixedPieces.push(regexEscape(eras[i].narrow)); - } +/***/ 3308: +/***/ ((module) => { - this._erasRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i'); - this._erasNameRegex = new RegExp('^(' + namePieces.join('|') + ')', 'i'); - this._erasAbbrRegex = new RegExp('^(' + abbrPieces.join('|') + ')', 'i'); - this._erasNarrowRegex = new RegExp( - '^(' + narrowPieces.join('|') + ')', - 'i' - ); - } +/** + * 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); +} - // FORMATTING +module.exports = isKeyable; - addFormatToken(0, ['gg', 2], 0, function () { - return this.weekYear() % 100; - }); - addFormatToken(0, ['GG', 2], 0, function () { - return this.isoWeekYear() % 100; - }); +/***/ }), - function addWeekYearFormatToken(token, getter) { - addFormatToken(0, [token, token.length], 0, getter); - } +/***/ 9058: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - addWeekYearFormatToken('gggg', 'weekYear'); - addWeekYearFormatToken('ggggg', 'weekYear'); - addWeekYearFormatToken('GGGG', 'isoWeekYear'); - addWeekYearFormatToken('GGGGG', 'isoWeekYear'); +var coreJsData = __nccwpck_require__(8380); - // ALIASES +/** 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) : ''; +}()); - addUnitAlias('weekYear', 'gg'); - addUnitAlias('isoWeekYear', 'GG'); +/** + * 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); +} - // PRIORITY +module.exports = isMasked; - addUnitPriority('weekYear', 1); - addUnitPriority('isoWeekYear', 1); - // PARSING +/***/ }), - addRegexToken('G', matchSigned); - addRegexToken('g', matchSigned); - addRegexToken('GG', match1to2, match2); - addRegexToken('gg', match1to2, match2); - addRegexToken('GGGG', match1to4, match4); - addRegexToken('gggg', match1to4, match4); - addRegexToken('GGGGG', match1to6, match6); - addRegexToken('ggggg', match1to6, match6); +/***/ 9792: +/***/ ((module) => { - addWeekParseToken( - ['gggg', 'ggggg', 'GGGG', 'GGGGG'], - function (input, week, config, token) { - week[token.substr(0, 2)] = toInt(input); - } - ); +/** + * Removes all key-value entries from the list cache. + * + * @private + * @name clear + * @memberOf ListCache + */ +function listCacheClear() { + this.__data__ = []; + this.size = 0; +} - addWeekParseToken(['gg', 'GG'], function (input, week, config, token) { - week[token] = hooks.parseTwoDigitYear(input); - }); +module.exports = listCacheClear; - // MOMENTS - function getSetWeekYear(input) { - return getSetWeekYearHelper.call( - this, - input, - this.week(), - this.weekday(), - this.localeData()._week.dow, - this.localeData()._week.doy - ); - } +/***/ }), - function getSetISOWeekYear(input) { - return getSetWeekYearHelper.call( - this, - input, - this.isoWeek(), - this.isoWeekday(), - 1, - 4 - ); - } +/***/ 7716: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - function getISOWeeksInYear() { - return weeksInYear(this.year(), 1, 4); - } +var assocIndexOf = __nccwpck_require__(6752); - function getISOWeeksInISOWeekYear() { - return weeksInYear(this.isoWeekYear(), 1, 4); - } +/** Used for built-in method references. */ +var arrayProto = Array.prototype; - function getWeeksInYear() { - var weekInfo = this.localeData()._week; - return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy); - } +/** Built-in value references. */ +var splice = arrayProto.splice; - function getWeeksInWeekYear() { - var weekInfo = this.localeData()._week; - return weeksInYear(this.weekYear(), weekInfo.dow, weekInfo.doy); - } +/** + * 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); - function getSetWeekYearHelper(input, week, weekday, dow, doy) { - var weeksTarget; - if (input == null) { - return weekOfYear(this, dow, doy).year; - } else { - weeksTarget = weeksInYear(input, dow, doy); - if (week > weeksTarget) { - week = weeksTarget; - } - return setWeekAll.call(this, input, week, weekday, dow, doy); - } - } + 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; +} - function setWeekAll(weekYear, week, weekday, dow, doy) { - var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy), - date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear); +module.exports = listCacheDelete; - this.year(date.getUTCFullYear()); - this.month(date.getUTCMonth()); - this.date(date.getUTCDate()); - return this; - } - // FORMATTING +/***/ }), - addFormatToken('Q', 0, 'Qo', 'quarter'); +/***/ 5789: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - // ALIASES +var assocIndexOf = __nccwpck_require__(6752); - addUnitAlias('quarter', 'Q'); +/** + * 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); - // PRIORITY + return index < 0 ? undefined : data[index][1]; +} - addUnitPriority('quarter', 7); +module.exports = listCacheGet; - // PARSING - addRegexToken('Q', match1); - addParseToken('Q', function (input, array) { - array[MONTH] = (toInt(input) - 1) * 3; - }); +/***/ }), - // MOMENTS +/***/ 9386: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - function getSetQuarter(input) { - return input == null - ? Math.ceil((this.month() + 1) / 3) - : this.month((input - 1) * 3 + (this.month() % 3)); - } +var assocIndexOf = __nccwpck_require__(6752); - // FORMATTING +/** + * 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; +} - addFormatToken('D', ['DD', 2], 'Do', 'date'); +module.exports = listCacheHas; - // ALIASES - addUnitAlias('date', 'D'); +/***/ }), - // PRIORITY - addUnitPriority('date', 9); +/***/ 7399: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - // PARSING +var assocIndexOf = __nccwpck_require__(6752); - addRegexToken('D', match1to2); - addRegexToken('DD', match1to2, match2); - addRegexToken('Do', function (isStrict, locale) { - // TODO: Remove "ordinalParse" fallback in next major release. - return isStrict - ? locale._dayOfMonthOrdinalParse || locale._ordinalParse - : locale._dayOfMonthOrdinalParseLenient; - }); +/** + * 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); - addParseToken(['D', 'DD'], DATE); - addParseToken('Do', function (input, array) { - array[DATE] = toInt(input.match(match1to2)[0]); - }); + if (index < 0) { + ++this.size; + data.push([key, value]); + } else { + data[index][1] = value; + } + return this; +} - // MOMENTS +module.exports = listCacheSet; - var getSetDayOfMonth = makeGetSet('Date', true); - // FORMATTING +/***/ }), - addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear'); +/***/ 1610: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - // ALIASES +var Hash = __nccwpck_require__(5902), + ListCache = __nccwpck_require__(6608), + Map = __nccwpck_require__(881); - addUnitAlias('dayOfYear', 'DDD'); +/** + * 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 + }; +} - // PRIORITY - addUnitPriority('dayOfYear', 4); +module.exports = mapCacheClear; - // PARSING - addRegexToken('DDD', match1to3); - addRegexToken('DDDD', match3); - addParseToken(['DDD', 'DDDD'], function (input, array, config) { - config._dayOfYear = toInt(input); - }); +/***/ }), - // HELPERS +/***/ 6657: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - // MOMENTS +var getMapData = __nccwpck_require__(9980); - function getSetDayOfYear(input) { - var dayOfYear = - Math.round( - (this.clone().startOf('day') - this.clone().startOf('year')) / 864e5 - ) + 1; - return input == null ? dayOfYear : this.add(input - dayOfYear, 'd'); - } +/** + * 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; +} - // FORMATTING +module.exports = mapCacheDelete; - addFormatToken('m', ['mm', 2], 0, 'minute'); - // ALIASES +/***/ }), - addUnitAlias('minute', 'm'); +/***/ 1372: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - // PRIORITY +var getMapData = __nccwpck_require__(9980); - addUnitPriority('minute', 14); +/** + * 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); +} - // PARSING +module.exports = mapCacheGet; - addRegexToken('m', match1to2); - addRegexToken('mm', match1to2, match2); - addParseToken(['m', 'mm'], MINUTE); - // MOMENTS +/***/ }), - var getSetMinute = makeGetSet('Minutes', false); +/***/ 609: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - // FORMATTING +var getMapData = __nccwpck_require__(9980); - addFormatToken('s', ['ss', 2], 0, 'second'); +/** + * 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); +} - // ALIASES +module.exports = mapCacheHas; - addUnitAlias('second', 's'); - // PRIORITY +/***/ }), - addUnitPriority('second', 15); +/***/ 5582: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - // PARSING +var getMapData = __nccwpck_require__(9980); - addRegexToken('s', match1to2); - addRegexToken('ss', match1to2, match2); - addParseToken(['s', 'ss'], SECOND); +/** + * 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; - // MOMENTS + data.set(key, value); + this.size += data.size == size ? 0 : 1; + return this; +} - var getSetSecond = makeGetSet('Seconds', false); +module.exports = mapCacheSet; - // FORMATTING - addFormatToken('S', 0, 0, function () { - return ~~(this.millisecond() / 100); - }); +/***/ }), - addFormatToken(0, ['SS', 2], 0, function () { - return ~~(this.millisecond() / 10); - }); +/***/ 9422: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - addFormatToken(0, ['SSS', 3], 0, 'millisecond'); - addFormatToken(0, ['SSSS', 4], 0, function () { - return this.millisecond() * 10; - }); - addFormatToken(0, ['SSSSS', 5], 0, function () { - return this.millisecond() * 100; - }); - addFormatToken(0, ['SSSSSS', 6], 0, function () { - return this.millisecond() * 1000; - }); - addFormatToken(0, ['SSSSSSS', 7], 0, function () { - return this.millisecond() * 10000; - }); - addFormatToken(0, ['SSSSSSSS', 8], 0, function () { - return this.millisecond() * 100000; - }); - addFormatToken(0, ['SSSSSSSSS', 9], 0, function () { - return this.millisecond() * 1000000; - }); +var memoize = __nccwpck_require__(9885); - // ALIASES +/** Used as the maximum memoize cache size. */ +var MAX_MEMOIZE_SIZE = 500; - addUnitAlias('millisecond', 'ms'); +/** + * 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; + }); - // PRIORITY + var cache = result.cache; + return result; +} - addUnitPriority('millisecond', 16); +module.exports = memoizeCapped; - // PARSING - addRegexToken('S', match1to3, match1); - addRegexToken('SS', match1to3, match2); - addRegexToken('SSS', match1to3, match3); +/***/ }), - var token, getSetMillisecond; - for (token = 'SSSS'; token.length <= 9; token += 'S') { - addRegexToken(token, matchUnsigned); - } +/***/ 3041: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - function parseMs(input, array) { - array[MILLISECOND] = toInt(('0.' + input) * 1000); - } +var getNative = __nccwpck_require__(4479); - for (token = 'S'; token.length <= 9; token += 'S') { - addParseToken(token, parseMs); - } +/* Built-in method references that are verified to be native. */ +var nativeCreate = getNative(Object, 'create'); - getSetMillisecond = makeGetSet('Milliseconds', false); +module.exports = nativeCreate; - // FORMATTING - addFormatToken('z', 0, 0, 'zoneAbbr'); - addFormatToken('zz', 0, 0, 'zoneName'); +/***/ }), - // MOMENTS +/***/ 4200: +/***/ ((module) => { - function getZoneAbbr() { - return this._isUTC ? 'UTC' : ''; - } +/** Used for built-in method references. */ +var objectProto = Object.prototype; - function getZoneName() { - return this._isUTC ? 'Coordinated Universal Time' : ''; - } +/** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ +var nativeObjectToString = objectProto.toString; - var proto = Moment.prototype; +/** + * 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); +} - proto.add = add; - proto.calendar = calendar$1; - proto.clone = clone; - proto.diff = diff; - proto.endOf = endOf; - proto.format = format; - proto.from = from; - proto.fromNow = fromNow; - proto.to = to; - proto.toNow = toNow; - proto.get = stringGet; - proto.invalidAt = invalidAt; - proto.isAfter = isAfter; - proto.isBefore = isBefore; - proto.isBetween = isBetween; - proto.isSame = isSame; - proto.isSameOrAfter = isSameOrAfter; - proto.isSameOrBefore = isSameOrBefore; - proto.isValid = isValid$2; - proto.lang = lang; - proto.locale = locale; - proto.localeData = localeData; - proto.max = prototypeMax; - proto.min = prototypeMin; - proto.parsingFlags = parsingFlags; - proto.set = stringSet; - proto.startOf = startOf; - proto.subtract = subtract; - proto.toArray = toArray; - proto.toObject = toObject; - proto.toDate = toDate; - proto.toISOString = toISOString; - proto.inspect = inspect; - if (typeof Symbol !== 'undefined' && Symbol.for != null) { - proto[Symbol.for('nodejs.util.inspect.custom')] = function () { - return 'Moment<' + this.format() + '>'; - }; - } - proto.toJSON = toJSON; - proto.toString = toString; - proto.unix = unix; - proto.valueOf = valueOf; - proto.creationData = creationData; - proto.eraName = getEraName; - proto.eraNarrow = getEraNarrow; - proto.eraAbbr = getEraAbbr; - proto.eraYear = getEraYear; - proto.year = getSetYear; - proto.isLeapYear = getIsLeapYear; - proto.weekYear = getSetWeekYear; - proto.isoWeekYear = getSetISOWeekYear; - proto.quarter = proto.quarters = getSetQuarter; - proto.month = getSetMonth; - proto.daysInMonth = getDaysInMonth; - proto.week = proto.weeks = getSetWeek; - proto.isoWeek = proto.isoWeeks = getSetISOWeek; - proto.weeksInYear = getWeeksInYear; - proto.weeksInWeekYear = getWeeksInWeekYear; - proto.isoWeeksInYear = getISOWeeksInYear; - proto.isoWeeksInISOWeekYear = getISOWeeksInISOWeekYear; - proto.date = getSetDayOfMonth; - proto.day = proto.days = getSetDayOfWeek; - proto.weekday = getSetLocaleDayOfWeek; - proto.isoWeekday = getSetISODayOfWeek; - proto.dayOfYear = getSetDayOfYear; - proto.hour = proto.hours = getSetHour; - proto.minute = proto.minutes = getSetMinute; - proto.second = proto.seconds = getSetSecond; - proto.millisecond = proto.milliseconds = getSetMillisecond; - proto.utcOffset = getSetOffset; - proto.utc = setOffsetToUTC; - proto.local = setOffsetToLocal; - proto.parseZone = setOffsetToParsedOffset; - proto.hasAlignedHourOffset = hasAlignedHourOffset; - proto.isDST = isDaylightSavingTime; - proto.isLocal = isLocal; - proto.isUtcOffset = isUtcOffset; - proto.isUtc = isUtc; - proto.isUTC = isUtc; - proto.zoneAbbr = getZoneAbbr; - proto.zoneName = getZoneName; - proto.dates = deprecate( - 'dates accessor is deprecated. Use date instead.', - getSetDayOfMonth - ); - proto.months = deprecate( - 'months accessor is deprecated. Use month instead', - getSetMonth - ); - proto.years = deprecate( - 'years accessor is deprecated. Use year instead', - getSetYear - ); - proto.zone = deprecate( - 'moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', - getSetZone - ); - proto.isDSTShifted = deprecate( - 'isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', - isDaylightSavingTimeShifted - ); +module.exports = objectToString; - function createUnix(input) { - return createLocal(input * 1000); - } - function createInZone() { - return createLocal.apply(null, arguments).parseZone(); - } +/***/ }), - function preParsePostFormat(string) { - return string; - } +/***/ 9882: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - var proto$1 = Locale.prototype; +var freeGlobal = __nccwpck_require__(2085); - proto$1.calendar = calendar; - proto$1.longDateFormat = longDateFormat; - proto$1.invalidDate = invalidDate; - proto$1.ordinal = ordinal; - proto$1.preparse = preParsePostFormat; - proto$1.postformat = preParsePostFormat; - proto$1.relativeTime = relativeTime; - proto$1.pastFuture = pastFuture; - proto$1.set = set; - proto$1.eras = localeEras; - proto$1.erasParse = localeErasParse; - proto$1.erasConvertYear = localeErasConvertYear; - proto$1.erasAbbrRegex = erasAbbrRegex; - proto$1.erasNameRegex = erasNameRegex; - proto$1.erasNarrowRegex = erasNarrowRegex; +/** Detect free variable `self`. */ +var freeSelf = typeof self == 'object' && self && self.Object === Object && self; - proto$1.months = localeMonths; - proto$1.monthsShort = localeMonthsShort; - proto$1.monthsParse = localeMonthsParse; - proto$1.monthsRegex = monthsRegex; - proto$1.monthsShortRegex = monthsShortRegex; - proto$1.week = localeWeek; - proto$1.firstDayOfYear = localeFirstDayOfYear; - proto$1.firstDayOfWeek = localeFirstDayOfWeek; +/** Used as a reference to the global object. */ +var root = freeGlobal || freeSelf || Function('return this')(); - proto$1.weekdays = localeWeekdays; - proto$1.weekdaysMin = localeWeekdaysMin; - proto$1.weekdaysShort = localeWeekdaysShort; - proto$1.weekdaysParse = localeWeekdaysParse; +module.exports = root; - proto$1.weekdaysRegex = weekdaysRegex; - proto$1.weekdaysShortRegex = weekdaysShortRegex; - proto$1.weekdaysMinRegex = weekdaysMinRegex; - proto$1.isPM = localeIsPM; - proto$1.meridiem = localeMeridiem; +/***/ }), - function get$1(format, index, field, setter) { - var locale = getLocale(), - utc = createUTC().set(setter, index); - return locale[field](utc, format); - } +/***/ 1853: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - function listMonthsImpl(format, index, field) { - if (isNumber(format)) { - index = format; - format = undefined; - } +var memoizeCapped = __nccwpck_require__(9422); - format = format || ''; +/** Used to match property names within property paths. */ +var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; - if (index != null) { - return get$1(format, index, field, 'month'); - } +/** Used to match backslashes in property paths. */ +var reEscapeChar = /\\(\\)?/g; - var i, - out = []; - for (i = 0; i < 12; i++) { - out[i] = get$1(format, i, field, 'month'); - } - return out; - } - - // () - // (5) - // (fmt, 5) - // (fmt) - // (true) - // (true, 5) - // (true, fmt, 5) - // (true, fmt) - function listWeekdaysImpl(localeSorted, format, index, field) { - if (typeof localeSorted === 'boolean') { - if (isNumber(format)) { - index = format; - format = undefined; - } +/** + * 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; +}); - format = format || ''; - } else { - format = localeSorted; - index = format; - localeSorted = false; +module.exports = stringToPath; - if (isNumber(format)) { - index = format; - format = undefined; - } - format = format || ''; - } +/***/ }), - var locale = getLocale(), - shift = localeSorted ? locale._week.dow : 0, - i, - out = []; +/***/ 9071: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - if (index != null) { - return get$1(format, (index + shift) % 7, field, 'day'); - } +var isSymbol = __nccwpck_require__(6403); - for (i = 0; i < 7; i++) { - out[i] = get$1(format, (i + shift) % 7, field, 'day'); - } - return out; - } +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; - function listMonths(format, index) { - return listMonthsImpl(format, index, 'months'); - } +/** + * 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; +} - function listMonthsShort(format, index) { - return listMonthsImpl(format, index, 'monthsShort'); - } +module.exports = toKey; - function listWeekdays(localeSorted, format, index) { - return listWeekdaysImpl(localeSorted, format, index, 'weekdays'); - } - function listWeekdaysShort(localeSorted, format, index) { - return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort'); - } +/***/ }), - function listWeekdaysMin(localeSorted, format, index) { - return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin'); - } +/***/ 6928: +/***/ ((module) => { - getSetGlobalLocale('en', { - eras: [ - { - since: '0001-01-01', - until: +Infinity, - offset: 1, - name: 'Anno Domini', - narrow: 'AD', - abbr: 'AD', - }, - { - since: '0000-12-31', - until: -Infinity, - offset: 1, - name: 'Before Christ', - narrow: 'BC', - abbr: 'BC', - }, - ], - dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/, - ordinal: function (number) { - var b = number % 10, - output = - toInt((number % 100) / 10) === 1 - ? 'th' - : b === 1 - ? 'st' - : b === 2 - ? 'nd' - : b === 3 - ? 'rd' - : 'th'; - return number + output; - }, - }); +/** Used for built-in method references. */ +var funcProto = Function.prototype; - // Side effect imports +/** Used to resolve the decompiled source of functions. */ +var funcToString = funcProto.toString; - hooks.lang = deprecate( - 'moment.lang is deprecated. Use moment.locale instead.', - getSetGlobalLocale - ); - hooks.langData = deprecate( - 'moment.langData is deprecated. Use moment.localeData instead.', - getLocale - ); +/** + * 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 ''; +} - var mathAbs = Math.abs; +module.exports = toSource; - function abs() { - var data = this._data; - this._milliseconds = mathAbs(this._milliseconds); - this._days = mathAbs(this._days); - this._months = mathAbs(this._months); +/***/ }), - data.milliseconds = mathAbs(data.milliseconds); - data.seconds = mathAbs(data.seconds); - data.minutes = mathAbs(data.minutes); - data.hours = mathAbs(data.hours); - data.months = mathAbs(data.months); - data.years = mathAbs(data.years); +/***/ 1901: +/***/ ((module) => { - return this; - } +/** + * 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); +} - function addSubtract$1(duration, input, value, direction) { - var other = createDuration(input, value); +module.exports = eq; - duration._milliseconds += direction * other._milliseconds; - duration._days += direction * other._days; - duration._months += direction * other._months; - return duration._bubble(); - } +/***/ }), - // supports only 2.0-style add(1, 's') or add(duration) - function add$1(input, value) { - return addSubtract$1(this, input, value, 1); - } +/***/ 6908: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - // supports only 2.0-style subtract(1, 's') or subtract(duration) - function subtract$1(input, value) { - return addSubtract$1(this, input, value, -1); - } +var baseGet = __nccwpck_require__(5758); - function absCeil(number) { - if (number < 0) { - return Math.floor(number); - } else { - return Math.ceil(number); - } - } +/** + * 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; +} - function bubble() { - var milliseconds = this._milliseconds, - days = this._days, - months = this._months, - data = this._data, - seconds, - minutes, - hours, - years, - monthsFromDays; - - // if we have a mix of positive and negative values, bubble down first - // check: https://github.com/moment/moment/issues/2166 - if ( - !( - (milliseconds >= 0 && days >= 0 && months >= 0) || - (milliseconds <= 0 && days <= 0 && months <= 0) - ) - ) { - milliseconds += absCeil(monthsToDays(months) + days) * 864e5; - days = 0; - months = 0; - } +module.exports = get; - // The following code bubbles up values, see the tests for - // examples of what that means. - data.milliseconds = milliseconds % 1000; - seconds = absFloor(milliseconds / 1000); - data.seconds = seconds % 60; +/***/ }), - minutes = absFloor(seconds / 60); - data.minutes = minutes % 60; +/***/ 4869: +/***/ ((module) => { - hours = absFloor(minutes / 60); - data.hours = hours % 24; +/** + * 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; - days += absFloor(hours / 24); +module.exports = isArray; - // convert days to months - monthsFromDays = absFloor(daysToMonths(days)); - months += monthsFromDays; - days -= absCeil(monthsToDays(monthsFromDays)); - // 12 months -> 1 year - years = absFloor(months / 12); - months %= 12; +/***/ }), - data.days = days; - data.months = months; - data.years = years; +/***/ 7799: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - return this; - } +var baseGetTag = __nccwpck_require__(7497), + isObject = __nccwpck_require__(3334); - function daysToMonths(days) { - // 400 years have 146097 days (taking into account leap year rules) - // 400 years have 12 months === 4800 - return (days * 4800) / 146097; - } +/** `Object#toString` result references. */ +var asyncTag = '[object AsyncFunction]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + proxyTag = '[object Proxy]'; - function monthsToDays(months) { - // the reverse of daysToMonths - return (months * 146097) / 4800; - } +/** + * 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; +} - function as(units) { - if (!this.isValid()) { - return NaN; - } - var days, - months, - milliseconds = this._milliseconds; - - units = normalizeUnits(units); - - if (units === 'month' || units === 'quarter' || units === 'year') { - days = this._days + milliseconds / 864e5; - months = this._months + daysToMonths(days); - switch (units) { - case 'month': - return months; - case 'quarter': - return months / 3; - case 'year': - return months / 12; - } - } else { - // handle milliseconds separately because of floating point math errors (issue #1867) - days = this._days + Math.round(monthsToDays(this._months)); - switch (units) { - case 'week': - return days / 7 + milliseconds / 6048e5; - case 'day': - return days + milliseconds / 864e5; - case 'hour': - return days * 24 + milliseconds / 36e5; - case 'minute': - return days * 1440 + milliseconds / 6e4; - case 'second': - return days * 86400 + milliseconds / 1000; - // Math.floor prevents floating point math errors here - case 'millisecond': - return Math.floor(days * 864e5) + milliseconds; - default: - throw new Error('Unknown unit ' + units); - } - } - } +module.exports = isFunction; - // TODO: Use this.as('ms')? - function valueOf$1() { - if (!this.isValid()) { - return NaN; - } - return ( - this._milliseconds + - this._days * 864e5 + - (this._months % 12) * 2592e6 + - toInt(this._months / 12) * 31536e6 - ); - } - function makeAs(alias) { - return function () { - return this.as(alias); - }; - } +/***/ }), - var asMilliseconds = makeAs('ms'), - asSeconds = makeAs('s'), - asMinutes = makeAs('m'), - asHours = makeAs('h'), - asDays = makeAs('d'), - asWeeks = makeAs('w'), - asMonths = makeAs('M'), - asQuarters = makeAs('Q'), - asYears = makeAs('y'); +/***/ 3334: +/***/ ((module) => { - function clone$1() { - return createDuration(this); - } +/** + * 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'); +} - function get$2(units) { - units = normalizeUnits(units); - return this.isValid() ? this[units + 's']() : NaN; - } +module.exports = isObject; - function makeGetter(name) { - return function () { - return this.isValid() ? this._data[name] : NaN; - }; - } - var milliseconds = makeGetter('milliseconds'), - seconds = makeGetter('seconds'), - minutes = makeGetter('minutes'), - hours = makeGetter('hours'), - days = makeGetter('days'), - months = makeGetter('months'), - years = makeGetter('years'); +/***/ }), - function weeks() { - return absFloor(this.days() / 7); - } +/***/ 5926: +/***/ ((module) => { - var round = Math.round, - thresholds = { - ss: 44, // a few seconds to seconds - s: 45, // seconds to minute - m: 45, // minutes to hour - h: 22, // hours to day - d: 26, // days to month/week - w: null, // weeks to month - M: 11, // months to year - }; +/** + * 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'; +} - // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize - function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) { - return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture); - } - - function relativeTime$1(posNegDuration, withoutSuffix, thresholds, locale) { - var duration = createDuration(posNegDuration).abs(), - seconds = round(duration.as('s')), - minutes = round(duration.as('m')), - hours = round(duration.as('h')), - days = round(duration.as('d')), - months = round(duration.as('M')), - weeks = round(duration.as('w')), - years = round(duration.as('y')), - a = - (seconds <= thresholds.ss && ['s', seconds]) || - (seconds < thresholds.s && ['ss', seconds]) || - (minutes <= 1 && ['m']) || - (minutes < thresholds.m && ['mm', minutes]) || - (hours <= 1 && ['h']) || - (hours < thresholds.h && ['hh', hours]) || - (days <= 1 && ['d']) || - (days < thresholds.d && ['dd', days]); - - if (thresholds.w != null) { - a = - a || - (weeks <= 1 && ['w']) || - (weeks < thresholds.w && ['ww', weeks]); - } - a = a || - (months <= 1 && ['M']) || - (months < thresholds.M && ['MM', months]) || - (years <= 1 && ['y']) || ['yy', years]; +module.exports = isObjectLike; - a[2] = withoutSuffix; - a[3] = +posNegDuration > 0; - a[4] = locale; - return substituteTimeAgo.apply(null, a); - } - // This function allows you to set the rounding function for relative time strings - function getSetRelativeTimeRounding(roundingFunction) { - if (roundingFunction === undefined) { - return round; - } - if (typeof roundingFunction === 'function') { - round = roundingFunction; - return true; - } - return false; - } +/***/ }), - // This function allows you to set a threshold for relative time strings - function getSetRelativeTimeThreshold(threshold, limit) { - if (thresholds[threshold] === undefined) { - return false; - } - if (limit === undefined) { - return thresholds[threshold]; - } - thresholds[threshold] = limit; - if (threshold === 's') { - thresholds.ss = limit - 1; - } - return true; - } +/***/ 6403: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - function humanize(argWithSuffix, argThresholds) { - if (!this.isValid()) { - return this.localeData().invalidDate(); - } +var baseGetTag = __nccwpck_require__(7497), + isObjectLike = __nccwpck_require__(5926); - var withSuffix = false, - th = thresholds, - locale, - output; +/** `Object#toString` result references. */ +var symbolTag = '[object Symbol]'; - if (typeof argWithSuffix === 'object') { - argThresholds = argWithSuffix; - argWithSuffix = false; - } - if (typeof argWithSuffix === 'boolean') { - withSuffix = argWithSuffix; - } - if (typeof argThresholds === 'object') { - th = Object.assign({}, thresholds, argThresholds); - if (argThresholds.s != null && argThresholds.ss == null) { - th.ss = argThresholds.s - 1; - } - } +/** + * 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); +} - locale = this.localeData(); - output = relativeTime$1(this, !withSuffix, th, locale); +module.exports = isSymbol; - if (withSuffix) { - output = locale.pastFuture(+this, output); - } - return locale.postformat(output); - } +/***/ }), - var abs$1 = Math.abs; +/***/ 9885: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - function sign(x) { - return (x > 0) - (x < 0) || +x; - } +var MapCache = __nccwpck_require__(938); - function toISOString$1() { - // for ISO strings we do not use the normal bubbling rules: - // * milliseconds bubble up until they become hours - // * days do not bubble at all - // * months bubble up until they become years - // This is because there is no context-free conversion between hours and days - // (think of clock changes) - // and also not between days and months (28-31 days per month) - if (!this.isValid()) { - return this.localeData().invalidDate(); - } +/** Error message constants. */ +var FUNC_ERROR_TEXT = 'Expected a function'; - var seconds = abs$1(this._milliseconds) / 1000, - days = abs$1(this._days), - months = abs$1(this._months), - minutes, - hours, - years, - s, - total = this.asSeconds(), - totalSign, - ymSign, - daysSign, - hmsSign; - - if (!total) { - // this is the same as C#'s (Noda) and python (isodate)... - // but not other JS (goog.date) - return 'P0D'; - } +/** + * 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; - // 3600 seconds -> 60 minutes -> 1 hour - minutes = absFloor(seconds / 60); - hours = absFloor(minutes / 60); - seconds %= 60; - minutes %= 60; - - // 12 months -> 1 year - years = absFloor(months / 12); - months %= 12; - - // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js - s = seconds ? seconds.toFixed(3).replace(/\.?0+$/, '') : ''; - - totalSign = total < 0 ? '-' : ''; - ymSign = sign(this._months) !== sign(total) ? '-' : ''; - daysSign = sign(this._days) !== sign(total) ? '-' : ''; - hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : ''; - - return ( - totalSign + - 'P' + - (years ? ymSign + years + 'Y' : '') + - (months ? ymSign + months + 'M' : '') + - (days ? daysSign + days + 'D' : '') + - (hours || minutes || seconds ? 'T' : '') + - (hours ? hmsSign + hours + 'H' : '') + - (minutes ? hmsSign + minutes + 'M' : '') + - (seconds ? hmsSign + s + 'S' : '') - ); + 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; +} - var proto$2 = Duration.prototype; - - proto$2.isValid = isValid$1; - proto$2.abs = abs; - proto$2.add = add$1; - proto$2.subtract = subtract$1; - proto$2.as = as; - proto$2.asMilliseconds = asMilliseconds; - proto$2.asSeconds = asSeconds; - proto$2.asMinutes = asMinutes; - proto$2.asHours = asHours; - proto$2.asDays = asDays; - proto$2.asWeeks = asWeeks; - proto$2.asMonths = asMonths; - proto$2.asQuarters = asQuarters; - proto$2.asYears = asYears; - proto$2.valueOf = valueOf$1; - proto$2._bubble = bubble; - proto$2.clone = clone$1; - proto$2.get = get$2; - proto$2.milliseconds = milliseconds; - proto$2.seconds = seconds; - proto$2.minutes = minutes; - proto$2.hours = hours; - proto$2.days = days; - proto$2.weeks = weeks; - proto$2.months = months; - proto$2.years = years; - proto$2.humanize = humanize; - proto$2.toISOString = toISOString$1; - proto$2.toString = toISOString$1; - proto$2.toJSON = toISOString$1; - proto$2.locale = locale; - proto$2.localeData = localeData; - - proto$2.toIsoString = deprecate( - 'toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', - toISOString$1 - ); - proto$2.lang = lang; +// Expose `MapCache`. +memoize.Cache = MapCache; - // FORMATTING +module.exports = memoize; - addFormatToken('X', 0, 0, 'unix'); - addFormatToken('x', 0, 0, 'valueOf'); - // PARSING +/***/ }), - addRegexToken('x', matchSigned); - addRegexToken('X', matchTimestamp); - addParseToken('X', function (input, array, config) { - config._d = new Date(parseFloat(input) * 1000); - }); - addParseToken('x', function (input, array, config) { - config._d = new Date(toInt(input)); - }); +/***/ 2931: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - //! moment.js - - hooks.version = '2.29.4'; - - setHookCallback(createLocal); - - hooks.fn = proto; - hooks.min = min; - hooks.max = max; - hooks.now = now; - hooks.utc = createUTC; - hooks.unix = createUnix; - hooks.months = listMonths; - hooks.isDate = isDate; - hooks.locale = getSetGlobalLocale; - hooks.invalid = createInvalid; - hooks.duration = createDuration; - hooks.isMoment = isMoment; - hooks.weekdays = listWeekdays; - hooks.parseZone = createInZone; - hooks.localeData = getLocale; - hooks.isDuration = isDuration; - hooks.monthsShort = listMonthsShort; - hooks.weekdaysMin = listWeekdaysMin; - hooks.defineLocale = defineLocale; - hooks.updateLocale = updateLocale; - hooks.locales = listLocales; - hooks.weekdaysShort = listWeekdaysShort; - hooks.normalizeUnits = normalizeUnits; - hooks.relativeTimeRounding = getSetRelativeTimeRounding; - hooks.relativeTimeThreshold = getSetRelativeTimeThreshold; - hooks.calendarFormat = getCalendarFormat; - hooks.prototype = proto; - - // currently HTML5 input type only supports 24-hour formats - hooks.HTML5_FMT = { - DATETIME_LOCAL: 'YYYY-MM-DDTHH:mm', // - DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss', // - DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS', // - DATE: 'YYYY-MM-DD', // - TIME: 'HH:mm', // - TIME_SECONDS: 'HH:mm:ss', // - TIME_MS: 'HH:mm:ss.SSS', // - WEEK: 'GGGG-[W]WW', // - MONTH: 'YYYY-MM', // - }; +var baseToString = __nccwpck_require__(6792); - return hooks; +/** + * 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); +} -}))); +module.exports = toString; /***/ }), @@ -23017,6 +20081,34 @@ module.exports = require("zlib"); /***/ }), +/***/ 3286: +/***/ ((module) => { + +function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { + "default": obj + }; +} +module.exports = _interopRequireDefault, module.exports.__esModule = true, module.exports["default"] = module.exports; + +/***/ }), + +/***/ 5605: +/***/ ((module) => { + +function _typeof(o) { + "@babel/helpers - typeof"; + + return (module.exports = _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { + return typeof o; + } : function (o) { + return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; + }, module.exports.__esModule = true, module.exports["default"] = module.exports), _typeof(o); +} +module.exports = _typeof, module.exports.__esModule = true, module.exports["default"] = module.exports; + +/***/ }), + /***/ 6717: /***/ ((__unused_webpack_module, exports) => { @@ -25286,8 +22378,8 @@ module.exports = JSON.parse('[[[0,44],"disallowed_STD3_valid"],[[45,46],"valid"] /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { -/******/ id: moduleId, -/******/ loaded: false, +/******/ // no module.id needed +/******/ // no module.loaded needed /******/ exports: {} /******/ }; /******/ @@ -25300,23 +22392,11 @@ module.exports = JSON.parse('[[[0,44],"disallowed_STD3_valid"],[[45,46],"valid"] /******/ if(threw) delete __webpack_module_cache__[moduleId]; /******/ } /******/ -/******/ // Flag the module as loaded -/******/ module.loaded = true; -/******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /************************************************************************/ -/******/ /* webpack/runtime/node module decorator */ -/******/ (() => { -/******/ __nccwpck_require__.nmd = (module) => { -/******/ module.paths = []; -/******/ if (!module.children) module.children = []; -/******/ return module; -/******/ }; -/******/ })(); -/******/ /******/ /* webpack/runtime/compat */ /******/ /******/ if (typeof __nccwpck_require__ !== 'undefined') __nccwpck_require__.ab = __dirname + "/"; diff --git a/.github/actions/javascript/getDeployPullRequestList/index.js b/.github/actions/javascript/getDeployPullRequestList/index.js index 96a6b0c4c2ac..6d9f714f0b77 100644 --- a/.github/actions/javascript/getDeployPullRequestList/index.js +++ b/.github/actions/javascript/getDeployPullRequestList/index.js @@ -63,6 +63,7 @@ const CONST = { DEPLOY_BLOCKER: 'DeployBlockerCash', INTERNAL_QA: 'InternalQA', }, + DATE_FORMAT_STRING: 'yyyy-MM-dd', }; CONST.APP_REPO_URL = `https://github.com/${CONST.GITHUB_OWNER}/${CONST.APP_REPO}`; diff --git a/.github/actions/javascript/getPullRequestDetails/index.js b/.github/actions/javascript/getPullRequestDetails/index.js index 82e03e3075d9..3c5bd277a60e 100644 --- a/.github/actions/javascript/getPullRequestDetails/index.js +++ b/.github/actions/javascript/getPullRequestDetails/index.js @@ -63,6 +63,7 @@ const CONST = { DEPLOY_BLOCKER: 'DeployBlockerCash', INTERNAL_QA: 'InternalQA', }, + DATE_FORMAT_STRING: 'yyyy-MM-dd', }; CONST.APP_REPO_URL = `https://github.com/${CONST.GITHUB_OWNER}/${CONST.APP_REPO}`; diff --git a/.github/actions/javascript/getReleaseBody/index.js b/.github/actions/javascript/getReleaseBody/index.js index 8cf926d63030..9ae04c4ef02a 100644 --- a/.github/actions/javascript/getReleaseBody/index.js +++ b/.github/actions/javascript/getReleaseBody/index.js @@ -63,6 +63,7 @@ const CONST = { DEPLOY_BLOCKER: 'DeployBlockerCash', INTERNAL_QA: 'InternalQA', }, + DATE_FORMAT_STRING: 'yyyy-MM-dd', }; CONST.APP_REPO_URL = `https://github.com/${CONST.GITHUB_OWNER}/${CONST.APP_REPO}`; diff --git a/.github/actions/javascript/isStagingDeployLocked/index.js b/.github/actions/javascript/isStagingDeployLocked/index.js index b355e5c126b8..fb4cdc1afd40 100644 --- a/.github/actions/javascript/isStagingDeployLocked/index.js +++ b/.github/actions/javascript/isStagingDeployLocked/index.js @@ -47,6 +47,7 @@ const CONST = { DEPLOY_BLOCKER: 'DeployBlockerCash', INTERNAL_QA: 'InternalQA', }, + DATE_FORMAT_STRING: 'yyyy-MM-dd', }; CONST.APP_REPO_URL = `https://github.com/${CONST.GITHUB_OWNER}/${CONST.APP_REPO}`; diff --git a/.github/actions/javascript/markPullRequestsAsDeployed/index.js b/.github/actions/javascript/markPullRequestsAsDeployed/index.js index 83a32d258509..73a51b622759 100644 --- a/.github/actions/javascript/markPullRequestsAsDeployed/index.js +++ b/.github/actions/javascript/markPullRequestsAsDeployed/index.js @@ -212,6 +212,7 @@ const CONST = { DEPLOY_BLOCKER: 'DeployBlockerCash', INTERNAL_QA: 'InternalQA', }, + DATE_FORMAT_STRING: 'yyyy-MM-dd', }; CONST.APP_REPO_URL = `https://github.com/${CONST.GITHUB_OWNER}/${CONST.APP_REPO}`; diff --git a/.github/actions/javascript/postTestBuildComment/index.js b/.github/actions/javascript/postTestBuildComment/index.js index c2d486b325bb..2c0fa6726ede 100644 --- a/.github/actions/javascript/postTestBuildComment/index.js +++ b/.github/actions/javascript/postTestBuildComment/index.js @@ -91,6 +91,7 @@ const CONST = { DEPLOY_BLOCKER: 'DeployBlockerCash', INTERNAL_QA: 'InternalQA', }, + DATE_FORMAT_STRING: 'yyyy-MM-dd', }; CONST.APP_REPO_URL = `https://github.com/${CONST.GITHUB_OWNER}/${CONST.APP_REPO}`; diff --git a/.github/actions/javascript/reopenIssueWithComment/index.js b/.github/actions/javascript/reopenIssueWithComment/index.js index c387679d3a05..39906af7bd05 100644 --- a/.github/actions/javascript/reopenIssueWithComment/index.js +++ b/.github/actions/javascript/reopenIssueWithComment/index.js @@ -17,6 +17,7 @@ const CONST = { DEPLOY_BLOCKER: 'DeployBlockerCash', INTERNAL_QA: 'InternalQA', }, + DATE_FORMAT_STRING: 'yyyy-MM-dd', }; CONST.APP_REPO_URL = `https://github.com/${CONST.GITHUB_OWNER}/${CONST.APP_REPO}`; diff --git a/.github/actions/javascript/reviewerChecklist/index.js b/.github/actions/javascript/reviewerChecklist/index.js index 09fb168330ec..aebf5205feab 100644 --- a/.github/actions/javascript/reviewerChecklist/index.js +++ b/.github/actions/javascript/reviewerChecklist/index.js @@ -17,6 +17,7 @@ const CONST = { DEPLOY_BLOCKER: 'DeployBlockerCash', INTERNAL_QA: 'InternalQA', }, + DATE_FORMAT_STRING: 'yyyy-MM-dd', }; CONST.APP_REPO_URL = `https://github.com/${CONST.GITHUB_OWNER}/${CONST.APP_REPO}`; diff --git a/.github/actions/javascript/verifySignedCommits/index.js b/.github/actions/javascript/verifySignedCommits/index.js index 71a01456457b..7f08a5f95790 100644 --- a/.github/actions/javascript/verifySignedCommits/index.js +++ b/.github/actions/javascript/verifySignedCommits/index.js @@ -17,6 +17,7 @@ const CONST = { DEPLOY_BLOCKER: 'DeployBlockerCash', INTERNAL_QA: 'InternalQA', }, + DATE_FORMAT_STRING: 'yyyy-MM-dd', }; CONST.APP_REPO_URL = `https://github.com/${CONST.GITHUB_OWNER}/${CONST.APP_REPO}`; From 876fc14a2bb75296600faa58bd3e5274dc8fb11e Mon Sep 17 00:00:00 2001 From: Viktoryia Kliushun Date: Thu, 9 Nov 2023 18:46:50 +0100 Subject: [PATCH 122/212] Update file extension --- fastlane/Fastfile | 4 ++-- tests/e2e/ADDING_TESTS.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 6c2cb5964bbc..2b5c15146eb3 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -15,7 +15,7 @@ opt_out_usage platform :android do desc "Generate a new local APK for e2e testing" - + lane :build_e2e do ENV["ENVFILE"]="tests/e2e/.env.e2e" ENV["ENTRY_FILE"]="src/libs/E2E/reactNativeLaunchingTest.ts" @@ -31,7 +31,7 @@ platform :android do lane :build_e2edelta do ENV["ENVFILE"]="tests/e2e/.env.e2edelta" - ENV["ENTRY_FILE"]="src/libs/E2E/reactNativeLaunchingTest.js" + ENV["ENTRY_FILE"]="src/libs/E2E/reactNativeLaunchingTest.ts" ENV["E2E_TESTING"]="true" gradle( diff --git a/tests/e2e/ADDING_TESTS.md b/tests/e2e/ADDING_TESTS.md index 00b194e68fc8..8d4683636e70 100644 --- a/tests/e2e/ADDING_TESTS.md +++ b/tests/e2e/ADDING_TESTS.md @@ -129,7 +129,7 @@ export default test; ### Last step: register the test in the e2e react native entry -In `src/lib/E2E/reactNativeLaunchingTest.js` you have to add your newly created +In `src/lib/E2E/reactNativeLaunchingTest.ts` you have to add your newly created test file: ```diff From 3b7199be403bfc9ca5ea9f8fb65feeb7bc770fed Mon Sep 17 00:00:00 2001 From: Daniel Edwards Date: Thu, 9 Nov 2023 15:17:33 -0500 Subject: [PATCH 123/212] Update src/components/ReceiptEmptyState.js Co-authored-by: Carlos Alvarez --- src/components/ReceiptEmptyState.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ReceiptEmptyState.js b/src/components/ReceiptEmptyState.js index 01c1b8a484f5..4275aa8739c0 100644 --- a/src/components/ReceiptEmptyState.js +++ b/src/components/ReceiptEmptyState.js @@ -8,7 +8,7 @@ import * as Expensicons from './Icon/Expensicons'; import PressableWithoutFeedback from './Pressable/PressableWithoutFeedback'; const propTypes = { - /** Whether or not there is a violation error */ + /** Whether or not there is an error */ hasError: PropTypes.bool, /** Callback to be called on onPress */ From 3d11e236923525bd3887ff5e00c720cc32c51de2 Mon Sep 17 00:00:00 2001 From: Daniel Edwards Date: Thu, 9 Nov 2023 15:17:52 -0500 Subject: [PATCH 124/212] Update src/components/ReceiptEmptyState.js Co-authored-by: Carlos Alvarez --- src/components/ReceiptEmptyState.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ReceiptEmptyState.js b/src/components/ReceiptEmptyState.js index 4275aa8739c0..e3e888cbf74b 100644 --- a/src/components/ReceiptEmptyState.js +++ b/src/components/ReceiptEmptyState.js @@ -17,7 +17,7 @@ const propTypes = { const defaultProps = { hasError: false, - onPress: undefined, + onPress: () => {}, }; // Create a component with the above instructions: From 162572c2f0a36b22207087b26c34c229f2f05e5b Mon Sep 17 00:00:00 2001 From: Daniel Edwards Date: Thu, 9 Nov 2023 15:25:36 -0500 Subject: [PATCH 125/212] Updates comment for component --- src/components/ReceiptEmptyState.js | 3 +-- src/components/ReportActionItem/MoneyRequestView.js | 10 ++++------ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/components/ReceiptEmptyState.js b/src/components/ReceiptEmptyState.js index e3e888cbf74b..205dd83dd42d 100644 --- a/src/components/ReceiptEmptyState.js +++ b/src/components/ReceiptEmptyState.js @@ -20,8 +20,7 @@ const defaultProps = { onPress: () => {}, }; -// Create a component with the above instructions: - +// Returns an SVG icon indicating that the user should attach a receipt function ReceiptEmptyState({hasError, onPress}) { return ( )} {!hasReceipt && Permissions.canUseViolations() && ( - - Navigation.navigate(ROUTES.EDIT_REQUEST.getRoute(report.reportID, CONST.EDIT_REQUEST_FIELD.RECEIPT))} - /> - + Navigation.navigate(ROUTES.EDIT_REQUEST.getRoute(report.reportID, CONST.EDIT_REQUEST_FIELD.RECEIPT))} + /> )} Date: Thu, 9 Nov 2023 15:55:01 -0600 Subject: [PATCH 126/212] Update Employees.md --- .../getting-started/Employees.md | 135 +++++++++++++++++- 1 file changed, 134 insertions(+), 1 deletion(-) diff --git a/docs/articles/expensify-classic/getting-started/Employees.md b/docs/articles/expensify-classic/getting-started/Employees.md index 6d3c2dc705e1..089a90c3dd21 100644 --- a/docs/articles/expensify-classic/getting-started/Employees.md +++ b/docs/articles/expensify-classic/getting-started/Employees.md @@ -2,4 +2,137 @@ title: Employees description: Employees --- -## Resource Coming Soon! +# Overview + +This post will cover getting started with Expensify for new users (submitters and employees). + +# Download the Mobile App + +You can download Expensify for iOS and Android devices using the respective links [here](#). + +# How to review homepage tasks + +Every time you log into Expensify, you'll land on your Home page. Here, you'll find tasks you need to take care of, like: +- Reviewing and fixing mistakes before sending your report +- Starting the review process for upcoming expense reports +- Getting helpful tips on how to use Expensify + +# Create your first expense + +You can create expenses in two ways: manually or automatically with SmartScan. + +### Manual Expense Creation: +- On the mobile app, tap the blue "+" icon. +- On the desktop app, click "New Expense." + +### Automatic Expense Creation with SmartScan: +- On the mobile app, tap the "camera" icon. +- Take a clear picture of your receipt. +- Click "Save" for the expense. + SmartScan will pull the details from the receipt and fill them in for you. + +You can also forward receipts from your email address to [receipts@expensify.com](mailto:receipts@expensify.com). SmartScan will handle the receipts the same way. + +Feel free to add coding details, categories, tags, comments, or attendees while SmartScan processes your receipt. SmartScan will handle the merchant, date, amount, and currency for you. + +For more details on how to create and edit expenses, take a look [here](#). + +# Submit your first report + +Expensify can automatically handle your reports through Scheduled Submit. There are two ways to activate this: + +### Activating Scheduled Submit for personal use: +- Go to Settings > Workspaces > Individual > [Workspace Name] > Reports. +- Toggle the setting to "Enabled". +- Choose how often you want reports to be submitted. + +### Activating Scheduled Submit globally for members of your Group Workspace: +- Go to Settings > Workspaces > Group > [Workspace Name] > Reports. +- Toggle the setting to "Enabled". +- Choose how often you want reports to be submitted. + +_Note: If you are a member of a Group Workspace, the company's settings might already have Scheduled Submit enabled. In this case, your personal Scheduled Submit settings will be ignored in favor of the Group Workspace’s submission schedule._ + +If you need to send a report manually: +- Click the Submit button in the top left of the report. +- On the mobile app, tap the report and click, Submit Report. + +For more details on creating and submitting reports, take a look [here](#). + +# What happens to my reports when they’re submitted? + +When you create a report, Expensify will automatically set your report to submit under the company Workspace your account is set to submit under. That means, when your report is submitted, it will follow the rules and approval chain of the Workspace. + +Every new user account has access to a “personal” Workspace, which is essentially a set of rules that you set for your own, non-company reports. + +With that in mind, it’s important to make sure your account is set to your company’s Workspace by default, to ensure that all newly created reports will be submitted under your company’s Workspace by default. + +If you find your reports are being submitted under your personal Workspace, you can correct this by changing your default Workspace which can be found in the account menu by clicking your Account Switcher icon. Additionally, if you have a Draft report that is set to submit under your personal Workspace, you can correct that by navigating to the report, clicking the Details button in the top right corner, and selecting your company Workspace from the dropdown. + +# How to use the Expenses page + +The Expenses page is your hub for managing your expenses. Here you'll see three types of expenses, each with an icon representing an expense type: + +- Cash Expense (represented by an icon of a bank note) +- Personal Credit Card (represented by an icon of a credit card) +- Corporate Company Card (represented by an icon of a credit card with a lock) + +In Expensify, any expense that has been manually created (i.e., not imported from a bank automatically) is considered a Cash Expense. These are typically out-of-pocket expenses and default to "reimbursable" unless indicated otherwise by your Workspace Admin. + +A Personal Credit Card expense is an expense that has been imported automatically from your personal bank. Personal Credit Cards can be imported through your Personal Settings, and the expenses are considered reimbursable by default unless you set it otherwise. + +A Corporate Company Card expense is an expense that has been imported automatically from your company card feed set on your company's domain. This card is assigned to you by your Domain Admin, and the expenses are typically non-reimbursable. + +### Navigating the Expenses page + +The Expenses page allows you to search your expenses using a wide variety of filters, including date ranges, merchant names, categories and tags, and the state of the report that the expense is contained within. You can also change the view of the Expenses page to fit your personal preferences. + +# How to use the Reports page + +The Reports page is a hub for managing your expense reports. There are four available states for reports: + +- Draft Reports: These are reports you've created but haven't submitted for approval. +- Processing Reports: These are reports currently under review by your admin. +- Approved Reports: These are reports that have been reviewed and approved by your admin. +- Reimbursed Reports: These are reports that have been reimbursed either through Expensify or by your admin outside of Expensify. + +### Navigating the Reports page + +The Reports page allows you to search your reports using a wide variety of filters, including date range, Report name or email address of the submitter, Report type, and Report state. + +# How to add a deposit account + +Adding a deposit account allows you to be reimbursed through Expensify by your company. There are a few nuanced differences between how to add deposit accounts depending on the currency you will be reimbursed in. Take a look at the different options [here](#). + +# Add a Secondary Login to your account + +Expensify accounts are personal by design. They belong to you, the user, forever. Yes, you might change careers, but your account will always be yours, just add your new company email address. + +To ensure you get to keep your Expensify account as you shuffle through your professional life, we recommend adding your personal email address as your Secondary Login. This will ensure that, even if you were to leave your current position for something new and exciting, your account will not be closed when you are removed from the company. Instead, your company email address would be stripped from the account, but you would maintain ownership of the Expensify account. + +Here’s how you can do that! + +# How to secure your account + +You can add an extra layer of security to your account by turning on Two Factor Authentication (2FA). Follow these steps on either your computer or mobile phone: + +### On Computer (Desktop): +- Open the desktop app. +- Go to Settings > Accounts > Account Details > Two Factor Authentication. +- Toggle the switch to "Enabled." +- Save or download your Recovery Codes. If you can't use your authenticator app, these codes are essential for access. + +### On Mobile phone: +- Open the Expensify app and go to Settings. +- Turn on the switch next to Two Factor Authentication. +- Save or download your Recovery Codes. +- On the next screen, copy the Secret Key and paste it into your preferred authenticator app. +- Once connected, enter the code from your app into Expensify before the time runs out. + +*Note: It's best to keep the time/date set to "Network" for Android and iOS to avoid issues with authentication codes that depend on time zones.* + +### Using Recovery Codes + +Only use a recovery code as a last resort to sign into your Expensify account. If you do use a recovery code: +- Reset 2FA in your account settings on the web or mobile app after gaining access. +- Toggle off and on 2FA to set it up again and get new recovery codes. From 2a52cfad42b4ec4b371f609d396f7199239e1d41 Mon Sep 17 00:00:00 2001 From: Jakub Trzebiatowski Date: Fri, 10 Nov 2023 10:23:34 +0100 Subject: [PATCH 127/212] `ReportActionItemFragment`: Add a default for `displayAsGroup` --- src/pages/home/report/ReportActionItemFragment.js | 3 ++- src/pages/home/report/ReportActionItemSingle.js | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/home/report/ReportActionItemFragment.js b/src/pages/home/report/ReportActionItemFragment.js index fe2308afab27..bdef759d0ed6 100644 --- a/src/pages/home/report/ReportActionItemFragment.js +++ b/src/pages/home/report/ReportActionItemFragment.js @@ -60,7 +60,7 @@ const propTypes = { isThreadParentMessage: PropTypes.bool, /** Should the comment have the appearance of being grouped with the previous comment? */ - displayAsGroup: PropTypes.bool.isRequired, + displayAsGroup: PropTypes.bool, /** Whether the report action type is 'APPROVED' or 'SUBMITTED'. Used to style system messages from Old Dot */ isApprovedOrSubmittedReportAction: PropTypes.bool, @@ -90,6 +90,7 @@ const defaultProps = { isThreadParentMessage: false, isApprovedOrSubmittedReportAction: false, isFragmentContainingDisplayName: false, + displayAsGroup: false, }; function ReportActionItemFragment(props) { diff --git a/src/pages/home/report/ReportActionItemSingle.js b/src/pages/home/report/ReportActionItemSingle.js index 2e1ba0664279..955e024bd7a8 100644 --- a/src/pages/home/report/ReportActionItemSingle.js +++ b/src/pages/home/report/ReportActionItemSingle.js @@ -243,7 +243,6 @@ function ReportActionItemSingle(props) { delegateAccountID={props.action.delegateAccountID} isSingleLine actorIcon={icon} - displayAsGroup={false} /> ))} From b67775ba779c039ef2efd93e45876874d4bfd968 Mon Sep 17 00:00:00 2001 From: Dylan Date: Fri, 10 Nov 2023 17:28:47 +0700 Subject: [PATCH 128/212] re-order field in address page --- src/components/AddressSearch/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/AddressSearch/index.js b/src/components/AddressSearch/index.js index 3e122e029969..f386c7cad96d 100644 --- a/src/components/AddressSearch/index.js +++ b/src/components/AddressSearch/index.js @@ -229,6 +229,7 @@ function AddressSearch(props) { street2: subpremise, // Make sure country is updated first, since city and state will be reset if the country changes country: '', + state: state || stateAutoCompleteFallback, // When locality is not returned, many countries return the city as postalTown (e.g. 5 New Street // Square, London), otherwise as sublocality (e.g. 384 Court Street Brooklyn). If postalTown is // returned, the sublocality will be a city subdivision so shouldn't take precedence (e.g. @@ -236,7 +237,6 @@ function AddressSearch(props) { city: locality || postalTown || sublocality || cityAutocompleteFallback, zipCode, - state: state || stateAutoCompleteFallback, lat: lodashGet(details, 'geometry.location.lat', 0), lng: lodashGet(details, 'geometry.location.lng', 0), address: lodashGet(details, 'formatted_address', ''), From ba75ff99bdef26ff2af65cbb535e4a683f871908 Mon Sep 17 00:00:00 2001 From: tienifr Date: Fri, 10 Nov 2023 18:46:06 +0700 Subject: [PATCH 129/212] fix: 31101 Eye icon to show password on password protected PDF file is not working --- ...ve-web+0.19.9+003+fix-pointer-events.patch | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 patches/react-native-web+0.19.9+003+fix-pointer-events.patch diff --git a/patches/react-native-web+0.19.9+003+fix-pointer-events.patch b/patches/react-native-web+0.19.9+003+fix-pointer-events.patch new file mode 100644 index 000000000000..ac8d16b866ff --- /dev/null +++ b/patches/react-native-web+0.19.9+003+fix-pointer-events.patch @@ -0,0 +1,20 @@ +diff --git a/node_modules/react-native-web/src/exports/StyleSheet/compiler/index.js b/node_modules/react-native-web/src/exports/StyleSheet/compiler/index.js +index 639f532..524c13f 100644 +--- a/node_modules/react-native-web/src/exports/StyleSheet/compiler/index.js ++++ b/node_modules/react-native-web/src/exports/StyleSheet/compiler/index.js +@@ -385,13 +385,14 @@ function createAtomicRules(identifier: string, property, value): Rules { + finalValue = 'auto!important'; + if (value === 'box-only') { + const block = createDeclarationBlock({ pointerEvents: 'none' }); +- rules.push(`${selector}>*${block}`); ++ rules.push(`${selector} *${block}`); + } + } else if (value === 'none' || value === 'box-none') { + finalValue = 'none!important'; + if (value === 'box-none') { + const block = createDeclarationBlock({ pointerEvents: 'auto' }); +- rules.push(`${selector}>*${block}`); ++ rules.push(`${selector} *${block}`); + } + } + const block = createDeclarationBlock({ pointerEvents: finalValue }); From 1e1db5f8d32f4170f2d0532f3e452ea8abb66721 Mon Sep 17 00:00:00 2001 From: pradeepkumar Date: Thu, 2 Nov 2023 08:58:49 +0530 Subject: [PATCH 130/212] load pdf correct path --- src/CONST.ts | 1 + src/components/ReportActionItem/MoneyRequestView.js | 1 + .../ReportActionItem/ReportActionItemImage.js | 12 ++++++++---- src/libs/ReceiptUtils.ts | 7 ++++++- 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/CONST.ts b/src/CONST.ts index 6b9c504555ee..c3bb63d32299 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -1162,6 +1162,7 @@ const CONST = { DOC: 'doc', DOCX: 'docx', SVG: 'svg', + PDF: 'pdf', }, }, diff --git a/src/components/ReportActionItem/MoneyRequestView.js b/src/components/ReportActionItem/MoneyRequestView.js index 4b69f14213a2..ee852d5c146a 100644 --- a/src/components/ReportActionItem/MoneyRequestView.js +++ b/src/components/ReportActionItem/MoneyRequestView.js @@ -170,6 +170,7 @@ function MoneyRequestView({report, betas, parentReport, policyCategories, should diff --git a/src/components/ReportActionItem/ReportActionItemImage.js b/src/components/ReportActionItem/ReportActionItemImage.js index d5f9f7ed06b8..b5711d43abb9 100644 --- a/src/components/ReportActionItem/ReportActionItemImage.js +++ b/src/components/ReportActionItem/ReportActionItemImage.js @@ -18,7 +18,7 @@ import ROUTES from '@src/ROUTES'; const propTypes = { /** thumbnail URI for the image */ - thumbnail: PropTypes.string, + thumbnail: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), /** URI for the image or local numeric reference for the image */ image: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired, @@ -28,12 +28,16 @@ const propTypes = { /* The transaction associated with this image, if any. Passed for handling eReceipts. */ transaction: transactionPropTypes, + + /** whether thumbnail is refer the local file or not */ + isLocalFile: PropTypes.bool, }; const defaultProps = { thumbnail: null, transaction: {}, enablePreviewModal: false, + isLocalFile: false, }; /** @@ -42,7 +46,7 @@ const defaultProps = { * and optional preview modal as well. */ -function ReportActionItemImage({thumbnail, image, enablePreviewModal, transaction}) { +function ReportActionItemImage({thumbnail, image, enablePreviewModal, transaction, isLocalFile}) { const {translate} = useLocalize(); const imageSource = tryResolveUrlFromApiRoot(image || ''); const thumbnailSource = tryResolveUrlFromApiRoot(thumbnail || ''); @@ -56,7 +60,7 @@ function ReportActionItemImage({thumbnail, image, enablePreviewModal, transactio ); - } else if (thumbnail) { + } else if (thumbnail && !isLocalFile) { receiptImageComponent = ( ); diff --git a/src/libs/ReceiptUtils.ts b/src/libs/ReceiptUtils.ts index 5ee177b8f831..26edade89d1c 100644 --- a/src/libs/ReceiptUtils.ts +++ b/src/libs/ReceiptUtils.ts @@ -11,8 +11,9 @@ import * as FileUtils from './fileDownload/FileUtils'; type ThumbnailAndImageURI = { image: ImageSourcePropType | string; - thumbnail: string | null; + thumbnail: ImageSourcePropType | string | null; transaction?: Transaction; + isLocalFile?: boolean; }; type FileNameAndExtension = { @@ -65,6 +66,10 @@ function getThumbnailAndImageURIs(transaction: Transaction, receiptPath: string image = ReceiptSVG; } + if (fileExtension === CONST.IOU.FILE_TYPES.PDF) { + return {thumbnail: image, image: path, isLocalFile: true}; + } + return {thumbnail: null, image}; } From 61c8b1116489f2ea3a9d3cee1007b100611dba6c Mon Sep 17 00:00:00 2001 From: pradeepkumar Date: Wed, 8 Nov 2023 18:22:51 +0530 Subject: [PATCH 131/212] update all types --- src/libs/ReceiptUtils.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/libs/ReceiptUtils.ts b/src/libs/ReceiptUtils.ts index 26edade89d1c..737e5ddc2e31 100644 --- a/src/libs/ReceiptUtils.ts +++ b/src/libs/ReceiptUtils.ts @@ -66,11 +66,7 @@ function getThumbnailAndImageURIs(transaction: Transaction, receiptPath: string image = ReceiptSVG; } - if (fileExtension === CONST.IOU.FILE_TYPES.PDF) { - return {thumbnail: image, image: path, isLocalFile: true}; - } - - return {thumbnail: null, image}; + return {thumbnail: image, image: path, isLocalFile: true}; } // eslint-disable-next-line import/prefer-default-export From 7d28502e2a62b76eddf76c65109782458df7e980 Mon Sep 17 00:00:00 2001 From: pradeepkumar Date: Wed, 8 Nov 2023 19:23:34 +0530 Subject: [PATCH 132/212] remove pdf --- src/CONST.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/CONST.ts b/src/CONST.ts index c3bb63d32299..6b9c504555ee 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -1162,7 +1162,6 @@ const CONST = { DOC: 'doc', DOCX: 'docx', SVG: 'svg', - PDF: 'pdf', }, }, From 24d0843cbcc73d50445cdc1221217f5d36aafe37 Mon Sep 17 00:00:00 2001 From: pradeepkumar Date: Fri, 10 Nov 2023 19:14:35 +0530 Subject: [PATCH 133/212] add is local file field --- src/components/ReportActionItem/ReportActionItemImages.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/ReportActionItem/ReportActionItemImages.js b/src/components/ReportActionItem/ReportActionItemImages.js index e44e27bb7ec0..d9fea9a8ca07 100644 --- a/src/components/ReportActionItem/ReportActionItemImages.js +++ b/src/components/ReportActionItem/ReportActionItemImages.js @@ -74,7 +74,7 @@ function ReportActionItemImages({images, size, total, isHovered}) { return ( - {_.map(shownImages, ({thumbnail, image, transaction}, index) => { + {_.map(shownImages, ({thumbnail, image, transaction, isLocalFile}, index) => { const isLastImage = index === numberOfShownImages - 1; // Show a border to separate multiple images. Shown to the right for each except the last. @@ -88,6 +88,7 @@ function ReportActionItemImages({images, size, total, isHovered}) { {isLastImage && remaining > 0 && ( From ad1ee152612f57dbdfe278dcd11403868cd6cadf Mon Sep 17 00:00:00 2001 From: pradeepkumar Date: Fri, 10 Nov 2023 20:46:04 +0530 Subject: [PATCH 134/212] update props ty;e --- src/components/ReportActionItem/ReportActionItemImages.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ReportActionItem/ReportActionItemImages.js b/src/components/ReportActionItem/ReportActionItemImages.js index d9fea9a8ca07..21d7c5fa3488 100644 --- a/src/components/ReportActionItem/ReportActionItemImages.js +++ b/src/components/ReportActionItem/ReportActionItemImages.js @@ -15,7 +15,7 @@ const propTypes = { /** array of image and thumbnail URIs */ images: PropTypes.arrayOf( PropTypes.shape({ - thumbnail: PropTypes.string, + thumbnail: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), image: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), transaction: transactionPropTypes, }), From 4b76cb55d5adaefb272177d5b47b6f7123ad9faa Mon Sep 17 00:00:00 2001 From: Daniel Edwards Date: Fri, 10 Nov 2023 16:12:59 -0500 Subject: [PATCH 135/212] Moved styles to Pressable and centered SVG better --- src/components/ReceiptEmptyState.js | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/components/ReceiptEmptyState.js b/src/components/ReceiptEmptyState.js index 205dd83dd42d..134124017b83 100644 --- a/src/components/ReceiptEmptyState.js +++ b/src/components/ReceiptEmptyState.js @@ -1,6 +1,5 @@ import PropTypes from 'prop-types'; import React from 'react'; -import {View} from 'react-native'; import styles from '@styles/styles'; import variables from '@styles/variables'; import Icon from './Icon'; @@ -26,15 +25,14 @@ function ReceiptEmptyState({hasError, onPress}) { - - - + ); } From 876557576f3fc462700a79b26ffd21ca4861852f Mon Sep 17 00:00:00 2001 From: Daniel Edwards Date: Fri, 10 Nov 2023 16:15:52 -0500 Subject: [PATCH 136/212] Updated Accessibility prop --- src/components/ReceiptEmptyState.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ReceiptEmptyState.js b/src/components/ReceiptEmptyState.js index 134124017b83..ef2f6a5b62e4 100644 --- a/src/components/ReceiptEmptyState.js +++ b/src/components/ReceiptEmptyState.js @@ -23,7 +23,7 @@ const defaultProps = { function ReceiptEmptyState({hasError, onPress}) { return ( From 3f98313f78b0b6bd842ef4735525aeca145661af Mon Sep 17 00:00:00 2001 From: dukenv0307 Date: Mon, 13 Nov 2023 10:22:32 +0700 Subject: [PATCH 137/212] fix lint --- src/pages/workspace/WorkspaceInitialPage.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/pages/workspace/WorkspaceInitialPage.js b/src/pages/workspace/WorkspaceInitialPage.js index 48483d68e80b..1a568babaff0 100644 --- a/src/pages/workspace/WorkspaceInitialPage.js +++ b/src/pages/workspace/WorkspaceInitialPage.js @@ -16,6 +16,7 @@ import ScreenWrapper from '@components/ScreenWrapper'; import Text from '@components/Text'; import Tooltip from '@components/Tooltip'; import useLocalize from '@hooks/useLocalize'; +import usePrevious from '@hooks/usePrevious'; import useSingleExecution from '@hooks/useSingleExecution'; import useWaitForNavigation from '@hooks/useWaitForNavigation'; import useWindowDimensions from '@hooks/useWindowDimensions'; @@ -223,12 +224,6 @@ function WorkspaceInitialPage(props) { const prevPolicy = usePrevious(policy); - useEffect(() => { - if (PolicyUtils.isPendingDeletePolicy(policy) && !PolicyUtils.isPendingDeletePolicy(prevPolicy)) { - Navigation.goBack(ROUTES.SETTINGS_WORKSPACES); - } - }, [policy, prevPolicy]); - return ( Date: Mon, 13 Nov 2023 10:40:39 +0700 Subject: [PATCH 138/212] rename patch file --- ...ve-web+0.19.9+003+fix-pointer-events.patch | 20 ----------------- ...ve-web+0.19.9+004+fix-pointer-events.patch | 22 +++++++++++++++++++ 2 files changed, 22 insertions(+), 20 deletions(-) delete mode 100644 patches/react-native-web+0.19.9+003+fix-pointer-events.patch create mode 100644 patches/react-native-web+0.19.9+004+fix-pointer-events.patch diff --git a/patches/react-native-web+0.19.9+003+fix-pointer-events.patch b/patches/react-native-web+0.19.9+003+fix-pointer-events.patch deleted file mode 100644 index ac8d16b866ff..000000000000 --- a/patches/react-native-web+0.19.9+003+fix-pointer-events.patch +++ /dev/null @@ -1,20 +0,0 @@ -diff --git a/node_modules/react-native-web/src/exports/StyleSheet/compiler/index.js b/node_modules/react-native-web/src/exports/StyleSheet/compiler/index.js -index 639f532..524c13f 100644 ---- a/node_modules/react-native-web/src/exports/StyleSheet/compiler/index.js -+++ b/node_modules/react-native-web/src/exports/StyleSheet/compiler/index.js -@@ -385,13 +385,14 @@ function createAtomicRules(identifier: string, property, value): Rules { - finalValue = 'auto!important'; - if (value === 'box-only') { - const block = createDeclarationBlock({ pointerEvents: 'none' }); -- rules.push(`${selector}>*${block}`); -+ rules.push(`${selector} *${block}`); - } - } else if (value === 'none' || value === 'box-none') { - finalValue = 'none!important'; - if (value === 'box-none') { - const block = createDeclarationBlock({ pointerEvents: 'auto' }); -- rules.push(`${selector}>*${block}`); -+ rules.push(`${selector} *${block}`); - } - } - const block = createDeclarationBlock({ pointerEvents: finalValue }); diff --git a/patches/react-native-web+0.19.9+004+fix-pointer-events.patch b/patches/react-native-web+0.19.9+004+fix-pointer-events.patch new file mode 100644 index 000000000000..a457fbcfe36c --- /dev/null +++ b/patches/react-native-web+0.19.9+004+fix-pointer-events.patch @@ -0,0 +1,22 @@ +diff --git a/node_modules/react-native-web/dist/exports/StyleSheet/compiler/index.js b/node_modules/react-native-web/dist/exports/StyleSheet/compiler/index.js +index bdcecc2..63f1364 100644 +--- a/node_modules/react-native-web/dist/exports/StyleSheet/compiler/index.js ++++ b/node_modules/react-native-web/dist/exports/StyleSheet/compiler/index.js +@@ -353,7 +353,7 @@ function createAtomicRules(identifier, property, value) { + var _block2 = createDeclarationBlock({ + pointerEvents: 'none' + }); +- rules.push(selector + ">*" + _block2); ++ rules.push(selector + " *" + _block2); + } + } else if (value === 'none' || value === 'box-none') { + finalValue = 'none!important'; +@@ -361,7 +361,7 @@ function createAtomicRules(identifier, property, value) { + var _block3 = createDeclarationBlock({ + pointerEvents: 'auto' + }); +- rules.push(selector + ">*" + _block3); ++ rules.push(selector + " *" + _block3); + } + } + var _block4 = createDeclarationBlock({ From 464dae23ac0900b15fdbea3aafcef6271bec17dd Mon Sep 17 00:00:00 2001 From: dukenv0307 Date: Mon, 13 Nov 2023 11:59:40 +0700 Subject: [PATCH 139/212] update onMouseDown logic --- .../AppleSignIn/index.desktop.js | 2 +- .../AppleSignIn/index.website.js | 4 -- .../GoogleSignIn/index.desktop.js | 2 +- .../GoogleSignIn/index.website.js | 4 +- src/components/SignInButtons/IconButton.js | 7 +--- src/pages/signin/LoginForm/BaseLoginForm.js | 37 +++++++++++-------- 6 files changed, 26 insertions(+), 30 deletions(-) diff --git a/src/components/SignInButtons/AppleSignIn/index.desktop.js b/src/components/SignInButtons/AppleSignIn/index.desktop.js index fac187c6fcc4..c17705110c63 100644 --- a/src/components/SignInButtons/AppleSignIn/index.desktop.js +++ b/src/components/SignInButtons/AppleSignIn/index.desktop.js @@ -19,7 +19,7 @@ function AppleSignIn() { pointerEvents="box-none" > { + onPress={() => { window.open(appleSignInWebRouteForDesktopFlow); }} provider={CONST.SIGN_IN_METHOD.APPLE} diff --git a/src/components/SignInButtons/AppleSignIn/index.website.js b/src/components/SignInButtons/AppleSignIn/index.website.js index f30e06a9bcab..adae0a691e13 100644 --- a/src/components/SignInButtons/AppleSignIn/index.website.js +++ b/src/components/SignInButtons/AppleSignIn/index.website.js @@ -83,7 +83,6 @@ function AppleSignInDiv({isDesktopFlow}) { }, []); return isDesktopFlow ? ( - /* eslint-disable-next-line jsx-a11y/no-static-element-interactions */
event.preventDefault()} /> ) : ( - /* eslint-disable-next-line jsx-a11y/no-static-element-interactions */
event.preventDefault()} /> ); } diff --git a/src/components/SignInButtons/GoogleSignIn/index.desktop.js b/src/components/SignInButtons/GoogleSignIn/index.desktop.js index b2f3cb01a980..e69905dcad05 100644 --- a/src/components/SignInButtons/GoogleSignIn/index.desktop.js +++ b/src/components/SignInButtons/GoogleSignIn/index.desktop.js @@ -19,7 +19,7 @@ function GoogleSignIn() { return ( { + onPress={() => { window.open(googleSignInWebRouteForDesktopFlow); }} provider={CONST.SIGN_IN_METHOD.GOOGLE} diff --git a/src/components/SignInButtons/GoogleSignIn/index.website.js b/src/components/SignInButtons/GoogleSignIn/index.website.js index 33f98efe4568..1ff52c949752 100644 --- a/src/components/SignInButtons/GoogleSignIn/index.website.js +++ b/src/components/SignInButtons/GoogleSignIn/index.website.js @@ -78,7 +78,7 @@ function GoogleSignIn({translate, isDesktopFlow}) { id={desktopId} role={CONST.ACCESSIBILITY_ROLE.BUTTON} aria-label={translate('common.signInWithGoogle')} - onMouseDown={(event) => event.preventDefault()} + // onMouseDown={(event) => event.preventDefault()} /> ) : ( @@ -88,7 +88,7 @@ function GoogleSignIn({translate, isDesktopFlow}) { id={mainId} role={CONST.ACCESSIBILITY_ROLE.BUTTON} aria-label={translate('common.signInWithGoogle')} - onMouseDown={(event) => event.preventDefault()} + // onMouseDown={(event) => event.preventDefault()} /> ); diff --git a/src/components/SignInButtons/IconButton.js b/src/components/SignInButtons/IconButton.js index 95ec49a74621..ce932b875542 100644 --- a/src/components/SignInButtons/IconButton.js +++ b/src/components/SignInButtons/IconButton.js @@ -11,9 +11,6 @@ const propTypes = { /** The on press method */ onPress: PropTypes.func, - /** The on press in method */ - onPressIn: PropTypes.func, - /** Which provider you are using to sign in */ provider: PropTypes.string.isRequired, @@ -22,7 +19,6 @@ const propTypes = { const defaultProps = { onPress: () => {}, - onPressIn: () => {}, }; const providerData = { @@ -36,10 +32,9 @@ const providerData = { }, }; -function IconButton({onPress, translate, provider, onPressIn}) { +function IconButton({onPress, translate, provider}) { return ( { - if (firstBlurred.current) { + if (firstBlurred.current || !Visibility.isVisible() || !Visibility.hasFocus()) { return; } firstBlurred.current = true; @@ -301,22 +302,26 @@ function LoginForm(props) { // for developers about possible regressions, we won't render buttons in development mode. // For more information about these differences and how to test in development mode, // see`Expensify/App/contributingGuides/APPLE_GOOGLE_SIGNIN.md` - CONFIG.ENVIRONMENT !== CONST.ENVIRONMENT.DEV && ( - - - {props.translate('common.signInWith')} - - - - - + CONFIG.ENVIRONMENT !== CONST.ENVIRONMENT.DEV || + (true && ( + + + {props.translate('common.signInWith')} + + + e.preventDefault()} + style={props.isSmallScreenWidth ? styles.loginButtonRowSmallScreen : styles.loginButtonRow} + > + + + - - ) + )) } ) From f3d226113659ea76119cf609ceba241a6cc57d14 Mon Sep 17 00:00:00 2001 From: dukenv0307 Date: Mon, 13 Nov 2023 12:01:23 +0700 Subject: [PATCH 140/212] merge main --- src/components/SignInButtons/AppleSignIn/index.desktop.js | 5 +---- src/components/SignInButtons/GoogleSignIn/index.website.js | 4 ---- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/src/components/SignInButtons/AppleSignIn/index.desktop.js b/src/components/SignInButtons/AppleSignIn/index.desktop.js index c17705110c63..cad37d585de4 100644 --- a/src/components/SignInButtons/AppleSignIn/index.desktop.js +++ b/src/components/SignInButtons/AppleSignIn/index.desktop.js @@ -14,10 +14,7 @@ const appleSignInWebRouteForDesktopFlow = `${CONFIG.EXPENSIFY.NEW_EXPENSIFY_URL} */ function AppleSignIn() { return ( - + { window.open(appleSignInWebRouteForDesktopFlow); diff --git a/src/components/SignInButtons/GoogleSignIn/index.website.js b/src/components/SignInButtons/GoogleSignIn/index.website.js index 1ff52c949752..d65af124bfe8 100644 --- a/src/components/SignInButtons/GoogleSignIn/index.website.js +++ b/src/components/SignInButtons/GoogleSignIn/index.website.js @@ -73,22 +73,18 @@ function GoogleSignIn({translate, isDesktopFlow}) { // ref: https://stackoverflow.com/questions/75306089/safari-when-using-border-radius-and-overflow-hidden-to-parent-and-the-child-th return isDesktopFlow ? ( - {/* eslint-disable-next-line jsx-a11y/interactive-supports-focus */}
event.preventDefault()} /> ) : ( - {/* eslint-disable-next-line jsx-a11y/interactive-supports-focus */}
event.preventDefault()} /> ); From b588fbbcc5eaf706ec2e4709cdbca0f2c8764093 Mon Sep 17 00:00:00 2001 From: dukenv0307 Date: Mon, 13 Nov 2023 14:38:54 +0700 Subject: [PATCH 141/212] revert hard code --- src/pages/signin/LoginForm/BaseLoginForm.js | 37 ++++++++++----------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/src/pages/signin/LoginForm/BaseLoginForm.js b/src/pages/signin/LoginForm/BaseLoginForm.js index 9a862273f89e..2576401d06a7 100644 --- a/src/pages/signin/LoginForm/BaseLoginForm.js +++ b/src/pages/signin/LoginForm/BaseLoginForm.js @@ -302,26 +302,25 @@ function LoginForm(props) { // for developers about possible regressions, we won't render buttons in development mode. // For more information about these differences and how to test in development mode, // see`Expensify/App/contributingGuides/APPLE_GOOGLE_SIGNIN.md` - CONFIG.ENVIRONMENT !== CONST.ENVIRONMENT.DEV || - (true && ( - - - {props.translate('common.signInWith')} - - - e.preventDefault()} - style={props.isSmallScreenWidth ? styles.loginButtonRowSmallScreen : styles.loginButtonRow} - > - - - + CONFIG.ENVIRONMENT !== CONST.ENVIRONMENT.DEV && ( + + + {props.translate('common.signInWith')} + + + e.preventDefault()} + style={props.isSmallScreenWidth ? styles.loginButtonRowSmallScreen : styles.loginButtonRow} + > + + - )) + + ) } ) From 20e80d13a434ac8bc2876394a92cf3c54f557e3a Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Mon, 13 Nov 2023 09:28:17 +0100 Subject: [PATCH 142/212] destructure props in Modal --- src/components/Modal/index.ios.tsx | 6 +++--- src/components/Modal/index.tsx | 17 +++++++++-------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/components/Modal/index.ios.tsx b/src/components/Modal/index.ios.tsx index 6952392a6326..f780775ec216 100644 --- a/src/components/Modal/index.ios.tsx +++ b/src/components/Modal/index.ios.tsx @@ -3,13 +3,13 @@ import withWindowDimensions from '@components/withWindowDimensions'; import BaseModal from './BaseModal'; import BaseModalProps from './types'; -function Modal(props: BaseModalProps) { +function Modal({children, ...rest}: BaseModalProps) { return ( - {props.children} + {children} ); } diff --git a/src/components/Modal/index.tsx b/src/components/Modal/index.tsx index 3d8a30ba3e2a..a3d21d67b9af 100644 --- a/src/components/Modal/index.tsx +++ b/src/components/Modal/index.tsx @@ -7,11 +7,11 @@ import CONST from '@src/CONST'; import BaseModal from './BaseModal'; import BaseModalProps from './types'; -function Modal(props: BaseModalProps) { +function Modal({fullscreen, onModalHide, type, onModalShow, children, ...rest}: BaseModalProps) { const [previousStatusBarColor, setPreviousStatusBarColor] = useState(); const setStatusBarColor = (color = themeColors.appBG) => { - if (!props.fullscreen) { + if (!fullscreen) { return; } @@ -20,14 +20,13 @@ function Modal(props: BaseModalProps) { const hideModal = () => { setStatusBarColor(previousStatusBarColor); - props.onModalHide(); + onModalHide(); }; const showModal = () => { const statusBarColor = StatusBar.getBackgroundColor(); - const isFullScreenModal = - props.type === CONST.MODAL.MODAL_TYPE.CENTERED || props.type === CONST.MODAL.MODAL_TYPE.CENTERED_UNSWIPEABLE || props.type === CONST.MODAL.MODAL_TYPE.RIGHT_DOCKED; + const isFullScreenModal = type === CONST.MODAL.MODAL_TYPE.CENTERED || type === CONST.MODAL.MODAL_TYPE.CENTERED_UNSWIPEABLE || type === CONST.MODAL.MODAL_TYPE.RIGHT_DOCKED; if (statusBarColor) { setPreviousStatusBarColor(statusBarColor); @@ -35,18 +34,20 @@ function Modal(props: BaseModalProps) { setStatusBarColor(isFullScreenModal ? themeColors.appBG : StyleUtils.getThemeBackgroundColor(statusBarColor)); } - props.onModalShow?.(); + onModalShow?.(); }; return ( - {props.children} + {children} ); } From 633606e09b3b7809ae48938b8c853b145e923b95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20Henriques?= Date: Mon, 13 Nov 2023 06:28:22 -0300 Subject: [PATCH 143/212] Rename file to TS --- src/components/{Badge.js => Badge.tsx} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/components/{Badge.js => Badge.tsx} (100%) diff --git a/src/components/Badge.js b/src/components/Badge.tsx similarity index 100% rename from src/components/Badge.js rename to src/components/Badge.tsx From a5d22486c58d0b31a2808edb74e4383a3d7b08c4 Mon Sep 17 00:00:00 2001 From: Viktoryia Kliushun Date: Mon, 13 Nov 2023 11:41:31 +0100 Subject: [PATCH 144/212] Remove extra params from Report type --- src/types/onyx/Report.ts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/types/onyx/Report.ts b/src/types/onyx/Report.ts index 5b6480dfb2e1..4c37a87436eb 100644 --- a/src/types/onyx/Report.ts +++ b/src/types/onyx/Report.ts @@ -63,12 +63,6 @@ type Report = { /** PayPalMe address of the submitter */ submitterPayPalMeAddress?: string; - /** The email address of the report owner */ - ownerEmail?: string; - - /** The email address of the manager */ - managerEmail?: string; - /** Linked policy's ID */ policyID?: string; From 38aa4fecfe4790f3fa23a2ad2113fc18453c64d7 Mon Sep 17 00:00:00 2001 From: dukenv0307 Date: Mon, 13 Nov 2023 17:42:26 +0700 Subject: [PATCH 145/212] add comment --- src/components/AvatarSkeleton.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/AvatarSkeleton.js b/src/components/AvatarSkeleton.js index 3bd940e13078..5c22643aff97 100644 --- a/src/components/AvatarSkeleton.js +++ b/src/components/AvatarSkeleton.js @@ -5,7 +5,7 @@ import themeColors from '@styles/themes/default'; import SkeletonViewContentLoader from './SkeletonViewContentLoader'; const propTypes = { - /** */ + /** Whether enable animtaion */ shouldAnimate: PropTypes.bool, }; From 6c7368eacb7d30edc8d8c3d813efe30c349c0293 Mon Sep 17 00:00:00 2001 From: dukenv0307 Date: Mon, 13 Nov 2023 17:46:36 +0700 Subject: [PATCH 146/212] remove prop --- src/components/AvatarSkeleton.js | 16 ++-------------- src/components/AvatarWithIndicator.js | 6 +++--- 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/src/components/AvatarSkeleton.js b/src/components/AvatarSkeleton.js index 5c22643aff97..2a633833f228 100644 --- a/src/components/AvatarSkeleton.js +++ b/src/components/AvatarSkeleton.js @@ -1,22 +1,12 @@ -import PropTypes from 'prop-types'; import React from 'react'; import {Circle} from 'react-native-svg'; import themeColors from '@styles/themes/default'; import SkeletonViewContentLoader from './SkeletonViewContentLoader'; -const propTypes = { - /** Whether enable animtaion */ - shouldAnimate: PropTypes.bool, -}; - -const defaultTypes = { - shouldAnimate: true, -}; - -function AvatarSkeleton(props) { +function AvatarSkeleton() { return ( - {!props.isLoading ? ( + {props.isLoading ? ( + + ) : ( <> - ) : ( - )} From fa04a3f7702418dc816397a78ba48c155cf0ac91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20Henriques?= Date: Mon, 13 Nov 2023 09:33:41 -0300 Subject: [PATCH 147/212] Migrate file to TS --- src/components/Badge.tsx | 62 ++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 37 deletions(-) diff --git a/src/components/Badge.tsx b/src/components/Badge.tsx index 49b330ae37b2..8a0fea75f99a 100644 --- a/src/components/Badge.tsx +++ b/src/components/Badge.tsx @@ -1,79 +1,67 @@ -import PropTypes from 'prop-types'; import React from 'react'; -import {View} from 'react-native'; +import {GestureResponderEvent, PressableStateCallbackType, StyleProp, TextStyle, View, ViewStyle} from 'react-native'; import styles from '@styles/styles'; import * as StyleUtils from '@styles/StyleUtils'; import CONST from '@src/CONST'; import PressableWithoutFeedback from './Pressable/PressableWithoutFeedback'; import Text from './Text'; -const propTypes = { +type BadgeProps = { /** Is Success type */ - success: PropTypes.bool, + success?: boolean; /** Is Error type */ - error: PropTypes.bool, + error?: boolean; /** Whether badge is clickable */ - pressable: PropTypes.bool, + pressable?: boolean; /** Text to display in the Badge */ - text: PropTypes.string.isRequired, + text: string; /** Text to display in the Badge */ - environment: PropTypes.string, + environment?: string; /** Styles for Badge */ - // eslint-disable-next-line react/forbid-prop-types - badgeStyles: PropTypes.arrayOf(PropTypes.object), + badgeStyles?: StyleProp; /** Styles for Badge Text */ - // eslint-disable-next-line react/forbid-prop-types - textStyles: PropTypes.arrayOf(PropTypes.object), + textStyles?: StyleProp; /** Callback to be called on onPress */ - onPress: PropTypes.func, + onPress: (event?: GestureResponderEvent | KeyboardEvent) => void; }; -const defaultProps = { - success: false, - error: false, - pressable: false, - badgeStyles: [], - textStyles: [], - onPress: undefined, - environment: CONST.ENVIRONMENT.DEV, -}; +function Badge({success = false, error = false, pressable = false, text, environment = CONST.ENVIRONMENT.DEV, badgeStyles, textStyles, onPress = () => {}}: BadgeProps) { + const textColorStyles = success || error ? styles.textWhite : undefined; + const Wrapper = pressable ? PressableWithoutFeedback : View; -function Badge(props) { - const textStyles = props.success || props.error ? styles.textWhite : undefined; - const Wrapper = props.pressable ? PressableWithoutFeedback : View; - const wrapperStyles = ({pressed}) => [ + const wrapperStyles: (state: PressableStateCallbackType) => StyleProp = ({pressed}) => [ styles.badge, styles.ml2, - StyleUtils.getBadgeColorStyle(props.success, props.error, pressed, props.environment === CONST.ENVIRONMENT.ADHOC), - ...props.badgeStyles, + StyleUtils.getBadgeColorStyle(success, error, pressed, environment === CONST.ENVIRONMENT.ADHOC), + badgeStyles, ]; return ( - {props.text} + {text} ); } Badge.displayName = 'Badge'; -Badge.propTypes = propTypes; -Badge.defaultProps = defaultProps; + export default Badge; From 95d237b608b6bd9b5f50f9b9c221615602bbfaf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20Henriques?= Date: Mon, 13 Nov 2023 09:51:51 -0300 Subject: [PATCH 148/212] Add useCallback --- src/components/Badge.tsx | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/components/Badge.tsx b/src/components/Badge.tsx index 8a0fea75f99a..2ccd41575073 100644 --- a/src/components/Badge.tsx +++ b/src/components/Badge.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, {useCallback} from 'react'; import {GestureResponderEvent, PressableStateCallbackType, StyleProp, TextStyle, View, ViewStyle} from 'react-native'; import styles from '@styles/styles'; import * as StyleUtils from '@styles/StyleUtils'; @@ -36,12 +36,10 @@ function Badge({success = false, error = false, pressable = false, text, environ const textColorStyles = success || error ? styles.textWhite : undefined; const Wrapper = pressable ? PressableWithoutFeedback : View; - const wrapperStyles: (state: PressableStateCallbackType) => StyleProp = ({pressed}) => [ - styles.badge, - styles.ml2, - StyleUtils.getBadgeColorStyle(success, error, pressed, environment === CONST.ENVIRONMENT.ADHOC), - badgeStyles, - ]; + const wrapperStyles: (state: PressableStateCallbackType) => StyleProp = useCallback( + ({pressed}) => [styles.badge, styles.ml2, StyleUtils.getBadgeColorStyle(success, error, pressed, environment === CONST.ENVIRONMENT.ADHOC), badgeStyles], + [success, error, environment, badgeStyles], + ); return ( Date: Mon, 13 Nov 2023 14:26:27 +0100 Subject: [PATCH 149/212] update for undefined state Co-authored-by: Monil Bhavsar --- src/components/MentionSuggestions.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/MentionSuggestions.tsx b/src/components/MentionSuggestions.tsx index a009364c2223..2d0f3bf32b41 100644 --- a/src/components/MentionSuggestions.tsx +++ b/src/components/MentionSuggestions.tsx @@ -73,7 +73,7 @@ function MentionSuggestions({prefix, mentions, highlightedMentionIndex = 0, onSe style={[styles.mentionSuggestionsText, styles.flexShrink1]} numberOfLines={1} > - {styledDisplayName.map(({text, isColored}, i) => ( + {styledDisplayName?.map(({text, isColored}, i) => ( Date: Mon, 13 Nov 2023 21:54:15 +0700 Subject: [PATCH 150/212] fix not blured --- src/pages/signin/LoginForm/BaseLoginForm.js | 38 +++++++++++---------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/src/pages/signin/LoginForm/BaseLoginForm.js b/src/pages/signin/LoginForm/BaseLoginForm.js index 2576401d06a7..bdac88d7e420 100644 --- a/src/pages/signin/LoginForm/BaseLoginForm.js +++ b/src/pages/signin/LoginForm/BaseLoginForm.js @@ -302,25 +302,27 @@ function LoginForm(props) { // for developers about possible regressions, we won't render buttons in development mode. // For more information about these differences and how to test in development mode, // see`Expensify/App/contributingGuides/APPLE_GOOGLE_SIGNIN.md` - CONFIG.ENVIRONMENT !== CONST.ENVIRONMENT.DEV && ( - - - {props.translate('common.signInWith')} - - - e.preventDefault()} - style={props.isSmallScreenWidth ? styles.loginButtonRowSmallScreen : styles.loginButtonRow} - > - - + CONFIG.ENVIRONMENT !== CONST.ENVIRONMENT.DEV || + (true && ( + + + {props.translate('common.signInWith')} + + + + e.preventDefault()}> + + + e.preventDefault()}> + + + - - ) + )) } ) From b5ef9c25f55037ba093287441943845b9079e296 Mon Sep 17 00:00:00 2001 From: Viktoryia Kliushun Date: Mon, 13 Nov 2023 15:57:14 +0100 Subject: [PATCH 151/212] [TS migration] Migrate 'DragAndDrop' component --- .../Consumer/dragAndDropConsumerPropTypes.js | 9 ------- .../{index.native.js => index.native.tsx} | 3 --- .../Consumer/{index.js => index.tsx} | 7 +++-- src/components/DragAndDrop/Consumer/types.ts | 11 ++++++++ .../DragAndDrop/NoDropZone/index.native.js | 5 ---- .../DragAndDrop/NoDropZone/index.native.tsx | 7 +++++ .../NoDropZone/{index.js => index.tsx} | 14 ++++------ .../DragAndDrop/NoDropZone/types.ts | 8 ++++++ .../Provider/dragAndDropProviderPropTypes.js | 12 --------- .../DragAndDrop/Provider/index.native.js | 13 --------- .../DragAndDrop/Provider/index.native.tsx | 12 +++++++++ .../Provider/{index.js => index.tsx} | 25 +++++++---------- src/components/DragAndDrop/Provider/types.ts | 27 +++++++++++++++++++ src/hooks/useDragAndDrop.ts | 9 ++++--- 14 files changed, 88 insertions(+), 74 deletions(-) delete mode 100644 src/components/DragAndDrop/Consumer/dragAndDropConsumerPropTypes.js rename src/components/DragAndDrop/Consumer/{index.native.js => index.native.tsx} (51%) rename src/components/DragAndDrop/Consumer/{index.js => index.tsx} (70%) create mode 100644 src/components/DragAndDrop/Consumer/types.ts delete mode 100644 src/components/DragAndDrop/NoDropZone/index.native.js create mode 100644 src/components/DragAndDrop/NoDropZone/index.native.tsx rename src/components/DragAndDrop/NoDropZone/{index.js => index.tsx} (61%) create mode 100644 src/components/DragAndDrop/NoDropZone/types.ts delete mode 100644 src/components/DragAndDrop/Provider/dragAndDropProviderPropTypes.js delete mode 100644 src/components/DragAndDrop/Provider/index.native.js create mode 100644 src/components/DragAndDrop/Provider/index.native.tsx rename src/components/DragAndDrop/Provider/{index.js => index.tsx} (71%) create mode 100644 src/components/DragAndDrop/Provider/types.ts diff --git a/src/components/DragAndDrop/Consumer/dragAndDropConsumerPropTypes.js b/src/components/DragAndDrop/Consumer/dragAndDropConsumerPropTypes.js deleted file mode 100644 index 66f8ed996e2e..000000000000 --- a/src/components/DragAndDrop/Consumer/dragAndDropConsumerPropTypes.js +++ /dev/null @@ -1,9 +0,0 @@ -import PropTypes from 'prop-types'; - -export default { - /** Children to render inside this component. */ - children: PropTypes.node.isRequired, - - /** Function to execute when an item is dropped in the drop zone. */ - onDrop: PropTypes.func.isRequired, -}; diff --git a/src/components/DragAndDrop/Consumer/index.native.js b/src/components/DragAndDrop/Consumer/index.native.tsx similarity index 51% rename from src/components/DragAndDrop/Consumer/index.native.js rename to src/components/DragAndDrop/Consumer/index.native.tsx index ff9825ffac97..99706a73fe19 100644 --- a/src/components/DragAndDrop/Consumer/index.native.js +++ b/src/components/DragAndDrop/Consumer/index.native.tsx @@ -1,10 +1,7 @@ -import dragAndDropConsumerPropTypes from './dragAndDropConsumerPropTypes'; - function DragAndDropConsumer() { return null; } -DragAndDropConsumer.propTypes = dragAndDropConsumerPropTypes; DragAndDropConsumer.displayName = 'DragAndDropConsumer'; export default DragAndDropConsumer; diff --git a/src/components/DragAndDrop/Consumer/index.js b/src/components/DragAndDrop/Consumer/index.tsx similarity index 70% rename from src/components/DragAndDrop/Consumer/index.js rename to src/components/DragAndDrop/Consumer/index.tsx index 5c9f16bc0bed..7cd557608450 100644 --- a/src/components/DragAndDrop/Consumer/index.js +++ b/src/components/DragAndDrop/Consumer/index.tsx @@ -1,13 +1,13 @@ import {Portal} from '@gorhom/portal'; import React, {useContext, useEffect} from 'react'; import {DragAndDropContext} from '@components/DragAndDrop/Provider'; -import dragAndDropConsumerPropTypes from './dragAndDropConsumerPropTypes'; +import type DragAndDropConsumerProps from './types'; -function DragAndDropConsumer({children, onDrop}) { +function DragAndDropConsumer({children, onDrop}: DragAndDropConsumerProps) { const {isDraggingOver, setOnDropHandler, dropZoneID} = useContext(DragAndDropContext); useEffect(() => { - setOnDropHandler(onDrop); + setOnDropHandler?.(onDrop); }, [onDrop, setOnDropHandler]); if (!isDraggingOver) { @@ -17,7 +17,6 @@ function DragAndDropConsumer({children, onDrop}) { return {children}; } -DragAndDropConsumer.propTypes = dragAndDropConsumerPropTypes; DragAndDropConsumer.displayName = 'DragAndDropConsumer'; export default DragAndDropConsumer; diff --git a/src/components/DragAndDrop/Consumer/types.ts b/src/components/DragAndDrop/Consumer/types.ts new file mode 100644 index 000000000000..1f85f32a0153 --- /dev/null +++ b/src/components/DragAndDrop/Consumer/types.ts @@ -0,0 +1,11 @@ +import {ReactNode} from 'react'; + +type DragAndDropConsumerProps = { + /** Children to render inside this component. */ + children: ReactNode; + + /** Function to execute when an item is dropped in the drop zone. */ + onDrop: (event: DragEvent) => void; +}; + +export default DragAndDropConsumerProps; diff --git a/src/components/DragAndDrop/NoDropZone/index.native.js b/src/components/DragAndDrop/NoDropZone/index.native.js deleted file mode 100644 index c091ce4b6597..000000000000 --- a/src/components/DragAndDrop/NoDropZone/index.native.js +++ /dev/null @@ -1,5 +0,0 @@ -const NoDropZone = (props) => props.children; - -NoDropZone.displayName = 'NoDropZone'; - -export default NoDropZone; diff --git a/src/components/DragAndDrop/NoDropZone/index.native.tsx b/src/components/DragAndDrop/NoDropZone/index.native.tsx new file mode 100644 index 000000000000..16766328c625 --- /dev/null +++ b/src/components/DragAndDrop/NoDropZone/index.native.tsx @@ -0,0 +1,7 @@ +import type NoDropZoneProps from './types'; + +const NoDropZone = (props: NoDropZoneProps) => props.children; + +NoDropZone.displayName = 'NoDropZone'; + +export default NoDropZone; diff --git a/src/components/DragAndDrop/NoDropZone/index.js b/src/components/DragAndDrop/NoDropZone/index.tsx similarity index 61% rename from src/components/DragAndDrop/NoDropZone/index.js rename to src/components/DragAndDrop/NoDropZone/index.tsx index ac5b759dee63..5c914b646e0c 100644 --- a/src/components/DragAndDrop/NoDropZone/index.js +++ b/src/components/DragAndDrop/NoDropZone/index.tsx @@ -1,23 +1,20 @@ -import PropTypes from 'prop-types'; import React, {useRef} from 'react'; import {View} from 'react-native'; import useDragAndDrop from '@hooks/useDragAndDrop'; import styles from '@styles/styles'; +import type NoDropZoneProps from './types'; -const propTypes = { - /** Content */ - children: PropTypes.node.isRequired, -}; +function NoDropZone({children}: NoDropZoneProps) { + const noDropZone = useRef(null); -function NoDropZone({children}) { - const noDropZone = useRef(null); useDragAndDrop({ dropZone: noDropZone, shouldAllowDrop: false, }); + return ( (noDropZone.current = e)} + ref={noDropZone} style={[styles.fullScreen]} > {children} @@ -26,6 +23,5 @@ function NoDropZone({children}) { } NoDropZone.displayName = 'NoDropZone'; -NoDropZone.propTypes = propTypes; export default NoDropZone; diff --git a/src/components/DragAndDrop/NoDropZone/types.ts b/src/components/DragAndDrop/NoDropZone/types.ts new file mode 100644 index 000000000000..09715ecd942f --- /dev/null +++ b/src/components/DragAndDrop/NoDropZone/types.ts @@ -0,0 +1,8 @@ +import {ReactNode} from 'react'; + +type NoDropZoneProps = { + /** Content */ + children: ReactNode; +}; + +export default NoDropZoneProps; diff --git a/src/components/DragAndDrop/Provider/dragAndDropProviderPropTypes.js b/src/components/DragAndDrop/Provider/dragAndDropProviderPropTypes.js deleted file mode 100644 index 82e503456f7d..000000000000 --- a/src/components/DragAndDrop/Provider/dragAndDropProviderPropTypes.js +++ /dev/null @@ -1,12 +0,0 @@ -import PropTypes from 'prop-types'; - -export default { - /** Children to render inside this component. */ - children: PropTypes.node.isRequired, - - /** Should this dropZone be disabled? */ - isDisabled: PropTypes.bool, - - /** Indicate that users are dragging file or not */ - setIsDraggingOver: PropTypes.func, -}; diff --git a/src/components/DragAndDrop/Provider/index.native.js b/src/components/DragAndDrop/Provider/index.native.js deleted file mode 100644 index 4dac66912531..000000000000 --- a/src/components/DragAndDrop/Provider/index.native.js +++ /dev/null @@ -1,13 +0,0 @@ -import dragAndDropProviderPropTypes from './dragAndDropProviderPropTypes'; - -const DragAndDropContext = {}; - -function DragAndDropProvider({children}) { - return children; -} - -DragAndDropProvider.propTypes = dragAndDropProviderPropTypes; -DragAndDropProvider.displayName = 'DragAndDropProvider'; - -export default DragAndDropProvider; -export {DragAndDropContext}; diff --git a/src/components/DragAndDrop/Provider/index.native.tsx b/src/components/DragAndDrop/Provider/index.native.tsx new file mode 100644 index 000000000000..ba32599c62b5 --- /dev/null +++ b/src/components/DragAndDrop/Provider/index.native.tsx @@ -0,0 +1,12 @@ +import type {DragAndDropContextParams, DragAndDropProviderProps} from './types'; + +const DragAndDropContext: DragAndDropContextParams = {}; + +function DragAndDropProvider({children}: DragAndDropProviderProps) { + return children; +} + +DragAndDropProvider.displayName = 'DragAndDropProvider'; + +export default DragAndDropProvider; +export {DragAndDropContext}; diff --git a/src/components/DragAndDrop/Provider/index.js b/src/components/DragAndDrop/Provider/index.tsx similarity index 71% rename from src/components/DragAndDrop/Provider/index.js rename to src/components/DragAndDrop/Provider/index.tsx index c31b83a7d605..fbf9ffd30e80 100644 --- a/src/components/DragAndDrop/Provider/index.js +++ b/src/components/DragAndDrop/Provider/index.tsx @@ -2,27 +2,22 @@ import {PortalHost} from '@gorhom/portal'; import Str from 'expensify-common/lib/str'; import React, {useCallback, useEffect, useMemo, useRef} from 'react'; import {View} from 'react-native'; -import _ from 'underscore'; import useDragAndDrop from '@hooks/useDragAndDrop'; import styles from '@styles/styles'; -import dragAndDropProviderPropTypes from './dragAndDropProviderPropTypes'; +import type {DragAndDropContextParams, DragAndDropProviderProps, SetOnDropHandlerCallback} from './types'; -const DragAndDropContext = React.createContext({}); +const DragAndDropContext = React.createContext({}); -/** - * @param {Event} event – drag event - * @returns {Boolean} - */ -function shouldAcceptDrop(event) { - return _.some(event.dataTransfer.types, (type) => type === 'Files'); +function shouldAcceptDrop(event: DragEvent): boolean { + return !!event.dataTransfer?.types.some((type) => type === 'Files'); } -function DragAndDropProvider({children, isDisabled = false, setIsDraggingOver = () => {}}) { - const dropZone = useRef(null); +function DragAndDropProvider({children, isDisabled = false, setIsDraggingOver = () => {}}: DragAndDropProviderProps) { + const dropZone = useRef(null); const dropZoneID = useRef(Str.guid('drag-n-drop')); - const onDropHandler = useRef(() => {}); - const setOnDropHandler = useCallback((callback) => { + const onDropHandler = useRef(() => {}); + const setOnDropHandler = useCallback((callback: SetOnDropHandlerCallback) => { onDropHandler.current = callback; }, []); @@ -38,10 +33,11 @@ function DragAndDropProvider({children, isDisabled = false, setIsDraggingOver = }, [isDraggingOver, setIsDraggingOver]); const contextValue = useMemo(() => ({isDraggingOver, setOnDropHandler, dropZoneID: dropZoneID.current}), [isDraggingOver, setOnDropHandler]); + return ( (dropZone.current = e)} + ref={dropZone} style={[styles.flex1, styles.w100, styles.h100]} > {isDraggingOver && ( @@ -55,7 +51,6 @@ function DragAndDropProvider({children, isDisabled = false, setIsDraggingOver = ); } -DragAndDropProvider.propTypes = dragAndDropProviderPropTypes; DragAndDropProvider.displayName = 'DragAndDropProvider'; export default DragAndDropProvider; diff --git a/src/components/DragAndDrop/Provider/types.ts b/src/components/DragAndDrop/Provider/types.ts new file mode 100644 index 000000000000..eae83d10682a --- /dev/null +++ b/src/components/DragAndDrop/Provider/types.ts @@ -0,0 +1,27 @@ +import {ReactNode} from 'react'; + +type DragAndDropProviderProps = { + /** Children to render inside this component. */ + children: ReactNode; + + /** Should this dropZone be disabled? */ + isDisabled?: boolean; + + /** Indicate that users are dragging file or not */ + setIsDraggingOver: (value: boolean) => void; +}; + +type SetOnDropHandlerCallback = (event: DragEvent) => void; + +type DragAndDropContextParams = { + /** Whether something is dragging over a drop zone. */ + isDraggingOver?: boolean; + + /** Execute callback when an item is dropped in the drop zone. */ + setOnDropHandler?: (callback: SetOnDropHandlerCallback) => void; + + /** Drop zone id. */ + dropZoneID?: string; +}; + +export type {DragAndDropProviderProps, DragAndDropContextParams, SetOnDropHandlerCallback}; diff --git a/src/hooks/useDragAndDrop.ts b/src/hooks/useDragAndDrop.ts index 3f0142492d0d..c34b32db6425 100644 --- a/src/hooks/useDragAndDrop.ts +++ b/src/hooks/useDragAndDrop.ts @@ -1,5 +1,6 @@ import {useIsFocused} from '@react-navigation/native'; import React, {useCallback, useEffect, useRef, useState} from 'react'; +import {View} from 'react-native'; const COPY_DROP_EFFECT = 'copy'; const NONE_DROP_EFFECT = 'none'; @@ -9,11 +10,11 @@ const DRAG_LEAVE_EVENT = 'dragleave'; const DROP_EVENT = 'drop'; type DragAndDropParams = { - dropZone: React.MutableRefObject; - onDrop?: (event?: DragEvent) => void; + dropZone: React.MutableRefObject; + onDrop?: (event: DragEvent) => void; shouldAllowDrop?: boolean; isDisabled?: boolean; - shouldAcceptDrop?: (event?: DragEvent) => boolean; + shouldAcceptDrop?: (event: DragEvent) => boolean; }; type DragAndDropOptions = { @@ -105,7 +106,7 @@ export default function useDragAndDrop({dropZone, onDrop = () => {}, shouldAllow return; } - const dropZoneRef = dropZone.current; + const dropZoneRef = dropZone.current as HTMLDivElement; // Note that the dragover event needs to be called with `event.preventDefault` in order for the drop event to be fired: // https://stackoverflow.com/questions/21339924/drop-event-not-firing-in-chrome From 5671583543da6d0a4d62cf728c61ebf720534060 Mon Sep 17 00:00:00 2001 From: dukenv0307 Date: Mon, 13 Nov 2023 21:57:26 +0700 Subject: [PATCH 152/212] revert hard code --- src/pages/signin/LoginForm/BaseLoginForm.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/pages/signin/LoginForm/BaseLoginForm.js b/src/pages/signin/LoginForm/BaseLoginForm.js index bdac88d7e420..632419fd4293 100644 --- a/src/pages/signin/LoginForm/BaseLoginForm.js +++ b/src/pages/signin/LoginForm/BaseLoginForm.js @@ -302,8 +302,7 @@ function LoginForm(props) { // for developers about possible regressions, we won't render buttons in development mode. // For more information about these differences and how to test in development mode, // see`Expensify/App/contributingGuides/APPLE_GOOGLE_SIGNIN.md` - CONFIG.ENVIRONMENT !== CONST.ENVIRONMENT.DEV || - (true && ( + CONFIG.ENVIRONMENT !== CONST.ENVIRONMENT.DEV && ( - )) + ) } ) From 0a5f8974d6c69b9e4255cb48df17b87a102e724e Mon Sep 17 00:00:00 2001 From: Viktoryia Kliushun Date: Mon, 13 Nov 2023 16:01:51 +0100 Subject: [PATCH 153/212] Destructure props for NoDropZone component --- src/components/DragAndDrop/NoDropZone/index.native.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/DragAndDrop/NoDropZone/index.native.tsx b/src/components/DragAndDrop/NoDropZone/index.native.tsx index 16766328c625..bf5d18e3bad4 100644 --- a/src/components/DragAndDrop/NoDropZone/index.native.tsx +++ b/src/components/DragAndDrop/NoDropZone/index.native.tsx @@ -1,6 +1,6 @@ import type NoDropZoneProps from './types'; -const NoDropZone = (props: NoDropZoneProps) => props.children; +const NoDropZone = ({children}: NoDropZoneProps) => children; NoDropZone.displayName = 'NoDropZone'; From 57031a6bd243218ed08931826b811a6db85a9966 Mon Sep 17 00:00:00 2001 From: dukenv0307 Date: Mon, 13 Nov 2023 22:05:36 +0700 Subject: [PATCH 154/212] fix lint --- src/pages/signin/LoginForm/BaseLoginForm.js | 34 ++++++++++----------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/pages/signin/LoginForm/BaseLoginForm.js b/src/pages/signin/LoginForm/BaseLoginForm.js index 632419fd4293..9cd620cf8f12 100644 --- a/src/pages/signin/LoginForm/BaseLoginForm.js +++ b/src/pages/signin/LoginForm/BaseLoginForm.js @@ -303,25 +303,25 @@ function LoginForm(props) { // For more information about these differences and how to test in development mode, // see`Expensify/App/contributingGuides/APPLE_GOOGLE_SIGNIN.md` CONFIG.ENVIRONMENT !== CONST.ENVIRONMENT.DEV && ( - - - {props.translate('common.signInWith')} - - - - e.preventDefault()}> - - - e.preventDefault()}> - - + + + {props.translate('common.signInWith')} + + + + e.preventDefault()}> + + + e.preventDefault()}> + - ) + + ) } ) From 5f77ea718239d74398ee5899cf42112ca415fb5d Mon Sep 17 00:00:00 2001 From: c3024 Date: Mon, 13 Nov 2023 20:51:47 +0530 Subject: [PATCH 155/212] fix 30166 --- src/components/TagPicker/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/TagPicker/index.js b/src/components/TagPicker/index.js index 65aa71c7ac06..546898afde8e 100644 --- a/src/components/TagPicker/index.js +++ b/src/components/TagPicker/index.js @@ -53,7 +53,7 @@ function TagPicker({selectedTag, tag, policyTags, policyRecentlyUsedTags, onSubm [searchValue, selectedOptions, policyTagList, policyRecentlyUsedTagsList], ); - const headerMessage = OptionsListUtils.getHeaderMessageForNonUserList(lodashGet(sections, '[0].data.length', 0) > 0, ''); + const headerMessage = OptionsListUtils.getHeaderMessageForNonUserList(lodashGet(sections, '[0].data.length', 0) > 0, searchValue); return ( Date: Mon, 13 Nov 2023 17:22:46 +0100 Subject: [PATCH 156/212] Update currentUserAccountID type --- src/libs/actions/App.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libs/actions/App.ts b/src/libs/actions/App.ts index d3366ad6dd8c..d58926eb22c4 100644 --- a/src/libs/actions/App.ts +++ b/src/libs/actions/App.ts @@ -29,12 +29,12 @@ type PolicyParamsForOpenOrReconnect = { type Locale = ValueOf; -let currentUserAccountID: number | string; +let currentUserAccountID: number | null; let currentUserEmail: string; Onyx.connect({ key: ONYXKEYS.SESSION, callback: (val) => { - currentUserAccountID = val?.accountID ?? ''; + currentUserAccountID = val?.accountID ?? null; currentUserEmail = val?.email ?? ''; }, }); @@ -461,7 +461,7 @@ function openProfile(personalDetails: OnyxTypes.PersonalDetails) { onyxMethod: Onyx.METHOD.MERGE, key: ONYXKEYS.PERSONAL_DETAILS_LIST, value: { - [currentUserAccountID]: { + [currentUserAccountID ?? '']: { timezone: newTimezoneData, }, }, @@ -472,7 +472,7 @@ function openProfile(personalDetails: OnyxTypes.PersonalDetails) { onyxMethod: Onyx.METHOD.MERGE, key: ONYXKEYS.PERSONAL_DETAILS_LIST, value: { - [currentUserAccountID]: { + [currentUserAccountID ?? '']: { timezone: oldTimezoneData, }, }, From d790b481a542f959747d12533fd804cb0044b795 Mon Sep 17 00:00:00 2001 From: Viktoryia Kliushun Date: Mon, 13 Nov 2023 18:43:44 +0100 Subject: [PATCH 157/212] Fix ts issues --- src/libs/E2E/apiMocks/openApp.ts | 12 ++++++------ src/libs/E2E/apiMocks/openReport.ts | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/libs/E2E/apiMocks/openApp.ts b/src/libs/E2E/apiMocks/openApp.ts index 351aba50aeb0..13fc9f1f6784 100644 --- a/src/libs/E2E/apiMocks/openApp.ts +++ b/src/libs/E2E/apiMocks/openApp.ts @@ -1129,7 +1129,7 @@ const openApp = (): Response => ({ pronouns: '', timezone: { automatic: true, - selected: 'Europe/Kiev', + selected: 'Europe/Kyiv', }, firstName: '', lastName: '', @@ -1174,7 +1174,7 @@ const openApp = (): Response => ({ pronouns: '__predefined_heHimHis', timezone: { automatic: false, - selected: 'Europe/Belfast', + selected: 'Europe/London', }, firstName: 'Main', lastName: 'Ios🏴󠁧󠁢󠁳󠁣󠁴󠁿ios', @@ -1219,7 +1219,7 @@ const openApp = (): Response => ({ pronouns: '__predefined_sheHerHers', timezone: { automatic: false, - selected: 'US/Eastern', + selected: 'America/New_York', }, firstName: 'Katya', lastName: 'Becciv', @@ -1294,7 +1294,7 @@ const openApp = (): Response => ({ pronouns: '__predefined_callMeByMyName', timezone: { automatic: true, - selected: 'Europe/Kiev', + selected: 'Europe/Kyiv', }, firstName: 'Chat', lastName: 'HT', @@ -1385,7 +1385,7 @@ const openApp = (): Response => ({ pronouns: '__predefined_coCos', timezone: { automatic: true, - selected: 'Europe/Kiev', + selected: 'Europe/Kyiv', }, firstName: 'Applause', lastName: 'Main Account', @@ -1430,7 +1430,7 @@ const openApp = (): Response => ({ pronouns: '', timezone: { automatic: true, - selected: 'Europe/Kiev', + selected: 'Europe/Kyiv', }, firstName: 'Chat S', lastName: '', diff --git a/src/libs/E2E/apiMocks/openReport.ts b/src/libs/E2E/apiMocks/openReport.ts index 27c9a09705c6..1d0b5a4c54ac 100644 --- a/src/libs/E2E/apiMocks/openReport.ts +++ b/src/libs/E2E/apiMocks/openReport.ts @@ -1961,7 +1961,7 @@ export default (): Response => ({ pronouns: '', timezone: { automatic: true, - selected: 'Europe/Kiev', + selected: 'Europe/Kyiv', }, payPalMeAddress: '', phoneNumber: '', From 0b23ac2ac1930d458fa3665087112fdba07509a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucas=20M=C3=B3rawski?= Date: Mon, 13 Nov 2023 19:18:13 +0100 Subject: [PATCH 158/212] native camera fix and useTabNavigatorFocus refactor --- src/hooks/useTabNavigatorFocus/index.js | 8 +- .../useTabNavigatorFocus/index.native.js | 75 ------------------- src/libs/DomUtils/index.native.ts | 9 +++ src/libs/DomUtils/index.ts | 1 + 4 files changed, 13 insertions(+), 80 deletions(-) delete mode 100644 src/hooks/useTabNavigatorFocus/index.native.js diff --git a/src/hooks/useTabNavigatorFocus/index.js b/src/hooks/useTabNavigatorFocus/index.js index 7af6bc5950ac..86feb282f44f 100644 --- a/src/hooks/useTabNavigatorFocus/index.js +++ b/src/hooks/useTabNavigatorFocus/index.js @@ -1,6 +1,7 @@ import {useTabAnimation} from '@react-navigation/material-top-tabs'; import {useIsFocused} from '@react-navigation/native'; import {useEffect, useState} from 'react'; +import DomUtils from '@libs/DomUtils'; /** * Custom React hook to determine the focus status of a tab in a Material Top Tab Navigator. @@ -16,9 +17,6 @@ import {useEffect, useState} from 'react'; * might not be used within a Material Top Tabs Navigator context. Proper usage should ensure that * this hook is only used where appropriate. * - * Note: This hook is almost identical to native implementation, except for the `selectedTab` parameter - * and the fact that it uses requestAnimationFrame to mitigate issues when updating the isTabFocused state. - * * @param {Object} params - The parameters object. * @param {number} params.tabIndex - The index of the tab for which focus status is being determined. * @returns {boolean} Returns `true` if the tab is both animation-focused and screen-focused, otherwise `false`. @@ -50,7 +48,7 @@ function useTabNavigatorFocus({tabIndex}) { const listenerId = tabPositionAnimation.addListener(({value}) => { // Activate camera as soon the index is animating towards the `tabIndex` - requestAnimationFrame(() => { + DomUtils.requestAnimationFrame(() => { setIsTabFocused(value > index - 1 && value < index + 1); }); }); @@ -62,7 +60,7 @@ function useTabNavigatorFocus({tabIndex}) { const initialTabPositionValue = tabPositionAnimation.__getValue(); if (typeof initialTabPositionValue === 'number') { - requestAnimationFrame(() => { + DomUtils.requestAnimationFrame(() => { setIsTabFocused(initialTabPositionValue > index - 1 && initialTabPositionValue < index + 1); }); } diff --git a/src/hooks/useTabNavigatorFocus/index.native.js b/src/hooks/useTabNavigatorFocus/index.native.js deleted file mode 100644 index 7f9da7b3f841..000000000000 --- a/src/hooks/useTabNavigatorFocus/index.native.js +++ /dev/null @@ -1,75 +0,0 @@ -import {useTabAnimation} from '@react-navigation/material-top-tabs'; -import {useIsFocused} from '@react-navigation/native'; -import {useEffect, useState} from 'react'; -import CONST from '@src/CONST'; - -/** - * Custom React hook to determine the focus status of a specific tab in a Material Top Tab Navigator, with additional - * conditions based on a selected tab state. It evaluates whether the specified tab is focused by combining the tab's - * animation position and the screen's focus status within a React Navigation environment. - * - * The hook is primarily intended for use with Material Top Tabs provided by '@react-navigation/material-top-tabs'. - * It utilizes the `useTabAnimation` hook from this package to track the animated position of the tabs and the - * `useIsFocused` hook from '@react-navigation/native' to determine if the current screen is focused. Additionally, - * it uses a `selectedTab` parameter to apply custom logic based on the currently selected tab. - * - * Note: This hook employs a conditional invocation of the `useTabAnimation` hook, which is generally against React's - * rules of hooks. This pattern is used here to handle scenarios where the hook might not be employed within a - * Material Top Tabs Navigator context. Ensure this hook is only used in appropriate scenarios to avoid potential issues. - * - * @param {Object} params - The parameters object. - * @param {number} params.tabIndex - The index of the tab for which focus status is being determined. - * @param {string} params.selectedTab - The tab identifier passed by to the component. Used only on native platform - * - * @returns {boolean} Returns `true` if the specified tab is both animation-focused and screen-focused, otherwise `false`. - * - * @example - * const isTabFocused = useTabNavigatorFocus({ tabIndex: 1, selectedTab: 'home' }); - */ -function useTabNavigatorFocus({tabIndex, selectedTab}) { - let tabPositionAnimation = null; - try { - // Retrieve the animation value from the tab navigator, which ranges from 0 to the total number of pages displayed. - // Even a minimal scroll towards the camera page (e.g., a value of 0.001 at start) should activate the camera for immediate responsiveness. - // STOP!!!!!!! This is not a pattern to be followed! We are conditionally rendering this hook becase when used in the edit flow we'll never be inside a tab navigator. - // eslint-disable-next-line react-hooks/rules-of-hooks - tabPositionAnimation = useTabAnimation(); - } catch (error) { - tabPositionAnimation = null; - } - const isPageFocused = useIsFocused(); - // set to true if the hook is not used within the MaterialTopTabs context - // the hook will then return true if the screen is focused - const [isTabFocused, setIsTabFocused] = useState(!tabPositionAnimation); - - // Retrieve the animation value from the tab navigator, which ranges from 0 to the total number of pages displayed. - // Even a minimal scroll towards the camera page (e.g., a value of 0.001 at start) should activate the camera for immediate responsiveness. - - // STOP!!!!!!! This is not a pattern to be followed! We are conditionally rendering this hook becase when used in the edit flow we'll never be inside a tab navigator. - // eslint-disable-next-line react-hooks/rules-of-hooks - - useEffect(() => { - if (!tabPositionAnimation) { - return; - } - - const listenerId = tabPositionAnimation.addListener(({value}) => { - if (selectedTab !== CONST.TAB.SCAN) { - return; - } - // Activate camera as soon the index is animating towards the `cameraTabIndex` - setIsTabFocused(value > tabIndex - 1 && value < tabIndex + 1); - }); - - return () => { - if (!tabPositionAnimation) { - return; - } - tabPositionAnimation.removeListener(listenerId); - }; - }, [tabIndex, tabPositionAnimation, selectedTab]); - - return isTabFocused && isPageFocused; -} - -export default useTabNavigatorFocus; diff --git a/src/libs/DomUtils/index.native.ts b/src/libs/DomUtils/index.native.ts index 9a9758228776..0864f1a16ac0 100644 --- a/src/libs/DomUtils/index.native.ts +++ b/src/libs/DomUtils/index.native.ts @@ -2,6 +2,15 @@ import GetActiveElement from './types'; const getActiveElement: GetActiveElement = () => null; +const requestAnimationFrame = (callback: () => void) => { + if (!callback) { + return; + } + + callback(); +}; + export default { getActiveElement, + requestAnimationFrame, }; diff --git a/src/libs/DomUtils/index.ts b/src/libs/DomUtils/index.ts index 94dd54547454..6a2eed57fbe6 100644 --- a/src/libs/DomUtils/index.ts +++ b/src/libs/DomUtils/index.ts @@ -4,4 +4,5 @@ const getActiveElement: GetActiveElement = () => document.activeElement; export default { getActiveElement, + requestAnimationFrame: window.requestAnimationFrame.bind(window), }; From d0159d214b266a9794d10a5db8c496bdf5c7a51a Mon Sep 17 00:00:00 2001 From: John Schuster Date: Mon, 13 Nov 2023 13:54:21 -0600 Subject: [PATCH 159/212] Update Employees.md adding all the links that ChatGPT missed. --- .../expensify-classic/getting-started/Employees.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/articles/expensify-classic/getting-started/Employees.md b/docs/articles/expensify-classic/getting-started/Employees.md index 089a90c3dd21..76660edf94eb 100644 --- a/docs/articles/expensify-classic/getting-started/Employees.md +++ b/docs/articles/expensify-classic/getting-started/Employees.md @@ -8,7 +8,7 @@ This post will cover getting started with Expensify for new users (submitters an # Download the Mobile App -You can download Expensify for iOS and Android devices using the respective links [here](#). +You can download Expensify for [iOS](https://apps.apple.com/us/app/new-expensify/id1530278510) and [Android](https://play.google.com/store/apps/details?id=com.expensify.chat&hl=en_US&gl=US) devices using the respective links here. # How to review homepage tasks @@ -35,7 +35,7 @@ You can also forward receipts from your email address to [receipts@expensify.com Feel free to add coding details, categories, tags, comments, or attendees while SmartScan processes your receipt. SmartScan will handle the merchant, date, amount, and currency for you. -For more details on how to create and edit expenses, take a look [here](#). +For more details on how to create and edit expenses, take a look [here](https://help.expensify.com/articles/expensify-classic/get-paid-back/expenses/Create-Expenses). # Submit your first report @@ -57,7 +57,7 @@ If you need to send a report manually: - Click the Submit button in the top left of the report. - On the mobile app, tap the report and click, Submit Report. -For more details on creating and submitting reports, take a look [here](#). +For more details on creating and submitting reports, take a look [here](https://help.expensify.com/articles/expensify-classic/get-paid-back/reports/Create-A-Report#how-to-create-a-report). # What happens to my reports when they’re submitted? @@ -102,7 +102,7 @@ The Reports page allows you to search your reports using a wide variety of filte # How to add a deposit account -Adding a deposit account allows you to be reimbursed through Expensify by your company. There are a few nuanced differences between how to add deposit accounts depending on the currency you will be reimbursed in. Take a look at the different options [here](#). +Adding a deposit account allows you to be reimbursed through Expensify by your company. There are a few nuanced differences between how to add deposit accounts depending on the currency you will be reimbursed in. Take a look at the different options [here](https://help.expensify.com/expensify-classic/hubs/bank-accounts-and-credit-cards/deposit-accounts). # Add a Secondary Login to your account @@ -110,7 +110,7 @@ Expensify accounts are personal by design. They belong to you, the user, forever To ensure you get to keep your Expensify account as you shuffle through your professional life, we recommend adding your personal email address as your Secondary Login. This will ensure that, even if you were to leave your current position for something new and exciting, your account will not be closed when you are removed from the company. Instead, your company email address would be stripped from the account, but you would maintain ownership of the Expensify account. -Here’s how you can do that! +[Here’s](https://help.expensify.com/articles/expensify-classic/account-settings/Account-Details#how-to-add-a-secondary-login) how you can do that! # How to secure your account From 44b8a3f25d26c1a8bd6ac6c2bc4543fcd043b503 Mon Sep 17 00:00:00 2001 From: David Cardoza Date: Tue, 14 Nov 2023 07:54:57 +0800 Subject: [PATCH 160/212] Update docs/articles/expensify-classic/expensify-partner-program/How-to-Join-the-ExpensifyApproved!-Partner-Program.md Co-authored-by: Rushat Gabhane --- .../How-to-Join-the-ExpensifyApproved!-Partner-Program.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/articles/expensify-classic/expensify-partner-program/How-to-Join-the-ExpensifyApproved!-Partner-Program.md b/docs/articles/expensify-classic/expensify-partner-program/How-to-Join-the-ExpensifyApproved!-Partner-Program.md index 054dae5e2e14..79ad2ef4556e 100644 --- a/docs/articles/expensify-classic/expensify-partner-program/How-to-Join-the-ExpensifyApproved!-Partner-Program.md +++ b/docs/articles/expensify-classic/expensify-partner-program/How-to-Join-the-ExpensifyApproved!-Partner-Program.md @@ -22,7 +22,7 @@ Cobranded Marketing - Collaborate with your Partner Manager to craft custom mark Visit university.expensify.com and enroll in the “Getting Started with Expensify” course. This course imparts the essentials of Expensify, ensuring you follow the best practices for client setups. -# 2. Complete the course +2. Complete the course Grasp the core features and functionalities of Expensify. Ensure you're equipped to serve your clients using Expensify to its fullest. Once completed, you’ll be prompted to schedule a call with your Partner Manager. **This call is required to earn your certification.** From 5627efdb49d90ab5e8c19f31630edf6901c85c45 Mon Sep 17 00:00:00 2001 From: David Cardoza Date: Tue, 14 Nov 2023 07:55:02 +0800 Subject: [PATCH 161/212] Update docs/articles/expensify-classic/expensify-partner-program/How-to-Join-the-ExpensifyApproved!-Partner-Program.md Co-authored-by: Rushat Gabhane --- .../How-to-Join-the-ExpensifyApproved!-Partner-Program.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/articles/expensify-classic/expensify-partner-program/How-to-Join-the-ExpensifyApproved!-Partner-Program.md b/docs/articles/expensify-classic/expensify-partner-program/How-to-Join-the-ExpensifyApproved!-Partner-Program.md index 79ad2ef4556e..54436a48ea8d 100644 --- a/docs/articles/expensify-classic/expensify-partner-program/How-to-Join-the-ExpensifyApproved!-Partner-Program.md +++ b/docs/articles/expensify-classic/expensify-partner-program/How-to-Join-the-ExpensifyApproved!-Partner-Program.md @@ -27,7 +27,7 @@ Grasp the core features and functionalities of Expensify. Ensure you're equipped to serve your clients using Expensify to its fullest. Once completed, you’ll be prompted to schedule a call with your Partner Manager. **This call is required to earn your certification.** -# 3. Once you successfully complete the course, you'll unlock: +3. Once you successfully complete the course, you'll unlock: - A dedicated Partner Manager - assigned to you after you have completed the course! - A dedicated Client Setup Specialist - Membership to the ExpensifyApproved! Partner Program. From d9172176f3db85fc7745c4fb6faad1eeda60c76a Mon Sep 17 00:00:00 2001 From: Janic Duplessis Date: Mon, 13 Nov 2023 21:12:55 -0500 Subject: [PATCH 162/212] Use default batch size on web --- src/components/InvertedFlatList/index.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/components/InvertedFlatList/index.js b/src/components/InvertedFlatList/index.js index bf552c06b4d7..731bacb241a4 100644 --- a/src/components/InvertedFlatList/index.js +++ b/src/components/InvertedFlatList/index.js @@ -109,9 +109,6 @@ function InvertedFlatList(props) { shouldMeasureItems contentContainerStyle={contentContainerStyle} onScroll={handleScroll} - // We need to keep batch size to one to workaround a bug in react-native-web. - // This can be removed once https://github.com/Expensify/App/pull/24482 is merged. - maxToRenderPerBatch={1} /> ); } From 68946ccf4e9c56e5239c7b04fd4ac537ae87f028 Mon Sep 17 00:00:00 2001 From: Janic Duplessis Date: Mon, 13 Nov 2023 21:55:18 -0500 Subject: [PATCH 163/212] Remove measure items and cleanup BaseInvertedFlatList --- .../InvertedFlatList/BaseInvertedFlatList.js | 151 ++---------------- src/components/InvertedFlatList/index.js | 1 - src/pages/home/report/ReportActionsList.js | 1 - 3 files changed, 14 insertions(+), 139 deletions(-) diff --git a/src/components/InvertedFlatList/BaseInvertedFlatList.js b/src/components/InvertedFlatList/BaseInvertedFlatList.js index 90b4e02e2e4a..4206d5086a9e 100644 --- a/src/components/InvertedFlatList/BaseInvertedFlatList.js +++ b/src/components/InvertedFlatList/BaseInvertedFlatList.js @@ -1,9 +1,6 @@ import PropTypes from 'prop-types'; -import React, {forwardRef, useCallback, useRef} from 'react'; -import {FlatList as NativeFlatlist, View} from 'react-native'; -import _ from 'underscore'; +import React, {forwardRef} from 'react'; import FlatList from '@components/FlatList'; -import * as CollectionUtils from '@libs/CollectionUtils'; const AUTOSCROLL_TO_TOP_THRESHOLD = 128; @@ -14,148 +11,28 @@ const propTypes = { /** Same as FlatList although we wrap it in a measuring helper before passing to the actual FlatList component */ renderItem: PropTypes.func.isRequired, - - /** This must be set to the minimum size of one of the renderItem rows. Web experiences issues when inaccurate. */ - initialRowHeight: PropTypes.number.isRequired, - - /** Passed via forwardRef so we can access the FlatList ref */ - innerRef: PropTypes.oneOfType([PropTypes.func, PropTypes.shape({current: PropTypes.instanceOf(NativeFlatlist)})]).isRequired, - - /** Should we measure these items and call getItemLayout? */ - shouldMeasureItems: PropTypes.bool, }; const defaultProps = { data: [], - shouldMeasureItems: false, }; -function BaseInvertedFlatList(props) { - const {initialRowHeight, shouldMeasureItems, innerRef, renderItem} = props; - - // Stores each item's computed height after it renders - // once and is then referenced for the life of this component. - // This is essential to getting FlatList inverted to work on web - // and also enables more predictable scrolling on native platforms. - const sizeMap = useRef({}); - - /** - * Return default or previously cached height for - * a renderItem row - * - * @param {*} data - * @param {Number} index - * - * @return {Object} - */ - const getItemLayout = (data, index) => { - const size = sizeMap.current[index]; - - if (size) { - return { - length: size.length, - offset: size.offset, - index, - }; - } - - // If we don't have a size yet means we haven't measured this - // item yet. However, we can still calculate the offset by looking - // at the last size we have recorded (if any) - const lastMeasuredItem = CollectionUtils.lastItem(sizeMap.current); - - return { - // We haven't measured this so we must return the minimum row height - length: initialRowHeight, - - // Offset will either be based on the lastMeasuredItem or the index + - // initialRowHeight since we can only assume that all previous items - // have not yet been measured - offset: _.isUndefined(lastMeasuredItem) ? initialRowHeight * index : lastMeasuredItem.offset + initialRowHeight, - index, - }; - }; - - /** - * Measure item and cache the returned length (a.k.a. height) - * - * @param {React.NativeSyntheticEvent} nativeEvent - * @param {Number} index - */ - const measureItemLayout = useCallback((nativeEvent, index) => { - const computedHeight = nativeEvent.layout.height; - - // We've already measured this item so we don't need to - // measure it again. - if (sizeMap.current[index]) { - return; - } - - const previousItem = sizeMap.current[index - 1] || {}; - - // If there is no previousItem this can mean we haven't yet measured - // the previous item or that we are at index 0 and there is no previousItem - const previousLength = previousItem.length || 0; - const previousOffset = previousItem.offset || 0; - sizeMap.current[index] = { - length: computedHeight, - offset: previousLength + previousOffset, - }; - }, []); - - /** - * Render item method wraps the prop renderItem to render in a - * View component so we can attach an onLayout handler and - * measure it when it renders. - * - * @param {Object} params - * @param {Object} params.item - * @param {Number} params.index - * - * @return {React.Component} - */ - const renderItemFromProp = useCallback( - ({item, index}) => { - if (shouldMeasureItems) { - return measureItemLayout(nativeEvent, index)}>{renderItem({item, index})}; - } - - return renderItem({item, index}); - }, - [shouldMeasureItems, measureItemLayout, renderItem], - ); - - return ( - - ); -} - -BaseInvertedFlatList.propTypes = propTypes; -BaseInvertedFlatList.defaultProps = defaultProps; -BaseInvertedFlatList.displayName = 'BaseInvertedFlatList'; - -const BaseInvertedFlatListWithRef = forwardRef((props, ref) => ( - ( + )); -BaseInvertedFlatListWithRef.displayName = 'BaseInvertedFlatListWithRef'; +BaseInvertedFlatList.propTypes = propTypes; +BaseInvertedFlatList.defaultProps = defaultProps; +BaseInvertedFlatList.displayName = 'BaseInvertedFlatList'; -export default BaseInvertedFlatListWithRef; +export default BaseInvertedFlatList; diff --git a/src/components/InvertedFlatList/index.js b/src/components/InvertedFlatList/index.js index 731bacb241a4..815b58ad8308 100644 --- a/src/components/InvertedFlatList/index.js +++ b/src/components/InvertedFlatList/index.js @@ -106,7 +106,6 @@ function InvertedFlatList(props) { // eslint-disable-next-line react/jsx-props-no-spreading {...props} ref={innerRef} - shouldMeasureItems contentContainerStyle={contentContainerStyle} onScroll={handleScroll} /> diff --git a/src/pages/home/report/ReportActionsList.js b/src/pages/home/report/ReportActionsList.js index 759e73aa90e5..cc19170ae318 100644 --- a/src/pages/home/report/ReportActionsList.js +++ b/src/pages/home/report/ReportActionsList.js @@ -420,7 +420,6 @@ function ReportActionsList({ renderItem={renderItem} contentContainerStyle={contentContainerStyle} keyExtractor={keyExtractor} - initialRowHeight={32} initialNumToRender={initialNumToRender} onEndReached={loadOlderChats} onEndReachedThreshold={0.75} From 8353d56168808a55fe29a999ff3c4900f1378707 Mon Sep 17 00:00:00 2001 From: dukenv0307 Date: Tue, 14 Nov 2023 11:22:00 +0700 Subject: [PATCH 164/212] fix forwardedRef warning --- src/components/withTabAnimation.js | 34 ++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/src/components/withTabAnimation.js b/src/components/withTabAnimation.js index a2afdb26dc6e..82f45162b149 100644 --- a/src/components/withTabAnimation.js +++ b/src/components/withTabAnimation.js @@ -1,13 +1,22 @@ import {useTabAnimation} from '@react-navigation/material-top-tabs'; import PropTypes from 'prop-types'; import * as React from 'react'; +import _ from 'underscore'; import getComponentDisplayName from '@libs/getComponentDisplayName'; const propTypes = { + /** The HOC takes an optional ref as a prop and passes it as a ref to the wrapped component. + * That way, if a ref is passed to a component wrapped in the HOC, the ref is a reference to the wrapped component, not the HOC. */ + forwardedRef: PropTypes.func, + /* Whether we're in a tab navigator */ isInTabNavigator: PropTypes.bool.isRequired, }; +const defaultProps = { + forwardedRef: () => {}, +}; + export default function (WrappedComponent) { function WrappedComponentWithTabAnimation(props) { const animation = useTabAnimation(); @@ -23,27 +32,40 @@ export default function (WrappedComponent) { WrappedComponentWithTabAnimation.displayName = `withAnimation(${getComponentDisplayName(WrappedComponent)})`; - function WithTabAnimation(props, ref) { + function WithTabAnimation(props) { + const rest = _.omit(props, ['forwardedRef']); if (props.isInTabNavigator) { return ( ); } return ( ); } WithTabAnimation.propTypes = propTypes; + WithTabAnimation.defaultProps = defaultProps; WithTabAnimation.displayName = `withTabAnimation(${getComponentDisplayName(WrappedComponent)})`; - return React.forwardRef(WithTabAnimation); + // eslint-disable-next-line rulesdir/no-negated-variables + const WithTabAnimationWithRef = React.forwardRef((props, ref) => ( + + )); + + WithTabAnimationWithRef.displayName = 'WithTabAnimationWithRef'; + + return WithTabAnimation; } From a532c0439cb14e44a540ea7f0bf4d8e8d80a1300 Mon Sep 17 00:00:00 2001 From: dukenv0307 Date: Tue, 14 Nov 2023 12:00:53 +0700 Subject: [PATCH 165/212] add variable --- src/pages/workspace/WorkspaceInitialPage.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/pages/workspace/WorkspaceInitialPage.js b/src/pages/workspace/WorkspaceInitialPage.js index 1a568babaff0..81afb148bfbc 100644 --- a/src/pages/workspace/WorkspaceInitialPage.js +++ b/src/pages/workspace/WorkspaceInitialPage.js @@ -224,6 +224,9 @@ function WorkspaceInitialPage(props) { const prevPolicy = usePrevious(policy); + // We should check both policy and prevPolicy to prevent not found page appearing after we delete the workspace and navigate + const shouldShowNotFound = _.isEmpty(policy) || !PolicyUtils.isPolicyAdmin(policy) || (PolicyUtils.isPendingDeletePolicy(policy) && PolicyUtils.isPendingDeletePolicy(prevPolicy)); + return ( ( Navigation.goBack(ROUTES.SETTINGS_WORKSPACES)} - shouldShow={_.isEmpty(policy) || !PolicyUtils.isPolicyAdmin(policy) || (PolicyUtils.isPendingDeletePolicy(policy) && PolicyUtils.isPendingDeletePolicy(prevPolicy))} + shouldShow={shouldShowNotFound} subtitleKey={_.isEmpty(policy) ? undefined : 'workspace.common.notAuthorized'} > Date: Tue, 14 Nov 2023 12:17:20 +0700 Subject: [PATCH 166/212] fix lint --- src/pages/workspace/WorkspaceInitialPage.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/pages/workspace/WorkspaceInitialPage.js b/src/pages/workspace/WorkspaceInitialPage.js index 81afb148bfbc..c6f76e63e221 100644 --- a/src/pages/workspace/WorkspaceInitialPage.js +++ b/src/pages/workspace/WorkspaceInitialPage.js @@ -225,7 +225,8 @@ function WorkspaceInitialPage(props) { const prevPolicy = usePrevious(policy); // We should check both policy and prevPolicy to prevent not found page appearing after we delete the workspace and navigate - const shouldShowNotFound = _.isEmpty(policy) || !PolicyUtils.isPolicyAdmin(policy) || (PolicyUtils.isPendingDeletePolicy(policy) && PolicyUtils.isPendingDeletePolicy(prevPolicy)); + // eslint-disable-next-line rulesdir/no-negated-variables + const shouldShowNotFoundPage = _.isEmpty(policy) || !PolicyUtils.isPolicyAdmin(policy) || (PolicyUtils.isPendingDeletePolicy(policy) && PolicyUtils.isPendingDeletePolicy(prevPolicy)); return ( ( Navigation.goBack(ROUTES.SETTINGS_WORKSPACES)} - shouldShow={shouldShowNotFound} + shouldShow={shouldShowNotFoundPage} subtitleKey={_.isEmpty(policy) ? undefined : 'workspace.common.notAuthorized'} > Date: Tue, 14 Nov 2023 09:28:02 +0100 Subject: [PATCH 167/212] bring back default props --- src/components/Modal/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Modal/index.tsx b/src/components/Modal/index.tsx index a3d21d67b9af..b4cfc1f06211 100644 --- a/src/components/Modal/index.tsx +++ b/src/components/Modal/index.tsx @@ -7,7 +7,7 @@ import CONST from '@src/CONST'; import BaseModal from './BaseModal'; import BaseModalProps from './types'; -function Modal({fullscreen, onModalHide, type, onModalShow, children, ...rest}: BaseModalProps) { +function Modal({fullscreen = true, onModalHide = () => {}, type, onModalShow = () => {}, children, ...rest}: BaseModalProps) { const [previousStatusBarColor, setPreviousStatusBarColor] = useState(); const setStatusBarColor = (color = themeColors.appBG) => { From ad9534daffdc5997b10e33eebee5afb75318e7e7 Mon Sep 17 00:00:00 2001 From: Wojciech Boman Date: Tue, 14 Nov 2023 09:54:24 +0100 Subject: [PATCH 168/212] Add width and height to AnimatedIcon in FloatingActionButton component --- src/components/FloatingActionButton.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/FloatingActionButton.js b/src/components/FloatingActionButton.js index c0e01cab2954..d8a5a0256e62 100644 --- a/src/components/FloatingActionButton.js +++ b/src/components/FloatingActionButton.js @@ -4,6 +4,7 @@ import {Animated, Easing, View} from 'react-native'; import styles from '@styles/styles'; import * as StyleUtils from '@styles/StyleUtils'; import themeColors from '@styles/themes/default'; +import variables from '@styles/variables'; import Icon from './Icon'; import * as Expensicons from './Icon/Expensicons'; import PressableWithFeedback from './Pressable/PressableWithFeedback'; @@ -100,6 +101,8 @@ class FloatingActionButton extends PureComponent { style={[styles.floatingActionButton, StyleUtils.getAnimatedFABStyle(rotate, backgroundColor)]} > From 1349a1e21f786a638120794bfdfc331bb4597a27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucas=20M=C3=B3rawski?= Date: Tue, 14 Nov 2023 10:15:16 +0100 Subject: [PATCH 169/212] JSDocs types improvements --- src/hooks/useTabNavigatorFocus/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hooks/useTabNavigatorFocus/index.js b/src/hooks/useTabNavigatorFocus/index.js index 86feb282f44f..f83ec5bd9270 100644 --- a/src/hooks/useTabNavigatorFocus/index.js +++ b/src/hooks/useTabNavigatorFocus/index.js @@ -18,8 +18,8 @@ import DomUtils from '@libs/DomUtils'; * this hook is only used where appropriate. * * @param {Object} params - The parameters object. - * @param {number} params.tabIndex - The index of the tab for which focus status is being determined. - * @returns {boolean} Returns `true` if the tab is both animation-focused and screen-focused, otherwise `false`. + * @param {Number} params.tabIndex - The index of the tab for which focus status is being determined. + * @returns {Boolean} Returns `true` if the tab is both animation-focused and screen-focused, otherwise `false`. * * @example * const isTabFocused = useTabNavigatorFocus({ tabIndex: 1 }); From b311a90361f33f1d62a05e8c3b8c5e64fa8451ed Mon Sep 17 00:00:00 2001 From: dukenv0307 Date: Tue, 14 Nov 2023 17:04:54 +0700 Subject: [PATCH 170/212] edit comment --- src/pages/workspace/WorkspaceInitialPage.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/pages/workspace/WorkspaceInitialPage.js b/src/pages/workspace/WorkspaceInitialPage.js index c6f76e63e221..a2082396f196 100644 --- a/src/pages/workspace/WorkspaceInitialPage.js +++ b/src/pages/workspace/WorkspaceInitialPage.js @@ -224,9 +224,14 @@ function WorkspaceInitialPage(props) { const prevPolicy = usePrevious(policy); - // We should check both policy and prevPolicy to prevent not found page appearing after we delete the workspace and navigate // eslint-disable-next-line rulesdir/no-negated-variables - const shouldShowNotFoundPage = _.isEmpty(policy) || !PolicyUtils.isPolicyAdmin(policy) || (PolicyUtils.isPendingDeletePolicy(policy) && PolicyUtils.isPendingDeletePolicy(prevPolicy)); + const shouldShowNotFoundPage = + _.isEmpty(policy) || + !PolicyUtils.isPolicyAdmin(policy) || + // Somtimes, when we delete the workspace, the data is updated into Onyx faster than navigation time. + // That makes delete condition return true and not found page appears briefly before navigating. + // We check delete condition for both policy and prevPolicy to prevent the not found page showing if we are deleting the workspace + (PolicyUtils.isPendingDeletePolicy(policy) && PolicyUtils.isPendingDeletePolicy(prevPolicy)); return ( Date: Tue, 14 Nov 2023 17:05:33 +0700 Subject: [PATCH 171/212] edit comment --- src/pages/workspace/WorkspaceInitialPage.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/workspace/WorkspaceInitialPage.js b/src/pages/workspace/WorkspaceInitialPage.js index a2082396f196..913a28e6e698 100644 --- a/src/pages/workspace/WorkspaceInitialPage.js +++ b/src/pages/workspace/WorkspaceInitialPage.js @@ -228,7 +228,7 @@ function WorkspaceInitialPage(props) { const shouldShowNotFoundPage = _.isEmpty(policy) || !PolicyUtils.isPolicyAdmin(policy) || - // Somtimes, when we delete the workspace, the data is updated into Onyx faster than navigation time. + // Somtimes, when we delete the workspace, the data is updated into Onyx faster than navigation trasaction time. // That makes delete condition return true and not found page appears briefly before navigating. // We check delete condition for both policy and prevPolicy to prevent the not found page showing if we are deleting the workspace (PolicyUtils.isPendingDeletePolicy(policy) && PolicyUtils.isPendingDeletePolicy(prevPolicy)); From 66092e7284a61d52835084ee3befdbcdb4616086 Mon Sep 17 00:00:00 2001 From: Jakub Trzebiatowski Date: Tue, 14 Nov 2023 11:55:39 +0100 Subject: [PATCH 172/212] AttachmentCommentFragment: Convert back to a named function --- .../home/report/comment/AttachmentCommentFragment.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pages/home/report/comment/AttachmentCommentFragment.js b/src/pages/home/report/comment/AttachmentCommentFragment.js index ee5d2c99c783..a8a35cfb3925 100644 --- a/src/pages/home/report/comment/AttachmentCommentFragment.js +++ b/src/pages/home/report/comment/AttachmentCommentFragment.js @@ -16,14 +16,14 @@ const propTypes = { addExtraMargin: PropTypes.bool.isRequired, }; -const AttachmentCommentFragment = ({addExtraMargin, html, source}) => ( - +function AttachmentCommentFragment({addExtraMargin, html, source}) { + return - -); + ; +} AttachmentCommentFragment.propTypes = propTypes; AttachmentCommentFragment.displayName = 'AttachmentCommentFragment'; From a9eb4686f8844a27e6a75fe0d7e8770823ac98d2 Mon Sep 17 00:00:00 2001 From: Jakub Trzebiatowski Date: Tue, 14 Nov 2023 11:59:46 +0100 Subject: [PATCH 173/212] Run Prettier --- .../report/comment/AttachmentCommentFragment.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/pages/home/report/comment/AttachmentCommentFragment.js b/src/pages/home/report/comment/AttachmentCommentFragment.js index a8a35cfb3925..8ee161600aee 100644 --- a/src/pages/home/report/comment/AttachmentCommentFragment.js +++ b/src/pages/home/report/comment/AttachmentCommentFragment.js @@ -17,12 +17,14 @@ const propTypes = { }; function AttachmentCommentFragment({addExtraMargin, html, source}) { - return - - ; + return ( + + + + ); } AttachmentCommentFragment.propTypes = propTypes; From 4ff98835710b8f5ad8a77319f77e11ac4d924ef3 Mon Sep 17 00:00:00 2001 From: Cheryl W <58196921+CherylWalsh@users.noreply.github.com> Date: Tue, 14 Nov 2023 12:26:11 +0000 Subject: [PATCH 174/212] Update Connect-Company-Cards.md Adding the company card settings resource to the help site --- .../company-cards/Connect-Company-Cards.md | 92 ++++++++++++++++++- 1 file changed, 89 insertions(+), 3 deletions(-) diff --git a/docs/articles/expensify-classic/bank-accounts-and-credit-cards/company-cards/Connect-Company-Cards.md b/docs/articles/expensify-classic/bank-accounts-and-credit-cards/company-cards/Connect-Company-Cards.md index 112c3b9617c9..f2ff837d7638 100644 --- a/docs/articles/expensify-classic/bank-accounts-and-credit-cards/company-cards/Connect-Company-Cards.md +++ b/docs/articles/expensify-classic/bank-accounts-and-credit-cards/company-cards/Connect-Company-Cards.md @@ -1,5 +1,91 @@ --- -title: Connect Company Cards -description: Connect Company Cards +title: Company-Card-Settings.md +description: Company card settings --- -## Resource Coming Soon! +# Overview +Once you’ve imported your company cards via commercial card feed, direct bank feed, or CSV import, the next step is to configure the cards’ settings. + +As a Domain Admin, you can access the company card settings by navigating to Settings > Domains> Domain Name > Company Card > Settings. + +If you cannot access Domains, you will need to request Domain Admin access my the Domain Admin. + +# How to configure company card settings +You can manage company cards and set and adjust the settings from the Domains page by navigating to Settings > Domains > [Domain name] > Settings + +## Reimbursable preference + +You can control how your employees' company card expenses are flagged for reimbursement: + +Force Yes: All expenses will be marked as reimbursable, and employees cannot change this setting. +Force No: All expenses will be marked as non-reimbursable, and employees cannot change this setting. +Do Not Force: Expenses will default to either reimbursable or non-reimbursable (your choice), but employees can adjust if necessary. + +## Liability type + +Choose the liability type that suits your needs: + +Corporate Liability: Users cannot delete company card expenses. +Personal Liability: Users are allowed to delete company card expenses. + +If you update the settings on an existing company card feed, the changes will apply to expenses imported after the date the setting is saved. The update will not affect previously imported expenses. + +## Preferred policy + +Setting a preferred policy for a company card feed will ensure that the imported transactions are added to a report on the policy you set. This setting is useful when members are on multiple policies and need to ensure their company card expenses are reported to a particular policy. + +# How to use Scheduled Submit with company cards +All expenses must be placed on a report if they need to be approved; with Scheduled Submit, you no longer need to worry about the arduous task of employees creating their expenses, adding them to a report, and submitting them manually. All they need to do is SmartScan their receipts and Concierge will take care of the rest, on a variety of schedules that you can set according to your preferences! + +Concierge won't automatically submit expenses on reports that have Expense Violations. Instead, these expenses will be moved to a new report, creating an additional report for the current reporting period. + +An employee can add comments in the Expense Comment field or at the bottom of the report to clarify any details. + +## Enable Scheduled Submit +Scheduled Submit is enabled in the Group Policy by navigating to Settings > Policies > Group > Policy Name > Reports > Scheduled Submit +Use the toggle to enable Scheduled Submit +Choose your desired frequency + +If Scheduled Submit is disabled on the group policy level (or set to a manual frequency), and you have noticed expense reports are still automatically submitted to the group policy, it's likely Scheduled Submit is enabled on the user’s Individual Policy settings. + +# How to connect company cards to an accounting integration + +If you're using a connected accounting system such as NetSuite, Xero, Intacct, Quickbooks Desktop, or QuickBooks Online, you can also connect the card to export to a specific credit card GL account. First, connect the card itself, and once completed, follow the steps below: +Go to Settings > Domains > Domain name > Company Cards +Click Edit Exports on the right-hand side of the card table and select the GL account you want to export expenses to +You're all done. After the account is set, exported expenses will be mapped to the specific account selected when exported by a Domain Admin. + +# How to export company card expenses to a connected accounting integration + +## Pooled GL account + +To export credit card expenses to a pooled GL account: +Go to Settings > Policies > Group > Policy Name > Connections > Accounting Integrations > Configure +Select Credit Card / Charge Card / Bank Transaction as your Non-reimbursable export option. +Please review the Export Settings page for exporting Expense Reports to NetSuite +Select the Vendor/liability account you want to export all non-reimbursable expenses to. + +## Individual GL account + +Go to Settings > Domain > Domain name > Company Cards +Click the Export Settings cog to the right-hand side of the card and select the GL account you want to export expenses to. +You're all done! After the account is set, exported expenses will be mapped to the specific account selected. + +# Deep Dive +## Identifying company card transactions +When you link your credit cards to Expensify, the transactions will appear in each user's account on the Expenses page as soon as they're posted. You can identify transactions from centrally managed cards by seeing the locked card icon next to them. That icon indicates that they’re company card expenses: +[add image here] + +## Importing historical transactions + +After a card is connected via direct connection or via Approved! banks, Expensify will import 30-90 days' worth of historical transactions to your account (the timeframe is based on your bank's discretion). Any historical expenses beyond that date range can be imported using the CSV spreadsheet import method. + +## Using eReceipts +Expensify eReceipts serve as digital substitutes for paper receipts in your purchase transactions, eliminating the necessity to retain physical receipts or utilize SmartScanning receipts. In the case of Expensify Card transactions, eReceipts are automatically generated for all amounts. For other card programs, eReceipts are specifically generated for purchases amounting to $75 or less, provided the transactions are in USD. +To ensure seamless automatic importation, it's essential to maintain your transactions in US Dollars. Additionally, eReceipts can be directly imported from your bank account. Please be aware that CSV/OFX imported files of bank transactions do not support eReceipts. +It's important to note that eReceipts are not generated for lodging expenses. Moreover, due to incomplete or inaccurate category information from certain banks, there may be instances of invalid eReceipts being generated for hotel purchases. If you choose to re-categorize expenses, a similar situation may arise. It's crucial to remember that our Expensify eReceipt Guarantee excludes coverage for hotel and motel expenses. + +# FAQ +## What plan/subscription is required in order to manage corporate cards? +Group Policy (Collect or Control plan only) +## When do my company card transactions import to Expensify? +Credit card transactions are imported to Expensify once they’re posted to the bank account. This usually takes 1-3 business days between the point of purchase and when the transactions populate in your account. From f93ad6c7dea342a5bcf18fd1aafcac1e4f292af3 Mon Sep 17 00:00:00 2001 From: dukenv0307 <129500732+dukenv0307@users.noreply.github.com> Date: Tue, 14 Nov 2023 19:33:52 +0700 Subject: [PATCH 175/212] Update src/components/withTabAnimation.js Co-authored-by: Rajat Parashar --- src/components/withTabAnimation.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/withTabAnimation.js b/src/components/withTabAnimation.js index a542454e9cf7..0e35395b7742 100644 --- a/src/components/withTabAnimation.js +++ b/src/components/withTabAnimation.js @@ -34,8 +34,7 @@ export default function (WrappedComponent) { WrappedComponentWithTabAnimation.displayName = `withAnimation(${getComponentDisplayName(WrappedComponent)})`; // Return a component with tab animation prop if this component is in tab navigator, otherwise return itself - function WithTabAnimation(props) { - const rest = _.omit(props, ['forwardedRef']); + function WithTabAnimation({forwardedRef, ...rest}) { if (props.isInTabNavigator) { return ( Date: Tue, 14 Nov 2023 19:34:06 +0700 Subject: [PATCH 176/212] Update src/components/withTabAnimation.js Co-authored-by: Rajat Parashar --- src/components/withTabAnimation.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/withTabAnimation.js b/src/components/withTabAnimation.js index 0e35395b7742..b5000a102ab5 100644 --- a/src/components/withTabAnimation.js +++ b/src/components/withTabAnimation.js @@ -40,7 +40,7 @@ export default function (WrappedComponent) { ); } From c68201da3ea58d401ede81a6de06312ac929482a Mon Sep 17 00:00:00 2001 From: dukenv0307 <129500732+dukenv0307@users.noreply.github.com> Date: Tue, 14 Nov 2023 19:34:17 +0700 Subject: [PATCH 177/212] Update src/components/withTabAnimation.js Co-authored-by: Rajat Parashar --- src/components/withTabAnimation.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/withTabAnimation.js b/src/components/withTabAnimation.js index b5000a102ab5..5dd20f19c4b3 100644 --- a/src/components/withTabAnimation.js +++ b/src/components/withTabAnimation.js @@ -48,7 +48,7 @@ export default function (WrappedComponent) { ); } From 96e77db11f48b32ef003d81f1e2ce0d02ea3c777 Mon Sep 17 00:00:00 2001 From: dukenv0307 <129500732+dukenv0307@users.noreply.github.com> Date: Tue, 14 Nov 2023 19:34:27 +0700 Subject: [PATCH 178/212] Update src/components/withTabAnimation.js Co-authored-by: Rajat Parashar --- src/components/withTabAnimation.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/withTabAnimation.js b/src/components/withTabAnimation.js index 5dd20f19c4b3..45121c4d3fa0 100644 --- a/src/components/withTabAnimation.js +++ b/src/components/withTabAnimation.js @@ -7,7 +7,7 @@ import getComponentDisplayName from '@libs/getComponentDisplayName'; const propTypes = { /** The HOC takes an optional ref as a prop and passes it as a ref to the wrapped component. * That way, if a ref is passed to a component wrapped in the HOC, the ref is a reference to the wrapped component, not the HOC. */ - forwardedRef: PropTypes.func, + forwardedRef: refPropTypes, /* Whether we're in a tab navigator */ isInTabNavigator: PropTypes.bool.isRequired, From af6553ab541581285bee184dbd04df9afaed02db Mon Sep 17 00:00:00 2001 From: dukenv0307 Date: Tue, 14 Nov 2023 19:37:12 +0700 Subject: [PATCH 179/212] fix lint --- src/components/withTabAnimation.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/withTabAnimation.js b/src/components/withTabAnimation.js index 45121c4d3fa0..2af96f0215a3 100644 --- a/src/components/withTabAnimation.js +++ b/src/components/withTabAnimation.js @@ -1,8 +1,8 @@ import {useTabAnimation} from '@react-navigation/material-top-tabs'; import PropTypes from 'prop-types'; import * as React from 'react'; -import _ from 'underscore'; import getComponentDisplayName from '@libs/getComponentDisplayName'; +import refPropTypes from './refPropTypes'; const propTypes = { /** The HOC takes an optional ref as a prop and passes it as a ref to the wrapped component. @@ -35,7 +35,7 @@ export default function (WrappedComponent) { // Return a component with tab animation prop if this component is in tab navigator, otherwise return itself function WithTabAnimation({forwardedRef, ...rest}) { - if (props.isInTabNavigator) { + if (rest.isInTabNavigator) { return ( Date: Tue, 14 Nov 2023 18:50:50 +0600 Subject: [PATCH 180/212] fix wrong condition of assigning ref in Hoverable --- src/components/Hoverable/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Hoverable/index.tsx b/src/components/Hoverable/index.tsx index a52dfa296925..af8b66454a44 100644 --- a/src/components/Hoverable/index.tsx +++ b/src/components/Hoverable/index.tsx @@ -35,7 +35,7 @@ function assignRef(ref: ((instance: HTMLElement | null) => void) | MutableRefObj } if (typeof ref === 'function') { ref(element); - } else if (ref?.current) { + } else if (ref.current !== undefined) { // eslint-disable-next-line no-param-reassign ref.current = element; } From e081a52df2912d21f25a2ebd174224cc37844d74 Mon Sep 17 00:00:00 2001 From: situchan Date: Tue, 14 Nov 2023 19:52:39 +0600 Subject: [PATCH 181/212] correct check if object has property --- src/components/Hoverable/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Hoverable/index.tsx b/src/components/Hoverable/index.tsx index af8b66454a44..9c641cfc19be 100644 --- a/src/components/Hoverable/index.tsx +++ b/src/components/Hoverable/index.tsx @@ -35,7 +35,7 @@ function assignRef(ref: ((instance: HTMLElement | null) => void) | MutableRefObj } if (typeof ref === 'function') { ref(element); - } else if (ref.current !== undefined) { + } else if ('current' in ref) { // eslint-disable-next-line no-param-reassign ref.current = element; } From f80dad1fa121ab01085ffd6592c0bdfac4bc999b Mon Sep 17 00:00:00 2001 From: Wojciech Boman Date: Tue, 14 Nov 2023 15:19:46 +0100 Subject: [PATCH 182/212] Refactor FAB size --- src/components/FloatingActionButton.js | 3 --- src/styles/styles.ts | 4 ++-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/components/FloatingActionButton.js b/src/components/FloatingActionButton.js index d8a5a0256e62..c0e01cab2954 100644 --- a/src/components/FloatingActionButton.js +++ b/src/components/FloatingActionButton.js @@ -4,7 +4,6 @@ import {Animated, Easing, View} from 'react-native'; import styles from '@styles/styles'; import * as StyleUtils from '@styles/StyleUtils'; import themeColors from '@styles/themes/default'; -import variables from '@styles/variables'; import Icon from './Icon'; import * as Expensicons from './Icon/Expensicons'; import PressableWithFeedback from './Pressable/PressableWithFeedback'; @@ -101,8 +100,6 @@ class FloatingActionButton extends PureComponent { style={[styles.floatingActionButton, StyleUtils.getAnimatedFABStyle(rotate, backgroundColor)]} > diff --git a/src/styles/styles.ts b/src/styles/styles.ts index ada77e124c38..b70b50ffbbbc 100644 --- a/src/styles/styles.ts +++ b/src/styles/styles.ts @@ -1362,8 +1362,8 @@ const styles = (theme: ThemeColors) => floatingActionButton: { backgroundColor: theme.success, - height: variables.componentSizeNormal, - width: variables.componentSizeNormal, + height: variables.componentSizeLarge, + width: variables.componentSizeLarge, borderRadius: 999, alignItems: 'center', justifyContent: 'center', From c57dc10fec5795d6109499e1763b4bd1f8bdad1c Mon Sep 17 00:00:00 2001 From: dukenv0307 <129500732+dukenv0307@users.noreply.github.com> Date: Tue, 14 Nov 2023 22:49:07 +0700 Subject: [PATCH 183/212] Update src/pages/workspace/WorkspaceInitialPage.js Co-authored-by: Vinh Hoang --- src/pages/workspace/WorkspaceInitialPage.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/pages/workspace/WorkspaceInitialPage.js b/src/pages/workspace/WorkspaceInitialPage.js index 913a28e6e698..50aa87041c21 100644 --- a/src/pages/workspace/WorkspaceInitialPage.js +++ b/src/pages/workspace/WorkspaceInitialPage.js @@ -228,9 +228,7 @@ function WorkspaceInitialPage(props) { const shouldShowNotFoundPage = _.isEmpty(policy) || !PolicyUtils.isPolicyAdmin(policy) || - // Somtimes, when we delete the workspace, the data is updated into Onyx faster than navigation trasaction time. - // That makes delete condition return true and not found page appears briefly before navigating. - // We check delete condition for both policy and prevPolicy to prevent the not found page showing if we are deleting the workspace + // We check isPendingDelete for both policy and prevPolicy to prevent the NotFound view from showing right after we delete the workspace (PolicyUtils.isPendingDeletePolicy(policy) && PolicyUtils.isPendingDeletePolicy(prevPolicy)); return ( From 77d2eab744ffc29d118cfc2ef35589c99498b70e Mon Sep 17 00:00:00 2001 From: Amy Evans Date: Tue, 14 Nov 2023 11:11:47 -0500 Subject: [PATCH 184/212] Remove tags beta --- src/CONST.ts | 1 - src/components/MoneyRequestConfirmationList.js | 5 ++--- src/components/ReportActionItem/MoneyRequestView.js | 4 ++-- src/libs/Permissions.ts | 5 ----- src/pages/EditRequestPage.js | 2 +- 5 files changed, 5 insertions(+), 12 deletions(-) diff --git a/src/CONST.ts b/src/CONST.ts index 9192e6e2f2c1..69ca8256cc6f 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -260,7 +260,6 @@ const CONST = { TASKS: 'tasks', THREADS: 'threads', CUSTOM_STATUS: 'customStatus', - NEW_DOT_TAGS: 'newDotTags', NEW_DOT_SAML: 'newDotSAML', PDF_META_STORE: 'pdfMetaStore', REPORT_ACTION_CONTEXT_MENU: 'reportActionContextMenu', diff --git a/src/components/MoneyRequestConfirmationList.js b/src/components/MoneyRequestConfirmationList.js index db70d5a18dfc..8fd8537143fe 100755 --- a/src/components/MoneyRequestConfirmationList.js +++ b/src/components/MoneyRequestConfirmationList.js @@ -241,12 +241,11 @@ function MoneyRequestConfirmationList(props) { const policyTag = PolicyUtils.getTag(props.policyTags); const policyTagList = lodashGet(policyTag, 'tags', {}); const policyTagListName = lodashGet(policyTag, 'name', translate('common.tag')); - const canUseTags = Permissions.canUseTags(props.betas); // A flag for showing the tags field - const shouldShowTags = props.isPolicyExpenseChat && canUseTags && OptionsListUtils.hasEnabledOptions(_.values(policyTagList)); + const shouldShowTags = props.isPolicyExpenseChat && OptionsListUtils.hasEnabledOptions(_.values(policyTagList)); // A flag for showing the billable field - const shouldShowBillable = canUseTags && !lodashGet(props.policy, 'disabledFields.defaultBillable', true); + const shouldShowBillable = !lodashGet(props.policy, 'disabledFields.defaultBillable', true); const hasRoute = TransactionUtils.hasRoute(transaction); const isDistanceRequestWithoutRoute = props.isDistanceRequest && !hasRoute; diff --git a/src/components/ReportActionItem/MoneyRequestView.js b/src/components/ReportActionItem/MoneyRequestView.js index ee852d5c146a..82bed61d98ad 100644 --- a/src/components/ReportActionItem/MoneyRequestView.js +++ b/src/components/ReportActionItem/MoneyRequestView.js @@ -120,8 +120,8 @@ function MoneyRequestView({report, betas, parentReport, policyCategories, should // Flags for showing categories and tags const shouldShowCategory = isPolicyExpenseChat && (transactionCategory || OptionsListUtils.hasEnabledOptions(lodashValues(policyCategories))); - const shouldShowTag = isPolicyExpenseChat && Permissions.canUseTags(betas) && (transactionTag || OptionsListUtils.hasEnabledOptions(lodashValues(policyTagsList))); - const shouldShowBillable = isPolicyExpenseChat && Permissions.canUseTags(betas) && (transactionBillable || !lodashGet(policy, 'disabledFields.defaultBillable', true)); + const shouldShowTag = isPolicyExpenseChat && (transactionTag || OptionsListUtils.hasEnabledOptions(lodashValues(policyTagsList))); + const shouldShowBillable = isPolicyExpenseChat && (transactionBillable || !lodashGet(policy, 'disabledFields.defaultBillable', true)); let amountDescription = `${translate('iou.amount')}`; diff --git a/src/libs/Permissions.ts b/src/libs/Permissions.ts index 5200e5803ee3..0c8843b87415 100644 --- a/src/libs/Permissions.ts +++ b/src/libs/Permissions.ts @@ -42,10 +42,6 @@ function canUseCustomStatus(betas: Beta[]): boolean { return betas?.includes(CONST.BETAS.CUSTOM_STATUS) || canUseAllBetas(betas); } -function canUseTags(betas: Beta[]): boolean { - return betas?.includes(CONST.BETAS.NEW_DOT_TAGS) || canUseAllBetas(betas); -} - function canUseViolations(betas: Beta[]): boolean { return betas?.includes(CONST.BETAS.VIOLATIONS) || canUseAllBetas(betas); } @@ -66,7 +62,6 @@ export default { canUsePolicyRooms, canUseTasks, canUseCustomStatus, - canUseTags, canUseLinkPreviews, canUseViolations, }; diff --git a/src/pages/EditRequestPage.js b/src/pages/EditRequestPage.js index c958189d68b5..7d62efb586a5 100644 --- a/src/pages/EditRequestPage.js +++ b/src/pages/EditRequestPage.js @@ -107,7 +107,7 @@ function EditRequestPage({betas, report, route, parentReport, policyCategories, const shouldShowCategories = isPolicyExpenseChat && (transactionCategory || OptionsListUtils.hasEnabledOptions(lodashValues(policyCategories))); // A flag for showing the tags page - const shouldShowTags = isPolicyExpenseChat && Permissions.canUseTags(betas) && (transactionTag || OptionsListUtils.hasEnabledOptions(lodashValues(policyTagList))); + const shouldShowTags = isPolicyExpenseChat && (transactionTag || OptionsListUtils.hasEnabledOptions(lodashValues(policyTagList))); // Decides whether to allow or disallow editing a money request useEffect(() => { From 29a3f3475b080ff94d5e1032d38c81bef3ca6515 Mon Sep 17 00:00:00 2001 From: David Cardoza Date: Wed, 15 Nov 2023 00:16:00 +0800 Subject: [PATCH 185/212] Update docs/articles/expensify-classic/expensify-partner-program/How-to-Join-the-ExpensifyApproved!-Partner-Program.md Co-authored-by: Rushat Gabhane --- .../How-to-Join-the-ExpensifyApproved!-Partner-Program.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/articles/expensify-classic/expensify-partner-program/How-to-Join-the-ExpensifyApproved!-Partner-Program.md b/docs/articles/expensify-classic/expensify-partner-program/How-to-Join-the-ExpensifyApproved!-Partner-Program.md index 54436a48ea8d..e14fadbec915 100644 --- a/docs/articles/expensify-classic/expensify-partner-program/How-to-Join-the-ExpensifyApproved!-Partner-Program.md +++ b/docs/articles/expensify-classic/expensify-partner-program/How-to-Join-the-ExpensifyApproved!-Partner-Program.md @@ -18,7 +18,7 @@ Cobranded Marketing - Collaborate with your Partner Manager to craft custom mark # How to join the ExpensifyApproved! Partner Program -## 1. Enroll in ExpensifyApproved! University (EA!U) +1. Enroll in ExpensifyApproved! University (EA!U) Visit university.expensify.com and enroll in the “Getting Started with Expensify” course. This course imparts the essentials of Expensify, ensuring you follow the best practices for client setups. From bb69e00eb1018776ba155bdf4e15d70efe2efb9e Mon Sep 17 00:00:00 2001 From: Amy Evans Date: Tue, 14 Nov 2023 11:19:52 -0500 Subject: [PATCH 186/212] Remove unused props --- src/components/MoneyRequestConfirmationList.js | 7 ------- src/components/ReportActionItem/MoneyRequestView.js | 9 +-------- src/pages/EditRequestPage.js | 9 +-------- 3 files changed, 2 insertions(+), 23 deletions(-) diff --git a/src/components/MoneyRequestConfirmationList.js b/src/components/MoneyRequestConfirmationList.js index 8fd8537143fe..da2ec9b0c3d4 100755 --- a/src/components/MoneyRequestConfirmationList.js +++ b/src/components/MoneyRequestConfirmationList.js @@ -110,9 +110,6 @@ const propTypes = { email: PropTypes.string.isRequired, }), - /** List of betas available to current user */ - betas: PropTypes.arrayOf(PropTypes.string), - /** The policyID of the request */ policyID: PropTypes.string, @@ -188,7 +185,6 @@ const defaultProps = { session: { email: null, }, - betas: [], policyID: '', reportID: '', ...withCurrentUserPersonalDetailsDefaultProps, @@ -744,9 +740,6 @@ export default compose( session: { key: ONYXKEYS.SESSION, }, - betas: { - key: ONYXKEYS.BETAS, - }, policyCategories: { key: ({policyID}) => `${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policyID}`, }, diff --git a/src/components/ReportActionItem/MoneyRequestView.js b/src/components/ReportActionItem/MoneyRequestView.js index 82bed61d98ad..6b2488074dc4 100644 --- a/src/components/ReportActionItem/MoneyRequestView.js +++ b/src/components/ReportActionItem/MoneyRequestView.js @@ -47,9 +47,6 @@ const propTypes = { shouldShowHorizontalRule: PropTypes.bool.isRequired, /* Onyx Props */ - /** List of betas available to current user */ - betas: PropTypes.arrayOf(PropTypes.string), - /** The expense report or iou report (only will have a value if this is a transaction thread) */ parentReport: iouReportPropTypes, @@ -66,7 +63,6 @@ const propTypes = { }; const defaultProps = { - betas: [], parentReport: {}, policyCategories: {}, transaction: { @@ -77,7 +73,7 @@ const defaultProps = { policyTags: {}, }; -function MoneyRequestView({report, betas, parentReport, policyCategories, shouldShowHorizontalRule, transaction, policyTags, policy}) { +function MoneyRequestView({report, parentReport, policyCategories, shouldShowHorizontalRule, transaction, policyTags, policy}) { const {isSmallScreenWidth} = useWindowDimensions(); const {translate} = useLocalize(); const parentReportAction = ReportActionsUtils.getParentReportAction(report); @@ -301,9 +297,6 @@ MoneyRequestView.displayName = 'MoneyRequestView'; export default compose( withCurrentUserPersonalDetails, withOnyx({ - betas: { - key: ONYXKEYS.BETAS, - }, parentReport: { key: ({report}) => `${ONYXKEYS.COLLECTION.REPORT}${report.parentReportID}`, }, diff --git a/src/pages/EditRequestPage.js b/src/pages/EditRequestPage.js index 7d62efb586a5..1bba1636d9bd 100644 --- a/src/pages/EditRequestPage.js +++ b/src/pages/EditRequestPage.js @@ -45,9 +45,6 @@ const propTypes = { }).isRequired, /** Onyx props */ - /** List of betas available to current user */ - betas: PropTypes.arrayOf(PropTypes.string), - /** The report object for the thread report */ report: reportPropTypes, @@ -68,7 +65,6 @@ const propTypes = { }; const defaultProps = { - betas: [], report: {}, parentReport: {}, policyCategories: {}, @@ -77,7 +73,7 @@ const defaultProps = { transaction: {}, }; -function EditRequestPage({betas, report, route, parentReport, policyCategories, policyTags, parentReportActions, transaction}) { +function EditRequestPage({report, route, parentReport, policyCategories, policyTags, parentReportActions, transaction}) { const parentReportActionID = lodashGet(report, 'parentReportActionID', '0'); const parentReportAction = lodashGet(parentReportActions, parentReportActionID, {}); const { @@ -278,9 +274,6 @@ EditRequestPage.propTypes = propTypes; EditRequestPage.defaultProps = defaultProps; export default compose( withOnyx({ - betas: { - key: ONYXKEYS.BETAS, - }, report: { key: ({route}) => `${ONYXKEYS.COLLECTION.REPORT}${route.params.threadReportID}`, }, From c36e045e102810f1ae11b18d131153a0d37c1c2e Mon Sep 17 00:00:00 2001 From: Amy Evans Date: Tue, 14 Nov 2023 11:30:48 -0500 Subject: [PATCH 187/212] Fix lint errors --- src/components/MoneyRequestConfirmationList.js | 1 - src/components/ReportActionItem/MoneyRequestView.js | 1 - src/pages/EditRequestPage.js | 1 - 3 files changed, 3 deletions(-) diff --git a/src/components/MoneyRequestConfirmationList.js b/src/components/MoneyRequestConfirmationList.js index da2ec9b0c3d4..309ee8bd6cb2 100755 --- a/src/components/MoneyRequestConfirmationList.js +++ b/src/components/MoneyRequestConfirmationList.js @@ -16,7 +16,6 @@ import Log from '@libs/Log'; import * as MoneyRequestUtils from '@libs/MoneyRequestUtils'; import Navigation from '@libs/Navigation/Navigation'; import * as OptionsListUtils from '@libs/OptionsListUtils'; -import Permissions from '@libs/Permissions'; import * as PolicyUtils from '@libs/PolicyUtils'; import * as ReceiptUtils from '@libs/ReceiptUtils'; import * as ReportUtils from '@libs/ReportUtils'; diff --git a/src/components/ReportActionItem/MoneyRequestView.js b/src/components/ReportActionItem/MoneyRequestView.js index 6b2488074dc4..f1fc51bd2be8 100644 --- a/src/components/ReportActionItem/MoneyRequestView.js +++ b/src/components/ReportActionItem/MoneyRequestView.js @@ -21,7 +21,6 @@ import compose from '@libs/compose'; import * as CurrencyUtils from '@libs/CurrencyUtils'; import Navigation from '@libs/Navigation/Navigation'; import * as OptionsListUtils from '@libs/OptionsListUtils'; -import Permissions from '@libs/Permissions'; import * as PolicyUtils from '@libs/PolicyUtils'; import * as ReceiptUtils from '@libs/ReceiptUtils'; import * as ReportActionsUtils from '@libs/ReportActionsUtils'; diff --git a/src/pages/EditRequestPage.js b/src/pages/EditRequestPage.js index 1bba1636d9bd..194cd2855dbd 100644 --- a/src/pages/EditRequestPage.js +++ b/src/pages/EditRequestPage.js @@ -12,7 +12,6 @@ import compose from '@libs/compose'; import * as CurrencyUtils from '@libs/CurrencyUtils'; import Navigation from '@libs/Navigation/Navigation'; import * as OptionsListUtils from '@libs/OptionsListUtils'; -import Permissions from '@libs/Permissions'; import * as PolicyUtils from '@libs/PolicyUtils'; import * as ReportUtils from '@libs/ReportUtils'; import * as TransactionUtils from '@libs/TransactionUtils'; From f6878c8385cfa96e9dfcf8eba8b54808b3e76a1a Mon Sep 17 00:00:00 2001 From: Viktoryia Kliushun Date: Tue, 14 Nov 2023 22:36:39 +0100 Subject: [PATCH 188/212] Add currentUserAccountID check --- src/libs/actions/App.ts | 42 +++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/src/libs/actions/App.ts b/src/libs/actions/App.ts index d58926eb22c4..0979238a44d7 100644 --- a/src/libs/actions/App.ts +++ b/src/libs/actions/App.ts @@ -455,30 +455,32 @@ function openProfile(personalDetails: OnyxTypes.PersonalDetails) { timezone: JSON.stringify(newTimezoneData), }; - API.write('OpenProfile', parameters, { - optimisticData: [ - { - onyxMethod: Onyx.METHOD.MERGE, - key: ONYXKEYS.PERSONAL_DETAILS_LIST, - value: { - [currentUserAccountID ?? '']: { - timezone: newTimezoneData, + if (typeof currentUserAccountID === 'number') { + API.write('OpenProfile', parameters, { + optimisticData: [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: ONYXKEYS.PERSONAL_DETAILS_LIST, + value: { + [currentUserAccountID]: { + timezone: newTimezoneData, + }, }, }, - }, - ], - failureData: [ - { - onyxMethod: Onyx.METHOD.MERGE, - key: ONYXKEYS.PERSONAL_DETAILS_LIST, - value: { - [currentUserAccountID ?? '']: { - timezone: oldTimezoneData, + ], + failureData: [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: ONYXKEYS.PERSONAL_DETAILS_LIST, + value: { + [currentUserAccountID]: { + timezone: oldTimezoneData, + }, }, }, - }, - ], - }); + ], + }); + } } /** From d7f4e3d14372b3e3166788ffbd5aabec9900f2a6 Mon Sep 17 00:00:00 2001 From: OSBotify Date: Tue, 14 Nov 2023 21:40:38 +0000 Subject: [PATCH 189/212] Update version to 1.3.99-0 --- android/app/build.gradle | 4 ++-- ios/NewExpensify/Info.plist | 4 ++-- ios/NewExpensifyTests/Info.plist | 4 ++-- package-lock.json | 4 ++-- package.json | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index d777f6c977e6..af7f43adad0d 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -91,8 +91,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1001039805 - versionName "1.3.98-5" + versionCode 1001039900 + versionName "1.3.99-0" } flavorDimensions "default" diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist index 0d91c1eaba10..d40d36701731 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -19,7 +19,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.3.98 + 1.3.99 CFBundleSignature ???? CFBundleURLTypes @@ -40,7 +40,7 @@ CFBundleVersion - 1.3.98.5 + 1.3.99.0 ITSAppUsesNonExemptEncryption LSApplicationQueriesSchemes diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index be17155b8035..4e3ca3ebce6d 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -15,10 +15,10 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.3.98 + 1.3.99 CFBundleSignature ???? CFBundleVersion - 1.3.98.5 + 1.3.99.0 diff --git a/package-lock.json b/package-lock.json index 66d1183b6465..2b32065e96bb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "new.expensify", - "version": "1.3.98-5", + "version": "1.3.99-0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "new.expensify", - "version": "1.3.98-5", + "version": "1.3.99-0", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 63273e3fafeb..c72d52ab4bba 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "1.3.98-5", + "version": "1.3.99-0", "author": "Expensify, Inc.", "homepage": "https://new.expensify.com", "description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.", From 5ecd6f77eb89e73ba3edba39add7231d10db6703 Mon Sep 17 00:00:00 2001 From: Viktoryia Kliushun Date: Tue, 14 Nov 2023 23:24:08 +0100 Subject: [PATCH 190/212] Add comment --- src/libs/actions/App.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libs/actions/App.ts b/src/libs/actions/App.ts index 0979238a44d7..4d5983980846 100644 --- a/src/libs/actions/App.ts +++ b/src/libs/actions/App.ts @@ -455,6 +455,7 @@ function openProfile(personalDetails: OnyxTypes.PersonalDetails) { timezone: JSON.stringify(newTimezoneData), }; + // We expect currentUserAccountID to be a number because it doesn't make sense to open profile if currentUserAccountID is not set if (typeof currentUserAccountID === 'number') { API.write('OpenProfile', parameters, { optimisticData: [ From 60f26d3968f16d800873adb53fefd1f46f1da8d0 Mon Sep 17 00:00:00 2001 From: Viktoryia Kliushun Date: Wed, 15 Nov 2023 11:26:16 +0100 Subject: [PATCH 191/212] Update icon type --- src/types/onyx/OnyxCommon.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/types/onyx/OnyxCommon.ts b/src/types/onyx/OnyxCommon.ts index 4d376b8b7da8..ac69baed3ef1 100644 --- a/src/types/onyx/OnyxCommon.ts +++ b/src/types/onyx/OnyxCommon.ts @@ -12,16 +12,16 @@ type Errors = Record; type Icon = { /** Avatar source to display */ - source?: AvatarSource; + source: AvatarSource; /** Denotes whether it is an avatar or a workspace avatar */ - type?: typeof CONST.ICON_TYPE_AVATAR | typeof CONST.ICON_TYPE_WORKSPACE; + type: typeof CONST.ICON_TYPE_AVATAR | typeof CONST.ICON_TYPE_WORKSPACE; /** Owner of the avatar. If user, displayName. If workspace, policy name */ - name?: string; + name: string; /** Avatar id */ - id?: number | string; + id: number | string; /** A fallback avatar icon to display when there is an error on loading avatar from remote URL. */ fallbackIcon?: AvatarSource; From 60807870728cd1bb56eb1f059e8af28de11133da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucas=20M=C3=B3rawski?= Date: Wed, 15 Nov 2023 15:24:57 +0100 Subject: [PATCH 192/212] removed unnecessary HOC and unused prop --- src/components/withTabAnimation.js | 72 ------------------- .../NavigationAwareCamera/index.native.js | 20 +----- src/pages/iou/ReceiptSelector/index.native.js | 3 +- 3 files changed, 4 insertions(+), 91 deletions(-) delete mode 100644 src/components/withTabAnimation.js diff --git a/src/components/withTabAnimation.js b/src/components/withTabAnimation.js deleted file mode 100644 index 2af96f0215a3..000000000000 --- a/src/components/withTabAnimation.js +++ /dev/null @@ -1,72 +0,0 @@ -import {useTabAnimation} from '@react-navigation/material-top-tabs'; -import PropTypes from 'prop-types'; -import * as React from 'react'; -import getComponentDisplayName from '@libs/getComponentDisplayName'; -import refPropTypes from './refPropTypes'; - -const propTypes = { - /** The HOC takes an optional ref as a prop and passes it as a ref to the wrapped component. - * That way, if a ref is passed to a component wrapped in the HOC, the ref is a reference to the wrapped component, not the HOC. */ - forwardedRef: refPropTypes, - - /* Whether we're in a tab navigator */ - isInTabNavigator: PropTypes.bool.isRequired, -}; - -const defaultProps = { - forwardedRef: () => {}, -}; - -export default function (WrappedComponent) { - // The component with tab animation prop - function WrappedComponentWithTabAnimation(props) { - const animation = useTabAnimation(); - - return ( - - ); - } - - WrappedComponentWithTabAnimation.displayName = `withAnimation(${getComponentDisplayName(WrappedComponent)})`; - - // Return a component with tab animation prop if this component is in tab navigator, otherwise return itself - function WithTabAnimation({forwardedRef, ...rest}) { - if (rest.isInTabNavigator) { - return ( - - ); - } - return ( - - ); - } - - WithTabAnimation.propTypes = propTypes; - WithTabAnimation.defaultProps = defaultProps; - WithTabAnimation.displayName = `withTabAnimation(${getComponentDisplayName(WrappedComponent)})`; - - // eslint-disable-next-line rulesdir/no-negated-variables - const WithTabAnimationWithRef = React.forwardRef((props, ref) => ( - - )); - - WithTabAnimationWithRef.displayName = `withTabAnimationWithRef(${getComponentDisplayName(WrappedComponent)})`; - - return WithTabAnimationWithRef; -} diff --git a/src/pages/iou/ReceiptSelector/NavigationAwareCamera/index.native.js b/src/pages/iou/ReceiptSelector/NavigationAwareCamera/index.native.js index 3d1ffb238722..65c17d3cb7ab 100644 --- a/src/pages/iou/ReceiptSelector/NavigationAwareCamera/index.native.js +++ b/src/pages/iou/ReceiptSelector/NavigationAwareCamera/index.native.js @@ -6,24 +6,11 @@ import useTabNavigatorFocus from '@hooks/useTabNavigatorFocus'; const propTypes = { /* The index of the tab that contains this camera */ cameraTabIndex: PropTypes.number.isRequired, - - /** Name of the selected receipt tab */ - selectedTab: PropTypes.string.isRequired, - - /** The tab animation from hook */ - tabAnimation: PropTypes.shape({ - addListener: PropTypes.func, - removeListener: PropTypes.func, - }), -}; - -const defaultProps = { - tabAnimation: undefined, }; // Wraps a camera that will only be active when the tab is focused or as soon as it starts to become focused. -const NavigationAwareCamera = React.forwardRef(({cameraTabIndex, selectedTab, ...props}, ref) => { - const isCameraActive = useTabNavigatorFocus({tabIndex: cameraTabIndex, selectedTab}); +const NavigationAwareCamera = React.forwardRef(({cameraTabIndex, ...props}, ref) => { + const isCameraActive = useTabNavigatorFocus({tabIndex: cameraTabIndex}); return ( )} From ce0d8611abc49ea05dd6b4f1f686daacba0d6ec9 Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Wed, 15 Nov 2023 15:28:29 +0100 Subject: [PATCH 193/212] Add test file --- src/styles/test.js | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 src/styles/test.js diff --git a/src/styles/test.js b/src/styles/test.js new file mode 100644 index 000000000000..ee12b5ed8d53 --- /dev/null +++ b/src/styles/test.js @@ -0,0 +1,3 @@ +const test = 'js'; + +export default test; From ad9d4203963a538dee37d3fdede48747bfbeb98b Mon Sep 17 00:00:00 2001 From: Daniel Edwards Date: Wed, 15 Nov 2023 09:34:42 -0500 Subject: [PATCH 194/212] Updates from review --- src/components/ReportActionItem/MoneyRequestView.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ReportActionItem/MoneyRequestView.js b/src/components/ReportActionItem/MoneyRequestView.js index d60ea2c59e03..9ff1e0761594 100644 --- a/src/components/ReportActionItem/MoneyRequestView.js +++ b/src/components/ReportActionItem/MoneyRequestView.js @@ -177,7 +177,7 @@ function MoneyRequestView({report, betas, parentReport, policyCategories, should )} - {!hasReceipt && Permissions.canUseViolations() && ( + {!hasReceipt && canEdit && !isSettled && Permissions.canUseViolations() && ( Navigation.navigate(ROUTES.EDIT_REQUEST.getRoute(report.reportID, CONST.EDIT_REQUEST_FIELD.RECEIPT))} From 5da6f16998bc1ce0d9efa46f53d57c7f5b1fde6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucas=20M=C3=B3rawski?= Date: Wed, 15 Nov 2023 15:40:49 +0100 Subject: [PATCH 195/212] linting --- src/pages/iou/ReceiptSelector/index.native.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/pages/iou/ReceiptSelector/index.native.js b/src/pages/iou/ReceiptSelector/index.native.js index d0e978fee15b..ef81109ffb90 100644 --- a/src/pages/iou/ReceiptSelector/index.native.js +++ b/src/pages/iou/ReceiptSelector/index.native.js @@ -50,16 +50,12 @@ const propTypes = { /** The id of the transaction we're editing */ transactionID: PropTypes.string, - - /** Name of the selected receipt tab */ - selectedTab: PropTypes.string, }; const defaultProps = { report: {}, iou: iouDefaultProps, transactionID: '', - selectedTab: '', }; function ReceiptSelector({route, report, iou, transactionID}) { From b5112f41490a39293e333d996c9b77f32834be6e Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Wed, 15 Nov 2023 15:41:23 +0100 Subject: [PATCH 196/212] Update typecheck --- .github/workflows/typecheck.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/typecheck.yml b/.github/workflows/typecheck.yml index 3e54975433f6..cfeeb397ee77 100644 --- a/.github/workflows/typecheck.yml +++ b/.github/workflows/typecheck.yml @@ -20,3 +20,11 @@ jobs: run: npm run typecheck env: CI: true + + - name: Check for new JavaScript files + run: | + count_new_js=$(git diff --name-only --diff-filter=A main -- '*.{js,jsx}' | grep -cE 'src/libs|src/hooks|src/styles|src/languages') + if [ "$count_new_js" -gt "0" ]; then + echo "ERROR: Found new JS or JSX files in the /src/libs, /src/hooks, /src/styles, or /src/languages directories." + exit 1 + fi \ No newline at end of file From 59a08831e69bbdbb628be1b4116f530abc07aaa2 Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Wed, 15 Nov 2023 15:44:40 +0100 Subject: [PATCH 197/212] Add js to typecheck to run checks also when only ts is added --- .github/workflows/typecheck.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/typecheck.yml b/.github/workflows/typecheck.yml index cfeeb397ee77..1e0373db0687 100644 --- a/.github/workflows/typecheck.yml +++ b/.github/workflows/typecheck.yml @@ -5,7 +5,7 @@ on: pull_request: types: [opened, synchronize] branches-ignore: [staging, production] - paths: ['**.ts', '**.tsx', 'package.json', 'package-lock.json', 'tsconfig.json'] + paths: ['**.js', '**.jsx', '**.ts', '**.tsx', 'package.json', 'package-lock.json', 'tsconfig.json'] jobs: typecheck: From a6699a1a8c3eb1f278db83d3252c8f3cf9bed4fa Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Wed, 15 Nov 2023 15:48:37 +0100 Subject: [PATCH 198/212] Fetch main before comparing --- .github/workflows/typecheck.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/typecheck.yml b/.github/workflows/typecheck.yml index 1e0373db0687..e01e87c7cb0f 100644 --- a/.github/workflows/typecheck.yml +++ b/.github/workflows/typecheck.yml @@ -23,6 +23,7 @@ jobs: - name: Check for new JavaScript files run: | + git fetch origin main --no-tags --depth=1 count_new_js=$(git diff --name-only --diff-filter=A main -- '*.{js,jsx}' | grep -cE 'src/libs|src/hooks|src/styles|src/languages') if [ "$count_new_js" -gt "0" ]; then echo "ERROR: Found new JS or JSX files in the /src/libs, /src/hooks, /src/styles, or /src/languages directories." From 12ce31a7c2253a28f893ccade5bd26af89154023 Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Wed, 15 Nov 2023 16:02:23 +0100 Subject: [PATCH 199/212] Fix the diff filtering --- .github/workflows/typecheck.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/typecheck.yml b/.github/workflows/typecheck.yml index e01e87c7cb0f..fae744b66ba0 100644 --- a/.github/workflows/typecheck.yml +++ b/.github/workflows/typecheck.yml @@ -5,7 +5,7 @@ on: pull_request: types: [opened, synchronize] branches-ignore: [staging, production] - paths: ['**.js', '**.jsx', '**.ts', '**.tsx', 'package.json', 'package-lock.json', 'tsconfig.json'] + paths: ['**.js', '**.ts', '**.tsx', 'package.json', 'package-lock.json', 'tsconfig.json'] jobs: typecheck: @@ -24,8 +24,8 @@ jobs: - name: Check for new JavaScript files run: | git fetch origin main --no-tags --depth=1 - count_new_js=$(git diff --name-only --diff-filter=A main -- '*.{js,jsx}' | grep -cE 'src/libs|src/hooks|src/styles|src/languages') + count_new_js=$(git diff --name-only --diff-filter=A origin/main HEAD -- 'src/libs/*.js' 'src/hooks/*.js' 'src/styles/*.js' 'src/languages/*.js' | wc -l) if [ "$count_new_js" -gt "0" ]; then - echo "ERROR: Found new JS or JSX files in the /src/libs, /src/hooks, /src/styles, or /src/languages directories." + echo "ERROR: Found new JavaScript files in the /src/libs, /src/hooks, /src/styles, or /src/languages directories; use TypeScript instead" exit 1 - fi \ No newline at end of file + fi From e272047e8afaade3e6bf634171b98c9584b8512c Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Wed, 15 Nov 2023 16:03:56 +0100 Subject: [PATCH 200/212] Remove test.js --- src/styles/test.js | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 src/styles/test.js diff --git a/src/styles/test.js b/src/styles/test.js deleted file mode 100644 index ee12b5ed8d53..000000000000 --- a/src/styles/test.js +++ /dev/null @@ -1,3 +0,0 @@ -const test = 'js'; - -export default test; From 77b016942fb50d7c8368033abf5fcda639128ecc Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Wed, 15 Nov 2023 16:06:00 +0100 Subject: [PATCH 201/212] Add ts file to trigger typecheck --- src/styles/test.ts | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 src/styles/test.ts diff --git a/src/styles/test.ts b/src/styles/test.ts new file mode 100644 index 000000000000..ee12b5ed8d53 --- /dev/null +++ b/src/styles/test.ts @@ -0,0 +1,3 @@ +const test = 'js'; + +export default test; From 43f0db54b68d9058ad6aa6a4ffcb5591ecbd7c9c Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Wed, 15 Nov 2023 16:08:20 +0100 Subject: [PATCH 202/212] Revert "Add ts file to trigger typecheck" This reverts commit 77b016942fb50d7c8368033abf5fcda639128ecc. --- src/styles/test.ts | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 src/styles/test.ts diff --git a/src/styles/test.ts b/src/styles/test.ts deleted file mode 100644 index ee12b5ed8d53..000000000000 --- a/src/styles/test.ts +++ /dev/null @@ -1,3 +0,0 @@ -const test = 'js'; - -export default test; From f604d1f016190497def00c1407e8048e189f08e9 Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Wed, 15 Nov 2023 16:49:13 +0100 Subject: [PATCH 203/212] Test modifying JS file --- src/libs/ComposerFocusManager.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libs/ComposerFocusManager.js b/src/libs/ComposerFocusManager.js index 569e165da962..8c2ba092a1c2 100644 --- a/src/libs/ComposerFocusManager.js +++ b/src/libs/ComposerFocusManager.js @@ -6,12 +6,14 @@ function resetReadyToFocus() { resolveIsReadyToFocus = resolve; }); } + function setReadyToFocus() { if (!resolveIsReadyToFocus) { return; } resolveIsReadyToFocus(); } + function isReadyToFocus() { return isReadyToFocusPromise; } From b8b60a86df4a8b8cd06e25bb2b323b4c294377e8 Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Wed, 15 Nov 2023 16:56:02 +0100 Subject: [PATCH 204/212] Revert "Test modifying JS file" This reverts commit f604d1f016190497def00c1407e8048e189f08e9. --- src/libs/ComposerFocusManager.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libs/ComposerFocusManager.js b/src/libs/ComposerFocusManager.js index 8c2ba092a1c2..569e165da962 100644 --- a/src/libs/ComposerFocusManager.js +++ b/src/libs/ComposerFocusManager.js @@ -6,14 +6,12 @@ function resetReadyToFocus() { resolveIsReadyToFocus = resolve; }); } - function setReadyToFocus() { if (!resolveIsReadyToFocus) { return; } resolveIsReadyToFocus(); } - function isReadyToFocus() { return isReadyToFocusPromise; } From 1c1b7399dd46be47ab1e8492d65fb7fbabdeb1a9 Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Wed, 15 Nov 2023 16:59:40 +0100 Subject: [PATCH 205/212] Test renaming JS file --- src/components/Modal/BaseModal.js | 2 +- src/components/Modal/index.android.js | 2 +- .../{ComposerFocusManager.js => ComposerFocusManagerRename.js} | 0 src/libs/focusComposerWithDelay.ts | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) rename src/libs/{ComposerFocusManager.js => ComposerFocusManagerRename.js} (100%) diff --git a/src/components/Modal/BaseModal.js b/src/components/Modal/BaseModal.js index bf1fdc8ee7de..e732a92380ba 100644 --- a/src/components/Modal/BaseModal.js +++ b/src/components/Modal/BaseModal.js @@ -5,7 +5,7 @@ import ReactNativeModal from 'react-native-modal'; import {useSafeAreaInsets} from 'react-native-safe-area-context'; import usePrevious from '@hooks/usePrevious'; import useWindowDimensions from '@hooks/useWindowDimensions'; -import ComposerFocusManager from '@libs/ComposerFocusManager'; +import ComposerFocusManager from '@libs/ComposerFocusManagerRename'; import useNativeDriver from '@libs/useNativeDriver'; import getModalStyles from '@styles/getModalStyles'; import styles from '@styles/styles'; diff --git a/src/components/Modal/index.android.js b/src/components/Modal/index.android.js index 51745ae6a20f..952aa66a5ea9 100644 --- a/src/components/Modal/index.android.js +++ b/src/components/Modal/index.android.js @@ -1,7 +1,7 @@ import React from 'react'; import {AppState} from 'react-native'; import withWindowDimensions from '@components/withWindowDimensions'; -import ComposerFocusManager from '@libs/ComposerFocusManager'; +import ComposerFocusManager from '@libs/ComposerFocusManagerRename'; import BaseModal from './BaseModal'; import {defaultProps, propTypes} from './modalPropTypes'; diff --git a/src/libs/ComposerFocusManager.js b/src/libs/ComposerFocusManagerRename.js similarity index 100% rename from src/libs/ComposerFocusManager.js rename to src/libs/ComposerFocusManagerRename.js diff --git a/src/libs/focusComposerWithDelay.ts b/src/libs/focusComposerWithDelay.ts index 19f1050d24bd..788e1025c06b 100644 --- a/src/libs/focusComposerWithDelay.ts +++ b/src/libs/focusComposerWithDelay.ts @@ -1,6 +1,6 @@ import {TextInput} from 'react-native'; import * as EmojiPickerAction from './actions/EmojiPickerAction'; -import ComposerFocusManager from './ComposerFocusManager'; +import ComposerFocusManager from './ComposerFocusManagerRename'; type FocusComposerWithDelay = (shouldDelay?: boolean) => void; /** From 550f7a8222245139f1596b60c79748ffadec3dda Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Wed, 15 Nov 2023 17:08:16 +0100 Subject: [PATCH 206/212] Rerun workflows From 590d8d7cf39f5136dcc5cbf6b5903ccd18b8493c Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Wed, 15 Nov 2023 17:08:47 +0100 Subject: [PATCH 207/212] Revert "Test renaming JS file" This reverts commit 1c1b7399dd46be47ab1e8492d65fb7fbabdeb1a9. --- src/components/Modal/BaseModal.js | 2 +- src/components/Modal/index.android.js | 2 +- .../{ComposerFocusManagerRename.js => ComposerFocusManager.js} | 0 src/libs/focusComposerWithDelay.ts | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) rename src/libs/{ComposerFocusManagerRename.js => ComposerFocusManager.js} (100%) diff --git a/src/components/Modal/BaseModal.js b/src/components/Modal/BaseModal.js index e732a92380ba..bf1fdc8ee7de 100644 --- a/src/components/Modal/BaseModal.js +++ b/src/components/Modal/BaseModal.js @@ -5,7 +5,7 @@ import ReactNativeModal from 'react-native-modal'; import {useSafeAreaInsets} from 'react-native-safe-area-context'; import usePrevious from '@hooks/usePrevious'; import useWindowDimensions from '@hooks/useWindowDimensions'; -import ComposerFocusManager from '@libs/ComposerFocusManagerRename'; +import ComposerFocusManager from '@libs/ComposerFocusManager'; import useNativeDriver from '@libs/useNativeDriver'; import getModalStyles from '@styles/getModalStyles'; import styles from '@styles/styles'; diff --git a/src/components/Modal/index.android.js b/src/components/Modal/index.android.js index 952aa66a5ea9..51745ae6a20f 100644 --- a/src/components/Modal/index.android.js +++ b/src/components/Modal/index.android.js @@ -1,7 +1,7 @@ import React from 'react'; import {AppState} from 'react-native'; import withWindowDimensions from '@components/withWindowDimensions'; -import ComposerFocusManager from '@libs/ComposerFocusManagerRename'; +import ComposerFocusManager from '@libs/ComposerFocusManager'; import BaseModal from './BaseModal'; import {defaultProps, propTypes} from './modalPropTypes'; diff --git a/src/libs/ComposerFocusManagerRename.js b/src/libs/ComposerFocusManager.js similarity index 100% rename from src/libs/ComposerFocusManagerRename.js rename to src/libs/ComposerFocusManager.js diff --git a/src/libs/focusComposerWithDelay.ts b/src/libs/focusComposerWithDelay.ts index 788e1025c06b..19f1050d24bd 100644 --- a/src/libs/focusComposerWithDelay.ts +++ b/src/libs/focusComposerWithDelay.ts @@ -1,6 +1,6 @@ import {TextInput} from 'react-native'; import * as EmojiPickerAction from './actions/EmojiPickerAction'; -import ComposerFocusManager from './ComposerFocusManagerRename'; +import ComposerFocusManager from './ComposerFocusManager'; type FocusComposerWithDelay = (shouldDelay?: boolean) => void; /** From 813c4c4ac2e2a41bacc8ff5f20fa059b92f4ca91 Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Wed, 15 Nov 2023 17:09:18 +0100 Subject: [PATCH 208/212] Test renaming JS file --- src/components/Modal/BaseModal.tsx | 2 +- src/components/Modal/index.android.tsx | 2 +- .../{ComposerFocusManager.js => ComposerFocusManagerRename.js} | 0 src/libs/focusComposerWithDelay.ts | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) rename src/libs/{ComposerFocusManager.js => ComposerFocusManagerRename.js} (100%) diff --git a/src/components/Modal/BaseModal.tsx b/src/components/Modal/BaseModal.tsx index e428b062798f..356f7c5baa16 100644 --- a/src/components/Modal/BaseModal.tsx +++ b/src/components/Modal/BaseModal.tsx @@ -4,7 +4,7 @@ import ReactNativeModal from 'react-native-modal'; import {useSafeAreaInsets} from 'react-native-safe-area-context'; import usePrevious from '@hooks/usePrevious'; import useWindowDimensions from '@hooks/useWindowDimensions'; -import ComposerFocusManager from '@libs/ComposerFocusManager'; +import ComposerFocusManager from '@libs/ComposerFocusManagerRename'; import useNativeDriver from '@libs/useNativeDriver'; import getModalStyles from '@styles/getModalStyles'; import styles from '@styles/styles'; diff --git a/src/components/Modal/index.android.tsx b/src/components/Modal/index.android.tsx index 2343cb4c70a9..3486e414d8c2 100644 --- a/src/components/Modal/index.android.tsx +++ b/src/components/Modal/index.android.tsx @@ -1,7 +1,7 @@ import React from 'react'; import {AppState} from 'react-native'; import withWindowDimensions from '@components/withWindowDimensions'; -import ComposerFocusManager from '@libs/ComposerFocusManager'; +import ComposerFocusManager from '@libs/ComposerFocusManagerRename'; import BaseModal from './BaseModal'; import BaseModalProps from './types'; diff --git a/src/libs/ComposerFocusManager.js b/src/libs/ComposerFocusManagerRename.js similarity index 100% rename from src/libs/ComposerFocusManager.js rename to src/libs/ComposerFocusManagerRename.js diff --git a/src/libs/focusComposerWithDelay.ts b/src/libs/focusComposerWithDelay.ts index 19f1050d24bd..788e1025c06b 100644 --- a/src/libs/focusComposerWithDelay.ts +++ b/src/libs/focusComposerWithDelay.ts @@ -1,6 +1,6 @@ import {TextInput} from 'react-native'; import * as EmojiPickerAction from './actions/EmojiPickerAction'; -import ComposerFocusManager from './ComposerFocusManager'; +import ComposerFocusManager from './ComposerFocusManagerRename'; type FocusComposerWithDelay = (shouldDelay?: boolean) => void; /** From 602b95b9ab055b4041d09ad43f710afa0f6bd0e4 Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Wed, 15 Nov 2023 17:09:30 +0100 Subject: [PATCH 209/212] Revert "Test renaming JS file" This reverts commit 813c4c4ac2e2a41bacc8ff5f20fa059b92f4ca91. --- src/components/Modal/BaseModal.tsx | 2 +- src/components/Modal/index.android.tsx | 2 +- .../{ComposerFocusManagerRename.js => ComposerFocusManager.js} | 0 src/libs/focusComposerWithDelay.ts | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) rename src/libs/{ComposerFocusManagerRename.js => ComposerFocusManager.js} (100%) diff --git a/src/components/Modal/BaseModal.tsx b/src/components/Modal/BaseModal.tsx index 356f7c5baa16..e428b062798f 100644 --- a/src/components/Modal/BaseModal.tsx +++ b/src/components/Modal/BaseModal.tsx @@ -4,7 +4,7 @@ import ReactNativeModal from 'react-native-modal'; import {useSafeAreaInsets} from 'react-native-safe-area-context'; import usePrevious from '@hooks/usePrevious'; import useWindowDimensions from '@hooks/useWindowDimensions'; -import ComposerFocusManager from '@libs/ComposerFocusManagerRename'; +import ComposerFocusManager from '@libs/ComposerFocusManager'; import useNativeDriver from '@libs/useNativeDriver'; import getModalStyles from '@styles/getModalStyles'; import styles from '@styles/styles'; diff --git a/src/components/Modal/index.android.tsx b/src/components/Modal/index.android.tsx index 3486e414d8c2..2343cb4c70a9 100644 --- a/src/components/Modal/index.android.tsx +++ b/src/components/Modal/index.android.tsx @@ -1,7 +1,7 @@ import React from 'react'; import {AppState} from 'react-native'; import withWindowDimensions from '@components/withWindowDimensions'; -import ComposerFocusManager from '@libs/ComposerFocusManagerRename'; +import ComposerFocusManager from '@libs/ComposerFocusManager'; import BaseModal from './BaseModal'; import BaseModalProps from './types'; diff --git a/src/libs/ComposerFocusManagerRename.js b/src/libs/ComposerFocusManager.js similarity index 100% rename from src/libs/ComposerFocusManagerRename.js rename to src/libs/ComposerFocusManager.js diff --git a/src/libs/focusComposerWithDelay.ts b/src/libs/focusComposerWithDelay.ts index 788e1025c06b..19f1050d24bd 100644 --- a/src/libs/focusComposerWithDelay.ts +++ b/src/libs/focusComposerWithDelay.ts @@ -1,6 +1,6 @@ import {TextInput} from 'react-native'; import * as EmojiPickerAction from './actions/EmojiPickerAction'; -import ComposerFocusManager from './ComposerFocusManagerRename'; +import ComposerFocusManager from './ComposerFocusManager'; type FocusComposerWithDelay = (shouldDelay?: boolean) => void; /** From 839c07f65f3aa1f32fb47767708b3500cf1d9597 Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Wed, 15 Nov 2023 18:12:09 +0100 Subject: [PATCH 210/212] Add a dot at the end of the error message --- .github/workflows/typecheck.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/typecheck.yml b/.github/workflows/typecheck.yml index fae744b66ba0..cdb95bd66779 100644 --- a/.github/workflows/typecheck.yml +++ b/.github/workflows/typecheck.yml @@ -26,6 +26,6 @@ jobs: git fetch origin main --no-tags --depth=1 count_new_js=$(git diff --name-only --diff-filter=A origin/main HEAD -- 'src/libs/*.js' 'src/hooks/*.js' 'src/styles/*.js' 'src/languages/*.js' | wc -l) if [ "$count_new_js" -gt "0" ]; then - echo "ERROR: Found new JavaScript files in the /src/libs, /src/hooks, /src/styles, or /src/languages directories; use TypeScript instead" + echo "ERROR: Found new JavaScript files in the /src/libs, /src/hooks, /src/styles, or /src/languages directories; use TypeScript instead." exit 1 fi From b79391ecbac85fe89dba8470f2d19edf69d75b9a Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Wed, 15 Nov 2023 18:12:37 +0100 Subject: [PATCH 211/212] Test adding a file in a nested directory --- src/styles/addOutlineWidth/test.js | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 src/styles/addOutlineWidth/test.js diff --git a/src/styles/addOutlineWidth/test.js b/src/styles/addOutlineWidth/test.js new file mode 100644 index 000000000000..ef7ebe89ed2c --- /dev/null +++ b/src/styles/addOutlineWidth/test.js @@ -0,0 +1,3 @@ +const x = 'test '; + +export default x; From 4acc1df5e27c2142b567d1263b2cb8ed47944f80 Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Wed, 15 Nov 2023 18:21:28 +0100 Subject: [PATCH 212/212] Revert "Test adding a file in a nested directory" This reverts commit b79391ecbac85fe89dba8470f2d19edf69d75b9a. --- src/styles/addOutlineWidth/test.js | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 src/styles/addOutlineWidth/test.js diff --git a/src/styles/addOutlineWidth/test.js b/src/styles/addOutlineWidth/test.js deleted file mode 100644 index ef7ebe89ed2c..000000000000 --- a/src/styles/addOutlineWidth/test.js +++ /dev/null @@ -1,3 +0,0 @@ -const x = 'test '; - -export default x;