Moved all entries to db

This commit is contained in:
a-ill 2023-07-28 17:49:29 +03:00
parent f8f1b28ea9
commit cc00b78711
112 changed files with 3887 additions and 895 deletions

View File

@ -10,12 +10,6 @@ dict_layouts = Dict(
:landing => generate_layout_html("main",controller,"landing",css=["landing"],libraries=["Leaflet"]), :landing => generate_layout_html("main",controller,"landing",css=["landing"],libraries=["Leaflet"]),
:manifesto => generate_layout_html("main",controller,"manifesto"), :manifesto => generate_layout_html("main",controller,"manifesto"),
:join_us => generate_layout_html("main",controller,"join_us",libraries=["Leaflet"]), :join_us => generate_layout_html("main",controller,"join_us",libraries=["Leaflet"]),
:groups => generate_layout_html("main",controller,"groups",libraries=["Leaflet"]),
:groups_add => generate_layout_html("main",controller,"groups_add",libraries=["Leaflet"]),
:cooperatives => generate_layout_html("main",controller,"cooperatives",libraries=["Leaflet"]),
:communes => generate_layout_html("main",controller,"communes",libraries=["Leaflet"]),
:parties => generate_layout_html("main",controller,"parties",libraries=["Leaflet"]),
:partners => generate_layout_html("main",controller,"partners",libraries=["Leaflet"]),
:compass => generate_layout_html("main",controller,"compass"), :compass => generate_layout_html("main",controller,"compass"),
) )
@ -54,61 +48,6 @@ const join_us_info = Dict(
), ),
) )
const groups_info = Dict(
"en" => Dict(
:title => "LibSoc - Groups",
:description => ""
),
"ru" => Dict(
:title => "LibSoc - Группы",
:description => ""
)
)
const cooperatives_info = Dict(
"en" => Dict(
:title => "LibSoc - Cooperatives",
:description => ""
),
"ru" => Dict(
:title => "LibSoc - Кооперативы",
:description => ""
)
)
const communes_info = Dict(
"en" => Dict(
:title => "LibSoc - Communes",
:description => ""
),
"ru" => Dict(
:title => "LibSoc - Коммуны",
:description => ""
)
)
const partners_info = Dict(
"en" => Dict(
:title => "LibSoc - Partners",
:description => ""
),
"ru" => Dict(
:title => "LibSoc - Партнеры",
:description => ""
)
)
const parties_info = Dict(
"en" => Dict(
:title => "LibSoc - Parties",
:description => ""
),
"ru" => Dict(
:title => "LibSoc - Партии",
:description => ""
)
)
const compass_info = Dict( const compass_info = Dict(
"en" => Dict( "en" => Dict(
:title => "LibSoc - Political Compass", :title => "LibSoc - Political Compass",
@ -147,62 +86,6 @@ function manifesto()
) )
end end
function join_us()
locale = get_locale()
html(:basic,:join_us, layout = dict_layouts[:join_us], context = @__MODULE__,
title = join_us_info[locale][:title],
description = join_us_info[locale][:description]
)
end
function groups()
locale = get_locale()
html(:basic,:groups, layout = dict_layouts[:groups], context = @__MODULE__,
title = groups_info[locale][:title],
description = groups_info[locale][:description]
)
end
function groups_add()
locale = get_locale()
html(:basic,:groups_add, layout = dict_layouts[:groups_add], context = @__MODULE__,
title = groups_info[locale][:title],
description = groups_info[locale][:description]
)
end
function cooperatives()
locale = get_locale()
html(:basic,:cooperatives, layout = dict_layouts[:cooperatives], context = @__MODULE__,
title = cooperatives_info[locale][:title],
description = cooperatives_info[locale][:description]
)
end
function communes()
locale = get_locale()
html(:basic,:communes, layout = dict_layouts[:communes], context = @__MODULE__,
title = communes_info[locale][:title],
description = communes_info[locale][:description]
)
end
function partners()
locale = get_locale()
html(:basic,:partners, layout = dict_layouts[:partners], context = @__MODULE__,
title = partners_info[locale][:title],
description = partners_info[locale][:description]
)
end
function parties()
locale = get_locale()
html(:basic,:parties, layout = dict_layouts[:parties], context = @__MODULE__,
title = parties_info[locale][:title],
description = parties_info[locale][:description]
)
end
function political_compass() function political_compass()
locale = get_locale() locale = get_locale()
html(:basic,:compass, layout = dict_layouts[:compass], context = @__MODULE__, html(:basic,:compass, layout = dict_layouts[:compass], context = @__MODULE__,
@ -211,9 +94,12 @@ function political_compass()
) )
end end
function groups_add_post() function join_us()
data = jsonpayload() locale = get_locale()
insert_into_table("groups_requests",data) html(:basic,:join_us, layout = dict_layouts[:join_us], context = @__MODULE__,
title = join_us_info[locale][:title],
description = join_us_info[locale][:description]
)
end end
end end

View File

@ -0,0 +1,59 @@
module CommunesController
using Genie, Genie.Renderer, Genie.Renderer.Html, Genie.Requests
using JSON3
using SearchLight
using Server.DatabaseSupport, Server.TemplateEditor
controller = "communes"
dict_layouts = Dict(
:communes => generate_layout_html("main",controller,"communes",libraries=["Leaflet"]),
:communes_add => generate_layout_html("main",controller,"communes_add",libraries=["Leaflet"]),
)
#---Page info-----------------------------------------------------
const communes_info = Dict(
"en" => Dict(
:title => "LibSoc - Communes",
:description => ""
),
"ru" => Dict(
:title => "LibSoc - Коммуны",
:description => ""
)
)
function get_locale()
data = payload()
if :locale in keys(data)
return data[:locale]
else
return "en"
end
end
#---Functions---------------------------------------------------------
function communes()
locale = get_locale()
html(:communes,:communes, layout = dict_layouts[:communes], context = @__MODULE__,
title = communes_info[locale][:title],
description = communes_info[locale][:description]
)
end
function communes_add()
locale = get_locale()
html(:communes,:communes_add, layout = dict_layouts[:communes_add], context = @__MODULE__,
title = communes_info[locale][:title],
description = communes_info[locale][:description]
)
end
function communes_add_post()
data = jsonpayload()
insert_into_table("communes_requests",data)
end
end

View File

@ -0,0 +1 @@
<communes-add-component></communes-add-component>

View File

@ -0,0 +1,60 @@
module CooperativesController
using Genie, Genie.Renderer, Genie.Renderer.Html, Genie.Requests
using JSON3
using SearchLight
using Server.DatabaseSupport, Server.TemplateEditor
controller = "cooperatives"
dict_layouts = Dict(
:cooperatives => generate_layout_html("main",controller,"cooperatives",libraries=["Leaflet"]),
:cooperatives_add => generate_layout_html("main",controller,"cooperatives_add",libraries=["Leaflet"]),
)
#---Page info-----------------------------------------------------
const cooperatives_info = Dict(
"en" => Dict(
:title => "LibSoc - Cooperatives",
:description => ""
),
"ru" => Dict(
:title => "LibSoc - Кооперативы",
:description => ""
)
)
function get_locale()
data = payload()
if :locale in keys(data)
return data[:locale]
else
return "en"
end
end
#---Functions---------------------------------------------------------
function cooperatives_add()
locale = get_locale()
html(:cooperatives,:cooperatives_add, layout = dict_layouts[:cooperatives_add], context = @__MODULE__,
title = cooperatives_info[locale][:title],
description = cooperatives_info[locale][:description]
)
end
function cooperatives()
locale = get_locale()
html(:cooperatives,:cooperatives, layout = dict_layouts[:cooperatives], context = @__MODULE__,
title = cooperatives_info[locale][:title],
description = cooperatives_info[locale][:description]
)
end
function cooperatives_add_post()
data = jsonpayload()
insert_into_table("cooperatives_requests",data)
end
end

View File

@ -0,0 +1 @@
<cooperatives-add-component></cooperatives-add-component>

View File

@ -0,0 +1,59 @@
module GroupsController
using Genie, Genie.Renderer, Genie.Renderer.Html, Genie.Requests
using JSON3
using SearchLight
using Server.DatabaseSupport, Server.TemplateEditor
controller = "groups"
dict_layouts = Dict(
:groups => generate_layout_html("main",controller,"groups",libraries=["Leaflet"]),
:groups_add => generate_layout_html("main",controller,"groups_add",libraries=["Leaflet"]),
)
#---Page info-----------------------------------------------------
const groups_info = Dict(
"en" => Dict(
:title => "LibSoc - Groups",
:description => ""
),
"ru" => Dict(
:title => "LibSoc - Группы",
:description => ""
)
)
function get_locale()
data = payload()
if :locale in keys(data)
return data[:locale]
else
return "en"
end
end
#---Functions---------------------------------------------------------
function groups()
locale = get_locale()
html(:groups,:groups, layout = dict_layouts[:groups], context = @__MODULE__,
title = groups_info[locale][:title],
description = groups_info[locale][:description]
)
end
function groups_add()
locale = get_locale()
html(:groups,:groups_add, layout = dict_layouts[:groups_add], context = @__MODULE__,
title = groups_info[locale][:title],
description = groups_info[locale][:description]
)
end
function groups_add_post()
data = jsonpayload()
insert_into_table("groups_requests",data)
end
end

View File

@ -0,0 +1,60 @@
module PartiesController
using Genie, Genie.Renderer, Genie.Renderer.Html, Genie.Requests
using JSON3
using SearchLight
using Server.DatabaseSupport, Server.TemplateEditor
controller = "parties"
dict_layouts = Dict(
:parties_add => generate_layout_html("main",controller,"parties_add",libraries=["Leaflet"]),
:parties => generate_layout_html("main",controller,"parties",libraries=["Leaflet"]),
)
#---Page info-----------------------------------------------------
const parties_info = Dict(
"en" => Dict(
:title => "LibSoc - Parties",
:description => ""
),
"ru" => Dict(
:title => "LibSoc - Партии",
:description => ""
)
)
function get_locale()
data = payload()
if :locale in keys(data)
return data[:locale]
else
return "en"
end
end
#---Functions---------------------------------------------------------
function parties()
locale = get_locale()
html(:parties,:parties, layout = dict_layouts[:parties], context = @__MODULE__,
title = parties_info[locale][:title],
description = parties_info[locale][:description]
)
end
function parties_add()
locale = get_locale()
html(:parties,:parties_add, layout = dict_layouts[:parties_add], context = @__MODULE__,
title = parties_info[locale][:title],
description = parties_info[locale][:description]
)
end
function parties_add_post()
data = jsonpayload()
insert_into_table("parties_requests",data)
end
end

View File

@ -0,0 +1 @@
<parties-add-component></parties-add-component>

View File

@ -0,0 +1,59 @@
module PartnersController
using Genie, Genie.Renderer, Genie.Renderer.Html, Genie.Requests
using JSON3
using SearchLight
using Server.DatabaseSupport, Server.TemplateEditor
controller = "partners"
dict_layouts = Dict(
:partners => generate_layout_html("main",controller,"partners",libraries=["Leaflet"]),
:partners_add => generate_layout_html("main",controller,"partners_add",libraries=["Leaflet"]),
)
#---Page info-----------------------------------------------------
const partners_info = Dict(
"en" => Dict(
:title => "LibSoc - Partners",
:description => ""
),
"ru" => Dict(
:title => "LibSoc - Партнеры",
:description => ""
)
)
function get_locale()
data = payload()
if :locale in keys(data)
return data[:locale]
else
return "en"
end
end
#---Functions---------------------------------------------------------
function partners()
locale = get_locale()
html(:partners,:partners, layout = dict_layouts[:partners], context = @__MODULE__,
title = partners_info[locale][:title],
description = partners_info[locale][:description]
)
end
function partners_add()
locale = get_locale()
html(:partners,:partners_add, layout = dict_layouts[:partners_add], context = @__MODULE__,
title = partners_info[locale][:title],
description = partners_info[locale][:description]
)
end
function partners_add_post()
data = jsonpayload()
insert_into_table("partners_requests",data)
end
end

View File

@ -0,0 +1 @@
<partners-add-component></partners-add-component>

View File

@ -1,99 +0,0 @@
export let communes = [
{
location: [["Canada","Montreal"],[45.55541047232767, -73.42859611607271]],
status: "forming",
members: 2,
contact: ["https://discord.gg/Qk8KUk787z","DiscordInviteLink"]
},
{
location: [["Denmark"],[55.915625218626275, 9.673445220831253]],
status: "forming",
members: 1,
contact: ["https://discord.gg/Qk8KUk787z","DiscordInviteLink"]
},
{
location: [["Estonia","Kohtla-Jarve"],[59.409521829709504, 27.288415912535914]],
status: "forming",
members: 2,
contact: ["https://discord.gg/Qk8KUk787z","DiscordInviteLink"]
},
{
location: [["Latvia"],[56.934159375258055, 25.269099001330265]],
status: "forming",
members: 1,
contact: ["https://discord.gg/Qk8KUk787z","DiscordInviteLink"]
},
{
location: [["Switzerland"],[46.97045202584917, 8.05130091516525]],
status: "forming",
members: 1,
contact: ["https://discord.gg/Qk8KUk787z","DiscordInviteLink"]
}
]
export let communesByCountry = {}
for (let c of communes) {
let country = c.location[0][0]
if (country in communesByCountry) {
communesByCountry[country].push(c)
}
else {
communesByCountry[country] = [c]
}
}
export let communesMarkersLayer = L.layerGroup()
export function translate(content, x) {
let out = content[x]
if (out==undefined) {
return x
}
else {
return out
}
}
export function addMarkersCommunes(map,content,locale) {
for (let g of communes) {
let coordinates
let text = "<b>"+content["Commune"]+"</b><br>"
for (let field in g) {
let fieldText = content[field] + ": "
if (field=="contact") {
text += fieldText + "<a href='" + g.contact[0] + "' target='_blank' rel=noreferrer>" + content[g.contact[1]]+ "</a>"
}
else if (field=="location") {
let location = g[field][0]
let locationString
if (locale=="en") {
locationString = location.map(x => x).join(", ")
}
else {
locationString = location.map(x => translate(content, x)).join(", ")
}
text += fieldText + locationString + "<br>"
coordinates = g[field][1]
}
else if (field=="status") {
text += fieldText + content[g[field]] + "<br>"
}
else {
text += fieldText + g[field] + "<br>"
}
}
var markerIcon = new L.Icon({
iconUrl: 'https://www.libsoc.org/img/common/markers/marker-red.png',
shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/images/marker-shadow.png',
iconSize: [25, 41],
iconAnchor: [12, 41],
popupAnchor: [1, -34],
shadowSize: [41, 41]
});
let marker = L.marker(coordinates, {icon: markerIcon})
marker.addTo(communesMarkersLayer).bindPopup(text)
}
communesMarkersLayer.addTo(map)
}

View File

@ -1,79 +0,0 @@
export let coops = [
{
logo: "chiron_logo",
name: "Chiron Health",
location: [["Estonia","Kohtla-Järve"],[59.41038769769602, 27.287802936242034]],
market: "wellnessAndHealth",
workers: 2,
status: "inDevelopment",
website: ["https://www.chrn.health/", "chrn.health"],
contact: ["https://discord.gg/Qk8KUk787z","DiscordInviteLink"],
description: "descriptionChironHealth"
},
{
logo: "kuusk_logo",
name: "Kuusk",
location: [["Estonia","Kohtla-Järve"],[59.399947051803004, 27.277159931677055]],
market: "herbalTeas",
workers: 1,
status: "inDevelopment",
website: ["-","-"],
contact: ["https://discord.gg/Qk8KUk787z","DiscordInviteLink"],
description: "kuuskDescription"
}
]
export let coopsByCountry = {}
for (let g of coops) {
let country = g.location[0][0]
if (country in coopsByCountry) {
coopsByCountry[country].push(g)
}
else {
coopsByCountry[country] = [g]
}
}
export let coopsMarkersLayer = L.layerGroup()
export function addMarkersCoops(map,content,locale) {
for (let g of coops) {
let coordinates
let text = "<b>"+content["Cooperative"]+"</b><br>"
for (let field in g) {
let fieldText
if (field!="logo") {
fieldText = content[field] + ": "
}
if (field=="logo") {
text += "<picture><source srcset=" + "/img/coops/" + g.logo + ".webp><source srcset='/img/coops/" + g.logo + ".png'><img alt='logo' style='position: relative; max-height: 5rem; max-width: 100%; margin: auto;'></picture>" + "<br>"
}
else if (field=="contact") {
text += fieldText + "<a href='https://www." + g.contact[0] + "' target='_blank' rel=noreferrer>" + content[g.contact[1]] + "</a>" + "<br>"
}
else if (field=="website") {
text += fieldText + "<a href='" + g.website[0] + "' target='_blank' rel=noreferrer>" + g.website[1] + "</a>" + "<br>"
}
else if (field=="location") {
let location = g[field][0]
let locationString
if (locale=="en") {
locationString = location.map(x => x).join(", ")
}
else {
locationString = location.map(x => content[x]).join(", ")
}
text += fieldText + locationString + "<br>"
coordinates = g[field][1]
}
else if (field=="market" || field=="status" || field=="description") {
text += fieldText + content[g[field]] + "<br>"
}
else {
text += fieldText + g[field] + "<br>"
}
}
L.marker(coordinates).addTo(coopsMarkersLayer).bindPopup(text)
}
coopsMarkersLayer.addTo(map)
}

View File

@ -1,198 +0,0 @@
/*
export let groups = [
{
location: [["Bulgaria","Varna"],[43.21582161671174, 27.89896092161012]],
members: 1,
contact: ["https://discord.gg/Qk8KUk787z","DiscordInviteLink"]
},
{
location: [["Canada","Halifax"],[44.65166135030067, -63.59289968306866]],
members: 2,
contact: ["https://discord.gg/Qk8KUk787z","DiscordInviteLink"]
},
{
location: [["Canada","Toronto"], [43.6960589794647, -79.37396957644577]],
members: 1,
contact: ["https://discord.gg/Qk8KUk787z","DiscordInviteLink"]
},
{
location: [["Denmark","Copenhagen"],[55.6840661150132, 12.557133959514688]],
members: 1,
contact: ["https://discord.gg/Qk8KUk787z","DiscordInviteLink"]
},
{
location: [["Denmark","Kolding"], [55.49261908652738, 9.470268969851743]],
members: 1,
contact: ["https://discord.gg/Qk8KUk787z","DiscordInviteLink"]
},
{
location: [["Estonia","Kohtla-Järve"], [59.40629447076191, 27.280605339416322]],
members: 3,
contact: ["https://discord.gg/Qk8KUk787z","DiscordInviteLink"]
},
{
location: [["Estonia","Tallinn"], [59.39180354687856, 24.72304565687877]],
members: 1,
contact: ["https://discord.gg/Qk8KUk787z","DiscordInviteLink"]
},
{
location: [["Germany","Wiesbaden"], [50.07459620869791, 8.234984059337897]],
members: 1,
contact: ["https://discord.gg/Qk8KUk787z","DiscordInviteLink"]
},
{
location: [["Greece","Athens"], [37.94877252621736, 23.677622972996158]],
members: 1,
contact: ["https://discord.gg/Qk8KUk787z","DiscordInviteLink"]
},
{
location: [["Ireland"], [53.280192832733576, -7.688103518964818]],
members: 6,
contact: ["https://discord.gg/4BUau4AZre","DiscordInviteLink"]
},
{
location: [["Latvia","Riga"], [56.94748425529816, 24.003027136431925]],
members: 2,
contact: ["https://discord.gg/Qk8KUk787z","DiscordInviteLink"]
},
{
location: [["USA","Florida"], [26.945024427155868, -81.22162645059898]],
members: 2,
contact: ["https://discord.gg/Qk8KUk787z","DiscordInviteLink"]
},
{
location: [["USA","Colorado","Louisville"], [39.965026323855334, -105.15948886693151]],
members: 1,
contact: ["https://discord.gg/Qk8KUk787z","DiscordInviteLink"]
},
{
location: [["USA","Georgia"], [33.91813982808364, -84.38058579763135]],
members: 1,
contact: ["https://discord.gg/Qk8KUk787z","DiscordInviteLink"]
},
{
location: [["USA","Ohio"], [40.18243610076637, -83.07800532738788]],
members: 1,
contact: ["https://discord.gg/Qk8KUk787z","DiscordInviteLink"]
},
{
location: [["Thailand","Chiang Mai"], [18.788343253574393, 98.99423221087719]],
members: 1,
contact: ["https://discord.gg/Qk8KUk787z","DiscordInviteLink"]
},
{
location: [["Switzerland","Cham"], [47.18298143153399, 8.460076421717238]],
members: 1,
contact: ["https://discord.gg/Qk8KUk787z","DiscordInviteLink"]
}
]
*/
export let groupsMarkersLayer = L.layerGroup()
let groupsMarkersLayerOut = L.layerGroup()
let groupsMarkersLayerIn = L.layerGroup()
let contactGeneral =["https://discord.gg/4BUau4AZre","DiscordInviteLink"]
export function translate(content, x) {
let out = content[x]
if (out==undefined) {
return x
}
else {
return out
}
}
function addMarkersToLayer(g,layer,content,locale) {
let coordinates
let text = "<b>"+content["Group"]+"</b><br>"
for (let field of ["location","members","contact"]) {
let fieldText = content[field] + ": "
if (field=="contact") {
text += fieldText + "<a href='" + g.contact + "' target='_blank' rel=noreferrer>" + g.contact + "</a>"
}
else if (field=="location") {
let location = [g.country,g.state,g.town].filter(x => x!=null && x!=undefined)
let locationString
if (locale=="en") {
locationString = location.map(x => x).join(", ")
}
else {
locationString = location.map(x => translate(content, x)).join(", ")
}
text += fieldText + locationString + "<br>"
coordinates = [g.latitude,g.longitude]
}
else {
text += fieldText + g[field] + "<br>"
}
}
var markerIcon = new L.Icon({
iconUrl: 'https://www.libsoc.org/img/common/markers/marker-green.png',
shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/images/marker-shadow.png',
iconSize: [25, 41],
iconAnchor: [12, 41],
popupAnchor: [1, -34],
shadowSize: [41, 41]
})
//console.log(text)
let marker = L.marker(coordinates, {icon: markerIcon})
marker.addTo(layer).bindPopup(text)
}
export function addMarkersGroups(groups,groupsByCountry,map,content,locale) {
for (let g of groups) {
addMarkersToLayer(g,groupsMarkersLayerIn,content,locale)
}
for (let gs of Object.values(groupsByCountry)) {
if (gs.length==1) {
let g = {...gs[0]}
g.country = [g.country]
addMarkersToLayer(g,groupsMarkersLayerOut,content,locale)
}
else {
let locationName = gs[0].country
let locationCoordinates = [0,0]
let members = 0
let contact = gs[0].contact
for (let g of gs) {
locationCoordinates[0] += g.latitude
locationCoordinates[1] += g.longitude
members += g.members
if (g.contact[0]!=gs[0].contact[0]) {
contact = contactGeneral
}
}
locationCoordinates[0] = locationCoordinates[0]/gs.length
locationCoordinates[1] = locationCoordinates[1]/gs.length
let gNew = {
country: locationName,
latitude: locationCoordinates[0],
longitude: locationCoordinates[1],
members: members,
contact: contact
}
addMarkersToLayer(gNew,groupsMarkersLayerOut,content,locale)
}
}
groupsMarkersLayerOut.addTo(groupsMarkersLayer)
groupsMarkersLayer.addTo(map)
map.on("zoomend", () => onZoomEnd(map))
}
function onZoomEnd(map) {
let zoomLevel = map.getZoom()
if (zoomLevel==3) {
groupsMarkersLayer.removeLayer(groupsMarkersLayerIn)
groupsMarkersLayerOut.addTo(groupsMarkersLayer)
}
else if (zoomLevel==4) {
groupsMarkersLayer.removeLayer(groupsMarkersLayerOut)
groupsMarkersLayerIn.addTo(groupsMarkersLayer)
}
}

View File

@ -0,0 +1,90 @@
let contactGeneral =["https://discord.gg/4BUau4AZre","DiscordInviteLink"]
export function translate(content, x) {
let out = content[x]
if (out==undefined) {
return x
}
else {
return out
}
}
function addMarkersToLayer(g,layer,content,locale,addPinContent,markerColor) {
let {text,coordinates} = addPinContent(g,content,locale)
var markerIcon = new L.Icon({
iconUrl: 'https://www.libsoc.org/img/common/markers/marker-' + markerColor + '.png',
shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/images/marker-shadow.png',
iconSize: [25, 41],
iconAnchor: [12, 41],
popupAnchor: [1, -34],
shadowSize: [41, 41]
})
let marker = L.marker(coordinates, {icon: markerIcon})
marker.addTo(layer).bindPopup(text)
}
export function addMarkersEntries(entries,entriesByCountry,map,content,locale,addPinContent,markerColor) {
let entriesMarkersLayer = L.layerGroup()
let entriesMarkersLayerOut = L.layerGroup()
let entriesMarkersLayerIn = L.layerGroup()
for (let g of entries) {
if (g.country!="Online" && g.country!="Worldwide") {
addMarkersToLayer(g,entriesMarkersLayerIn,content,locale,addPinContent,markerColor)
}
}
for (let gs of Object.values(entriesByCountry)) {
if (gs.length==1) {
let g = {...gs[0]}
g.country = [g.country]
if (g.country!="Online" && g.country!="Worldwide") {
addMarkersToLayer(g,entriesMarkersLayerOut,content,locale,addPinContent,markerColor)
}
}
else {
if (gs[0].country!="Online" && gs[0].country!="Worldwide") {
let locationName = gs[0].country
let locationCoordinates = [0,0]
let members = 0
let contact = gs[0].contact
for (let g of gs) {
locationCoordinates[0] += g.latitude
locationCoordinates[1] += g.longitude
members += g.members
if (g.contact[0]!=gs[0].contact[0]) {
contact = contactGeneral
}
}
locationCoordinates[0] = locationCoordinates[0]/gs.length
locationCoordinates[1] = locationCoordinates[1]/gs.length
let gNew = {
country: locationName,
latitude: locationCoordinates[0],
longitude: locationCoordinates[1],
members: members,
contact: contact
}
addMarkersToLayer(gNew,entriesMarkersLayerOut,content,locale,addPinContent,markerColor)
}
}
}
entriesMarkersLayerOut.addTo(entriesMarkersLayer)
entriesMarkersLayer.addTo(map)
map.on("zoomend", () => onZoomEnd(map,entriesMarkersLayer,entriesMarkersLayerOut,entriesMarkersLayerIn))
return entriesMarkersLayer
}
function onZoomEnd(map,entriesMarkersLayer,entriesMarkersLayerOut,entriesMarkersLayerIn) {
let zoomLevel = map.getZoom()
if (zoomLevel==3) {
entriesMarkersLayer.removeLayer(entriesMarkersLayerIn)
entriesMarkersLayerOut.addTo(entriesMarkersLayer)
}
else if (zoomLevel==4) {
entriesMarkersLayer.removeLayer(entriesMarkersLayerOut)
entriesMarkersLayerIn.addTo(entriesMarkersLayer)
}
}

View File

@ -0,0 +1,178 @@
import { translate } from "/js/libraries/mapTools.js"
export function addGroupPinContent(g,content,locale) {
let coordinates
let text = "<b>"+content["Group"]+"</b><br>"
for (let field of ["location","members","contact"]) {
let fieldText = content[field] + ": "
if (field=="contact") {
text += fieldText + "<a href='" + g.contact + "' target='_blank' rel=noreferrer>" + g.contact + "</a>"
}
else if (field=="location") {
let location = [g.country,g.state,g.town].filter(x => x!=null && x!=undefined)
let locationString
if (locale=="en") {
locationString = location.map(x => x).join(", ")
}
else {
locationString = location.map(x => translate(content, x)).join(", ")
}
text += fieldText + locationString + "<br>"
coordinates = [g.latitude,g.longitude]
}
else {
text += fieldText + g[field] + "<br>"
}
}
return {text,coordinates}
}
export function addCommunePinContent(g,content,locale) {
let coordinates
let text = "<b>"+content["Commune"]+"</b><br>"
for (let field of ["location","status","members","contact"]) {
let fieldText = content[field] + ": "
if (field=="contact") {
text += fieldText + "<a href='" + g.contact + "' target='_blank' rel=noreferrer>" + g.contact + "</a>"
}
else if (field=="location") {
let location = [g.country,g.state,g.town].filter(x => x!=null && x!=undefined)
let locationString
if (locale=="en") {
locationString = location.map(x => x).join(", ")
}
else {
locationString = location.map(x => translate(content, x)).join(", ")
}
text += fieldText + locationString + "<br>"
coordinates = [g.latitude,g.longitude]
}
else if (field=="status") {
text += fieldText + content[g[field]] + "<br>"
}
else {
text += fieldText + g[field] + "<br>"
}
}
return {text,coordinates}
}
export function addCoopPinContent(g,content,locale) {
let coordinates
let text = "<b>"+content["Cooperative"]+"</b><br>"
for (let field of ["logo","name","location","workers","status","website","contact","description"]) {
let fieldText
if (field!="logo") {
fieldText = content[field] + ": "
}
if (field=="logo") {
text += "<picture><source srcset=" + "/img/coops/" + g.logo + ".webp><source srcset='/img/coops/" + g.logo + ".png'><img alt='logo' style='position: relative; max-height: 5rem; max-width: 100%; margin: auto;'></picture>" + "<br>"
}
else if (field=="contact") {
text += fieldText + "<a href='https://www." + g.contact + "' target='_blank' rel=noreferrer>" + g.contact + "</a>" + "<br>"
}
else if (field=="website") {
text += fieldText + "<a href='" + g.website + "' target='_blank' rel=noreferrer>" + g.website + "</a>" + "<br>"
}
else if (field=="location") {
let location = [g.country,g.state,g.town].filter(x => x!=null && x!=undefined)
let locationString
if (locale=="en") {
locationString = location.map(x => x).join(", ")
}
else {
locationString = location.map(x => translate(content, x)).join(", ")
}
text += fieldText + locationString + "<br>"
coordinates = [g.latitude,g.longitude]
}
else if (field=="market" || field=="status" || field=="description") {
text += fieldText + g[field] + "<br>"
}
else {
text += fieldText + g[field] + "<br>"
}
}
return {text,coordinates}
}
export function addPartyPinContent(g,content,locale) {
let coordinates
let text = "<b>"+content["Cooperative"]+"</b><br>"
for (let field of ["logo","name","location","website","contact","description"]) {
let fieldText
if (field!="logo") {
fieldText = content[field] + ": "
}
if (field=="logo") {
text += "<picture><source srcset=" + "/img/parties/" + g.logo + ".webp><source srcset='/img/parties/" + g.logo + ".png'><img alt='logo' style='position: relative; max-height: 5rem; max-width: 100%; margin: auto;'></picture>" + "<br>"
}
else if (field=="link") {
text += fieldText + "<a href='" + g.link + "' target='_blank' rel=noreferrer>" + g.link + "</a>" + "<br>"
}
else if (field=="website") {
text += fieldText + "<a href='" + g.website + "' target='_blank' rel=noreferrer>" + g.website + "</a>" + "<br>"
}
else if (field=="location") {
let location = [g.country,g.state,g.town].filter(x => x!=null && x!=undefined)
let locationString
if (locale=="en") {
locationString = location.map(x => x).join(", ")
}
else {
locationString = location.map(x => translate(content, x)).join(", ")
}
text += fieldText + locationString + "<br>"
coordinates = [g.latitude,g.longitude]
}
else if (field=="description") {
text += fieldText + content[g[field]] + "<br>"
}
else if (field=="contact") {
text += fieldText + "<a href='" + g.contact + "' target='_blank' rel=noreferrer>" + g.contact + "</a>" + "<br>"
}
else {
text += fieldText + g[field] + "<br>"
}
}
return {text,coordinates}
}
export function addPartnersPinContent(g,content,locale) {
let coordinates
let text = "<b>"+content["Partner"]+"</b><br>"
for (let field of ["logo","name","location","website","contact","description"]) {
let fieldText
if (field!="logo") {
fieldText = content[field] + ": "
}
if (field=="logo") {
text += "<picture><source srcset=" + "/img/coops/" + g.logo + ".webp><source srcset='/img/coops/" + g.logo + ".png'><img alt='logo' style='position: relative; max-height: 5rem; max-width: 100%; margin: auto;'></picture>" + "<br>"
}
else if (field=="contact") {
text += fieldText + "<a href='https://www." + g.contact + "' target='_blank' rel=noreferrer>" + g.contact + "</a>" + "<br>"
}
else if (field=="website") {
text += fieldText + "<a href='" + g.website + "' target='_blank' rel=noreferrer>" + g.website + "</a>" + "<br>"
}
else if (field=="location") {
let location = [g.country,g.state,g.town].filter(x => x!=null && x!=undefined)
let locationString
if (locale=="en") {
locationString = location.map(x => x).join(", ")
}
else {
locationString = location.map(x => translate(content, x)).join(", ")
}
text += fieldText + locationString + "<br>"
coordinates = [g.latitude,g.longitude]
}
else if (field=="description") {
text += fieldText + g[field] + "<br>"
}
else {
text += fieldText + g[field] + "<br>"
}
}
return {text,coordinates}
}

View File

@ -1,74 +0,0 @@
export let parties = [
{
logo: "roots",
name: "Roots",
location: ["Ireland",[52.98479517270413, -7.649233227534782]],
//members: 6,
link: "https://discord.gg/pSTMacJZsK",
description: "descriptionRoots"
}
]
export let partiesByCountry = {}
for (let g of parties) {
let country = g.location[0]
if (country in partiesByCountry) {
partiesByCountry[country].push(g)
}
else {
partiesByCountry[country] = [g]
}
}
export let partiesMarkersLayer = L.layerGroup()
export function addMarkersParties(map,content,locale) {
for (let g of parties) {
let coordinates
let text = "<b>"+content["Party"]+"</b><br>"
for (let field in g) {
let fieldText
if (field!="logo") {
fieldText = content[field] + ": "
}
if (field=="logo") {
text += "<picture><source srcset=" + "/img/parties/" + g.logo + ".webp><source srcset='/img/parties/" + g.logo + ".png'><img alt='logo' style='position: relative; max-height: 5rem; max-width: 100%; margin: auto;'></picture>" + "<br>"
}
else if (field=="link") {
text += fieldText + "<a href='" + g.link + "' target='_blank' rel=noreferrer>" + g.link + "</a>" + "<br>"
}
else if (field=="website") {
text += fieldText + "<a href='" + g.website + "' target='_blank' rel=noreferrer>" + g.website + "</a>" + "<br>"
}
else if (field=="location") {
let location = g[field][0]
let locationString
if (locale=="en") {
locationString = location
}
else {
locationString = content[location]
}
text += fieldText + locationString + "<br>"
coordinates = g[field][1]
}
else if (field=="description") {
text += fieldText + content[g[field]] + "<br>"
}
else {
text += fieldText + g[field] + "<br>"
}
}
var markerIcon = new L.Icon({
iconUrl: 'https://www.libsoc.org/img/common/markers/marker-gold.png',
shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/images/marker-shadow.png',
iconSize: [25, 41],
iconAnchor: [12, 41],
popupAnchor: [1, -34],
shadowSize: [41, 41]
});
let marker = L.marker(coordinates, {icon: markerIcon})
marker.addTo(partiesMarkersLayer).bindPopup(text)
}
partiesMarkersLayer.addTo(map)
}

View File

@ -1,21 +0,0 @@
export let partners = [
{
name: "Gaia's Fall",
type: "typeGaiasFall",
location: [["Online"],[0,0]],
link: "https://discord.libsoc.org/invite/",
description: "descriptionGaiasFall",
logo: "gaias_fall"
}
]
export let partnersByCountry = {}
for (let g of partners) {
let country = g.location[0][0]
if (country in partnersByCountry) {
partnersByCountry[country].push(g)
}
else {
partnersByCountry[country] = [g]
}
}

View File

@ -10,5 +10,6 @@
"forming": "forming", "forming": "forming",
"WhatsAppInviteLink": "WhatsApp invite link", "WhatsAppInviteLink": "WhatsApp invite link",
"DiscordInviteLink": "Discord invite link", "DiscordInviteLink": "Discord invite link",
"Commune": "Commune" "Commune": "Commune",
"map-prompt": "Want to appear on our map? Contact us!"
} }

