{"version":3,"file":"application.ee58e010.js","sources":["../../../../_packs/controllers/base_controller.js","../../../../_packs/controllers/array_controller.js","../../../../_packs/controllers/floating_alert_controller.js","../../../../_packs/controllers/image_preview_controller.js","../../../../_packs/controllers/profile_controller.js","../../../../_packs/controllers/profiles_controller.js","../../../../_packs/controllers/remote_profile_controller.js","../../../../_packs/controllers/slutty_controller.js","../../../../_packs/entrypoints/application.js"],"sourcesContent":["import { Controller } from \"@suttyweb/stimulus\";\n\nexport class BaseController extends Controller {\n /*\n * Visita una página con soporte para Turbo\n *\n * @param [String] URL\n */\n visit(url) {\n try {\n if (url.startsWith(\"http\")) {\n throw \"External\";\n } else {\n Turbo.visit(url);\n }\n } catch {\n window.location = url;\n }\n }\n\n disableForm(formTarget, state) {\n if (!formTarget) return;\n\n formTarget.elements.forEach((x) => (x.disabled = state));\n }\n\n setCustomValidity (event) {\n event.target.setCustomValidity(event.params.customValidity);\n }\n\n unsetCustomValidity (event) {\n event.target.setCustomValidity(\"\");\n }\n\n dispatchToWindow(name, detail = {}) {\n window.dispatchEvent(new CustomEvent(name, { detail }));\n }\n\n localizeNumber(string) {\n return parseFloat(string).toLocaleString(this.locale);\n }\n\n get locale () {\n return document.querySelector(\"html\").lang;\n }\n\n applyTemplate(data, template = undefined) {\n if (!template) {\n console.log(\"default template\");\n template = this.templateTarget;\n }\n\n if (!template) {\n console.error(\"Can't find template\", data);\n return;\n }\n\n const elementContainer = template.content.cloneNode(true);\n\n for (const key in data) {\n const dasherizedKey = this.dasherize(key);\n const attribute = `data-${dasherizedKey}`;\n const attributeAttribute = `${attribute}-attribute`;\n const contentAttribute = `${attribute}-content`;\n const datasetAttribute = attribute;\n const classAttribute = `${attribute}-class`;\n\n const attributeSelector = `[${attributeAttribute}]`;\n const contentSelector = `[${contentAttribute}]`;\n const datasetSelector = `[${datasetAttribute}]`;\n const classSelector = `[${classAttribute}]`;\n\n for (const element of elementContainer.querySelectorAll(attributeSelector)) {\n element.setAttribute(element.dataset[`${key}Attribute`], data[key]);\n element.removeAttribute(attributeAttribute);\n }\n\n for (const element of elementContainer.querySelectorAll(contentSelector)) {\n element.textContent = data[key];\n element.removeAttribute(contentAttribute);\n }\n\n for (const element of elementContainer.querySelectorAll(datasetSelector)) {\n element.dataset[key] = data[key];\n }\n\n for (const element of elementContainer.querySelectorAll(classSelector)) {\n if (data[key]) element.classList.add(data[key]);\n element.removeAttribute(classAttribute);\n }\n }\n\n return elementContainer;\n }\n\n // this comes from Stimulus but isn't exported\n camelize(value) {\n return value.replace(/(?:[_-])([a-z0-9])/g, (_, char) => char.toUpperCase());\n }\n\n // this comes from Stimulus but isn't exported\n dasherize(value) {\n return value.replace(/([A-Z])/g, (_, char) => `-${char.toLowerCase()}`);\n }\n}\n","import { BaseController } from \"./base_controller\";\n\nexport default class extends BaseController {\n static targets = [\"value\", \"valueTemplate\", \"values\", \"datalist\", \"optionTemplate\"];\n static values = {\n name: String,\n values: Array,\n };\n\n connect() {\n if (!this.hasDatalistTarget || !this.hasOptionTemplateTarget) return;\n\n const storedValues = window.localStorage[this.nameValue];\n\n if (!storedValues) return;\n\n for (const value of JSON.parse(storedValues)) {\n const data = { value };\n this.datalistTarget.appendChild(this.applyTemplate(data, this.optionTemplateTarget));\n }\n }\n\n valuesValueChanged(valuesValue, oldValuesValue) {\n const valuesToRemove = oldValuesValue.filter(x => !valuesValue.includes(x));\n const valuesToAdd = valuesValue.filter(x => !oldValuesValue.includes(x));\n\n for (const valueToAdd of valuesToAdd) {\n this.add(valueToAdd);\n }\n }\n\n enter(event) {\n switch (event.keyCode) {\n case 13:\n case 32:\n break;\n default:\n return\n }\n\n this.input();\n }\n\n add(value) {\n const data = {\n name: `${this.nameValue}[]`,\n value,\n id: `${this.nameValue}_${value}`,\n };\n\n const inputTarget = this.applyTemplate(data, this.valueTemplateTarget);\n\n this.valuesTarget.appendChild(inputTarget);\n }\n\n input(event) {\n event?.preventDefault();\n const value = this.valueTarget.value.trim();\n\n if (!value) return;\n if (this.valuesValue.includes(value)) return;\n\n this.valuesValue = [...this.valuesValue, value];\n this.valueTarget.value = \"\";\n }\n}\n","import { Controller } from \"@suttyweb/stimulus\";\n\n// Ejemplo de uso:\n// window.dispatchEvent(\n// new CustomEvent(\"floatingAlert\", { detail: { content: \"¡Hola, usuarix!\" } })\n// );\nexport default class extends Controller {\n static targets = [\"content\"];\n\n show({ detail: { content } }) {\n this.contentTarget.innerText = content;\n this.set(true);\n\n if (this.interval) clearTimeout(this.interval);\n\n this.interval = setTimeout(() => {\n this.set(false);\n this.interval = null;\n }, 3000);\n }\n\n set(show) {\n if (show) {\n this.element.classList.remove(\"hide\");\n this.element.classList.add(\"show\");\n } else {\n this.element.classList.add(\"hide\");\n this.element.classList.remove(\"show\");\n }\n }\n}\n","import { Controller } from \"@suttyweb/stimulus\";\n\nexport default class extends Controller {\n static targets = [\"image\", \"input\"];\n static values = {\n data: String,\n };\n\n dataValueChanged(dataValue) {\n if (!dataValue) return;\n\n this.imageTarget.src = dataValue;\n }\n\n preview(event) {\n this.imageTarget.src = window.URL.createObjectURL(this.inputTarget.files[0]);\n }\n}\n","import { BaseController } from \"./base_controller\";\n\nexport default class extends BaseController {\n static targets = [\"form\"];\n static values = {\n floatingAlert: {\n type: String,\n default: \"Saved!\",\n },\n };\n\n connect() {\n this.storedProfile = window.localStorage.sluttyProfile;\n\n if (!this.storedProfile) return;\n\n this.sluttyProfile = JSON.parse(this.storedProfile);\n\n for (const field in this.sluttyProfile) {\n if (field == \"version\") continue;\n if (field == \"peerId\") continue;\n\n const inputGroup = this.formTarget.querySelector(`[data-name=\"${field}\"]`);\n\n if (!inputGroup) {\n console.error(\"Field missing\", field);\n continue;\n }\n\n let value = this.sluttyProfile[field];\n\n switch (inputGroup.dataset.type) {\n case \"array\":\n inputGroup.dataset.arrayValuesValue = JSON.stringify(value);\n break;\n case \"image\":\n inputGroup.dataset.imagePreviewDataValue = value;\n break;\n default:\n const input = inputGroup.querySelector(\"input,textarea\");\n if (!input) continue;\n\n input.value = value;\n }\n }\n }\n\n async save(event) {\n event?.preventDefault();\n\n const formData = new FormData(event.target);\n const arrayEntries = {};\n const sluttyProfile = {\n version: `${(new Date).getTime()}`,\n peerId: window.localStorage.peerId,\n };\n\n for (const entry of formData.entries()) {\n let key = entry[0];\n let value = entry[1];\n\n if (key.endsWith(\"[]\")) {\n key = key.slice(0, key.length - 2);\n\n if (!arrayEntries[key]) arrayEntries[key] = [];\n\n arrayEntries[key].push(value);\n continue;\n }\n\n switch (value.constructor.name) {\n case \"File\":\n const inputGroup = this.formTarget.querySelector(`[data-name=\"${key}\"]`);\n const file = inputGroup.querySelector(`input[type=\"file\"]`).files[0];\n\n if (file) {\n value = await this.toBase64(file);\n } else {\n value = inputGroup.dataset.imagePreviewDataValue;\n }\n default:\n sluttyProfile[key] = value;\n }\n }\n\n this.sluttyProfile = {...this.sluttyProfile, ...sluttyProfile, ...arrayEntries};\n\n window.localStorage.sluttyProfile = JSON.stringify(this.sluttyProfile);\n\n const content = this.floatingAlertValue;\n\n this.dispatchToWindow(\"floatingAlert\", { content });\n }\n\n toBase64(file) {\n return new Promise((resolve, reject) => {\n const fileReader = new FileReader();\n\n fileReader.onload = () => resolve(fileReader.result);\n fileReader.onerror = (error) => reject(error);\n\n fileReader.readAsDataURL(file);\n });\n }\n}\n","import { BaseController } from \"./base_controller\";\nimport JaroWinkler from \"jaro-winkler\";\n\nexport default class extends BaseController {\n static targets = [\"profiles\", \"profile\", \"profileTemplate\"];\n static values = {\n remoteProfileUrl: String,\n };\n\n connect() {\n this.profiles = {};\n this.sluttyProfile = JSON.parse(window.localStorage.sluttyProfile || \"{}\");\n }\n\n newProfile({ detail: profile }) {\n const peerId = profile.peerId;\n const previousProfile = this.profiles[peerId];\n\n if (!this.matches(profile)) {\n if (previousProfile) previousProfile.remove();\n window.localStorage.removeItem(peerId);\n\n return;\n }\n\n if (previousProfile) {\n if (previousProfile.dataset.version == profile.version) return;\n\n previousProfile.remove();\n }\n\n profile.remoteProfile = `${this.remoteProfileUrlValue}#${peerId}`;\n\n window.localStorage[peerId] = JSON.stringify(profile);\n\n const profileTarget = this.applyTemplate(profile, this.profileTemplateTarget);\n\n this.profilesTarget.appendChild(profileTarget);\n this.profiles[peerId] = this.profilesTarget.lastElementChild;\n }\n\n matches(profile) {\n const theyAreNotAMatchForMe = profile.include.some(x => this.includesSimilar(x, this.sluttyProfile.exclude));\n const iAmNotAMatchForThem = this.sluttyProfile.include.some(x => this.includesSimilar(x, profile.exclude));\n\n return !theyAreNotAMatchForMe && !iAmNotAMatchForThem;\n }\n\n includesSimilar(needle, stack, similarity = 0.9) {\n return stack.includes(needle) || stack.some(x => JaroWinkler(needle, x) > similarity);\n }\n}\n","import { BaseController } from \"./base_controller\";\nimport JaroWinkler from \"jaro-winkler\";\n\nexport default class extends BaseController {\n static targets = [\"image\", \"name\", \"bio\", \"age\", \"common\", \"tag\", \"pronouns\"];\n static values = {\n peerId: String,\n image: String,\n name: String,\n bio: String,\n age: Number,\n common: Array,\n pronouns: Array,\n };\n\n connect() {\n if (!window.location.hash) return;\n\n this.peerIdValue = window.location.hash.slice(1);\n this.sluttyProfile = JSON.parse(window.localStorage.sluttyProfile || \"{}\");\n }\n\n peerIdValueChanged(peerIdValue, oldPeerIdValue) {\n if (!peerIdValue) return;\n if (peerIdValue === oldPeerIdValue) return;\n\n const remoteProfile = window.localStorage[peerIdValue];\n\n if (!remoteProfile) return;\n\n this.remoteProfile = JSON.parse(remoteProfile);\n this.remoteProfile.common = this.remoteProfile.include.filter(x => {\n return this.sluttyProfile.include.includes(x) || this.sluttyProfile.include.some(y => JaroWinkler(x, y) > 0.9);\n });\n const keys = Object.keys(this.constructor.values);\n\n for (const field in this.remoteProfile) {\n if (!keys.includes(field)) continue;\n\n this[`${field}Value`] = this.remoteProfile[field];\n }\n }\n\n imageValueChanged(imageValue) {\n for (const imageTarget of this.imageTargets) {\n imageTarget.src = imageValue;\n }\n }\n\n nameValueChanged(nameValue) {\n for (const nameTarget of this.nameTargets) {\n nameTarget.innerText = nameValue;\n }\n }\n\n bioValueChanged(bioValue) {\n for (const bioTarget of this.bioTargets) {\n bioTarget.innerText = bioValue;\n }\n }\n\n ageValueChanged(ageValue) {\n for (const ageTarget of this.ageTargets) {\n ageTarget.innerText = ageValue;\n }\n }\n\n pronounsValueChanged(pronounsValue) {\n pronounsValue = pronounsValue.join(\"/\");\n\n for (const pronounsTarget of this.pronounsTargets) {\n pronounsTarget.innerText = pronounsValue;\n }\n }\n\n commonValueChanged(commonValue, oldCommonValue = []) {\n const valuesToRemove = oldCommonValue.filter(x => !commonValue.includes(x));\n const valuesToAdd = commonValue.filter(x => !oldCommonValue.includes(x));\n\n for (const commonTarget of this.commonTargets) {\n for (const value of valuesToAdd) {\n commonTarget.appendChild(this.applyTemplate({ value }, this.tagTarget));\n }\n\n for (const value of valuesToRemove) {\n commonTarget.querySelector(`[data-tag=\"${value}\"]`)?.remove();\n }\n }\n }\n}\n","import { BaseController } from \"./base_controller\";\nimport { createLibp2p } from \"libp2p\";\nimport { WebSockets } from \"@libp2p/websockets\";\nimport { WebRTCStar } from \"@libp2p/webrtc-star\";\nimport { Noise } from \"@chainsafe/libp2p-noise\";\nimport { Mplex } from \"@libp2p/mplex\";\nimport { GossipSub } from \"@chainsafe/libp2p-gossipsub\";\nimport { fromString } from \"uint8arrays/from-string\";\nimport { toString } from \"uint8arrays/to-string\";\nimport { peerIdFromKeys } from \"@libp2p/peer-id\";\n\nexport default class extends BaseController {\n static targets = [\"peers\", \"log\", \"discoveredPeers\"];\n static values = {\n topic: {\n type: String,\n default: \"slutty\",\n },\n peers: {\n type: Number,\n default: 0,\n },\n discoveredPeers: {\n type: Number,\n default: 0,\n },\n rendezVous: {\n type: Array,\n default: [\n \"/dns4/slutty.sutty.local/tcp/4000/wss/p2p-webrtc-star\",\n ],\n },\n pronouns: Array,\n tags: Array,\n };\n\n pronounsValueChanged(pronounsValue) {\n if (pronounsValue.length === 0) return;\n\n window.localStorage.pronouns = JSON.stringify(pronounsValue);\n }\n\n tagsValueChanged(tagsValue) {\n if (tagsValue.length === 0) return;\n\n window.localStorage.include = JSON.stringify(tagsValue);\n window.localStorage.exclude = JSON.stringify(tagsValue);\n }\n\n peersValueChanged(peersValue, oldPeersValue) {\n for (const peersTarget of this.peersTargets) {\n peersTarget.innerText = peersValue;\n }\n }\n\n discoveredPeersValueChanged(discoveredPeersValue, oldPeersValue) {\n for (const peersTarget of this.discoveredPeersTargets) {\n peersTarget.innerText = discoveredPeersValue;\n }\n }\n\n get webRTCStar() {\n if (!this._webRTCStar) this._webRTCStar = new WebRTCStar();\n\n return this._webRTCStar;\n }\n\n async configure() {\n let peerId;\n const privateKey = window.localStorage.privateKey;\n const publicKey = window.localStorage.publicKey;\n if (privateKey && publicKey) {\n this.appendToLog(\"Recovering peerId\");\n peerId = await peerIdFromKeys(\n new Uint8Array(JSON.parse(publicKey)),\n new Uint8Array(JSON.parse(privateKey))\n );\n }\n\n this.libp2p = await createLibp2p({\n peerId,\n addresses: {\n listen: this.rendezVousValue,\n },\n transports: [\n new WebSockets(),\n this.webRTCStar,\n ],\n connectionEncryption: [\n new Noise(),\n ],\n streamMuxers: [\n new Mplex(),\n ],\n peerDiscovery: [\n this.webRTCStar.discovery,\n ],\n pubsub: new GossipSub(),\n });\n\n window.libp2p = this.libp2p;\n window.localStorage.privateKey = JSON.stringify(Array.from(this.libp2p.peerId.privateKey));\n window.localStorage.publicKey = JSON.stringify(Array.from(this.libp2p.peerId.publicKey));\n\n return this.libp2p;\n }\n\n async connect() {\n await this.configure();\n\n this.peerIds = new Set();\n this.discoveredPeerIds = new Set();\n\n this.peerDiscovery = this.peerDiscovery.bind(this);\n this.peerConnect = this.peerConnect.bind(this);\n this.peerDisconnect = this.peerDisconnect.bind(this);\n this.messageReception = this.messageReception.bind(this);\n\n this.libp2p.addEventListener(\"peer:discovery\", this.peerDiscovery);\n this.libp2p.connectionManager.addEventListener(\"peer:connect\", this.peerConnect);\n this.libp2p.connectionManager.addEventListener(\"peer:disconnect\", this.peerDisconnect);\n\n await this.libp2p.start();\n\n this.peerId = this.libp2p.peerId.toString();\n\n window.localStorage.peerId = this.peerId;\n\n this.appendToLog(`Connected as ${this.peerId}`);\n\n await this.libp2p.pubsub.subscribe(this.topicValue);\n this.libp2p.pubsub.addEventListener(\"message\", this.messageReception);\n this.appendToLog(`Subscribed to ${this.topicValue}`);\n\n setInterval(async () => {\n const profile = window.localStorage.sluttyProfile;\n\n if (!profile) return;\n\n const parsedProfile = JSON.parse(profile);\n parsedProfile.peerId = this.peerId;\n\n this.appendToLog(\"Distributing our profile...\");\n\n try {\n await this.libp2p.pubsub.publish(this.topicValue, fromString(JSON.stringify(parsedProfile)));\n } catch(e) {\n console.log(e);\n }\n }, 5000);\n }\n\n async peerDiscovery(event) {\n const peer = event.detail;\n const peerId = peer.id.toString();\n\n this.appendToLog(`Peer discovered: ${peerId}`);\n\n if (![...this.discoveredPeerIds].includes(peerId)) {\n this.discoveredPeersValue = this.discoveredPeersValue + 1;\n this.discoveredPeerIds.add(peerId);\n }\n\n this.libp2p.peerStore.addressBook.set(peer.id, peer.multiaddrs);\n\n try {\n await this.libp2p.dial(peer.id);\n } catch(e) {\n this.appendToLog(`Couldn't connect to: ${peerId}`);\n }\n }\n\n peerConnect(event) {\n const connection = event.detail;\n const peer = connection.remotePeer;\n const peerId = peer.string;\n\n this.peersValue = this.peersValue + 1;\n this.appendToLog(`Peer joined: ${peerId}`);\n }\n\n peerDisconnect(event) {\n const connection = event.detail;\n const peer = connection.remotePeer;\n const peerId = peer.string;\n\n this.discoveredPeersValue = this.discoveredPeersValue - 1;\n this.discoveredPeerIds.delete(peerId);\n\n this.peersValue = this.peersValue - 1;\n this.appendToLog(`Peer left: ${peerId}`);\n }\n\n appendToLog(message) {\n console.log(message);\n }\n\n messageReception(event) {\n const peer = event.detail.from;\n const peerId = peer.toString();\n const message = JSON.parse(toString(event.detail.data));\n\n if (message.peerId !== peerId) return;\n\n const profile = message;\n\n let tags = [];\n\n if (profile.exclude) tags = [...tags, ...profile.exclude];\n if (profile.include) tags = [...tags, ...profile.include];\n\n this.tagsValue = this.unique(tags);\n\n if (profile.pronouns) this.pronounsValue = this.unique([...this.pronounsValue, ...profile.pronouns]);\n\n this.dispatchToWindow(\"profile\", profile);\n }\n\n unique(array) {\n return array.filter((x, i, a) => a.indexOf(x) === i);\n }\n}\n","// Example: Import a stylesheet in /index.css\n// import '~/index.css'\nimport \"regenerator-runtime/runtime\";\n\n// Turbo acelera la navegación al no tener que recargar todo el JS y CSS\n// de la página, con lo que se siente más rápida y \"nativa\".\n//\n// Cambiamos de turbolinks a turbo porque turbo soporta la función\n// fetch(), que luego es interceptada por el SW para obtener las\n// direcciones localmente.\nimport * as Turbo from \"@hotwired/turbo\";\nTurbo.start();\n\nimport { Application } from \"@suttyweb/stimulus\";\nimport { registerControllers } from \"stimulus-vite-helpers\";\n\nconst application = Application.start();\nconst controllers = import.meta.globEager(\"../controllers/*_controller.js\");\nregisterControllers(application, controllers);\n"],"names":["BaseController","Controller","url","formTarget","state","x","event","name","detail","string","data","template","elementContainer","key","attribute","attributeAttribute","contentAttribute","datasetAttribute","classAttribute","attributeSelector","contentSelector","datasetSelector","classSelector","element","value","_","char","array_controller","storedValues","valuesValue","oldValuesValue","valuesToAdd","valueToAdd","inputTarget","__publicField","floating_alert_controller","content","show","image_preview_controller","dataValue","profile_controller","field","inputGroup","input","formData","arrayEntries","sluttyProfile","entry","file","resolve","reject","fileReader","error","profiles_controller","profile","peerId","previousProfile","profileTarget","theyAreNotAMatchForMe","iAmNotAMatchForThem","needle","stack","similarity","JaroWinkler","remote_profile_controller","peerIdValue","oldPeerIdValue","remoteProfile","y","keys","imageValue","imageTarget","nameValue","nameTarget","bioValue","bioTarget","ageValue","ageTarget","pronounsValue","pronounsTarget","commonValue","oldCommonValue","valuesToRemove","commonTarget","slutty_controller","tagsValue","peersValue","oldPeersValue","peersTarget","discoveredPeersValue","WebRTCStar","privateKey","publicKey","peerIdFromKeys","createLibp2p","WebSockets","Noise","Mplex","GossipSub","parsedProfile","fromString","e","peer","message","toString","tags","array","i","a","Turbo.start","application","Application","controllers","registerControllers"],"mappings":"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"}