@rivet-health/design-system 40.44.0 → 40.44.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.
- package/{esm2020 → esm2022}/lib/accessibility/sr-only/sr-only.component.mjs +4 -4
- package/esm2022/lib/download/download.service.mjs +47 -0
- package/{esm2020 → esm2022}/lib/format/pipes/common.mjs +5 -5
- package/{esm2020 → esm2022}/lib/format/pipes/date.pipe.mjs +4 -4
- package/{esm2020 → esm2022}/lib/format/pipes/days.pipe.mjs +4 -4
- package/{esm2020 → esm2022}/lib/format/pipes/dollars.pipe.mjs +4 -4
- package/{esm2020 → esm2022}/lib/format/pipes/number.pipe.mjs +4 -4
- package/{esm2020 → esm2022}/lib/format/pipes/percentage.pipe.mjs +4 -4
- package/esm2022/lib/format/pipes/sentence-case.pipe.mjs +61 -0
- package/esm2022/lib/format/pipes/small-currency.pipe.mjs +24 -0
- package/esm2022/lib/format/pipes/small-number.pipe.mjs +29 -0
- package/esm2022/lib/format/svg-text-truncate/svg-text-truncate.directive.mjs +62 -0
- package/esm2022/lib/format/truncate/truncate.component.mjs +51 -0
- package/esm2022/lib/icon/dom-cache.mjs +32 -0
- package/esm2022/lib/icon/icon.component.mjs +86 -0
- package/{esm2020 → esm2022}/lib/icon/icons.mjs +1 -1
- package/{esm2020 → esm2022}/lib/input/alphabetic-field/alphabetic-field.component.mjs +4 -4
- package/esm2022/lib/input/auto-focus/auto-focus.directive.mjs +48 -0
- package/esm2022/lib/input/button/button.component.mjs +139 -0
- package/esm2022/lib/input/button-group/button-group.component.mjs +39 -0
- package/{esm2020 → esm2022}/lib/input/calendar/calendar.component.mjs +4 -4
- package/{esm2020 → esm2022}/lib/input/card-checkbox/card-checkbox.component.mjs +4 -4
- package/{esm2020 → esm2022}/lib/input/checkbox/checkbox.component.mjs +4 -4
- package/{esm2020 → esm2022}/lib/input/currency-field/currency-field.component.mjs +4 -4
- package/esm2022/lib/input/date/date.component.mjs +279 -0
- package/esm2022/lib/input/date-range/date-range.component.mjs +477 -0
- package/esm2022/lib/input/filter-chip/filter-chip.component.mjs +47 -0
- package/{esm2020 → esm2022}/lib/input/filter-dropdown/filter-dropdown.component.mjs +5 -5
- package/{esm2020 → esm2022}/lib/input/input-label/input-label.component.mjs +4 -4
- package/esm2022/lib/input/mentions-input/mentions-input.component.mjs +745 -0
- package/esm2022/lib/input/number-field/number-field.component.mjs +125 -0
- package/{esm2020 → esm2022}/lib/input/percentage-field/percentage-field.component.mjs +4 -4
- package/esm2022/lib/input/phone-field/phone-field.component.mjs +74 -0
- package/{esm2020 → esm2022}/lib/input/radio/radio.component.mjs +4 -4
- package/{esm2020 → esm2022}/lib/input/search/search.component.mjs +4 -4
- package/esm2022/lib/input/search-select/search-select.component.mjs +189 -0
- package/esm2022/lib/input/select/select/select.component.mjs +178 -0
- package/{esm2020 → esm2022}/lib/input/select/select-node/select-node.component.mjs +4 -4
- package/esm2022/lib/input/select/state.mjs +882 -0
- package/{esm2020 → esm2022}/lib/input/simple-select/option-group.pipe.mjs +4 -4
- package/esm2022/lib/input/simple-select/simple-select.component.mjs +178 -0
- package/esm2022/lib/input/switch-checkbox/switch-checkbox.component.mjs +33 -0
- package/esm2022/lib/input/text-field/text-field.component.mjs +115 -0
- package/{esm2020 → esm2022}/lib/input/textarea-field/textarea-field.component.mjs +4 -4
- package/{esm2020 → esm2022}/lib/input/validation-message/validation-message.component.mjs +4 -4
- package/{esm2020 → esm2022}/lib/layout/card/card-actions.component.mjs +4 -4
- package/esm2022/lib/layout/card/card-content.component.mjs +64 -0
- package/esm2022/lib/layout/card/card-header.component.mjs +201 -0
- package/{esm2020 → esm2022}/lib/layout/card/card-link.component.mjs +5 -5
- package/{esm2020 → esm2022}/lib/layout/card/card-media.component.mjs +4 -4
- package/esm2022/lib/layout/card/card.component.mjs +291 -0
- package/{esm2020 → esm2022}/lib/layout/setting-row/setting-row.component.mjs +4 -4
- package/esm2022/lib/load/loading/loading.component.mjs +43 -0
- package/{esm2020 → esm2022}/lib/load/loading-cover/loading-cover.component.mjs +4 -4
- package/esm2022/lib/navigation/editable-heading/editable-heading.component.mjs +243 -0
- package/{esm2020 → esm2022}/lib/navigation/link/link.component.mjs +6 -6
- package/{esm2020 → esm2022}/lib/navigation/page-header/page-header.component.mjs +4 -4
- package/{esm2020 → esm2022}/lib/navigation/simple-tabs/simple-tab/simple-tab.component.mjs +4 -4
- package/{esm2020 → esm2022}/lib/navigation/simple-tabs/simple-tabs/simple-tabs.component.mjs +4 -4
- package/{esm2020 → esm2022}/lib/navigation/tabs/tab/tab.component.mjs +4 -4
- package/{esm2020 → esm2022}/lib/navigation/tabs/tabs/tabs.component.mjs +4 -4
- package/{esm2020 → esm2022}/lib/navigation/views/all-views-modal/all-views-modal.component.mjs +4 -4
- package/{esm2020 → esm2022}/lib/navigation/views/edit-view/edit-view.component.mjs +9 -9
- package/esm2022/lib/navigation/views/permission-picker/permission-picker.component.mjs +151 -0
- package/esm2022/lib/navigation/views/state.mjs +456 -0
- package/{esm2020 → esm2022}/lib/navigation/views/view-menu/view-menu.component.mjs +5 -5
- package/esm2022/lib/navigation/views/views/views.component.mjs +90 -0
- package/{esm2020 → esm2022}/lib/notification/badge/badge.component.mjs +4 -4
- package/esm2022/lib/notification/banner/banner-action.component.mjs +48 -0
- package/esm2022/lib/notification/banner/banner.component.mjs +61 -0
- package/esm2022/lib/notification/map-indicator/map-indicator.component.mjs +50 -0
- package/esm2022/lib/notification/map-indicator/map-indicators.mjs +15 -0
- package/{esm2020 → esm2022}/lib/notification/notification-badge/notification-badge.component.mjs +4 -4
- package/esm2022/lib/overlay/callout/callout.component.mjs +130 -0
- package/esm2022/lib/overlay/callout/callout.helpers.mjs +113 -0
- package/{esm2020 → esm2022}/lib/overlay/callout/help/help.component.mjs +4 -4
- package/esm2022/lib/overlay/callout/lock-scroll.directive.mjs +69 -0
- package/{esm2020 → esm2022}/lib/overlay/callout/menu/menu-item/menu-item.component.mjs +5 -5
- package/{esm2020 → esm2022}/lib/overlay/callout/menu/menu.component.mjs +4 -4
- package/esm2022/lib/overlay/callout/tooltip/locked-tooltip.directive.mjs +30 -0
- package/{esm2020 → esm2022}/lib/overlay/callout/tooltip/tooltip.component.mjs +4 -4
- package/esm2022/lib/overlay/callout/tooltip/tooltip.directive.mjs +138 -0
- package/esm2022/lib/overlay/modal/dialog/dialog.component.mjs +47 -0
- package/{esm2020 → esm2022}/lib/overlay/modal/dialog-stack.service.mjs +4 -4
- package/esm2022/lib/overlay/modal/form-dialog/form-dialog.component.mjs +146 -0
- package/esm2022/lib/overlay/modal/modal.component.mjs +31 -0
- package/{esm2020 → esm2022}/lib/overlay/modal/side-sheet/side-sheet.component.mjs +4 -4
- package/esm2022/lib/overlay/overlay-outlet.component.mjs +98 -0
- package/{esm2020 → esm2022}/lib/overlay/overlay.directive.mjs +5 -5
- package/{esm2020 → esm2022}/lib/overlay/overlay.service.mjs +5 -5
- package/{esm2020 → esm2022}/lib/overlay/toast/toast-action.component.mjs +4 -4
- package/esm2022/lib/overlay/toast/toast.component.mjs +41 -0
- package/{esm2020 → esm2022}/lib/riv.module.mjs +227 -227
- package/esm2022/lib/size/size.directive.mjs +33 -0
- package/esm2022/lib/table/simple-table/coordinate-helper.mjs +61 -0
- package/esm2022/lib/table/simple-table/simple-table-cell.component.mjs +36 -0
- package/esm2022/lib/table/simple-table/simple-table-header-cell.component.mjs +37 -0
- package/{esm2020 → esm2022}/lib/table/simple-table/simple-table-row.component.mjs +4 -4
- package/esm2022/lib/table/simple-table/simple-table.component.mjs +104 -0
- package/esm2022/lib/table/table/clipboard.mjs +182 -0
- package/esm2022/lib/table/table/state-helpers/collapse-helpers.mjs +116 -0
- package/esm2022/lib/table/table/state-helpers/column-helpers.mjs +383 -0
- package/{esm2020 → esm2022}/lib/table/table/state-helpers/display-helpers.mjs +1 -1
- package/esm2022/lib/table/table/state-helpers/nesting-helpers.mjs +123 -0
- package/esm2022/lib/table/table/state-helpers/order-helpers.mjs +164 -0
- package/esm2022/lib/table/table/state-helpers/pagination-helpers.mjs +139 -0
- package/esm2022/lib/table/table/state-helpers/result-helpers.mjs +70 -0
- package/esm2022/lib/table/table/state-helpers/search-helpers.mjs +72 -0
- package/esm2022/lib/table/table/state-helpers/selection-helpers.mjs +180 -0
- package/esm2022/lib/table/table/state.mjs +1035 -0
- package/esm2022/lib/table/table/table/table.component.mjs +367 -0
- package/{esm2020 → esm2022}/lib/table/table/table-collapse-all/table-collapse-all.component.mjs +5 -5
- package/esm2022/lib/table/table/table-column-settings/table-column-settings-side-sheet.component.mjs +227 -0
- package/esm2022/lib/table/table/table-column-settings/table-column-settings.component.mjs +134 -0
- package/esm2022/lib/table/table/table-csv-export/table-csv-export.component.mjs +35 -0
- package/{esm2020 → esm2022}/lib/table/table/table-header-resize-handle/table-header-resize-handle.component.mjs +6 -6
- package/esm2022/lib/table/table/table-search/table-search.component.mjs +71 -0
- package/{esm2020 → esm2022}/lib/table/table/table-search-columns/table-search-columns.component.mjs +4 -4
- package/esm2022/lib/visibility/visibility.directive.mjs +34 -0
- package/esm2022/lib/visualization/chart/chart-scaling.mjs +380 -0
- package/esm2022/lib/visualization/chart/chart.component.mjs +626 -0
- package/esm2022/lib/visualization/chart/chart.mjs +3768 -0
- package/{esm2020 → esm2022}/lib/visualization/data-table/data-table-cell.component.mjs +5 -5
- package/{esm2020 → esm2022}/lib/visualization/data-table/data-table-header-cell.component.mjs +4 -4
- package/{esm2020 → esm2022}/lib/visualization/data-table/data-table-row.component.mjs +4 -4
- package/{esm2020 → esm2022}/lib/visualization/data-table/data-table.component.mjs +4 -4
- package/{esm2020 → esm2022}/lib/visualization/donut/donut.component.mjs +4 -4
- package/{esm2020 → esm2022}/lib/visualization/funnel-chart/funnel-chart.component.mjs +5 -5
- package/esm2022/lib/visualization/funnel-chart/funnel-chart.helpers.mjs +33 -0
- package/{esm2020 → esm2022}/lib/visualization/highlight/highlight.component.mjs +4 -4
- package/esm2022/lib/visualization/highlight/highlight.helpers.mjs +20 -0
- package/esm2022/lib/visualization/intervals.mjs +63 -0
- package/{esm2020 → esm2022}/lib/visualization/issue/issue.component.mjs +4 -4
- package/{esm2020 → esm2022}/lib/visualization/legend-item/legend-item.component.mjs +4 -4
- package/{esm2020 → esm2022}/lib/visualization/metric/metric.component.mjs +4 -4
- package/{esm2020 → esm2022}/lib/visualization/mini-pie/mini-pie.component.mjs +4 -4
- package/{esm2020 → esm2022}/lib/visualization/progress/progress.component.mjs +5 -5
- package/esm2022/lib/visualization/stacked-column/stacked-column.component.mjs +377 -0
- package/esm2022/lib/visualization/stacked-column/stacked-column.helpers.mjs +18 -0
- package/esm2022/lib/visualization/stacked-row/stacked-row.component.mjs +270 -0
- package/esm2022/lib/visualization/stacked-row/stacked-row.helpers.mjs +74 -0
- package/esm2022/lib/visualization/time-series/time-series.component.mjs +374 -0
- package/esm2022/lib/visualization/time-series/time-series.helpers.mjs +15 -0
- package/esm2022/lib/visualization/trend/trend.component.mjs +51 -0
- package/{esm2020 → esm2022}/lib/visualization/zero-state/zero-state.component.mjs +4 -4
- package/{fesm2020 → fesm2022}/rivet-health-design-system.mjs +670 -670
- package/{fesm2020 → fesm2022}/rivet-health-design-system.mjs.map +1 -1
- package/lib/format/svg-text-truncate/svg-text-truncate.directive.d.ts +1 -1
- package/lib/format/truncate/truncate.component.d.ts +1 -1
- package/lib/icon/icon.component.d.ts +1 -1
- package/lib/input/auto-focus/auto-focus.directive.d.ts +1 -1
- package/lib/input/button/button.component.d.ts +1 -1
- package/lib/input/calendar/calendar.component.d.ts +1 -1
- package/lib/input/checkbox/checkbox.component.d.ts +1 -1
- package/lib/input/currency-field/currency-field.component.d.ts +1 -1
- package/lib/input/date/date.component.d.ts +1 -1
- package/lib/input/date-range/date-range.component.d.ts +1 -1
- package/lib/input/filter-chip/filter-chip.component.d.ts +1 -1
- package/lib/input/filter-dropdown/filter-dropdown.component.d.ts +1 -1
- package/lib/input/input-label/input-label.component.d.ts +1 -1
- package/lib/input/mentions-input/mentions-input.component.d.ts +1 -1
- package/lib/input/number-field/number-field.component.d.ts +1 -1
- package/lib/input/percentage-field/percentage-field.component.d.ts +1 -1
- package/lib/input/phone-field/phone-field.component.d.ts +1 -1
- package/lib/input/radio/radio.component.d.ts +1 -1
- package/lib/input/search/search.component.d.ts +1 -1
- package/lib/input/search-select/search-select.component.d.ts +1 -1
- package/lib/input/select/select/select.component.d.ts +1 -1
- package/lib/input/select/select-node/select-node.component.d.ts +1 -1
- package/lib/input/simple-select/simple-select.component.d.ts +1 -1
- package/lib/input/switch-checkbox/switch-checkbox.component.d.ts +1 -1
- package/lib/input/text-field/text-field.component.d.ts +1 -1
- package/lib/input/textarea-field/textarea-field.component.d.ts +1 -1
- package/lib/input/validation-message/validation-message.component.d.ts +1 -1
- package/lib/layout/card/card-actions.component.d.ts +1 -1
- package/lib/layout/card/card-content.component.d.ts +1 -1
- package/lib/layout/card/card-header.component.d.ts +1 -1
- package/lib/layout/card/card-link.component.d.ts +1 -1
- package/lib/layout/card/card-media.component.d.ts +1 -1
- package/lib/layout/card/card.component.d.ts +1 -1
- package/lib/layout/setting-row/setting-row.component.d.ts +1 -1
- package/lib/load/loading/loading.component.d.ts +1 -1
- package/lib/load/loading-cover/loading-cover.component.d.ts +1 -1
- package/lib/navigation/editable-heading/editable-heading.component.d.ts +1 -1
- package/lib/navigation/link/link.component.d.ts +1 -1
- package/lib/navigation/page-header/page-header.component.d.ts +1 -1
- package/lib/navigation/simple-tabs/simple-tab/simple-tab.component.d.ts +1 -1
- package/lib/navigation/tabs/tab/tab.component.d.ts +1 -1
- package/lib/navigation/views/all-views-modal/all-views-modal.component.d.ts +1 -1
- package/lib/navigation/views/edit-view/edit-view.component.d.ts +1 -1
- package/lib/navigation/views/permission-picker/permission-picker.component.d.ts +3 -3
- package/lib/navigation/views/view-menu/view-menu.component.d.ts +1 -1
- package/lib/navigation/views/views/views.component.d.ts +1 -1
- package/lib/notification/badge/badge.component.d.ts +1 -1
- package/lib/notification/banner/banner-action.component.d.ts +1 -1
- package/lib/notification/banner/banner.component.d.ts +1 -1
- package/lib/notification/map-indicator/map-indicator.component.d.ts +1 -1
- package/lib/notification/notification-badge/notification-badge.component.d.ts +1 -1
- package/lib/overlay/callout/callout.component.d.ts +1 -1
- package/lib/overlay/callout/help/help.component.d.ts +1 -1
- package/lib/overlay/callout/lock-scroll.directive.d.ts +1 -1
- package/lib/overlay/callout/menu/menu-item/menu-item.component.d.ts +1 -1
- package/lib/overlay/callout/menu/menu.component.d.ts +1 -1
- package/lib/overlay/callout/tooltip/locked-tooltip.directive.d.ts +1 -1
- package/lib/overlay/callout/tooltip/tooltip.component.d.ts +1 -1
- package/lib/overlay/callout/tooltip/tooltip.directive.d.ts +1 -1
- package/lib/overlay/modal/dialog/dialog.component.d.ts +1 -1
- package/lib/overlay/modal/form-dialog/form-dialog.component.d.ts +1 -1
- package/lib/overlay/modal/modal.component.d.ts +1 -1
- package/lib/overlay/modal/side-sheet/side-sheet.component.d.ts +1 -1
- package/lib/overlay/toast/toast.component.d.ts +1 -1
- package/lib/table/simple-table/simple-table-header-cell.component.d.ts +1 -1
- package/lib/table/simple-table/simple-table-row.component.d.ts +1 -1
- package/lib/table/table/table/table.component.d.ts +1 -1
- package/lib/table/table/table-collapse-all/table-collapse-all.component.d.ts +1 -1
- package/lib/table/table/table-column-settings/table-column-settings-side-sheet.component.d.ts +1 -1
- package/lib/table/table/table-column-settings/table-column-settings.component.d.ts +1 -1
- package/lib/table/table/table-csv-export/table-csv-export.component.d.ts +1 -1
- package/lib/table/table/table-search/table-search.component.d.ts +1 -1
- package/lib/table/table/table-search-columns/table-search-columns.component.d.ts +1 -1
- package/lib/visualization/chart/chart.component.d.ts +1 -1
- package/lib/visualization/data-table/data-table-row.component.d.ts +1 -1
- package/lib/visualization/donut/donut.component.d.ts +1 -1
- package/lib/visualization/funnel-chart/funnel-chart.component.d.ts +1 -1
- package/lib/visualization/highlight/highlight.component.d.ts +1 -1
- package/lib/visualization/issue/issue.component.d.ts +1 -1
- package/lib/visualization/legend-item/legend-item.component.d.ts +1 -1
- package/lib/visualization/metric/metric.component.d.ts +1 -1
- package/lib/visualization/mini-pie/mini-pie.component.d.ts +1 -1
- package/lib/visualization/progress/progress.component.d.ts +1 -1
- package/lib/visualization/stacked-column/stacked-column.component.d.ts +3 -3
- package/lib/visualization/stacked-row/stacked-row.component.d.ts +1 -1
- package/lib/visualization/time-series/time-series.component.d.ts +3 -3
- package/lib/visualization/trend/trend.component.d.ts +1 -1
- package/lib/visualization/zero-state/zero-state.component.d.ts +1 -1
- package/package.json +5 -11
- package/esm2020/lib/download/download.service.mjs +0 -47
- package/esm2020/lib/format/pipes/sentence-case.pipe.mjs +0 -61
- package/esm2020/lib/format/pipes/small-currency.pipe.mjs +0 -24
- package/esm2020/lib/format/pipes/small-number.pipe.mjs +0 -29
- package/esm2020/lib/format/svg-text-truncate/svg-text-truncate.directive.mjs +0 -62
- package/esm2020/lib/format/truncate/truncate.component.mjs +0 -51
- package/esm2020/lib/icon/dom-cache.mjs +0 -32
- package/esm2020/lib/icon/icon.component.mjs +0 -86
- package/esm2020/lib/input/auto-focus/auto-focus.directive.mjs +0 -48
- package/esm2020/lib/input/button/button.component.mjs +0 -139
- package/esm2020/lib/input/button-group/button-group.component.mjs +0 -39
- package/esm2020/lib/input/date/date.component.mjs +0 -279
- package/esm2020/lib/input/date-range/date-range.component.mjs +0 -477
- package/esm2020/lib/input/filter-chip/filter-chip.component.mjs +0 -47
- package/esm2020/lib/input/mentions-input/mentions-input.component.mjs +0 -745
- package/esm2020/lib/input/number-field/number-field.component.mjs +0 -125
- package/esm2020/lib/input/phone-field/phone-field.component.mjs +0 -74
- package/esm2020/lib/input/search-select/search-select.component.mjs +0 -189
- package/esm2020/lib/input/select/select/select.component.mjs +0 -178
- package/esm2020/lib/input/select/state.mjs +0 -882
- package/esm2020/lib/input/simple-select/simple-select.component.mjs +0 -178
- package/esm2020/lib/input/switch-checkbox/switch-checkbox.component.mjs +0 -33
- package/esm2020/lib/input/text-field/text-field.component.mjs +0 -115
- package/esm2020/lib/layout/card/card-content.component.mjs +0 -64
- package/esm2020/lib/layout/card/card-header.component.mjs +0 -201
- package/esm2020/lib/layout/card/card.component.mjs +0 -291
- package/esm2020/lib/load/loading/loading.component.mjs +0 -43
- package/esm2020/lib/navigation/editable-heading/editable-heading.component.mjs +0 -243
- package/esm2020/lib/navigation/views/permission-picker/permission-picker.component.mjs +0 -151
- package/esm2020/lib/navigation/views/state.mjs +0 -456
- package/esm2020/lib/navigation/views/views/views.component.mjs +0 -90
- package/esm2020/lib/notification/banner/banner-action.component.mjs +0 -48
- package/esm2020/lib/notification/banner/banner.component.mjs +0 -61
- package/esm2020/lib/notification/map-indicator/map-indicator.component.mjs +0 -50
- package/esm2020/lib/notification/map-indicator/map-indicators.mjs +0 -15
- package/esm2020/lib/overlay/callout/callout.component.mjs +0 -130
- package/esm2020/lib/overlay/callout/callout.helpers.mjs +0 -113
- package/esm2020/lib/overlay/callout/lock-scroll.directive.mjs +0 -69
- package/esm2020/lib/overlay/callout/tooltip/locked-tooltip.directive.mjs +0 -30
- package/esm2020/lib/overlay/callout/tooltip/tooltip.directive.mjs +0 -138
- package/esm2020/lib/overlay/modal/dialog/dialog.component.mjs +0 -47
- package/esm2020/lib/overlay/modal/form-dialog/form-dialog.component.mjs +0 -146
- package/esm2020/lib/overlay/modal/modal.component.mjs +0 -31
- package/esm2020/lib/overlay/overlay-outlet.component.mjs +0 -98
- package/esm2020/lib/overlay/toast/toast.component.mjs +0 -41
- package/esm2020/lib/size/size.directive.mjs +0 -33
- package/esm2020/lib/table/simple-table/coordinate-helper.mjs +0 -61
- package/esm2020/lib/table/simple-table/simple-table-cell.component.mjs +0 -36
- package/esm2020/lib/table/simple-table/simple-table-header-cell.component.mjs +0 -37
- package/esm2020/lib/table/simple-table/simple-table.component.mjs +0 -104
- package/esm2020/lib/table/table/clipboard.mjs +0 -182
- package/esm2020/lib/table/table/state-helpers/collapse-helpers.mjs +0 -116
- package/esm2020/lib/table/table/state-helpers/column-helpers.mjs +0 -383
- package/esm2020/lib/table/table/state-helpers/nesting-helpers.mjs +0 -123
- package/esm2020/lib/table/table/state-helpers/order-helpers.mjs +0 -164
- package/esm2020/lib/table/table/state-helpers/pagination-helpers.mjs +0 -139
- package/esm2020/lib/table/table/state-helpers/result-helpers.mjs +0 -70
- package/esm2020/lib/table/table/state-helpers/search-helpers.mjs +0 -72
- package/esm2020/lib/table/table/state-helpers/selection-helpers.mjs +0 -180
- package/esm2020/lib/table/table/state.mjs +0 -1035
- package/esm2020/lib/table/table/table/table.component.mjs +0 -367
- package/esm2020/lib/table/table/table-column-settings/table-column-settings-side-sheet.component.mjs +0 -227
- package/esm2020/lib/table/table/table-column-settings/table-column-settings.component.mjs +0 -134
- package/esm2020/lib/table/table/table-csv-export/table-csv-export.component.mjs +0 -35
- package/esm2020/lib/table/table/table-search/table-search.component.mjs +0 -71
- package/esm2020/lib/visibility/visibility.directive.mjs +0 -34
- package/esm2020/lib/visualization/chart/chart-scaling.mjs +0 -380
- package/esm2020/lib/visualization/chart/chart.component.mjs +0 -626
- package/esm2020/lib/visualization/chart/chart.mjs +0 -3768
- package/esm2020/lib/visualization/funnel-chart/funnel-chart.helpers.mjs +0 -33
- package/esm2020/lib/visualization/highlight/highlight.helpers.mjs +0 -20
- package/esm2020/lib/visualization/intervals.mjs +0 -63
- package/esm2020/lib/visualization/stacked-column/stacked-column.component.mjs +0 -377
- package/esm2020/lib/visualization/stacked-column/stacked-column.helpers.mjs +0 -18
- package/esm2020/lib/visualization/stacked-row/stacked-row.component.mjs +0 -270
- package/esm2020/lib/visualization/stacked-row/stacked-row.helpers.mjs +0 -74
- package/esm2020/lib/visualization/time-series/time-series.component.mjs +0 -374
- package/esm2020/lib/visualization/time-series/time-series.helpers.mjs +0 -15
- package/esm2020/lib/visualization/trend/trend.component.mjs +0 -51
- package/fesm2015/rivet-health-design-system.mjs +0 -18370
- package/fesm2015/rivet-health-design-system.mjs.map +0 -1
- /package/{esm2020 → esm2022}/lib/overlay/callout/select-callout-defaults.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/util/local-storage.mjs +0 -0
- /package/{esm2020 → esm2022}/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/rivet-health-design-system.mjs +0 -0
|
@@ -1,745 +0,0 @@
|
|
|
1
|
-
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output, ViewChild, ViewEncapsulation, } from '@angular/core';
|
|
2
|
-
import * as i0 from "@angular/core";
|
|
3
|
-
import * as i1 from "@angular/common";
|
|
4
|
-
import * as i2 from "../../overlay/callout/callout.component";
|
|
5
|
-
const ZWS = '';
|
|
6
|
-
const ZWS_REGEX = //g;
|
|
7
|
-
/**
|
|
8
|
-
* A rich text input that supports `@`-mentions inside a `contenteditable` div.
|
|
9
|
-
*
|
|
10
|
-
* ## Data Model
|
|
11
|
-
* - **Input/Output**: `ContentItem[]` (mentions, text, newlines)
|
|
12
|
-
*
|
|
13
|
-
* ## DOM Invariant
|
|
14
|
-
* Every mention `<span data-type="mention" contenteditable="false">` is wrapped
|
|
15
|
-
* by exactly one zero-width-space (ZWS) text node before and after it. ZWS gives
|
|
16
|
-
* the cursor a valid landing spot adjacent to a non-editable element. The
|
|
17
|
-
* invariant is established at render time and re-established by
|
|
18
|
-
* `normalizeMentionPadding()` after any DOM-mutating operation.
|
|
19
|
-
*
|
|
20
|
-
* ## Copy/Paste
|
|
21
|
-
* - **Copy**: `range.cloneContents()` preserves `data-*` attributes (only the
|
|
22
|
-
* browser's default copy path strips them). We override copy, serialize the
|
|
23
|
-
* clone ourselves, and strip ZWS from the output.
|
|
24
|
-
* - **Paste**: HTML paths look for `data-type="mention"` spans and rebuild
|
|
25
|
-
* them; otherwise plaintext fallback.
|
|
26
|
-
*/
|
|
27
|
-
export class MentionsInputComponent {
|
|
28
|
-
constructor(cdr) {
|
|
29
|
-
this.cdr = cdr;
|
|
30
|
-
this.content = [];
|
|
31
|
-
this.users = [];
|
|
32
|
-
this.readonly = false;
|
|
33
|
-
this.placeholder = 'Add a comment';
|
|
34
|
-
this.contentChange = new EventEmitter();
|
|
35
|
-
this.mentionsVisible = false;
|
|
36
|
-
this.mentionSearchText = '';
|
|
37
|
-
this.mentionAnchor = null;
|
|
38
|
-
this.selectedUserIndex = 0;
|
|
39
|
-
this.savedRange = null;
|
|
40
|
-
}
|
|
41
|
-
ngAfterViewInit() {
|
|
42
|
-
this.renderContent();
|
|
43
|
-
}
|
|
44
|
-
//DAHNE NOTE - ngOnChanges is called whenever any @Input() property changes, where the changed input contains information about those changes
|
|
45
|
-
//So if @Input() content changes and it's not the first change (the first render is handled by ngAfterViewInit()), we render the content
|
|
46
|
-
ngOnChanges(changes) {
|
|
47
|
-
if (changes['content'] && !changes['content'].firstChange) {
|
|
48
|
-
this.renderContent();
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
renderContent() {
|
|
52
|
-
//This is necessary because the @ViewChild reference isn't available until after the view initializes
|
|
53
|
-
if (!this.inputElement?.nativeElement) {
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
const html = this.content
|
|
57
|
-
.map(item => {
|
|
58
|
-
const itemHtml = MentionsInputComponent.contentItemToHtml(item, this.readonly);
|
|
59
|
-
return item.type === 'mention' ? `${ZWS}${itemHtml}${ZWS}` : itemHtml;
|
|
60
|
-
})
|
|
61
|
-
.join('');
|
|
62
|
-
this.inputElement.nativeElement.innerHTML = html;
|
|
63
|
-
}
|
|
64
|
-
static contentItemToHtml(item, readonly) {
|
|
65
|
-
switch (item.type) {
|
|
66
|
-
//DAHNE TODO - maybe we escape HTML here too? Although I don't think it will be possible for users to input an XSS attack in item.name
|
|
67
|
-
case 'mention':
|
|
68
|
-
return `<span class="${readonly ? 'readonly-mention' : 'mention'}" data-id="${item.id}" data-type="mention" contenteditable="false">@${MentionsInputComponent.escapeHtml(item.name)}</span>`;
|
|
69
|
-
case 'text':
|
|
70
|
-
return MentionsInputComponent.escapeHtml(item.text);
|
|
71
|
-
case 'newline':
|
|
72
|
-
return '<br>';
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
static escapeHtml(text) {
|
|
76
|
-
const div = document.createElement('div');
|
|
77
|
-
div.textContent = text;
|
|
78
|
-
return div.innerHTML;
|
|
79
|
-
}
|
|
80
|
-
// ─── Event handlers ───────────────────────────────────────────────────
|
|
81
|
-
onInput() {
|
|
82
|
-
this.normalizeMentionPadding();
|
|
83
|
-
this.checkForMentionTrigger();
|
|
84
|
-
this.emitContentChange();
|
|
85
|
-
}
|
|
86
|
-
onKeyDown(event) {
|
|
87
|
-
if (this.mentionsVisible) {
|
|
88
|
-
this.handleMentionsDropdownNav(event);
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
91
|
-
// Word/line jump: native behavior.
|
|
92
|
-
if (event.metaKey || event.ctrlKey) {
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
95
|
-
if (event.key === 'ArrowLeft' || event.key === 'ArrowRight') {
|
|
96
|
-
const direction = event.key === 'ArrowLeft' ? 'before' : 'after';
|
|
97
|
-
const mention = this.findMentionAdjacentToCursor(direction);
|
|
98
|
-
if (mention) {
|
|
99
|
-
event.preventDefault();
|
|
100
|
-
if (event.shiftKey) {
|
|
101
|
-
this.extendSelectionAcrossMention(mention, direction);
|
|
102
|
-
}
|
|
103
|
-
else {
|
|
104
|
-
this.placeCursorAdjacentToMention(mention, direction);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
if (event.key === 'Backspace' || event.key === 'Delete') {
|
|
110
|
-
const direction = event.key === 'Backspace' ? 'before' : 'after';
|
|
111
|
-
const mention = this.findMentionAdjacentToCursor(direction);
|
|
112
|
-
if (mention) {
|
|
113
|
-
event.preventDefault();
|
|
114
|
-
this.removeMention(mention);
|
|
115
|
-
this.emitContentChange();
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
|
-
if (event.key === 'Backspace') {
|
|
119
|
-
const br = this.findBrAdjacentToCursor();
|
|
120
|
-
if (br) {
|
|
121
|
-
event.preventDefault();
|
|
122
|
-
br.remove();
|
|
123
|
-
this.emitContentChange();
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
return;
|
|
127
|
-
}
|
|
128
|
-
//Handle newlines when mentions aren't visible
|
|
129
|
-
if (event.key === 'Enter') {
|
|
130
|
-
event.preventDefault();
|
|
131
|
-
this.insertLineBreak();
|
|
132
|
-
this.emitContentChange();
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
onPaste(event) {
|
|
136
|
-
event.preventDefault();
|
|
137
|
-
if (!event.clipboardData) {
|
|
138
|
-
return;
|
|
139
|
-
}
|
|
140
|
-
//Look for HTML first
|
|
141
|
-
const html = event.clipboardData.getData('text/html');
|
|
142
|
-
const plainText = event.clipboardData.getData('text/plain');
|
|
143
|
-
const nodes = html && html.includes('data-type="mention"')
|
|
144
|
-
? this.parsePastedHtml(html)
|
|
145
|
-
: this.plainTextToNodes(plainText);
|
|
146
|
-
this.insertNodesAtCursor(nodes);
|
|
147
|
-
this.normalizeMentionPadding();
|
|
148
|
-
this.emitContentChange();
|
|
149
|
-
}
|
|
150
|
-
// The browser strips data-* attributes during default copy serialization, but
|
|
151
|
-
// range.cloneContents() preserves them. We serialize the clone ourselves and
|
|
152
|
-
// strip ZWS so it doesn't leak into the clipboard.
|
|
153
|
-
onCopy(event) {
|
|
154
|
-
const selection = window.getSelection();
|
|
155
|
-
if (!selection?.rangeCount) {
|
|
156
|
-
return;
|
|
157
|
-
}
|
|
158
|
-
event.preventDefault();
|
|
159
|
-
const div = document.createElement('div');
|
|
160
|
-
div.appendChild(selection.getRangeAt(0).cloneContents());
|
|
161
|
-
const html = div.innerHTML.replace(ZWS_REGEX, '');
|
|
162
|
-
const text = (div.textContent || '').replace(ZWS_REGEX, '');
|
|
163
|
-
event.clipboardData?.setData('text/html', html);
|
|
164
|
-
event.clipboardData?.setData('text/plain', text);
|
|
165
|
-
}
|
|
166
|
-
onCut(event) {
|
|
167
|
-
this.onCopy(event);
|
|
168
|
-
const selection = window.getSelection();
|
|
169
|
-
if (!selection?.rangeCount) {
|
|
170
|
-
return;
|
|
171
|
-
}
|
|
172
|
-
selection.getRangeAt(0).deleteContents();
|
|
173
|
-
this.normalizeMentionPadding();
|
|
174
|
-
this.emitContentChange();
|
|
175
|
-
}
|
|
176
|
-
// ─── Mention helpers ───────────────────────────────────────────────────
|
|
177
|
-
static isMention(node) {
|
|
178
|
-
return (!!node &&
|
|
179
|
-
node.nodeType === Node.ELEMENT_NODE &&
|
|
180
|
-
node.getAttribute('data-type') === 'mention');
|
|
181
|
-
}
|
|
182
|
-
static isZws(node) {
|
|
183
|
-
return (!!node &&
|
|
184
|
-
node.nodeType === Node.TEXT_NODE &&
|
|
185
|
-
(node.textContent || '').replace(ZWS_REGEX, '') === '');
|
|
186
|
-
}
|
|
187
|
-
// Resolve the node logically adjacent to (container, offset) in the given
|
|
188
|
-
// direction, transparently skipping any ZWS-only text nodes in between.
|
|
189
|
-
resolveAdjacentNode(container, offset, direction) {
|
|
190
|
-
let candidate = null;
|
|
191
|
-
if (container.nodeType === Node.TEXT_NODE) {
|
|
192
|
-
const length = (container.textContent || '').length;
|
|
193
|
-
const atBoundary = MentionsInputComponent.isZws(container) ||
|
|
194
|
-
(direction === 'before' ? offset === 0 : offset === length);
|
|
195
|
-
if (!atBoundary) {
|
|
196
|
-
return null;
|
|
197
|
-
}
|
|
198
|
-
candidate =
|
|
199
|
-
direction === 'before'
|
|
200
|
-
? container.previousSibling
|
|
201
|
-
: container.nextSibling;
|
|
202
|
-
}
|
|
203
|
-
else if (container.nodeType === Node.ELEMENT_NODE) {
|
|
204
|
-
const children = container.childNodes;
|
|
205
|
-
candidate =
|
|
206
|
-
direction === 'before' ? children[offset - 1] : children[offset];
|
|
207
|
-
}
|
|
208
|
-
while (candidate && MentionsInputComponent.isZws(candidate)) {
|
|
209
|
-
candidate =
|
|
210
|
-
direction === 'before'
|
|
211
|
-
? candidate.previousSibling
|
|
212
|
-
: candidate.nextSibling;
|
|
213
|
-
}
|
|
214
|
-
return candidate;
|
|
215
|
-
}
|
|
216
|
-
findMentionAdjacentToCursor(direction) {
|
|
217
|
-
const selection = window.getSelection();
|
|
218
|
-
if (!selection?.isCollapsed || !selection.rangeCount) {
|
|
219
|
-
return null;
|
|
220
|
-
}
|
|
221
|
-
const range = selection.getRangeAt(0);
|
|
222
|
-
const node = this.resolveAdjacentNode(range.startContainer, range.startOffset, direction);
|
|
223
|
-
return MentionsInputComponent.isMention(node) ? node : null;
|
|
224
|
-
}
|
|
225
|
-
findBrAdjacentToCursor() {
|
|
226
|
-
const selection = window.getSelection();
|
|
227
|
-
if (!selection?.isCollapsed || !selection.rangeCount) {
|
|
228
|
-
return null;
|
|
229
|
-
}
|
|
230
|
-
const range = selection.getRangeAt(0);
|
|
231
|
-
const node = this.resolveAdjacentNode(range.startContainer, range.startOffset, 'before');
|
|
232
|
-
return node?.nodeName === 'BR' ? node : null;
|
|
233
|
-
}
|
|
234
|
-
extendSelectionAcrossMention(mention, direction) {
|
|
235
|
-
const selection = window.getSelection();
|
|
236
|
-
const parent = mention.parentNode;
|
|
237
|
-
if (!selection || !parent) {
|
|
238
|
-
return;
|
|
239
|
-
}
|
|
240
|
-
const index = Array.from(parent.childNodes).indexOf(mention);
|
|
241
|
-
selection.extend(parent, direction === 'before' ? index : index + 1);
|
|
242
|
-
}
|
|
243
|
-
placeCursorAdjacentToMention(mention, side) {
|
|
244
|
-
const parent = mention.parentNode;
|
|
245
|
-
if (!parent) {
|
|
246
|
-
return;
|
|
247
|
-
}
|
|
248
|
-
const sibling = side === 'before' ? mention.previousSibling : mention.nextSibling;
|
|
249
|
-
let zws;
|
|
250
|
-
if (sibling && MentionsInputComponent.isZws(sibling)) {
|
|
251
|
-
zws = sibling;
|
|
252
|
-
}
|
|
253
|
-
else {
|
|
254
|
-
zws = document.createTextNode(ZWS);
|
|
255
|
-
parent.insertBefore(zws, side === 'before' ? mention : mention.nextSibling);
|
|
256
|
-
}
|
|
257
|
-
const range = document.createRange();
|
|
258
|
-
range.setStart(zws, side === 'before' ? (zws.textContent || '').length : 0);
|
|
259
|
-
range.collapse(true);
|
|
260
|
-
const selection = window.getSelection();
|
|
261
|
-
selection?.removeAllRanges();
|
|
262
|
-
selection?.addRange(range);
|
|
263
|
-
}
|
|
264
|
-
removeMention(mention) {
|
|
265
|
-
const parent = mention.parentNode;
|
|
266
|
-
if (!parent) {
|
|
267
|
-
return;
|
|
268
|
-
}
|
|
269
|
-
// Empty text-node anchor preserves cursor position through the removal.
|
|
270
|
-
const anchor = document.createTextNode('');
|
|
271
|
-
parent.insertBefore(anchor, mention);
|
|
272
|
-
const prev = mention.previousSibling;
|
|
273
|
-
const next = mention.nextSibling;
|
|
274
|
-
if (prev && MentionsInputComponent.isZws(prev)) {
|
|
275
|
-
prev.remove();
|
|
276
|
-
}
|
|
277
|
-
if (next && MentionsInputComponent.isZws(next)) {
|
|
278
|
-
next.remove();
|
|
279
|
-
}
|
|
280
|
-
mention.remove();
|
|
281
|
-
const range = document.createRange();
|
|
282
|
-
range.setStart(anchor, 0);
|
|
283
|
-
range.collapse(true);
|
|
284
|
-
const selection = window.getSelection();
|
|
285
|
-
selection?.removeAllRanges();
|
|
286
|
-
selection?.addRange(range);
|
|
287
|
-
}
|
|
288
|
-
// Re-establishes the invariant: every mention has exactly one ZWS text
|
|
289
|
-
// node immediately before and after it, and there are no orphan ZWS-only
|
|
290
|
-
// text nodes anywhere else. Run after any operation that may disturb the
|
|
291
|
-
// tree (typing, paste, cut, delete) so cruft doesn't accumulate across
|
|
292
|
-
// repeated copy/paste cycles.
|
|
293
|
-
normalizeMentionPadding() {
|
|
294
|
-
const root = this.inputElement?.nativeElement;
|
|
295
|
-
if (!root) {
|
|
296
|
-
return;
|
|
297
|
-
}
|
|
298
|
-
// 1. Ensure each mention has a ZWS pad on both sides.
|
|
299
|
-
const mentions = Array.from(root.querySelectorAll('span[data-type="mention"]'));
|
|
300
|
-
for (const m of mentions) {
|
|
301
|
-
const parent = m.parentNode;
|
|
302
|
-
if (!parent) {
|
|
303
|
-
continue;
|
|
304
|
-
}
|
|
305
|
-
if (!m.previousSibling ||
|
|
306
|
-
!MentionsInputComponent.isZws(m.previousSibling)) {
|
|
307
|
-
parent.insertBefore(document.createTextNode(ZWS), m);
|
|
308
|
-
}
|
|
309
|
-
if (!m.nextSibling || !MentionsInputComponent.isZws(m.nextSibling)) {
|
|
310
|
-
parent.insertBefore(document.createTextNode(ZWS), m.nextSibling);
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
// 2. Remove any ZWS-only text node that isn't directly adjacent to a
|
|
314
|
-
// mention (orphans from line-break pads, leftover splits from previous
|
|
315
|
-
// paste insertions, duplicate pads from accumulated copy/paste cycles).
|
|
316
|
-
// Skip a node if the cursor currently lives in it — preserves caret
|
|
317
|
-
// position without needing manual restoration.
|
|
318
|
-
const selection = window.getSelection();
|
|
319
|
-
const cursorNode = selection?.rangeCount &&
|
|
320
|
-
root.contains(selection.getRangeAt(0).startContainer)
|
|
321
|
-
? selection.getRangeAt(0).startContainer
|
|
322
|
-
: null;
|
|
323
|
-
const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, null);
|
|
324
|
-
const orphans = [];
|
|
325
|
-
while (walker.nextNode()) {
|
|
326
|
-
const node = walker.currentNode;
|
|
327
|
-
if (!MentionsInputComponent.isZws(node) || node === cursorNode) {
|
|
328
|
-
continue;
|
|
329
|
-
}
|
|
330
|
-
const adjacentToMention = MentionsInputComponent.isMention(node.previousSibling) ||
|
|
331
|
-
MentionsInputComponent.isMention(node.nextSibling);
|
|
332
|
-
if (!adjacentToMention) {
|
|
333
|
-
orphans.push(node);
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
for (const node of orphans) {
|
|
337
|
-
node.remove();
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
handleMentionsDropdownNav(event) {
|
|
341
|
-
const filteredUsers = this.getFilteredUsers();
|
|
342
|
-
if (filteredUsers.length === 0) {
|
|
343
|
-
this.closeMentions();
|
|
344
|
-
return;
|
|
345
|
-
}
|
|
346
|
-
switch (event.key) {
|
|
347
|
-
case 'ArrowDown':
|
|
348
|
-
event.preventDefault();
|
|
349
|
-
this.selectedUserIndex = Math.min(this.selectedUserIndex + 1, filteredUsers.length - 1);
|
|
350
|
-
this.cdr.markForCheck();
|
|
351
|
-
break;
|
|
352
|
-
case 'ArrowUp':
|
|
353
|
-
event.preventDefault();
|
|
354
|
-
this.selectedUserIndex = Math.max(this.selectedUserIndex - 1, 0);
|
|
355
|
-
this.cdr.markForCheck();
|
|
356
|
-
break;
|
|
357
|
-
case 'Enter':
|
|
358
|
-
case 'Tab':
|
|
359
|
-
event.preventDefault();
|
|
360
|
-
if (filteredUsers[this.selectedUserIndex]) {
|
|
361
|
-
this.selectUser(filteredUsers[this.selectedUserIndex]);
|
|
362
|
-
}
|
|
363
|
-
break;
|
|
364
|
-
case 'Escape':
|
|
365
|
-
event.preventDefault();
|
|
366
|
-
this.closeMentions();
|
|
367
|
-
break;
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
// ─── Insertion ─────────────────────────────────────────────────────────
|
|
371
|
-
plainTextToNodes(text) {
|
|
372
|
-
const nodes = [];
|
|
373
|
-
const lines = text.split('\n');
|
|
374
|
-
lines.forEach((line, index) => {
|
|
375
|
-
if (line) {
|
|
376
|
-
nodes.push(document.createTextNode(line));
|
|
377
|
-
}
|
|
378
|
-
if (index < lines.length - 1) {
|
|
379
|
-
nodes.push(document.createElement('br'));
|
|
380
|
-
}
|
|
381
|
-
});
|
|
382
|
-
return nodes;
|
|
383
|
-
}
|
|
384
|
-
// Create a temporary container to parse the HTML
|
|
385
|
-
parsePastedHtml(html) {
|
|
386
|
-
// Create a temporary container to parse the HTML
|
|
387
|
-
const tempContainer = document.createElement('div');
|
|
388
|
-
tempContainer.innerHTML = html;
|
|
389
|
-
const nodes = [];
|
|
390
|
-
const walk = (node) => {
|
|
391
|
-
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
392
|
-
const el = node;
|
|
393
|
-
// DAHNE NOTE - we only want mention spans, br elements, and text
|
|
394
|
-
if (el.tagName === 'SPAN' &&
|
|
395
|
-
el.getAttribute('data-type') === 'mention' &&
|
|
396
|
-
el.hasAttribute('data-id')) {
|
|
397
|
-
//Create mention to ultimately insert into the DOM
|
|
398
|
-
const span = document.createElement('span');
|
|
399
|
-
span.className = this.readonly ? 'readonly-mention' : 'mention';
|
|
400
|
-
span.setAttribute('data-id', el.getAttribute('data-id') || '');
|
|
401
|
-
span.setAttribute('data-type', 'mention');
|
|
402
|
-
span.setAttribute('contenteditable', 'false');
|
|
403
|
-
const raw = el.textContent || '';
|
|
404
|
-
span.textContent = raw.startsWith('@') ? raw : `@${raw}`;
|
|
405
|
-
nodes.push(span);
|
|
406
|
-
}
|
|
407
|
-
else if (el.tagName === 'BR') {
|
|
408
|
-
// Preserve line breaks
|
|
409
|
-
nodes.push(document.createElement('br'));
|
|
410
|
-
}
|
|
411
|
-
else {
|
|
412
|
-
//Recursively look for nested children
|
|
413
|
-
for (const child of Array.from(el.childNodes)) {
|
|
414
|
-
walk(child);
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
else if (node.nodeType === Node.TEXT_NODE) {
|
|
419
|
-
const text = (node.textContent || '').replace(ZWS_REGEX, '');
|
|
420
|
-
if (text) {
|
|
421
|
-
nodes.push(document.createTextNode(text));
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
};
|
|
425
|
-
for (const child of Array.from(tempContainer.childNodes)) {
|
|
426
|
-
walk(child);
|
|
427
|
-
}
|
|
428
|
-
//DAHNE NOTE - the result here should be an array of text/span-mention/br nodes
|
|
429
|
-
return nodes;
|
|
430
|
-
}
|
|
431
|
-
insertNodesAtCursor(nodes) {
|
|
432
|
-
//Get selection object, representing user cursor position/selection
|
|
433
|
-
//Get Range object at start of selection, which should represent cursor position
|
|
434
|
-
//If there is a selection, delete it
|
|
435
|
-
//Insert the parsed nodes from above, move range ends to after node
|
|
436
|
-
//Then remove the range and reset it to move the cursor position to the end
|
|
437
|
-
const selection = window.getSelection();
|
|
438
|
-
if (!selection?.rangeCount) {
|
|
439
|
-
return;
|
|
440
|
-
}
|
|
441
|
-
const range = selection.getRangeAt(0);
|
|
442
|
-
range.deleteContents();
|
|
443
|
-
let cursorTarget = null;
|
|
444
|
-
for (const node of nodes) {
|
|
445
|
-
if (MentionsInputComponent.isMention(node)) {
|
|
446
|
-
const before = document.createTextNode(ZWS);
|
|
447
|
-
const after = document.createTextNode(ZWS);
|
|
448
|
-
range.insertNode(before);
|
|
449
|
-
range.setStartAfter(before);
|
|
450
|
-
range.insertNode(node);
|
|
451
|
-
range.setStartAfter(node);
|
|
452
|
-
range.insertNode(after);
|
|
453
|
-
range.setStartAfter(after);
|
|
454
|
-
cursorTarget = after;
|
|
455
|
-
}
|
|
456
|
-
else {
|
|
457
|
-
range.insertNode(node);
|
|
458
|
-
range.setStartAfter(node);
|
|
459
|
-
cursorTarget = node;
|
|
460
|
-
}
|
|
461
|
-
range.collapse(true);
|
|
462
|
-
}
|
|
463
|
-
// After a mention, leave the cursor inside the trailing ZWS so ArrowLeft
|
|
464
|
-
// can step back to before-the-mention naturally.
|
|
465
|
-
if (cursorTarget && MentionsInputComponent.isZws(cursorTarget)) {
|
|
466
|
-
range.setStart(cursorTarget, 0);
|
|
467
|
-
range.collapse(true);
|
|
468
|
-
}
|
|
469
|
-
selection.removeAllRanges();
|
|
470
|
-
selection.addRange(range);
|
|
471
|
-
}
|
|
472
|
-
insertLineBreak() {
|
|
473
|
-
const selection = window.getSelection();
|
|
474
|
-
if (!selection?.rangeCount || !this.inputElement?.nativeElement) {
|
|
475
|
-
return;
|
|
476
|
-
}
|
|
477
|
-
const range = selection.getRangeAt(0);
|
|
478
|
-
range.deleteContents();
|
|
479
|
-
const br = document.createElement('br');
|
|
480
|
-
range.insertNode(br);
|
|
481
|
-
range.setStartAfter(br);
|
|
482
|
-
range.collapse(true);
|
|
483
|
-
// A trailing <br> alone doesn't render an empty line in contenteditable —
|
|
484
|
-
// a ZWS gives the caret a place to land.
|
|
485
|
-
if (!br.nextSibling) {
|
|
486
|
-
const zws = document.createTextNode(ZWS);
|
|
487
|
-
range.insertNode(zws);
|
|
488
|
-
range.setStart(zws, 0);
|
|
489
|
-
range.collapse(true);
|
|
490
|
-
}
|
|
491
|
-
selection.removeAllRanges();
|
|
492
|
-
selection.addRange(range);
|
|
493
|
-
}
|
|
494
|
-
// ─── Mention trigger / dropdown ────────────────────────────────────────
|
|
495
|
-
checkForMentionTrigger() {
|
|
496
|
-
const selection = window.getSelection();
|
|
497
|
-
if (!selection || !selection.rangeCount || !this.inputElement) {
|
|
498
|
-
return;
|
|
499
|
-
}
|
|
500
|
-
const range = selection.getRangeAt(0);
|
|
501
|
-
const textBeforeCursor = this.getTextBeforeCursor(range);
|
|
502
|
-
const lastAtIndex = textBeforeCursor.lastIndexOf('@');
|
|
503
|
-
if (lastAtIndex === -1) {
|
|
504
|
-
this.closeMentions();
|
|
505
|
-
return;
|
|
506
|
-
}
|
|
507
|
-
//If we allow for a single space, we need to check to make sure that this logic won't pick up previous
|
|
508
|
-
//'@' mentions and keep the mention dropdown open
|
|
509
|
-
const atPosition = this.findDomPositionAtCharIndex(lastAtIndex);
|
|
510
|
-
if (atPosition && this.isInsideMentionSpan(atPosition.node)) {
|
|
511
|
-
this.closeMentions();
|
|
512
|
-
return;
|
|
513
|
-
}
|
|
514
|
-
const textAfterAt = textBeforeCursor.substring(lastAtIndex + 1);
|
|
515
|
-
const char1 = textAfterAt.charCodeAt(0);
|
|
516
|
-
const charN = textAfterAt.charCodeAt(textAfterAt.length - 1);
|
|
517
|
-
const charN_1 = textAfterAt.charCodeAt(textAfterAt.length - 2);
|
|
518
|
-
//These are the Unicode representations of normal space and non-breaking space
|
|
519
|
-
const unicodeSpaceChars = [32, 160];
|
|
520
|
-
// Close mentions if:
|
|
521
|
-
// - There's a double space (allows single spaces in the middle of search)
|
|
522
|
-
// - The text starts with a space (typing "@ " should not trigger mentions)
|
|
523
|
-
if (textAfterAt.includes(' ') ||
|
|
524
|
-
textAfterAt.startsWith(' ') ||
|
|
525
|
-
char1 == 160 ||
|
|
526
|
-
(unicodeSpaceChars.includes(charN) && unicodeSpaceChars.includes(charN_1))) {
|
|
527
|
-
this.closeMentions();
|
|
528
|
-
return;
|
|
529
|
-
}
|
|
530
|
-
// Trim trailing/leading spaces from search text while preserving spaces in the middle
|
|
531
|
-
this.mentionSearchText = textAfterAt.trim();
|
|
532
|
-
// Only show mentions if there are filtered users
|
|
533
|
-
const filteredUsers = this.getFilteredUsers();
|
|
534
|
-
if (filteredUsers.length === 0) {
|
|
535
|
-
this.closeMentions();
|
|
536
|
-
return;
|
|
537
|
-
}
|
|
538
|
-
this.mentionsVisible = true;
|
|
539
|
-
this.selectedUserIndex = 0;
|
|
540
|
-
//Save the current range for later restoration (needed for click selection)
|
|
541
|
-
//DAHNE NOTE - this is annoyingly neceessary because clicks and enter keys have different effects on the
|
|
542
|
-
//focus of the contenteditable div
|
|
543
|
-
this.savedRange = range.cloneRange();
|
|
544
|
-
if (atPosition) {
|
|
545
|
-
const atRange = document.createRange();
|
|
546
|
-
atRange.setStart(atPosition.node, atPosition.offset);
|
|
547
|
-
atRange.setEnd(atPosition.node, atPosition.offset + 1);
|
|
548
|
-
this.mentionAnchor = atRange.getBoundingClientRect();
|
|
549
|
-
}
|
|
550
|
-
this.cdr.markForCheck();
|
|
551
|
-
}
|
|
552
|
-
getTextBeforeCursor(range) {
|
|
553
|
-
const clonedRange = range.cloneRange();
|
|
554
|
-
//We select all of the input contents, and then move the end point to the current cursor position
|
|
555
|
-
clonedRange.selectNodeContents(this.inputElement.nativeElement);
|
|
556
|
-
clonedRange.setEnd(range.endContainer, range.endOffset);
|
|
557
|
-
//Create a temporary div so that we can extract text content from it
|
|
558
|
-
const fragment = clonedRange.cloneContents();
|
|
559
|
-
const div = document.createElement('div');
|
|
560
|
-
div.appendChild(fragment);
|
|
561
|
-
//Get text content, replacing mention spans with @name
|
|
562
|
-
return div.textContent || '';
|
|
563
|
-
}
|
|
564
|
-
getFilteredUsers() {
|
|
565
|
-
const users = !this.mentionSearchText
|
|
566
|
-
? this.users
|
|
567
|
-
: this.users.filter(user => user.name
|
|
568
|
-
.toLowerCase()
|
|
569
|
-
.includes(this.mentionSearchText.toLowerCase()));
|
|
570
|
-
return users.slice().sort((a, b) => a.name.localeCompare(b.name));
|
|
571
|
-
}
|
|
572
|
-
onUserHover(index) {
|
|
573
|
-
this.selectedUserIndex = index;
|
|
574
|
-
this.cdr.markForCheck();
|
|
575
|
-
}
|
|
576
|
-
selectUser(user) {
|
|
577
|
-
if (!this.inputElement) {
|
|
578
|
-
return;
|
|
579
|
-
}
|
|
580
|
-
//This gets DOM info from user (e.g. highlighted selections, and cursor position)
|
|
581
|
-
const selection = window.getSelection();
|
|
582
|
-
if (!selection) {
|
|
583
|
-
return;
|
|
584
|
-
}
|
|
585
|
-
// Restore the saved range if available (needed when selecting via click)
|
|
586
|
-
if (this.savedRange) {
|
|
587
|
-
selection.removeAllRanges();
|
|
588
|
-
selection.addRange(this.savedRange);
|
|
589
|
-
}
|
|
590
|
-
if (!selection.rangeCount) {
|
|
591
|
-
return;
|
|
592
|
-
}
|
|
593
|
-
// Delete the "@" and search text
|
|
594
|
-
this.deleteAtMentionSearch();
|
|
595
|
-
//DAHNE NOTE - this would ideally be the same as contentItemToHTML, but we need an actual element reference here in order to append it to the DOM
|
|
596
|
-
const mentionSpan = document.createElement('span');
|
|
597
|
-
mentionSpan.className = this.readonly ? 'readonly-mention' : 'mention';
|
|
598
|
-
mentionSpan.setAttribute('data-id', String(user.id));
|
|
599
|
-
mentionSpan.setAttribute('data-type', 'mention');
|
|
600
|
-
mentionSpan.setAttribute('contenteditable', 'false');
|
|
601
|
-
mentionSpan.textContent = `@${user.name}`;
|
|
602
|
-
this.insertNodesAtCursor([mentionSpan, document.createTextNode(' ')]);
|
|
603
|
-
this.normalizeMentionPadding();
|
|
604
|
-
this.closeMentions();
|
|
605
|
-
this.emitContentChange();
|
|
606
|
-
}
|
|
607
|
-
deleteAtMentionSearch() {
|
|
608
|
-
const selection = window.getSelection();
|
|
609
|
-
if (!selection || !selection.rangeCount) {
|
|
610
|
-
return;
|
|
611
|
-
}
|
|
612
|
-
//This represents the current position of the cursor
|
|
613
|
-
const cursorRange = selection.getRangeAt(0);
|
|
614
|
-
//This will return all of the raw text (HTML-stripped) before the cursor
|
|
615
|
-
const textBeforeCursor = this.getTextBeforeCursor(cursorRange);
|
|
616
|
-
//We do that^ so that we can find the correct index of the most recent '@'
|
|
617
|
-
const lastAtIndex = textBeforeCursor.lastIndexOf('@');
|
|
618
|
-
if (lastAtIndex === -1) {
|
|
619
|
-
return;
|
|
620
|
-
}
|
|
621
|
-
const atPosition = this.findDomPositionAtCharIndex(lastAtIndex);
|
|
622
|
-
if (!atPosition) {
|
|
623
|
-
return;
|
|
624
|
-
}
|
|
625
|
-
// Create range from "@" to cursor and delete it
|
|
626
|
-
const deleteRange = document.createRange();
|
|
627
|
-
deleteRange.setStart(atPosition.node, atPosition.offset);
|
|
628
|
-
deleteRange.setEnd(cursorRange.endContainer, cursorRange.endOffset);
|
|
629
|
-
deleteRange.deleteContents();
|
|
630
|
-
}
|
|
631
|
-
isInsideMentionSpan(node) {
|
|
632
|
-
let currentNode = node;
|
|
633
|
-
while (currentNode && currentNode !== this.inputElement?.nativeElement) {
|
|
634
|
-
if (MentionsInputComponent.isMention(currentNode)) {
|
|
635
|
-
return true;
|
|
636
|
-
}
|
|
637
|
-
currentNode = currentNode.parentNode;
|
|
638
|
-
}
|
|
639
|
-
return false;
|
|
640
|
-
}
|
|
641
|
-
//This will go text node by node looking for the
|
|
642
|
-
//@ mention and give its position in the context of that node
|
|
643
|
-
findDomPositionAtCharIndex(charIndex) {
|
|
644
|
-
if (!this.inputElement) {
|
|
645
|
-
return null;
|
|
646
|
-
}
|
|
647
|
-
// Walk through all text nodes in the input, counting characters
|
|
648
|
-
const treeWalker = document.createTreeWalker(this.inputElement.nativeElement, NodeFilter.SHOW_TEXT, null);
|
|
649
|
-
let charCount = 0;
|
|
650
|
-
while (treeWalker.nextNode()) {
|
|
651
|
-
const node = treeWalker.currentNode;
|
|
652
|
-
const text = node.textContent || '';
|
|
653
|
-
// Check if our target character is in this text node
|
|
654
|
-
if (charCount + text.length > charIndex) {
|
|
655
|
-
return { node, offset: charIndex - charCount };
|
|
656
|
-
}
|
|
657
|
-
charCount += text.length;
|
|
658
|
-
}
|
|
659
|
-
return null;
|
|
660
|
-
}
|
|
661
|
-
closeMentions() {
|
|
662
|
-
this.mentionsVisible = false;
|
|
663
|
-
this.mentionSearchText = '';
|
|
664
|
-
this.mentionAnchor = null;
|
|
665
|
-
this.selectedUserIndex = 0;
|
|
666
|
-
this.savedRange = null;
|
|
667
|
-
this.cdr.markForCheck();
|
|
668
|
-
}
|
|
669
|
-
emitContentChange() {
|
|
670
|
-
if (!this.inputElement) {
|
|
671
|
-
return;
|
|
672
|
-
}
|
|
673
|
-
this.contentChange.emit(this.domToContentItems());
|
|
674
|
-
}
|
|
675
|
-
domToContentItems() {
|
|
676
|
-
if (!this.inputElement?.nativeElement) {
|
|
677
|
-
return [];
|
|
678
|
-
}
|
|
679
|
-
const items = [];
|
|
680
|
-
const childNodes = this.inputElement.nativeElement.childNodes;
|
|
681
|
-
for (const node of Array.from(childNodes)) {
|
|
682
|
-
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
683
|
-
const element = node;
|
|
684
|
-
if (element.tagName === 'SPAN' &&
|
|
685
|
-
element.getAttribute('data-type') === 'mention') {
|
|
686
|
-
const id = Number(element.getAttribute('data-id'));
|
|
687
|
-
const name = element.textContent?.replace('@', '') || '';
|
|
688
|
-
items.push({ type: 'mention', id, name });
|
|
689
|
-
}
|
|
690
|
-
else if (element.tagName === 'BR') {
|
|
691
|
-
items.push({ type: 'newline' });
|
|
692
|
-
}
|
|
693
|
-
}
|
|
694
|
-
else if (node.nodeType === Node.TEXT_NODE) {
|
|
695
|
-
// ZWS pads are a DOM affordance — they shouldn't leak into the data model.
|
|
696
|
-
const text = (node.textContent || '').replace(ZWS_REGEX, '');
|
|
697
|
-
if (text) {
|
|
698
|
-
items.push({ type: 'text', text });
|
|
699
|
-
}
|
|
700
|
-
}
|
|
701
|
-
}
|
|
702
|
-
return items;
|
|
703
|
-
}
|
|
704
|
-
onCalloutClose() {
|
|
705
|
-
this.closeMentions();
|
|
706
|
-
}
|
|
707
|
-
}
|
|
708
|
-
MentionsInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MentionsInputComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
709
|
-
MentionsInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: MentionsInputComponent, selector: "riv-mentions-input", inputs: { content: "content", users: "users", readonly: "readonly", placeholder: "placeholder" }, outputs: { contentChange: "contentChange" }, viewQueries: [{ propertyName: "inputElement", first: true, predicate: ["input"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"mentions-container\" #container>\n <div\n *ngIf=\"!readonly\"\n #input\n class=\"text-content editable\"\n contenteditable=\"true\"\n [attr.data-placeholder]=\"placeholder\"\n (input)=\"onInput()\"\n (keydown)=\"onKeyDown($event)\"\n (paste)=\"onPaste($event)\"\n (copy)=\"onCopy($event)\"\n (cut)=\"onCut($event)\"\n ></div>\n\n <div *ngIf=\"readonly\" #input class=\"text-content\"></div>\n\n <riv-callout\n *ngIf=\"!readonly && mentionsVisible && mentionAnchor\"\n [anchor]=\"mentionAnchor\"\n [isModal]=\"true\"\n [showCaret]=\"false\"\n [allowedPositions]=\"['bottom-right', 'top-right']\"\n [theme]=\"'light'\"\n (close)=\"onCalloutClose()\"\n >\n <div class=\"mentions-content\">\n <div class=\"mentions-header\">Mention someone</div>\n <div class=\"mentions-list\">\n <button\n type=\"button\"\n *ngFor=\"let user of getFilteredUsers(); let i = index\"\n [class.selected]=\"i === selectedUserIndex\"\n (mouseenter)=\"onUserHover(i)\"\n (click)=\"selectUser(user)\"\n >\n {{ user.name }}\n </button>\n </div>\n </div>\n </riv-callout>\n</div>\n", styles: [".mentions-container{position:relative;width:100%}.mentions-input{width:100%;border:var(--border-width) solid var(--border-light);border-radius:var(--border-radius-small);color:var(--type-light-high-contrast);overflow-y:auto;white-space:pre-wrap;word-wrap:break-word}.mentions-input:empty:before{content:attr(data-placeholder);color:var(--type-light-low-contrast);pointer-events:none}.mentions-input:focus{outline:none;border:var(--border-width) solid var(--purp-60)}.mentions-input[contenteditable=false]{color:var(--type-light-disabled);background-color:var(--surface-light-1);cursor:not-allowed}span.mention{color:var(--type-light-link);font-weight:var(--font-weight-heavy);white-space:nowrap;display:inline}span.readonly-mention{font-weight:var(--font-weight-heavy);white-space:nowrap;display:inline}.mentions-input.warning{border-color:var(--surface-dark-caution)}.mentions-input.error{border-color:var(--surface-dark-danger);box-shadow:inset 0 0 0 var(--border-width-large) var(--surface-dark-danger)}.mentions-input.large{font:var(--input-large);padding:var(--size-medium)}.mentions-list{margin:0;padding:0;max-height:calc(var(--base-grid-size) * 50);overflow-y:auto;display:flex;flex-direction:column;gap:var(--size-xxsmall)}.mentions-list button{padding:var(--size-small) var(--size-small);border-radius:var(--border-radius-medium);cursor:pointer;transition:background-color .2s;font:var(--input-medium);text-align:left}.mentions-list button:hover,.mentions-list button.selected{background-color:var(--surface-light-2)}.mentions-content{max-height:50vh;min-width:calc(var(--base-grid-size) * 62);max-width:50vw;padding:var(--size-large);display:flex;flex-direction:column}.mentions-header{padding:var(--size-small) var(--size-small);font:var(--input-medium);color:var(--type-light-low-contrast)}.text-content{width:100%;min-height:9em;border-radius:var(--border-radius-small);font:var(--input-medium);color:var(--type-light-high-contrast);padding:var(--size-large);resize:vertical}.editable{border:var(--border-width) solid var(--border-light);background-color:var(--surface-light-0)}.text-content::placeholder{color:var(--type-light-low-contrast)}.text-content.editable[data-placeholder]:empty:before{content:attr(data-placeholder);color:var(--type-light-low-contrast)}.text-content:disabled{color:var(--type-light-disabled);background-color:var(--surface-light-1)}.text-content:focus{outline:none;border:var(--border-width) solid var(--purp-60)}.text-content.warning{border-color:var(--surface-dark-caution)}.text-content.error{border-color:var(--surface-dark-danger);box-shadow:inset 0 0 0 var(--border-width-large) var(--surface-dark-danger)}.text-content.large{font:var(--input-large);padding:var(--size-medium)}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.CalloutComponent, selector: "riv-callout", inputs: ["anchor", "isModal", "preferredPosition", "allowedPositions", "fallbackDirection", "showCaret", "theme"], outputs: ["close"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
710
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MentionsInputComponent, decorators: [{
|
|
711
|
-
type: Component,
|
|
712
|
-
args: [{ selector: 'riv-mentions-input', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"mentions-container\" #container>\n <div\n *ngIf=\"!readonly\"\n #input\n class=\"text-content editable\"\n contenteditable=\"true\"\n [attr.data-placeholder]=\"placeholder\"\n (input)=\"onInput()\"\n (keydown)=\"onKeyDown($event)\"\n (paste)=\"onPaste($event)\"\n (copy)=\"onCopy($event)\"\n (cut)=\"onCut($event)\"\n ></div>\n\n <div *ngIf=\"readonly\" #input class=\"text-content\"></div>\n\n <riv-callout\n *ngIf=\"!readonly && mentionsVisible && mentionAnchor\"\n [anchor]=\"mentionAnchor\"\n [isModal]=\"true\"\n [showCaret]=\"false\"\n [allowedPositions]=\"['bottom-right', 'top-right']\"\n [theme]=\"'light'\"\n (close)=\"onCalloutClose()\"\n >\n <div class=\"mentions-content\">\n <div class=\"mentions-header\">Mention someone</div>\n <div class=\"mentions-list\">\n <button\n type=\"button\"\n *ngFor=\"let user of getFilteredUsers(); let i = index\"\n [class.selected]=\"i === selectedUserIndex\"\n (mouseenter)=\"onUserHover(i)\"\n (click)=\"selectUser(user)\"\n >\n {{ user.name }}\n </button>\n </div>\n </div>\n </riv-callout>\n</div>\n", styles: [".mentions-container{position:relative;width:100%}.mentions-input{width:100%;border:var(--border-width) solid var(--border-light);border-radius:var(--border-radius-small);color:var(--type-light-high-contrast);overflow-y:auto;white-space:pre-wrap;word-wrap:break-word}.mentions-input:empty:before{content:attr(data-placeholder);color:var(--type-light-low-contrast);pointer-events:none}.mentions-input:focus{outline:none;border:var(--border-width) solid var(--purp-60)}.mentions-input[contenteditable=false]{color:var(--type-light-disabled);background-color:var(--surface-light-1);cursor:not-allowed}span.mention{color:var(--type-light-link);font-weight:var(--font-weight-heavy);white-space:nowrap;display:inline}span.readonly-mention{font-weight:var(--font-weight-heavy);white-space:nowrap;display:inline}.mentions-input.warning{border-color:var(--surface-dark-caution)}.mentions-input.error{border-color:var(--surface-dark-danger);box-shadow:inset 0 0 0 var(--border-width-large) var(--surface-dark-danger)}.mentions-input.large{font:var(--input-large);padding:var(--size-medium)}.mentions-list{margin:0;padding:0;max-height:calc(var(--base-grid-size) * 50);overflow-y:auto;display:flex;flex-direction:column;gap:var(--size-xxsmall)}.mentions-list button{padding:var(--size-small) var(--size-small);border-radius:var(--border-radius-medium);cursor:pointer;transition:background-color .2s;font:var(--input-medium);text-align:left}.mentions-list button:hover,.mentions-list button.selected{background-color:var(--surface-light-2)}.mentions-content{max-height:50vh;min-width:calc(var(--base-grid-size) * 62);max-width:50vw;padding:var(--size-large);display:flex;flex-direction:column}.mentions-header{padding:var(--size-small) var(--size-small);font:var(--input-medium);color:var(--type-light-low-contrast)}.text-content{width:100%;min-height:9em;border-radius:var(--border-radius-small);font:var(--input-medium);color:var(--type-light-high-contrast);padding:var(--size-large);resize:vertical}.editable{border:var(--border-width) solid var(--border-light);background-color:var(--surface-light-0)}.text-content::placeholder{color:var(--type-light-low-contrast)}.text-content.editable[data-placeholder]:empty:before{content:attr(data-placeholder);color:var(--type-light-low-contrast)}.text-content:disabled{color:var(--type-light-disabled);background-color:var(--surface-light-1)}.text-content:focus{outline:none;border:var(--border-width) solid var(--purp-60)}.text-content.warning{border-color:var(--surface-dark-caution)}.text-content.error{border-color:var(--surface-dark-danger);box-shadow:inset 0 0 0 var(--border-width-large) var(--surface-dark-danger)}.text-content.large{font:var(--input-large);padding:var(--size-medium)}\n"] }]
|
|
713
|
-
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { content: [{
|
|
714
|
-
type: Input
|
|
715
|
-
}], users: [{
|
|
716
|
-
type: Input
|
|
717
|
-
}], readonly: [{
|
|
718
|
-
type: Input
|
|
719
|
-
}], placeholder: [{
|
|
720
|
-
type: Input
|
|
721
|
-
}], contentChange: [{
|
|
722
|
-
type: Output
|
|
723
|
-
}], inputElement: [{
|
|
724
|
-
type: ViewChild,
|
|
725
|
-
args: ['input', { static: false }]
|
|
726
|
-
}] } });
|
|
727
|
-
(function (MentionsInputComponent) {
|
|
728
|
-
MentionsInputComponent.ContentTypes = ['mention', 'text', 'newline'];
|
|
729
|
-
function contentToPlainText(content) {
|
|
730
|
-
return content
|
|
731
|
-
.map(item => {
|
|
732
|
-
switch (item.type) {
|
|
733
|
-
case 'mention':
|
|
734
|
-
return `@${item.name}`;
|
|
735
|
-
case 'text':
|
|
736
|
-
return item.text;
|
|
737
|
-
case 'newline':
|
|
738
|
-
return '\n';
|
|
739
|
-
}
|
|
740
|
-
})
|
|
741
|
-
.join('');
|
|
742
|
-
}
|
|
743
|
-
MentionsInputComponent.contentToPlainText = contentToPlainText;
|
|
744
|
-
})(MentionsInputComponent || (MentionsInputComponent = {}));
|
|
745
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVudGlvbnMtaW5wdXQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvcml2L3NyYy9saWIvaW5wdXQvbWVudGlvbnMtaW5wdXQvbWVudGlvbnMtaW5wdXQuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvcml2L3NyYy9saWIvaW5wdXQvbWVudGlvbnMtaW5wdXQvbWVudGlvbnMtaW5wdXQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUVMLHVCQUF1QixFQUV2QixTQUFTLEVBRVQsWUFBWSxFQUNaLEtBQUssRUFFTCxNQUFNLEVBRU4sU0FBUyxFQUNULGlCQUFpQixHQUNsQixNQUFNLGVBQWUsQ0FBQzs7OztBQUV2QixNQUFNLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDaEIsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDO0FBRXZCOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBbUJHO0FBUUgsTUFBTSxPQUFPLHNCQUFzQjtJQUNqQyxZQUE2QixHQUFzQjtRQUF0QixRQUFHLEdBQUgsR0FBRyxDQUFtQjtRQUUxQyxZQUFPLEdBQXlDLEVBQUUsQ0FBQztRQUNuRCxVQUFLLEdBQWtDLEVBQUUsQ0FBQztRQUMxQyxhQUFRLEdBQUcsS0FBSyxDQUFDO1FBQ2pCLGdCQUFXLEdBQVcsZUFBZSxDQUFDO1FBRTVCLGtCQUFhLEdBQUcsSUFBSSxZQUFZLEVBRWhELENBQUM7UUFLSixvQkFBZSxHQUFHLEtBQUssQ0FBQztRQUN4QixzQkFBaUIsR0FBRyxFQUFFLENBQUM7UUFDdkIsa0JBQWEsR0FBbUIsSUFBSSxDQUFDO1FBQ3JDLHNCQUFpQixHQUFHLENBQUMsQ0FBQztRQUNkLGVBQVUsR0FBaUIsSUFBSSxDQUFDO0lBbEJjLENBQUM7SUFvQnZELGVBQWU7UUFDYixJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7SUFDdkIsQ0FBQztJQUVE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QUNuQixLQUFLLFNBQVM7b0JBQ1osT0FBTyxJQUFJLENBQUM7YUFDZjtRQUNILENBQUMsQ0FBQzthQUNELElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUNkLENBQUM7SUFiZSx5Q0FBa0IscUJBYWpDLENBQUE7QUFDSCxDQUFDLEVBOUJnQixzQkFBc0IsS0FBdEIsc0JBQXNCLFFBOEJ0QyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEFmdGVyVmlld0luaXQsXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIElucHV0LFxuICBPbkNoYW5nZXMsXG4gIE91dHB1dCxcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgVmlld0NoaWxkLFxuICBWaWV3RW5jYXBzdWxhdGlvbixcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmNvbnN0IFpXUyA9ICfigIsnO1xuY29uc3QgWldTX1JFR0VYID0gL+KAiy9nO1xuXG4vKipcbiAqIEEgcmljaCB0ZXh0IGlucHV0IHRoYXQgc3VwcG9ydHMgYEBgLW1lbnRpb25zIGluc2lkZSBhIGBjb250ZW50ZWRpdGFibGVgIGRpdi5cbiAqXG4gKiAjIyBEYXRhIE1vZGVsXG4gKiAtICoqSW5wdXQvT3V0cHV0Kio6IGBDb250ZW50SXRlbVtdYCAobWVudGlvbnMsIHRleHQsIG5ld2xpbmVzKVxuICpcbiAqICMjIERPTSBJbnZhcmlhbnRcbiAqIEV2ZXJ5IG1lbnRpb24gYDxzcGFuIGRhdGEtdHlwZT1cIm1lbnRpb25cIiBjb250ZW50ZWRpdGFibGU9XCJmYWxzZVwiPmAgaXMgd3JhcHBlZFxuICogYnkgZXhhY3RseSBvbmUgemVyby13aWR0aC1zcGFjZSAoWldTKSB0ZXh0IG5vZGUgYmVmb3JlIGFuZCBhZnRlciBpdC4gWldTIGdpdmVzXG4gKiB0aGUgY3Vyc29yIGEgdmFsaWQgbGFuZGluZyBzcG90IGFkamFjZW50IHRvIGEgbm9uLWVkaXRhYmxlIGVsZW1lbnQuIFRoZVxuICogaW52YXJpYW50IGlzIGVzdGFibGlzaGVkIGF0IHJlbmRlciB0aW1lIGFuZCByZS1lc3RhYmxpc2hlZCBieVxuICogYG5vcm1hbGl6ZU1lbnRpb25QYWRkaW5nKClgIGFmdGVyIGFueSBET00tbXV0YXRpbmcgb3BlcmF0aW9uLlxuICpcbiAqICMjIENvcHkvUGFzdGVcbiAqIC0gKipDb3B5Kio6IGByYW5nZS5jbG9uZUNvbnRlbnRzKClgIHByZXNlcnZlcyBgZGF0YS0qYCBhdHRyaWJ1dGVzIChvbmx5IHRoZVxuICogICBicm93c2VyJ3MgZGVmYXVsdCBjb3B5IHBhdGggc3RyaXBzIHRoZW0pLiBXZSBvdmVycmlkZSBjb3B5LCBzZXJpYWxpemUgdGhlXG4gKiAgIGNsb25lIG91cnNlbHZlcywgYW5kIHN0cmlwIFpXUyBmcm9tIHRoZSBvdXRwdXQuXG4gKiAtICoqUGFzdGUqKjogSFRNTCBwYXRocyBsb29rIGZvciBgZGF0YS10eXBlPVwibWVudGlvblwiYCBzcGFucyBhbmQgcmVidWlsZFxuICogICB0aGVtOyBvdGhlcndpc2UgcGxhaW50ZXh0IGZhbGxiYWNrLlxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdyaXYtbWVudGlvbnMtaW5wdXQnLFxuICB0ZW1wbGF0ZVVybDogYC4vbWVudGlvbnMtaW5wdXQuY29tcG9uZW50Lmh0bWxgLFxuICBzdHlsZVVybHM6IFsnLi9tZW50aW9ucy1pbnB1dC5jb21wb25lbnQuY3NzJ10sXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxufSlcbmV4cG9ydCBjbGFzcyBNZW50aW9uc0lucHV0Q29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzLCBBZnRlclZpZXdJbml0IHtcbiAgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSBjZHI6IENoYW5nZURldGVjdG9yUmVmKSB7fVxuXG4gIEBJbnB1dCgpIGNvbnRlbnQ6IE1lbnRpb25zSW5wdXRDb21wb25lbnQuQ29udGVudEl0ZW1bXSA9IFtdO1xuICBASW5wdXQoKSB1c2VyczogTWVudGlvbnNJbnB1dENvbXBvbmVudC5Vc2VyW10gPSBbXTtcbiAgQElucHV0KCkgcmVhZG9ubHkgPSBmYWxzZTtcbiAgQElucHV0KCkgcGxhY2Vob2xkZXI6IHN0cmluZyA9ICdBZGQgYSBjb21tZW50JztcblxuICBAT3V0cHV0KCkgcmVhZG9ubHkgY29udGVudENoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8XG4gICAgTWVudGlvbnNJbnB1dENvbXBvbmVudC5Db250ZW50SXRlbVtdXG4gID4oKTtcblxuICBAVmlld0NoaWxkKCdpbnB1dCcsIHsgc3RhdGljOiBmYWxzZSB9KVxuICBwcml2YXRlIHJlYWRvbmx5IGlucHV0RWxlbWVudD86IEVsZW1lbnRSZWY8SFRNTERpdkVsZW1lbnQ+O1xuXG4gIG1lbnRpb25zVmlzaWJsZSA9IGZhbHNlO1xuICBtZW50aW9uU2VhcmNoVGV4dCA9ICcnO1xuICBtZW50aW9uQW5jaG9yOiBET01SZWN0IHwgbnVsbCA9IG51bGw7XG4gIHNlbGVjdGVkVXNlckluZGV4ID0gMDtcbiAgcHJpdmF0ZSBzYXZlZFJhbmdlOiBSYW5nZSB8IG51bGwgPSBudWxsO1xuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLnJlbmRlckNvbnRlbnQoKTtcbiAgfVxuXG4gIC8vREFITkUgTk9URSAtIG5nT25DaGFuZ2VzIGlzIGNhbGxlZCB3aGVuZXZlciBhbnkgQElucHV0KCkgcHJvcGVydHkgY2hhbmdlcywgd2hlcmUgdGhlIGNoYW5nZWQgaW5wdXQgY29udGFpbnMgaW5mb3JtYXRpb24gYWJvdXQgdGhvc2UgY2hhbmdlc1xuICAvL1NvIGlmIEBJbnB1dCgpIGNvbnRlbnQgY2hhbmdlcyBhbmQgaXQncyBub3QgdGhlIGZpcnN0IGNoYW5nZSAodGhlIGZpcnN0IHJlbmRlciBpcyBoYW5kbGVkIGJ5IG5nQWZ0ZXJWaWV3SW5pdCgpKSwgd2UgcmVuZGVyIHRoZSBjb250ZW50XG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBpZiAoY2hhbmdlc1snY29udGVudCddICYmICFjaGFuZ2VzWydjb250ZW50J10uZmlyc3RDaGFuZ2UpIHtcbiAgICAgIHRoaXMucmVuZGVyQ29udGVudCgpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgcmVuZGVyQ29udGVudCgpOiB2b2lkIHtcbiAgICAvL1RoaXMgaXMgbmVjZXNzYXJ5IGJlY2F1c2UgdGhlIEBWaWV3Q2hpbGQgcmVmZXJlbmNlIGlzbid0IGF2YWlsYWJsZSB1bnRpbCBhZnRlciB0aGUgdmlldyBpbml0aWFsaXplc1xuICAgIGlmICghdGhpcy5pbnB1dEVsZW1lbnQ/Lm5hdGl2ZUVsZW1lbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgaHRtbCA9IHRoaXMuY29udGVudFxuICAgICAgLm1hcChpdGVtID0+IHtcbiAgICAgICAgY29uc3QgaXRlbUh0bWwgPSBNZW50aW9uc0lucHV0Q29tcG9uZW50LmNvbnRlbnRJdGVtVG9IdG1sKFxuICAgICAgICAgIGl0ZW0sXG4gICAgICAgICAgdGhpcy5yZWFkb25seSxcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIGl0ZW0udHlwZSA9PT0gJ21lbnRpb24nID8gYCR7WldTfSR7aXRlbUh0bWx9JHtaV1N9YCA6IGl0ZW1IdG1sO1xuICAgICAgfSlcbiAgICAgIC5qb2luKCcnKTtcbiAgICB0aGlzLmlucHV0RWxlbWVudC5uYXRpdmVFbGVtZW50LmlubmVySFRNTCA9IGh0bWw7XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyBjb250ZW50SXRlbVRvSHRtbChcbiAgICBpdGVtOiBNZW50aW9uc0lucHV0Q29tcG9uZW50LkNvbnRlbnRJdGVtLFxuICAgIHJlYWRvbmx5OiBib29sZWFuLFxuICApOiBzdHJpbmcge1xuICAgIHN3aXRjaCAoaXRlbS50eXBlKSB7XG4gICAgICAvL0RBSE5FIFRPRE8gLSBtYXliZSB3ZSBlc2NhcGUgSFRNTCBoZXJlIHRvbz8gQWx0aG91Z2ggSSBkb24ndCB0aGluayBpdCB3aWxsIGJlIHBvc3NpYmxlIGZvciB1c2VycyB0byBpbnB1dCBhbiBYU1MgYXR0YWNrIGluIGl0ZW0ubmFtZVxuICAgICAgY2FzZSAnbWVudGlvbic6XG4gICAgICAgIHJldHVybiBgPHNwYW4gY2xhc3M9XCIke1xuICAgICAgICAgIHJlYWRvbmx5ID8gJ3JlYWRvbmx5LW1lbnRpb24nIDogJ21lbnRpb24nXG4gICAgICAgIH1cIiBkYXRhLWlkPVwiJHtcbiAgICAgICAgICBpdGVtLmlkXG4gICAgICAgIH1cIiBkYXRhLXR5cGU9XCJtZW50aW9uXCIgY29udGVudGVkaXRhYmxlPVwiZmFsc2VcIj5AJHtNZW50aW9uc0lucHV0Q29tcG9uZW50LmVzY2FwZUh0bWwoXG4gICAgICAgICAgaXRlbS5uYW1lLFxuICAgICAgICApfTwvc3Bhbj5gO1xuICAgICAgY2FzZSAndGV4dCc6XG4gICAgICAgIHJldHVybiBNZW50aW9uc0lucHV0Q29tcG9uZW50LmVzY2FwZUh0bWwoaXRlbS50ZXh0KTtcbiAgICAgIGNhc2UgJ25ld2xpbmUnOlxuICAgICAgICByZXR1cm4gJzxicj4nO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGVzY2FwZUh0bWwodGV4dDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBkaXYudGV4dENvbnRlbnQgPSB0ZXh0O1xuICAgIHJldHVybiBkaXYuaW5uZXJIVE1MO1xuICB9XG5cbiAgLy8g4pSA4pSA4pSAIEV2ZW50IGhhbmRsZXJzIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIG9uSW5wdXQoKTogdm9pZCB7XG4gICAgdGhpcy5ub3JtYWxpemVNZW50aW9uUGFkZGluZygpO1xuICAgIHRoaXMuY2hlY2tGb3JNZW50aW9uVHJpZ2dlcigpO1xuICAgIHRoaXMuZW1pdENvbnRlbnRDaGFuZ2UoKTtcbiAgfVxuXG4gIG9uS2V5RG93bihldmVudDogS2V5Ym9hcmRFdmVudCk6IHZvaWQge1xuICAgIGlmICh0aGlzLm1lbnRpb25zVmlzaWJsZSkge1xuICAgICAgdGhpcy5oYW5kbGVNZW50aW9uc0Ryb3Bkb3duTmF2KGV2ZW50KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBXb3JkL2xpbmUganVtcDogbmF0aXZlIGJlaGF2aW9yLlxuICAgIGlmIChldmVudC5tZXRhS2V5IHx8IGV2ZW50LmN0cmxLZXkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoZXZlbnQua2V5ID09PSAnQXJyb3dMZWZ0JyB8fCBldmVudC5rZXkgPT09ICdBcnJvd1JpZ2h0Jykge1xuICAgICAgY29uc3QgZGlyZWN0aW9uID0gZXZlbnQua2V5ID09PSAnQXJyb3dMZWZ0JyA/ICdiZWZvcmUnIDogJ2FmdGVyJztcbiAgICAgIGNvbnN0IG1lbnRpb24gPSB0aGlzLmZpbmRNZW50aW9uQWRqYWNlbnRUb0N1cnNvcihkaXJlY3Rpb24pO1xuICAgICAgaWYgKG1lbnRpb24pIHtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgaWYgKGV2ZW50LnNoaWZ0S2V5KSB7XG4gICAgICAgICAgdGhpcy5leHRlbmRTZWxlY3Rpb25BY3Jvc3NNZW50aW9uKG1lbnRpb24sIGRpcmVjdGlvbik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5wbGFjZUN1cnNvckFkamFjZW50VG9NZW50aW9uKG1lbnRpb24sIGRpcmVjdGlvbik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoZXZlbnQua2V5ID09PSAnQmFja3NwYWNlJyB8fCBldmVudC5rZXkgPT09ICdEZWxldGUnKSB7XG4gICAgICBjb25zdCBkaXJlY3Rpb24gPSBldmVudC5rZXkgPT09ICdCYWNrc3BhY2UnID8gJ2JlZm9yZScgOiAnYWZ0ZXInO1xuICAgICAgY29uc3QgbWVudGlvbiA9IHRoaXMuZmluZE1lbnRpb25BZGphY2VudFRvQ3Vyc29yKGRpcmVjdGlvbik7XG4gICAgICBpZiAobWVudGlvbikge1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB0aGlzLnJlbW92ZU1lbnRpb24obWVudGlvbik7XG4gICAgICAgIHRoaXMuZW1pdENvbnRlbnRDaGFuZ2UoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKGV2ZW50LmtleSA9PT0gJ0JhY2tzcGFjZScpIHtcbiAgICAgICAgY29uc3QgYnIgPSB0aGlzLmZpbmRCckFkamFjZW50VG9DdXJzb3IoKTtcbiAgICAgICAgaWYgKGJyKSB7XG4gICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICBici5yZW1vdmUoKTtcbiAgICAgICAgICB0aGlzLmVtaXRDb250ZW50Q2hhbmdlKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy9IYW5kbGUgbmV3bGluZXMgd2hlbiBtZW50aW9ucyBhcmVuJ3QgdmlzaWJsZVxuICAgIGlmIChldmVudC5rZXkgPT09ICdFbnRlcicpIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICB0aGlzLmluc2VydExpbmVCcmVhaygpO1xuICAgICAgdGhpcy5lbWl0Q29udGVudENoYW5nZSgpO1xuICAgIH1cbiAgfVxuXG4gIG9uUGFzdGUoZXZlbnQ6IENsaXBib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICBpZiAoIWV2ZW50LmNsaXBib2FyZERhdGEpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy9Mb29rIGZvciBIVE1MIGZpcnN0XG4gICAgY29uc3QgaHRtbCA9IGV2ZW50LmNsaXBib2FyZERhdGEuZ2V0RGF0YSgndGV4dC9odG1sJyk7XG4gICAgY29uc3QgcGxhaW5UZXh0ID0gZXZlbnQuY2xpcGJvYXJkRGF0YS5nZXREYXRhKCd0ZXh0L3BsYWluJyk7XG5cbiAgICBjb25zdCBub2RlcyA9XG4gICAgICBodG1sICYmIGh0bWwuaW5jbHVkZXMoJ2RhdGEtdHlwZT1cIm1lbnRpb25cIicpXG4gICAgICAgID8gdGhpcy5wYXJzZVBhc3RlZEh0bWwoaHRtbClcbiAgICAgICAgOiB0aGlzLnBsYWluVGV4dFRvTm9kZXMocGxhaW5UZXh0KTtcblxuICAgIHRoaXMuaW5zZXJ0Tm9kZXNBdEN1cnNvcihub2Rlcyk7XG4gICAgdGhpcy5ub3JtYWxpemVNZW50aW9uUGFkZGluZygpO1xuICAgIHRoaXMuZW1pdENvbnRlbnRDaGFuZ2UoKTtcbiAgfVxuXG4gIC8vIFRoZSBicm93c2VyIHN0cmlwcyBkYXRhLSogYXR0cmlidXRlcyBkdXJpbmcgZGVmYXVsdCBjb3B5IHNlcmlhbGl6YXRpb24sIGJ1dFxuICAvLyByYW5nZS5jbG9uZUNvbnRlbnRzKCkgcHJlc2VydmVzIHRoZW0uIFdlIHNlcmlhbGl6ZSB0aGUgY2xvbmUgb3Vyc2VsdmVzIGFuZFxuICAvLyBzdHJpcCBaV1Mgc28gaXQgZG9lc24ndCBsZWFrIGludG8gdGhlIGNsaXBib2FyZC5cbiAgb25Db3B5KGV2ZW50OiBDbGlwYm9hcmRFdmVudCk6IHZvaWQge1xuICAgIGNvbnN0IHNlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcbiAgICBpZiAoIXNlbGVjdGlvbj8ucmFuZ2VDb3VudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgY29uc3QgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgZGl2LmFwcGVuZENoaWxkKHNlbGVjdGlvbi5nZXRSYW5nZUF0KDApLmNsb25lQ29udGVudHMoKSk7XG5cbiAgICBjb25zdCBodG1sID0gZGl2LmlubmVySFRNTC5yZXBsYWNlKFpXU19SRUdFWCwgJycpO1xuICAgIGNvbnN0IHRleHQgPSAoZGl2LnRleHRDb250ZW50IHx8ICcnKS5yZXBsYWNlKFpXU19SRUdFWCwgJycpO1xuXG4gICAgZXZlbnQuY2xpcGJvYXJkRGF0YT8uc2V0RGF0YSgndGV4dC9odG1sJywgaHRtbCk7XG4gICAgZXZlbnQuY2xpcGJvYXJkRGF0YT8uc2V0RGF0YSgndGV4dC9wbGFpbicsIHRleHQpO1xuICB9XG5cbiAgb25DdXQoZXZlbnQ6IENsaXBib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgdGhpcy5vbkNvcHkoZXZlbnQpO1xuICAgIGNvbnN0IHNlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcbiAgICBpZiAoIXNlbGVjdGlvbj8ucmFuZ2VDb3VudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBzZWxlY3Rpb24uZ2V0UmFuZ2VBdCgwKS5kZWxldGVDb250ZW50cygpO1xuICAgIHRoaXMubm9ybWFsaXplTWVudGlvblBhZGRpbmcoKTtcbiAgICB0aGlzLmVtaXRDb250ZW50Q2hhbmdlKCk7XG4gIH1cblxuICAvLyDilIDilIDilIAgTWVudGlvbiBoZWxwZXJzIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIHByaXZhdGUgc3RhdGljIGlzTWVudGlvbihub2RlOiBOb2RlIHwgbnVsbCB8IHVuZGVmaW5lZCk6IG5vZGUgaXMgSFRNTEVsZW1lbnQge1xuICAgIHJldHVybiAoXG4gICAgICAhIW5vZGUgJiZcbiAgICAgIG5vZGUubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFICYmXG4gICAgICAobm9kZSBhcyBIVE1MRWxlbWVudCkuZ2V0QXR0cmlidXRlKCdkYXRhLXR5cGUnKSA9PT0gJ21lbnRpb24nXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGlzWndzKG5vZGU6IE5vZGUgfCBudWxsIHwgdW5kZWZpbmVkKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIChcbiAgICAgICEhbm9kZSAmJlxuICAgICAgbm9kZS5ub2RlVHlwZSA9PT0gTm9kZS5URVhUX05PREUgJiZcbiAgICAgIChub2RlLnRleHRDb250ZW50IHx8ICcnKS5yZXBsYWNlKFpXU19SRUdFWCwgJycpID09PSAnJ1xuICAgICk7XG4gIH1cblxuICAvLyBSZXNvbHZlIHRoZSBub2RlIGxvZ2ljYWxseSBhZGphY2VudCB0byAoY29udGFpbmVyLCBvZmZzZXQpIGluIHRoZSBnaXZlblxuICAvLyBkaXJlY3Rpb24sIHRyYW5zcGFyZW50bHkgc2tpcHBpbmcgYW55IFpXUy1vbmx5IHRleHQgbm9kZXMgaW4gYmV0d2Vlbi5cbiAgcHJpdmF0ZSByZXNvbHZlQWRqYWNlbnROb2RlKFxuICAgIGNvbnRhaW5lcjogTm9kZSxcbiAgICBvZmZzZXQ6IG51bWJlcixcbiAgICBkaXJlY3Rpb246ICdiZWZvcmUnIHwgJ2FmdGVyJyxcbiAgKTogTm9kZSB8IG51bGwge1xuICAgIGxldCBjYW5kaWRhdGU6IE5vZGUgfCBudWxsID0gbnVsbDtcblxuICAgIGlmIChjb250YWluZXIubm9kZVR5cGUgPT09IE5vZGUuVEVYVF9OT0RFKSB7XG4gICAgICBjb25zdCBsZW5ndGggPSAoY29udGFpbmVyLnRleHRDb250ZW50IHx8ICcnKS5sZW5ndGg7XG4gICAgICBjb25zdCBhdEJvdW5kYXJ5ID1cbiAgICAgICAgTWVudGlvbnNJbnB1dENvbXBvbmVudC5pc1p3cyhjb250YWluZXIpIHx8XG4gICAgICAgIChkaXJlY3Rpb24gPT09ICdiZWZvcmUnID8gb2Zmc2V0ID09PSAwIDogb2Zmc2V0ID09PSBsZW5ndGgpO1xuICAgICAgaWYgKCFhdEJvdW5kYXJ5KSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgICAgY2FuZGlkYXRlID1cbiAgICAgICAgZGlyZWN0aW9uID09PSAnYmVmb3JlJ1xuICAgICAgICAgID8gY29udGFpbmVyLnByZXZpb3VzU2libGluZ1xuICAgICAgICAgIDogY29udGFpbmVyLm5leHRTaWJsaW5nO1xuICAgIH0gZWxzZSBpZiAoY29udGFpbmVyLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERSkge1xuICAgICAgY29uc3QgY2hpbGRyZW4gPSAoY29udGFpbmVyIGFzIEhUTUxFbGVtZW50KS5jaGlsZE5vZGVzO1xuICAgICAgY2FuZGlkYXRlID1cbiAgICAgICAgZGlyZWN0aW9uID09PSAnYmVmb3JlJyA/IGNoaWxkcmVuW29mZnNldCAtIDFdIDogY2hpbGRyZW5bb2Zmc2V0XTtcbiAgICB9XG5cbiAgICB3aGlsZSAoY2FuZGlkYXRlICYmIE1lbnRpb25zSW5wdXRDb21wb25lbnQuaXNad3MoY2FuZGlkYXRlKSkge1xuICAgICAgY2FuZGlkYXRlID1cbiAgICAgICAgZGlyZWN0aW9uID09PSAnYmVmb3JlJ1xuICAgICAgICAgID8gY2FuZGlkYXRlLnByZXZpb3VzU2libGluZ1xuICAgICAgICAgIDogY2FuZGlkYXRlLm5leHRTaWJsaW5nO1xuICAgIH1cbiAgICByZXR1cm4gY2FuZGlkYXRlO1xuICB9XG5cbiAgcHJpdmF0ZSBmaW5kTWVudGlvbkFkamFjZW50VG9DdXJzb3IoXG4gICAgZGlyZWN0aW9uOiAnYmVmb3JlJyB8ICdhZnRlcicsXG4gICk6IEhUTUxFbGVtZW50IHwgbnVsbCB7XG4gICAgY29uc3Qgc2VsZWN0aW9uID0gd2luZG93LmdldFNlbGVjdGlvbigpO1xuICAgIGlmICghc2VsZWN0aW9uPy5pc0NvbGxhcHNlZCB8fCAhc2VsZWN0aW9uLnJhbmdlQ291bnQpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBjb25zdCByYW5nZSA9IHNlbGVjdGlvbi5nZXRSYW5nZUF0KDApO1xuICAgIGNvbnN0IG5vZGUgPSB0aGlzLnJlc29sdmVBZGphY2VudE5vZGUoXG4gICAgICByYW5nZS5zdGFydENvbnRhaW5lcixcbiAgICAgIHJhbmdlLnN0YXJ0T2Zmc2V0LFxuICAgICAgZGlyZWN0aW9uLFxuICAgICk7XG4gICAgcmV0dXJuIE1lbnRpb25zSW5wdXRDb21wb25lbnQuaXNNZW50aW9uKG5vZGUpID8gbm9kZSA6IG51bGw7XG4gIH1cblxuICBwcml2YXRlIGZpbmRCckFkamFjZW50VG9DdXJzb3IoKTogSFRNTEVsZW1lbnQgfCBudWxsIHtcbiAgICBjb25zdCBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gICAgaWYgKCFzZWxlY3Rpb24/LmlzQ29sbGFwc2VkIHx8ICFzZWxlY3Rpb24ucmFuZ2VDb3VudCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGNvbnN0IHJhbmdlID0gc2VsZWN0aW9uLmdldFJhbmdlQXQoMCk7XG4gICAgY29uc3Qgbm9kZSA9IHRoaXMucmVzb2x2ZUFkamFjZW50Tm9kZShcbiAgICAgIHJhbmdlLnN0YXJ0Q29udGFpbmVyLFxuICAgICAgcmFuZ2Uuc3RhcnRPZmZzZXQsXG4gICAgICAnYmVmb3JlJyxcbiAgICApO1xuICAgIHJldHVybiBub2RlPy5ub2RlTmFtZSA9PT0gJ0JSJyA/IChub2RlIGFzIEhUTUxFbGVtZW50KSA6IG51bGw7XG4gIH1cblxuICBwcml2YXRlIGV4dGVuZFNlbGVjdGlvbkFjcm9zc01lbnRpb24oXG4gICAgbWVudGlvbjogSFRNTEVsZW1lbnQsXG4gICAgZGlyZWN0aW9uOiAnYmVmb3JlJyB8ICdhZnRlcicsXG4gICk6IHZvaWQge1xuICAgIGNvbnN0IHNlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcbiAgICBjb25zdCBwYXJlbnQgPSBtZW50aW9uLnBhcmVudE5vZGU7XG4gICAgaWYgKCFzZWxlY3Rpb24gfHwgIXBhcmVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBpbmRleCA9IEFycmF5LmZyb20ocGFyZW50LmNoaWxkTm9kZXMpLmluZGV4T2YobWVudGlvbiBhcyBDaGlsZE5vZGUpO1xuICAgIHNlbGVjdGlvbi5leHRlbmQocGFyZW50LCBkaXJlY3Rpb24gPT09ICdiZWZvcmUnID8gaW5kZXggOiBpbmRleCArIDEpO1xuICB9XG5cbiAgcHJpdmF0ZSBwbGFjZUN1cnNvckFkamFjZW50VG9NZW50aW9uKFxuICAgIG1lbnRpb246IEhUTUxFbGVtZW50LFxuICAgIHNpZGU6ICdiZWZvcmUnIHwgJ2FmdGVyJyxcbiAgKTogdm9pZCB7XG4gICAgY29uc3QgcGFyZW50ID0gbWVudGlvbi5wYXJlbnROb2RlO1xuICAgIGlmICghcGFyZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHNpYmxpbmcgPVxuICAgICAgc2lkZSA9PT0gJ2JlZm9yZScgPyBtZW50aW9uLnByZXZpb3VzU2libGluZyA6IG1lbnRpb24ubmV4dFNpYmxpbmc7XG4gICAgbGV0IHp3czogTm9kZTtcbiAgICBpZiAoc2libGluZyAmJiBNZW50aW9uc0lucHV0Q29tcG9uZW50LmlzWndzKHNpYmxpbmcpKSB7XG4gICAgICB6d3MgPSBzaWJsaW5nO1xuICAgIH0gZWxzZSB7XG4gICAgICB6d3MgPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShaV1MpO1xuICAgICAgcGFyZW50Lmluc2VydEJlZm9yZShcbiAgICAgICAgendzLFxuICAgICAgICBzaWRlID09PSAnYmVmb3JlJyA/IG1lbnRpb24gOiBtZW50aW9uLm5leHRTaWJsaW5nLFxuICAgICAgKTtcbiAgICB9XG4gICAgY29uc3QgcmFuZ2UgPSBkb2N1bWVudC5jcmVhdGVSYW5nZSgpO1xuICAgIHJhbmdlLnNldFN0YXJ0KHp3cywgc2lkZSA9PT0gJ2JlZm9yZScgPyAoendzLnRleHRDb250ZW50IHx8ICcnKS5sZW5ndGggOiAwKTtcbiAgICByYW5nZS5jb2xsYXBzZSh0cnVlKTtcbiAgICBjb25zdCBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gICAgc2VsZWN0aW9uPy5yZW1vdmVBbGxSYW5nZXMoKTtcbiAgICBzZWxlY3Rpb24/LmFkZFJhbmdlKHJhbmdlKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVtb3ZlTWVudGlvbihtZW50aW9uOiBIVE1MRWxlbWVudCk6IHZvaWQge1xuICAgIGNvbnN0IHBhcmVudCA9IG1lbnRpb24ucGFyZW50Tm9kZTtcbiAgICBpZiAoIXBhcmVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBFbXB0eSB0ZXh0LW5vZGUgYW5jaG9yIHByZXNlcnZlcyBjdXJzb3IgcG9zaXRpb24gdGhyb3VnaCB0aGUgcmVtb3ZhbC5cbiAgICBjb25zdCBhbmNob3IgPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSgnJyk7XG4gICAgcGFyZW50Lmluc2VydEJlZm9yZShhbmNob3IsIG1lbnRpb24pO1xuXG4gICAgY29uc3QgcHJldiA9IG1lbnRpb24ucHJldmlvdXNTaWJsaW5nO1xuICAgIGNvbnN0IG5leHQgPSBtZW50aW9uLm5leHRTaWJsaW5nO1xuICAgIGlmIChwcmV2ICYmIE1lbnRpb25zSW5wdXRDb21wb25lbnQuaXNad3MocHJldikpIHtcbiAgICAgIHByZXYucmVtb3ZlKCk7XG4gICAgfVxuICAgIGlmIChuZXh0ICYmIE1lbnRpb25zSW5wdXRDb21wb25lbnQuaXNad3MobmV4dCkpIHtcbiAgICAgIG5leHQucmVtb3ZlKCk7XG4gICAgfVxuICAgIG1lbnRpb24ucmVtb3ZlKCk7XG5cbiAgICBjb25zdCByYW5nZSA9IGRvY3VtZW50LmNyZWF0ZVJhbmdlKCk7XG4gICAgcmFuZ2Uuc2V0U3RhcnQoYW5jaG9yLCAwKTtcbiAgICByYW5nZS5jb2xsYXBzZSh0cnVlKTtcbiAgICBjb25zdCBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gICAgc2VsZWN0aW9uPy5yZW1vdmVBbGxSYW5nZXMoKTtcbiAgICBzZWxlY3Rpb24/LmFkZFJhbmdlKHJhbmdlKTtcbiAgfVxuXG4gIC8vIFJlLWVzdGFibGlzaGVzIHRoZSBpbnZhcmlhbnQ6IGV2ZXJ5IG1lbnRpb24gaGFzIGV4YWN0bHkgb25lIFpXUyB0ZXh0XG4gIC8vIG5vZGUgaW1tZWRpYXRlbHkgYmVmb3JlIGFuZCBhZnRlciBpdCwgYW5kIHRoZXJlIGFyZSBubyBvcnBoYW4gWldTLW9ubHlcbiAgLy8gdGV4dCBub2RlcyBhbnl3aGVyZSBlbHNlLiBSdW4gYWZ0ZXIgYW55IG9wZXJhdGlvbiB0aGF0IG1heSBkaXN0dXJiIHRoZVxuICAvLyB0cmVlICh0eXBpbmcsIHBhc3RlLCBjdXQsIGRlbGV0ZSkgc28gY3J1ZnQgZG9lc24ndCBhY2N1bXVsYXRlIGFjcm9zc1xuICAvLyByZXBlYXRlZCBjb3B5L3Bhc3RlIGN5Y2xlcy5cbiAgcHJpdmF0ZSBub3JtYWxpemVNZW50aW9uUGFkZGluZygpOiB2b2lkIHtcbiAgICBjb25zdCByb290ID0gdGhpcy5pbnB1dEVsZW1lbnQ/Lm5hdGl2ZUVsZW1lbnQ7XG4gICAgaWYgKCFyb290KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gMS4gRW5zdXJlIGVhY2ggbWVudGlvbiBoYXMgYSBaV1MgcGFkIG9uIGJvdGggc2lkZXMuXG4gICAgY29uc3QgbWVudGlvbnMgPSBBcnJheS5mcm9tKFxuICAgICAgcm9vdC5xdWVyeVNlbGVjdG9yQWxsKCdzcGFuW2RhdGEtdHlwZT1cIm1lbnRpb25cIl0nKSxcbiAgICApIGFzIEhUTUxFbGVtZW50W107XG4gICAgZm9yIChjb25zdCBtIG9mIG1lbnRpb25zKSB7XG4gICAgICBjb25zdCBwYXJlbnQgPSBtLnBhcmVudE5vZGU7XG4gICAgICBpZiAoIXBhcmVudCkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlmIChcbiAgICAgICAgIW0ucHJldmlvdXNTaWJsaW5nIHx8XG4gICAgICAgICFNZW50aW9uc0lucHV0Q29tcG9uZW50LmlzWndzKG0ucHJldmlvdXNTaWJsaW5nKVxuICAgICAgKSB7XG4gICAgICAgIHBhcmVudC5pbnNlcnRCZWZvcmUoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoWldTKSwgbSk7XG4gICAgICB9XG4gICAgICBpZiAoIW0ubmV4dFNpYmxpbmcgfHwgIU1lbnRpb25zSW5wdXRDb21wb25lbnQuaXNad3MobS5uZXh0U2libGluZykpIHtcbiAgICAgICAgcGFyZW50Lmluc2VydEJlZm9yZShkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShaV1MpLCBtLm5leHRTaWJsaW5nKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyAyLiBSZW1vdmUgYW55IFpXUy1vbmx5IHRleHQgbm9kZSB0aGF0IGlzbid0IGRpcmVjdGx5IGFkamFjZW50IHRvIGFcbiAgICAvLyAgICBtZW50aW9uIChvcnBoYW5zIGZyb20gbGluZS1icmVhayBwYWRzLCBsZWZ0b3ZlciBzcGxpdHMgZnJvbSBwcmV2aW91c1xuICAgIC8vICAgIHBhc3RlIGluc2VydGlvbnMsIGR1cGxpY2F0ZSBwYWRzIGZyb20gYWNjdW11bGF0ZWQgY29weS9wYXN0ZSBjeWNsZXMpLlxuICAgIC8vICAgIFNraXAgYSBub2RlIGlmIHRoZSBjdXJzb3IgY3VycmVudGx5IGxpdmVzIGluIGl0IOKAlCBwcmVzZXJ2ZXMgY2FyZXRcbiAgICAvLyAgICBwb3NpdGlvbiB3aXRob3V0IG5lZWRpbmcgbWFudWFsIHJlc3RvcmF0aW9uLlxuICAgIGNvbnN0IHNlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcbiAgICBjb25zdCBjdXJzb3JOb2RlID1cbiAgICAgIHNlbGVjdGlvbj8ucmFuZ2VDb3VudCAmJlxuICAgICAgcm9vdC5jb250YWlucyhzZWxlY3Rpb24uZ2V0UmFuZ2VBdCgwKS5zdGFydENvbnRhaW5lcilcbiAgICAgICAgPyBzZWxlY3Rpb24uZ2V0UmFuZ2VBdCgwKS5zdGFydENvbnRhaW5lclxuICAgICAgICA6IG51bGw7XG5cbiAgICBjb25zdCB3YWxrZXIgPSBkb2N1bWVudC5jcmVhdGVUcmVlV2Fsa2VyKHJvb3QsIE5vZGVGaWx0ZXIuU0hPV19URVhULCBudWxsKTtcbiAgICBjb25zdCBvcnBoYW5zOiBUZXh0W10gPSBbXTtcbiAgICB3aGlsZSAod2Fsa2VyLm5leHROb2RlKCkpIHtcbiAgICAgIGNvbnN0IG5vZGUgPSB3YWxrZXIuY3VycmVudE5vZGUgYXMgVGV4dDtcbiAgICAgIGlmICghTWVudGlvbnNJbnB1dENvbXBvbmVudC5pc1p3cyhub2RlKSB8fCBub2RlID09PSBjdXJzb3JOb2RlKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgY29uc3QgYWRqYWNlbnRUb01lbnRpb24gPVxuICAgICAgICBNZW50aW9uc0lucHV0Q29tcG9uZW50LmlzTWVudGlvbihub2RlLnByZXZpb3VzU2libGluZykgfHxcbiAgICAgICAgTWVudGlvbnNJbnB1dENvbXBvbmVudC5pc01lbnRpb24obm9kZS5uZXh0U2libGluZyk7XG4gICAgICBpZiAoIWFkamFjZW50VG9NZW50aW9uKSB7XG4gICAgICAgIG9ycGhhbnMucHVzaChub2RlKTtcbiAgICAgIH1cbiAgICB9XG4gICAgZm9yIChjb25zdCBub2RlIG9mIG9ycGhhbnMpIHtcbiAgICAgIG5vZGUucmVtb3ZlKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVNZW50aW9uc0Ryb3Bkb3duTmF2KGV2ZW50OiBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgY29uc3QgZmlsdGVyZWRVc2VycyA9IHRoaXMuZ2V0RmlsdGVyZWRVc2VycygpO1xuICAgIGlmIChmaWx0ZXJlZFVzZXJzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhpcy5jbG9zZU1lbnRpb25zKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgc3dpdGNoIChldmVudC5rZXkpIHtcbiAgICAgIGNhc2UgJ0Fycm93RG93bic6XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRVc2VySW5kZXggPSBNYXRoLm1pbihcbiAgICAgICAgICB0aGlzLnNlbGVjdGVkVXNlckluZGV4ICsgMSxcbiAgICAgICAgICBmaWx0ZXJlZFVzZXJzLmxlbmd0aCAtIDEsXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ0Fycm93VXAnOlxuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB0aGlzLnNlbGVjdGVkVXNlckluZGV4ID0gTWF0aC5tYXgodGhpcy5zZWxlY3RlZFVzZXJJbmRleCAtIDEsIDApO1xuICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdFbnRlcic6XG4gICAgICBjYXNlICdUYWInOlxuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBpZiAoZmlsdGVyZWRVc2Vyc1t0aGlzLnNlbGVjdGVkVXNlckluZGV4XSkge1xuICAgICAgICAgIHRoaXMuc2VsZWN0VXNlcihmaWx0ZXJlZFVzZXJzW3RoaXMuc2VsZWN0ZWRVc2VySW5kZXhdKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ0VzY2FwZSc6XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIHRoaXMuY2xvc2VNZW50aW9ucygpO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICAvLyDilIDilIDilIAgSW5zZXJ0aW9uIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIHByaXZhdGUgcGxhaW5UZXh0VG9Ob2Rlcyh0ZXh0OiBzdHJpbmcpOiBOb2RlW10ge1xuICAgIGNvbnN0IG5vZGVzOiBOb2RlW10gPSBbXTtcbiAgICBjb25zdCBsaW5lcyA9IHRleHQuc3BsaXQoJ1xcbicpO1xuICAgIGxpbmVzLmZvckVhY2goKGxpbmUsIGluZGV4KSA9PiB7XG4gICAgICBpZiAobGluZSkge1xuICAgICAgICBub2Rlcy5wdXNoKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKGxpbmUpKTtcbiAgICAgIH1cbiAgICAgIGlmIChpbmRleCA8IGxpbmVzLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgbm9kZXMucHVzaChkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdicicpKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gbm9kZXM7XG4gIH1cbiAgLy8gQ3JlYXRlIGEgdGVtcG9yYXJ5IGNvbnRhaW5lciB0byBwYXJzZSB0aGUgSFRNTFxuICBwcml2YXRlIHBhcnNlUGFzdGVkSHRtbChodG1sOiBzdHJpbmcpOiBOb2RlW10ge1xuICAgIC8vIENyZWF0ZSBhIHRlbXBvcmFyeSBjb250YWluZXIgdG8gcGFyc2UgdGhlIEhUTUxcbiAgICBjb25zdCB0ZW1wQ29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgdGVtcENvbnRhaW5lci5pbm5lckhUTUwgPSBodG1sO1xuXG4gICAgY29uc3Qgbm9kZXM6IE5vZGVbXSA9IFtdO1xuICAgIGNvbnN0IHdhbGsgPSAobm9kZTogTm9kZSk6IHZvaWQgPT4ge1xuICAgICAgaWYgKG5vZGUubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFKSB7XG4gICAgICAgIGNvbnN0IGVsID0gbm9kZSBhcyBIVE1MRWxlbWVudDtcbiAgICAgICAgLy8gREFITkUgTk9URSAtIHdlIG9ubHkgd2FudCBtZW50aW9uIHNwYW5zLCBiciBlbGVtZW50cywgYW5kIHRleHRcbiAgICAgICAgaWYgKFxuICAgICAgICAgIGVsLnRhZ05hbWUgPT09ICdTUEFOJyAmJlxuICAgICAgICAgIGVsLmdldEF0dHJpYnV0ZSgnZGF0YS10eXBlJykgPT09ICdtZW50aW9uJyAmJlxuICAgICAgICAgIGVsLmhhc0F0dHJpYnV0ZSgnZGF0YS1pZCcpXG4gICAgICAgICkge1xuICAgICAgICAgIC8vQ3JlYXRlIG1lbnRpb24gdG8gdWx0aW1hdGVseSBpbnNlcnQgaW50byB0aGUgRE9NXG4gICAgICAgICAgY29uc3Qgc3BhbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTtcbiAgICAgICAgICBzcGFuLmNsYXNzTmFtZSA9IHRoaXMucmVhZG9ubHkgPyAncmVhZG9ubHktbWVudGlvbicgOiAnbWVudGlvbic7XG4gICAgICAgICAgc3Bhbi5zZXRBdHRyaWJ1dGUoJ2RhdGEtaWQnLCBlbC5nZXRBdHRyaWJ1dGUoJ2RhdGEtaWQnKSB8fCAnJyk7XG4gICAgICAgICAgc3Bhbi5zZXRBdHRyaWJ1dGUoJ2RhdGEtdHlwZScsICdtZW50aW9uJyk7XG4gICAgICAgICAgc3Bhbi5zZXRBdHRyaWJ1dGUoJ2NvbnRlbnRlZGl0YWJsZScsICdmYWxzZScpO1xuICAgICAgICAgIGNvbnN0IHJhdyA9IGVsLnRleHRDb250ZW50IHx8ICcnO1xuICAgICAgICAgIHNwYW4udGV4dENvbnRlbnQgPSByYXcuc3RhcnRzV2l0aCgnQCcpID8gcmF3IDogYEAke3Jhd31gO1xuICAgICAgICAgIG5vZGVzLnB1c2goc3Bhbik7XG4gICAgICAgIH0gZWxzZSBpZiAoZWwudGFnTmFtZSA9PT0gJ0JSJykge1xuICAgICAgICAgIC8vIFByZXNlcnZlIGxpbmUgYnJlYWtzXG4gICAgICAgICAgbm9kZXMucHVzaChkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdicicpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvL1JlY3Vyc2l2ZWx5IGxvb2sgZm9yIG5lc3RlZCBjaGlsZHJlblxuICAgICAgICAgIGZvciAoY29uc3QgY2hpbGQgb2YgQXJyYXkuZnJvbShlbC5jaGlsZE5vZGVzKSkge1xuICAgICAgICAgICAgd2FsayhjaGlsZCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKG5vZGUubm9kZVR5cGUgPT09IE5vZGUuVEVYVF9OT0RFKSB7XG4gICAgICAgIGNvbnN0IHRleHQgPSAobm9kZS50ZXh0Q29udGVudCB8fCAnJykucmVwbGFjZShaV1NfUkVHRVgsICcnKTtcbiAgICAgICAgaWYgKHRleHQpIHtcbiAgICAgICAgICBub2Rlcy5wdXNoKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHRleHQpKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICBmb3IgKGNvbnN0IGNoaWxkIG9mIEFycmF5LmZyb20odGVtcENvbnRhaW5lci5jaGlsZE5vZGVzKSkge1xuICAgICAgd2FsayhjaGlsZCk7XG4gICAgfVxuICAgIC8vREFITkUgTk9URSAtIHRoZSByZXN1bHQgaGVyZSBzaG91bGQgYmUgYW4gYXJyYXkgb2YgdGV4dC9zcGFuLW1lbnRpb24vYnIgbm9kZXNcbiAgICByZXR1cm4gbm9kZXM7XG4gIH1cblxuICBwcml2YXRlIGluc2VydE5vZGVzQXRDdXJzb3Iobm9kZXM6IE5vZGVbXSk6IHZvaWQge1xuICAgIC8vR2V0IHNlbGVjdGlvbiBvYmplY3QsIHJlcHJlc2VudGluZyB1c2VyIGN1cnNvciBwb3NpdGlvbi9zZWxlY3Rpb25cbiAgICAvL0dldCBSYW5nZSBvYmplY3QgYXQgc3RhcnQgb2Ygc2VsZWN0aW9uLCB3aGljaCBzaG91bGQgcmVwcmVzZW50IGN1cnNvciBwb3NpdGlvblxuICAgIC8vSWYgdGhlcmUgaXMgYSBzZWxlY3Rpb24sIGRlbGV0ZSBpdFxuICAgIC8vSW5zZXJ0IHRoZSBwYXJzZWQgbm9kZXMgZnJvbSBhYm92ZSwgbW92ZSByYW5nZSBlbmRzIHRvIGFmdGVyIG5vZGVcbiAgICAvL1RoZW4gcmVtb3ZlIHRoZSByYW5nZSBhbmQgcmVzZXQgaXQgdG8gbW92ZSB0aGUgY3Vyc29yIHBvc2l0aW9uIHRvIHRoZSBlbmRcbiAgICBjb25zdCBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gICAgaWYgKCFzZWxlY3Rpb24/LnJhbmdlQ291bnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgcmFuZ2UgPSBzZWxlY3Rpb24uZ2V0UmFuZ2VBdCgwKTtcbiAgICByYW5nZS5kZWxldGVDb250ZW50cygpO1xuXG4gICAgbGV0IGN1cnNvclRhcmdldDogTm9kZSB8IG51bGwgPSBudWxsO1xuICAgIGZvciAoY29uc3Qgbm9kZSBvZiBub2Rlcykge1xuICAgICAgaWYgKE1lbnRpb25zSW5wdXRDb21wb25lbnQuaXNNZW50aW9uKG5vZGUpKSB7XG4gICAgICAgIGNvbnN0IGJlZm9yZSA9IGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKFpXUyk7XG4gICAgICAgIGNvbnN0IGFmdGVyID0gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoWldTKTtcbiAgICAgICAgcmFuZ2UuaW5zZXJ0Tm9kZShiZWZvcmUpO1xuICAgICAgICByYW5nZS5zZXRTdGFydEFmdGVyKGJlZm9yZSk7XG4gICAgICAgIHJhbmdlLmluc2VydE5vZGUobm9kZSk7XG4gICAgICAgIHJhbmdlLnNldFN0YXJ0QWZ0ZXIobm9kZSk7XG4gICAgICAgIHJhbmdlLmluc2VydE5vZGUoYWZ0ZXIpO1xuICAgICAgICByYW5nZS5zZXRTdGFydEFmdGVyKGFmdGVyKTtcbiAgICAgICAgY3Vyc29yVGFyZ2V0ID0gYWZ0ZXI7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByYW5nZS5pbnNlcnROb2RlKG5vZGUpO1xuICAgICAgICByYW5nZS5zZXRTdGFydEFmdGVyKG5vZGUpO1xuICAgICAgICBjdXJzb3JUYXJnZXQgPSBub2RlO1xuICAgICAgfVxuICAgICAgcmFuZ2UuY29sbGFwc2UodHJ1ZSk7XG4gICAgfVxuXG4gICAgLy8gQWZ0ZXIgYSBtZW50aW9uLCBsZWF2ZSB0aGUgY3Vyc29yIGluc2lkZSB0aGUgdHJhaWxpbmcgWldTIHNvIEFycm93TGVmdFxuICAgIC8vIGNhbiBzdGVwIGJhY2sgdG8gYmVmb3JlLXRoZS1tZW50aW9uIG5hdHVyYWxseS5cbiAgICBpZiAoY3Vyc29yVGFyZ2V0ICYmIE1lbnRpb25zSW5wdXRDb21wb25lbnQuaXNad3MoY3Vyc29yVGFyZ2V0KSkge1xuICAgICAgcmFuZ2Uuc2V0U3RhcnQoY3Vyc29yVGFyZ2V0LCAwKTtcbiAgICAgIHJhbmdlLmNvbGxhcHNlKHRydWUpO1xuICAgIH1cblxuICAgIHNlbGVjdGlvbi5yZW1vdmVBbGxSYW5nZXMoKTtcbiAgICBzZWxlY3Rpb24uYWRkUmFuZ2UocmFuZ2UpO1xuICB9XG5cbiAgcHJpdmF0ZSBpbnNlcnRMaW5lQnJlYWsoKTogdm9pZCB7XG4gICAgY29uc3Qgc2VsZWN0aW9uID0gd2luZG93LmdldFNlbGVjdGlvbigpO1xuICAgIGlmICghc2VsZWN0aW9uPy5yYW5nZUNvdW50IHx8ICF0aGlzLmlucHV0RWxlbWVudD8ubmF0aXZlRWxlbWVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCByYW5nZSA9IHNlbGVjdGlvbi5nZXRSYW5nZUF0KDApO1xuICAgIHJhbmdlLmRlbGV0ZUNvbnRlbnRzKCk7XG5cbiAgICBjb25zdCBiciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2JyJyk7XG4gICAgcmFuZ2UuaW5zZXJ0Tm9kZShicik7XG4gICAgcmFuZ2Uuc2V0U3RhcnRBZnRlcihicik7XG4gICAgcmFuZ2UuY29sbGFwc2UodHJ1ZSk7XG5cbiAgICAvLyBBIHRyYWlsaW5nIDxicj4gYWxvbmUgZG9lc24ndCByZW5kZXIgYW4gZW1wdHkgbGluZSBpbiBjb250ZW50ZWRpdGFibGUg4oCUXG4gICAgLy8gYSBaV1MgZ2l2ZXMgdGhlIGNhcmV0IGEgcGxhY2UgdG8gbGFuZC5cbiAgICBpZiAoIWJyLm5leHRTaWJsaW5nKSB7XG4gICAgICBjb25zdCB6d3MgPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShaV1MpO1xuICAgICAgcmFuZ2UuaW5zZXJ0Tm9kZSh6d3MpO1xuICAgICAgcmFuZ2Uuc2V0U3RhcnQoendzLCAwKTtcbiAgICAgIHJhbmdlLmNvbGxhcHNlKHRydWUpO1xuICAgIH1cblxuICAgIHNlbGVjdGlvbi5yZW1vdmVBbGxSYW5nZXMoKTtcbiAgICBzZWxlY3Rpb24uYWRkUmFuZ2UocmFuZ2UpO1xuICB9XG5cbiAgLy8g4pSA4pSA4pSAIE1lbnRpb24gdHJpZ2dlciAvIGRyb3Bkb3duIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIHByaXZhdGUgY2hlY2tGb3JNZW50aW9uVHJpZ2dlcigpOiB2b2lkIHtcbiAgICBjb25zdCBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gICAgaWYgKCFzZWxlY3Rpb24gfHwgIXNlbGVjdGlvbi5yYW5nZUNvdW50IHx8ICF0aGlzLmlucHV0RWxlbWVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHJhbmdlID0gc2VsZWN0aW9uLmdldFJhbmdlQXQoMCk7XG4gICAgY29uc3QgdGV4dEJlZm9yZUN1cnNvciA9IHRoaXMuZ2V0VGV4dEJlZm9yZUN1cnNvcihyYW5nZSk7XG4gICAgY29uc3QgbGFzdEF0SW5kZXggPSB0ZXh0QmVmb3JlQ3Vyc29yLmxhc3RJbmRleE9mKCdAJyk7XG5cbiAgICBpZiAobGFzdEF0SW5kZXggPT09IC0xKSB7XG4gICAgICB0aGlzLmNsb3NlTWVudGlvbnMoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy9JZiB3ZSBhbGxvdyBmb3IgYSBzaW5nbGUgc3BhY2UsIHdlIG5lZWQgdG8gY2hlY2sgdG8gbWFrZSBzdXJlIHRoYXQgdGhpcyBsb2dpYyB3b24ndCBwaWNrIHVwIHByZXZpb3VzXG4gICAgLy8nQCcgbWVudGlvbnMgYW5kIGtlZXAgdGhlIG1lbnRpb24gZHJvcGRvd24gb3BlblxuICAgIGNvbnN0IGF0UG9zaXRpb24gPSB0aGlzLmZpbmREb21Qb3NpdGlvbkF0Q2hhckluZGV4KGxhc3RBdEluZGV4KTtcbiAgICBpZiAoYXRQb3NpdGlvbiAmJiB0aGlzLmlzSW5zaWRlTWVudGlvblNwYW4oYXRQb3NpdGlvbi5ub2RlKSkge1xuICAgICAgdGhpcy5jbG9zZU1lbnRpb25zKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgdGV4dEFmdGVyQXQgPSB0ZXh0QmVmb3JlQ3Vyc29yLnN1YnN0cmluZyhsYXN0QXRJbmRleCArIDEpO1xuICAgIGNvbnN0IGNoYXIxID0gdGV4dEFmdGVyQXQuY2hhckNvZGVBdCgwKTtcbiAgICBjb25zdCBjaGFyTiA9IHRleHRBZnRlckF0LmNoYXJDb2RlQXQodGV4dEFmdGVyQXQubGVuZ3RoIC0gMSk7XG4gICAgY29uc3QgY2hhck5fMSA9IHRleHRBZnRlckF0LmNoYXJDb2RlQXQodGV4dEFmdGVyQXQubGVuZ3RoIC0gMik7XG4gICAgLy9UaGVzZSBhcmUgdGhlIFVuaWNvZGUgcmVwcmVzZW50YXRpb25zIG9mIG5vcm1hbCBzcGFjZSBhbmQgbm9uLWJyZWFraW5nIHNwYWNlXG4gICAgY29uc3QgdW5pY29kZVNwYWNlQ2hhcnMgPSBbMzIsIDE2MF07XG5cbiAgICAvLyBDbG9zZSBtZW50aW9ucyBpZjpcbiAgICAvLyAtIFRoZXJlJ3MgYSBkb3VibGUgc3BhY2UgKGFsbG93cyBzaW5nbGUgc3BhY2VzIGluIHRoZSBtaWRkbGUgb2Ygc2VhcmNoKVxuICAgIC8vIC0gVGhlIHRleHQgc3RhcnRzIHdpdGggYSBzcGFjZSAodHlwaW5nIFwiQCBcIiBzaG91bGQgbm90IHRyaWdnZXIgbWVudGlvbnMpXG4gICAgaWYgKFxuICAgICAgdGV4dEFmdGVyQXQuaW5jbHVkZXMoJyAgJykgfHxcbiAgICAgIHRleHRBZnRlckF0LnN0YXJ0c1dpdGgoJyAnKSB8fFxuICAgICAgY2hhcjEgPT0gMTYwIHx8XG4gICAgICAodW5pY29kZVNwYWNlQ2hhcnMuaW5jbHVkZXMoY2hhck4pICYmIHVuaWNvZGVTcGFjZUNoYXJzLmluY2x1ZGVzKGNoYXJOXzEpKVxuICAgICkge1xuICAgICAgdGhpcy5jbG9zZU1lbnRpb25zKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIFRyaW0gdHJhaWxpbmcvbGVhZGluZyBzcGFjZXMgZnJvbSBzZWFyY2ggdGV4dCB3aGlsZSBwcmVzZXJ2aW5nIHNwYWNlcyBpbiB0aGUgbWlkZGxlXG4gICAgdGhpcy5tZW50aW9uU2VhcmNoVGV4dCA9IHRleHRBZnRlckF0LnRyaW0oKTtcbiAgICAvLyBPbmx5IHNob3cgbWVudGlvbnMgaWYgdGhlcmUgYXJlIGZpbHRlcmVkIHVzZXJzXG4gICAgY29uc3QgZmlsdGVyZWRVc2VycyA9IHRoaXMuZ2V0RmlsdGVyZWRVc2VycygpO1xuICAgIGlmIChmaWx0ZXJlZFVzZXJzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhpcy5jbG9zZU1lbnRpb25zKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5tZW50aW9uc1Zpc2libGUgPSB0cnVlO1xuICAgIHRoaXMuc2VsZWN0ZWRVc2VySW5kZXggPSAwO1xuXG4gICAgLy9TYXZlIHRoZSBjdXJyZW50IHJhbmdlIGZvciBsYXRlciByZXN0b3JhdGlvbiAobmVlZGVkIGZvciBjbGljayBzZWxlY3Rpb24pXG4gICAgLy9EQUhORSBOT1RFIC0gdGhpcyBpcyBhbm5veWluZ2x5IG5lY2Vlc3NhcnkgYmVjYXVzZSBjbGlja3MgYW5kIGVudGVyIGtleXMgaGF2ZSBkaWZmZXJlbnQgZWZmZWN0cyBvbiB0aGVcbiAgICAvL2ZvY3VzIG9mIHRoZSBjb250ZW50ZWRpdGFibGUgZGl2XG4gICAgdGhpcy5zYXZlZFJhbmdlID0gcmFuZ2UuY2xvbmVSYW5nZSgpO1xuXG4gICAgaWYgKGF0UG9zaXRpb24pIHtcbiAgICAgIGNvbnN0IGF0UmFuZ2UgPSBkb2N1bWVudC5jcmVhdGVSYW5nZSgpO1xuICAgICAgYXRSYW5nZS5zZXRTdGFydChhdFBvc2l0aW9uLm5vZGUsIGF0UG9zaXRpb24ub2Zmc2V0KTtcbiAgICAgIGF0UmFuZ2Uuc2V0RW5kKGF0UG9zaXRpb24ubm9kZSwgYXRQb3NpdGlvbi5vZmZzZXQgKyAxKTtcbiAgICAgIHRoaXMubWVudGlvbkFuY2hvciA9IGF0UmFuZ2UuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgfVxuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRUZXh0QmVmb3JlQ3Vyc29yKHJhbmdlOiBSYW5nZSk6IHN0cmluZyB7XG4gICAgY29uc3QgY2xvbmVkUmFuZ2UgPSByYW5nZS5jbG9uZVJhbmdlKCk7XG4gICAgLy9XZSBzZWxlY3QgYWxsIG9mIHRoZSBpbnB1dCBjb250ZW50cywgYW5kIHRoZW4gbW92ZSB0aGUgZW5kIHBvaW50IHRvIHRoZSBjdXJyZW50IGN1cnNvciBwb3NpdGlvblxuICAgIGNsb25lZFJhbmdlLnNlbGVjdE5vZGVDb250ZW50cyh0aGlzLmlucHV0RWxlbWVudCEubmF0aXZlRWxlbWVudCk7XG4gICAgY2xvbmVkUmFuZ2Uuc2V0RW5kKHJhbmdlLmVuZENvbnRhaW5lciwgcmFuZ2UuZW5kT2Zmc2V0KTtcbiAgICAvL0NyZWF0ZSBhIHRlbXBvcmFyeSBkaXYgc28gdGhhdCB3ZSBjYW4gZXh0cmFjdCB0ZXh0IGNvbnRlbnQgZnJvbSBpdFxuICAgIGNvbnN0IGZyYWdtZW50ID0gY2xvbmVkUmFuZ2UuY2xvbmVDb250ZW50cygpO1xuICAgIGNvbnN0IGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIGRpdi5hcHBlbmRDaGlsZChmcmFnbWVudCk7XG4gICAgLy9HZXQgdGV4dCBjb250ZW50LCByZXBsYWNpbmcgbWVudGlvbiBzcGFucyB3aXRoIEBuYW1lXG4gICAgcmV0dXJuIGRpdi50ZXh0Q29udGVudCB8fCAnJztcbiAgfVxuXG4gIGdldEZpbHRlcmVkVXNlcnMoKTogTWVudGlvbnNJbnB1dENvbXBvbmVudC5Vc2VyW10ge1xuICAgIGNvbnN0IHVzZXJzID0gIXRoaXMubWVudGlvblNlYXJjaFRleHRcbiAgICAgID8gdGhpcy51c2Vyc1xuICAgICAgOiB0aGlzLnVzZXJzLmZpbHRlcih1c2VyID0+XG4gICAgICAgICAgdXNlci5uYW1lXG4gICAgICAgICAgICAudG9Mb3dlckNhc2UoKVxuICAgICAgICAgICAgLmluY2x1ZGVzKHRoaXMubWVudGlvblNlYXJjaFRleHQudG9Mb3dlckNhc2UoKSksXG4gICAgICAgICk7XG4gICAgcmV0dXJuIHVzZXJzLnNsaWNlKCkuc29ydCgoYSwgYikgPT4gYS5uYW1lLmxvY2FsZUNvbXBhcmUoYi5uYW1lKSk7XG4gIH1cblxuICBvblVzZXJIb3ZlcihpbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5zZWxlY3RlZFVzZXJJbmRleCA9IGluZGV4O1xuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgc2VsZWN0VXNlcih1c2VyOiBNZW50aW9uc0lucHV0Q29tcG9uZW50LlVzZXIpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuaW5wdXRFbGVtZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vVGhpcyBnZXRzIERPTSBpbmZvIGZyb20gdXNlciAoZS5nLiBoaWdobGlnaHRlZCBzZWxlY3Rpb25zLCBhbmQgY3Vyc29yIHBvc2l0aW9uKVxuICAgIGNvbnN0IHNlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcbiAgICBpZiAoIXNlbGVjdGlvbikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBSZXN0b3JlIHRoZSBzYXZlZCByYW5nZSBpZiBhdmFpbGFibGUgKG5lZWRlZCB3aGVuIHNlbGVjdGluZyB2aWEgY2xpY2spXG4gICAgaWYgKHRoaXMuc2F2ZWRSYW5nZSkge1xuICAgICAgc2VsZWN0aW9uLnJlbW92ZUFsbFJhbmdlcygpO1xuICAgICAgc2VsZWN0aW9uLmFkZFJhbmdlKHRoaXMuc2F2ZWRSYW5nZSk7XG4gICAgfVxuICAgIGlmICghc2VsZWN0aW9uLnJhbmdlQ291bnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gRGVsZXRlIHRoZSBcIkBcIiBhbmQgc2VhcmNoIHRleHRcbiAgICB0aGlzLmRlbGV0ZUF0TWVudGlvblNlYXJjaCgpO1xuXG4gICAgLy9EQUhORSBOT1RFIC0gdGhpcyB3b3VsZCBpZGVhbGx5IGJlIHRoZSBzYW1lIGFzIGNvbnRlbnRJdGVtVG9IVE1MLCBidXQgd2UgbmVlZCBhbiBhY3R1YWwgZWxlbWVudCByZWZlcmVuY2UgaGVyZSBpbiBvcmRlciB0byBhcHBlbmQgaXQgdG8gdGhlIERPTVxuICAgIGNvbnN0IG1lbnRpb25TcGFuID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpO1xuICAgIG1lbnRpb25TcGFuLmNsYXNzTmFtZSA9IHRoaXMucmVhZG9ubHkgPyAncmVhZG9ubHktbWVudGlvbicgOiAnbWVudGlvbic7XG4gICAgbWVudGlvblNwYW4uc2V0QXR0cmlidXRlKCdkYXRhLWlkJywgU3RyaW5nKHVzZXIuaWQpKTtcbiAgICBtZW50aW9uU3Bhbi5zZXRBdHRyaWJ1dGUoJ2RhdGEtdHlwZScsICdtZW50aW9uJyk7XG4gICAgbWVudGlvblNwYW4uc2V0QXR0cmlidXRlKCdjb250ZW50ZWRpdGFibGUnLCAnZmFsc2UnKTtcbiAgICBtZW50aW9uU3Bhbi50ZXh0Q29udGVudCA9IGBAJHt1c2VyLm5hbWV9YDtcblxuICAgIHRoaXMuaW5zZXJ0Tm9kZXNBdEN1cnNvcihbbWVudGlvblNwYW4sIGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKCcgJyldKTtcbiAgICB0aGlzLm5vcm1hbGl6ZU1lbnRpb25QYWRkaW5nKCk7XG5cbiAgICB0aGlzLmNsb3NlTWVudGlvbnMoKTtcbiAgICB0aGlzLmVtaXRDb250ZW50Q2hhbmdlKCk7XG4gIH1cblxuICBwcml2YXRlIGRlbGV0ZUF0TWVudGlvblNlYXJjaCgpOiB2b2lkIHtcbiAgICBjb25zdCBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gICAgaWYgKCFzZWxlY3Rpb24gfHwgIXNlbGVjdGlvbi5yYW5nZUNvdW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vVGhpcyByZXByZXNlbnRzIHRoZSBjdXJyZW50IHBvc2l0aW9uIG9mIHRoZSBjdXJzb3JcbiAgICBjb25zdCBjdXJzb3JSYW5nZSA9IHNlbGVjdGlvbi5nZXRSYW5nZUF0KDApO1xuICAgIC8vVGhpcyB3aWxsIHJldHVybiBhbGwgb2YgdGhlIHJhdyB0ZXh0IChIVE1MLXN0cmlwcGVkKSBiZWZvcmUgdGhlIGN1cnNvclxuICAgIGNvbnN0IHRleHRCZWZvcmVDdXJzb3IgPSB0aGlzLmdldFRleHRCZWZvcmVDdXJzb3IoY3Vyc29yUmFuZ2UpO1xuICAgIC8vV2UgZG8gdGhhdF4gc28gdGhhdCB3ZSBjYW4gZmluZCB0aGUgY29ycmVjdCBpbmRleCBvZiB0aGUgbW9zdCByZWNlbnQgJ0AnXG4gICAgY29uc3QgbGFzdEF0SW5kZXggPSB0ZXh0QmVmb3JlQ3Vyc29yLmxhc3RJbmRleE9mKCdAJyk7XG5cbiAgICBpZiAobGFzdEF0SW5kZXggPT09IC0xKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGF0UG9zaXRpb24gPSB0aGlzLmZpbmREb21Qb3NpdGlvbkF0Q2hhckluZGV4KGxhc3RBdEluZGV4KTtcbiAgICBpZiAoIWF0UG9zaXRpb24pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gQ3JlYXRlIHJhbmdlIGZyb20gXCJAXCIgdG8gY3Vyc29yIGFuZCBkZWxldGUgaXRcbiAgICBjb25zdCBkZWxldGVSYW5nZSA9IGRvY3VtZW50LmNyZWF0ZVJhbmdlKCk7XG4gICAgZGVsZXRlUmFuZ2Uuc2V0U3RhcnQoYXRQb3NpdGlvbi5ub2RlLCBhdFBvc2l0aW9uLm9mZnNldCk7XG4gICAgZGVsZXRlUmFuZ2Uuc2V0RW5kKGN1cnNvclJhbmdlLmVuZENvbnRhaW5lciwgY3Vyc29yUmFuZ2UuZW5kT2Zmc2V0KTtcbiAgICBkZWxldGVSYW5nZS5kZWxldGVDb250ZW50cygpO1xuICB9XG5cbiAgcHJpdmF0ZSBpc0luc2lkZU1lbnRpb25TcGFuKG5vZGU6IE5vZGUpOiBib29sZWFuIHtcbiAgICBsZXQgY3VycmVudE5vZGU6IE5vZGUgfCBudWxsID0gbm9kZTtcbiAgICB3aGlsZSAoY3VycmVudE5vZGUgJiYgY3VycmVudE5vZGUgIT09IHRoaXMuaW5wdXRFbGVtZW50Py5uYXRpdmVFbGVtZW50KSB7XG4gICAgICBpZiAoTWVudGlvbnNJbnB1dENvbXBvbmVudC5pc01lbnRpb24oY3VycmVudE5vZGUpKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgICAgY3VycmVudE5vZGUgPSBjdXJyZW50Tm9kZS5wYXJlbnROb2RlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgLy9UaGlzIHdpbGwgZ28gdGV4dCBub2RlIGJ5IG5vZGUgbG9va2luZyBmb3IgdGhlXG4gIC8vQCBtZW50aW9uIGFuZCBnaXZlIGl0cyBwb3NpdGlvbiBpbiB0aGUgY29udGV4dCBvZiB0aGF0IG5vZGVcbiAgcHJpdmF0ZSBmaW5kRG9tUG9zaXRpb25BdENoYXJJbmRleChcbiAgICBjaGFySW5kZXg6IG51bWJlcixcbiAgKTogeyBub2RlOiBOb2RlOyBvZmZzZXQ6IG51bWJlciB9IHwgbnVsbCB7XG4gICAgaWYgKCF0aGlzLmlucHV0RWxlbWVudCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIC8vIFdhbGsgdGhyb3VnaCBhbGwgdGV4dCBub2RlcyBpbiB0aGUgaW5wdXQsIGNvdW50aW5nIGNoYXJhY3RlcnNcbiAgICBjb25zdCB0cmVlV2Fsa2VyID0gZG9jdW1lbnQuY3JlYXRlVHJlZVdhbGtlcihcbiAgICAgIHRoaXMuaW5wdXRFbGVtZW50Lm5hdGl2ZUVsZW1lbnQsXG4gICAgICBOb2RlRmlsdGVyLlNIT1dfVEVYVCxcbiAgICAgIG51bGwsXG4gICAgKTtcbiAgICBsZXQgY2hhckNvdW50ID0gMDtcbiAgICB3aGlsZSAodHJlZVdhbGtlci5uZXh0Tm9kZSgpKSB7XG4gICAgICBjb25zdCBub2RlID0gdHJlZVdhbGtlci5jdXJyZW50Tm9kZTtcbiAgICAgIGNvbnN0IHRleHQgPSBub2RlLnRleHRDb250ZW50IHx8ICcnO1xuICAgICAgLy8gQ2hlY2sgaWYgb3VyIHRhcmdldCBjaGFyYWN0ZXIgaXMgaW4gdGhpcyB0ZXh0IG5vZGVcbiAgICAgIGlmIChjaGFyQ291bnQgKyB0ZXh0Lmxlbmd0aCA+IGNoYXJJbmRleCkge1xuICAgICAgICByZXR1cm4geyBub2RlLCBvZmZzZXQ6IGNoYXJJbmRleCAtIGNoYXJDb3VudCB9O1xuICAgICAgfVxuICAgICAgY2hhckNvdW50ICs9IHRleHQubGVuZ3RoO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHByaXZhdGUgY2xvc2VNZW50aW9ucygpOiB2b2lkIHtcbiAgICB0aGlzLm1lbnRpb25zVmlzaWJsZSA9IGZhbHNlO1xuICAgIHRoaXMubWVudGlvblNlYXJjaFRleHQgPSAnJztcbiAgICB0aGlzLm1lbnRpb25BbmNob3IgPSBudWxsO1xuICAgIHRoaXMuc2VsZWN0ZWRVc2VySW5kZXggPSAwO1xuICAgIHRoaXMuc2F2ZWRSYW5nZSA9IG51bGw7XG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBwcml2YXRlIGVtaXRDb250ZW50Q2hhbmdlKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5pbnB1dEVsZW1lbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5jb250ZW50Q2hhbmdlLmVtaXQodGhpcy5kb21Ub0NvbnRlbnRJdGVtcygpKTtcbiAgfVxuXG4gIHByaXZhdGUgZG9tVG9Db250ZW50SXRlbXMoKTogTWVudGlvbnNJbnB1dENvbXBvbmVudC5Db250ZW50SXRlbVtdIHtcbiAgICBpZiAoIXRoaXMuaW5wdXRFbGVtZW50Py5uYXRpdmVFbGVtZW50KSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIGNvbnN0IGl0ZW1zOiBNZW50aW9uc0lucHV0Q29tcG9uZW50LkNvbnRlbnRJdGVtW10gPSBbXTtcbiAgICBjb25zdCBjaGlsZE5vZGVzID0gdGhpcy5pbnB1dEVsZW1lbnQubmF0aXZlRWxlbWVudC5jaGlsZE5vZGVzO1xuXG4gICAgZm9yIChjb25zdCBub2RlIG9mIEFycmF5LmZyb20oY2hpbGROb2RlcykpIHtcbiAgICAgIGlmIChub2RlLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERSkge1xuICAgICAgICBjb25zdCBlbGVtZW50ID0gbm9kZSBhcyBIVE1MRWxlbWVudDtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIGVsZW1lbnQudGFnTmFtZSA9PT0gJ1NQQU4nICYmXG4gICAgICAgICAgZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2RhdGEtdHlwZScpID09PSAnbWVudGlvbidcbiAgICAgICAgKSB7XG4gICAgICAgICAgY29uc3QgaWQgPSBOdW1iZXIoZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2RhdGEtaWQnKSk7XG4gICAgICAgICAgY29uc3QgbmFtZSA9IGVsZW1lbnQudGV4dENvbnRlbnQ/LnJlcGxhY2UoJ0AnLCAnJykgfHwgJyc7XG4gICAgICAgICAgaXRlbXMucHVzaCh7IHR5cGU6ICdtZW50aW9uJywgaWQsIG5hbWUgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAoZWxlbWVudC50YWdOYW1lID09PSAnQlInKSB7XG4gICAgICAgICAgaXRlbXMucHVzaCh7IHR5cGU6ICduZXdsaW5lJyB9KTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChub2RlLm5vZGVUeXBlID09PSBOb2RlLlRFWFRfTk9ERSkge1xuICAgICAgICAvLyBaV1MgcGFkcyBhcmUgYSBET00gYWZmb3JkYW5jZSDigJQgdGhleSBzaG91bGRuJ3QgbGVhayBpbnRvIHRoZSBkYXRhIG1vZGVsLlxuICAgICAgICBjb25zdCB0ZXh0ID0gKG5vZGUudGV4dENvbnRlbnQgfHwgJycpLnJlcGxhY2UoWldTX1JFR0VYLCAnJyk7XG4gICAgICAgIGlmICh0ZXh0KSB7XG4gICAgICAgICAgaXRlbXMucHVzaCh7IHR5cGU6ICd0ZXh0JywgdGV4dCB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gaXRlbXM7XG4gIH1cblxuICBvbkNhbGxvdXRDbG9zZSgpOiB2b2lkIHtcbiAgICB0aGlzLmNsb3NlTWVudGlvbnMoKTtcbiAgfVxufVxuXG5leHBvcnQgbmFtZXNwYWNlIE1lbnRpb25zSW5wdXRDb21wb25lbnQge1xuICBleHBvcnQgY29uc3QgQ29udGVudFR5cGVzID0gWydtZW50aW9uJywgJ3RleHQnLCAnbmV3bGluZSddIGFzIGNvbnN0O1xuICBleHBvcnQgdHlwZSBDb250ZW50VHlwZSA9XG4gICAgKHR5cGVvZiBNZW50aW9uc0lucHV0Q29tcG9uZW50LkNvbnRlbnRUeXBlcylbbnVtYmVyXTtcbiAgZXhwb3J0IGludGVyZmFjZSBVc2VyIHtcbiAgICBpZDogbnVtYmVyO1xuICAgIG5hbWU6IHN0cmluZztcbiAgfVxuICBleHBvcnQgdHlwZSBDb250ZW50PFQgZXh0ZW5kcyBDb250ZW50VHlwZT4gPSB7IHR5cGU6IFQgfTtcblxuICBleHBvcnQgdHlwZSBVc2VyTWVudGlvbiA9IENvbnRlbnQ8J21lbnRpb24nPiAmIFVzZXI7XG4gIGV4cG9ydCB0eXBlIFRleHQgPSBDb250ZW50PCd0ZXh0Jz4gJiB7IHRleHQ6IHN0cmluZyB9O1xuICBleHBvcnQgdHlwZSBOZXdsaW5lID0gQ29udGVudDwnbmV3bGluZSc+O1xuXG4gIGV4cG9ydCB0eXBlIENvbnRlbnRJdGVtID0gVXNlck1lbnRpb24gfCBUZXh0IHwgTmV3bGluZTtcblxuICBleHBvcnQgZnVuY3Rpb24gY29udGVudFRvUGxhaW5UZXh0KGNvbnRlbnQ6IENvbnRlbnRJdGVtW10pOiBzdHJpbmcge1xuICAgIHJldHVybiBjb250ZW50XG4gICAgICAubWFwKGl0ZW0gPT4ge1xuICAgICAgICBzd2l0Y2ggKGl0ZW0udHlwZSkge1xuICAgICAgICAgIGNhc2UgJ21lbnRpb24nOlxuICAgICAgICAgICAgcmV0dXJuIGBAJHtpdGVtLm5hbWV9YDtcbiAgICAgICAgICBjYXNlICd0ZXh0JzpcbiAgICAgICAgICAgIHJldHVybiBpdGVtLnRleHQ7XG4gICAgICAgICAgY2FzZSAnbmV3bGluZSc6XG4gICAgICAgICAgICByZXR1cm4gJ1xcbic7XG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgICAuam9pbignJyk7XG4gIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJtZW50aW9ucy1jb250YWluZXJcIiAjY29udGFpbmVyPlxuICA8ZGl2XG4gICAgKm5nSWY9XCIhcmVhZG9ubHlcIlxuICAgICNpbnB1dFxuICAgIGNsYXNzPVwidGV4dC1jb250ZW50IGVkaXRhYmxlXCJcbiAgICBjb250ZW50ZWRpdGFibGU9XCJ0cnVlXCJcbiAgICBbYXR0ci5kYXRhLXBsYWNlaG9sZGVyXT1cInBsYWNlaG9sZGVyXCJcbiAgICAoaW5wdXQpPVwib25JbnB1dCgpXCJcbiAgICAoa2V5ZG93bik9XCJvbktleURvd24oJGV2ZW50KVwiXG4gICAgKHBhc3RlKT1cIm9uUGFzdGUoJGV2ZW50KVwiXG4gICAgKGNvcHkpPVwib25Db3B5KCRldmVudClcIlxuICAgIChjdXQpPVwib25DdXQoJGV2ZW50KVwiXG4gID48L2Rpdj5cblxuICA8ZGl2ICpuZ0lmPVwicmVhZG9ubHlcIiAjaW5wdXQgY2xhc3M9XCJ0ZXh0LWNvbnRlbnRcIj48L2Rpdj5cblxuICA8cml2LWNhbGxvdXRcbiAgICAqbmdJZj1cIiFyZWFkb25seSAmJiBtZW50aW9uc1Zpc2libGUgJiYgbWVudGlvbkFuY2hvclwiXG4gICAgW2FuY2hvcl09XCJtZW50aW9uQW5jaG9yXCJcbiAgICBbaXNNb2RhbF09XCJ0cnVlXCJcbiAgICBbc2hvd0NhcmV0XT1cImZhbHNlXCJcbiAgICBbYWxsb3dlZFBvc2l0aW9uc109XCJbJ2JvdHRvbS1yaWdodCcsICd0b3AtcmlnaHQnXVwiXG4gICAgW3RoZW1lXT1cIidsaWdodCdcIlxuICAgIChjbG9zZSk9XCJvbkNhbGxvdXRDbG9zZSgpXCJcbiAgPlxuICAgIDxkaXYgY2xhc3M9XCJtZW50aW9ucy1jb250ZW50XCI+XG4gICAgICA8ZGl2IGNsYXNzPVwibWVudGlvbnMtaGVhZGVyXCI+TWVudGlvbiBzb21lb25lPC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwibWVudGlvbnMtbGlzdFwiPlxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgKm5nRm9yPVwibGV0IHVzZXIgb2YgZ2V0RmlsdGVyZWRVc2VycygpOyBsZXQgaSA9IGluZGV4XCJcbiAgICAgICAgICBbY2xhc3Muc2VsZWN0ZWRdPVwiaSA9PT0gc2VsZWN0ZWRVc2VySW5kZXhcIlxuICAgICAgICAgIChtb3VzZWVudGVyKT1cIm9uVXNlckhvdmVyKGkpXCJcbiAgICAgICAgICAoY2xpY2spPVwic2VsZWN0VXNlcih1c2VyKVwiXG4gICAgICAgID5cbiAgICAgICAgICB7eyB1c2VyLm5hbWUgfX1cbiAgICAgICAgPC9idXR0b24+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9yaXYtY2FsbG91dD5cbjwvZGl2PlxuIl19
|