diff --git a/assets/js/manager.js b/assets/js/manager.js index b138312..a70613f 100644 --- a/assets/js/manager.js +++ b/assets/js/manager.js @@ -1,82 +1,176 @@ -import { tns } from "tiny-slider" +import { tns } from "tiny-slider"; export class Manager { - constructor(context) { - this.context = context - this.currentPage = parseInt(context.el.dataset.currentPage) - this.maxPage = parseInt(context.el.dataset.maxPage) + this.context = context; + this.currentPage = parseInt(context.el.dataset.currentPage); + this.maxPage = parseInt(context.el.dataset.maxPage); } init() { - - this.context.handleEvent('page-manage', data => { - var el = document.getElementById("slide-preview-" + data.current_page) + this.context.handleEvent("page-manage", (data) => { + var el = document.getElementById("slide-preview-" + data.current_page); if (el) { - setTimeout(() => { - document.getElementById("slides").scrollTo({ - top: el.offsetTop - el.scrollHeight, - left: 0, - behavior: 'smooth' - }); - }, data.timeout ? data.timeout : 0) + setTimeout( + () => { + const slidesLayout = document.getElementById("slides-layout"); + const layoutWidth = slidesLayout.clientWidth; + const elementWidth = el.children[0].scrollWidth; + const scrollPosition = + el.children[0].offsetLeft - layoutWidth / 2 + elementWidth / 2; + + slidesLayout.scrollTo({ + left: scrollPosition, + }); + }, + data.timeout ? data.timeout : 0 + ); } - }) + }); - window.addEventListener('keydown', (e) => { - - if ((e.target.tagName || '').toLowerCase() != "input") { - e.preventDefault() + window.addEventListener("keydown", (e) => { + if ((e.target.tagName || "").toLowerCase() != "input") { + e.preventDefault(); switch (e.key) { - case 'ArrowUp': - this.prevPage() - break - case 'ArrowLeft': - this.prevPage() - break - case 'ArrowRight': - this.nextPage() - break - case 'ArrowDown': - this.nextPage() - break + case "ArrowUp": + this.prevPage(); + break; + case "ArrowLeft": + this.prevPage(); + break; + case "ArrowRight": + this.nextPage(); + break; + case "ArrowDown": + this.nextPage(); + break; } } }); + + this.initPreview(); } - update() { - this.currentPage = parseInt(this.context.el.dataset.currentPage) - var el = document.getElementById("slide-preview-" + this.currentPage) + initPreview() { + var preview = document.getElementById("preview"); - if (el) { - setTimeout(() => { - document.getElementById("slides").scrollTo({ - top: el.offsetTop - el.scrollHeight, - left: 0, - behavior: 'smooth' - }); - }, 50) + if (preview) { + let isDragging = false; + let startX, startY; + + let originalSnap = localStorage.getItem("preview-position"); + if (originalSnap) { + let snaps = originalSnap.split(":"); + preview.style.left = `${snaps[0]}px`; + preview.style.top = `${snaps[1]}px`; + } + + const startDrag = (e) => { + isDragging = true; + startX = (e.clientX || e.touches[0].clientX) - preview.offsetLeft; + startY = (e.clientY || e.touches[0].clientY) - preview.offsetTop; + }; + + const drag = (e) => { + if (!isDragging) return; + + e.preventDefault(); + + const clientX = e.clientX || e.touches[0].clientX; + const clientY = e.clientY || e.touches[0].clientY; + + const newX = clientX - startX; + const newY = clientY - startY; + + preview.style.left = `${newX}px`; + preview.style.top = `${newY}px`; + }; + + const endDrag = () => { + if (!isDragging) return; + isDragging = false; + + const windowWidth = window.innerWidth; + const windowHeight = window.innerHeight; + const previewRect = preview.getBoundingClientRect(); + const padding = 20; // Add 20px padding + + let snapX, snapY; + + if (previewRect.left < windowWidth / 2) { + snapX = padding; + } else { + snapX = windowWidth - previewRect.width - padding; + } + + if (previewRect.top < windowHeight / 2) { + snapY = padding; + } else { + snapY = windowHeight - previewRect.height - padding; + } + + preview.style.transition = "left 0.3s ease-out, top 0.3s ease-out"; + preview.style.left = `${snapX}px`; + preview.style.top = `${snapY}px`; + + localStorage.setItem("preview-position", `${snapX}:${snapY}`); + + // Remove the transition after it's complete + setTimeout(() => { + preview.style.transition = ""; + }, 300); + }; + + preview.addEventListener("mousedown", startDrag); + preview.addEventListener("touchstart", startDrag); + + document.addEventListener("mousemove", drag); + document.addEventListener("touchmove", drag); + + document.addEventListener("mouseup", endDrag); + document.addEventListener("touchend", endDrag); } } + update() { + this.currentPage = parseInt(this.context.el.dataset.currentPage); + var el = document.getElementById("slide-preview-" + this.currentPage); + + if (el) { + setTimeout(() => { + const slidesLayout = document.getElementById("slides-layout"); + const layoutWidth = slidesLayout.clientWidth; + const elementWidth = el.children[0].scrollWidth; + const scrollPosition = + el.children[0].offsetLeft - layoutWidth / 2 + elementWidth / 2; + + slidesLayout.scrollTo({ + left: scrollPosition, + behavior: "smooth", + }); + }, 50); + } + + this.initPreview(); + } + nextPage() { - if (this.currentPage == this.maxPage - 1) - return; + if (this.currentPage == this.maxPage - 1) return; this.currentPage += 1; - this.context.pushEventTo(this.context.el, "current-page", { "page": this.currentPage.toString() }); + this.context.pushEventTo(this.context.el, "current-page", { + page: this.currentPage.toString(), + }); } prevPage() { - if (this.currentPage == 0) - return; + if (this.currentPage == 0) return; this.currentPage -= 1; - this.context.pushEventTo(this.context.el, "current-page", { "page": this.currentPage.toString() }); - + this.context.pushEventTo(this.context.el, "current-page", { + page: this.currentPage.toString(), + }); } - } diff --git a/assets/package-lock.json b/assets/package-lock.json index 5ae5a83..75ca013 100644 --- a/assets/package-lock.json +++ b/assets/package-lock.json @@ -6,6 +6,7 @@ "": { "dependencies": { "@sjmc11/tourguidejs": "^0.0.16", + "@tailwindcss/container-queries": "^0.1.1", "air-datepicker": "^3.5.0", "animate.css": "^4.1.1", "moment": "^2.29.4", @@ -45,7 +46,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", - "dev": true, "engines": { "node": ">=10" }, @@ -447,7 +447,6 @@ "version": "0.3.3", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", - "dev": true, "dependencies": { "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -461,7 +460,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", - "dev": true, "engines": { "node": ">=6.0.0" } @@ -470,7 +468,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true, "engines": { "node": ">=6.0.0" } @@ -478,14 +475,12 @@ "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.15", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.20", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", - "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -495,7 +490,6 @@ "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -508,7 +502,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, "engines": { "node": ">= 8" } @@ -517,7 +510,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -535,6 +527,14 @@ "sass": "^1.55.0" } }, + "node_modules/@tailwindcss/container-queries": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/container-queries/-/container-queries-0.1.1.tgz", + "integrity": "sha512-p18dswChx6WnTSaJCSGx6lTmrGzNNvm2FtXmiO6AuA1V4U5REyoqwmT6kgAsIMdjo07QdAfYXHJ4hnMtfHzWgA==", + "peerDependencies": { + "tailwindcss": ">=3.2.0" + } + }, "node_modules/@vue/reactivity": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.1.5.tgz", @@ -572,8 +572,7 @@ "node_modules/any-promise": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", - "dev": true + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" }, "node_modules/anymatch": { "version": "3.1.3", @@ -590,8 +589,7 @@ "node_modules/arg": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", - "dev": true + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" }, "node_modules/autoprefixer": { "version": "10.4.19", @@ -633,8 +631,7 @@ "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "node_modules/binary-extensions": { "version": "2.3.0", @@ -651,7 +648,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -704,7 +700,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", - "dev": true, "engines": { "node": ">= 6" } @@ -756,7 +751,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", - "dev": true, "engines": { "node": ">= 6" } @@ -764,14 +758,12 @@ "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "node_modules/cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "dev": true, "bin": { "cssesc": "bin/cssesc" }, @@ -782,14 +774,12 @@ "node_modules/didyoumean": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", - "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", - "dev": true + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" }, "node_modules/dlv": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", - "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", - "dev": true + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" }, "node_modules/electron-to-chromium": { "version": "1.4.736", @@ -848,7 +838,6 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", - "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -864,7 +853,6 @@ "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, "dependencies": { "braces": "^3.0.2", "picomatch": "^2.3.1" @@ -877,7 +865,6 @@ "version": "1.15.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", - "dev": true, "dependencies": { "reusify": "^1.0.4" } @@ -909,8 +896,7 @@ "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8= sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8= sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "node_modules/fsevents": { "version": "2.3.3", @@ -929,7 +915,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -949,7 +934,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", - "dev": true, "dependencies": { "function-bind": "^1.1.2" }, @@ -966,7 +950,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -975,8 +958,7 @@ "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "node_modules/is-binary-path": { "version": "2.1.0", @@ -993,7 +975,6 @@ "version": "2.13.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", - "dev": true, "dependencies": { "hasown": "^2.0.0" }, @@ -1032,7 +1013,6 @@ "version": "1.20.0", "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.20.0.tgz", "integrity": "sha512-3TV69ZbrvV6U5DfQimop50jE9Dl6J8O1ja1dvBbMba/sZ3YBEQqJ2VZRoQPVnhlzjNtU1vaXRZVrVjU4qtm8yA==", - "dev": true, "bin": { "jiti": "bin/jiti.js" } @@ -1041,7 +1021,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", - "dev": true, "engines": { "node": ">=10" } @@ -1049,14 +1028,12 @@ "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, "engines": { "node": ">= 8" } @@ -1065,7 +1042,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -1096,7 +1072,6 @@ "version": "2.7.0", "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "dev": true, "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", @@ -1107,7 +1082,6 @@ "version": "3.3.7", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", - "dev": true, "funding": [ { "type": "github", @@ -1148,7 +1122,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -1157,7 +1130,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", - "dev": true, "engines": { "node": ">= 6" } @@ -1166,7 +1138,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E= sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, "dependencies": { "wrappy": "1" } @@ -1175,7 +1146,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18= sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -1183,8 +1153,7 @@ "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, "node_modules/phoenix": { "resolved": "../deps/phoenix", @@ -1201,8 +1170,7 @@ "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" }, "node_modules/picomatch": { "version": "2.3.1", @@ -1219,7 +1187,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw= sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -1228,7 +1195,6 @@ "version": "4.0.6", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", - "dev": true, "engines": { "node": ">= 6" } @@ -1237,7 +1203,6 @@ "version": "8.4.38", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", - "dev": true, "funding": [ { "type": "opencollective", @@ -1265,7 +1230,6 @@ "version": "15.1.0", "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", - "dev": true, "dependencies": { "postcss-value-parser": "^4.0.0", "read-cache": "^1.0.0", @@ -1282,7 +1246,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", - "dev": true, "dependencies": { "camelcase-css": "^2.0.1" }, @@ -1301,7 +1264,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.1.tgz", "integrity": "sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==", - "dev": true, "dependencies": { "lilconfig": "^2.0.5", "yaml": "^2.1.1" @@ -1330,7 +1292,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz", "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==", - "dev": true, "dependencies": { "postcss-selector-parser": "^6.0.11" }, @@ -1349,7 +1310,6 @@ "version": "6.0.13", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz", "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==", - "dev": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -1361,8 +1321,7 @@ "node_modules/postcss-value-parser": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "dev": true + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" }, "node_modules/qr-code-styling": { "version": "1.6.0-rc.1", @@ -1381,7 +1340,6 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, "funding": [ { "type": "github", @@ -1401,7 +1359,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", "integrity": "sha1-5mTvMRYRZsl1HNvo28+GtftY93Q= sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", - "dev": true, "dependencies": { "pify": "^2.3.0" } @@ -1421,7 +1378,6 @@ "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dev": true, "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -1438,7 +1394,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" @@ -1448,7 +1403,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, "funding": [ { "type": "github", @@ -1505,7 +1459,6 @@ "version": "3.34.0", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.34.0.tgz", "integrity": "sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw==", - "dev": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.2", "commander": "^4.0.0", @@ -1527,7 +1480,6 @@ "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -1547,7 +1499,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, "engines": { "node": ">= 0.4" }, @@ -1559,7 +1510,6 @@ "version": "3.3.3", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.3.tgz", "integrity": "sha512-A0KgSkef7eE4Mf+nKJ83i75TMyq8HqY3qmFIJSWy8bNt0v1lG7jUcpGpoTFxAwYcWOphcTBLPPJg+bDfhDf52w==", - "dev": true, "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", @@ -1596,7 +1546,6 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, "dependencies": { "is-glob": "^4.0.3" }, @@ -1608,7 +1557,6 @@ "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, "dependencies": { "braces": "^3.0.2", "picomatch": "^2.3.1" @@ -1621,7 +1569,6 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "dev": true, "dependencies": { "any-promise": "^1.0.0" } @@ -1630,7 +1577,6 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", - "dev": true, "dependencies": { "thenify": ">= 3.1.0 < 4" }, @@ -1657,8 +1603,7 @@ "node_modules/ts-interface-checker": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", - "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", - "dev": true + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==" }, "node_modules/update-browserslist-db": { "version": "1.0.13", @@ -1693,20 +1638,17 @@ "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "node_modules/yaml": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.3.tgz", "integrity": "sha512-zw0VAJxgeZ6+++/su5AFoqBbZbrEakwu+X0M5HmcwUiBL7AzcuPKjj5we4xfQLp78LkEMpD0cOnUhmgOVy3KdQ==", - "dev": true, "engines": { "node": ">= 14" } @@ -1716,8 +1658,7 @@ "@alloc/quick-lru": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", - "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", - "dev": true + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==" }, "@esbuild/aix-ppc64": { "version": "0.20.2", @@ -1906,7 +1847,6 @@ "version": "0.3.3", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", - "dev": true, "requires": { "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -1916,26 +1856,22 @@ "@jridgewell/resolve-uri": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", - "dev": true + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==" }, "@jridgewell/set-array": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==" }, "@jridgewell/sourcemap-codec": { "version": "1.4.15", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" }, "@jridgewell/trace-mapping": { "version": "0.3.20", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", - "dev": true, "requires": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -1945,7 +1881,6 @@ "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, "requires": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -1954,14 +1889,12 @@ "@nodelib/fs.stat": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==" }, "@nodelib/fs.walk": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, "requires": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -1976,6 +1909,12 @@ "sass": "^1.55.0" } }, + "@tailwindcss/container-queries": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/container-queries/-/container-queries-0.1.1.tgz", + "integrity": "sha512-p18dswChx6WnTSaJCSGx6lTmrGzNNvm2FtXmiO6AuA1V4U5REyoqwmT6kgAsIMdjo07QdAfYXHJ4hnMtfHzWgA==", + "requires": {} + }, "@vue/reactivity": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.1.5.tgz", @@ -2013,8 +1952,7 @@ "any-promise": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", - "dev": true + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" }, "anymatch": { "version": "3.1.3", @@ -2028,8 +1966,7 @@ "arg": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", - "dev": true + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" }, "autoprefixer": { "version": "10.4.19", @@ -2048,8 +1985,7 @@ "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "binary-extensions": { "version": "2.3.0", @@ -2060,7 +1996,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -2089,8 +2024,7 @@ "camelcase-css": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", - "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", - "dev": true + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==" }, "caniuse-lite": { "version": "1.0.30001609", @@ -2116,32 +2050,27 @@ "commander": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", - "dev": true + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==" }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "dev": true + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==" }, "didyoumean": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", - "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", - "dev": true + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" }, "dlv": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", - "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", - "dev": true + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" }, "electron-to-chromium": { "version": "1.4.736", @@ -2190,7 +2119,6 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", - "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -2203,7 +2131,6 @@ "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, "requires": { "braces": "^3.0.2", "picomatch": "^2.3.1" @@ -2215,7 +2142,6 @@ "version": "1.15.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", - "dev": true, "requires": { "reusify": "^1.0.4" } @@ -2237,8 +2163,7 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8= sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8= sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "fsevents": { "version": "2.3.3", @@ -2249,8 +2174,7 @@ "function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" }, "glob-parent": { "version": "5.1.2", @@ -2264,7 +2188,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", - "dev": true, "requires": { "function-bind": "^1.1.2" } @@ -2278,7 +2201,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -2287,8 +2209,7 @@ "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "is-binary-path": { "version": "2.1.0", @@ -2302,7 +2223,6 @@ "version": "2.13.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", - "dev": true, "requires": { "hasown": "^2.0.0" } @@ -2328,32 +2248,27 @@ "jiti": { "version": "1.20.0", "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.20.0.tgz", - "integrity": "sha512-3TV69ZbrvV6U5DfQimop50jE9Dl6J8O1ja1dvBbMba/sZ3YBEQqJ2VZRoQPVnhlzjNtU1vaXRZVrVjU4qtm8yA==", - "dev": true + "integrity": "sha512-3TV69ZbrvV6U5DfQimop50jE9Dl6J8O1ja1dvBbMba/sZ3YBEQqJ2VZRoQPVnhlzjNtU1vaXRZVrVjU4qtm8yA==" }, "lilconfig": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", - "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", - "dev": true + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==" }, "lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, "merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" }, "minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, "requires": { "brace-expansion": "^1.1.7" } @@ -2375,7 +2290,6 @@ "version": "2.7.0", "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "dev": true, "requires": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", @@ -2385,8 +2299,7 @@ "nanoid": { "version": "3.3.7", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", - "dev": true + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==" }, "node-releases": { "version": "2.0.14", @@ -2408,20 +2321,17 @@ "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" }, "object-hash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", - "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", - "dev": true + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==" }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E= sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, "requires": { "wrappy": "1" } @@ -2429,14 +2339,12 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18= sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18= sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" }, "path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, "phoenix": { "version": "file:../deps/phoenix" @@ -2453,8 +2361,7 @@ "picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" }, "picomatch": { "version": "2.3.1", @@ -2464,20 +2371,17 @@ "pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw= sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw= sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==" }, "pirates": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", - "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", - "dev": true + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==" }, "postcss": { "version": "8.4.38", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", - "dev": true, "requires": { "nanoid": "^3.3.7", "picocolors": "^1.0.0", @@ -2488,7 +2392,6 @@ "version": "15.1.0", "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", - "dev": true, "requires": { "postcss-value-parser": "^4.0.0", "read-cache": "^1.0.0", @@ -2499,7 +2402,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", - "dev": true, "requires": { "camelcase-css": "^2.0.1" } @@ -2508,7 +2410,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.1.tgz", "integrity": "sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==", - "dev": true, "requires": { "lilconfig": "^2.0.5", "yaml": "^2.1.1" @@ -2518,7 +2419,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz", "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==", - "dev": true, "requires": { "postcss-selector-parser": "^6.0.11" } @@ -2527,7 +2427,6 @@ "version": "6.0.13", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz", "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==", - "dev": true, "requires": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -2536,8 +2435,7 @@ "postcss-value-parser": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "dev": true + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" }, "qr-code-styling": { "version": "1.6.0-rc.1", @@ -2555,14 +2453,12 @@ "queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" }, "read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", "integrity": "sha1-5mTvMRYRZsl1HNvo28+GtftY93Q= sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", - "dev": true, "requires": { "pify": "^2.3.0" } @@ -2579,7 +2475,6 @@ "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dev": true, "requires": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -2589,14 +2484,12 @@ "reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" }, "run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, "requires": { "queue-microtask": "^1.2.2" } @@ -2630,7 +2523,6 @@ "version": "3.34.0", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.34.0.tgz", "integrity": "sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw==", - "dev": true, "requires": { "@jridgewell/gen-mapping": "^0.3.2", "commander": "^4.0.0", @@ -2645,7 +2537,6 @@ "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -2660,14 +2551,12 @@ "supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" }, "tailwindcss": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.3.tgz", "integrity": "sha512-A0KgSkef7eE4Mf+nKJ83i75TMyq8HqY3qmFIJSWy8bNt0v1lG7jUcpGpoTFxAwYcWOphcTBLPPJg+bDfhDf52w==", - "dev": true, "requires": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", @@ -2697,7 +2586,6 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, "requires": { "is-glob": "^4.0.3" } @@ -2706,7 +2594,6 @@ "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, "requires": { "braces": "^3.0.2", "picomatch": "^2.3.1" @@ -2718,7 +2605,6 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "dev": true, "requires": { "any-promise": "^1.0.0" } @@ -2727,7 +2613,6 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", - "dev": true, "requires": { "thenify": ">= 3.1.0 < 4" } @@ -2748,8 +2633,7 @@ "ts-interface-checker": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", - "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", - "dev": true + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==" }, "update-browserslist-db": { "version": "1.0.13", @@ -2764,20 +2648,17 @@ "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "yaml": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.3.tgz", - "integrity": "sha512-zw0VAJxgeZ6+++/su5AFoqBbZbrEakwu+X0M5HmcwUiBL7AzcuPKjj5we4xfQLp78LkEMpD0cOnUhmgOVy3KdQ==", - "dev": true + "integrity": "sha512-zw0VAJxgeZ6+++/su5AFoqBbZbrEakwu+X0M5HmcwUiBL7AzcuPKjj5we4xfQLp78LkEMpD0cOnUhmgOVy3KdQ==" } } } diff --git a/assets/package.json b/assets/package.json index 489c528..f7f2c37 100644 --- a/assets/package.json +++ b/assets/package.json @@ -12,6 +12,7 @@ }, "dependencies": { "@sjmc11/tourguidejs": "^0.0.16", + "@tailwindcss/container-queries": "^0.1.1", "air-datepicker": "^3.5.0", "animate.css": "^4.1.1", "moment": "^2.29.4", @@ -24,4 +25,4 @@ "split.js": "^1.6.5", "tiny-slider": "^2.9.4" } -} \ No newline at end of file +} diff --git a/assets/tailwind.config.js b/assets/tailwind.config.js index 8b9604a..d927e1d 100644 --- a/assets/tailwind.config.js +++ b/assets/tailwind.config.js @@ -1,112 +1,109 @@ -const { colors: defaultColors } = require('tailwindcss/defaultTheme') +const { colors: defaultColors } = require("tailwindcss/defaultTheme"); const colors = { ...defaultColors, ...{ "water-blue": { - "50": "#E3F2FD", - "100": "#C2E3FA", - "200": "#84C8F6", - "300": "#3DA7F0", - "400": "#1395EC", - "500": "#1186D5", - "600": "#0D65A1", - "700": "#0A5689", - "800": "#0A4B76", - "900": "#073250", + 50: "#E3F2FD", + 100: "#C2E3FA", + 200: "#84C8F6", + 300: "#3DA7F0", + 400: "#1395EC", + 500: "#1186D5", + 600: "#0D65A1", + 700: "#0A5689", + 800: "#0A4B76", + 900: "#073250", }, "electric-purple": { - "50": "#F2E0FF", - "100": "#E3BDFF", - "200": "#C77AFF", - "300": "#A62EFF", - "400": "#9200FF", - "500": "#A327FF", - "600": "#6400AD", - "700": "#550094", - "800": "#490080", - "900": "#320057", + 50: "#F2E0FF", + 100: "#E3BDFF", + 200: "#C77AFF", + 300: "#A62EFF", + 400: "#9200FF", + 500: "#A327FF", + 600: "#6400AD", + 700: "#550094", + 800: "#490080", + 900: "#320057", }, - "wedgewood": { - "50": "#F0F4F8", - "100": "#D9E3ED", - "200": "#B9CCDF", - "300": "#97B3CE", - "400": "#7499BE", - "500": "#507DAA", - "600": "#3F6388", - "700": "#314D68", - "800": "#253B50", - "900": "#1A2938", + wedgewood: { + 50: "#F0F4F8", + 100: "#D9E3ED", + 200: "#B9CCDF", + 300: "#97B3CE", + 400: "#7499BE", + 500: "#507DAA", + 600: "#3F6388", + 700: "#314D68", + 800: "#253B50", + 900: "#1A2938", }, "rose-madder": { - "50": "#FCEDEE", - "100": "#F9D5D7", - "200": "#F3ABB0", - "300": "#ED8188", - "400": "#E75761", - "500": "#E12D39", - "600": "#B4242E", - "700": "#871B22", - "800": "#5A1217", - "900": "#2D090B", + 50: "#FCEDEE", + 100: "#F9D5D7", + 200: "#F3ABB0", + 300: "#ED8188", + 400: "#E75761", + 500: "#E12D39", + 600: "#B4242E", + 700: "#871B22", + 800: "#5A1217", + 900: "#2D090B", }, "school-bus-yellow": { - "50": "#FFFBEB", - "100": "#FEF3C7", - "200": "#FDE68A", - "300": "#FCD34D", - "400": "#FBBF24", - "500": "#F59E0B", - "600": "#D97706", - "700": "#B45309", - "800": "#92400E", - "900": "#78350F", + 50: "#FFFBEB", + 100: "#FEF3C7", + 200: "#FDE68A", + 300: "#FCD34D", + 400: "#FBBF24", + 500: "#F59E0B", + 600: "#D97706", + 700: "#B45309", + 800: "#92400E", + 900: "#78350F", }, "green-teal": { - "50": "#ECFDF5", - "100": "#D1FAE5", - "200": "#A7F3D0", - "300": "#6EE7B7", - "400": "#34D399", - "500": "#10B981", - "600": "#059669", - "700": "#047857", - "800": "#065F46", - "900": "#064E3B", + 50: "#ECFDF5", + 100: "#D1FAE5", + 200: "#A7F3D0", + 300: "#6EE7B7", + 400: "#34D399", + 500: "#10B981", + 600: "#059669", + 700: "#047857", + 800: "#065F46", + 900: "#064E3B", }, }, -} +}; module.exports = { - mode: 'jit', - content: [ - './js/**/*.js', - '../lib/*_web/**/*.*ex' - ], + mode: "jit", + content: ["./js/**/*.js", "../lib/*_web/**/*.*ex"], safelist: [ - '-top-1.5', - 'top-1', - 'left-3', - 'top-6', - 'h-5', - 'left-2.5', - 'top-3', - 'h-7', - 'bg-secondary-600', - 'text-white', - 'bg-white', - 'text-gray-600' + "-top-1.5", + "top-1", + "left-3", + "top-6", + "h-5", + "left-2.5", + "top-3", + "h-7", + "bg-secondary-600", + "text-white", + "bg-white", + "text-gray-600", ], - darkMode: 'media', + darkMode: "media", theme: { extend: { backgroundSize: { - 'size-200': '200% 200%', + "size-200": "200% 200%", }, backgroundPosition: { - 'pos-0': '0% 0%', - 'pos-100': '100% 100%', + "pos-0": "0% 0%", + "pos-100": "100% 100%", }, colors: { primary: colors["water-blue"], @@ -114,24 +111,24 @@ module.exports = { neutral: colors["wedgewood"], "supporting-red": colors["rose-madder"], "supporting-yellow": colors["school-bus-yellow"], - "supporting-green": colors["green-teal"] - } + "supporting-green": colors["green-teal"], + }, }, fontFamily: { - sans: ['Roboto', 'sans-serif'], - serif: ['Merriweather', 'serif'], + sans: ["Roboto", "sans-serif"], + serif: ["Merriweather", "serif"], }, boxShadow: { - "base": "0px 1px 3px 0px rgba(0,0,0,0.1), 0px 1px 2px 0px rgba(0,0,0,0.06)", - "lg": "0px 4px 6px 0px rgba(0,0,0,0.05), 0px 10px 15px 0px rgba(0,0,0,0.1)", - "md": "0px 4px 6px 0px rgba(0,0,0,0.1), 0px 2px 4px 0px rgba(0,0,0,0.06)", - "xl": "0px 10px 10px 0px rgba(0,0,0,0.04), 0px 20px 25px 0px rgba(0,0,0,0.1)", + base: "0px 1px 3px 0px rgba(0,0,0,0.1), 0px 1px 2px 0px rgba(0,0,0,0.06)", + lg: "0px 4px 6px 0px rgba(0,0,0,0.05), 0px 10px 15px 0px rgba(0,0,0,0.1)", + md: "0px 4px 6px 0px rgba(0,0,0,0.1), 0px 2px 4px 0px rgba(0,0,0,0.06)", + xl: "0px 10px 10px 0px rgba(0,0,0,0.04), 0px 20px 25px 0px rgba(0,0,0,0.1)", "2xl": "0px 25px 50px 0px rgba(0,0,0,0.25)", - "inner": "inset 0px 2px 4px 0px rgba(0,0,0,0.06)" - } + inner: "inset 0px 2px 4px 0px rgba(0,0,0,0.06)", + }, }, variants: { extend: {}, }, - plugins: [], -} + plugins: [require("@tailwindcss/container-queries")], +}; diff --git a/lib/claper/embeds.ex b/lib/claper/embeds.ex index 772b215..b9b2e5d 100644 --- a/lib/claper/embeds.ex +++ b/lib/claper/embeds.ex @@ -93,6 +93,14 @@ defmodule Claper.Embeds do %Embed{} |> Embed.changeset(attrs) |> Repo.insert() + |> case do + {:ok, embed} -> + embed = Repo.preload(embed, presentation_file: :event) + broadcast({:ok, embed, embed.presentation_file.event.uuid}, :embed_created) + + {:error, changeset} -> + {:error, %{changeset | action: :insert}} + end end @doc """ @@ -157,22 +165,16 @@ defmodule Claper.Embeds do |> Repo.update_all(set: [enabled: false]) end - def set_status(id, presentation_file_id, position, status) do - if status do - from(e in Embed, - where: - e.presentation_file_id == ^presentation_file_id and e.position == ^position and - e.id != ^id - ) - |> Repo.update_all(set: [enabled: false]) - end + def set_enabled(id) do + get_embed!(id) + |> Ecto.Changeset.change(enabled: true) + |> Repo.update() + end - from(e in Embed, - where: - e.presentation_file_id == ^presentation_file_id and e.position == ^position and - e.id == ^id - ) - |> Repo.update_all(set: [enabled: status]) + def set_disabled(id) do + get_embed!(id) + |> Ecto.Changeset.change(enabled: false) + |> Repo.update() end defp broadcast({:error, _reason} = error, _embed), do: error diff --git a/lib/claper/forms.ex b/lib/claper/forms.ex index 893825d..0fc1091 100644 --- a/lib/claper/forms.ex +++ b/lib/claper/forms.ex @@ -95,6 +95,14 @@ defmodule Claper.Forms do %Form{} |> Form.changeset(attrs) |> Repo.insert() + |> case do + {:ok, form} -> + form = Repo.preload(form, presentation_file: :event) + broadcast({:ok, form, form.presentation_file.event.uuid}, :form_created) + + {:error, changeset} -> + {:error, %{changeset | action: :insert}} + end end @doc """ @@ -181,22 +189,16 @@ defmodule Claper.Forms do |> Repo.update_all(set: [enabled: false]) end - def set_status(id, presentation_file_id, position, status) do - if status do - from(f in Form, - where: - f.presentation_file_id == ^presentation_file_id and f.position == ^position and - f.id != ^id - ) - |> Repo.update_all(set: [enabled: false]) - end + def set_enabled(id) do + get_form!(id) + |> Ecto.Changeset.change(enabled: true) + |> Repo.update() + end - from(f in Form, - where: - f.presentation_file_id == ^presentation_file_id and f.position == ^position and - f.id == ^id - ) - |> Repo.update_all(set: [enabled: status]) + def set_disabled(id) do + get_form!(id) + |> Ecto.Changeset.change(enabled: false) + |> Repo.update() end defp broadcast({:error, _reason} = error, _form), do: error diff --git a/lib/claper/interactions.ex b/lib/claper/interactions.ex new file mode 100644 index 0000000..2e9d662 --- /dev/null +++ b/lib/claper/interactions.ex @@ -0,0 +1,115 @@ +defmodule Claper.Interactions do + alias Claper.Polls + alias Claper.Forms + alias Claper.Embeds + alias Claper.Events + alias Claper.Presentations + + import Ecto.Query, warn: false + + @type interaction :: Polls.Poll | Forms.Form | Embeds.Embed + + def get_number_total_interactions(presentation_file_id) do + from(p in Polls.Poll, + where: p.presentation_file_id == ^presentation_file_id, + select: count(p.id) + ) + |> Claper.Repo.one() + |> Kernel.+( + from(f in Forms.Form, + where: f.presentation_file_id == ^presentation_file_id, + select: count(f.id) + ) + |> Claper.Repo.one() + ) + |> Kernel.+( + from(e in Embeds.Embed, + where: e.presentation_file_id == ^presentation_file_id, + select: count(e.id) + ) + |> Claper.Repo.one() + ) + end + + def get_active_interaction(event, position) do + with {:ok, interactions} <- get_interactions_at_position(event, position) do + interactions |> Enum.filter(&(&1.enabled == true)) |> List.first() + end + end + + def get_interactions_at_position( + %Events.Event{ + presentation_file: %Presentations.PresentationFile{id: presentation_file_id} + } = event, + position, + broadcast \\ false + ) do + with polls <- Polls.list_polls_at_position(presentation_file_id, position), + forms <- Forms.list_forms_at_position(presentation_file_id, position), + embeds <- Embeds.list_embeds_at_position(presentation_file_id, position) do + interactions = + (polls ++ forms ++ embeds) + |> Enum.sort_by(& &1.inserted_at, {:asc, NaiveDateTime}) + + if broadcast do + active_interaction = interactions |> Enum.filter(&(&1.enabled == true)) |> List.first() + + Phoenix.PubSub.broadcast( + Claper.PubSub, + "event:#{event.uuid}", + {:current_interaction, active_interaction} + ) + end + + {:ok, interactions} + end + end + + def enable_interaction(interaction) do + Ecto.Multi.new() + |> Ecto.Multi.run(:disable_polls, fn _repo, _ -> + {count, _} = Polls.disable_all(interaction.presentation_file_id, interaction.position) + {:ok, count} + end) + |> Ecto.Multi.run(:disable_forms, fn _repo, _ -> + {count, _} = Forms.disable_all(interaction.presentation_file_id, interaction.position) + {:ok, count} + end) + |> Ecto.Multi.run(:disable_embeds, fn _repo, _ -> + {count, _} = Embeds.disable_all(interaction.presentation_file_id, interaction.position) + {:ok, count} + end) + |> Ecto.Multi.run(:enable_interaction, fn _repo, _ -> + set_enabled(interaction) + end) + |> Claper.Repo.transaction() + |> case do + {:ok, _} -> :ok + {:error, _, reason, _} -> {:error, reason} + end + end + + defp set_enabled(%Polls.Poll{} = interaction) do + Polls.set_enabled(interaction.id) + end + + defp set_enabled(%Forms.Form{} = interaction) do + Forms.set_enabled(interaction.id) + end + + defp set_enabled(%Embeds.Embed{} = interaction) do + Embeds.set_enabled(interaction.id) + end + + def disable_interaction(%Polls.Poll{} = interaction) do + Polls.set_disabled(interaction.id) + end + + def disable_interaction(%Forms.Form{} = interaction) do + Forms.set_disabled(interaction.id) + end + + def disable_interaction(%Embeds.Embed{} = interaction) do + Embeds.set_disabled(interaction.id) + end +end diff --git a/lib/claper/polls.ex b/lib/claper/polls.ex index 724dec2..4ed6d1a 100644 --- a/lib/claper/polls.ex +++ b/lib/claper/polls.ex @@ -142,6 +142,14 @@ defmodule Claper.Polls do %Poll{} |> Poll.changeset(attrs) |> Repo.insert() + |> case do + {:ok, poll} -> + poll = Repo.preload(poll, presentation_file: :event) + broadcast({:ok, poll, poll.presentation_file.event.uuid}, :poll_created) + + {:error, changeset} -> + {:error, %{changeset | action: :insert}} + end end @doc """ @@ -275,22 +283,16 @@ defmodule Claper.Polls do |> Repo.update_all(set: [enabled: false]) end - def set_status(id, presentation_file_id, position, status) do - if status do - from(p in Poll, - where: - p.presentation_file_id == ^presentation_file_id and p.position == ^position and - p.id != ^id - ) - |> Repo.update_all(set: [enabled: false]) - end + def set_enabled(id) do + get_poll!(id) + |> Ecto.Changeset.change(enabled: true) + |> Repo.update() + end - from(p in Poll, - where: - p.presentation_file_id == ^presentation_file_id and p.position == ^position and - p.id == ^id - ) - |> Repo.update_all(set: [enabled: status]) + def set_disabled(id) do + get_poll!(id) + |> Ecto.Changeset.change(enabled: false) + |> Repo.update() end defp broadcast({:error, _reason} = error, _poll), do: error diff --git a/lib/claper_web/live/event_live/manage.ex b/lib/claper_web/live/event_live/manage.ex index ba55949..b011fa4 100644 --- a/lib/claper_web/live/event_live/manage.ex +++ b/lib/claper_web/live/event_live/manage.ex @@ -26,6 +26,7 @@ defmodule ClaperWeb.EventLive.Manage do else if connected?(socket) do Claper.Events.Event.subscribe(event.uuid) + Claper.Presentations.subscribe(event.presentation_file.id) Presence.track( self(), @@ -54,23 +55,23 @@ defmodule ClaperWeb.EventLive.Manage do |> assign(:pinned_post_count, length(pinned_posts)) |> assign(:question_count, length(questions)) |> assign(:post_count, length(posts)) + |> assign( + :total_interactions, + Claper.Interactions.get_number_total_interactions(event.presentation_file.id) + ) |> assign( :form_submit_count, length(form_submits) ) - |> assign(:polls, list_polls(socket, event.presentation_file.id)) - |> assign(:forms, list_forms(socket, event.presentation_file.id)) - |> assign(:embeds, list_embeds(socket, event.presentation_file.id)) |> assign(:create, nil) |> assign(:list_tab, :posts) |> assign(:create_action, :new) + |> assign(:preview, false) |> push_event("page-manage", %{ current_page: event.presentation_file.presentation_state.position, timeout: 500 }) - |> poll_at_position(false) - |> form_at_position(false) - |> embed_at_position(false) + |> interactions_at_position(event.presentation_file.presentation_state.position) {:ok, socket} end @@ -190,33 +191,92 @@ defmodule ClaperWeb.EventLive.Manage do end @impl true - def handle_info({:poll_updated, poll}, socket) do + def handle_info({:poll_created, poll}, socket) do {:noreply, socket - |> update(:current_poll, fn _current_poll -> poll end)} + |> interactions_at_position(poll.position)} end @impl true - def handle_info( - {:current_poll, poll}, - socket - ) do - {:noreply, socket |> assign(:current_poll, poll)} + def handle_info({:form_created, form}, socket) do + {:noreply, + socket + |> interactions_at_position(form.position)} + end + + @impl true + def handle_info({:embed_created, embed}, socket) do + {:noreply, + socket + |> interactions_at_position(embed.position)} + end + + @impl true + def handle_info({:poll_updated, poll}, socket) do + {:noreply, + socket + |> interactions_at_position(poll.position)} end @impl true def handle_info({:embed_updated, embed}, socket) do {:noreply, socket - |> update(:current_embed, fn _current_embed -> embed end)} + |> interactions_at_position(embed.position)} + end + + @impl true + def handle_info({:form_updated, form}, socket) do + {:noreply, + socket + |> interactions_at_position(form.position)} + end + + @impl true + def handle_info({:poll_deleted, poll}, socket) do + {:noreply, + socket + |> interactions_at_position(poll.position)} + end + + @impl true + def handle_info({:embed_deleted, embed}, socket) do + {:noreply, + socket + |> interactions_at_position(embed.position)} + end + + @impl true + def handle_info({:form_deleted, form}, socket) do + {:noreply, + socket + |> interactions_at_position(form.position)} end @impl true def handle_info( - {:current_embed, embed}, + {:current_interaction, interaction}, socket ) do - {:noreply, socket |> assign(:current_embed, embed)} + if socket.assigns.current_interaction != interaction do + position = if interaction, do: interaction.position, else: socket.assigns.state.position + + {:noreply, + socket + |> assign(:current_interaction, interaction) + |> interactions_at_position(position)} + else + {:noreply, socket} + end + end + + @impl true + def handle_info({:state_updated, state}, socket) do + if state.position != socket.assigns.state.position do + {:noreply, socket |> assign(:state, state) |> interactions_at_position(state.position)} + else + {:noreply, socket |> assign(:state, state)} + end end @impl true @@ -249,9 +309,7 @@ defmodule ClaperWeb.EventLive.Manage do {:noreply, socket |> assign(:state, new_state) - |> poll_at_position - |> form_at_position - |> embed_at_position} + |> interactions_at_position(page)} end @impl true @@ -278,174 +336,94 @@ defmodule ClaperWeb.EventLive.Manage do end def handle_event("poll-set-active", %{"id" => id}, socket) do - Forms.disable_all(socket.assigns.event.presentation_file.id, socket.assigns.state.position) - Embeds.disable_all(socket.assigns.event.presentation_file.id, socket.assigns.state.position) + with poll <- Polls.get_poll!(id), :ok <- Claper.Interactions.enable_interaction(poll) do + Phoenix.PubSub.broadcast( + Claper.PubSub, + "event:#{socket.assigns.event.uuid}", + {:current_interaction, poll} + ) - Polls.set_status( - id, - socket.assigns.event.presentation_file.id, - socket.assigns.state.position, - true - ) - - poll = Polls.get_poll!(id) - - Phoenix.PubSub.broadcast( - Claper.PubSub, - "event:#{socket.assigns.event.uuid}", - {:current_poll, poll} - ) - - Phoenix.PubSub.broadcast( - Claper.PubSub, - "event:#{socket.assigns.event.uuid}", - {:current_form, nil} - ) - - Phoenix.PubSub.broadcast( - Claper.PubSub, - "event:#{socket.assigns.event.uuid}", - {:current_embed, nil} - ) - - {:noreply, - socket - |> assign(:polls, list_polls(socket, socket.assigns.event.presentation_file.id)) - |> assign(:forms, list_forms(socket, socket.assigns.event.presentation_file.id)) - |> assign(:embeds, list_embeds(socket, socket.assigns.event.presentation_file.id))} + {:noreply, + socket + |> assign(:current_interaction, poll) + |> interactions_at_position(socket.assigns.state.position)} + end end def handle_event("form-set-active", %{"id" => id}, socket) do - Polls.disable_all(socket.assigns.event.presentation_file.id, socket.assigns.state.position) - Embeds.disable_all(socket.assigns.event.presentation_file.id, socket.assigns.state.position) + with form <- Forms.get_form!(id), :ok <- Claper.Interactions.enable_interaction(form) do + Phoenix.PubSub.broadcast( + Claper.PubSub, + "event:#{socket.assigns.event.uuid}", + {:current_interaction, form} + ) - Forms.set_status( - id, - socket.assigns.event.presentation_file.id, - socket.assigns.state.position, - true - ) - - form = Forms.get_form!(id) - - Phoenix.PubSub.broadcast( - Claper.PubSub, - "event:#{socket.assigns.event.uuid}", - {:current_form, form} - ) - - Phoenix.PubSub.broadcast( - Claper.PubSub, - "event:#{socket.assigns.event.uuid}", - {:current_poll, nil} - ) - - Phoenix.PubSub.broadcast( - Claper.PubSub, - "event:#{socket.assigns.event.uuid}", - {:current_embed, nil} - ) - - {:noreply, - socket - |> assign(:polls, list_polls(socket, socket.assigns.event.presentation_file.id)) - |> assign(:forms, list_forms(socket, socket.assigns.event.presentation_file.id)) - |> assign(:embeds, list_embeds(socket, socket.assigns.event.presentation_file.id))} + {:noreply, + socket + |> assign(:current_interaction, form) + |> interactions_at_position(socket.assigns.state.position)} + end end def handle_event("embed-set-active", %{"id" => id}, socket) do - Polls.disable_all(socket.assigns.event.presentation_file.id, socket.assigns.state.position) - Forms.disable_all(socket.assigns.event.presentation_file.id, socket.assigns.state.position) + with embed <- Embeds.get_embed!(id), :ok <- Claper.Interactions.enable_interaction(embed) do + Phoenix.PubSub.broadcast( + Claper.PubSub, + "event:#{socket.assigns.event.uuid}", + {:current_interaction, embed} + ) - Embeds.set_status( - id, - socket.assigns.event.presentation_file.id, - socket.assigns.state.position, - true - ) - - embed = Embeds.get_embed!(id) - - Phoenix.PubSub.broadcast( - Claper.PubSub, - "event:#{socket.assigns.event.uuid}", - {:current_embed, embed} - ) - - Phoenix.PubSub.broadcast( - Claper.PubSub, - "event:#{socket.assigns.event.uuid}", - {:current_poll, nil} - ) - - Phoenix.PubSub.broadcast( - Claper.PubSub, - "event:#{socket.assigns.event.uuid}", - {:current_form, nil} - ) - - {:noreply, - socket - |> assign(:polls, list_polls(socket, socket.assigns.event.presentation_file.id)) - |> assign(:forms, list_forms(socket, socket.assigns.event.presentation_file.id)) - |> assign(:embeds, list_embeds(socket, socket.assigns.event.presentation_file.id))} + {:noreply, + socket + |> assign(:current_interaction, embed) + |> interactions_at_position(socket.assigns.state.position)} + end end def handle_event("poll-set-inactive", %{"id" => id}, socket) do - Polls.set_status( - id, - socket.assigns.event.presentation_file.id, - socket.assigns.state.position, - false - ) - - Phoenix.PubSub.broadcast( - Claper.PubSub, - "event:#{socket.assigns.event.uuid}", - {:current_poll, nil} - ) + with poll <- Polls.get_poll!(id), {:ok, _} <- Claper.Interactions.disable_interaction(poll) do + Phoenix.PubSub.broadcast( + Claper.PubSub, + "event:#{socket.assigns.event.uuid}", + {:current_interaction, nil} + ) + end {:noreply, socket - |> assign(:polls, list_polls(socket, socket.assigns.event.presentation_file.id))} + |> assign(:current_interaction, nil) + |> interactions_at_position(socket.assigns.state.position)} end def handle_event("form-set-inactive", %{"id" => id}, socket) do - Forms.set_status( - id, - socket.assigns.event.presentation_file.id, - socket.assigns.state.position, - false - ) - - Phoenix.PubSub.broadcast( - Claper.PubSub, - "event:#{socket.assigns.event.uuid}", - {:current_form, nil} - ) + with form <- Forms.get_form!(id), {:ok, _} <- Claper.Interactions.disable_interaction(form) do + Phoenix.PubSub.broadcast( + Claper.PubSub, + "event:#{socket.assigns.event.uuid}", + {:current_interaction, nil} + ) + end {:noreply, socket - |> assign(:forms, list_forms(socket, socket.assigns.event.presentation_file.id))} + |> assign(:current_interaction, nil) + |> interactions_at_position(socket.assigns.state.position)} end def handle_event("embed-set-inactive", %{"id" => id}, socket) do - Embeds.set_status( - id, - socket.assigns.event.presentation_file.id, - socket.assigns.state.position, - false - ) - - Phoenix.PubSub.broadcast( - Claper.PubSub, - "event:#{socket.assigns.event.uuid}", - {:current_embed, nil} - ) + with embed <- Embeds.get_embed!(id), + {:ok, _} <- Claper.Interactions.disable_interaction(embed) do + Phoenix.PubSub.broadcast( + Claper.PubSub, + "event:#{socket.assigns.event.uuid}", + {:current_interaction, nil} + ) + end {:noreply, socket - |> assign(:embeds, list_embeds(socket, socket.assigns.event.presentation_file.id))} + |> assign(:current_interaction, nil) + |> interactions_at_position(socket.assigns.state.position)} end @impl true @@ -499,6 +477,8 @@ defmodule ClaperWeb.EventLive.Manage do %{"key" => "poll_visible", "value" => value}, %{assigns: %{state: state}} = socket ) do + IO.inspect(value) + {:ok, new_state} = Claper.Presentations.update_presentation_state( state, @@ -704,9 +684,12 @@ defmodule ClaperWeb.EventLive.Manage do poll = Polls.get_poll!(id) {:ok, _} = Polls.delete_poll(socket.assigns.event.uuid, poll) - {:noreply, - socket - |> assign(:polls, list_polls(socket, socket.assigns.event.presentation_file.id))} + {:noreply, socket} + end + + @impl true + def handle_event("toggle-preview", _params, %{assigns: %{preview: preview}} = socket) do + {:noreply, socket |> assign(:preview, !preview)} end @impl true @@ -795,75 +778,12 @@ defmodule ClaperWeb.EventLive.Manage do |> assign(:embed, embed) end - defp poll_at_position( - %{assigns: %{event: event, state: state}} = socket, - broadcast \\ true - ) do - with poll <- - Claper.Polls.get_poll_current_position( - event.presentation_file.id, - state.position - ) do - if broadcast do - Phoenix.PubSub.broadcast( - Claper.PubSub, - "event:#{event.uuid}", - {:current_poll, poll} - ) - end - - socket |> assign(:current_poll, poll) - end - end - - defp form_at_position( - %{assigns: %{event: event, state: state}} = socket, - broadcast \\ true - ) do - with form <- - Claper.Forms.get_form_current_position( - event.presentation_file.id, - state.position - ) do - if broadcast do - Phoenix.PubSub.broadcast( - Claper.PubSub, - "event:#{event.uuid}", - {:current_form, form} - ) - end - - socket |> assign(:current_form, form) - end - end - defp pin(post, socket) do {:ok, _updated_post} = Claper.Posts.toggle_pin_post(post) {:noreply, socket} end - defp embed_at_position( - %{assigns: %{event: event, state: state}} = socket, - broadcast \\ true - ) do - with embed <- - Claper.Embeds.get_embed_current_position( - event.presentation_file.id, - state.position - ) do - if broadcast do - Phoenix.PubSub.broadcast( - Claper.PubSub, - "event:#{event.uuid}", - {:current_embed, embed} - ) - end - - socket |> assign(:current_embed, embed) - end - end - defp ban(user, %{assigns: %{event: event, state: state}} = socket) do {:ok, new_state} = Claper.Presentations.update_presentation_state(state, %{ @@ -879,6 +799,18 @@ defmodule ClaperWeb.EventLive.Manage do {:noreply, socket |> assign(:state, new_state)} end + defp interactions_at_position( + %{assigns: %{event: event}} = socket, + position, + broadcast \\ false + ) do + with {:ok, interactions} <- + Claper.Interactions.get_interactions_at_position(event, position, broadcast) do + active = interactions |> Enum.find(& &1.enabled) + socket |> assign(:interactions, interactions) |> assign(:current_interaction, active) + end + end + defp list_pinned_posts(_socket, event_id) do Claper.Posts.list_pinned_posts(event_id, [:event, :reactions]) end @@ -891,18 +823,6 @@ defmodule ClaperWeb.EventLive.Manage do Claper.Posts.list_questions(event_id, [:event, :reactions], String.to_atom(sort)) end - defp list_polls(_socket, presentation_file_id) do - Claper.Polls.list_polls(presentation_file_id) - end - - defp list_forms(_socket, presentation_file_id) do - Claper.Forms.list_forms(presentation_file_id) - end - - defp list_embeds(_socket, presentation_file_id) do - Claper.Embeds.list_embeds(presentation_file_id) - end - defp list_form_submits(_socket, presentation_file_id) do Claper.Forms.list_form_submits(presentation_file_id, [:form]) end diff --git a/lib/claper_web/live/event_live/manage.html.heex b/lib/claper_web/live/event_live/manage.html.heex index c075427..cd26ac6 100644 --- a/lib/claper_web/live/event_live/manage.html.heex +++ b/lib/claper_web/live/event_live/manage.html.heex @@ -6,6 +6,29 @@ data-max-page={@event.presentation_file.length} data-current-page={@state.position} > +