refactoring: move logic of lastclick into special layer, fix labels, fix anchoring

This commit is contained in:
Pieter Vander Vennet 2023-04-02 02:59:20 +02:00
parent 25a98af057
commit 52a0810ea9
47 changed files with 682 additions and 197 deletions

View file

@ -50,6 +50,9 @@ export default class SelectedElementTagsUpdater {
const state = this.state const state = this.state
state.selectedElement.addCallbackAndRunD(async (s) => { state.selectedElement.addCallbackAndRunD(async (s) => {
let id = s.properties?.id let id = s.properties?.id
if (!id) {
return
}
const backendUrl = state.osmConnection._oauth_config.url const backendUrl = state.osmConnection._oauth_config.url
if (id.startsWith(backendUrl)) { if (id.startsWith(backendUrl)) {

View file

@ -20,32 +20,24 @@ export default class TitleHandler {
(selected) => { (selected) => {
const defaultTitle = state.layout?.title?.txt ?? "MapComplete" const defaultTitle = state.layout?.title?.txt ?? "MapComplete"
if (selected === undefined) { if (selected === undefined || selectedLayer.data === undefined) {
return defaultTitle return defaultTitle
} }
const tags = selected.properties const tags = selected.properties
for (const layer of state.layout?.layers ?? []) { const layer = selectedLayer.data
if (layer.title === undefined) { const tagsSource =
continue allElements.getStore(tags.id) ?? new UIEventSource<Record<string, string>>(tags)
} const title = new SvelteUIElement(TagRenderingAnswer, {
if (layer.source.osmTags.matchesProperties(tags)) { tags: tagsSource,
const tagsSource = state,
allElements.getStore(tags.id) ?? selectedElement: selectedElement.data,
new UIEventSource<Record<string, string>>(tags) layer,
const title = new SvelteUIElement(TagRenderingAnswer, { })
tags: tagsSource, return (
state, new Combine([defaultTitle, " | ", title]).ConstructElement()?.textContent ??
selectedElement: selectedElement.data, defaultTitle
layer: selectedLayer.data, )
})
return (
new Combine([defaultTitle, " | ", title]).ConstructElement()
?.textContent ?? defaultTitle
)
}
}
return defaultTitle
}, },
[Locale.language, selectedLayer] [Locale.language, selectedLayer]
) )

View file

@ -43,6 +43,10 @@ export default class FeaturePropertiesStore {
return this._elements.get(id) return this._elements.get(id)
} }
public addSpecial(id: string, store: UIEventSource<Record<string, string>>) {
this._elements.set(id, store)
}
/** /**
* Overwrites the tags of the old properties object, returns true if a change was made. * Overwrites the tags of the old properties object, returns true if a change was made.
* Metatags are overriden if they are in the new properties, but not removed * Metatags are overriden if they are in the new properties, but not removed

View file

@ -0,0 +1,57 @@
import LayoutConfig from "../../../Models/ThemeConfig/LayoutConfig"
import FeatureSource from "../FeatureSource"
import { ImmutableStore, Store } from "../../UIEventSource"
import { Feature, Point } from "geojson"
import { TagUtils } from "../../Tags/TagUtils"
import BaseUIElement from "../../../UI/BaseUIElement"
import { Utils } from "../../../Utils"
import { regex_not_newline_characters } from "svelte/types/compiler/utils/patterns"
import { render } from "sass"
/**
* Highly specialized feature source.
* Based on a lon/lat UIEVentSource, will generate the corresponding feature with the correct properties
*/
export class LastClickFeatureSource implements FeatureSource {
features: Store<Feature[]>
public properties: Record<string, string>
constructor(location: Store<{ lon: number; lat: number }>, layout: LayoutConfig) {
const allPresets: BaseUIElement[] = []
for (const layer of layout.layers)
for (let i = 0; i < (layer.presets ?? []).length; i++) {
const preset = layer.presets[i]
const tags = new ImmutableStore(TagUtils.KVtoProperties(preset.tags))
const { html } = layer.mapRendering[0].RenderIcon(tags, false, {
noSize: true,
includeBadges: false,
})
allPresets.push(html)
}
const renderings = Utils.Dedup(
allPresets.map((uiElem) => uiElem.ConstructElement().innerHTML)
)
const properties = {
lastclick: "yes",
id: "last_click",
has_note_layer: layout.layers.some((l) => l.id === "note") ? "yes" : "no",
has_presets: layout.layers.some((l) => l.presets?.length > 0) ? "yes" : "no",
renderings: renderings.join(""),
number_of_presets: "" + renderings.length,
first_preset: renderings[0],
}
this.properties = properties
this.features = location.mapD(({ lon, lat }) => [
<Feature<Point>>{
type: "Feature",
properties,
geometry: {
type: "Point",
coordinates: [lon, lat],
},
},
])
}
}

View file

@ -21,16 +21,16 @@ export class TagUtils {
[">", (a, b) => a > b], [">", (a, b) => a > b],
] ]
static KVtoProperties(tags: Tag[]): any { static KVtoProperties(tags: Tag[]): Record<string, string> {
const properties = {} const properties : Record<string, string> = {}
for (const tag of tags) { for (const tag of tags) {
properties[tag.key] = tag.value properties[tag.key] = tag.value
} }
return properties return properties
} }
static changeAsProperties(kvs: { k: string; v: string }[]): any { static changeAsProperties(kvs: { k: string; v: string }[]): Record<string, string> {
const tags = {} const tags: Record<string, string> = {}
for (const kv of kvs) { for (const kv of kvs) {
tags[kv.k] = kv.v tags[kv.k] = kv.v
} }

View file

@ -33,6 +33,7 @@ export default class Constants {
"home_location", "home_location",
"gps_track", "gps_track",
"range", "range",
"last_click",
] as const ] as const
/** /**
* Special layers which are not included in a theme by default * Special layers which are not included in a theme by default
@ -66,10 +67,10 @@ export default class Constants {
themeGeneratorReadOnlyUnlock: 50, themeGeneratorReadOnlyUnlock: 50,
themeGeneratorFullUnlock: 500, themeGeneratorFullUnlock: 500,
addNewPointWithUnreadMessagesUnlock: 500, addNewPointWithUnreadMessagesUnlock: 500,
minZoomLevelToAddNewPoints: Constants.isRetina() ? 18 : 19,
importHelperUnlock: 5000, importHelperUnlock: 5000,
} }
static readonly minZoomLevelToAddNewPoint = Constants.isRetina() ? 18 : 19
/** /**
* Used by 'PendingChangesUploader', which waits this amount of seconds to upload changes. * Used by 'PendingChangesUploader', which waits this amount of seconds to upload changes.
* (Note that pendingChanges might upload sooner if the popup is closed or similar) * (Note that pendingChanges might upload sooner if the popup is closed or similar)

View file

@ -1,4 +1,4 @@
import { UIEventSource } from "../Logic/UIEventSource" import { Store, UIEventSource } from "../Logic/UIEventSource"
import { BBox } from "../Logic/BBox" import { BBox } from "../Logic/BBox"
import { RasterLayerPolygon } from "./RasterLayers" import { RasterLayerPolygon } from "./RasterLayers"
@ -10,5 +10,7 @@ export interface MapProperties {
readonly maxbounds: UIEventSource<undefined | BBox> readonly maxbounds: UIEventSource<undefined | BBox>
readonly allowMoving: UIEventSource<true | boolean> readonly allowMoving: UIEventSource<true | boolean>
readonly lastClickLocation: Store<{ lon: number; lat: number }>
readonly allowZooming: UIEventSource<true | boolean> readonly allowZooming: UIEventSource<true | boolean>
} }

View file

@ -5,6 +5,7 @@ import metapaths from "../../../assets/layoutconfigmeta.json"
import tagrenderingmetapaths from "../../../assets/questionabletagrenderingconfigmeta.json" import tagrenderingmetapaths from "../../../assets/questionabletagrenderingconfigmeta.json"
import Translations from "../../../UI/i18n/Translations" import Translations from "../../../UI/i18n/Translations"
import { parse as parse_html } from "node-html-parser"
export class ExtractImages extends Conversion< export class ExtractImages extends Conversion<
LayoutConfigJson, LayoutConfigJson,
{ path: string; context: string }[] { path: string; context: string }[]
@ -190,6 +191,17 @@ export class ExtractImages extends Conversion<
const cleanedImages: { path: string; context: string }[] = [] const cleanedImages: { path: string; context: string }[] = []
for (const foundImage of allFoundImages) { for (const foundImage of allFoundImages) {
if (foundImage.path.startsWith("<") && foundImage.path.endsWith(">")) {
// These is probably html - we ignore
const doc = parse_html(foundImage.path)
const images = Array.from(doc.getElementsByTagName("img"))
const paths = images.map((i) => i.getAttribute("src"))
cleanedImages.push(
...paths.map((path) => ({ path, context: foundImage.context + " (in html)" }))
)
continue
}
// Split "circle:white;./assets/layers/.../something.svg" into ["circle", "./assets/layers/.../something.svg"] // Split "circle:white;./assets/layers/.../something.svg" into ["circle", "./assets/layers/.../something.svg"]
const allPaths = Utils.NoNull( const allPaths = Utils.NoNull(
Utils.NoEmpty(foundImage.path?.split(";")?.map((part) => part.split(":")[0])) Utils.NoEmpty(foundImage.path?.split(";")?.map((part) => part.split(":")[0]))

View file

@ -101,6 +101,11 @@ export class DoesImageExist extends DesugaringStep<string> {
} }
} }
if (image.startsWith("<") && image.endsWith(">")) {
// This is probably HTML, you're on your own here
return { result: image }
}
if (!this._knownImagePaths.has(image)) { if (!this._knownImagePaths.has(image)) {
if (this.doesPathExist === undefined) { if (this.doesPathExist === undefined) {
errors.push( errors.push(
@ -730,9 +735,9 @@ export class ValidateLayer extends DesugaringStep<LayerConfigJson> {
} }
} }
if (json.minzoom > Constants.userJourney.minZoomLevelToAddNewPoints) { if (json.minzoom > Constants.minZoomLevelToAddNewPoint) {
;(json.presets?.length > 0 ? errors : warnings).push( ;(json.presets?.length > 0 ? errors : warnings).push(
`At ${context}: minzoom is ${json.minzoom}, this should be at most ${Constants.userJourney.minZoomLevelToAddNewPoints} as a preset is set. Why? Selecting the pin for a new item will zoom in to level before adding the point. Having a greater minzoom will hide the points, resulting in possible duplicates` `At ${context}: minzoom is ${json.minzoom}, this should be at most ${Constants.minZoomLevelToAddNewPoint} as a preset is set. Why? Selecting the pin for a new item will zoom in to level before adding the point. Having a greater minzoom will hide the points, resulting in possible duplicates`
) )
} }
{ {

View file

@ -69,15 +69,25 @@ export default interface PointRenderingConfigJson {
label?: string | TagRenderingConfigJson label?: string | TagRenderingConfigJson
/** /**
* A snippet of css code * A snippet of css code which is applied onto the container of the entire marker
*/ */
css?: string | TagRenderingConfigJson css?: string | TagRenderingConfigJson
/** /**
* A snippet of css-classes. They can be space-separated * A snippet of css-classes which are applied onto the container of the entire marker. They can be space-separated
*/ */
cssClasses?: string | TagRenderingConfigJson cssClasses?: string | TagRenderingConfigJson
/**
* Css that is applied onto the label
*/
labelCss?: string | TagRenderingConfigJson
/**
* Css classes that are applied onto the label; can be space-separated
*/
labelCssClasses?: string | TagRenderingConfigJson
/** /**
* If the map is pitched, the marker will stay parallel to the screen. * If the map is pitched, the marker will stay parallel to the screen.
* Set to 'map' if you want to put it flattened on the map * Set to 'map' if you want to put it flattened on the map

View file

@ -30,6 +30,7 @@ import { FixedUiElement } from "../../UI/Base/FixedUiElement"
import Svg from "../../Svg" import Svg from "../../Svg"
import { ImmutableStore } from "../../Logic/UIEventSource" import { ImmutableStore } from "../../Logic/UIEventSource"
import { OsmTags } from "../OsmFeature" import { OsmTags } from "../OsmFeature"
import Constants from "../Constants"
export default class LayerConfig extends WithContextLoader { export default class LayerConfig extends WithContextLoader {
public static readonly syncSelectionAllowed = ["no", "local", "theme-only", "global"] as const public static readonly syncSelectionAllowed = ["no", "local", "theme-only", "global"] as const
@ -322,7 +323,8 @@ export default class LayerConfig extends WithContextLoader {
} else if ( } else if (
!hasCenterRendering && !hasCenterRendering &&
this.lineRendering.length === 0 && this.lineRendering.length === 0 &&
!this.source.geojsonSource?.startsWith( Constants.priviliged_layers.indexOf(<any>this.id) < 0 &&
!this.source?.geojsonSource?.startsWith(
"https://api.openstreetmap.org/api/0.6/notes.json" "https://api.openstreetmap.org/api/0.6/notes.json"
) )
) { ) {
@ -425,8 +427,10 @@ export default class LayerConfig extends WithContextLoader {
return mapRendering.GetBaseIcon(this.GetBaseTags()) return mapRendering.GetBaseIcon(this.GetBaseTags())
} }
public GetBaseTags(): any { public GetBaseTags(): Record<string, string> {
return TagUtils.changeAsProperties(this.source.osmTags.asChange({ id: "node/-1" })) return TagUtils.changeAsProperties(
this.source?.osmTags?.asChange({ id: "node/-1" }) ?? [{ k: "id", v: "node/-1" }]
)
} }
public GenerateDocumentation( public GenerateDocumentation(

View file

@ -11,6 +11,7 @@ import { FixedUiElement } from "../../UI/Base/FixedUiElement"
import Img from "../../UI/Base/Img" import Img from "../../UI/Base/Img"
import Combine from "../../UI/Base/Combine" import Combine from "../../UI/Base/Combine"
import { VariableUiElement } from "../../UI/Base/VariableUIElement" import { VariableUiElement } from "../../UI/Base/VariableUIElement"
import { html } from "svelte/types/compiler/utils/namespaces"
export default class PointRenderingConfig extends WithContextLoader { export default class PointRenderingConfig extends WithContextLoader {
private static readonly allowed_location_codes = new Set<string>([ private static readonly allowed_location_codes = new Set<string>([
@ -28,6 +29,8 @@ export default class PointRenderingConfig extends WithContextLoader {
public readonly iconBadges: { if: TagsFilter; then: TagRenderingConfig }[] public readonly iconBadges: { if: TagsFilter; then: TagRenderingConfig }[]
public readonly iconSize: TagRenderingConfig public readonly iconSize: TagRenderingConfig
public readonly label: TagRenderingConfig public readonly label: TagRenderingConfig
public readonly labelCss: TagRenderingConfig
public readonly labelCssClasses: TagRenderingConfig
public readonly rotation: TagRenderingConfig public readonly rotation: TagRenderingConfig
public readonly cssDef: TagRenderingConfig public readonly cssDef: TagRenderingConfig
public readonly cssClasses?: TagRenderingConfig public readonly cssClasses?: TagRenderingConfig
@ -72,6 +75,8 @@ export default class PointRenderingConfig extends WithContextLoader {
this.cssDef = this.tr("css", undefined) this.cssDef = this.tr("css", undefined)
} }
this.cssClasses = this.tr("cssClasses", undefined) this.cssClasses = this.tr("cssClasses", undefined)
this.labelCss = this.tr("labelCss", undefined)
this.labelCssClasses = this.tr("labelCssClasses", undefined)
this.iconBadges = (json.iconBadges ?? []).map((overlay, i) => { this.iconBadges = (json.iconBadges ?? []).map((overlay, i) => {
return { return {
if: TagUtils.Tag(overlay.if), if: TagUtils.Tag(overlay.if),
@ -150,7 +155,7 @@ export default class PointRenderingConfig extends WithContextLoader {
} }
} }
public GetBaseIcon(tags?: any): BaseUIElement { public GetBaseIcon(tags?: Record<string, string>): BaseUIElement {
tags = tags ?? { id: "node/-1" } tags = tags ?? { id: "node/-1" }
let defaultPin: BaseUIElement = undefined let defaultPin: BaseUIElement = undefined
if (this.label === undefined) { if (this.label === undefined) {
@ -168,6 +173,10 @@ export default class PointRenderingConfig extends WithContextLoader {
// This layer doesn't want to show an icon right now // This layer doesn't want to show an icon right now
return undefined return undefined
} }
if (htmlDefs.startsWith("<") && htmlDefs.endsWith(">")) {
// This is probably already prepared HTML
return new FixedUiElement(Utils.SubstituteKeys(htmlDefs, tags))
}
return PointRenderingConfig.FromHtmlMulti(htmlDefs, rotation, false, defaultPin) return PointRenderingConfig.FromHtmlMulti(htmlDefs, rotation, false, defaultPin)
} }
@ -225,10 +234,10 @@ export default class PointRenderingConfig extends WithContextLoader {
} }
if (mode === "top") { if (mode === "top") {
anchorH = -iconH / 2 anchorH = iconH / 2
} }
if (mode === "bottom") { if (mode === "bottom") {
anchorH = iconH / 2 anchorH = -iconH / 2
} }
const icon = this.GetSimpleIcon(tags) const icon = this.GetSimpleIcon(tags)
@ -244,10 +253,11 @@ export default class PointRenderingConfig extends WithContextLoader {
iconAndBadges.SetClass("w-full h-full") iconAndBadges.SetClass("w-full h-full")
} }
const css = this.cssDef?.GetRenderValue(tags)?.txt const css = this.cssDef?.GetRenderValue(tags.data)?.txt
const cssClasses = this.cssClasses?.GetRenderValue(tags)?.txt const cssClasses = this.cssClasses?.GetRenderValue(tags.data)?.txt
let label = this.GetLabel(tags) let label = this.GetLabel(tags)
let htmlEl: BaseUIElement let htmlEl: BaseUIElement
if (icon === undefined && label === undefined) { if (icon === undefined && label === undefined) {
htmlEl = undefined htmlEl = undefined
@ -288,6 +298,12 @@ export default class PointRenderingConfig extends WithContextLoader {
badge.then.GetRenderValue(tags)?.txt, badge.then.GetRenderValue(tags)?.txt,
tags tags
) )
if (htmlDefs.startsWith("<") && htmlDefs.endsWith(">")) {
// This is probably an HTML-element
return new FixedUiElement(Utils.SubstituteKeys(htmlDefs, tags))
.SetStyle("width: 1.5rem")
.SetClass("block")
}
const badgeElement = PointRenderingConfig.FromHtmlMulti( const badgeElement = PointRenderingConfig.FromHtmlMulti(
htmlDefs, htmlDefs,
"0", "0",
@ -308,14 +324,20 @@ export default class PointRenderingConfig extends WithContextLoader {
if (this.label === undefined) { if (this.label === undefined) {
return undefined return undefined
} }
const cssLabel = this.labelCss?.GetRenderValue(tags.data)?.txt
const cssClassesLabel = this.labelCssClasses?.GetRenderValue(tags.data)?.txt
const self = this const self = this
return new VariableUiElement( return new VariableUiElement(
tags.map((tags) => { tags.map((tags) => {
const label = self.label const label = self.label
?.GetRenderValue(tags) ?.GetRenderValue(tags)
?.Subs(tags) ?.Subs(tags)
?.SetClass("block text-center") ?.SetClass("block center absolute text-center ")
return new Combine([label]).SetClass("flex flex-col items-center mt-1") ?.SetClass(cssClassesLabel)
if (cssLabel) {
label.SetStyle(cssLabel)
}
return new Combine([label]).SetClass("flex flex-col items-center")
}) })
) )
} }

View file

@ -1,7 +1,7 @@
import LayoutConfig from "./ThemeConfig/LayoutConfig" import LayoutConfig from "./ThemeConfig/LayoutConfig"
import { SpecialVisualizationState } from "../UI/SpecialVisualization" import { SpecialVisualizationState } from "../UI/SpecialVisualization"
import { Changes } from "../Logic/Osm/Changes" import { Changes } from "../Logic/Osm/Changes"
import { Store, UIEventSource } from "../Logic/UIEventSource" import { ImmutableStore, Store, UIEventSource } from "../Logic/UIEventSource"
import FeatureSource, { import FeatureSource, {
IndexedFeatureSource, IndexedFeatureSource,
WritableFeatureSource, WritableFeatureSource,
@ -38,6 +38,7 @@ import Constants from "./Constants"
import Hotkeys from "../UI/Base/Hotkeys" import Hotkeys from "../UI/Base/Hotkeys"
import Translations from "../UI/i18n/Translations" import Translations from "../UI/i18n/Translations"
import { GeoIndexedStoreForLayer } from "../Logic/FeatureSource/Actors/GeoIndexedStore" import { GeoIndexedStoreForLayer } from "../Logic/FeatureSource/Actors/GeoIndexedStore"
import { LastClickFeatureSource } from "../Logic/FeatureSource/Sources/LastClickFeatureSource"
/** /**
* *
@ -105,6 +106,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
this.mapProperties, this.mapProperties,
this.userRelatedState.gpsLocationHistoryRetentionTime this.userRelatedState.gpsLocationHistoryRetentionTime
) )
this.availableLayers = AvailableRasterLayers.layersAvailableAt(this.mapProperties.location) this.availableLayers = AvailableRasterLayers.layersAvailableAt(this.mapProperties.location)
this.layerState = new LayerState(this.osmConnection, layout.layers, layout.id) this.layerState = new LayerState(this.osmConnection, layout.layers, layout.id)
@ -203,11 +205,45 @@ export default class ThemeViewState implements SpecialVisualizationState {
*/ */
private drawSpecialLayers() { private drawSpecialLayers() {
type AddedByDefaultTypes = typeof Constants.added_by_default[number] type AddedByDefaultTypes = typeof Constants.added_by_default[number]
const empty = []
{
// The last_click gets a _very_ special treatment
const last_click = new LastClickFeatureSource(
this.mapProperties.lastClickLocation,
this.layout
)
const last_click_layer = this.layerState.filteredLayers.get("last_click")
this.featureProperties.addSpecial(
"last_click",
new UIEventSource<Record<string, string>>(last_click.properties)
)
new ShowDataLayer(this.map, {
features: last_click,
doShowLayer: new ImmutableStore(true),
layer: last_click_layer.layerDef,
selectedElement: this.selectedElement,
selectedLayer: this.selectedLayer,
onClick: (feature: Feature) => {
if (this.mapProperties.zoom.data < Constants.minZoomLevelToAddNewPoint) {
this.map.data.flyTo({
zoom: Constants.minZoomLevelToAddNewPoint,
center: this.mapProperties.lastClickLocation.data,
})
return
}
this.selectedElement.setData(feature)
this.selectedLayer.setData(last_click_layer.layerDef)
},
})
}
/** /**
* A listing which maps the layerId onto the featureSource * A listing which maps the layerId onto the featureSource
*/ */
const empty = [] const specialLayers: Record<
const specialLayers: Record<AddedByDefaultTypes | "current_view", FeatureSource> = { Exclude<AddedByDefaultTypes, "last_click"> | "current_view",
FeatureSource
> = {
home_location: this.userRelatedState.homeLocation, home_location: this.userRelatedState.homeLocation,
gps_location: this.geolocation.currentUserLocation, gps_location: this.geolocation.currentUserLocation,
gps_location_history: this.geolocation.historicalUserLocations, gps_location_history: this.geolocation.historicalUserLocations,
@ -261,12 +297,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
*/ */
private initActors() { private initActors() {
// Various actors that we don't need to reference // Various actors that we don't need to reference
new TitleHandler( new TitleHandler(this.selectedElement, this.selectedLayer, this.featureProperties, this)
this.selectedElement,
this.selectedLayer,
this.featureProperties,
this.layout
)
new ChangeToElementsActor(this.changes, this.featureProperties) new ChangeToElementsActor(this.changes, this.featureProperties)
new PendingChangesUploader(this.changes, this.selectedElement) new PendingChangesUploader(this.changes, this.selectedElement)
new SelectedElementTagsUpdater({ new SelectedElementTagsUpdater({

11
UI/Base/FloatOver.svelte Normal file
View file

@ -0,0 +1,11 @@
<script lang="ts">
/**
* The slotted element will be shown on top, with a lower-opacity border
*/
</script>
<div class="absolute top-0 right-0 w-screen h-screen overflow-auto" style="background-color: #00000088">
<div class="flex flex-col m-4 sm:m-6 md:m-8 p-4 sm:p-6 md:m-8 normal-background rounded normal-background">
<slot></slot>
</div>
</div>

View file

@ -1,7 +1,7 @@
/** /**
* Asks to add a feature at the last clicked location, at least if zoom is sufficient * Asks to add a feature at the last clicked location, at least if zoom is sufficient
*/ */
import { ImmutableStore, Store, UIEventSource } from "../../Logic/UIEventSource" import { ImmutableStore, UIEventSource } from "../../Logic/UIEventSource"
import Svg from "../../Svg" import Svg from "../../Svg"
import { SubtleButton } from "../Base/SubtleButton" import { SubtleButton } from "../Base/SubtleButton"
import Combine from "../Base/Combine" import Combine from "../Base/Combine"
@ -16,18 +16,14 @@ import CreateNewNodeAction from "../../Logic/Osm/Actions/CreateNewNodeAction"
import { OsmObject, OsmWay } from "../../Logic/Osm/OsmObject" import { OsmObject, OsmWay } from "../../Logic/Osm/OsmObject"
import PresetConfig from "../../Models/ThemeConfig/PresetConfig" import PresetConfig from "../../Models/ThemeConfig/PresetConfig"
import FilteredLayer from "../../Models/FilteredLayer" import FilteredLayer from "../../Models/FilteredLayer"
import Loc from "../../Models/Loc"
import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig"
import { Changes } from "../../Logic/Osm/Changes"
import FeaturePipeline from "../../Logic/FeatureSource/FeaturePipeline"
import { ElementStorage } from "../../Logic/ElementStorage"
import ConfirmLocationOfPoint from "../NewPoint/ConfirmLocationOfPoint" import ConfirmLocationOfPoint from "../NewPoint/ConfirmLocationOfPoint"
import Loading from "../Base/Loading" import Loading from "../Base/Loading"
import Hash from "../../Logic/Web/Hash" import Hash from "../../Logic/Web/Hash"
import { WayId } from "../../Models/OsmFeature" import { WayId } from "../../Models/OsmFeature"
import { Tag } from "../../Logic/Tags/Tag" import { Tag } from "../../Logic/Tags/Tag"
import { LoginToggle } from "../Popup/LoginButton" import { LoginToggle } from "../Popup/LoginButton"
import { GlobalFilter } from "../../Models/GlobalFilter" import { SpecialVisualizationState } from "../SpecialVisualization"
import { Feature } from "geojson"
/* /*
* The SimpleAddUI is a single panel, which can have multiple states: * The SimpleAddUI is a single panel, which can have multiple states:
@ -47,34 +43,8 @@ export interface PresetInfo extends PresetConfig {
export default class SimpleAddUI extends LoginToggle { export default class SimpleAddUI extends LoginToggle {
/** /**
* *
* @param isShown
* @param resetScrollSignal
* @param filterViewIsOpened
* @param state
* @param takeLocationFrom: defaults to state.lastClickLocation. Take this location to add the new point around
*/ */
constructor( constructor(state: SpecialVisualizationState) {
isShown: UIEventSource<boolean>,
resetScrollSignal: UIEventSource<void>,
filterViewIsOpened: UIEventSource<boolean>,
state: {
featureSwitchIsTesting: UIEventSource<boolean>
featureSwitchUserbadge: Store<boolean>
layoutToUse: LayoutConfig
osmConnection: OsmConnection
changes: Changes
allElements: ElementStorage
LastClickLocation: UIEventSource<{ lat: number; lon: number }>
featurePipeline: FeaturePipeline
selectedElement: UIEventSource<any>
locationControl: UIEventSource<Loc>
filteredLayers: UIEventSource<FilteredLayer[]>
featureSwitchFilter: UIEventSource<boolean>
backgroundLayer: UIEventSource<BaseLayer>
globalFilters: UIEventSource<GlobalFilter[]>
},
takeLocationFrom?: UIEventSource<{ lat: number; lon: number }>
) {
const readYourMessages = new Combine([ const readYourMessages = new Combine([
Translations.t.general.readYourMessages.Clone().SetClass("alert"), Translations.t.general.readYourMessages.Clone().SetClass("alert"),
new SubtleButton(Svg.envelope_ui(), Translations.t.general.goToInbox, { new SubtleButton(Svg.envelope_ui(), Translations.t.general.goToInbox, {
@ -83,13 +53,10 @@ export default class SimpleAddUI extends LoginToggle {
}), }),
]) ])
takeLocationFrom = takeLocationFrom ?? state.LastClickLocation const filterViewIsOpened = state.guistate.filterViewIsOpened
const takeLocationFrom = state.mapProperties.lastClickLocation
const selectedPreset = new UIEventSource<PresetInfo>(undefined) const selectedPreset = new UIEventSource<PresetInfo>(undefined)
selectedPreset.addCallback((_) => {
resetScrollSignal.ping()
})
isShown.addCallback((_) => selectedPreset.setData(undefined)) // Clear preset selection when the UI is closed/opened
takeLocationFrom.addCallback((_) => selectedPreset.setData(undefined)) takeLocationFrom.addCallback((_) => selectedPreset.setData(undefined))
const presetsOverview = SimpleAddUI.CreateAllPresetsPanel(selectedPreset, state) const presetsOverview = SimpleAddUI.CreateAllPresetsPanel(selectedPreset, state)
@ -104,14 +71,13 @@ export default class SimpleAddUI extends LoginToggle {
tags.push(new Tag("_referencing_ways", "way/" + snapOntoWay.id)) tags.push(new Tag("_referencing_ways", "way/" + snapOntoWay.id))
} }
const newElementAction = new CreateNewNodeAction(tags, location.lat, location.lon, { const newElementAction = new CreateNewNodeAction(tags, location.lat, location.lon, {
theme: state.layoutToUse?.id ?? "unkown", theme: state.layout?.id ?? "unkown",
changeType: "create", changeType: "create",
snapOnto: snapOntoWay, snapOnto: snapOntoWay,
}) })
await state.changes.applyAction(newElementAction) await state.changes.applyAction(newElementAction)
selectedPreset.setData(undefined) selectedPreset.setData(undefined)
isShown.setData(false) const selectedFeature: Feature = state.indexedFeatures.featuresById.data.get(
const selectedFeature = state.allElements.ContainingFeatures.get(
newElementAction.newElementId newElementAction.newElementId
) )
state.selectedElement.setData(selectedFeature) state.selectedElement.setData(selectedFeature)
@ -156,7 +122,7 @@ export default class SimpleAddUI extends LoginToggle {
confirm, confirm,
cancel, cancel,
() => { () => {
isShown.setData(false) selectedPreset.setData(undefined)
}, },
{ {
cancelIcon: Svg.back_svg(), cancelIcon: Svg.back_svg(),
@ -172,11 +138,11 @@ export default class SimpleAddUI extends LoginToggle {
new Toggle( new Toggle(
new Loading(Translations.t.general.add.stillLoading).SetClass("alert"), new Loading(Translations.t.general.add.stillLoading).SetClass("alert"),
addUi, addUi,
state.featurePipeline.runningQuery state.dataIsLoading
), ),
Translations.t.general.add.zoomInFurther.Clone().SetClass("alert"), Translations.t.general.add.zoomInFurther.Clone().SetClass("alert"),
state.locationControl.map( state.mapProperties.zoom.map(
(loc) => loc.zoom >= Constants.userJourney.minZoomLevelToAddNewPoints (zoom) => zoom >= Constants.minZoomLevelToAddNewPoint
) )
), ),
readYourMessages, readYourMessages,
@ -222,12 +188,7 @@ export default class SimpleAddUI extends LoginToggle {
private static CreateAllPresetsPanel( private static CreateAllPresetsPanel(
selectedPreset: UIEventSource<PresetInfo>, selectedPreset: UIEventSource<PresetInfo>,
state: { state: SpecialVisualizationState
featureSwitchIsTesting: UIEventSource<boolean>
filteredLayers: UIEventSource<FilteredLayer[]>
featureSwitchFilter: UIEventSource<boolean>
osmConnection: OsmConnection
}
): BaseUIElement { ): BaseUIElement {
const presetButtons = SimpleAddUI.CreatePresetButtons(state, selectedPreset) const presetButtons = SimpleAddUI.CreatePresetButtons(state, selectedPreset)
let intro: BaseUIElement = Translations.t.general.add.intro let intro: BaseUIElement = Translations.t.general.add.intro
@ -260,18 +221,14 @@ export default class SimpleAddUI extends LoginToggle {
/* /*
* Generates the list with all the buttons.*/ * Generates the list with all the buttons.*/
private static CreatePresetButtons( private static CreatePresetButtons(
state: { state: SpecialVisualizationState,
filteredLayers: UIEventSource<FilteredLayer[]>
featureSwitchFilter: UIEventSource<boolean>
osmConnection: OsmConnection
},
selectedPreset: UIEventSource<PresetInfo> selectedPreset: UIEventSource<PresetInfo>
): BaseUIElement { ): BaseUIElement {
const allButtons = [] const allButtons = []
for (const layer of state.filteredLayers.data) { for (const layer of Array.from(state.layerState.filteredLayers.values())) {
if (layer.isDisplayed.data === false) { if (layer.isDisplayed.data === false) {
// The layer is not displayed... // The layer is not displayed...
if (!state.featureSwitchFilter.data) { if (!state.featureSwitches.featureSwitchFilter.data) {
// ...and we cannot enable the layer control -> we skip, as these presets can never be shown anyway // ...and we cannot enable the layer control -> we skip, as these presets can never be shown anyway
continue continue
} }

View file

@ -48,7 +48,6 @@ export default class DefaultGUI {
public setup() { public setup() {
this.SetupUIElements() this.SetupUIElements()
this.SetupMap() this.SetupMap()
ScrollableFullScreen.ActivateCurrent()
if ( if (
this.state.layoutToUse.customCss !== undefined && this.state.layoutToUse.customCss !== undefined &&
@ -168,13 +167,6 @@ export default class DefaultGUI {
features: state.selectedElementsLayer, features: state.selectedElementsLayer,
state, state,
}) })
state.leafletMap.addCallbackAndRunD((_) => {
// Lets assume that all showDataLayers are initialized at this point
state.selectedElement.ping()
State.state.locationControl.ping()
return true
})
} }
private SetupUIElements() { private SetupUIElements() {

View file

@ -20,11 +20,12 @@ import StaticFeatureSource from "../../Logic/FeatureSource/Sources/StaticFeature
class PointRenderingLayer { class PointRenderingLayer {
private readonly _config: PointRenderingConfig private readonly _config: PointRenderingConfig
private readonly _visibility?: Store<boolean>
private readonly _fetchStore?: (id: string) => Store<Record<string, string>> private readonly _fetchStore?: (id: string) => Store<Record<string, string>>
private readonly _map: MlMap private readonly _map: MlMap
private readonly _onClick: (feature: Feature) => void private readonly _onClick: (feature: Feature) => void
private readonly _allMarkers: Map<string, Marker> = new Map<string, Marker>() private readonly _allMarkers: Map<string, Marker> = new Map<string, Marker>()
private _dirty = false
constructor( constructor(
map: MlMap, map: MlMap,
features: FeatureSource, features: FeatureSource,
@ -33,6 +34,7 @@ class PointRenderingLayer {
fetchStore?: (id: string) => Store<Record<string, string>>, fetchStore?: (id: string) => Store<Record<string, string>>,
onClick?: (feature: Feature) => void onClick?: (feature: Feature) => void
) { ) {
this._visibility = visibility
this._config = config this._config = config
this._map = map this._map = map
this._fetchStore = fetchStore this._fetchStore = fetchStore
@ -40,10 +42,20 @@ class PointRenderingLayer {
const self = this const self = this
features.features.addCallbackAndRunD((features) => self.updateFeatures(features)) features.features.addCallbackAndRunD((features) => self.updateFeatures(features))
visibility?.addCallbackAndRunD((visible) => self.setVisibility(visible)) visibility?.addCallbackAndRunD((visible) => {
if (visible === true && self._dirty) {
self.updateFeatures(features.features.data)
}
self.setVisibility(visible)
})
} }
private updateFeatures(features: Feature[]) { private updateFeatures(features: Feature[]) {
if (this._visibility?.data === false) {
this._dirty = true
return
}
this._dirty = false
const cache = this._allMarkers const cache = this._allMarkers
const unseenKeys = new Set(cache.keys()) const unseenKeys = new Set(cache.keys())
for (const location of this._config.location) { for (const location of this._config.location) {
@ -58,6 +70,9 @@ class PointRenderingLayer {
this._config this._config
) )
} }
const id = feature.properties.id + "-" + location
unseenKeys.delete(id)
const loc = GeoOperations.featureToCoordinateWithRenderingType( const loc = GeoOperations.featureToCoordinateWithRenderingType(
<any>feature, <any>feature,
location location
@ -65,8 +80,6 @@ class PointRenderingLayer {
if (loc === undefined) { if (loc === undefined) {
continue continue
} }
const id = feature.properties.id + "-" + location
unseenKeys.delete(id)
if (cache.has(id)) { if (cache.has(id)) {
const cached = cache.get(id) const cached = cache.get(id)
@ -357,10 +370,12 @@ export default class ShowDataLayer {
private initDrawFeatures(map: MlMap) { private initDrawFeatures(map: MlMap) {
let { features, doShowLayer, fetchStore, selectedElement, selectedLayer } = this._options let { features, doShowLayer, fetchStore, selectedElement, selectedLayer } = this._options
const onClick = (feature: Feature) => { const onClick =
selectedElement?.setData(feature) this._options.onClick ??
selectedLayer?.setData(this._options.layer) ((feature: Feature) => {
} selectedElement?.setData(feature)
selectedLayer?.setData(this._options.layer)
})
for (let i = 0; i < this._options.layer.lineRendering.length; i++) { for (let i = 0; i < this._options.layer.lineRendering.length; i++) {
const lineRenderingConfig = this._options.layer.lineRendering[i] const lineRenderingConfig = this._options.layer.lineRendering[i]
new LineRenderingLayer( new LineRenderingLayer(

View file

@ -33,4 +33,6 @@ export interface ShowDataLayerOptions {
* If given, the map will update when a property is changed * If given, the map will update when a property is changed
*/ */
fetchStore?: (id: string) => Store<Record<string, string>> fetchStore?: (id: string) => Store<Record<string, string>>
onClick?: (feature: Feature) => void
} }

View file

@ -18,6 +18,8 @@ import Toggle from "../Input/Toggle"
import Title from "../Base/Title" import Title from "../Base/Title"
import { MapillaryLinkVis } from "./MapillaryLinkVis" import { MapillaryLinkVis } from "./MapillaryLinkVis"
import { SpecialVisualization, SpecialVisualizationState } from "../SpecialVisualization" import { SpecialVisualization, SpecialVisualizationState } from "../SpecialVisualization"
import LayerConfig from "../../Models/ThemeConfig/LayerConfig"
import { Feature } from "geojson"
export class NearbyImageVis implements SpecialVisualization { export class NearbyImageVis implements SpecialVisualization {
args: { name: string; defaultValue?: string; doc: string; required?: boolean }[] = [ args: { name: string; defaultValue?: string; doc: string; required?: boolean }[] = [
@ -39,11 +41,12 @@ export class NearbyImageVis implements SpecialVisualization {
constr( constr(
state: SpecialVisualizationState, state: SpecialVisualizationState,
tagSource: UIEventSource<Record<string, string>>, tagSource: UIEventSource<Record<string, string>>,
args: string[] args: string[],
feature: Feature,
layer: LayerConfig
): BaseUIElement { ): BaseUIElement {
const t = Translations.t.image.nearbyPictures const t = Translations.t.image.nearbyPictures
const mode: "open" | "expandable" | "collapsable" = <any>args[0] const mode: "open" | "expandable" | "collapsable" = <any>args[0]
const feature = state.indexedFeatures.featuresById.data.get(tagSource.data.id)
const [lon, lat] = GeoOperations.centerpointCoordinates(feature) const [lon, lat] = GeoOperations.centerpointCoordinates(feature)
const id: string = tagSource.data["id"] const id: string = tagSource.data["id"]
const canBeEdited: boolean = !!id?.match("(node|way|relation)/-?[0-9]+") const canBeEdited: boolean = !!id?.match("(node|way|relation)/-?[0-9]+")
@ -128,7 +131,7 @@ export class NearbyImageVis implements SpecialVisualization {
slideshow, slideshow,
controls, controls,
saveButton, saveButton,
new MapillaryLinkVis().constr(state, tagSource, []).SetClass("mt-6"), new MapillaryLinkVis().constr(state, tagSource, [], feature).SetClass("mt-6"),
]) ])
}) })

View file

@ -4,6 +4,7 @@
import { onDestroy } from "svelte"; import { onDestroy } from "svelte";
import { Translation } from "../../i18n/Translation"; import { Translation } from "../../i18n/Translation";
import Locale from "../../i18n/Locale"; import Locale from "../../i18n/Locale";
import FromHtml from "../../Base/FromHtml.svelte";
export let template: Translation; export let template: Translation;
let _template: string let _template: string
@ -20,7 +21,7 @@
</script> </script>
<span> <span>
{Utils.SubstituteKeys(before, _tags)} <FromHtml src={Utils.SubstituteKeys(before, _tags)}/>
<slot /> <slot />
{Utils.SubstituteKeys(after, _tags)} <FromHtml src={Utils.SubstituteKeys(after, _tags)}/>
</span> </span>

View file

@ -41,10 +41,7 @@
return true; return true;
} }
console.log("Got layer", layer, onlyForLabels, notForLabels);
const baseQuestions = (layer.tagRenderings ?? [])?.filter(tr => allowed(tr.labels) && tr.question !== undefined); const baseQuestions = (layer.tagRenderings ?? [])?.filter(tr => allowed(tr.labels) && tr.question !== undefined);
console.log("BaseQuestions are", baseQuestions);
let skippedQuestions = new UIEventSource<Set<string>>(new Set<string>()); let skippedQuestions = new UIEventSource<Set<string>>(new Set<string>());
let questionsToAsk = tags.map(tags => { let questionsToAsk = tags.map(tags => {

View file

@ -15,6 +15,7 @@
import { createEventDispatcher } from "svelte"; import { createEventDispatcher } from "svelte";
import LayerConfig from "../../../Models/ThemeConfig/LayerConfig"; import LayerConfig from "../../../Models/ThemeConfig/LayerConfig";
import { ExclamationIcon } from "@rgossiaux/svelte-heroicons/solid"; import { ExclamationIcon } from "@rgossiaux/svelte-heroicons/solid";
import SpecialTranslation from "./SpecialTranslation.svelte";
export let config: TagRenderingConfig; export let config: TagRenderingConfig;
export let tags: UIEventSource<Record<string, string>>; export let tags: UIEventSource<Record<string, string>>;
@ -86,15 +87,15 @@
<div class="border border-black subtle-background flex flex-col"> <div class="border border-black subtle-background flex flex-col">
<If condition={state.featureSwitchIsTesting}> <If condition={state.featureSwitchIsTesting}>
<div class="flex justify-between"> <div class="flex justify-between">
<Tr t={config.question}></Tr> <SpecialTranslation t={config.question} {tags} {state} {layer} feature={selectedElement}></SpecialTranslation>
<span class="alert">{config.id}</span> <span class="alert">{config.id}</span>
</div> </div>
<Tr slot="else" t={config.question}></Tr> <SpecialTranslation slot="else" t={config.question} {tags} {state} {layer} feature={selectedElement}></SpecialTranslation>
</If> </If>
{#if config.questionhint} {#if config.questionhint}
<div class="subtle"> <div class="subtle">
<Tr t={config.questionHint}></Tr> <SpecialTranslation t={config.questionhint} {tags} {state} {layer} feature={selectedElement}></SpecialTranslation>
</div> </div>
{/if} {/if}

View file

@ -12,6 +12,7 @@ import FullNodeDatabaseSource from "../Logic/FeatureSource/TiledFeatureSource/Fu
import { MangroveIdentity } from "../Logic/Web/MangroveReviews" import { MangroveIdentity } from "../Logic/Web/MangroveReviews"
import { GeoIndexedStoreForLayer } from "../Logic/FeatureSource/Actors/GeoIndexedStore" import { GeoIndexedStoreForLayer } from "../Logic/FeatureSource/Actors/GeoIndexedStore"
import LayerConfig from "../Models/ThemeConfig/LayerConfig" import LayerConfig from "../Models/ThemeConfig/LayerConfig"
import FeatureSwitchState from "../Logic/State/FeatureSwitchState"
/** /**
* The state needed to render a special Visualisation. * The state needed to render a special Visualisation.
@ -19,6 +20,7 @@ import LayerConfig from "../Models/ThemeConfig/LayerConfig"
export interface SpecialVisualizationState { export interface SpecialVisualizationState {
readonly guistate: DefaultGuiState readonly guistate: DefaultGuiState
readonly layout: LayoutConfig readonly layout: LayoutConfig
readonly featureSwitches: FeatureSwitchState
readonly layerState: LayerState readonly layerState: LayerState
readonly featureProperties: { getStore(id: string): UIEventSource<Record<string, string>> } readonly featureProperties: { getStore(id: string): UIEventSource<Record<string, string>> }

View file

@ -56,6 +56,7 @@ import Maproulette from "../Logic/Maproulette"
import SvelteUIElement from "./Base/SvelteUIElement" import SvelteUIElement from "./Base/SvelteUIElement"
import { BBoxFeatureSourceForLayer } from "../Logic/FeatureSource/Sources/TouchesBboxFeatureSource" import { BBoxFeatureSourceForLayer } from "../Logic/FeatureSource/Sources/TouchesBboxFeatureSource"
import QuestionViz from "./Popup/QuestionViz" import QuestionViz from "./Popup/QuestionViz"
import SimpleAddUI from "./BigComponents/SimpleAddUI"
export default class SpecialVisualizations { export default class SpecialVisualizations {
public static specialVisualizations: SpecialVisualization[] = SpecialVisualizations.initList() public static specialVisualizations: SpecialVisualization[] = SpecialVisualizations.initList()
@ -232,6 +233,15 @@ export default class SpecialVisualizations {
private static initList(): SpecialVisualization[] { private static initList(): SpecialVisualization[] {
const specialVisualizations: SpecialVisualization[] = [ const specialVisualizations: SpecialVisualization[] = [
new QuestionViz(), new QuestionViz(),
{
funcName: "add_new_point",
docs: "An element which allows to add a new point on the 'last_click'-location. Only makes sense in the layer `last_click`",
args: [],
constr(state: SpecialVisualizationState): BaseUIElement {
return new SimpleAddUI(state)
},
},
new HistogramViz(), new HistogramViz(),
new StealViz(), new StealViz(),
new MinimapViz(), new MinimapViz(),
@ -670,7 +680,9 @@ export default class SpecialVisualizations {
if (title === undefined) { if (title === undefined) {
return undefined return undefined
} }
return new SubstitutedTranslation(title, tagsSource, state) return new SubstitutedTranslation(title, tagsSource, state).RemoveClass(
"w-full"
)
}) })
), ),
}, },

View file

@ -11,6 +11,7 @@ import LinkToWeblate from "./Base/LinkToWeblate"
import { SpecialVisualization, SpecialVisualizationState } from "./SpecialVisualization" import { SpecialVisualization, SpecialVisualizationState } from "./SpecialVisualization"
import SpecialVisualizations from "./SpecialVisualizations" import SpecialVisualizations from "./SpecialVisualizations"
import { Feature } from "geojson" import { Feature } from "geojson"
import LayerConfig from "../Models/ThemeConfig/LayerConfig"
export class SubstitutedTranslation extends VariableUiElement { export class SubstitutedTranslation extends VariableUiElement {
public constructor( public constructor(
@ -24,7 +25,8 @@ export class SubstitutedTranslation extends VariableUiElement {
state: SpecialVisualizationState, state: SpecialVisualizationState,
tagSource: UIEventSource<Record<string, string>>, tagSource: UIEventSource<Record<string, string>>,
argument: string[], argument: string[],
feature: Feature feature: Feature,
layer: LayerConfig
) => BaseUIElement) ) => BaseUIElement)
> = undefined > = undefined
) { ) {
@ -85,7 +87,7 @@ export class SubstitutedTranslation extends VariableUiElement {
tagsSource.data.id tagsSource.data.id
) )
return viz.func return viz.func
.constr(state, tagsSource, proto.args, feature) .constr(state, tagsSource, proto.args, feature, undefined)
?.SetStyle(proto.style) ?.SetStyle(proto.style)
} catch (e) { } catch (e) {
console.error("SPECIALRENDERING FAILED for", tagsSource.data?.id, e) console.error("SPECIALRENDERING FAILED for", tagsSource.data?.id, e)

View file

@ -1,5 +1,5 @@
<script lang="ts"> <script lang="ts">
import { Store, UIEventSource } from "../Logic/UIEventSource"; import { ImmutableStore, Store, UIEventSource } from "../Logic/UIEventSource";
import { Map as MlMap } from "maplibre-gl"; import { Map as MlMap } from "maplibre-gl";
import MaplibreMap from "./Map/MaplibreMap.svelte"; import MaplibreMap from "./Map/MaplibreMap.svelte";
import LayoutConfig from "../Models/ThemeConfig/LayoutConfig"; import LayoutConfig from "../Models/ThemeConfig/LayoutConfig";
@ -22,6 +22,7 @@
import { MenuIcon } from "@rgossiaux/svelte-heroicons/solid"; import { MenuIcon } from "@rgossiaux/svelte-heroicons/solid";
import Tr from "./Base/Tr.svelte"; import Tr from "./Base/Tr.svelte";
import CommunityIndexView from "./BigComponents/CommunityIndexView.svelte"; import CommunityIndexView from "./BigComponents/CommunityIndexView.svelte";
import FloatOver from "./Base/FloatOver.svelte";
export let layout: LayoutConfig; export let layout: LayoutConfig;
const state = new ThemeViewState(layout); const state = new ThemeViewState(layout);
@ -57,6 +58,11 @@
<MapControlButton on:click={() =>state.guistate.menuIsOpened.setData(true)}> <MapControlButton on:click={() =>state.guistate.menuIsOpened.setData(true)}>
<MenuIcon class="w-8 h-8"></MenuIcon> <MenuIcon class="w-8 h-8"></MenuIcon>
</MapControlButton> </MapControlButton>
<If condition={state.featureSwitchIsTesting}>
<span class="alert">
Testmode
</span>
</If>
</div> </div>
<div class="absolute bottom-0 left-0 mb-4 ml-4"> <div class="absolute bottom-0 left-0 mb-4 ml-4">
@ -87,8 +93,7 @@
<If condition={state.guistate.welcomeMessageIsOpened}> <If condition={state.guistate.welcomeMessageIsOpened}>
<!-- Theme page --> <!-- Theme page -->
<div class="absolute top-0 left-0 w-screen h-screen" style="background-color: #00000088"> <FloatOver>
<div class="flex flex-col m-4 sm:m-6 md:m-8 p-4 sm:p-6 md:m-8 normal-background rounded">
<div on:click={() => state.guistate.welcomeMessageIsOpened.setData(false)}>Close</div> <div on:click={() => state.guistate.welcomeMessageIsOpened.setData(false)}>Close</div>
<TabGroup> <TabGroup>
<TabList> <TabList>
@ -136,15 +141,13 @@
<TabPanel>Content 3</TabPanel> <TabPanel>Content 3</TabPanel>
</TabPanels> </TabPanels>
</TabGroup> </TabGroup>
</div> </FloatOver>
</div>
</If> </If>
<If condition={state.guistate.menuIsOpened}> <If condition={state.guistate.menuIsOpened}>
<!-- Menu page --> <!-- Menu page -->
<div class="absolute top-0 left-0 w-screen h-screen overflow-auto" style="background-color: #00000088"> <FloatOver>
<div class="flex flex-col m-4 sm:m-6 md:m-8 p-4 sm:p-6 md:m-8 normal-background rounded">
<div on:click={() => state.guistate.menuIsOpened.setData(false)}>Close</div> <div on:click={() => state.guistate.menuIsOpened.setData(false)}>Close</div>
<TabGroup> <TabGroup>
<TabList> <TabList>
@ -174,20 +177,15 @@
<TabPanel>Privacy</TabPanel> <TabPanel>Privacy</TabPanel>
</TabPanels> </TabPanels>
</TabGroup> </TabGroup>
</div> </FloatOver>
</div>
</If> </If>
{#if $selectedElement !== undefined && $selectedLayer !== undefined} {#if $selectedElement !== undefined && $selectedLayer !== undefined}
<div class="absolute top-0 right-0 w-screen h-screen overflow-auto" style="background-color: #00000088"> <FloatOver>
<SelectedElementView layer={$selectedLayer} selectedElement={$selectedElement}
tags={$selectedElementTags} state={state}></SelectedElementView>
</FloatOver>
<div class="flex flex-col m-4 sm:m-6 md:m-8 p-4 sm:p-6 md:m-8 normal-background rounded normal-background">
<SelectedElementView layer={$selectedLayer} selectedElement={$selectedElement}
tags={$selectedElementTags} state={state}></SelectedElementView>
</div>
</div>
{/if} {/if}
<style> <style>
/* WARNING: This is just for demonstration. /* WARNING: This is just for demonstration.

View file

@ -0,0 +1,116 @@
{
"id": "last_click",
"description": "This layer defines how to render the 'last click'-location. By default, it will show a marker with the possibility to add a new point (if there are some presets) and/or to add a new note (if the 'note' layer attribute is set). If none are possible, this layer won't show up",
"source": "special",
"name": null,
"titleIcons": [],
"title": {
"mappings": [
{
"if": {
"and": [
"has_note_layer=yes",
"has_presets=yes"
]
},
"then": {
"en": "Add a new point or add a note",
"nl": "Voeg een nieuw punt of een nieuwe kaartnota toe"
}
},
{
"if": "has_note_layer=yes",
"then": {
"en": "Add a new note",
"nl": "Voeg een nieuwe kaartnota toe"
}
},
{
"if": "has_presets=yes",
"then": {
"en": "Add a new point",
"nl": "Voeg een nieuw punt toe"
}
}
]
},
"tagRenderings": [
{
"id": "add_new",
"mappings": [
{
"if": "has_presets=yes",
"then": {
"*": "{add_new_point()}"
}
}
]
},
"all_tags"
],
"mapRendering": [
{
"icon": {
"mappings": [
{
"if": "number_of_presets=1",
"then": "{first_preset}"
}
],
"render": "<div class='relative'> <img src='./assets/svg/add_pin.svg' class='absolute' style='height: 50px'> <div class='absolute top-0 left-0 rounded-full overflow-hidden' style='width: 40px; height: 40px'><div class='flex slide min-w-min' style='animation: slide linear {number_of_presets}s infinite; width: calc( (1 + {number_of_presets}) * 40px ); height: 40px'>{renderings}{first_preset}</div></div></div>"
},
"labelCssClasses": "text-sm min-w-min pl-1 pr-1 bg-gray-400 rounded-3xl text-white opacity-65 whitespace-nowrap",
"label": {
"render": {
"ca": "Afegir nou element",
"cs": "Klikněte zde pro přidání nové položky",
"da": "Klik her for at tilføje et nyt punkt",
"de": "Hier klicken, um ein neues Element hinzuzufügen",
"en": "Click here to add a new item",
"es": "Haga clic aquí para añadir un nuevo ítem",
"fil": "I-click ito para mag-dagdag ng bagong bagay",
"fr": "Cliquez ici pour ajouter un élément",
"hu": "Új elem hozzáadásához kattints ide",
"id": "Klik di sini untuk menambahkan item baru",
"it": "Aggiungi nuovo elemento",
"nb_NO": "Legg til nytt element",
"nl": "Klik hier om een item toe te voegen",
"pt": "Adicionar novo item",
"zh_Hant": "點這邊新增新項目"
}
},
"iconBadges": [
{
"if": {
"or": [
"has_note_layer=yes",
"has_presets=yes"
]
},
"then": "<img class='animate-pulse' src='./assets/svg/addSmall.svg'>"
}
],
"location": [
"point"
],
"iconSize": "40,50,bottom"
}
],
"filter": [
{
"id": "action",
"options": [
{
"default": true,
"question": "only_if_action_is_possible",
"osmTags": {
"or": [
"has_note_layer=yes",
"has_presets=yes"
]
}
}
]
}
]
}

View file

@ -22,4 +22,4 @@
"cssClasses": "block relative rounded-full" "cssClasses": "block relative rounded-full"
} }
] ]
} }

View file

@ -2,27 +2,39 @@
"id": "shared_questions", "id": "shared_questions",
"questions": { "questions": {
"description": "Show the images block at this location", "description": "Show the images block at this location",
"render": "{questions()}" "render": {
"*": "{questions()}"
}
}, },
"images": { "images": {
"description": "This block shows the known images which are linked with the `image`-keys, but also via `mapillary` and `wikidata`", "description": "This block shows the known images which are linked with the `image`-keys, but also via `mapillary` and `wikidata`",
"render": "{image_carousel()}{image_upload()}{nearby_images(expandable)}" "render": {
"*": "{image_carousel()}{image_upload()}{nearby_images(expandable)}"
}
}, },
"mapillary": { "mapillary": {
"description": "Shows a button to open Mapillary on this location", "description": "Shows a button to open Mapillary on this location",
"render": "{mapillary()}" "render": {
"*": "{mapillary()}"
}
}, },
"export_as_gpx": { "export_as_gpx": {
"description": "Shows a button to export this feature as GPX. Especially useful for route relations", "description": "Shows a button to export this feature as GPX. Especially useful for route relations",
"render": "{export_as_gpx()}" "render": {
"*": "{export_as_gpx()}"
}
}, },
"export_as_geojson": { "export_as_geojson": {
"description": "Shows a button to export this feature as geojson. Especially useful for debugging or using this in other programs", "description": "Shows a button to export this feature as geojson. Especially useful for debugging or using this in other programs",
"render": "{export_as_geojson()}" "render": {
"*": "{export_as_geojson()}"
}
}, },
"wikipedia": { "wikipedia": {
"description": "Shows a wikipedia box with the corresponding wikipedia article; the wikidata-item link can be changed by a contributor", "description": "Shows a wikipedia box with the corresponding wikipedia article; the wikidata-item link can be changed by a contributor",
"render": "{wikipedia():max-height:25rem}", "render": {
"*": "{wikipedia():max-height:25rem}"
},
"question": { "question": {
"en": "What is the corresponding Wikidata entity?", "en": "What is the corresponding Wikidata entity?",
"nl": "Welk Wikidata-item komt overeen met dit object?", "nl": "Welk Wikidata-item komt overeen met dit object?",
@ -106,11 +118,15 @@
}, },
"reviews": { "reviews": {
"description": "Shows the reviews module (including the possibility to leave a review)", "description": "Shows the reviews module (including the possibility to leave a review)",
"render": "{reviews()}" "render": {
"*": "{reviews()}"
}
}, },
"minimap": { "minimap": {
"description": "Shows a small map with the feature. Added by default to every popup", "description": "Shows a small map with the feature. Added by default to every popup",
"render": "{minimap(18, id): width:100%; height:8rem; border-radius:2rem; overflow: hidden; pointer-events: none;}" "render": {
"*": "{minimap(18, id): width:100%; height:8rem; border-radius:2rem; overflow: hidden; pointer-events: none;}"
}
}, },
"phone": { "phone": {
"question": { "question": {
@ -138,7 +154,9 @@
"da": "Hvad er telefonnummeret til {title()}?", "da": "Hvad er telefonnummeret til {title()}?",
"cs": "Jaké je telefonní číslo {title()}?" "cs": "Jaké je telefonní číslo {title()}?"
}, },
"render": "<a href='tel:{phone}'>{phone}</a>", "render": {
"*": "<a href='tel:{phone}'>{phone}</a>"
},
"mappings": [ "mappings": [
{ {
"if": "contact:phone~*", "if": "contact:phone~*",
@ -155,7 +173,9 @@
} }
}, },
"osmlink": { "osmlink": {
"render": "<a href='https://openstreetmap.org/{id}' target='_blank'><img src='./assets/svg/osm-logo-us.svg'/></a>", "render": {
"*": "<a href='https://openstreetmap.org/{id}' target='_blank'><img src='./assets/svg/osm-logo-us.svg'/></a>"
},
"mappings": [ "mappings": [
{ {
"if": "id~=-", "if": "id~=-",
@ -164,7 +184,9 @@
] ]
}, },
"wikipedialink": { "wikipedialink": {
"render": "<a href='https://wikipedia.org/wiki/{wikipedia}' target='_blank'><img src='./assets/wikipedia.svg' alt='WP'/></a>", "render": {
"*": "<a href='https://wikipedia.org/wiki/{wikipedia}' target='_blank'><img src='./assets/wikipedia.svg' alt='WP'/></a>"
},
"question": { "question": {
"en": "What is the corresponding item on Wikipedia?", "en": "What is the corresponding item on Wikipedia?",
"nl": "Welk Wikipedia-artikel beschrijft dit object?", "nl": "Welk Wikipedia-artikel beschrijft dit object?",
@ -217,7 +239,9 @@
} }
}, },
"email": { "email": {
"render": "<a href='mailto:{email}' target='_blank'>{email}</a>", "render": {
"*": "<a href='mailto:{email}' target='_blank'>{email}</a>"
},
"question": { "question": {
"nl": "Wat is het e-mailadres van {title()}?", "nl": "Wat is het e-mailadres van {title()}?",
"fr": "Quelle est l'adresse courriel de {title()} ?", "fr": "Quelle est l'adresse courriel de {title()} ?",
@ -284,7 +308,9 @@
"da": "Hvad er webstedet for {title()}?", "da": "Hvad er webstedet for {title()}?",
"cs": "Jaká je webová stránka {title()}?" "cs": "Jaká je webová stránka {title()}?"
}, },
"render": "<a href='{website}' rel='nofollow noopener noreferrer' target='_blank'>{website}</a>", "render": {
"*": "<a href='{website}' rel='nofollow noopener noreferrer' target='_blank'>{website}</a>"
},
"freeform": { "freeform": {
"key": "website", "key": "website",
"type": "url", "type": "url",
@ -598,7 +624,9 @@
"da": "Er der stadig noget relevant, du ikke kunne give i de foregående spørgsmål? Tilføj det her.", "da": "Er der stadig noget relevant, du ikke kunne give i de foregående spørgsmål? Tilføj det her.",
"cs": "Je ještě něco relevantního, co jste nemohli uvést v předchozích otázkách? Přidejte to sem." "cs": "Je ještě něco relevantního, co jste nemohli uvést v předchozích otázkách? Přidejte to sem."
}, },
"render": "{description}", "render": {
"*": "{description}"
},
"freeform": { "freeform": {
"key": "description" "key": "description"
}, },
@ -1385,11 +1413,15 @@
"last_edit": { "last_edit": {
"#": "Gives some metainfo about the last edit and who did edit it - rendering only", "#": "Gives some metainfo about the last edit and who did edit it - rendering only",
"condition": "_last_edit:contributor~*", "condition": "_last_edit:contributor~*",
"render": "<div class='subtle' style='font-size: small; margin-top: 2em; margin-bottom: 0.5em;'><a href='https://www.openStreetMap.org/changeset/{_last_edit:changeset}' target='_blank'>Last edited on {_last_edit:timestamp}</a> by <a href='https://www.openStreetMap.org/user/{_last_edit:contributor}' target='_blank'>{_last_edit:contributor}</a></div>" "render": {
"*": "<div class='subtle' style='font-size: small; margin-top: 2em; margin-bottom: 0.5em;'><a href='https://www.openStreetMap.org/changeset/{_last_edit:changeset}' target='_blank'>Last edited on {_last_edit:timestamp}</a> by <a href='https://www.openStreetMap.org/user/{_last_edit:contributor}' target='_blank'>{_last_edit:contributor}</a></div>"
}
}, },
"all_tags": { "all_tags": {
"description": "Shows a table with all the tags of the feature", "description": "Shows a table with all the tags of the feature",
"render": "{all_tags()}" "render": {
"*": "{all_tags()}"
}
}, },
"multilevels": { "multilevels": {
"builtin": "level", "builtin": "level",
@ -1984,4 +2016,4 @@
"pl": "Nazwa sieci to <b>{internet_access:ssid}</b>" "pl": "Nazwa sieci to <b>{internet_access:ssid}</b>"
} }
} }
} }

View file

@ -71,7 +71,6 @@
"aboutMapcomplete": "<h3>Sobre</h3><p>Utilitza MapCompelte per afegir informació a OpenStreetMap amb una <b>petició.</b> Respon preguntes i en minuts les teves contribucions estaran disponibles arreu. En molts temes pots afegir fotografies o fins i tot afegeix \"reviews\". La persona <b>gestionadora</b> defineix elements, preguntes i idiomes per a fer-ho possible.</p><h3>Troba més info</h3><p>MapComplete sempre <b>ofereix el següent pas</b> per aprendre'n més sobre OpenStreetMap.</p><ul><li>Inclòs en una pàgina web et porta a MapComplete a pantalla completa.</li><li>Aquesta versió ofereix informació sobre OpenStreetMap.</li><li>Veure funciona sense entrar però editar o contribuir requereix un compte d'OSM.</li><li>Si no has entrat et demanarà que ho facis.</li><li>Responent una simple pregunta, pots afegir nous elements al mapa</li><li> Després d'una estona es mostraran les etiquetes actuals , i després els enllaços a la wiki.</li></ul><p></p><br><p>Has trobat alguna <b>incidència</b>? Tens alguna <b> petició </b>? Vols <b>ajudar a traduir</b>? Vés a <a href=\"https://github.com/pietervdvn/MapComplete\" target=\"_blank\"> per accedir al codi font</a> o al <a href=\"https://github.com/pietervdvn/MapComplete/issues\" target=\"_blank\">registre d'incidències.</a> </p><p> Vols veure <b>els teus progressos </b>? Segueix el recompte d'edicions a <a href=\"{osmcha_link}\" target=\"_blank\">OsmCha</a>.</p>", "aboutMapcomplete": "<h3>Sobre</h3><p>Utilitza MapCompelte per afegir informació a OpenStreetMap amb una <b>petició.</b> Respon preguntes i en minuts les teves contribucions estaran disponibles arreu. En molts temes pots afegir fotografies o fins i tot afegeix \"reviews\". La persona <b>gestionadora</b> defineix elements, preguntes i idiomes per a fer-ho possible.</p><h3>Troba més info</h3><p>MapComplete sempre <b>ofereix el següent pas</b> per aprendre'n més sobre OpenStreetMap.</p><ul><li>Inclòs en una pàgina web et porta a MapComplete a pantalla completa.</li><li>Aquesta versió ofereix informació sobre OpenStreetMap.</li><li>Veure funciona sense entrar però editar o contribuir requereix un compte d'OSM.</li><li>Si no has entrat et demanarà que ho facis.</li><li>Responent una simple pregunta, pots afegir nous elements al mapa</li><li> Després d'una estona es mostraran les etiquetes actuals , i després els enllaços a la wiki.</li></ul><p></p><br><p>Has trobat alguna <b>incidència</b>? Tens alguna <b> petició </b>? Vols <b>ajudar a traduir</b>? Vés a <a href=\"https://github.com/pietervdvn/MapComplete\" target=\"_blank\"> per accedir al codi font</a> o al <a href=\"https://github.com/pietervdvn/MapComplete/issues\" target=\"_blank\">registre d'incidències.</a> </p><p> Vols veure <b>els teus progressos </b>? Segueix el recompte d'edicions a <a href=\"{osmcha_link}\" target=\"_blank\">OsmCha</a>.</p>",
"add": { "add": {
"addNew": "Afegir {category} aquí", "addNew": "Afegir {category} aquí",
"addNewMapLabel": "Afegir nou element",
"backToSelect": "Selecciona una categoria diferent", "backToSelect": "Selecciona una categoria diferent",
"confirmButton": "Afegir una {category}<br/><div class='alert'>La teva atribució és visible per a tots</div>", "confirmButton": "Afegir una {category}<br/><div class='alert'>La teva atribució és visible per a tots</div>",
"confirmIntro": "<h3>Afegir {title} aquí?</h3>L'element que estàs creant <b>el veurà tothom</b>. Només afegeix coses que realment existeixen. Moltes aplicacions fan servir aquestes dades.", "confirmIntro": "<h3>Afegir {title} aquí?</h3>L'element que estàs creant <b>el veurà tothom</b>. Només afegeix coses que realment existeixen. Moltes aplicacions fan servir aquestes dades.",

View file

@ -52,7 +52,6 @@
"aboutMapcomplete": "<h3>O službě</h3><p>Pomocí MapComplete můžete přidávat informace z OpenStreetMap na <b>samostatné téma</b>. Odpovězte na otázky a během několika minut jsou vaše příspěvky dostupné všude. Ve většině témat můžete přidávat obrázky nebo dokonce zanechat hodnocení. <b>Správce tématu</b> pro něj definuje prvky, otázky a jazyky.</p><h3>Další informace</h3><p>MapComplete vždy <b>nabízí další krok</b> k získání dalších informací o OpenStreetMap.<ul><li>Při vložení do webové stránky odkazuje iframe na MapComplete na celou obrazovku.</li><li>Verze na celou obrazovku nabízí informace o OpenStreetMap.</li><li>Prohlížení funguje bez přihlášení, ale editace vyžaduje účet OSM.</li><li>Pokud nejste přihlášeni, jste k tomu vyzváni</li><li>Po zodpovězení jedné otázky můžete do mapy přidávat nové funkce</li><li>Po chvíli se zobrazí aktuální značky OSM, později odkaz na wiki</li></ul></p><br/><p>Všimli jste si <b>problému</b>? Máte <b>požadavek na funkci</b>? Chcete <b>pomoci s překladem</b>? Přejděte na <a href='https://github.com/pietervdvn/MapComplete' target='_blank'>zdrojový kód</a> nebo <a href='https://github.com/pietervdvn/MapComplete/issues' target='_blank'>sledovač problémů.</a> </p><p> Chcete se podívat na <b>svůj pokrok</b>? Sledujte počet úprav na <a href='{osmcha_link}' target='_blank' >OsmCha</a>.</p>", "aboutMapcomplete": "<h3>O službě</h3><p>Pomocí MapComplete můžete přidávat informace z OpenStreetMap na <b>samostatné téma</b>. Odpovězte na otázky a během několika minut jsou vaše příspěvky dostupné všude. Ve většině témat můžete přidávat obrázky nebo dokonce zanechat hodnocení. <b>Správce tématu</b> pro něj definuje prvky, otázky a jazyky.</p><h3>Další informace</h3><p>MapComplete vždy <b>nabízí další krok</b> k získání dalších informací o OpenStreetMap.<ul><li>Při vložení do webové stránky odkazuje iframe na MapComplete na celou obrazovku.</li><li>Verze na celou obrazovku nabízí informace o OpenStreetMap.</li><li>Prohlížení funguje bez přihlášení, ale editace vyžaduje účet OSM.</li><li>Pokud nejste přihlášeni, jste k tomu vyzváni</li><li>Po zodpovězení jedné otázky můžete do mapy přidávat nové funkce</li><li>Po chvíli se zobrazí aktuální značky OSM, později odkaz na wiki</li></ul></p><br/><p>Všimli jste si <b>problému</b>? Máte <b>požadavek na funkci</b>? Chcete <b>pomoci s překladem</b>? Přejděte na <a href='https://github.com/pietervdvn/MapComplete' target='_blank'>zdrojový kód</a> nebo <a href='https://github.com/pietervdvn/MapComplete/issues' target='_blank'>sledovač problémů.</a> </p><p> Chcete se podívat na <b>svůj pokrok</b>? Sledujte počet úprav na <a href='{osmcha_link}' target='_blank' >OsmCha</a>.</p>",
"add": { "add": {
"addNew": "Přidat {category}", "addNew": "Přidat {category}",
"addNewMapLabel": "Klikněte zde pro přidání nové položky",
"confirmButton": "Přidat kategorii {category}<br/><div class='alert'>Váš příspěvek je viditelný pro všechny</div>", "confirmButton": "Přidat kategorii {category}<br/><div class='alert'>Váš příspěvek je viditelný pro všechny</div>",
"disableFilters": "Vypnout všechny filtry", "disableFilters": "Vypnout všechny filtry",
"import": { "import": {

View file

@ -44,7 +44,6 @@
"aboutMapcomplete": "<h3>Om MapComplete</h3><p>Brug det til at tilføje OpenStreetMap information om et <b>bestemt tema.</b> Besvar spørgsmål, og i løbet af få minutter er dine bidrag tilgængelige overalt. <b>temabestyreren</b> definerer elementer, spørgsmål og sprog for temaet.</p><h3>Find ud af mere</h3><p>MapComplete <b>tilbyder altid det næste trin</b> for at lære mere om OpenStreetMap.</p><ul><li>Når det er indlejret på et websted, linker iframe-en til et fuldskærms MapComplete</li><li>Fuldskærmsversionen tilbyder information om OpenStreetMap</li><li>Man kan se det uden at logge ind, men redigering kræver en OSM-konto.</li><li>Hvis du ikke har logget ind, vil du blive bedt om at gøre det</li><li>Når du har besvaret et enkelt spørgsmål, kan du tilføje nye punkter til kortet</li><li>Efter et stykke tid bliver faktiske OSM-tags vist, senere igen links til wiki-en</li></ul><p></p><br><p>Bemærkede du <b>et problem</b>? Har du en<b>anmodning om en ny funktion</b>? Vil du <b>hjælpe med at oversætte</b>? Gå til <a href=\"https://github.com/pietervdvn/MapComplete\" target=\"_blank\">kildekoden</a> eller <a href=\"https://github.com/pietervdvn/MapComplete/issues\" target=\"_blank\">issue trackeren.</a> </p><p> Vil du se <b>dit fremskridt</b>? Følg antallet af rettelser på <a href=\"{osmcha_link}\" target=\"_blank\">OsmCha</a>.</p>", "aboutMapcomplete": "<h3>Om MapComplete</h3><p>Brug det til at tilføje OpenStreetMap information om et <b>bestemt tema.</b> Besvar spørgsmål, og i løbet af få minutter er dine bidrag tilgængelige overalt. <b>temabestyreren</b> definerer elementer, spørgsmål og sprog for temaet.</p><h3>Find ud af mere</h3><p>MapComplete <b>tilbyder altid det næste trin</b> for at lære mere om OpenStreetMap.</p><ul><li>Når det er indlejret på et websted, linker iframe-en til et fuldskærms MapComplete</li><li>Fuldskærmsversionen tilbyder information om OpenStreetMap</li><li>Man kan se det uden at logge ind, men redigering kræver en OSM-konto.</li><li>Hvis du ikke har logget ind, vil du blive bedt om at gøre det</li><li>Når du har besvaret et enkelt spørgsmål, kan du tilføje nye punkter til kortet</li><li>Efter et stykke tid bliver faktiske OSM-tags vist, senere igen links til wiki-en</li></ul><p></p><br><p>Bemærkede du <b>et problem</b>? Har du en<b>anmodning om en ny funktion</b>? Vil du <b>hjælpe med at oversætte</b>? Gå til <a href=\"https://github.com/pietervdvn/MapComplete\" target=\"_blank\">kildekoden</a> eller <a href=\"https://github.com/pietervdvn/MapComplete/issues\" target=\"_blank\">issue trackeren.</a> </p><p> Vil du se <b>dit fremskridt</b>? Følg antallet af rettelser på <a href=\"{osmcha_link}\" target=\"_blank\">OsmCha</a>.</p>",
"add": { "add": {
"addNew": "Tilføj {category}", "addNew": "Tilføj {category}",
"addNewMapLabel": "Klik her for at tilføje et nyt punkt",
"confirmButton": "Tilføj en {category}<br><div class=\"alert\">Din tilføjelse er synlig for alle</div>", "confirmButton": "Tilføj en {category}<br><div class=\"alert\">Din tilføjelse er synlig for alle</div>",
"confirmIntro": "<h3>Tilføj en {title}?</h3>Punktet du opretter her vil være <b>synligt for alle</b>. Tilføj kun ting til kortet, hvis de virkelig findes. Mange programmer bruger disse data.", "confirmIntro": "<h3>Tilføj en {title}?</h3>Punktet du opretter her vil være <b>synligt for alle</b>. Tilføj kun ting til kortet, hvis de virkelig findes. Mange programmer bruger disse data.",
"disableFilters": "Slå alle filtre fra", "disableFilters": "Slå alle filtre fra",

View file

@ -85,7 +85,6 @@
"aboutMapcomplete": "<h3>Über</h3><p>Verwenden Sie MapComplete, um <b>themenbezogene Informationen</b> zu OpenStreetMap hinzuzufügen. Beantworten Sie Fragen, und in wenigen Minuten sind Ihre Beiträge überall verfügbar. Zu den meisten Themen können Sie Bilder hinzufügen oder eine Bewertung hinterlassen. Der <b>Theme-Maintainer</b> definiert dafür Elemente, Fragen und Sprachen.</p><h3>Mehr erfahren</h3><p>MapComplete bietet immer <b>den nächsten Schritt</b>, um mehr über OpenStreetMap zu erfahren.</p><ul><li>In einer Website eingebettet, verlinkt der iframe zu einer Vollbildversion von MapComplete</li><li>Die Vollbildversion bietet Informationen über OpenStreetMap</li><li>Das Betrachten funktioniert ohne Anmeldung, das Bearbeiten erfordert ein OSM-Konto.</li><li>Wenn Sie nicht angemeldet sind, werden Sie dazu aufgefordert</li><li>Sobald Sie eine Frage beantwortet haben, können Sie der Karte neue Objekte hinzufügen</li><li>Nach einer Weile werden aktuelle OSM-Tags angezeigt, die später mit dem Wiki verlinkt werden</li></ul><p></p><br/><p>Haben Sie ein <b>Problem</b> bemerkt? Haben Sie einen <b>Funktionswunsch</b>? Möchten Sie bei der <b>Übersetzung</b> helfen? Hier geht es zum <a href='https://github.com/pietervdvn/MapComplete' target='_blank'>Quellcode</a> und <a href='https://github.com/pietervdvn/MapComplete/issues' target='_blank'>Issue Tracker</a> </p><p>Möchten Sie Ihre <b>Bearbeitungen</b> sehen? Verfolgen Sie Ihre Änderungen auf <a href='{osmcha_link}' target='_blank' >OsmCha</a>.</p>", "aboutMapcomplete": "<h3>Über</h3><p>Verwenden Sie MapComplete, um <b>themenbezogene Informationen</b> zu OpenStreetMap hinzuzufügen. Beantworten Sie Fragen, und in wenigen Minuten sind Ihre Beiträge überall verfügbar. Zu den meisten Themen können Sie Bilder hinzufügen oder eine Bewertung hinterlassen. Der <b>Theme-Maintainer</b> definiert dafür Elemente, Fragen und Sprachen.</p><h3>Mehr erfahren</h3><p>MapComplete bietet immer <b>den nächsten Schritt</b>, um mehr über OpenStreetMap zu erfahren.</p><ul><li>In einer Website eingebettet, verlinkt der iframe zu einer Vollbildversion von MapComplete</li><li>Die Vollbildversion bietet Informationen über OpenStreetMap</li><li>Das Betrachten funktioniert ohne Anmeldung, das Bearbeiten erfordert ein OSM-Konto.</li><li>Wenn Sie nicht angemeldet sind, werden Sie dazu aufgefordert</li><li>Sobald Sie eine Frage beantwortet haben, können Sie der Karte neue Objekte hinzufügen</li><li>Nach einer Weile werden aktuelle OSM-Tags angezeigt, die später mit dem Wiki verlinkt werden</li></ul><p></p><br/><p>Haben Sie ein <b>Problem</b> bemerkt? Haben Sie einen <b>Funktionswunsch</b>? Möchten Sie bei der <b>Übersetzung</b> helfen? Hier geht es zum <a href='https://github.com/pietervdvn/MapComplete' target='_blank'>Quellcode</a> und <a href='https://github.com/pietervdvn/MapComplete/issues' target='_blank'>Issue Tracker</a> </p><p>Möchten Sie Ihre <b>Bearbeitungen</b> sehen? Verfolgen Sie Ihre Änderungen auf <a href='{osmcha_link}' target='_blank' >OsmCha</a>.</p>",
"add": { "add": {
"addNew": "{category} hinzufügen", "addNew": "{category} hinzufügen",
"addNewMapLabel": "Hier klicken, um ein neues Element hinzuzufügen",
"backToSelect": "Wählen Sie eine andere Kategorie", "backToSelect": "Wählen Sie eine andere Kategorie",
"confirmButton": "Eine {category} hinzufügen.<br><div class=\"alert\">Ihre Ergänzung ist für alle sichtbar</div>", "confirmButton": "Eine {category} hinzufügen.<br><div class=\"alert\">Ihre Ergänzung ist für alle sichtbar</div>",
"confirmIntro": "<h3>Einen {title} hinzufügen?</h3>Das Objekt, das Sie erstellen wird <b>für alle sichtbar sein</b>. Bitte nur Dinge hinzufügen, die wirklich existieren. Viele Anwendungen verwenden diese Daten.", "confirmIntro": "<h3>Einen {title} hinzufügen?</h3>Das Objekt, das Sie erstellen wird <b>für alle sichtbar sein</b>. Bitte nur Dinge hinzufügen, die wirklich existieren. Viele Anwendungen verwenden diese Daten.",

View file

@ -91,7 +91,6 @@
"aboutMapcomplete": "<p>Use MapComplete to add OpenStreetMap info on a <b>single theme.</b> Answer questions, and within minutes your contributions are available everywhere. In most themes you can add pictures or even leave a review. The <b>theme maintainer</b> defines elements, questions and languages for it.</p><h3>Find out more</h3><p>MapComplete always <b>offers the next step</b> to learn more about OpenStreetMap.<ul><li>When embedded in a website, the iframe links to a full-screen MapComplete.</li><li>The fullscreen version offers info about OpenStreetMap.</li><li>Viewing works without login, but editing requires an OSM account.</li><li>If you are not logged in, you are asked to do so</li><li>Once you answered a single question, you can add new features to the map</li><li>After a while, actual OSM-tags are shown, later linking to the wiki</li></ul></p><br/><p>Did you notice <b>an issue</b>? Do you have a <b>feature request</b>? Want to <b>help translate</b>? Head over to <a href='https://github.com/pietervdvn/MapComplete' target='_blank'>the source code</a> or <a href='https://github.com/pietervdvn/MapComplete/issues' target='_blank'>issue tracker.</a> </p><p> Want to see <b>your progress</b>? Follow the edit count on <a href='{osmcha_link}' target='_blank' >OsmCha</a>.</p>", "aboutMapcomplete": "<p>Use MapComplete to add OpenStreetMap info on a <b>single theme.</b> Answer questions, and within minutes your contributions are available everywhere. In most themes you can add pictures or even leave a review. The <b>theme maintainer</b> defines elements, questions and languages for it.</p><h3>Find out more</h3><p>MapComplete always <b>offers the next step</b> to learn more about OpenStreetMap.<ul><li>When embedded in a website, the iframe links to a full-screen MapComplete.</li><li>The fullscreen version offers info about OpenStreetMap.</li><li>Viewing works without login, but editing requires an OSM account.</li><li>If you are not logged in, you are asked to do so</li><li>Once you answered a single question, you can add new features to the map</li><li>After a while, actual OSM-tags are shown, later linking to the wiki</li></ul></p><br/><p>Did you notice <b>an issue</b>? Do you have a <b>feature request</b>? Want to <b>help translate</b>? Head over to <a href='https://github.com/pietervdvn/MapComplete' target='_blank'>the source code</a> or <a href='https://github.com/pietervdvn/MapComplete/issues' target='_blank'>issue tracker.</a> </p><p> Want to see <b>your progress</b>? Follow the edit count on <a href='{osmcha_link}' target='_blank' >OsmCha</a>.</p>",
"add": { "add": {
"addNew": "Add {category}", "addNew": "Add {category}",
"addNewMapLabel": "Click here to add a new item",
"backToSelect": "Select a different category", "backToSelect": "Select a different category",
"confirmButton": "Add a {category}<br/><div class='alert'>Your addition is visible for everyone</div>", "confirmButton": "Add a {category}<br/><div class='alert'>Your addition is visible for everyone</div>",
"confirmIntro": "<h3>Add a {title}?</h3>The feature you create here will be <b>visible for everyone</b>. Please, only add things on to the map if they truly exist. A lot of applications use this data.", "confirmIntro": "<h3>Add a {title}?</h3>The feature you create here will be <b>visible for everyone</b>. Please, only add things on to the map if they truly exist. A lot of applications use this data.",

View file

@ -44,7 +44,6 @@
"aboutMapcomplete": "<h3>Aceca de MapComplete</h3><p>Lo utilizamos para añadir información de OpenStreetMap en un <b>único tema. Responde preguntas, y en minutos tus contribuciones estarán disponibles en todos lados. El <b>mantenedor del tema</b> define elementos, preguntas e idiomas para él.</b></p><h3><b>Descubre más</b></h3><p><b>MapComplete siempre <b>ofrece el siguiente paso</b> para aprender más sobre OpenStreetMap.</b></p><ul><li><b>Cuando se embebe en un sitio web, el iframe enlaza a un MapComplete a pantalla completa</b></li><li><b>La versión a pantalla completa ofrece información sobre OpenStreetMpa</b></li><li><b>Se puede ver el trabajo sin iniciar sesión, pero la edición requiere una cuenta de OSM.</b></li><li><b>Si no has iniciado sesión, se te pedirá que lo hagas</b></li><li><b>Una vez que hayas respondido a una simple pregunta, podrás añadir nuevos puntos al mapa</b></li><li><b>Después de un poco, las etiquetas de OSM se mostrarán, después de enlazar a la wiki</b></li></ul><p></p><b><br><p>¿Te fijaste en <b>un problema</b>? Tienes una <b>petición de característica</b>?¿Quieres ayudar a traducir? Ve <a href=\"https://github.com/pietervdvn/MapComplete\" target=\"_blank\"> al código fuente</a> o <a href=\"https://github/pietervdvn/MapComplete/issues\" target=\"_blank\">issue tracker.</a> </p><p>¿Quieres ver <b>tu progreso</b>? Sigue a la cuenta de ediciones en <a href=\"{osmcha_link}\" target=\"_blank\">OsmCha</a>.</p></b>", "aboutMapcomplete": "<h3>Aceca de MapComplete</h3><p>Lo utilizamos para añadir información de OpenStreetMap en un <b>único tema. Responde preguntas, y en minutos tus contribuciones estarán disponibles en todos lados. El <b>mantenedor del tema</b> define elementos, preguntas e idiomas para él.</b></p><h3><b>Descubre más</b></h3><p><b>MapComplete siempre <b>ofrece el siguiente paso</b> para aprender más sobre OpenStreetMap.</b></p><ul><li><b>Cuando se embebe en un sitio web, el iframe enlaza a un MapComplete a pantalla completa</b></li><li><b>La versión a pantalla completa ofrece información sobre OpenStreetMpa</b></li><li><b>Se puede ver el trabajo sin iniciar sesión, pero la edición requiere una cuenta de OSM.</b></li><li><b>Si no has iniciado sesión, se te pedirá que lo hagas</b></li><li><b>Una vez que hayas respondido a una simple pregunta, podrás añadir nuevos puntos al mapa</b></li><li><b>Después de un poco, las etiquetas de OSM se mostrarán, después de enlazar a la wiki</b></li></ul><p></p><b><br><p>¿Te fijaste en <b>un problema</b>? Tienes una <b>petición de característica</b>?¿Quieres ayudar a traducir? Ve <a href=\"https://github.com/pietervdvn/MapComplete\" target=\"_blank\"> al código fuente</a> o <a href=\"https://github/pietervdvn/MapComplete/issues\" target=\"_blank\">issue tracker.</a> </p><p>¿Quieres ver <b>tu progreso</b>? Sigue a la cuenta de ediciones en <a href=\"{osmcha_link}\" target=\"_blank\">OsmCha</a>.</p></b>",
"add": { "add": {
"addNew": "Añadir {category}", "addNew": "Añadir {category}",
"addNewMapLabel": "Haga clic aquí para añadir un nuevo ítem",
"confirmButton": "Añadir una {category} .<br><div class=\"alert\">Tu contribución es visible para todos</div>", "confirmButton": "Añadir una {category} .<br><div class=\"alert\">Tu contribución es visible para todos</div>",
"confirmIntro": "<h3>Añadir {title} aquí?</h3>El punto que estás creando <b>lo verá todo el mundo</b>. Sólo añade cosas que realmente existan. Muchas aplicaciones usan estos datos.", "confirmIntro": "<h3>Añadir {title} aquí?</h3>El punto que estás creando <b>lo verá todo el mundo</b>. Sólo añade cosas que realmente existan. Muchas aplicaciones usan estos datos.",
"disableFilters": "Desactivar todos los filtros", "disableFilters": "Desactivar todos los filtros",

View file

@ -41,7 +41,6 @@
"about": "Madaling i-edit at mag-dagdag sa OpenStreetMap gamit ang mga partikular na tikha", "about": "Madaling i-edit at mag-dagdag sa OpenStreetMap gamit ang mga partikular na tikha",
"add": { "add": {
"addNew": "Dagdagan ng {category}", "addNew": "Dagdagan ng {category}",
"addNewMapLabel": "I-click ito para mag-dagdag ng bagong bagay",
"confirmButton": "Magdagdag ng {category}<br><div class=\"alert\">Makikita ng lahat ang idinagdag mo</div>", "confirmButton": "Magdagdag ng {category}<br><div class=\"alert\">Makikita ng lahat ang idinagdag mo</div>",
"confirmIntro": "<h3>Mag-dagdag ng {title}?</h3>Ang tampók na ida-dagdag mo ay <b>makikita ng lahat</b>. Paki-usap, mag-dagdag lamang ng mga bagay na tutuong umiiral. Marami pang mga aplikasyon ang gumagamit ng datos na ito.", "confirmIntro": "<h3>Mag-dagdag ng {title}?</h3>Ang tampók na ida-dagdag mo ay <b>makikita ng lahat</b>. Paki-usap, mag-dagdag lamang ng mga bagay na tutuong umiiral. Marami pang mga aplikasyon ang gumagamit ng datos na ito.",
"disableFilters": "Huwag paganahin ang lahat ng filter", "disableFilters": "Huwag paganahin ang lahat ng filter",

View file

@ -57,7 +57,6 @@
"aboutMapcomplete": "<h3>À propos de MapComplete</h3><p>Avec MapComplete vous pouvez enrichir OpenStreetMap d'informations sur un <b>thème unique.</b> Répondez à quelques questions, et en quelques minutes vos contributions seront disponibles dans le monde entier ! Le <b>concepteur du thème</b> définis les éléments, questions et langues pour le thème.</p><h3>En savoir plus</h3><p>MapComplete <b>propose toujours l'étape suivante</b> pour en apprendre plus sur OpenStreetMap.</p><ul><li>Lorsqu'il est intégré dans un site Web, l'<i>iframe</i> pointe vers MapComplete en plein écran</li><li>La version plein écran donne des informations sur OpenStreetMap</li><li>Il est possible de regarder sans se connecter, mais l'édition demande une connexion à OSM.</li><li>Si vous n'êtes pas connecté, il vous est demandé de le faire</li><li>Une fois que vous avez répondu à une seule question, vous pouvez ajouter de nouveaux points à la carte</li><li>Au bout d'un moment, les vrais tags OSM sont montrés, qui pointent ensuite vers le wiki</li></ul><p></p><br><p>Vous avez remarqué <b>un problème</b> ? Vous souhaitez <b>demander une fonctionnalité</b> ? Vous voulez <b>aider à traduire</b> ? Allez voir <a href=\"https://github.com/pietervdvn/MapComplete\" target=\"_blank\">le code source</a> ou le <a href=\"https://github.com/pietervdvn/MapComplete/issues\" target=\"_blank\"><i>gestionnaire de tickets</i></a>.</p><p> Vous voulez visualiser <b>votre progression</b> ? Suivez le compteur d'édition sur <a href=\"{osmcha_link}\" target=\"_blank\">OsmCha</a>.</p>", "aboutMapcomplete": "<h3>À propos de MapComplete</h3><p>Avec MapComplete vous pouvez enrichir OpenStreetMap d'informations sur un <b>thème unique.</b> Répondez à quelques questions, et en quelques minutes vos contributions seront disponibles dans le monde entier ! Le <b>concepteur du thème</b> définis les éléments, questions et langues pour le thème.</p><h3>En savoir plus</h3><p>MapComplete <b>propose toujours l'étape suivante</b> pour en apprendre plus sur OpenStreetMap.</p><ul><li>Lorsqu'il est intégré dans un site Web, l'<i>iframe</i> pointe vers MapComplete en plein écran</li><li>La version plein écran donne des informations sur OpenStreetMap</li><li>Il est possible de regarder sans se connecter, mais l'édition demande une connexion à OSM.</li><li>Si vous n'êtes pas connecté, il vous est demandé de le faire</li><li>Une fois que vous avez répondu à une seule question, vous pouvez ajouter de nouveaux points à la carte</li><li>Au bout d'un moment, les vrais tags OSM sont montrés, qui pointent ensuite vers le wiki</li></ul><p></p><br><p>Vous avez remarqué <b>un problème</b> ? Vous souhaitez <b>demander une fonctionnalité</b> ? Vous voulez <b>aider à traduire</b> ? Allez voir <a href=\"https://github.com/pietervdvn/MapComplete\" target=\"_blank\">le code source</a> ou le <a href=\"https://github.com/pietervdvn/MapComplete/issues\" target=\"_blank\"><i>gestionnaire de tickets</i></a>.</p><p> Vous voulez visualiser <b>votre progression</b> ? Suivez le compteur d'édition sur <a href=\"{osmcha_link}\" target=\"_blank\">OsmCha</a>.</p>",
"add": { "add": {
"addNew": "Ajouter {category}", "addNew": "Ajouter {category}",
"addNewMapLabel": "Cliquez ici pour ajouter un élément",
"backToSelect": "Sélectionner une catégorie différente", "backToSelect": "Sélectionner une catégorie différente",
"confirmButton": "Ajouter un/une {category} ici.<br><div class=\"alert\">Votre ajout sera visible par tout le monde</div>", "confirmButton": "Ajouter un/une {category} ici.<br><div class=\"alert\">Votre ajout sera visible par tout le monde</div>",
"confirmIntro": "<h3>Ajouter un/une {title} ici?</h3>Lélément que vous ajouterez sera <b>visible par tout le monde</b>. Merci de vous assurer que celui-ci existe réellement. Beaucoup d'autres applications utilisent ces données.", "confirmIntro": "<h3>Ajouter un/une {title} ici?</h3>Lélément que vous ajouterez sera <b>visible par tout le monde</b>. Merci de vous assurer que celui-ci existe réellement. Beaucoup d'autres applications utilisent ces données.",

View file

@ -42,7 +42,6 @@
"aboutMapcomplete": "<h3>Névjegy</h3><p>A MapComplete-et használhatod, hogy egy <b>egy adott téma szerint</b> OpenStreetMap-adatokat adj hozzá az adatbázishoz. Válaszolj a kérdésekre, és a szerkesztéseid perceken belül mindenhol elérhetővé válnak. A legtöbb témánál hozzáadhatsz képeket vagy akár véleményt is írhatsz. A témához tartozó elemeket, kérdéseket és nyelveket a <b>téma karbantartója</b> határozza meg .</p><h3>További információk</h3><p>A MapComplete mindig <b>felkínálja a következő lépést</b> ahhoz, hogy tanulhass az OpenStreetMapről.</p><ul><li>Weboldalba ágyazva az iframe egy teljes képernyős MapComplete-hez vezet</li><li>A teljes képernyős változat az OpenStreetMapről mutat adatokat</li><li>A megtekintés bejelentkezés nélkül is működik, de a szerkesztéshez OSM-fiók szükséges</li><li>Ha nem vagy bejelentkezve, kérjük, tedd meg</li><li>Miután válaszoltál egy kérdésre, új elemeket helyezhetsz a térképre</li><li>Egy idő után megjelennek a tényleges OSM-címkék, amelyek később a wikire hivatkoznak</li></ul><p></p><br><p>Észrevettél <b>egy problémát</b>? Új <b>funkciót szeretnél kérni</b>? Szeretnél <b>segíteni a fordításban</b>? Látogass el a <a href=\"https://github.com/pietervdvn/MapComplete\" target=\"_blank\">forráskódhoz</a> vagy a <a href=\"https://github.com/pietervdvn/MapComplete/issues\" target=\"_blank\">problémakövetőhöz (issue tracker)</a>. </p><p> Szeretnéd látni <b>a fejlődést</b>? Kövesd a szerkesztések számát az <a href=\"{osmcha_link}\" target=\"_blank\">OsmCha</a> módosításkészlet-elemzőn.</p>", "aboutMapcomplete": "<h3>Névjegy</h3><p>A MapComplete-et használhatod, hogy egy <b>egy adott téma szerint</b> OpenStreetMap-adatokat adj hozzá az adatbázishoz. Válaszolj a kérdésekre, és a szerkesztéseid perceken belül mindenhol elérhetővé válnak. A legtöbb témánál hozzáadhatsz képeket vagy akár véleményt is írhatsz. A témához tartozó elemeket, kérdéseket és nyelveket a <b>téma karbantartója</b> határozza meg .</p><h3>További információk</h3><p>A MapComplete mindig <b>felkínálja a következő lépést</b> ahhoz, hogy tanulhass az OpenStreetMapről.</p><ul><li>Weboldalba ágyazva az iframe egy teljes képernyős MapComplete-hez vezet</li><li>A teljes képernyős változat az OpenStreetMapről mutat adatokat</li><li>A megtekintés bejelentkezés nélkül is működik, de a szerkesztéshez OSM-fiók szükséges</li><li>Ha nem vagy bejelentkezve, kérjük, tedd meg</li><li>Miután válaszoltál egy kérdésre, új elemeket helyezhetsz a térképre</li><li>Egy idő után megjelennek a tényleges OSM-címkék, amelyek később a wikire hivatkoznak</li></ul><p></p><br><p>Észrevettél <b>egy problémát</b>? Új <b>funkciót szeretnél kérni</b>? Szeretnél <b>segíteni a fordításban</b>? Látogass el a <a href=\"https://github.com/pietervdvn/MapComplete\" target=\"_blank\">forráskódhoz</a> vagy a <a href=\"https://github.com/pietervdvn/MapComplete/issues\" target=\"_blank\">problémakövetőhöz (issue tracker)</a>. </p><p> Szeretnéd látni <b>a fejlődést</b>? Kövesd a szerkesztések számát az <a href=\"{osmcha_link}\" target=\"_blank\">OsmCha</a> módosításkészlet-elemzőn.</p>",
"add": { "add": {
"addNew": "Új {category} hozzáadása", "addNew": "Új {category} hozzáadása",
"addNewMapLabel": "Új elem hozzáadásához kattints ide",
"confirmButton": "{category} hozzáadása.<br><div class=\"alert\">A hozzáadott objektum mindenki számára látható lesz</div>", "confirmButton": "{category} hozzáadása.<br><div class=\"alert\">A hozzáadott objektum mindenki számára látható lesz</div>",
"confirmIntro": "<h3>Felrajzolsz egy {title} objektumot?</h3>Az itt létrehozandó térképelemet <b>mindenki láthatja majd</b>. Kérjük, csak valóban létező dolgokat rajzolj fel a térképre. Ezeket az adatokat sok alkalmazás használja.", "confirmIntro": "<h3>Felrajzolsz egy {title} objektumot?</h3>Az itt létrehozandó térképelemet <b>mindenki láthatja majd</b>. Kérjük, csak valóban létező dolgokat rajzolj fel a térképre. Ezeket az adatokat sok alkalmazás használja.",
"disableFilters": "Minden szűrő kikapcsolása", "disableFilters": "Minden szűrő kikapcsolása",

View file

@ -37,7 +37,6 @@
"general": { "general": {
"add": { "add": {
"addNew": "Tambahkan {category}", "addNew": "Tambahkan {category}",
"addNewMapLabel": "Klik di sini untuk menambahkan item baru",
"confirmButton": "Tambahkan {category}<br><div class=\"alert\">Penambahan Anda akan terlihat oleh semua orang</div>", "confirmButton": "Tambahkan {category}<br><div class=\"alert\">Penambahan Anda akan terlihat oleh semua orang</div>",
"confirmIntro": "<h3>Tambahkan {title}?</h3>Fitur yang Anda buat di sini akan <b>terlihat oleh semua orang</b>. Harap menambahkan sesuatu ke peta hanya jika ia benar-benar ada. Banyak aplikasi menggunakan data ini.", "confirmIntro": "<h3>Tambahkan {title}?</h3>Fitur yang Anda buat di sini akan <b>terlihat oleh semua orang</b>. Harap menambahkan sesuatu ke peta hanya jika ia benar-benar ada. Banyak aplikasi menggunakan data ini.",
"disableFiltersExplanation": "Beberapa fitur mungkin disembunyikan oleh penyaringan", "disableFiltersExplanation": "Beberapa fitur mungkin disembunyikan oleh penyaringan",

View file

@ -44,7 +44,6 @@
"aboutMapcomplete": "<h3>Informazioni</h3><p>Con MapComplete puoi arricchire OpenStreetMap con informazioni su un <b>singolo argomento</b>. Rispondi a poche domande e in pochi minuti i tuoi contributi saranno disponibili a tutto il mondo! Lutente <b>gestore del tema</b> definisce gli elementi, le domande e le lingue per quel tema.</p><h3>Scopri altro</h3><p>MapComplete <b>propone sempre un passo in più</b> per imparare qualcosa di nuovo su OpenStreetMap.</p><ul><li>Quando viene incorporato in un sito web, il collegamento delliframe punta a MapComplete a tutto schermo</li><li>La versione a tutto schermo fornisce informazioni su OpenStreetMap</li><li>La visualizzazione non necessita di alcun accesso ma per modificare occorre aver effettuato laccesso su OSM.</li><li>Se non hai effettuato laccesso, ti verrà richiesto di farlo</li><li>Dopo aver risposto ad una sola domanda potrai aggiungere dei nuovi punti alla mappa</li><li>Dopo qualche momento verranno mostrate le etichette effettive, in seguito i collegamenti alla wiki</li></ul><p></p><br><p>Hai trovato un <b>errore</b>? Vuoi richiedere <b>nuove funzionalità</b>? Vuoi aiutare con la <b>traduzione</b>? Dai unocchiata al <a href=\"https://github.com/pietervdvn/MapComplete\" target=\"_blank\">codice sorgente</a> oppure al <a href=\"https://github.com/pietervdvn/MapComplete/issues\" target=\"_blank\">tracker degli errori.</a></p><p>Vuoi vedere i <b>tuoi progressi</b>?Segui il contatore delle modifiche su <a href=\"{osmcha_link}\" target=\"_blank\">OsmCha</a>.</p>", "aboutMapcomplete": "<h3>Informazioni</h3><p>Con MapComplete puoi arricchire OpenStreetMap con informazioni su un <b>singolo argomento</b>. Rispondi a poche domande e in pochi minuti i tuoi contributi saranno disponibili a tutto il mondo! Lutente <b>gestore del tema</b> definisce gli elementi, le domande e le lingue per quel tema.</p><h3>Scopri altro</h3><p>MapComplete <b>propone sempre un passo in più</b> per imparare qualcosa di nuovo su OpenStreetMap.</p><ul><li>Quando viene incorporato in un sito web, il collegamento delliframe punta a MapComplete a tutto schermo</li><li>La versione a tutto schermo fornisce informazioni su OpenStreetMap</li><li>La visualizzazione non necessita di alcun accesso ma per modificare occorre aver effettuato laccesso su OSM.</li><li>Se non hai effettuato laccesso, ti verrà richiesto di farlo</li><li>Dopo aver risposto ad una sola domanda potrai aggiungere dei nuovi punti alla mappa</li><li>Dopo qualche momento verranno mostrate le etichette effettive, in seguito i collegamenti alla wiki</li></ul><p></p><br><p>Hai trovato un <b>errore</b>? Vuoi richiedere <b>nuove funzionalità</b>? Vuoi aiutare con la <b>traduzione</b>? Dai unocchiata al <a href=\"https://github.com/pietervdvn/MapComplete\" target=\"_blank\">codice sorgente</a> oppure al <a href=\"https://github.com/pietervdvn/MapComplete/issues\" target=\"_blank\">tracker degli errori.</a></p><p>Vuoi vedere i <b>tuoi progressi</b>?Segui il contatore delle modifiche su <a href=\"{osmcha_link}\" target=\"_blank\">OsmCha</a>.</p>",
"add": { "add": {
"addNew": "Aggiungi {category} qua", "addNew": "Aggiungi {category} qua",
"addNewMapLabel": "Aggiungi nuovo elemento",
"confirmButton": "Aggiungi una {category} qua.<br><div class=\"alert\">La tua aggiunta è visibile a chiunque</div>", "confirmButton": "Aggiungi una {category} qua.<br><div class=\"alert\">La tua aggiunta è visibile a chiunque</div>",
"confirmIntro": "<h3>Aggiungere un {title}?</h3>L'elemento che hai creato qui sarà <b>visibile da chiunque</b>. Per favore, aggiungi sulla mappa solo oggetti realmente esistenti. Molte applicazioni usano questi dati.", "confirmIntro": "<h3>Aggiungere un {title}?</h3>L'elemento che hai creato qui sarà <b>visibile da chiunque</b>. Per favore, aggiungi sulla mappa solo oggetti realmente esistenti. Molte applicazioni usano questi dati.",
"disableFilters": "Disabilita tutti i filtri", "disableFilters": "Disabilita tutti i filtri",

View file

@ -74,7 +74,6 @@
"aboutMapcomplete": "<h3>Om</h3><p>Bruk MapComplete til å legge til OpenStreetMap-info i <b>ett tema. </b>Besvar spørsmål og få endringene vist i løpet av minutter. I de fleste temaene kan du legge inn bilder eller legge igjen en vurdering. <b>Temavedlikeholderen</b> definerer elementer, spørsmål og språk for det.</p><h3>Finn ut mer</h3><p>MapComplete tilbyr alltid <b>neste steg</b> for å lære mer om OpenStreetMap.<ul><li>Når bygd inn på en nettside lenker iframe-elementet til en fullskjermsversjon av MapComplete.</li><li>Fullskjermsversjonen tilbyr info om OpenStreetMap.</li><li>Visning fungerer uten innlogging, men redigering krever en OSM-konto.</li><li>Hvis du ikke er innlogget blir du spurt om å gjøre det.</li><li>Når du har besvart ett spørsmål, kan du legge til nye funksjoner på kartet.</li><li>Etter en stund vil OSM-etiketter bli vist, som i sin tur lenker til wiki-en.</li></ul></p><br/><p>Har du oppdaget <b>et problem</b>? Har du en <b>funksjonsforespørsel</b>? Vil du bistå <b>oversettelsen</b>? Gå til <a href='https://github.com/pietervdvn/MapComplete' target='_blank'>kildekoden</a> eller <a href='https://github.com/pietervdvn/MapComplete/issues' target='_blank'>problemsporeren.</a> </p><p>Vil du se <b>din framdrift</b>? Følg redigeringsantallet på <a href='{osmcha_link}' target='_blank' >OsmCha</a>.</p>", "aboutMapcomplete": "<h3>Om</h3><p>Bruk MapComplete til å legge til OpenStreetMap-info i <b>ett tema. </b>Besvar spørsmål og få endringene vist i løpet av minutter. I de fleste temaene kan du legge inn bilder eller legge igjen en vurdering. <b>Temavedlikeholderen</b> definerer elementer, spørsmål og språk for det.</p><h3>Finn ut mer</h3><p>MapComplete tilbyr alltid <b>neste steg</b> for å lære mer om OpenStreetMap.<ul><li>Når bygd inn på en nettside lenker iframe-elementet til en fullskjermsversjon av MapComplete.</li><li>Fullskjermsversjonen tilbyr info om OpenStreetMap.</li><li>Visning fungerer uten innlogging, men redigering krever en OSM-konto.</li><li>Hvis du ikke er innlogget blir du spurt om å gjøre det.</li><li>Når du har besvart ett spørsmål, kan du legge til nye funksjoner på kartet.</li><li>Etter en stund vil OSM-etiketter bli vist, som i sin tur lenker til wiki-en.</li></ul></p><br/><p>Har du oppdaget <b>et problem</b>? Har du en <b>funksjonsforespørsel</b>? Vil du bistå <b>oversettelsen</b>? Gå til <a href='https://github.com/pietervdvn/MapComplete' target='_blank'>kildekoden</a> eller <a href='https://github.com/pietervdvn/MapComplete/issues' target='_blank'>problemsporeren.</a> </p><p>Vil du se <b>din framdrift</b>? Følg redigeringsantallet på <a href='{osmcha_link}' target='_blank' >OsmCha</a>.</p>",
"add": { "add": {
"addNew": "Legg til {category} her", "addNew": "Legg til {category} her",
"addNewMapLabel": "Legg til nytt element",
"backToSelect": "Velg en annen kategori", "backToSelect": "Velg en annen kategori",
"confirmButton": "Legg til en {category} her.<br/><div class='alert'>Din endring er synlig for alle</div>", "confirmButton": "Legg til en {category} her.<br/><div class='alert'>Din endring er synlig for alle</div>",
"confirmIntro": "<h3>Legg til {title} her?</h3>Punktet du oppretter her vil være <b>synlig for alle</b>. Kun legg til ting på kartet hvis de virkelig finnes. Mange programmer bruker denne dataen.", "confirmIntro": "<h3>Legg til {title} her?</h3>Punktet du oppretter her vil være <b>synlig for alle</b>. Kun legg til ting på kartet hvis de virkelig finnes. Mange programmer bruker denne dataen.",

View file

@ -91,7 +91,6 @@
"aboutMapcomplete": "<h3>Over MapComplete</h3><p>Met MapComplete kun je OpenStreetMap verrijken met informatie over een bepaald thema. Beantwoord enkele vragen, en binnen een paar minuten is jouw bijdrage wereldwijd beschikbaar! In de meeste thema's kan je foto's toevoegen of zelfs een review achterlaten. De <b>maker van het thema</b> bepaalt de elementen, vragen en taalversies voor het thema.</p><h3>Ontdek meer</h3><p>MapComplete <b>biedt altijd de volgende stap</b> naar meer OpenStreetMap:</p><ul><li>Indien ingebed in een website linkt het iframe naar de volledige MapComplete</li><li>De volledige versie heeft uitleg over OpenStreetMap</li><li>Bekijken kan altijd, maar wijzigen vereist een OSM-account</li><li>Als je niet aangemeld bent, wordt je gevraagd dit te doen</li><li>Als je minstens één vraag hebt beantwoord, kan je ook elementen toevoegen</li><li>Heb je genoeg changesets, dan verschijnen de OSM-tags, nog later links naar de wiki</li></ul><p></p><p>Merk je <b>een bug</b> of wil je een <b>extra feature</b>? Wil je <b>helpen vertalen</b>? Bezoek dan de <a href=\"https://github.com/pietervdvn/MapComplete\" target=\"_blank\">broncode</a> en <a href=\"https://github.com/pietervdvn/MapComplete/issues\" target=\"_blank\">issue tracker</a>. </p><p></p>Wil je <b>je vorderingen</b> zien? Volg de edits <a href=\"{osmcha_link}\" target=\"_blank\">op OsmCha</a>.<p></p>", "aboutMapcomplete": "<h3>Over MapComplete</h3><p>Met MapComplete kun je OpenStreetMap verrijken met informatie over een bepaald thema. Beantwoord enkele vragen, en binnen een paar minuten is jouw bijdrage wereldwijd beschikbaar! In de meeste thema's kan je foto's toevoegen of zelfs een review achterlaten. De <b>maker van het thema</b> bepaalt de elementen, vragen en taalversies voor het thema.</p><h3>Ontdek meer</h3><p>MapComplete <b>biedt altijd de volgende stap</b> naar meer OpenStreetMap:</p><ul><li>Indien ingebed in een website linkt het iframe naar de volledige MapComplete</li><li>De volledige versie heeft uitleg over OpenStreetMap</li><li>Bekijken kan altijd, maar wijzigen vereist een OSM-account</li><li>Als je niet aangemeld bent, wordt je gevraagd dit te doen</li><li>Als je minstens één vraag hebt beantwoord, kan je ook elementen toevoegen</li><li>Heb je genoeg changesets, dan verschijnen de OSM-tags, nog later links naar de wiki</li></ul><p></p><p>Merk je <b>een bug</b> of wil je een <b>extra feature</b>? Wil je <b>helpen vertalen</b>? Bezoek dan de <a href=\"https://github.com/pietervdvn/MapComplete\" target=\"_blank\">broncode</a> en <a href=\"https://github.com/pietervdvn/MapComplete/issues\" target=\"_blank\">issue tracker</a>. </p><p></p>Wil je <b>je vorderingen</b> zien? Volg de edits <a href=\"{osmcha_link}\" target=\"_blank\">op OsmCha</a>.<p></p>",
"add": { "add": {
"addNew": "Voeg {category} toe", "addNew": "Voeg {category} toe",
"addNewMapLabel": "Klik hier om een item toe te voegen",
"backToSelect": "Selecteer een andere categorie", "backToSelect": "Selecteer een andere categorie",
"confirmButton": "Voeg een {category} toe<br><div class=\"alert\">Je toevoeging is voor iedereen zichtbaar</div>", "confirmButton": "Voeg een {category} toe<br><div class=\"alert\">Je toevoeging is voor iedereen zichtbaar</div>",
"confirmIntro": "<h3>Voeg een {title} toe?</h3>Het object dat je toevoegt, is <b>zichtbaar voor iedereen</b>. Veel applicaties gebruiken deze data, voeg dus enkel punten toe die echt bestaan.", "confirmIntro": "<h3>Voeg een {title} toe?</h3>Het object dat je toevoegt, is <b>zichtbaar voor iedereen</b>. Veel applicaties gebruiken deze data, voeg dus enkel punten toe die echt bestaan.",

View file

@ -44,7 +44,6 @@
"aboutMapcomplete": "<h3>Sobre</h3><p>Use o MapComplete para adicionar informações ao OpenStreetMap <b>sobre um tema específico</b>. Responda a perguntas e em poucos minutos as suas contribuições estão disponíveis em todos os lugares. Na maioria dos temas pode adicionar imagens ou mesmo deixar uma avaliação. O <b>responsável pelo tema</b> define os elementos, as perguntas e os idiomas disponíveis nele.</p> <h3>Descubra mais</h3><p>O MapComplete <b>mostra sempre o próximo passo</b> para saber mais sobre o OpenStreetMap.</p><ul> <li>Quando incorporado num site, o iframe liga-se ao MapComplete em ecrã cheio.</li><li>A versão ecrã cheio fornece informações sobre o OpenStreetMap</li><li>A visualização funciona sem ser preciso autenticar-se, mas a edição requer uma conta no OpenStreetMap.</li> <li>Se não estiver autenticado, é solicitado a fazê-lo</li><li>Após responder a uma pergunta, pode adicionar novos elementos ao mapa</li><li>Depois de um tempo, as etiquetas reais do OpenStreetMap são mostradas, mais tarde vinculando-se à wiki</li></ul><p></p><br><p>Deparou-se com <b>um problema</b>? Quer uma <b>nova funcionalidade</b>? Quer <b>ajudar a traduzir</b>? Vá ao <a href=\"https://github.com/pietervdvn/MapComplete\" target=\"_blank\">código-fonte</a> ou <a href=\"https://github.com/pietervdvn/MapComplete/issues\" target=\"_blank\">rastreador de problemas</a>. </p> <p>Quer ver <b>o seu progresso</b>? Veja a contagem de edições em <a href=\"{osmcha_link}\" target=\"_blank\">OsmCha</a>.</p>", "aboutMapcomplete": "<h3>Sobre</h3><p>Use o MapComplete para adicionar informações ao OpenStreetMap <b>sobre um tema específico</b>. Responda a perguntas e em poucos minutos as suas contribuições estão disponíveis em todos os lugares. Na maioria dos temas pode adicionar imagens ou mesmo deixar uma avaliação. O <b>responsável pelo tema</b> define os elementos, as perguntas e os idiomas disponíveis nele.</p> <h3>Descubra mais</h3><p>O MapComplete <b>mostra sempre o próximo passo</b> para saber mais sobre o OpenStreetMap.</p><ul> <li>Quando incorporado num site, o iframe liga-se ao MapComplete em ecrã cheio.</li><li>A versão ecrã cheio fornece informações sobre o OpenStreetMap</li><li>A visualização funciona sem ser preciso autenticar-se, mas a edição requer uma conta no OpenStreetMap.</li> <li>Se não estiver autenticado, é solicitado a fazê-lo</li><li>Após responder a uma pergunta, pode adicionar novos elementos ao mapa</li><li>Depois de um tempo, as etiquetas reais do OpenStreetMap são mostradas, mais tarde vinculando-se à wiki</li></ul><p></p><br><p>Deparou-se com <b>um problema</b>? Quer uma <b>nova funcionalidade</b>? Quer <b>ajudar a traduzir</b>? Vá ao <a href=\"https://github.com/pietervdvn/MapComplete\" target=\"_blank\">código-fonte</a> ou <a href=\"https://github.com/pietervdvn/MapComplete/issues\" target=\"_blank\">rastreador de problemas</a>. </p> <p>Quer ver <b>o seu progresso</b>? Veja a contagem de edições em <a href=\"{osmcha_link}\" target=\"_blank\">OsmCha</a>.</p>",
"add": { "add": {
"addNew": "Adicionar {category} aqui", "addNew": "Adicionar {category} aqui",
"addNewMapLabel": "Adicionar novo item",
"confirmButton": "Adicione uma {category} aqui.<br><div class=\"alert\">Esta adição será visível a todos</div>", "confirmButton": "Adicione uma {category} aqui.<br><div class=\"alert\">Esta adição será visível a todos</div>",
"confirmIntro": "<h3>Adicionar {title} aqui?</h3>O elemento que criar aqui será <b>visível a todos</b>. Por favor, só adicione coisas ao mapa se elas realmente existirem. Muitas aplicações usam estes dados.", "confirmIntro": "<h3>Adicionar {title} aqui?</h3>O elemento que criar aqui será <b>visível a todos</b>. Por favor, só adicione coisas ao mapa se elas realmente existirem. Muitas aplicações usam estes dados.",
"disableFilters": "Desativar todos os filtros", "disableFilters": "Desativar todos os filtros",

View file

@ -50,7 +50,6 @@
"aboutMapcomplete": "<h3>關於</h3><p>使用 MapComplete 你可以藉由<b>單一主題</b>新增開放街圖的圖資。回答幾個問題,然後幾分鐘之內你的貢獻立刻就傳遍全球!大部分的主題都能新增圖片甚至留下評論。<b>主題維護者</b>定議主題的元素、問題與語言。</p><h3>發現更多</h3><p>MapComplete 總是提供學習更多開放街圖<b>下一步的知識</b>。</p><ul><li>當你內嵌網站,網頁內嵌會連結到全螢幕的 MapComplete</li><li>全螢幕的版本提供關於開放街圖的資訊</li><li>不登入檢視成果,但是要編輯則需要 OSM 帳號。</li><li>如果你沒有登入,你會被要求先登入</li><li>當你回答單一問題時,你可以在地圖新增新的圖徵</li><li>過了一陣子,實際的 OSM-標籤會顯示,之後會連結到 wiki</li></ul><p></p><br><p>你有注意到<b>問題</b>嗎?你想請求<b>功能</b>嗎?想要<b>幫忙翻譯</b>嗎?來到<a href=\"https://github.com/pietervdvn/MapComplete\" target=\"_blank\">原始碼</a>或是<a href=\"https://github.com/pietervdvn/MapComplete/issues\" target=\"_blank\">問題追蹤器。</a></p><p>想要看到<b>你的進度</b>嗎?到<a href=\"{osmcha_link}\" target=\"_blank\">OsmCha</a>追蹤編輯數。</p>", "aboutMapcomplete": "<h3>關於</h3><p>使用 MapComplete 你可以藉由<b>單一主題</b>新增開放街圖的圖資。回答幾個問題,然後幾分鐘之內你的貢獻立刻就傳遍全球!大部分的主題都能新增圖片甚至留下評論。<b>主題維護者</b>定議主題的元素、問題與語言。</p><h3>發現更多</h3><p>MapComplete 總是提供學習更多開放街圖<b>下一步的知識</b>。</p><ul><li>當你內嵌網站,網頁內嵌會連結到全螢幕的 MapComplete</li><li>全螢幕的版本提供關於開放街圖的資訊</li><li>不登入檢視成果,但是要編輯則需要 OSM 帳號。</li><li>如果你沒有登入,你會被要求先登入</li><li>當你回答單一問題時,你可以在地圖新增新的圖徵</li><li>過了一陣子,實際的 OSM-標籤會顯示,之後會連結到 wiki</li></ul><p></p><br><p>你有注意到<b>問題</b>嗎?你想請求<b>功能</b>嗎?想要<b>幫忙翻譯</b>嗎?來到<a href=\"https://github.com/pietervdvn/MapComplete\" target=\"_blank\">原始碼</a>或是<a href=\"https://github.com/pietervdvn/MapComplete/issues\" target=\"_blank\">問題追蹤器。</a></p><p>想要看到<b>你的進度</b>嗎?到<a href=\"{osmcha_link}\" target=\"_blank\">OsmCha</a>追蹤編輯數。</p>",
"add": { "add": {
"addNew": "在這裡新增新的 {category}", "addNew": "在這裡新增新的 {category}",
"addNewMapLabel": "點這邊新增新項目",
"confirmButton": "在此新增 {category}。<br><div class=\"alert\">大家都可以看到您新增的內容</div>", "confirmButton": "在此新增 {category}。<br><div class=\"alert\">大家都可以看到您新增的內容</div>",
"confirmIntro": "<h3>在這裡新增 {title} </h3>你在這裡新增的圖徵<b>所有人都看得到</b>。請只有在確定有物件存在的情形下才新增上去,許多應用程式都使用這份資料。", "confirmIntro": "<h3>在這裡新增 {title} </h3>你在這裡新增的圖徵<b>所有人都看得到</b>。請只有在確定有物件存在的情形下才新增上去,許多應用程式都使用這份資料。",
"disableFilters": "關閉所有篩選器", "disableFilters": "關閉所有篩選器",

221
package-lock.json generated
View file

@ -38,6 +38,7 @@
"lz-string": "^1.4.4", "lz-string": "^1.4.4",
"mangrove-reviews-typescript": "^1.1.0", "mangrove-reviews-typescript": "^1.1.0",
"maplibre-gl": "^2.4.0", "maplibre-gl": "^2.4.0",
"node-html-parser": "^6.1.5",
"opening_hours": "^3.6.0", "opening_hours": "^3.6.0",
"osm-auth": "^1.0.2", "osm-auth": "^1.0.2",
"osmtogeojson": "^3.0.0-beta.5", "osmtogeojson": "^3.0.0-beta.5",
@ -4281,6 +4282,11 @@
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
"integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA=="
}, },
"node_modules/boolbase": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
"integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="
},
"node_modules/bops": { "node_modules/bops": {
"version": "0.0.6", "version": "0.0.6",
"resolved": "https://registry.npmjs.org/bops/-/bops-0.0.6.tgz", "resolved": "https://registry.npmjs.org/bops/-/bops-0.0.6.tgz",
@ -4871,6 +4877,70 @@
"utrie": "^1.0.2" "utrie": "^1.0.2"
} }
}, },
"node_modules/css-select": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
"integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==",
"dependencies": {
"boolbase": "^1.0.0",
"css-what": "^6.1.0",
"domhandler": "^5.0.2",
"domutils": "^3.0.1",
"nth-check": "^2.0.1"
},
"funding": {
"url": "https://github.com/sponsors/fb55"
}
},
"node_modules/css-select/node_modules/domelementtype": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
"integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/fb55"
}
]
},
"node_modules/css-select/node_modules/domhandler": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
"dependencies": {
"domelementtype": "^2.3.0"
},
"engines": {
"node": ">= 4"
},
"funding": {
"url": "https://github.com/fb55/domhandler?sponsor=1"
}
},
"node_modules/css-select/node_modules/domutils": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz",
"integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==",
"dependencies": {
"dom-serializer": "^2.0.0",
"domelementtype": "^2.3.0",
"domhandler": "^5.0.1"
},
"funding": {
"url": "https://github.com/fb55/domutils?sponsor=1"
}
},
"node_modules/css-what": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
"integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==",
"engines": {
"node": ">= 6"
},
"funding": {
"url": "https://github.com/sponsors/fb55"
}
},
"node_modules/csscolorparser": { "node_modules/csscolorparser": {
"version": "1.0.3", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/csscolorparser/-/csscolorparser-1.0.3.tgz", "resolved": "https://registry.npmjs.org/csscolorparser/-/csscolorparser-1.0.3.tgz",
@ -5342,6 +5412,44 @@
"doctest-ts-improved": "dist/main.js" "doctest-ts-improved": "dist/main.js"
} }
}, },
"node_modules/dom-serializer": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
"integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
"dependencies": {
"domelementtype": "^2.3.0",
"domhandler": "^5.0.2",
"entities": "^4.2.0"
},
"funding": {
"url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
}
},
"node_modules/dom-serializer/node_modules/domelementtype": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
"integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/fb55"
}
]
},
"node_modules/dom-serializer/node_modules/domhandler": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
"dependencies": {
"domelementtype": "^2.3.0"
},
"engines": {
"node": ">= 4"
},
"funding": {
"url": "https://github.com/fb55/domhandler?sponsor=1"
}
},
"node_modules/dom-walk": { "node_modules/dom-walk": {
"version": "0.1.2", "version": "0.1.2",
"resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz",
@ -5464,7 +5572,6 @@
"version": "4.4.0", "version": "4.4.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz", "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz",
"integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==", "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==",
"devOptional": true,
"engines": { "engines": {
"node": ">=0.12" "node": ">=0.12"
}, },
@ -7860,6 +7967,15 @@
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"dev": true "dev": true
}, },
"node_modules/node-html-parser": {
"version": "6.1.5",
"resolved": "https://registry.npmjs.org/node-html-parser/-/node-html-parser-6.1.5.tgz",
"integrity": "sha512-fAaM511feX++/Chnhe475a0NHD8M7AxDInsqQpz6x63GRF7xYNdS8Vo5dKsIVPgsOvG7eioRRTZQnWBrhDHBSg==",
"dependencies": {
"css-select": "^5.1.0",
"he": "1.2.0"
}
},
"node_modules/node-releases": { "node_modules/node-releases": {
"version": "2.0.8", "version": "2.0.8",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.8.tgz", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.8.tgz",
@ -7874,6 +7990,17 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/nth-check": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
"integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
"dependencies": {
"boolbase": "^1.0.0"
},
"funding": {
"url": "https://github.com/fb55/nth-check?sponsor=1"
}
},
"node_modules/nwmatcher": { "node_modules/nwmatcher": {
"version": "1.4.4", "version": "1.4.4",
"resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.4.tgz", "resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.4.tgz",
@ -15160,6 +15287,11 @@
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
"integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA=="
}, },
"boolbase": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
"integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="
},
"bops": { "bops": {
"version": "0.0.6", "version": "0.0.6",
"resolved": "https://registry.npmjs.org/bops/-/bops-0.0.6.tgz", "resolved": "https://registry.npmjs.org/bops/-/bops-0.0.6.tgz",
@ -15591,6 +15723,48 @@
"utrie": "^1.0.2" "utrie": "^1.0.2"
} }
}, },
"css-select": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
"integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==",
"requires": {
"boolbase": "^1.0.0",
"css-what": "^6.1.0",
"domhandler": "^5.0.2",
"domutils": "^3.0.1",
"nth-check": "^2.0.1"
},
"dependencies": {
"domelementtype": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
"integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="
},
"domhandler": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
"requires": {
"domelementtype": "^2.3.0"
}
},
"domutils": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz",
"integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==",
"requires": {
"dom-serializer": "^2.0.0",
"domelementtype": "^2.3.0",
"domhandler": "^5.0.1"
}
}
}
},
"css-what": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
"integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw=="
},
"csscolorparser": { "csscolorparser": {
"version": "1.0.3", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/csscolorparser/-/csscolorparser-1.0.3.tgz", "resolved": "https://registry.npmjs.org/csscolorparser/-/csscolorparser-1.0.3.tgz",
@ -15938,6 +16112,31 @@
"typescript": "^4.6.2" "typescript": "^4.6.2"
} }
}, },
"dom-serializer": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
"integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
"requires": {
"domelementtype": "^2.3.0",
"domhandler": "^5.0.2",
"entities": "^4.2.0"
},
"dependencies": {
"domelementtype": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
"integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="
},
"domhandler": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
"requires": {
"domelementtype": "^2.3.0"
}
}
}
},
"dom-walk": { "dom-walk": {
"version": "0.1.2", "version": "0.1.2",
"resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz",
@ -16050,8 +16249,7 @@
"entities": { "entities": {
"version": "4.4.0", "version": "4.4.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz", "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz",
"integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==", "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA=="
"devOptional": true
}, },
"es6-object-assign": { "es6-object-assign": {
"version": "1.1.0", "version": "1.1.0",
@ -17867,6 +18065,15 @@
} }
} }
}, },
"node-html-parser": {
"version": "6.1.5",
"resolved": "https://registry.npmjs.org/node-html-parser/-/node-html-parser-6.1.5.tgz",
"integrity": "sha512-fAaM511feX++/Chnhe475a0NHD8M7AxDInsqQpz6x63GRF7xYNdS8Vo5dKsIVPgsOvG7eioRRTZQnWBrhDHBSg==",
"requires": {
"css-select": "^5.1.0",
"he": "1.2.0"
}
},
"node-releases": { "node-releases": {
"version": "2.0.8", "version": "2.0.8",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.8.tgz", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.8.tgz",
@ -17878,6 +18085,14 @@
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="
}, },
"nth-check": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
"integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
"requires": {
"boolbase": "^1.0.0"
}
},
"nwmatcher": { "nwmatcher": {
"version": "1.4.4", "version": "1.4.4",
"resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.4.tgz", "resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.4.tgz",

View file

@ -90,7 +90,7 @@
"lz-string": "^1.4.4", "lz-string": "^1.4.4",
"mangrove-reviews-typescript": "^1.1.0", "mangrove-reviews-typescript": "^1.1.0",
"maplibre-gl": "^2.4.0", "maplibre-gl": "^2.4.0",
"opening_hours": "^3.6.0", "opening_hours": "^3.6.0",
"osm-auth": "^1.0.2", "osm-auth": "^1.0.2",
"osmtogeojson": "^3.0.0-beta.5", "osmtogeojson": "^3.0.0-beta.5",
"papaparse": "^5.3.1", "papaparse": "^5.3.1",
@ -126,6 +126,7 @@
"dependency-cruiser": "^10.4.0", "dependency-cruiser": "^10.4.0",
"fs": "0.0.1-security", "fs": "0.0.1-security",
"jsdom": "^21.1.0", "jsdom": "^21.1.0",
"node-html-parser": "^6.1.5",
"prettier": "^2.7.1", "prettier": "^2.7.1",
"prettier-plugin-svelte": "^2.9.0", "prettier-plugin-svelte": "^2.9.0",
"read-file": "^0.2.0", "read-file": "^0.2.0",

View file

@ -2,7 +2,7 @@ import SvelteUIElement from "./UI/Base/SvelteUIElement"
import ThemeViewGUI from "./UI/ThemeViewGUI.svelte" import ThemeViewGUI from "./UI/ThemeViewGUI.svelte"
import { FixedUiElement } from "./UI/Base/FixedUiElement" import { FixedUiElement } from "./UI/Base/FixedUiElement"
import LayoutConfig from "./Models/ThemeConfig/LayoutConfig" import LayoutConfig from "./Models/ThemeConfig/LayoutConfig"
import * as benches from "./assets/generated/themes/cyclofix.json" import * as theme from "./assets/generated/themes/shops.json"
import { UIEventSource } from "./Logic/UIEventSource" import { UIEventSource } from "./Logic/UIEventSource"
import ThemeViewState from "./Models/ThemeViewState" import ThemeViewState from "./Models/ThemeViewState"
import Combine from "./UI/Base/Combine" import Combine from "./UI/Base/Combine"
@ -13,13 +13,13 @@ import { Translation } from "./UI/i18n/Translation"
async function main() { async function main() {
new FixedUiElement("").AttachTo("extradiv") new FixedUiElement("").AttachTo("extradiv")
const layout = new LayoutConfig(<any>benches, true) // qp.data === "" ? : new AllKnownLayoutsLazy().get(qp.data) const layout = new LayoutConfig(<any>theme, true) // qp.data === "" ? : new AllKnownLayoutsLazy().get(qp.data)
const main = new SvelteUIElement(ThemeViewGUI, { layout }) const main = new SvelteUIElement(ThemeViewGUI, { layout })
main.AttachTo("maindiv") main.AttachTo("maindiv")
} }
async function testspecial() { async function testspecial() {
const layout = new LayoutConfig(<any>benches, true) // qp.data === "" ? : new AllKnownLayoutsLazy().get(qp.data) const layout = new LayoutConfig(<any>theme, true) // qp.data === "" ? : new AllKnownLayoutsLazy().get(qp.data)
const state = new ThemeViewState(layout) const state = new ThemeViewState(layout)
const all = SpecialVisualizations.specialVisualizations.map((s) => const all = SpecialVisualizations.specialVisualizations.map((s) =>