stimulus_reflex 3.5.0.pre9 → 3.5.0.rc1
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.
Potentially problematic release.
This version of stimulus_reflex might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Gemfile +0 -1
- data/Gemfile.lock +122 -127
- data/README.md +13 -19
- data/app/assets/javascripts/stimulus_reflex.js +1017 -523
- data/app/assets/javascripts/stimulus_reflex.umd.js +940 -496
- data/app/channels/stimulus_reflex/channel.rb +9 -24
- data/bin/console +0 -2
- data/bin/standardize +2 -1
- data/lib/generators/stimulus_reflex/stimulus_reflex_generator.rb +68 -9
- data/lib/generators/stimulus_reflex/templates/app/controllers/examples_controller.rb.tt +9 -0
- data/lib/generators/stimulus_reflex/templates/app/javascript/channels/consumer.js.tt +6 -0
- data/lib/generators/stimulus_reflex/templates/app/javascript/channels/index.js.esbuild.tt +4 -0
- data/lib/generators/stimulus_reflex/templates/app/javascript/channels/index.js.importmap.tt +2 -0
- data/lib/generators/stimulus_reflex/templates/app/javascript/channels/index.js.shakapacker.tt +5 -0
- data/lib/generators/stimulus_reflex/templates/app/javascript/channels/index.js.vite.tt +1 -0
- data/lib/generators/stimulus_reflex/templates/app/javascript/channels/index.js.webpacker.tt +5 -0
- data/lib/generators/stimulus_reflex/templates/app/javascript/config/cable_ready.js.tt +4 -0
- data/lib/generators/stimulus_reflex/templates/app/javascript/config/index.js.tt +2 -0
- data/lib/generators/stimulus_reflex/templates/app/javascript/config/mrujs.js.tt +9 -0
- data/lib/generators/stimulus_reflex/templates/app/javascript/config/stimulus_reflex.js.tt +5 -0
- data/lib/generators/stimulus_reflex/templates/app/javascript/controllers/%file_name%_controller.js.tt +141 -0
- data/lib/generators/stimulus_reflex/templates/app/javascript/controllers/application.js.tt +11 -0
- data/lib/generators/stimulus_reflex/templates/app/javascript/controllers/application_controller.js.tt +74 -0
- data/lib/generators/stimulus_reflex/templates/app/javascript/controllers/index.js.esbuild.tt +7 -0
- data/lib/generators/stimulus_reflex/templates/app/javascript/controllers/index.js.importmap.tt +5 -0
- data/lib/generators/stimulus_reflex/templates/app/javascript/controllers/index.js.shakapacker.tt +5 -0
- data/lib/generators/stimulus_reflex/templates/app/javascript/controllers/index.js.vite.tt +5 -0
- data/lib/generators/stimulus_reflex/templates/app/javascript/controllers/index.js.webpacker.tt +5 -0
- data/{test/tmp/app/reflexes/user_reflex.rb → lib/generators/stimulus_reflex/templates/app/reflexes/%file_name%_reflex.rb.tt} +38 -9
- data/lib/generators/stimulus_reflex/templates/app/reflexes/application_reflex.rb.tt +27 -0
- data/lib/generators/stimulus_reflex/templates/app/views/examples/show.html.erb.tt +207 -0
- data/lib/generators/stimulus_reflex/templates/config/initializers/cable_ready.rb +27 -0
- data/lib/generators/stimulus_reflex/templates/config/initializers/stimulus_reflex.rb +18 -13
- data/lib/generators/stimulus_reflex/templates/esbuild.config.mjs.tt +94 -0
- data/lib/install/action_cable.rb +155 -0
- data/lib/install/broadcaster.rb +90 -0
- data/lib/install/bundle.rb +56 -0
- data/lib/install/compression.rb +41 -0
- data/lib/install/config.rb +87 -0
- data/lib/install/development.rb +110 -0
- data/lib/install/esbuild.rb +114 -0
- data/lib/install/example.rb +22 -0
- data/lib/install/importmap.rb +133 -0
- data/lib/install/initializers.rb +25 -0
- data/lib/install/mrujs.rb +133 -0
- data/lib/install/npm_packages.rb +25 -0
- data/lib/install/reflexes.rb +25 -0
- data/lib/install/shakapacker.rb +64 -0
- data/lib/install/spring.rb +54 -0
- data/lib/install/updatable.rb +34 -0
- data/lib/install/vite.rb +64 -0
- data/lib/install/webpacker.rb +90 -0
- data/lib/install/yarn.rb +55 -0
- data/lib/stimulus_reflex/broadcasters/broadcaster.rb +15 -8
- data/lib/stimulus_reflex/broadcasters/page_broadcaster.rb +7 -8
- data/lib/stimulus_reflex/broadcasters/selector_broadcaster.rb +10 -10
- data/lib/stimulus_reflex/broadcasters/update.rb +3 -0
- data/lib/stimulus_reflex/cable_readiness.rb +29 -0
- data/lib/stimulus_reflex/cable_ready_channels.rb +6 -5
- data/lib/stimulus_reflex/callbacks.rb +17 -1
- data/lib/stimulus_reflex/concern_enhancer.rb +6 -4
- data/lib/stimulus_reflex/configuration.rb +12 -2
- data/lib/stimulus_reflex/dataset.rb +11 -1
- data/lib/stimulus_reflex/engine.rb +16 -9
- data/lib/stimulus_reflex/html/document.rb +59 -0
- data/lib/stimulus_reflex/html/document_fragment.rb +13 -0
- data/lib/stimulus_reflex/importmap.rb +6 -3
- data/lib/stimulus_reflex/installer.rb +274 -0
- data/lib/stimulus_reflex/open_struct_fix.rb +2 -0
- data/lib/stimulus_reflex/reflex.rb +40 -31
- data/lib/stimulus_reflex/reflex_data.rb +19 -3
- data/lib/stimulus_reflex/reflex_factory.rb +6 -3
- data/lib/stimulus_reflex/request_parameters.rb +2 -0
- data/lib/stimulus_reflex/utils/logger.rb +10 -0
- data/lib/stimulus_reflex/utils/sanity_checker.rb +8 -48
- data/lib/stimulus_reflex/version.rb +1 -1
- data/lib/stimulus_reflex/version_checker.rb +54 -0
- data/lib/stimulus_reflex.rb +2 -0
- data/lib/tasks/stimulus_reflex/stimulus_reflex.rake +250 -0
- data/package.json +36 -28
- data/{rollup.config.js → rollup.config.mjs} +6 -24
- data/stimulus_reflex.gemspec +16 -19
- data/yarn.lock +1331 -748
- metadata +129 -79
- data/LATEST +0 -1
- data/app/assets/javascripts/stimulus_reflex.min.js +0 -2
- data/app/assets/javascripts/stimulus_reflex.min.js.map +0 -1
- data/app/assets/javascripts/stimulus_reflex.umd.min.js +0 -905
- data/app/assets/javascripts/stimulus_reflex.umd.min.js.map +0 -1
- data/lib/generators/stimulus_reflex/initializer_generator.rb +0 -14
- data/test/broadcasters/broadcaster_test.rb +0 -11
- data/test/broadcasters/broadcaster_test_case.rb +0 -39
- data/test/broadcasters/nothing_broadcaster_test.rb +0 -31
- data/test/broadcasters/page_broadcaster_test.rb +0 -79
- data/test/broadcasters/selector_broadcaster_test.rb +0 -173
- data/test/callbacks_test.rb +0 -652
- data/test/concern_enhancer_test.rb +0 -54
- data/test/element_test.rb +0 -254
- data/test/generators/stimulus_reflex_generator_test.rb +0 -58
- data/test/reflex_test.rb +0 -43
- data/test/test_helper.rb +0 -71
- data/test/tmp/app/reflexes/application_reflex.rb +0 -12
- data/yarn-error.log +0 -4964
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"stimulus_reflex.umd.min.js","sources":["../../../javascript/schema.js","../../../javascript/debug.js","../../../javascript/reflex_store.js","../../../javascript/log.js","../../../javascript/deprecate.js","../../../javascript/utils.js","../../../javascript/attributes.js","../../../javascript/isolation_mode.js","../../../javascript/lifecycle.js","../../../javascript/controllers.js","../../../javascript/reflexes.js","../../../javascript/reflex_data.js","../../../javascript/transports/action_cable.js","../../../javascript/callbacks.js","../../../javascript/stimulus_reflex.js","../../../javascript/index.js"],"sourcesContent":["const defaultSchema = {\n reflexAttribute: 'data-reflex',\n reflexPermanentAttribute: 'data-reflex-permanent',\n reflexRootAttribute: 'data-reflex-root',\n reflexSuppressLoggingAttribute: 'data-reflex-suppress-logging',\n reflexDatasetAttribute: 'data-reflex-dataset',\n reflexDatasetAllAttribute: 'data-reflex-dataset-all',\n reflexSerializeFormAttribute: 'data-reflex-serialize-form',\n reflexFormSelectorAttribute: 'data-reflex-form-selector',\n reflexIncludeInnerHtmlAttribute: 'data-reflex-include-inner-html',\n reflexIncludeTextContentAttribute: 'data-reflex-include-text-content'\n}\n\nlet schema = {}\n\nexport { schema, defaultSchema }\n\nexport default {\n set (application) {\n schema = { ...defaultSchema, ...application.schema }\n for (const attribute in schema) {\n Object.defineProperty(this, attribute.slice(0, -9), {\n get: () => {\n return schema[attribute]\n }\n })\n }\n }\n}\n","let debugging = false\n\nexport default {\n get enabled () {\n return debugging\n },\n get disabled () {\n return !debugging\n },\n get value () {\n return debugging\n },\n set (value) {\n debugging = !!value\n },\n set debug (value) {\n debugging = !!value\n }\n}\n","const reflexes = {}\n\nexport { reflexes }\n","import Debug from './debug'\n\nimport { reflexes } from './reflex_store'\n\nconst request = (\n reflexId,\n target,\n args,\n controller,\n element,\n controllerElement\n) => {\n const reflex = reflexes[reflexId]\n if (Debug.disabled || reflex.promise.data.suppressLogging) return\n reflex.timestamp = new Date()\n console.log(`\\u2191 stimulus \\u2191 ${target}`, {\n reflexId,\n args,\n controller,\n element,\n controllerElement\n })\n}\n\nconst success = (event, halted) => {\n const { detail } = event || {}\n const { selector, payload } = detail || {}\n const { reflexId, target, morph } = detail.stimulusReflex || {}\n const reflex = reflexes[reflexId]\n if (Debug.disabled || reflex.promise.data.suppressLogging) return\n const progress =\n reflex.totalOperations > 1\n ? ` ${reflex.completedOperations}/${reflex.totalOperations}`\n : ''\n const duration = reflex.timestamp\n ? `in ${new Date() - reflex.timestamp}ms`\n : 'CLONED'\n const operation = event.type\n .split(':')[1]\n .split('-')\n .slice(1)\n .join('_')\n console.log(\n `\\u2193 reflex \\u2193 ${target} \\u2192 ${selector ||\n '\\u221E'}${progress} ${duration}`,\n { reflexId, morph, operation, halted, payload }\n )\n}\n\nconst error = event => {\n const { detail } = event || {}\n const { reflexId, target, payload } = detail.stimulusReflex || {}\n const reflex = reflexes[reflexId]\n if (Debug.disabled || reflex.promise.data.suppressLogging) return\n const duration = reflex.timestamp\n ? `in ${new Date() - reflex.timestamp}ms`\n : 'CLONED'\n console.log(\n `\\u2193 reflex \\u2193 ${target} ${duration} %cERROR: ${event.detail.body}`,\n 'color: #f00;',\n { reflexId, payload }\n )\n}\n\nexport default { request, success, error }\n","let deprecationWarnings = true\n\nexport default {\n get enabled () {\n return deprecationWarnings\n },\n get disabled () {\n return !deprecationWarnings\n },\n get value () {\n return deprecationWarnings\n },\n set (value) {\n deprecationWarnings = !!value\n },\n set deprecate (value) {\n deprecationWarnings = !!value\n }\n}\n","// uuid4 function taken from stackoverflow\n// https://stackoverflow.com/a/2117523/554903\n\nconst uuidv4 = () => {\n const crypto = window.crypto || window.msCrypto\n return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c =>\n (\n c ^\n (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))\n ).toString(16)\n )\n}\n\nconst serializeForm = (form, options = {}) => {\n if (!form) return ''\n\n const w = options.w || window\n const { element } = options\n const formData = new w.FormData(form)\n const data = Array.from(formData, e => e.map(encodeURIComponent).join('='))\n const submitButton = form.querySelector('input[type=submit]')\n if (\n element &&\n element.name &&\n element.nodeName === 'INPUT' &&\n element.type === 'submit'\n ) {\n data.push(\n `${encodeURIComponent(element.name)}=${encodeURIComponent(element.value)}`\n )\n } else if (submitButton && submitButton.name) {\n data.push(\n `${encodeURIComponent(submitButton.name)}=${encodeURIComponent(\n submitButton.value\n )}`\n )\n }\n return Array.from(data).join('&')\n}\n\nconst camelize = (value, uppercaseFirstLetter = true) => {\n if (typeof value !== 'string') return ''\n value = value\n .replace(/[\\s_](.)/g, $1 => $1.toUpperCase())\n .replace(/[\\s_]/g, '')\n .replace(/^(.)/, $1 => $1.toLowerCase())\n\n if (uppercaseFirstLetter)\n value = value.substr(0, 1).toUpperCase() + value.substr(1)\n\n return value\n}\n\nconst debounce = (callback, delay = 250) => {\n let timeoutId\n return (...args) => {\n clearTimeout(timeoutId)\n timeoutId = setTimeout(() => {\n timeoutId = null\n callback(...args)\n }, delay)\n }\n}\n\nconst extractReflexName = reflexString => {\n const match = reflexString.match(/(?:.*->)?(.*?)(?:Reflex)?#/)\n\n return match ? match[1] : ''\n}\n\nconst emitEvent = (event, detail) => {\n document.dispatchEvent(\n new CustomEvent(event, {\n bubbles: true,\n cancelable: false,\n detail\n })\n )\n if (window.jQuery) window.jQuery(document).trigger(event, detail)\n}\n\n// construct a valid xPath for an element in the DOM\nconst elementToXPath = element => {\n if (element.id !== '') return \"//*[@id='\" + element.id + \"']\"\n if (element === document.body) return '/html/body'\n\n let ix = 0\n const siblings = element?.parentNode ? element.parentNode.childNodes : []\n\n for (var i = 0; i < siblings.length; i++) {\n const sibling = siblings[i]\n if (sibling === element) {\n const computedPath = elementToXPath(element.parentNode)\n const tagName = element.tagName.toLowerCase()\n const ixInc = ix + 1\n return `${computedPath}/${tagName}[${ixInc}]`\n }\n\n if (sibling.nodeType === 1 && sibling.tagName === element.tagName) {\n ix++\n }\n }\n}\n\nconst XPathToElement = xpath => {\n return document.evaluate(\n xpath,\n document,\n null,\n XPathResult.FIRST_ORDERED_NODE_TYPE,\n null\n ).singleNodeValue\n}\n\nconst XPathToArray = (xpath, reverse = false) => {\n const snapshotList = document.evaluate(\n xpath,\n document,\n null,\n XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,\n null\n )\n\n const snapshots = []\n\n for (let i = 0; i < snapshotList.snapshotLength; i++) {\n snapshots.push(snapshotList.snapshotItem(i))\n }\n\n return reverse ? snapshots.reverse() : snapshots\n}\n\nexport {\n uuidv4,\n serializeForm,\n camelize,\n debounce,\n extractReflexName,\n emitEvent,\n elementToXPath,\n XPathToElement,\n XPathToArray\n}\n","import Schema from './schema'\nimport Debug from './debug'\nimport Deprecate from './deprecate'\n\nimport { elementToXPath, XPathToArray } from './utils'\n\nconst multipleInstances = element => {\n if (['checkbox', 'radio'].includes(element.type)) {\n return (\n document.querySelectorAll(\n `input[type=\"${element.type}\"][name=\"${element.name}\"]`\n ).length > 1\n )\n }\n return false\n}\nconst collectCheckedOptions = element => {\n return Array.from(element.querySelectorAll('option:checked'))\n .concat(\n Array.from(\n document.querySelectorAll(\n `input[type=\"${element.type}\"][name=\"${element.name}\"]`\n )\n ).filter(elem => elem.checked)\n )\n .map(o => o.value)\n}\n\n// Returns a string value for the passed array.\n//\n// attributeValue(['', 'one', null, 'two', 'three ']) // 'one two three'\n//\nconst attributeValue = (values = []) => {\n const value = values\n .filter(v => v && String(v).length)\n .map(v => v.trim())\n .join(' ')\n .trim()\n return value.length ? value : null\n}\n\n// Returns an array for the passed string value by splitting on whitespace.\n//\n// attributeValues('one two three ') // ['one', 'two', 'three']\n//\nconst attributeValues = value => {\n if (!value) return []\n if (!value.length) return []\n return value.split(' ').filter(v => v.trim().length)\n}\n\n// Extracts attributes from a DOM element.\n//\nconst extractElementAttributes = element => {\n let attrs = Array.from(element.attributes).reduce((memo, attr) => {\n memo[attr.name] = attr.value\n return memo\n }, {})\n\n attrs.checked = !!element.checked\n attrs.selected = !!element.selected\n attrs.tag_name = element.tagName\n\n if (element.tagName.match(/select/i) || multipleInstances(element)) {\n const collectedOptions = collectCheckedOptions(element)\n attrs.values = collectedOptions\n attrs.value = collectedOptions.join(',')\n } else {\n attrs.value = element.value\n }\n return attrs\n}\n\n// Returns an array of elements for the provided tokens.\n// Tokens is an array of space separated string coming from the `data-reflex-dataset`\n// or `data-reflex-dataset-all` attribute.\n//\nconst getElementsFromTokens = (element, tokens) => {\n if (!tokens || tokens.length === 0) return []\n\n let elements = [element]\n\n const xPath = elementToXPath(element)\n\n tokens.forEach(token => {\n try {\n switch (token) {\n case 'combined':\n if (Deprecate.enabled)\n console.warn(\n \"In the next version of StimulusReflex, the 'combined' option to data-reflex-dataset will become 'ancestors'.\"\n )\n elements = [\n ...elements,\n ...XPathToArray(`${xPath}/ancestor::*`, true)\n ]\n break\n case 'ancestors':\n elements = [\n ...elements,\n ...XPathToArray(`${xPath}/ancestor::*`, true)\n ]\n break\n case 'parent':\n elements = [...elements, ...XPathToArray(`${xPath}/parent::*`)]\n break\n case 'siblings':\n elements = [\n ...elements,\n ...XPathToArray(\n `${xPath}/preceding-sibling::*|${xPath}/following-sibling::*`\n )\n ]\n break\n case 'children':\n elements = [...elements, ...XPathToArray(`${xPath}/child::*`)]\n break\n case 'descendants':\n elements = [...elements, ...XPathToArray(`${xPath}/descendant::*`)]\n break\n default:\n elements = [...elements, ...document.querySelectorAll(token)]\n }\n } catch (error) {\n if (Debug.enabled) console.error(error)\n }\n })\n\n return elements\n}\n\n// Extracts the dataset of an element and combines it with the data attributes from all specified tokens\n//\nconst extractElementDataset = element => {\n const dataset = element.attributes[Schema.reflexDataset]\n const allDataset = element.attributes[Schema.reflexDatasetAll]\n\n const tokens = (dataset && dataset.value.split(' ')) || []\n const allTokens = (allDataset && allDataset.value.split(' ')) || []\n\n const datasetElements = getElementsFromTokens(element, tokens)\n const datasetAllElements = getElementsFromTokens(element, allTokens)\n\n const datasetAttributes = datasetElements.reduce((acc, ele) => {\n return { ...extractDataAttributes(ele), ...acc }\n }, {})\n\n const reflexElementAttributes = extractDataAttributes(element)\n\n const elementDataset = {\n dataset: { ...reflexElementAttributes, ...datasetAttributes },\n datasetAll: {}\n }\n\n datasetAllElements.forEach(element => {\n const elementAttributes = extractDataAttributes(element)\n\n Object.keys(elementAttributes).forEach(key => {\n const value = elementAttributes[key]\n\n if (\n elementDataset.datasetAll[key] &&\n Array.isArray(elementDataset.datasetAll[key])\n ) {\n elementDataset.datasetAll[key].push(value)\n } else {\n elementDataset.datasetAll[key] = [value]\n }\n })\n })\n\n return elementDataset\n}\n\n// Extracts all data attributes from a DOM element.\n//\nconst extractDataAttributes = element => {\n let attrs = {}\n\n if (element && element.attributes) {\n Array.from(element.attributes).forEach(attr => {\n if (attr.name.startsWith('data-')) {\n attrs[attr.name] = attr.value\n }\n })\n }\n\n return attrs\n}\n\nexport {\n attributeValue,\n attributeValues,\n extractElementAttributes,\n extractElementDataset,\n extractDataAttributes\n}\n","let isolationMode = false\n\nexport default {\n get disabled () {\n return !isolationMode\n },\n set (value) {\n isolationMode = value\n }\n}\n","import Debug from './debug'\n\nimport { camelize } from './utils'\nimport { reflexes } from './reflex_store'\n\n// Invokes a lifecycle method on a StimulusReflex controller.\n//\n// - stage - the lifecycle stage\n// * before\n// * success\n// * error\n// * halted\n// * after\n// * finalize\n//\n// - reflexElement - the element that triggered the Reflex (not necessarily the StimulusReflex Controller Element)\n// - controllerElement - the element holding the StimulusReflex Controller\n// - reflexId - the UUIDv4 which uniquely identifies the Reflex\n// - payload - the optional \"return value\" from the Reflex method\n//\nconst invokeLifecycleMethod = (\n stage,\n reflexElement,\n controllerElement,\n reflexId,\n payload\n) => {\n if (!controllerElement || !controllerElement.reflexData[reflexId]) return\n\n const controller = controllerElement.reflexController[reflexId]\n const reflex = controllerElement.reflexData[reflexId].target\n const reflexMethodName = reflex.split('#')[1]\n\n const specificLifecycleMethodName = ['before', 'after', 'finalize'].includes(\n stage\n )\n ? `${stage}${camelize(reflexMethodName)}`\n : `${camelize(reflexMethodName, false)}${camelize(stage)}`\n const specificLifecycleMethod = controller[specificLifecycleMethodName]\n\n const genericLifecycleMethodName = ['before', 'after', 'finalize'].includes(\n stage\n )\n ? `${stage}Reflex`\n : `reflex${camelize(stage)}`\n const genericLifecycleMethod = controller[genericLifecycleMethodName]\n\n if (typeof specificLifecycleMethod === 'function') {\n specificLifecycleMethod.call(\n controller,\n reflexElement,\n reflex,\n controllerElement.reflexError[reflexId],\n reflexId,\n payload\n )\n }\n\n if (typeof genericLifecycleMethod === 'function') {\n genericLifecycleMethod.call(\n controller,\n reflexElement,\n reflex,\n controllerElement.reflexError[reflexId],\n reflexId,\n payload\n )\n }\n\n if (reflexes[reflexId] && stage === reflexes[reflexId].finalStage) {\n Reflect.deleteProperty(controllerElement.reflexController, reflexId)\n Reflect.deleteProperty(controllerElement.reflexData, reflexId)\n Reflect.deleteProperty(controllerElement.reflexError, reflexId)\n // Removing this on a trial basis\n // 1. Prevents race condition with CR broadcasts\n // 2. Planning to remove it for v4 as part of queueing refactor\n // 3. Removing reflexes shouldn't be the responsibility of the lifecycle subsystem\n // Reflect.deleteProperty(reflexes, reflexId)\n }\n}\n\ndocument.addEventListener(\n 'stimulus-reflex:before',\n event =>\n invokeLifecycleMethod(\n 'before',\n event.detail.element,\n event.detail.controller.element,\n event.detail.reflexId,\n event.detail.payload\n ),\n true\n)\n\ndocument.addEventListener(\n 'stimulus-reflex:success',\n event => {\n invokeLifecycleMethod(\n 'success',\n event.detail.element,\n event.detail.controller.element,\n event.detail.reflexId,\n event.detail.payload\n )\n dispatchLifecycleEvent(\n 'after',\n event.detail.element,\n event.detail.controller.element,\n event.detail.reflexId,\n event.detail.payload\n )\n },\n true\n)\n\ndocument.addEventListener(\n 'stimulus-reflex:nothing',\n event => {\n dispatchLifecycleEvent(\n 'success',\n event.detail.element,\n event.detail.controller.element,\n event.detail.reflexId,\n event.detail.payload\n )\n },\n true\n)\n\ndocument.addEventListener(\n 'stimulus-reflex:error',\n event => {\n invokeLifecycleMethod(\n 'error',\n event.detail.element,\n event.detail.controller.element,\n event.detail.reflexId,\n event.detail.payload\n )\n dispatchLifecycleEvent(\n 'after',\n event.detail.element,\n event.detail.controller.element,\n event.detail.reflexId,\n event.detail.payload\n )\n },\n true\n)\n\ndocument.addEventListener(\n 'stimulus-reflex:halted',\n event =>\n invokeLifecycleMethod(\n 'halted',\n event.detail.element,\n event.detail.controller.element,\n event.detail.reflexId,\n event.detail.payload\n ),\n true\n)\n\ndocument.addEventListener(\n 'stimulus-reflex:after',\n event =>\n invokeLifecycleMethod(\n 'after',\n event.detail.element,\n event.detail.controller.element,\n event.detail.reflexId,\n event.detail.payload\n ),\n true\n)\n\ndocument.addEventListener(\n 'stimulus-reflex:finalize',\n event =>\n invokeLifecycleMethod(\n 'finalize',\n event.detail.element,\n event.detail.controller.element,\n event.detail.reflexId,\n event.detail.payload\n ),\n true\n)\n\n// Dispatches a lifecycle event on document\n//\n// - stage - the lifecycle stage\n// * before\n// * success\n// * error\n// * halted\n// * after\n// * finalize\n//\n// - reflexElement - the element that triggered the Reflex (not necessarily the StimulusReflex Controller Element)\n//\n// - controllerElement - the element holding the StimulusReflex Controller\n//\n// - reflexId - the UUIDv4 which uniquely identifies the Reflex\n//\n// - payload - optional Reflex return value\n//\nconst dispatchLifecycleEvent = (\n stage,\n reflexElement,\n controllerElement,\n reflexId,\n payload\n) => {\n if (!controllerElement) {\n if (Debug.enabled && !reflexes[reflexId].warned) {\n console.warn(\n `StimulusReflex was not able execute callbacks or emit events for \"${stage}\" or later life-cycle stages for this Reflex. The StimulusReflex Controller Element is no longer present in the DOM. Could you move the StimulusReflex Controller to an element higher in your DOM?`\n )\n reflexes[reflexId].warned = true\n }\n return\n }\n\n if (\n !controllerElement.reflexController ||\n (controllerElement.reflexController &&\n !controllerElement.reflexController[reflexId])\n ) {\n if (Debug.enabled && !reflexes[reflexId].warned) {\n console.warn(\n `StimulusReflex detected that the StimulusReflex Controller responsible for this Reflex has been replaced with a new instance. Callbacks and events for \"${stage}\" or later life-cycle stages cannot be executed.`\n )\n reflexes[reflexId].warned = true\n }\n return\n }\n\n const { target } = controllerElement.reflexData[reflexId] || {}\n const controller = controllerElement.reflexController[reflexId] || {}\n const event = `stimulus-reflex:${stage}`\n const action = `${event}:${target.split('#')[1]}`\n const detail = {\n reflex: target,\n controller,\n reflexId,\n element: reflexElement,\n payload\n }\n const options = { bubbles: true, cancelable: false, detail }\n\n controllerElement.dispatchEvent(new CustomEvent(event, options))\n controllerElement.dispatchEvent(new CustomEvent(action, options))\n\n if (window.jQuery) {\n window.jQuery(controllerElement).trigger(event, detail)\n window.jQuery(controllerElement).trigger(action, detail)\n }\n}\n\nexport { dispatchLifecycleEvent }\n","import Schema from './schema'\n\nimport { attributeValues } from './attributes'\nimport { extractReflexName } from './utils'\n\n// Returns StimulusReflex controllers local to the passed element based on the data-controller attribute.\n//\nconst localReflexControllers = (app, element) => {\n return attributeValues(element.getAttribute(Schema.controller)).reduce(\n (memo, name) => {\n const controller = app.getControllerForElementAndIdentifier(element, name)\n if (controller && controller.StimulusReflex) memo.push(controller)\n return memo\n },\n []\n )\n}\n\n// Returns all StimulusReflex controllers for the passed element.\n// Traverses DOM ancestors starting with element.\n//\nconst allReflexControllers = (app, element) => {\n let controllers = []\n while (element) {\n controllers = controllers.concat(localReflexControllers(app, element))\n element = element.parentElement\n }\n return controllers\n}\n\n// Given a reflex string such as 'click->TestReflex#create' and a list of\n// controllers. It will find the matching controller based on the controller's\n// identifier. e.g. Given these controller identifiers ['foo', 'bar', 'test'],\n// it would select the 'test' controller.\nconst findControllerByReflexName = (reflexName, controllers) => {\n const controller = controllers.find(controller => {\n if (!controller.identifier) return\n\n return (\n extractReflexName(reflexName)\n .replace(/([a-z0–9])([A-Z])/g, '$1-$2')\n .replace(/(::)/g, '--')\n .toLowerCase() === controller.identifier\n )\n })\n\n return controller || controllers[0]\n}\n\nexport { allReflexControllers, findControllerByReflexName }\n","import CableReady from 'cable_ready'\n\nimport Debug from './debug'\nimport Schema from './schema'\nimport IsolationMode from './isolation_mode'\n\nimport { reflexes } from './reflex_store'\nimport { dispatchLifecycleEvent } from './lifecycle'\nimport { XPathToElement, debounce, emitEvent } from './utils'\nimport { allReflexControllers, findControllerByReflexName } from './controllers'\nimport { attributeValue, attributeValues } from './attributes'\n\nconst received = data => {\n if (!data.cableReady) return\n\n if (data.version.replace('.pre', '-pre') !== CableReady.version) {\n if (Debug.enabled)\n console.error(\n `Reflex failed due to cable_ready gem/NPM package version mismatch. Package versions must match exactly.\\nNote that if you are using pre-release builds, gems use the \"x.y.z.preN\" version format, while NPM packages use \"x.y.z-preN\".\\n\\ncable_ready gem: ${data.version}\\ncable_ready NPM: ${CableReady.version}`\n )\n return\n }\n\n let reflexOperations = []\n\n for (let i = data.operations.length - 1; i >= 0; i--) {\n if (data.operations[i].stimulusReflex) {\n reflexOperations.push(data.operations[i])\n data.operations.splice(i, 1)\n }\n }\n\n if (\n reflexOperations.some(\n operation => operation.stimulusReflex.url !== location.href\n )\n ) {\n return\n }\n\n let reflexData\n\n if (reflexOperations.length) {\n reflexData = reflexOperations[0].stimulusReflex\n reflexData.payload = reflexOperations[0].payload\n }\n\n if (reflexData) {\n const { reflexId, payload } = reflexData\n\n if (!reflexes[reflexId] && IsolationMode.disabled) {\n const controllerElement = XPathToElement(reflexData.xpathController)\n const reflexElement = XPathToElement(reflexData.xpathElement)\n\n controllerElement.reflexController =\n controllerElement.reflexController || {}\n controllerElement.reflexData = controllerElement.reflexData || {}\n controllerElement.reflexError = controllerElement.reflexError || {}\n\n controllerElement.reflexController[\n reflexId\n ] = reflexes.app.getControllerForElementAndIdentifier(\n controllerElement,\n reflexData.reflexController\n )\n\n controllerElement.reflexData[reflexId] = reflexData\n\n dispatchLifecycleEvent(\n 'before',\n reflexElement,\n controllerElement,\n reflexId,\n payload\n )\n\n registerReflex(reflexData)\n }\n\n if (reflexes[reflexId]) {\n reflexes[reflexId].totalOperations = reflexOperations.length\n reflexes[reflexId].pendingOperations = reflexOperations.length\n reflexes[reflexId].completedOperations = 0\n reflexes[reflexId].piggybackOperations = data.operations\n CableReady.perform(reflexOperations)\n }\n } else {\n if (data.operations.length && reflexes[data.operations[0].reflexId]) {\n CableReady.perform(data.operations)\n }\n }\n}\n\nconst registerReflex = data => {\n const { reflexId } = data\n reflexes[reflexId] = { finalStage: 'finalize' }\n\n const promise = new Promise((resolve, reject) => {\n reflexes[reflexId].promise = {\n resolve,\n reject,\n data\n }\n })\n\n promise.reflexId = reflexId\n\n if (Debug.enabled) promise.catch(() => {})\n\n return promise\n}\n\n// compute the DOM element(s) which will be the morph root\n// use the data-reflex-root attribute on the reflex or the controller\n// optional value is a CSS selector(s); comma-separated list\n// order of preference is data-reflex, data-controller, document body (default)\nconst getReflexRoots = element => {\n let list = []\n while (list.length === 0 && element) {\n let reflexRoot = element.getAttribute(Schema.reflexRoot)\n if (reflexRoot) {\n if (reflexRoot.length === 0 && element.id) reflexRoot = `#${element.id}`\n const selectors = reflexRoot.split(',').filter(s => s.trim().length)\n if (Debug.enabled && selectors.length === 0) {\n console.error(\n `No value found for ${Schema.reflexRoot}. Add an #id to the element or provide a value for ${Schema.reflexRoot}.`,\n element\n )\n }\n list = list.concat(selectors.filter(s => document.querySelector(s)))\n }\n element = element.parentElement\n ? element.parentElement.closest(`[${Schema.reflexRoot}]`)\n : null\n }\n return list\n}\n\n// Sets up declarative reflex behavior.\n// Any elements that define data-reflex will automatically be wired up with the default StimulusReflexController.\n//\nconst setupDeclarativeReflexes = debounce(() => {\n document.querySelectorAll(`[${Schema.reflex}]`).forEach(element => {\n const controllers = attributeValues(element.getAttribute(Schema.controller))\n const reflexAttributeNames = attributeValues(\n element.getAttribute(Schema.reflex)\n )\n const actions = attributeValues(element.getAttribute(Schema.action))\n reflexAttributeNames.forEach(reflexName => {\n const controller = findControllerByReflexName(\n reflexName,\n allReflexControllers(reflexes.app, element)\n )\n let action\n if (controller) {\n action = `${reflexName.split('->')[0]}->${\n controller.identifier\n }#__perform`\n if (!actions.includes(action)) actions.push(action)\n } else {\n action = `${reflexName.split('->')[0]}->stimulus-reflex#__perform`\n if (!controllers.includes('stimulus-reflex')) {\n controllers.push('stimulus-reflex')\n }\n if (!actions.includes(action)) actions.push(action)\n }\n })\n const controllerValue = attributeValue(controllers)\n const actionValue = attributeValue(actions)\n if (\n controllerValue &&\n element.getAttribute(Schema.controller) != controllerValue\n ) {\n element.setAttribute(Schema.controller, controllerValue)\n }\n if (actionValue && element.getAttribute(Schema.action) != actionValue)\n element.setAttribute(Schema.action, actionValue)\n })\n emitEvent('stimulus-reflex:ready')\n}, 20)\n\nexport { received, registerReflex, getReflexRoots, setupDeclarativeReflexes }\n","import Schema from './schema'\n\nimport { extractElementAttributes, extractElementDataset } from './attributes'\nimport { getReflexRoots } from './reflexes'\nimport { uuidv4 } from './utils'\nimport { elementToXPath } from './utils'\n\nimport { version } from '../package.json'\n\nexport default class ReflexData {\n constructor (\n options,\n reflexElement,\n controllerElement,\n reflexController,\n permanentAttributeName,\n target,\n args,\n url,\n tabId\n ) {\n this.options = options\n this.reflexElement = reflexElement\n this.controllerElement = controllerElement\n this.reflexController = reflexController\n this.permanentAttributeName = permanentAttributeName\n this.target = target\n this.args = args\n this.url = url\n this.tabId = tabId\n }\n\n get attrs () {\n this._attrs =\n this._attrs ||\n this.options['attrs'] ||\n extractElementAttributes(this.reflexElement)\n\n return this._attrs\n }\n\n get reflexId () {\n this._reflexId = this._reflexId || this.options['reflexId'] || uuidv4()\n return this._reflexId\n }\n\n get selectors () {\n this._selectors =\n this._selectors ||\n this.options['selectors'] ||\n getReflexRoots(this.reflexElement)\n\n return typeof this._selectors === 'string'\n ? [this._selectors]\n : this._selectors\n }\n\n get resolveLate () {\n return this.options['resolveLate'] || false\n }\n\n get dataset () {\n this._dataset = this._dataset || extractElementDataset(this.reflexElement)\n return this._dataset\n }\n\n get innerHTML () {\n return this.includeInnerHtml ? this.reflexElement.innerHTML : ''\n }\n\n get textContent () {\n return this.includeTextContent ? this.reflexElement.textContent : ''\n }\n\n get xpathController () {\n return elementToXPath(this.controllerElement)\n }\n\n get xpathElement () {\n return elementToXPath(this.reflexElement)\n }\n\n get formSelector () {\n const attr = this.reflexElement.attributes[Schema.reflexFormSelector]\n ? this.reflexElement.attributes[Schema.reflexFormSelector].value\n : undefined\n return this.options['formSelector'] || attr\n }\n\n get includeInnerHtml () {\n const attr =\n this.reflexElement.attributes[Schema.reflexIncludeInnerHtml] || false\n return this.options['includeInnerHTML'] || attr\n ? attr.value !== 'false'\n : false\n }\n\n get includeTextContent () {\n const attr =\n this.reflexElement.attributes[Schema.reflexIncludeTextContent] || false\n return this.options['includeTextContent'] || attr\n ? attr.value !== 'false'\n : false\n }\n\n get suppressLogging () {\n return (\n this.options['suppressLogging'] ||\n this.reflexElement.attributes[Schema.reflexSuppressLogging] ||\n false\n )\n }\n\n valueOf () {\n return {\n attrs: this.attrs,\n dataset: this.dataset,\n selectors: this.selectors,\n reflexId: this.reflexId,\n resolveLate: this.resolveLate,\n suppressLogging: this.suppressLogging,\n xpathController: this.xpathController,\n xpathElement: this.xpathElement,\n inner_html: this.innerHTML,\n text_content: this.textContent,\n formSelector: this.formSelector,\n reflexController: this.reflexController,\n permanentAttributeName: this.permanentAttributeName,\n target: this.target,\n args: this.args,\n url: this.url,\n tabId: this.tabId,\n version\n }\n }\n}\n","import { createConsumer } from '@rails/actioncable'\nimport { received } from '../reflexes'\nimport { emitEvent } from '../utils'\n\nlet consumer\nlet params\nlet subscriptionActive\n\nconst createSubscription = controller => {\n consumer = consumer || controller.application.consumer || createConsumer()\n const { channel } = controller.StimulusReflex\n const subscription = { channel, ...params }\n const identifier = JSON.stringify(subscription)\n\n controller.StimulusReflex.subscription =\n consumer.subscriptions.findAll(identifier)[0] ||\n consumer.subscriptions.create(subscription, {\n received,\n connected,\n rejected,\n disconnected\n })\n}\n\nconst connected = () => {\n subscriptionActive = true\n document.body.classList.replace(\n 'stimulus-reflex-disconnected',\n 'stimulus-reflex-connected'\n )\n emitEvent('stimulus-reflex:connected')\n emitEvent('stimulus-reflex:action-cable:connected')\n}\n\nconst rejected = () => {\n subscriptionActive = false\n document.body.classList.replace(\n 'stimulus-reflex-connected',\n 'stimulus-reflex-disconnected'\n )\n emitEvent('stimulus-reflex:rejected')\n emitEvent('stimulus-reflex:action-cable:rejected')\n if (Debug.enabled) console.warn('Channel subscription was rejected.')\n}\n\nconst disconnected = willAttemptReconnect => {\n subscriptionActive = false\n document.body.classList.replace(\n 'stimulus-reflex-connected',\n 'stimulus-reflex-disconnected'\n )\n emitEvent('stimulus-reflex:disconnected', willAttemptReconnect)\n emitEvent('stimulus-reflex:action-cable:disconnected', willAttemptReconnect)\n}\n\nexport default {\n consumer,\n params,\n get subscriptionActive () {\n return subscriptionActive\n },\n createSubscription,\n connected,\n rejected,\n disconnected,\n set (consumerValue, paramsValue) {\n consumer = consumerValue\n params = paramsValue\n }\n}\n","import CableReady from 'cable_ready'\n\nimport Log from './log'\n\nimport { reflexes } from './reflex_store'\nimport { dispatchLifecycleEvent } from './lifecycle'\nimport { XPathToElement } from './utils'\n\nconst beforeDOMUpdate = event => {\n const { stimulusReflex, payload } = event.detail || {}\n if (!stimulusReflex) return\n const { reflexId, xpathElement, xpathController } = stimulusReflex\n const controllerElement = XPathToElement(xpathController)\n const reflexElement = XPathToElement(xpathElement)\n const reflex = reflexes[reflexId]\n const { promise } = reflex\n\n reflex.pendingOperations--\n\n if (reflex.pendingOperations > 0) return\n\n if (!stimulusReflex.resolveLate)\n setTimeout(() =>\n promise.resolve({\n element: reflexElement,\n event,\n data: promise.data,\n payload,\n reflexId,\n toString: () => ''\n })\n )\n\n setTimeout(() =>\n dispatchLifecycleEvent(\n 'success',\n reflexElement,\n controllerElement,\n reflexId,\n payload\n )\n )\n}\n\nconst afterDOMUpdate = event => {\n const { stimulusReflex, payload } = event.detail || {}\n if (!stimulusReflex) return\n const { reflexId, xpathElement, xpathController } = stimulusReflex\n const controllerElement = XPathToElement(xpathController)\n const reflexElement = XPathToElement(xpathElement)\n const reflex = reflexes[reflexId]\n const { promise } = reflex\n\n reflex.completedOperations++\n\n Log.success(event, false)\n\n if (reflex.completedOperations < reflex.totalOperations) return\n\n if (stimulusReflex.resolveLate)\n setTimeout(() =>\n promise.resolve({\n element: reflexElement,\n event,\n data: promise.data,\n payload,\n reflexId,\n toString: () => ''\n })\n )\n\n setTimeout(() =>\n dispatchLifecycleEvent(\n 'finalize',\n reflexElement,\n controllerElement,\n reflexId,\n payload\n )\n )\n\n if (reflex.piggybackOperations.length)\n CableReady.perform(reflex.piggybackOperations)\n}\n\nconst routeReflexEvent = event => {\n const { stimulusReflex, payload, name, body } = event.detail || {}\n const eventType = name.split('-')[2]\n if (!stimulusReflex || !['nothing', 'halted', 'error'].includes(eventType))\n return\n\n const { reflexId, xpathElement, xpathController } = stimulusReflex\n const reflexElement = XPathToElement(xpathElement)\n const controllerElement = XPathToElement(xpathController)\n const reflex = reflexes[reflexId]\n const { promise } = reflex\n\n if (controllerElement) {\n controllerElement.reflexError = controllerElement.reflexError || {}\n if (eventType === 'error') controllerElement.reflexError[reflexId] = body\n }\n\n switch (eventType) {\n case 'nothing':\n nothing(event, payload, promise, reflex, reflexElement)\n break\n case 'error':\n error(event, payload, promise, reflex, reflexElement)\n break\n case 'halted':\n halted(event, payload, promise, reflex, reflexElement)\n break\n }\n\n setTimeout(() =>\n dispatchLifecycleEvent(\n eventType,\n reflexElement,\n controllerElement,\n reflexId,\n payload\n )\n )\n\n if (reflex.piggybackOperations.length)\n CableReady.perform(reflex.piggybackOperations)\n}\n\nconst nothing = (event, payload, promise, reflex, reflexElement) => {\n reflex.finalStage = 'after'\n\n Log.success(event, false)\n\n setTimeout(() =>\n promise.resolve({\n data: promise.data,\n element: reflexElement,\n event,\n payload,\n reflexId: promise.data.reflexId,\n toString: () => ''\n })\n )\n}\n\nconst halted = (event, payload, promise, reflex, reflexElement) => {\n reflex.finalStage = 'halted'\n\n Log.success(event, true)\n\n setTimeout(() =>\n promise.resolve({\n data: promise.data,\n element: reflexElement,\n event,\n payload,\n reflexId: promise.data.reflexId,\n toString: () => ''\n })\n )\n}\n\nconst error = (event, payload, promise, reflex, reflexElement) => {\n reflex.finalStage = 'after'\n\n Log.error(event)\n\n setTimeout(() =>\n promise.reject({\n data: promise.data,\n element: reflexElement,\n event,\n payload,\n reflexId: promise.data.reflexId,\n error: event.detail.body,\n toString: () => event.detail.body\n })\n )\n}\n\nexport { beforeDOMUpdate, afterDOMUpdate, routeReflexEvent }\n","import { Controller } from '@hotwired/stimulus'\n\nimport Schema from './schema'\nimport Log from './log'\nimport Debug from './debug'\nimport Deprecate from './deprecate'\nimport ReflexData from './reflex_data'\nimport IsolationMode from './isolation_mode'\nimport ActionCableTransport from './transports/action_cable'\n\nimport { dispatchLifecycleEvent } from './lifecycle'\nimport { uuidv4, serializeForm } from './utils'\nimport { beforeDOMUpdate, afterDOMUpdate, routeReflexEvent } from './callbacks'\nimport { registerReflex, setupDeclarativeReflexes } from './reflexes'\nimport { reflexes } from './reflex_store'\nimport { attributeValues } from './attributes'\n\n// Default StimulusReflexController that is implicitly wired up as data-controller for any DOM elements\n// that have configured data-reflex. Note that this default can be overridden when initializing the application.\n// i.e. StimulusReflex.initialize(myStimulusApplication, MyCustomDefaultController);\n//\nclass StimulusReflexController extends Controller {\n constructor (...args) {\n super(...args)\n register(this)\n }\n}\n\n// Initializes StimulusReflex by registering the default Stimulus controller with the passed Stimulus application.\n//\n// - application - the Stimulus application\n// - options\n// * controller - [optional] the default StimulusReflexController\n// * consumer - [optional] the ActionCable consumer\n// * debug - [false] log all Reflexes to the console\n// * params - [{}] key/value parameters to send during channel subscription\n// * isolate - [false] restrict Reflex playback to the tab which initiated it\n// * deprecate - [true] show warnings regarding upcoming changes to the library\n//\nconst initialize = (\n application,\n { controller, consumer, debug, params, isolate, deprecate } = {}\n) => {\n ActionCableTransport.set(consumer, params)\n document.addEventListener(\n 'DOMContentLoaded',\n () => {\n document.body.classList.remove('stimulus-reflex-connected')\n document.body.classList.add('stimulus-reflex-disconnected')\n if (Deprecate.enabled && consumer)\n console.warn(\n \"Deprecation warning: the next version of StimulusReflex will obtain a reference to consumer via the Stimulus application object.\\nPlease add 'application.consumer = consumer' to your index.js after your Stimulus application has been established, and remove the consumer key from your StimulusReflex initialize() options object.\"\n )\n if (Deprecate.enabled && IsolationMode.disabled)\n console.warn(\n 'Deprecation warning: the next version of StimulusReflex will standardize isolation mode, and the isolate option will be removed.\\nPlease update your applications to assume that every tab will be isolated.'\n )\n },\n { once: true }\n )\n IsolationMode.set(!!isolate)\n reflexes.app = application\n Schema.set(application)\n reflexes.app.register(\n 'stimulus-reflex',\n controller || StimulusReflexController\n )\n Debug.set(!!debug)\n if (typeof deprecate !== 'undefined') Deprecate.set(deprecate)\n const observer = new MutationObserver(setupDeclarativeReflexes)\n observer.observe(document.documentElement, {\n attributeFilter: [Schema.reflex, Schema.action],\n childList: true,\n subtree: true\n })\n}\n\n// Registers a Stimulus controller and extends it with StimulusReflex behavior\n//\n// controller - the Stimulus controller\n// options - [optional] configuration\n//\nconst register = (controller, options = {}) => {\n const channel = 'StimulusReflex::Channel'\n controller.StimulusReflex = { ...options, channel }\n ActionCableTransport.createSubscription(controller)\n Object.assign(controller, {\n // Indicates if the ActionCable web socket connection is open.\n // The connection must be open before calling stimulate.\n //\n isActionCableConnectionOpen () {\n return this.StimulusReflex.subscription.consumer.connection.isOpen()\n },\n\n // Invokes a server side reflex method.\n //\n // - target - the reflex target (full name of the server side reflex) i.e. 'ReflexClassName#method'\n // - reflexElement - [optional] the element that triggered the reflex, defaults to this.element\n // - options - [optional] an object that contains at least one of attrs, reflexId, selectors, resolveLate, serializeForm\n // - *args - remaining arguments are forwarded to the server side reflex method\n //\n stimulate () {\n const url = location.href\n const args = Array.from(arguments)\n const target = args.shift() || 'StimulusReflex::Reflex#default_reflex'\n const controllerElement = this.element\n const reflexElement =\n args[0] && args[0].nodeType === Node.ELEMENT_NODE\n ? args.shift()\n : controllerElement\n if (\n reflexElement.type === 'number' &&\n reflexElement.validity &&\n reflexElement.validity.badInput\n ) {\n if (Debug.enabled) console.warn('Reflex aborted: invalid numeric input')\n return\n }\n const options = {}\n if (\n args[0] &&\n typeof args[0] === 'object' &&\n Object.keys(args[0]).filter(key =>\n [\n 'attrs',\n 'selectors',\n 'reflexId',\n 'resolveLate',\n 'serializeForm',\n 'suppressLogging',\n 'includeInnerHTML',\n 'includeTextContent'\n ].includes(key)\n ).length\n ) {\n const opts = args.shift()\n Object.keys(opts).forEach(o => (options[o] = opts[o]))\n }\n\n const reflexData = new ReflexData(\n options,\n reflexElement,\n controllerElement,\n this.identifier,\n Schema.reflexPermanent,\n target,\n args,\n url,\n tabId\n )\n\n const reflexId = reflexData.reflexId\n\n if (!this.isActionCableConnectionOpen())\n throw 'The ActionCable connection is not open! `this.isActionCableConnectionOpen()` must return true before calling `this.stimulate()`'\n\n if (!ActionCableTransport.subscriptionActive)\n throw 'The ActionCable channel subscription for StimulusReflex was rejected.'\n\n // lifecycle setup\n controllerElement.reflexController =\n controllerElement.reflexController || {}\n controllerElement.reflexData = controllerElement.reflexData || {}\n controllerElement.reflexError = controllerElement.reflexError || {}\n\n controllerElement.reflexController[reflexId] = this\n controllerElement.reflexData[reflexId] = reflexData.valueOf()\n\n dispatchLifecycleEvent(\n 'before',\n reflexElement,\n controllerElement,\n reflexId\n )\n\n setTimeout(() => {\n const { params } = controllerElement.reflexData[reflexId] || {}\n const check = reflexElement.attributes[Schema.reflexSerializeForm]\n if (check) {\n // not needed after v4 because this is only here for the deprecation warning\n options['serializeForm'] = check.value !== 'false'\n }\n\n const form =\n reflexElement.closest(reflexData.formSelector) ||\n document.querySelector(reflexData.formSelector) ||\n reflexElement.closest('form')\n\n if (Deprecate.enabled && options['serializeForm'] === undefined && form)\n console.warn(\n `Deprecation warning: the next version of StimulusReflex will not serialize forms by default.\\nPlease set ${Schema.reflexSerializeForm}=\\\"true\\\" on your Reflex Controller Element or pass { serializeForm: true } as an option to stimulate.`\n )\n const formData =\n options['serializeForm'] === false\n ? ''\n : serializeForm(form, {\n element: reflexElement\n })\n\n controllerElement.reflexData[reflexId] = {\n ...reflexData.valueOf(),\n params,\n formData\n }\n\n this.StimulusReflex.subscription.send(\n controllerElement.reflexData[reflexId]\n )\n })\n\n const promise = registerReflex(reflexData.valueOf())\n\n Log.request(\n reflexId,\n target,\n args,\n this.context.scope.identifier,\n reflexElement,\n controllerElement\n )\n\n return promise\n },\n\n // Wraps the call to stimulate for any data-reflex elements.\n // This is internal and should not be invoked directly.\n __perform (event) {\n let element = event.target\n let reflex\n\n while (element && !reflex) {\n reflex = element.getAttribute(Schema.reflex)\n if (!reflex || !reflex.trim().length) element = element.parentElement\n }\n\n const match = attributeValues(reflex).find(\n reflex => reflex.split('->')[0] === event.type\n )\n\n if (match) {\n event.preventDefault()\n event.stopPropagation()\n this.stimulate(match.split('->')[1], element)\n }\n }\n })\n}\n\n// Uniquely identify this browser tab in each Reflex\nconst tabId = uuidv4()\n\nconst useReflex = (controller, options = {}) => {\n register(controller, options)\n}\n\ndocument.addEventListener('cable-ready:after-dispatch-event', routeReflexEvent)\ndocument.addEventListener('cable-ready:before-inner-html', beforeDOMUpdate)\ndocument.addEventListener('cable-ready:before-morph', beforeDOMUpdate)\ndocument.addEventListener('cable-ready:after-inner-html', afterDOMUpdate)\ndocument.addEventListener('cable-ready:after-morph', afterDOMUpdate)\nwindow.addEventListener('load', setupDeclarativeReflexes)\n\nexport {\n initialize,\n register,\n useReflex\n}\n","export * from './stimulus_reflex'\n\nimport * as StimulusReflex from './stimulus_reflex'\n\nimport Debug from './debug'\nimport Deprecate from './deprecate'\n\nconst global = {\n ...StimulusReflex,\n get debug () {\n return Debug.value\n },\n set debug (value) {\n Debug.set(!!value)\n },\n get deprecate () {\n return Deprecate.value\n },\n set deprecate (value) {\n Deprecate.set(!!value)\n }\n}\n\nwindow.StimulusReflex = global\n\nexport default global\n"],"names":["defaultSchema","reflexAttribute","reflexPermanentAttribute","reflexRootAttribute","reflexSuppressLoggingAttribute","reflexDatasetAttribute","reflexDatasetAllAttribute","reflexSerializeFormAttribute","reflexFormSelectorAttribute","reflexIncludeInnerHtmlAttribute","reflexIncludeTextContentAttribute","schema","Schema","set","application","attribute","Object","defineProperty","this","slice","get","debugging","Debug$1","enabled","disabled","value","debug","reflexes","request","reflexId","target","args","controller","element","controllerElement","reflex","Debug","promise","data","suppressLogging","timestamp","Date","console","log","success","event","halted","detail","selector","payload","morph","stimulusReflex","progress","totalOperations","completedOperations","duration","operation","type","split","join","error","body","Log","deprecationWarnings","Deprecate","deprecate","uuidv4","crypto","window","msCrypto","replace","c","getRandomValues","Uint8Array","toString","serializeForm","form","options","w","formData","FormData","Array","from","e","map","encodeURIComponent","submitButton","querySelector","name","nodeName","push","camelize","uppercaseFirstLetter","$1","toUpperCase","toLowerCase","substr","debounce","callback","delay","timeoutId","clearTimeout","setTimeout","extractReflexName","reflexString","match","emitEvent","document","dispatchEvent","CustomEvent","bubbles","cancelable","jQuery","trigger","elementToXPath","id","ix","siblings","parentNode","childNodes","i","length","sibling","computedPath","tagName","ixInc","nodeType","XPathToElement","xpath","evaluate","XPathResult","FIRST_ORDERED_NODE_TYPE","singleNodeValue","XPathToArray","reverse","snapshotList","ORDERED_NODE_SNAPSHOT_TYPE","snapshots","snapshotLength","snapshotItem","multipleInstances","includes","querySelectorAll","collectCheckedOptions","concat","filter","elem","checked","o","attributeValue","values","v","String","trim","attributeValues","extractElementAttributes","attrs","attributes","reduce","memo","attr","selected","tag_name","collectedOptions","getElementsFromTokens","tokens","elements","xPath","forEach","token","warn","extractElementDataset","dataset","reflexDataset","allDataset","reflexDatasetAll","allTokens","datasetElements","datasetAllElements","datasetAttributes","acc","ele","extractDataAttributes","reflexElementAttributes","elementDataset","datasetAll","elementAttributes","keys","key","isArray","startsWith","isolationMode","IsolationMode","invokeLifecycleMethod","stage","reflexElement","reflexData","reflexController","reflexMethodName","specificLifecycleMethodName","specificLifecycleMethod","genericLifecycleMethodName","genericLifecycleMethod","call","reflexError","finalStage","Reflect","deleteProperty","addEventListener","dispatchLifecycleEvent","warned","action","localReflexControllers","app","getAttribute","getControllerForElementAndIdentifier","StimulusReflex","allReflexControllers","controllers","parentElement","findControllerByReflexName","reflexName","find","identifier","received","cableReady","version","CableReady","reflexOperations","operations","splice","some","url","location","href","xpathController","xpathElement","registerReflex","pendingOperations","piggybackOperations","perform","Promise","resolve","reject","catch","getReflexRoots","list","reflexRoot","selectors","s","closest","setupDeclarativeReflexes","reflexAttributeNames","actions","controllerValue","actionValue","setAttribute","ReflexData","constructor","permanentAttributeName","tabId","_attrs","_reflexId","_selectors","resolveLate","_dataset","innerHTML","includeInnerHtml","textContent","includeTextContent","formSelector","reflexFormSelector","undefined","reflexIncludeInnerHtml","reflexIncludeTextContent","reflexSuppressLogging","valueOf","inner_html","text_content","consumer","params","subscriptionActive","createSubscription","createConsumer","channel","subscription","JSON","stringify","subscriptions","findAll","create","connected","rejected","disconnected","classList","willAttemptReconnect","ActionCableTransport","consumerValue","paramsValue","beforeDOMUpdate","afterDOMUpdate","routeReflexEvent","eventType","nothing","StimulusReflexController","Controller","super","register","initialize","isolate","remove","add","once","observer","MutationObserver","observe","documentElement","attributeFilter","childList","subtree","assign","isActionCableConnectionOpen","connection","isOpen","stimulate","arguments","shift","Node","ELEMENT_NODE","validity","badInput","opts","reflexPermanent","check","reflexSerializeForm","send","context","scope","__perform","preventDefault","stopPropagation","useReflex","global"],"mappings":";;;;;;;;;;;EAAA,MAAMA,gBAAgB;IACpBC,iBAAiB;IACjBC,0BAA0B;IAC1BC,qBAAqB;IACrBC,gCAAgC;IAChCC,wBAAwB;IACxBC,2BAA2B;IAC3BC,8BAA8B;IAC9BC,6BAA6B;IAC7BC,iCAAiC;IACjCC,mCAAmC;;EAGrC,IAAIC,SAAS;EAIE,IAAAC,SAAA;IACbC,IAAKC;MACHH,SAAS;WAAKX;WAAkBc,YAAYH;;MAC5C,KAAK,MAAMI,aAAaJ,QAAQ;QAC9BK,OAAOC,eAAeC,MAAMH,UAAUI,MAAM,IAAI,IAAI;UAClDC,KAAK,MACIT,OAAOI;;;;;ECvBxB,IAAIM,YAAY;EAED,IAAAC,UAAA;IACTC;MACF,OAAOF;;IAELG;MACF,QAAQH;;IAENI;MACF,OAAOJ;;IAETR,IAAKY;MACHJ,cAAcI;;IAEZC,UAAOD;MACTJ,cAAcI;;;EChBlB,MAAME,WAAW;ECIjB,MAAMC,UAAU,CACdC,UACAC,QACAC,MACAC,YACAC,SACAC;IAEA,MAAMC,SAASR,SAASE;IACxB,IAAIO,QAAMZ,YAAYW,OAAOE,QAAQC,KAAKC,iBAAiB;IAC3DJ,OAAOK,YAAY,IAAIC;IACvBC,QAAQC,IAAI,gBAA0Bb,UAAU;MAC9CD,UAAAA;MACAE,MAAAA;MACAC,YAAAA;MACAC,SAAAA;MACAC,mBAAAA;;;EAIJ,MAAMU,UAAU,CAACC,OAAOC;IACtB,OAAMC,QAAEA,UAAWF,SAAS;IAC5B,OAAMG,UAAEA,UAAQC,SAAEA,WAAYF,UAAU;IACxC,OAAMlB,UAAEA,UAAQC,QAAEA,QAAMoB,OAAEA,SAAUH,OAAOI,kBAAkB;IAC7D,MAAMhB,SAASR,SAASE;IACxB,IAAIO,QAAMZ,YAAYW,OAAOE,QAAQC,KAAKC,iBAAiB;IAC3D,MAAMa,WACJjB,OAAOkB,kBAAkB,IACrB,IAAIlB,OAAOmB,uBAAuBnB,OAAOkB,oBACzC;IACN,MAAME,WAAWpB,OAAOK,YACpB,MAAM,IAAIC,OAASN,OAAOK,gBAC1B;IACJ,MAAMgB,YAAYX,MAAMY,KACrBC,MAAM,KAAK,GACXA,MAAM,KACNvC,MAAM,GACNwC,KAAK;IACRjB,QAAQC,IACN,cAAwBb,YAAiBkB,YACvC,MAAWI,YAAYG,YACzB;MAAE1B,UAAAA;MAAUqB,OAAAA;MAAOM,WAAAA;MAAWV,QAAAA;MAAQG,SAAAA;;;EAI1C,MAAMW,UAAQf;IACZ,OAAME,QAAEA,UAAWF,SAAS;IAC5B,OAAMhB,UAAEA,UAAQC,QAAEA,QAAMmB,SAAEA,WAAYF,OAAOI,kBAAkB;IAC/D,MAAMhB,SAASR,SAASE;IACxB,IAAIO,QAAMZ,YAAYW,OAAOE,QAAQC,KAAKC,iBAAiB;IAC3D,MAAMgB,WAAWpB,OAAOK,YACpB,MAAM,IAAIC,OAASN,OAAOK,gBAC1B;IACJE,QAAQC,IACN,cAAwBb,UAAUyB,qBAAqBV,MAAME,OAAOc,QACpE,gBACA;MAAEhC,UAAAA;MAAUoB,SAAAA;;;EAIhB,IAAAa,MAAe;IAAElC,SAAAA;IAASgB,SAAAA;WAASgB;;EChEnC,IAAIG,sBAAsB;EAEX,IAAAC,YAAA;IACTzC;MACF,OAAOwC;;IAELvC;MACF,QAAQuC;;IAENtC;MACF,OAAOsC;;IAETlD,IAAKY;MACHsC,wBAAwBtC;;IAEtBwC,cAAWxC;MACbsC,wBAAwBtC;;;ECb5B,MAAMyC,SAAS;IACb,MAAMC,SAASC,OAAOD,UAAUC,OAAOC;IACvC,QAAQ,EAAC,SAAQ,OAAO,OAAO,OAAO,MAAMC,QAAQ,WAAUC,MAE1DA,IACCJ,OAAOK,gBAAgB,IAAIC,WAAW,IAAI,KAAM,MAAOF,IAAI,GAC5DG,SAAS;;EAIf,MAAMC,gBAAgB,CAACC,MAAMC,UAAU;IACrC,KAAKD,MAAM,OAAO;IAElB,MAAME,IAAID,QAAQC,KAAKV;IACvB,OAAMnC,SAAEA,WAAY4C;IACpB,MAAME,WAAW,IAAID,EAAEE,SAASJ;IAChC,MAAMtC,OAAO2C,MAAMC,KAAKH,WAAUI,KAAKA,EAAEC,IAAIC,oBAAoB1B,KAAK;IACtE,MAAM2B,eAAeV,KAAKW,cAAc;IACxC,IACEtD,WACAA,QAAQuD,QACRvD,QAAQwD,aAAa,WACrBxD,QAAQwB,SAAS,UACjB;MACAnB,KAAKoD,KACH,GAAGL,mBAAmBpD,QAAQuD,SAASH,mBAAmBpD,QAAQR;WAE/D,IAAI6D,gBAAgBA,aAAaE,MAAM;MAC5ClD,KAAKoD,KACH,GAAGL,mBAAmBC,aAAaE,SAASH,mBAC1CC,aAAa7D;;IAInB,OAAOwD,MAAMC,KAAK5C,MAAMqB,KAAK;;EAG/B,MAAMgC,WAAW,CAAClE,OAAOmE,uBAAuB;IAC9C,WAAWnE,UAAU,UAAU,OAAO;IACtCA,QAAQA,MACL6C,QAAQ,cAAauB,MAAMA,GAAGC,gBAC9BxB,QAAQ,UAAU,IAClBA,QAAQ,SAAQuB,MAAMA,GAAGE;IAE5B,IAAIH,sBACFnE,QAAQA,MAAMuE,OAAO,GAAG,GAAGF,gBAAgBrE,MAAMuE,OAAO;IAE1D,OAAOvE;;EAGT,MAAMwE,WAAW,CAACC,UAAUC,QAAQ;IAClC,IAAIC;IACJ,OAAO,IAAIrE;MACTsE,aAAaD;MACbA,YAAYE,YAAW;QACrBF,YAAY;QACZF,YAAYnE;UACXoE;;;EAIP,MAAMI,oBAAoBC;IACxB,MAAMC,QAAQD,aAAaC,MAAM;IAEjC,OAAOA,QAAQA,MAAM,KAAK;;EAG5B,MAAMC,YAAY,CAAC7D,OAAOE;IACxB4D,SAASC,cACP,IAAIC,YAAYhE,OAAO;MACrBiE,SAAS;MACTC,YAAY;MACZhE,QAAAA;;IAGJ,IAAIqB,OAAO4C,QAAQ5C,OAAO4C,OAAOL,UAAUM,QAAQpE,OAAOE;;EAI5D,MAAMmE,iBAAiBjF;IACrB,IAAIA,QAAQkF,OAAO,IAAI,OAAO,cAAclF,QAAQkF,KAAK;IACzD,IAAIlF,YAAY0E,SAAS9C,MAAM,OAAO;IAEtC,IAAIuD,KAAK;IACT,MAAMC,WAAWpF,SAASqF,aAAarF,QAAQqF,WAAWC,aAAa;IAEvE,KAAK,IAAIC,IAAI,GAAGA,IAAIH,SAASI,QAAQD,KAAK;MACxC,MAAME,UAAUL,SAASG;MACzB,IAAIE,YAAYzF,SAAS;QACvB,MAAM0F,eAAeT,eAAejF,QAAQqF;QAC5C,MAAMM,UAAU3F,QAAQ2F,QAAQ7B;QAChC,MAAM8B,QAAQT,KAAK;QACnB,OAAO,GAAGO,gBAAgBC,WAAWC;;MAGvC,IAAIH,QAAQI,aAAa,KAAKJ,QAAQE,YAAY3F,QAAQ2F,SAAS;QACjER;;;;EAKN,MAAMW,iBAAiBC,SACdrB,SAASsB,SACdD,OACArB,UACA,MACAuB,YAAYC,yBACZ,MACAC;EAGJ,MAAMC,eAAe,CAACL,OAAOM,UAAU;IACrC,MAAMC,eAAe5B,SAASsB,SAC5BD,OACArB,UACA,MACAuB,YAAYM,4BACZ;IAGF,MAAMC,YAAY;IAElB,KAAK,IAAIjB,IAAI,GAAGA,IAAIe,aAAaG,gBAAgBlB,KAAK;MACpDiB,UAAU/C,KAAK6C,aAAaI,aAAanB;;IAG3C,OAAOc,UAAUG,UAAUH,YAAYG;;EC3HzC,MAAMG,oBAAoB3G;IACxB,IAAI,EAAC,YAAY,UAAS4G,SAAS5G,QAAQwB,OAAO;MAChD,OACEkD,SAASmC,iBACP,eAAe7G,QAAQwB,gBAAgBxB,QAAQuD,UAC/CiC,SAAS;;IAGf,OAAO;;EAET,MAAMsB,wBAAwB9G,WACrBgD,MAAMC,KAAKjD,QAAQ6G,iBAAiB,mBACxCE,OACC/D,MAAMC,KACJyB,SAASmC,iBACP,eAAe7G,QAAQwB,gBAAgBxB,QAAQuD,WAEjDyD,QAAOC,QAAQA,KAAKC,WAEvB/D,KAAIgE,KAAKA,EAAE3H;EAOhB,MAAM4H,iBAAiB,CAACC,SAAS;IAC/B,MAAM7H,QAAQ6H,OACXL,QAAOM,KAAKA,KAAKC,OAAOD,GAAG9B,SAC3BrC,KAAImE,KAAKA,EAAEE,SACX9F,KAAK,KACL8F;IACH,OAAOhI,MAAMgG,SAAShG,QAAQ;;EAOhC,MAAMiI,kBAAkBjI;IACtB,KAAKA,OAAO,OAAO;IACnB,KAAKA,MAAMgG,QAAQ,OAAO;IAC1B,OAAOhG,MAAMiC,MAAM,KAAKuF,QAAOM,KAAKA,EAAEE,OAAOhC;;EAK/C,MAAMkC,2BAA2B1H;IAC/B,IAAI2H,QAAQ3E,MAAMC,KAAKjD,QAAQ4H,YAAYC,QAAO,CAACC,MAAMC;MACvDD,KAAKC,KAAKxE,QAAQwE,KAAKvI;MACvB,OAAOsI;QACN;IAEHH,MAAMT,YAAYlH,QAAQkH;IAC1BS,MAAMK,aAAahI,QAAQgI;IAC3BL,MAAMM,WAAWjI,QAAQ2F;IAEzB,IAAI3F,QAAQ2F,QAAQnB,MAAM,cAAcmC,kBAAkB3G,UAAU;MAClE,MAAMkI,mBAAmBpB,sBAAsB9G;MAC/C2H,MAAMN,SAASa;MACfP,MAAMnI,QAAQ0I,iBAAiBxG,KAAK;WAC/B;MACLiG,MAAMnI,QAAQQ,QAAQR;;IAExB,OAAOmI;;EAOT,MAAMQ,wBAAwB,CAACnI,SAASoI;IACtC,KAAKA,UAAUA,OAAO5C,WAAW,GAAG,OAAO;IAE3C,IAAI6C,WAAW,EAACrI;IAEhB,MAAMsI,QAAQrD,eAAejF;IAE7BoI,OAAOG,SAAQC;MACb;QACE,QAAQA;SACN,KAAK;UACH,IAAIzG,UAAUzC,SACZmB,QAAQgI,KACN;UAEJJ,WAAW,KACNA,aACAjC,aAAa,GAAGkC,qBAAqB;UAE1C;;SACF,KAAK;UACHD,WAAW,KACNA,aACAjC,aAAa,GAAGkC,qBAAqB;UAE1C;;SACF,KAAK;UACHD,WAAW,KAAIA,aAAajC,aAAa,GAAGkC;UAC5C;;SACF,KAAK;UACHD,WAAW,KACNA,aACAjC,aACD,GAAGkC,8BAA8BA;UAGrC;;SACF,KAAK;UACHD,WAAW,KAAIA,aAAajC,aAAa,GAAGkC;UAC5C;;SACF,KAAK;UACHD,WAAW,KAAIA,aAAajC,aAAa,GAAGkC;UAC5C;;SACF;UACED,WAAW,KAAIA,aAAa3D,SAASmC,iBAAiB2B;;QAE1D,OAAO7G;QACP,IAAIxB,QAAMb,SAASmB,QAAQkB,MAAMA;;;IAIrC,OAAO0G;;EAKT,MAAMK,wBAAwB1I;IAC5B,MAAM2I,UAAU3I,QAAQ4H,WAAWjJ,OAAOiK;IAC1C,MAAMC,aAAa7I,QAAQ4H,WAAWjJ,OAAOmK;IAE7C,MAAMV,SAAUO,WAAWA,QAAQnJ,MAAMiC,MAAM,QAAS;IACxD,MAAMsH,YAAaF,cAAcA,WAAWrJ,MAAMiC,MAAM,QAAS;IAEjE,MAAMuH,kBAAkBb,sBAAsBnI,SAASoI;IACvD,MAAMa,qBAAqBd,sBAAsBnI,SAAS+I;IAE1D,MAAMG,oBAAoBF,gBAAgBnB,QAAO,CAACsB,KAAKC,SAC9C;SAAKC,sBAAsBD;SAASD;SAC1C;IAEH,MAAMG,0BAA0BD,sBAAsBrJ;IAEtD,MAAMuJ,iBAAiB;MACrBZ,SAAS;WAAKW;WAA4BJ;;MAC1CM,YAAY;;IAGdP,mBAAmBV,SAAQvI;MACzB,MAAMyJ,oBAAoBJ,sBAAsBrJ;MAEhDjB,OAAO2K,KAAKD,mBAAmBlB,SAAQoB;QACrC,MAAMnK,QAAQiK,kBAAkBE;QAEhC,IACEJ,eAAeC,WAAWG,QAC1B3G,MAAM4G,QAAQL,eAAeC,WAAWG,OACxC;UACAJ,eAAeC,WAAWG,KAAKlG,KAAKjE;eAC/B;UACL+J,eAAeC,WAAWG,OAAO,EAACnK;;;;IAKxC,OAAO+J;;EAKT,MAAMF,wBAAwBrJ;IAC5B,IAAI2H,QAAQ;IAEZ,IAAI3H,WAAWA,QAAQ4H,YAAY;MACjC5E,MAAMC,KAAKjD,QAAQ4H,YAAYW,SAAQR;QACrC,IAAIA,KAAKxE,KAAKsG,WAAW,UAAU;UACjClC,MAAMI,KAAKxE,QAAQwE,KAAKvI;;;;IAK9B,OAAOmI;;EC3LT,IAAImC,gBAAgB;EAEL,IAAAC,gBAAA;IACTxK;MACF,QAAQuK;;IAEVlL,IAAKY;MACHsK,gBAAgBtK;;;ECapB,MAAMwK,wBAAwB,CAC5BC,OACAC,eACAjK,mBACAL,UACAoB;IAEA,KAAKf,sBAAsBA,kBAAkBkK,WAAWvK,WAAW;IAEnE,MAAMG,aAAaE,kBAAkBmK,iBAAiBxK;IACtD,MAAMM,SAASD,kBAAkBkK,WAAWvK,UAAUC;IACtD,MAAMwK,mBAAmBnK,OAAOuB,MAAM,KAAK;IAE3C,MAAM6I,8BAA8B,EAAC,UAAU,SAAS,aAAY1D,SAClEqD,SAEE,GAAGA,QAAQvG,SAAS2G,sBACpB,GAAG3G,SAAS2G,kBAAkB,SAAS3G,SAASuG;IACpD,MAAMM,0BAA0BxK,WAAWuK;IAE3C,MAAME,6BAA6B,EAAC,UAAU,SAAS,aAAY5D,SACjEqD,SAEE,GAAGA,gBACH,SAASvG,SAASuG;IACtB,MAAMQ,yBAAyB1K,WAAWyK;IAE1C,WAAWD,4BAA4B,YAAY;MACjDA,wBAAwBG,KACtB3K,YACAmK,eACAhK,QACAD,kBAAkB0K,YAAY/K,WAC9BA,UACAoB;;IAIJ,WAAWyJ,2BAA2B,YAAY;MAChDA,uBAAuBC,KACrB3K,YACAmK,eACAhK,QACAD,kBAAkB0K,YAAY/K,WAC9BA,UACAoB;;IAIJ,IAAItB,SAASE,aAAaqK,UAAUvK,SAASE,UAAUgL,YAAY;MACjEC,QAAQC,eAAe7K,kBAAkBmK,kBAAkBxK;MAC3DiL,QAAQC,eAAe7K,kBAAkBkK,YAAYvK;MACrDiL,QAAQC,eAAe7K,kBAAkB0K,aAAa/K;;;EAS1D8E,SAASqG,iBACP,2BACAnK,SACEoJ,sBACE,UACApJ,MAAME,OAAOd,SACbY,MAAME,OAAOf,WAAWC,SACxBY,MAAME,OAAOlB,UACbgB,MAAME,OAAOE,WAEjB;EAGF0D,SAASqG,iBACP,4BACAnK;IACEoJ,sBACE,WACApJ,MAAME,OAAOd,SACbY,MAAME,OAAOf,WAAWC,SACxBY,MAAME,OAAOlB,UACbgB,MAAME,OAAOE;IAEfgK,uBACE,SACApK,MAAME,OAAOd,SACbY,MAAME,OAAOf,WAAWC,SACxBY,MAAME,OAAOlB,UACbgB,MAAME,OAAOE;MAGjB;EAGF0D,SAASqG,iBACP,4BACAnK;IACEoK,uBACE,WACApK,MAAME,OAAOd,SACbY,MAAME,OAAOf,WAAWC,SACxBY,MAAME,OAAOlB,UACbgB,MAAME,OAAOE;MAGjB;EAGF0D,SAASqG,iBACP,0BACAnK;IACEoJ,sBACE,SACApJ,MAAME,OAAOd,SACbY,MAAME,OAAOf,WAAWC,SACxBY,MAAME,OAAOlB,UACbgB,MAAME,OAAOE;IAEfgK,uBACE,SACApK,MAAME,OAAOd,SACbY,MAAME,OAAOf,WAAWC,SACxBY,MAAME,OAAOlB,UACbgB,MAAME,OAAOE;MAGjB;EAGF0D,SAASqG,iBACP,2BACAnK,SACEoJ,sBACE,UACApJ,MAAME,OAAOd,SACbY,MAAME,OAAOf,WAAWC,SACxBY,MAAME,OAAOlB,UACbgB,MAAME,OAAOE,WAEjB;EAGF0D,SAASqG,iBACP,0BACAnK,SACEoJ,sBACE,SACApJ,MAAME,OAAOd,SACbY,MAAME,OAAOf,WAAWC,SACxBY,MAAME,OAAOlB,UACbgB,MAAME,OAAOE,WAEjB;EAGF0D,SAASqG,iBACP,6BACAnK,SACEoJ,sBACE,YACApJ,MAAME,OAAOd,SACbY,MAAME,OAAOf,WAAWC,SACxBY,MAAME,OAAOlB,UACbgB,MAAME,OAAOE,WAEjB;EAqBF,MAAMgK,yBAAyB,CAC7Bf,OACAC,eACAjK,mBACAL,UACAoB;IAEA,KAAKf,mBAAmB;MACtB,IAAIE,QAAMb,YAAYI,SAASE,UAAUqL,QAAQ;QAC/CxK,QAAQgI,KACN,qEAAqEwB;QAEvEvK,SAASE,UAAUqL,SAAS;;MAE9B;;IAGF,KACGhL,kBAAkBmK,oBAClBnK,kBAAkBmK,qBAChBnK,kBAAkBmK,iBAAiBxK,WACtC;MACA,IAAIO,QAAMb,YAAYI,SAASE,UAAUqL,QAAQ;QAC/CxK,QAAQgI,KACN,2JAA2JwB;QAE7JvK,SAASE,UAAUqL,SAAS;;MAE9B;;IAGF,OAAMpL,QAAEA,UAAWI,kBAAkBkK,WAAWvK,aAAa;IAC7D,MAAMG,aAAaE,kBAAkBmK,iBAAiBxK,aAAa;IACnE,MAAMgB,QAAQ,mBAAmBqJ;IACjC,MAAMiB,SAAS,GAAGtK,SAASf,OAAO4B,MAAM,KAAK;IAC7C,MAAMX,SAAS;MACbZ,QAAQL;MACRE,YAAAA;MACAH,UAAAA;MACAI,SAASkK;MACTlJ,SAAAA;;IAEF,MAAM4B,UAAU;MAAEiC,SAAS;MAAMC,YAAY;MAAOhE,QAAAA;;IAEpDb,kBAAkB0E,cAAc,IAAIC,YAAYhE,OAAOgC;IACvD3C,kBAAkB0E,cAAc,IAAIC,YAAYsG,QAAQtI;IAExD,IAAIT,OAAO4C,QAAQ;MACjB5C,OAAO4C,OAAO9E,mBAAmB+E,QAAQpE,OAAOE;MAChDqB,OAAO4C,OAAO9E,mBAAmB+E,QAAQkG,QAAQpK;;;ECzPrD,MAAMqK,yBAAyB,CAACC,KAAKpL,YAC5ByH,gBAAgBzH,QAAQqL,aAAa1M,OAAOoB,aAAa8H,QAC9D,CAACC,MAAMvE;IACL,MAAMxD,aAAaqL,IAAIE,qCAAqCtL,SAASuD;IACrE,IAAIxD,cAAcA,WAAWwL,gBAAgBzD,KAAKrE,KAAK1D;IACvD,OAAO+H;MAET;EAOJ,MAAM0D,uBAAuB,CAACJ,KAAKpL;IACjC,IAAIyL,cAAc;IAClB,OAAOzL,SAAS;MACdyL,cAAcA,YAAY1E,OAAOoE,uBAAuBC,KAAKpL;MAC7DA,UAAUA,QAAQ0L;;IAEpB,OAAOD;;EAOT,MAAME,6BAA6B,CAACC,YAAYH;IAC9C,MAAM1L,aAAa0L,YAAYI,MAAK9L;MAClC,KAAKA,WAAW+L,YAAY;MAE5B,OACExH,kBAAkBsH,YACfvJ,QAAQ,sBAAsB,SAC9BA,QAAQ,SAAS,MACjByB,kBAAkB/D,WAAW+L;;IAIpC,OAAO/L,cAAc0L,YAAY;;EClCnC,MAAMM,WAAW1L;IACf,KAAKA,KAAK2L,YAAY;IAEtB,IAAI3L,KAAK4L,QAAQ5J,QAAQ,QAAQ,YAAY6J,oBAAU,WAACD,SAAS;MAC/D,IAAI9L,QAAMb,SACRmB,QAAQkB,MACN,8PAA8PtB,KAAK4L,6BAA6BC,oBAAAA,WAAWD;MAE/S;;IAGF,IAAIE,mBAAmB;IAEvB,KAAK,IAAI5G,IAAIlF,KAAK+L,WAAW5G,SAAS,GAAGD,KAAK,GAAGA,KAAK;MACpD,IAAIlF,KAAK+L,WAAW7G,GAAGrE,gBAAgB;QACrCiL,iBAAiB1I,KAAKpD,KAAK+L,WAAW7G;QACtClF,KAAK+L,WAAWC,OAAO9G,GAAG;;;IAI9B,IACE4G,iBAAiBG,MACf/K,aAAaA,UAAUL,eAAeqL,QAAQC,SAASC,QAEzD;MACA;;IAGF,IAAItC;IAEJ,IAAIgC,iBAAiB3G,QAAQ;MAC3B2E,aAAagC,iBAAiB,GAAGjL;MACjCiJ,WAAWnJ,UAAUmL,iBAAiB,GAAGnL;;IAG3C,IAAImJ,YAAY;MACd,OAAMvK,UAAEA,UAAQoB,SAAEA,WAAYmJ;MAE9B,KAAKzK,SAASE,aAAamK,cAAcxK,UAAU;QACjD,MAAMU,oBAAoB6F,eAAeqE,WAAWuC;QACpD,MAAMxC,gBAAgBpE,eAAeqE,WAAWwC;QAEhD1M,kBAAkBmK,mBAChBnK,kBAAkBmK,oBAAoB;QACxCnK,kBAAkBkK,aAAalK,kBAAkBkK,cAAc;QAC/DlK,kBAAkB0K,cAAc1K,kBAAkB0K,eAAe;QAEjE1K,kBAAkBmK,iBAChBxK,YACEF,SAAS0L,IAAIE,qCACfrL,mBACAkK,WAAWC;QAGbnK,kBAAkBkK,WAAWvK,YAAYuK;QAEzCa,uBACE,UACAd,eACAjK,mBACAL,UACAoB;QAGF4L,eAAezC;;MAGjB,IAAIzK,SAASE,WAAW;QACtBF,SAASE,UAAUwB,kBAAkB+K,iBAAiB3G;QACtD9F,SAASE,UAAUiN,oBAAoBV,iBAAiB3G;QACxD9F,SAASE,UAAUyB,sBAAsB;QACzC3B,SAASE,UAAUkN,sBAAsBzM,KAAK+L;QAC9CF,oBAAU,WAACa,QAAQZ;;WAEhB;MACL,IAAI9L,KAAK+L,WAAW5G,UAAU9F,SAASW,KAAK+L,WAAW,GAAGxM,WAAW;QACnEsM,+BAAWa,QAAQ1M,KAAK+L;;;;EAK9B,MAAMQ,iBAAiBvM;IACrB,OAAMT,UAAEA,YAAaS;IACrBX,SAASE,YAAY;MAAEgL,YAAY;;IAEnC,MAAMxK,UAAU,IAAI4M,SAAQ,CAACC,SAASC;MACpCxN,SAASE,UAAUQ,UAAU;QAC3B6M,SAAAA;QACAC,QAAAA;QACA7M,MAAAA;;;IAIJD,QAAQR,WAAWA;IAEnB,IAAIO,QAAMb,SAASc,QAAQ+M,OAAM;IAEjC,OAAO/M;;EAOT,MAAMgN,iBAAiBpN;IACrB,IAAIqN,OAAO;IACX,OAAOA,KAAK7H,WAAW,KAAKxF,SAAS;MACnC,IAAIsN,aAAatN,QAAQqL,aAAa1M,OAAO2O;MAC7C,IAAIA,YAAY;QACd,IAAIA,WAAW9H,WAAW,KAAKxF,QAAQkF,IAAIoI,aAAa,IAAItN,QAAQkF;QACpE,MAAMqI,YAAYD,WAAW7L,MAAM,KAAKuF,QAAOwG,KAAKA,EAAEhG,OAAOhC;QAC7D,IAAIrF,QAAMb,WAAWiO,UAAU/H,WAAW,GAAG;UAC3C/E,QAAQkB,MACN,sBAAsBhD,OAAO2O,gEAAgE3O,OAAO2O,eACpGtN;;QAGJqN,OAAOA,KAAKtG,OAAOwG,UAAUvG,QAAOwG,KAAK9I,SAASpB,cAAckK;;MAElExN,UAAUA,QAAQ0L,gBACd1L,QAAQ0L,cAAc+B,QAAQ,IAAI9O,OAAO2O,iBACzC;;IAEN,OAAOD;;EAMT,MAAMK,2BAA2B1J,UAAS;IACxCU,SAASmC,iBAAiB,IAAIlI,OAAOuB,WAAWqI,SAAQvI;MACtD,MAAMyL,cAAchE,gBAAgBzH,QAAQqL,aAAa1M,OAAOoB;MAChE,MAAM4N,uBAAuBlG,gBAC3BzH,QAAQqL,aAAa1M,OAAOuB;MAE9B,MAAM0N,UAAUnG,gBAAgBzH,QAAQqL,aAAa1M,OAAOuM;MAC5DyC,qBAAqBpF,SAAQqD;QAC3B,MAAM7L,aAAa4L,2BACjBC,YACAJ,qBAAqB9L,SAAS0L,KAAKpL;QAErC,IAAIkL;QACJ,IAAInL,YAAY;UACdmL,SAAS,GAAGU,WAAWnK,MAAM,MAAM,OACjC1B,WAAW+L;UAEb,KAAK8B,QAAQhH,SAASsE,SAAS0C,QAAQnK,KAAKyH;eACvC;UACLA,SAAS,GAAGU,WAAWnK,MAAM,MAAM;UACnC,KAAKgK,YAAY7E,SAAS,oBAAoB;YAC5C6E,YAAYhI,KAAK;;UAEnB,KAAKmK,QAAQhH,SAASsE,SAAS0C,QAAQnK,KAAKyH;;;MAGhD,MAAM2C,kBAAkBzG,eAAeqE;MACvC,MAAMqC,cAAc1G,eAAewG;MACnC,IACEC,mBACA7N,QAAQqL,aAAa1M,OAAOoB,eAAe8N,iBAC3C;QACA7N,QAAQ+N,aAAapP,OAAOoB,YAAY8N;;MAE1C,IAAIC,eAAe9N,QAAQqL,aAAa1M,OAAOuM,WAAW4C,aACxD9N,QAAQ+N,aAAapP,OAAOuM,QAAQ4C;;IAExCrJ,UAAU;MACT;;EC1KY,MAAMuJ;IACnBC,YACErL,SACAsH,eACAjK,mBACAmK,kBACA8D,wBACArO,QACAC,MACAyM,KACA4B;MAEAlP,KAAK2D,UAAUA;MACf3D,KAAKiL,gBAAgBA;MACrBjL,KAAKgB,oBAAoBA;MACzBhB,KAAKmL,mBAAmBA;MACxBnL,KAAKiP,yBAAyBA;MAC9BjP,KAAKY,SAASA;MACdZ,KAAKa,OAAOA;MACZb,KAAKsN,MAAMA;MACXtN,KAAKkP,QAAQA;;IAGXxG;MACF1I,KAAKmP,SACHnP,KAAKmP,UACLnP,KAAK2D,QAAQ,YACb8E,yBAAyBzI,KAAKiL;MAEhC,OAAOjL,KAAKmP;;IAGVxO;MACFX,KAAKoP,YAAYpP,KAAKoP,aAAapP,KAAK2D,QAAQ,eAAeX;MAC/D,OAAOhD,KAAKoP;;IAGVd;MACFtO,KAAKqP,aACHrP,KAAKqP,cACLrP,KAAK2D,QAAQ,gBACbwK,eAAenO,KAAKiL;MAEtB,cAAcjL,KAAKqP,eAAe,WAC9B,EAACrP,KAAKqP,eACNrP,KAAKqP;;IAGPC;MACF,OAAOtP,KAAK2D,QAAQ,kBAAkB;;IAGpC+F;MACF1J,KAAKuP,WAAWvP,KAAKuP,YAAY9F,sBAAsBzJ,KAAKiL;MAC5D,OAAOjL,KAAKuP;;IAGVC;MACF,OAAOxP,KAAKyP,mBAAmBzP,KAAKiL,cAAcuE,YAAY;;IAG5DE;MACF,OAAO1P,KAAK2P,qBAAqB3P,KAAKiL,cAAcyE,cAAc;;IAGhEjC;MACF,OAAOzH,eAAehG,KAAKgB;;IAGzB0M;MACF,OAAO1H,eAAehG,KAAKiL;;IAGzB2E;MACF,MAAM9G,OAAO9I,KAAKiL,cAActC,WAAWjJ,OAAOmQ,sBAC9C7P,KAAKiL,cAActC,WAAWjJ,OAAOmQ,oBAAoBtP,QACzDuP;MACJ,OAAO9P,KAAK2D,QAAQ,mBAAmBmF;;IAGrC2G;MACF,MAAM3G,OACJ9I,KAAKiL,cAActC,WAAWjJ,OAAOqQ,2BAA2B;MAClE,OAAO/P,KAAK2D,QAAQ,uBAAuBmF,OACvCA,KAAKvI,UAAU,UACf;;IAGFoP;MACF,MAAM7G,OACJ9I,KAAKiL,cAActC,WAAWjJ,OAAOsQ,6BAA6B;MACpE,OAAOhQ,KAAK2D,QAAQ,yBAAyBmF,OACzCA,KAAKvI,UAAU,UACf;;IAGFc;MACF,OACErB,KAAK2D,QAAQ,sBACb3D,KAAKiL,cAActC,WAAWjJ,OAAOuQ,0BACrC;;IAIJC;MACE,OAAO;QACLxH,OAAO1I,KAAK0I;QACZgB,SAAS1J,KAAK0J;QACd4E,WAAWtO,KAAKsO;QAChB3N,UAAUX,KAAKW;QACf2O,aAAatP,KAAKsP;QAClBjO,iBAAiBrB,KAAKqB;QACtBoM,iBAAiBzN,KAAKyN;QACtBC,cAAc1N,KAAK0N;QACnByC,YAAYnQ,KAAKwP;QACjBY,cAAcpQ,KAAK0P;QACnBE,cAAc5P,KAAK4P;QACnBzE,kBAAkBnL,KAAKmL;QACvB8D,wBAAwBjP,KAAKiP;QAC7BrO,QAAQZ,KAAKY;QACbC,MAAMb,KAAKa;QACXyM,KAAKtN,KAAKsN;QACV4B,OAAOlP,KAAKkP;QACZlC,SAAAA;;;;EChIN,IAAIqD;EACJ,IAAIC;EACJ,IAAIC;EAEJ,MAAMC,qBAAqB1P;IACzBuP,WAAWA,YAAYvP,WAAWlB,YAAYyQ,YAAYI,YAAAA;IAC1D,OAAMC,SAAEA,WAAY5P,WAAWwL;IAC/B,MAAMqE,eAAe;MAAED,SAAAA;SAAYJ;;IACnC,MAAMzD,aAAa+D,KAAKC,UAAUF;IAElC7P,WAAWwL,eAAeqE,eACxBN,SAASS,cAAcC,QAAQlE,YAAY,MAC3CwD,SAASS,cAAcE,OAAOL,cAAc;MAC1C7D,UAAAA;MACAmE,WAAAA;MACAC,UAAAA;MACAC,cAAAA;;;EAIN,MAAMF,YAAY;IAChBV,qBAAqB;IACrB9K,SAAS9C,KAAKyO,UAAUhO,QACtB,gCACA;IAEFoC,UAAU;IACVA,UAAU;;EAGZ,MAAM0L,WAAW;IACfX,qBAAqB;IACrB9K,SAAS9C,KAAKyO,UAAUhO,QACtB,6BACA;IAEFoC,UAAU;IACVA,UAAU;IACV,IAAItE,MAAMb,SAASmB,QAAQgI,KAAK;;EAGlC,MAAM2H,eAAeE;IACnBd,qBAAqB;IACrB9K,SAAS9C,KAAKyO,UAAUhO,QACtB,6BACA;IAEFoC,UAAU,gCAAgC6L;IAC1C7L,UAAU,6CAA6C6L;;EAG1C,IAAAC,uBAAA;IACbjB,UAAAA;IACAC,QAAAA;IACIC;MACF,OAAOA;;IAETC,oBAAAA;IACAS,WAAAA;IACAC,UAAAA;IACAC,cAAAA;IACAxR,IAAK4R,eAAeC;MAClBnB,WAAWkB;MACXjB,SAASkB;;;EC3Db,MAAMC,kBAAkB9P;IACtB,OAAMM,gBAAEA,gBAAcF,SAAEA,WAAYJ,MAAME,UAAU;IACpD,KAAKI,gBAAgB;IACrB,OAAMtB,UAAEA,UAAQ+M,cAAEA,cAAYD,iBAAEA,mBAAoBxL;IACpD,MAAMjB,oBAAoB6F,eAAe4G;IACzC,MAAMxC,gBAAgBpE,eAAe6G;IACrC,MAAMzM,SAASR,SAASE;IACxB,OAAMQ,SAAEA,WAAYF;IAEpBA,OAAO2M;IAEP,IAAI3M,OAAO2M,oBAAoB,GAAG;IAElC,KAAK3L,eAAeqN,aAClBlK,YAAW,MACTjE,QAAQ6M,QAAQ;MACdjN,SAASkK;MACTtJ,OAAAA;MACAP,MAAMD,QAAQC;MACdW,SAAAA;MACApB,UAAAA;MACA6C,UAAU,MAAM;;IAItB4B,YAAW,MACT2G,uBACE,WACAd,eACAjK,mBACAL,UACAoB;;EAKN,MAAM2P,iBAAiB/P;IACrB,OAAMM,gBAAEA,gBAAcF,SAAEA,WAAYJ,MAAME,UAAU;IACpD,KAAKI,gBAAgB;IACrB,OAAMtB,UAAEA,UAAQ+M,cAAEA,cAAYD,iBAAEA,mBAAoBxL;IACpD,MAAMjB,oBAAoB6F,eAAe4G;IACzC,MAAMxC,gBAAgBpE,eAAe6G;IACrC,MAAMzM,SAASR,SAASE;IACxB,OAAMQ,SAAEA,WAAYF;IAEpBA,OAAOmB;IAEPQ,IAAIlB,QAAQC,OAAO;IAEnB,IAAIV,OAAOmB,sBAAsBnB,OAAOkB,iBAAiB;IAEzD,IAAIF,eAAeqN,aACjBlK,YAAW,MACTjE,QAAQ6M,QAAQ;MACdjN,SAASkK;MACTtJ,OAAAA;MACAP,MAAMD,QAAQC;MACdW,SAAAA;MACApB,UAAAA;MACA6C,UAAU,MAAM;;IAItB4B,YAAW,MACT2G,uBACE,YACAd,eACAjK,mBACAL,UACAoB;IAIJ,IAAId,OAAO4M,oBAAoBtH,QAC7B0G,+BAAWa,QAAQ7M,OAAO4M;;EAG9B,MAAM8D,mBAAmBhQ;IACvB,OAAMM,gBAAEA,gBAAcF,SAAEA,SAAOuC,MAAEA,MAAI3B,MAAEA,QAAShB,MAAME,UAAU;IAChE,MAAM+P,YAAYtN,KAAK9B,MAAM,KAAK;IAClC,KAAKP,mBAAmB,EAAC,WAAW,UAAU,UAAS0F,SAASiK,YAC9D;IAEF,OAAMjR,UAAEA,UAAQ+M,cAAEA,cAAYD,iBAAEA,mBAAoBxL;IACpD,MAAMgJ,gBAAgBpE,eAAe6G;IACrC,MAAM1M,oBAAoB6F,eAAe4G;IACzC,MAAMxM,SAASR,SAASE;IACxB,OAAMQ,SAAEA,WAAYF;IAEpB,IAAID,mBAAmB;MACrBA,kBAAkB0K,cAAc1K,kBAAkB0K,eAAe;MACjE,IAAIkG,cAAc,SAAS5Q,kBAAkB0K,YAAY/K,YAAYgC;;IAGvE,QAAQiP;KACN,KAAK;MACHC,QAAQlQ,OAAOI,SAASZ,SAASF,QAAQgK;MACzC;;KACF,KAAK;MACHvI,MAAMf,OAAOI,SAASZ,SAASF,QAAQgK;MACvC;;KACF,KAAK;MACHrJ,OAAOD,OAAOI,SAASZ,SAASF,QAAQgK;MACxC;;IAGJ7F,YAAW,MACT2G,uBACE6F,WACA3G,eACAjK,mBACAL,UACAoB;IAIJ,IAAId,OAAO4M,oBAAoBtH,QAC7B0G,+BAAWa,QAAQ7M,OAAO4M;;EAG9B,MAAMgE,UAAU,CAAClQ,OAAOI,SAASZ,SAASF,QAAQgK;IAChDhK,OAAO0K,aAAa;IAEpB/I,IAAIlB,QAAQC,OAAO;IAEnByD,YAAW,MACTjE,QAAQ6M,QAAQ;MACd5M,MAAMD,QAAQC;MACdL,SAASkK;MACTtJ,OAAAA;MACAI,SAAAA;MACApB,UAAUQ,QAAQC,KAAKT;MACvB6C,UAAU,MAAM;;;EAKtB,MAAM5B,SAAS,CAACD,OAAOI,SAASZ,SAASF,QAAQgK;IAC/ChK,OAAO0K,aAAa;IAEpB/I,IAAIlB,QAAQC,OAAO;IAEnByD,YAAW,MACTjE,QAAQ6M,QAAQ;MACd5M,MAAMD,QAAQC;MACdL,SAASkK;MACTtJ,OAAAA;MACAI,SAAAA;MACApB,UAAUQ,QAAQC,KAAKT;MACvB6C,UAAU,MAAM;;;EAKtB,MAAMd,QAAQ,CAACf,OAAOI,SAASZ,SAASF,QAAQgK;IAC9ChK,OAAO0K,aAAa;IAEpB/I,IAAIF,MAAMf;IAEVyD,YAAW,MACTjE,QAAQ8M,OAAO;MACb7M,MAAMD,QAAQC;MACdL,SAASkK;MACTtJ,OAAAA;MACAI,SAAAA;MACApB,UAAUQ,QAAQC,KAAKT;MACvB+B,OAAOf,MAAME,OAAOc;MACpBa,UAAU,MAAM7B,MAAME,OAAOc;;;EC1JnC,MAAMmP,iCAAiCC,SAAAA;IACrC/C,eAAgBnO;MACdmR,SAASnR;MACToR,SAASjS;;;EAeR,MAACkS,aAAa,CACjBtS,cACEkB,YAAAA,YAAYuP,UAAAA,UAAU7P,OAAAA,OAAO8P,QAAAA,QAAQ6B,SAAAA,SAASpP,WAAAA,aAAc;IAE9DuO,qBAAqB3R,IAAI0Q,UAAUC;IACnC7K,SAASqG,iBACP,qBACA;MACErG,SAAS9C,KAAKyO,UAAUgB,OAAO;MAC/B3M,SAAS9C,KAAKyO,UAAUiB,IAAI;MAC5B,IAAIvP,UAAUzC,WAAWgQ,UACvB7O,QAAQgI,KACN;MAEJ,IAAI1G,UAAUzC,WAAWyK,cAAcxK,UACrCkB,QAAQgI,KACN;QAGN;MAAE8I,MAAM;;IAEVxH,cAAcnL,MAAMwS;IACpB1R,SAAS0L,MAAMvM;IACfF,OAAOC,IAAIC;IACXa,SAAS0L,IAAI8F,SACX,mBACAnR,cAAcgR;IAEhB5Q,QAAMvB,MAAMa;IACZ,WAAWuC,cAAc,aAAaD,UAAUnD,IAAIoD;IACpD,MAAMwP,WAAW,IAAIC,iBAAiB/D;IACtC8D,SAASE,QAAQhN,SAASiN,iBAAiB;MACzCC,iBAAiB,EAACjT,OAAOuB,QAAQvB,OAAOuM;MACxC2G,WAAW;MACXC,SAAS;;;EASP,MAAAZ,WAAW,CAACnR,YAAY6C,UAAU;IACtC,MAAM+M,UAAU;IAChB5P,WAAWwL,iBAAiB;SAAK3I;MAAS+M,SAAAA;;IAC1CY,qBAAqBd,mBAAmB1P;IACxChB,OAAOgT,OAAOhS,YAAY;MAIxBiS;QACE,OAAO/S,KAAKsM,eAAeqE,aAAaN,SAAS2C,WAAWC;;MAU9DC;QACE,MAAM5F,MAAMC,SAASC;QACrB,MAAM3M,OAAOkD,MAAMC,KAAKmP;QACxB,MAAMvS,SAASC,KAAKuS,WAAW;QAC/B,MAAMpS,oBAAoBhB,KAAKe;QAC/B,MAAMkK,gBACJpK,KAAK,MAAMA,KAAK,GAAG+F,aAAayM,KAAKC,eACjCzS,KAAKuS,UACLpS;QACN,IACEiK,cAAc1I,SAAS,YACvB0I,cAAcsI,YACdtI,cAAcsI,SAASC,UACvB;UACA,IAAItS,QAAMb,SAASmB,QAAQgI,KAAK;UAChC;;QAEF,MAAM7F,UAAU;QAChB,IACE9C,KAAK,aACEA,KAAK,OAAO,YACnBf,OAAO2K,KAAK5J,KAAK,IAAIkH,QAAO2C,OAC1B,EACE,SACA,aACA,YACA,eACA,iBACA,mBACA,oBACA,uBACA/C,SAAS+C,OACXnE,QACF;UACA,MAAMkN,OAAO5S,KAAKuS;UAClBtT,OAAO2K,KAAKgJ,MAAMnK,SAAQpB,KAAMvE,QAAQuE,KAAKuL,KAAKvL;;QAGpD,MAAMgD,aAAa,IAAI6D,WACrBpL,SACAsH,eACAjK,mBACAhB,KAAK6M,YACLnN,OAAOgU,iBACP9S,QACAC,MACAyM,KACA4B;QAGF,MAAMvO,WAAWuK,WAAWvK;QAE5B,KAAKX,KAAK+S,+BACR,MAAM;QAER,KAAKzB,qBAAqBf,oBACxB,MAAM;QAGRvP,kBAAkBmK,mBAChBnK,kBAAkBmK,oBAAoB;QACxCnK,kBAAkBkK,aAAalK,kBAAkBkK,cAAc;QAC/DlK,kBAAkB0K,cAAc1K,kBAAkB0K,eAAe;QAEjE1K,kBAAkBmK,iBAAiBxK,YAAYX;QAC/CgB,kBAAkBkK,WAAWvK,YAAYuK,WAAWgF;QAEpDnE,uBACE,UACAd,eACAjK,mBACAL;QAGFyE,YAAW;UACT,OAAMkL,QAAEA,UAAWtP,kBAAkBkK,WAAWvK,aAAa;UAC7D,MAAMgT,QAAQ1I,cAActC,WAAWjJ,OAAOkU;UAC9C,IAAID,OAAO;YAEThQ,QAAQ,mBAAmBgQ,MAAMpT,UAAU;;UAG7C,MAAMmD,OACJuH,cAAcuD,QAAQtD,WAAW0E,iBACjCnK,SAASpB,cAAc6G,WAAW0E,iBAClC3E,cAAcuD,QAAQ;UAExB,IAAI1L,UAAUzC,WAAWsD,QAAQ,qBAAqBmM,aAAapM,MACjElC,QAAQgI,KACN,4GAA4G9J,OAAOkU;UAEvH,MAAM/P,WACJF,QAAQ,qBAAqB,QACzB,KACAF,cAAcC,MAAM;YAClB3C,SAASkK;;UAGjBjK,kBAAkBkK,WAAWvK,YAAY;eACpCuK,WAAWgF;YACdI,QAAAA;YACAzM,UAAAA;;UAGF7D,KAAKsM,eAAeqE,aAAakD,KAC/B7S,kBAAkBkK,WAAWvK;;QAIjC,MAAMQ,UAAUwM,eAAezC,WAAWgF;QAE1CtN,IAAIlC,QACFC,UACAC,QACAC,MACAb,KAAK8T,QAAQC,MAAMlH,YACnB5B,eACAjK;QAGF,OAAOG;;MAKT6S,UAAWrS;QACT,IAAIZ,UAAUY,MAAMf;QACpB,IAAIK;QAEJ,OAAOF,YAAYE,QAAQ;UACzBA,SAASF,QAAQqL,aAAa1M,OAAOuB;UACrC,KAAKA,WAAWA,OAAOsH,OAAOhC,QAAQxF,UAAUA,QAAQ0L;;QAG1D,MAAMlH,QAAQiD,gBAAgBvH,QAAQ2L,MACpC3L,UAAUA,OAAOuB,MAAM,MAAM,OAAOb,MAAMY;QAG5C,IAAIgD,OAAO;UACT5D,MAAMsS;UACNtS,MAAMuS;UACNlU,KAAKkT,UAAU3N,MAAM/C,MAAM,MAAM,IAAIzB;;;;;EAO7C,MAAMmO,QAAQlM;EAER,MAAAmR,YAAY,CAACrT,YAAY6C,UAAU;IACvCsO,SAASnR,YAAY6C;;EAGvB8B,SAASqG,iBAAiB,oCAAoC6F;EAC9DlM,SAASqG,iBAAiB,iCAAiC2F;EAC3DhM,SAASqG,iBAAiB,4BAA4B2F;EACtDhM,SAASqG,iBAAiB,gCAAgC4F;EAC1DjM,SAASqG,iBAAiB,2BAA2B4F;EACrDxO,OAAO4I,iBAAiB,QAAQ2C;;;;;;;EC7P3B,MAAC2F,SAAS;OACV9H;IACC9L;MACF,OAAOU,QAAMX;;IAEXC,UAAOD;MACTW,QAAMvB,MAAMY;;IAEVwC;MACF,OAAOD,UAAUvC;;IAEfwC,cAAWxC;MACbuC,UAAUnD,MAAMY;;;EAIpB2C,OAAOoJ,iBAAiB8H;;;;;;"}
|
@@ -1,14 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "rails/generators"
|
4
|
-
|
5
|
-
module StimulusReflex
|
6
|
-
class InitializerGenerator < Rails::Generators::Base
|
7
|
-
desc "Creates a StimulusReflex initializer in config/initializers"
|
8
|
-
source_root File.expand_path("templates", __dir__)
|
9
|
-
|
10
|
-
def copy_initializer_file
|
11
|
-
copy_file "config/initializers/stimulus_reflex.rb"
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
@@ -1,11 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative "broadcaster_test_case"
|
4
|
-
|
5
|
-
class StimulusReflex::BroadcasterTest < StimulusReflex::BroadcasterTestCase
|
6
|
-
test "raises a NotImplementedError if called directly" do
|
7
|
-
broadcaster = StimulusReflex::Broadcaster.new(@reflex)
|
8
|
-
|
9
|
-
assert_raises(NotImplementedError) { broadcaster.broadcast }
|
10
|
-
end
|
11
|
-
end
|
@@ -1,39 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative "../test_helper"
|
4
|
-
|
5
|
-
class StimulusReflex::BroadcasterTestCase < ActionCable::Channel::TestCase
|
6
|
-
tests StimulusReflex::Channel
|
7
|
-
|
8
|
-
def assert_broadcast_on(stream, data, &block)
|
9
|
-
serialized_msg = ActiveSupport::JSON.decode(ActiveSupport::JSON.encode(data))
|
10
|
-
|
11
|
-
new_messages = broadcasts(stream)
|
12
|
-
if block
|
13
|
-
old_messages = new_messages
|
14
|
-
clear_messages(stream)
|
15
|
-
|
16
|
-
yield
|
17
|
-
new_messages = broadcasts(stream)
|
18
|
-
clear_messages(stream)
|
19
|
-
|
20
|
-
(old_messages + new_messages).each { |m| pubsub_adapter.broadcast(stream, m) }
|
21
|
-
end
|
22
|
-
|
23
|
-
message = new_messages.find { |msg| ActiveSupport::JSON.decode(msg) == serialized_msg }
|
24
|
-
|
25
|
-
unless message
|
26
|
-
puts "\n\n#{ActiveSupport::JSON.decode(new_messages.first)}\n#{data}\n\n"
|
27
|
-
end
|
28
|
-
|
29
|
-
assert message, "No messages sent with #{data} to #{stream}"
|
30
|
-
end
|
31
|
-
|
32
|
-
setup do
|
33
|
-
stub_connection(session_id: SecureRandom.uuid)
|
34
|
-
def connection.env
|
35
|
-
@env ||= {}
|
36
|
-
end
|
37
|
-
@reflex = StimulusReflex::Reflex.new(subscribe, url: "https://test.stimulusreflex.com", client_attributes: {reflex_id: "666", version: StimulusReflex::VERSION})
|
38
|
-
end
|
39
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative "broadcaster_test_case"
|
4
|
-
|
5
|
-
class StimulusReflex::NothingBroadcasterTest < StimulusReflex::BroadcasterTestCase
|
6
|
-
test "broadcasts a nothing morph when called" do
|
7
|
-
broadcaster = StimulusReflex::NothingBroadcaster.new(@reflex)
|
8
|
-
|
9
|
-
expected = {
|
10
|
-
"cableReady" => true,
|
11
|
-
"operations" => [
|
12
|
-
{
|
13
|
-
"name" => "stimulus-reflex:morph-nothing",
|
14
|
-
"selector" => nil,
|
15
|
-
"payload" => {},
|
16
|
-
"stimulusReflex" => {
|
17
|
-
"some" => "data",
|
18
|
-
"morph" => "nothing"
|
19
|
-
},
|
20
|
-
"reflexId" => "666",
|
21
|
-
"operation" => "dispatchEvent"
|
22
|
-
}
|
23
|
-
],
|
24
|
-
"version" => CableReady::VERSION
|
25
|
-
}
|
26
|
-
|
27
|
-
assert_broadcast_on @reflex.stream_name, expected do
|
28
|
-
broadcaster.broadcast nil, {some: :data}
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
@@ -1,79 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative "broadcaster_test_case"
|
4
|
-
|
5
|
-
class StimulusReflex::PageBroadcasterTest < StimulusReflex::BroadcasterTestCase
|
6
|
-
test "returns if the response html is empty" do
|
7
|
-
broadcaster = StimulusReflex::PageBroadcaster.new(@reflex)
|
8
|
-
broadcaster.broadcast(["#foo"], {some: :data})
|
9
|
-
# TODO: figure out how to refute_broadcast_on
|
10
|
-
end
|
11
|
-
|
12
|
-
test "performs a page morph on body" do
|
13
|
-
class << @reflex.controller.response
|
14
|
-
def body
|
15
|
-
"<html><head></head><body><div>New Content</div><div>Another Content</div></body></html>"
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
broadcaster = StimulusReflex::PageBroadcaster.new(@reflex)
|
20
|
-
|
21
|
-
expected = {
|
22
|
-
"cableReady" => true,
|
23
|
-
"operations" => [
|
24
|
-
{
|
25
|
-
"selector" => "body",
|
26
|
-
"html" => "<div>New Content</div><div>Another Content</div>",
|
27
|
-
"payload" => {},
|
28
|
-
"childrenOnly" => true,
|
29
|
-
"permanentAttributeName" => nil,
|
30
|
-
"stimulusReflex" => {
|
31
|
-
"some" => :data,
|
32
|
-
"morph" => :page
|
33
|
-
},
|
34
|
-
"reflexId" => "666",
|
35
|
-
"operation" => "morph"
|
36
|
-
}
|
37
|
-
],
|
38
|
-
"version" => CableReady::VERSION
|
39
|
-
}
|
40
|
-
|
41
|
-
assert_broadcast_on @reflex.stream_name, expected do
|
42
|
-
broadcaster.broadcast(["body"], {some: :data})
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
test "performs a page morph given an array of reflex root selectors" do
|
47
|
-
class << @reflex.controller.response
|
48
|
-
def body
|
49
|
-
"<html><head></head><body><div id=\"foo\">New Content</div></body></html>"
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
broadcaster = StimulusReflex::PageBroadcaster.new(@reflex)
|
54
|
-
|
55
|
-
expected = {
|
56
|
-
"cableReady" => true,
|
57
|
-
"operations" => [
|
58
|
-
{
|
59
|
-
"selector" => "#foo",
|
60
|
-
"html" => "New Content",
|
61
|
-
"payload" => {},
|
62
|
-
"childrenOnly" => true,
|
63
|
-
"permanentAttributeName" => nil,
|
64
|
-
"stimulusReflex" => {
|
65
|
-
"some" => :data,
|
66
|
-
"morph" => :page
|
67
|
-
},
|
68
|
-
"reflexId" => "666",
|
69
|
-
"operation" => "morph"
|
70
|
-
}
|
71
|
-
],
|
72
|
-
"version" => CableReady::VERSION
|
73
|
-
}
|
74
|
-
|
75
|
-
assert_broadcast_on @reflex.stream_name, expected do
|
76
|
-
broadcaster.broadcast(["#foo"], {some: :data})
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
@@ -1,173 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative "broadcaster_test_case"
|
4
|
-
|
5
|
-
module StimulusReflex
|
6
|
-
class SelectorBroadcasterTest < StimulusReflex::BroadcasterTestCase
|
7
|
-
test "morphs the contents of an element if the selector(s) are present in both original and morphed html fragments" do
|
8
|
-
broadcaster = StimulusReflex::SelectorBroadcaster.new(@reflex)
|
9
|
-
broadcaster.append_morph("#foo", '<div id="foo"><div>bar</div><div>baz</div></div>')
|
10
|
-
|
11
|
-
expected = {
|
12
|
-
"cableReady" => true,
|
13
|
-
"operations" => [
|
14
|
-
{
|
15
|
-
"selector" => "#foo",
|
16
|
-
"html" => "<div>bar</div><div>baz</div>",
|
17
|
-
"payload" => {},
|
18
|
-
"childrenOnly" => true,
|
19
|
-
"permanentAttributeName" => nil,
|
20
|
-
"stimulusReflex" => {
|
21
|
-
"some" => "data",
|
22
|
-
"morph" => "selector"
|
23
|
-
},
|
24
|
-
"reflexId" => "666",
|
25
|
-
"operation" => "morph"
|
26
|
-
}
|
27
|
-
],
|
28
|
-
"version" => CableReady::VERSION
|
29
|
-
}
|
30
|
-
|
31
|
-
assert_broadcast_on @reflex.stream_name, expected do
|
32
|
-
broadcaster.broadcast nil, some: :data
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
test "replaces the contents of an element and ignores permanent-attributes if the selector(s) aren't present in the replacing html fragment" do
|
37
|
-
broadcaster = StimulusReflex::SelectorBroadcaster.new(@reflex)
|
38
|
-
broadcaster.append_morph("#foo", '<div id="baz"><span>bar</span></div>')
|
39
|
-
|
40
|
-
expected = {
|
41
|
-
"cableReady" => true,
|
42
|
-
"operations" => [
|
43
|
-
{
|
44
|
-
"selector" => "#foo",
|
45
|
-
"html" => '<div id="baz"><span>bar</span></div>',
|
46
|
-
"payload" => {},
|
47
|
-
"stimulusReflex" => {
|
48
|
-
"some" => "data",
|
49
|
-
"morph" => "selector"
|
50
|
-
},
|
51
|
-
"reflexId" => "666",
|
52
|
-
"operation" => "innerHtml"
|
53
|
-
}
|
54
|
-
],
|
55
|
-
"version" => CableReady::VERSION
|
56
|
-
}
|
57
|
-
|
58
|
-
assert_broadcast_on @reflex.stream_name, expected do
|
59
|
-
broadcaster.broadcast nil, some: :data
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
test "morphs the contents of an element to an empty string if no content specified" do
|
64
|
-
broadcaster = StimulusReflex::SelectorBroadcaster.new(@reflex)
|
65
|
-
broadcaster.append_morph("#foo", nil)
|
66
|
-
|
67
|
-
expected = {
|
68
|
-
"cableReady" => true,
|
69
|
-
"operations" => [
|
70
|
-
{
|
71
|
-
"selector" => "#foo",
|
72
|
-
"html" => "",
|
73
|
-
"payload" => {},
|
74
|
-
"stimulusReflex" => {
|
75
|
-
"some" => "data",
|
76
|
-
"morph" => "selector"
|
77
|
-
},
|
78
|
-
"reflexId" => "666",
|
79
|
-
"operation" => "innerHtml"
|
80
|
-
}
|
81
|
-
],
|
82
|
-
"version" => CableReady::VERSION
|
83
|
-
}
|
84
|
-
|
85
|
-
assert_broadcast_on @reflex.stream_name, expected do
|
86
|
-
broadcaster.broadcast nil, some: :data
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
test "morphs the contents of an element to an empty string if empty specified" do
|
91
|
-
broadcaster = StimulusReflex::SelectorBroadcaster.new(@reflex)
|
92
|
-
broadcaster.append_morph("#foo", "")
|
93
|
-
|
94
|
-
expected = {
|
95
|
-
"cableReady" => true,
|
96
|
-
"operations" => [
|
97
|
-
{
|
98
|
-
"selector" => "#foo",
|
99
|
-
"html" => "",
|
100
|
-
"payload" => {},
|
101
|
-
"stimulusReflex" => {
|
102
|
-
"some" => "data",
|
103
|
-
"morph" => "selector"
|
104
|
-
},
|
105
|
-
"reflexId" => "666",
|
106
|
-
"operation" => "innerHtml"
|
107
|
-
}
|
108
|
-
],
|
109
|
-
"version" => CableReady::VERSION
|
110
|
-
}
|
111
|
-
|
112
|
-
assert_broadcast_on @reflex.stream_name, expected do
|
113
|
-
broadcaster.broadcast nil, some: :data
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
test "morphs the contents of an element to an empty string if no content specified, hash form" do
|
118
|
-
broadcaster = StimulusReflex::SelectorBroadcaster.new(@reflex)
|
119
|
-
broadcaster.append_morph({"#foo": nil}, nil)
|
120
|
-
|
121
|
-
expected = {
|
122
|
-
"cableReady" => true,
|
123
|
-
"operations" => [
|
124
|
-
{
|
125
|
-
"selector" => "#foo",
|
126
|
-
"html" => "",
|
127
|
-
"payload" => {},
|
128
|
-
"stimulusReflex" => {
|
129
|
-
"some" => "data",
|
130
|
-
"morph" => "selector"
|
131
|
-
},
|
132
|
-
"reflexId" => "666",
|
133
|
-
"operation" => "innerHtml"
|
134
|
-
}
|
135
|
-
],
|
136
|
-
"version" => CableReady::VERSION
|
137
|
-
}
|
138
|
-
|
139
|
-
assert_broadcast_on @reflex.stream_name, expected do
|
140
|
-
broadcaster.broadcast nil, some: :data
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
test "morphs the contents of an element to specified HTML, hash form" do
|
145
|
-
broadcaster = StimulusReflex::SelectorBroadcaster.new(@reflex)
|
146
|
-
broadcaster.append_morph({"#foo": '<div id="foo"><div>bar</div><div>baz</div></div>'}, nil)
|
147
|
-
|
148
|
-
expected = {
|
149
|
-
"cableReady" => true,
|
150
|
-
"operations" => [
|
151
|
-
{
|
152
|
-
"selector" => "#foo",
|
153
|
-
"html" => "<div>bar</div><div>baz</div>",
|
154
|
-
"payload" => {},
|
155
|
-
"childrenOnly" => true,
|
156
|
-
"permanentAttributeName" => nil,
|
157
|
-
"stimulusReflex" => {
|
158
|
-
"some" => "data",
|
159
|
-
"morph" => "selector"
|
160
|
-
},
|
161
|
-
"reflexId" => "666",
|
162
|
-
"operation" => "morph"
|
163
|
-
}
|
164
|
-
],
|
165
|
-
"version" => CableReady::VERSION
|
166
|
-
}
|
167
|
-
|
168
|
-
assert_broadcast_on @reflex.stream_name, expected do
|
169
|
-
broadcaster.broadcast nil, some: :data
|
170
|
-
end
|
171
|
-
end
|
172
|
-
end
|
173
|
-
end
|