studiokit-scaffolding-js 7.0.14-alpha.1 → 7.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/components/ActionList.d.ts +2 -2
- package/lib/components/ActionList.js +166 -87
- package/lib/components/AlertDialog.d.ts +3 -3
- package/lib/components/AlertDialog.js +133 -18
- package/lib/components/AlertWithIcon.js +93 -52
- package/lib/components/ConnectedModal.d.ts +1 -2
- package/lib/components/ConnectedModal.js +41 -35
- package/lib/components/Dropdowns/GroupsDropdown.d.ts +4 -4
- package/lib/components/Dropdowns/GroupsDropdown.js +69 -82
- package/lib/components/Dropdowns/ManagedNavDropdown.d.ts +2 -2
- package/lib/components/Dropdowns/ManagedNavDropdown.js +96 -108
- package/lib/components/Dropdowns/UserDropdown.js +109 -70
- package/lib/components/Dropdowns/index.js +27 -11
- package/lib/components/EntityOwnerList.d.ts +3 -3
- package/lib/components/EntityOwnerList.js +52 -60
- package/lib/components/Error.js +107 -27
- package/lib/components/ErrorBoundary.js +133 -94
- package/lib/components/ErrorMessage.d.ts +2 -2
- package/lib/components/ErrorMessage.js +44 -14
- package/lib/components/Forms/DateField.d.ts +2 -2
- package/lib/components/Forms/DateField.js +63 -95
- package/lib/components/Forms/TimeField.d.ts +2 -2
- package/lib/components/Forms/TimeField.js +84 -108
- package/lib/components/Forms/index.js +27 -13
- package/lib/components/Groups/CreateEditCopySaveButtons.d.ts +2 -2
- package/lib/components/Groups/CreateEditCopySaveButtons.js +102 -14
- package/lib/components/Groups/ExternalGroups/Attach.d.ts +6 -7
- package/lib/components/Groups/ExternalGroups/Attach.js +213 -188
- package/lib/components/Groups/ExternalGroups/Table.js +183 -76
- package/lib/components/Groups/GroupCreateOrEditCommonProps.js +5 -1
- package/lib/components/Groups/RosterSyncInfo.js +140 -49
- package/lib/components/HOC/AccessibleAppComponent.d.ts +2 -2
- package/lib/components/HOC/AccessibleAppComponent.js +96 -119
- package/lib/components/HOC/ActivityRequiredComponent.d.ts +14 -14
- package/lib/components/HOC/ActivityRequiredComponent.js +72 -86
- package/lib/components/HOC/AsyncComponent.d.ts +9 -9
- package/lib/components/HOC/AsyncComponent.js +53 -129
- package/lib/components/HOC/AuthenticatedComponent.d.ts +4 -4
- package/lib/components/HOC/AuthenticatedComponent.js +59 -96
- package/lib/components/HOC/CollectionComponent.d.ts +12 -12
- package/lib/components/HOC/CollectionComponent.js +161 -161
- package/lib/components/HOC/CollectionFirstItemComponent.d.ts +13 -13
- package/lib/components/HOC/CollectionFirstItemComponent.js +49 -91
- package/lib/components/HOC/CollectionItemComponent.d.ts +9 -9
- package/lib/components/HOC/CollectionItemComponent.js +159 -158
- package/lib/components/HOC/ConnectedModalComponent.d.ts +9 -9
- package/lib/components/HOC/ConnectedModalComponent.js +96 -126
- package/lib/components/HOC/DataDependentComponent.d.ts +3 -55
- package/lib/components/HOC/DataDependentComponent.js +30 -79
- package/lib/components/HOC/EntityComponent.d.ts +13 -13
- package/lib/components/HOC/EntityComponent.js +63 -101
- package/lib/components/HOC/FullscreenModalComponent.d.ts +9 -9
- package/lib/components/HOC/FullscreenModalComponent.js +145 -165
- package/lib/components/HOC/GroupActivityRequiredComponent.d.ts +2 -2
- package/lib/components/HOC/GroupActivityRequiredComponent.js +32 -31
- package/lib/components/HOC/GuidComponent.d.ts +1 -1
- package/lib/components/HOC/GuidComponent.js +25 -64
- package/lib/components/HOC/ModelContextDependencyVerifyComponent.d.ts +28 -29
- package/lib/components/HOC/ModelContextDependencyVerifyComponent.js +36 -59
- package/lib/components/HOC/ModelErrorRedirectComponent.d.ts +10 -10
- package/lib/components/HOC/ModelErrorRedirectComponent.js +40 -83
- package/lib/components/HOC/SearchPersistorComponent.d.ts +4 -4
- package/lib/components/HOC/SearchPersistorComponent.js +243 -216
- package/lib/components/HOC/UnauthenticatedComponent.d.ts +12 -12
- package/lib/components/HOC/UnauthenticatedComponent.js +37 -82
- package/lib/components/HOC/UserComponent.d.ts +1 -1
- package/lib/components/HOC/UserComponent.js +12 -11
- package/lib/components/Icons/IconAlphaList.js +34 -20
- package/lib/components/Icons/IconExternalUser.js +34 -20
- package/lib/components/Icons/IconImpersonation.js +34 -20
- package/lib/components/Icons/IconStopImpersonating.js +34 -20
- package/lib/components/Icons/IconTable.js +35 -21
- package/lib/components/Icons/IconTableDeleteCol.js +34 -20
- package/lib/components/Icons/IconTableDeleteRow.js +34 -20
- package/lib/components/Icons/IconTableInsertCol.js +34 -20
- package/lib/components/Icons/IconTableInsertRow.js +34 -20
- package/lib/components/Impersonation/Button.d.ts +2 -2
- package/lib/components/Impersonation/Button.js +76 -56
- package/lib/components/Impersonation/Link.d.ts +2 -2
- package/lib/components/Impersonation/Link.js +76 -53
- package/lib/components/Impersonation/UserDetail.d.ts +2 -2
- package/lib/components/Impersonation/UserDetail.js +64 -15
- package/lib/components/Loading.js +27 -21
- package/lib/components/LockDownBrowser/Check.js +194 -107
- package/lib/components/LockDownBrowser/ExitButton.js +27 -14
- package/lib/components/LockDownBrowser/Launch.js +70 -85
- package/lib/components/Lti/Confirm.js +152 -33
- package/lib/components/Lti/CreateNonLtiGroupAlertDialog.d.ts +4 -2
- package/lib/components/Lti/CreateNonLtiGroupAlertDialog.js +170 -78
- package/lib/components/Lti/Launch.js +105 -49
- package/lib/components/Lti/LaunchGroup.js +85 -39
- package/lib/components/ManageTable.d.ts +1 -2
- package/lib/components/ManageTable.js +309 -104
- package/lib/components/ManageTableNoDataComponent.js +42 -22
- package/lib/components/NewVersionAlert.d.ts +2 -2
- package/lib/components/NewVersionAlert.js +82 -91
- package/lib/components/NotFound.js +87 -28
- package/lib/components/Notifications.d.ts +4 -4
- package/lib/components/Notifications.js +187 -169
- package/lib/components/PaginationNextButton.js +33 -21
- package/lib/components/PaginationPreviousButton.js +33 -21
- package/lib/components/Quill/CustomToolbar.d.ts +2 -2
- package/lib/components/Quill/CustomToolbar.js +432 -257
- package/lib/components/Quill/Formats/Image.d.ts +10 -25
- package/lib/components/Quill/Formats/Image.js +76 -82
- package/lib/components/Quill/Formats/List.d.ts +6 -3
- package/lib/components/Quill/Formats/List.js +50 -72
- package/lib/components/Quill/Formats/Video.d.ts +2 -1
- package/lib/components/Quill/Formats/Video.js +29 -43
- package/lib/components/Quill/ImageDropModule.d.ts +1 -1
- package/lib/components/Quill/ImageDropModule.js +142 -115
- package/lib/components/Quill/ImageWarning.d.ts +2 -2
- package/lib/components/Quill/ImageWarning.js +45 -32
- package/lib/components/Quill/ImageWithAltTextModal.d.ts +0 -1
- package/lib/components/Quill/ImageWithAltTextModal.js +425 -141
- package/lib/components/Quill/Specs/CustomImageSpec.d.ts +1 -1
- package/lib/components/Quill/Specs/CustomImageSpec.js +37 -45
- package/lib/components/Quill/Specs/CustomVideoSpec.d.ts +1 -1
- package/lib/components/Quill/Specs/CustomVideoSpec.js +27 -36
- package/lib/components/Quill/TableModule/Blots/BaseTableBlot.d.ts +2 -1
- package/lib/components/Quill/TableModule/Blots/BaseTableBlot.js +100 -116
- package/lib/components/Quill/TableModule/Blots/TableBlot.js +53 -66
- package/lib/components/Quill/TableModule/Blots/TableBodyBlot.js +54 -67
- package/lib/components/Quill/TableModule/Blots/TableCellBlot.d.ts +1 -1
- package/lib/components/Quill/TableModule/Blots/TableCellBlot.js +225 -241
- package/lib/components/Quill/TableModule/Blots/TableContainer.js +82 -99
- package/lib/components/Quill/TableModule/Blots/TableRowBlot.js +76 -87
- package/lib/components/Quill/TableModule/constants.js +45 -41
- package/lib/components/Quill/TableModule/index.css +25 -25
- package/lib/components/Quill/TableModule/index.d.ts +14 -5
- package/lib/components/Quill/TableModule/index.js +373 -313
- package/lib/components/Quill/TableModule/utils.js +45 -45
- package/lib/components/Quill/accessibilityFix.d.ts +0 -1
- package/lib/components/Quill/accessibilityFix.js +222 -238
- package/lib/components/Quill/index.js +36 -32
- package/lib/components/RefreshIndicator/Bordered.js +48 -32
- package/lib/components/RefreshIndicator/Inline.js +48 -33
- package/lib/components/RefreshIndicator/index.d.ts +2 -2
- package/lib/components/RefreshIndicator/index.js +263 -113
- package/lib/components/SearchControls.js +216 -31
- package/lib/components/SentryRoute.js +10 -23
- package/lib/components/Tables/RoleFilter.d.ts +3 -4
- package/lib/components/Tables/RoleFilter.js +71 -46
- package/lib/components/Tables/TextFilter.d.ts +2 -3
- package/lib/components/Tables/TextFilter.js +62 -20
- package/lib/components/UserRoles/Add.d.ts +3 -3
- package/lib/components/UserRoles/Add.js +199 -161
- package/lib/components/UserRoles/Context.js +8 -6
- package/lib/components/UserRoles/RoleCell.js +181 -100
- package/lib/components/UserRoles/Select.js +168 -54
- package/lib/components/UserRoles/Table.js +221 -102
- package/lib/components/UserRoles/index.d.ts +6 -6
- package/lib/components/UserRoles/index.js +535 -464
- package/lib/config/eslint/index.d.ts +2 -0
- package/lib/config/eslint/index.js +36 -0
- package/lib/config/eslint/lib/order.d.ts +3 -0
- package/lib/config/eslint/lib/order.js +30 -0
- package/lib/config/eslint/lib/prettier.d.ts +3 -0
- package/lib/config/eslint/lib/prettier.js +23 -0
- package/lib/config/eslint/lib/typescript.d.ts +2 -0
- package/lib/config/eslint/lib/typescript.js +98 -0
- package/lib/config/eslint/react.d.ts +2 -0
- package/lib/config/eslint/react.js +30 -0
- package/lib/constants/baseActivity.js +30 -26
- package/lib/constants/baseRole.js +14 -10
- package/lib/constants/configuration.d.ts +1 -1
- package/lib/constants/configuration.js +43 -39
- package/lib/constants/externalProviderType.js +10 -6
- package/lib/constants/fetchErrorData.js +15 -11
- package/lib/constants/index.js +137 -23
- package/lib/constants/lockDownBrowser.js +28 -24
- package/lib/constants/mockData.d.ts +4 -6
- package/lib/constants/mockData.js +383 -324
- package/lib/constants/modelStatus.js +15 -11
- package/lib/constants/notificationType.js +12 -8
- package/lib/constants/operatingSystem.js +12 -8
- package/lib/constants/shard.js +11 -7
- package/lib/constants/table.js +21 -21
- package/lib/constants/tier.js +12 -8
- package/lib/constants/userRole.d.ts +1 -2
- package/lib/constants/userRole.js +15 -17
- package/lib/css/components/_buttons.css +11 -3
- package/lib/css/components/_quill.css +3 -3
- package/lib/css/components/_tables.css +6 -5
- package/lib/css/utils/_display.css +12 -19
- package/lib/css/utils/_general.css +1 -1
- package/lib/css/utils/_text.css +2 -1
- package/lib/css/variables.css +0 -4
- package/lib/endpointMappings.js +197 -193
- package/lib/hooks/useCollection.js +83 -65
- package/lib/hooks/useCollectionConfiguration.d.ts +0 -1
- package/lib/hooks/useCollectionConfiguration.js +179 -82
- package/lib/hooks/useCollectionItem.js +155 -58
- package/lib/hooks/useEventCalback.d.ts +14 -0
- package/lib/hooks/useEventCalback.js +51 -0
- package/lib/hooks/useGuid.js +19 -8
- package/lib/hooks/usePrevious.d.ts +24 -1
- package/lib/hooks/usePrevious.js +82 -12
- package/lib/index.js +156 -36
- package/lib/redux/actionCreator.d.ts +6 -6
- package/lib/redux/actionCreator.js +51 -40
- package/lib/redux/actions/AuthAction.js +44 -31
- package/lib/redux/actions/ModalAction.d.ts +1 -1
- package/lib/redux/actions/ModalAction.js +10 -6
- package/lib/redux/actions/ModelAction.d.ts +1 -1
- package/lib/redux/actions/ModelAction.js +77 -49
- package/lib/redux/actions/NotificationAction.js +10 -6
- package/lib/redux/actions/SearchAction.js +9 -5
- package/lib/redux/actions/index.js +60 -16
- package/lib/redux/configureReducers.d.ts +2 -5
- package/lib/redux/configureReducers.js +61 -72
- package/lib/redux/configureStore.d.ts +2 -2
- package/lib/redux/configureStore.js +83 -115
- package/lib/redux/helpers.js +7 -2
- package/lib/redux/reducers/authReducer.js +50 -44
- package/lib/redux/reducers/index.js +41 -15
- package/lib/redux/reducers/modalsReducer.js +49 -52
- package/lib/redux/reducers/modelsReducer.d.ts +2 -2
- package/lib/redux/reducers/modelsReducer.js +136 -135
- package/lib/redux/reducers/notificationsReducer.js +26 -21
- package/lib/redux/reducers/searchReducer.js +18 -12
- package/lib/redux/sagas/appInsightsSaga.js +24 -62
- package/lib/redux/sagas/authSaga.js +287 -414
- package/lib/redux/sagas/caliperSaga.js +154 -248
- package/lib/redux/sagas/clockOffsetSaga.js +35 -76
- package/lib/redux/sagas/configurationSaga.js +13 -46
- package/lib/redux/sagas/downtimeApiErrorSaga.d.ts +0 -1
- package/lib/redux/sagas/downtimeApiErrorSaga.js +23 -64
- package/lib/redux/sagas/errorSaga.d.ts +0 -1
- package/lib/redux/sagas/errorSaga.js +29 -63
- package/lib/redux/sagas/googleAnalyticsSaga.js +29 -69
- package/lib/redux/sagas/identityProviderSaga.js +24 -69
- package/lib/redux/sagas/initialDataLoadSaga.js +38 -29
- package/lib/redux/sagas/lockDownBrowserErrorSaga.d.ts +0 -1
- package/lib/redux/sagas/lockDownBrowserErrorSaga.js +32 -81
- package/lib/redux/sagas/modelFetchSaga.js +331 -411
- package/lib/redux/sagas/noStoreSaga.d.ts +1 -1
- package/lib/redux/sagas/noStoreSaga.js +68 -101
- package/lib/redux/sagas/postLoginDataSaga.js +42 -74
- package/lib/redux/sagas/postLoginRedirectSaga.js +27 -68
- package/lib/redux/sagas/rootSaga.js +85 -137
- package/lib/redux/sagas/sentrySaga.js +29 -85
- package/lib/redux/sagas/userIdSaga.js +18 -54
- package/lib/services/codeProviderService.js +25 -29
- package/lib/services/dateService.js +12 -10
- package/lib/services/documentService.js +15 -10
- package/lib/services/fetchService.js +110 -144
- package/lib/services/persistenceService.d.ts +4 -4
- package/lib/services/persistenceService.js +45 -43
- package/lib/services/ticketProviderService.js +29 -33
- package/lib/services/tokenPersistenceService.js +13 -9
- package/lib/services/windowService.js +21 -17
- package/lib/startup.d.ts +1 -1
- package/lib/startup.js +115 -118
- package/lib/types/AppConfiguration.js +5 -1
- package/lib/types/Artifact.js +11 -7
- package/lib/types/BaseReduxState.js +5 -1
- package/lib/types/Client.js +5 -1
- package/lib/types/Collection.d.ts +3 -3
- package/lib/types/Collection.js +5 -1
- package/lib/types/Configuration.js +5 -1
- package/lib/types/DeepLinkingResponseRequest.js +5 -1
- package/lib/types/DeletableModel.js +5 -1
- package/lib/types/Event.js +5 -1
- package/lib/types/ExternalGroup.js +5 -1
- package/lib/types/ExternalProvider.js +5 -1
- package/lib/types/ExternalTerm.js +5 -1
- package/lib/types/Group.js +5 -1
- package/lib/types/IdentityProvider.js +5 -1
- package/lib/types/LtiLaunch.js +5 -1
- package/lib/types/NameOnlyEntity.js +5 -1
- package/lib/types/Notification.d.ts +2 -2
- package/lib/types/Notification.js +5 -1
- package/lib/types/OptionalRecord.d.ts +1 -1
- package/lib/types/OptionalRecord.js +5 -1
- package/lib/types/OwnerSchedule.d.ts +3 -1
- package/lib/types/OwnerSchedule.js +5 -1
- package/lib/types/PropertyOfType.d.ts +3 -3
- package/lib/types/PropertyOfType.js +5 -1
- package/lib/types/Quill.js +5 -1
- package/lib/types/RoleDescription.d.ts +0 -1
- package/lib/types/RoleDescription.js +5 -1
- package/lib/types/Search.js +5 -1
- package/lib/types/SimpleLocation.js +5 -1
- package/lib/types/UniTime.js +5 -1
- package/lib/types/User.js +5 -1
- package/lib/types/UserRole.js +5 -1
- package/lib/types/auth/AuthState.js +5 -1
- package/lib/types/auth/CasV1LoginRequestBody.js +5 -1
- package/lib/types/auth/ClientCredentials.js +5 -1
- package/lib/types/auth/CodeProviderService.js +5 -1
- package/lib/types/auth/LocalLoginRequestBody.js +5 -1
- package/lib/types/auth/TicketProviderService.js +5 -1
- package/lib/types/auth/TokenPersistenceService.js +5 -1
- package/lib/types/auth/index.js +82 -18
- package/lib/types/externals.d.js +2 -0
- package/lib/types/index.js +313 -39
- package/lib/types/net/EndpointConfig.js +5 -1
- package/lib/types/net/EndpointMapping.js +5 -1
- package/lib/types/net/EndpointMappings.js +5 -1
- package/lib/types/net/ErrorHandler.d.ts +1 -1
- package/lib/types/net/ErrorHandler.js +5 -1
- package/lib/types/net/FetchConfig.d.ts +1 -1
- package/lib/types/net/FetchConfig.js +5 -1
- package/lib/types/net/FetchErrorData.js +10 -6
- package/lib/types/net/FetchResult.d.ts +2 -2
- package/lib/types/net/FetchResult.js +5 -1
- package/lib/types/net/HTTPMethod.d.ts +1 -1
- package/lib/types/net/HTTPMethod.js +5 -1
- package/lib/types/net/HTTPStatusCode.js +16 -12
- package/lib/types/net/Metadata.js +5 -1
- package/lib/types/net/Model.js +5 -1
- package/lib/types/net/ModelCollection.js +5 -1
- package/lib/types/net/ModelsState.js +5 -1
- package/lib/types/net/OAuthToken.js +5 -1
- package/lib/types/net/OAuthTokenOrNull.d.ts +1 -1
- package/lib/types/net/OAuthTokenOrNull.js +5 -1
- package/lib/types/net/TokenAccessFunction.d.ts +1 -1
- package/lib/types/net/TokenAccessFunction.js +5 -1
- package/lib/types/net/index.js +181 -27
- package/lib/utils/baseActivity.d.ts +2 -2
- package/lib/utils/baseActivity.js +93 -91
- package/lib/utils/baseRole.js +37 -33
- package/lib/utils/collection.js +413 -291
- package/lib/utils/cookies.js +22 -37
- package/lib/utils/date.js +210 -210
- package/lib/utils/dom.js +145 -133
- package/lib/utils/domainIdentifier.js +9 -9
- package/lib/utils/entityUserRole.js +6 -2
- package/lib/utils/error.d.ts +1 -1
- package/lib/utils/error.js +18 -16
- package/lib/utils/events.js +37 -30
- package/lib/utils/externalGroup.js +25 -21
- package/lib/utils/externalProviders.js +8 -4
- package/lib/utils/externalTerms.js +9 -6
- package/lib/utils/fetch.d.ts +1 -1
- package/lib/utils/fetch.js +179 -176
- package/lib/utils/group.js +17 -9
- package/lib/utils/groupDates.d.ts +1 -1
- package/lib/utils/groupDates.js +43 -39
- package/lib/utils/groupRoles.js +28 -28
- package/lib/utils/lockDownBrowser.js +16 -12
- package/lib/utils/logger.js +30 -25
- package/lib/utils/lti.js +10 -5
- package/lib/utils/model.d.ts +2 -2
- package/lib/utils/model.js +35 -44
- package/lib/utils/number.js +13 -16
- package/lib/utils/promise.d.ts +6 -1
- package/lib/utils/promise.js +34 -15
- package/lib/utils/quill.js +60 -71
- package/lib/utils/route.d.ts +2 -2
- package/lib/utils/route.js +61 -60
- package/lib/utils/search.d.ts +1 -1
- package/lib/utils/search.js +78 -85
- package/lib/utils/shard.js +38 -41
- package/lib/utils/sort.d.ts +3 -3
- package/lib/utils/sort.js +62 -58
- package/lib/utils/string.js +14 -10
- package/lib/utils/table.d.ts +3 -3
- package/lib/utils/table.js +36 -33
- package/lib/utils/timezone.js +12 -26
- package/lib/utils/url.d.ts +2 -1
- package/lib/utils/url.js +139 -193
- package/lib/utils/user.js +59 -61
- package/lib/utils/userAgent.js +11 -11
- package/lib/utils/userRole.d.ts +3 -3
- package/lib/utils/userRole.js +46 -44
- package/package.json +90 -73
- package/lib/config/eslint/index.cjs +0 -21
- package/lib/config/eslint/lib/order.cjs +0 -22
- package/lib/config/eslint/lib/prettier.cjs +0 -18
- package/lib/config/eslint/lib/typescript.cjs +0 -86
- package/lib/config/eslint/react.cjs +0 -9
- package/lib/css/utils/_focus.css +0 -4
|
@@ -1,320 +1,380 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
3
7
|
exports.TableModule = void 0;
|
|
4
|
-
var
|
|
5
|
-
var
|
|
6
|
-
var
|
|
7
|
-
var
|
|
8
|
-
var
|
|
9
|
-
var
|
|
10
|
-
var
|
|
11
|
-
var
|
|
12
|
-
var
|
|
13
|
-
var
|
|
14
|
-
var
|
|
15
|
-
var
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
if (context.offset === 0 && utils_1.isLineAfterTable(line)) {
|
|
40
|
-
logger_1.getLogger().debug('prevent backspace after table', { range: range, context: context, line: line });
|
|
41
|
-
return false;
|
|
42
|
-
}
|
|
43
|
-
// if inside a TableCellBlot and at the start of the cell
|
|
44
|
-
// prevent "backspace" from removing previous cell
|
|
45
|
-
// or items before the table if in the first cell
|
|
46
|
-
if (
|
|
47
|
-
// in a cell
|
|
48
|
-
utils_1.isLineInTableCell(line) &&
|
|
49
|
-
// at the start of the cell
|
|
50
|
-
context.offset === 0 &&
|
|
51
|
-
!line.prev &&
|
|
52
|
-
// there is a cell before this one in the row
|
|
53
|
-
((line.parent.prev && line.parent.prev instanceof TableCellBlot_1.TableCellBlot) ||
|
|
54
|
-
// or the cell is at the start of a row
|
|
55
|
-
!line.parent.prev)) {
|
|
56
|
-
logger_1.getLogger().debug('prevent cell backspace', { range: range, context: context, line: line });
|
|
57
|
-
return false;
|
|
58
|
-
}
|
|
59
|
-
return true;
|
|
60
|
-
};
|
|
61
|
-
this.handleDelete = function (range, context) {
|
|
62
|
-
var length = /^[\uD800-\uDBFF][\uDC00-\uDFFF]/.test(context.suffix) ? 2 : 1;
|
|
63
|
-
if (range.index >= _this.quill.getLength() - length)
|
|
64
|
-
return true;
|
|
65
|
-
var line = _this.quill.getLine(range.index)[0];
|
|
66
|
-
if (context.offset === line.length() - 1 && utils_1.isLineBeforeTable(line)) {
|
|
67
|
-
logger_1.getLogger().debug('prevent delete before table', { range: range, context: context, line: line });
|
|
68
|
-
return false;
|
|
69
|
-
}
|
|
70
|
-
// if inside a TableCellBlot and at the end of the cell
|
|
71
|
-
// prevent "delete" from removing the next cell
|
|
72
|
-
// or items after the table if in the last cell
|
|
73
|
-
if (
|
|
74
|
-
// in a cell
|
|
75
|
-
utils_1.isLineInTableCell(line) &&
|
|
76
|
-
// at the end of the cell
|
|
77
|
-
!line.next &&
|
|
78
|
-
context.offset === line.length() - 1 &&
|
|
79
|
-
// there is a cell after this one in the row
|
|
80
|
-
((line.parent.next && line.parent.next instanceof TableCellBlot_1.TableCellBlot) ||
|
|
81
|
-
// or the cell is at the start of a row
|
|
82
|
-
!line.parent.next)) {
|
|
83
|
-
logger_1.getLogger().debug('prevent cell delete', { range: range, context: context, line: line });
|
|
84
|
-
return false;
|
|
85
|
-
}
|
|
86
|
-
return true;
|
|
87
|
-
};
|
|
88
|
-
this.handleDeleteRange = function (range) {
|
|
89
|
-
var lines = _this.quill.getLines(range);
|
|
90
|
-
logger_1.getLogger().debug('handleDeleteRange', { range: range, lines: lines });
|
|
91
|
-
var willDeleteCellWithoutRow = utils_1.rangeRemovalWillDeleteCellWithoutRow(_this.quill, range);
|
|
92
|
-
if (willDeleteCellWithoutRow) {
|
|
93
|
-
logger_1.getLogger().debug('prevent delete cell out of row');
|
|
94
|
-
}
|
|
95
|
-
return !willDeleteCellWithoutRow;
|
|
96
|
-
};
|
|
97
|
-
this.quill = quill;
|
|
98
|
-
this.options = options;
|
|
99
|
-
// Define Toolbar Handler
|
|
100
|
-
var toolbar = quill.getModule('toolbar');
|
|
101
|
-
if (toolbar) {
|
|
102
|
-
toolbar.addHandler('table', function (action) {
|
|
103
|
-
return _this.tableHandler(action);
|
|
104
|
-
});
|
|
105
|
-
// by default, hide all table controls
|
|
106
|
-
toolbar.controls.forEach(function (control) {
|
|
107
|
-
var name = control[0], domNode = control[1];
|
|
108
|
-
if (name === 'table' && domNode.tagName === 'BUTTON') {
|
|
109
|
-
_this.tableToolbarControls.push(domNode);
|
|
110
|
-
domNode.classList.add('dn');
|
|
111
|
-
}
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
this.quill.on('editor-change', this.showOrHideToolbarControls);
|
|
115
|
-
this.quill.on('selection-change', this.showOrHideToolbarControls);
|
|
116
|
-
// Define Clipboard Matchers
|
|
117
|
-
// When HTML is loaded or pasted into Quill, the matchers
|
|
118
|
-
// will find the given HTML Tag and allow the delta for the element's
|
|
119
|
-
// content to be modified.
|
|
120
|
-
var clipboard = quill.getModule('clipboard');
|
|
121
|
-
if (clipboard) {
|
|
122
|
-
clipboard.addMatcher(constants_1.TAG_NAME.TD, function (node, delta) {
|
|
123
|
-
logger_1.getLogger().debug(constants_1.TAG_NAME.TD + " matched", { node: node, delta: delta });
|
|
124
|
-
// load the table cell attribute to use as the delta operation attributes
|
|
125
|
-
var dataValue = node.getAttribute(constants_1.ATTRIBUTE.DATA_VALUE);
|
|
126
|
-
var defaultAttributes = {
|
|
127
|
-
td: dataValue
|
|
128
|
-
};
|
|
129
|
-
// handle empty cells, insert a single block / paragraph
|
|
130
|
-
if (delta.length() === 0) {
|
|
131
|
-
var updatedDelta_1 = new Delta().insert('\n', defaultAttributes);
|
|
132
|
-
logger_1.getLogger().debug(constants_1.TAG_NAME.TD + " matched - final delta (empty cell)", updatedDelta_1);
|
|
133
|
-
return updatedDelta_1;
|
|
134
|
-
}
|
|
135
|
-
// for each operation inside the cell's delta, add the table cell attributes
|
|
136
|
-
var updatedDelta = delta.reduce(function (newDelta, op) {
|
|
137
|
-
newDelta.insert(op.insert, lodash_1.merge({}, op.attributes, defaultAttributes));
|
|
138
|
-
return newDelta;
|
|
139
|
-
}, new Delta());
|
|
140
|
-
logger_1.getLogger().debug(constants_1.TAG_NAME.TD + " matched - final delta", updatedDelta);
|
|
141
|
-
return updatedDelta;
|
|
142
|
-
});
|
|
143
|
-
}
|
|
144
|
-
// Override "backspace" and "delete" actions that would delete or combine a table cell
|
|
145
|
-
var keyboard = quill.getModule('keyboard');
|
|
146
|
-
if (keyboard) {
|
|
147
|
-
keyboard.addBinding({ key: constants_1.KEY.BACKSPACE, altKey: null, ctrlKey: null, metaKey: null, shiftKey: null }, { collapsed: true, offset: 0 }, this.handleBackspace);
|
|
148
|
-
// move binding to first position
|
|
149
|
-
var backspaceOtherBinding = keyboard.bindings[constants_1.KEY.BACKSPACE].pop();
|
|
150
|
-
keyboard.bindings[constants_1.KEY.BACKSPACE].splice(0, 0, backspaceOtherBinding);
|
|
151
|
-
keyboard.addBinding({ key: constants_1.KEY.BACKSPACE }, { collapsed: false }, this.handleDeleteRange);
|
|
152
|
-
// move binding to first position
|
|
153
|
-
var backspaceRangeBinding = keyboard.bindings[constants_1.KEY.BACKSPACE].pop();
|
|
154
|
-
keyboard.bindings[constants_1.KEY.BACKSPACE].splice(0, 0, backspaceRangeBinding);
|
|
155
|
-
keyboard.addBinding({ key: constants_1.KEY.BACKSPACE }, { collapsed: true }, this.handleBackspace);
|
|
156
|
-
// move binding to first position
|
|
157
|
-
var backspaceBinding = keyboard.bindings[constants_1.KEY.BACKSPACE].pop();
|
|
158
|
-
keyboard.bindings[constants_1.KEY.BACKSPACE].splice(0, 0, backspaceBinding);
|
|
159
|
-
keyboard.addBinding({ key: constants_1.KEY.DELETE }, { collapsed: false }, this.handleDeleteRange);
|
|
160
|
-
// move binding to first position
|
|
161
|
-
var deleteRangeBinding = keyboard.bindings[constants_1.KEY.DELETE].pop();
|
|
162
|
-
keyboard.bindings[constants_1.KEY.DELETE].splice(0, 0, deleteRangeBinding);
|
|
163
|
-
keyboard.addBinding({ key: constants_1.KEY.DELETE }, { collapsed: true, altKey: true }, this.handleDelete);
|
|
164
|
-
// move binding to first position
|
|
165
|
-
var deleteWithAltBinding = keyboard.bindings[constants_1.KEY.DELETE].pop();
|
|
166
|
-
keyboard.bindings[constants_1.KEY.DELETE].splice(0, 0, deleteWithAltBinding);
|
|
167
|
-
keyboard.addBinding({ key: constants_1.KEY.DELETE }, { collapsed: true }, this.handleDelete);
|
|
168
|
-
// move binding to first position
|
|
169
|
-
var deleteBinding = keyboard.bindings[constants_1.KEY.DELETE].pop();
|
|
170
|
-
keyboard.bindings[constants_1.KEY.DELETE].splice(0, 0, deleteBinding);
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
TableModule.register = function () {
|
|
174
|
-
react_quill_1.Quill.register(BaseTableBlot_1.BaseTableBlot);
|
|
175
|
-
react_quill_1.Quill.register(TableCellBlot_1.TableCellBlot);
|
|
176
|
-
react_quill_1.Quill.register(TableRowBlot_1.TableRowBlot);
|
|
177
|
-
react_quill_1.Quill.register(TableBodyBlot_1.TableBodyBlot);
|
|
178
|
-
react_quill_1.Quill.register(TableBlot_1.TableBlot);
|
|
179
|
-
react_quill_1.Quill.register(TableContainer_1.TableContainerBlot);
|
|
180
|
-
};
|
|
181
|
-
TableModule.prototype.getSelectedCell = function () {
|
|
182
|
-
var selection = this.quill.getSelection();
|
|
183
|
-
if (!selection) {
|
|
184
|
-
return null;
|
|
185
|
-
}
|
|
186
|
-
var leaf = this.quill.getLeaf(selection.index);
|
|
187
|
-
var blot = leaf[0];
|
|
188
|
-
while (blot && !(blot instanceof TableCellBlot_1.TableCellBlot) && blot.parent) {
|
|
189
|
-
blot = blot.parent;
|
|
190
|
-
}
|
|
191
|
-
if (blot instanceof TableCellBlot_1.TableCellBlot) {
|
|
192
|
-
return blot;
|
|
193
|
-
}
|
|
194
|
-
return null;
|
|
195
|
-
};
|
|
196
|
-
TableModule.prototype.getSelectedTable = function () {
|
|
197
|
-
var _a;
|
|
198
|
-
return (_a = this.getSelectedCell()) === null || _a === void 0 ? void 0 : _a.table();
|
|
199
|
-
};
|
|
200
|
-
//#endregion Helpers
|
|
201
|
-
//#region Table Handler
|
|
202
|
-
TableModule.prototype.tableHandler = function (action) {
|
|
203
|
-
logger_1.getLogger().debug('tableHandler', action);
|
|
204
|
-
// require a selection range
|
|
205
|
-
var range = this.quill.getSelection();
|
|
206
|
-
if (!range)
|
|
207
|
-
return;
|
|
208
|
-
if (action.includes(constants_1.TABLE_ACTION.NEW_TABLE)) {
|
|
209
|
-
this.addNewTable(action, range);
|
|
210
|
-
return;
|
|
211
|
-
}
|
|
212
|
-
// require a selected cell
|
|
213
|
-
var selectedCell = this.getSelectedCell();
|
|
214
|
-
if (!selectedCell)
|
|
215
|
-
return;
|
|
216
|
-
switch (action) {
|
|
217
|
-
case constants_1.TABLE_ACTION.INSERT_COL:
|
|
218
|
-
this.insertCol(selectedCell, range);
|
|
219
|
-
break;
|
|
220
|
-
case constants_1.TABLE_ACTION.INSERT_ROW:
|
|
221
|
-
this.insertRow(selectedCell, range);
|
|
222
|
-
break;
|
|
223
|
-
case constants_1.TABLE_ACTION.DELETE_COL:
|
|
224
|
-
this.deleteCol(selectedCell);
|
|
225
|
-
break;
|
|
226
|
-
case constants_1.TABLE_ACTION.DELETE_ROW:
|
|
227
|
-
this.deleteRow(selectedCell);
|
|
228
|
-
break;
|
|
229
|
-
}
|
|
230
|
-
};
|
|
231
|
-
TableModule.prototype.addNewTable = function (action, range) {
|
|
232
|
-
var index = range.index;
|
|
233
|
-
// e.g. "new-table-2-2"
|
|
234
|
-
var sizes = action.replace(constants_1.TABLE_ACTION.NEW_TABLE, '').split('_');
|
|
235
|
-
var rows = parseInt(sizes[0]);
|
|
236
|
-
var cols = parseInt(sizes[1]);
|
|
237
|
-
var tableContainer = TableContainer_1.TableContainerBlot.createWithChildren(rows, cols);
|
|
238
|
-
// insert the table into the top level scroll element
|
|
239
|
-
// before the current leaf's top level branch
|
|
240
|
-
// PREVENT NESTED TABLES
|
|
241
|
-
var topBranch = null;
|
|
242
|
-
var leaf = this.quill.getLeaf(index);
|
|
243
|
-
var blot = leaf[0];
|
|
244
|
-
while (blot && blot.parent && !(blot instanceof Scroll)) {
|
|
245
|
-
topBranch = blot;
|
|
246
|
-
blot = blot.parent;
|
|
247
|
-
}
|
|
248
|
-
if (!blot || !(blot instanceof Scroll))
|
|
249
|
-
return;
|
|
250
|
-
blot.insertBefore(tableContainer, topBranch || undefined);
|
|
251
|
-
this.quill.setSelection(tableContainer.offset(this.quill.scroll), 0, 'user');
|
|
252
|
-
};
|
|
253
|
-
TableModule.prototype.insertCol = function (selectedCell, range) {
|
|
254
|
-
var _a;
|
|
255
|
-
var selectedCellColumn = selectedCell.column();
|
|
256
|
-
var tableId = selectedCell.tableId();
|
|
257
|
-
var tableBody = (_a = selectedCell.row()) === null || _a === void 0 ? void 0 : _a.tableBody();
|
|
258
|
-
if (!tableBody)
|
|
259
|
-
return;
|
|
260
|
-
tableBody.children.forEach(function (child) {
|
|
261
|
-
var tableRow = child;
|
|
262
|
-
var rowId = tableRow.id();
|
|
263
|
-
var tableCell = TableCellBlot_1.TableCellBlot.createWithChildren(tableId, rowId);
|
|
264
|
-
var cells = tableRow.children.map(function (c) { return c; });
|
|
265
|
-
var nextColumnCell = cells.length > selectedCellColumn - 1 ? cells[selectedCellColumn] : undefined;
|
|
266
|
-
if (nextColumnCell) {
|
|
267
|
-
tableRow.insertBefore(tableCell, nextColumnCell);
|
|
268
|
-
}
|
|
269
|
-
else {
|
|
270
|
-
tableRow.appendChild(tableCell);
|
|
271
|
-
}
|
|
8
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
9
|
+
var _lodash = require("lodash");
|
|
10
|
+
var _reactQuill = require("react-quill");
|
|
11
|
+
var _logger = require("../../../utils/logger");
|
|
12
|
+
var _BaseTableBlot = require("./Blots/BaseTableBlot");
|
|
13
|
+
var _TableBlot = require("./Blots/TableBlot");
|
|
14
|
+
var _TableBodyBlot = require("./Blots/TableBodyBlot");
|
|
15
|
+
var _TableCellBlot = require("./Blots/TableCellBlot");
|
|
16
|
+
var _TableContainer = require("./Blots/TableContainer");
|
|
17
|
+
var _TableRowBlot = require("./Blots/TableRowBlot");
|
|
18
|
+
var _constants = require("./constants");
|
|
19
|
+
var _utils = require("./utils");
|
|
20
|
+
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
|
|
21
|
+
|
|
22
|
+
const Delta = _reactQuill.Quill.import('delta');
|
|
23
|
+
const Scroll = _reactQuill.Quill.import('blots/scroll');
|
|
24
|
+
class TableModule {
|
|
25
|
+
static register() {
|
|
26
|
+
_reactQuill.Quill.register(_BaseTableBlot.BaseTableBlot);
|
|
27
|
+
_reactQuill.Quill.register(_TableCellBlot.TableCellBlot);
|
|
28
|
+
_reactQuill.Quill.register(_TableRowBlot.TableRowBlot);
|
|
29
|
+
_reactQuill.Quill.register(_TableBodyBlot.TableBodyBlot);
|
|
30
|
+
_reactQuill.Quill.register(_TableBlot.TableBlot);
|
|
31
|
+
_reactQuill.Quill.register(_TableContainer.TableContainerBlot);
|
|
32
|
+
}
|
|
33
|
+
constructor(quill, options) {
|
|
34
|
+
(0, _defineProperty2.default)(this, "quill", void 0);
|
|
35
|
+
(0, _defineProperty2.default)(this, "options", void 0);
|
|
36
|
+
(0, _defineProperty2.default)(this, "tableToolbarControls", []);
|
|
37
|
+
//#region Helpers
|
|
38
|
+
(0, _defineProperty2.default)(this, "showOrHideToolbarControls", () => {
|
|
39
|
+
const selectedCell = this.getSelectedCell();
|
|
40
|
+
if (selectedCell) {
|
|
41
|
+
this.tableToolbarControls.forEach(domNode => {
|
|
42
|
+
domNode.classList.remove('dn');
|
|
272
43
|
});
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
44
|
+
} else {
|
|
45
|
+
this.tableToolbarControls.forEach(domNode => {
|
|
46
|
+
domNode.classList.add('dn');
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
(0, _defineProperty2.default)(this, "handleBackspace", (range, context) => {
|
|
51
|
+
if (range.index === 0 || this.quill.getLength() <= 1) return true;
|
|
52
|
+
const [line] = this.quill.getLine(range.index);
|
|
53
|
+
if (context.offset === 0 && (0, _utils.isLineAfterTable)(line)) {
|
|
54
|
+
(0, _logger.getLogger)().debug('prevent backspace after table', {
|
|
55
|
+
range,
|
|
56
|
+
context,
|
|
57
|
+
line
|
|
58
|
+
});
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
// if inside a TableCellBlot and at the start of the cell
|
|
62
|
+
// prevent "backspace" from removing previous cell
|
|
63
|
+
// or items before the table if in the first cell
|
|
64
|
+
if (
|
|
65
|
+
// in a cell
|
|
66
|
+
(0, _utils.isLineInTableCell)(line) &&
|
|
67
|
+
// at the start of the cell
|
|
68
|
+
context.offset === 0 && !line.prev && (
|
|
69
|
+
// there is a cell before this one in the row
|
|
70
|
+
line.parent.prev && line.parent.prev instanceof _TableCellBlot.TableCellBlot ||
|
|
71
|
+
// or the cell is at the start of a row
|
|
72
|
+
!line.parent.prev)) {
|
|
73
|
+
(0, _logger.getLogger)().debug('prevent cell backspace', {
|
|
74
|
+
range,
|
|
75
|
+
context,
|
|
76
|
+
line
|
|
77
|
+
});
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
return true;
|
|
81
|
+
});
|
|
82
|
+
(0, _defineProperty2.default)(this, "handleDelete", (range, context) => {
|
|
83
|
+
const length = /^[\uD800-\uDBFF][\uDC00-\uDFFF]/.test(context.suffix) ? 2 : 1;
|
|
84
|
+
if (range.index >= this.quill.getLength() - length) return true;
|
|
85
|
+
const [line] = this.quill.getLine(range.index);
|
|
86
|
+
if (context.offset === line.length() - 1 && (0, _utils.isLineBeforeTable)(line)) {
|
|
87
|
+
(0, _logger.getLogger)().debug('prevent delete before table', {
|
|
88
|
+
range,
|
|
89
|
+
context,
|
|
90
|
+
line
|
|
91
|
+
});
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
// if inside a TableCellBlot and at the end of the cell
|
|
95
|
+
// prevent "delete" from removing the next cell
|
|
96
|
+
// or items after the table if in the last cell
|
|
97
|
+
if (
|
|
98
|
+
// in a cell
|
|
99
|
+
(0, _utils.isLineInTableCell)(line) &&
|
|
100
|
+
// at the end of the cell
|
|
101
|
+
!line.next && context.offset === line.length() - 1 && (
|
|
102
|
+
// there is a cell after this one in the row
|
|
103
|
+
line.parent.next && line.parent.next instanceof _TableCellBlot.TableCellBlot ||
|
|
104
|
+
// or the cell is at the start of a row
|
|
105
|
+
!line.parent.next)) {
|
|
106
|
+
(0, _logger.getLogger)().debug('prevent cell delete', {
|
|
107
|
+
range,
|
|
108
|
+
context,
|
|
109
|
+
line
|
|
110
|
+
});
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
return true;
|
|
114
|
+
});
|
|
115
|
+
(0, _defineProperty2.default)(this, "handleDeleteRange", range => {
|
|
116
|
+
const lines = this.quill.getLines(range);
|
|
117
|
+
(0, _logger.getLogger)().debug('handleDeleteRange', {
|
|
118
|
+
range,
|
|
119
|
+
lines
|
|
120
|
+
});
|
|
121
|
+
const willDeleteCellWithoutRow = (0, _utils.rangeRemovalWillDeleteCellWithoutRow)(this.quill, range);
|
|
122
|
+
if (willDeleteCellWithoutRow) {
|
|
123
|
+
(0, _logger.getLogger)().debug('prevent delete cell out of row');
|
|
124
|
+
}
|
|
125
|
+
return !willDeleteCellWithoutRow;
|
|
126
|
+
});
|
|
127
|
+
this.quill = quill;
|
|
128
|
+
this.options = options;
|
|
129
|
+
|
|
130
|
+
// Define Toolbar Handler
|
|
131
|
+
const toolbar = quill.getModule('toolbar');
|
|
132
|
+
if (toolbar) {
|
|
133
|
+
toolbar.addHandler('table', action => {
|
|
134
|
+
this.tableHandler(action);
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
// by default, hide all table controls
|
|
138
|
+
toolbar.controls.forEach(control => {
|
|
139
|
+
const [name, domNode] = control;
|
|
140
|
+
if (name === 'table' && domNode.tagName === 'BUTTON') {
|
|
141
|
+
this.tableToolbarControls.push(domNode);
|
|
142
|
+
domNode.classList.add('dn');
|
|
288
143
|
}
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
this.quill.on('editor-change', this.showOrHideToolbarControls);
|
|
147
|
+
this.quill.on('selection-change', this.showOrHideToolbarControls);
|
|
148
|
+
|
|
149
|
+
// Define Clipboard Matchers
|
|
150
|
+
// When HTML is loaded or pasted into Quill, the matchers
|
|
151
|
+
// will find the given HTML Tag and allow the delta for the element's
|
|
152
|
+
// content to be modified.
|
|
153
|
+
const clipboard = quill.getModule('clipboard');
|
|
154
|
+
if (clipboard) {
|
|
155
|
+
clipboard.addMatcher(_constants.TAG_NAME.TD, function (node, delta) {
|
|
156
|
+
(0, _logger.getLogger)().debug(`${_constants.TAG_NAME.TD} matched`, {
|
|
157
|
+
node,
|
|
158
|
+
delta
|
|
301
159
|
});
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
var index = rowToSelectAfter.offset(this.quill.scroll);
|
|
315
|
-
this.quill.setSelection(index + cellOffset, 0);
|
|
160
|
+
|
|
161
|
+
// load the table cell attribute to use as the delta operation attributes
|
|
162
|
+
const dataValue = node.getAttribute(_constants.ATTRIBUTE.DATA_VALUE);
|
|
163
|
+
const defaultAttributes = {
|
|
164
|
+
td: dataValue
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
// handle empty cells, insert a single block / paragraph
|
|
168
|
+
if (delta.length() === 0) {
|
|
169
|
+
const updatedDelta = new Delta().insert('\n', defaultAttributes);
|
|
170
|
+
(0, _logger.getLogger)().debug(`${_constants.TAG_NAME.TD} matched - final delta (empty cell)`, updatedDelta);
|
|
171
|
+
return updatedDelta;
|
|
316
172
|
}
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
173
|
+
|
|
174
|
+
// for each operation inside the cell's delta, add the table cell attributes
|
|
175
|
+
const updatedDelta = delta.reduce((newDelta, op) => {
|
|
176
|
+
newDelta.insert(op.insert, (0, _lodash.merge)({}, op.attributes, defaultAttributes));
|
|
177
|
+
return newDelta;
|
|
178
|
+
}, new Delta());
|
|
179
|
+
(0, _logger.getLogger)().debug(`${_constants.TAG_NAME.TD} matched - final delta`, updatedDelta);
|
|
180
|
+
return updatedDelta;
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Override "backspace" and "delete" actions that would delete or combine a table cell
|
|
185
|
+
const keyboard = quill.getModule('keyboard');
|
|
186
|
+
if (keyboard) {
|
|
187
|
+
keyboard.addBinding({
|
|
188
|
+
key: _constants.KEY.BACKSPACE,
|
|
189
|
+
altKey: null,
|
|
190
|
+
ctrlKey: null,
|
|
191
|
+
metaKey: null,
|
|
192
|
+
shiftKey: null
|
|
193
|
+
}, {
|
|
194
|
+
collapsed: true,
|
|
195
|
+
offset: 0
|
|
196
|
+
}, this.handleBackspace);
|
|
197
|
+
// move binding to first position
|
|
198
|
+
const backspaceOtherBinding = keyboard.bindings[_constants.KEY.BACKSPACE].pop();
|
|
199
|
+
keyboard.bindings[_constants.KEY.BACKSPACE].splice(0, 0, backspaceOtherBinding);
|
|
200
|
+
keyboard.addBinding({
|
|
201
|
+
key: _constants.KEY.BACKSPACE
|
|
202
|
+
}, {
|
|
203
|
+
collapsed: false
|
|
204
|
+
}, this.handleDeleteRange);
|
|
205
|
+
// move binding to first position
|
|
206
|
+
const backspaceRangeBinding = keyboard.bindings[_constants.KEY.BACKSPACE].pop();
|
|
207
|
+
keyboard.bindings[_constants.KEY.BACKSPACE].splice(0, 0, backspaceRangeBinding);
|
|
208
|
+
keyboard.addBinding({
|
|
209
|
+
key: _constants.KEY.BACKSPACE
|
|
210
|
+
}, {
|
|
211
|
+
collapsed: true
|
|
212
|
+
}, this.handleBackspace);
|
|
213
|
+
// move binding to first position
|
|
214
|
+
const backspaceBinding = keyboard.bindings[_constants.KEY.BACKSPACE].pop();
|
|
215
|
+
keyboard.bindings[_constants.KEY.BACKSPACE].splice(0, 0, backspaceBinding);
|
|
216
|
+
keyboard.addBinding({
|
|
217
|
+
key: _constants.KEY.DELETE
|
|
218
|
+
}, {
|
|
219
|
+
collapsed: false
|
|
220
|
+
}, this.handleDeleteRange);
|
|
221
|
+
// move binding to first position
|
|
222
|
+
const deleteRangeBinding = keyboard.bindings[_constants.KEY.DELETE].pop();
|
|
223
|
+
keyboard.bindings[_constants.KEY.DELETE].splice(0, 0, deleteRangeBinding);
|
|
224
|
+
keyboard.addBinding({
|
|
225
|
+
key: _constants.KEY.DELETE
|
|
226
|
+
}, {
|
|
227
|
+
collapsed: true,
|
|
228
|
+
altKey: true
|
|
229
|
+
}, this.handleDelete);
|
|
230
|
+
// move binding to first position
|
|
231
|
+
const deleteWithAltBinding = keyboard.bindings[_constants.KEY.DELETE].pop();
|
|
232
|
+
keyboard.bindings[_constants.KEY.DELETE].splice(0, 0, deleteWithAltBinding);
|
|
233
|
+
keyboard.addBinding({
|
|
234
|
+
key: _constants.KEY.DELETE
|
|
235
|
+
}, {
|
|
236
|
+
collapsed: true
|
|
237
|
+
}, this.handleDelete);
|
|
238
|
+
// move binding to first position
|
|
239
|
+
const deleteBinding = keyboard.bindings[_constants.KEY.DELETE].pop();
|
|
240
|
+
keyboard.bindings[_constants.KEY.DELETE].splice(0, 0, deleteBinding);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
getSelectedCell() {
|
|
244
|
+
const selection = this.quill.getSelection();
|
|
245
|
+
if (!selection) {
|
|
246
|
+
return null;
|
|
247
|
+
}
|
|
248
|
+
const leaf = this.quill.getLeaf(selection.index);
|
|
249
|
+
let blot = leaf[0];
|
|
250
|
+
while (blot && !(blot instanceof _TableCellBlot.TableCellBlot) && blot.parent) {
|
|
251
|
+
blot = blot.parent;
|
|
252
|
+
}
|
|
253
|
+
if (blot instanceof _TableCellBlot.TableCellBlot) {
|
|
254
|
+
return blot;
|
|
255
|
+
}
|
|
256
|
+
return null;
|
|
257
|
+
}
|
|
258
|
+
getSelectedTable() {
|
|
259
|
+
return this.getSelectedCell()?.table();
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
//#endregion Helpers
|
|
263
|
+
|
|
264
|
+
//#region Table Handler
|
|
265
|
+
|
|
266
|
+
tableHandler(action) {
|
|
267
|
+
(0, _logger.getLogger)().debug('tableHandler', action);
|
|
268
|
+
|
|
269
|
+
// require a selection range
|
|
270
|
+
const range = this.quill.getSelection();
|
|
271
|
+
if (!range) return;
|
|
272
|
+
if (action.includes(_constants.TABLE_ACTION.NEW_TABLE)) {
|
|
273
|
+
this.addNewTable(action, range);
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// require a selected cell
|
|
278
|
+
const selectedCell = this.getSelectedCell();
|
|
279
|
+
if (!selectedCell) return;
|
|
280
|
+
switch (action) {
|
|
281
|
+
case _constants.TABLE_ACTION.INSERT_COL:
|
|
282
|
+
this.insertCol(selectedCell);
|
|
283
|
+
break;
|
|
284
|
+
case _constants.TABLE_ACTION.INSERT_ROW:
|
|
285
|
+
this.insertRow(selectedCell);
|
|
286
|
+
break;
|
|
287
|
+
case _constants.TABLE_ACTION.DELETE_COL:
|
|
288
|
+
this.deleteCol(selectedCell);
|
|
289
|
+
break;
|
|
290
|
+
case _constants.TABLE_ACTION.DELETE_ROW:
|
|
291
|
+
this.deleteRow(selectedCell);
|
|
292
|
+
break;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
addNewTable(action, range) {
|
|
296
|
+
const {
|
|
297
|
+
index
|
|
298
|
+
} = range;
|
|
299
|
+
|
|
300
|
+
// e.g. "new-table-2-2"
|
|
301
|
+
const sizes = action.replace(_constants.TABLE_ACTION.NEW_TABLE, '').split('_');
|
|
302
|
+
const rows = parseInt(sizes[0]);
|
|
303
|
+
const cols = parseInt(sizes[1]);
|
|
304
|
+
const tableContainer = _TableContainer.TableContainerBlot.createWithChildren(rows, cols);
|
|
305
|
+
|
|
306
|
+
// insert the table into the top level scroll element
|
|
307
|
+
// before the current leaf's top level branch
|
|
308
|
+
// PREVENT NESTED TABLES
|
|
309
|
+
let topBranch = null;
|
|
310
|
+
const leaf = this.quill.getLeaf(index);
|
|
311
|
+
let blot = leaf[0];
|
|
312
|
+
while (blot && blot.parent && !(blot instanceof Scroll)) {
|
|
313
|
+
topBranch = blot;
|
|
314
|
+
blot = blot.parent;
|
|
315
|
+
}
|
|
316
|
+
if (!blot || !(blot instanceof Scroll)) return;
|
|
317
|
+
blot.insertBefore(tableContainer, topBranch || undefined);
|
|
318
|
+
this.quill.setSelection(tableContainer.offset(this.quill.scroll), 0, 'user');
|
|
319
|
+
}
|
|
320
|
+
insertCol(selectedCell) {
|
|
321
|
+
const selectedCellColumn = selectedCell.column();
|
|
322
|
+
const tableId = selectedCell.tableId();
|
|
323
|
+
const tableBody = selectedCell.row()?.tableBody();
|
|
324
|
+
if (!tableBody) return;
|
|
325
|
+
tableBody.children.forEach(child => {
|
|
326
|
+
const tableRow = child;
|
|
327
|
+
const rowId = tableRow.id();
|
|
328
|
+
const tableCell = _TableCellBlot.TableCellBlot.createWithChildren(tableId, rowId);
|
|
329
|
+
const cells = tableRow.children.map(c => c);
|
|
330
|
+
const nextColumnCell = cells.length > selectedCellColumn - 1 ? cells[selectedCellColumn] : undefined;
|
|
331
|
+
if (nextColumnCell) {
|
|
332
|
+
tableRow.insertBefore(tableCell, nextColumnCell);
|
|
333
|
+
} else {
|
|
334
|
+
tableRow.appendChild(tableCell);
|
|
335
|
+
}
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
insertRow(selectedCell) {
|
|
339
|
+
const currentRow = selectedCell.row();
|
|
340
|
+
if (!currentRow) return;
|
|
341
|
+
const nextRow = currentRow.next;
|
|
342
|
+
const tableBody = currentRow.tableBody();
|
|
343
|
+
if (!tableBody) return;
|
|
344
|
+
const newRow = _TableRowBlot.TableRowBlot.createFromReference(currentRow);
|
|
345
|
+
if (nextRow) {
|
|
346
|
+
tableBody.insertBefore(newRow, nextRow);
|
|
347
|
+
} else {
|
|
348
|
+
tableBody.appendChild(newRow);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
deleteCol(selectedCell) {
|
|
352
|
+
const selectedCellColumn = selectedCell.column();
|
|
353
|
+
const tableBody = selectedCell.row()?.tableBody();
|
|
354
|
+
if (!tableBody) return;
|
|
355
|
+
tableBody.children.forEach(c => {
|
|
356
|
+
const tableRow = c;
|
|
357
|
+
const cells = tableRow.children.map(c => c);
|
|
358
|
+
const cell = cells[selectedCellColumn - 1];
|
|
359
|
+
cell?.remove();
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
deleteRow(selectedCell) {
|
|
363
|
+
const selectedRow = selectedCell.row();
|
|
364
|
+
if (!selectedRow) return;
|
|
365
|
+
const cellOffset = selectedCell.offset(); // offset inside row
|
|
366
|
+
const tableBody = selectedRow.tableBody();
|
|
367
|
+
const rowToSelectAfter = selectedRow.next || selectedRow.prev;
|
|
368
|
+
// delete the row
|
|
369
|
+
selectedRow.remove();
|
|
370
|
+
// focus the next row or prev row if possible
|
|
371
|
+
if (tableBody && tableBody.children.length > 0 && rowToSelectAfter) {
|
|
372
|
+
const index = rowToSelectAfter.offset(this.quill.scroll);
|
|
373
|
+
this.quill.setSelection(index + cellOffset, 0);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
//#endregion Table Handler
|
|
378
|
+
}
|
|
320
379
|
exports.TableModule = TableModule;
|
|
380
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfbG9kYXNoIiwicmVxdWlyZSIsIl9yZWFjdFF1aWxsIiwiX2xvZ2dlciIsIl9CYXNlVGFibGVCbG90IiwiX1RhYmxlQmxvdCIsIl9UYWJsZUJvZHlCbG90IiwiX1RhYmxlQ2VsbEJsb3QiLCJfVGFibGVDb250YWluZXIiLCJfVGFibGVSb3dCbG90IiwiX2NvbnN0YW50cyIsIl91dGlscyIsIkRlbHRhIiwiUXVpbGwiLCJpbXBvcnQiLCJTY3JvbGwiLCJUYWJsZU1vZHVsZSIsInJlZ2lzdGVyIiwiQmFzZVRhYmxlQmxvdCIsIlRhYmxlQ2VsbEJsb3QiLCJUYWJsZVJvd0Jsb3QiLCJUYWJsZUJvZHlCbG90IiwiVGFibGVCbG90IiwiVGFibGVDb250YWluZXJCbG90IiwiY29uc3RydWN0b3IiLCJxdWlsbCIsIm9wdGlvbnMiLCJfZGVmaW5lUHJvcGVydHkyIiwiZGVmYXVsdCIsInNlbGVjdGVkQ2VsbCIsImdldFNlbGVjdGVkQ2VsbCIsInRhYmxlVG9vbGJhckNvbnRyb2xzIiwiZm9yRWFjaCIsImRvbU5vZGUiLCJjbGFzc0xpc3QiLCJyZW1vdmUiLCJhZGQiLCJyYW5nZSIsImNvbnRleHQiLCJpbmRleCIsImdldExlbmd0aCIsImxpbmUiLCJnZXRMaW5lIiwib2Zmc2V0IiwiaXNMaW5lQWZ0ZXJUYWJsZSIsImdldExvZ2dlciIsImRlYnVnIiwiaXNMaW5lSW5UYWJsZUNlbGwiLCJwcmV2IiwicGFyZW50IiwibGVuZ3RoIiwidGVzdCIsInN1ZmZpeCIsImlzTGluZUJlZm9yZVRhYmxlIiwibmV4dCIsImxpbmVzIiwiZ2V0TGluZXMiLCJ3aWxsRGVsZXRlQ2VsbFdpdGhvdXRSb3ciLCJyYW5nZVJlbW92YWxXaWxsRGVsZXRlQ2VsbFdpdGhvdXRSb3ciLCJ0b29sYmFyIiwiZ2V0TW9kdWxlIiwiYWRkSGFuZGxlciIsImFjdGlvbiIsInRhYmxlSGFuZGxlciIsImNvbnRyb2xzIiwiY29udHJvbCIsIm5hbWUiLCJ0YWdOYW1lIiwicHVzaCIsIm9uIiwic2hvd09ySGlkZVRvb2xiYXJDb250cm9scyIsImNsaXBib2FyZCIsImFkZE1hdGNoZXIiLCJUQUdfTkFNRSIsIlREIiwibm9kZSIsImRlbHRhIiwiZGF0YVZhbHVlIiwiZ2V0QXR0cmlidXRlIiwiQVRUUklCVVRFIiwiREFUQV9WQUxVRSIsImRlZmF1bHRBdHRyaWJ1dGVzIiwidGQiLCJ1cGRhdGVkRGVsdGEiLCJpbnNlcnQiLCJyZWR1Y2UiLCJuZXdEZWx0YSIsIm9wIiwibWVyZ2UiLCJhdHRyaWJ1dGVzIiwia2V5Ym9hcmQiLCJhZGRCaW5kaW5nIiwia2V5IiwiS0VZIiwiQkFDS1NQQUNFIiwiYWx0S2V5IiwiY3RybEtleSIsIm1ldGFLZXkiLCJzaGlmdEtleSIsImNvbGxhcHNlZCIsImhhbmRsZUJhY2tzcGFjZSIsImJhY2tzcGFjZU90aGVyQmluZGluZyIsImJpbmRpbmdzIiwicG9wIiwic3BsaWNlIiwiaGFuZGxlRGVsZXRlUmFuZ2UiLCJiYWNrc3BhY2VSYW5nZUJpbmRpbmciLCJiYWNrc3BhY2VCaW5kaW5nIiwiREVMRVRFIiwiZGVsZXRlUmFuZ2VCaW5kaW5nIiwiaGFuZGxlRGVsZXRlIiwiZGVsZXRlV2l0aEFsdEJpbmRpbmciLCJkZWxldGVCaW5kaW5nIiwic2VsZWN0aW9uIiwiZ2V0U2VsZWN0aW9uIiwibGVhZiIsImdldExlYWYiLCJibG90IiwiZ2V0U2VsZWN0ZWRUYWJsZSIsInRhYmxlIiwiaW5jbHVkZXMiLCJUQUJMRV9BQ1RJT04iLCJORVdfVEFCTEUiLCJhZGROZXdUYWJsZSIsIklOU0VSVF9DT0wiLCJpbnNlcnRDb2wiLCJJTlNFUlRfUk9XIiwiaW5zZXJ0Um93IiwiREVMRVRFX0NPTCIsImRlbGV0ZUNvbCIsIkRFTEVURV9ST1ciLCJkZWxldGVSb3ciLCJzaXplcyIsInJlcGxhY2UiLCJzcGxpdCIsInJvd3MiLCJwYXJzZUludCIsImNvbHMiLCJ0YWJsZUNvbnRhaW5lciIsImNyZWF0ZVdpdGhDaGlsZHJlbiIsInRvcEJyYW5jaCIsImluc2VydEJlZm9yZSIsInVuZGVmaW5lZCIsInNldFNlbGVjdGlvbiIsInNjcm9sbCIsInNlbGVjdGVkQ2VsbENvbHVtbiIsImNvbHVtbiIsInRhYmxlSWQiLCJ0YWJsZUJvZHkiLCJyb3ciLCJjaGlsZHJlbiIsImNoaWxkIiwidGFibGVSb3ciLCJyb3dJZCIsImlkIiwidGFibGVDZWxsIiwiY2VsbHMiLCJtYXAiLCJjIiwibmV4dENvbHVtbkNlbGwiLCJhcHBlbmRDaGlsZCIsImN1cnJlbnRSb3ciLCJuZXh0Um93IiwibmV3Um93IiwiY3JlYXRlRnJvbVJlZmVyZW5jZSIsImNlbGwiLCJzZWxlY3RlZFJvdyIsImNlbGxPZmZzZXQiLCJyb3dUb1NlbGVjdEFmdGVyIiwiZXhwb3J0cyJdLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21wb25lbnRzL1F1aWxsL1RhYmxlTW9kdWxlL2luZGV4LnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11bm5lY2Vzc2FyeS1jb25kaXRpb24gKi9cbmltcG9ydCB7IG1lcmdlIH0gZnJvbSAnbG9kYXNoJ1xuaW1wb3J0IFBhcmNobWVudFR5cGUgZnJvbSAncGFyY2htZW50J1xuaW1wb3J0IHsgQmxvdCB9IGZyb20gJ3BhcmNobWVudC9kaXN0L3NyYy9ibG90L2Fic3RyYWN0L2Jsb3QnXG5pbXBvcnQgeyBDbGlwYm9hcmRTdGF0aWMsIERlbHRhU3RhdGljLCBSYW5nZVN0YXRpYywgU3RyaW5nTWFwIH0gZnJvbSAncXVpbGwnXG5pbXBvcnQgeyBRdWlsbCB9IGZyb20gJ3JlYWN0LXF1aWxsJ1xuaW1wb3J0IHsgZ2V0TG9nZ2VyIH0gZnJvbSAnLi4vLi4vLi4vdXRpbHMvbG9nZ2VyJ1xuaW1wb3J0IHsgQmFzZVRhYmxlQmxvdCB9IGZyb20gJy4vQmxvdHMvQmFzZVRhYmxlQmxvdCdcbmltcG9ydCB7IFRhYmxlQmxvdCB9IGZyb20gJy4vQmxvdHMvVGFibGVCbG90J1xuaW1wb3J0IHsgVGFibGVCb2R5QmxvdCB9IGZyb20gJy4vQmxvdHMvVGFibGVCb2R5QmxvdCdcbmltcG9ydCB7IFRhYmxlQ2VsbEJsb3QgfSBmcm9tICcuL0Jsb3RzL1RhYmxlQ2VsbEJsb3QnXG5pbXBvcnQgeyBUYWJsZUNvbnRhaW5lckJsb3QgfSBmcm9tICcuL0Jsb3RzL1RhYmxlQ29udGFpbmVyJ1xuaW1wb3J0IHsgVGFibGVSb3dCbG90IH0gZnJvbSAnLi9CbG90cy9UYWJsZVJvd0Jsb3QnXG5pbXBvcnQgeyBBVFRSSUJVVEUsIEtFWSwgVEFCTEVfQUNUSU9OLCBUQUdfTkFNRSB9IGZyb20gJy4vY29uc3RhbnRzJ1xuaW1wb3J0IHsgaXNMaW5lQWZ0ZXJUYWJsZSwgaXNMaW5lQmVmb3JlVGFibGUsIGlzTGluZUluVGFibGVDZWxsLCByYW5nZVJlbW92YWxXaWxsRGVsZXRlQ2VsbFdpdGhvdXRSb3cgfSBmcm9tICcuL3V0aWxzJ1xuXG5jb25zdCBEZWx0YSA9IFF1aWxsLmltcG9ydCgnZGVsdGEnKVxuY29uc3QgU2Nyb2xsID0gUXVpbGwuaW1wb3J0KCdibG90cy9zY3JvbGwnKSBhcyB0eXBlb2YgUGFyY2htZW50VHlwZS5TY3JvbGxcblxuaW50ZXJmYWNlIENvbnRleHQge1xuXHRjb2xsYXBzZWQ6IGJvb2xlYW5cblx0ZW1wdHk6IGJvb2xlYW5cblx0Zm9ybWF0OiBTdHJpbmdNYXBcblx0b2Zmc2V0OiBudW1iZXJcblx0cHJlZml4OiBzdHJpbmdcblx0c3VmZml4OiBzdHJpbmdcbn1cblxuZXhwb3J0IGNsYXNzIFRhYmxlTW9kdWxlIHtcblx0c3RhdGljIHJlZ2lzdGVyKCkge1xuXHRcdFF1aWxsLnJlZ2lzdGVyKEJhc2VUYWJsZUJsb3QpXG5cdFx0UXVpbGwucmVnaXN0ZXIoVGFibGVDZWxsQmxvdClcblx0XHRRdWlsbC5yZWdpc3RlcihUYWJsZVJvd0Jsb3QpXG5cdFx0UXVpbGwucmVnaXN0ZXIoVGFibGVCb2R5QmxvdClcblx0XHRRdWlsbC5yZWdpc3RlcihUYWJsZUJsb3QpXG5cdFx0UXVpbGwucmVnaXN0ZXIoVGFibGVDb250YWluZXJCbG90KVxuXHR9XG5cblx0cXVpbGw6IFF1aWxsXG5cdG9wdGlvbnM6IGFueVxuXHR0YWJsZVRvb2xiYXJDb250cm9sczogSFRNTEVsZW1lbnRbXSA9IFtdXG5cblx0Y29uc3RydWN0b3IocXVpbGw6IFF1aWxsLCBvcHRpb25zOiBhbnkpIHtcblx0XHR0aGlzLnF1aWxsID0gcXVpbGxcblx0XHR0aGlzLm9wdGlvbnMgPSBvcHRpb25zXG5cblx0XHQvLyBEZWZpbmUgVG9vbGJhciBIYW5kbGVyXG5cdFx0Y29uc3QgdG9vbGJhciA9IHF1aWxsLmdldE1vZHVsZSgndG9vbGJhcicpXG5cdFx0aWYgKHRvb2xiYXIpIHtcblx0XHRcdHRvb2xiYXIuYWRkSGFuZGxlcigndGFibGUnLCAoYWN0aW9uOiBzdHJpbmcpID0+IHtcblx0XHRcdFx0dGhpcy50YWJsZUhhbmRsZXIoYWN0aW9uKVxuXHRcdFx0fSlcblxuXHRcdFx0Ly8gYnkgZGVmYXVsdCwgaGlkZSBhbGwgdGFibGUgY29udHJvbHNcblx0XHRcdHRvb2xiYXIuY29udHJvbHMuZm9yRWFjaCgoY29udHJvbDogW3N0cmluZywgSFRNTEVsZW1lbnRdKSA9PiB7XG5cdFx0XHRcdGNvbnN0IFtuYW1lLCBkb21Ob2RlXSA9IGNvbnRyb2xcblx0XHRcdFx0aWYgKG5hbWUgPT09ICd0YWJsZScgJiYgZG9tTm9kZS50YWdOYW1lID09PSAnQlVUVE9OJykge1xuXHRcdFx0XHRcdHRoaXMudGFibGVUb29sYmFyQ29udHJvbHMucHVzaChkb21Ob2RlKVxuXHRcdFx0XHRcdGRvbU5vZGUuY2xhc3NMaXN0LmFkZCgnZG4nKVxuXHRcdFx0XHR9XG5cdFx0XHR9KVxuXHRcdH1cblxuXHRcdHRoaXMucXVpbGwub24oJ2VkaXRvci1jaGFuZ2UnLCB0aGlzLnNob3dPckhpZGVUb29sYmFyQ29udHJvbHMpXG5cdFx0dGhpcy5xdWlsbC5vbignc2VsZWN0aW9uLWNoYW5nZScsIHRoaXMuc2hvd09ySGlkZVRvb2xiYXJDb250cm9scylcblxuXHRcdC8vIERlZmluZSBDbGlwYm9hcmQgTWF0Y2hlcnNcblx0XHQvLyBXaGVuIEhUTUwgaXMgbG9hZGVkIG9yIHBhc3RlZCBpbnRvIFF1aWxsLCB0aGUgbWF0Y2hlcnNcblx0XHQvLyB3aWxsIGZpbmQgdGhlIGdpdmVuIEhUTUwgVGFnIGFuZCBhbGxvdyB0aGUgZGVsdGEgZm9yIHRoZSBlbGVtZW50J3Ncblx0XHQvLyBjb250ZW50IHRvIGJlIG1vZGlmaWVkLlxuXHRcdGNvbnN0IGNsaXBib2FyZCA9IHF1aWxsLmdldE1vZHVsZSgnY2xpcGJvYXJkJykgYXMgQ2xpcGJvYXJkU3RhdGljIHwgdW5kZWZpbmVkXG5cdFx0aWYgKGNsaXBib2FyZCkge1xuXHRcdFx0Y2xpcGJvYXJkLmFkZE1hdGNoZXIoVEFHX05BTUUuVEQsIGZ1bmN0aW9uIChub2RlOiBIVE1MVGFibGVDZWxsRWxlbWVudCwgZGVsdGE6IERlbHRhU3RhdGljKSB7XG5cdFx0XHRcdGdldExvZ2dlcigpLmRlYnVnKGAke1RBR19OQU1FLlREfSBtYXRjaGVkYCwgeyBub2RlLCBkZWx0YSB9KVxuXG5cdFx0XHRcdC8vIGxvYWQgdGhlIHRhYmxlIGNlbGwgYXR0cmlidXRlIHRvIHVzZSBhcyB0aGUgZGVsdGEgb3BlcmF0aW9uIGF0dHJpYnV0ZXNcblx0XHRcdFx0Y29uc3QgZGF0YVZhbHVlID0gbm9kZS5nZXRBdHRyaWJ1dGUoQVRUUklCVVRFLkRBVEFfVkFMVUUpXG5cdFx0XHRcdGNvbnN0IGRlZmF1bHRBdHRyaWJ1dGVzID0ge1xuXHRcdFx0XHRcdHRkOiBkYXRhVmFsdWVcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIGhhbmRsZSBlbXB0eSBjZWxscywgaW5zZXJ0IGEgc2luZ2xlIGJsb2NrIC8gcGFyYWdyYXBoXG5cdFx0XHRcdGlmIChkZWx0YS5sZW5ndGgoKSA9PT0gMCkge1xuXHRcdFx0XHRcdGNvbnN0IHVwZGF0ZWREZWx0YSA9IChuZXcgRGVsdGEoKSBhcyBEZWx0YVN0YXRpYykuaW5zZXJ0KCdcXG4nLCBkZWZhdWx0QXR0cmlidXRlcylcblx0XHRcdFx0XHRnZXRMb2dnZXIoKS5kZWJ1ZyhgJHtUQUdfTkFNRS5URH0gbWF0Y2hlZCAtIGZpbmFsIGRlbHRhIChlbXB0eSBjZWxsKWAsIHVwZGF0ZWREZWx0YSlcblx0XHRcdFx0XHRyZXR1cm4gdXBkYXRlZERlbHRhXG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBmb3IgZWFjaCBvcGVyYXRpb24gaW5zaWRlIHRoZSBjZWxsJ3MgZGVsdGEsIGFkZCB0aGUgdGFibGUgY2VsbCBhdHRyaWJ1dGVzXG5cdFx0XHRcdGNvbnN0IHVwZGF0ZWREZWx0YSA9IGRlbHRhLnJlZHVjZSgobmV3RGVsdGEsIG9wKSA9PiB7XG5cdFx0XHRcdFx0bmV3RGVsdGEuaW5zZXJ0KG9wLmluc2VydCwgbWVyZ2Uoe30sIG9wLmF0dHJpYnV0ZXMsIGRlZmF1bHRBdHRyaWJ1dGVzKSlcblx0XHRcdFx0XHRyZXR1cm4gbmV3RGVsdGFcblx0XHRcdFx0fSwgbmV3IERlbHRhKCkgYXMgRGVsdGFTdGF0aWMpXG5cblx0XHRcdFx0Z2V0TG9nZ2VyKCkuZGVidWcoYCR7VEFHX05BTUUuVER9IG1hdGNoZWQgLSBmaW5hbCBkZWx0YWAsIHVwZGF0ZWREZWx0YSlcblxuXHRcdFx0XHRyZXR1cm4gdXBkYXRlZERlbHRhXG5cdFx0XHR9KVxuXHRcdH1cblxuXHRcdC8vIE92ZXJyaWRlIFwiYmFja3NwYWNlXCIgYW5kIFwiZGVsZXRlXCIgYWN0aW9ucyB0aGF0IHdvdWxkIGRlbGV0ZSBvciBjb21iaW5lIGEgdGFibGUgY2VsbFxuXHRcdGNvbnN0IGtleWJvYXJkID0gcXVpbGwuZ2V0TW9kdWxlKCdrZXlib2FyZCcpXG5cdFx0aWYgKGtleWJvYXJkKSB7XG5cdFx0XHRrZXlib2FyZC5hZGRCaW5kaW5nKFxuXHRcdFx0XHR7IGtleTogS0VZLkJBQ0tTUEFDRSwgYWx0S2V5OiBudWxsLCBjdHJsS2V5OiBudWxsLCBtZXRhS2V5OiBudWxsLCBzaGlmdEtleTogbnVsbCB9LFxuXHRcdFx0XHR7IGNvbGxhcHNlZDogdHJ1ZSwgb2Zmc2V0OiAwIH0sXG5cdFx0XHRcdHRoaXMuaGFuZGxlQmFja3NwYWNlXG5cdFx0XHQpXG5cdFx0XHQvLyBtb3ZlIGJpbmRpbmcgdG8gZmlyc3QgcG9zaXRpb25cblx0XHRcdGNvbnN0IGJhY2tzcGFjZU90aGVyQmluZGluZyA9IGtleWJvYXJkLmJpbmRpbmdzW0tFWS5CQUNLU1BBQ0VdLnBvcCgpXG5cdFx0XHRrZXlib2FyZC5iaW5kaW5nc1tLRVkuQkFDS1NQQUNFXS5zcGxpY2UoMCwgMCwgYmFja3NwYWNlT3RoZXJCaW5kaW5nKVxuXG5cdFx0XHRrZXlib2FyZC5hZGRCaW5kaW5nKHsga2V5OiBLRVkuQkFDS1NQQUNFIH0sIHsgY29sbGFwc2VkOiBmYWxzZSB9LCB0aGlzLmhhbmRsZURlbGV0ZVJhbmdlKVxuXHRcdFx0Ly8gbW92ZSBiaW5kaW5nIHRvIGZpcnN0IHBvc2l0aW9uXG5cdFx0XHRjb25zdCBiYWNrc3BhY2VSYW5nZUJpbmRpbmcgPSBrZXlib2FyZC5iaW5kaW5nc1tLRVkuQkFDS1NQQUNFXS5wb3AoKVxuXHRcdFx0a2V5Ym9hcmQuYmluZGluZ3NbS0VZLkJBQ0tTUEFDRV0uc3BsaWNlKDAsIDAsIGJhY2tzcGFjZVJhbmdlQmluZGluZylcblxuXHRcdFx0a2V5Ym9hcmQuYWRkQmluZGluZyh7IGtleTogS0VZLkJBQ0tTUEFDRSB9LCB7IGNvbGxhcHNlZDogdHJ1ZSB9LCB0aGlzLmhhbmRsZUJhY2tzcGFjZSlcblx0XHRcdC8vIG1vdmUgYmluZGluZyB0byBmaXJzdCBwb3NpdGlvblxuXHRcdFx0Y29uc3QgYmFja3NwYWNlQmluZGluZyA9IGtleWJvYXJkLmJpbmRpbmdzW0tFWS5CQUNLU1BBQ0VdLnBvcCgpXG5cdFx0XHRrZXlib2FyZC5iaW5kaW5nc1tLRVkuQkFDS1NQQUNFXS5zcGxpY2UoMCwgMCwgYmFja3NwYWNlQmluZGluZylcblxuXHRcdFx0a2V5Ym9hcmQuYWRkQmluZGluZyh7IGtleTogS0VZLkRFTEVURSB9LCB7IGNvbGxhcHNlZDogZmFsc2UgfSwgdGhpcy5oYW5kbGVEZWxldGVSYW5nZSlcblx0XHRcdC8vIG1vdmUgYmluZGluZyB0byBmaXJzdCBwb3NpdGlvblxuXHRcdFx0Y29uc3QgZGVsZXRlUmFuZ2VCaW5kaW5nID0ga2V5Ym9hcmQuYmluZGluZ3NbS0VZLkRFTEVURV0ucG9wKClcblx0XHRcdGtleWJvYXJkLmJpbmRpbmdzW0tFWS5ERUxFVEVdLnNwbGljZSgwLCAwLCBkZWxldGVSYW5nZUJpbmRpbmcpXG5cblx0XHRcdGtleWJvYXJkLmFkZEJpbmRpbmcoeyBrZXk6IEtFWS5ERUxFVEUgfSwgeyBjb2xsYXBzZWQ6IHRydWUsIGFsdEtleTogdHJ1ZSB9LCB0aGlzLmhhbmRsZURlbGV0ZSlcblx0XHRcdC8vIG1vdmUgYmluZGluZyB0byBmaXJzdCBwb3NpdGlvblxuXHRcdFx0Y29uc3QgZGVsZXRlV2l0aEFsdEJpbmRpbmcgPSBrZXlib2FyZC5iaW5kaW5nc1tLRVkuREVMRVRFXS5wb3AoKVxuXHRcdFx0a2V5Ym9hcmQuYmluZGluZ3NbS0VZLkRFTEVURV0uc3BsaWNlKDAsIDAsIGRlbGV0ZVdpdGhBbHRCaW5kaW5nKVxuXG5cdFx0XHRrZXlib2FyZC5hZGRCaW5kaW5nKHsga2V5OiBLRVkuREVMRVRFIH0sIHsgY29sbGFwc2VkOiB0cnVlIH0sIHRoaXMuaGFuZGxlRGVsZXRlKVxuXHRcdFx0Ly8gbW92ZSBiaW5kaW5nIHRvIGZpcnN0IHBvc2l0aW9uXG5cdFx0XHRjb25zdCBkZWxldGVCaW5kaW5nID0ga2V5Ym9hcmQuYmluZGluZ3NbS0VZLkRFTEVURV0ucG9wKClcblx0XHRcdGtleWJvYXJkLmJpbmRpbmdzW0tFWS5ERUxFVEVdLnNwbGljZSgwLCAwLCBkZWxldGVCaW5kaW5nKVxuXHRcdH1cblx0fVxuXG5cdC8vI3JlZ2lvbiBIZWxwZXJzXG5cblx0c2hvd09ySGlkZVRvb2xiYXJDb250cm9scyA9ICgpID0+IHtcblx0XHRjb25zdCBzZWxlY3RlZENlbGwgPSB0aGlzLmdldFNlbGVjdGVkQ2VsbCgpXG5cdFx0aWYgKHNlbGVjdGVkQ2VsbCkge1xuXHRcdFx0dGhpcy50YWJsZVRvb2xiYXJDb250cm9scy5mb3JFYWNoKGRvbU5vZGUgPT4ge1xuXHRcdFx0XHRkb21Ob2RlLmNsYXNzTGlzdC5yZW1vdmUoJ2RuJylcblx0XHRcdH0pXG5cdFx0fSBlbHNlIHtcblx0XHRcdHRoaXMudGFibGVUb29sYmFyQ29udHJvbHMuZm9yRWFjaChkb21Ob2RlID0+IHtcblx0XHRcdFx0ZG9tTm9kZS5jbGFzc0xpc3QuYWRkKCdkbicpXG5cdFx0XHR9KVxuXHRcdH1cblx0fVxuXG5cdGhhbmRsZUJhY2tzcGFjZSA9IChyYW5nZTogUmFuZ2VTdGF0aWMsIGNvbnRleHQ6IENvbnRleHQpID0+IHtcblx0XHRpZiAocmFuZ2UuaW5kZXggPT09IDAgfHwgdGhpcy5xdWlsbC5nZXRMZW5ndGgoKSA8PSAxKSByZXR1cm4gdHJ1ZVxuXHRcdGNvbnN0IFtsaW5lXTogW0Jsb3QsIG51bWJlcl0gPSB0aGlzLnF1aWxsLmdldExpbmUocmFuZ2UuaW5kZXgpXG5cdFx0aWYgKGNvbnRleHQub2Zmc2V0ID09PSAwICYmIGlzTGluZUFmdGVyVGFibGUobGluZSkpIHtcblx0XHRcdGdldExvZ2dlcigpLmRlYnVnKCdwcmV2ZW50IGJhY2tzcGFjZSBhZnRlciB0YWJsZScsIHsgcmFuZ2UsIGNvbnRleHQsIGxpbmUgfSlcblx0XHRcdHJldHVybiBmYWxzZVxuXHRcdH1cblx0XHQvLyBpZiBpbnNpZGUgYSBUYWJsZUNlbGxCbG90IGFuZCBhdCB0aGUgc3RhcnQgb2YgdGhlIGNlbGxcblx0XHQvLyBwcmV2ZW50IFwiYmFja3NwYWNlXCIgZnJvbSByZW1vdmluZyBwcmV2aW91cyBjZWxsXG5cdFx0Ly8gb3IgaXRlbXMgYmVmb3JlIHRoZSB0YWJsZSBpZiBpbiB0aGUgZmlyc3QgY2VsbFxuXHRcdGlmIChcblx0XHRcdC8vIGluIGEgY2VsbFxuXHRcdFx0aXNMaW5lSW5UYWJsZUNlbGwobGluZSkgJiZcblx0XHRcdC8vIGF0IHRoZSBzdGFydCBvZiB0aGUgY2VsbFxuXHRcdFx0Y29udGV4dC5vZmZzZXQgPT09IDAgJiZcblx0XHRcdCFsaW5lLnByZXYgJiZcblx0XHRcdC8vIHRoZXJlIGlzIGEgY2VsbCBiZWZvcmUgdGhpcyBvbmUgaW4gdGhlIHJvd1xuXHRcdFx0KChsaW5lLnBhcmVudC5wcmV2ICYmIGxpbmUucGFyZW50LnByZXYgaW5zdGFuY2VvZiBUYWJsZUNlbGxCbG90KSB8fFxuXHRcdFx0XHQvLyBvciB0aGUgY2VsbCBpcyBhdCB0aGUgc3RhcnQgb2YgYSByb3dcblx0XHRcdFx0IWxpbmUucGFyZW50LnByZXYpXG5cdFx0KSB7XG5cdFx0XHRnZXRMb2dnZXIoKS5kZWJ1ZygncHJldmVudCBjZWxsIGJhY2tzcGFjZScsIHsgcmFuZ2UsIGNvbnRleHQsIGxpbmUgfSlcblx0XHRcdHJldHVybiBmYWxzZVxuXHRcdH1cblx0XHRyZXR1cm4gdHJ1ZVxuXHR9XG5cblx0aGFuZGxlRGVsZXRlID0gKHJhbmdlOiBSYW5nZVN0YXRpYywgY29udGV4dDogQ29udGV4dCkgPT4ge1xuXHRcdGNvbnN0IGxlbmd0aCA9IC9eW1xcdUQ4MDAtXFx1REJGRl1bXFx1REMwMC1cXHVERkZGXS8udGVzdChjb250ZXh0LnN1ZmZpeCkgPyAyIDogMVxuXHRcdGlmIChyYW5nZS5pbmRleCA+PSB0aGlzLnF1aWxsLmdldExlbmd0aCgpIC0gbGVuZ3RoKSByZXR1cm4gdHJ1ZVxuXHRcdGNvbnN0IFtsaW5lXTogW0Jsb3QsIG51bWJlcl0gPSB0aGlzLnF1aWxsLmdldExpbmUocmFuZ2UuaW5kZXgpXG5cdFx0aWYgKGNvbnRleHQub2Zmc2V0ID09PSBsaW5lLmxlbmd0aCgpIC0gMSAmJiBpc0xpbmVCZWZvcmVUYWJsZShsaW5lKSkge1xuXHRcdFx0Z2V0TG9nZ2VyKCkuZGVidWcoJ3ByZXZlbnQgZGVsZXRlIGJlZm9yZSB0YWJsZScsIHsgcmFuZ2UsIGNvbnRleHQsIGxpbmUgfSlcblx0XHRcdHJldHVybiBmYWxzZVxuXHRcdH1cblx0XHQvLyBpZiBpbnNpZGUgYSBUYWJsZUNlbGxCbG90IGFuZCBhdCB0aGUgZW5kIG9mIHRoZSBjZWxsXG5cdFx0Ly8gcHJldmVudCBcImRlbGV0ZVwiIGZyb20gcmVtb3ZpbmcgdGhlIG5leHQgY2VsbFxuXHRcdC8vIG9yIGl0ZW1zIGFmdGVyIHRoZSB0YWJsZSBpZiBpbiB0aGUgbGFzdCBjZWxsXG5cdFx0aWYgKFxuXHRcdFx0Ly8gaW4gYSBjZWxsXG5cdFx0XHRpc0xpbmVJblRhYmxlQ2VsbChsaW5lKSAmJlxuXHRcdFx0Ly8gYXQgdGhlIGVuZCBvZiB0aGUgY2VsbFxuXHRcdFx0IWxpbmUubmV4dCAmJlxuXHRcdFx0Y29udGV4dC5vZmZzZXQgPT09IGxpbmUubGVuZ3RoKCkgLSAxICYmXG5cdFx0XHQvLyB0aGVyZSBpcyBhIGNlbGwgYWZ0ZXIgdGhpcyBvbmUgaW4gdGhlIHJvd1xuXHRcdFx0KChsaW5lLnBhcmVudC5uZXh0ICYmIGxpbmUucGFyZW50Lm5leHQgaW5zdGFuY2VvZiBUYWJsZUNlbGxCbG90KSB8fFxuXHRcdFx0XHQvLyBvciB0aGUgY2VsbCBpcyBhdCB0aGUgc3RhcnQgb2YgYSByb3dcblx0XHRcdFx0IWxpbmUucGFyZW50Lm5leHQpXG5cdFx0KSB7XG5cdFx0XHRnZXRMb2dnZXIoKS5kZWJ1ZygncHJldmVudCBjZWxsIGRlbGV0ZScsIHsgcmFuZ2UsIGNvbnRleHQsIGxpbmUgfSlcblx0XHRcdHJldHVybiBmYWxzZVxuXHRcdH1cblx0XHRyZXR1cm4gdHJ1ZVxuXHR9XG5cblx0aGFuZGxlRGVsZXRlUmFuZ2UgPSAocmFuZ2U6IFJhbmdlU3RhdGljKSA9PiB7XG5cdFx0Y29uc3QgbGluZXMgPSB0aGlzLnF1aWxsLmdldExpbmVzKHJhbmdlKVxuXHRcdGdldExvZ2dlcigpLmRlYnVnKCdoYW5kbGVEZWxldGVSYW5nZScsIHsgcmFuZ2UsIGxpbmVzIH0pXG5cdFx0Y29uc3Qgd2lsbERlbGV0ZUNlbGxXaXRob3V0Um93ID0gcmFuZ2VSZW1vdmFsV2lsbERlbGV0ZUNlbGxXaXRob3V0Um93KHRoaXMucXVpbGwsIHJhbmdlKVxuXHRcdGlmICh3aWxsRGVsZXRlQ2VsbFdpdGhvdXRSb3cpIHtcblx0XHRcdGdldExvZ2dlcigpLmRlYnVnKCdwcmV2ZW50IGRlbGV0ZSBjZWxsIG91dCBvZiByb3cnKVxuXHRcdH1cblx0XHRyZXR1cm4gIXdpbGxEZWxldGVDZWxsV2l0aG91dFJvd1xuXHR9XG5cblx0Z2V0U2VsZWN0ZWRDZWxsKCkge1xuXHRcdGNvbnN0IHNlbGVjdGlvbiA9IHRoaXMucXVpbGwuZ2V0U2VsZWN0aW9uKClcblx0XHRpZiAoIXNlbGVjdGlvbikge1xuXHRcdFx0cmV0dXJuIG51bGxcblx0XHR9XG5cdFx0Y29uc3QgbGVhZiA9IHRoaXMucXVpbGwuZ2V0TGVhZihzZWxlY3Rpb24uaW5kZXgpXG5cdFx0bGV0IGJsb3Q6IEJsb3QgfCBudWxsID0gbGVhZlswXVxuXHRcdHdoaWxlIChibG90ICYmICEoYmxvdCBpbnN0YW5jZW9mIFRhYmxlQ2VsbEJsb3QpICYmIGJsb3QucGFyZW50KSB7XG5cdFx0XHRibG90ID0gYmxvdC5wYXJlbnRcblx0XHR9XG5cdFx0aWYgKGJsb3QgaW5zdGFuY2VvZiBUYWJsZUNlbGxCbG90KSB7XG5cdFx0XHRyZXR1cm4gYmxvdFxuXHRcdH1cblx0XHRyZXR1cm4gbnVsbFxuXHR9XG5cblx0Z2V0U2VsZWN0ZWRUYWJsZSgpIHtcblx0XHRyZXR1cm4gdGhpcy5nZXRTZWxlY3RlZENlbGwoKT8udGFibGUoKVxuXHR9XG5cblx0Ly8jZW5kcmVnaW9uIEhlbHBlcnNcblxuXHQvLyNyZWdpb24gVGFibGUgSGFuZGxlclxuXG5cdHRhYmxlSGFuZGxlcihhY3Rpb246IHN0cmluZykge1xuXHRcdGdldExvZ2dlcigpLmRlYnVnKCd0YWJsZUhhbmRsZXInLCBhY3Rpb24pXG5cblx0XHQvLyByZXF1aXJlIGEgc2VsZWN0aW9uIHJhbmdlXG5cdFx0Y29uc3QgcmFuZ2UgPSB0aGlzLnF1aWxsLmdldFNlbGVjdGlvbigpXG5cdFx0aWYgKCFyYW5nZSkgcmV0dXJuXG5cblx0XHRpZiAoYWN0aW9uLmluY2x1ZGVzKFRBQkxFX0FDVElPTi5ORVdfVEFCTEUpKSB7XG5cdFx0XHR0aGlzLmFkZE5ld1RhYmxlKGFjdGlvbiwgcmFuZ2UpXG5cdFx0XHRyZXR1cm5cblx0XHR9XG5cblx0XHQvLyByZXF1aXJlIGEgc2VsZWN0ZWQgY2VsbFxuXHRcdGNvbnN0IHNlbGVjdGVkQ2VsbCA9IHRoaXMuZ2V0U2VsZWN0ZWRDZWxsKClcblx0XHRpZiAoIXNlbGVjdGVkQ2VsbCkgcmV0dXJuXG5cblx0XHRzd2l0Y2ggKGFjdGlvbikge1xuXHRcdFx0Y2FzZSBUQUJMRV9BQ1RJT04uSU5TRVJUX0NPTDpcblx0XHRcdFx0dGhpcy5pbnNlcnRDb2woc2VsZWN0ZWRDZWxsKVxuXHRcdFx0XHRicmVha1xuXHRcdFx0Y2FzZSBUQUJMRV9BQ1RJT04uSU5TRVJUX1JPVzpcblx0XHRcdFx0dGhpcy5pbnNlcnRSb3coc2VsZWN0ZWRDZWxsKVxuXHRcdFx0XHRicmVha1xuXHRcdFx0Y2FzZSBUQUJMRV9BQ1RJT04uREVMRVRFX0NPTDpcblx0XHRcdFx0dGhpcy5kZWxldGVDb2woc2VsZWN0ZWRDZWxsKVxuXHRcdFx0XHRicmVha1xuXHRcdFx0Y2FzZSBUQUJMRV9BQ1RJT04uREVMRVRFX1JPVzpcblx0XHRcdFx0dGhpcy5kZWxldGVSb3coc2VsZWN0ZWRDZWxsKVxuXHRcdFx0XHRicmVha1xuXHRcdH1cblx0fVxuXG5cdGFkZE5ld1RhYmxlKGFjdGlvbjogc3RyaW5nLCByYW5nZTogUmFuZ2VTdGF0aWMpIHtcblx0XHRjb25zdCB7IGluZGV4IH0gPSByYW5nZVxuXG5cdFx0Ly8gZS5nLiBcIm5ldy10YWJsZS0yLTJcIlxuXHRcdGNvbnN0IHNpemVzID0gYWN0aW9uLnJlcGxhY2UoVEFCTEVfQUNUSU9OLk5FV19UQUJMRSwgJycpLnNwbGl0KCdfJylcblx0XHRjb25zdCByb3dzID0gcGFyc2VJbnQoc2l6ZXNbMF0pXG5cdFx0Y29uc3QgY29scyA9IHBhcnNlSW50KHNpemVzWzFdKVxuXHRcdGNvbnN0IHRhYmxlQ29udGFpbmVyID0gVGFibGVDb250YWluZXJCbG90LmNyZWF0ZVdpdGhDaGlsZHJlbihyb3dzLCBjb2xzKVxuXG5cdFx0Ly8gaW5zZXJ0IHRoZSB0YWJsZSBpbnRvIHRoZSB0b3AgbGV2ZWwgc2Nyb2xsIGVsZW1lbnRcblx0XHQvLyBiZWZvcmUgdGhlIGN1cnJlbnQgbGVhZidzIHRvcCBsZXZlbCBicmFuY2hcblx0XHQvLyBQUkVWRU5UIE5FU1RFRCBUQUJMRVNcblx0XHRsZXQgdG9wQnJhbmNoID0gbnVsbFxuXHRcdGNvbnN0IGxlYWYgPSB0aGlzLnF1aWxsLmdldExlYWYoaW5kZXgpXG5cdFx0bGV0IGJsb3Q6IEJsb3QgfCBudWxsID0gbGVhZlswXVxuXHRcdHdoaWxlIChibG90ICYmIGJsb3QucGFyZW50ICYmICEoYmxvdCBpbnN0YW5jZW9mIFNjcm9sbCkpIHtcblx0XHRcdHRvcEJyYW5jaCA9IGJsb3Rcblx0XHRcdGJsb3QgPSBibG90LnBhcmVudFxuXHRcdH1cblxuXHRcdGlmICghYmxvdCB8fCAhKGJsb3QgaW5zdGFuY2VvZiBTY3JvbGwpKSByZXR1cm5cblxuXHRcdGJsb3QuaW5zZXJ0QmVmb3JlKHRhYmxlQ29udGFpbmVyLCB0b3BCcmFuY2ggfHwgdW5kZWZpbmVkKVxuXHRcdHRoaXMucXVpbGwuc2V0U2VsZWN0aW9uKHRhYmxlQ29udGFpbmVyLm9mZnNldCh0aGlzLnF1aWxsLnNjcm9sbCksIDAsICd1c2VyJylcblx0fVxuXG5cdGluc2VydENvbChzZWxlY3RlZENlbGw6IFRhYmxlQ2VsbEJsb3QpIHtcblx0XHRjb25zdCBzZWxlY3RlZENlbGxDb2x1bW4gPSBzZWxlY3RlZENlbGwuY29sdW1uKClcblx0XHRjb25zdCB0YWJsZUlkID0gc2VsZWN0ZWRDZWxsLnRhYmxlSWQoKVxuXHRcdGNvbnN0IHRhYmxlQm9keSA9IHNlbGVjdGVkQ2VsbC5yb3coKT8udGFibGVCb2R5KClcblx0XHRpZiAoIXRhYmxlQm9keSkgcmV0dXJuXG5cdFx0dGFibGVCb2R5LmNoaWxkcmVuLmZvckVhY2goY2hpbGQgPT4ge1xuXHRcdFx0Y29uc3QgdGFibGVSb3cgPSBjaGlsZCBhcyBUYWJsZVJvd0Jsb3Rcblx0XHRcdGNvbnN0IHJvd0lkID0gdGFibGVSb3cuaWQoKVxuXHRcdFx0Y29uc3QgdGFibGVDZWxsID0gVGFibGVDZWxsQmxvdC5jcmVhdGVXaXRoQ2hpbGRyZW4odGFibGVJZCwgcm93SWQpXG5cdFx0XHRjb25zdCBjZWxsczogQmxvdFtdID0gdGFibGVSb3cuY2hpbGRyZW4ubWFwKGMgPT4gYylcblx0XHRcdGNvbnN0IG5leHRDb2x1bW5DZWxsID0gY2VsbHMubGVuZ3RoID4gc2VsZWN0ZWRDZWxsQ29sdW1uIC0gMSA/IGNlbGxzW3NlbGVjdGVkQ2VsbENvbHVtbl0gOiB1bmRlZmluZWRcblx0XHRcdGlmIChuZXh0Q29sdW1uQ2VsbCkge1xuXHRcdFx0XHR0YWJsZVJvdy5pbnNlcnRCZWZvcmUodGFibGVDZWxsLCBuZXh0Q29sdW1uQ2VsbClcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHRhYmxlUm93LmFwcGVuZENoaWxkKHRhYmxlQ2VsbClcblx0XHRcdH1cblx0XHR9KVxuXHR9XG5cblx0aW5zZXJ0Um93KHNlbGVjdGVkQ2VsbDogVGFibGVDZWxsQmxvdCkge1xuXHRcdGNvbnN0IGN1cnJlbnRSb3cgPSBzZWxlY3RlZENlbGwucm93KClcblx0XHRpZiAoIWN1cnJlbnRSb3cpIHJldHVyblxuXHRcdGNvbnN0IG5leHRSb3cgPSBjdXJyZW50Um93Lm5leHRcblx0XHRjb25zdCB0YWJsZUJvZHkgPSBjdXJyZW50Um93LnRhYmxlQm9keSgpXG5cdFx0aWYgKCF0YWJsZUJvZHkpIHJldHVyblxuXHRcdGNvbnN0IG5ld1JvdyA9IFRhYmxlUm93QmxvdC5jcmVhdGVGcm9tUmVmZXJlbmNlKGN1cnJlbnRSb3cpXG5cdFx0aWYgKG5leHRSb3cpIHtcblx0XHRcdHRhYmxlQm9keS5pbnNlcnRCZWZvcmUobmV3Um93LCBuZXh0Um93KVxuXHRcdH0gZWxzZSB7XG5cdFx0XHR0YWJsZUJvZHkuYXBwZW5kQ2hpbGQobmV3Um93KVxuXHRcdH1cblx0fVxuXG5cdGRlbGV0ZUNvbChzZWxlY3RlZENlbGw6IFRhYmxlQ2VsbEJsb3QpIHtcblx0XHRjb25zdCBzZWxlY3RlZENlbGxDb2x1bW4gPSBzZWxlY3RlZENlbGwuY29sdW1uKClcblx0XHRjb25zdCB0YWJsZUJvZHkgPSBzZWxlY3RlZENlbGwucm93KCk/LnRhYmxlQm9keSgpXG5cdFx0aWYgKCF0YWJsZUJvZHkpIHJldHVyblxuXHRcdHRhYmxlQm9keS5jaGlsZHJlbi5mb3JFYWNoKGMgPT4ge1xuXHRcdFx0Y29uc3QgdGFibGVSb3cgPSBjIGFzIFRhYmxlUm93QmxvdFxuXHRcdFx0Y29uc3QgY2VsbHMgPSB0YWJsZVJvdy5jaGlsZHJlbi5tYXAoYyA9PiBjKVxuXHRcdFx0Y29uc3QgY2VsbCA9IGNlbGxzW3NlbGVjdGVkQ2VsbENvbHVtbiAtIDFdXG5cdFx0XHRjZWxsPy5yZW1vdmUoKVxuXHRcdH0pXG5cdH1cblxuXHRkZWxldGVSb3coc2VsZWN0ZWRDZWxsOiBUYWJsZUNlbGxCbG90KSB7XG5cdFx0Y29uc3Qgc2VsZWN0ZWRSb3cgPSBzZWxlY3RlZENlbGwucm93KClcblx0XHRpZiAoIXNlbGVjdGVkUm93KSByZXR1cm5cblx0XHRjb25zdCBjZWxsT2Zmc2V0ID0gc2VsZWN0ZWRDZWxsLm9mZnNldCgpIC8vIG9mZnNldCBpbnNpZGUgcm93XG5cdFx0Y29uc3QgdGFibGVCb2R5ID0gc2VsZWN0ZWRSb3cudGFibGVCb2R5KClcblx0XHRjb25zdCByb3dUb1NlbGVjdEFmdGVyID0gc2VsZWN0ZWRSb3cubmV4dCB8fCBzZWxlY3RlZFJvdy5wcmV2XG5cdFx0Ly8gZGVsZXRlIHRoZSByb3dcblx0XHRzZWxlY3RlZFJvdy5yZW1vdmUoKVxuXHRcdC8vIGZvY3VzIHRoZSBuZXh0IHJvdyBvciBwcmV2IHJvdyBpZiBwb3NzaWJsZVxuXHRcdGlmICh0YWJsZUJvZHkgJiYgdGFibGVCb2R5LmNoaWxkcmVuLmxlbmd0aCA+IDAgJiYgcm93VG9TZWxlY3RBZnRlcikge1xuXHRcdFx0Y29uc3QgaW5kZXggPSByb3dUb1NlbGVjdEFmdGVyLm9mZnNldCh0aGlzLnF1aWxsLnNjcm9sbClcblx0XHRcdHRoaXMucXVpbGwuc2V0U2VsZWN0aW9uKGluZGV4ICsgY2VsbE9mZnNldCwgMClc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T0FBTyxDQUFDO0lBQ3hDLENBQUMsTUFBTTtNQUNOZCxTQUFTLENBQUNZLFdBQVcsQ0FBQ0csTUFBTSxDQUFDO0lBQzlCO0VBQ0Q7RUFFQWxDLFNBQVNBLENBQUNwRyxZQUEyQixFQUFFO0lBQ3RDLE1BQU1vSCxrQkFBa0IsR0FBR3BILFlBQVksQ0FBQ3FILE1BQU0sQ0FBQyxDQUFDO0lBQ2hELE1BQU1FLFNBQVMsR0FBR3ZILFlBQVksQ0FBQ3dILEdBQUcsQ0FBQyxDQUFDLEVBQUVELFNBQVMsQ0FBQyxDQUFDO0lBQ2pELElBQUksQ0FBQ0EsU0FBUyxFQUFFO0lBQ2hCQSxTQUFTLENBQUNFLFFBQVEsQ0FBQ3RILE9BQU8sQ0FBQzhILENBQUMsSUFBSTtNQUMvQixNQUFNTixRQUFRLEdBQUdNLENBQWlCO01BQ2xDLE1BQU1GLEtBQUssR0FBR0osUUFBUSxDQUFDRixRQUFRLENBQUNPLEdBQUcsQ0FBQ0MsQ0FBQyxJQUFJQSxDQUFDLENBQUM7TUFDM0MsTUFBTU8sSUFBSSxHQUFHVCxLQUFLLENBQUNYLGtCQUFrQixHQUFHLENBQUMsQ0FBQztNQUMxQ29CLElBQUksRUFBRWxJLE1BQU0sQ0FBQyxDQUFDO0lBQ2YsQ0FBQyxDQUFDO0VBQ0g7RUFFQWdHLFNBQVNBLENBQUN0RyxZQUEyQixFQUFFO0lBQ3RDLE1BQU15SSxXQUFXLEdBQUd6SSxZQUFZLENBQUN3SCxHQUFHLENBQUMsQ0FBQztJQUN0QyxJQUFJLENBQUNpQixXQUFXLEVBQUU7SUFDbEIsTUFBTUMsVUFBVSxHQUFHMUksWUFBWSxDQUFDYyxNQUFNLENBQUMsQ0FBQyxFQUFDO0lBQ3pDLE1BQU15RyxTQUFTLEdBQUdrQixXQUFXLENBQUNsQixTQUFTLENBQUMsQ0FBQztJQUN6QyxNQUFNb0IsZ0JBQWdCLEdBQUdGLFdBQVcsQ0FBQ2hILElBQUksSUFBSWdILFdBQVcsQ0FBQ3RILElBQUk7SUFDN0Q7SUFDQXNILFdBQVcsQ0FBQ25JLE1BQU0sQ0FBQyxDQUFDO0lBQ3BCO0lBQ0EsSUFBSWlILFNBQVMsSUFBSUEsU0FBUyxDQUFDRSxRQUFRLENBQUNwRyxNQUFNLEdBQUcsQ0FBQyxJQUFJc0gsZ0JBQWdCLEVBQUU7TUFDbkUsTUFBTWpJLEtBQUssR0FBR2lJLGdCQUFnQixDQUFDN0gsTUFBTSxDQUFDLElBQUksQ0FBQ2xCLEtBQUssQ0FBQ3VILE1BQU0sQ0FBQztNQUN4RCxJQUFJLENBQUN2SCxLQUFLLENBQUNzSCxZQUFZLENBQUN4RyxLQUFLLEdBQUdnSSxVQUFVLEVBQUUsQ0FBQyxDQUFDO0lBQy9DO0VBQ0Q7O0VBRUE7QUFDRDtBQUFDRSxPQUFBLENBQUF6SixXQUFBLEdBQUFBLFdBQUEiLCJpZ25vcmVMaXN0IjpbXX0=
|