@tylertech/forge-ai 0.10.1 → 0.11.0
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/custom-elements.json +5456 -3863
- package/dist/ai-chatbot/ai-chatbot-base.d.ts +92 -0
- package/dist/ai-chatbot/ai-chatbot-base.mjs +467 -0
- package/dist/ai-chatbot/ai-chatbot.d.ts +26 -75
- package/dist/ai-chatbot/ai-chatbot.mjs +51 -808
- package/dist/ai-chatbot/index.d.ts +3 -2
- package/dist/ai-chatbot/index.mjs +2 -0
- package/dist/ai-chatbot/message-state-controller.mjs +1 -1
- package/dist/ai-chatbot-launcher/ai-chatbot-launcher.d.ts +71 -0
- package/dist/ai-chatbot-launcher/ai-chatbot-launcher.mjs +288 -0
- package/dist/ai-chatbot-launcher/ai-chatbot-launcher.scss.mjs +4 -0
- package/dist/ai-chatbot-launcher/index.d.ts +1 -0
- package/dist/ai-chatbot-launcher/index.mjs +5 -0
- package/dist/ai-embedded-chat/ai-embedded-chat.mjs +1 -0
- package/dist/ai-message-thread/ai-message-thread.d.ts +2 -0
- package/dist/ai-message-thread/ai-message-thread.mjs +1 -1
- package/dist/ai-message-thread/ai-message-thread.scss.mjs +1 -1
- package/dist/ai-prompt/ai-prompt.scss.mjs +1 -1
- package/dist/core/chatbot-core-controller.d.ts +51 -0
- package/dist/core/chatbot-core-controller.mjs +400 -0
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.mjs +2 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +5 -0
- package/dist/tools/ai-data-table/ai-data-table-definition.mjs +1 -0
- package/package.json +24 -24
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const styles = '/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n.forge-card {\n --_card-background: var(--forge-card-background, var(--forge-theme-surface, #ffffff));\n --_card-height: var(--forge-card-height, 100%);\n --_card-width: var(--forge-card-width, 100%);\n --_card-outline-color: var(--forge-card-outline-color, var(--forge-theme-outline, #e0e0e0));\n --_card-outline-width: var(--forge-card-outline-width, var(--forge-border-thin, 1px));\n --_card-outline-style: var(--forge-card-outline-style, solid);\n --_card-elevation: var(--forge-card-elevation, none);\n --_card-padding: var(--forge-card-padding, var(--forge-spacing-medium, 16px));\n --_card-shape: var(--forge-card-shape, calc(var(--forge-shape-medium, 4px) * var(--forge-shape-factor, 1)));\n --_card-overflow: var(--forge-card-overflow, initial);\n --_card-raised-elevation: var(--forge-card-raised-elevation, 0px 2px 1px -1px rgba(0, 0, 0, 0.2), 0px 1px 1px 0px rgba(0, 0, 0, 0.14), 0px 1px 3px 0px rgba(0, 0, 0, 0.12));\n --_card-raised-outline-width: var(--forge-card-raised-outline-width, 0);\n --_card-height: var(--forge-card-height, auto);\n --_card-width: var(--forge-card-width, auto);\n}\n\n.forge-card {\n background: var(--_card-background);\n border-color: var(--_card-outline-color);\n border-width: var(--_card-outline-width);\n border-style: var(--_card-outline-style);\n border-radius: var(--_card-shape);\n box-shadow: var(--_card-elevation);\n box-sizing: border-box;\n padding: var(--_card-padding);\n overflow: var(--_card-overflow);\n height: var(--_card-height);\n width: var(--_card-width);\n -webkit-tap-highlight-color: transparent;\n}\n\n.forge-card--raised {\n --_card-elevation: var(--_card-raised-elevation);\n --_card-outline-width: var(--_card-raised-outline-width);\n}\n\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/* prettier-ignore */\n@keyframes float-in-label-animation {\n from {\n translate: 0;\n opacity: 40%;\n }\n to {\n translate: var(--_field-floating-label-translation);\n opacity: 100%;\n }\n}\n@keyframes float-out-label-animation {\n from {\n translate: var(--_field-floating-label-translation);\n opacity: 40%;\n }\n to {\n translate: 0;\n opacity: 100%;\n }\n}\n@keyframes multiline-inset-label-background-animation {\n from {\n opacity: 0%;\n }\n to {\n opacity: 100%;\n }\n}\n@layer base, textarea, density, invalid, disabled;\n@layer base {\n .forge-field {\n --_field-shape: var(--forge-field-shape, calc(var(--forge-shape-medium, 4px) * var(--forge-shape-factor, 1)));\n --_field-outline-style: var(--forge-field-outline-style, solid);\n --_field-outline-width: var(--forge-field-outline-width, var(--forge-border-thin, 1px));\n --_field-height: var(--forge-field-height, 40px);\n --_field-inset-height: var(--forge-field-inset-height, 48px);\n --_field-background: var(--forge-field-background, transparent);\n --_field-padding-inline: var(--forge-field-padding-inline, 12px);\n --_field-disabled-background: var(--forge-field-disabled-background, var(--forge-theme-surface-container-low, #ebebeb));\n --_field-disabled-opacity: var(--forge-field-disabled-opacity, 0.38);\n --_field-placeholder-color: var(--forge-field-placeholder-color, var(--forge-theme-text-medium, rgba(0, 0, 0, 0.6)));\n }\n .forge-field {\n position: relative;\n display: flex;\n align-items: center;\n gap: var(--forge-spacing-xsmall, 8px);\n box-shadow: var(--_field-elevation);\n padding-inline: var(--_field-padding-inline);\n border-radius: var(--_field-shape);\n outline-style: var(--_field-outline-style);\n outline-width: var(--_field-outline-width);\n outline-color: var(--forge-theme-outline-low, #9e9e9e);\n outline-offset: calc(var(--_field-outline-width) * -1);\n background: var(--_field-background);\n opacity: var(--_field-disableable-opacity);\n cursor: var(--_field-disableable-cursor);\n }\n .forge-field:hover:not(:has(:where(input, textarea, select, .forge-field__input):disabled)) {\n outline-color: var(--forge-theme-outline-high, #212121);\n }\n .forge-field :where(input, textarea, select, .forge-field__input) {\n box-sizing: border-box;\n margin: 0;\n outline: none;\n border: none;\n background-color: transparent;\n padding-block: 0;\n padding-inline: 0;\n inline-size: 100%;\n block-size: 100%;\n color: inherit;\n font: inherit;\n font-size: var(--_field-font-size);\n text-overflow: ellipsis;\n padding-block-start: 0;\n padding-block-end: 0;\n transition: padding-block var(--_field-floating-animation-duration) var(--_field-floating-animation-timing);\n display: flex;\n block-size: var(--_field-height);\n inline-size: 100%;\n overflow: hidden;\n color: var(--forge-theme-text-high, rgba(0, 0, 0, 0.87));\n background: transparent;\n appearance: none;\n }\n .forge-field :where(input, textarea, select, .forge-field__input)::placeholder {\n color: var(--_field-placeholder-color);\n }\n .forge-field--plain {\n --_field-multiline-inset-label-background: var(--forge-field-multiline-inset-label-background, var(--forge-theme-surface, #ffffff));\n --_field-multiline-inset-label-background-hover: var(--forge-field-multiline-inset-label-background-hover, var(--forge-theme-surface, #ffffff));\n --_field-outline-color: var(--forge-field-outline-color, transparent);\n --_field-outline-color-hover: var(--forge-field-outline-color-hover, transparent);\n --_field-inner-border-display: var(--forge-field-inner-border-display, none);\n --_field-padding-inline: var(--forge-field-padding-inline, 0);\n --_field-surface-display: var(--forge-field-surface-display, none);\n outline-width: 0;\n }\n .forge-field--tonal {\n --_field-outline-color: var(--forge-field-outline-color, transparent);\n --_field-outline-color-hover: var(--forge-field-outline-color-hover, transparent);\n --_field-inner-border-block-size: var(--forge-field-inner-border-block-size, calc(100% - 8px));\n --_field-background: var(--_field-tonal-background);\n --_field-multiline-inset-label-background: var(--forge-field-multiline-inset-label-background, var(--_field-background));\n --_field-hover-background: var(--forge-field-hover-background, tonal-background-hover);\n --_field-multiline-inset-label-background: var(--forge-field-multiline-inset-label-background, var(--_field-multiline-inset-label-tonal-background));\n outline-width: 0;\n background: var(--forge-theme-primary-container-low, #e8eaf6);\n }\n .forge-field--tonal:hover:not(:has(:where(input, textarea, select, .forge-field__input):disabled)) {\n background: var(--forge-theme-surface-container-minimum, #f5f5f5);\n }\n .forge-field--filled {\n --_field-background: var(--_field-filled-background);\n --_field-multiline-inset-label-background: var(--forge-field-multiline-inset-label-background, var(--_field-background));\n background: var(--forge-theme-surface-bright, #ffffff);\n }\n .forge-field--raised {\n --_field-elevation: var(--forge-field-elevation, 0px 2px 1px -1px rgba(0, 0, 0, 0.2), 0px 1px 1px 0px rgba(0, 0, 0, 0.14), 0px 1px 3px 0px rgba(0, 0, 0, 0.12));\n --_field-elevation-active: var(--forge-field-elevation-active, 0px 3px 3px -2px rgba(0, 0, 0, 0.2), 0px 3px 4px 0px rgba(0, 0, 0, 0.14), 0px 1px 8px 0px rgba(0, 0, 0, 0.12));\n --_field-outline-color: var(--forge-field-outline-color, transparent);\n --_field-outline-color-hover: var(--forge-field-outline-color-hover, transparent);\n --_field-inner-border-block-size: var(--forge-field-inner-border-block-size, calc(100% - 8px));\n --_field-background: var(--_field-filled-background);\n --_field-multiline-inset-label-background: var(--forge-field-multiline-inset-label-background, var(--_field-background));\n outline-width: 0;\n }\n .forge-field--raised:hover:not(:has(:where(input, textarea, select, .forge-field__input):disabled)) {\n box-shadow: var(--_field-elevation-active);\n }\n .forge-field--rounded {\n --_field-shape: var(--forge-field-shape, calc(var(--forge-shape-full, 9999px) * var(--forge-shape-factor, 1)));\n --_field-padding-inline: var(--forge-field-padding-inline, var(--_field-rounded-container-padding-inline-start));\n }\n .forge-field:has(label) {\n --_field-floating-label-translation: var(--forge-field-floating-label-translation, 0 calc(calc(calc(max(var(--forge-typography-body2-line-height, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-body-line-height-scale, 1.375))), var(--forge-typography-label2-line-height, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-label-line-height-scale, 1.25)))) / 2) + calc((var(--_field-height) - 56px) / 8)) * -1));\n display: grid;\n grid-template-columns: auto 1fr auto;\n gap: 0;\n block-size: var(--_field-height);\n --_field-height: var(--forge-field-height, 48px);\n }\n .forge-field:has(label) label {\n position: absolute;\n grid-column: 2;\n pointer-events: none;\n color: var(--forge-theme-text-medium, rgba(0, 0, 0, 0.6));\n }\n .forge-field:has(label).forge-field--rounded {\n padding-inline: var(--forge-spacing-large, 24px);\n }\n @keyframes forge-field-float-label-in {\n from {\n transform: translateY(15%);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n }\n .forge-field:has(label).forge-field--float-label-in label {\n animation: forge-field-float-label-in var(--forge-animation-duration-short4, 200ms) var(--forge-animation-easing-accelerate, cubic-bezier(0.3, 0, 1, 1)) forwards;\n }\n @keyframes forge-field-float-label-out {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n }\n .forge-field:has(label).forge-field--float-label-out label {\n animation: forge-field-float-label-out var(--forge-animation-duration-short4, 200ms) var(--forge-animation-easing-accelerate, cubic-bezier(0.3, 0, 1, 1)) forwards;\n }\n .forge-field:has(label).forge-field--float-label label, .forge-field:has(label):has(:where(:where(input, textarea, select, .forge-field__input):autofill, :where(input, textarea, select, .forge-field__input):placeholder-shown)) label {\n -moz-osx-font-smoothing: grayscale;\n -webkit-font-smoothing: antialiased;\n font-family: var(--forge-typography-label2-font-family, var(--forge-typography-font-family, "Roboto", sans-serif));\n font-size: var(--forge-typography-label2-font-size, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-label-font-size-scale, 0.8125)));\n font-weight: var(--forge-typography-label2-font-weight, 400);\n line-height: var(--forge-typography-label2-line-height, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-label-line-height-scale, 1.25)));\n letter-spacing: var(--forge-typography-label2-letter-spacing, 0.0096153846em);\n text-transform: var(--forge-typography-label2-text-transform, inherit);\n text-decoration: var(--forge-typography-label2-text-decoration, inherit);\n translate: var(--_field-floating-label-translation);\n }\n .forge-field:has(label).forge-field--float-label:not(.forge-field--extra-small) :where(input, textarea, select, .forge-field__input), .forge-field:has(label):has(:where(:where(input, textarea, select, .forge-field__input):autofill, :where(input, textarea, select, .forge-field__input):placeholder-shown)):not(.forge-field--extra-small) :where(input, textarea, select, .forge-field__input) {\n padding-block-start: calc((max(var(--forge-typography-body2-line-height, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-body-line-height-scale, 1.375))), var(--forge-typography-label2-line-height, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-label-line-height-scale, 1.25)))) / 2 + (var(--_field-height) - 56px) / 8) * 2) !important;\n }\n .forge-field:has(label) :where(input, textarea, select, .forge-field__input) {\n grid-column: 2;\n block-size: var(--_field-height);\n }\n .forge-field:has(label) :where(input, textarea, select, .forge-field__input) ~ * {\n grid-column: 3;\n margin-inline-start: var(--forge-spacing-xsmall, 8px);\n }\n .forge-field:has(label) > :not(:where(input, textarea, select, .forge-field__input) ~ *, :where(input, textarea, select, .forge-field__input), label) {\n grid-column: 1;\n margin-inline-end: var(--forge-spacing-xsmall, 8px);\n }\n @keyframes forge-focus-indicator-outward-grow {\n from {\n outline-width: 0;\n }\n to {\n outline-width: var(--_focus-indicator-active-width);\n }\n }\n @keyframes forge-focus-indicator-outward-shrink {\n from {\n outline-width: var(--_focus-indicator-active-width);\n }\n }\n @keyframes forge-focus-indicator-inward-grow {\n from {\n border-width: 0;\n }\n to {\n border-width: var(--_focus-indicator-active-width);\n }\n }\n @keyframes forge-focus-indicator-inward-shrink {\n from {\n border-width: var(--_focus-indicator-active-width);\n }\n }\n .forge-field:has(:where(input, textarea, select, .forge-field__input):focus) {\n outline: none;\n }\n .forge-field:has(:where(input, textarea, select, .forge-field__input):focus)::after {\n --_focus-indicator-display: var(--forge-focus-indicator-display, flex);\n --_focus-indicator-width: var(--forge-focus-indicator-width, var(--forge-border-medium, 2px));\n --_focus-indicator-active-width: var(--forge-focus-indicator-active-width, 6px);\n --_focus-indicator-color: var(--forge-focus-indicator-color, var(--forge-theme-primary, #3f51b5));\n --_focus-indicator-shape: var(--forge-focus-indicator-shape, calc(var(--forge-shape-extra-small, 1px) * var(--forge-shape-factor, 1)));\n --_focus-indicator-duration: var(--forge-focus-indicator-duration, var(--forge-animation-duration-long4, 600ms));\n --_focus-indicator-easing: var(--forge-focus-indicator-easing, var(--forge-animation-easing-emphasized, cubic-bezier(0.2, 0, 0, 1)));\n --_focus-indicator-shape-start-start: var(--forge-focus-indicator-shape-start-start, var(--_focus-indicator-shape));\n --_focus-indicator-shape-start-end: var(--forge-focus-indicator-shape-start-end, var(--_focus-indicator-shape));\n --_focus-indicator-shape-end-end: var(--forge-focus-indicator-shape-end-end, var(--_focus-indicator-shape));\n --_focus-indicator-shape-end-start: var(--forge-focus-indicator-shape-end-start, var(--_focus-indicator-shape));\n --_focus-indicator-outward-offset: var(--forge-focus-indicator-outward-offset, var(--forge-spacing-xxsmall, 4px));\n --_focus-indicator-inward-offset: var(--forge-focus-indicator-inward-offset, 0px);\n --_focus-indicator-offset-block: var(--forge-focus-indicator-offset-block, 0);\n --_focus-indicator-offset-inline: var(--forge-focus-indicator-offset-inline, 0);\n animation-delay: 0s, calc(var(--_focus-indicator-duration) * 0.25);\n animation-duration: calc(var(--_focus-indicator-duration) * 0.25), calc(var(--_focus-indicator-duration) * 0.75);\n animation-timing-function: var(--_focus-indicator-easing);\n box-sizing: border-box;\n color: var(--_focus-indicator-color);\n display: none;\n pointer-events: none;\n position: absolute;\n margin-block: var(--_focus-indicator-offset-block);\n margin-inline: var(--_focus-indicator-offset-inline);\n animation-name: forge-focus-indicator-outward-grow, forge-focus-indicator-outward-shrink;\n border-end-end-radius: calc(var(--_focus-indicator-shape-end-end) + var(--_focus-indicator-outward-offset));\n border-end-start-radius: calc(var(--_focus-indicator-shape-end-start) + var(--_focus-indicator-outward-offset));\n border-start-end-radius: calc(var(--_focus-indicator-shape-start-end) + var(--_focus-indicator-outward-offset));\n border-start-start-radius: calc(var(--_focus-indicator-shape-start-start) + var(--_focus-indicator-outward-offset));\n inset: calc(-1 * var(--_focus-indicator-outward-offset));\n outline: var(--_focus-indicator-width) solid currentColor;\n content: "";\n display: block;\n border-radius: inherit;\n }\n .forge-field:has(:where(input, textarea, select, .forge-field__input):focus) {\n --forge-focus-indicator-color: var(--forge-theme-primary, #3f51b5);\n --forge-focus-indicator-outward-offset: 0px;\n }\n}\n@layer textarea {\n .forge-field:has(textarea:only-child) {\n padding-inline: 0;\n }\n .forge-field:has(textarea:only-child) textarea {\n padding-inline: var(--_field-padding-inline);\n }\n .forge-field:has(textarea) {\n align-items: start;\n block-size: fit-content;\n }\n .forge-field:has(textarea) textarea {\n padding-block-start: calc((var(--_field-height) - var(--forge-typography-body2-line-height, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-body-line-height-scale, 1.375)))) / 2);\n padding-block-end: calc(max(var(--forge-typography-body2-line-height, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-body-line-height-scale, 1.375))), var(--forge-typography-label2-line-height, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-label-line-height-scale, 1.25)))) / 2 + (var(--_field-height) - 56px) / 8 + (var(--_field-height) - var(--forge-typography-body2-line-height, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-body-line-height-scale, 1.375)))) / 2);\n resize: vertical;\n block-size: fit-content;\n }\n .forge-field:has(textarea) *:not(textarea) {\n margin-block-start: var(--forge-spacing-xsmall, 8px);\n }\n}\n@layer density {\n .forge-field--dense, .forge-field--extra-small {\n --_field-height: var(--forge-field-height, 24px);\n --_field-padding-inline-start: var(--forge-field-padding-inline-start, 8px);\n --_field-padding-inline-end: var(--forge-field-padding-inline-end, 4px);\n }\n .forge-field--dense:has(label) label, .forge-field--extra-small:has(label) label {\n display: none;\n }\n .forge-field--small {\n --_field-height: var(--forge-field-height, 32px);\n }\n .forge-field--small:has(label) {\n --_field-height: var(--forge-field-height, 40px);\n }\n .forge-field--large {\n --_field-height: var(--forge-field-height, 48px);\n }\n .forge-field--large:has(label) {\n --_field-height: var(--forge-field-height, 56px);\n }\n .forge-field--extra-large {\n --_field-height: var(--forge-field-height, 56px);\n }\n .forge-field--extra-large:has(label) {\n --_field-height: var(--forge-field-height, 64px);\n }\n}\n@layer disabled {\n .forge-field:has(:where(input, textarea, select, .forge-field__input):disabled) {\n --_field-background: var(--_field-disabled-background);\n --_field-disableable-cursor: var(--forge-field-disableable-cursor, not-allowed);\n --_field-disableable-opacity: var(--forge-field-disableable-opacity, var(--_field-disabled-opacity));\n }\n .forge-field:has(:where(input, textarea, select, .forge-field__input):disabled) :where(input, textarea, select, .forge-field__input):disabled {\n cursor: not-allowed;\n }\n}\n@layer invalid {\n .forge-field--invalid, .forge-field:has(:where(input, textarea, select, .forge-field__input):invalid) {\n outline-color: var(--forge-theme-error, #b00020);\n }\n .forge-field--invalid :not(:where(input, textarea, select, .forge-field__input)), .forge-field:has(:where(input, textarea, select, .forge-field__input):invalid) :not(:where(input, textarea, select, .forge-field__input)) {\n color: var(--forge-theme-on-error-container, #5f0011);\n }\n .forge-field--invalid.forge-field:has(:where(input, textarea, select, .forge-field__input):focus), .forge-field:has(:where(input, textarea, select, .forge-field__input):invalid).forge-field:has(:where(input, textarea, select, .forge-field__input):focus) {\n --forge-focus-indicator-color: var(--forge-theme-error, #b00020);\n --forge-focus-indicator-outward-offset: calc(var(--_field-outline-width) * -1);\n }\n .forge-field--invalid label, .forge-field:has(:where(input, textarea, select, .forge-field__input):invalid) label {\n color: var(--forge-theme-error, #b00020);\n }\n .forge-field--invalid.forge-field--tonal, .forge-field:has(:where(input, textarea, select, .forge-field__input):invalid).forge-field--tonal {\n background: var(--forge-theme-error-container-low, #f6e0e4);\n }\n .forge-field--invalid.forge-field--tonal:hover:not(:has(:where(input, textarea, select, .forge-field__input):disabled)), .forge-field:has(:where(input, textarea, select, .forge-field__input):invalid).forge-field--tonal:hover:not(:has(:where(input, textarea, select, .forge-field__input):disabled)) {\n background: var(--forge-theme-error-container-minimum, #fcf5f6);\n }\n}\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n.forge-divider {\n --_divider-color: var(--forge-divider-color, var(--forge-theme-outline, #e0e0e0));\n --_divider-width: var(--forge-divider-width, var(--forge-border-thin, 1px));\n --_divider-border-style: var(--forge-divider-border-style, solid);\n --_divider-margin: var(--forge-divider-margin, 0);\n}\n\n.forge-divider {\n display: block;\n margin: var(--_divider-margin);\n border: none;\n border-bottom-color: var(--_divider-color);\n border-bottom-width: var(--_divider-width);\n border-bottom-style: var(--_divider-border-style);\n height: 0;\n}\n\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/* prettier-ignore */\n.forge-icon-button {\n --_icon-button-display: var(--forge-icon-button-display, inline-flex);\n --_icon-button-size: var(--forge-icon-button-size, 48px);\n --_icon-button-gap: var(--forge-icon-button-gap, 0);\n --_icon-button-icon-color: var(--forge-icon-button-icon-color, currentColor);\n --_icon-button-background-color: var(--forge-icon-button-background-color, none);\n --_icon-button-icon-size: var(--forge-icon-button-icon-size, calc(var(--forge-typography-font-size, 1rem) * 1.5));\n --_icon-button-cursor: var(--forge-icon-button-cursor, pointer);\n --_icon-button-padding: var(--forge-icon-button-padding, var(--forge-spacing-xxsmall, 4px));\n --_icon-button-border: var(--forge-icon-button-border, none);\n --_icon-button-shadow: var(--forge-icon-button-shadow, none);\n --_icon-button-transition-duration: var(--forge-icon-button-transition-duration, var(--forge-animation-duration-short3, 150ms));\n --_icon-button-transition-timing: var(--forge-icon-button-transition-timing, var(--forge-animation-easing-standard, cubic-bezier(0.2, 0, 0, 1)));\n --_icon-button-shape: var(--forge-icon-button-shape, calc(var(--forge-shape-full, 9999px) * var(--forge-shape-factor, 1)));\n --_icon-button-shape-start-start: var(--forge-icon-button-shape-start-start, var(--_icon-button-shape));\n --_icon-button-shape-start-end: var(--forge-icon-button-shape-start-end, var(--_icon-button-shape));\n --_icon-button-shape-end-start: var(--forge-icon-button-shape-end-start, var(--_icon-button-shape));\n --_icon-button-shape-end-end: var(--forge-icon-button-shape-end-end, var(--_icon-button-shape));\n --_icon-button-shape-squared: var(--forge-icon-button-shape-squared, calc(var(--forge-shape-medium, 4px) * var(--forge-shape-factor, 1)));\n --_icon-button-outlined-border-width: var(--forge-icon-button-outlined-border-width, 1px);\n --_icon-button-outlined-border-style: var(--forge-icon-button-outlined-border-style, solid);\n --_icon-button-outlined-border-color: var(--forge-icon-button-outlined-border-color, var(--_icon-button-icon-color));\n --_icon-button-tonal-icon-color: var(--forge-icon-button-tonal-icon-color, var(--forge-theme-on-primary-container, #222c62));\n --_icon-button-tonal-background-color: var(--forge-icon-button-tonal-background-color, var(--forge-theme-primary-container, #d1d5ed));\n --_icon-button-filled-icon-color: var(--forge-icon-button-filled-icon-color, var(--forge-theme-on-primary, #ffffff));\n --_icon-button-filled-background-color: var(--forge-icon-button-filled-background-color, var(--forge-theme-primary, #3f51b5));\n --_icon-button-raised-shadow: var(--forge-icon-button-raised-shadow, 0px 3px 1px -2px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 1px 5px 0px rgba(0, 0, 0, 0.12));\n --_icon-button-raised-hover-shadow: var(--forge-icon-button-raised-hover-shadow, 0px 2px 4px -1px rgba(0, 0, 0, 0.2), 0px 4px 5px 0px rgba(0, 0, 0, 0.14), 0px 1px 10px 0px rgba(0, 0, 0, 0.12));\n --_icon-button-raised-active-shadow: var(--forge-icon-button-raised-active-shadow, 0px 5px 5px -3px rgba(0, 0, 0, 0.2), 0px 8px 10px 1px rgba(0, 0, 0, 0.14), 0px 3px 14px 2px rgba(0, 0, 0, 0.12));\n --_icon-button-raised-disabled-shadow: var(--forge-icon-button-raised-disabled-shadow, none);\n --_icon-button-density-small-size: var(--forge-icon-button-density-small-size, 24px);\n --_icon-button-density-small-padding: var(--forge-icon-button-density-small-padding, var(--forge-spacing-xxxsmall, 2px));\n --_icon-button-density-small-icon-size: var(--forge-icon-button-density-small-icon-size, calc(var(--forge-typography-font-size, 1rem) * 1.125));\n --_icon-button-density-medium-size: var(--forge-icon-button-density-medium-size, 36px);\n --_icon-button-density-medium-padding: var(--forge-icon-button-density-medium-padding, var(--forge-spacing-xxsmall, 4px));\n --_icon-button-density-large-size: var(--forge-icon-button-density-large-size, var(--_icon-button-size));\n --_icon-button-toggle-on-background-color: var(--forge-icon-button-toggle-on-background-color, var(--forge-theme-primary-container, #d1d5ed));\n --_icon-button-toggle-on-icon-color: var(--forge-icon-button-toggle-on-icon-color, var(--forge-theme-primary, #3f51b5));\n --_icon-button-outlined-toggle-on-background-color: var(--forge-icon-button-outlined-toggle-on-background-color, var(--forge-theme-primary-container, #d1d5ed));\n --_icon-button-outlined-toggle-on-icon-color: var(--forge-icon-button-outlined-toggle-on-icon-color, var(--forge-theme-primary, #3f51b5));\n --_icon-button-tonal-toggle-background-color: var(--forge-icon-button-tonal-toggle-background-color, var(--forge-theme-surface-container-low, #ebebeb));\n --_icon-button-tonal-toggle-on-background-color: var(--forge-icon-button-tonal-toggle-on-background-color, var(--forge-theme-primary-container, #d1d5ed));\n --_icon-button-tonal-toggle-on-icon-color: var(--forge-icon-button-tonal-toggle-on-icon-color, var(--forge-theme-primary, #3f51b5));\n --_icon-button-filled-toggle-background-color: var(--forge-icon-button-filled-toggle-background-color, var(--forge-theme-surface-container-low, #ebebeb));\n --_icon-button-filled-toggle-icon-color: var(--forge-icon-button-filled-toggle-icon-color, var(--forge-theme-primary, #3f51b5));\n --_icon-button-filled-toggle-on-background-color: var(--forge-icon-button-filled-toggle-on-background-color, var(--forge-theme-primary, #3f51b5));\n --_icon-button-filled-toggle-on-icon-color: var(--forge-icon-button-filled-toggle-on-icon-color, var(--forge-theme-on-primary, #ffffff));\n --_icon-button-disabled-cursor: var(--forge-icon-button-disabled-cursor, not-allowed);\n --_icon-button-disabled-opacity: var(--forge-icon-button-disabled-opacity, 0.38);\n --_icon-button-popover-icon-padding: var(--forge-icon-button-popover-icon-padding, var(--forge-spacing-xsmall, 8px));\n --_icon-button-focus-indicator-color: var(--forge-icon-button-focus-indicator-color, var(--forge-theme-primary, #3f51b5));\n}\n\n.forge-icon-button {\n display: var(--_icon-button-display);\n position: relative;\n outline: none;\n -webkit-tap-highlight-color: transparent;\n position: relative;\n z-index: 0;\n display: var(--_icon-button-display);\n align-items: center;\n justify-content: center;\n gap: var(--_icon-button-gap);\n box-sizing: border-box;\n height: var(--_icon-button-density-large-size);\n min-width: var(--_icon-button-density-large-size);\n border: var(--_icon-button-border);\n border-start-start-radius: var(--_icon-button-shape-start-start);\n border-start-end-radius: var(--_icon-button-shape-start-end);\n border-end-start-radius: var(--_icon-button-shape-end-start);\n border-end-end-radius: var(--_icon-button-shape-end-end);\n padding: var(--_icon-button-padding);\n box-shadow: var(--_icon-button-shadow);\n color: var(--_icon-button-icon-color);\n background: var(--_icon-button-background-color);\n font-size: var(--_icon-button-icon-size);\n cursor: var(--_icon-button-cursor);\n user-select: none;\n transition-property: box-shadow, background;\n transition-duration: var(--_icon-button-transition-duration);\n transition-timing-function: var(--_icon-button-transition-timing);\n}\n\n.forge-icon-button img,\n.forge-icon-button svg {\n height: var(--_icon-button-icon-size);\n width: var(--_icon-button-icon-size);\n}\n\n.forge-icon-button svg {\n fill: currentColor;\n}\n\n.forge-icon-button:not(:disabled) {\n --_state-layer-display: var(--forge-state-layer-display, flex);\n --_state-layer-color: var(--forge-state-layer-color, var(--forge-theme-on-surface, #000000));\n --_state-layer-hover-color: var(--forge-state-layer-hover-color, var(--_state-layer-color));\n --_state-layer-hover-opacity: var(--forge-state-layer-hover-opacity, 0.08);\n --_state-layer-pressed-color: var(--forge-state-layer-pressed-color, var(--_state-layer-color));\n --_state-layer-pressed-opacity: var(--forge-state-layer-pressed-opacity, 0.12);\n --_state-layer-hover-duration: var(--forge-state-layer-hover-duration, 15ms);\n --_state-layer-pressed-duration: var(--forge-state-layer-pressed-duration, 105ms);\n --_state-layer-animation-duration: var(--forge-state-layer-animation-duration, 375ms);\n}\n\n.forge-icon-button:not(:disabled)::before {\n opacity: 0;\n position: absolute;\n backface-visibility: hidden;\n transform: translateZ(0);\n background-color: var(--_state-layer-hover-color);\n inset: 0;\n transition: opacity var(--_state-layer-hover-duration) linear, background-color var(--_state-layer-hover-duration) linear;\n --_state-layer-hover-duration: var(--forge-state-layer-hover-duration, 100ms);\n content: "";\n opacity: 0;\n border-radius: inherit;\n}\n\n.forge-icon-button:not(:disabled):hover::before {\n background-color: var(--_state-layer-hover-color);\n opacity: var(--_state-layer-hover-opacity);\n}\n\n.forge-icon-button:not(:disabled):active::before {\n opacity: var(--_state-layer-pressed-opacity);\n transition-duration: var(--_state-layer-pressed-duration);\n --_state-layer-pressed-opacity: var(--forge-state-layer-pressed-opacity, 0.18);\n}\n\n.forge-icon-button:not(:disabled) {\n --forge-state-layer-color: var(--_icon-button-icon-color);\n}\n\n@keyframes forge-focus-indicator-outward-grow {\n from {\n outline-width: 0;\n }\n to {\n outline-width: var(--_focus-indicator-active-width);\n }\n}\n@keyframes forge-focus-indicator-outward-shrink {\n from {\n outline-width: var(--_focus-indicator-active-width);\n }\n}\n@keyframes forge-focus-indicator-inward-grow {\n from {\n border-width: 0;\n }\n to {\n border-width: var(--_focus-indicator-active-width);\n }\n}\n@keyframes forge-focus-indicator-inward-shrink {\n from {\n border-width: var(--_focus-indicator-active-width);\n }\n}\n.forge-icon-button:not(:disabled) {\n outline: none;\n}\n\n.forge-icon-button:not(:disabled):focus-visible::after {\n --_focus-indicator-display: var(--forge-focus-indicator-display, flex);\n --_focus-indicator-width: var(--forge-focus-indicator-width, var(--forge-border-medium, 2px));\n --_focus-indicator-active-width: var(--forge-focus-indicator-active-width, 6px);\n --_focus-indicator-color: var(--forge-focus-indicator-color, var(--forge-theme-primary, #3f51b5));\n --_focus-indicator-shape: var(--forge-focus-indicator-shape, calc(var(--forge-shape-extra-small, 1px) * var(--forge-shape-factor, 1)));\n --_focus-indicator-duration: var(--forge-focus-indicator-duration, var(--forge-animation-duration-long4, 600ms));\n --_focus-indicator-easing: var(--forge-focus-indicator-easing, var(--forge-animation-easing-emphasized, cubic-bezier(0.2, 0, 0, 1)));\n --_focus-indicator-shape-start-start: var(--forge-focus-indicator-shape-start-start, var(--_focus-indicator-shape));\n --_focus-indicator-shape-start-end: var(--forge-focus-indicator-shape-start-end, var(--_focus-indicator-shape));\n --_focus-indicator-shape-end-end: var(--forge-focus-indicator-shape-end-end, var(--_focus-indicator-shape));\n --_focus-indicator-shape-end-start: var(--forge-focus-indicator-shape-end-start, var(--_focus-indicator-shape));\n --_focus-indicator-outward-offset: var(--forge-focus-indicator-outward-offset, var(--forge-spacing-xxsmall, 4px));\n --_focus-indicator-inward-offset: var(--forge-focus-indicator-inward-offset, 0px);\n --_focus-indicator-offset-block: var(--forge-focus-indicator-offset-block, 0);\n --_focus-indicator-offset-inline: var(--forge-focus-indicator-offset-inline, 0);\n}\n\n.forge-icon-button:not(:disabled):focus-visible::after {\n animation-delay: 0s, calc(var(--_focus-indicator-duration) * 0.25);\n animation-duration: calc(var(--_focus-indicator-duration) * 0.25), calc(var(--_focus-indicator-duration) * 0.75);\n animation-timing-function: var(--_focus-indicator-easing);\n box-sizing: border-box;\n color: var(--_focus-indicator-color);\n display: none;\n pointer-events: none;\n position: absolute;\n margin-block: var(--_focus-indicator-offset-block);\n margin-inline: var(--_focus-indicator-offset-inline);\n animation-name: forge-focus-indicator-outward-grow, forge-focus-indicator-outward-shrink;\n border-end-end-radius: calc(var(--_focus-indicator-shape-end-end) + var(--_focus-indicator-outward-offset));\n border-end-start-radius: calc(var(--_focus-indicator-shape-end-start) + var(--_focus-indicator-outward-offset));\n border-start-end-radius: calc(var(--_focus-indicator-shape-start-end) + var(--_focus-indicator-outward-offset));\n border-start-start-radius: calc(var(--_focus-indicator-shape-start-start) + var(--_focus-indicator-outward-offset));\n inset: calc(-1 * var(--_focus-indicator-outward-offset));\n outline: var(--_focus-indicator-width) solid currentColor;\n content: "";\n display: block;\n}\n\n.forge-icon-button:not(:disabled) {\n --forge-focus-indicator-color: var(--_icon-button-focus-indicator-color);\n --forge-focus-indicator-shape: var(--_icon-button-shape);\n}\n\n.forge-icon-button:not(:disabled):where(.forge-icon-button--text,\n:not(:where(.forge-icon-button--outlined, .forge-icon-button--tonal, .forge-icon-button--filled, .forge-icon-button--raised))) {\n --forge-focus-indicator-outward-offset: 0px;\n}\n\n.forge-icon-button--outlined {\n border-width: var(--_icon-button-outlined-border-width);\n border-style: var(--_icon-button-outlined-border-style);\n border-color: var(--_icon-button-outlined-border-color);\n}\n\n.forge-icon-button--tonal {\n --_icon-button-icon-color: var(--_icon-button-tonal-icon-color);\n --_icon-button-background-color: var(--_icon-button-tonal-background-color);\n}\n\n.forge-icon-button--filled, .forge-icon-button--raised {\n --_icon-button-icon-color: var(--_icon-button-filled-icon-color);\n --_icon-button-background-color: var(--_icon-button-filled-background-color);\n}\n\n.forge-icon-button--raised {\n --_icon-button-shadow: var(--_icon-button-raised-shadow);\n}\n\n.forge-icon-button--raised:hover {\n --_icon-button-raised-shadow: var(--_icon-button-raised-hover-shadow);\n}\n\n.forge-icon-button--raised:active {\n --_icon-button-raised-shadow: var(--_icon-button-raised-active-shadow);\n}\n\n.forge-icon-button--squared {\n --_icon-button-shape: var(--_icon-button-shape-squared);\n}\n\n.forge-icon-button--small {\n --_icon-button-size: var(--_icon-button-density-small-size);\n --_icon-button-icon-size: var(--_icon-button-density-small-icon-size);\n --_icon-button-padding: var(--_icon-button-density-small-padding);\n}\n\n.forge-icon-button--small > * {\n font-size: var(--_icon-button-density-small-icon-size);\n}\n\n.forge-icon-button--medium {\n --_icon-button-size: var(--_icon-button-density-medium-size);\n --_icon-button-padding: var(--_icon-button-density-medium-padding);\n}\n\n.forge-icon-button:disabled {\n pointer-events: none;\n opacity: var(--_icon-button-disabled-opacity);\n pointer-events: auto;\n cursor: not-allowed;\n}\n\n.forge-icon-button forge-circular-progress {\n --forge-circular-progress-indicator-color: var(--_icon-button-icon-color);\n --forge-circular-progress-track-color: transparent;\n --forge-circular-progress-size: 1em;\n}\n\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n:host {\n display: block;\n}\n\n.input-container .forge-card {\n --forge-card-padding: 0;\n --forge-card-shape: calc(var(--forge-shape-large, 8px) * var(--forge-shape-factor, 1));\n}\n.input-container .forge-field {\n --forge-theme-outline-low: transparent;\n --forge-field-height: auto;\n padding-inline-start: var(--forge-spacing-medium, 16px);\n min-height: 40px;\n align-items: center;\n}\n.input-container .forge-field:has(textarea) *:not(textarea) {\n margin-block-start: initial;\n}\n.input-container textarea {\n field-sizing: content;\n resize: none;\n max-height: 150px;\n overflow-y: auto;\n outline: none;\n padding: var(--forge-spacing-small, 12px) 0;\n}\n.input-container textarea::-webkit-scrollbar {\n height: var(--forge-scrollbar-height, 16px);\n width: var(--forge-scrollbar-width, 16px);\n}\n.input-container textarea::-webkit-scrollbar-track {\n background-color: var(--forge-scrollbar-track-container, var(--forge-theme-surface-container-low, #ebebeb));\n}\n.input-container textarea::-webkit-scrollbar-track:hover {\n background-color: var(--forge-scrollbar-track-container-hover, var(--forge-theme-surface-container-low, #ebebeb));\n}\n.input-container textarea::-webkit-scrollbar-corner {\n background-color: var(--forge-scrollbar-track-container, var(--forge-theme-surface-container-low, #ebebeb));\n}\n.input-container textarea::-webkit-scrollbar-thumb {\n height: var(--forge-scrollbar-thumb-min-height, 32px);\n width: var(--forge-scrollbar-thumb-min-width, 32px);\n border-radius: var(--forge-scrollbar-border-radius, calc(var(--forge-shape-full, 9999px) * var(--forge-shape-factor, 1)));\n border-width: var(--forge-scrollbar-border-width, 3px);\n border-style: solid;\n border-color: transparent;\n background-color: var(--forge-scrollbar-thumb-container, var(--forge-theme-surface-container-medium, #c2c2c2));\n background-clip: content-box;\n}\n.input-container textarea::-webkit-scrollbar-thumb:hover {\n background-color: var(--forge-scrollbar-thumb-container-hover, var(--forge-theme-surface-container-high, #9e9e9e));\n}\n.input-container .debug-button {\n color: var(--forge-theme-on-error-container-low, #5f0011);\n --forge-icon-button-focus-indicator-color: var(--forge-theme-error, #b00020);\n --forge-icon-button-tonal-background-color: var(--forge-theme-error-container-low, #f6e0e4);\n}\n\n.actions {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: var(--forge-spacing-xxsmall, 4px);\n padding-inline-start: var(--forge-spacing-xsmall, 8px);\n gap: var(--forge-spacing-xxsmall, 4px);\n overflow-x: auto;\n}\n\n.actions-start-container,\n.actions-end-container {\n display: flex;\n align-items: center;\n}\n\n.send-button {\n margin-inline-end: var(--forge-spacing-xsmall, 8px);\n}\n.send-button svg {\n height: 18px;\n width: 18px;\n}\n\n:host(:state(stacked)) .vertical-divider {\n display: none;\n}\n\n:host(:state(inline)) .forge-field {\n --forge-field-height: 52px;\n padding-inline: var(--forge-spacing-xxsmall, 4px);\n}\n:host(:state(inline)) .actions {\n display: flex;\n align-items: center;\n overflow-x: visible;\n padding: var(--forge-spacing-xxsmall, 4px);\n}\n:host(:state(inline)) ::slotted([slot=actions]) {\n display: flex;\n align-items: center;\n}\n:host(:state(inline)) .vertical-divider {\n width: 1px;\n height: 32px;\n background-color: var(--forge-theme-outline, #e0e0e0);\n margin-inline-end: var(--forge-spacing-xsmall, 8px);\n}\n:host(:state(inline)) .forge-divider {\n display: none;\n}\n:host(:state(inline)) .send-button {\n margin-inline-end: var(--forge-spacing-xxsmall, 4px);\n}';
|
|
1
|
+
const styles = '/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n.forge-card {\n --_card-background: var(--forge-card-background, var(--forge-theme-surface, #ffffff));\n --_card-height: var(--forge-card-height, 100%);\n --_card-width: var(--forge-card-width, 100%);\n --_card-outline-color: var(--forge-card-outline-color, var(--forge-theme-outline, #e0e0e0));\n --_card-outline-width: var(--forge-card-outline-width, var(--forge-border-thin, 1px));\n --_card-outline-style: var(--forge-card-outline-style, solid);\n --_card-elevation: var(--forge-card-elevation, none);\n --_card-padding: var(--forge-card-padding, var(--forge-spacing-medium, 16px));\n --_card-shape: var(--forge-card-shape, calc(var(--forge-shape-medium, 4px) * var(--forge-shape-factor, 1)));\n --_card-overflow: var(--forge-card-overflow, initial);\n --_card-raised-elevation: var(--forge-card-raised-elevation, 0px 2px 1px -1px rgba(0, 0, 0, 0.2), 0px 1px 1px 0px rgba(0, 0, 0, 0.14), 0px 1px 3px 0px rgba(0, 0, 0, 0.12));\n --_card-raised-outline-width: var(--forge-card-raised-outline-width, 0);\n --_card-height: var(--forge-card-height, auto);\n --_card-width: var(--forge-card-width, auto);\n}\n\n.forge-card {\n background: var(--_card-background);\n border-color: var(--_card-outline-color);\n border-width: var(--_card-outline-width);\n border-style: var(--_card-outline-style);\n border-radius: var(--_card-shape);\n box-shadow: var(--_card-elevation);\n box-sizing: border-box;\n padding: var(--_card-padding);\n overflow: var(--_card-overflow);\n height: var(--_card-height);\n width: var(--_card-width);\n -webkit-tap-highlight-color: transparent;\n}\n\n.forge-card--raised {\n --_card-elevation: var(--_card-raised-elevation);\n --_card-outline-width: var(--_card-raised-outline-width);\n}\n\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/* prettier-ignore */\n@keyframes float-in-label-animation {\n from {\n translate: 0;\n opacity: 40%;\n }\n to {\n translate: var(--_field-floating-label-translation);\n opacity: 100%;\n }\n}\n@keyframes float-out-label-animation {\n from {\n translate: var(--_field-floating-label-translation);\n opacity: 40%;\n }\n to {\n translate: 0;\n opacity: 100%;\n }\n}\n@keyframes multiline-inset-label-background-animation {\n from {\n opacity: 0%;\n }\n to {\n opacity: 100%;\n }\n}\n@layer base, textarea, density, invalid, disabled;\n@layer base {\n .forge-field {\n --_field-shape: var(--forge-field-shape, calc(var(--forge-shape-medium, 4px) * var(--forge-shape-factor, 1)));\n --_field-outline-style: var(--forge-field-outline-style, solid);\n --_field-outline-width: var(--forge-field-outline-width, var(--forge-border-thin, 1px));\n --_field-height: var(--forge-field-height, 40px);\n --_field-inset-height: var(--forge-field-inset-height, 48px);\n --_field-background: var(--forge-field-background, transparent);\n --_field-padding-inline: var(--forge-field-padding-inline, 12px);\n --_field-disabled-background: var(--forge-field-disabled-background, var(--forge-theme-surface-container-low, #ebebeb));\n --_field-disabled-opacity: var(--forge-field-disabled-opacity, 0.38);\n --_field-placeholder-color: var(--forge-field-placeholder-color, var(--forge-theme-text-medium, rgba(0, 0, 0, 0.6)));\n }\n .forge-field {\n position: relative;\n display: flex;\n align-items: center;\n gap: var(--forge-spacing-xsmall, 8px);\n box-shadow: var(--_field-elevation);\n padding-inline: var(--_field-padding-inline);\n border-radius: var(--_field-shape);\n outline-style: var(--_field-outline-style);\n outline-width: var(--_field-outline-width);\n outline-color: var(--forge-theme-outline-low, #9e9e9e);\n outline-offset: calc(var(--_field-outline-width) * -1);\n background: var(--_field-background);\n opacity: var(--_field-disableable-opacity);\n cursor: var(--_field-disableable-cursor);\n }\n .forge-field:hover:not(:has(:where(input, textarea, select, .forge-field__input):disabled)) {\n outline-color: var(--forge-theme-outline-high, #212121);\n }\n .forge-field :where(input, textarea, select, .forge-field__input) {\n box-sizing: border-box;\n margin: 0;\n outline: none;\n border: none;\n background-color: transparent;\n padding-block: 0;\n padding-inline: 0;\n inline-size: 100%;\n block-size: 100%;\n color: inherit;\n font: inherit;\n font-size: var(--_field-font-size);\n text-overflow: ellipsis;\n padding-block-start: 0;\n padding-block-end: 0;\n transition: padding-block var(--_field-floating-animation-duration) var(--_field-floating-animation-timing);\n display: flex;\n block-size: var(--_field-height);\n inline-size: 100%;\n overflow: hidden;\n color: var(--forge-theme-text-high, rgba(0, 0, 0, 0.87));\n background: transparent;\n appearance: none;\n }\n .forge-field :where(input, textarea, select, .forge-field__input)::placeholder {\n color: var(--_field-placeholder-color);\n }\n .forge-field--plain {\n --_field-multiline-inset-label-background: var(--forge-field-multiline-inset-label-background, var(--forge-theme-surface, #ffffff));\n --_field-multiline-inset-label-background-hover: var(--forge-field-multiline-inset-label-background-hover, var(--forge-theme-surface, #ffffff));\n --_field-outline-color: var(--forge-field-outline-color, transparent);\n --_field-outline-color-hover: var(--forge-field-outline-color-hover, transparent);\n --_field-inner-border-display: var(--forge-field-inner-border-display, none);\n --_field-padding-inline: var(--forge-field-padding-inline, 0);\n --_field-surface-display: var(--forge-field-surface-display, none);\n outline-width: 0;\n }\n .forge-field--tonal {\n --_field-outline-color: var(--forge-field-outline-color, transparent);\n --_field-outline-color-hover: var(--forge-field-outline-color-hover, transparent);\n --_field-inner-border-block-size: var(--forge-field-inner-border-block-size, calc(100% - 8px));\n --_field-background: var(--_field-tonal-background);\n --_field-multiline-inset-label-background: var(--forge-field-multiline-inset-label-background, var(--_field-background));\n --_field-hover-background: var(--forge-field-hover-background, tonal-background-hover);\n --_field-multiline-inset-label-background: var(--forge-field-multiline-inset-label-background, var(--_field-multiline-inset-label-tonal-background));\n outline-width: 0;\n background: var(--forge-theme-primary-container-low, #e8eaf6);\n }\n .forge-field--tonal:hover:not(:has(:where(input, textarea, select, .forge-field__input):disabled)) {\n background: var(--forge-theme-surface-container-minimum, #f5f5f5);\n }\n .forge-field--filled {\n --_field-background: var(--_field-filled-background);\n --_field-multiline-inset-label-background: var(--forge-field-multiline-inset-label-background, var(--_field-background));\n background: var(--forge-theme-surface-bright, #ffffff);\n }\n .forge-field--raised {\n --_field-elevation: var(--forge-field-elevation, 0px 2px 1px -1px rgba(0, 0, 0, 0.2), 0px 1px 1px 0px rgba(0, 0, 0, 0.14), 0px 1px 3px 0px rgba(0, 0, 0, 0.12));\n --_field-elevation-active: var(--forge-field-elevation-active, 0px 3px 3px -2px rgba(0, 0, 0, 0.2), 0px 3px 4px 0px rgba(0, 0, 0, 0.14), 0px 1px 8px 0px rgba(0, 0, 0, 0.12));\n --_field-outline-color: var(--forge-field-outline-color, transparent);\n --_field-outline-color-hover: var(--forge-field-outline-color-hover, transparent);\n --_field-inner-border-block-size: var(--forge-field-inner-border-block-size, calc(100% - 8px));\n --_field-background: var(--_field-filled-background);\n --_field-multiline-inset-label-background: var(--forge-field-multiline-inset-label-background, var(--_field-background));\n outline-width: 0;\n }\n .forge-field--raised:hover:not(:has(:where(input, textarea, select, .forge-field__input):disabled)) {\n box-shadow: var(--_field-elevation-active);\n }\n .forge-field--rounded {\n --_field-shape: var(--forge-field-shape, calc(var(--forge-shape-full, 9999px) * var(--forge-shape-factor, 1)));\n --_field-padding-inline: var(--forge-field-padding-inline, var(--_field-rounded-container-padding-inline-start));\n }\n .forge-field:has(label) {\n --_field-floating-label-translation: var(--forge-field-floating-label-translation, 0 calc(calc(calc(max(var(--forge-typography-body2-line-height, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-body-line-height-scale, 1.375))), var(--forge-typography-label2-line-height, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-label-line-height-scale, 1.25)))) / 2) + calc((var(--_field-height) - 56px) / 8)) * -1));\n display: grid;\n grid-template-columns: auto 1fr auto;\n gap: 0;\n block-size: var(--_field-height);\n --_field-height: var(--forge-field-height, 48px);\n }\n .forge-field:has(label) label {\n position: absolute;\n grid-column: 2;\n pointer-events: none;\n color: var(--forge-theme-text-medium, rgba(0, 0, 0, 0.6));\n }\n .forge-field:has(label).forge-field--rounded {\n padding-inline: var(--forge-spacing-large, 24px);\n }\n @keyframes forge-field-float-label-in {\n from {\n transform: translateY(15%);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n }\n .forge-field:has(label).forge-field--float-label-in label {\n animation: forge-field-float-label-in var(--forge-animation-duration-short4, 200ms) var(--forge-animation-easing-accelerate, cubic-bezier(0.3, 0, 1, 1)) forwards;\n }\n @keyframes forge-field-float-label-out {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n }\n .forge-field:has(label).forge-field--float-label-out label {\n animation: forge-field-float-label-out var(--forge-animation-duration-short4, 200ms) var(--forge-animation-easing-accelerate, cubic-bezier(0.3, 0, 1, 1)) forwards;\n }\n .forge-field:has(label).forge-field--float-label label, .forge-field:has(label):has(:where(:where(input, textarea, select, .forge-field__input):autofill, :where(input, textarea, select, .forge-field__input):placeholder-shown)) label {\n -moz-osx-font-smoothing: grayscale;\n -webkit-font-smoothing: antialiased;\n font-family: var(--forge-typography-label2-font-family, var(--forge-typography-font-family, "Roboto", sans-serif));\n font-size: var(--forge-typography-label2-font-size, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-label-font-size-scale, 0.8125)));\n font-weight: var(--forge-typography-label2-font-weight, 400);\n line-height: var(--forge-typography-label2-line-height, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-label-line-height-scale, 1.25)));\n letter-spacing: var(--forge-typography-label2-letter-spacing, 0.0096153846em);\n text-transform: var(--forge-typography-label2-text-transform, inherit);\n text-decoration: var(--forge-typography-label2-text-decoration, inherit);\n translate: var(--_field-floating-label-translation);\n }\n .forge-field:has(label).forge-field--float-label:not(.forge-field--extra-small) :where(input, textarea, select, .forge-field__input), .forge-field:has(label):has(:where(:where(input, textarea, select, .forge-field__input):autofill, :where(input, textarea, select, .forge-field__input):placeholder-shown)):not(.forge-field--extra-small) :where(input, textarea, select, .forge-field__input) {\n padding-block-start: calc((max(var(--forge-typography-body2-line-height, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-body-line-height-scale, 1.375))), var(--forge-typography-label2-line-height, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-label-line-height-scale, 1.25)))) / 2 + (var(--_field-height) - 56px) / 8) * 2) !important;\n }\n .forge-field:has(label) :where(input, textarea, select, .forge-field__input) {\n grid-column: 2;\n block-size: var(--_field-height);\n }\n .forge-field:has(label) :where(input, textarea, select, .forge-field__input) ~ * {\n grid-column: 3;\n margin-inline-start: var(--forge-spacing-xsmall, 8px);\n }\n .forge-field:has(label) > :not(:where(input, textarea, select, .forge-field__input) ~ *, :where(input, textarea, select, .forge-field__input), label) {\n grid-column: 1;\n margin-inline-end: var(--forge-spacing-xsmall, 8px);\n }\n @keyframes forge-focus-indicator-outward-grow {\n from {\n outline-width: 0;\n }\n to {\n outline-width: var(--_focus-indicator-active-width);\n }\n }\n @keyframes forge-focus-indicator-outward-shrink {\n from {\n outline-width: var(--_focus-indicator-active-width);\n }\n }\n @keyframes forge-focus-indicator-inward-grow {\n from {\n border-width: 0;\n }\n to {\n border-width: var(--_focus-indicator-active-width);\n }\n }\n @keyframes forge-focus-indicator-inward-shrink {\n from {\n border-width: var(--_focus-indicator-active-width);\n }\n }\n .forge-field:has(:where(input, textarea, select, .forge-field__input):focus) {\n outline: none;\n }\n .forge-field:has(:where(input, textarea, select, .forge-field__input):focus)::after {\n --_focus-indicator-display: var(--forge-focus-indicator-display, flex);\n --_focus-indicator-width: var(--forge-focus-indicator-width, var(--forge-border-medium, 2px));\n --_focus-indicator-active-width: var(--forge-focus-indicator-active-width, 6px);\n --_focus-indicator-color: var(--forge-focus-indicator-color, var(--forge-theme-primary, #3f51b5));\n --_focus-indicator-shape: var(--forge-focus-indicator-shape, calc(var(--forge-shape-extra-small, 1px) * var(--forge-shape-factor, 1)));\n --_focus-indicator-duration: var(--forge-focus-indicator-duration, var(--forge-animation-duration-long4, 600ms));\n --_focus-indicator-easing: var(--forge-focus-indicator-easing, var(--forge-animation-easing-emphasized, cubic-bezier(0.2, 0, 0, 1)));\n --_focus-indicator-shape-start-start: var(--forge-focus-indicator-shape-start-start, var(--_focus-indicator-shape));\n --_focus-indicator-shape-start-end: var(--forge-focus-indicator-shape-start-end, var(--_focus-indicator-shape));\n --_focus-indicator-shape-end-end: var(--forge-focus-indicator-shape-end-end, var(--_focus-indicator-shape));\n --_focus-indicator-shape-end-start: var(--forge-focus-indicator-shape-end-start, var(--_focus-indicator-shape));\n --_focus-indicator-outward-offset: var(--forge-focus-indicator-outward-offset, var(--forge-spacing-xxsmall, 4px));\n --_focus-indicator-inward-offset: var(--forge-focus-indicator-inward-offset, 0px);\n --_focus-indicator-offset-block: var(--forge-focus-indicator-offset-block, 0);\n --_focus-indicator-offset-inline: var(--forge-focus-indicator-offset-inline, 0);\n animation-delay: 0s, calc(var(--_focus-indicator-duration) * 0.25);\n animation-duration: calc(var(--_focus-indicator-duration) * 0.25), calc(var(--_focus-indicator-duration) * 0.75);\n animation-timing-function: var(--_focus-indicator-easing);\n box-sizing: border-box;\n color: var(--_focus-indicator-color);\n display: none;\n pointer-events: none;\n position: absolute;\n margin-block: var(--_focus-indicator-offset-block);\n margin-inline: var(--_focus-indicator-offset-inline);\n animation-name: forge-focus-indicator-outward-grow, forge-focus-indicator-outward-shrink;\n border-end-end-radius: calc(var(--_focus-indicator-shape-end-end) + var(--_focus-indicator-outward-offset));\n border-end-start-radius: calc(var(--_focus-indicator-shape-end-start) + var(--_focus-indicator-outward-offset));\n border-start-end-radius: calc(var(--_focus-indicator-shape-start-end) + var(--_focus-indicator-outward-offset));\n border-start-start-radius: calc(var(--_focus-indicator-shape-start-start) + var(--_focus-indicator-outward-offset));\n inset: calc(-1 * var(--_focus-indicator-outward-offset));\n outline: var(--_focus-indicator-width) solid currentColor;\n content: "";\n display: block;\n border-radius: inherit;\n }\n .forge-field:has(:where(input, textarea, select, .forge-field__input):focus) {\n --forge-focus-indicator-color: var(--forge-theme-primary, #3f51b5);\n --forge-focus-indicator-outward-offset: 0px;\n }\n}\n@layer textarea {\n .forge-field:has(textarea:only-child) {\n padding-inline: 0;\n }\n .forge-field:has(textarea:only-child) textarea {\n padding-inline: var(--_field-padding-inline);\n }\n .forge-field:has(textarea) {\n align-items: start;\n block-size: fit-content;\n }\n .forge-field:has(textarea) textarea {\n padding-block-start: calc((var(--_field-height) - var(--forge-typography-body2-line-height, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-body-line-height-scale, 1.375)))) / 2);\n padding-block-end: calc(max(var(--forge-typography-body2-line-height, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-body-line-height-scale, 1.375))), var(--forge-typography-label2-line-height, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-label-line-height-scale, 1.25)))) / 2 + (var(--_field-height) - 56px) / 8 + (var(--_field-height) - var(--forge-typography-body2-line-height, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-body-line-height-scale, 1.375)))) / 2);\n resize: vertical;\n block-size: fit-content;\n }\n .forge-field:has(textarea) *:not(textarea) {\n margin-block-start: var(--forge-spacing-xsmall, 8px);\n }\n}\n@layer density {\n .forge-field--dense, .forge-field--extra-small {\n --_field-height: var(--forge-field-height, 24px);\n --_field-padding-inline-start: var(--forge-field-padding-inline-start, 8px);\n --_field-padding-inline-end: var(--forge-field-padding-inline-end, 4px);\n }\n .forge-field--dense:has(label) label, .forge-field--extra-small:has(label) label {\n display: none;\n }\n .forge-field--small {\n --_field-height: var(--forge-field-height, 32px);\n }\n .forge-field--small:has(label) {\n --_field-height: var(--forge-field-height, 40px);\n }\n .forge-field--large {\n --_field-height: var(--forge-field-height, 48px);\n }\n .forge-field--large:has(label) {\n --_field-height: var(--forge-field-height, 56px);\n }\n .forge-field--extra-large {\n --_field-height: var(--forge-field-height, 56px);\n }\n .forge-field--extra-large:has(label) {\n --_field-height: var(--forge-field-height, 64px);\n }\n}\n@layer disabled {\n .forge-field:has(:where(input, textarea, select, .forge-field__input):disabled) {\n --_field-background: var(--_field-disabled-background);\n --_field-disableable-cursor: var(--forge-field-disableable-cursor, not-allowed);\n --_field-disableable-opacity: var(--forge-field-disableable-opacity, var(--_field-disabled-opacity));\n }\n .forge-field:has(:where(input, textarea, select, .forge-field__input):disabled) :where(input, textarea, select, .forge-field__input):disabled {\n cursor: not-allowed;\n }\n}\n@layer invalid {\n .forge-field--invalid, .forge-field:has(:where(input, textarea, select, .forge-field__input):invalid) {\n outline-color: var(--forge-theme-error, #b00020);\n }\n .forge-field--invalid :not(:where(input, textarea, select, .forge-field__input)), .forge-field:has(:where(input, textarea, select, .forge-field__input):invalid) :not(:where(input, textarea, select, .forge-field__input)) {\n color: var(--forge-theme-on-error-container, #5f0011);\n }\n .forge-field--invalid.forge-field:has(:where(input, textarea, select, .forge-field__input):focus), .forge-field:has(:where(input, textarea, select, .forge-field__input):invalid).forge-field:has(:where(input, textarea, select, .forge-field__input):focus) {\n --forge-focus-indicator-color: var(--forge-theme-error, #b00020);\n --forge-focus-indicator-outward-offset: calc(var(--_field-outline-width) * -1);\n }\n .forge-field--invalid label, .forge-field:has(:where(input, textarea, select, .forge-field__input):invalid) label {\n color: var(--forge-theme-error, #b00020);\n }\n .forge-field--invalid.forge-field--tonal, .forge-field:has(:where(input, textarea, select, .forge-field__input):invalid).forge-field--tonal {\n background: var(--forge-theme-error-container-low, #f6e0e4);\n }\n .forge-field--invalid.forge-field--tonal:hover:not(:has(:where(input, textarea, select, .forge-field__input):disabled)), .forge-field:has(:where(input, textarea, select, .forge-field__input):invalid).forge-field--tonal:hover:not(:has(:where(input, textarea, select, .forge-field__input):disabled)) {\n background: var(--forge-theme-error-container-minimum, #fcf5f6);\n }\n}\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n.forge-divider {\n --_divider-color: var(--forge-divider-color, var(--forge-theme-outline, #e0e0e0));\n --_divider-width: var(--forge-divider-width, var(--forge-border-thin, 1px));\n --_divider-border-style: var(--forge-divider-border-style, solid);\n --_divider-margin: var(--forge-divider-margin, 0);\n}\n\n.forge-divider {\n display: block;\n margin: var(--_divider-margin);\n border: none;\n border-bottom-color: var(--_divider-color);\n border-bottom-width: var(--_divider-width);\n border-bottom-style: var(--_divider-border-style);\n height: 0;\n}\n\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/* prettier-ignore */\n.forge-icon-button {\n --_icon-button-display: var(--forge-icon-button-display, inline-flex);\n --_icon-button-size: var(--forge-icon-button-size, 48px);\n --_icon-button-gap: var(--forge-icon-button-gap, 0);\n --_icon-button-icon-color: var(--forge-icon-button-icon-color, currentColor);\n --_icon-button-background-color: var(--forge-icon-button-background-color, none);\n --_icon-button-icon-size: var(--forge-icon-button-icon-size, calc(var(--forge-typography-font-size, 1rem) * 1.5));\n --_icon-button-cursor: var(--forge-icon-button-cursor, pointer);\n --_icon-button-padding: var(--forge-icon-button-padding, var(--forge-spacing-xxsmall, 4px));\n --_icon-button-border: var(--forge-icon-button-border, none);\n --_icon-button-shadow: var(--forge-icon-button-shadow, none);\n --_icon-button-transition-duration: var(--forge-icon-button-transition-duration, var(--forge-animation-duration-short3, 150ms));\n --_icon-button-transition-timing: var(--forge-icon-button-transition-timing, var(--forge-animation-easing-standard, cubic-bezier(0.2, 0, 0, 1)));\n --_icon-button-shape: var(--forge-icon-button-shape, calc(var(--forge-shape-full, 9999px) * var(--forge-shape-factor, 1)));\n --_icon-button-shape-start-start: var(--forge-icon-button-shape-start-start, var(--_icon-button-shape));\n --_icon-button-shape-start-end: var(--forge-icon-button-shape-start-end, var(--_icon-button-shape));\n --_icon-button-shape-end-start: var(--forge-icon-button-shape-end-start, var(--_icon-button-shape));\n --_icon-button-shape-end-end: var(--forge-icon-button-shape-end-end, var(--_icon-button-shape));\n --_icon-button-shape-squared: var(--forge-icon-button-shape-squared, calc(var(--forge-shape-medium, 4px) * var(--forge-shape-factor, 1)));\n --_icon-button-outlined-border-width: var(--forge-icon-button-outlined-border-width, 1px);\n --_icon-button-outlined-border-style: var(--forge-icon-button-outlined-border-style, solid);\n --_icon-button-outlined-border-color: var(--forge-icon-button-outlined-border-color, var(--_icon-button-icon-color));\n --_icon-button-tonal-icon-color: var(--forge-icon-button-tonal-icon-color, var(--forge-theme-on-primary-container, #222c62));\n --_icon-button-tonal-background-color: var(--forge-icon-button-tonal-background-color, var(--forge-theme-primary-container, #d1d5ed));\n --_icon-button-filled-icon-color: var(--forge-icon-button-filled-icon-color, var(--forge-theme-on-primary, #ffffff));\n --_icon-button-filled-background-color: var(--forge-icon-button-filled-background-color, var(--forge-theme-primary, #3f51b5));\n --_icon-button-raised-shadow: var(--forge-icon-button-raised-shadow, 0px 3px 1px -2px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 1px 5px 0px rgba(0, 0, 0, 0.12));\n --_icon-button-raised-hover-shadow: var(--forge-icon-button-raised-hover-shadow, 0px 2px 4px -1px rgba(0, 0, 0, 0.2), 0px 4px 5px 0px rgba(0, 0, 0, 0.14), 0px 1px 10px 0px rgba(0, 0, 0, 0.12));\n --_icon-button-raised-active-shadow: var(--forge-icon-button-raised-active-shadow, 0px 5px 5px -3px rgba(0, 0, 0, 0.2), 0px 8px 10px 1px rgba(0, 0, 0, 0.14), 0px 3px 14px 2px rgba(0, 0, 0, 0.12));\n --_icon-button-raised-disabled-shadow: var(--forge-icon-button-raised-disabled-shadow, none);\n --_icon-button-density-small-size: var(--forge-icon-button-density-small-size, 24px);\n --_icon-button-density-small-padding: var(--forge-icon-button-density-small-padding, var(--forge-spacing-xxxsmall, 2px));\n --_icon-button-density-small-icon-size: var(--forge-icon-button-density-small-icon-size, calc(var(--forge-typography-font-size, 1rem) * 1.125));\n --_icon-button-density-medium-size: var(--forge-icon-button-density-medium-size, 36px);\n --_icon-button-density-medium-padding: var(--forge-icon-button-density-medium-padding, var(--forge-spacing-xxsmall, 4px));\n --_icon-button-density-large-size: var(--forge-icon-button-density-large-size, var(--_icon-button-size));\n --_icon-button-toggle-on-background-color: var(--forge-icon-button-toggle-on-background-color, var(--forge-theme-primary-container, #d1d5ed));\n --_icon-button-toggle-on-icon-color: var(--forge-icon-button-toggle-on-icon-color, var(--forge-theme-primary, #3f51b5));\n --_icon-button-outlined-toggle-on-background-color: var(--forge-icon-button-outlined-toggle-on-background-color, var(--forge-theme-primary-container, #d1d5ed));\n --_icon-button-outlined-toggle-on-icon-color: var(--forge-icon-button-outlined-toggle-on-icon-color, var(--forge-theme-primary, #3f51b5));\n --_icon-button-tonal-toggle-background-color: var(--forge-icon-button-tonal-toggle-background-color, var(--forge-theme-surface-container-low, #ebebeb));\n --_icon-button-tonal-toggle-on-background-color: var(--forge-icon-button-tonal-toggle-on-background-color, var(--forge-theme-primary-container, #d1d5ed));\n --_icon-button-tonal-toggle-on-icon-color: var(--forge-icon-button-tonal-toggle-on-icon-color, var(--forge-theme-primary, #3f51b5));\n --_icon-button-filled-toggle-background-color: var(--forge-icon-button-filled-toggle-background-color, var(--forge-theme-surface-container-low, #ebebeb));\n --_icon-button-filled-toggle-icon-color: var(--forge-icon-button-filled-toggle-icon-color, var(--forge-theme-primary, #3f51b5));\n --_icon-button-filled-toggle-on-background-color: var(--forge-icon-button-filled-toggle-on-background-color, var(--forge-theme-primary, #3f51b5));\n --_icon-button-filled-toggle-on-icon-color: var(--forge-icon-button-filled-toggle-on-icon-color, var(--forge-theme-on-primary, #ffffff));\n --_icon-button-disabled-cursor: var(--forge-icon-button-disabled-cursor, not-allowed);\n --_icon-button-disabled-opacity: var(--forge-icon-button-disabled-opacity, 0.38);\n --_icon-button-popover-icon-padding: var(--forge-icon-button-popover-icon-padding, var(--forge-spacing-xsmall, 8px));\n --_icon-button-focus-indicator-color: var(--forge-icon-button-focus-indicator-color, var(--forge-theme-primary, #3f51b5));\n}\n\n.forge-icon-button {\n display: var(--_icon-button-display);\n position: relative;\n outline: none;\n -webkit-tap-highlight-color: transparent;\n position: relative;\n z-index: 0;\n display: var(--_icon-button-display);\n align-items: center;\n justify-content: center;\n gap: var(--_icon-button-gap);\n box-sizing: border-box;\n height: var(--_icon-button-density-large-size);\n min-width: var(--_icon-button-density-large-size);\n border: var(--_icon-button-border);\n border-start-start-radius: var(--_icon-button-shape-start-start);\n border-start-end-radius: var(--_icon-button-shape-start-end);\n border-end-start-radius: var(--_icon-button-shape-end-start);\n border-end-end-radius: var(--_icon-button-shape-end-end);\n padding: var(--_icon-button-padding);\n box-shadow: var(--_icon-button-shadow);\n color: var(--_icon-button-icon-color);\n background: var(--_icon-button-background-color);\n font-size: var(--_icon-button-icon-size);\n cursor: var(--_icon-button-cursor);\n user-select: none;\n transition-property: box-shadow, background;\n transition-duration: var(--_icon-button-transition-duration);\n transition-timing-function: var(--_icon-button-transition-timing);\n}\n\n.forge-icon-button img,\n.forge-icon-button svg {\n height: var(--_icon-button-icon-size);\n width: var(--_icon-button-icon-size);\n}\n\n.forge-icon-button svg {\n fill: currentColor;\n}\n\n.forge-icon-button:not(:disabled) {\n --_state-layer-display: var(--forge-state-layer-display, flex);\n --_state-layer-color: var(--forge-state-layer-color, var(--forge-theme-on-surface, #000000));\n --_state-layer-hover-color: var(--forge-state-layer-hover-color, var(--_state-layer-color));\n --_state-layer-hover-opacity: var(--forge-state-layer-hover-opacity, 0.08);\n --_state-layer-pressed-color: var(--forge-state-layer-pressed-color, var(--_state-layer-color));\n --_state-layer-pressed-opacity: var(--forge-state-layer-pressed-opacity, 0.12);\n --_state-layer-hover-duration: var(--forge-state-layer-hover-duration, 15ms);\n --_state-layer-pressed-duration: var(--forge-state-layer-pressed-duration, 105ms);\n --_state-layer-animation-duration: var(--forge-state-layer-animation-duration, 375ms);\n}\n\n.forge-icon-button:not(:disabled)::before {\n opacity: 0;\n position: absolute;\n backface-visibility: hidden;\n transform: translateZ(0);\n background-color: var(--_state-layer-hover-color);\n inset: 0;\n transition: opacity var(--_state-layer-hover-duration) linear, background-color var(--_state-layer-hover-duration) linear;\n --_state-layer-hover-duration: var(--forge-state-layer-hover-duration, 100ms);\n content: "";\n opacity: 0;\n border-radius: inherit;\n}\n\n.forge-icon-button:not(:disabled):hover::before {\n background-color: var(--_state-layer-hover-color);\n opacity: var(--_state-layer-hover-opacity);\n}\n\n.forge-icon-button:not(:disabled):active::before {\n opacity: var(--_state-layer-pressed-opacity);\n transition-duration: var(--_state-layer-pressed-duration);\n --_state-layer-pressed-opacity: var(--forge-state-layer-pressed-opacity, 0.18);\n}\n\n.forge-icon-button:not(:disabled) {\n --forge-state-layer-color: var(--_icon-button-icon-color);\n}\n\n@keyframes forge-focus-indicator-outward-grow {\n from {\n outline-width: 0;\n }\n to {\n outline-width: var(--_focus-indicator-active-width);\n }\n}\n@keyframes forge-focus-indicator-outward-shrink {\n from {\n outline-width: var(--_focus-indicator-active-width);\n }\n}\n@keyframes forge-focus-indicator-inward-grow {\n from {\n border-width: 0;\n }\n to {\n border-width: var(--_focus-indicator-active-width);\n }\n}\n@keyframes forge-focus-indicator-inward-shrink {\n from {\n border-width: var(--_focus-indicator-active-width);\n }\n}\n.forge-icon-button:not(:disabled) {\n outline: none;\n}\n\n.forge-icon-button:not(:disabled):focus-visible::after {\n --_focus-indicator-display: var(--forge-focus-indicator-display, flex);\n --_focus-indicator-width: var(--forge-focus-indicator-width, var(--forge-border-medium, 2px));\n --_focus-indicator-active-width: var(--forge-focus-indicator-active-width, 6px);\n --_focus-indicator-color: var(--forge-focus-indicator-color, var(--forge-theme-primary, #3f51b5));\n --_focus-indicator-shape: var(--forge-focus-indicator-shape, calc(var(--forge-shape-extra-small, 1px) * var(--forge-shape-factor, 1)));\n --_focus-indicator-duration: var(--forge-focus-indicator-duration, var(--forge-animation-duration-long4, 600ms));\n --_focus-indicator-easing: var(--forge-focus-indicator-easing, var(--forge-animation-easing-emphasized, cubic-bezier(0.2, 0, 0, 1)));\n --_focus-indicator-shape-start-start: var(--forge-focus-indicator-shape-start-start, var(--_focus-indicator-shape));\n --_focus-indicator-shape-start-end: var(--forge-focus-indicator-shape-start-end, var(--_focus-indicator-shape));\n --_focus-indicator-shape-end-end: var(--forge-focus-indicator-shape-end-end, var(--_focus-indicator-shape));\n --_focus-indicator-shape-end-start: var(--forge-focus-indicator-shape-end-start, var(--_focus-indicator-shape));\n --_focus-indicator-outward-offset: var(--forge-focus-indicator-outward-offset, var(--forge-spacing-xxsmall, 4px));\n --_focus-indicator-inward-offset: var(--forge-focus-indicator-inward-offset, 0px);\n --_focus-indicator-offset-block: var(--forge-focus-indicator-offset-block, 0);\n --_focus-indicator-offset-inline: var(--forge-focus-indicator-offset-inline, 0);\n}\n\n.forge-icon-button:not(:disabled):focus-visible::after {\n animation-delay: 0s, calc(var(--_focus-indicator-duration) * 0.25);\n animation-duration: calc(var(--_focus-indicator-duration) * 0.25), calc(var(--_focus-indicator-duration) * 0.75);\n animation-timing-function: var(--_focus-indicator-easing);\n box-sizing: border-box;\n color: var(--_focus-indicator-color);\n display: none;\n pointer-events: none;\n position: absolute;\n margin-block: var(--_focus-indicator-offset-block);\n margin-inline: var(--_focus-indicator-offset-inline);\n animation-name: forge-focus-indicator-outward-grow, forge-focus-indicator-outward-shrink;\n border-end-end-radius: calc(var(--_focus-indicator-shape-end-end) + var(--_focus-indicator-outward-offset));\n border-end-start-radius: calc(var(--_focus-indicator-shape-end-start) + var(--_focus-indicator-outward-offset));\n border-start-end-radius: calc(var(--_focus-indicator-shape-start-end) + var(--_focus-indicator-outward-offset));\n border-start-start-radius: calc(var(--_focus-indicator-shape-start-start) + var(--_focus-indicator-outward-offset));\n inset: calc(-1 * var(--_focus-indicator-outward-offset));\n outline: var(--_focus-indicator-width) solid currentColor;\n content: "";\n display: block;\n}\n\n.forge-icon-button:not(:disabled) {\n --forge-focus-indicator-color: var(--_icon-button-focus-indicator-color);\n --forge-focus-indicator-shape: var(--_icon-button-shape);\n}\n\n.forge-icon-button:not(:disabled):where(.forge-icon-button--text,\n:not(:where(.forge-icon-button--outlined, .forge-icon-button--tonal, .forge-icon-button--filled, .forge-icon-button--raised))) {\n --forge-focus-indicator-outward-offset: 0px;\n}\n\n.forge-icon-button--outlined {\n border-width: var(--_icon-button-outlined-border-width);\n border-style: var(--_icon-button-outlined-border-style);\n border-color: var(--_icon-button-outlined-border-color);\n}\n\n.forge-icon-button--tonal {\n --_icon-button-icon-color: var(--_icon-button-tonal-icon-color);\n --_icon-button-background-color: var(--_icon-button-tonal-background-color);\n}\n\n.forge-icon-button--filled, .forge-icon-button--raised {\n --_icon-button-icon-color: var(--_icon-button-filled-icon-color);\n --_icon-button-background-color: var(--_icon-button-filled-background-color);\n}\n\n.forge-icon-button--raised {\n --_icon-button-shadow: var(--_icon-button-raised-shadow);\n}\n\n.forge-icon-button--raised:hover {\n --_icon-button-raised-shadow: var(--_icon-button-raised-hover-shadow);\n}\n\n.forge-icon-button--raised:active {\n --_icon-button-raised-shadow: var(--_icon-button-raised-active-shadow);\n}\n\n.forge-icon-button--squared {\n --_icon-button-shape: var(--_icon-button-shape-squared);\n}\n\n.forge-icon-button--small {\n --_icon-button-size: var(--_icon-button-density-small-size);\n --_icon-button-icon-size: var(--_icon-button-density-small-icon-size);\n --_icon-button-padding: var(--_icon-button-density-small-padding);\n}\n\n.forge-icon-button--small > * {\n font-size: var(--_icon-button-density-small-icon-size);\n}\n\n.forge-icon-button--medium {\n --_icon-button-size: var(--_icon-button-density-medium-size);\n --_icon-button-padding: var(--_icon-button-density-medium-padding);\n}\n\n.forge-icon-button:disabled {\n pointer-events: none;\n opacity: var(--_icon-button-disabled-opacity);\n pointer-events: auto;\n cursor: not-allowed;\n}\n\n.forge-icon-button forge-circular-progress {\n --forge-circular-progress-indicator-color: var(--_icon-button-icon-color);\n --forge-circular-progress-track-color: transparent;\n --forge-circular-progress-size: 1em;\n}\n\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n:host {\n display: block;\n}\n\n.input-container .forge-card {\n --forge-card-padding: 0;\n --forge-card-shape: calc(var(--forge-shape-large, 8px) * var(--forge-shape-factor, 1));\n position: relative;\n}\n.input-container .forge-card:hover {\n --forge-card-outline-color: var(--forge-theme-outline-high, #212121);\n}\n.input-container .forge-field {\n --forge-theme-outline-low: transparent;\n --forge-field-height: auto;\n position: static;\n padding-inline-start: var(--forge-spacing-medium, 16px);\n min-height: 40px;\n align-items: center;\n}\n.input-container .forge-field:hover {\n outline: none;\n}\n.input-container .forge-field:has(textarea) *:not(textarea) {\n margin-block-start: initial;\n}\n.input-container .forge-field::after {\n border-radius: calc(var(--forge-shape-large, 8px) * var(--forge-shape-factor, 1));\n}\n.input-container textarea {\n field-sizing: content;\n resize: none;\n max-height: 150px;\n overflow-y: auto;\n outline: none;\n padding: var(--forge-spacing-small, 12px) 0;\n}\n.input-container textarea::-webkit-scrollbar {\n height: var(--forge-scrollbar-height, 16px);\n width: var(--forge-scrollbar-width, 16px);\n}\n.input-container textarea::-webkit-scrollbar-track {\n background-color: var(--forge-scrollbar-track-container, var(--forge-theme-surface-container-low, #ebebeb));\n}\n.input-container textarea::-webkit-scrollbar-track:hover {\n background-color: var(--forge-scrollbar-track-container-hover, var(--forge-theme-surface-container-low, #ebebeb));\n}\n.input-container textarea::-webkit-scrollbar-corner {\n background-color: var(--forge-scrollbar-track-container, var(--forge-theme-surface-container-low, #ebebeb));\n}\n.input-container textarea::-webkit-scrollbar-thumb {\n height: var(--forge-scrollbar-thumb-min-height, 32px);\n width: var(--forge-scrollbar-thumb-min-width, 32px);\n border-radius: var(--forge-scrollbar-border-radius, calc(var(--forge-shape-full, 9999px) * var(--forge-shape-factor, 1)));\n border-width: var(--forge-scrollbar-border-width, 3px);\n border-style: solid;\n border-color: transparent;\n background-color: var(--forge-scrollbar-thumb-container, var(--forge-theme-surface-container-medium, #c2c2c2));\n background-clip: content-box;\n}\n.input-container textarea::-webkit-scrollbar-thumb:hover {\n background-color: var(--forge-scrollbar-thumb-container-hover, var(--forge-theme-surface-container-high, #9e9e9e));\n}\n.input-container .debug-button {\n color: var(--forge-theme-on-error-container-low, #5f0011);\n --forge-icon-button-focus-indicator-color: var(--forge-theme-error, #b00020);\n --forge-icon-button-tonal-background-color: var(--forge-theme-error-container-low, #f6e0e4);\n}\n\n.actions {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: var(--forge-spacing-xxsmall, 4px);\n padding-inline-start: var(--forge-spacing-xsmall, 8px);\n gap: var(--forge-spacing-xxsmall, 4px);\n overflow-x: auto;\n}\n\n.actions-start-container,\n.actions-end-container {\n display: flex;\n align-items: center;\n}\n\n.send-button {\n margin-inline-end: var(--forge-spacing-xsmall, 8px);\n}\n.send-button svg {\n height: 18px;\n width: 18px;\n}\n\n:host(:state(stacked)) .vertical-divider {\n display: none;\n}\n\n:host(:state(inline)) .forge-field {\n --forge-field-height: 52px;\n padding-inline: var(--forge-spacing-xxsmall, 4px);\n}\n:host(:state(inline)) .actions {\n display: flex;\n align-items: center;\n overflow-x: visible;\n padding: var(--forge-spacing-xxsmall, 4px);\n}\n:host(:state(inline)) ::slotted([slot=actions]) {\n display: flex;\n align-items: center;\n}\n:host(:state(inline)) .vertical-divider {\n width: 1px;\n height: 32px;\n background-color: var(--forge-theme-outline, #e0e0e0);\n margin-inline-end: var(--forge-spacing-xsmall, 8px);\n}\n:host(:state(inline)) .forge-divider {\n display: none;\n}\n:host(:state(inline)) .send-button {\n margin-inline-end: var(--forge-spacing-xxsmall, 4px);\n}';
|
|
2
2
|
export {
|
|
3
3
|
styles as default
|
|
4
4
|
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { ReactiveController, ReactiveControllerHost } from 'lit';
|
|
2
|
+
import { AgentAdapter } from '../ai-chatbot/agent-adapter.js';
|
|
3
|
+
import { ChatMessage, FileAttachment, FileUploadCallbacks, MessageItem, ThreadState, ToolCall, ToolDefinition } from '../ai-chatbot/types.js';
|
|
4
|
+
export interface ChatbotCoreCallbacks {
|
|
5
|
+
onRequestUpdate: () => void;
|
|
6
|
+
onScrollToBottom: () => void;
|
|
7
|
+
onDispatchEvent: (type: string, detail?: unknown, cancelable?: boolean) => CustomEvent;
|
|
8
|
+
}
|
|
9
|
+
export interface ChatbotCoreControllerConfig {
|
|
10
|
+
callbacks: ChatbotCoreCallbacks;
|
|
11
|
+
}
|
|
12
|
+
export declare class ChatbotCoreController implements ReactiveController {
|
|
13
|
+
#private;
|
|
14
|
+
constructor(host: ReactiveControllerHost, config: ChatbotCoreControllerConfig);
|
|
15
|
+
hostConnected(): void;
|
|
16
|
+
hostDisconnected(): void;
|
|
17
|
+
get adapter(): AgentAdapter | undefined;
|
|
18
|
+
set adapter(value: AgentAdapter | undefined);
|
|
19
|
+
get messageItems(): MessageItem[];
|
|
20
|
+
get isStreaming(): boolean;
|
|
21
|
+
get isUploading(): boolean;
|
|
22
|
+
get hasMessages(): boolean;
|
|
23
|
+
get tools(): Map<string, ToolDefinition>;
|
|
24
|
+
get pendingAttachments(): FileAttachment[];
|
|
25
|
+
get completedAttachments(): FileAttachment[];
|
|
26
|
+
sendMessage(config: {
|
|
27
|
+
content: string;
|
|
28
|
+
timestamp?: number;
|
|
29
|
+
attachments?: FileAttachment[];
|
|
30
|
+
}): Promise<void>;
|
|
31
|
+
processFileUpload(file: File, timestamp: number): string;
|
|
32
|
+
createFileUploadCallbacks(fileId: string): FileUploadCallbacks;
|
|
33
|
+
abortFileUpload(fileId: string): void;
|
|
34
|
+
removeCompletedAttachment(attachmentId: string): void;
|
|
35
|
+
getMessage(id: string): ChatMessage | undefined;
|
|
36
|
+
getToolCall(id: string): ToolCall | undefined;
|
|
37
|
+
clearMessages(): void;
|
|
38
|
+
getMessages(): ChatMessage[];
|
|
39
|
+
setMessages(messages: ChatMessage[]): void;
|
|
40
|
+
updateMessageContent(id: string, content: string): void;
|
|
41
|
+
removeMessageItemsFrom(index: number): void;
|
|
42
|
+
setResponseFeedback(responseId: string, feedback: {
|
|
43
|
+
type: 'positive' | 'negative';
|
|
44
|
+
reason?: string;
|
|
45
|
+
}): void;
|
|
46
|
+
addMessage(message: ChatMessage): void;
|
|
47
|
+
getThreadState(): ThreadState;
|
|
48
|
+
setThreadState(state: ThreadState): void;
|
|
49
|
+
abort(): void;
|
|
50
|
+
canSendMessage(): boolean;
|
|
51
|
+
}
|
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
import { SubscriptionManager } from "../ai-chatbot/event-emitter.mjs";
|
|
2
|
+
import { FileUploadManager } from "../ai-chatbot/file-upload-manager.mjs";
|
|
3
|
+
import { MessageStateController } from "../ai-chatbot/message-state-controller.mjs";
|
|
4
|
+
import { generateId } from "../ai-chatbot/utils.mjs";
|
|
5
|
+
class ChatbotCoreController {
|
|
6
|
+
#host;
|
|
7
|
+
#callbacks;
|
|
8
|
+
#messageStateController;
|
|
9
|
+
#fileUploadManager;
|
|
10
|
+
#adapterSubscriptions;
|
|
11
|
+
#adapter;
|
|
12
|
+
#toolsMap;
|
|
13
|
+
#executingToolHandlers = 0;
|
|
14
|
+
constructor(host, config) {
|
|
15
|
+
this.#host = host;
|
|
16
|
+
this.#callbacks = config.callbacks;
|
|
17
|
+
host.addController(this);
|
|
18
|
+
}
|
|
19
|
+
hostConnected() {
|
|
20
|
+
this.#messageStateController = new MessageStateController(this.#host, {
|
|
21
|
+
tools: this.tools,
|
|
22
|
+
onThreadSettled: () => this.#emitThreadStateChange()
|
|
23
|
+
});
|
|
24
|
+
this.#fileUploadManager = new FileUploadManager({
|
|
25
|
+
onError: (error) => {
|
|
26
|
+
this.#callbacks.onDispatchEvent("forge-ai-chatbot-error", { error });
|
|
27
|
+
},
|
|
28
|
+
onStateChange: () => {
|
|
29
|
+
this.#callbacks.onRequestUpdate();
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
if (this.#adapter) {
|
|
33
|
+
void this.#setupAdapter();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
hostDisconnected() {
|
|
37
|
+
this.#adapterSubscriptions?.unsubscribe();
|
|
38
|
+
this.#adapter?.disconnect();
|
|
39
|
+
this.#callbacks.onDispatchEvent("forge-ai-chatbot-disconnected");
|
|
40
|
+
}
|
|
41
|
+
get adapter() {
|
|
42
|
+
return this.#adapter;
|
|
43
|
+
}
|
|
44
|
+
set adapter(value) {
|
|
45
|
+
this.#adapter = value;
|
|
46
|
+
this.#toolsMap = void 0;
|
|
47
|
+
if (value) {
|
|
48
|
+
this.#setupAdapter();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
get messageItems() {
|
|
52
|
+
return this.#messageStateController?.messageItems ?? [];
|
|
53
|
+
}
|
|
54
|
+
get isStreaming() {
|
|
55
|
+
return (this.#adapter?.isRunning ?? false) || this.#executingToolHandlers > 0;
|
|
56
|
+
}
|
|
57
|
+
get isUploading() {
|
|
58
|
+
return this.#fileUploadManager?.isUploading ?? false;
|
|
59
|
+
}
|
|
60
|
+
get hasMessages() {
|
|
61
|
+
return this.messageItems.length > 0;
|
|
62
|
+
}
|
|
63
|
+
get tools() {
|
|
64
|
+
if (!this.#toolsMap) {
|
|
65
|
+
this.#toolsMap = new Map(this.#adapter?.getTools().map((t) => [t.name, t]) ?? []);
|
|
66
|
+
}
|
|
67
|
+
return this.#toolsMap;
|
|
68
|
+
}
|
|
69
|
+
get pendingAttachments() {
|
|
70
|
+
return this.#fileUploadManager?.pendingAttachments ?? [];
|
|
71
|
+
}
|
|
72
|
+
get completedAttachments() {
|
|
73
|
+
return this.#fileUploadManager?.completedAttachments ?? [];
|
|
74
|
+
}
|
|
75
|
+
async #setupAdapter() {
|
|
76
|
+
if (!this.#adapter || this.#adapter.isConnecting) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
await this.#adapter.connect();
|
|
80
|
+
this.#adapterSubscriptions?.unsubscribe();
|
|
81
|
+
this.#adapterSubscriptions = new SubscriptionManager();
|
|
82
|
+
this.#adapterSubscriptions.add(
|
|
83
|
+
this.#adapter.onMessageStart(this.#handleMessageStart.bind(this)),
|
|
84
|
+
this.#adapter.onMessageDelta(this.#handleMessageDelta.bind(this)),
|
|
85
|
+
this.#adapter.onMessageEnd(this.#handleMessageEnd.bind(this)),
|
|
86
|
+
this.#adapter.onToolCallStart(this.#handleToolCallStart.bind(this)),
|
|
87
|
+
this.#adapter.onToolCallArgs(this.#handleToolCallArgs.bind(this)),
|
|
88
|
+
this.#adapter.onToolCallEnd(this.#handleToolCallEnd.bind(this)),
|
|
89
|
+
this.#adapter.onToolCall(this.#handleToolCall.bind(this)),
|
|
90
|
+
this.#adapter.onToolCallResult(this.#handleToolCallResult.bind(this)),
|
|
91
|
+
this.#adapter.onRunFinished(this.#handleRunFinished.bind(this)),
|
|
92
|
+
this.#adapter.onRunAborted(this.#handleRunAborted.bind(this)),
|
|
93
|
+
this.#adapter.onError(this.#handleError.bind(this)),
|
|
94
|
+
this.#adapter.onStateChange(this.#handleStateChange.bind(this))
|
|
95
|
+
);
|
|
96
|
+
this.#toolsMap = void 0;
|
|
97
|
+
this.#messageStateController?.updateConfig({ tools: this.tools });
|
|
98
|
+
this.#callbacks.onDispatchEvent("forge-ai-chatbot-connected");
|
|
99
|
+
}
|
|
100
|
+
#handleMessageStart(event) {
|
|
101
|
+
this.#messageStateController.addTextToResponse(event.messageId, "", event);
|
|
102
|
+
}
|
|
103
|
+
#handleMessageDelta(event) {
|
|
104
|
+
this.#messageStateController.appendTextDelta(event.messageId, event.delta, event);
|
|
105
|
+
this.#callbacks.onScrollToBottom();
|
|
106
|
+
}
|
|
107
|
+
#handleMessageEnd(event) {
|
|
108
|
+
this.#messageStateController.markTextComplete(event.messageId, event);
|
|
109
|
+
}
|
|
110
|
+
#handleRunFinished() {
|
|
111
|
+
this.#tryCompleteResponse();
|
|
112
|
+
}
|
|
113
|
+
#tryCompleteResponse() {
|
|
114
|
+
if (this.#executingToolHandlers > 0 || this.#adapter?.isRunning) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
this.#messageStateController.tryFinalizeResponse();
|
|
118
|
+
const messages = this.getMessages();
|
|
119
|
+
const lastMessage = messages[messages.length - 1];
|
|
120
|
+
if (lastMessage?.role === "assistant" && lastMessage.status === "complete") {
|
|
121
|
+
this.#callbacks.onDispatchEvent("forge-ai-chatbot-message-received", { message: lastMessage });
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
#handleToolCallStart(event) {
|
|
125
|
+
const toolCall = {
|
|
126
|
+
id: event.id,
|
|
127
|
+
messageId: event.messageId,
|
|
128
|
+
name: event.name,
|
|
129
|
+
args: {},
|
|
130
|
+
argsBuffer: "",
|
|
131
|
+
status: "parsing",
|
|
132
|
+
type: this.tools.has(event.name) ? "client" : "agent"
|
|
133
|
+
};
|
|
134
|
+
this.#messageStateController.addToolCallToResponse(toolCall, event);
|
|
135
|
+
}
|
|
136
|
+
#handleToolCallArgs(event) {
|
|
137
|
+
const updates = {
|
|
138
|
+
argsBuffer: event.argsBuffer,
|
|
139
|
+
args: event.partialArgs ?? {}
|
|
140
|
+
};
|
|
141
|
+
const rawEvent = { eventType: "tool-call-args", event };
|
|
142
|
+
this.#messageStateController.updateToolCallInResponse(event.id, updates, rawEvent);
|
|
143
|
+
this.#callbacks.onScrollToBottom();
|
|
144
|
+
}
|
|
145
|
+
#handleToolCallEnd(event) {
|
|
146
|
+
const updates = {
|
|
147
|
+
args: event.args,
|
|
148
|
+
argsBuffer: void 0,
|
|
149
|
+
status: "executing"
|
|
150
|
+
};
|
|
151
|
+
const rawEvent = { eventType: "tool-call-end", event };
|
|
152
|
+
this.#messageStateController.updateToolCallInResponse(event.id, updates, rawEvent);
|
|
153
|
+
}
|
|
154
|
+
#createToolResponse(toolName, handlerReturn) {
|
|
155
|
+
if (typeof handlerReturn === "string") {
|
|
156
|
+
return handlerReturn;
|
|
157
|
+
}
|
|
158
|
+
if (handlerReturn && typeof handlerReturn === "object") {
|
|
159
|
+
return handlerReturn;
|
|
160
|
+
}
|
|
161
|
+
return `Tool '${toolName}' executed successfully`;
|
|
162
|
+
}
|
|
163
|
+
async #handleToolCall(event) {
|
|
164
|
+
let toolCall = this.#messageStateController.getToolCall(event.id);
|
|
165
|
+
if (toolCall) {
|
|
166
|
+
this.#messageStateController.updateToolCallInResponse(event.id, {
|
|
167
|
+
args: event.args,
|
|
168
|
+
status: "executing"
|
|
169
|
+
});
|
|
170
|
+
} else {
|
|
171
|
+
toolCall = {
|
|
172
|
+
id: event.id,
|
|
173
|
+
messageId: event.messageId,
|
|
174
|
+
name: event.name,
|
|
175
|
+
args: event.args,
|
|
176
|
+
status: "executing",
|
|
177
|
+
type: this.tools.has(event.name) ? "client" : "agent"
|
|
178
|
+
};
|
|
179
|
+
this.#messageStateController.addToolCallToResponse(toolCall);
|
|
180
|
+
}
|
|
181
|
+
if (toolCall?.type === "client") {
|
|
182
|
+
this.#callbacks.onDispatchEvent("forge-ai-chatbot-tool-call", {
|
|
183
|
+
toolCallId: event.id,
|
|
184
|
+
toolName: event.name,
|
|
185
|
+
arguments: event.args
|
|
186
|
+
});
|
|
187
|
+
const toolDef = this.tools.get(event.name);
|
|
188
|
+
if (toolDef?.handler) {
|
|
189
|
+
await Promise.resolve(this.#executeToolHandler(event.id, event.name, toolDef.handler, event.args));
|
|
190
|
+
} else {
|
|
191
|
+
this.#sendToolResult(event.id, this.#createToolResponse(event.name));
|
|
192
|
+
}
|
|
193
|
+
} else {
|
|
194
|
+
this.#messageStateController.updateToolCallInResponse(event.id, { status: "complete" });
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
async #executeToolHandler(toolCallId, toolName, handler, args) {
|
|
198
|
+
this.#executingToolHandlers++;
|
|
199
|
+
this.#callbacks.onRequestUpdate();
|
|
200
|
+
try {
|
|
201
|
+
const context = {
|
|
202
|
+
args,
|
|
203
|
+
toolCallId,
|
|
204
|
+
toolName,
|
|
205
|
+
signal: void 0
|
|
206
|
+
};
|
|
207
|
+
const handlerReturn = await handler(context);
|
|
208
|
+
await this.#sendToolResult(toolCallId, this.#createToolResponse(toolName, handlerReturn));
|
|
209
|
+
} catch (error) {
|
|
210
|
+
console.error(`Tool handler error [${toolName}]:`, error);
|
|
211
|
+
this.#messageStateController.updateToolCallInResponse(toolCallId, {
|
|
212
|
+
status: "error",
|
|
213
|
+
result: { error: error.message }
|
|
214
|
+
});
|
|
215
|
+
const errorMessage = {
|
|
216
|
+
id: generateId(),
|
|
217
|
+
role: "assistant",
|
|
218
|
+
content: "An unexpected error occurred.",
|
|
219
|
+
timestamp: Date.now(),
|
|
220
|
+
status: "error"
|
|
221
|
+
};
|
|
222
|
+
this.#messageStateController.addMessage(errorMessage);
|
|
223
|
+
this.#callbacks.onDispatchEvent("forge-ai-chatbot-error", { error: error.message });
|
|
224
|
+
} finally {
|
|
225
|
+
this.#executingToolHandlers--;
|
|
226
|
+
this.#tryCompleteResponse();
|
|
227
|
+
this.#callbacks.onRequestUpdate();
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
#handleError(event) {
|
|
231
|
+
const errorMessage = {
|
|
232
|
+
id: generateId(),
|
|
233
|
+
role: "assistant",
|
|
234
|
+
content: event.message,
|
|
235
|
+
timestamp: Date.now(),
|
|
236
|
+
status: "error"
|
|
237
|
+
};
|
|
238
|
+
this.#messageStateController.addMessage(errorMessage);
|
|
239
|
+
this.#callbacks.onDispatchEvent("forge-ai-chatbot-message-received", { message: errorMessage });
|
|
240
|
+
this.#callbacks.onDispatchEvent("forge-ai-chatbot-error", { error: event.message });
|
|
241
|
+
}
|
|
242
|
+
#handleRunAborted() {
|
|
243
|
+
const abortMessage = {
|
|
244
|
+
id: generateId(),
|
|
245
|
+
role: "system",
|
|
246
|
+
content: "Run cancelled",
|
|
247
|
+
timestamp: Date.now(),
|
|
248
|
+
status: "complete",
|
|
249
|
+
clientOnly: true
|
|
250
|
+
};
|
|
251
|
+
this.#messageStateController.addMessage(abortMessage);
|
|
252
|
+
this.#callbacks.onDispatchEvent("forge-ai-chatbot-message-received", { message: abortMessage });
|
|
253
|
+
}
|
|
254
|
+
#handleStateChange(_state) {
|
|
255
|
+
this.#callbacks.onRequestUpdate();
|
|
256
|
+
}
|
|
257
|
+
#handleToolCallResult(event) {
|
|
258
|
+
this.#messageStateController.completeToolCallInResponse(event.toolCallId, event.result, event);
|
|
259
|
+
}
|
|
260
|
+
async #sendToolResult(toolCallId, result) {
|
|
261
|
+
const toolCall = this.#messageStateController.getToolCall(toolCallId);
|
|
262
|
+
if (!toolCall || !this.#adapter) {
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
this.#messageStateController.completeToolCallInResponse(toolCallId, result);
|
|
266
|
+
this.#adapter.sendToolResult(toolCallId, result, this.getMessages());
|
|
267
|
+
}
|
|
268
|
+
async sendMessage(config) {
|
|
269
|
+
if (!config.content.trim() || !this.#adapter || this.isStreaming) {
|
|
270
|
+
if (!this.#adapter) {
|
|
271
|
+
console.warn("No adapter configured.");
|
|
272
|
+
}
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
if (!this.#fileUploadManager.canSend()) {
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
const userMessage = {
|
|
279
|
+
id: generateId(),
|
|
280
|
+
role: "user",
|
|
281
|
+
content: config.content,
|
|
282
|
+
timestamp: config.timestamp ?? Date.now(),
|
|
283
|
+
status: "pending"
|
|
284
|
+
};
|
|
285
|
+
this.#messageStateController.addMessage(userMessage);
|
|
286
|
+
try {
|
|
287
|
+
this.#adapter.sendMessage(this.getMessages());
|
|
288
|
+
this.#messageStateController.updateMessageStatus(userMessage.id, "complete");
|
|
289
|
+
} catch (error) {
|
|
290
|
+
this.#messageStateController.updateMessageStatus(userMessage.id, "error");
|
|
291
|
+
const errorMessage = error instanceof Error ? error.message : "Failed to send message";
|
|
292
|
+
this.#callbacks.onDispatchEvent("forge-ai-chatbot-error", { error: errorMessage });
|
|
293
|
+
} finally {
|
|
294
|
+
this.#callbacks.onDispatchEvent("forge-ai-chatbot-message-sent", { message: userMessage });
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
processFileUpload(file, timestamp) {
|
|
298
|
+
const fileId = generateId();
|
|
299
|
+
this.#fileUploadManager.addAttachment(fileId, {
|
|
300
|
+
filename: file.name,
|
|
301
|
+
size: file.size,
|
|
302
|
+
mimeType: file.type,
|
|
303
|
+
timestamp
|
|
304
|
+
});
|
|
305
|
+
const callbacks = this.createFileUploadCallbacks(fileId);
|
|
306
|
+
this.#adapter?.emitFileUpload(file, callbacks);
|
|
307
|
+
return fileId;
|
|
308
|
+
}
|
|
309
|
+
createFileUploadCallbacks(fileId) {
|
|
310
|
+
return {
|
|
311
|
+
updateProgress: (progress) => {
|
|
312
|
+
this.#fileUploadManager.updateProgress(fileId, progress);
|
|
313
|
+
},
|
|
314
|
+
markComplete: (uploadedFile) => {
|
|
315
|
+
this.#fileUploadManager.markComplete(fileId, uploadedFile);
|
|
316
|
+
},
|
|
317
|
+
markError: (error) => {
|
|
318
|
+
this.#fileUploadManager.markError(fileId, error);
|
|
319
|
+
},
|
|
320
|
+
onAbort: (callback) => {
|
|
321
|
+
this.#fileUploadManager.registerOnAbort(fileId, callback);
|
|
322
|
+
}
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
abortFileUpload(fileId) {
|
|
326
|
+
this.#fileUploadManager.abort(fileId);
|
|
327
|
+
}
|
|
328
|
+
removeCompletedAttachment(attachmentId) {
|
|
329
|
+
const attachment = this.completedAttachments.find((a) => a.id === attachmentId);
|
|
330
|
+
if (attachment) {
|
|
331
|
+
this.#fileUploadManager.removeCompletedAttachment(attachmentId);
|
|
332
|
+
this.#callbacks.onRequestUpdate();
|
|
333
|
+
if (attachment.fileId) {
|
|
334
|
+
this.#adapter?.emitFileRemove(attachment.fileId, {
|
|
335
|
+
onSuccess: () => {
|
|
336
|
+
},
|
|
337
|
+
onError: (error) => {
|
|
338
|
+
console.error(`Failed to remove file ${attachment.filename}:`, error);
|
|
339
|
+
}
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
getMessage(id) {
|
|
345
|
+
return this.#messageStateController.getMessage(id);
|
|
346
|
+
}
|
|
347
|
+
getToolCall(id) {
|
|
348
|
+
return this.#messageStateController.getToolCall(id);
|
|
349
|
+
}
|
|
350
|
+
clearMessages() {
|
|
351
|
+
this.#messageStateController.clearMessages();
|
|
352
|
+
this.#fileUploadManager.clear();
|
|
353
|
+
}
|
|
354
|
+
getMessages() {
|
|
355
|
+
return this.#messageStateController.getMessages();
|
|
356
|
+
}
|
|
357
|
+
setMessages(messages) {
|
|
358
|
+
this.#messageStateController.setMessages(messages);
|
|
359
|
+
}
|
|
360
|
+
updateMessageContent(id, content) {
|
|
361
|
+
this.#messageStateController.updateMessageContent(id, content);
|
|
362
|
+
}
|
|
363
|
+
removeMessageItemsFrom(index) {
|
|
364
|
+
this.#messageStateController.removeMessageItemsFrom(index);
|
|
365
|
+
}
|
|
366
|
+
setResponseFeedback(responseId, feedback) {
|
|
367
|
+
this.#messageStateController.setResponseFeedback(responseId, feedback);
|
|
368
|
+
}
|
|
369
|
+
addMessage(message) {
|
|
370
|
+
this.#messageStateController.addMessage(message);
|
|
371
|
+
}
|
|
372
|
+
getThreadState() {
|
|
373
|
+
return {
|
|
374
|
+
threadId: this.#adapter?.threadId,
|
|
375
|
+
messages: this.getMessages(),
|
|
376
|
+
timestamp: Date.now()
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
setThreadState(state) {
|
|
380
|
+
this.setMessages(state.messages);
|
|
381
|
+
if (state.threadId && this.#adapter) {
|
|
382
|
+
this.#adapter.threadId = state.threadId;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
abort() {
|
|
386
|
+
if (this.#adapter?.isRunning) {
|
|
387
|
+
this.#adapter.abort();
|
|
388
|
+
}
|
|
389
|
+
this.#callbacks.onRequestUpdate();
|
|
390
|
+
}
|
|
391
|
+
canSendMessage() {
|
|
392
|
+
return this.#fileUploadManager?.canSend() ?? true;
|
|
393
|
+
}
|
|
394
|
+
#emitThreadStateChange() {
|
|
395
|
+
this.#callbacks.onDispatchEvent("forge-ai-chatbot-thread-state-change");
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
export {
|
|
399
|
+
ChatbotCoreController
|
|
400
|
+
};
|
package/dist/core/index.d.ts
CHANGED