View File

@ -18,6 +18,7 @@
"descriptionChironHealth": "Chiron Health is a health platform providing courses and services on the topics of nutrition, exercise, sleep and mental wellbeing.", "descriptionChironHealth": "Chiron Health is a health platform providing courses and services on the topics of nutrition, exercise, sleep and mental wellbeing.",
"herbalTeas": "herbal teas", "herbalTeas": "herbal teas",
"kuuskDescription": "Kuusk is an online store that sells herbal teas from exclusively local wild plants, as well as an online gathering course.", "kuuskDescription": "Kuusk is an online store that sells herbal teas from exclusively local wild plants, as well as an online gathering course.",
"Cooperative": "Cooperative" "Cooperative": "Cooperative",
"map-prompt": "Want to appear on our map? Contact us!"
} }

View File

@ -1,3 +1,3 @@
{ {
"map-prompt": "Want to appear on our map? Contact us!"
} }

View File

@ -8,5 +8,6 @@
"contact": "Contact", "contact": "Contact",
"DiscordInviteLink": "Discord invite link", "DiscordInviteLink": "Discord invite link",
"WhatsAppInviteLink": "WhatsApp invite link", "WhatsAppInviteLink": "WhatsApp invite link",
"Group": "Group" "Group": "Group",
"map-prompt": "Want to appear on our map? Contact us!"
} }

View File

@ -5,8 +5,10 @@
"name": "Name", "name": "Name",
"location": "Location", "location": "Location",
"members": "Members", "members": "Members",
"link": "Link", "website": "Website",
"contact": "Contact",
"description": "Description", "description": "Description",
"descriptionRoots": "We are a left libertarian organization based in Ireland. We have a focus on rebuilding the country's infrastructure, sense of governance, housing, agricultural industries and youth affairs.", "descriptionRoots": "We are a left libertarian organization based in Ireland. We have a focus on rebuilding the country's infrastructure, sense of governance, housing, agricultural industries and youth affairs.",
"Party": "Party" "Party": "Party",
"map-prompt": "Want to appear on our map? Contact us!"
} }

View File

@ -5,10 +5,11 @@
"subheading2": "Online", "subheading2": "Online",
"name": "Name", "name": "Name",
"location": "Location", "location": "Location",
"type": "Type", "website": "Website",
"link": "Link", "contact": "Contact",
"description": "Description", "description": "Description",
"typeGaiasFall": "a place for discussions", "typeGaiasFall": "a place for discussions",
"descriptionGaiasFall": "Gaia's Fall is a server that promotes Solarpunk ideals, environmentalism, anarchism, and anti-capitalism. We encourage civil debates, discussions of theories and possibilities, and the creation of communities focused on shaping a better world." "descriptionGaiasFall": "Gaia's Fall is a server that promotes Solarpunk ideals, environmentalism, anarchism, and anti-capitalism. We encourage civil debates, discussions of theories and possibilities, and the creation of communities focused on shaping a better world.",
"map-prompt": "Want to appear on our map? Contact us!"
} }

View File

@ -9,5 +9,6 @@
"forming": "формируется", "forming": "формируется",
"WhatsAppInviteLink": "WhatsApp ссылка", "WhatsAppInviteLink": "WhatsApp ссылка",
"DiscordInviteLink": "Discord ссылка", "DiscordInviteLink": "Discord ссылка",
"Commune": "Коммуна" "Commune": "Коммуна",
"map-prompt": "Хочешь оказаться на нашей карте? Напиши нам!"
} }

View File

@ -18,5 +18,6 @@
"descriptionChironHealth": "Chiron Health — это платформа о здоровье, предлагающая курсы и услуги по вопросам питания, физических упражнений, сна и психического благополучия", "descriptionChironHealth": "Chiron Health — это платформа о здоровье, предлагающая курсы и услуги по вопросам питания, физических упражнений, сна и психического благополучия",
"herbalTeas": "травяные чаи", "herbalTeas": "травяные чаи",
"kuuskDescription": "Kuusk — интернет-магазин, в котором продаются травяные чаи исключительно из местных дикорастущих растений, а также онлайн-курс по собирательству.", "kuuskDescription": "Kuusk — интернет-магазин, в котором продаются травяные чаи исключительно из местных дикорастущих растений, а также онлайн-курс по собирательству.",
"Cooperative": "Кооператив" "Cooperative": "Кооператив",
"map-prompt": "Хочешь оказаться на нашей карте? Напиши нам!"
} }

View File

@ -1,30 +1,3 @@
{ {
"map-prompt": "Хочешь оказаться на нашей карте? Напиши нам!",
"Online": "Онлайн",
"Denmark": "Дания",
"Estonia": "Эстония",
"Greece": "Греция",
"Latvia": "Латвия",
"Canada": "Канада",
"Ireland": "Ирландия",
"Germany": "Германия",
"USA": "CША",
"Bulgaria": "Болгария",
"Thailand": "Тайланд",
"Colorado": "Колорадо",
"Georgia": "Джорджия",
"Ohio": "Огайо",
"Copenhagen": "Копенгаген",
"Kolding": "Колдинг",
"Kohtla-Järve": "Кохтла-Ярве",
"Athens": "Афины",
"Riga": "Рига",
"Halifax": "Галифакс",
"Montreal": "Монреаль",
"Wiesbaden": "Висбаден",
"Florida": "Флорида",
"Tallinn": "Таллинн",
"Varna": "Варна",
"Louisville": "Луисвилл",
"Toronto": "Торонто"
} }

View File

@ -7,5 +7,6 @@
"contact": "Контакт", "contact": "Контакт",
"DiscordInviteLink": "Discord ссылка", "DiscordInviteLink": "Discord ссылка",
"WhatsAppInviteLink": "WhatsApp ссылка", "WhatsAppInviteLink": "WhatsApp ссылка",
"Group": "Группа" "Group": "Группа",
"map-prompt": "Хочешь оказаться на нашей карте? Напиши нам!"
} }

View File

@ -30,5 +30,6 @@
"market": "Рынок", "market": "Рынок",
"workers": "Работники", "workers": "Работники",
"description": "Описание", "description": "Описание",
"website": "Вебсайт" "website": "Вебсайт",
"map-prompt": "Хочешь оказаться на нашей карте? Напиши нам!"
} }

View File

@ -11,5 +11,6 @@
"findUs": "Найди нас", "findUs": "Найди нас",
"whatNow": "Что теперь?", "whatNow": "Что теперь?",
"joinUs": "Присоединяйся", "joinUs": "Присоединяйся",
"talkWithUs": "Напиши нам" "talkWithUs": "Напиши нам",
"map-prompt": "Хочешь оказаться на нашей карте? Напиши нам!"
} }

View File

@ -5,9 +5,11 @@
"name": "Имя", "name": "Имя",
"location": "Локация", "location": "Локация",
"members": "Участники", "members": "Участники",
"link": "Ссылка", "website": "Вебсайт",
"contact": "Контакт",
"description": "Описание", "description": "Описание",
"ireland": "Ирландия", "ireland": "Ирландия",
"descriptionRoots": "Мы — левая либертарная организация, базирующаяся в Ирландии. Мы уделяем особое внимание восстановлению инфраструктуры страны, самоуправлению, жилищному строительству, сельскохозяйственной промышленности и делам молодежи.", "descriptionRoots": "Мы — левая либертарная организация, базирующаяся в Ирландии. Мы уделяем особое внимание восстановлению инфраструктуры страны, самоуправлению, жилищному строительству, сельскохозяйственной промышленности и делам молодежи.",
"Party": "Партия" "Party": "Партия",
"map-prompt": "Хочешь оказаться на нашей карте? Напиши нам!"
} }

View File

@ -6,8 +6,10 @@
"name": "Название", "name": "Название",
"location": "Локация", "location": "Локация",
"type": "Тип", "type": "Тип",
"link": "Ссылка", "website": "Вебсайт",
"contact": "Контакт",
"description": "Описание", "description": "Описание",
"typeGaiasFall": "место для общения", "typeGaiasFall": "место для общения",
"descriptionGaiasFall": "Gaia's Fall — это сервер, который продвигает идеалы соларпанка, защиту окружающей среды, анархизм и антикапитализм. Мы поощряем гражданские дебаты, обсуждение теорий и возможностей, а также создание сообществ, сосредоточенных на формировании лучшего мира." "descriptionGaiasFall": "Gaia's Fall — это сервер, который продвигает идеалы соларпанка, защиту окружающей среды, анархизм и антикапитализм. Мы поощряем гражданские дебаты, обсуждение теорий и возможностей, а также создание сообществ, сосредоточенных на формировании лучшего мира.",
"map-prompt": "Хочешь оказаться на нашей карте? Напиши нам!"
} }

View File

@ -10,7 +10,6 @@ import watch from "rollup-plugin-watch";
const production = !process.env.ROLLUP_WATCH; const production = !process.env.ROLLUP_WATCH;
function serve() { function serve() {
let server; let server;

View File

@ -0,0 +1,415 @@
<svelte:options tag="communes-add-component" />
<script>
// Import statements
import { onMount } from 'svelte'
import { writable } from 'svelte/store'
import { loadLocaleContent, getData, sendData } from "/js/libraries/serverTools.js"
import { addMarkersEntries, translate } from "/js/libraries/mapTools.js"
// Import components
import "/js/components/map-component.js"
import "/js/components/select-component.js"
// Main code
let loaded = writable(0)
let content = writable({})
let entries
let entriesByCountry
let callback = (response) => {
entries = JSON.parse(response)
entriesByCountry = {}
for (let g of entries) {
let country = g.country
if (g.contact==null) {
g.contact = "https://discord.gg/Qk8KUk787z"
}
if (country in entriesByCountry) {
entriesByCountry[country].push(g)
}
else {
entriesByCountry[country] = [g]
}
}
loaded.update((val) => {
return val + 1
})
}
getData("/assets/communes.json",callback)
let confirmationMsg
let addressInput
let contactInput
let statusInput
let addressVec
let userPinLat = 0
let userPinLng = 0
let userPin = createPin(0,0)
userPin.setOpacity(0)
let locale = loadLocaleContent(content,"communes-component",loaded)
loadLocaleContent(content,"countries",loaded)
function createPin(lat,lng) {
let markerIcon = new L.Icon({
iconUrl: '/img/common/markers/marker-black.png',
shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/images/marker-shadow.png',
iconSize: [25, 41],
iconAnchor: [12, 41],
popupAnchor: [1, -34],
shadowSize: [41, 41]
})
return L.marker([lat,lng], {icon: markerIcon})
}
function updatePin(marker,lat,lng) {
let newLatLng = L.latLng(lat, lng); // Replace with the desired coordinates
marker.setLatLng(newLatLng)
}
function reverseGeocodeLocal(latitude, longitude) {
let url = `https://nominatim.openstreetmap.org/reverse?lat=${latitude}&lon=${longitude}&format=jsonv2`;
let callback = (response) => {
// Parse the response JSON
response = JSON.parse(response)
// Extract the address information from the response
let address = response.address
let city = address.city || address.town || address.village || address.hamlet
let state = address.state
let country = address.country
let fullAddress = country
if (state!=undefined) {
fullAddress += ", " + state
}
else {
state = ""
}
if (city!=undefined) {
fullAddress += ", " + city
}
else {
city = ""
}
addressInput.value = fullAddress
resizeInput(addressInput)
}
getData(url,callback)
}
function reverseGeocode(latitude, longitude) {
let url = `https://nominatim.openstreetmap.org/reverse?lat=${latitude}&lon=${longitude}&format=jsonv2&accept-language=en`;
let callback = (response) => {
// Parse the response JSON
response = JSON.parse(response)
// Extract the address information from the response
let address = response.address
let city = address.city || address.town || address.village || address.hamlet
let state = address.state
let country = address.country
let fullAddress = country
if (state!=undefined) {
fullAddress += ", " + state
}
else {
state = ""
}
if (city!=undefined) {
fullAddress += ", " + city
}
else {
city = ""
}
addressVec = [country,state,city]
}
getData(url,callback)
}
function addGroupPinContent(g,content,locale) {
let coordinates
let text = "<b>"+content["Group"]+"</b><br>"
for (let field of ["location","members","contact"]) {
let fieldText = content[field] + ": "
if (field=="contact") {
text += fieldText + "<a href='" + g.contact + "' target='_blank' rel=noreferrer>" + g.contact + "</a>"
}
else if (field=="location") {
let location = [g.country,g.state,g.town].filter(x => x!=null && x!=undefined)
let locationString
if (locale=="en") {
locationString = location.map(x => x).join(", ")
}
else {
locationString = location.map(x => translate(content, x)).join(", ")
}
text += fieldText + locationString + "<br>"
coordinates = [g.latitude,g.longitude]
}
else {
text += fieldText + g[field] + "<br>"
}
}
return {text,coordinates}
}
function mapCallback(createMap,content,locale) {
let map = createMap([22, 0],2)
addMarkersEntries(entries,entriesByCountry,map,content,locale,addGroupPinContent,"green")
userPin.addTo(map)
map.on('click', function(event) {
let lat = event.latlng.lat;
let lng = event.latlng.lng;
userPinLat = lat
userPinLng = lng
updatePin(userPin,lat,lng)
userPin.setOpacity(1)
reverseGeocodeLocal(lat, lng)
reverseGeocode(lat, lng)
})
}
function updateConfirmationMsg(response) {
if (response!==false) {
confirmationMsg.innerHTML = "You have been added to our database! Now go to our Discord to verify yourself."
confirmationMsg.style.color = "green"
}
else {
confirmationMsg.innerHTML = "Something went wrong."
confirmationMsg.style.color = "red"
}
}
function submitLocation() {
if (addressVec!=undefined) {
let data = {
country: addressVec[0],
state: addressVec[1],
town: addressVec[2],
latitude: userPinLat,
longitude: userPinLng,
contact: contactInput.value,
status: statusInput.value
}
if (data.state=="") {
data.state = null
}
if (data.town=="") {
data.town = null
}
if (data.contact=="") {
data.contact = null
}
let url = "/" + locale + "/communes-add-post/"
sendData(url,data,updateConfirmationMsg)
}
}
function resizeInput(el) {
el.nextElementSibling.innerHTML = el.value
}
onMount(() => {
})
</script>
{#key $loaded}
{#if $loaded==3}
<div id="container">
<!--<img src="img/crowd.png" id="crowd" alt="crowd">-->
<div id="text-container">
<h1>Add a Commune</h1>
<img id="communes-img" src="/img/common/communes.svg" alt="communes">
<p class="description">If there are no communes near you who you can join and you want to start your own then do the following:</p>
<ol>
<li>Click on the map to show us where you are located;</li>
<li>Add a way to contact you or leave blank for a pin to point to our discord;</li>
<li>Press "Submit" to add yourself to our map;</li>
<li>Verify yourself by having a chat with us at our Discord server to show on the map;</li>
</ol>
<div id="address-input-wrapper" class="input-label-wrapper">
<label for="address-input">Location: </label>
<div class="input-wrapper">
<input bind:this={addressInput} on:input={() => resizeInput(addressInput)} id="address-input" type="text" readonly>
<div class="ghost-input"></div>
</div>
</div>
<div class="input-label-wrapper">
<label for="contact-input">Contact: </label>
<div class="input-wrapper">
<input bind:this={contactInput} on:input={() => resizeInput(contactInput)} id="contact-input" type="text">
<div class="ghost-input"></div>
</div>
</div>
<div id="status-input-wrapper" class="input-label-wrapper">
<label for="contact-input">Status: </label>
<div class="input-wrapper">
<select-component bind:this={statusInput} id="status-input" options={["forming","growing","not growing"]}></select-component>
<div class="ghost-input"></div>
</div>
</div>
<button id="submit-button" on:click={submitLocation}>Submit</button>
<p id="confirmation-msg" bind:this={confirmationMsg}></p>
<map-component id="map" callback={(createMap) => mapCallback(createMap,$content,locale)}></map-component>
</div>
</div>
{/if}
{/key}
<style>
@import '/css/common.css';
#confirmation-msg {
margin-top: 0.5rem;
margin-bottom: 2rem;
}
ol li {
margin-left: 3rem;
margin-bottom: 0.5rem;
}
label {
display: inline-block;
font-family: var(--serif,serif);
font-size: 1.15rem;
line-height: 160%;
color: #222222;
width: 5.5rem;
}
input, .ghost-input {
font-size: 1.15rem;
font-family: var(--serif,serif);
}
input {
height: 2.5rem;
display: inline-block;
position: relative;
}
#address-input, #contact-input {
width: 100%;
}
#address-input-wrapper {
margin-top: 2rem;
margin-bottom: 1rem;
}
#status-input {
--width: 100%;
--height: 2.5rem;
--display: inline-block;
--position: relative;
--background-color: white;
--border-radius: 0.4rem;
--border: black solid 0.063rem;
--padding-left: 0.5rem;
--font-size: 1.15rem;
--font-family: var(--serif, serif);
}
#status-input-wrapper {
margin-top: 1rem;
margin-bottom: 0rem;
}
.ghost-input {
display: block;
visibility: hidden;
height: 0;
padding-left: 0.5rem;
padding-right: 0.5rem;
}
.input-wrapper {
display: inline-block;
max-width: calc(100% - 5.5rem);
min-width: min(20rem, calc(100% - 5.5rem));
height: 2.5rem;
}
.input-label-wrapper {
display: flex;
justify-content: start;
}
.input-label-wrapper label {
position: relative;
top: 0.3rem;
}
.description {
margin-bottom: 1rem;
}
#submit-button {
display: block;
margin: auto;
margin-top: 2rem;
padding: 1rem 2rem;
font-size: 1.4rem;
font-family: var(--sans-serif,sans-serif);
border: 0rem solid black;
border-radius: 0.5rem;
background: #cb1816;
color: white;
}
#communes-img {
position: absolute;
width: 11.5rem;
left: 50%;
transform: translate(-50%);
z-index: 0;
opacity: 0.2;
}
#text-container>:nth-child(3) {
margin-top: 8rem;
}
#map {
--height: 30rem;
--width: 100%;
--margin-top: 2rem;
--margin-bottom: 0.5rem;
}
#text-container {
position: relative;
max-width: calc(100vw - 4rem);
margin: auto;
}
h1 {
margin-bottom: 1rem;
font-size: 2.2rem;
text-align: center;
}
#container {
margin: auto;
max-width: 800px;
margin-top: 1rem;
margin-bottom: 4rem;
}
#container p {
text-align: justify;
}
</style>

