studiokit-scaffolding-js 7.0.12-next.1.4 → 7.0.12-next.2.2

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