@lumiastream/ui 0.5.3 → 0.5.5
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/dist/LSButton.js +1 -1
- package/dist/LSCheckbox.js +1 -1
- package/dist/LSColorPicker.js +18 -31
- package/dist/LSDatePicker.js +18 -31
- package/dist/LSFontPicker.js +11 -20
- package/dist/LSInput.d.ts +0 -4
- package/dist/LSInput.js +18 -31
- package/dist/LSMultiSelect.js +21 -39
- package/dist/LSRadio.js +1 -1
- package/dist/LSSelect.js +11 -23
- package/dist/LSSliderInput.js +27 -40
- package/dist/LSTextField.d.ts +4 -5
- package/dist/LSTextField.js +5 -13
- package/dist/LSVariableInputField.js +47 -74
- package/dist/components.d.ts +1 -0
- package/dist/components.js +86 -140
- package/dist/index.d.ts +2 -1
- package/dist/index.js +938 -598
- package/dist/se-import.d.ts +9 -3
- package/dist/se-import.js +927 -581
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -21,7 +21,7 @@ function styleInject(css, { insertAt } = {}) {
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
// src/lumia-ui.css
|
|
24
|
-
styleInject(".ls-color-picker,\n.ls-color-picker *,\n.mui-multi-select,\n.mui-multi-select *,\n.ls-multi-select-value,\n.ls-multi-select-value *,\n.ls-variable-picker,\n.ls-variable-picker *,\n.ls-variable-token,\n.ls-variable-token *,\n.ls-font-picker,\n.ls-font-picker *,\n.mui-ls-input,\n.mui-ls-input * {\n box-sizing: border-box;\n}\n.ls-color-picker button,\n.mui-multi-select button {\n font: inherit;\n letter-spacing: inherit;\n color: inherit;\n margin: 0;\n}\n.ls-color-picker__preview {\n appearance: none;\n -webkit-appearance: none;\n background-color: transparent;\n background-image: none;\n cursor: pointer;\n text-transform: uppercase;\n user-select: none;\n}\n.mui-ls-button.Mui-disabled {\n color: var(--neutralLight2, var(--white2, #cac9d5));\n opacity: 0.45;\n background-color: var(--separator, #0a0821);\n cursor: not-allowed;\n}\n.mui-ls-button {\n border-radius: var(--radius, 1rem);\n padding: 0.375rem 1.5rem;\n text-transform: uppercase;\n}\n.mui-ls-button.MuiButton-sizeSmall {\n padding: 0.25rem 1rem;\n}\n.mui-ls-button.MuiButton-sizeLarge {\n padding: 0.625rem 2rem;\n}\n.mui-ls-button--extended {\n padding-inline: 3rem;\n}\n.mui-ls-button.MuiButton-containedPrimary,\n.mui-ls-button.Mui-disabled.MuiButton-containedPrimary {\n background: var(--primary, #ff4076);\n color: var(--alwayswhite, #fff) !important;\n}\n.mui-ls-button.MuiButton-containedSecondary {\n background-color: var(--secondary, #535395);\n color: var(--alwayswhite, #fff) !important;\n}\n.mui-ls-button.Mui-disabled.MuiButton-containedSecondary {\n background-color: var(--secondary, #535395);\n color: var(--neutralLight2, var(--white2, #cac9d5));\n opacity: 0.4;\n}\n.mui-ls-button.MuiButton-outlinedPrimary {\n color: var(--primary, #ff4076);\n border-color: var(--primary, #ff4076);\n}\n.mui-ls-button.MuiButton-outlinedPrimary:hover {\n border-color: var(--primary, #ff4076);\n background-color: color-mix(in srgb, var(--primary, #ff4076) 12%, transparent);\n}\n.mui-ls-button.MuiButton-outlinedSecondary {\n color: var(--neutralLight1, var(--white, #fff));\n border-color: var(--secondary, #535395);\n}\n.mui-ls-button.MuiButton-outlinedSecondary.Mui-disabled {\n color: var(--neutralLight2, var(--white2, #cac9d5));\n border-color: var(--neutralDark4, var(--cardborder, #393853));\n background-color: var(--transwhite, rgba(255, 255, 255, 0.05));\n opacity: 0.5;\n}\n.mui-ls-button.MuiButton-outlinedSecondary:hover {\n border-color: var(--secondary, #535395);\n background-color: var(--transwhite, rgba(255, 255, 255, 0.05));\n}\n.mui-ls-button.MuiButton-containedError {\n color: var(--alwayswhite, #fff) !important;\n}\n.mui-ls-button.MuiButton-outlinedError {\n color: var(--error, #fd5454);\n border-color: var(--error, #fd5454);\n}\n.mui-ls-button.MuiButton-outlinedError:hover {\n border-color: var(--error, #fd5454);\n background-color: color-mix(in srgb, var(--error, #fd5454) 12%, transparent);\n}\n.mui-ls-button--neutral.mui-ls-button--contained {\n background-color: var(--neutralDark4, var(--cardborder, #393853));\n color: var(--neutralLight1, var(--white, #fff)) !important;\n}\n.mui-ls-button--neutral.mui-ls-button--contained:hover {\n background-color: color-mix(in srgb, var(--neutralDark4, var(--cardborder, #393853)) 82%, var(--neutralLight1, #fff));\n}\n.mui-ls-button--neutral.mui-ls-button--outlined {\n color: var(--neutralLight1, var(--white, #fff));\n border-color: var(--neutralDark4, var(--cardborder, #393853));\n background-color: transparent;\n}\n.mui-ls-button--neutral.mui-ls-button--outlined:hover {\n border-color: var(--neutralLight3, var(--grey, #9392a1));\n background-color: var(--transwhite, rgba(255, 255, 255, 0.05));\n}\n.mui-ls-button--neutral.mui-ls-button--text {\n color: var(--neutralLight1, var(--white, #fff));\n}\n.mui-ls-button--neutral.mui-ls-button--text:hover {\n background-color: var(--transwhite, rgba(255, 255, 255, 0.05));\n}\n.mui-ls-button svg {\n max-height: 24px;\n max-width: 24px;\n}\n.mui-ls-input,\n.ls-font-picker,\n.ls-color-picker__input {\n width: 100%;\n}\n.mui-ls-input,\n.mui-ls-select-form-control,\n.mui-multi-select,\n.ls-font-picker,\n.mui-ls-slider-input-root {\n --ls-control-height: 55px;\n}\n.mui-ls-input .MuiOutlinedInput-root,\n.mui-ls-input .MuiInputBase-root,\n.mui-ls-input .MuiOutlinedInput-notchedOutline,\n.mui-ls-select.MuiOutlinedInput-root,\n.mui-ls-select .MuiOutlinedInput-notchedOutline,\n.mui-multi-select .mui-ls-select.MuiOutlinedInput-root,\n.mui-multi-select .mui-ls-select .MuiOutlinedInput-notchedOutline,\n.ls-font-picker .MuiOutlinedInput-root,\n.ls-font-picker .MuiInputBase-root,\n.ls-font-picker .MuiOutlinedInput-notchedOutline,\n.ls-color-picker__input .MuiOutlinedInput-root,\n.ls-color-picker__input .MuiInputBase-root,\n.ls-color-picker__input .MuiOutlinedInput-notchedOutline {\n border-radius: var(--radius) !important;\n}\n.mui-ls-input .MuiInputBase-root,\n.mui-ls-select.MuiInputBase-root,\n.mui-multi-select .mui-ls-select.MuiInputBase-root,\n.ls-font-picker .MuiInputBase-root {\n min-height: var(--ls-control-height);\n}\n.mui-ls-input.small .MuiInputBase-root {\n min-height: 25px;\n}\n.mui-ls-input.medium .MuiInputBase-root {\n min-height: 35px;\n}\n.mui-ls-input.noMinHeight .MuiInputBase-root {\n min-height: unset;\n}\n.mui-ls-date-picker input[type=datetime-local]::-webkit-calendar-picker-indicator {\n cursor: pointer;\n opacity: 0.9;\n filter: invert(1);\n}\n.mui-ls-select .MuiSelect-select,\n.mui-multi-select .MuiSelect-select {\n display: flex;\n min-height: calc(var(--ls-control-height) - 2px);\n align-items: center;\n box-sizing: border-box;\n border-radius: var(--radius);\n}\n.mui-multi-select .MuiSelect-select {\n min-width: 0;\n}\n.MuiSvgIcon-root svg {\n color: var(--neutralLight1, var(--white, #fff)) !important;\n}\n.mui-ls-input .MuiSvgIcon-root svg path {\n fill: currentcolor;\n stroke: currentcolor;\n}\n.mui-ls-input input::placeholder,\n.mui-ls-input textarea::placeholder {\n color: var(--neutralLight3, var(--grey, #9392a1));\n opacity: 1;\n}\n.mui-ls-input .Mui-focused .MuiOutlinedInput-notchedOutline,\n.mui-ls-input .MuiOutlinedInput-root.Mui-focused .MuiOutlinedInput-notchedOutline {\n border-color: var(--primary, #ff4076) !important;\n}\n.ls-variable-autocomplete-popper .MuiAutocomplete-paper,\n.ls-variable-autocomplete-paper {\n border: 1px solid var(--neutralDark4, var(--cardborder, #393853)) !important;\n border-radius: var(--radius, 1rem) !important;\n background: var(--neutralDark2, var(--cardbackground, #211f45)) !important;\n color: var(--neutralLight1, var(--white, #fff)) !important;\n box-shadow: 0 16px 32px rgba(0, 0, 0, 0.32) !important;\n overflow: hidden !important;\n}\n.ls-variable-autocomplete-popper .MuiAutocomplete-listbox,\n.ls-variable-autocomplete-listbox {\n padding: 0.25rem 0 !important;\n background: var(--neutralDark2, var(--cardbackground, #211f45)) !important;\n color: var(--neutralLight1, var(--white, #fff)) !important;\n}\n.ls-variable-autocomplete-popper .MuiAutocomplete-option,\n.ls-variable-autocomplete-listbox .MuiAutocomplete-option {\n display: flex !important;\n min-height: 44px !important;\n align-items: center !important;\n padding: 0.625rem 1rem !important;\n color: var(--neutralLight1, var(--white, #fff)) !important;\n font-size: 1rem !important;\n line-height: 1.35 !important;\n cursor: pointer !important;\n transition: background-color 120ms ease, color 120ms ease !important;\n}\n.ls-variable-autocomplete-popper .MuiAutocomplete-option > *,\n.ls-variable-autocomplete-listbox .MuiAutocomplete-option > * {\n min-width: 0;\n}\n.ls-variable-autocomplete-popper .MuiAutocomplete-option:hover,\n.ls-variable-autocomplete-popper .MuiAutocomplete-option.Mui-focused,\n.ls-variable-autocomplete-popper .MuiAutocomplete-option[data-focus=true],\n.ls-variable-autocomplete-popper .MuiAutocomplete-option[aria-selected=true],\n.ls-variable-autocomplete-listbox .MuiAutocomplete-option:hover,\n.ls-variable-autocomplete-listbox .MuiAutocomplete-option.Mui-focused,\n.ls-variable-autocomplete-listbox .MuiAutocomplete-option[data-focus=true],\n.ls-variable-autocomplete-listbox .MuiAutocomplete-option[aria-selected=true] {\n background: var( --cardHover, var(--transwhite, rgba(255, 255, 255, 0.05)) ) !important;\n color: var(--neutralLight1, var(--white, #fff)) !important;\n}\n.ls-variable-option {\n gap: 0.75rem;\n}\n.ls-variable-option__thumb {\n width: 40px;\n height: 40px;\n flex: 0 0 40px;\n border-radius: var(--radius, 1rem);\n object-fit: cover;\n}\n.ls-variable-option__thumb--placeholder {\n background: var(--neutralDark4, var(--cardborder, #393853));\n}\n.ls-variable-option__body {\n min-width: 0;\n}\n.ls-variable-option__label {\n color: var(--neutralLight1, var(--white, #fff));\n font-weight: 500;\n line-height: 1.25;\n}\n.ls-variable-option__helper {\n margin-top: 0.125rem;\n color: var(--neutralLight3, var(--grey, #9392a1));\n font-size: 0.875rem;\n line-height: 1.25;\n}\n.ls-variable-autocomplete-popup-indicator,\n.ls-variable-autocomplete-popup-indicator.MuiIconButton-root,\n.ls-variable-autocomplete-popup-indicator svg {\n color: var(--neutralLight1, var(--white, #fff)) !important;\n}\n.ls-variable-autocomplete-popup-indicator svg path {\n fill: currentcolor !important;\n stroke: currentcolor !important;\n}\n.ls-variable-input-adornment,\n.ls-variable-input-adornment.MuiInputAdornment-root {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n height: 24px;\n width: 24px;\n min-width: 24px;\n margin-left: 0.35rem;\n border-radius: var(--radius, 1rem);\n background: var(--primary, #ff4076) !important;\n color: var(--alwayswhite, var(--white, #fff)) !important;\n font-weight: 800;\n line-height: 1;\n letter-spacing: 0;\n cursor: pointer;\n user-select: none;\n}\n.ls-variable-input-adornment svg,\n.ls-variable-input-adornment path {\n color: currentcolor !important;\n fill: currentcolor !important;\n stroke: currentcolor !important;\n}\n.ls-variable-input-adornment:hover,\n.ls-variable-input-adornment.MuiInputAdornment-root:hover {\n filter: brightness(1.08);\n}\n.ls-variable-input-adornment:active,\n.ls-variable-input-adornment.MuiInputAdornment-root:active {\n filter: brightness(0.96);\n}\n.mui-ls-slider-input-root {\n width: 100%;\n}\n.mui-ls-slider-input-fieldset {\n position: relative;\n min-width: 0;\n width: 100%;\n min-height: var(--ls-control-height);\n margin: 0;\n border: 2px solid var(--neutralDark4, var(--cardborder, #393853));\n border-radius: var(--radius, 1rem);\n padding: 0 0.875rem 0.5rem 0.875rem;\n background: transparent;\n color: var(--neutralLight1, var(--white, #fff));\n}\n.mui-ls-slider-input-fieldset:hover {\n border-color: var(--primary, #ff4076);\n}\n.mui-ls-slider-input-legend {\n display: block;\n width: auto;\n max-width: calc(100% - 1rem);\n margin: 0;\n padding: 0 0.25rem;\n color: var(--neutralLight1, var(--white, #fff));\n font-size: 0.875rem;\n line-height: 1.1;\n white-space: nowrap;\n}\n.mui-ls-slider-input-row {\n display: flex;\n min-width: 0;\n min-height: calc(var(--ls-control-height) - 14px);\n align-items: center;\n gap: 1rem;\n}\n.mui-ls-slider-input-row--slider {\n flex-wrap: nowrap;\n}\n.mui-ls-slider-input-row--input {\n justify-content: stretch;\n}\n.mui-ls-slider-input-value.mui-ls-input {\n margin: 0;\n}\n.mui-ls-slider-input-value.mui-ls-input .MuiFormControl-root,\n.mui-ls-slider-input-value.mui-ls-input .MuiTextField-root {\n margin: 0;\n}\n.mui-ls-slider-input-value.mui-ls-input .MuiInputBase-root {\n min-height: 36px;\n}\n.mui-ls-slider-input-value.mui-ls-input .MuiOutlinedInput-notchedOutline {\n border-color: var(--neutralDark4, var(--cardborder, #393853));\n}\n.mui-ls-slider-input-helper {\n display: block;\n margin-top: 0.25rem;\n color: var(--neutralLight3, var(--grey, #9392a1));\n font-size: 0.75rem;\n line-height: 1.25;\n}\n.ls-multi-select-value {\n display: flex;\n width: 100%;\n min-width: 0;\n flex-wrap: nowrap;\n align-items: center;\n justify-content: space-between;\n gap: 0.5rem;\n overflow: hidden;\n white-space: nowrap;\n}\n.ls-multi-select-value__label {\n min-width: 0;\n flex: 1 1 0%;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.ls-multi-select-value__count {\n flex-shrink: 0;\n white-space: nowrap;\n}\n.ls-color-picker__preview {\n position: relative;\n display: inline-block;\n width: 1.5rem;\n height: 1.5rem;\n flex-shrink: 0;\n padding: 0;\n border: 1px solid color-mix(in srgb, #fff 25%, transparent);\n border-radius: var(--radius, 1rem);\n background-size: cover;\n background-position: center;\n background-repeat: no-repeat;\n box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.25);\n color: transparent;\n line-height: 0;\n}\n.ls-color-picker__preview:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n.ls-color-picker__preview:focus {\n outline: none;\n}\n.ls-color-picker__preview:focus-visible {\n box-shadow:\n 0 0 0 2px var(--primary, #ff4076),\n 0 0 0 4px var(--neutralDark1, #1b1a28),\n 0 0 0 1px rgba(0, 0, 0, 0.25);\n}\n.ls-color-picker__gradient circle,\n.ls-color-picker__gradient polyline {\n stroke: #fff;\n}\n.ls-variable-picker {\n --variable-custom-color: var(--customVariables, #69ffd2);\n --variable-function-color: var( --functionVariables, var(--semanticPurple, #b489ff) );\n --variable-normal-color: var(--normalVariables, var(--semanticBlue, #65b8ff));\n display: flex;\n width: 92vw;\n max-width: 1100px;\n min-height: 50vh;\n max-height: 55vh;\n flex-direction: column;\n overflow: hidden;\n padding: 1rem;\n}\n.ls-variable-picker__field {\n margin: 0 0 0.75rem;\n border: 1px solid color-mix(in srgb, var(--primary, #ff4076) 42%, var(--neutralDark4, #393853));\n border-radius: var(--radius, 1rem);\n padding: 0.5rem;\n}\n.ls-variable-picker__legend {\n padding-inline: 0.375rem;\n color: var(--primary, #ff4076);\n font-size: 0.75rem;\n font-weight: 700;\n}\n.ls-variable-picker__intro {\n margin-bottom: 1rem;\n color: var(--neutralLight2, #cac9d5);\n}\n.ls-variable-picker__header,\n.ls-variable-picker__row {\n display: grid;\n grid-template-columns: minmax(300px, 1.5fr) 1fr 1fr;\n gap: 2rem;\n}\n.ls-variable-picker__header {\n margin-bottom: 0.25rem;\n padding-inline: 0.25rem;\n padding-right: 1.7rem;\n color: var(--neutralLight3, #9392a1);\n}\n.ls-variable-picker__list {\n height: 100%;\n overflow: auto;\n padding-right: 1rem;\n}\n.ls-variable-picker__row {\n cursor: pointer;\n align-items: start;\n border-bottom: 1px solid color-mix(in srgb, var(--neutralDark4, #393853) 70%, transparent);\n padding: 1rem 0.25rem;\n}\n.ls-variable-picker__row--no-border {\n border-bottom: 0;\n}\n.ls-variable-picker__token-cell {\n display: flex;\n min-width: 0;\n align-items: center;\n gap: 0.375rem;\n}\n.ls-variable-picker__expand-toggle,\n.ls-variable-picker__expand-spacer {\n width: 24px;\n height: 24px;\n flex: 0 0 24px;\n}\n.ls-variable-picker__expand-toggle {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border: 1px solid color-mix(in srgb, var(--neutralDark4, #393853) 75%, transparent);\n border-radius: var(--radius, 1rem);\n padding: 0;\n background: var(--neutralDark3, var(--containerbackground, #1f1f3a));\n color: var(--neutralLight2, #cac9d5);\n transition:\n background-color 140ms ease,\n border-color 140ms ease,\n color 140ms ease,\n transform 140ms ease;\n}\n.ls-variable-picker__expand-toggle:hover {\n border-color: var(--primary, #ff4076);\n background: color-mix(in srgb, var(--primary, #ff4076) 16%, var(--neutralDark3, #1f1f3a));\n color: var(--neutralLight1, #fff);\n}\n.ls-variable-picker__expand-toggle svg {\n transform: rotate(-90deg);\n transition: transform 140ms ease;\n}\n.ls-variable-picker__expand-toggle--expanded svg {\n transform: rotate(0deg);\n}\n.ls-variable-picker__row:active {\n opacity: 0.8;\n}\n.ls-variable-picker__description {\n max-width: 600px;\n overflow-wrap: break-word;\n line-height: 1.25;\n word-break: break-all;\n}\n.ls-variable-picker__value {\n min-width: 0;\n}\n.ls-variable-picker__value-input {\n width: 100%;\n min-width: 0;\n cursor: text;\n overflow: hidden;\n border: 0;\n background: transparent;\n color: var(--neutralLight1, var(--white, #fff));\n caret-color: transparent;\n font: inherit;\n font-size: 1rem;\n line-height: 1.25;\n outline: 0;\n padding: 0;\n text-overflow: ellipsis;\n}\n.ls-variable-picker__value-input:focus {\n outline: 0;\n}\n.ls-variable-picker__value-input::selection {\n background: color-mix(in srgb, var(--primary, #ff4076) 45%, transparent);\n color: var(--alwayswhite, var(--white, #fff));\n}\n.ls-variable-token {\n display: flex;\n min-width: 0;\n align-items: center;\n}\n.ls-variable-token--suggested {\n color: var(--suggestedVariables, #ffb469);\n}\n.ls-variable-token--custom {\n color: var(--customVariables, #69ffd2);\n}\n.ls-variable-token--function {\n color: var(--functionVariables, var(--semanticPurple, #b489ff));\n}\n.ls-variable-token--system {\n color: var(--normalVariables, var(--semanticBlue, #65b8ff));\n}\n.ls-variable-token__name {\n min-width: 0;\n word-break: break-all;\n}\n.ls-variable-token__badge {\n display: inline-flex;\n margin-left: 0.5rem;\n flex-shrink: 0;\n align-items: center;\n border: 1px solid currentcolor;\n border-radius: var(--radius, 1rem);\n padding-inline: 0.25rem;\n padding-block: 0;\n font-size: 10px;\n font-weight: 600;\n line-height: 1;\n text-transform: uppercase;\n}\n");
|
|
24
|
+
styleInject(".ls-color-picker,\n.ls-color-picker *,\n.mui-multi-select,\n.mui-multi-select *,\n.ls-multi-select-value,\n.ls-multi-select-value *,\n.ls-variable-picker,\n.ls-variable-picker *,\n.ls-variable-token,\n.ls-variable-token *,\n.ls-font-picker,\n.ls-font-picker *,\n.mui-ls-input,\n.mui-ls-input * {\n box-sizing: border-box;\n}\n.ls-color-picker button,\n.mui-multi-select button {\n font: inherit;\n letter-spacing: inherit;\n color: inherit;\n margin: 0;\n}\n.ls-color-picker__preview {\n appearance: none;\n -webkit-appearance: none;\n background-color: transparent;\n background-image: none;\n cursor: pointer;\n text-transform: uppercase;\n user-select: none;\n}\n.mui-ls-button.Mui-disabled {\n color: var(--neutralLight2, var(--white2, #cac9d5));\n opacity: 0.45;\n background-color: var(--separator, #0a0821);\n cursor: not-allowed;\n}\n.mui-ls-button {\n border-radius: var(--radius, 1rem);\n padding: 0.375rem 1.5rem;\n text-transform: uppercase;\n}\n.mui-ls-button.MuiButton-sizeSmall {\n padding: 0.25rem 1rem;\n}\n.mui-ls-button.MuiButton-sizeLarge {\n padding: 0.625rem 2rem;\n}\n.mui-ls-button--extended {\n padding-inline: 3rem;\n}\n.mui-ls-button.MuiButton-containedPrimary,\n.mui-ls-button.Mui-disabled.MuiButton-containedPrimary {\n background: var(--primary, #ff4076);\n color: var(--alwayswhite, #fff) !important;\n}\n.mui-ls-button.MuiButton-containedSecondary {\n background-color: var(--secondary, #535395);\n color: var(--alwayswhite, #fff) !important;\n}\n.mui-ls-button.Mui-disabled.MuiButton-containedSecondary {\n background-color: var(--secondary, #535395);\n color: var(--neutralLight2, var(--white2, #cac9d5));\n opacity: 0.4;\n}\n.mui-ls-button.MuiButton-outlinedPrimary {\n color: var(--primary, #ff4076);\n border-color: var(--primary, #ff4076);\n}\n.mui-ls-button.MuiButton-outlinedPrimary:hover {\n border-color: var(--primary, #ff4076);\n background-color: color-mix(in srgb, var(--primary, #ff4076) 12%, transparent);\n}\n.mui-ls-button.MuiButton-outlinedSecondary {\n color: var(--neutralLight1, var(--white, #fff));\n border-color: var(--secondary, #535395);\n}\n.mui-ls-button.MuiButton-outlinedSecondary.Mui-disabled {\n color: var(--neutralLight2, var(--white2, #cac9d5));\n border-color: var(--neutralDark4, var(--cardborder, #393853));\n background-color: var(--transwhite, rgba(255, 255, 255, 0.05));\n opacity: 0.5;\n}\n.mui-ls-button.MuiButton-outlinedSecondary:hover {\n border-color: var(--secondary, #535395);\n background-color: var(--transwhite, rgba(255, 255, 255, 0.05));\n}\n.mui-ls-button.MuiButton-containedError {\n color: var(--alwayswhite, #fff) !important;\n}\n.mui-ls-button.MuiButton-outlinedError {\n color: var(--error, #fd5454);\n border-color: var(--error, #fd5454);\n}\n.mui-ls-button.MuiButton-outlinedError:hover {\n border-color: var(--error, #fd5454);\n background-color: color-mix(in srgb, var(--error, #fd5454) 12%, transparent);\n}\n.mui-ls-button--neutral.mui-ls-button--contained {\n background-color: var(--neutralDark4, var(--cardborder, #393853));\n color: var(--neutralLight1, var(--white, #fff)) !important;\n}\n.mui-ls-button--neutral.mui-ls-button--contained:hover {\n background-color: color-mix(in srgb, var(--neutralDark4, var(--cardborder, #393853)) 82%, var(--neutralLight1, #fff));\n}\n.mui-ls-button--neutral.mui-ls-button--outlined {\n color: var(--neutralLight1, var(--white, #fff));\n border-color: var(--neutralDark4, var(--cardborder, #393853));\n background-color: transparent;\n}\n.mui-ls-button--neutral.mui-ls-button--outlined:hover {\n border-color: var(--neutralLight3, var(--grey, #9392a1));\n background-color: var(--transwhite, rgba(255, 255, 255, 0.05));\n}\n.mui-ls-button--neutral.mui-ls-button--text {\n color: var(--neutralLight1, var(--white, #fff));\n}\n.mui-ls-button--neutral.mui-ls-button--text:hover {\n background-color: var(--transwhite, rgba(255, 255, 255, 0.05));\n}\n.mui-ls-button svg {\n max-height: 24px;\n max-width: 24px;\n}\n.mui-ls-input,\n.ls-font-picker,\n.ls-color-picker__input {\n width: 100%;\n}\n.mui-ls-input,\n.mui-ls-select-form-control,\n.mui-multi-select,\n.ls-font-picker,\n.mui-ls-slider-input-root {\n --ls-control-height: 55px;\n}\n.mui-ls-input .MuiOutlinedInput-root,\n.mui-ls-input .MuiInputBase-root,\n.mui-ls-input .MuiOutlinedInput-notchedOutline,\n.mui-ls-select.MuiOutlinedInput-root,\n.mui-ls-select .MuiOutlinedInput-notchedOutline,\n.mui-multi-select .mui-ls-select.MuiOutlinedInput-root,\n.mui-multi-select .mui-ls-select .MuiOutlinedInput-notchedOutline,\n.ls-font-picker .MuiOutlinedInput-root,\n.ls-font-picker .MuiInputBase-root,\n.ls-font-picker .MuiOutlinedInput-notchedOutline,\n.ls-color-picker__input .MuiOutlinedInput-root,\n.ls-color-picker__input .MuiInputBase-root,\n.ls-color-picker__input .MuiOutlinedInput-notchedOutline {\n border-radius: var(--radius) !important;\n}\n.mui-ls-input .MuiInputBase-root,\n.mui-ls-select.MuiInputBase-root,\n.mui-multi-select .mui-ls-select.MuiInputBase-root,\n.ls-font-picker .MuiInputBase-root {\n min-height: var(--ls-control-height);\n}\n.mui-ls-input.small .MuiInputBase-root {\n min-height: 25px;\n}\n.mui-ls-input.medium .MuiInputBase-root {\n min-height: 35px;\n}\n.mui-ls-input.noMinHeight .MuiInputBase-root {\n min-height: unset;\n}\n.mui-ls-date-picker input[type=datetime-local]::-webkit-calendar-picker-indicator {\n cursor: pointer;\n opacity: 0.9;\n filter: invert(1);\n}\n.mui-ls-select .MuiSelect-select,\n.mui-multi-select .MuiSelect-select {\n display: flex;\n min-height: calc(var(--ls-control-height) - 2px);\n align-items: center;\n box-sizing: border-box;\n border-radius: var(--radius);\n}\n.mui-multi-select .MuiSelect-select {\n min-width: 0;\n}\n.MuiSvgIcon-root svg {\n color: var(--neutralLight1, var(--white, #fff)) !important;\n}\n.mui-ls-input .MuiSvgIcon-root svg path {\n fill: currentcolor;\n stroke: currentcolor;\n}\n.mui-ls-input input::placeholder,\n.mui-ls-input textarea::placeholder {\n color: var(--neutralLight3, var(--grey, #9392a1));\n opacity: 0.55;\n font-style: italic;\n}\n.mui-ls-input .MuiInputBase-input,\n.mui-ls-input .MuiInputAdornment-root,\n.mui-ls-input .MuiSvgIcon-root,\n.mui-ls-input .MuiFormHelperText-root {\n color: var(--neutralLight1, var(--white, #fff));\n opacity: 1;\n}\n.mui-ls-input .Mui-focused .MuiOutlinedInput-notchedOutline,\n.mui-ls-input .MuiOutlinedInput-root.Mui-focused .MuiOutlinedInput-notchedOutline {\n border-color: var(--primary, #ff4076) !important;\n}\n.ls-variable-autocomplete-popper .MuiAutocomplete-paper,\n.ls-variable-autocomplete-paper {\n border: 1px solid var(--neutralDark4, var(--cardborder, #393853)) !important;\n border-radius: var(--radius, 1rem) !important;\n background: var(--neutralDark2, var(--cardbackground, #211f45)) !important;\n color: var(--neutralLight1, var(--white, #fff)) !important;\n box-shadow: 0 16px 32px rgba(0, 0, 0, 0.32) !important;\n overflow: hidden !important;\n}\n.ls-variable-autocomplete-popper .MuiAutocomplete-listbox,\n.ls-variable-autocomplete-listbox {\n padding: 0.25rem 0 !important;\n background: var(--neutralDark2, var(--cardbackground, #211f45)) !important;\n color: var(--neutralLight1, var(--white, #fff)) !important;\n}\n.ls-variable-autocomplete-popper .MuiAutocomplete-option,\n.ls-variable-autocomplete-listbox .MuiAutocomplete-option {\n display: flex !important;\n min-height: 44px !important;\n align-items: center !important;\n padding: 0.625rem 1rem !important;\n color: var(--neutralLight1, var(--white, #fff)) !important;\n font-size: 1rem !important;\n line-height: 1.35 !important;\n cursor: pointer !important;\n transition: background-color 120ms ease, color 120ms ease !important;\n}\n.ls-variable-autocomplete-popper .MuiAutocomplete-option > *,\n.ls-variable-autocomplete-listbox .MuiAutocomplete-option > * {\n min-width: 0;\n}\n.ls-variable-autocomplete-popper .MuiAutocomplete-option:hover,\n.ls-variable-autocomplete-popper .MuiAutocomplete-option.Mui-focused,\n.ls-variable-autocomplete-popper .MuiAutocomplete-option[data-focus=true],\n.ls-variable-autocomplete-popper .MuiAutocomplete-option[aria-selected=true],\n.ls-variable-autocomplete-listbox .MuiAutocomplete-option:hover,\n.ls-variable-autocomplete-listbox .MuiAutocomplete-option.Mui-focused,\n.ls-variable-autocomplete-listbox .MuiAutocomplete-option[data-focus=true],\n.ls-variable-autocomplete-listbox .MuiAutocomplete-option[aria-selected=true] {\n background: var( --cardHover, var(--transwhite, rgba(255, 255, 255, 0.05)) ) !important;\n color: var(--neutralLight1, var(--white, #fff)) !important;\n}\n.ls-variable-option {\n gap: 0.75rem;\n}\n.ls-variable-option__thumb {\n width: 40px;\n height: 40px;\n flex: 0 0 40px;\n border-radius: var(--radius, 1rem);\n object-fit: cover;\n}\n.ls-variable-option__thumb--placeholder {\n background: var(--neutralDark4, var(--cardborder, #393853));\n}\n.ls-variable-option__body {\n min-width: 0;\n}\n.ls-variable-option__label {\n color: var(--neutralLight1, var(--white, #fff));\n font-weight: 500;\n line-height: 1.25;\n}\n.ls-variable-option__helper {\n margin-top: 0.125rem;\n color: var(--neutralLight3, var(--grey, #9392a1));\n font-size: 0.875rem;\n line-height: 1.25;\n}\n.ls-variable-autocomplete-popup-indicator,\n.ls-variable-autocomplete-popup-indicator.MuiIconButton-root,\n.ls-variable-autocomplete-popup-indicator svg {\n color: var(--neutralLight1, var(--white, #fff)) !important;\n}\n.ls-variable-autocomplete-popup-indicator svg path {\n fill: currentcolor !important;\n stroke: currentcolor !important;\n}\n.ls-variable-input-adornment,\n.ls-variable-input-adornment.MuiInputAdornment-root {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n height: 24px;\n width: 24px;\n min-width: 24px;\n margin-left: 0.35rem;\n border-radius: var(--radius, 1rem);\n background: var(--primary, #ff4076) !important;\n color: var(--alwayswhite, var(--white, #fff)) !important;\n font-weight: 800;\n line-height: 1;\n letter-spacing: 0;\n cursor: pointer;\n user-select: none;\n}\n.ls-variable-input-adornment svg,\n.ls-variable-input-adornment path {\n color: currentcolor !important;\n fill: currentcolor !important;\n stroke: currentcolor !important;\n}\n.ls-variable-input-adornment:hover,\n.ls-variable-input-adornment.MuiInputAdornment-root:hover {\n filter: brightness(1.08);\n}\n.ls-variable-input-adornment:active,\n.ls-variable-input-adornment.MuiInputAdornment-root:active {\n filter: brightness(0.96);\n}\n.mui-ls-slider-input-root {\n width: 100%;\n}\n.mui-ls-slider-input-fieldset {\n position: relative;\n min-width: 0;\n width: 100%;\n min-height: var(--ls-control-height);\n margin: 0;\n border: 2px solid var(--neutralDark4, var(--cardborder, #393853));\n border-radius: var(--radius, 1rem);\n padding: 0 0.875rem 0.5rem 0.875rem;\n background: transparent;\n color: var(--neutralLight1, var(--white, #fff));\n}\n.mui-ls-slider-input-fieldset:hover {\n border-color: var(--primary, #ff4076);\n}\n.mui-ls-slider-input-legend {\n display: block;\n width: auto;\n max-width: calc(100% - 1rem);\n margin: 0;\n padding: 0 0.25rem;\n color: var(--neutralLight1, var(--white, #fff));\n font-size: 0.875rem;\n line-height: 1.1;\n white-space: nowrap;\n}\n.mui-ls-slider-input-row {\n display: flex;\n min-width: 0;\n min-height: calc(var(--ls-control-height) - 14px);\n align-items: center;\n gap: 1rem;\n}\n.mui-ls-slider-input-row--slider {\n flex-wrap: nowrap;\n}\n.mui-ls-slider-input-row--input {\n justify-content: stretch;\n}\n.mui-ls-slider-input-value.mui-ls-input {\n margin: 0;\n}\n.mui-ls-slider-input-value.mui-ls-input .MuiFormControl-root,\n.mui-ls-slider-input-value.mui-ls-input .MuiTextField-root {\n margin: 0;\n}\n.mui-ls-slider-input-value.mui-ls-input .MuiInputBase-root {\n min-height: 36px;\n}\n.mui-ls-slider-input-value.mui-ls-input .MuiOutlinedInput-notchedOutline {\n border-color: var(--neutralDark4, var(--cardborder, #393853));\n}\n.mui-ls-slider-input-helper {\n display: block;\n margin-top: 0.25rem;\n color: var(--neutralLight3, var(--grey, #9392a1));\n font-size: 0.75rem;\n line-height: 1.25;\n}\n.ls-multi-select-value {\n display: flex;\n width: 100%;\n min-width: 0;\n flex-wrap: nowrap;\n align-items: center;\n justify-content: space-between;\n gap: 0.5rem;\n overflow: hidden;\n white-space: nowrap;\n}\n.ls-multi-select-value__label {\n min-width: 0;\n flex: 1 1 0%;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.ls-multi-select-value__count {\n flex-shrink: 0;\n white-space: nowrap;\n}\n.ls-color-picker__preview {\n position: relative;\n display: inline-block;\n width: 1.5rem;\n height: 1.5rem;\n flex-shrink: 0;\n padding: 0;\n border: 1px solid color-mix(in srgb, #fff 25%, transparent);\n border-radius: var(--radius, 1rem);\n background-size: cover;\n background-position: center;\n background-repeat: no-repeat;\n box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.25);\n color: transparent;\n line-height: 0;\n}\n.ls-color-picker__preview:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n.ls-color-picker__preview:focus {\n outline: none;\n}\n.ls-color-picker__preview:focus-visible {\n box-shadow:\n 0 0 0 2px var(--primary, #ff4076),\n 0 0 0 4px var(--neutralDark1, #1b1a28),\n 0 0 0 1px rgba(0, 0, 0, 0.25);\n}\n.ls-color-picker__gradient circle,\n.ls-color-picker__gradient polyline {\n stroke: #fff;\n}\n.ls-variable-picker {\n --variable-custom-color: var(--customVariables, #69ffd2);\n --variable-function-color: var( --functionVariables, var(--semanticPurple, #b489ff) );\n --variable-normal-color: var(--normalVariables, var(--semanticBlue, #65b8ff));\n display: flex;\n width: 92vw;\n max-width: 1100px;\n min-height: 50vh;\n max-height: 55vh;\n flex-direction: column;\n overflow: hidden;\n padding: 1rem;\n}\n.ls-variable-picker__field {\n margin: 0 0 0.75rem;\n border: 1px solid color-mix(in srgb, var(--primary, #ff4076) 42%, var(--neutralDark4, #393853));\n border-radius: var(--radius, 1rem);\n padding: 0.5rem;\n}\n.ls-variable-picker__legend {\n padding-inline: 0.375rem;\n color: var(--primary, #ff4076);\n font-size: 0.75rem;\n font-weight: 700;\n}\n.ls-variable-picker__intro {\n margin-bottom: 1rem;\n color: var(--neutralLight2, #cac9d5);\n}\n.ls-variable-picker__header,\n.ls-variable-picker__row {\n display: grid;\n grid-template-columns: minmax(300px, 1.5fr) 1fr 1fr;\n gap: 2rem;\n}\n.ls-variable-picker__header {\n margin-bottom: 0.25rem;\n padding-inline: 0.25rem;\n padding-right: 1.7rem;\n color: var(--neutralLight3, #9392a1);\n}\n.ls-variable-picker__list {\n height: 100%;\n overflow: auto;\n padding-right: 1rem;\n}\n.ls-variable-picker__row {\n cursor: pointer;\n align-items: start;\n border-bottom: 1px solid color-mix(in srgb, var(--neutralDark4, #393853) 70%, transparent);\n padding: 1rem 0.25rem;\n}\n.ls-variable-picker__row--no-border {\n border-bottom: 0;\n}\n.ls-variable-picker__token-cell {\n display: flex;\n min-width: 0;\n align-items: center;\n gap: 0.375rem;\n}\n.ls-variable-picker__expand-toggle,\n.ls-variable-picker__expand-spacer {\n width: 24px;\n height: 24px;\n flex: 0 0 24px;\n}\n.ls-variable-picker__expand-toggle {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border: 1px solid color-mix(in srgb, var(--neutralDark4, #393853) 75%, transparent);\n border-radius: var(--radius, 1rem);\n padding: 0;\n background: var(--neutralDark3, var(--containerbackground, #1f1f3a));\n color: var(--neutralLight2, #cac9d5);\n transition:\n background-color 140ms ease,\n border-color 140ms ease,\n color 140ms ease,\n transform 140ms ease;\n}\n.ls-variable-picker__expand-toggle:hover {\n border-color: var(--primary, #ff4076);\n background: color-mix(in srgb, var(--primary, #ff4076) 16%, var(--neutralDark3, #1f1f3a));\n color: var(--neutralLight1, #fff);\n}\n.ls-variable-picker__expand-toggle svg {\n transform: rotate(-90deg);\n transition: transform 140ms ease;\n}\n.ls-variable-picker__expand-toggle--expanded svg {\n transform: rotate(0deg);\n}\n.ls-variable-picker__row:active {\n opacity: 0.8;\n}\n.ls-variable-picker__description {\n max-width: 600px;\n overflow-wrap: break-word;\n line-height: 1.25;\n word-break: break-all;\n}\n.ls-variable-picker__value {\n min-width: 0;\n}\n.ls-variable-picker__value-input {\n width: 100%;\n min-width: 0;\n cursor: text;\n overflow: hidden;\n border: 0;\n background: transparent;\n color: var(--neutralLight1, var(--white, #fff));\n caret-color: transparent;\n font: inherit;\n font-size: 1rem;\n line-height: 1.25;\n outline: 0;\n padding: 0;\n text-overflow: ellipsis;\n}\n.ls-variable-picker__value-input:focus {\n outline: 0;\n}\n.ls-variable-picker__value-input::selection {\n background: color-mix(in srgb, var(--primary, #ff4076) 45%, transparent);\n color: var(--alwayswhite, var(--white, #fff));\n}\n.ls-variable-token {\n display: flex;\n min-width: 0;\n align-items: center;\n}\n.ls-variable-token--suggested {\n color: var(--suggestedVariables, #ffb469);\n}\n.ls-variable-token--custom {\n color: var(--customVariables, #69ffd2);\n}\n.ls-variable-token--function {\n color: var(--functionVariables, var(--semanticPurple, #b489ff));\n}\n.ls-variable-token--system {\n color: var(--normalVariables, var(--semanticBlue, #65b8ff));\n}\n.ls-variable-token__name {\n min-width: 0;\n word-break: break-all;\n}\n.ls-variable-token__badge {\n display: inline-flex;\n margin-left: 0.5rem;\n flex-shrink: 0;\n align-items: center;\n border: 1px solid currentcolor;\n border-radius: var(--radius, 1rem);\n padding-inline: 0.25rem;\n padding-block: 0;\n font-size: 10px;\n font-weight: 600;\n line-height: 1;\n text-transform: uppercase;\n}\n");
|
|
25
25
|
|
|
26
26
|
// src/components/LSButton/LSButton.tsx
|
|
27
27
|
import Button from "@mui/material/Button";
|
|
@@ -93,9 +93,6 @@ var LSInput = forwardRef(
|
|
|
93
93
|
inputAfterText,
|
|
94
94
|
maxWidth,
|
|
95
95
|
className = "",
|
|
96
|
-
InputProps: inputPropsProp,
|
|
97
|
-
InputLabelProps: inputLabelPropsProp,
|
|
98
|
-
inputProps: htmlInputPropsProp,
|
|
99
96
|
slotProps: slotPropsProp,
|
|
100
97
|
onChange,
|
|
101
98
|
onChangeStart,
|
|
@@ -130,25 +127,11 @@ var LSInput = forwardRef(
|
|
|
130
127
|
onChange?.(event, sanitizedValue);
|
|
131
128
|
onChangeEnd?.(event, sanitizedValue);
|
|
132
129
|
};
|
|
133
|
-
const
|
|
134
|
-
const
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
endAdornment: resolvedEndAdornment,
|
|
139
|
-
readOnly: rest.readOnly ?? inputPropsProp?.readOnly,
|
|
140
|
-
sx: {
|
|
141
|
-
...inputPropsProp?.sx ?? {},
|
|
142
|
-
"& input, & textarea": {
|
|
143
|
-
textAlign: centerText ? "center" : void 0,
|
|
144
|
-
color: textColor ?? void 0
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
};
|
|
148
|
-
const inputLabelProps = {
|
|
149
|
-
shrink: true,
|
|
150
|
-
...inputLabelPropsProp
|
|
151
|
-
};
|
|
130
|
+
const callerInputSlot = slotPropsProp?.input ?? {};
|
|
131
|
+
const callerHtmlInputSlot = slotPropsProp?.htmlInput ?? {};
|
|
132
|
+
const callerInputLabelSlot = slotPropsProp?.inputLabel ?? {};
|
|
133
|
+
const resolvedStartAdornment = callerInputSlot.startAdornment ?? (startAdornment ? /* @__PURE__ */ jsx2(InputAdornment, { position: "start", children: startAdornment }) : inputBeforeText ? /* @__PURE__ */ jsx2(InputAdornment, { position: "start", children: /* @__PURE__ */ jsx2("span", { className: "mui-ls-input-affix", children: inputBeforeText }) }) : void 0);
|
|
134
|
+
const resolvedEndAdornment = callerInputSlot.endAdornment ?? (endAdornment ? /* @__PURE__ */ jsx2(InputAdornment, { position: "end", children: endAdornment }) : inputAfterText ? /* @__PURE__ */ jsx2(InputAdornment, { position: "end", children: /* @__PURE__ */ jsx2("span", { className: "mui-ls-input-affix", children: inputAfterText }) }) : void 0);
|
|
152
135
|
const helperContent = helperText ?? (typeof error === "string" ? error : "");
|
|
153
136
|
const hasError = typeof error === "string" ? true : Boolean(error);
|
|
154
137
|
const resolvedMaxWidth = maxWidth ?? style?.maxWidth;
|
|
@@ -156,20 +139,24 @@ var LSInput = forwardRef(
|
|
|
156
139
|
const slotProps = {
|
|
157
140
|
...slotPropsProp ?? {},
|
|
158
141
|
input: {
|
|
159
|
-
...
|
|
160
|
-
|
|
142
|
+
...callerInputSlot,
|
|
143
|
+
startAdornment: resolvedStartAdornment,
|
|
144
|
+
endAdornment: resolvedEndAdornment,
|
|
145
|
+
readOnly: rest.readOnly ?? callerInputSlot.readOnly,
|
|
161
146
|
sx: {
|
|
162
|
-
...
|
|
163
|
-
|
|
147
|
+
...callerInputSlot.sx ?? {},
|
|
148
|
+
"& input, & textarea": {
|
|
149
|
+
textAlign: centerText ? "center" : void 0,
|
|
150
|
+
color: textColor ?? void 0
|
|
151
|
+
}
|
|
164
152
|
}
|
|
165
153
|
},
|
|
166
154
|
inputLabel: {
|
|
167
|
-
|
|
168
|
-
...
|
|
155
|
+
shrink: true,
|
|
156
|
+
...callerInputLabelSlot
|
|
169
157
|
},
|
|
170
158
|
htmlInput: {
|
|
171
|
-
...
|
|
172
|
-
...htmlInputPropsProp ?? {}
|
|
159
|
+
...callerHtmlInputSlot
|
|
173
160
|
}
|
|
174
161
|
};
|
|
175
162
|
const TextFieldComponent = TextField;
|
|
@@ -359,15 +346,15 @@ var LSSliderInput = ({
|
|
|
359
346
|
onChange: (_event, nextValue) => handleInputChange({ target: { value: nextValue ?? "" } }),
|
|
360
347
|
value: displayValue ?? "",
|
|
361
348
|
inputAfterText,
|
|
362
|
-
|
|
363
|
-
...inputProps?.
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
349
|
+
slotProps: {
|
|
350
|
+
...inputProps?.slotProps ?? {},
|
|
351
|
+
htmlInput: {
|
|
352
|
+
...inputProps?.slotProps?.htmlInput ?? {},
|
|
353
|
+
min: displayMinimum,
|
|
354
|
+
max: displayMaximum,
|
|
355
|
+
step: displayStep,
|
|
356
|
+
inputMode: stepPrecision > 0 ? "decimal" : "numeric"
|
|
357
|
+
}
|
|
371
358
|
},
|
|
372
359
|
fullWidth: hideSlider ? fullWidth : false,
|
|
373
360
|
$noMinHeight: false,
|
|
@@ -431,6 +418,16 @@ var LSSelect = ({
|
|
|
431
418
|
border: "1px solid var(--neutralDark4)",
|
|
432
419
|
borderRadius: "var(--radius, 1rem)",
|
|
433
420
|
boxShadow: "0 16px 32px rgba(0, 0, 0, 0.32)",
|
|
421
|
+
"& .MuiList-root": {
|
|
422
|
+
backgroundColor: "var(--neutralDark2)"
|
|
423
|
+
},
|
|
424
|
+
"& .MuiListSubheader-root": {
|
|
425
|
+
backgroundColor: "var(--neutralDark1)",
|
|
426
|
+
color: "var(--neutralLight2)"
|
|
427
|
+
},
|
|
428
|
+
"& .MuiMenuItem-root": {
|
|
429
|
+
color: "var(--neutralLight1)"
|
|
430
|
+
},
|
|
434
431
|
...MenuProps?.slotProps?.paper?.sx
|
|
435
432
|
}
|
|
436
433
|
},
|
|
@@ -442,28 +439,6 @@ var LSSelect = ({
|
|
|
442
439
|
...MenuProps?.slotProps?.list?.sx
|
|
443
440
|
}
|
|
444
441
|
}
|
|
445
|
-
},
|
|
446
|
-
PaperProps: {
|
|
447
|
-
...MenuProps?.PaperProps ?? {},
|
|
448
|
-
sx: {
|
|
449
|
-
background: "var(--neutralDark2) !important",
|
|
450
|
-
backgroundColor: "var(--neutralDark2)",
|
|
451
|
-
color: "var(--neutralLight1)",
|
|
452
|
-
border: "1px solid var(--neutralDark4)",
|
|
453
|
-
borderRadius: "var(--radius, 1rem)",
|
|
454
|
-
boxShadow: "0 16px 32px rgba(0, 0, 0, 0.32)",
|
|
455
|
-
"& .MuiList-root": {
|
|
456
|
-
backgroundColor: "var(--neutralDark2)"
|
|
457
|
-
},
|
|
458
|
-
"& .MuiListSubheader-root": {
|
|
459
|
-
backgroundColor: "var(--neutralDark1)",
|
|
460
|
-
color: "var(--neutralLight2)"
|
|
461
|
-
},
|
|
462
|
-
"& .MuiMenuItem-root": {
|
|
463
|
-
color: "var(--neutralLight1)"
|
|
464
|
-
},
|
|
465
|
-
...MenuProps?.PaperProps?.sx
|
|
466
|
-
}
|
|
467
442
|
}
|
|
468
443
|
};
|
|
469
444
|
return /* @__PURE__ */ jsxs2(
|
|
@@ -783,14 +758,7 @@ LSDatePicker.displayName = "LSDatePicker";
|
|
|
783
758
|
import { KeyboardArrowDown } from "@mui/icons-material";
|
|
784
759
|
import Autocomplete from "@mui/material/Autocomplete";
|
|
785
760
|
import TextField2 from "@mui/material/TextField";
|
|
786
|
-
import {
|
|
787
|
-
memo,
|
|
788
|
-
startTransition,
|
|
789
|
-
useEffect as useEffect3,
|
|
790
|
-
useMemo as useMemo2,
|
|
791
|
-
useRef as useRef2,
|
|
792
|
-
useState as useState3
|
|
793
|
-
} from "react";
|
|
761
|
+
import { memo, startTransition, useEffect as useEffect3, useMemo as useMemo2, useRef as useRef2, useState as useState3 } from "react";
|
|
794
762
|
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
795
763
|
var LSFontPicker = memo(function LSFontPicker2({
|
|
796
764
|
value,
|
|
@@ -848,9 +816,7 @@ var LSFontPicker = memo(function LSFontPicker2({
|
|
|
848
816
|
popupIcon: /* @__PURE__ */ jsx8(KeyboardArrowDown, {}),
|
|
849
817
|
isOptionEqualToValue: (option, selectedValue) => option === selectedValue,
|
|
850
818
|
onChange: (_event, newValue) => {
|
|
851
|
-
handleValueChange(
|
|
852
|
-
typeof newValue === "string" ? newValue : `${newValue ?? ""}`
|
|
853
|
-
);
|
|
819
|
+
handleValueChange(typeof newValue === "string" ? newValue : `${newValue ?? ""}`);
|
|
854
820
|
},
|
|
855
821
|
onInputChange: (_event, newInputValue, reason) => {
|
|
856
822
|
if (reason === "input" || reason === "clear") {
|
|
@@ -907,11 +873,7 @@ var LSFontPicker = memo(function LSFontPicker2({
|
|
|
907
873
|
);
|
|
908
874
|
},
|
|
909
875
|
renderInput: (params) => {
|
|
910
|
-
const {
|
|
911
|
-
InputLabelProps: paramsInputLabelProps,
|
|
912
|
-
InputProps: paramsInputProps,
|
|
913
|
-
...restParams
|
|
914
|
-
} = params;
|
|
876
|
+
const { slotProps: paramsSlotProps = {}, ...restParams } = params;
|
|
915
877
|
return /* @__PURE__ */ jsx8(
|
|
916
878
|
TextFieldComponent,
|
|
917
879
|
{
|
|
@@ -928,12 +890,16 @@ var LSFontPicker = memo(function LSFontPicker2({
|
|
|
928
890
|
}
|
|
929
891
|
},
|
|
930
892
|
slotProps: {
|
|
893
|
+
...paramsSlotProps,
|
|
931
894
|
inputLabel: {
|
|
932
|
-
|
|
933
|
-
|
|
895
|
+
...paramsSlotProps.inputLabel ?? {},
|
|
896
|
+
shrink: true
|
|
934
897
|
},
|
|
935
898
|
input: {
|
|
936
|
-
...
|
|
899
|
+
...paramsSlotProps.input ?? {}
|
|
900
|
+
},
|
|
901
|
+
htmlInput: {
|
|
902
|
+
...paramsSlotProps.htmlInput ?? {}
|
|
937
903
|
}
|
|
938
904
|
}
|
|
939
905
|
}
|
|
@@ -976,6 +942,12 @@ var LSMultiSelect = ({
|
|
|
976
942
|
/* @__PURE__ */ jsx9("div", { className: "ls-multi-select-value__count", children: `(${selected.length})` })
|
|
977
943
|
] }),
|
|
978
944
|
MenuProps: {
|
|
945
|
+
// The previous version of this also set `PaperProps` here — that
|
|
946
|
+
// prop was removed from Menu in @mui/material v9 and React warns
|
|
947
|
+
// "does not recognize the `PaperProps` prop on a DOM element"
|
|
948
|
+
// when Menu spreads it through. Folded the one unique selector
|
|
949
|
+
// (`& .MuiList-root`) into `slotProps.paper.sx` below; everything
|
|
950
|
+
// else was already duplicated there.
|
|
979
951
|
slotProps: {
|
|
980
952
|
paper: {
|
|
981
953
|
sx: {
|
|
@@ -987,7 +959,10 @@ var LSMultiSelect = ({
|
|
|
987
959
|
boxShadow: "0 16px 32px rgba(0, 0, 0, 0.32)",
|
|
988
960
|
backdropFilter: "none",
|
|
989
961
|
opacity: 1,
|
|
990
|
-
maxHeight: "280px !important"
|
|
962
|
+
maxHeight: "280px !important",
|
|
963
|
+
"& .MuiList-root": {
|
|
964
|
+
backgroundColor: "var(--neutralDark2)"
|
|
965
|
+
}
|
|
991
966
|
}
|
|
992
967
|
},
|
|
993
968
|
list: {
|
|
@@ -996,21 +971,6 @@ var LSMultiSelect = ({
|
|
|
996
971
|
color: "var(--neutralLight1)"
|
|
997
972
|
}
|
|
998
973
|
}
|
|
999
|
-
},
|
|
1000
|
-
PaperProps: {
|
|
1001
|
-
sx: {
|
|
1002
|
-
background: "var(--neutralDark2) !important",
|
|
1003
|
-
backgroundColor: "var(--neutralDark2)",
|
|
1004
|
-
color: "var(--neutralLight1)",
|
|
1005
|
-
backdropFilter: "none",
|
|
1006
|
-
opacity: 1,
|
|
1007
|
-
maxHeight: "280px !important",
|
|
1008
|
-
border: "1px solid var(--neutralDark4)",
|
|
1009
|
-
borderRadius: "var(--radius, 1rem)",
|
|
1010
|
-
"& .MuiList-root": {
|
|
1011
|
-
backgroundColor: "var(--neutralDark2)"
|
|
1012
|
-
}
|
|
1013
|
-
}
|
|
1014
974
|
}
|
|
1015
975
|
},
|
|
1016
976
|
children: options.map((option) => /* @__PURE__ */ jsxs4(
|
|
@@ -1077,7 +1037,8 @@ import { forwardRef as forwardRef4 } from "react";
|
|
|
1077
1037
|
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
1078
1038
|
var LSTextField = forwardRef4(
|
|
1079
1039
|
(props, ref) => {
|
|
1080
|
-
const {
|
|
1040
|
+
const { slotProps, ...rest } = props;
|
|
1041
|
+
const paramsInputLabel = slotProps?.inputLabel ?? {};
|
|
1081
1042
|
return /* @__PURE__ */ jsx11(
|
|
1082
1043
|
TextField3,
|
|
1083
1044
|
{
|
|
@@ -1086,18 +1047,9 @@ var LSTextField = forwardRef4(
|
|
|
1086
1047
|
className: "mui-ls-input",
|
|
1087
1048
|
slotProps: {
|
|
1088
1049
|
...slotProps ?? {},
|
|
1089
|
-
input: {
|
|
1090
|
-
...slotProps?.input ?? {},
|
|
1091
|
-
...InputProps ?? {},
|
|
1092
|
-
sx: {
|
|
1093
|
-
...slotProps?.input?.sx ?? {},
|
|
1094
|
-
...InputProps?.sx ?? {}
|
|
1095
|
-
}
|
|
1096
|
-
},
|
|
1097
1050
|
inputLabel: {
|
|
1098
|
-
...
|
|
1099
|
-
shrink: true
|
|
1100
|
-
...InputLabelProps ?? {}
|
|
1051
|
+
...paramsInputLabel,
|
|
1052
|
+
shrink: true
|
|
1101
1053
|
}
|
|
1102
1054
|
},
|
|
1103
1055
|
ref
|
|
@@ -2256,14 +2208,12 @@ var VariableInputTextField = forwardRef5(
|
|
|
2256
2208
|
containerRef,
|
|
2257
2209
|
showVariableIcon
|
|
2258
2210
|
}, ref) => {
|
|
2259
|
-
const
|
|
2260
|
-
const
|
|
2261
|
-
const inputPropsSlotInputProps = inputProps?.slotProps?.input ?? {};
|
|
2262
|
-
const paramsSlotInputProps = params?.slotProps?.input ?? {};
|
|
2211
|
+
const inputPropsSlotInput = inputProps?.slotProps?.input ?? {};
|
|
2212
|
+
const paramsSlotInput = params?.slotProps?.input ?? {};
|
|
2263
2213
|
const explicitStartAdornment = inputProps?.startAdornment;
|
|
2264
2214
|
const resolvedExplicitStartAdornment = explicitStartAdornment ? /* @__PURE__ */ jsx12(InputAdornment2, { position: "start", children: explicitStartAdornment }) : void 0;
|
|
2265
|
-
const startAdornment =
|
|
2266
|
-
const endAdornment =
|
|
2215
|
+
const startAdornment = paramsSlotInput.startAdornment ?? inputPropsSlotInput.startAdornment ?? resolvedExplicitStartAdornment;
|
|
2216
|
+
const endAdornment = paramsSlotInput.endAdornment ?? inputPropsSlotInput.endAdornment;
|
|
2267
2217
|
return /* @__PURE__ */ jsx12(
|
|
2268
2218
|
LSTextField,
|
|
2269
2219
|
{
|
|
@@ -2285,31 +2235,27 @@ var VariableInputTextField = forwardRef5(
|
|
|
2285
2235
|
onChange: onChange ? (e) => onChange(e.target.value) : void 0,
|
|
2286
2236
|
...inputProps,
|
|
2287
2237
|
...params,
|
|
2288
|
-
|
|
2289
|
-
...
|
|
2290
|
-
...
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
endAdornment
|
|
2296
|
-
|
|
2297
|
-
Tooltip,
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
)
|
|
2310
|
-
}
|
|
2311
|
-
) : null
|
|
2312
|
-
] })
|
|
2238
|
+
slotProps: {
|
|
2239
|
+
...inputProps?.slotProps ?? {},
|
|
2240
|
+
...params?.slotProps ?? {},
|
|
2241
|
+
input: {
|
|
2242
|
+
...inputPropsSlotInput,
|
|
2243
|
+
...paramsSlotInput,
|
|
2244
|
+
startAdornment,
|
|
2245
|
+
endAdornment: /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
2246
|
+
endAdornment ?? null,
|
|
2247
|
+
showVariableIcon ? /* @__PURE__ */ jsx12(Tooltip, { title: t("chatbot.allowed-variables", "Allowed Variables"), children: /* @__PURE__ */ jsx12(
|
|
2248
|
+
InputAdornment2,
|
|
2249
|
+
{
|
|
2250
|
+
position: "end",
|
|
2251
|
+
onClick: clickedVariableIcon,
|
|
2252
|
+
ref: containerRef,
|
|
2253
|
+
className: "ls-variable-input-adornment",
|
|
2254
|
+
children: "{}"
|
|
2255
|
+
}
|
|
2256
|
+
) }) : null
|
|
2257
|
+
] })
|
|
2258
|
+
}
|
|
2313
2259
|
},
|
|
2314
2260
|
inputRef: ref
|
|
2315
2261
|
}
|
|
@@ -3133,7 +3079,7 @@ var resolveChatterProfileUrlWithResolvers = async ({
|
|
|
3133
3079
|
};
|
|
3134
3080
|
|
|
3135
3081
|
// src/se-import/index.ts
|
|
3136
|
-
import { nanoid as
|
|
3082
|
+
import { nanoid as nanoid8 } from "nanoid";
|
|
3137
3083
|
|
|
3138
3084
|
// src/se-import/translate.ts
|
|
3139
3085
|
var SE_TO_LUMIA_PLACEHOLDER = {
|
|
@@ -4184,26 +4130,55 @@ function mapText(widget, ctx) {
|
|
|
4184
4130
|
ctx
|
|
4185
4131
|
);
|
|
4186
4132
|
}
|
|
4133
|
+
function seInnerAutoFit(widget, innerCss, mode) {
|
|
4134
|
+
const isInnerAutoWidth = innerCss?.width === "auto";
|
|
4135
|
+
const isInnerAutoHeight = innerCss?.height === "auto";
|
|
4136
|
+
if (mode === "width-drives-both") {
|
|
4137
|
+
if (!isInnerAutoWidth) return {};
|
|
4138
|
+
return { objectFit: "contain", autoWidth: true, autoHeight: true };
|
|
4139
|
+
}
|
|
4140
|
+
if (!isInnerAutoWidth && !isInnerAutoHeight) return {};
|
|
4141
|
+
const result = { objectFit: "contain" };
|
|
4142
|
+
if (isInnerAutoWidth && !isExplicitPxSize(widget.css?.width))
|
|
4143
|
+
result.autoWidth = true;
|
|
4144
|
+
if (isInnerAutoHeight && !isExplicitPxSize(widget.css?.height))
|
|
4145
|
+
result.autoHeight = true;
|
|
4146
|
+
return result;
|
|
4147
|
+
}
|
|
4148
|
+
function applySeAutoFitBounds(unit, fit) {
|
|
4149
|
+
const bounds = unit.layer.bounds;
|
|
4150
|
+
if (fit.autoWidth) bounds.autoWidth = true;
|
|
4151
|
+
if (fit.autoHeight) bounds.autoHeight = true;
|
|
4152
|
+
}
|
|
4187
4153
|
function mapImage(widget, ctx) {
|
|
4154
|
+
const fit = seInnerAutoFit(widget, widget.image?.css, "inner-axis-gated");
|
|
4188
4155
|
const unit = buildUnit(
|
|
4189
4156
|
widget,
|
|
4190
4157
|
"image",
|
|
4191
4158
|
{
|
|
4192
4159
|
content: {
|
|
4193
4160
|
src: widget.image?.src ?? "",
|
|
4194
|
-
loop: true
|
|
4161
|
+
loop: true,
|
|
4162
|
+
...fit.objectFit ? { objectFit: fit.objectFit } : {}
|
|
4195
4163
|
}
|
|
4196
4164
|
},
|
|
4197
4165
|
ctx
|
|
4198
4166
|
);
|
|
4199
|
-
|
|
4200
|
-
const innerHeight = widget.image?.css?.height;
|
|
4201
|
-
const bounds = unit.layer.bounds;
|
|
4202
|
-
if (innerWidth === "auto") bounds.autoWidth = true;
|
|
4203
|
-
if (innerHeight === "auto") bounds.autoHeight = true;
|
|
4167
|
+
applySeAutoFitBounds(unit, fit);
|
|
4204
4168
|
return unit;
|
|
4205
4169
|
}
|
|
4170
|
+
function isExplicitPxSize(value) {
|
|
4171
|
+
if (value == null) return false;
|
|
4172
|
+
if (typeof value === "number") return Number.isFinite(value) && value > 0;
|
|
4173
|
+
if (typeof value !== "string") return false;
|
|
4174
|
+
const s = value.trim().toLowerCase();
|
|
4175
|
+
if (s === "" || s === "auto") return false;
|
|
4176
|
+
if (s.endsWith("%")) return false;
|
|
4177
|
+
const parsed = parseFloat(s);
|
|
4178
|
+
return Number.isFinite(parsed) && parsed > 0;
|
|
4179
|
+
}
|
|
4206
4180
|
function mapVideo(widget, ctx) {
|
|
4181
|
+
const fit = seInnerAutoFit(widget, widget.video?.css, "width-drives-both");
|
|
4207
4182
|
const unit = buildUnit(
|
|
4208
4183
|
widget,
|
|
4209
4184
|
"video",
|
|
@@ -4217,6 +4192,7 @@ function mapVideo(widget, ctx) {
|
|
|
4217
4192
|
},
|
|
4218
4193
|
ctx
|
|
4219
4194
|
);
|
|
4195
|
+
applySeAutoFitBounds(unit, fit);
|
|
4220
4196
|
unit.layer.bounds.autoHeight = true;
|
|
4221
4197
|
return unit;
|
|
4222
4198
|
}
|
|
@@ -4276,118 +4252,157 @@ function mapReadout(widget, fallbackVar, ctx) {
|
|
|
4276
4252
|
|
|
4277
4253
|
// src/se-import/mappers/alert.ts
|
|
4278
4254
|
import { LumiaAlertConfigs } from "@lumiastream/lumia-types";
|
|
4255
|
+
import { nanoid as nanoid2 } from "nanoid";
|
|
4256
|
+
|
|
4257
|
+
// src/se-import/import-utils.ts
|
|
4258
|
+
function pxToNumber(raw, fallback) {
|
|
4259
|
+
if (typeof raw === "number" && Number.isFinite(raw)) return raw;
|
|
4260
|
+
if (typeof raw !== "string") return fallback;
|
|
4261
|
+
const trimmed = raw.trim();
|
|
4262
|
+
if (!trimmed) return fallback;
|
|
4263
|
+
if (trimmed.endsWith("px")) {
|
|
4264
|
+
const n2 = parseFloat(trimmed.slice(0, -2));
|
|
4265
|
+
return Number.isFinite(n2) ? n2 : fallback;
|
|
4266
|
+
}
|
|
4267
|
+
const n = parseFloat(trimmed);
|
|
4268
|
+
return Number.isFinite(n) ? n : fallback;
|
|
4269
|
+
}
|
|
4270
|
+
function parseDurationMs(raw, fallbackMs) {
|
|
4271
|
+
if (typeof raw === "number" && Number.isFinite(raw)) return raw;
|
|
4272
|
+
if (typeof raw !== "string") return fallbackMs;
|
|
4273
|
+
const trimmed = raw.trim();
|
|
4274
|
+
if (!trimmed) return fallbackMs;
|
|
4275
|
+
if (trimmed.endsWith("ms")) {
|
|
4276
|
+
const n2 = parseFloat(trimmed.slice(0, -2));
|
|
4277
|
+
return Number.isFinite(n2) ? n2 : fallbackMs;
|
|
4278
|
+
}
|
|
4279
|
+
if (trimmed.endsWith("s")) {
|
|
4280
|
+
const n2 = parseFloat(trimmed.slice(0, -1));
|
|
4281
|
+
return Number.isFinite(n2) ? n2 * 1e3 : fallbackMs;
|
|
4282
|
+
}
|
|
4283
|
+
const n = parseFloat(trimmed);
|
|
4284
|
+
return Number.isFinite(n) ? n : fallbackMs;
|
|
4285
|
+
}
|
|
4286
|
+
function buildImportDescription(head, sourceUrl) {
|
|
4287
|
+
if (typeof sourceUrl === "string" && sourceUrl.trim().length > 0) {
|
|
4288
|
+
return `${head}
|
|
4289
|
+
Source: ${sourceUrl.trim()}`;
|
|
4290
|
+
}
|
|
4291
|
+
return head;
|
|
4292
|
+
}
|
|
4279
4293
|
|
|
4280
4294
|
// src/se-import/mappers/provider-alerts.ts
|
|
4295
|
+
import { LumiaAlertValues } from "@lumiastream/lumia-types";
|
|
4281
4296
|
var ALERT_BOX_KEYS = {
|
|
4282
4297
|
twitch: {
|
|
4283
|
-
follower: [
|
|
4284
|
-
subscriber: [
|
|
4285
|
-
tip: [
|
|
4286
|
-
cheer: [
|
|
4287
|
-
raid: [
|
|
4288
|
-
merch: [
|
|
4289
|
-
purchase: [
|
|
4290
|
-
charityCampaignDonation: [
|
|
4298
|
+
follower: [LumiaAlertValues.TWITCH_FOLLOWER],
|
|
4299
|
+
subscriber: [LumiaAlertValues.TWITCH_SUBSCRIBER],
|
|
4300
|
+
tip: [LumiaAlertValues.LUMIASTREAM_DONATION, LumiaAlertValues.STREAMELEMENTS_DONATION],
|
|
4301
|
+
cheer: [LumiaAlertValues.TWITCH_BITS],
|
|
4302
|
+
raid: [LumiaAlertValues.TWITCH_RAID],
|
|
4303
|
+
merch: [LumiaAlertValues.FOURTHWALL_SHOPORDER],
|
|
4304
|
+
purchase: [LumiaAlertValues.FOURTHWALL_SHOPORDER],
|
|
4305
|
+
charityCampaignDonation: [LumiaAlertValues.TWITCH_CHARITY_DONATION]
|
|
4291
4306
|
},
|
|
4292
4307
|
kick: {
|
|
4293
|
-
follower: [
|
|
4294
|
-
subscriber: [
|
|
4295
|
-
tip: [
|
|
4296
|
-
cheer: [
|
|
4297
|
-
raid: [
|
|
4298
|
-
host: [
|
|
4299
|
-
merch: [
|
|
4300
|
-
purchase: [
|
|
4308
|
+
follower: [LumiaAlertValues.KICK_FOLLOWER],
|
|
4309
|
+
subscriber: [LumiaAlertValues.KICK_SUBSCRIBER],
|
|
4310
|
+
tip: [LumiaAlertValues.LUMIASTREAM_DONATION, LumiaAlertValues.STREAMELEMENTS_DONATION],
|
|
4311
|
+
cheer: [LumiaAlertValues.KICK_KICKS],
|
|
4312
|
+
raid: [LumiaAlertValues.KICK_HOST],
|
|
4313
|
+
host: [LumiaAlertValues.KICK_HOST],
|
|
4314
|
+
merch: [LumiaAlertValues.FOURTHWALL_SHOPORDER],
|
|
4315
|
+
purchase: [LumiaAlertValues.FOURTHWALL_SHOPORDER]
|
|
4301
4316
|
},
|
|
4302
4317
|
youtube: {
|
|
4303
|
-
follower: [
|
|
4304
|
-
subscriber: [
|
|
4305
|
-
tip: [
|
|
4306
|
-
cheer: [
|
|
4307
|
-
merch: [
|
|
4308
|
-
purchase: [
|
|
4318
|
+
follower: [LumiaAlertValues.YOUTUBE_SUBSCRIBER],
|
|
4319
|
+
subscriber: [LumiaAlertValues.YOUTUBE_MEMBER],
|
|
4320
|
+
tip: [LumiaAlertValues.LUMIASTREAM_DONATION, LumiaAlertValues.STREAMELEMENTS_DONATION],
|
|
4321
|
+
cheer: [LumiaAlertValues.YOUTUBE_SUPERCHAT],
|
|
4322
|
+
merch: [LumiaAlertValues.FOURTHWALL_SHOPORDER],
|
|
4323
|
+
purchase: [LumiaAlertValues.FOURTHWALL_SHOPORDER]
|
|
4309
4324
|
}
|
|
4310
4325
|
};
|
|
4311
4326
|
var KAPPAGEN_KEYS = {
|
|
4312
4327
|
twitch: {
|
|
4313
|
-
follower:
|
|
4314
|
-
subscriber:
|
|
4315
|
-
cheer:
|
|
4316
|
-
raid:
|
|
4317
|
-
tip:
|
|
4328
|
+
follower: LumiaAlertValues.TWITCH_FOLLOWER,
|
|
4329
|
+
subscriber: LumiaAlertValues.TWITCH_SUBSCRIBER,
|
|
4330
|
+
cheer: LumiaAlertValues.TWITCH_BITS,
|
|
4331
|
+
raid: LumiaAlertValues.TWITCH_RAID,
|
|
4332
|
+
tip: LumiaAlertValues.LUMIASTREAM_DONATION
|
|
4318
4333
|
},
|
|
4319
4334
|
kick: {
|
|
4320
|
-
follower:
|
|
4321
|
-
subscriber:
|
|
4322
|
-
cheer:
|
|
4323
|
-
raid:
|
|
4324
|
-
tip:
|
|
4335
|
+
follower: LumiaAlertValues.KICK_FOLLOWER,
|
|
4336
|
+
subscriber: LumiaAlertValues.KICK_SUBSCRIBER,
|
|
4337
|
+
cheer: LumiaAlertValues.KICK_KICKS,
|
|
4338
|
+
raid: LumiaAlertValues.KICK_HOST,
|
|
4339
|
+
tip: LumiaAlertValues.LUMIASTREAM_DONATION
|
|
4325
4340
|
},
|
|
4326
4341
|
youtube: {
|
|
4327
|
-
follower:
|
|
4328
|
-
subscriber:
|
|
4329
|
-
cheer:
|
|
4330
|
-
tip:
|
|
4342
|
+
follower: LumiaAlertValues.YOUTUBE_SUBSCRIBER,
|
|
4343
|
+
subscriber: LumiaAlertValues.YOUTUBE_MEMBER,
|
|
4344
|
+
cheer: LumiaAlertValues.YOUTUBE_SUPERCHAT,
|
|
4345
|
+
tip: LumiaAlertValues.LUMIASTREAM_DONATION
|
|
4331
4346
|
}
|
|
4332
4347
|
};
|
|
4333
4348
|
var STREAMBOSS_LISTENER_KEYS = {
|
|
4334
4349
|
twitch: {
|
|
4335
|
-
"follower-latest": [
|
|
4336
|
-
"subscriber-latest": [
|
|
4337
|
-
"tip-latest": [
|
|
4338
|
-
"cheer-latest": [
|
|
4339
|
-
"raid-latest": [
|
|
4350
|
+
"follower-latest": [LumiaAlertValues.TWITCH_FOLLOWER],
|
|
4351
|
+
"subscriber-latest": [LumiaAlertValues.TWITCH_SUBSCRIBER],
|
|
4352
|
+
"tip-latest": [LumiaAlertValues.LUMIASTREAM_DONATION, LumiaAlertValues.STREAMELEMENTS_DONATION],
|
|
4353
|
+
"cheer-latest": [LumiaAlertValues.TWITCH_BITS],
|
|
4354
|
+
"raid-latest": [LumiaAlertValues.TWITCH_RAID]
|
|
4340
4355
|
},
|
|
4341
4356
|
kick: {
|
|
4342
|
-
"follower-latest": [
|
|
4343
|
-
"subscriber-latest": [
|
|
4344
|
-
"tip-latest": [
|
|
4345
|
-
"cheer-latest": [
|
|
4346
|
-
"raid-latest": [
|
|
4357
|
+
"follower-latest": [LumiaAlertValues.KICK_FOLLOWER],
|
|
4358
|
+
"subscriber-latest": [LumiaAlertValues.KICK_SUBSCRIBER],
|
|
4359
|
+
"tip-latest": [LumiaAlertValues.LUMIASTREAM_DONATION, LumiaAlertValues.STREAMELEMENTS_DONATION],
|
|
4360
|
+
"cheer-latest": [LumiaAlertValues.KICK_KICKS],
|
|
4361
|
+
"raid-latest": [LumiaAlertValues.KICK_HOST]
|
|
4347
4362
|
},
|
|
4348
4363
|
youtube: {
|
|
4349
|
-
"follower-latest": [
|
|
4350
|
-
"subscriber-latest": [
|
|
4351
|
-
"tip-latest": [
|
|
4352
|
-
"cheer-latest": [
|
|
4364
|
+
"follower-latest": [LumiaAlertValues.YOUTUBE_SUBSCRIBER],
|
|
4365
|
+
"subscriber-latest": [LumiaAlertValues.YOUTUBE_MEMBER],
|
|
4366
|
+
"tip-latest": [LumiaAlertValues.LUMIASTREAM_DONATION, LumiaAlertValues.STREAMELEMENTS_DONATION],
|
|
4367
|
+
"cheer-latest": [LumiaAlertValues.YOUTUBE_SUPERCHAT]
|
|
4353
4368
|
}
|
|
4354
4369
|
};
|
|
4355
4370
|
var CURATED_ALERTS = {
|
|
4356
4371
|
twitch: [
|
|
4357
|
-
|
|
4358
|
-
|
|
4359
|
-
|
|
4360
|
-
|
|
4361
|
-
|
|
4362
|
-
|
|
4363
|
-
|
|
4364
|
-
|
|
4365
|
-
|
|
4366
|
-
|
|
4367
|
-
|
|
4368
|
-
|
|
4369
|
-
|
|
4370
|
-
|
|
4371
|
-
|
|
4372
|
+
LumiaAlertValues.TWITCH_FOLLOWER,
|
|
4373
|
+
LumiaAlertValues.TWITCH_SUBSCRIBER,
|
|
4374
|
+
LumiaAlertValues.TWITCH_GIFT_SUBSCRIPTION,
|
|
4375
|
+
LumiaAlertValues.TWITCH_BITS,
|
|
4376
|
+
LumiaAlertValues.TWITCH_BITS_COMBO,
|
|
4377
|
+
LumiaAlertValues.TWITCH_RAID,
|
|
4378
|
+
LumiaAlertValues.TWITCH_POINTS,
|
|
4379
|
+
LumiaAlertValues.TWITCH_REDEMPTION,
|
|
4380
|
+
LumiaAlertValues.TWITCH_CHARITY_DONATION,
|
|
4381
|
+
LumiaAlertValues.TWITCH_HYPETRAIN_STARTED,
|
|
4382
|
+
LumiaAlertValues.TWITCH_CLIP,
|
|
4383
|
+
LumiaAlertValues.TWITCH_SHOUTOUT_RECEIVE,
|
|
4384
|
+
LumiaAlertValues.TWITCH_WATCH_STREAK,
|
|
4385
|
+
LumiaAlertValues.TWITCH_FIRST_CHATTER,
|
|
4386
|
+
LumiaAlertValues.TWITCH_EXTENSION
|
|
4372
4387
|
],
|
|
4373
4388
|
kick: [
|
|
4374
|
-
|
|
4375
|
-
|
|
4376
|
-
|
|
4377
|
-
|
|
4378
|
-
|
|
4379
|
-
|
|
4380
|
-
|
|
4389
|
+
LumiaAlertValues.KICK_FOLLOWER,
|
|
4390
|
+
LumiaAlertValues.KICK_SUBSCRIBER,
|
|
4391
|
+
LumiaAlertValues.KICK_GIFT_SUBSCRIPTION,
|
|
4392
|
+
LumiaAlertValues.KICK_KICKS,
|
|
4393
|
+
LumiaAlertValues.KICK_HOST,
|
|
4394
|
+
LumiaAlertValues.KICK_POINTS,
|
|
4395
|
+
LumiaAlertValues.KICK_FIRST_CHATTER
|
|
4381
4396
|
],
|
|
4382
4397
|
youtube: [
|
|
4383
|
-
|
|
4384
|
-
|
|
4385
|
-
|
|
4386
|
-
|
|
4387
|
-
|
|
4388
|
-
|
|
4389
|
-
|
|
4390
|
-
|
|
4398
|
+
LumiaAlertValues.YOUTUBE_SUBSCRIBER,
|
|
4399
|
+
LumiaAlertValues.YOUTUBE_MEMBER,
|
|
4400
|
+
LumiaAlertValues.YOUTUBE_GIFT_MEMBERS,
|
|
4401
|
+
LumiaAlertValues.YOUTUBE_SUPERCHAT,
|
|
4402
|
+
LumiaAlertValues.YOUTUBE_SUPERSTICKER,
|
|
4403
|
+
LumiaAlertValues.YOUTUBE_GIFTS,
|
|
4404
|
+
LumiaAlertValues.YOUTUBE_LIKE,
|
|
4405
|
+
LumiaAlertValues.YOUTUBE_FIRST_CHATTER
|
|
4391
4406
|
]
|
|
4392
4407
|
};
|
|
4393
4408
|
function curatedAlertsFor(provider = "twitch") {
|
|
@@ -4455,8 +4470,12 @@ function buildAlertEvent(seEvent, seEventType) {
|
|
|
4455
4470
|
const shadowEnabled = text.enableShadow !== false;
|
|
4456
4471
|
const importedTextShadow = css["text-shadow"] ?? "rgba(0, 0, 0, 0.8) 1px 1px 1px";
|
|
4457
4472
|
const textShadow = shadowEnabled ? importedTextShadow : "none";
|
|
4458
|
-
const
|
|
4459
|
-
const pushTextUp =
|
|
4473
|
+
const allowPush = seLayoutUsesPushText(seEvent.layout);
|
|
4474
|
+
const pushTextUp = allowPush ? pxToNumber(css["margin-top"], 0) : 0;
|
|
4475
|
+
const pushTextLeft = allowPush ? pxToNumber(css["margin-left"], 0) : 0;
|
|
4476
|
+
const usesColumnLayout = !seEvent.layout || seEvent.layout === "column";
|
|
4477
|
+
const usesRowLayout = seEvent.layout === "row";
|
|
4478
|
+
const tightLayout = allowPush && (usesColumnLayout || usesRowLayout);
|
|
4460
4479
|
const variations = (seEvent.variations ?? []).map((variation) => buildAlertVariation(variation, seEventType, seEvent)).filter((v) => v != null);
|
|
4461
4480
|
const defaultDuration = (seEventType && SE_DEFAULT_DURATION_BY_EVENT[seEventType]) ?? 8;
|
|
4462
4481
|
return {
|
|
@@ -4483,7 +4502,7 @@ function buildAlertEvent(seEvent, seEventType) {
|
|
|
4483
4502
|
showBrandIcon: true
|
|
4484
4503
|
},
|
|
4485
4504
|
settings: { duration: (seEvent.duration ?? defaultDuration) * 1e3 },
|
|
4486
|
-
layout: { value: translateLayout(seEvent.layout), css: {}, customCss: "", pushTextUp, pushTextLeft:
|
|
4505
|
+
layout: { value: translateLayout(seEvent.layout), css: {}, customCss: "", pushTextUp, pushTextLeft, tight: tightLayout },
|
|
4487
4506
|
text: {
|
|
4488
4507
|
css: {
|
|
4489
4508
|
fontFamily: css["font-family"] ?? "Roboto",
|
|
@@ -4492,6 +4511,10 @@ function buildAlertEvent(seEvent, seEventType) {
|
|
|
4492
4511
|
fontWeight: css["font-weight"] ?? "bold",
|
|
4493
4512
|
textShadow,
|
|
4494
4513
|
textAlign: css["text-align"] ?? "center"
|
|
4514
|
+
// SE's per-event `margin-top` / `margin-left` are routed to
|
|
4515
|
+
// `layout.pushTextUp` / `layout.pushTextLeft` above (not
|
|
4516
|
+
// stamped on `text.css`) so they land in the alert editor's
|
|
4517
|
+
// dedicated sliders. See the long comment near `pushTextUp`.
|
|
4495
4518
|
},
|
|
4496
4519
|
messageCss,
|
|
4497
4520
|
content: { value: translateSeText(text.message ?? "") }
|
|
@@ -4561,6 +4584,15 @@ function buildAlertVariation(v, seEventType, parentSettings) {
|
|
|
4561
4584
|
const mergedSettings = deepMergeSeSettings(parentSettings ? parentInheritable : void 0, v.settings);
|
|
4562
4585
|
const base = buildAlertEvent(mergedSettings, seEventType);
|
|
4563
4586
|
return {
|
|
4587
|
+
// Stable per-variation ID. Lumia's alert editor (Settings.tsx) auto-
|
|
4588
|
+
// stamps a nanoid on first open for any variation missing an id, but
|
|
4589
|
+
// that leaves a window where the imported overlay's variations have
|
|
4590
|
+
// no stable key — list components rendering them key on
|
|
4591
|
+
// `variation.id || variation.name || idx` and adjacent variations
|
|
4592
|
+
// with the same name collide. Stamping at import time gives every
|
|
4593
|
+
// variation a stable identity from save #1 without waiting for the
|
|
4594
|
+
// editor's first mount.
|
|
4595
|
+
id: nanoid2(),
|
|
4564
4596
|
name: v.name ?? "Variation",
|
|
4565
4597
|
on: v.enabled !== false,
|
|
4566
4598
|
randomChance: v.chance ?? 100,
|
|
@@ -4644,7 +4676,7 @@ function mapSingleAlert(widget, lumiaAlertKey, ctx) {
|
|
|
4644
4676
|
css: { ...topCss, ...innerCss }
|
|
4645
4677
|
};
|
|
4646
4678
|
}
|
|
4647
|
-
const built = buildAlertEvent(merged);
|
|
4679
|
+
const built = buildAlertEvent(merged, void 0);
|
|
4648
4680
|
const events = {
|
|
4649
4681
|
[lumiaAlertKey]: built
|
|
4650
4682
|
};
|
|
@@ -4790,7 +4822,7 @@ function mapGoal(widget, ctx) {
|
|
|
4790
4822
|
}
|
|
4791
4823
|
|
|
4792
4824
|
// src/se-import/mappers/custom.ts
|
|
4793
|
-
import { nanoid as
|
|
4825
|
+
import { nanoid as nanoid3 } from "nanoid";
|
|
4794
4826
|
var SOURCE_TO_LUMIA_FIELD_TYPE = {
|
|
4795
4827
|
text: "input",
|
|
4796
4828
|
number: "number",
|
|
@@ -4880,7 +4912,7 @@ function mapCustom(widget, ctx) {
|
|
|
4880
4912
|
// imports — codeId is the scoping key for variables, storage, and
|
|
4881
4913
|
// event listeners. Mint a fresh nanoid so every imported widget
|
|
4882
4914
|
// has its own scope.
|
|
4883
|
-
codeId:
|
|
4915
|
+
codeId: nanoid3(),
|
|
4884
4916
|
html: v.html ?? "",
|
|
4885
4917
|
css: v.css ?? "",
|
|
4886
4918
|
js: v.js ?? "",
|
|
@@ -5017,6 +5049,63 @@ var TIPJAR_DEFAULT_MODULE = {
|
|
|
5017
5049
|
version: 1,
|
|
5018
5050
|
content: TIPJAR_DEFAULT_CONTENT_FIELDS
|
|
5019
5051
|
};
|
|
5052
|
+
var EVENTLIST_DEFAULT_CONTENT_FIELDS = {
|
|
5053
|
+
version: 2,
|
|
5054
|
+
eventListType: {},
|
|
5055
|
+
theme: "basic",
|
|
5056
|
+
themeConfig: {},
|
|
5057
|
+
borderRadius: "10px",
|
|
5058
|
+
condensedText: true,
|
|
5059
|
+
src: "",
|
|
5060
|
+
// Category blacklist — events whose Lumia type appears here are
|
|
5061
|
+
// hidden. SL `show_<type>: false` maps to inserting the equivalent
|
|
5062
|
+
// Lumia category here.
|
|
5063
|
+
filters: [],
|
|
5064
|
+
sites: [],
|
|
5065
|
+
maxItemsToShow: 20,
|
|
5066
|
+
removeAfter: 0,
|
|
5067
|
+
reverse: false,
|
|
5068
|
+
horizontal: false,
|
|
5069
|
+
animations: {
|
|
5070
|
+
enterAnimation: "fadeIn",
|
|
5071
|
+
exitAnimation: "fadeOut",
|
|
5072
|
+
enterAnimationDuration: 1e3,
|
|
5073
|
+
exitAnimationDuration: 1e3,
|
|
5074
|
+
enterAnimationDelay: 0,
|
|
5075
|
+
exitAnimationDelay: 0
|
|
5076
|
+
},
|
|
5077
|
+
showDetailedText: true,
|
|
5078
|
+
hideAlertMessage: false,
|
|
5079
|
+
showAlertIcon: true,
|
|
5080
|
+
showSiteIcon: false,
|
|
5081
|
+
showUserAvatar: false,
|
|
5082
|
+
fadeOutAfterDelay: false,
|
|
5083
|
+
fadeOutDelayTime: 5,
|
|
5084
|
+
image: "",
|
|
5085
|
+
itemGap: 16,
|
|
5086
|
+
audio: {
|
|
5087
|
+
enter: "",
|
|
5088
|
+
volume: 1
|
|
5089
|
+
}
|
|
5090
|
+
};
|
|
5091
|
+
var EVENTLIST_DEFAULT_MODULE = {
|
|
5092
|
+
version: 2,
|
|
5093
|
+
content: EVENTLIST_DEFAULT_CONTENT_FIELDS,
|
|
5094
|
+
css: {
|
|
5095
|
+
borderRadius: "0px",
|
|
5096
|
+
borderStyle: "solid",
|
|
5097
|
+
borderWidth: "0px",
|
|
5098
|
+
borderColor: "transparent",
|
|
5099
|
+
fontSize: 16,
|
|
5100
|
+
lineHeight: 1.2,
|
|
5101
|
+
textAlign: "left",
|
|
5102
|
+
fontFamily: "Roboto",
|
|
5103
|
+
fontWeight: "normal",
|
|
5104
|
+
color: "#ffffff",
|
|
5105
|
+
textShadow: "",
|
|
5106
|
+
background: "transparent"
|
|
5107
|
+
}
|
|
5108
|
+
};
|
|
5020
5109
|
|
|
5021
5110
|
// src/se-import/mappers/misc.ts
|
|
5022
5111
|
function mapChatboxTheme(seTheme) {
|
|
@@ -5303,7 +5392,11 @@ function mapEventList(widget, ctx) {
|
|
|
5303
5392
|
...isMarquee ? { marqueeItemGap: 24 } : {},
|
|
5304
5393
|
showAlertIcon: !isMarquee,
|
|
5305
5394
|
showSiteIcon: !isMarquee,
|
|
5306
|
-
|
|
5395
|
+
// SE event lists are text-only (`{name}: {amount}` rows for tip-recent,
|
|
5396
|
+
// follower-recent, etc.) — no avatar column. Mirror that on import so
|
|
5397
|
+
// the streamer's layout matches what they had in SE; they can re-enable
|
|
5398
|
+
// avatars from the Eventlist settings panel if they want.
|
|
5399
|
+
showUserAvatar: false,
|
|
5307
5400
|
showDetailedText: false,
|
|
5308
5401
|
hideAlertMessage: false
|
|
5309
5402
|
}
|
|
@@ -6966,11 +7059,6 @@ function rewriteAssetURLs(overlay, mapping) {
|
|
|
6966
7059
|
};
|
|
6967
7060
|
}
|
|
6968
7061
|
var MAX_MIRROR_ASSET_BYTES = 100 * 1024 * 1024;
|
|
6969
|
-
function looksLikeCorsError2(err) {
|
|
6970
|
-
if (!(err instanceof TypeError)) return false;
|
|
6971
|
-
const msg = (err.message ?? "").toLowerCase();
|
|
6972
|
-
return msg.includes("failed to fetch") || msg.includes("networkerror") || msg.includes("network error") || msg.includes("cors") || msg.includes("access-control") || err.message.length > 0;
|
|
6973
|
-
}
|
|
6974
7062
|
async function mirrorOneAsset(url, upload, signal, proxyAssetFetch) {
|
|
6975
7063
|
const blob = await fetchAssetBlob(url, signal, proxyAssetFetch);
|
|
6976
7064
|
if (signal?.aborted) throw new DOMException("Aborted", "AbortError");
|
|
@@ -7002,7 +7090,7 @@ async function fetchAssetBlob(url, signal, proxyAssetFetch) {
|
|
|
7002
7090
|
return res.blob();
|
|
7003
7091
|
}
|
|
7004
7092
|
if (signal?.aborted) throw new DOMException("Aborted", "AbortError");
|
|
7005
|
-
if (proxyAssetFetch &&
|
|
7093
|
+
if (proxyAssetFetch && looksLikeCorsError(directErr)) {
|
|
7006
7094
|
try {
|
|
7007
7095
|
return await proxyAssetFetch(url);
|
|
7008
7096
|
} catch (proxyErr) {
|
|
@@ -7053,7 +7141,7 @@ function guessMime(name) {
|
|
|
7053
7141
|
}
|
|
7054
7142
|
|
|
7055
7143
|
// src/se-import/transplant.ts
|
|
7056
|
-
import { nanoid as
|
|
7144
|
+
import { nanoid as nanoid4 } from "nanoid";
|
|
7057
7145
|
function cloneModuleForTransplant(srcModule, newId) {
|
|
7058
7146
|
const clonedContent = srcModule.content ? structuredClone(srcModule.content) : srcModule.content;
|
|
7059
7147
|
if (srcModule.settings?.type === "custom" && clonedContent) {
|
|
@@ -7071,7 +7159,7 @@ function transplantLayer(source, sourceLayerId) {
|
|
|
7071
7159
|
const srcLayer = layers.find((l) => l.id === sourceLayerId);
|
|
7072
7160
|
const srcModule = modules[sourceLayerId];
|
|
7073
7161
|
if (!srcLayer || !srcModule) return null;
|
|
7074
|
-
const rootNewId =
|
|
7162
|
+
const rootNewId = nanoid4();
|
|
7075
7163
|
if (srcLayer.type !== "group") {
|
|
7076
7164
|
const layer = { ...srcLayer, id: rootNewId };
|
|
7077
7165
|
const module = cloneModuleForTransplant(srcModule, rootNewId);
|
|
@@ -7089,7 +7177,7 @@ function transplantLayer(source, sourceLayerId) {
|
|
|
7089
7177
|
if (seen.has(child.id)) continue;
|
|
7090
7178
|
seen.add(child.id);
|
|
7091
7179
|
descendants.push(child);
|
|
7092
|
-
idRemap.set(child.id,
|
|
7180
|
+
idRemap.set(child.id, nanoid4());
|
|
7093
7181
|
if (child.type === "group") queue.push(child.id);
|
|
7094
7182
|
}
|
|
7095
7183
|
}
|
|
@@ -7593,7 +7681,74 @@ function readSLProvider(response) {
|
|
|
7593
7681
|
}
|
|
7594
7682
|
|
|
7595
7683
|
// src/sl-import/mappers/alert-box.ts
|
|
7596
|
-
import { nanoid as
|
|
7684
|
+
import { nanoid as nanoid6 } from "nanoid";
|
|
7685
|
+
import { LumiaAlertValues as LumiaAlertValues2 } from "@lumiastream/lumia-types";
|
|
7686
|
+
|
|
7687
|
+
// src/se-import/import-envelope.ts
|
|
7688
|
+
import { nanoid as nanoid5 } from "nanoid";
|
|
7689
|
+
function buildModuleEnvelope(opts) {
|
|
7690
|
+
const id = opts.id ?? nanoid5();
|
|
7691
|
+
const locked = opts.locked ?? false;
|
|
7692
|
+
const visible = opts.visible ?? true;
|
|
7693
|
+
const layer = {
|
|
7694
|
+
id,
|
|
7695
|
+
...opts.parentGroupId !== void 0 ? { group: opts.parentGroupId } : {},
|
|
7696
|
+
...opts.type_layer ? { type: opts.type_layer } : {},
|
|
7697
|
+
state: {
|
|
7698
|
+
visible,
|
|
7699
|
+
locked,
|
|
7700
|
+
...opts.expanded !== void 0 ? { expanded: opts.expanded } : {}
|
|
7701
|
+
},
|
|
7702
|
+
bounds: {
|
|
7703
|
+
x: opts.bounds.x,
|
|
7704
|
+
y: opts.bounds.y,
|
|
7705
|
+
width: opts.bounds.width,
|
|
7706
|
+
height: opts.bounds.height,
|
|
7707
|
+
scale: [1, 1],
|
|
7708
|
+
...opts.zIndex !== void 0 ? { zIndex: opts.zIndex } : {}
|
|
7709
|
+
}
|
|
7710
|
+
};
|
|
7711
|
+
const module = {
|
|
7712
|
+
id,
|
|
7713
|
+
version: opts.version ?? 1,
|
|
7714
|
+
loaded: true,
|
|
7715
|
+
settings: { type: opts.type, title: opts.title, locked },
|
|
7716
|
+
lights: opts.lights ?? [],
|
|
7717
|
+
css: opts.css ?? {},
|
|
7718
|
+
content: opts.content ?? {},
|
|
7719
|
+
variables: opts.variables ?? {},
|
|
7720
|
+
events: opts.events ?? {},
|
|
7721
|
+
...opts.alert !== void 0 ? { alert: opts.alert } : {}
|
|
7722
|
+
};
|
|
7723
|
+
return { id, layer, module };
|
|
7724
|
+
}
|
|
7725
|
+
var IMPORT_META_KEY = "importMeta";
|
|
7726
|
+
function stampImportMetaMerge(module, meta) {
|
|
7727
|
+
const existing = module.content?.[IMPORT_META_KEY] ?? {};
|
|
7728
|
+
module.content = {
|
|
7729
|
+
...module.content ?? {},
|
|
7730
|
+
[IMPORT_META_KEY]: {
|
|
7731
|
+
importedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
7732
|
+
...existing,
|
|
7733
|
+
...meta
|
|
7734
|
+
}
|
|
7735
|
+
};
|
|
7736
|
+
}
|
|
7737
|
+
function customHtmlReviewItem(moduleId, importSourceType, settings, reason) {
|
|
7738
|
+
return {
|
|
7739
|
+
moduleId,
|
|
7740
|
+
// ReviewItem's `seWidget` is typed against SEWidget but the review
|
|
7741
|
+
// UI just reads `.type` and `.settings`. Cast through unknown is
|
|
7742
|
+
// the only place we touch the shape mismatch; widening the
|
|
7743
|
+
// ReviewItem type is a future cleanup.
|
|
7744
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
7745
|
+
seWidget: { type: importSourceType, settings },
|
|
7746
|
+
status: "template",
|
|
7747
|
+
reason
|
|
7748
|
+
};
|
|
7749
|
+
}
|
|
7750
|
+
|
|
7751
|
+
// src/sl-import/mappers/alert-box.ts
|
|
7597
7752
|
var SL_EVENT_ROUTING = {
|
|
7598
7753
|
// Platform-native — provider routes (Twitch / Kick / YouTube).
|
|
7599
7754
|
follow: { pickProviderKeys: "follower" },
|
|
@@ -7605,47 +7760,35 @@ var SL_EVENT_ROUTING = {
|
|
|
7605
7760
|
// `subscriber` here is YouTube subscribe (free); `sponsor` is YouTube
|
|
7606
7761
|
// channel membership; `fanfunding` is YouTube superchat. SL ships these
|
|
7607
7762
|
// even on Twitch-primary accounts so we always map them.
|
|
7608
|
-
subscriber: { keys: [
|
|
7609
|
-
sponsor: { keys: [
|
|
7610
|
-
fanfunding: { keys: [
|
|
7611
|
-
super_sticker: { keys: [
|
|
7763
|
+
subscriber: { keys: [LumiaAlertValues2.YOUTUBE_SUBSCRIBER] },
|
|
7764
|
+
sponsor: { keys: [LumiaAlertValues2.YOUTUBE_MEMBER] },
|
|
7765
|
+
fanfunding: { keys: [LumiaAlertValues2.YOUTUBE_SUPERCHAT] },
|
|
7766
|
+
super_sticker: { keys: [LumiaAlertValues2.YOUTUBE_SUPERSTICKER] },
|
|
7612
7767
|
// Donation / tip channels — Lumia ships dedicated alert keys for each
|
|
7613
7768
|
// integration. `donation` itself fans out to `streamlabs-donation` AND
|
|
7614
7769
|
// `lumiastream-donation` so the imported alert fires regardless of which
|
|
7615
7770
|
// channel the donation actually came in on.
|
|
7616
|
-
donation: { keys: [
|
|
7617
|
-
eldonation: { keys: [
|
|
7618
|
-
tiltifydonation: { keys: [
|
|
7619
|
-
donordrivedonation: { keys: [
|
|
7620
|
-
justgivingdonation: { keys: [
|
|
7621
|
-
pledge: { keys: [
|
|
7771
|
+
donation: { keys: [LumiaAlertValues2.STREAMLABS_DONATION, LumiaAlertValues2.LUMIASTREAM_DONATION] },
|
|
7772
|
+
eldonation: { keys: [LumiaAlertValues2.EXTRALIFE_DONATION] },
|
|
7773
|
+
tiltifydonation: { keys: [LumiaAlertValues2.TILTIFY_DONATION] },
|
|
7774
|
+
donordrivedonation: { keys: [LumiaAlertValues2.DONORDRIVE_DONATION] },
|
|
7775
|
+
justgivingdonation: { keys: [LumiaAlertValues2.STREAMLABS_DONATION] },
|
|
7776
|
+
pledge: { keys: [LumiaAlertValues2.PATREON_PLEDGE] },
|
|
7622
7777
|
// Charity / merch / loyalty / prime gifting — SL-flavored channels with
|
|
7623
7778
|
// matching Lumia keys.
|
|
7624
|
-
streamlabscharitydonation: { keys: [
|
|
7625
|
-
twitchcharitydonation: { keys: [
|
|
7626
|
-
merch: { keys: [
|
|
7627
|
-
loyalty_store_redemption: { keys: [
|
|
7628
|
-
prime_sub_gift: { keys: [
|
|
7629
|
-
treat: { keys: [
|
|
7779
|
+
streamlabscharitydonation: { keys: [LumiaAlertValues2.STREAMLABS_CHARITY] },
|
|
7780
|
+
twitchcharitydonation: { keys: [LumiaAlertValues2.TWITCH_CHARITY_DONATION] },
|
|
7781
|
+
merch: { keys: [LumiaAlertValues2.STREAMLABS_MERCH] },
|
|
7782
|
+
loyalty_store_redemption: { keys: [LumiaAlertValues2.STREAMLABS_REDEMPTION] },
|
|
7783
|
+
prime_sub_gift: { keys: [LumiaAlertValues2.STREAMLABS_PRIMEGIFT] },
|
|
7784
|
+
treat: { keys: [LumiaAlertValues2.TREATSTREAM_TREAT] },
|
|
7630
7785
|
// TikTok-flavored (jewel gift is TikTok-ish in concept).
|
|
7631
|
-
jewel_gift: { keys: [
|
|
7786
|
+
jewel_gift: { keys: [LumiaAlertValues2.TIKTOK_GIFT] }
|
|
7632
7787
|
};
|
|
7633
7788
|
function getField(settings, prefix, field) {
|
|
7634
7789
|
const key = `${prefix}_${field}`;
|
|
7635
7790
|
return settings[key];
|
|
7636
7791
|
}
|
|
7637
|
-
function pxToNumber(raw, fallback) {
|
|
7638
|
-
if (typeof raw === "number" && Number.isFinite(raw)) return raw;
|
|
7639
|
-
if (typeof raw !== "string") return fallback;
|
|
7640
|
-
const trimmed = raw.trim();
|
|
7641
|
-
if (!trimmed) return fallback;
|
|
7642
|
-
if (trimmed.endsWith("px")) {
|
|
7643
|
-
const n2 = parseFloat(trimmed.slice(0, -2));
|
|
7644
|
-
return Number.isFinite(n2) ? n2 : fallback;
|
|
7645
|
-
}
|
|
7646
|
-
const n = parseFloat(trimmed);
|
|
7647
|
-
return Number.isFinite(n) ? n : fallback;
|
|
7648
|
-
}
|
|
7649
7792
|
function translateLayout2(slLayout) {
|
|
7650
7793
|
switch (slLayout) {
|
|
7651
7794
|
case "above":
|
|
@@ -7755,9 +7898,7 @@ function buildBaseAlertEvent(settings, prefix, defaultMessage) {
|
|
|
7755
7898
|
tts: {
|
|
7756
7899
|
enabled: getField(settings, prefix, "tts_enabled") ?? false,
|
|
7757
7900
|
voice: getField(settings, prefix, "tts_language") ?? "Brian",
|
|
7758
|
-
volume: clampVolume(
|
|
7759
|
-
getField(settings, prefix, "tts_volume") ?? 75
|
|
7760
|
-
),
|
|
7901
|
+
volume: clampVolume(getField(settings, prefix, "tts_volume") ?? 75),
|
|
7761
7902
|
minAmount: getField(settings, prefix, "tts_min_amount") ?? 0
|
|
7762
7903
|
},
|
|
7763
7904
|
variations: []
|
|
@@ -7772,10 +7913,7 @@ function readSecondaryMessageConfig(settings, prefix, primaryFontFamily) {
|
|
|
7772
7913
|
const enabled = settings[showKey];
|
|
7773
7914
|
if (enabled !== true) return null;
|
|
7774
7915
|
const fontFamily = getField(settings, secondaryPrefix, "message_font") ?? primaryFontFamily;
|
|
7775
|
-
const fontSize = pxToNumber(
|
|
7776
|
-
getField(settings, secondaryPrefix, "message_font_size"),
|
|
7777
|
-
20
|
|
7778
|
-
);
|
|
7916
|
+
const fontSize = pxToNumber(getField(settings, secondaryPrefix, "message_font_size"), 20);
|
|
7779
7917
|
const fontWeight = getField(settings, secondaryPrefix, "message_font_weight") ?? 400;
|
|
7780
7918
|
const fontColor = getField(settings, secondaryPrefix, "message_font_color") ?? "#FFFFFF";
|
|
7781
7919
|
return {
|
|
@@ -7802,11 +7940,20 @@ function translateSLVariationCondition(v) {
|
|
|
7802
7940
|
const numericData = typeof data === "number" ? data : Number(data);
|
|
7803
7941
|
switch (v.condition) {
|
|
7804
7942
|
case "RANDOM":
|
|
7805
|
-
return {
|
|
7943
|
+
return {
|
|
7944
|
+
conditionType: "RANDOM",
|
|
7945
|
+
condition: Number.isFinite(numericData) ? numericData : 100
|
|
7946
|
+
};
|
|
7806
7947
|
case "MIN_BITS_USED":
|
|
7807
|
-
return {
|
|
7948
|
+
return {
|
|
7949
|
+
conditionType: "GREATER_NUMBER",
|
|
7950
|
+
condition: Number.isFinite(numericData) ? numericData : 0
|
|
7951
|
+
};
|
|
7808
7952
|
case "EXACT_BITS_USED":
|
|
7809
|
-
return {
|
|
7953
|
+
return {
|
|
7954
|
+
conditionType: "EQUAL_NUMBER",
|
|
7955
|
+
condition: Number.isFinite(numericData) ? numericData : 0
|
|
7956
|
+
};
|
|
7810
7957
|
case "MIN_MONTHS_SUBSCRIBED":
|
|
7811
7958
|
return {
|
|
7812
7959
|
conditionType: "SUBSCRIBED_MONTHS_GREATER",
|
|
@@ -7871,6 +8018,14 @@ function buildVariationEvent(v, parentBase) {
|
|
|
7871
8018
|
if (s.hideAnimation) inherited.animations.alertExitAnimation = s.hideAnimation;
|
|
7872
8019
|
if (s.layout) inherited.layout.value = translateLayout2(s.layout);
|
|
7873
8020
|
return {
|
|
8021
|
+
// Reuse SL's own `uuid` when present so re-importing the same SL
|
|
8022
|
+
// alert-box keeps the variation identity stable across import
|
|
8023
|
+
// runs. SL always emits a uuid in their config (every fixture we've
|
|
8024
|
+
// seen has one); fall back to nanoid for the edge case of a
|
|
8025
|
+
// hand-crafted / older payload that omits it. Matches the SE
|
|
8026
|
+
// alert mapper's variation-id pattern — see Settings.tsx auto-fill
|
|
8027
|
+
// note there for why a stable id matters from save #1.
|
|
8028
|
+
id: typeof v.uuid === "string" && v.uuid.length > 0 ? v.uuid : nanoid6(),
|
|
7874
8029
|
name: v.name ?? "Variation",
|
|
7875
8030
|
on: v.paused !== true,
|
|
7876
8031
|
randomChance: 100,
|
|
@@ -7936,11 +8091,7 @@ function buildSLAlertBox(settings, options = {}) {
|
|
|
7936
8091
|
for (const [prefix, routing] of Object.entries(SL_EVENT_ROUTING)) {
|
|
7937
8092
|
const lumiaKeys = routing.pickProviderKeys ? alertBoxKeysFor(routing.pickProviderKeys, provider) : routing.keys ?? [];
|
|
7938
8093
|
if (lumiaKeys.length === 0) continue;
|
|
7939
|
-
const built = buildBaseAlertEvent(
|
|
7940
|
-
settings,
|
|
7941
|
-
prefix,
|
|
7942
|
-
DEFAULT_MESSAGES[prefix] ?? "{name}"
|
|
7943
|
-
);
|
|
8094
|
+
const built = buildBaseAlertEvent(settings, prefix, DEFAULT_MESSAGES[prefix] ?? "{name}");
|
|
7944
8095
|
if (!built) continue;
|
|
7945
8096
|
const variationKey = VARIATION_KEY_FOR_PREFIX[prefix];
|
|
7946
8097
|
const variations = variationKey ? settings[variationKey] : void 0;
|
|
@@ -7957,53 +8108,32 @@ function buildSLAlertBox(settings, options = {}) {
|
|
|
7957
8108
|
channelsImported.push(prefix);
|
|
7958
8109
|
if (firstEvent == null) firstEvent = built;
|
|
7959
8110
|
}
|
|
7960
|
-
const id = nanoid4();
|
|
7961
|
-
const layer = {
|
|
7962
|
-
id,
|
|
7963
|
-
state: { visible: true, locked: false },
|
|
7964
|
-
bounds: { x: 100, y: 100, width: 700, height: 600, scale: [1, 1] }
|
|
7965
|
-
};
|
|
7966
8111
|
const baseAlert = firstEvent ? stripEventOnlyFields(firstEvent) : {};
|
|
7967
|
-
const module = {
|
|
7968
|
-
|
|
7969
|
-
|
|
7970
|
-
|
|
7971
|
-
settings: { type: "alert", title: "Streamlabs Alerts", locked: false },
|
|
7972
|
-
lights: [],
|
|
7973
|
-
css: {},
|
|
7974
|
-
content: {},
|
|
7975
|
-
variables: {},
|
|
7976
|
-
events: {},
|
|
8112
|
+
const { layer, module } = buildModuleEnvelope({
|
|
8113
|
+
type: "alert",
|
|
8114
|
+
title: "Streamlabs Alerts",
|
|
8115
|
+
bounds: { x: 100, y: 100, width: 700, height: 600 },
|
|
7977
8116
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
7978
8117
|
alert: { ...baseAlert, events }
|
|
7979
|
-
};
|
|
8118
|
+
});
|
|
7980
8119
|
return { layer, module, channelsImported };
|
|
7981
8120
|
}
|
|
7982
8121
|
function stripEventOnlyFields(event) {
|
|
7983
|
-
const {
|
|
8122
|
+
const {
|
|
8123
|
+
on: _on,
|
|
8124
|
+
variations: _variations,
|
|
8125
|
+
matchEmptyCondition: _mec,
|
|
8126
|
+
...base
|
|
8127
|
+
} = event;
|
|
7984
8128
|
return base;
|
|
7985
8129
|
}
|
|
7986
8130
|
|
|
7987
8131
|
// src/sl-import/mappers/tip-jar.ts
|
|
7988
|
-
import { nanoid as nanoid5 } from "nanoid";
|
|
7989
|
-
function pxToNumber2(raw, fallback) {
|
|
7990
|
-
if (typeof raw === "number" && Number.isFinite(raw)) return raw;
|
|
7991
|
-
if (typeof raw !== "string") return fallback;
|
|
7992
|
-
const trimmed = raw.trim();
|
|
7993
|
-
if (!trimmed) return fallback;
|
|
7994
|
-
if (trimmed.endsWith("px")) {
|
|
7995
|
-
const n2 = parseFloat(trimmed.slice(0, -2));
|
|
7996
|
-
return Number.isFinite(n2) ? n2 : fallback;
|
|
7997
|
-
}
|
|
7998
|
-
const n = parseFloat(trimmed);
|
|
7999
|
-
return Number.isFinite(n) ? n : fallback;
|
|
8000
|
-
}
|
|
8001
8132
|
function buildSLTipJar(settings) {
|
|
8002
|
-
const id = nanoid5();
|
|
8003
8133
|
const backgroundColor = settings.background?.color ?? "transparent";
|
|
8004
8134
|
const textColor = settings.text?.color ?? "#FFFFFF";
|
|
8005
8135
|
const fontFamily = settings.text?.font ?? "Open Sans";
|
|
8006
|
-
const fontSize =
|
|
8136
|
+
const fontSize = pxToNumber(settings.text?.size, 32);
|
|
8007
8137
|
const types = settings.types ?? {};
|
|
8008
8138
|
const tipsConfig = types.tips ?? {};
|
|
8009
8139
|
const slEvents = {
|
|
@@ -8019,17 +8149,11 @@ function buildSLTipJar(settings) {
|
|
|
8019
8149
|
...TIPJAR_DEFAULT_MODULE.content.display,
|
|
8020
8150
|
showEventMessages: settings.text?.show !== false
|
|
8021
8151
|
};
|
|
8022
|
-
const layer = {
|
|
8023
|
-
|
|
8024
|
-
|
|
8025
|
-
bounds: { x: 100, y: 100, width: 600, height: 700
|
|
8026
|
-
};
|
|
8027
|
-
const module = {
|
|
8028
|
-
id,
|
|
8152
|
+
const { layer, module } = buildModuleEnvelope({
|
|
8153
|
+
type: "tipjar",
|
|
8154
|
+
title: "Streamlabs Tip Jar",
|
|
8155
|
+
bounds: { x: 100, y: 100, width: 600, height: 700 },
|
|
8029
8156
|
version: TIPJAR_DEFAULT_MODULE.version,
|
|
8030
|
-
loaded: true,
|
|
8031
|
-
settings: { type: "tipjar", title: "Streamlabs Tip Jar", locked: false },
|
|
8032
|
-
lights: [],
|
|
8033
8157
|
css: {
|
|
8034
8158
|
fontFamily,
|
|
8035
8159
|
fontSize,
|
|
@@ -8050,12 +8174,7 @@ function buildSLTipJar(settings) {
|
|
|
8050
8174
|
source: "streamlabs",
|
|
8051
8175
|
widgetType: "tip_jar",
|
|
8052
8176
|
importedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
8053
|
-
// SL jar type doesn't have a 1:1 mapping to Lumia's preset
|
|
8054
|
-
// vocabulary (cup-01, cup-02, …). Stashed for review.
|
|
8055
8177
|
slJarType: settings.jar?.type ?? null,
|
|
8056
|
-
// SL tier coin tiers — Lumia's sprite tiers are per-event and
|
|
8057
|
-
// configured in the sprite editor; the user re-creates these
|
|
8058
|
-
// manually. Stored here so they're not lost.
|
|
8059
8178
|
slTipTiers: Array.isArray(tipsConfig.tiers) ? tipsConfig.tiers.map((t) => ({
|
|
8060
8179
|
minimumAmount: t.minimum_amount,
|
|
8061
8180
|
imageSrc: t.image_src ?? null
|
|
@@ -8063,15 +8182,12 @@ function buildSLTipJar(settings) {
|
|
|
8063
8182
|
slMinimumTipAmount: tipsConfig.minimum_amount ?? null,
|
|
8064
8183
|
slHadCustomHtml: settings.custom_html_enabled === true
|
|
8065
8184
|
}
|
|
8066
|
-
}
|
|
8067
|
-
|
|
8068
|
-
events: {}
|
|
8069
|
-
};
|
|
8185
|
+
}
|
|
8186
|
+
});
|
|
8070
8187
|
return { layer, module };
|
|
8071
8188
|
}
|
|
8072
8189
|
|
|
8073
8190
|
// src/sl-import/mappers/goal.ts
|
|
8074
|
-
import { nanoid as nanoid6 } from "nanoid";
|
|
8075
8191
|
var GOAL_SOURCE_MAP = {
|
|
8076
8192
|
follower_goal: "follower",
|
|
8077
8193
|
sub_goal: "subscriber",
|
|
@@ -8084,69 +8200,262 @@ var GOAL_TITLE_MAP = {
|
|
|
8084
8200
|
donation_goal: "Donation Goal",
|
|
8085
8201
|
bit_goal: "Bits Goal"
|
|
8086
8202
|
};
|
|
8087
|
-
|
|
8088
|
-
|
|
8089
|
-
|
|
8090
|
-
|
|
8091
|
-
|
|
8092
|
-
|
|
8093
|
-
const n2 = parseFloat(trimmed.slice(0, -2));
|
|
8094
|
-
return Number.isFinite(n2) ? n2 : fallback;
|
|
8095
|
-
}
|
|
8096
|
-
const n = parseFloat(trimmed);
|
|
8097
|
-
return Number.isFinite(n) ? n : fallback;
|
|
8098
|
-
}
|
|
8203
|
+
var GOAL_CURRENT_TEMPLATE = {
|
|
8204
|
+
follower_goal: "{{twitch_total_follower_count}}",
|
|
8205
|
+
sub_goal: "{{twitch_total_subscriber_count}}",
|
|
8206
|
+
donation_goal: "{{total_donation_amount}}",
|
|
8207
|
+
bit_goal: "{{twitch_total_bits_count}}"
|
|
8208
|
+
};
|
|
8099
8209
|
function buildSLGoal(settings, widgetType) {
|
|
8100
|
-
const id = nanoid6();
|
|
8101
8210
|
const goalSource = GOAL_SOURCE_MAP[widgetType] ?? "follower";
|
|
8102
8211
|
const defaultTitle = GOAL_TITLE_MAP[widgetType] ?? "Goal";
|
|
8212
|
+
const currentTemplate = GOAL_CURRENT_TEMPLATE[widgetType] ?? "";
|
|
8213
|
+
const requiresReview = settings.custom_enabled === true;
|
|
8103
8214
|
const title = typeof settings.title === "string" ? settings.title : defaultTitle;
|
|
8104
8215
|
const goalAmount = typeof settings.goal === "number" ? settings.goal : 100;
|
|
8105
8216
|
const currentAmount = typeof settings.current === "number" ? settings.current : 0;
|
|
8106
8217
|
const startingAmount = typeof settings.starting_amount === "number" ? settings.starting_amount : 0;
|
|
8107
|
-
const endsAt = typeof settings.ends_at === "string" ? settings.ends_at :
|
|
8218
|
+
const endsAt = typeof settings.ends_at === "string" ? settings.ends_at : "";
|
|
8108
8219
|
const barColor = settings.bar_color ?? "#32C3A6";
|
|
8109
|
-
const
|
|
8220
|
+
const barBgColor = settings.bar_bg_color ?? "#181818";
|
|
8221
|
+
const widgetBgColor = settings.background_color ?? "transparent";
|
|
8110
8222
|
const textColor = settings.text_color ?? "#FFFFFF";
|
|
8111
8223
|
const barTextColor = settings.bar_text_color ?? textColor;
|
|
8112
8224
|
const fontFamily = settings.font ?? "Open Sans";
|
|
8113
|
-
const
|
|
8114
|
-
|
|
8115
|
-
|
|
8116
|
-
|
|
8117
|
-
|
|
8118
|
-
|
|
8119
|
-
|
|
8120
|
-
version: 1,
|
|
8121
|
-
loaded: true,
|
|
8122
|
-
settings: { type: "goal", title, locked: false },
|
|
8123
|
-
lights: [],
|
|
8225
|
+
const fontSize = pxToNumber(settings.font_size, 24);
|
|
8226
|
+
const barThickness = pxToNumber(settings.bar_thickness, 48);
|
|
8227
|
+
const layerHeight = Math.max(60, barThickness + 32);
|
|
8228
|
+
const { layer, module } = buildModuleEnvelope({
|
|
8229
|
+
type: "goal",
|
|
8230
|
+
title,
|
|
8231
|
+
bounds: { x: 100, y: 100, width: 740, height: layerHeight },
|
|
8124
8232
|
css: {
|
|
8125
8233
|
fontFamily,
|
|
8126
8234
|
color: textColor,
|
|
8127
|
-
background:
|
|
8235
|
+
background: widgetBgColor,
|
|
8236
|
+
fontSize
|
|
8128
8237
|
},
|
|
8238
|
+
// Use Lumia's canonical goal field names — `targetGoal` (string),
|
|
8239
|
+
// `current` (template string), `display`, `filledColor` /
|
|
8240
|
+
// `unfilledColor`. The prior schema used invented field names
|
|
8241
|
+
// (`goalAmount`, `barColor`) that the renderer ignored.
|
|
8129
8242
|
content: {
|
|
8130
|
-
|
|
8131
|
-
|
|
8132
|
-
|
|
8133
|
-
|
|
8134
|
-
|
|
8135
|
-
|
|
8136
|
-
|
|
8137
|
-
|
|
8138
|
-
|
|
8139
|
-
|
|
8140
|
-
|
|
8243
|
+
version: 1,
|
|
8244
|
+
type: "bar",
|
|
8245
|
+
label: title,
|
|
8246
|
+
subLabel: "",
|
|
8247
|
+
display: "{{current}} / {{goal}}",
|
|
8248
|
+
current: currentAmount > 0 ? String(currentAmount) : currentTemplate,
|
|
8249
|
+
targetGoal: String(goalAmount),
|
|
8250
|
+
image: "",
|
|
8251
|
+
audio: {
|
|
8252
|
+
decrement: "",
|
|
8253
|
+
increment: "",
|
|
8254
|
+
goal: "",
|
|
8255
|
+
goalFailed: "",
|
|
8256
|
+
volume: 1
|
|
8257
|
+
},
|
|
8258
|
+
endDate: endsAt,
|
|
8259
|
+
goalAnimation: "",
|
|
8260
|
+
goalAnimationLoop: true,
|
|
8261
|
+
unfilledColor: barBgColor,
|
|
8262
|
+
filledColor: barColor,
|
|
8263
|
+
alignItemsToEdges: false,
|
|
8264
|
+
border: "solid 1px transparent",
|
|
8265
|
+
borderRadius: "40px",
|
|
8266
|
+
highlightColor: "inherit",
|
|
8267
|
+
importMeta: {
|
|
8268
|
+
source: "streamlabs",
|
|
8269
|
+
widgetType,
|
|
8270
|
+
importedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
8271
|
+
goalSource,
|
|
8272
|
+
slLayout: settings.layout ?? null,
|
|
8273
|
+
slBarTextColor: barTextColor,
|
|
8274
|
+
slBarThickness: barThickness,
|
|
8275
|
+
slStartingAmount: startingAmount,
|
|
8276
|
+
slHadCustomHtml: settings.custom_enabled === true
|
|
8277
|
+
}
|
|
8278
|
+
}
|
|
8279
|
+
});
|
|
8280
|
+
return { layer, module, requiresReview };
|
|
8281
|
+
}
|
|
8282
|
+
|
|
8283
|
+
// src/sl-import/mappers/chat-box.ts
|
|
8284
|
+
function buildSitesArray(settings) {
|
|
8285
|
+
const defaultSites = [...CHATBOX_DEFAULT_MODULE.content.sites];
|
|
8286
|
+
const drop = /* @__PURE__ */ new Set();
|
|
8287
|
+
if (settings.show_bttv_emotes === false) drop.add("bttv");
|
|
8288
|
+
if (settings.show_franker_emotes === false) drop.add("ffz");
|
|
8289
|
+
if (settings.show_7tv_emotes === false) drop.add("seventv");
|
|
8290
|
+
if (settings.twitch_enabled === false) drop.add("twitch");
|
|
8291
|
+
if (settings.youtube_enabled === false) drop.add("youtube");
|
|
8292
|
+
if (settings.facebook_enabled === false) drop.add("facebook");
|
|
8293
|
+
if (settings.tiktok_enabled === false) drop.add("tiktok");
|
|
8294
|
+
if (settings.kick_enabled === false) drop.add("kick");
|
|
8295
|
+
if (drop.size === 0) return defaultSites;
|
|
8296
|
+
return defaultSites.filter((s) => !drop.has(s));
|
|
8297
|
+
}
|
|
8298
|
+
function buildSLChatBox(settings) {
|
|
8299
|
+
const requiresReview = settings.custom_enabled === true;
|
|
8300
|
+
const backgroundColor = settings.background_color ?? "transparent";
|
|
8301
|
+
const textColor = settings.text_color ?? "#FFFFFF";
|
|
8302
|
+
const textSize = pxToNumber(settings.text_size, 16);
|
|
8303
|
+
const fadeOutAfterDelay = settings.always_show_messages !== true;
|
|
8304
|
+
const fadeOutDelayTime = fadeOutAfterDelay ? Math.max(1, Math.round((settings.message_hide_delay ?? 15e3) / 1e3)) : 0;
|
|
8305
|
+
const sites = buildSitesArray(settings);
|
|
8306
|
+
const { layer, module } = buildModuleEnvelope({
|
|
8307
|
+
type: "chatbox",
|
|
8308
|
+
title: "Streamlabs Chat Box",
|
|
8309
|
+
bounds: { x: 100, y: 100, width: 375, height: 470 },
|
|
8310
|
+
version: CHATBOX_DEFAULT_MODULE.version,
|
|
8311
|
+
css: {
|
|
8312
|
+
background: backgroundColor,
|
|
8313
|
+
color: textColor,
|
|
8314
|
+
fontSize: textSize
|
|
8141
8315
|
},
|
|
8142
|
-
|
|
8143
|
-
|
|
8144
|
-
|
|
8145
|
-
|
|
8316
|
+
content: {
|
|
8317
|
+
// Spread canonical defaults FIRST so the renderer's dereferences
|
|
8318
|
+
// (chatboxStreamingSite.<platform>.themeConfig, animations,
|
|
8319
|
+
// chatboxStreamingSite.<platform>.message, etc.) all exist.
|
|
8320
|
+
...CHATBOX_DEFAULT_MODULE.content,
|
|
8321
|
+
// Then override the bits SL controls.
|
|
8322
|
+
sites,
|
|
8323
|
+
fadeOutAfterDelay,
|
|
8324
|
+
fadeOutDelayTime,
|
|
8325
|
+
// SL keeps history forever by default — `always_show_messages`
|
|
8326
|
+
// implies the streamer wants a permanent scrollback. Lumia
|
|
8327
|
+
// exposes that as `permanent: true`.
|
|
8328
|
+
permanent: settings.always_show_messages === true,
|
|
8329
|
+
// Preserve the SL-specific provenance for the review step.
|
|
8330
|
+
importMeta: {
|
|
8331
|
+
source: "streamlabs",
|
|
8332
|
+
widgetType: "chat_box",
|
|
8333
|
+
importedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
8334
|
+
slTheme: settings.theme ?? null,
|
|
8335
|
+
slHadCustomHtml: settings.custom_enabled === true,
|
|
8336
|
+
slHidesCommonBots: settings.hide_common_chat_bots === true,
|
|
8337
|
+
slHidesCommands: settings.hide_commands === true,
|
|
8338
|
+
slMutedChatters: settings.muted_chatters ?? "",
|
|
8339
|
+
slMessageShowDelayMs: settings.message_show_delay ?? 0
|
|
8340
|
+
}
|
|
8341
|
+
}
|
|
8342
|
+
});
|
|
8343
|
+
return { layer, module, requiresReview };
|
|
8344
|
+
}
|
|
8345
|
+
|
|
8346
|
+
// src/sl-import/mappers/event-list.ts
|
|
8347
|
+
var SL_SHOW_FLAG_TO_LUMIA_FILTER = {
|
|
8348
|
+
show_follows: "follower",
|
|
8349
|
+
show_subscriptions: "subscribers",
|
|
8350
|
+
show_resubs: "subscribers",
|
|
8351
|
+
show_sub_gifts: "gifts",
|
|
8352
|
+
show_subscribers: "subscribers",
|
|
8353
|
+
show_sponsors: "subscribers",
|
|
8354
|
+
// YouTube channel members
|
|
8355
|
+
show_sponsor_gifts: "gifts",
|
|
8356
|
+
show_bits: "bits",
|
|
8357
|
+
show_donations: "donation",
|
|
8358
|
+
show_pledges: "donation",
|
|
8359
|
+
// Patreon
|
|
8360
|
+
show_eldonations: "donation",
|
|
8361
|
+
show_tiltifydonations: "donation",
|
|
8362
|
+
show_donordrivedonations: "donation",
|
|
8363
|
+
show_justgivingdonations: "donation",
|
|
8364
|
+
show_streamlabscharitydonations: "donation",
|
|
8365
|
+
show_twitchcharitydonations: "donation",
|
|
8366
|
+
show_twitch_charity: "donation",
|
|
8367
|
+
show_treats: "donation",
|
|
8368
|
+
// TreatStream
|
|
8369
|
+
show_merch: "purchases",
|
|
8370
|
+
show_raids: "raids",
|
|
8371
|
+
show_hosts: "raids",
|
|
8372
|
+
show_redemptions: "redemption",
|
|
8373
|
+
show_fanfundings: "superchats",
|
|
8374
|
+
// YouTube Super Chat
|
|
8375
|
+
show_super_stickers: "superstickers",
|
|
8376
|
+
show_jewel_gifts: "stars"
|
|
8377
|
+
// TikTok-flavored, closest analogue
|
|
8378
|
+
};
|
|
8379
|
+
function buildFilters(settings) {
|
|
8380
|
+
const drop = /* @__PURE__ */ new Set();
|
|
8381
|
+
for (const [slFlag, lumiaCategory] of Object.entries(SL_SHOW_FLAG_TO_LUMIA_FILTER)) {
|
|
8382
|
+
if (settings[slFlag] === false) {
|
|
8383
|
+
drop.add(lumiaCategory);
|
|
8384
|
+
}
|
|
8385
|
+
}
|
|
8386
|
+
return Array.from(drop);
|
|
8387
|
+
}
|
|
8388
|
+
function buildSLEventList(settings) {
|
|
8389
|
+
const requiresReview = settings.custom_enabled === true;
|
|
8390
|
+
const backgroundColor = settings.background_color ?? "transparent";
|
|
8391
|
+
const textColor = settings.text_color ?? "#FFFFFF";
|
|
8392
|
+
const textSize = pxToNumber(settings.text_size, 16);
|
|
8393
|
+
const fontFamily = settings.font_family ?? "Roboto";
|
|
8394
|
+
const maxEvents = typeof settings.max_events === "number" && settings.max_events > 0 ? settings.max_events : EVENTLIST_DEFAULT_MODULE.content.maxItemsToShow;
|
|
8395
|
+
const enterAnimation = settings.show_animation ?? "fadeIn";
|
|
8396
|
+
const exitAnimation = settings.hide_animation ?? "fadeOut";
|
|
8397
|
+
const animationDuration = typeof settings.animation_speed === "number" ? settings.animation_speed : 1e3;
|
|
8398
|
+
const filters = buildFilters(settings);
|
|
8399
|
+
const { layer, module } = buildModuleEnvelope({
|
|
8400
|
+
type: "eventlist",
|
|
8401
|
+
title: "Streamlabs Event List",
|
|
8402
|
+
bounds: { x: 100, y: 100, width: 375, height: 470 },
|
|
8403
|
+
version: EVENTLIST_DEFAULT_MODULE.version,
|
|
8404
|
+
css: {
|
|
8405
|
+
...EVENTLIST_DEFAULT_MODULE.css,
|
|
8406
|
+
background: backgroundColor,
|
|
8407
|
+
color: textColor,
|
|
8408
|
+
fontSize: textSize,
|
|
8409
|
+
fontFamily
|
|
8410
|
+
},
|
|
8411
|
+
content: {
|
|
8412
|
+
// Spread canonical defaults FIRST so the renderer's dereferences
|
|
8413
|
+
// don't crash on missing nested objects.
|
|
8414
|
+
...EVENTLIST_DEFAULT_MODULE.content,
|
|
8415
|
+
maxItemsToShow: maxEvents,
|
|
8416
|
+
// SL's `flip_y` corresponds to Lumia's `reverse` (newest item
|
|
8417
|
+
// at the bottom vs the top). SL's `flip_x` flips the alignment
|
|
8418
|
+
// to right; Lumia covers that via css.textAlign but doesn't
|
|
8419
|
+
// have a per-module horizontal flip — stash as importMeta for
|
|
8420
|
+
// the review step.
|
|
8421
|
+
reverse: settings.flip_y === true,
|
|
8422
|
+
// SL's `keep_history: false` means events disappear after the
|
|
8423
|
+
// fade time; map to `fadeOutAfterDelay: true` with the fade
|
|
8424
|
+
// time SL configured.
|
|
8425
|
+
fadeOutAfterDelay: settings.keep_history === false,
|
|
8426
|
+
fadeOutDelayTime: typeof settings.fade_time === "number" && settings.fade_time > 0 ? Math.max(1, Math.round(settings.fade_time / 1e3)) : EVENTLIST_DEFAULT_MODULE.content.fadeOutDelayTime,
|
|
8427
|
+
animations: {
|
|
8428
|
+
...EVENTLIST_DEFAULT_MODULE.content.animations,
|
|
8429
|
+
enterAnimation,
|
|
8430
|
+
exitAnimation,
|
|
8431
|
+
enterAnimationDuration: animationDuration,
|
|
8432
|
+
exitAnimationDuration: animationDuration
|
|
8433
|
+
},
|
|
8434
|
+
filters,
|
|
8435
|
+
importMeta: {
|
|
8436
|
+
source: "streamlabs",
|
|
8437
|
+
widgetType: "event_list",
|
|
8438
|
+
importedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
8439
|
+
slTheme: settings.theme ?? null,
|
|
8440
|
+
slThemeColor: settings.theme_color ?? null,
|
|
8441
|
+
slFlipX: settings.flip_x === true,
|
|
8442
|
+
slHadCustomHtml: settings.custom_enabled === true,
|
|
8443
|
+
// Per-event-type minimums SL filters by — Lumia's eventlist
|
|
8444
|
+
// has no equivalent thresholding; preserve so the streamer
|
|
8445
|
+
// can recreate via the alert module's variation conditions.
|
|
8446
|
+
slHostViewerMinimum: settings.host_viewer_minimum ?? 0,
|
|
8447
|
+
slBitsMinimum: settings.bits_minimum ?? 0,
|
|
8448
|
+
slRaidRaiderMinimum: settings.raid_raider_minimum ?? 0
|
|
8449
|
+
}
|
|
8450
|
+
}
|
|
8451
|
+
});
|
|
8452
|
+
return { layer, module, requiresReview };
|
|
8146
8453
|
}
|
|
8147
8454
|
|
|
8148
8455
|
// src/sl-import/sl-dispatch.ts
|
|
8149
|
-
|
|
8456
|
+
function buildSLDescription(widgetType, sourceUrl) {
|
|
8457
|
+
return buildImportDescription(`Imported from Streamlabs ${widgetType}`, sourceUrl);
|
|
8458
|
+
}
|
|
8150
8459
|
var GOAL_WIDGET_TYPES = /* @__PURE__ */ new Set([
|
|
8151
8460
|
"follower_goal",
|
|
8152
8461
|
"sub_goal",
|
|
@@ -8154,8 +8463,6 @@ var GOAL_WIDGET_TYPES = /* @__PURE__ */ new Set([
|
|
|
8154
8463
|
"bit_goal"
|
|
8155
8464
|
]);
|
|
8156
8465
|
var PLACEHOLDER_WIDGET_TYPES = /* @__PURE__ */ new Set([
|
|
8157
|
-
"chat_box",
|
|
8158
|
-
"event_list",
|
|
8159
8466
|
"donation_ticker",
|
|
8160
8467
|
"stream_boss",
|
|
8161
8468
|
"credits",
|
|
@@ -8165,8 +8472,6 @@ var PLACEHOLDER_WIDGET_TYPES = /* @__PURE__ */ new Set([
|
|
|
8165
8472
|
"streamlabels"
|
|
8166
8473
|
]);
|
|
8167
8474
|
var PLACEHOLDER_REASONS = {
|
|
8168
|
-
chat_box: "Lumia has a native chatbox module \u2014 set it up directly rather than importing the SL config.",
|
|
8169
|
-
event_list: "Lumia has a native eventlist module \u2014 set it up directly rather than importing the SL config.",
|
|
8170
8475
|
donation_ticker: "No native Lumia equivalent yet \u2014 imported as a placeholder text layer.",
|
|
8171
8476
|
stream_boss: "Lumia has a native streamboss module \u2014 set it up directly rather than importing the SL config.",
|
|
8172
8477
|
credits: "Lumia has a native credits module \u2014 set it up directly rather than importing the SL config.",
|
|
@@ -8175,19 +8480,14 @@ var PLACEHOLDER_REASONS = {
|
|
|
8175
8480
|
sub_train: "No native Lumia equivalent yet \u2014 imported as a placeholder text layer.",
|
|
8176
8481
|
streamlabels: "Use Lumia template variables (e.g. {{twitch_last_follower}}) inside a Text module instead of importing the SL streamlabels config."
|
|
8177
8482
|
};
|
|
8483
|
+
var CUSTOM_HTML_REVIEW_REASON = "The Streamlabs widget used custom HTML/CSS/JS that Lumia cannot host. The native Lumia module is the right starting point \u2014 recreate the styling there. The original SL settings are stashed under module.content.importMeta for reference.";
|
|
8178
8484
|
function stampImportMeta(module, widgetType, role, extra = {}) {
|
|
8179
|
-
|
|
8180
|
-
|
|
8181
|
-
|
|
8182
|
-
|
|
8183
|
-
|
|
8184
|
-
|
|
8185
|
-
role,
|
|
8186
|
-
importedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
8187
|
-
...existing,
|
|
8188
|
-
...extra
|
|
8189
|
-
}
|
|
8190
|
-
};
|
|
8485
|
+
stampImportMetaMerge(module, {
|
|
8486
|
+
source: "streamlabs",
|
|
8487
|
+
widgetType,
|
|
8488
|
+
role,
|
|
8489
|
+
...extra
|
|
8490
|
+
});
|
|
8191
8491
|
}
|
|
8192
8492
|
function buildPlaceholder(widgetType) {
|
|
8193
8493
|
const id = nanoid7();
|
|
@@ -8219,7 +8519,7 @@ function buildPlaceholder(widgetType) {
|
|
|
8219
8519
|
};
|
|
8220
8520
|
return { layer, module };
|
|
8221
8521
|
}
|
|
8222
|
-
function importStreamlabsWidget(response, widgetType) {
|
|
8522
|
+
function importStreamlabsWidget(response, widgetType, options = {}) {
|
|
8223
8523
|
if (!isSLWidgetConfigResponse(response)) {
|
|
8224
8524
|
throw new Error(
|
|
8225
8525
|
"Streamlabs response is missing the expected `settings` envelope. The widget may be private or the response format may have changed."
|
|
@@ -8269,9 +8569,61 @@ function importStreamlabsWidget(response, widgetType) {
|
|
|
8269
8569
|
coverage.mappings.push({
|
|
8270
8570
|
seType: `streamlabs:${widgetType}`,
|
|
8271
8571
|
lumiaType: "goal",
|
|
8272
|
-
status: "direct",
|
|
8572
|
+
status: built.requiresReview ? "partial" : "direct",
|
|
8573
|
+
count: 1
|
|
8574
|
+
});
|
|
8575
|
+
if (built.requiresReview) {
|
|
8576
|
+
reviewItems.push(
|
|
8577
|
+
customHtmlReviewItem(
|
|
8578
|
+
built.module.id,
|
|
8579
|
+
`streamlabs-${widgetType}`,
|
|
8580
|
+
response.settings,
|
|
8581
|
+
CUSTOM_HTML_REVIEW_REASON
|
|
8582
|
+
)
|
|
8583
|
+
);
|
|
8584
|
+
}
|
|
8585
|
+
} else if (widgetType === "chat_box") {
|
|
8586
|
+
const built = buildSLChatBox(response.settings);
|
|
8587
|
+
stampImportMeta(built.module, widgetType, "chatbox");
|
|
8588
|
+
layers.push(built.layer);
|
|
8589
|
+
modules[built.layer.id] = built.module;
|
|
8590
|
+
coverage.mappings.push({
|
|
8591
|
+
seType: "streamlabs:chat_box",
|
|
8592
|
+
lumiaType: "chatbox",
|
|
8593
|
+
status: built.requiresReview ? "partial" : "direct",
|
|
8594
|
+
count: 1
|
|
8595
|
+
});
|
|
8596
|
+
if (built.requiresReview) {
|
|
8597
|
+
reviewItems.push(
|
|
8598
|
+
customHtmlReviewItem(
|
|
8599
|
+
built.module.id,
|
|
8600
|
+
"streamlabs-chat_box",
|
|
8601
|
+
response.settings,
|
|
8602
|
+
CUSTOM_HTML_REVIEW_REASON
|
|
8603
|
+
)
|
|
8604
|
+
);
|
|
8605
|
+
}
|
|
8606
|
+
} else if (widgetType === "event_list") {
|
|
8607
|
+
const built = buildSLEventList(response.settings);
|
|
8608
|
+
stampImportMeta(built.module, widgetType, "eventlist");
|
|
8609
|
+
layers.push(built.layer);
|
|
8610
|
+
modules[built.layer.id] = built.module;
|
|
8611
|
+
coverage.mappings.push({
|
|
8612
|
+
seType: "streamlabs:event_list",
|
|
8613
|
+
lumiaType: "eventlist",
|
|
8614
|
+
status: built.requiresReview ? "partial" : "direct",
|
|
8273
8615
|
count: 1
|
|
8274
8616
|
});
|
|
8617
|
+
if (built.requiresReview) {
|
|
8618
|
+
reviewItems.push(
|
|
8619
|
+
customHtmlReviewItem(
|
|
8620
|
+
built.module.id,
|
|
8621
|
+
"streamlabs-event_list",
|
|
8622
|
+
response.settings,
|
|
8623
|
+
CUSTOM_HTML_REVIEW_REASON
|
|
8624
|
+
)
|
|
8625
|
+
);
|
|
8626
|
+
}
|
|
8275
8627
|
} else if (PLACEHOLDER_WIDGET_TYPES.has(widgetType)) {
|
|
8276
8628
|
const placeholder = buildPlaceholder(widgetType);
|
|
8277
8629
|
const reason = PLACEHOLDER_REASONS[widgetType] ?? "No native Lumia mapping yet.";
|
|
@@ -8320,7 +8672,7 @@ function importStreamlabsWidget(response, widgetType) {
|
|
|
8320
8672
|
uuid: "",
|
|
8321
8673
|
listen_id: "",
|
|
8322
8674
|
name: overlayName,
|
|
8323
|
-
description:
|
|
8675
|
+
description: buildSLDescription(widgetType, options.sourceUrl),
|
|
8324
8676
|
settings: {
|
|
8325
8677
|
metadata: { width: 1920, height: 1080 },
|
|
8326
8678
|
layers,
|
|
@@ -9882,7 +10234,12 @@ function SEImportWizard({
|
|
|
9882
10234
|
);
|
|
9883
10235
|
}
|
|
9884
10236
|
importedOverlays.push({
|
|
9885
|
-
result: importSEBootstrap(bootstrap
|
|
10237
|
+
result: importSEBootstrap(bootstrap, {
|
|
10238
|
+
// JWT-flow imports don't come from a pasted URL; synthesize
|
|
10239
|
+
// the SE dashboard URL so the description still carries a
|
|
10240
|
+
// useful traceback. Same shape SE editor links use.
|
|
10241
|
+
sourceUrl: `https://streamelements.com/dashboard/overlays/${overlayId}/editor`
|
|
10242
|
+
}),
|
|
9886
10243
|
summary
|
|
9887
10244
|
});
|
|
9888
10245
|
}
|
|
@@ -9927,7 +10284,9 @@ function SEImportWizard({
|
|
|
9927
10284
|
"StreamElements returned a payload that doesn't look like an overlay bootstrap."
|
|
9928
10285
|
);
|
|
9929
10286
|
}
|
|
9930
|
-
const imported = importSEBootstrap(bootstrap
|
|
10287
|
+
const imported = importSEBootstrap(bootstrap, {
|
|
10288
|
+
sourceUrl: `https://streamelements.com/dashboard/overlays/${overlayId}/editor`
|
|
10289
|
+
});
|
|
9931
10290
|
setBatchImports([{ result: imported, summary }]);
|
|
9932
10291
|
setResult(imported);
|
|
9933
10292
|
setAssetUrls(findSEAssetURLs(imported.overlay));
|
|
@@ -10015,7 +10374,9 @@ function SEImportWizard({
|
|
|
10015
10374
|
"Streamlabs returned a response that does not look like a widget config payload."
|
|
10016
10375
|
);
|
|
10017
10376
|
}
|
|
10018
|
-
const imported = importStreamlabsWidget(raw, slParts.widgetType
|
|
10377
|
+
const imported = importStreamlabsWidget(raw, slParts.widgetType, {
|
|
10378
|
+
sourceUrl: url
|
|
10379
|
+
});
|
|
10019
10380
|
setBatchImports([]);
|
|
10020
10381
|
setResult(imported);
|
|
10021
10382
|
setAssetUrls(findSEAssetURLs(imported.overlay));
|
|
@@ -10056,7 +10417,7 @@ function SEImportWizard({
|
|
|
10056
10417
|
"StreamElements returned a response that does not look like an Element widget payload."
|
|
10057
10418
|
);
|
|
10058
10419
|
}
|
|
10059
|
-
const imported = importElementOverlay(raw);
|
|
10420
|
+
const imported = importElementOverlay(raw, { sourceUrl: url });
|
|
10060
10421
|
setBatchImports([]);
|
|
10061
10422
|
setResult(imported);
|
|
10062
10423
|
setAssetUrls(findSEAssetURLs(imported.overlay));
|
|
@@ -10104,7 +10465,7 @@ function SEImportWizard({
|
|
|
10104
10465
|
...parts,
|
|
10105
10466
|
proxyFetch: bindings.proxyFetch
|
|
10106
10467
|
});
|
|
10107
|
-
const imported = importSEBootstrap(bootstrap);
|
|
10468
|
+
const imported = importSEBootstrap(bootstrap, { sourceUrl: url });
|
|
10108
10469
|
setBatchImports([]);
|
|
10109
10470
|
setResult(imported);
|
|
10110
10471
|
setAssetUrls(findSEAssetURLs(imported.overlay));
|
|
@@ -10763,7 +11124,7 @@ function extractErrorMessage(err) {
|
|
|
10763
11124
|
}
|
|
10764
11125
|
|
|
10765
11126
|
// src/se-import/element-dispatch.ts
|
|
10766
|
-
import {
|
|
11127
|
+
import { LumiaAlertValues as LumiaAlertValues3 } from "@lumiastream/lumia-types";
|
|
10767
11128
|
|
|
10768
11129
|
// src/se-import/element-types.ts
|
|
10769
11130
|
function isSEElementResponse(value) {
|
|
@@ -11007,34 +11368,8 @@ function translateAnimationName(name, fallback) {
|
|
|
11007
11368
|
if (PINNED_ANIMATION_MAP[name]) return PINNED_ANIMATION_MAP[name];
|
|
11008
11369
|
return name.replace(/-([a-z])/g, (_m, c) => c.toUpperCase());
|
|
11009
11370
|
}
|
|
11010
|
-
|
|
11011
|
-
|
|
11012
|
-
if (typeof raw !== "string") return fallbackMs;
|
|
11013
|
-
const trimmed = raw.trim();
|
|
11014
|
-
if (!trimmed) return fallbackMs;
|
|
11015
|
-
if (trimmed.endsWith("ms")) {
|
|
11016
|
-
const n2 = parseFloat(trimmed.slice(0, -2));
|
|
11017
|
-
return Number.isFinite(n2) ? n2 : fallbackMs;
|
|
11018
|
-
}
|
|
11019
|
-
if (trimmed.endsWith("s")) {
|
|
11020
|
-
const n2 = parseFloat(trimmed.slice(0, -1));
|
|
11021
|
-
return Number.isFinite(n2) ? n2 * 1e3 : fallbackMs;
|
|
11022
|
-
}
|
|
11023
|
-
const n = parseFloat(trimmed);
|
|
11024
|
-
return Number.isFinite(n) ? n : fallbackMs;
|
|
11025
|
-
}
|
|
11026
|
-
function parsePx2(raw) {
|
|
11027
|
-
if (typeof raw === "number" && Number.isFinite(raw)) return raw;
|
|
11028
|
-
if (typeof raw !== "string") return NaN;
|
|
11029
|
-
const trimmed = raw.trim();
|
|
11030
|
-
if (!trimmed) return NaN;
|
|
11031
|
-
if (trimmed.endsWith("px")) {
|
|
11032
|
-
const n2 = parseFloat(trimmed.slice(0, -2));
|
|
11033
|
-
return Number.isFinite(n2) ? n2 : NaN;
|
|
11034
|
-
}
|
|
11035
|
-
const n = parseFloat(trimmed);
|
|
11036
|
-
return Number.isFinite(n) ? n : NaN;
|
|
11037
|
-
}
|
|
11371
|
+
var parseAnimationDurationMs = parseDurationMs;
|
|
11372
|
+
var parsePx2 = (raw) => pxToNumber(raw, NaN);
|
|
11038
11373
|
function findFieldByType(fields, type) {
|
|
11039
11374
|
if (!fields) return void 0;
|
|
11040
11375
|
for (const f of Object.values(fields)) {
|
|
@@ -11110,6 +11445,47 @@ function buildAnimations(title) {
|
|
|
11110
11445
|
const visibleDurationMs = enterDelay + enterDuration + staticDuration + exitDuration;
|
|
11111
11446
|
return { animations, visibleDurationMs: visibleDurationMs || DEFAULT_DURATION_MS };
|
|
11112
11447
|
}
|
|
11448
|
+
function resolveFieldBoundsInCanvas(style, canvas, textContent) {
|
|
11449
|
+
if (!style) return null;
|
|
11450
|
+
const x = parsePx2(style.left);
|
|
11451
|
+
const y = parsePx2(style.top);
|
|
11452
|
+
const hasXY = Number.isFinite(x) || Number.isFinite(y);
|
|
11453
|
+
if (!hasXY && style.width == null && style.height == null) return null;
|
|
11454
|
+
const sx = Number.isFinite(x) ? x : 0;
|
|
11455
|
+
const sy = Number.isFinite(y) ? y : 0;
|
|
11456
|
+
let width = parsePx2(style.width);
|
|
11457
|
+
let height = parsePx2(style.height);
|
|
11458
|
+
if (!Number.isFinite(width)) width = Math.max(1, canvas.width - sx);
|
|
11459
|
+
if (!Number.isFinite(height)) {
|
|
11460
|
+
if (typeof textContent === "string") {
|
|
11461
|
+
const lineCount = (textContent.match(/\n/g)?.length ?? 0) + 1;
|
|
11462
|
+
const lhPx = parsePx2(style.lineHeight) || parsePx2(style["line-height"]);
|
|
11463
|
+
const fsPx = parsePx2(style.fontSize);
|
|
11464
|
+
let effectiveLh = lhPx;
|
|
11465
|
+
if (!Number.isFinite(effectiveLh) || effectiveLh < 8) {
|
|
11466
|
+
effectiveLh = Number.isFinite(fsPx) ? fsPx * 1.3 : 24 * 1.3;
|
|
11467
|
+
}
|
|
11468
|
+
height = Math.max(1, lineCount * effectiveLh);
|
|
11469
|
+
} else {
|
|
11470
|
+
height = Math.max(1, canvas.height - sy);
|
|
11471
|
+
}
|
|
11472
|
+
}
|
|
11473
|
+
return { x: sx, y: sy, width, height };
|
|
11474
|
+
}
|
|
11475
|
+
function unionBounds(boxes) {
|
|
11476
|
+
if (boxes.length === 0) return null;
|
|
11477
|
+
let minX = Infinity;
|
|
11478
|
+
let minY = Infinity;
|
|
11479
|
+
let maxX = -Infinity;
|
|
11480
|
+
let maxY = -Infinity;
|
|
11481
|
+
for (const b of boxes) {
|
|
11482
|
+
minX = Math.min(minX, b.x);
|
|
11483
|
+
minY = Math.min(minY, b.y);
|
|
11484
|
+
maxX = Math.max(maxX, b.x + b.width);
|
|
11485
|
+
maxY = Math.max(maxY, b.y + b.height);
|
|
11486
|
+
}
|
|
11487
|
+
return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };
|
|
11488
|
+
}
|
|
11113
11489
|
function buildElementAlertEvent(state, options = {}) {
|
|
11114
11490
|
const compositeFields = state.settings?.compositeFields;
|
|
11115
11491
|
const titleField = findFieldByType(compositeFields, "text");
|
|
@@ -11127,6 +11503,31 @@ function buildElementAlertEvent(state, options = {}) {
|
|
|
11127
11503
|
const titleStyle = titleField?.style;
|
|
11128
11504
|
const highlightColor = titleField?.highlightedStyle?.color ?? null;
|
|
11129
11505
|
const { animations, visibleDurationMs } = buildAnimations(titleField);
|
|
11506
|
+
const canvas = options.canvas ?? { width: 1920, height: 1080 };
|
|
11507
|
+
const mediaBounds = resolveFieldBoundsInCanvas(mainAsset?.style, canvas);
|
|
11508
|
+
const textBounds = resolveFieldBoundsInCanvas(titleStyle, canvas, rawMessage);
|
|
11509
|
+
const collected = [];
|
|
11510
|
+
if (mediaBounds) collected.push(mediaBounds);
|
|
11511
|
+
if (textBounds) collected.push(textBounds);
|
|
11512
|
+
let layerBounds = unionBounds(collected);
|
|
11513
|
+
if (!layerBounds) {
|
|
11514
|
+
layerBounds = {
|
|
11515
|
+
x: Math.round(canvas.width * 0.6),
|
|
11516
|
+
y: Math.round(canvas.height * 0.15),
|
|
11517
|
+
width: 400,
|
|
11518
|
+
height: 300
|
|
11519
|
+
};
|
|
11520
|
+
}
|
|
11521
|
+
let pushTextUp = 0;
|
|
11522
|
+
let pushTextLeft = 0;
|
|
11523
|
+
if (textBounds) {
|
|
11524
|
+
const desiredTextTopInLayer = textBounds.y - layerBounds.y;
|
|
11525
|
+
const naturalTextTopInLayer = Math.max(0, (layerBounds.height - textBounds.height) / 2);
|
|
11526
|
+
pushTextUp = Math.round(desiredTextTopInLayer - naturalTextTopInLayer);
|
|
11527
|
+
const desiredTextLeftInLayer = textBounds.x - layerBounds.x;
|
|
11528
|
+
const naturalTextLeftInLayer = Math.max(0, (layerBounds.width - textBounds.width) / 2);
|
|
11529
|
+
pushTextLeft = Math.round(desiredTextLeftInLayer - naturalTextLeftInLayer);
|
|
11530
|
+
}
|
|
11130
11531
|
const event = {
|
|
11131
11532
|
on: true,
|
|
11132
11533
|
// `'custom'` lowercase is load-bearing in Lumia's AlertBoxHandler —
|
|
@@ -11145,7 +11546,11 @@ function buildElementAlertEvent(state, options = {}) {
|
|
|
11145
11546
|
showBrandIcon: true
|
|
11146
11547
|
},
|
|
11147
11548
|
settings: { duration: visibleDurationMs },
|
|
11148
|
-
|
|
11549
|
+
// `textOver` matches SE Element's text-on-video render pattern.
|
|
11550
|
+
// `imageOver` / `column` / `row` would all stack the text outside
|
|
11551
|
+
// the media, which is the bug this layout fixes (text rendered
|
|
11552
|
+
// below the alert graphic instead of overlaid on it).
|
|
11553
|
+
layout: { value: "textOver", css: {}, customCss: "", pushTextUp, pushTextLeft },
|
|
11149
11554
|
text: {
|
|
11150
11555
|
css: titleCss(titleStyle),
|
|
11151
11556
|
messageCss: {},
|
|
@@ -11167,44 +11572,13 @@ function buildElementAlertEvent(state, options = {}) {
|
|
|
11167
11572
|
},
|
|
11168
11573
|
variations: []
|
|
11169
11574
|
};
|
|
11170
|
-
|
|
11171
|
-
let bounds;
|
|
11172
|
-
if (style) {
|
|
11173
|
-
const x = parsePx2(style.left);
|
|
11174
|
-
const y = parsePx2(style.top);
|
|
11175
|
-
const width = parsePx2(style.width);
|
|
11176
|
-
const height = parsePx2(style.height);
|
|
11177
|
-
if (Number.isFinite(x) && Number.isFinite(y) && Number.isFinite(width)) {
|
|
11178
|
-
bounds = {
|
|
11179
|
-
x,
|
|
11180
|
-
y,
|
|
11181
|
-
width,
|
|
11182
|
-
// Height isn't always present on video Main Assets (the video
|
|
11183
|
-
// aspect-ratios itself from the source). Fall back to a
|
|
11184
|
-
// reasonable default that matches SE's preview row.
|
|
11185
|
-
height: Number.isFinite(height) ? height : Math.round(width * 0.75)
|
|
11186
|
-
};
|
|
11187
|
-
}
|
|
11188
|
-
}
|
|
11189
|
-
return { event, bounds };
|
|
11575
|
+
return { event, bounds: layerBounds };
|
|
11190
11576
|
}
|
|
11191
11577
|
|
|
11192
11578
|
// src/se-import/mappers/element-scene.ts
|
|
11193
|
-
import { nanoid as nanoid8 } from "nanoid";
|
|
11194
11579
|
var TEXT_FALLBACK = { width: 400, height: 50 };
|
|
11195
11580
|
var IMAGE_FALLBACK = { width: 300, height: 100 };
|
|
11196
|
-
|
|
11197
|
-
if (typeof raw === "number" && Number.isFinite(raw)) return raw;
|
|
11198
|
-
if (typeof raw !== "string") return NaN;
|
|
11199
|
-
const trimmed = raw.trim();
|
|
11200
|
-
if (!trimmed) return NaN;
|
|
11201
|
-
if (trimmed.endsWith("px")) {
|
|
11202
|
-
const n2 = parseFloat(trimmed.slice(0, -2));
|
|
11203
|
-
return Number.isFinite(n2) ? n2 : NaN;
|
|
11204
|
-
}
|
|
11205
|
-
const n = parseFloat(trimmed);
|
|
11206
|
-
return Number.isFinite(n) ? n : NaN;
|
|
11207
|
-
}
|
|
11581
|
+
var parsePx3 = (raw) => pxToNumber(raw, NaN);
|
|
11208
11582
|
function styleToBounds(style, type, canvas) {
|
|
11209
11583
|
const x = Number.isFinite(parsePx3(style?.left)) ? parsePx3(style?.left) : 0;
|
|
11210
11584
|
const y = Number.isFinite(parsePx3(style?.top)) ? parsePx3(style?.top) : 0;
|
|
@@ -11240,33 +11614,17 @@ function styleToBounds(style, type, canvas) {
|
|
|
11240
11614
|
}
|
|
11241
11615
|
return { x, y, width, height };
|
|
11242
11616
|
}
|
|
11243
|
-
function
|
|
11244
|
-
|
|
11245
|
-
|
|
11246
|
-
|
|
11247
|
-
|
|
11248
|
-
bounds: {
|
|
11249
|
-
x: bounds.x,
|
|
11250
|
-
y: bounds.y,
|
|
11251
|
-
width: bounds.width,
|
|
11252
|
-
height: bounds.height,
|
|
11253
|
-
scale: [1, 1],
|
|
11254
|
-
zIndex
|
|
11255
|
-
}
|
|
11256
|
-
};
|
|
11257
|
-
}
|
|
11258
|
-
function buildModule(id, type, title, content, css = {}) {
|
|
11259
|
-
return {
|
|
11260
|
-
id,
|
|
11261
|
-
version: 1,
|
|
11262
|
-
loaded: true,
|
|
11263
|
-
settings: { type, title, locked: false },
|
|
11264
|
-
lights: [],
|
|
11265
|
-
css,
|
|
11617
|
+
function buildChild(groupId, zIndex, bounds, type, title, content, css = {}) {
|
|
11618
|
+
const { layer, module } = buildModuleEnvelope({
|
|
11619
|
+
type,
|
|
11620
|
+
title,
|
|
11621
|
+
bounds,
|
|
11266
11622
|
content,
|
|
11267
|
-
|
|
11268
|
-
|
|
11269
|
-
|
|
11623
|
+
css,
|
|
11624
|
+
parentGroupId: groupId,
|
|
11625
|
+
zIndex
|
|
11626
|
+
});
|
|
11627
|
+
return { layer, module };
|
|
11270
11628
|
}
|
|
11271
11629
|
function textStyleToCss(style) {
|
|
11272
11630
|
const s = style ?? {};
|
|
@@ -11281,80 +11639,69 @@ function textStyleToCss(style) {
|
|
|
11281
11639
|
return out;
|
|
11282
11640
|
}
|
|
11283
11641
|
function mapCompositeField(name, field, groupId, zIndex, provider, canvas) {
|
|
11284
|
-
const id = nanoid8();
|
|
11285
11642
|
switch (field.type) {
|
|
11286
11643
|
case "video": {
|
|
11287
|
-
const bounds = styleToBounds(field.style, "video", canvas);
|
|
11288
|
-
const layer = buildLayer(id, groupId, bounds, zIndex);
|
|
11289
11644
|
const src = pickFieldMediaHref(field.media, "video/");
|
|
11290
11645
|
const volume = typeof field.volume === "number" ? field.volume : 1;
|
|
11291
|
-
|
|
11292
|
-
|
|
11293
|
-
|
|
11294
|
-
|
|
11295
|
-
|
|
11296
|
-
|
|
11297
|
-
|
|
11298
|
-
|
|
11646
|
+
return buildChild(
|
|
11647
|
+
groupId,
|
|
11648
|
+
zIndex,
|
|
11649
|
+
styleToBounds(field.style, "video", canvas),
|
|
11650
|
+
"video",
|
|
11651
|
+
name,
|
|
11652
|
+
{ src, volume, loop: true, autoplay: true, muted: volume === 0 }
|
|
11653
|
+
);
|
|
11299
11654
|
}
|
|
11300
11655
|
case "image": {
|
|
11301
|
-
const bounds = styleToBounds(field.style, "image", canvas);
|
|
11302
|
-
const layer = buildLayer(id, groupId, bounds, zIndex);
|
|
11303
11656
|
const src = pickFieldMediaHref(field.media, "image/");
|
|
11304
|
-
|
|
11305
|
-
|
|
11657
|
+
return buildChild(
|
|
11658
|
+
groupId,
|
|
11659
|
+
zIndex,
|
|
11660
|
+
styleToBounds(field.style, "image", canvas),
|
|
11661
|
+
"image",
|
|
11662
|
+
name,
|
|
11663
|
+
{ src }
|
|
11664
|
+
);
|
|
11306
11665
|
}
|
|
11307
11666
|
case "text": {
|
|
11308
|
-
const bounds = styleToBounds(field.style, "text", canvas);
|
|
11309
|
-
const layer = buildLayer(id, groupId, bounds, zIndex);
|
|
11310
11667
|
const raw = field.text?.[0]?.content ?? "";
|
|
11311
11668
|
const value = substituteElementTokens(raw, { provider });
|
|
11312
|
-
|
|
11313
|
-
|
|
11669
|
+
return buildChild(
|
|
11670
|
+
groupId,
|
|
11671
|
+
zIndex,
|
|
11672
|
+
styleToBounds(field.style, "text", canvas),
|
|
11314
11673
|
"text",
|
|
11315
11674
|
name,
|
|
11316
11675
|
{ value, highlightColor: "inherit" },
|
|
11317
11676
|
textStyleToCss(field.style)
|
|
11318
11677
|
);
|
|
11319
|
-
return { layer, module };
|
|
11320
11678
|
}
|
|
11321
11679
|
case "audio": {
|
|
11322
|
-
const layer = buildLayer(id, groupId, { x: 0, y: 0, width: 1, height: 1 }, zIndex);
|
|
11323
11680
|
const src = pickFieldMediaHref(field.media, "audio/");
|
|
11324
11681
|
const volume = typeof field.volume === "number" ? field.volume : 0.5;
|
|
11325
|
-
|
|
11326
|
-
|
|
11682
|
+
return buildChild(
|
|
11683
|
+
groupId,
|
|
11684
|
+
zIndex,
|
|
11685
|
+
{ x: 0, y: 0, width: 1, height: 1 },
|
|
11686
|
+
"audio",
|
|
11687
|
+
name,
|
|
11688
|
+
{ src, volume, loop: false }
|
|
11689
|
+
);
|
|
11327
11690
|
}
|
|
11328
11691
|
default:
|
|
11329
11692
|
return null;
|
|
11330
11693
|
}
|
|
11331
11694
|
}
|
|
11332
11695
|
function buildElementScene(state, options) {
|
|
11333
|
-
const groupId = nanoid8();
|
|
11334
11696
|
const groupTitle = typeof state.displayName === "string" && state.displayName || state.referenceId || "Scene";
|
|
11335
|
-
const groupLayer = {
|
|
11336
|
-
id: groupId,
|
|
11697
|
+
const { id: groupId, layer: groupLayer, module: groupModule } = buildModuleEnvelope({
|
|
11337
11698
|
type: "group",
|
|
11338
|
-
|
|
11339
|
-
bounds: {
|
|
11340
|
-
|
|
11341
|
-
|
|
11342
|
-
|
|
11343
|
-
|
|
11344
|
-
scale: [1, 1]
|
|
11345
|
-
},
|
|
11346
|
-
state: { visible: true, locked: false, expanded: false }
|
|
11347
|
-
};
|
|
11348
|
-
const groupModule = {
|
|
11349
|
-
id: groupId,
|
|
11350
|
-
loaded: true,
|
|
11351
|
-
settings: { type: "group", title: groupTitle },
|
|
11352
|
-
lights: [],
|
|
11353
|
-
css: {},
|
|
11354
|
-
content: {},
|
|
11355
|
-
variables: {},
|
|
11356
|
-
events: {}
|
|
11357
|
-
};
|
|
11699
|
+
title: groupTitle,
|
|
11700
|
+
bounds: { x: 0, y: 0, width: options.canvas.width, height: options.canvas.height },
|
|
11701
|
+
type_layer: "group",
|
|
11702
|
+
parentGroupId: null,
|
|
11703
|
+
expanded: false
|
|
11704
|
+
});
|
|
11358
11705
|
const children = [];
|
|
11359
11706
|
const fields = state.settings?.compositeFields ?? {};
|
|
11360
11707
|
let zIndex = 1;
|
|
@@ -11373,7 +11720,12 @@ function buildElementScene(state, options) {
|
|
|
11373
11720
|
}
|
|
11374
11721
|
|
|
11375
11722
|
// src/se-import/element-dispatch.ts
|
|
11376
|
-
|
|
11723
|
+
function buildElementDescription(widgetInstanceId, sourceUrl) {
|
|
11724
|
+
return buildImportDescription(
|
|
11725
|
+
`Imported from StreamElements Element widget ${widgetInstanceId}`,
|
|
11726
|
+
sourceUrl
|
|
11727
|
+
);
|
|
11728
|
+
}
|
|
11377
11729
|
function elementAlertKindToLumiaKeys(kind, provider) {
|
|
11378
11730
|
switch (kind) {
|
|
11379
11731
|
case "follower":
|
|
@@ -11392,9 +11744,9 @@ function elementAlertKindToLumiaKeys(kind, provider) {
|
|
|
11392
11744
|
return alertBoxKeysFor("charityCampaignDonation", provider);
|
|
11393
11745
|
case "subscriberGift":
|
|
11394
11746
|
case "communityGiftPurchase": {
|
|
11395
|
-
if (provider === "twitch") return [
|
|
11396
|
-
if (provider === "kick") return [
|
|
11397
|
-
if (provider === "youtube") return [
|
|
11747
|
+
if (provider === "twitch") return [LumiaAlertValues3.TWITCH_GIFT_SUBSCRIPTION];
|
|
11748
|
+
if (provider === "kick") return [LumiaAlertValues3.KICK_GIFT_SUBSCRIPTION];
|
|
11749
|
+
if (provider === "youtube") return [LumiaAlertValues3.YOUTUBE_GIFT_MEMBERS];
|
|
11398
11750
|
return alertBoxKeysFor("subscriber", provider);
|
|
11399
11751
|
}
|
|
11400
11752
|
default:
|
|
@@ -11409,7 +11761,7 @@ function buildCombinedAlertModule(alertStates, provider, canvas) {
|
|
|
11409
11761
|
for (const state of alertStates) {
|
|
11410
11762
|
const cls = classifyConfigState(state);
|
|
11411
11763
|
if (cls.kind !== "alert") continue;
|
|
11412
|
-
const { event, bounds: bounds2 } = buildElementAlertEvent(state, { provider });
|
|
11764
|
+
const { event, bounds: bounds2 } = buildElementAlertEvent(state, { provider, canvas });
|
|
11413
11765
|
const keys = elementAlertKindToLumiaKeys(cls.alertKind, provider);
|
|
11414
11766
|
if (keys.length === 0) continue;
|
|
11415
11767
|
for (const key of keys) {
|
|
@@ -11421,61 +11773,42 @@ function buildCombinedAlertModule(alertStates, provider, canvas) {
|
|
|
11421
11773
|
}
|
|
11422
11774
|
}
|
|
11423
11775
|
if (Object.keys(events).length === 0) return null;
|
|
11424
|
-
const id = nanoid9();
|
|
11425
11776
|
const bounds = firstBounds ?? {
|
|
11426
11777
|
x: Math.round(canvas.width * 0.6),
|
|
11427
11778
|
y: Math.round(canvas.height * 0.15),
|
|
11428
11779
|
width: 400,
|
|
11429
11780
|
height: 300
|
|
11430
11781
|
};
|
|
11431
|
-
const layer = {
|
|
11432
|
-
id,
|
|
11433
|
-
state: { visible: true, locked: false },
|
|
11434
|
-
bounds: {
|
|
11435
|
-
x: bounds.x,
|
|
11436
|
-
y: bounds.y,
|
|
11437
|
-
width: bounds.width,
|
|
11438
|
-
height: bounds.height,
|
|
11439
|
-
scale: [1, 1]
|
|
11440
|
-
}
|
|
11441
|
-
};
|
|
11442
11782
|
const baseAlert = firstEvent ? stripEventOnlyFields2(firstEvent) : {};
|
|
11443
|
-
const module = {
|
|
11444
|
-
|
|
11445
|
-
|
|
11446
|
-
|
|
11447
|
-
settings: { type: "alert", title: "Alerts (Element import)", locked: false },
|
|
11448
|
-
lights: [],
|
|
11449
|
-
css: {},
|
|
11450
|
-
content: {},
|
|
11451
|
-
variables: {},
|
|
11452
|
-
events: {},
|
|
11783
|
+
const { layer, module } = buildModuleEnvelope({
|
|
11784
|
+
type: "alert",
|
|
11785
|
+
title: "Alerts (Element import)",
|
|
11786
|
+
bounds,
|
|
11453
11787
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
11454
11788
|
alert: { ...baseAlert, events }
|
|
11455
|
-
};
|
|
11789
|
+
});
|
|
11456
11790
|
return { layer, module };
|
|
11457
11791
|
}
|
|
11458
11792
|
function stripEventOnlyFields2(event) {
|
|
11459
|
-
const {
|
|
11793
|
+
const {
|
|
11794
|
+
on: _on,
|
|
11795
|
+
variations: _variations,
|
|
11796
|
+
matchEmptyCondition: _mec,
|
|
11797
|
+
...base
|
|
11798
|
+
} = event;
|
|
11460
11799
|
return base;
|
|
11461
11800
|
}
|
|
11462
11801
|
function stampImportMeta2(module, state, role) {
|
|
11463
|
-
module
|
|
11464
|
-
|
|
11465
|
-
|
|
11466
|
-
|
|
11467
|
-
|
|
11468
|
-
|
|
11469
|
-
|
|
11470
|
-
displayName: state?.displayName,
|
|
11471
|
-
importedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
11472
|
-
}
|
|
11473
|
-
};
|
|
11802
|
+
stampImportMetaMerge(module, {
|
|
11803
|
+
source: "streamelements-element",
|
|
11804
|
+
role,
|
|
11805
|
+
referenceId: state?.referenceId,
|
|
11806
|
+
categoryId: state?.categoryId,
|
|
11807
|
+
displayName: state?.displayName
|
|
11808
|
+
});
|
|
11474
11809
|
}
|
|
11475
|
-
function importElementOverlay(response) {
|
|
11476
|
-
const configData = parseElementConfigData(
|
|
11477
|
-
response.widgetInstanceConfigVersion.configData
|
|
11478
|
-
);
|
|
11810
|
+
function importElementOverlay(response, options = {}) {
|
|
11811
|
+
const configData = parseElementConfigData(response.widgetInstanceConfigVersion.configData);
|
|
11479
11812
|
if (!configData) {
|
|
11480
11813
|
throw new Error(
|
|
11481
11814
|
"StreamElements Element response carries an invalid configData payload. The widget may be corrupted or the response format may have changed."
|
|
@@ -11545,7 +11878,10 @@ function importElementOverlay(response) {
|
|
|
11545
11878
|
uuid: "",
|
|
11546
11879
|
listen_id: "",
|
|
11547
11880
|
name: response.widgetInstance.displayName ? `[SE Element] ${response.widgetInstance.displayName}` : `Imported from StreamElements Element (${response.widgetInstance.widgetInstanceId})`,
|
|
11548
|
-
description:
|
|
11881
|
+
description: buildElementDescription(
|
|
11882
|
+
response.widgetInstance.widgetInstanceId,
|
|
11883
|
+
options.sourceUrl
|
|
11884
|
+
),
|
|
11549
11885
|
settings: {
|
|
11550
11886
|
metadata: { width: canvas.width, height: canvas.height },
|
|
11551
11887
|
layers,
|
|
@@ -11559,7 +11895,7 @@ function importElementOverlay(response) {
|
|
|
11559
11895
|
}
|
|
11560
11896
|
|
|
11561
11897
|
// src/se-import/index.ts
|
|
11562
|
-
var
|
|
11898
|
+
var IMPORT_META_KEY2 = "importMeta";
|
|
11563
11899
|
var REVIEW_REASONS = {
|
|
11564
11900
|
"se-widget-bit-boss": "No native Lumia equivalent \u2014 bit boss fight bar with HP/damage states.",
|
|
11565
11901
|
// `se-widget-hype-cup` intentionally omitted — it now routes to the native
|
|
@@ -11589,6 +11925,10 @@ function reasonFor(seType, status, flaggedOff) {
|
|
|
11589
11925
|
if (flaggedOff && FLAG_OFF_REASONS[seType]) return FLAG_OFF_REASONS[seType];
|
|
11590
11926
|
return REVIEW_REASONS[seType] ?? (status === "template" ? "Imported as a generic template stub." : "No native mapping yet \u2014 imported as a labelled text placeholder.");
|
|
11591
11927
|
}
|
|
11928
|
+
function buildSEBootstrapDescription(overlayId, sourceUrl) {
|
|
11929
|
+
const head = overlayId ? `Imported from StreamElements overlay ${overlayId}` : "Imported from StreamElements";
|
|
11930
|
+
return buildImportDescription(head, sourceUrl);
|
|
11931
|
+
}
|
|
11592
11932
|
function extractSEOverlayId(input) {
|
|
11593
11933
|
const trimmed = input.trim();
|
|
11594
11934
|
const m = trimmed.match(/[0-9a-f]{24}/i);
|
|
@@ -11643,7 +11983,7 @@ function isSEBootstrap(value) {
|
|
|
11643
11983
|
const o = v.overlay;
|
|
11644
11984
|
return Array.isArray(o.widgets);
|
|
11645
11985
|
}
|
|
11646
|
-
function importSEBootstrap(bootstrap) {
|
|
11986
|
+
function importSEBootstrap(bootstrap, options = {}) {
|
|
11647
11987
|
const seOverlay = bootstrap.overlay;
|
|
11648
11988
|
const widgets = seOverlay?.widgets ?? [];
|
|
11649
11989
|
const coverage = {
|
|
@@ -11666,7 +12006,7 @@ function importSEBootstrap(bootstrap) {
|
|
|
11666
12006
|
if (w.type !== "se-widget-group") continue;
|
|
11667
12007
|
const uid = w.variables?.uid;
|
|
11668
12008
|
if (typeof uid !== "string") continue;
|
|
11669
|
-
const lumiaGroupId =
|
|
12009
|
+
const lumiaGroupId = nanoid8();
|
|
11670
12010
|
seUidToLumiaGroupId[uid] = lumiaGroupId;
|
|
11671
12011
|
groupWidgetByUid[uid] = w;
|
|
11672
12012
|
}
|
|
@@ -11705,7 +12045,7 @@ function importSEBootstrap(bootstrap) {
|
|
|
11705
12045
|
lights: [],
|
|
11706
12046
|
css: {},
|
|
11707
12047
|
content: {
|
|
11708
|
-
[
|
|
12048
|
+
[IMPORT_META_KEY2]: {
|
|
11709
12049
|
source: "streamelements",
|
|
11710
12050
|
widgetType: w.type,
|
|
11711
12051
|
importedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -11743,7 +12083,7 @@ function importSEBootstrap(bootstrap) {
|
|
|
11743
12083
|
if (result.status === "placeholder" || result.status === "template") {
|
|
11744
12084
|
module.content = {
|
|
11745
12085
|
...module.content ?? {},
|
|
11746
|
-
[
|
|
12086
|
+
[IMPORT_META_KEY2]: {
|
|
11747
12087
|
source: "streamelements",
|
|
11748
12088
|
widgetType: w.type,
|
|
11749
12089
|
importedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -11783,7 +12123,7 @@ function importSEBootstrap(bootstrap) {
|
|
|
11783
12123
|
uuid: "",
|
|
11784
12124
|
listen_id: "",
|
|
11785
12125
|
name: seOverlay?.name ? `[SE] ${seOverlay.name}` : `Imported from StreamElements (${seOverlay?._id ?? ""})`,
|
|
11786
|
-
description: seOverlay?._id
|
|
12126
|
+
description: buildSEBootstrapDescription(seOverlay?._id, options.sourceUrl),
|
|
11787
12127
|
settings: {
|
|
11788
12128
|
metadata: {
|
|
11789
12129
|
width: seOverlay?.settings?.width ?? 1920,
|
|
@@ -11831,7 +12171,7 @@ function applyReviewAction(result, moduleId, action, payload) {
|
|
|
11831
12171
|
bounds: existingLayer.bounds,
|
|
11832
12172
|
state: existingLayer.state
|
|
11833
12173
|
};
|
|
11834
|
-
const importMeta2 = existing2.content?.[
|
|
12174
|
+
const importMeta2 = existing2.content?.[IMPORT_META_KEY2];
|
|
11835
12175
|
const mergedLights = (existing2.lights?.length ?? 0) > 0 ? existing2.lights : transplant.module.lights;
|
|
11836
12176
|
const mergedEvents = existing2.events && Object.keys(existing2.events).length > 0 ? { ...transplant.module.events, ...existing2.events } : transplant.module.events;
|
|
11837
12177
|
const mergedVariables = existing2.variables && Object.keys(existing2.variables).length > 0 ? { ...transplant.module.variables, ...existing2.variables } : transplant.module.variables;
|
|
@@ -11843,7 +12183,7 @@ function applyReviewAction(result, moduleId, action, payload) {
|
|
|
11843
12183
|
variables: mergedVariables,
|
|
11844
12184
|
content: {
|
|
11845
12185
|
...transplant.module.content ?? {},
|
|
11846
|
-
[
|
|
12186
|
+
[IMPORT_META_KEY2]: importMeta2
|
|
11847
12187
|
}
|
|
11848
12188
|
};
|
|
11849
12189
|
const rootOldNewId = transplant.layer.id;
|
|
@@ -11871,7 +12211,7 @@ function applyReviewAction(result, moduleId, action, payload) {
|
|
|
11871
12211
|
const existing = modules[moduleId];
|
|
11872
12212
|
const generated = payload;
|
|
11873
12213
|
if (!existing || !generated) return result;
|
|
11874
|
-
const importMeta = existing.content?.[
|
|
12214
|
+
const importMeta = existing.content?.[IMPORT_META_KEY2];
|
|
11875
12215
|
const replaced = {
|
|
11876
12216
|
...existing,
|
|
11877
12217
|
settings: { ...existing.settings ?? {}, type: "custom" },
|
|
@@ -11885,7 +12225,7 @@ function applyReviewAction(result, moduleId, action, payload) {
|
|
|
11885
12225
|
data: parseLooseJson(generated.data) ?? {},
|
|
11886
12226
|
configs: parseLooseJson(generated.configs) ?? [],
|
|
11887
12227
|
flavor: "ai-generated",
|
|
11888
|
-
[
|
|
12228
|
+
[IMPORT_META_KEY2]: importMeta
|
|
11889
12229
|
}
|
|
11890
12230
|
};
|
|
11891
12231
|
modules[moduleId] = replaced;
|