View File

@ -3,31 +3,56 @@
<script> <script>
// Import statements // Import statements
import { onMount } from 'svelte' import { onMount } from 'svelte'
import { writable } from 'svelte/store'; import { writable } from 'svelte/store'
import { communesByCountry, addMarkersCommunes } from '/js/communes.js' import { loadLocaleContent, getData} from "/js/libraries/serverTools.js"
import { loadLocaleContent } from "/js/libraries/serverTools.js" import { addMarkersEntries, translate } from "/js/libraries/mapTools.js"
import { addCommunePinContent } from "/js/mapFuncs.js"
// Import components // Import components
import "/js/components/map-component.js" import "/js/components/map-component.js"
// Main code // Main code
let loaded = writable(0) let loaded = writable(0)
let content = writable({}) let content = writable({})
let entries
let entriesByCountry
loadLocaleContent(content,"countries",loaded)
let locale = loadLocaleContent(content,"communes-component",loaded) let locale = loadLocaleContent(content,"communes-component",loaded)
loadLocaleContent(content,"countries",loaded)
let callback = (response) => {
entries = JSON.parse(response)
entriesByCountry = {}
for (let g of entries) {
let country = g.country
if (g.contact==null) {
g.contact = "https://discord.gg/Qk8KUk787z"
}
if (country in entriesByCountry) {
entriesByCountry[country].push(g)
}
else {
entriesByCountry[country] = [g]
}
}
loaded.update((val) => {
return val + 1
})
}
getData("/assets/communes.json",callback)
function mapCallbackCommunes(createMap,content,locale) { function mapCallback(createMap,content,locale) {
let map = createMap([22, 0],2) let map = createMap([22, 0],2)
addMarkersCommunes(map,content,locale) addMarkersEntries(entries,entriesByCountry,map,content,locale,addCommunePinContent,"red")
} }
function getCountry(name) { function getCountry(x) {
return locale=="en" ? name : $content[name] return locale=="en" ? x : translate($content,x)
} }
function getAddress(group) { function getAddress(g) {
return group.location[0].map(x => locale=="en" ? x : $content[x]).join(", ") let location = [g.country,g.state,g.town].filter(x => x!=null)
return location.map(x => locale=="en" ? x : translate($content,x)).join(", ")
} }
onMount(() => { onMount(() => {
@ -36,25 +61,27 @@
</script> </script>
{#key $loaded} {#key $loaded}
{#if $loaded==2} {#if $loaded==3}
<div id="container"> <div id="container">
<!--<img src="img/crowd.png" id="crowd" alt="crowd">--> <!--<img src="img/crowd.png" id="crowd" alt="crowd">-->
<div id="text-container"> <div id="text-container">
<h1>{$content.communes}</h1> <h1>{$content.communes}</h1>
<img id="commune-img" src="/img/common/commune.svg" alt="commune"> <img id="communes-img" src="/img/common/communes.svg" alt="commune">
<p class="description">{$content.p1}</p> <p class="description">{$content.p1}</p>
<h3>{$content.subheading1}</h3> <h3>{$content.subheading1}</h3>
<map-component id="map" callback={(createMap) => mapCallbackCommunes(createMap,$content,locale)}></map-component> <map-component id="map" callback={(createMap) => mapCallback(createMap,$content,locale)}></map-component>
<p id="add-prompt">{$content["map-prompt"]}</p> <p id="add-prompt">{$content["map-prompt"]}</p>
{#each Object.entries(communesByCountry) as [name,communes]} {#each Object.entries(entriesByCountry) as [name,entries]}
<h4 class="country-name">{getCountry(name)}</h4> <h4 class="country-name">{getCountry(name)}</h4>
<div class="country-block"> <div class="country-block">
{#each communes as commune} {#each entries as entry}
<div class="location-info"> <div class="location-info">
<p><b>{$content.location}: </b>{getAddress(commune)}</p> <p><b>{$content.location}: </b>{getAddress(entry)}</p>
<p><b>{$content.status}: </b>{$content[commune.status]}</p> <p><b>{$content.status}: </b>{$content[entry.status]}</p>
<p><b>{$content.members}: </b>{commune.members}</p> <p><b>{$content.members}: </b>{entry.members}</p>
<p><b>{$content.contact}: </b><a href={commune.contact[0]} target=;_blank; rel=noreferrer>{$content[commune.contact[1]]}</a></p> <p><b>{$content.contact}: </b><a href={entry.contact} target=;_blank; rel=noreferrer>{entry.contact}</a></p>
</div> </div>
{/each} {/each}
</div> </div>
@ -75,7 +102,7 @@
margin-bottom: 2rem; margin-bottom: 2rem;
} }
#commune-img { #communes-img {
position: absolute; position: absolute;
width: 11.5rem; width: 11.5rem;
left: 50%; left: 50%;

View File

@ -50,6 +50,8 @@
width: var(--width,100%); width: var(--width,100%);
margin-top: var(--margin-top,0); margin-top: var(--margin-top,0);
margin-bottom: var(--margin-bottom,0); margin-bottom: var(--margin-bottom,0);
position: relative;
z-index: 0;
} }
</style> </style>

View File

@ -194,6 +194,7 @@
.select span { .select span {
position: relative; position: relative;
padding-top: 0.5rem; padding-top: 0.5rem;
padding-left: 0.3rem;
white-space: nowrap; white-space: nowrap;
} }

View File

@ -0,0 +1,413 @@
<svelte:options tag="cooperatives-add-component" />
<script>
// Import statements
import { onMount } from 'svelte'
import { writable } from 'svelte/store';
import { loadLocaleContent, getData, sendData } from "/js/libraries/serverTools.js"
import { addMarkersEntries, translate } from "/js/libraries/mapTools.js"
// Import components
import "/js/components/map-component.js"
// Main code
let loaded = writable(0)
let content = writable({})
let entries
let entriesByCountry
let callback = (response) => {
entries = JSON.parse(response)
entriesByCountry = {}
for (let g of entries) {
let country = g.country
if (g.contact==null) {
g.contact = "https://discord.gg/Qk8KUk787z"
}
if (country in entriesByCountry) {
entriesByCountry[country].push(g)
}
else {
entriesByCountry[country] = [g]
}
}
loaded.update((val) => {
return val + 1
})
}
getData("/assets/groups.json",callback)
let confirmationMsg
let addressInput
let contactInput
let addressVec
let userPinLat = 0
let userPinLng = 0
let userPin = createPin(0,0)
userPin.setOpacity(0)
let locale = loadLocaleContent(content,"groups-component",loaded)
loadLocaleContent(content,"countries",loaded)
function createPin(lat,lng) {
let markerIcon = new L.Icon({
iconUrl: '/img/common/markers/marker-black.png',
shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/images/marker-shadow.png',
iconSize: [25, 41],
iconAnchor: [12, 41],
popupAnchor: [1, -34],
shadowSize: [41, 41]
})
return L.marker([lat,lng], {icon: markerIcon})
}
function updatePin(marker,lat,lng) {
let newLatLng = L.latLng(lat, lng); // Replace with the desired coordinates
marker.setLatLng(newLatLng)
}
function reverseGeocodeLocal(latitude, longitude) {
let url = `https://nominatim.openstreetmap.org/reverse?lat=${latitude}&lon=${longitude}&format=jsonv2`;
let callback = (response) => {
// Parse the response JSON
response = JSON.parse(response)
// Extract the address information from the response
let address = response.address
let city = address.city || address.town || address.village || address.hamlet
let state = address.state
let country = address.country
let fullAddress = country
if (state!=undefined) {
fullAddress += ", " + state
}
else {
state = ""
}
if (city!=undefined) {
fullAddress += ", " + city
}
else {
city = ""
}
addressInput.value = fullAddress
resizeInput(addressInput)
}
getData(url,callback)
}
function reverseGeocode(latitude, longitude) {
let url = `https://nominatim.openstreetmap.org/reverse?lat=${latitude}&lon=${longitude}&format=jsonv2&accept-language=en`;
let callback = (response) => {
// Parse the response JSON
response = JSON.parse(response)
// Extract the address information from the response
let address = response.address
let city = address.city || address.town || address.village || address.hamlet
let state = address.state
let country = address.country
let fullAddress = country
if (state!=undefined) {
fullAddress += ", " + state
}
else {
state = ""
}
if (city!=undefined) {
fullAddress += ", " + city
}
else {
city = ""
}
addressVec = [country,state,city]
}
getData(url,callback)
}
function addGroupPinContent(g,content,locale) {
let coordinates
let text = "<b>"+content["Group"]+"</b><br>"
for (let field of ["location","members","contact"]) {
let fieldText = content[field] + ": "
if (field=="contact") {
text += fieldText + "<a href='" + g.contact + "' target='_blank' rel=noreferrer>" + g.contact + "</a>"
}
else if (field=="location") {
let location = [g.country,g.state,g.town].filter(x => x!=null && x!=undefined)
let locationString
if (locale=="en") {
locationString = location.map(x => x).join(", ")
}
else {
locationString = location.map(x => translate(content, x)).join(", ")
}
text += fieldText + locationString + "<br>"
coordinates = [g.latitude,g.longitude]
}
else {
text += fieldText + g[field] + "<br>"
}
}
return {text,coordinates}
}
function mapCallback(createMap,content,locale) {
let map = createMap([22, 0],2)
addMarkersEntries(entries,entriesByCountry,map,content,locale,addGroupPinContent,"green")
userPin.addTo(map)
map.on('click', function(event) {
let lat = event.latlng.lat;
let lng = event.latlng.lng;
userPinLat = lat
userPinLng = lng
updatePin(userPin,lat,lng)
userPin.setOpacity(1)
reverseGeocodeLocal(lat, lng)
reverseGeocode(lat, lng)
})
}
function updateConfirmationMsg(response) {
if (response!==false) {
confirmationMsg.innerHTML = "You have been added to our database! Now go to our Discord to verify yourself."
confirmationMsg.style.color = "green"
}
else {
confirmationMsg.innerHTML = "Something went wrong."
confirmationMsg.style.color = "red"
}
}
function submitLocation() {
if (addressVec!=undefined) {
let data = {
country: addressVec[0],
state: addressVec[1],
town: addressVec[2],
latitude: userPinLat,
longitude: userPinLng,
contact: contactInput.value
}
if (data.state=="") {
data.state = null
}
if (data.town=="") {
data.town = null
}
if (data.contact=="") {
data.contact = null
}
let url = "/" + locale + "/groups-add-post/"
sendData(url,data,updateConfirmationMsg)
}
}
function resizeInput(el) {
el.nextElementSibling.innerHTML = el.value
}
onMount(() => {
})
</script>
{#key $loaded}
{#if $loaded==3}
<div id="container">
<!--<img src="img/crowd.png" id="crowd" alt="crowd">-->
<div id="text-container">
<h1>Add a Group</h1>
<img id="groups-img" src="/img/common/groups.svg" alt="groups">
<p class="description">If there are no groups in your town with whom you can organize then do the following:</p>
<ol>
<li>Click on the map to show us where you are located;</li>
<li>Add a way to contact you or leave blank for a pin to point to our discord;</li>
<li>Press "Submit" to add yourself to our map;</li>
<li>Verify yourself by having a chat with us at our Discord server to show on the map;</li>
</ol>
<div id="address-input-wrapper" class="input-label-wrapper">
<label for="address-input">Location: </label>
<div class="input-wrapper">
<input bind:this={addressInput} on:input={() => resizeInput(addressInput)} id="address-input" type="text" readonly>
<div class="ghost-input"></div>
</div>
</div>
<div class="input-label-wrapper">
<label for="contact-input">Contact: </label>
<div class="input-wrapper">
<input bind:this={contactInput} on:input={() => resizeInput(contactInput)} id="contact-input" type="text">
<div class="ghost-input"></div>
</div>
</div>
<button id="submit-button" on:click={submitLocation}>Submit</button>
<p id="confirmation-msg" bind:this={confirmationMsg}></p>
<map-component id="map" callback={(createMap) => mapCallback(createMap,$content,locale)}></map-component>
</div>
</div>
{/if}
{/key}
<style>
@import '/css/common.css';
#confirmation-msg {
margin-top: 0.5rem;
margin-bottom: 2rem;
}
ol li {
margin-left: 3rem;
margin-bottom: 0.5rem;
}
label {
display: inline-block;
font-family: var(--serif,serif);
font-size: 1.15rem;
line-height: 160%;
color: #222222;
width: 5.5rem;
}
input, .ghost-input {
font-size: 1.15rem;
font-family: var(--serif,serif);
}
input {
height: 2.5rem;
display: inline-block;
position: relative;
}
#address-input, #contact-input {
width: 100%;
}
#address-input-wrapper {
margin-top: 2rem;
margin-bottom: 1rem;
}
.ghost-input {
display: block;
visibility: hidden;
height: 0;
padding-left: 0.5rem;
padding-right: 0.5rem;
}
.input-wrapper {
display: inline-block;
max-width: calc(100% - 5.5rem);
min-width: min(20rem, calc(100% - 5.5rem));
height: 2.5rem;
}
.input-label-wrapper {
display: flex;
justify-content: start;
}
.input-label-wrapper label {
position: relative;
top: 0.3rem;
}
.description {
margin-bottom: 1rem;
}
#submit-button {
display: block;
margin: auto;
margin-top: 2rem;
padding: 1rem 2rem;
font-size: 1.4rem;
font-family: var(--sans-serif,sans-serif);
border: 0rem solid black;
border-radius: 0.5rem;
background: #cb1816;
color: white;
}
#add-prompt {
margin-bottom: 2rem;
}
#groups-img {
position: absolute;
width: 14rem;
left: 50%;
transform: translate(-50%);
z-index: 0;
opacity: 0.2;
}
#text-container>:nth-child(3) {
margin-top: 8rem;
}
.country-name {
margin-bottom: 0.5rem;
}
.country-block {
margin-bottom: 2rem;
}
.location-info {
margin-bottom: 0.75rem;
}
.location-info p {
margin-bottom: 0;
}
a {
color: #DD1C1A;
}
#map {
--height: 30rem;
--width: 100%;
--margin-top: 2rem;
--margin-bottom: 0.5rem;
}
#text-container {
position: relative;
max-width: calc(100vw - 4rem);
margin: auto;
}
h1 {
margin-bottom: 1rem;
font-size: 2.2rem;
text-align: center;
}
h3 {
margin-bottom: 1rem;
}
#container {
margin: auto;
max-width: 800px;
margin-top: 1rem;
margin-bottom: 4rem;
}
#container p {
text-align: justify;
}
</style>

View File

@ -4,8 +4,9 @@
// Import statements // Import statements
import { onMount } from 'svelte' import { onMount } from 'svelte'
import { writable } from 'svelte/store'; import { writable } from 'svelte/store';
import { coopsByCountry, addMarkersCoops } from '/js/coops.js' import { loadLocaleContent, getData} from "/js/libraries/serverTools.js"
import { loadLocaleContent } from "/js/libraries/serverTools.js" import { addMarkersEntries, translate } from "/js/libraries/mapTools.js"
import { addCoopPinContent } from "/js/mapFuncs.js"
// Import components // Import components
import "/js/components/map-component.js" import "/js/components/map-component.js"
@ -13,21 +14,45 @@
// Main code // Main code
let loaded = writable(0) let loaded = writable(0)
let content = writable({}) let content = writable({})
let entries
let entriesByCountry
let locale = loadLocaleContent(content,"countries",loaded) let locale = loadLocaleContent(content,"cooperatives-component",loaded)
loadLocaleContent(content,"cooperatives-component",loaded) loadLocaleContent(content,"countries",loaded)
function mapCallbackCoops(createMap,content) { let callback = (response) => {
entries = JSON.parse(response)
entriesByCountry = {}
for (let g of entries) {
let country = g.country
if (g.contact==null) {
g.contact = "https://discord.gg/Qk8KUk787z"
}
if (country in entriesByCountry) {
entriesByCountry[country].push(g)
}
else {
entriesByCountry[country] = [g]
}
}
loaded.update((val) => {
return val + 1
})
}
getData("/assets/cooperatives.json",callback)
function mapCallback(createMap,content,locale) {
let map = createMap([22, 0],2) let map = createMap([22, 0],2)
addMarkersCoops(map,content,locale) addMarkersEntries(entries,entriesByCountry,map,content,locale,addCoopPinContent,"blue")
} }
function getCountry(name) { function getCountry(x) {
return locale=="en" ? name : $content[name] return locale=="en" ? x : translate($content,x)
} }
function getAddress(group) { function getAddress(g) {
return group.location[0].map(x => locale=="en" ? x : $content[x]).join(", ") let location = [g.country,g.state,g.town].filter(x => x!=null)
return location.map(x => locale=="en" ? x : translate($content,x)).join(", ")
} }
onMount(() => { onMount(() => {
@ -36,37 +61,38 @@
</script> </script>
{#key $loaded} {#key $loaded}
{#if $loaded==2} {#if $loaded==3}
<div id="container"> <div id="container">
<div id="text-container"> <div id="text-container">
<h1>{$content.cooperatives}</h1> <h1>{$content.cooperatives}</h1>
<img id="coops-img" src="/img/common/coops.svg" alt="coops"> <img id="coops-img" src="/img/common/coops.svg" alt="coops">
<p class="description">{$content.p1}</p> <p class="description">{$content.p1}</p>
<h3>{$content.subheading1}</h3> <h3>{$content.subheading1}</h3>
<map-component id="map" callback={(createMap) => mapCallbackCoops(createMap,$content,locale)}></map-component> <map-component id="map" callback={(createMap) => mapCallback(createMap,$content,locale)}></map-component>
<p id="add-prompt">{$content["map-prompt"]}</p> <p id="add-prompt">{$content["map-prompt"]}</p>
{#each Object.entries(coopsByCountry) as [name,coops]} {#each Object.entries(entriesByCountry) as [name,entries]}
<h4 class="country-name">{getCountry(name)}</h4> <h4 class="country-name">{getCountry(name)}</h4>
<div class="country-block"> <div class="country-block">
{#each coops as coop} {#each entries as entry}
{console.log(entry)}
<div class="location-info"> <div class="location-info">
<div class="img-general-info"> <div class="img-general-info">
<div> <div>
<p><b>{$content.name}: </b>{coop.name}</p> <p><b>{$content.name}: </b>{entry.name}</p>
<p><b>{$content.location}: </b>{getAddress(coop)}</p> <p><b>{$content.location}: </b>{getAddress(entry)}</p>
<p><b>{$content.market}: </b>{$content[coop.market]}</p> <p><b>{$content.market}: </b>{entry.market}</p>
<p><b>{$content.workers}: </b>{coop.workers}</p> <p><b>{$content.workers}: </b>{entry.workers}</p>
<p><b>{$content.status}: </b>{$content[coop.status]}</p> <p><b>{$content.status}: </b>{entry.status}</p>
<p><b>{$content.website}: </b><a href={coop.website[0]} target="_blank" rel=noreferrer>{coop.website[1]}</a></p> <p><b>{$content.website}: </b><a href={entry.website} target="_blank" rel=noreferrer>{entry.website}</a></p>
<p><b>{$content.contact}: </b><a href={coop.contact[0]} target=;_blank; rel=noreferrer>{$content[coop.contact[1]]}</a></p> <p><b>{$content.contact}: </b><a href={entry.contact} target=;_blank; rel=noreferrer>{entry.contact}</a></p>
</div> </div>
<picture> <picture>
<source srcset={"/img/coops/"+coop.logo+".webp"}> <source srcset={"/img/coops/"+entry.logo+".webp"}>
<source srcset={"/img/coops/"+coop.logo+".png"}> <source srcset={"/img/coops/"+entry.logo+".png"}>
<img class="coop-logo" alt="logo"> <img class="coop-logo" alt="logo">
</picture> </picture>
</div> </div>
<p><b>{$content.description}: </b>{$content[coop.description]}</p> <p><b>{$content.description}: </b>{entry.description}</p>
</div> </div>
{/each} {/each}
</div> </div>

View File

@ -4,8 +4,8 @@
// Import statements // Import statements
import { onMount } from 'svelte' import { onMount } from 'svelte'
import { writable } from 'svelte/store'; import { writable } from 'svelte/store';
import { addMarkersGroups, translate } from '/js/groups.js'
import { loadLocaleContent, getData, sendData } from "/js/libraries/serverTools.js" import { loadLocaleContent, getData, sendData } from "/js/libraries/serverTools.js"
import { addMarkersEntries, translate } from "/js/libraries/mapTools.js"
// Import components // Import components
import "/js/components/map-component.js" import "/js/components/map-component.js"
@ -13,22 +13,22 @@
// Main code // Main code
let loaded = writable(0) let loaded = writable(0)
let content = writable({}) let content = writable({})
let groups let entries
let groupsByCountry let entriesByCountry
let callback = (response) => { let callback = (response) => {
groups = JSON.parse(response) entries = JSON.parse(response)
groupsByCountry = {} entriesByCountry = {}
for (let g of groups) { for (let g of entries) {
let country = g.country let country = g.country
if (g.contact==null) { if (g.contact==null) {
g.contact = "https://discord.gg/Qk8KUk787z" g.contact = "https://discord.gg/Qk8KUk787z"
} }
if (country in groupsByCountry) { if (country in entriesByCountry) {
groupsByCountry[country].push(g) entriesByCountry[country].push(g)
} }
else { else {
groupsByCountry[country] = [g] entriesByCountry[country] = [g]
} }
} }
loaded.update((val) => { loaded.update((val) => {
@ -126,9 +126,37 @@
getData(url,callback) getData(url,callback)
} }
function mapCallbackGroups(createMap,content,locale) { function addGroupPinContent(g,content,locale) {
let coordinates
let text = "<b>"+content["Group"]+"</b><br>"
for (let field of ["location","members","contact"]) {
let fieldText = content[field] + ": "
if (field=="contact") {
text += fieldText + "<a href='" + g.contact + "' target='_blank' rel=noreferrer>" + g.contact + "</a>"
}
else if (field=="location") {
let location = [g.country,g.state,g.town].filter(x => x!=null && x!=undefined)
let locationString
if (locale=="en") {
locationString = location.map(x => x).join(", ")
}
else {
locationString = location.map(x => translate(content, x)).join(", ")
}
text += fieldText + locationString + "<br>"
coordinates = [g.latitude,g.longitude]
}
else {
text += fieldText + g[field] + "<br>"
}
}
return {text,coordinates}
}
function mapCallback(createMap,content,locale) {
let map = createMap([22, 0],2) let map = createMap([22, 0],2)
addMarkersGroups(groups,groupsByCountry,map,content,locale) addMarkersEntries(entries,entriesByCountry,map,content,locale,addGroupPinContent,"green")
userPin.addTo(map) userPin.addTo(map)
map.on('click', function(event) { map.on('click', function(event) {
@ -220,7 +248,7 @@
</div> </div>
<button id="submit-button" on:click={submitLocation}>Submit</button> <button id="submit-button" on:click={submitLocation}>Submit</button>
<p id="confirmation-msg" bind:this={confirmationMsg}></p> <p id="confirmation-msg" bind:this={confirmationMsg}></p>
<map-component id="map" callback={(createMap) => mapCallbackGroups(createMap,$content,locale)}></map-component> <map-component id="map" callback={(createMap) => mapCallback(createMap,$content,locale)}></map-component>
</div> </div>
</div> </div>
{/if} {/if}

View File

@ -4,8 +4,9 @@
// Import statements // Import statements
import { onMount } from 'svelte' import { onMount } from 'svelte'
import { writable } from 'svelte/store'; import { writable } from 'svelte/store';
import { addMarkersGroups, translate } from '/js/groups.js' import { loadLocaleContent, getData} from "/js/libraries/serverTools.js"
import { loadLocaleContent, getData, sendData } from "/js/libraries/serverTools.js" import { addMarkersEntries, translate } from "/js/libraries/mapTools.js"
import { addGroupPinContent } from "/js/mapFuncs.js"
// Import components // Import components
import "/js/components/map-component.js" import "/js/components/map-component.js"
@ -13,25 +14,25 @@
// Main code // Main code
let loaded = writable(0) let loaded = writable(0)
let content = writable({}) let content = writable({})
let groups let entries
let groupsByCountry let entriesByCountry
let locale = loadLocaleContent(content,"groups-component",loaded) let locale = loadLocaleContent(content,"groups-component",loaded)
loadLocaleContent(content,"countries",loaded) loadLocaleContent(content,"countries",loaded)
let callback = (response) => { let callback = (response) => {
groups = JSON.parse(response) entries = JSON.parse(response)
groupsByCountry = {} entriesByCountry = {}
for (let g of groups) { for (let g of entries) {
let country = g.country let country = g.country
if (g.contact==null) { if (g.contact==null) {
g.contact = "https://discord.gg/Qk8KUk787z" g.contact = "https://discord.gg/Qk8KUk787z"
} }
if (country in groupsByCountry) { if (country in entriesByCountry) {
groupsByCountry[country].push(g) entriesByCountry[country].push(g)
} }
else { else {
groupsByCountry[country] = [g] entriesByCountry[country] = [g]
} }
} }
loaded.update((val) => { loaded.update((val) => {
@ -40,9 +41,9 @@
} }
getData("/assets/groups.json",callback) getData("/assets/groups.json",callback)
function mapCallbackGroups(createMap,content,locale) { function mapCallback(createMap,content,locale) {
let map = createMap([22, 0],2) let map = createMap([22, 0],2)
addMarkersGroups(groups,groupsByCountry,map,content,locale) addMarkersEntries(entries,entriesByCountry,map,content,locale,addGroupPinContent,"green")
} }
function getCountry(x) { function getCountry(x) {
@ -68,16 +69,16 @@
<img id="groups-img" src="/img/common/groups.svg" alt="groups"> <img id="groups-img" src="/img/common/groups.svg" alt="groups">
<p class="description">{$content.p1}</p> <p class="description">{$content.p1}</p>
<h3>{$content.subheading1}</h3> <h3>{$content.subheading1}</h3>
<map-component id="map" callback={(createMap) => mapCallbackGroups(createMap,$content,locale)}></map-component> <map-component id="map" callback={(createMap) => mapCallback(createMap,$content,locale)}></map-component>
<p id="add-prompt">{$content["map-prompt"]}</p> <p id="add-prompt">{$content["map-prompt"]}</p>
{#each Object.entries(groupsByCountry) as [name,groups]} {#each Object.entries(entriesByCountry) as [name,entries]}
<h4 class="country-name">{getCountry(name)}</h4> <h4 class="country-name">{getCountry(name)}</h4>
<div class="country-block"> <div class="country-block">
{#each groups as group} {#each entries as entry}
<div class="location-info"> <div class="location-info">
<p><b>{$content.location}: </b>{getAddress(group)}</p> <p><b>{$content.location}: </b>{getAddress(entry)}</p>
<p><b>{$content.members}: </b>{group.members}</p> <p><b>{$content.members}: </b>{entry.members}</p>
<p><b>{$content.contact}: </b><a href={group.contact} target=;_blank; rel=noreferrer>{group.contact}</a></p> <p><b>{$content.contact}: </b><a href={entry.contact} target=;_blank; rel=noreferrer>{entry.contact}</a></p>
</div> </div>
{/each} {/each}
</div> </div>

View File

@ -4,11 +4,9 @@
// Import statements // Import statements
import { onMount } from 'svelte' import { onMount } from 'svelte'
import { writable } from 'svelte/store'; import { writable } from 'svelte/store';
import { addMarkersGroups, groupsMarkersLayer } from '/js/groups.js'
import { addMarkersCoops, coopsMarkersLayer } from '/js/coops.js'
import { addMarkersCommunes, communesMarkersLayer } from '/js/communes.js'
import { addMarkersParties, partiesMarkersLayer } from '/js/parties.js'
import { loadLocaleContent, getData } from "/js/libraries/serverTools.js" import { loadLocaleContent, getData } from "/js/libraries/serverTools.js"
import { addMarkersEntries, translate } from "/js/libraries/mapTools.js"
import { addGroupPinContent, addCommunePinContent, addCoopPinContent, addPartyPinContent } from "/js/mapFuncs.js"
// Import components // Import components
import "/js/components/map-component.js" import "/js/components/map-component.js"
@ -16,8 +14,8 @@
// Main code // Main code
let loaded = writable(0) let loaded = writable(0)
let content = writable({}) let content = writable({})
let groups let entries = {}
let groupsByCountry let entriesByCountry ={}
loadLocaleContent(content,"groups-component",loaded) loadLocaleContent(content,"groups-component",loaded)
loadLocaleContent(content,"communes-component",loaded) loadLocaleContent(content,"communes-component",loaded)
@ -27,40 +25,42 @@
let locale = loadLocaleContent(content,"join-us-component",loaded) let locale = loadLocaleContent(content,"join-us-component",loaded)
let callback = (response) => { let callback = (response,name) => {
groups = JSON.parse(response) entries[name] = JSON.parse(response)
groupsByCountry = {} entriesByCountry[name] = {}
for (let g of groups) { for (let g of entries[name]) {
let country = g.country let country = g.country
if (g.contact==null) { if (g.contact==null) {
g.contact = "https://discord.gg/Qk8KUk787z" g.contact = "https://discord.gg/Qk8KUk787z"
} }
if (country in groupsByCountry) { if (country in entriesByCountry[name]) {
groupsByCountry[country].push(g) entriesByCountry[name][country].push(g)
} }
else { else {
groupsByCountry[country] = [g] entriesByCountry[name][country] = [g]
} }
} }
loaded.update((val) => { loaded.update((val) => {
return val + 1 return val + 1
}) })
} }
getData("/assets/groups.json",callback) getData("/assets/groups.json",(response) => callback(response,"groups"))
getData("/assets/communes.json",(response) => callback(response,"communes"))
getData("/assets/cooperatives.json",(response) => callback(response,"cooperatives"))
getData("/assets/parties.json",(response) => callback(response,"parties"))
function mapCallback(createMap,content,locale) { function mapCallback(createMap,content,locale) {
let map = createMap([22, 0],2) let map = createMap([22, 0],2)
addMarkersGroups(groups,groupsByCountry,map,content,locale) let groupsMarkersLayer = addMarkersEntries(entries["groups"],entriesByCountry["groups"],map,content,locale,addGroupPinContent,"green")
addMarkersCommunes(map,content,locale) let communesMarkersLayer = addMarkersEntries(entries["communes"],entriesByCountry["communes"],map,content,locale,addCommunePinContent,"red")
addMarkersCoops(map,content,locale) let coopsMarkersLayer = addMarkersEntries(entries["cooperatives"],entriesByCountry["cooperatives"],map,content,locale,addCoopPinContent,"blue")
addMarkersParties(map,content,locale) let partiesMarkersLayer = addMarkersEntries(entries["parties"],entriesByCountry["parties"],map,content,locale,addPartyPinContent,"gold")
let overlayMaps = { let overlayMaps = {}
"Groups": groupsMarkersLayer, overlayMaps[content.groups] = groupsMarkersLayer
"Communes": communesMarkersLayer, overlayMaps[content.communes] = communesMarkersLayer
"Coops": coopsMarkersLayer, overlayMaps[content.cooperatives] = coopsMarkersLayer
"Parties": partiesMarkersLayer, overlayMaps[content.parties] = partiesMarkersLayer
}
L.control.layers(null, overlayMaps).addTo(map) L.control.layers(null, overlayMaps).addTo(map)
} }
@ -70,7 +70,7 @@
</script> </script>
{#key $loaded} {#key $loaded}
{#if $loaded==7} {#if $loaded==10}
<div id="container"> <div id="container">
<div id="text-container"> <div id="text-container">
<h1>{$content.heading}</h1> <h1>{$content.heading}</h1>
@ -101,7 +101,7 @@
<p>{$content.nearYou}</p> <p>{$content.nearYou}</p>
</div> </div>
<p>{$content.noneNear} <a href="https://chat.whatsapp.com/BhnmUNljUxJ2AjeHUwyTKh" target="_blank" rel=noreferrer>{$content.WhatsAppGroup}</a> {$content.or} <a href="https://discord.gg/Qk8KUk787z" target="_blank" rel=noreferrer>{$content.DiscordServer}</a>{$content.helpStart}</p> <p>{$content.noneNear} <a href="https://chat.whatsapp.com/BhnmUNljUxJ2AjeHUwyTKh" target="_blank" rel=noreferrer>{$content.WhatsAppGroup}</a> {$content.or} <a href="https://discord.gg/Qk8KUk787z" target="_blank" rel=noreferrer>{$content.DiscordServer}</a>{$content.helpStart}</p>
<map-component id="map" callback={(createMap) => mapCallback(createMap,$content,locale)}></map-component> <map-component id="map" callback={(createMap) => mapCallback(createMap,$content,locale)} colors={["#23AC20","#CA2437","#217BC9","#FFD326"]}></map-component>
</div> </div>
</div> </div>
{/if} {/if}

View File

@ -4,11 +4,9 @@
// Import statements // Import statements
import { onMount } from 'svelte' import { onMount } from 'svelte'
import { writable } from 'svelte/store'; import { writable } from 'svelte/store';
import { addMarkersGroups, groupsMarkersLayer, translate } from '/js/groups.js'
import { addMarkersCoops, coopsMarkersLayer } from '/js/coops.js'
import { addMarkersCommunes, communesMarkersLayer } from '/js/communes.js'
import { addMarkersParties, partiesMarkersLayer } from '/js/parties.js'
import { loadLocaleContent, getData } from "/js/libraries/serverTools.js" import { loadLocaleContent, getData } from "/js/libraries/serverTools.js"
import { addMarkersEntries, translate } from "/js/libraries/mapTools.js"
import { addGroupPinContent, addCommunePinContent, addCoopPinContent, addPartyPinContent } from "/js/mapFuncs.js"
// Import components // Import components
import "/js/components/map-component.js" import "/js/components/map-component.js"
@ -18,8 +16,8 @@
let gridWidth let gridWidth
let loaded = writable(0) let loaded = writable(0)
let content = writable({}) let content = writable({})
let groups let entries = {}
let groupsByCountry let entriesByCountry ={}
function changeWidth(locale) { function changeWidth(locale) {
if (locale=="ru") { if (locale=="ru") {
@ -30,26 +28,29 @@
} }
} }
let callback = (response) => { let callback = (response,name) => {
groups = JSON.parse(response) entries[name] = JSON.parse(response)
groupsByCountry = {} entriesByCountry[name] = {}
for (let g of groups) { for (let g of entries[name]) {
let country = g.country let country = g.country
if (g.contact==null) { if (g.contact==null) {
g.contact = "https://discord.gg/Qk8KUk787z" g.contact = "https://discord.gg/Qk8KUk787z"
} }
if (country in groupsByCountry) { if (country in entriesByCountry[name]) {
groupsByCountry[country].push(g) entriesByCountry[name][country].push(g)
} }
else { else {
groupsByCountry[country] = [g] entriesByCountry[name][country] = [g]
} }
} }
loaded.update((val) => { loaded.update((val) => {
return val + 1 return val + 1
}) })
} }
getData("/assets/groups.json",callback) getData("/assets/groups.json",(response) => callback(response,"groups"))
getData("/assets/communes.json",(response) => callback(response,"communes"))
getData("/assets/cooperatives.json",(response) => callback(response,"cooperatives"))
getData("/assets/parties.json",(response) => callback(response,"parties"))
loadLocaleContent(content,"groups-component",loaded) loadLocaleContent(content,"groups-component",loaded)
loadLocaleContent(content,"communes-component",loaded) loadLocaleContent(content,"communes-component",loaded)
@ -61,10 +62,10 @@
function mapCallback(createMap,content,locale) { function mapCallback(createMap,content,locale) {
let map = createMap([22, 0],2) let map = createMap([22, 0],2)
addMarkersGroups(groups,groupsByCountry,map,content,locale) let groupsMarkersLayer = addMarkersEntries(entries["groups"],entriesByCountry["groups"],map,content,locale,addGroupPinContent,"green")
addMarkersCommunes(map,content,locale) let communesMarkersLayer = addMarkersEntries(entries["communes"],entriesByCountry["communes"],map,content,locale,addCommunePinContent,"red")
addMarkersCoops(map,content,locale) let coopsMarkersLayer = addMarkersEntries(entries["cooperatives"],entriesByCountry["cooperatives"],map,content,locale,addCoopPinContent,"blue")
addMarkersParties(map,content,locale) let partiesMarkersLayer = addMarkersEntries(entries["parties"],entriesByCountry["parties"],map,content,locale,addPartyPinContent,"gold")
let overlayMaps = {} let overlayMaps = {}
overlayMaps[content.groups] = groupsMarkersLayer overlayMaps[content.groups] = groupsMarkersLayer
@ -81,7 +82,7 @@
</script> </script>
{#key $loaded} {#key $loaded}
{#if $loaded==7} {#if $loaded==10}
<div id="container"> <div id="container">
<picture> <picture>
<source srcset="/img/crowd.webp"> <source srcset="/img/crowd.webp">
@ -97,9 +98,9 @@
<p>{$content.groupsText}</p> <p>{$content.groupsText}</p>
</div> </div>
<div> <div>
<a href={"/" + locale + "/communes"}><h2>{$content.communesTitle}</h2></a> <a href={"/" + locale + "/parties"}><h2>{$content.partiesTitle}</h2></a>
<img id="communes-img" src="/img/common/commune.svg" alt="communes"> <img id="parties-img" src="/img/common/parties.svg" alt="coops">
<p>{$content.communesText}</p> <p>{$content.partiesText}</p>
</div> </div>
<div> <div>
<a href={"/" + locale + "/coops"}><h2>{$content.cooperativesTitle}</h2></a> <a href={"/" + locale + "/coops"}><h2>{$content.cooperativesTitle}</h2></a>
@ -107,9 +108,9 @@
<p>{$content.cooperativesText}</p> <p>{$content.cooperativesText}</p>
</div> </div>
<div> <div>
<a href={"/" + locale + "/parties"}><h2>{$content.partiesTitle}</h2></a> <a href={"/" + locale + "/communes"}><h2>{$content.communesTitle}</h2></a>
<img id="parties-img" src="/img/common/parties.svg" alt="coops"> <img id="communes-img" src="/img/common/communes.svg" alt="communes">
<p>{$content.partiesText}</p> <p>{$content.communesText}</p>
</div> </div>
</div> </div>
<!-- <!--

View File

@ -0,0 +1,413 @@
<svelte:options tag="parties-add-component" />
<script>
// Import statements
import { onMount } from 'svelte'
import { writable } from 'svelte/store';
import { loadLocaleContent, getData, sendData } from "/js/libraries/serverTools.js"
import { addMarkersEntries, translate } from "/js/libraries/mapTools.js"
// Import components
import "/js/components/map-component.js"
// Main code
let loaded = writable(0)
let content = writable({})
let entries
let entriesByCountry
let callback = (response) => {
entries = JSON.parse(response)
entriesByCountry = {}
for (let g of entries) {
let country = g.country
if (g.contact==null) {
g.contact = "https://discord.gg/Qk8KUk787z"
}
if (country in entriesByCountry) {
entriesByCountry[country].push(g)
}
else {
entriesByCountry[country] = [g]
}
}
loaded.update((val) => {
return val + 1
})
}
getData("/assets/parties.json",callback)
let confirmationMsg
let addressInput
let contactInput
let addressVec
let userPinLat = 0
let userPinLng = 0
let userPin = createPin(0,0)
userPin.setOpacity(0)
let locale = loadLocaleContent(content,"parties-component",loaded)
loadLocaleContent(content,"countries",loaded)
function createPin(lat,lng) {
let markerIcon = new L.Icon({
iconUrl: '/img/common/markers/marker-black.png',
shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/images/marker-shadow.png',
iconSize: [25, 41],
iconAnchor: [12, 41],
popupAnchor: [1, -34],
shadowSize: [41, 41]
})
return L.marker([lat,lng], {icon: markerIcon})
}
function updatePin(marker,lat,lng) {
let newLatLng = L.latLng(lat, lng); // Replace with the desired coordinates
marker.setLatLng(newLatLng)
}
function reverseGeocodeLocal(latitude, longitude) {
let url = `https://nominatim.openstreetmap.org/reverse?lat=${latitude}&lon=${longitude}&format=jsonv2`;
let callback = (response) => {
// Parse the response JSON
response = JSON.parse(response)
// Extract the address information from the response
let address = response.address
let city = address.city || address.town || address.village || address.hamlet
let state = address.state
let country = address.country
let fullAddress = country
if (state!=undefined) {
fullAddress += ", " + state
}
else {
state = ""
}
if (city!=undefined) {
fullAddress += ", " + city
}
else {
city = ""
}
addressInput.value = fullAddress
resizeInput(addressInput)
}
getData(url,callback)
}
function reverseGeocode(latitude, longitude) {
let url = `https://nominatim.openstreetmap.org/reverse?lat=${latitude}&lon=${longitude}&format=jsonv2&accept-language=en`;
let callback = (response) => {
// Parse the response JSON
response = JSON.parse(response)
// Extract the address information from the response
let address = response.address
let city = address.city || address.town || address.village || address.hamlet
let state = address.state
let country = address.country
let fullAddress = country
if (state!=undefined) {
fullAddress += ", " + state
}
else {
state = ""
}
if (city!=undefined) {
fullAddress += ", " + city
}
else {
city = ""
}
addressVec = [country,state,city]
}
getData(url,callback)
}
function addGroupPinContent(g,content,locale) {
let coordinates
let text = "<b>"+content["Group"]+"</b><br>"
for (let field of ["location","members","contact"]) {
let fieldText = content[field] + ": "
if (field=="contact") {
text += fieldText + "<a href='" + g.contact + "' target='_blank' rel=noreferrer>" + g.contact + "</a>"
}
else if (field=="location") {
let location = [g.country,g.state,g.town].filter(x => x!=null && x!=undefined)
let locationString
if (locale=="en") {
locationString = location.map(x => x).join(", ")
}
else {
locationString = location.map(x => translate(content, x)).join(", ")
}
text += fieldText + locationString + "<br>"
coordinates = [g.latitude,g.longitude]
}
else {
text += fieldText + g[field] + "<br>"
}
}
return {text,coordinates}
}
function mapCallback(createMap,content,locale) {
let map = createMap([22, 0],2)
addMarkersEntries(entries,entriesByCountry,map,content,locale,addGroupPinContent,"green")
userPin.addTo(map)
map.on('click', function(event) {
let lat = event.latlng.lat;
let lng = event.latlng.lng;
userPinLat = lat
userPinLng = lng
updatePin(userPin,lat,lng)
userPin.setOpacity(1)
reverseGeocodeLocal(lat, lng)
reverseGeocode(lat, lng)
})
}
function updateConfirmationMsg(response) {
if (response!==false) {
confirmationMsg.innerHTML = "You have been added to our database! Now go to our Discord to verify yourself."
confirmationMsg.style.color = "green"
}
else {
confirmationMsg.innerHTML = "Something went wrong."
confirmationMsg.style.color = "red"
}
}
function submitLocation() {
if (addressVec!=undefined) {
let data = {
country: addressVec[0],
state: addressVec[1],
town: addressVec[2],
latitude: userPinLat,
longitude: userPinLng,
contact: contactInput.value
}
if (data.state=="") {
data.state = null
}
if (data.town=="") {
data.town = null
}
if (data.contact=="") {
data.contact = null
}
let url = "/" + locale + "/parties-add-post/"
sendData(url,data,updateConfirmationMsg)
}
}
function resizeInput(el) {
el.nextElementSibling.innerHTML = el.value
}
onMount(() => {
})
</script>
{#key $loaded}
{#if $loaded==3}
<div id="container">
<!--<img src="img/crowd.png" id="crowd" alt="crowd">-->
<div id="text-container">
<h1>Add a Party</h1>
<img id="parties-img" src="/img/common/parties.svg" alt="parties">
<p class="description">If there are no parties in your country which you can join then do the following:</p>
<ol>
<li>Click on the map to show us where you are located;</li>
<li>Add a way to contact you or leave blank for a pin to point to our discord;</li>
<li>Press "Submit" to add yourself to our map;</li>
<li>Verify yourself by having a chat with us at our Discord server to show on the map;</li>
</ol>
<div id="address-input-wrapper" class="input-label-wrapper">
<label for="address-input">Location: </label>
<div class="input-wrapper">
<input bind:this={addressInput} on:input={() => resizeInput(addressInput)} id="address-input" type="text" readonly>
<div class="ghost-input"></div>
</div>
</div>
<div class="input-label-wrapper">
<label for="contact-input">Contact: </label>
<div class="input-wrapper">
<input bind:this={contactInput} on:input={() => resizeInput(contactInput)} id="contact-input" type="text">
<div class="ghost-input"></div>
</div>
</div>
<button id="submit-button" on:click={submitLocation}>Submit</button>
<p id="confirmation-msg" bind:this={confirmationMsg}></p>
<map-component id="map" callback={(createMap) => mapCallback(createMap,$content,locale)}></map-component>
</div>
</div>
{/if}
{/key}
<style>
@import '/css/common.css';
#confirmation-msg {
margin-top: 0.5rem;
margin-bottom: 2rem;
}
ol li {
margin-left: 3rem;
margin-bottom: 0.5rem;
}
label {
display: inline-block;
font-family: var(--serif,serif);
font-size: 1.15rem;
line-height: 160%;
color: #222222;
width: 5.5rem;
}
input, .ghost-input {
font-size: 1.15rem;
font-family: var(--serif,serif);
}
input {
height: 2.5rem;
display: inline-block;
position: relative;
}
#address-input, #contact-input {
width: 100%;
}
#address-input-wrapper {
margin-top: 2rem;
margin-bottom: 1rem;
}
.ghost-input {
display: block;
visibility: hidden;
height: 0;
padding-left: 0.5rem;
padding-right: 0.5rem;
}
.input-wrapper {
display: inline-block;
max-width: calc(100% - 5.5rem);
min-width: min(20rem, calc(100% - 5.5rem));
height: 2.5rem;
}
.input-label-wrapper {
display: flex;
justify-content: start;
}
.input-label-wrapper label {
position: relative;
top: 0.3rem;
}
.description {
margin-bottom: 1rem;
}
#submit-button {
display: block;
margin: auto;
margin-top: 2rem;
padding: 1rem 2rem;
font-size: 1.4rem;
font-family: var(--sans-serif,sans-serif);
border: 0rem solid black;
border-radius: 0.5rem;
background: #cb1816;
color: white;
}
#add-prompt {
margin-bottom: 2rem;
}
#parties-img {
position: absolute;
width: 14rem;
left: 50%;
transform: translate(-50%);
z-index: 0;
opacity: 0.2;
}
#text-container>:nth-child(3) {
margin-top: 8rem;
}
.country-name {
margin-bottom: 0.5rem;
}
.country-block {
margin-bottom: 2rem;
}
.location-info {
margin-bottom: 0.75rem;
}
.location-info p {
margin-bottom: 0;
}
a {
color: #DD1C1A;
}
#map {
--height: 30rem;
--width: 100%;
--margin-top: 2rem;
--margin-bottom: 0.5rem;
}
#text-container {
position: relative;
max-width: calc(100vw - 4rem);
margin: auto;
}
h1 {
margin-bottom: 1rem;
font-size: 2.2rem;
text-align: center;
}
h3 {
margin-bottom: 1rem;
}
#container {
margin: auto;
max-width: 800px;
margin-top: 1rem;
margin-bottom: 4rem;
}
#container p {
text-align: justify;
}
</style>

View File

@ -4,8 +4,9 @@
// Import statements // Import statements
import { onMount } from 'svelte' import { onMount } from 'svelte'
import { writable } from 'svelte/store'; import { writable } from 'svelte/store';
import { partiesByCountry, addMarkersParties } from '/js/parties.js' import { loadLocaleContent, getData} from "/js/libraries/serverTools.js"
import { loadLocaleContent } from "/js/libraries/serverTools.js" import { addMarkersEntries, translate } from "/js/libraries/mapTools.js"
import { addPartyPinContent } from "/js/mapFuncs.js"
// Import components // Import components
import "/js/components/map-component.js" import "/js/components/map-component.js"
@ -13,21 +14,45 @@
// Main code // Main code
let loaded = writable(0) let loaded = writable(0)
let content = writable({}) let content = writable({})
let entries
let entriesByCountry
loadLocaleContent(content,"countries",loaded)
let locale = loadLocaleContent(content,"parties-component",loaded) let locale = loadLocaleContent(content,"parties-component",loaded)
loadLocaleContent(content,"countries",loaded)
function mapCallbackParties(createMap,content,locale) { let callback = (response) => {
entries = JSON.parse(response)
entriesByCountry = {}
for (let g of entries) {
let country = g.country
if (g.contact==null) {
g.contact = "https://discord.gg/Qk8KUk787z"
}
if (country in entriesByCountry) {
entriesByCountry[country].push(g)
}
else {
entriesByCountry[country] = [g]
}
}
loaded.update((val) => {
return val + 1
})
}
getData("/assets/parties.json",callback)
function mapCallback(createMap,content,locale) {
let map = createMap([22, 0],2) let map = createMap([22, 0],2)
addMarkersParties(map,content,locale) addMarkersEntries(entries,entriesByCountry,map,content,locale,addPartyPinContent,"gold")
} }
function getCountry(name) { function getCountry(x) {
return locale=="en" ? name : $content[name] return locale=="en" ? x : translate($content,x)
} }
function getAddress(group) { function getAddress(g) {
return locale=="en" ? group.location : $content[group.location] let location = [g.country,g.state,g.town].filter(x => x!=null)
return location.map(x => locale=="en" ? x : translate($content,x)).join(", ")
} }
onMount(() => { onMount(() => {
@ -36,7 +61,7 @@
</script> </script>
{#key $loaded} {#key $loaded}
{#if $loaded==2} {#if $loaded==3}
<div id="container"> <div id="container">
<!--<img src="img/crowd.png" id="crowd" alt="crowd">--> <!--<img src="img/crowd.png" id="crowd" alt="crowd">-->
<div id="text-container"> <div id="text-container">
@ -44,26 +69,27 @@
<img id="party-img" src="/img/common/parties.svg" alt="party"> <img id="party-img" src="/img/common/parties.svg" alt="party">
<p class="description">{$content.p1}</p> <p class="description">{$content.p1}</p>
<h3>{$content.subheading1}</h3> <h3>{$content.subheading1}</h3>
<map-component id="map" callback={(createMap) => mapCallbackParties(createMap,$content,locale)}></map-component> <map-component id="map" callback={(createMap) => mapCallback(createMap,$content,locale)}></map-component>
<p id="add-prompt">{$content["map-prompt"]}</p> <p id="add-prompt">{$content["map-prompt"]}</p>
{#each Object.entries(partiesByCountry) as [name,parties]} {#each Object.entries(entriesByCountry) as [name,entries]}
<h4 class="country-name">{getCountry(name)}</h4> <h4 class="country-name">{getCountry(name)}</h4>
<div class="country-block"> <div class="country-block">
{#each parties as party} {#each entries as entry}
<div class="location-info"> <div class="location-info">
<div class="img-general-info"> <div class="img-general-info">
<picture> <picture>
<source srcset={"/img/parties/"+party.logo+".webp"}> <source srcset={"/img/parties/"+entry.logo+".webp"}>
<source srcset={"/img/parties/"+party.logo+".jpg"}> <source srcset={"/img/parties/"+entry.logo+".jpg"}>
<img class="party-logo" alt="logo"> <img class="party-logo" alt="logo">
</picture> </picture>
<div> <div>
<p><b>{$content.name}: </b>{party.name}</p> <p><b>{$content.name}: </b>{entry.name}</p>
<p><b>{$content.location}: </b>{getAddress(party)}</p> <p><b>{$content.location}: </b>{getAddress(entry)}</p>
<p><b>{$content.link}: </b><a href={party.link} target=;_blank; rel=noreferrer>{party.link}</a></p> <p><b>{$content.website}: </b><a href={entry.website} target=;_blank; rel=noreferrer>{entry.website}</a></p>
<p><b>{$content.contact}: </b><a href={entry.contact} target=;_blank; rel=noreferrer>{entry.contact}</a></p>
</div> </div>
</div> </div>
<p><b>{$content.description}: </b>{$content[party.description]}</p> <p><b>{$content.description}: </b>{$content[entry.description]}</p>
</div> </div>
{/each} {/each}
</div> </div>
@ -134,7 +160,7 @@
.party-logo { .party-logo {
position: relative; position: relative;
right: 0; right: 0;
max-height: 5.5rem; max-height: 6.5rem;
max-width: 100%; max-width: 100%;
border-radius: 1rem; border-radius: 1rem;
} }

View File

@ -0,0 +1,195 @@
<svelte:options tag="partners-component" />
<script>
// Import statements
import { onMount } from 'svelte'
import { writable } from 'svelte/store';
import { loadLocaleContent, getData} from "/js/libraries/serverTools.js"
import { addMarkersEntries, translate } from "/js/libraries/mapTools.js"
// Import components
import "/js/components/map-component.js"
// Main code
let loaded = writable(0)
let content = writable({})
let entries
let entriesByCountry
let locale = loadLocaleContent(content,"groups-component",loaded)
loadLocaleContent(content,"countries",loaded)
let callback = (response) => {
entries = JSON.parse(response)
entriesByCountry = {}
for (let g of entries) {
let country = g.country
if (g.contact==null) {
g.contact = "https://discord.gg/Qk8KUk787z"
}
if (country in entriesByCountry) {
entriesByCountry[country].push(g)
}
else {
entriesByCountry[country] = [g]
}
}
loaded.update((val) => {
return val + 1
})
}
getData("/assets/groups.json",callback)
function addGroupPinContent(g,content,locale) {
let coordinates
let text = "<b>"+content["Group"]+"</b><br>"
for (let field of ["location","members","contact"]) {
let fieldText = content[field] + ": "
if (field=="contact") {
text += fieldText + "<a href='" + g.contact + "' target='_blank' rel=noreferrer>" + g.contact + "</a>"
}
else if (field=="location") {
let location = [g.country,g.state,g.town].filter(x => x!=null && x!=undefined)
let locationString
if (locale=="en") {
locationString = location.map(x => x).join(", ")
}
else {
locationString = location.map(x => translate(content, x)).join(", ")
}
text += fieldText + locationString + "<br>"
coordinates = [g.latitude,g.longitude]
}
else {
text += fieldText + g[field] + "<br>"
}
}
return {text,coordinates}
}
function mapCallback(createMap,content,locale) {
let map = createMap([22, 0],2)
addMarkersEntries(entries,entriesByCountry,map,content,locale,addGroupPinContent,"green")
}
function getCountry(x) {
return locale=="en" ? x : translate($content,x)
}
function getAddress(g) {
let location = [g.country,g.state,g.town].filter(x => x!=null)
return location.map(x => locale=="en" ? x : translate($content,x)).join(", ")
}
onMount(() => {
})
</script>
{#key $loaded}
{#if $loaded==3}
<div id="container">
<!--<img src="img/crowd.png" id="crowd" alt="crowd">-->
<div id="text-container">
<h1>{$content.groups}</h1>
<img id="groups-img" src="/img/common/groups.svg" alt="groups">
<p class="description">{$content.p1}</p>
<h3>{$content.subheading1}</h3>
<map-component id="map" callback={(createMap) => mapCallback(createMap,$content,locale)}></map-component>
<p id="add-prompt">{$content["map-prompt"]}</p>
{#each Object.entries(entriesByCountry) as [name,entries]}
<h4 class="country-name">{getCountry(name)}</h4>
<div class="country-block">
{#each entries as entry}
<div class="location-info">
<p><b>{$content.location}: </b>{getAddress(entry)}</p>
<p><b>{$content.members}: </b>{entry.members}</p>
<p><b>{$content.contact}: </b><a href={entry.contact} target=;_blank; rel=noreferrer>{entry.contact}</a></p>
</div>
{/each}
</div>
{/each}
</div>
</div>
{/if}
{/key}
<style>
@import '/css/common.css';
.description {
margin-bottom: 1rem;
}
#add-prompt {
margin-bottom: 2rem;
}
#groups-img {
position: absolute;
width: 14rem;
left: 50%;
transform: translate(-50%);
z-index: 0;
opacity: 0.2;
}
#text-container>:nth-child(3) {
margin-top: 8rem;
}
.country-name {
margin-bottom: 0.5rem;
}
.country-block {
margin-bottom: 2rem;
}
.location-info {
margin-bottom: 0.75rem;
}
.location-info p {
margin-bottom: 0;
}
a {
color: #DD1C1A;
}
#map {
--height: 30rem;
--width: 100%;
--margin-bottom: 0.5rem;
}
#text-container {
position: relative;
max-width: calc(100vw - 4rem);
margin: auto;
}
h1 {
margin-bottom: 1rem;
font-size: 2.2rem;
text-align: center;
}
h3 {
margin-bottom: 1rem;
}
#container {
margin: auto;
max-width: 800px;
margin-top: 1rem;
margin-bottom: 4rem;
}
#container p {
text-align: justify;
}
</style>

View File

@ -4,25 +4,55 @@
// Import statements // Import statements
import { onMount } from 'svelte' import { onMount } from 'svelte'
import { writable } from 'svelte/store'; import { writable } from 'svelte/store';
import { loadLocaleContent } from "/js/libraries/serverTools.js" import { loadLocaleContent, getData} from "/js/libraries/serverTools.js"
import { partnersByCountry } from '/js/partners.js' import { addMarkersEntries, translate } from "/js/libraries/mapTools.js"
import { addPartnersPinContent } from "/js/mapFuncs.js"
// Import components // Import components
import "/js/components/map-component.js" import "/js/components/map-component.js"
// Main code // Main code
let loaded = writable(0) let loaded = writable(0)
let content = writable({}) let content = writable({})
let entries
let entriesByCountry
loadLocaleContent(content,"countries",loaded)
let locale = loadLocaleContent(content,"partners-component",loaded) let locale = loadLocaleContent(content,"partners-component",loaded)
loadLocaleContent(content,"countries",loaded)
function getCountry(name) { let callback = (response) => {
return locale=="en" ? name : $content[name] entries = JSON.parse(response)
entriesByCountry = {}
for (let g of entries) {
let country = g.country
if (g.contact==null) {
g.contact = "https://discord.gg/Qk8KUk787z"
}
if (country in entriesByCountry) {
entriesByCountry[country].push(g)
}
else {
entriesByCountry[country] = [g]
}
}
loaded.update((val) => {
return val + 1
})
}
getData("/assets/partners.json",callback)
function mapCallback(createMap,content,locale) {
let map = createMap([22, 0],2)
addMarkersEntries(entries,entriesByCountry,map,content,locale,addPartnersPinContent,"blue")
} }
function getAddress(group) { function getCountry(x) {
return group.location[0].map(x => locale=="en" ? x : $content[x]).join(", ") return locale=="en" ? x : translate($content,x)
}
function getAddress(g) {
let location = [g.country,g.state,g.town].filter(x => x!=null)
return location.map(x => locale=="en" ? x : translate($content,x)).join(", ")
} }
onMount(() => { onMount(() => {
@ -31,7 +61,7 @@
</script> </script>
{#key $loaded} {#key $loaded}
{#if $loaded==2} {#if $loaded==3}
<div id="container"> <div id="container">
<!--<img src="img/crowd.png" id="crowd" alt="crowd">--> <!--<img src="img/crowd.png" id="crowd" alt="crowd">-->
<div id="text-container"> <div id="text-container">
@ -39,25 +69,27 @@
<img id="hands-img" src="/img/common/handshake.svg" alt="hands"> <img id="hands-img" src="/img/common/handshake.svg" alt="hands">
<p>{$content.p1}</p> <p>{$content.p1}</p>
<h3>{$content.subheading1}</h3> <h3>{$content.subheading1}</h3>
{#each Object.entries(partnersByCountry) as [name,partners]} <map-component id="map" callback={(createMap) => mapCallback(createMap,$content,locale)}></map-component>
<p id="add-prompt">{$content["map-prompt"]}</p>
{#each Object.entries(entriesByCountry) as [name,entries]}
<h4 class="country-name">{getCountry(name)}</h4> <h4 class="country-name">{getCountry(name)}</h4>
<div class="country-block"> <div class="country-block">
{#each partners as partner} {#each entries as entry}
<div class="location-info"> <div class="location-info">
<div class="img-general-info"> <div class="img-general-info">
<picture> <picture>
<source srcset={"/img/partners/"+partner.logo+".webp"}> <source srcset={"/img/partners/"+entry.logo+".webp"}>
<source srcset={"/img/partners/"+partner.logo+".jpg"}> <source srcset={"/img/partners/"+entry.logo+".jpg"}>
<img class="partner-logo" alt="logo"> <img class="partner-logo" alt="logo">
</picture> </picture>
<div> <div>
<p><b>{$content.name}: </b>{partner.name}</p> <p><b>{$content.name}: </b>{entry.name}</p>
<p><b>{$content.type}: </b>{$content[partner.type]}</p> <p><b>{$content.location}: </b>{getAddress(entry)}</p>
<p><b>{$content.location}: </b>{getAddress(partner)}</p> <p><b>{$content.website}: </b><a href={entry.website} target=;_blank; rel=noreferrer>{entry.website}</a></p>
<p><b>{$content.link}: </b><a href={partner.link} target=;_blank; rel=noreferrer>{partner.link}</a></p> <p><b>{$content.contact}: </b><a href={entry.website} target=;_blank; rel=noreferrer>{entry.contact}</a></p>
</div> </div>
</div> </div>
<p><b>{$content.description}: </b>{$content[partner.description]}</p> <p><b>{$content.description}: </b>{entry.description}</p>
</div> </div>
{/each} {/each}
</div> </div>
@ -133,7 +165,7 @@
#map { #map {
--height: 30rem; --height: 30rem;
--width: 100%; --width: 100%;
--margin-bottom: 3rem; --margin-bottom: 0.5rem;
} }
#text-container { #text-container {
@ -148,7 +180,7 @@
} }
h3 { h3 {
margin-bottom: 2rem; margin-bottom: 1rem;
} }
#container { #container {

View File

@ -18,14 +18,14 @@ function table_to_json(name,df)
end end
end end
function compile_groups() function compile(name)
df = select_from_table(["groups" => ["*"]]) df = select_from_table([name => ["*"]])
table_to_json("groups",df) table_to_json(name,df)
end end
function move_requests() function move_requests(name)
df_requests = select_from_table(["groups_requests" => ["*"]], where_data=["verified" => true, "added" => false]) df_requests = select_from_table(["$(name)_requests" => ["*"]], where_data=["verified" => true, "added" => false])
df = select_from_table(["groups" => ["*"]]) df = select_from_table([name => ["*"]])
latitudes = df.latitude latitudes = df.latitude
longitudes = df.longitude longitudes = df.longitude
for df_row in eachrow(df_requests) for df_row in eachrow(df_requests)
@ -35,11 +35,11 @@ function move_requests()
row_found = df[ind_id_given,Not(:id)] row_found = df[ind_id_given,Not(:id)]
dict = Dict(zip(names(row_found),values(row_found))) dict = Dict(zip(names(row_found),values(row_found)))
dict["members"] += 1 dict["members"] += 1
update_table("groups",dict, where_data=["id" => id]) update_table(name,dict, where_data=["id" => id])
else else
id = df_row.id id = df_row.id
dict_update = Dict("added" => true) dict_update = Dict("added" => true)
update_table("groups_requests",dict_update, where_data=["id" => id]) update_table("$(name)_requests",dict_update, where_data=["id" => id])
df_row_to_add = df_row[Not(:id_given)] df_row_to_add = df_row[Not(:id_given)]
df_row_to_add = df_row_to_add[Not(:verified)] df_row_to_add = df_row_to_add[Not(:verified)]
@ -47,11 +47,20 @@ function move_requests()
df_row_to_add = df_row_to_add[Not(:id)] df_row_to_add = df_row_to_add[Not(:id)]
dict = Dict(zip(names(df_row_to_add),values(df_row_to_add))) dict = Dict(zip(names(df_row_to_add),values(df_row_to_add)))
dict["members"] = 1 dict["members"] = 1
insert_into_table("groups",dict) insert_into_table(name,dict)
end end
end end
end end
move_requests() move_requests("groups")
compile_groups() compile("groups")
move_requests("communes")
compile("communes")
compile("cooperatives")
compile("parties")
compile("partners")

View File

@ -0,0 +1 @@
[{"town":"Saalfeld/Saale","contact":null,"latitude":50.61764000625769,"status":"forming","longitude":11.25,"id":1,"members":1,"country":"Germany","state":"Thuringia"}]

View File

@ -0,0 +1 @@
[{"market":"wellness and health","state":null,"town":"Kohtla-Järve","name":"Chiron Health","status":"in development","id":1,"description":"Chiron Health is a health platform providing courses and services on the topics of nutrition, exercise, sleep and mental wellbeing.","country":"Estonia","workers":2,"contact":"https://discord.gg/Qk8KUk787z","latitude":59.41038769769602,"longitude":27.287802936242034,"logo":"1690553207","website":"https://www.chrn.health"}]

View File

@ -0,0 +1 @@
[{"latitude":52.98479517270413,"name":"Roots","longitude":-7.649233227534782,"id":1,"logo":"1690554940","website":" ","members":null,"description":"descriptionRoots","country":"Ireland","contact":"https://discord.gg/pSTMacJZsK"}]

View File

@ -0,0 +1 @@
[{"state":null,"town":null,"name":"Gaia's Fall","id":1,"description":"Gaia's Fall is a server that promotes Solarpunk ideals, environmentalism, anarchism, and anti-capitalism. We encourage civil debates, discussions of theories and possibilities, and the creation of communities focused on shaping a better world.","country":"Online","contact":"https://discord.gg/xAPZmyr8B6","latitude":null,"longitude":null,"logo":"1690554942","website":" "}]

View File

Before

Width:  |  Height:  |  Size: 210 B

After

Width:  |  Height:  |  Size: 210 B

View File

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

View File

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 8.1 KiB

View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

View File

Before

Width:  |  Height:  |  Size: 165 KiB

After

Width:  |  Height:  |  Size: 165 KiB

View File

Before

Width:  |  Height:  |  Size: 93 KiB

After

Width:  |  Height:  |  Size: 93 KiB

View File

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 49 KiB

View File

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 35 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
import{S as e,i as s,a as t,b as o,s as i,f as a,n as r,h as n,d as c,o as d}from"./index-4348483d.js";function p(e){let s;return{c(){s=a("div"),s.innerHTML="<div><p>We use cookies to improve your experience, personalise your content and analyse site usage. By clicking “OK”, you agree to the use of cookies.</p></div>",this.c=r,n(s,"id","wrapper")},m(e,t){o(e,s,t)},p:r,i:r,o:r,d(e){e&&c(s)}}}function u(e){return d((()=>{})),[]}class h extends e{constructor(e){super(),this.shadowRoot.innerHTML="<style>@import '/css/common.css';#wrapper{display:none;position:relative;height:5rem;width:100%;background:white;box-shadow:0 0 0.314rem rgb(187, 187, 187);;}</style>",s(this,{target:this.shadowRoot,props:t(this.attributes),customElement:!0},u,p,i,{},null),e&&e.target&&o(e.target,this,e.anchor)}}customElements.define("cookies-dialog",h);export{h as default}; import{S as e,i as s,a as t,b as o,s as i,g as a,n as r,j as n,d as c,o as d}from"./index-8c09578c.js";function p(e){let s;return{c(){s=a("div"),s.innerHTML="<div><p>We use cookies to improve your experience, personalise your content and analyse site usage. By clicking “OK”, you agree to the use of cookies.</p></div>",this.c=r,n(s,"id","wrapper")},m(e,t){o(e,s,t)},p:r,i:r,o:r,d(e){e&&c(s)}}}function u(e){return d((()=>{})),[]}class h extends e{constructor(e){super(),this.shadowRoot.innerHTML="<style>@import '/css/common.css';#wrapper{display:none;position:relative;height:5rem;width:100%;background:white;box-shadow:0 0 0.314rem rgb(187, 187, 187);;}</style>",s(this,{target:this.shadowRoot,props:t(this.attributes),customElement:!0},u,p,i,{},null),e&&e.target&&o(e.target,this,e.anchor)}}customElements.define("cookies-dialog",h);export{h as default};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
import{S as t,i as e,a as o,b as r,s as a,e as i,n,d as s,c as m,f as c,t as f,g as d,h as l,v as g,l as h,q as p,m as u}from"./index-4348483d.js";import{w as b}from"./index-71440b21.js";import{loadLocaleContent as w}from"../../../../../../../../../js/libraries/serverTools.js";function v(t){let e,o,a,i,n,m,b,w,v,k,y,x,L,j,z,U,_,C,T,B,H,M,R=t[1].contactUs+"",A=t[1].inviteLink+"",D=t[1].inviteLink+"";return{c(){e=c("footer"),o=c("div"),a=c("div"),i=c("div"),n=c("h2"),m=f(R),b=d(),w=c("p"),v=f("Discord: "),k=c("a"),y=f(A),x=d(),L=c("p"),j=f("WhatsApp: "),z=c("a"),U=f(D),_=d(),C=c("button"),C.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="42.545" height="72.601" viewBox="0 0 42.545 72.601"><g id="Group_268" data-name="Group 268" transform="translate(-6.177 -2.399)"><rect id="Rectangle_146" data-name="Rectangle 146" width="11" height="51" rx="5.5" transform="translate(22 24)" fill="#cb1816"></rect><path id="Path_1145" data-name="Path 1145" d="M23.814,4.021a5,5,0,0,1,7.372,0l16.134,17.6c2.94,3.207,1.046,10.4-3.686,8.379S28.02,14.081,28.391,13.524,16.544,27.976,11.366,30,4.741,24.828,7.68,21.621Z" fill="#DD1C1A"></path></g></svg>',T=d(),B=c("p"),B.innerHTML='Licensed under a Creative Commons <a href="https://creativecommons.org/licenses/by/4.0/legalcode " target="_blank" rel="noreferrer">CC BY 4.0 license</a>',l(k,"href","https://discord.gg/Qk8KUk787z"),l(k,"target","_blank"),l(k,"rel","noreferrer"),g(k,"margin-left","1.8rem"),l(z,"href","https://chat.whatsapp.com/BhnmUNljUxJ2AjeHUwyTKh"),l(z,"target","_blank"),l(z,"rel","noreferrer"),g(z,"margin-left","0.5rem"),l(i,"id","contact-us-container"),l(a,"id","footer-grid-content-container"),l(a,"class","logged"),l(C,"id","footer-up"),l(C,"aria-label","go up"),l(B,"id","footer-copyright"),l(o,"id","footer-content-container")},m(s,c){r(s,e,c),h(e,o),h(o,a),h(a,i),h(i,n),h(n,m),h(i,b),h(i,w),h(w,v),h(w,k),h(k,y),h(i,x),h(i,L),h(L,j),h(L,z),h(z,U),h(o,_),h(o,C),h(o,T),h(o,B),H||(M=p(C,"click",t[4]),H=!0)},p(t,e){2&e&&R!==(R=t[1].contactUs+"")&&u(m,R),2&e&&A!==(A=t[1].inviteLink+"")&&u(y,A),2&e&&D!==(D=t[1].inviteLink+"")&&u(U,D)},d(t){t&&s(e),H=!1,M()}}}function k(t){let e,o=2==t[0]&&v(t);return{c(){o&&o.c(),e=i()},m(t,a){o&&o.m(t,a),r(t,e,a)},p(t,r){2==t[0]?o?o.p(t,r):(o=v(t),o.c(),o.m(e.parentNode,e)):o&&(o.d(1),o=null)},d(t){o&&o.d(t),t&&s(e)}}}function y(t){let e,o=t[0],m=k(t);return{c(){m.c(),e=i(),this.c=n},m(t,o){m.m(t,o),r(t,e,o)},p(t,[r]){1&r&&a(o,o=t[0])?(m.d(1),m=k(t),m.c(),m.m(e.parentNode,e)):m.p(t,r)},i:n,o:n,d(t){t&&s(e),m.d(t)}}}function x(t,e,o){let r,a,i=b(0);m(t,i,(t=>o(0,r=t)));let n=b({});m(t,n,(t=>o(1,a=t))),w(n,"countries",i),w(n,"footer-component",i);return[r,a,i,n,()=>{location.href="#"}]}class L extends t{constructor(t){super(),this.shadowRoot.innerHTML="<style>@import '/css/common.css';footer{position:relative;bottom:0;width:100%;height:auto;background:#5B6970;border-top:#cb1816 solid 0.5rem}footer p,footer a{font-family:var(--sans-serif)}#footer-content-container{position:relative;margin:auto;padding-top:2rem;max-width:116rem;width:97vw}#footer-grid-content-container{display:grid;margin-left:2rem;margin-right:2rem;margin-bottom:1rem}.logged{grid-template-columns:auto auto 2rem}footer h2{color:#ffffff;font-size:1.3rem;margin-bottom:0.5rem}#footer-copyright{position:relative;margin:auto;width:100%;bottom:0rem;height:3rem;top:0rem;margin-bottom:0;font-size:1rem;text-align:center}#footer-copyright *{font-size:1rem}footer a{font-size:1.1rem;color:#ffffff}footer p{display:block;font-size:1.1rem;color:#d8d8d8;font-family:var(--sans-serif,sans-serif);margin-bottom:0.5rem}#contact-us-container{width:16rem}#footer-up{position:absolute;width:4.8rem;height:4.8rem;border-radius:3.4rem;top:4rem;right:2rem;background:#ffffff}#footer-up svg{width:40%;height:auto}@media only screen and (max-width: 1170px){.logged{grid-template-rows:auto auto auto;grid-template-columns:auto;row-gap:2rem}#footer-copyright{height:1rem;top:-2rem}}</style>",e(this,{target:this.shadowRoot,props:o(this.attributes),customElement:!0},x,y,a,{},null),t&&t.target&&r(t.target,this,t.anchor)}}customElements.define("footer-component",L);export{L as default}; import{S as t,i as e,a as o,b as r,s as a,e as i,n,d as s,c as m,g as c,t as f,h as d,j as l,w as g,m as p,p as h,q as u}from"./index-8c09578c.js";import{w}from"./index-77787e10.js";import{loadLocaleContent as b}from"../../../../../../../../../js/libraries/serverTools.js";function v(t){let e,o,a,i,n,m,w,b,v,k,y,x,L,j,z,U,_,C,T,B,H,M,R=t[1].contactUs+"",A=t[1].inviteLink+"",D=t[1].inviteLink+"";return{c(){e=c("footer"),o=c("div"),a=c("div"),i=c("div"),n=c("h2"),m=f(R),w=d(),b=c("p"),v=f("Discord: "),k=c("a"),y=f(A),x=d(),L=c("p"),j=f("WhatsApp: "),z=c("a"),U=f(D),_=d(),C=c("button"),C.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="42.545" height="72.601" viewBox="0 0 42.545 72.601"><g id="Group_268" data-name="Group 268" transform="translate(-6.177 -2.399)"><rect id="Rectangle_146" data-name="Rectangle 146" width="11" height="51" rx="5.5" transform="translate(22 24)" fill="#cb1816"></rect><path id="Path_1145" data-name="Path 1145" d="M23.814,4.021a5,5,0,0,1,7.372,0l16.134,17.6c2.94,3.207,1.046,10.4-3.686,8.379S28.02,14.081,28.391,13.524,16.544,27.976,11.366,30,4.741,24.828,7.68,21.621Z" fill="#DD1C1A"></path></g></svg>',T=d(),B=c("p"),B.innerHTML='Licensed under a Creative Commons <a href="https://creativecommons.org/licenses/by/4.0/legalcode " target="_blank" rel="noreferrer">CC BY 4.0 license</a>',l(k,"href","https://discord.gg/Qk8KUk787z"),l(k,"target","_blank"),l(k,"rel","noreferrer"),g(k,"margin-left","1.8rem"),l(z,"href","https://chat.whatsapp.com/BhnmUNljUxJ2AjeHUwyTKh"),l(z,"target","_blank"),l(z,"rel","noreferrer"),g(z,"margin-left","0.5rem"),l(i,"id","contact-us-container"),l(a,"id","footer-grid-content-container"),l(a,"class","logged"),l(C,"id","footer-up"),l(C,"aria-label","go up"),l(B,"id","footer-copyright"),l(o,"id","footer-content-container")},m(s,c){r(s,e,c),p(e,o),p(o,a),p(a,i),p(i,n),p(n,m),p(i,w),p(i,b),p(b,v),p(b,k),p(k,y),p(i,x),p(i,L),p(L,j),p(L,z),p(z,U),p(o,_),p(o,C),p(o,T),p(o,B),H||(M=h(C,"click",t[4]),H=!0)},p(t,e){2&e&&R!==(R=t[1].contactUs+"")&&u(m,R),2&e&&A!==(A=t[1].inviteLink+"")&&u(y,A),2&e&&D!==(D=t[1].inviteLink+"")&&u(U,D)},d(t){t&&s(e),H=!1,M()}}}function k(t){let e,o=2==t[0]&&v(t);return{c(){o&&o.c(),e=i()},m(t,a){o&&o.m(t,a),r(t,e,a)},p(t,r){2==t[0]?o?o.p(t,r):(o=v(t),o.c(),o.m(e.parentNode,e)):o&&(o.d(1),o=null)},d(t){o&&o.d(t),t&&s(e)}}}function y(t){let e,o=t[0],m=k(t);return{c(){m.c(),e=i(),this.c=n},m(t,o){m.m(t,o),r(t,e,o)},p(t,[r]){1&r&&a(o,o=t[0])?(m.d(1),m=k(t),m.c(),m.m(e.parentNode,e)):m.p(t,r)},i:n,o:n,d(t){t&&s(e),m.d(t)}}}function x(t,e,o){let r,a,i=w(0);m(t,i,(t=>o(0,r=t)));let n=w({});m(t,n,(t=>o(1,a=t))),b(n,"countries",i),b(n,"footer-component",i);return[r,a,i,n,()=>{location.href="#"}]}class L extends t{constructor(t){super(),this.shadowRoot.innerHTML="<style>@import '/css/common.css';footer{position:relative;bottom:0;width:100%;height:auto;background:#5B6970;border-top:#cb1816 solid 0.5rem}footer p,footer a{font-family:var(--sans-serif)}#footer-content-container{position:relative;margin:auto;padding-top:2rem;max-width:116rem;width:97vw}#footer-grid-content-container{display:grid;margin-left:2rem;margin-right:2rem;margin-bottom:1rem}.logged{grid-template-columns:auto auto 2rem}footer h2{color:#ffffff;font-size:1.3rem;margin-bottom:0.5rem}#footer-copyright{position:relative;margin:auto;width:100%;bottom:0rem;height:3rem;top:0rem;margin-bottom:0;font-size:1rem;text-align:center}#footer-copyright *{font-size:1rem}footer a{font-size:1.1rem;color:#ffffff}footer p{display:block;font-size:1.1rem;color:#d8d8d8;font-family:var(--sans-serif,sans-serif);margin-bottom:0.5rem}#contact-us-container{width:16rem}#footer-up{position:absolute;width:4.8rem;height:4.8rem;border-radius:3.4rem;top:4rem;right:2rem;background:#ffffff}#footer-up svg{width:40%;height:auto}@media only screen and (max-width: 1170px){.logged{grid-template-rows:auto auto auto;grid-template-columns:auto;row-gap:2rem}#footer-copyright{height:1rem;top:-2rem}}</style>",e(this,{target:this.shadowRoot,props:o(this.attributes),customElement:!0},x,y,a,{},null),t&&t.target&&r(t.target,this,t.anchor)}}customElements.define("footer-component",L);export{L as default};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,513 @@
(function(l, r) { if (!l || l.getElementById('livereloadscript')) return; r = l.createElement('script'); r.async = 1; r.src = '//' + (self.location.host || 'localhost').split(':')[0] + ':35729/livereload.js?snipver=1'; r.id = 'livereloadscript'; l.getElementsByTagName('head')[0].appendChild(r) })(self.document);
function noop() { }
function add_location(element, file, line, column, char) {
element.__svelte_meta = {
loc: { file, line, column, char }
};
}
function run(fn) {
return fn();
}
function blank_object() {
return Object.create(null);
}
function run_all(fns) {
fns.forEach(run);
}
function is_function(thing) {
return typeof thing === 'function';
}
function safe_not_equal(a, b) {
return a != a ? b == b : a !== b || ((a && typeof a === 'object') || typeof a === 'function');
}
let src_url_equal_anchor;
function src_url_equal(element_src, url) {
if (!src_url_equal_anchor) {
src_url_equal_anchor = document.createElement('a');
}
src_url_equal_anchor.href = url;
return element_src === src_url_equal_anchor.href;
}
function is_empty(obj) {
return Object.keys(obj).length === 0;
}
function validate_store(store, name) {
if (store != null && typeof store.subscribe !== 'function') {
throw new Error(`'${name}' is not a store with a 'subscribe' method`);
}
}
function subscribe(store, ...callbacks) {
if (store == null) {
return noop;
}
const unsub = store.subscribe(...callbacks);
return unsub.unsubscribe ? () => unsub.unsubscribe() : unsub;
}
function component_subscribe(component, store, callback) {
component.$$.on_destroy.push(subscribe(store, callback));
}
function append(target, node) {
target.appendChild(node);
}
function insert(target, node, anchor) {
target.insertBefore(node, anchor || null);
}
function detach(node) {
node.parentNode.removeChild(node);
}
function destroy_each(iterations, detaching) {
for (let i = 0; i < iterations.length; i += 1) {
if (iterations[i])
iterations[i].d(detaching);
}
}
function element(name) {
return document.createElement(name);
}
function svg_element(name) {
return document.createElementNS('http://www.w3.org/2000/svg', name);
}
function text(data) {
return document.createTextNode(data);
}
function space() {
return text(' ');
}
function empty() {
return text('');
}
function listen(node, event, handler, options) {
node.addEventListener(event, handler, options);
return () => node.removeEventListener(event, handler, options);
}
function attr(node, attribute, value) {
if (value == null)
node.removeAttribute(attribute);
else if (node.getAttribute(attribute) !== value)
node.setAttribute(attribute, value);
}
function set_custom_element_data(node, prop, value) {
if (prop in node) {
node[prop] = typeof node[prop] === 'boolean' && value === '' ? true : value;
}
else {
attr(node, prop, value);
}
}
function children(element) {
return Array.from(element.childNodes);
}
function set_style(node, key, value, important) {
if (value === null) {
node.style.removeProperty(key);
}
else {
node.style.setProperty(key, value, important ? 'important' : '');
}
}
function custom_event(type, detail, { bubbles = false, cancelable = false } = {}) {
const e = document.createEvent('CustomEvent');
e.initCustomEvent(type, bubbles, cancelable, detail);
return e;
}
class HtmlTag {
constructor(is_svg = false) {
this.is_svg = false;
this.is_svg = is_svg;
this.e = this.n = null;
}
c(html) {
this.h(html);
}
m(html, target, anchor = null) {
if (!this.e) {
if (this.is_svg)
this.e = svg_element(target.nodeName);
else
this.e = element(target.nodeName);
this.t = target;
this.c(html);
}
this.i(anchor);
}
h(html) {
this.e.innerHTML = html;
this.n = Array.from(this.e.childNodes);
}
i(anchor) {
for (let i = 0; i < this.n.length; i += 1) {
insert(this.t, this.n[i], anchor);
}
}
p(html) {
this.d();
this.h(html);
this.i(this.a);
}
d() {
this.n.forEach(detach);
}
}
function attribute_to_object(attributes) {
const result = {};
for (const attribute of attributes) {
result[attribute.name] = attribute.value;
}
return result;
}
let current_component;
function set_current_component(component) {
current_component = component;
}
function get_current_component() {
if (!current_component)
throw new Error('Function called outside component initialization');
return current_component;
}
/**
* The `onMount` function schedules a callback to run as soon as the component has been mounted to the DOM.
* It must be called during the component's initialisation (but doesn't need to live *inside* the component;
* it can be called from an external module).
*
* `onMount` does not run inside a [server-side component](/docs#run-time-server-side-component-api).
*
* https://svelte.dev/docs#run-time-svelte-onmount
*/
function onMount(fn) {
get_current_component().$$.on_mount.push(fn);
}
/**
* Associates an arbitrary `context` object with the current component and the specified `key`
* and returns that object. The context is then available to children of the component
* (including slotted content) with `getContext`.
*
* Like lifecycle functions, this must be called during component initialisation.
*
* https://svelte.dev/docs#run-time-svelte-setcontext
*/
function setContext(key, context) {
get_current_component().$$.context.set(key, context);
return context;
}
/**
* Retrieves the context that belongs to the closest parent component with the specified `key`.
* Must be called during component initialisation.
*
* https://svelte.dev/docs#run-time-svelte-getcontext
*/
function getContext(key) {
return get_current_component().$$.context.get(key);
}
const dirty_components = [];
const binding_callbacks = [];
const render_callbacks = [];
const flush_callbacks = [];
const resolved_promise = Promise.resolve();
let update_scheduled = false;
function schedule_update() {
if (!update_scheduled) {
update_scheduled = true;
resolved_promise.then(flush);
}
}
function add_render_callback(fn) {
render_callbacks.push(fn);
}
// flush() calls callbacks in this order:
// 1. All beforeUpdate callbacks, in order: parents before children
// 2. All bind:this callbacks, in reverse order: children before parents.
// 3. All afterUpdate callbacks, in order: parents before children. EXCEPT
// for afterUpdates called during the initial onMount, which are called in
// reverse order: children before parents.
// Since callbacks might update component values, which could trigger another
// call to flush(), the following steps guard against this:
// 1. During beforeUpdate, any updated components will be added to the
// dirty_components array and will cause a reentrant call to flush(). Because
// the flush index is kept outside the function, the reentrant call will pick
// up where the earlier call left off and go through all dirty components. The
// current_component value is saved and restored so that the reentrant call will
// not interfere with the "parent" flush() call.
// 2. bind:this callbacks cannot trigger new flush() calls.
// 3. During afterUpdate, any updated components will NOT have their afterUpdate
// callback called a second time; the seen_callbacks set, outside the flush()
// function, guarantees this behavior.
const seen_callbacks = new Set();
let flushidx = 0; // Do *not* move this inside the flush() function
function flush() {
const saved_component = current_component;
do {
// first, call beforeUpdate functions
// and update components
while (flushidx < dirty_components.length) {
const component = dirty_components[flushidx];
flushidx++;
set_current_component(component);
update(component.$$);
}
set_current_component(null);
dirty_components.length = 0;
flushidx = 0;
while (binding_callbacks.length)
binding_callbacks.pop()();
// then, once components are updated, call
// afterUpdate functions. This may cause
// subsequent updates...
for (let i = 0; i < render_callbacks.length; i += 1) {
const callback = render_callbacks[i];
if (!seen_callbacks.has(callback)) {
// ...so guard against infinite loops
seen_callbacks.add(callback);
callback();
}
}
render_callbacks.length = 0;
} while (dirty_components.length);
while (flush_callbacks.length) {
flush_callbacks.pop()();
}
update_scheduled = false;
seen_callbacks.clear();
set_current_component(saved_component);
}
function update($$) {
if ($$.fragment !== null) {
$$.update();
run_all($$.before_update);
const dirty = $$.dirty;
$$.dirty = [-1];
$$.fragment && $$.fragment.p($$.ctx, dirty);
$$.after_update.forEach(add_render_callback);
}
}
const outroing = new Set();
function transition_in(block, local) {
if (block && block.i) {
outroing.delete(block);
block.i(local);
}
}
const globals = (typeof window !== 'undefined'
? window
: typeof globalThis !== 'undefined'
? globalThis
: global);
function mount_component(component, target, anchor, customElement) {
const { fragment, after_update } = component.$$;
fragment && fragment.m(target, anchor);
if (!customElement) {
// onMount happens before the initial afterUpdate
add_render_callback(() => {
const new_on_destroy = component.$$.on_mount.map(run).filter(is_function);
// if the component was destroyed immediately
// it will update the `$$.on_destroy` reference to `null`.
// the destructured on_destroy may still reference to the old array
if (component.$$.on_destroy) {
component.$$.on_destroy.push(...new_on_destroy);
}
else {
// Edge case - component was destroyed immediately,
// most likely as a result of a binding initialising
run_all(new_on_destroy);
}
component.$$.on_mount = [];
});
}
after_update.forEach(add_render_callback);
}
function destroy_component(component, detaching) {
const $$ = component.$$;
if ($$.fragment !== null) {
run_all($$.on_destroy);
$$.fragment && $$.fragment.d(detaching);
// TODO null out other refs, including component.$$ (but need to
// preserve final state?)
$$.on_destroy = $$.fragment = null;
$$.ctx = [];
}
}
function make_dirty(component, i) {
if (component.$$.dirty[0] === -1) {
dirty_components.push(component);
schedule_update();
component.$$.dirty.fill(0);
}
component.$$.dirty[(i / 31) | 0] |= (1 << (i % 31));
}
function init(component, options, instance, create_fragment, not_equal, props, append_styles, dirty = [-1]) {
const parent_component = current_component;
set_current_component(component);
const $$ = component.$$ = {
fragment: null,
ctx: [],
// state
props,
update: noop,
not_equal,
bound: blank_object(),
// lifecycle
on_mount: [],
on_destroy: [],
on_disconnect: [],
before_update: [],
after_update: [],
context: new Map(options.context || (parent_component ? parent_component.$$.context : [])),
// everything else
callbacks: blank_object(),
dirty,
skip_bound: false,
root: options.target || parent_component.$$.root
};
append_styles && append_styles($$.root);
let ready = false;
$$.ctx = instance
? instance(component, options.props || {}, (i, ret, ...rest) => {
const value = rest.length ? rest[0] : ret;
if ($$.ctx && not_equal($$.ctx[i], $$.ctx[i] = value)) {
if (!$$.skip_bound && $$.bound[i])
$$.bound[i](value);
if (ready)
make_dirty(component, i);
}
return ret;
})
: [];
$$.update();
ready = true;
run_all($$.before_update);
// `false` as a special case of no DOM component
$$.fragment = create_fragment ? create_fragment($$.ctx) : false;
if (options.target) {
if (options.hydrate) {
const nodes = children(options.target);
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
$$.fragment && $$.fragment.l(nodes);
nodes.forEach(detach);
}
else {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
$$.fragment && $$.fragment.c();
}
if (options.intro)
transition_in(component.$$.fragment);
mount_component(component, options.target, options.anchor, options.customElement);
flush();
}
set_current_component(parent_component);
}
let SvelteElement;
if (typeof HTMLElement === 'function') {
SvelteElement = class extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
}
connectedCallback() {
const { on_mount } = this.$$;
this.$$.on_disconnect = on_mount.map(run).filter(is_function);
// @ts-ignore todo: improve typings
for (const key in this.$$.slotted) {
// @ts-ignore todo: improve typings
this.appendChild(this.$$.slotted[key]);
}
}
attributeChangedCallback(attr, _oldValue, newValue) {
this[attr] = newValue;
}
disconnectedCallback() {
run_all(this.$$.on_disconnect);
}
$destroy() {
destroy_component(this, 1);
this.$destroy = noop;
}
$on(type, callback) {
// TODO should this delegate to addEventListener?
if (!is_function(callback)) {
return noop;
}
const callbacks = (this.$$.callbacks[type] || (this.$$.callbacks[type] = []));
callbacks.push(callback);
return () => {
const index = callbacks.indexOf(callback);
if (index !== -1)
callbacks.splice(index, 1);
};
}
$set($$props) {
if (this.$$set && !is_empty($$props)) {
this.$$.skip_bound = true;
this.$$set($$props);
this.$$.skip_bound = false;
}
}
};
}
function dispatch_dev(type, detail) {
document.dispatchEvent(custom_event(type, Object.assign({ version: '3.52.0' }, detail), { bubbles: true }));
}
function append_dev(target, node) {
dispatch_dev('SvelteDOMInsert', { target, node });
append(target, node);
}
function insert_dev(target, node, anchor) {
dispatch_dev('SvelteDOMInsert', { target, node, anchor });
insert(target, node, anchor);
}
function detach_dev(node) {
dispatch_dev('SvelteDOMRemove', { node });
detach(node);
}
function listen_dev(node, event, handler, options, has_prevent_default, has_stop_propagation) {
const modifiers = options === true ? ['capture'] : options ? Array.from(Object.keys(options)) : [];
if (has_prevent_default)
modifiers.push('preventDefault');
if (has_stop_propagation)
modifiers.push('stopPropagation');
dispatch_dev('SvelteDOMAddEventListener', { node, event, handler, modifiers });
const dispose = listen(node, event, handler, options);
return () => {
dispatch_dev('SvelteDOMRemoveEventListener', { node, event, handler, modifiers });
dispose();
};
}
function attr_dev(node, attribute, value) {
attr(node, attribute, value);
if (value == null)
dispatch_dev('SvelteDOMRemoveAttribute', { node, attribute });
else
dispatch_dev('SvelteDOMSetAttribute', { node, attribute, value });
}
function prop_dev(node, property, value) {
node[property] = value;
dispatch_dev('SvelteDOMSetProperty', { node, property, value });
}
function set_data_dev(text, data) {
data = '' + data;
if (text.wholeText === data)
return;
dispatch_dev('SvelteDOMSetData', { node: text, data });
text.data = data;
}
function validate_each_argument(arg) {
if (typeof arg !== 'string' && !(arg && typeof arg === 'object' && 'length' in arg)) {
let msg = '{#each} only iterates over array-like objects.';
if (typeof Symbol === 'function' && arg && Symbol.iterator in arg) {
msg += ' You can use a spread to convert this iterable into an array.';
}
throw new Error(msg);
}
}
function validate_slots(name, slot, keys) {
for (const slot_key of Object.keys(slot)) {
if (!~keys.indexOf(slot_key)) {
console.warn(`<${name}> received an unexpected slot "${slot_key}".`);
}
}
}
export { destroy_each as A, prop_dev as B, flush as C, set_style as D, getContext as E, setContext as F, svg_element as G, is_function as H, HtmlTag as I, SvelteElement as S, attribute_to_object as a, insert_dev as b, validate_store as c, dispatch_dev as d, component_subscribe as e, empty as f, detach_dev as g, binding_callbacks as h, init as i, element as j, space as k, add_location as l, attr_dev as m, noop as n, onMount as o, src_url_equal as p, set_custom_element_data as q, append_dev as r, safe_not_equal as s, listen_dev as t, run_all as u, validate_slots as v, globals as w, validate_each_argument as x, text as y, set_data_dev as z };

View File

@ -0,0 +1,53 @@
(function(l, r) { if (!l || l.getElementById('livereloadscript')) return; r = l.createElement('script'); r.async = 1; r.src = '//' + (self.location.host || 'localhost').split(':')[0] + ':35729/livereload.js?snipver=1'; r.id = 'livereloadscript'; l.getElementsByTagName('head')[0].appendChild(r) })(self.document);
import { n as noop, s as safe_not_equal } from './index-54dd49e1.js';
const subscriber_queue = [];
/**
* Create a `Writable` store that allows both updating and reading by subscription.
* @param {*=}value initial value
* @param {StartStopNotifier=}start start and stop notifications for subscriptions
*/
function writable(value, start = noop) {
let stop;
const subscribers = new Set();
function set(new_value) {
if (safe_not_equal(value, new_value)) {
value = new_value;
if (stop) { // store is ready
const run_queue = !subscriber_queue.length;
for (const subscriber of subscribers) {
subscriber[1]();
subscriber_queue.push(subscriber, value);
}
if (run_queue) {
for (let i = 0; i < subscriber_queue.length; i += 2) {
subscriber_queue[i][0](subscriber_queue[i + 1]);
}
subscriber_queue.length = 0;
}
}
}
}
function update(fn) {
set(fn(value));
}
function subscribe(run, invalidate = noop) {
const subscriber = [run, invalidate];
subscribers.add(subscriber);
if (subscribers.size === 1) {
stop = start(set) || noop;
}
run(value);
return () => {
subscribers.delete(subscriber);
if (subscribers.size === 0) {
stop();
stop = null;
}
};
}
return { set, update, subscribe };
}
export { writable as w };

View File

@ -0,0 +1 @@
import{n,s as t}from"./index-8c09578c.js";const e=[];function s(s,o=n){let c;const i=new Set;function f(n){if(t(s,n)&&(s=n,c)){const n=!e.length;for(const n of i)n[1](),e.push(n,s);if(n){for(let n=0;n<e.length;n+=2)e[n][0](e[n+1]);e.length=0}}}return{set:f,update:function(n){f(n(s))},subscribe:function(t,e=n){const r=[t,e];return i.add(r),1===i.size&&(c=o(f)||n),t(s),()=>{i.delete(r),0===i.size&&(c(),c=null)}}}}export{s as w};

View File

@ -0,0 +1 @@
function t(){}function n(t){return t()}function e(){return Object.create(null)}function o(t){t.forEach(n)}function s(t){return"function"==typeof t}function r(t,n){return t!=t?n==n:t!==n||t&&"object"==typeof t||"function"==typeof t}let i,c;function a(t,n){return i||(i=document.createElement("a")),i.href=n,t===i.href}function u(n,e,o){n.$$.on_destroy.push(function(n,...e){if(null==n)return t;const o=n.subscribe(...e);return o.unsubscribe?()=>o.unsubscribe():o}(e,o))}function f(t,n){t.appendChild(n)}function l(t,n,e){t.insertBefore(n,e||null)}function h(t){t.parentNode.removeChild(t)}function d(t,n){for(let e=0;e<t.length;e+=1)t[e]&&t[e].d(n)}function $(t){return document.createElement(t)}function p(t){return document.createTextNode(t)}function m(){return p(" ")}function g(){return p("")}function b(t,n,e,o){return t.addEventListener(n,e,o),()=>t.removeEventListener(n,e,o)}function y(t,n,e){null==e?t.removeAttribute(n):t.getAttribute(n)!==e&&t.setAttribute(n,e)}function _(t,n,e){n in t?t[n]="boolean"==typeof t[n]&&""===e||e:y(t,n,e)}function x(t,n){n=""+n,t.wholeText!==n&&(t.data=n)}function v(t,n,e,o){null===e?t.style.removeProperty(n):t.style.setProperty(n,e,o?"important":"")}class E{constructor(t=!1){this.is_svg=!1,this.is_svg=t,this.e=this.n=null}c(t){this.h(t)}m(t,n,e=null){var o;this.e||(this.is_svg?this.e=(o=n.nodeName,document.createElementNS("http://www.w3.org/2000/svg",o)):this.e=$(n.nodeName),this.t=n,this.c(t)),this.i(e)}h(t){this.e.innerHTML=t,this.n=Array.from(this.e.childNodes)}i(t){for(let n=0;n<this.n.length;n+=1)l(this.t,this.n[n],t)}p(t){this.d(),this.h(t),this.i(this.a)}d(){this.n.forEach(h)}}function w(t){const n={};for(const e of t)n[e.name]=e.value;return n}function k(t){c=t}function C(){if(!c)throw new Error("Function called outside component initialization");return c}function N(t){C().$$.on_mount.push(t)}function A(t){return C().$$.context.get(t)}const L=[],S=[],T=[],j=[],H=Promise.resolve();let M=!1;function O(t){T.push(t)}const P=new Set;let q=0;function z(){const t=c;do{for(;q<L.length;){const t=L[q];q++,k(t),B(t.$$)}for(k(null),L.length=0,q=0;S.length;)S.pop()();for(let t=0;t<T.length;t+=1){const n=T[t];P.has(n)||(P.add(n),n())}T.length=0}while(L.length);for(;j.length;)j.pop()();M=!1,P.clear(),k(t)}function B(t){if(null!==t.fragment){t.update(),o(t.before_update);const n=t.dirty;t.dirty=[-1],t.fragment&&t.fragment.p(t.ctx,n),t.after_update.forEach(O)}}const F=new Set;function D(t,n){-1===t.$$.dirty[0]&&(L.push(t),M||(M=!0,H.then(z)),t.$$.dirty.fill(0)),t.$$.dirty[n/31|0]|=1<<n%31}function G(r,i,a,u,f,l,d,$=[-1]){const p=c;k(r);const m=r.$$={fragment:null,ctx:[],props:l,update:t,not_equal:f,bound:e(),on_mount:[],on_destroy:[],on_disconnect:[],before_update:[],after_update:[],context:new Map(i.context||(p?p.$$.context:[])),callbacks:e(),dirty:$,skip_bound:!1,root:i.target||p.$$.root};d&&d(m.root);let g=!1;if(m.ctx=a?a(r,i.props||{},((t,n,...e)=>{const o=e.length?e[0]:n;return m.ctx&&f(m.ctx[t],m.ctx[t]=o)&&(!m.skip_bound&&m.bound[t]&&m.bound[t](o),g&&D(r,t)),n})):[],m.update(),g=!0,o(m.before_update),m.fragment=!!u&&u(m.ctx),i.target){if(i.hydrate){const t=function(t){return Array.from(t.childNodes)}(i.target);m.fragment&&m.fragment.l(t),t.forEach(h)}else m.fragment&&m.fragment.c();i.intro&&((b=r.$$.fragment)&&b.i&&(F.delete(b),b.i(y))),function(t,e,r,i){const{fragment:c,after_update:a}=t.$$;c&&c.m(e,r),i||O((()=>{const e=t.$$.on_mount.map(n).filter(s);t.$$.on_destroy?t.$$.on_destroy.push(...e):o(e),t.$$.on_mount=[]})),a.forEach(O)}(r,i.target,i.anchor,i.customElement),z()}var b,y;k(p)}let I;"function"==typeof HTMLElement&&(I=class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"})}connectedCallback(){const{on_mount:t}=this.$$;this.$$.on_disconnect=t.map(n).filter(s);for(const t in this.$$.slotted)this.appendChild(this.$$.slotted[t])}attributeChangedCallback(t,n,e){this[t]=e}disconnectedCallback(){o(this.$$.on_disconnect)}$destroy(){!function(t,n){const e=t.$$;null!==e.fragment&&(o(e.on_destroy),e.fragment&&e.fragment.d(n),e.on_destroy=e.fragment=null,e.ctx=[])}(this,1),this.$destroy=t}$on(n,e){if(!s(e))return t;const o=this.$$.callbacks[n]||(this.$$.callbacks[n]=[]);return o.push(e),()=>{const t=o.indexOf(e);-1!==t&&o.splice(t,1)}}$set(t){var n;this.$$set&&(n=t,0!==Object.keys(n).length)&&(this.$$.skip_bound=!0,this.$$set(t),this.$$.skip_bound=!1)}});export{E as H,I as S,w as a,l as b,u as c,h as d,g as e,S as f,$ as g,m as h,G as i,y as j,a as k,_ as l,f as m,t as n,N as o,b as p,x as q,o as r,r as s,p as t,d as u,z as v,v as w,A as x,s as y};

View File

@ -0,0 +1,53 @@
(function(l, r) { if (!l || l.getElementById('livereloadscript')) return; r = l.createElement('script'); r.async = 1; r.src = '//' + (self.location.host || 'localhost').split(':')[0] + ':35729/livereload.js?snipver=1'; r.id = 'livereloadscript'; l.getElementsByTagName('head')[0].appendChild(r) })(self.document);
import { n as noop, s as safe_not_equal } from './index-d77c7bdd.js';
const subscriber_queue = [];
/**
* Create a `Writable` store that allows both updating and reading by subscription.
* @param {*=}value initial value
* @param {StartStopNotifier=}start start and stop notifications for subscriptions
*/
function writable(value, start = noop) {
let stop;
const subscribers = new Set();
function set(new_value) {
if (safe_not_equal(value, new_value)) {
value = new_value;
if (stop) { // store is ready
const run_queue = !subscriber_queue.length;
for (const subscriber of subscribers) {
subscriber[1]();
subscriber_queue.push(subscriber, value);
}
if (run_queue) {
for (let i = 0; i < subscriber_queue.length; i += 2) {
subscriber_queue[i][0](subscriber_queue[i + 1]);
}
subscriber_queue.length = 0;
}
}
}
}
function update(fn) {
set(fn(value));
}
function subscribe(run, invalidate = noop) {
const subscriber = [run, invalidate];
subscribers.add(subscriber);
if (subscribers.size === 1) {
stop = start(set) || noop;
}
run(value);
return () => {
subscribers.delete(subscriber);
if (subscribers.size === 0) {
stop();
stop = null;
}
};
}
return { set, update, subscribe };
}
export { writable as w };

View File

@ -0,0 +1,521 @@
(function(l, r) { if (!l || l.getElementById('livereloadscript')) return; r = l.createElement('script'); r.async = 1; r.src = '//' + (self.location.host || 'localhost').split(':')[0] + ':35729/livereload.js?snipver=1'; r.id = 'livereloadscript'; l.getElementsByTagName('head')[0].appendChild(r) })(self.document);
function noop() { }
function add_location(element, file, line, column, char) {
element.__svelte_meta = {
loc: { file, line, column, char }
};
}
function run(fn) {
return fn();
}
function blank_object() {
return Object.create(null);
}
function run_all(fns) {
fns.forEach(run);
}
function is_function(thing) {
return typeof thing === 'function';
}
function safe_not_equal(a, b) {
return a != a ? b == b : a !== b || ((a && typeof a === 'object') || typeof a === 'function');
}
let src_url_equal_anchor;
function src_url_equal(element_src, url) {
if (!src_url_equal_anchor) {
src_url_equal_anchor = document.createElement('a');
}
src_url_equal_anchor.href = url;
return element_src === src_url_equal_anchor.href;
}
function is_empty(obj) {
return Object.keys(obj).length === 0;
}
function validate_store(store, name) {
if (store != null && typeof store.subscribe !== 'function') {
throw new Error(`'${name}' is not a store with a 'subscribe' method`);
}
}
function subscribe(store, ...callbacks) {
if (store == null) {
return noop;
}
const unsub = store.subscribe(...callbacks);
return unsub.unsubscribe ? () => unsub.unsubscribe() : unsub;
}
function component_subscribe(component, store, callback) {
component.$$.on_destroy.push(subscribe(store, callback));
}
function append(target, node) {
target.appendChild(node);
}
function insert(target, node, anchor) {
target.insertBefore(node, anchor || null);
}
function detach(node) {
node.parentNode.removeChild(node);
}
function destroy_each(iterations, detaching) {
for (let i = 0; i < iterations.length; i += 1) {
if (iterations[i])
iterations[i].d(detaching);
}
}
function element(name) {
return document.createElement(name);
}
function svg_element(name) {
return document.createElementNS('http://www.w3.org/2000/svg', name);
}
function text(data) {
return document.createTextNode(data);
}
function space() {
return text(' ');
}
function empty() {
return text('');
}
function listen(node, event, handler, options) {
node.addEventListener(event, handler, options);
return () => node.removeEventListener(event, handler, options);
}
function attr(node, attribute, value) {
if (value == null)
node.removeAttribute(attribute);
else if (node.getAttribute(attribute) !== value)
node.setAttribute(attribute, value);
}
function set_custom_element_data(node, prop, value) {
if (prop in node) {
node[prop] = typeof node[prop] === 'boolean' && value === '' ? true : value;
}
else {
attr(node, prop, value);
}
}
function children(element) {
return Array.from(element.childNodes);
}
function set_style(node, key, value, important) {
if (value === null) {
node.style.removeProperty(key);
}
else {
node.style.setProperty(key, value, important ? 'important' : '');
}
}
function custom_event(type, detail, { bubbles = false, cancelable = false } = {}) {
const e = document.createEvent('CustomEvent');
e.initCustomEvent(type, bubbles, cancelable, detail);
return e;
}
class HtmlTag {
constructor(is_svg = false) {
this.is_svg = false;
this.is_svg = is_svg;
this.e = this.n = null;
}
c(html) {
this.h(html);
}
m(html, target, anchor = null) {
if (!this.e) {
if (this.is_svg)
this.e = svg_element(target.nodeName);
else
this.e = element(target.nodeName);
this.t = target;
this.c(html);
}
this.i(anchor);
}
h(html) {
this.e.innerHTML = html;
this.n = Array.from(this.e.childNodes);
}
i(anchor) {
for (let i = 0; i < this.n.length; i += 1) {
insert(this.t, this.n[i], anchor);
}
}
p(html) {
this.d();
this.h(html);
this.i(this.a);
}
d() {
this.n.forEach(detach);
}
}
function attribute_to_object(attributes) {
const result = {};
for (const attribute of attributes) {
result[attribute.name] = attribute.value;
}
return result;
}
let current_component;
function set_current_component(component) {
current_component = component;
}
function get_current_component() {
if (!current_component)
throw new Error('Function called outside component initialization');
return current_component;
}
/**
* The `onMount` function schedules a callback to run as soon as the component has been mounted to the DOM.
* It must be called during the component's initialisation (but doesn't need to live *inside* the component;
* it can be called from an external module).
*
* `onMount` does not run inside a [server-side component](/docs#run-time-server-side-component-api).
*
* https://svelte.dev/docs#run-time-svelte-onmount
*/
function onMount(fn) {
get_current_component().$$.on_mount.push(fn);
}
/**
* Associates an arbitrary `context` object with the current component and the specified `key`
* and returns that object. The context is then available to children of the component
* (including slotted content) with `getContext`.
*
* Like lifecycle functions, this must be called during component initialisation.
*
* https://svelte.dev/docs#run-time-svelte-setcontext
*/
function setContext(key, context) {
get_current_component().$$.context.set(key, context);
return context;
}
/**
* Retrieves the context that belongs to the closest parent component with the specified `key`.
* Must be called during component initialisation.
*
* https://svelte.dev/docs#run-time-svelte-getcontext
*/
function getContext(key) {
return get_current_component().$$.context.get(key);
}
const dirty_components = [];
const binding_callbacks = [];
const render_callbacks = [];
const flush_callbacks = [];
const resolved_promise = Promise.resolve();
let update_scheduled = false;
function schedule_update() {
if (!update_scheduled) {
update_scheduled = true;
resolved_promise.then(flush);
}
}
function add_render_callback(fn) {
render_callbacks.push(fn);
}
// flush() calls callbacks in this order:
// 1. All beforeUpdate callbacks, in order: parents before children
// 2. All bind:this callbacks, in reverse order: children before parents.
// 3. All afterUpdate callbacks, in order: parents before children. EXCEPT
// for afterUpdates called during the initial onMount, which are called in
// reverse order: children before parents.
// Since callbacks might update component values, which could trigger another
// call to flush(), the following steps guard against this:
// 1. During beforeUpdate, any updated components will be added to the
// dirty_components array and will cause a reentrant call to flush(). Because
// the flush index is kept outside the function, the reentrant call will pick
// up where the earlier call left off and go through all dirty components. The
// current_component value is saved and restored so that the reentrant call will
// not interfere with the "parent" flush() call.
// 2. bind:this callbacks cannot trigger new flush() calls.
// 3. During afterUpdate, any updated components will NOT have their afterUpdate
// callback called a second time; the seen_callbacks set, outside the flush()
// function, guarantees this behavior.
const seen_callbacks = new Set();
let flushidx = 0; // Do *not* move this inside the flush() function
function flush() {
const saved_component = current_component;
do {
// first, call beforeUpdate functions
// and update components
while (flushidx < dirty_components.length) {
const component = dirty_components[flushidx];
flushidx++;
set_current_component(component);
update(component.$$);
}
set_current_component(null);
dirty_components.length = 0;
flushidx = 0;
while (binding_callbacks.length)
binding_callbacks.pop()();
// then, once components are updated, call
// afterUpdate functions. This may cause
// subsequent updates...
for (let i = 0; i < render_callbacks.length; i += 1) {
const callback = render_callbacks[i];
if (!seen_callbacks.has(callback)) {
// ...so guard against infinite loops
seen_callbacks.add(callback);
callback();
}
}
render_callbacks.length = 0;
} while (dirty_components.length);
while (flush_callbacks.length) {
flush_callbacks.pop()();
}
update_scheduled = false;
seen_callbacks.clear();
set_current_component(saved_component);
}
function update($$) {
if ($$.fragment !== null) {
$$.update();
run_all($$.before_update);
const dirty = $$.dirty;
$$.dirty = [-1];
$$.fragment && $$.fragment.p($$.ctx, dirty);
$$.after_update.forEach(add_render_callback);
}
}
const outroing = new Set();
function transition_in(block, local) {
if (block && block.i) {
outroing.delete(block);
block.i(local);
}
}
const globals = (typeof window !== 'undefined'
? window
: typeof globalThis !== 'undefined'
? globalThis
: global);
function mount_component(component, target, anchor, customElement) {
const { fragment, after_update } = component.$$;
fragment && fragment.m(target, anchor);
if (!customElement) {
// onMount happens before the initial afterUpdate
add_render_callback(() => {
const new_on_destroy = component.$$.on_mount.map(run).filter(is_function);
// if the component was destroyed immediately
// it will update the `$$.on_destroy` reference to `null`.
// the destructured on_destroy may still reference to the old array
if (component.$$.on_destroy) {
component.$$.on_destroy.push(...new_on_destroy);
}
else {
// Edge case - component was destroyed immediately,
// most likely as a result of a binding initialising
run_all(new_on_destroy);
}
component.$$.on_mount = [];
});
}
after_update.forEach(add_render_callback);
}
function destroy_component(component, detaching) {
const $$ = component.$$;
if ($$.fragment !== null) {
run_all($$.on_destroy);
$$.fragment && $$.fragment.d(detaching);
// TODO null out other refs, including component.$$ (but need to
// preserve final state?)
$$.on_destroy = $$.fragment = null;
$$.ctx = [];
}
}
function make_dirty(component, i) {
if (component.$$.dirty[0] === -1) {
dirty_components.push(component);
schedule_update();
component.$$.dirty.fill(0);
}
component.$$.dirty[(i / 31) | 0] |= (1 << (i % 31));
}
function init(component, options, instance, create_fragment, not_equal, props, append_styles, dirty = [-1]) {
const parent_component = current_component;
set_current_component(component);
const $$ = component.$$ = {
fragment: null,
ctx: [],
// state
props,
update: noop,
not_equal,
bound: blank_object(),
// lifecycle
on_mount: [],
on_destroy: [],
on_disconnect: [],
before_update: [],
after_update: [],
context: new Map(options.context || (parent_component ? parent_component.$$.context : [])),
// everything else
callbacks: blank_object(),
dirty,
skip_bound: false,
root: options.target || parent_component.$$.root
};
append_styles && append_styles($$.root);
let ready = false;
$$.ctx = instance
? instance(component, options.props || {}, (i, ret, ...rest) => {
const value = rest.length ? rest[0] : ret;
if ($$.ctx && not_equal($$.ctx[i], $$.ctx[i] = value)) {
if (!$$.skip_bound && $$.bound[i])
$$.bound[i](value);
if (ready)
make_dirty(component, i);
}
return ret;
})
: [];
$$.update();
ready = true;
run_all($$.before_update);
// `false` as a special case of no DOM component
$$.fragment = create_fragment ? create_fragment($$.ctx) : false;
if (options.target) {
if (options.hydrate) {
const nodes = children(options.target);
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
$$.fragment && $$.fragment.l(nodes);
nodes.forEach(detach);
}
else {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
$$.fragment && $$.fragment.c();
}
if (options.intro)
transition_in(component.$$.fragment);
mount_component(component, options.target, options.anchor, options.customElement);
flush();
}
set_current_component(parent_component);
}
let SvelteElement;
if (typeof HTMLElement === 'function') {
SvelteElement = class extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
}
connectedCallback() {
const { on_mount } = this.$$;
this.$$.on_disconnect = on_mount.map(run).filter(is_function);
// @ts-ignore todo: improve typings
for (const key in this.$$.slotted) {
// @ts-ignore todo: improve typings
this.appendChild(this.$$.slotted[key]);
}
}
attributeChangedCallback(attr, _oldValue, newValue) {
this[attr] = newValue;
}
disconnectedCallback() {
run_all(this.$$.on_disconnect);
}
$destroy() {
destroy_component(this, 1);
this.$destroy = noop;
}
$on(type, callback) {
// TODO should this delegate to addEventListener?
if (!is_function(callback)) {
return noop;
}
const callbacks = (this.$$.callbacks[type] || (this.$$.callbacks[type] = []));
callbacks.push(callback);
return () => {
const index = callbacks.indexOf(callback);
if (index !== -1)
callbacks.splice(index, 1);
};
}
$set($$props) {
if (this.$$set && !is_empty($$props)) {
this.$$.skip_bound = true;
this.$$set($$props);
this.$$.skip_bound = false;
}
}
};
}
function dispatch_dev(type, detail) {
document.dispatchEvent(custom_event(type, Object.assign({ version: '3.52.0' }, detail), { bubbles: true }));
}
function append_dev(target, node) {
dispatch_dev('SvelteDOMInsert', { target, node });
append(target, node);
}
function insert_dev(target, node, anchor) {
dispatch_dev('SvelteDOMInsert', { target, node, anchor });
insert(target, node, anchor);
}
function detach_dev(node) {
dispatch_dev('SvelteDOMRemove', { node });
detach(node);
}
function listen_dev(node, event, handler, options, has_prevent_default, has_stop_propagation) {
const modifiers = options === true ? ['capture'] : options ? Array.from(Object.keys(options)) : [];
if (has_prevent_default)
modifiers.push('preventDefault');
if (has_stop_propagation)
modifiers.push('stopPropagation');
dispatch_dev('SvelteDOMAddEventListener', { node, event, handler, modifiers });
const dispose = listen(node, event, handler, options);
return () => {
dispatch_dev('SvelteDOMRemoveEventListener', { node, event, handler, modifiers });
dispose();
};
}
function attr_dev(node, attribute, value) {
attr(node, attribute, value);
if (value == null)
dispatch_dev('SvelteDOMRemoveAttribute', { node, attribute });
else
dispatch_dev('SvelteDOMSetAttribute', { node, attribute, value });
}
function prop_dev(node, property, value) {
node[property] = value;
dispatch_dev('SvelteDOMSetProperty', { node, property, value });
}
function set_data_dev(text, data) {
data = '' + data;
if (text.wholeText === data)
return;
dispatch_dev('SvelteDOMSetData', { node: text, data });
text.data = data;
}
function validate_each_argument(arg) {
if (typeof arg !== 'string' && !(arg && typeof arg === 'object' && 'length' in arg)) {
let msg = '{#each} only iterates over array-like objects.';
if (typeof Symbol === 'function' && arg && Symbol.iterator in arg) {
msg += ' You can use a spread to convert this iterable into an array.';
}
throw new Error(msg);
}
}
function validate_slots(name, slot, keys) {
for (const slot_key of Object.keys(slot)) {
if (!~keys.indexOf(slot_key)) {
console.warn(`<${name}> received an unexpected slot "${slot_key}".`);
}
}
}
function loop_guard(timeout) {
const start = Date.now();
return () => {
if (Date.now() - start > timeout) {
throw new Error('Infinite loop detected');
}
};
}
export { set_data_dev as A, destroy_each as B, prop_dev as C, flush as D, set_style as E, getContext as F, setContext as G, svg_element as H, is_function as I, HtmlTag as J, SvelteElement as S, attribute_to_object as a, insert_dev as b, validate_store as c, dispatch_dev as d, component_subscribe as e, empty as f, detach_dev as g, binding_callbacks as h, init as i, element as j, space as k, add_location as l, attr_dev as m, noop as n, onMount as o, src_url_equal as p, set_custom_element_data as q, append_dev as r, safe_not_equal as s, listen_dev as t, run_all as u, validate_slots as v, loop_guard as w, globals as x, validate_each_argument as y, text as z };

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
import{S as t,i as e,a as s,b as o,u as n,s as r,f as i,n as a,h as l,d as c,p,o as u,g as h,t as d,v as m,l as f,q as g,m as y,w as $}from"./index-4348483d.js";import{pullLegendData as b}from"../../../../../../../../../js/predict/charts.js";function w(t,e,s){const o=t.slice();return o[10]=e[s],o[11]=e,o[12]=s,o}function x(t){let e,s,n,r,a,p,u,$,b=t[10].name+"",w=t[12];const x=()=>t[6](e,w),k=()=>t[6](null,w);function v(){return t[7](t[12])}return{c(){e=i("button"),s=i("div"),n=h(),r=i("span"),a=d(b),p=h(),l(s,"class","marker"),m(s,"background-color",t[10].color)},m(t,i){o(t,e,i),f(e,s),f(e,n),f(e,r),f(r,a),f(e,p),x(),u||($=g(e,"click",v),u=!0)},p(e,o){t=e,1&o&&m(s,"background-color",t[10].color),1&o&&b!==(b=t[10].name+"")&&y(a,b),w!==t[12]&&(k(),w=t[12],x())},d(t){t&&c(e),k(),u=!1,$()}}}function k(t){let e,s=t[0],n=[];for(let e=0;e<s.length;e+=1)n[e]=x(w(t,s,e));return{c(){e=i("div");for(let t=0;t<n.length;t+=1)n[t].c();this.c=a,l(e,"class","legend")},m(t,s){o(t,e,s);for(let t=0;t<n.length;t+=1)n[t].m(e,null)},p(t,[o]){if(7&o){let r;for(s=t[0],r=0;r<s.length;r+=1){const i=w(t,s,r);n[r]?n[r].p(i,o):(n[r]=x(i),n[r].c(),n[r].m(e,null))}for(;r<n.length;r+=1)n[r].d(1);n.length=s.length}},i:a,o:a,d(t){t&&c(e),p(n,t)}}}function v(t,e,s){let o,{option:n=null}=e,{chart:r=null}=e,{data:i={}}=e,a=[],l=[];function c(){if(null==n||null==n||null==r||null==r)setTimeout(c,100);else{s(0,a=b(a,n));for(let t of a)s(3,i[t.name]=!0,i);o=Object.keys(i)}}function p(t){s(3,i[o[t]]=!i[o[t]],i);let e=[],a=n.series.map((t=>t._id)),c=a[t];for(let t=0;t<a.length;t++)a[t]==c&&e.push(t);for(let t of e){let o=n.series[t];o.tooltip.show?(o.lineStyle.opacity=0,o.itemStyle.opacity=0,o.tooltip.show=!1,s(1,l[e[0]].style.opacity=.5,l)):(o.lineStyle.opacity=1,o.itemStyle.opacity=1,o.tooltip.show=!0,s(1,l[e[0]].style.opacity=1,l))}r.setOption(n)}u((()=>{c()}));return t.$$set=t=>{"option"in t&&s(4,n=t.option),"chart"in t&&s(5,r=t.chart),"data"in t&&s(3,i=t.data)},[a,l,p,i,n,r,function(t,e){$[t?"unshift":"push"]((()=>{l[e]=t,s(1,l)}))},t=>p(t)]}class j extends t{constructor(t){super(),this.shadowRoot.innerHTML="<style>@import '/css/common.css';@import '/css/test-basic.css';button{cursor:pointer}.legend{display:flex;flex-direction:row;flex-wrap:wrap;justify-content:center;gap:1rem}.legend *{font-family:var(--sans-serif)}.marker{position:relative;display:inline-block;margin-right:0.5rem;top:0.1rem;width:1rem;height:1rem;border-radius:1rem}</style>",e(this,{target:this.shadowRoot,props:s(this.attributes),customElement:!0},v,k,r,{option:4,chart:5,data:3},null),t&&(t.target&&o(t.target,this,t.anchor),t.props&&(this.$set(t.props),n()))}static get observedAttributes(){return["option","chart","data"]}get option(){return this.$$.ctx[4]}set option(t){this.$$set({option:t}),n()}get chart(){return this.$$.ctx[5]}set chart(t){this.$$set({chart:t}),n()}get data(){return this.$$.ctx[3]}set data(t){this.$$set({data:t}),n()}}customElements.define("legend-component",j);export{j as default}; import{S as t,i as e,a as s,b as o,v as n,s as r,g as i,n as a,j as l,d as c,u as p,o as u,h,t as d,w as m,m as f,p as g,q as y,f as $}from"./index-8c09578c.js";import{pullLegendData as b}from"../../../../../../../../../js/predict/charts.js";function w(t,e,s){const o=t.slice();return o[10]=e[s],o[11]=e,o[12]=s,o}function x(t){let e,s,n,r,a,p,u,$,b=t[10].name+"",w=t[12];const x=()=>t[6](e,w),k=()=>t[6](null,w);function j(){return t[7](t[12])}return{c(){e=i("button"),s=i("div"),n=h(),r=i("span"),a=d(b),p=h(),l(s,"class","marker"),m(s,"background-color",t[10].color)},m(t,i){o(t,e,i),f(e,s),f(e,n),f(e,r),f(r,a),f(e,p),x(),u||($=g(e,"click",j),u=!0)},p(e,o){t=e,1&o&&m(s,"background-color",t[10].color),1&o&&b!==(b=t[10].name+"")&&y(a,b),w!==t[12]&&(k(),w=t[12],x())},d(t){t&&c(e),k(),u=!1,$()}}}function k(t){let e,s=t[0],n=[];for(let e=0;e<s.length;e+=1)n[e]=x(w(t,s,e));return{c(){e=i("div");for(let t=0;t<n.length;t+=1)n[t].c();this.c=a,l(e,"class","legend")},m(t,s){o(t,e,s);for(let t=0;t<n.length;t+=1)n[t].m(e,null)},p(t,[o]){if(7&o){let r;for(s=t[0],r=0;r<s.length;r+=1){const i=w(t,s,r);n[r]?n[r].p(i,o):(n[r]=x(i),n[r].c(),n[r].m(e,null))}for(;r<n.length;r+=1)n[r].d(1);n.length=s.length}},i:a,o:a,d(t){t&&c(e),p(n,t)}}}function j(t,e,s){let o,{option:n=null}=e,{chart:r=null}=e,{data:i={}}=e,a=[],l=[];function c(){if(null==n||null==n||null==r||null==r)setTimeout(c,100);else{s(0,a=b(a,n));for(let t of a)s(3,i[t.name]=!0,i);o=Object.keys(i)}}function p(t){s(3,i[o[t]]=!i[o[t]],i);let e=[],a=n.series.map((t=>t._id)),c=a[t];for(let t=0;t<a.length;t++)a[t]==c&&e.push(t);for(let t of e){let o=n.series[t];o.tooltip.show?(o.lineStyle.opacity=0,o.itemStyle.opacity=0,o.tooltip.show=!1,s(1,l[e[0]].style.opacity=.5,l)):(o.lineStyle.opacity=1,o.itemStyle.opacity=1,o.tooltip.show=!0,s(1,l[e[0]].style.opacity=1,l))}r.setOption(n)}u((()=>{c()}));return t.$$set=t=>{"option"in t&&s(4,n=t.option),"chart"in t&&s(5,r=t.chart),"data"in t&&s(3,i=t.data)},[a,l,p,i,n,r,function(t,e){$[t?"unshift":"push"]((()=>{l[e]=t,s(1,l)}))},t=>p(t)]}class v extends t{constructor(t){super(),this.shadowRoot.innerHTML="<style>@import '/css/common.css';@import '/css/test-basic.css';button{cursor:pointer}.legend{display:flex;flex-direction:row;flex-wrap:wrap;justify-content:center;gap:1rem}.legend *{font-family:var(--sans-serif)}.marker{position:relative;display:inline-block;margin-right:0.5rem;top:0.1rem;width:1rem;height:1rem;border-radius:1rem}</style>",e(this,{target:this.shadowRoot,props:s(this.attributes),customElement:!0},j,k,r,{option:4,chart:5,data:3},null),t&&(t.target&&o(t.target,this,t.anchor),t.props&&(this.$set(t.props),n()))}static get observedAttributes(){return["option","chart","data"]}get option(){return this.$$.ctx[4]}set option(t){this.$$set({option:t}),n()}get chart(){return this.$$.ctx[5]}set chart(t){this.$$set({chart:t}),n()}get data(){return this.$$.ctx[3]}set data(t){this.$$set({data:t}),n()}}customElements.define("legend-component",v);export{v as default};

View File

@ -1 +1 @@
import{S as t,i as s,a as e,b as n,s as o,f as a,n as i,h as d,v as r,d as u,o as c,w as l}from"./index-4348483d.js";function h(t){let s;return{c(){s=a("div"),this.c=i,d(s,"id","loadscreen"),r(s,"width","100%"),r(s,"height","100%"),r(s,"background","white"),r(s,"position","absolute"),r(s,"z-index","100000")},m(e,o){n(e,s,o),t[1](s)},p:i,i:i,o:i,d(e){e&&u(s),t[1](null)}}}function p(t,s,e){let n;return c((()=>{window.addEventListener("load",(function(){e(0,n.parentNode.host.style.display="none",n)}))})),[n,function(t){l[t?"unshift":"push"]((()=>{n=t,e(0,n)}))}]}class f extends t{constructor(t){super(),s(this,{target:this.shadowRoot,props:e(this.attributes),customElement:!0},p,h,o,{},null),t&&t.target&&n(t.target,this,t.anchor)}}customElements.define("loadscreen-component",f);export{f as default}; import{S as t,i as s,a as e,b as n,s as o,g as a,n as i,j as r,w as d,d as c,o as u,f as l}from"./index-8c09578c.js";function h(t){let s;return{c(){s=a("div"),this.c=i,r(s,"id","loadscreen"),d(s,"width","100%"),d(s,"height","100%"),d(s,"background","white"),d(s,"position","absolute"),d(s,"z-index","100000")},m(e,o){n(e,s,o),t[1](s)},p:i,i:i,o:i,d(e){e&&c(s),t[1](null)}}}function p(t,s,e){let n;return u((()=>{window.addEventListener("load",(function(){e(0,n.parentNode.host.style.display="none",n)}))})),[n,function(t){l[t?"unshift":"push"]((()=>{n=t,e(0,n)}))}]}class f extends t{constructor(t){super(),s(this,{target:this.shadowRoot,props:e(this.attributes),customElement:!0},p,h,o,{},null),t&&t.target&&n(t.target,this,t.anchor)}}customElements.define("loadscreen-component",f);export{f as default};

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
import{S as t,i as e,a as o,b as s,u as a,s as r,f as l,n,h as i,d as c,o as m,w as h}from"./index-4348483d.js";function p(t){let e;return{c(){e=l("div"),this.c=n,i(e,"id","map")},m(o,a){s(o,e,a),t[3](e)},p:n,i:n,o:n,d(o){o&&c(e),t[3](null)}}}function u(t,e,o){let s,{callback:a=null}=e,{colors:r=null}=e;function l(t,e){let o=L.map(s,{center:t,zoom:e});return L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png",{attribution:'&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',minNativeZoom:2,minZoom:2,maxNativeZoom:14,maxZoom:14}).addTo(o),o}return m((()=>{if(a(l),null!=r){let t=s.getElementsByClassName("leaflet-control-layers-overlays")[0].children;for(let e=0;e<t.length;e++)t[e].children[0].children[0].style.accentColor=r[e]}})),t.$$set=t=>{"callback"in t&&o(1,a=t.callback),"colors"in t&&o(2,r=t.colors)},[s,a,r,function(t){h[t?"unshift":"push"]((()=>{s=t,o(0,s)}))}]}class d extends t{constructor(t){super(),this.shadowRoot.innerHTML="<style>@import 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.css';#map{height:var(--height);width:var(--width,100%);margin-top:var(--margin-top,0);margin-bottom:var(--margin-bottom,0)}</style>",e(this,{target:this.shadowRoot,props:o(this.attributes),customElement:!0},u,p,r,{callback:1,colors:2},null),t&&(t.target&&s(t.target,this,t.anchor),t.props&&(this.$set(t.props),a()))}static get observedAttributes(){return["callback","colors"]}get callback(){return this.$$.ctx[1]}set callback(t){this.$$set({callback:t}),a()}get colors(){return this.$$.ctx[2]}set colors(t){this.$$set({colors:t}),a()}}customElements.define("map-component",d);export{d as default}; import{S as t,i as e,a as o,b as s,v as a,s as r,g as l,n as i,j as n,d as c,o as m,f as p}from"./index-8c09578c.js";function h(t){let e;return{c(){e=l("div"),this.c=i,n(e,"id","map")},m(o,a){s(o,e,a),t[3](e)},p:i,i:i,o:i,d(o){o&&c(e),t[3](null)}}}function u(t,e,o){let s,{callback:a=null}=e,{colors:r=null}=e;function l(t,e){let o=L.map(s,{center:t,zoom:e});return L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png",{attribution:'&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',minNativeZoom:2,minZoom:2,maxNativeZoom:14,maxZoom:14}).addTo(o),o}return m((()=>{if(a(l),null!=r){let t=s.getElementsByClassName("leaflet-control-layers-overlays")[0].children;for(let e=0;e<t.length;e++)t[e].children[0].children[0].style.accentColor=r[e]}})),t.$$set=t=>{"callback"in t&&o(1,a=t.callback),"colors"in t&&o(2,r=t.colors)},[s,a,r,function(t){p[t?"unshift":"push"]((()=>{s=t,o(0,s)}))}]}class d extends t{constructor(t){super(),this.shadowRoot.innerHTML="<style>@import 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.css';#map{height:var(--height);width:var(--width,100%);margin-top:var(--margin-top,0);margin-bottom:var(--margin-bottom,0);position:relative;z-index:0}</style>",e(this,{target:this.shadowRoot,props:o(this.attributes),customElement:!0},u,h,r,{callback:1,colors:2},null),t&&(t.target&&s(t.target,this,t.anchor),t.props&&(this.$set(t.props),a()))}static get observedAttributes(){return["callback","colors"]}get callback(){return this.$$.ctx[1]}set callback(t){this.$$set({callback:t}),a()}get colors(){return this.$$.ctx[2]}set colors(t){this.$$set({colors:t}),a()}}customElements.define("map-component",d);export{d as default};

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
import{S as i,i as e,a,b as t,s as n,f as r,g as s,n as d,h as o,l,d as m,x as p,o as h,w as g}from"./index-4348483d.js";import{debounce as c}from"../../../../../../../../../js/libraries/miscTools.js";function f(i){let e,a,n,p,h,g,c,f,u,b;return{c(){e=r("div"),a=r("div"),n=r("div"),p=r("div"),p.innerHTML='<slot name="sidebar-left"></slot>',h=s(),g=r("div"),g.innerHTML='<slot name="sidebar-left2"></slot>',c=s(),f=r("div"),f.innerHTML='<slot name="sidebar-right"></slot>',u=s(),b=r("div"),b.innerHTML='<slot name="main" id="main-slot"></slot>',this.c=d,o(p,"id","sidebar-left"),o(p,"class","pane"),o(g,"id","sidebar-left2"),o(g,"class","pane"),o(n,"id","sidebars-left"),o(n,"class","sidebar"),o(f,"id","sidebar-right"),o(f,"class","pane sidebar"),o(b,"id","main-pane"),o(b,"class","pane"),o(a,"class","pane-container"),o(e,"id","root"),o(e,"class","pane-centering")},m(r,s){t(r,e,s),l(e,a),l(a,n),l(n,p),i[5](p),l(n,h),l(n,g),i[6](g),l(a,c),l(a,f),i[7](f),l(a,u),l(a,b),i[8](b),i[9](e)},p:d,i:d,o:d,d(a){a&&m(e),i[5](null),i[6](null),i[7](null),i[8](null),i[9](null)}}}function u(i,e,a){let t,n,r,s,d,o=null!=p("alignerParent")?p("alignerParent").switchView:void 0,l=!1,m=!1,f=!1;function u(){if(null!=t.parentNode){let i=t.parentNode.host.childNodes;if(0==i.length)setTimeout(u,50);else{let e=!1,n=t.parentNode.innerHTML;for(let a of i)"sidebar-left"!=a.slot||l?"sidebar-left2"!=a.slot||m?"sidebar-right"!=a.slot||f||(n=n.replace("#sidebar-right{display:none;","#sidebar-right{"),f=!0,e=!0):(n=n.replace("#sidebar-left2{display:none}",""),m=!0,e=!0):(n=n.replace("#sidebar-left{display:none}",""),l=!0,e=!0);null!=o&&(n=n.replace("1880px",o),e=!0),e&&a(0,t.parentNode.innerHTML=n,t)}}}return window.addEventListener("resize",c(u,100)),h((()=>{u()})),[t,n,r,s,d,function(i){g[i?"unshift":"push"]((()=>{r=i,a(2,r)}))},function(i){g[i?"unshift":"push"]((()=>{s=i,a(3,s)}))},function(i){g[i?"unshift":"push"]((()=>{d=i,a(4,d)}))},function(i){g[i?"unshift":"push"]((()=>{n=i,a(1,n)}))},function(i){g[i?"unshift":"push"]((()=>{t=i,a(0,t)}))}]}class b extends i{constructor(i){super(),this.shadowRoot.innerHTML="<style>@import '/css/common.css';.pane-container{display:block;margin-left:var(--total-margin-left,0rem)}#root{min-height:var(--min-height,auto)}#main-pane{position:relative;padding-left:var(--padding-left,0rem);padding-right:var(--padding-right,0rem);padding-top:var(--padding-top,0rem);padding-bottom:var(--padding-bottom,0rem);text-align:justify;background:var(--background,white);box-shadow:var(--box-shadow,0 0 0.314rem rgb(187, 187, 187));margin:auto;height:min-content;max-width:var(--width-main,66rem);width:var(--width-main,66rem);z-index:1;overflow-x:var(--overflow-x,hidden)}.sidebar{position:absolute}#sidebars-left{display:flex;flex-direction:column;gap:1rem;margin-left:calc(-1*var(--width-left,22.5rem) - 1rem - 4rem);width:calc(var(--width-left,22.5rem) + 4rem)}#sidebar-left,#sidebar-left2{position:relative;background-color:white;padding:2rem 2rem}#sidebar-left{display:none}#sidebar-left2{display:none}#sidebar-right{display:none;margin-left:calc(var(--width-main,66rem) + 1rem);width:var(--width-right,auto);background-color:white;padding:2rem 2rem}@media only screen and (max-width: 1880px){#main-pane{max-width:initial;width:100%;max-width:var(--width-main,66rem);padding-left:var(--padding-left-mobile,1.8rem);padding-right:var(--padding-right-mobile,1.8rem);padding-top:var(--padding-top-mobile,1.8rem);padding-bottom:var(--padding-bottom-mobile,1.8rem)}#sidebars-left,#sidebar-right{position:relative;margin:auto;margin-top:1rem;margin-bottom:1rem;max-width:var(--width-main,66rem);width:100%}.pane-container{width:95%;justify-items:center;grid-auto-flow:row;margin-left:0}}</style>",e(this,{target:this.shadowRoot,props:a(this.attributes),customElement:!0},u,f,n,{},null),i&&i.target&&t(i.target,this,i.anchor)}}customElements.define("pane-aligner",b);export{b as default}; import{S as i,i as e,a,b as t,s as n,g as r,h as s,n as d,j as o,m as l,d as m,x as p,o as h,f as g}from"./index-8c09578c.js";import{debounce as c}from"../../../../../../../../../js/libraries/miscTools.js";function f(i){let e,a,n,p,h,g,c,f,u,b;return{c(){e=r("div"),a=r("div"),n=r("div"),p=r("div"),p.innerHTML='<slot name="sidebar-left"></slot>',h=s(),g=r("div"),g.innerHTML='<slot name="sidebar-left2"></slot>',c=s(),f=r("div"),f.innerHTML='<slot name="sidebar-right"></slot>',u=s(),b=r("div"),b.innerHTML='<slot name="main" id="main-slot"></slot>',this.c=d,o(p,"id","sidebar-left"),o(p,"class","pane"),o(g,"id","sidebar-left2"),o(g,"class","pane"),o(n,"id","sidebars-left"),o(n,"class","sidebar"),o(f,"id","sidebar-right"),o(f,"class","pane sidebar"),o(b,"id","main-pane"),o(b,"class","pane"),o(a,"class","pane-container"),o(e,"id","root"),o(e,"class","pane-centering")},m(r,s){t(r,e,s),l(e,a),l(a,n),l(n,p),i[5](p),l(n,h),l(n,g),i[6](g),l(a,c),l(a,f),i[7](f),l(a,u),l(a,b),i[8](b),i[9](e)},p:d,i:d,o:d,d(a){a&&m(e),i[5](null),i[6](null),i[7](null),i[8](null),i[9](null)}}}function u(i,e,a){let t,n,r,s,d,o=null!=p("alignerParent")?p("alignerParent").switchView:void 0,l=!1,m=!1,f=!1;function u(){if(null!=t.parentNode){let i=t.parentNode.host.childNodes;if(0==i.length)setTimeout(u,50);else{let e=!1,n=t.parentNode.innerHTML;for(let a of i)"sidebar-left"!=a.slot||l?"sidebar-left2"!=a.slot||m?"sidebar-right"!=a.slot||f||(n=n.replace("#sidebar-right{display:none;","#sidebar-right{"),f=!0,e=!0):(n=n.replace("#sidebar-left2{display:none}",""),m=!0,e=!0):(n=n.replace("#sidebar-left{display:none}",""),l=!0,e=!0);null!=o&&(n=n.replace("1880px",o),e=!0),e&&a(0,t.parentNode.innerHTML=n,t)}}}return window.addEventListener("resize",c(u,100)),h((()=>{u()})),[t,n,r,s,d,function(i){g[i?"unshift":"push"]((()=>{r=i,a(2,r)}))},function(i){g[i?"unshift":"push"]((()=>{s=i,a(3,s)}))},function(i){g[i?"unshift":"push"]((()=>{d=i,a(4,d)}))},function(i){g[i?"unshift":"push"]((()=>{n=i,a(1,n)}))},function(i){g[i?"unshift":"push"]((()=>{t=i,a(0,t)}))}]}class b extends i{constructor(i){super(),this.shadowRoot.innerHTML="<style>@import '/css/common.css';.pane-container{display:block;margin-left:var(--total-margin-left,0rem)}#root{min-height:var(--min-height,auto)}#main-pane{position:relative;padding-left:var(--padding-left,0rem);padding-right:var(--padding-right,0rem);padding-top:var(--padding-top,0rem);padding-bottom:var(--padding-bottom,0rem);text-align:justify;background:var(--background,white);box-shadow:var(--box-shadow,0 0 0.314rem rgb(187, 187, 187));margin:auto;height:min-content;max-width:var(--width-main,66rem);width:var(--width-main,66rem);z-index:1;overflow-x:var(--overflow-x,hidden)}.sidebar{position:absolute}#sidebars-left{display:flex;flex-direction:column;gap:1rem;margin-left:calc(-1*var(--width-left,22.5rem) - 1rem - 4rem);width:calc(var(--width-left,22.5rem) + 4rem)}#sidebar-left,#sidebar-left2{position:relative;background-color:white;padding:2rem 2rem}#sidebar-left{display:none}#sidebar-left2{display:none}#sidebar-right{display:none;margin-left:calc(var(--width-main,66rem) + 1rem);width:var(--width-right,auto);background-color:white;padding:2rem 2rem}@media only screen and (max-width: 1880px){#main-pane{max-width:initial;width:100%;max-width:var(--width-main,66rem);padding-left:var(--padding-left-mobile,1.8rem);padding-right:var(--padding-right-mobile,1.8rem);padding-top:var(--padding-top-mobile,1.8rem);padding-bottom:var(--padding-bottom-mobile,1.8rem)}#sidebars-left,#sidebar-right{position:relative;margin:auto;margin-top:1rem;margin-bottom:1rem;max-width:var(--width-main,66rem);width:100%}.pane-container{width:95%;justify-items:center;grid-auto-flow:row;margin-left:0}}</style>",e(this,{target:this.shadowRoot,props:a(this.attributes),customElement:!0},u,f,n,{},null),i&&i.target&&t(i.target,this,i.anchor)}}customElements.define("pane-aligner",b);export{b as default};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
import{S as t,i as e,a as s,b as c,u as i,s as a,f as r,g as o,n as h,h as n,l,q as d,d as u,r as p,o as b}from"./index-4348483d.js";import"../../../../../../../../../js/libraries/miscTools.js";function k(t){let e,s,i,a,b,k;return{c(){e=r("label"),s=r("input"),i=o(),a=r("span"),this.c=h,n(s,"type","checkbox"),n(a,"class","switch-span"),n(e,"class","switch")},m(r,o){c(r,e,o),l(e,s),s.checked=t[0],l(e,i),l(e,a),b||(k=[d(s,"change",t[4]),d(s,"click",t[1])],b=!0)},p(t,[e]){1&e&&(s.checked=t[0])},i:h,o:h,d(t){t&&u(e),b=!1,p(k)}}}function g(t,e,s){let{callback:c=null}=e,{checked:i=!1}=e;const a=()=>{setTimeout((()=>{null!=c?(s(0,i=!i),c()):a()}),100)};return b((()=>{})),t.$$set=t=>{"callback"in t&&s(2,c=t.callback),"checked"in t&&s(0,i=t.checked)},[i,function(){null!=c&&(s(0,i=!i),c())},c,a,function(){i=this.checked,s(0,i)}]}class m extends t{constructor(t){super(),this.shadowRoot.innerHTML="<style>@import '/css/common.css';.switch span{position:absolute;cursor:pointer;top:0;left:0;right:0;bottom:0;background-color:#ccc;-webkit-transition:.4s;transition:.4s;border-radius:calc(2* 1.2rem)}.switch span:before{position:absolute;content:\"\";height:calc(var(--height) - 0.5rem);width:calc(var(--height) - 0.5rem);left:calc(0.3rem);bottom:0.25rem;background-color:white;-webkit-transition:.4s;transition:.4s;border-radius:50%}.switch input:checked+.switch-span{background-color:var(--pink)}.switch input:hover+.switch-span{box-shadow:0 0 0 var(--pink)}.switch input:checked+.switch-span:before{-webkit-transform:translateX(calc(var(--width) - var(--height)/2 - 2*0.6rem));-ms-transform:translateX(calc(var(--width) - var(--height)/2 - 2*0.6rem));transform:translateX(calc(var(--width) - var(--height)/2 - 2*0.6rem))}.switch{position:relative;display:inline-block;width:var(--width);height:var(--height)}.switch input{position:absolute;width:var(--width);height:var(--height);opacity:0}</style>",e(this,{target:this.shadowRoot,props:s(this.attributes),customElement:!0},g,k,a,{callback:2,checked:0,toggle:3},null),t&&(t.target&&c(t.target,this,t.anchor),t.props&&(this.$set(t.props),i()))}static get observedAttributes(){return["callback","checked","toggle"]}get callback(){return this.$$.ctx[2]}set callback(t){this.$$set({callback:t}),i()}get checked(){return this.$$.ctx[0]}set checked(t){this.$$set({checked:t}),i()}get toggle(){return this.$$.ctx[3]}}customElements.define("switch-component",m);export{m as default}; import{S as t,i as e,a as s,b as c,v as i,s as a,g as r,h as o,n as h,j as n,m as l,p as d,d as p,r as u,o as b}from"./index-8c09578c.js";import"../../../../../../../../../js/libraries/miscTools.js";function k(t){let e,s,i,a,b,k;return{c(){e=r("label"),s=r("input"),i=o(),a=r("span"),this.c=h,n(s,"type","checkbox"),n(a,"class","switch-span"),n(e,"class","switch")},m(r,o){c(r,e,o),l(e,s),s.checked=t[0],l(e,i),l(e,a),b||(k=[d(s,"change",t[4]),d(s,"click",t[1])],b=!0)},p(t,[e]){1&e&&(s.checked=t[0])},i:h,o:h,d(t){t&&p(e),b=!1,u(k)}}}function g(t,e,s){let{callback:c=null}=e,{checked:i=!1}=e;const a=()=>{setTimeout((()=>{null!=c?(s(0,i=!i),c()):a()}),100)};return b((()=>{})),t.$$set=t=>{"callback"in t&&s(2,c=t.callback),"checked"in t&&s(0,i=t.checked)},[i,function(){null!=c&&(s(0,i=!i),c())},c,a,function(){i=this.checked,s(0,i)}]}class m extends t{constructor(t){super(),this.shadowRoot.innerHTML="<style>@import '/css/common.css';.switch span{position:absolute;cursor:pointer;top:0;left:0;right:0;bottom:0;background-color:#ccc;-webkit-transition:.4s;transition:.4s;border-radius:calc(2* 1.2rem)}.switch span:before{position:absolute;content:\"\";height:calc(var(--height) - 0.5rem);width:calc(var(--height) - 0.5rem);left:calc(0.3rem);bottom:0.25rem;background-color:white;-webkit-transition:.4s;transition:.4s;border-radius:50%}.switch input:checked+.switch-span{background-color:var(--pink)}.switch input:hover+.switch-span{box-shadow:0 0 0 var(--pink)}.switch input:checked+.switch-span:before{-webkit-transform:translateX(calc(var(--width) - var(--height)/2 - 2*0.6rem));-ms-transform:translateX(calc(var(--width) - var(--height)/2 - 2*0.6rem));transform:translateX(calc(var(--width) - var(--height)/2 - 2*0.6rem))}.switch{position:relative;display:inline-block;width:var(--width);height:var(--height)}.switch input{position:absolute;width:var(--width);height:var(--height);opacity:0}</style>",e(this,{target:this.shadowRoot,props:s(this.attributes),customElement:!0},g,k,a,{callback:2,checked:0,toggle:3},null),t&&(t.target&&c(t.target,this,t.anchor),t.props&&(this.$set(t.props),i()))}static get observedAttributes(){return["callback","checked","toggle"]}get callback(){return this.$$.ctx[2]}set callback(t){this.$$set({callback:t}),i()}get checked(){return this.$$.ctx[0]}set checked(t){this.$$set({checked:t}),i()}get toggle(){return this.$$.ctx[3]}}customElements.define("switch-component",m);export{m as default};

View File

@ -0,0 +1,90 @@
let contactGeneral =["https://discord.gg/4BUau4AZre","DiscordInviteLink"]
export function translate(content, x) {
let out = content[x]
if (out==undefined) {
return x
}
else {
return out
}
}
function addMarkersToLayer(g,layer,content,locale,addPinContent,markerColor) {
let {text,coordinates} = addPinContent(g,content,locale)
var markerIcon = new L.Icon({
iconUrl: 'https://www.libsoc.org/img/common/markers/marker-' + markerColor + '.png',
shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/images/marker-shadow.png',
iconSize: [25, 41],
iconAnchor: [12, 41],
popupAnchor: [1, -34],
shadowSize: [41, 41]
})
let marker = L.marker(coordinates, {icon: markerIcon})
marker.addTo(layer).bindPopup(text)
}
export function addMarkersEntries(entries,entriesByCountry,map,content,locale,addPinContent,markerColor) {
let entriesMarkersLayer = L.layerGroup()
let entriesMarkersLayerOut = L.layerGroup()
let entriesMarkersLayerIn = L.layerGroup()
for (let g of entries) {
if (g.country!="Online" && g.country!="Worldwide") {
addMarkersToLayer(g,entriesMarkersLayerIn,content,locale,addPinContent,markerColor)
}
}
for (let gs of Object.values(entriesByCountry)) {
if (gs.length==1) {
let g = {...gs[0]}
g.country = [g.country]
if (g.country!="Online" && g.country!="Worldwide") {
addMarkersToLayer(g,entriesMarkersLayerOut,content,locale,addPinContent,markerColor)
}
}
else {
if (gs[0].country!="Online" && gs[0].country!="Worldwide") {
let locationName = gs[0].country
let locationCoordinates = [0,0]
let members = 0
let contact = gs[0].contact
for (let g of gs) {
locationCoordinates[0] += g.latitude
locationCoordinates[1] += g.longitude
members += g.members
if (g.contact[0]!=gs[0].contact[0]) {
contact = contactGeneral
}
}
locationCoordinates[0] = locationCoordinates[0]/gs.length
locationCoordinates[1] = locationCoordinates[1]/gs.length
let gNew = {
country: locationName,
latitude: locationCoordinates[0],
longitude: locationCoordinates[1],
members: members,
contact: contact
}
addMarkersToLayer(gNew,entriesMarkersLayerOut,content,locale,addPinContent,markerColor)
}
}
}
entriesMarkersLayerOut.addTo(entriesMarkersLayer)
entriesMarkersLayer.addTo(map)
map.on("zoomend", () => onZoomEnd(map,entriesMarkersLayer,entriesMarkersLayerOut,entriesMarkersLayerIn))
return entriesMarkersLayer
}
function onZoomEnd(map,entriesMarkersLayer,entriesMarkersLayerOut,entriesMarkersLayerIn) {
let zoomLevel = map.getZoom()
if (zoomLevel==3) {
entriesMarkersLayer.removeLayer(entriesMarkersLayerIn)
entriesMarkersLayerOut.addTo(entriesMarkersLayer)
}
else if (zoomLevel==4) {
entriesMarkersLayer.removeLayer(entriesMarkersLayerOut)
entriesMarkersLayerIn.addTo(entriesMarkersLayer)
}
}

View File

@ -0,0 +1,178 @@
import { translate } from "/js/libraries/mapTools.js"
export function addGroupPinContent(g,content,locale) {
let coordinates
let text = "<b>"+content["Group"]+"</b><br>"
for (let field of ["location","members","contact"]) {
let fieldText = content[field] + ": "
if (field=="contact") {
text += fieldText + "<a href='" + g.contact + "' target='_blank' rel=noreferrer>" + g.contact + "</a>"
}
else if (field=="location") {
let location = [g.country,g.state,g.town].filter(x => x!=null && x!=undefined)
let locationString
if (locale=="en") {
locationString = location.map(x => x).join(", ")
}
else {
locationString = location.map(x => translate(content, x)).join(", ")
}
text += fieldText + locationString + "<br>"
coordinates = [g.latitude,g.longitude]
}
else {
text += fieldText + g[field] + "<br>"
}
}
return {text,coordinates}
}
export function addCommunePinContent(g,content,locale) {
let coordinates
let text = "<b>"+content["Commune"]+"</b><br>"
for (let field of ["location","status","members","contact"]) {
let fieldText = content[field] + ": "
if (field=="contact") {
text += fieldText + "<a href='" + g.contact + "' target='_blank' rel=noreferrer>" + g.contact + "</a>"
}
else if (field=="location") {
let location = [g.country,g.state,g.town].filter(x => x!=null && x!=undefined)
let locationString
if (locale=="en") {
locationString = location.map(x => x).join(", ")
}
else {
locationString = location.map(x => translate(content, x)).join(", ")
}
text += fieldText + locationString + "<br>"
coordinates = [g.latitude,g.longitude]
}
else if (field=="status") {
text += fieldText + content[g[field]] + "<br>"
}
else {
text += fieldText + g[field] + "<br>"
}
}
return {text,coordinates}
}
export function addCoopPinContent(g,content,locale) {
let coordinates
let text = "<b>"+content["Cooperative"]+"</b><br>"
for (let field of ["logo","name","location","workers","status","website","contact","description"]) {
let fieldText
if (field!="logo") {
fieldText = content[field] + ": "
}
if (field=="logo") {
text += "<picture><source srcset=" + "/img/coops/" + g.logo + ".webp><source srcset='/img/coops/" + g.logo + ".png'><img alt='logo' style='position: relative; max-height: 5rem; max-width: 100%; margin: auto;'></picture>" + "<br>"
}
else if (field=="contact") {
text += fieldText + "<a href='https://www." + g.contact + "' target='_blank' rel=noreferrer>" + g.contact + "</a>" + "<br>"
}
else if (field=="website") {
text += fieldText + "<a href='" + g.website + "' target='_blank' rel=noreferrer>" + g.website + "</a>" + "<br>"
}
else if (field=="location") {
let location = [g.country,g.state,g.town].filter(x => x!=null && x!=undefined)
let locationString
if (locale=="en") {
locationString = location.map(x => x).join(", ")
}
else {
locationString = location.map(x => translate(content, x)).join(", ")
}
text += fieldText + locationString + "<br>"
coordinates = [g.latitude,g.longitude]
}
else if (field=="market" || field=="status" || field=="description") {
text += fieldText + g[field] + "<br>"
}
else {
text += fieldText + g[field] + "<br>"
}
}
return {text,coordinates}
}
export function addPartyPinContent(g,content,locale) {
let coordinates
let text = "<b>"+content["Cooperative"]+"</b><br>"
for (let field of ["logo","name","location","website","contact","description"]) {
let fieldText
if (field!="logo") {
fieldText = content[field] + ": "
}
if (field=="logo") {
text += "<picture><source srcset=" + "/img/parties/" + g.logo + ".webp><source srcset='/img/parties/" + g.logo + ".png'><img alt='logo' style='position: relative; max-height: 5rem; max-width: 100%; margin: auto;'></picture>" + "<br>"
}
else if (field=="link") {
text += fieldText + "<a href='" + g.link + "' target='_blank' rel=noreferrer>" + g.link + "</a>" + "<br>"
}
else if (field=="website") {
text += fieldText + "<a href='" + g.website + "' target='_blank' rel=noreferrer>" + g.website + "</a>" + "<br>"
}
else if (field=="location") {
let location = [g.country,g.state,g.town].filter(x => x!=null && x!=undefined)
let locationString
if (locale=="en") {
locationString = location.map(x => x).join(", ")
}
else {
locationString = location.map(x => translate(content, x)).join(", ")
}
text += fieldText + locationString + "<br>"
coordinates = [g.latitude,g.longitude]
}
else if (field=="description") {
text += fieldText + content[g[field]] + "<br>"
}
else if (field=="contact") {
text += fieldText + "<a href='" + g.contact + "' target='_blank' rel=noreferrer>" + g.contact + "</a>" + "<br>"
}
else {
text += fieldText + g[field] + "<br>"
}
}
return {text,coordinates}
}
export function addPartnersPinContent(g,content,locale) {
let coordinates
let text = "<b>"+content["Partner"]+"</b><br>"
for (let field of ["logo","name","location","website","contact","description"]) {
let fieldText
if (field!="logo") {
fieldText = content[field] + ": "
}
if (field=="logo") {
text += "<picture><source srcset=" + "/img/coops/" + g.logo + ".webp><source srcset='/img/coops/" + g.logo + ".png'><img alt='logo' style='position: relative; max-height: 5rem; max-width: 100%; margin: auto;'></picture>" + "<br>"
}
else if (field=="contact") {
text += fieldText + "<a href='https://www." + g.contact + "' target='_blank' rel=noreferrer>" + g.contact + "</a>" + "<br>"
}
else if (field=="website") {
text += fieldText + "<a href='" + g.website + "' target='_blank' rel=noreferrer>" + g.website + "</a>" + "<br>"
}
else if (field=="location") {
let location = [g.country,g.state,g.town].filter(x => x!=null && x!=undefined)
let locationString
if (locale=="en") {
locationString = location.map(x => x).join(", ")
}
else {
locationString = location.map(x => translate(content, x)).join(", ")
}
text += fieldText + locationString + "<br>"
coordinates = [g.latitude,g.longitude]
}
else if (field=="description") {
text += fieldText + g[field] + "<br>"
}
else {
text += fieldText + g[field] + "<br>"
}
}
return {text,coordinates}
}

View File

@ -10,5 +10,6 @@
"forming": "forming", "forming": "forming",
"WhatsAppInviteLink": "WhatsApp invite link", "WhatsAppInviteLink": "WhatsApp invite link",
"DiscordInviteLink": "Discord invite link", "DiscordInviteLink": "Discord invite link",
"Commune": "Commune" "Commune": "Commune",
"map-prompt": "Want to appear on our map? Contact us!"
} }

View File

@ -18,6 +18,7 @@
"descriptionChironHealth": "Chiron Health is a health platform providing courses and services on the topics of nutrition, exercise, sleep and mental wellbeing.", "descriptionChironHealth": "Chiron Health is a health platform providing courses and services on the topics of nutrition, exercise, sleep and mental wellbeing.",
"herbalTeas": "herbal teas", "herbalTeas": "herbal teas",
"kuuskDescription": "Kuusk is an online store that sells herbal teas from exclusively local wild plants, as well as an online gathering course.", "kuuskDescription": "Kuusk is an online store that sells herbal teas from exclusively local wild plants, as well as an online gathering course.",
"Cooperative": "Cooperative" "Cooperative": "Cooperative",
"map-prompt": "Want to appear on our map? Contact us!"
} }

View File

@ -1,3 +1,3 @@
{ {
"map-prompt": "Want to appear on our map? Contact us!"
} }

Some files were not shown because too many files have changed in this diff Show More