forked from MapComplete/MapComplete
Merge branches
This commit is contained in:
commit
bae90d50bc
304 changed files with 49983 additions and 31589 deletions
|
@ -16,6 +16,7 @@ export class LastClickFeatureSource {
|
|||
private i: number = 0
|
||||
private readonly hasPresets: boolean
|
||||
private readonly hasNoteLayer: boolean
|
||||
public static readonly newPointElementId= "new_point_dialog"
|
||||
|
||||
constructor(layout: LayoutConfig) {
|
||||
this.hasNoteLayer = layout.hasNoteLayer()
|
||||
|
@ -46,7 +47,7 @@ export class LastClickFeatureSource {
|
|||
|
||||
public createFeature(lon: number, lat: number): Feature<Point, OsmTags> {
|
||||
const properties: OsmTags = {
|
||||
id: "new_point_dialog",
|
||||
id: LastClickFeatureSource.newPointElementId,
|
||||
has_note_layer: this.hasNoteLayer ? "yes" : "no",
|
||||
has_presets: this.hasPresets ? "yes" : "no",
|
||||
renderings: this.renderings.join(""),
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
import Constants from "../Models/Constants"
|
||||
|
||||
export interface MaprouletteTask {
|
||||
name: string,
|
||||
description: string,
|
||||
instruction: string
|
||||
}
|
||||
export default class Maproulette {
|
||||
public static readonly defaultEndpoint = "https://maproulette.org/api/v2"
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ import Title from "../../UI/Base/Title"
|
|||
import Table from "../../UI/Base/Table"
|
||||
import ChangeLocationAction from "./Actions/ChangeLocationAction"
|
||||
import ChangeTagAction from "./Actions/ChangeTagAction"
|
||||
import FeatureSwitchState from "../State/FeatureSwitchState"
|
||||
|
||||
/**
|
||||
* Handles all changes made to OSM.
|
||||
|
@ -28,7 +29,7 @@ export class Changes {
|
|||
public readonly pendingChanges: UIEventSource<ChangeDescription[]> =
|
||||
LocalStorageSource.GetParsed<ChangeDescription[]>("pending-changes", [])
|
||||
public readonly allChanges = new UIEventSource<ChangeDescription[]>(undefined)
|
||||
public readonly state: { allElements?: IndexedFeatureSource; osmConnection: OsmConnection }
|
||||
public readonly state: { allElements?: IndexedFeatureSource; osmConnection: OsmConnection, featureSwitches?: FeatureSwitchState }
|
||||
public readonly extraComment: UIEventSource<string> = new UIEventSource(undefined)
|
||||
public readonly backend: string
|
||||
public readonly isUploading = new UIEventSource(false)
|
||||
|
@ -45,7 +46,8 @@ export class Changes {
|
|||
allElements?: IndexedFeatureSource
|
||||
featurePropertiesStore?: FeaturePropertiesStore
|
||||
osmConnection: OsmConnection
|
||||
historicalUserLocations?: FeatureSource
|
||||
historicalUserLocations?: FeatureSource,
|
||||
featureSwitches?: FeatureSwitchState
|
||||
},
|
||||
leftRightSensitive: boolean = false
|
||||
) {
|
||||
|
@ -431,6 +433,9 @@ export class Changes {
|
|||
// Probably irrelevant, such as a new helper node
|
||||
return
|
||||
}
|
||||
if(this.state.featureSwitches.featureSwitchMorePrivacy?.data){
|
||||
return
|
||||
}
|
||||
|
||||
const now = new Date()
|
||||
const recentLocationPoints = locations
|
||||
|
|
|
@ -6,14 +6,6 @@ import Constants from "../../Models/Constants"
|
|||
import { Changes } from "./Changes"
|
||||
import { Utils } from "../../Utils"
|
||||
import FeaturePropertiesStore from "../FeatureSource/Actors/FeaturePropertiesStore"
|
||||
import ChangeLocationAction from "./Actions/ChangeLocationAction"
|
||||
import ChangeTagAction from "./Actions/ChangeTagAction"
|
||||
import DeleteAction from "./Actions/DeleteAction"
|
||||
import LinkImageAction from "./Actions/LinkImageAction"
|
||||
import OsmChangeAction from "./Actions/OsmChangeAction"
|
||||
import RelationSplitHandler from "./Actions/RelationSplitHandler"
|
||||
import ReplaceGeometryAction from "./Actions/ReplaceGeometryAction"
|
||||
import SplitAction from "./Actions/SplitAction"
|
||||
|
||||
export interface ChangesetTag {
|
||||
key: string
|
||||
|
@ -232,7 +224,7 @@ export class ChangesetHandler {
|
|||
if (newMetaTag === undefined) {
|
||||
extraMetaTags.push({
|
||||
key: key,
|
||||
value: oldCsTags[key],
|
||||
value: oldCsTags[key]
|
||||
})
|
||||
continue
|
||||
}
|
||||
|
@ -361,21 +353,22 @@ export class ChangesetHandler {
|
|||
}
|
||||
|
||||
private defaultChangesetTags(): ChangesetTag[] {
|
||||
const usedGps = this.changes.state["currentUserLocation"]?.features?.data?.length > 0
|
||||
const hasMorePrivacy = !!this.changes.state?.featureSwitches?.featureSwitchMorePrivacy?.data
|
||||
const setSourceAsSurvey = !hasMorePrivacy && usedGps
|
||||
return [
|
||||
["created_by", `MapComplete ${Constants.vNumber}`],
|
||||
["locale", Locale.language.data],
|
||||
["host", `${window.location.origin}${window.location.pathname}`],
|
||||
[
|
||||
"source",
|
||||
this.changes.state["currentUserLocation"]?.features?.data?.length > 0
|
||||
? "survey"
|
||||
: undefined,
|
||||
setSourceAsSurvey ? "survey" : undefined
|
||||
],
|
||||
["imagery", this.changes.state["backgroundLayer"]?.data?.id],
|
||||
["imagery", this.changes.state["backgroundLayer"]?.data?.id]
|
||||
].map(([key, value]) => ({
|
||||
key,
|
||||
value,
|
||||
aggregate: false,
|
||||
aggregate: false
|
||||
}))
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
// @ts-ignore
|
||||
import { osmAuth } from "osm-auth"
|
||||
import { Store, Stores, UIEventSource } from "../UIEventSource"
|
||||
import { OsmPreferences } from "./OsmPreferences"
|
||||
|
@ -6,7 +5,18 @@ import { Utils } from "../../Utils"
|
|||
import { LocalStorageSource } from "../Web/LocalStorageSource"
|
||||
import { AuthConfig } from "./AuthConfig"
|
||||
import Constants from "../../Models/Constants"
|
||||
import OSMAuthInstance = OSMAuth.OSMAuthInstance
|
||||
|
||||
interface OsmUserInfo {
|
||||
id: number
|
||||
display_name: string
|
||||
account_created: string
|
||||
description: string
|
||||
contributor_terms: { agreed: boolean }
|
||||
roles: []
|
||||
changesets: { count: number }
|
||||
traces: { count: number }
|
||||
blocks: { received: { count: number; active: number } }
|
||||
}
|
||||
|
||||
export default class UserDetails {
|
||||
public loggedIn = false
|
||||
|
@ -31,7 +41,7 @@ export default class UserDetails {
|
|||
export type OsmServiceState = "online" | "readonly" | "offline" | "unknown" | "unreachable"
|
||||
|
||||
export class OsmConnection {
|
||||
public auth: OSMAuthInstance
|
||||
public auth: osmAuth
|
||||
public userDetails: UIEventSource<UserDetails>
|
||||
public isLoggedIn: Store<boolean>
|
||||
public gpxServiceIsOnline: UIEventSource<OsmServiceState> = new UIEventSource<OsmServiceState>(
|
||||
|
@ -49,7 +59,7 @@ export class OsmConnection {
|
|||
private readonly _dryRun: Store<boolean>
|
||||
private readonly fakeUser: boolean
|
||||
private _onLoggedIn: ((userDetails: UserDetails) => void)[] = []
|
||||
private readonly _iframeMode: Boolean | boolean
|
||||
private readonly _iframeMode: boolean
|
||||
private readonly _singlePage: boolean
|
||||
private isChecking = false
|
||||
private readonly _doCheckRegularly
|
||||
|
@ -99,20 +109,19 @@ export class OsmConnection {
|
|||
ud.languages = ["en"]
|
||||
this.loadingStatus.setData("logged-in")
|
||||
}
|
||||
const self = this
|
||||
this.UpdateCapabilities()
|
||||
|
||||
this.isLoggedIn = this.userDetails.map(
|
||||
(user) =>
|
||||
user.loggedIn &&
|
||||
(self.apiIsOnline.data === "unknown" || self.apiIsOnline.data === "online"),
|
||||
(this.apiIsOnline.data === "unknown" || this.apiIsOnline.data === "online"),
|
||||
[this.apiIsOnline]
|
||||
)
|
||||
this.isLoggedIn.addCallback((isLoggedIn) => {
|
||||
if (self.userDetails.data.loggedIn == false && isLoggedIn == true) {
|
||||
if (this.userDetails.data.loggedIn == false && isLoggedIn == true) {
|
||||
// We have an inconsistency: the userdetails say we _didn't_ log in, but this actor says we do
|
||||
// This means someone attempted to toggle this; so we attempt to login!
|
||||
self.AttemptLogin()
|
||||
this.AttemptLogin()
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -120,37 +129,36 @@ export class OsmConnection {
|
|||
|
||||
this.updateAuthObject()
|
||||
if (!this.fakeUser) {
|
||||
self.CheckForMessagesContinuously()
|
||||
this.CheckForMessagesContinuously()
|
||||
}
|
||||
|
||||
this.preferencesHandler = new OsmPreferences(this.auth, this, this.fakeUser)
|
||||
|
||||
if (options.oauth_token?.data !== undefined) {
|
||||
console.log(options.oauth_token.data)
|
||||
const self = this
|
||||
this.auth.bootstrapToken(options.oauth_token.data, (err, result) => {
|
||||
console.log("Bootstrap token called back", err, result)
|
||||
self.AttemptLogin()
|
||||
this.AttemptLogin()
|
||||
})
|
||||
|
||||
options.oauth_token.setData(undefined)
|
||||
}
|
||||
if (this.auth.authenticated() && options.attemptLogin !== false) {
|
||||
if (!Utils.runningFromConsole && this.auth.authenticated() && options.attemptLogin !== false) {
|
||||
this.AttemptLogin()
|
||||
} else {
|
||||
console.log("Not authenticated")
|
||||
}
|
||||
}
|
||||
|
||||
public GetPreference(
|
||||
public GetPreference<T extends string = string>(
|
||||
key: string,
|
||||
defaultValue: string = undefined,
|
||||
options?: {
|
||||
documentation?: string
|
||||
prefix?: string
|
||||
}
|
||||
): UIEventSource<string> {
|
||||
return this.preferencesHandler.GetPreference(key, defaultValue, options)
|
||||
): UIEventSource<T | undefined> {
|
||||
return <UIEventSource<T>>this.preferencesHandler.GetPreference(key, defaultValue, options)
|
||||
}
|
||||
|
||||
public GetLongPreference(key: string, prefix: string = "mapcomplete-"): UIEventSource<string> {
|
||||
|
@ -192,7 +200,7 @@ export class OsmConnection {
|
|||
console.log("AttemptLogin called, but ignored as fakeUser is set")
|
||||
return
|
||||
}
|
||||
const self = this
|
||||
|
||||
console.log("Trying to log in...")
|
||||
this.updateAuthObject()
|
||||
|
||||
|
@ -202,33 +210,33 @@ export class OsmConnection {
|
|||
this.auth.xhr(
|
||||
{
|
||||
method: "GET",
|
||||
path: "/api/0.6/user/details",
|
||||
path: "/api/0.6/user/details"
|
||||
},
|
||||
function (err, details: XMLDocument) {
|
||||
(err, details: XMLDocument) => {
|
||||
if (err != null) {
|
||||
console.log("Could not login due to:", err)
|
||||
self.loadingStatus.setData("error")
|
||||
this.loadingStatus.setData("error")
|
||||
if (err.status == 401) {
|
||||
console.log("Clearing tokens...")
|
||||
// Not authorized - our token probably got revoked
|
||||
self.auth.logout()
|
||||
self.LogOut()
|
||||
this.auth.logout()
|
||||
this.LogOut()
|
||||
} else {
|
||||
console.log("Other error. Status:", err.status)
|
||||
self.apiIsOnline.setData("unreachable")
|
||||
this.apiIsOnline.setData("unreachable")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if (details == null) {
|
||||
self.loadingStatus.setData("error")
|
||||
this.loadingStatus.setData("error")
|
||||
return
|
||||
}
|
||||
|
||||
// details is an XML DOM of user details
|
||||
let userInfo = details.getElementsByTagName("user")[0]
|
||||
const userInfo = details.getElementsByTagName("user")[0]
|
||||
|
||||
let data = self.userDetails.data
|
||||
const data = this.userDetails.data
|
||||
data.loggedIn = true
|
||||
console.log("Login completed, userinfo is ", userInfo)
|
||||
data.name = userInfo.getAttribute("display_name")
|
||||
|
@ -261,18 +269,18 @@ export class OsmConnection {
|
|||
data.home = { lat: lat, lon: lon }
|
||||
}
|
||||
|
||||
self.loadingStatus.setData("logged-in")
|
||||
this.loadingStatus.setData("logged-in")
|
||||
const messages = userInfo
|
||||
.getElementsByTagName("messages")[0]
|
||||
.getElementsByTagName("received")[0]
|
||||
data.unreadMessages = parseInt(messages.getAttribute("unread"))
|
||||
data.totalMessages = parseInt(messages.getAttribute("count"))
|
||||
|
||||
self.userDetails.ping()
|
||||
for (const action of self._onLoggedIn) {
|
||||
action(self.userDetails.data)
|
||||
this.userDetails.ping()
|
||||
for (const action of this._onLoggedIn) {
|
||||
action(this.userDetails.data)
|
||||
}
|
||||
self._onLoggedIn = []
|
||||
this._onLoggedIn = []
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -289,11 +297,11 @@ export class OsmConnection {
|
|||
public async interact(
|
||||
path: string,
|
||||
method: "GET" | "POST" | "PUT" | "DELETE",
|
||||
header?: Record<string, string | number>,
|
||||
header?: Record<string, string>,
|
||||
content?: string,
|
||||
allowAnonymous: boolean = false
|
||||
): Promise<string> {
|
||||
let connection: OSMAuthInstance = this.auth
|
||||
const connection: osmAuth = this.auth
|
||||
if (allowAnonymous && !this.auth.authenticated()) {
|
||||
const possibleResult = await Utils.downloadAdvanced(
|
||||
`${this.Backend()}/api/0.6/${path}`,
|
||||
|
@ -310,15 +318,13 @@ export class OsmConnection {
|
|||
|
||||
return new Promise((ok, error) => {
|
||||
connection.xhr(
|
||||
<any>{
|
||||
{
|
||||
method,
|
||||
options: {
|
||||
header,
|
||||
},
|
||||
headers: header,
|
||||
content,
|
||||
path: `/api/0.6/${path}`,
|
||||
path: `/api/0.6/${path}`
|
||||
},
|
||||
function (err, response) {
|
||||
function(err, response) {
|
||||
if (err !== null) {
|
||||
error(err)
|
||||
} else {
|
||||
|
@ -329,32 +335,32 @@ export class OsmConnection {
|
|||
})
|
||||
}
|
||||
|
||||
public async post(
|
||||
public async post<T extends string>(
|
||||
path: string,
|
||||
content?: string,
|
||||
header?: Record<string, string | number>,
|
||||
header?: Record<string, string>,
|
||||
allowAnonymous: boolean = false
|
||||
): Promise<any> {
|
||||
return await this.interact(path, "POST", header, content, allowAnonymous)
|
||||
): Promise<T> {
|
||||
return <T> await this.interact(path, "POST", header, content, allowAnonymous)
|
||||
}
|
||||
|
||||
public async put(
|
||||
public async put<T extends string>(
|
||||
path: string,
|
||||
content?: string,
|
||||
header?: Record<string, string | number>
|
||||
): Promise<any> {
|
||||
return await this.interact(path, "PUT", header, content)
|
||||
header?: Record<string, string>
|
||||
): Promise<T> {
|
||||
return <T> await this.interact(path, "PUT", header, content)
|
||||
}
|
||||
|
||||
public async get(
|
||||
path: string,
|
||||
header?: Record<string, string | number>,
|
||||
header?: Record<string, string>,
|
||||
allowAnonymous: boolean = false
|
||||
): Promise<string> {
|
||||
return await this.interact(path, "GET", header, undefined, allowAnonymous)
|
||||
}
|
||||
|
||||
public closeNote(id: number | string, text?: string): Promise<void> {
|
||||
public closeNote(id: number | string, text?: string): Promise<string> {
|
||||
let textSuffix = ""
|
||||
if ((text ?? "") !== "") {
|
||||
textSuffix = "?text=" + encodeURIComponent(text)
|
||||
|
@ -362,17 +368,17 @@ export class OsmConnection {
|
|||
if (this._dryRun.data) {
|
||||
console.warn("Dryrun enabled - not actually closing note ", id, " with text ", text)
|
||||
return new Promise((ok) => {
|
||||
ok()
|
||||
ok("")
|
||||
})
|
||||
}
|
||||
return this.post(`notes/${id}/close${textSuffix}`)
|
||||
}
|
||||
|
||||
public reopenNote(id: number | string, text?: string): Promise<void> {
|
||||
public reopenNote(id: number | string, text?: string): Promise<string> {
|
||||
if (this._dryRun.data) {
|
||||
console.warn("Dryrun enabled - not actually reopening note ", id, " with text ", text)
|
||||
return new Promise((ok) => {
|
||||
ok()
|
||||
return new Promise(resolve => {
|
||||
resolve("")
|
||||
})
|
||||
}
|
||||
let textSuffix = ""
|
||||
|
@ -398,7 +404,7 @@ export class OsmConnection {
|
|||
"notes.json",
|
||||
content,
|
||||
{
|
||||
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
|
||||
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"
|
||||
},
|
||||
true
|
||||
)
|
||||
|
@ -439,7 +445,7 @@ export class OsmConnection {
|
|||
file: gpx,
|
||||
description: options.description,
|
||||
tags: options.labels?.join(",") ?? "",
|
||||
visibility: options.visibility,
|
||||
visibility: options.visibility
|
||||
}
|
||||
|
||||
if (!contents.description) {
|
||||
|
@ -447,9 +453,9 @@ export class OsmConnection {
|
|||
}
|
||||
const extras = {
|
||||
file:
|
||||
'; filename="' +
|
||||
"; filename=\"" +
|
||||
(options.filename ?? "gpx_track_mapcomplete_" + new Date().toISOString()) +
|
||||
'"\r\nContent-Type: application/gpx+xml',
|
||||
"\"\r\nContent-Type: application/gpx+xml"
|
||||
}
|
||||
|
||||
const boundary = "987654"
|
||||
|
@ -457,7 +463,7 @@ export class OsmConnection {
|
|||
let body = ""
|
||||
for (const key in contents) {
|
||||
body += "--" + boundary + "\r\n"
|
||||
body += 'Content-Disposition: form-data; name="' + key + '"'
|
||||
body += "Content-Disposition: form-data; name=\"" + key + "\""
|
||||
if (extras[key] !== undefined) {
|
||||
body += extras[key]
|
||||
}
|
||||
|
@ -468,7 +474,7 @@ export class OsmConnection {
|
|||
|
||||
const response = await this.post("gpx/create", body, {
|
||||
"Content-Type": "multipart/form-data; boundary=" + boundary,
|
||||
"Content-Length": body.length,
|
||||
"Content-Length": ""+body.length
|
||||
})
|
||||
const parsed = JSON.parse(response)
|
||||
console.log("Uploaded GPX track", parsed)
|
||||
|
@ -491,9 +497,9 @@ export class OsmConnection {
|
|||
{
|
||||
method: "POST",
|
||||
|
||||
path: `/api/0.6/notes/${id}/comment?text=${encodeURIComponent(text)}`,
|
||||
path: `/api/0.6/notes/${id}/comment?text=${encodeURIComponent(text)}`
|
||||
},
|
||||
function (err, _) {
|
||||
function(err) {
|
||||
if (err !== null) {
|
||||
error(err)
|
||||
} else {
|
||||
|
@ -508,7 +514,7 @@ export class OsmConnection {
|
|||
* To be called by land.html
|
||||
*/
|
||||
public finishLogin(callback: (previousURL: string) => void) {
|
||||
this.auth.authenticate(function () {
|
||||
this.auth.authenticate(function() {
|
||||
// Fully authed at this point
|
||||
console.log("Authentication successful!")
|
||||
const previousLocation = LocalStorageSource.Get("location_before_login")
|
||||
|
@ -517,28 +523,6 @@ export class OsmConnection {
|
|||
}
|
||||
|
||||
private updateAuthObject() {
|
||||
let pwaStandAloneMode = false
|
||||
try {
|
||||
if (Utils.runningFromConsole) {
|
||||
pwaStandAloneMode = true
|
||||
} else if (
|
||||
window.matchMedia("(display-mode: standalone)").matches ||
|
||||
window.matchMedia("(display-mode: fullscreen)").matches
|
||||
) {
|
||||
pwaStandAloneMode = true
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn(
|
||||
"Detecting standalone mode failed",
|
||||
e,
|
||||
". Assuming in browser and not worrying furhter"
|
||||
)
|
||||
}
|
||||
const standalone = this._iframeMode || pwaStandAloneMode || !this._singlePage
|
||||
|
||||
// In standalone mode, we DON'T use single page login, as 'redirecting' opens a new window anyway...
|
||||
// Same for an iframe...
|
||||
|
||||
this.auth = new osmAuth({
|
||||
client_id: this._oauth_config.oauth_client_id,
|
||||
url: this._oauth_config.url,
|
||||
|
@ -546,23 +530,22 @@ export class OsmConnection {
|
|||
redirect_uri: Utils.runningFromConsole
|
||||
? "https://mapcomplete.org/land.html"
|
||||
: window.location.protocol + "//" + window.location.host + "/land.html",
|
||||
singlepage: true,
|
||||
auto: true,
|
||||
singlepage: true, // We always use 'singlePage', it is the most stable - including in PWA
|
||||
auto: true
|
||||
})
|
||||
}
|
||||
|
||||
private CheckForMessagesContinuously() {
|
||||
const self = this
|
||||
if (this.isChecking) {
|
||||
return
|
||||
}
|
||||
Stores.Chronic(3 * 1000).addCallback((_) => {
|
||||
if (!(self.apiIsOnline.data === "unreachable" || self.apiIsOnline.data === "offline")) {
|
||||
Stores.Chronic(3 * 1000).addCallback(() => {
|
||||
if (!(this.apiIsOnline.data === "unreachable" || this.apiIsOnline.data === "offline")) {
|
||||
return
|
||||
}
|
||||
try {
|
||||
console.log("Api is offline - trying to reconnect...")
|
||||
self.AttemptLogin()
|
||||
this.AttemptLogin()
|
||||
} catch (e) {
|
||||
console.log("Could not login due to", e)
|
||||
}
|
||||
|
@ -571,10 +554,10 @@ export class OsmConnection {
|
|||
if (!this._doCheckRegularly) {
|
||||
return
|
||||
}
|
||||
Stores.Chronic(60 * 5 * 1000).addCallback((_) => {
|
||||
if (self.isLoggedIn.data) {
|
||||
Stores.Chronic(60 * 5 * 1000).addCallback(() => {
|
||||
if (this.isLoggedIn.data) {
|
||||
try {
|
||||
self.AttemptLogin()
|
||||
this.AttemptLogin()
|
||||
} catch (e) {
|
||||
console.log("Could not login due to", e)
|
||||
}
|
||||
|
@ -592,19 +575,9 @@ export class OsmConnection {
|
|||
})
|
||||
}
|
||||
|
||||
private readonly _userInfoCache: Record<number, any> = {}
|
||||
private readonly _userInfoCache: Record<number, OsmUserInfo> = {}
|
||||
|
||||
public async getInformationAboutUser(id: number): Promise<{
|
||||
id: number
|
||||
display_name: string
|
||||
account_created: string
|
||||
description: string
|
||||
contributor_terms: { agreed: boolean }
|
||||
roles: []
|
||||
changesets: { count: number }
|
||||
traces: { count: number }
|
||||
blocks: { received: { count: number; active: number } }
|
||||
}> {
|
||||
public async getInformationAboutUser(id: number): Promise<OsmUserInfo> {
|
||||
if (id === undefined) {
|
||||
return undefined
|
||||
}
|
||||
|
|
|
@ -63,6 +63,7 @@ export default class FeatureSwitchState extends OsmConnectionFeatureSwitches {
|
|||
public readonly overpassMaxZoom: UIEventSource<number>
|
||||
public readonly osmApiTileSize: UIEventSource<number>
|
||||
public readonly backgroundLayerId: UIEventSource<string>
|
||||
public readonly featureSwitchMorePrivacy: UIEventSource<boolean>
|
||||
|
||||
public constructor(layoutToUse?: LayoutConfig) {
|
||||
super()
|
||||
|
@ -164,6 +165,14 @@ export default class FeatureSwitchState extends OsmConnectionFeatureSwitches {
|
|||
"If true, shows some extra debugging help such as all the available tags on every object"
|
||||
)
|
||||
|
||||
|
||||
this.featureSwitchMorePrivacy = QueryParameters.GetBooleanQueryParameter(
|
||||
"moreprivacy",
|
||||
layoutToUse.enableMorePrivacy,
|
||||
"If true, the location distance indication will not be written to the changeset and other privacy enhancing measures might be taken."
|
||||
)
|
||||
|
||||
|
||||
this.overpassUrl = QueryParameters.GetQueryParameter(
|
||||
"overpassUrl",
|
||||
(layoutToUse?.overpassUrl ?? Constants.defaultOverpassUrls).join(","),
|
||||
|
|
|
@ -43,6 +43,7 @@ export default class UserRelatedState {
|
|||
public readonly fixateNorth: UIEventSource<undefined | "yes">
|
||||
public readonly a11y: UIEventSource<undefined | "always" | "never" | "default">
|
||||
public readonly homeLocation: FeatureSource
|
||||
public readonly morePrivacy: UIEventSource<undefined | "yes" | "no">
|
||||
/**
|
||||
* The language as saved into the preferences of the user, if logged in.
|
||||
* Note that this is _different_ from the languages a user can set via the osm.org interface here: https://www.openstreetmap.org/preferences
|
||||
|
@ -106,12 +107,12 @@ export default class UserRelatedState {
|
|||
})
|
||||
)
|
||||
this.language = this.osmConnection.GetPreference("language")
|
||||
this.showTags = <UIEventSource<any>>this.osmConnection.GetPreference("show_tags")
|
||||
this.showCrosshair = <UIEventSource<any>>this.osmConnection.GetPreference("show_crosshair")
|
||||
this.fixateNorth = <UIEventSource<"yes">>this.osmConnection.GetPreference("fixate-north")
|
||||
this.a11y = <UIEventSource<"always" | "never" | "default">>(
|
||||
this.osmConnection.GetPreference("a11y")
|
||||
)
|
||||
this.showTags = this.osmConnection.GetPreference("show_tags")
|
||||
this.showCrosshair = this.osmConnection.GetPreference("show_crosshair")
|
||||
this.fixateNorth = this.osmConnection.GetPreference("fixate-north")
|
||||
this.morePrivacy = this.osmConnection.GetPreference("more_privacy", "no")
|
||||
|
||||
this.a11y = this.osmConnection.GetPreference("a11y")
|
||||
|
||||
this.mangroveIdentity = new MangroveIdentity(
|
||||
this.osmConnection.GetLongPreference("identity", "mangrove"),
|
||||
|
|
|
@ -5,6 +5,7 @@ import { Tag } from "./Tag"
|
|||
import { RegexTag } from "./RegexTag"
|
||||
import { TagConfigJson } from "../../Models/ThemeConfig/Json/TagConfigJson"
|
||||
import { ExpressionSpecification } from "maplibre-gl"
|
||||
import ComparingTag from "./ComparingTag"
|
||||
|
||||
export class And extends TagsFilter {
|
||||
public and: TagsFilter[]
|
||||
|
@ -242,6 +243,27 @@ export class And extends TagsFilter {
|
|||
* const raw = {"and": [{"and":["advertising=screen"]}, {"and":["advertising~*"]}]}]
|
||||
* const parsed = TagUtils.Tag(raw)
|
||||
* parsed.optimize().asJson() // => "advertising=screen"
|
||||
*
|
||||
* const raw = {"and": ["count=0", "count>0"]}
|
||||
* const parsed = TagUtils.Tag(raw)
|
||||
* parsed.optimize() // => false
|
||||
*
|
||||
* const raw = {"and": ["count>0", "count>10"]}
|
||||
* const parsed = TagUtils.Tag(raw)
|
||||
* parsed.optimize().asJson() // => "count>0"
|
||||
*
|
||||
* // regression test
|
||||
* const orig = {
|
||||
* "and": [
|
||||
* "sport=climbing",
|
||||
* "climbing!~route",
|
||||
* "climbing!=route_top",
|
||||
* "climbing!=route_bottom",
|
||||
* "leisure!~sports_centre"
|
||||
* ]
|
||||
* }
|
||||
* const parsed = TagUtils.Tag(orig)
|
||||
* parsed.optimize().asJson() // => orig
|
||||
*/
|
||||
optimize(): TagsFilter | boolean {
|
||||
if (this.and.length === 0) {
|
||||
|
@ -256,9 +278,30 @@ export class And extends TagsFilter {
|
|||
}
|
||||
const optimized = <TagsFilter[]>optimizedRaw
|
||||
|
||||
for (let i = 0; i <optimized.length; i++) {
|
||||
for (let j = i + 1; j < optimized.length; j++) {
|
||||
const ti = optimized[i]
|
||||
const tj = optimized[j]
|
||||
if(ti.shadows(tj)){
|
||||
// if 'ti' is true, this implies 'tj' is always true as well.
|
||||
// if 'ti' is false, then 'tj' might be true or false
|
||||
// (e.g. let 'ti' be 'count>0' and 'tj' be 'count>10'.
|
||||
// As such, it is no use to keep 'tj' around:
|
||||
// If 'ti' is true, then 'tj' will be true too and 'tj' can be ignored
|
||||
// If 'ti' is false, then the entire expression will be false and it doesn't matter what 'tj' yields
|
||||
optimized.splice(j, 1)
|
||||
}else if (tj.shadows(ti)){
|
||||
optimized.splice(i, 1)
|
||||
i--
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
// Conflicting keys do return false
|
||||
const properties: object = {}
|
||||
const properties: Record<string, string> = {}
|
||||
for (const opt of optimized) {
|
||||
if (opt instanceof Tag) {
|
||||
properties[opt.key] = opt.value
|
||||
|
@ -277,8 +320,7 @@ export class And extends TagsFilter {
|
|||
// detected an internal conflict
|
||||
return false
|
||||
}
|
||||
}
|
||||
if (opt instanceof RegexTag) {
|
||||
} else if (opt instanceof RegexTag) {
|
||||
const k = opt.key
|
||||
if (typeof k !== "string") {
|
||||
continue
|
||||
|
@ -316,6 +358,11 @@ export class And extends TagsFilter {
|
|||
i--
|
||||
}
|
||||
}
|
||||
}else if(opt instanceof ComparingTag) {
|
||||
const ct = opt
|
||||
if(properties[ct.key] !== undefined && !ct.matchesProperties(properties)){
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
import { TagsFilter } from "./TagsFilter"
|
||||
import { TagConfigJson } from "../../Models/ThemeConfig/Json/TagConfigJson"
|
||||
import { Tag } from "./Tag"
|
||||
import { ExpressionSpecification } from "maplibre-gl"
|
||||
|
||||
export default class ComparingTag extends TagsFilter {
|
||||
private readonly _key: string
|
||||
public readonly key: string
|
||||
private readonly _predicate: (value: string) => boolean
|
||||
private readonly _representation: "<" | ">" | "<=" | ">="
|
||||
private readonly _boundary: string
|
||||
|
@ -16,7 +15,7 @@ export default class ComparingTag extends TagsFilter {
|
|||
boundary: string
|
||||
) {
|
||||
super()
|
||||
this._key = key
|
||||
this.key = key
|
||||
this._predicate = predicate
|
||||
this._representation = representation
|
||||
this._boundary = boundary
|
||||
|
@ -27,7 +26,7 @@ export default class ComparingTag extends TagsFilter {
|
|||
}
|
||||
|
||||
asHumanString() {
|
||||
return this._key + this._representation + this._boundary
|
||||
return this.asJson()
|
||||
}
|
||||
|
||||
asOverpass(): string[] {
|
||||
|
@ -55,7 +54,7 @@ export default class ComparingTag extends TagsFilter {
|
|||
return true
|
||||
}
|
||||
if (other instanceof ComparingTag) {
|
||||
if (other._key !== this._key) {
|
||||
if (other.key !== this.key) {
|
||||
return false
|
||||
}
|
||||
const selfDesc = this._representation === "<" || this._representation === "<="
|
||||
|
@ -76,7 +75,7 @@ export default class ComparingTag extends TagsFilter {
|
|||
}
|
||||
|
||||
if (other instanceof Tag) {
|
||||
if (other.key !== this._key) {
|
||||
if (other.key !== this.key) {
|
||||
return false
|
||||
}
|
||||
if (this.matchesProperties({ [other.key]: other.value })) {
|
||||
|
@ -101,19 +100,25 @@ export default class ComparingTag extends TagsFilter {
|
|||
* t.matchesProperties({differentKey: 42}) // => false
|
||||
*/
|
||||
matchesProperties(properties: Record<string, string>): boolean {
|
||||
return this._predicate(properties[this._key])
|
||||
return this._predicate(properties[this.key])
|
||||
}
|
||||
|
||||
usedKeys(): string[] {
|
||||
return [this._key]
|
||||
return [this.key]
|
||||
}
|
||||
|
||||
usedTags(): { key: string; value: string }[] {
|
||||
return []
|
||||
}
|
||||
|
||||
asJson(): TagConfigJson {
|
||||
return this._key + this._representation
|
||||
/**
|
||||
* import { TagUtils } from "../../../src/Logic/Tags/TagUtils"
|
||||
*
|
||||
* TagUtils.Tag("count>42").asJson() // => "count>42"
|
||||
* TagUtils.Tag("count<0").asJson() // => "count<0"
|
||||
*/
|
||||
asJson(): string {
|
||||
return this.key + this._representation + this._boundary
|
||||
}
|
||||
|
||||
optimize(): TagsFilter | boolean {
|
||||
|
@ -124,11 +129,11 @@ export default class ComparingTag extends TagsFilter {
|
|||
return true
|
||||
}
|
||||
|
||||
visit(f: (TagsFilter) => void) {
|
||||
visit(f: (tf: TagsFilter) => void) {
|
||||
f(this)
|
||||
}
|
||||
|
||||
asMapboxExpression(): ExpressionSpecification {
|
||||
return [this._representation, ["get", this._key], this._boundary]
|
||||
return [this._representation, ["get", this.key], this._boundary]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -259,6 +259,13 @@ export class RegexTag extends TagsFilter {
|
|||
* new RegexTag("key",/^..*$/, true).shadows(new Tag("key","")) // => true
|
||||
* new RegexTag("key","value", true).shadows(new Tag("key","value")) // => false
|
||||
* new RegexTag("key","value", true).shadows(new Tag("key","some_other_value")) // => false
|
||||
* new RegexTag("key","value", true).shadows(new Tag("key","some_other_value", true)) // => false
|
||||
*
|
||||
* const route = TagUtils.Tag("climbing!~route")
|
||||
* const routeBottom = TagUtils.Tag("climbing!~route_bottom")
|
||||
* route.shadows(routeBottom) // => false
|
||||
* routeBottom.shadows(route) // => false
|
||||
*
|
||||
*/
|
||||
shadows(other: TagsFilter): boolean {
|
||||
if (other instanceof RegexTag) {
|
||||
|
@ -267,7 +274,7 @@ export class RegexTag extends TagsFilter {
|
|||
return false
|
||||
}
|
||||
if (
|
||||
(other.value["source"] ?? other.key) === (this.value["source"] ?? this.key) &&
|
||||
(other.value["source"] ?? other.value) === (this.value["source"] ?? this.value) &&
|
||||
this.invert == other.invert
|
||||
) {
|
||||
// Values (and inverts) match
|
||||
|
|
|
@ -2,6 +2,7 @@ import { Utils } from "../../Utils"
|
|||
import { TagsFilter } from "./TagsFilter"
|
||||
import { TagConfigJson } from "../../Models/ThemeConfig/Json/TagConfigJson"
|
||||
import { ExpressionSpecification } from "maplibre-gl"
|
||||
import { RegexTag } from "./RegexTag"
|
||||
|
||||
export class Tag extends TagsFilter {
|
||||
public key: string
|
||||
|
@ -122,6 +123,7 @@ export class Tag extends TagsFilter {
|
|||
/**
|
||||
*
|
||||
* import {RegexTag} from "./RegexTag";
|
||||
* import {And} from "./And";
|
||||
*
|
||||
* // should handle advanced regexes
|
||||
* new Tag("key", "aaa").shadows(new RegexTag("key", /a+/)) // => true
|
||||
|
@ -131,14 +133,20 @@ export class Tag extends TagsFilter {
|
|||
* new Tag("key","value").shadows(new RegexTag("key", "value", true)) // => false
|
||||
* new Tag("key","value").shadows(new RegexTag("otherkey", "value", true)) // => false
|
||||
* new Tag("key","value").shadows(new RegexTag("otherkey", "value", false)) // => false
|
||||
* new Tag("key","value").shadows(new And([new Tag("x","y"), new RegexTag("a","b", true)]) // => false
|
||||
*/
|
||||
shadows(other: TagsFilter): boolean {
|
||||
if (other["key"] !== undefined) {
|
||||
if (other["key"] !== this.key) {
|
||||
return false
|
||||
}
|
||||
if ((other["key"] !== this.key)) {
|
||||
return false
|
||||
}
|
||||
return other.matchesProperties({ [this.key]: this.value })
|
||||
if(other instanceof Tag){
|
||||
// Other.key === this.key
|
||||
return other.value === this.value
|
||||
}
|
||||
if(other instanceof RegexTag){
|
||||
return other.matchesProperties({[this.key]: this.value})
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
usedKeys(): string[] {
|
||||
|
|
|
@ -27,23 +27,23 @@ export default class LinkedDataLoader {
|
|||
opening_hours: { "@id": "http://schema.org/openingHoursSpecification" },
|
||||
openingHours: { "@id": "http://schema.org/openingHours", "@container": "@set" },
|
||||
geo: { "@id": "http://schema.org/geo" },
|
||||
alt_name: { "@id": "http://schema.org/alternateName" },
|
||||
alt_name: { "@id": "http://schema.org/alternateName" }
|
||||
}
|
||||
private static COMPACTING_CONTEXT_OH = {
|
||||
dayOfWeek: { "@id": "http://schema.org/dayOfWeek", "@container": "@set" },
|
||||
closes: {
|
||||
"@id": "http://schema.org/closes",
|
||||
"@type": "http://www.w3.org/2001/XMLSchema#time",
|
||||
"@type": "http://www.w3.org/2001/XMLSchema#time"
|
||||
},
|
||||
opens: {
|
||||
"@id": "http://schema.org/opens",
|
||||
"@type": "http://www.w3.org/2001/XMLSchema#time",
|
||||
},
|
||||
"@type": "http://www.w3.org/2001/XMLSchema#time"
|
||||
}
|
||||
}
|
||||
private static formatters: Record<"phone" | "email" | "website", Validator> = {
|
||||
phone: new PhoneValidator(),
|
||||
email: new EmailValidator(),
|
||||
website: new UrlValidator(undefined, undefined, true),
|
||||
website: new UrlValidator(undefined, undefined, true)
|
||||
}
|
||||
private static ignoreKeys = [
|
||||
"http://schema.org/logo",
|
||||
|
@ -56,7 +56,7 @@ export default class LinkedDataLoader {
|
|||
"http://schema.org/description",
|
||||
"http://schema.org/hasMap",
|
||||
"http://schema.org/priceRange",
|
||||
"http://schema.org/contactPoint",
|
||||
"http://schema.org/contactPoint"
|
||||
]
|
||||
|
||||
private static shapeToPolygon(str: string): Polygon {
|
||||
|
@ -69,8 +69,8 @@ export default class LinkedDataLoader {
|
|||
.trim()
|
||||
.split(" ")
|
||||
.map((n) => Number(n))
|
||||
),
|
||||
],
|
||||
)
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -92,18 +92,18 @@ export default class LinkedDataLoader {
|
|||
const context = {
|
||||
lat: {
|
||||
"@id": "http://schema.org/latitude",
|
||||
"@type": "http://www.w3.org/2001/XMLSchema#double",
|
||||
"@type": "http://www.w3.org/2001/XMLSchema#double"
|
||||
},
|
||||
lon: {
|
||||
"@id": "http://schema.org/longitude",
|
||||
"@type": "http://www.w3.org/2001/XMLSchema#double",
|
||||
},
|
||||
"@type": "http://www.w3.org/2001/XMLSchema#double"
|
||||
}
|
||||
}
|
||||
const flattened = await jsonld.compact(geo, context)
|
||||
|
||||
return {
|
||||
type: "Point",
|
||||
coordinates: [Number(flattened.lon), Number(flattened.lat)],
|
||||
coordinates: [Number(flattened.lon), Number(flattened.lat)]
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -194,7 +194,7 @@ export default class LinkedDataLoader {
|
|||
)
|
||||
delete compacted["openingHours"]
|
||||
}
|
||||
if(compacted["opening_hours"] === undefined){
|
||||
if (compacted["opening_hours"] === undefined) {
|
||||
delete compacted["opening_hours"]
|
||||
}
|
||||
if (compacted["geo"]) {
|
||||
|
@ -288,7 +288,7 @@ export default class LinkedDataLoader {
|
|||
if (properties["latitude"] && properties["longitude"]) {
|
||||
geometry = {
|
||||
type: "Point",
|
||||
coordinates: [Number(properties["longitude"]), Number(properties["latitude"])],
|
||||
coordinates: [Number(properties["longitude"]), Number(properties["latitude"])]
|
||||
}
|
||||
delete properties["latitude"]
|
||||
delete properties["longitude"]
|
||||
|
@ -300,7 +300,7 @@ export default class LinkedDataLoader {
|
|||
const geo: GeoJSON = {
|
||||
type: "Feature",
|
||||
properties,
|
||||
geometry,
|
||||
geometry
|
||||
}
|
||||
delete linkedData.geo
|
||||
delete properties.shape
|
||||
|
@ -331,7 +331,7 @@ export default class LinkedDataLoader {
|
|||
return
|
||||
}
|
||||
output[key] = output[key].map((v) => applyF(v))
|
||||
if(!output[key].some(v => v !== undefined)){
|
||||
if (!output[key].some(v => v !== undefined)) {
|
||||
delete output[key]
|
||||
}
|
||||
}
|
||||
|
@ -416,7 +416,7 @@ export default class LinkedDataLoader {
|
|||
"brede publiek",
|
||||
"iedereen",
|
||||
"bezoekers",
|
||||
"iedereen - vooral bezoekers gemeentehuis of bibliotheek.",
|
||||
"iedereen - vooral bezoekers gemeentehuis of bibliotheek."
|
||||
].indexOf(audience.toLowerCase()) >= 0
|
||||
) {
|
||||
return "yes"
|
||||
|
@ -483,7 +483,6 @@ export default class LinkedDataLoader {
|
|||
}
|
||||
rename("capacityElectric", "capacity:electric_bicycle")
|
||||
|
||||
delete output["name"]
|
||||
delete output["numberOfLevels"]
|
||||
|
||||
return output
|
||||
|
@ -500,13 +499,14 @@ export default class LinkedDataLoader {
|
|||
mv: "http://schema.mobivoc.org/",
|
||||
gr: "http://purl.org/goodrelations/v1#",
|
||||
vp: "https://data.velopark.be/openvelopark/vocabulary#",
|
||||
vpt: "https://data.velopark.be/openvelopark/terms#",
|
||||
vpt: "https://data.velopark.be/openvelopark/terms#"
|
||||
},
|
||||
[url],
|
||||
undefined,
|
||||
" ?parking a <http://schema.mobivoc.org/BicycleParkingStation>",
|
||||
"?parking " + property + " " + (variable ?? "")
|
||||
)
|
||||
console.log("Fetching a velopark property gave", property, results)
|
||||
return results
|
||||
}
|
||||
|
||||
|
@ -521,7 +521,7 @@ export default class LinkedDataLoader {
|
|||
mv: "http://schema.mobivoc.org/",
|
||||
gr: "http://purl.org/goodrelations/v1#",
|
||||
vp: "https://data.velopark.be/openvelopark/vocabulary#",
|
||||
vpt: "https://data.velopark.be/openvelopark/terms#",
|
||||
vpt: "https://data.velopark.be/openvelopark/terms#"
|
||||
},
|
||||
[url],
|
||||
"g",
|
||||
|
@ -643,36 +643,41 @@ export default class LinkedDataLoader {
|
|||
allPartialResults.push(r)
|
||||
}
|
||||
|
||||
const results = this.mergeResults(...allPartialResults)
|
||||
|
||||
return results
|
||||
return this.mergeResults(...allPartialResults)
|
||||
}
|
||||
|
||||
private static veloparkCache : Record<string, Feature[]> = {}
|
||||
private static veloparkCache: Record<string, Feature[]> = {}
|
||||
|
||||
/**
|
||||
* Fetches all data relevant to velopark.
|
||||
* The id will be saved as `ref:velopark`
|
||||
* @param url
|
||||
*/
|
||||
public static async fetchVeloparkEntry(url: string): Promise<Feature[]> {
|
||||
if(this.veloparkCache[url]){
|
||||
return this.veloparkCache[url]
|
||||
public static async fetchVeloparkEntry(url: string, includeExtras: boolean = false): Promise<Feature[]> {
|
||||
const cacheKey = includeExtras + url
|
||||
if (this.veloparkCache[cacheKey]) {
|
||||
return this.veloparkCache[cacheKey]
|
||||
}
|
||||
const withProxyUrl = Constants.linkedDataProxy.replace("{url}", encodeURIComponent(url))
|
||||
const optionalPaths: Record<string, string | Record<string, string>> = {
|
||||
"schema:interactionService": {
|
||||
"schema:url": "website",
|
||||
"schema:url": "website"
|
||||
},
|
||||
"schema:name": "name",
|
||||
"mv:operatedBy": {
|
||||
"gr:legalName": "operator",
|
||||
"gr:legalName": "operator"
|
||||
},
|
||||
"schema:contactPoint": {
|
||||
"schema:email": "email",
|
||||
"schema:telephone": "phone",
|
||||
"schema:telephone": "phone"
|
||||
},
|
||||
"schema:dateModified": "_last_edit_timestamp",
|
||||
"schema:dateModified": "_last_edit_timestamp"
|
||||
}
|
||||
if (includeExtras) {
|
||||
optionalPaths["schema:address"] = {
|
||||
"schema:streetAddress": "addr"
|
||||
}
|
||||
optionalPaths["schema:name"] = "name"
|
||||
optionalPaths["schema:description"] = "description"
|
||||
}
|
||||
|
||||
const graphOptionalPaths = {
|
||||
|
@ -687,19 +692,19 @@ export default class LinkedDataLoader {
|
|||
"schema:geo": {
|
||||
"schema:latitude": "latitude",
|
||||
"schema:longitude": "longitude",
|
||||
"schema:polygon": "shape",
|
||||
"schema:polygon": "shape"
|
||||
},
|
||||
"schema:priceSpecification": {
|
||||
"mv:freeOfCharge": "fee",
|
||||
"schema:price": "charge",
|
||||
},
|
||||
"schema:price": "charge"
|
||||
}
|
||||
}
|
||||
|
||||
const extra = [
|
||||
"schema:priceSpecification [ mv:dueForTime [ mv:timeStartValue ?chargeStart; mv:timeEndValue ?chargeEnd; mv:timeUnit ?timeUnit ] ]",
|
||||
"vp:allows [vp:bicycleType <https://data.velopark.be/openvelopark/terms#CargoBicycle>; vp:bicyclesAmount ?capacityCargobike; vp:bicycleType ?cargoBikeType]",
|
||||
"vp:allows [vp:bicycleType <https://data.velopark.be/openvelopark/terms#ElectricBicycle>; vp:bicyclesAmount ?capacityElectric; vp:bicycleType ?electricBikeType]",
|
||||
"vp:allows [vp:bicycleType <https://data.velopark.be/openvelopark/terms#TandemBicycle>; vp:bicyclesAmount ?capacityTandem; vp:bicycleType ?tandemBikeType]",
|
||||
"vp:allows [vp:bicycleType <https://data.velopark.be/openvelopark/terms#TandemBicycle>; vp:bicyclesAmount ?capacityTandem; vp:bicycleType ?tandemBikeType]"
|
||||
]
|
||||
|
||||
const unpatched = await this.fetchEntry(
|
||||
|
@ -714,7 +719,7 @@ export default class LinkedDataLoader {
|
|||
p["ref:velopark"] = [section]
|
||||
patched.push(LinkedDataLoader.asGeojson(p))
|
||||
}
|
||||
this.veloparkCache[url] = patched
|
||||
this.veloparkCache[cacheKey] = patched
|
||||
return patched
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@ import type { Feature, FeatureCollection, MultiPolygon } from "geojson"
|
|||
import * as turf from "@turf/turf"
|
||||
import { Utils } from "../../Utils"
|
||||
import TagInfo from "./TagInfo"
|
||||
import type { Feature, MultiPolygon } from "geojson"
|
||||
import * as turf from "@turf/turf"
|
||||
|
||||
/**
|
||||
* Main name suggestion index file
|
||||
|
@ -140,6 +142,7 @@ export default class NameSuggestionIndex {
|
|||
return true
|
||||
}
|
||||
const resolvedSet = NameSuggestionIndex.loco.resolveLocationSet(i.locationSet)
|
||||
|
||||
if (resolvedSet) {
|
||||
// We actually have a location set, so we can check if the feature is in it, by determining if our point is inside the MultiPolygon using @turf/boolean-point-in-polygon
|
||||
// This might occur for some extra boundaries, such as counties, ...
|
||||
|
|
|
@ -167,7 +167,7 @@ export class Denomination {
|
|||
* Returns null if it doesn't match this unit
|
||||
*/
|
||||
public StrippedValue(value: string, actAsDefault: boolean, inverted: boolean): string {
|
||||
if (value === undefined) {
|
||||
if (value === undefined || value === "") {
|
||||
return undefined
|
||||
}
|
||||
|
||||
|
@ -186,7 +186,7 @@ export class Denomination {
|
|||
if (self.prefix) {
|
||||
return value.substring(key.length).trim()
|
||||
}
|
||||
let trimmed = value.substring(0, value.length - key.length).trim()
|
||||
let trimmed = value.substring(0, value.length - key.length).trim()
|
||||
if(!inverted){
|
||||
return trimmed
|
||||
}
|
||||
|
|
|
@ -100,6 +100,11 @@ export class MenuState {
|
|||
})
|
||||
|
||||
this.allToggles = [
|
||||
{
|
||||
toggle: this.privacyPanelIsOpened,
|
||||
name: "privacy",
|
||||
showOverOthers: true,
|
||||
},
|
||||
{
|
||||
toggle: this.menuIsOpened,
|
||||
name: "menu",
|
||||
|
@ -120,11 +125,6 @@ export class MenuState {
|
|||
name: "community",
|
||||
showOverOthers: true,
|
||||
},
|
||||
{
|
||||
toggle: this.privacyPanelIsOpened,
|
||||
name: "privacy",
|
||||
showOverOthers: true,
|
||||
},
|
||||
{
|
||||
toggle: this.filtersPanelIsOpened,
|
||||
name: "filters",
|
||||
|
|
|
@ -258,11 +258,11 @@ export class ExpandRewrite<T> extends Conversion<T | RewritableConfigJson<T>, T[
|
|||
}
|
||||
}
|
||||
|
||||
let renderings = Array.isArray(rewrite.renderings)
|
||||
const renderings = Array.isArray(rewrite.renderings)
|
||||
? rewrite.renderings
|
||||
: [rewrite.renderings]
|
||||
for (let i = 0; i < keysToRewrite.into.length; i++) {
|
||||
let ts: T[] = <T[]>Utils.Clone(renderings)
|
||||
const ts: T[] = <T[]>Utils.Clone(renderings)
|
||||
for (const tx of ts) {
|
||||
let t = <T>tx
|
||||
const sourceKeysToIgnore: string[] = []
|
||||
|
|
|
@ -161,7 +161,9 @@ class ExpandTagRendering extends Conversion<
|
|||
private readonly _options: {
|
||||
/* If true, will copy the 'osmSource'-tags into the condition */
|
||||
applyCondition?: true | boolean
|
||||
noHardcodedStrings?: false | boolean
|
||||
noHardcodedStrings?: false | boolean,
|
||||
addToContext?: false | boolean
|
||||
|
||||
}
|
||||
|
||||
constructor(
|
||||
|
@ -169,11 +171,13 @@ class ExpandTagRendering extends Conversion<
|
|||
self: LayerConfigJson,
|
||||
options?: {
|
||||
applyCondition?: true | boolean
|
||||
noHardcodedStrings?: false | boolean
|
||||
noHardcodedStrings?: false | boolean,
|
||||
// If set, a question will be added to the 'sharedTagRenderings'. Should only be used for 'questions.json'
|
||||
addToContext?: false | boolean
|
||||
}
|
||||
) {
|
||||
super(
|
||||
"Converts a tagRenderingSpec into the full tagRendering, e.g. by substituting the tagRendering by the shared-question",
|
||||
"Converts a tagRenderingSpec into the full tagRendering, e.g. by substituting the tagRendering by the shared-question and reusing the builtins",
|
||||
[],
|
||||
"ExpandTagRendering"
|
||||
)
|
||||
|
@ -204,8 +208,17 @@ class ExpandTagRendering extends Conversion<
|
|||
if (typeof tr === "string" || tr["builtin"] !== undefined) {
|
||||
const stable = this.convert(tr, ctx.inOperation("recursive_resolve"))
|
||||
result.push(...stable)
|
||||
if(this._options?.addToContext){
|
||||
for (const tr of stable) {
|
||||
this._state.tagRenderings?.set(tr.id, tr)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
result.push(tr)
|
||||
if(this._options?.addToContext){
|
||||
this._state.tagRenderings?.set(tr["id"], <QuestionableTagRenderingConfigJson> tr)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -220,7 +233,7 @@ class ExpandTagRendering extends Conversion<
|
|||
}
|
||||
const result: TagRenderingConfigJson[] = []
|
||||
for (const tagRenderingConfigJson of direct) {
|
||||
let nm: string | string[] | undefined = tagRenderingConfigJson["builtin"]
|
||||
const nm: string | string[] | undefined = tagRenderingConfigJson["builtin"]
|
||||
if (nm !== undefined) {
|
||||
let indirect: TagRenderingConfigJson[]
|
||||
if (typeof nm === "string") {
|
||||
|
@ -1261,12 +1274,14 @@ export class AutoTitleIcon extends DesugaringStep<LayerConfigJson> {
|
|||
}
|
||||
|
||||
export class PrepareLayer extends Fuse<LayerConfigJson> {
|
||||
constructor(state: DesugaringContext) {
|
||||
constructor(state: DesugaringContext, options?: {addTagRenderingsToContext?: false | boolean}) {
|
||||
super(
|
||||
"Fully prepares and expands a layer for the LayerConfig.",
|
||||
new On("tagRenderings", new Each(new RewriteSpecial())),
|
||||
new On("tagRenderings", new Concat(new ExpandRewrite()).andThenF(Utils.Flatten)),
|
||||
new On("tagRenderings", (layer) => new Concat(new ExpandTagRendering(state, layer))),
|
||||
new On("tagRenderings", (layer) => new Concat(new ExpandTagRendering(state, layer, {
|
||||
addToContext: options?.addTagRenderingsToContext ?? false
|
||||
}))),
|
||||
new On("tagRenderings", new Each(new DetectInline())),
|
||||
new AddQuestionBox(),
|
||||
new AddEditingElements(state),
|
||||
|
|
|
@ -562,6 +562,65 @@ export class DetectNonErasedKeysInMappings extends DesugaringStep<QuestionableTa
|
|||
}
|
||||
}
|
||||
|
||||
export class DetectMappingsShadowedByCondition extends DesugaringStep<TagRenderingConfigJson> {
|
||||
private readonly _forceError: boolean
|
||||
|
||||
constructor(forceError: boolean = false) {
|
||||
super("Checks that, if the tagrendering has a condition, that a mapping is not contradictory to it, i.e. that there are no dead mappings", [], "DetectMappingsShadowedByCondition")
|
||||
this._forceError = forceError
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* const validator = new DetectMappingsShadowedByCondition(true)
|
||||
* const ctx = ConversionContext.construct([],["test"])
|
||||
* validator.convert({
|
||||
* condition: "count>0",
|
||||
* mappings:[
|
||||
* {
|
||||
* if: "count=0",
|
||||
* then:{
|
||||
* en: "No count"
|
||||
* }
|
||||
* }
|
||||
* ]
|
||||
* }, ctx)
|
||||
* ctx.hasErrors() // => true
|
||||
*/
|
||||
convert(json: TagRenderingConfigJson, context: ConversionContext): TagRenderingConfigJson {
|
||||
if(!json.condition && !json.metacondition){
|
||||
return json
|
||||
}
|
||||
if(!json.mappings || json.mappings?.length ==0){
|
||||
return json
|
||||
}
|
||||
let conditionJson = json.condition ?? json.metacondition
|
||||
if(json.condition !== undefined && json.metacondition !== undefined){
|
||||
conditionJson = {and: [json.condition, json.metacondition]}
|
||||
}
|
||||
const condition = TagUtils.Tag(conditionJson, context.path.join("."))
|
||||
|
||||
for (let i = 0; i < json.mappings.length; i++){
|
||||
const mapping = json.mappings[i]
|
||||
const tagIf = TagUtils.Tag(mapping.if, context.path.join("."))
|
||||
const optimized = new And([tagIf, condition]).optimize()
|
||||
if(optimized === false){
|
||||
const msg = ("Detected a conflicting mapping and condition. The mapping requires tags " + tagIf.asHumanString() + ", yet this can never happen because the set condition requires " + condition.asHumanString())
|
||||
const ctx = context.enters("mappings", i)
|
||||
if (this._forceError) {
|
||||
ctx.err(msg)
|
||||
} else {
|
||||
ctx.warn(msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return undefined
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class DetectShadowedMappings extends DesugaringStep<TagRenderingConfigJson> {
|
||||
private readonly _calculatedTagNames: string[]
|
||||
|
||||
|
@ -1088,6 +1147,8 @@ export class ValidateTagRenderings extends Fuse<TagRenderingConfigJson> {
|
|||
"Various validation on tagRenderingConfigs",
|
||||
new MiscTagRenderingChecks(),
|
||||
new DetectShadowedMappings(layerConfig),
|
||||
|
||||
new DetectMappingsShadowedByCondition(),
|
||||
new DetectConflictingAddExtraTags(),
|
||||
// TODO enable new DetectNonErasedKeysInMappings(),
|
||||
new DetectMappingsWithImages(doesImageExist),
|
||||
|
|
|
@ -554,4 +554,15 @@ export interface LayerConfigJson {
|
|||
* group: hidden
|
||||
*/
|
||||
fullNodeDatabase?: boolean
|
||||
|
||||
/**
|
||||
* question: Should a theme using this layer leak some location info when making changes?
|
||||
*
|
||||
* When a changeset is made, a 'distance to object'-class is written to the changeset.
|
||||
* For some particular themes and layers, this might leak too much information, and we want to obfuscate this
|
||||
*
|
||||
* ifunset: Write 'change_within_x_m' as usual and if GPS is enabled
|
||||
* iftrue: Do not write 'change_within_x_m' and do not indicate that this was done by survey
|
||||
*/
|
||||
enableMorePrivacy?: boolean
|
||||
}
|
||||
|
|
|
@ -439,4 +439,16 @@ export interface LayoutConfigJson {
|
|||
* group: hidden
|
||||
*/
|
||||
enableNodeDatabase?: boolean
|
||||
|
||||
/**
|
||||
* question: Should this theme leak some location info when making changes?
|
||||
*
|
||||
* When a changeset is made, a 'distance to object'-class is written to the changeset.
|
||||
* For some particular themes and layers, this might leak too much information, and we want to obfuscate this
|
||||
*
|
||||
* ifunset: Write 'change_within_x_m' as usual and if GPS is enabled
|
||||
* iftrue: Do not write 'change_within_x_m' and do not indicate that this was done by survey
|
||||
*/
|
||||
enableMorePrivacy: boolean
|
||||
|
||||
}
|
||||
|
|
|
@ -229,6 +229,7 @@ export interface QuestionableTagRenderingConfigJson extends TagRenderingConfigJs
|
|||
* A (translated) text that is shown (as gray text) within the textfield
|
||||
* type: translation
|
||||
* group: expert
|
||||
* ifunset: No specific placeholder is set, show the type of the textfield
|
||||
*/
|
||||
placeholder?: Translatable
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@ export interface TagRenderingConfigJson {
|
|||
*
|
||||
* question: When should this item be shown?
|
||||
* type: tag
|
||||
* ifunset: No specific condition set; always show this tagRendering or ask the question if unkown
|
||||
* ifunset: No specific condition set; always show this tagRendering or show this question if unknown
|
||||
*
|
||||
* Only show this tagrendering (or ask the question) if the selected object also matches the tags specified as `condition`.
|
||||
*
|
||||
|
@ -132,9 +132,10 @@ export interface TagRenderingConfigJson {
|
|||
|
||||
/** question: When should this item be shown (including special conditions)?
|
||||
* type: tag
|
||||
* ifunset: No specific metacondition set which is evaluated against the <i>usersettings/application state</i>; always show this tagRendering or show this question if unknown
|
||||
*
|
||||
* If set, this tag will be evaluated agains the _usersettings/application state_ table.
|
||||
* Enable 'show debug info' in user settings to see available options.
|
||||
* If set, this tag will be evaluated against the _usersettings/application state_ table.
|
||||
* Enable 'show debug info' in user settings to see available options (at the settings-tab).
|
||||
* Note that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_
|
||||
*/
|
||||
metacondition?: TagConfigJson
|
||||
|
|
|
@ -67,6 +67,7 @@ export default class LayerConfig extends WithContextLoader {
|
|||
|
||||
public readonly _needsFullNodeDatabase: boolean
|
||||
public readonly popupInFloatover: boolean | string
|
||||
public readonly enableMorePrivacy: boolean
|
||||
|
||||
constructor(json: LayerConfigJson, context?: string, official: boolean = true) {
|
||||
context = context + "." + json.id
|
||||
|
@ -149,6 +150,7 @@ export default class LayerConfig extends WithContextLoader {
|
|||
this.shownByDefault = json.shownByDefault ?? true
|
||||
this.doCount = json.isCounted ?? this.shownByDefault ?? true
|
||||
this.forceLoad = json.forceLoad ?? false
|
||||
this.enableMorePrivacy = json.enableMorePrivacy ?? false
|
||||
if (json.presets === null) json.presets = undefined
|
||||
if (json.presets !== undefined && json.presets?.map === undefined) {
|
||||
throw "Presets should be a list of items (at " + context + ")"
|
||||
|
|
|
@ -63,6 +63,8 @@ export default class LayoutConfig implements LayoutInformation {
|
|||
public readonly enableExportButton: boolean
|
||||
public readonly enablePdfDownload: boolean
|
||||
public readonly enableTerrain: boolean
|
||||
public readonly enableMorePrivacy: boolean
|
||||
|
||||
|
||||
public readonly customCss?: string
|
||||
|
||||
|
@ -204,6 +206,7 @@ export default class LayoutConfig implements LayoutInformation {
|
|||
this.overpassTimeout = json.overpassTimeout ?? 30
|
||||
this.overpassMaxZoom = json.overpassMaxZoom ?? 16
|
||||
this.osmApiTileSize = json.osmApiTileSize ?? this.overpassMaxZoom + 1
|
||||
this.enableMorePrivacy = json.enableMorePrivacy || json.layers.some(l => (<LayerConfigJson> l).enableMorePrivacy)
|
||||
|
||||
this.layersDict = new Map<string, LayerConfig>()
|
||||
for (const layer of this.layers) {
|
||||
|
|
|
@ -69,6 +69,7 @@ import {
|
|||
import summaryLayer from "../assets/generated/layers/summary.json"
|
||||
import { LayerConfigJson } from "./ThemeConfig/Json/LayerConfigJson"
|
||||
import Locale from "../UI/i18n/Locale"
|
||||
import Hash from "../Logic/Web/Hash"
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -265,6 +266,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
|
|||
featurePropertiesStore: this.featureProperties,
|
||||
osmConnection: this.osmConnection,
|
||||
historicalUserLocations: this.geolocation.historicalUserLocations,
|
||||
featureSwitches: this.featureSwitches
|
||||
},
|
||||
layout?.isLeftRightSensitive() ?? false
|
||||
)
|
||||
|
@ -495,6 +497,12 @@ export default class ThemeViewState implements SpecialVisualizationState {
|
|||
if (this.layout.customCss !== undefined && window.location.pathname.indexOf("theme") >= 0) {
|
||||
Utils.LoadCustomCss(this.layout.customCss)
|
||||
}
|
||||
|
||||
Hash.hash.addCallbackAndRunD(hash => {
|
||||
if(hash === "current_view" || hash.match(/current_view_[0-9]+/)){
|
||||
this.selectCurrentView()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -820,4 +828,9 @@ export default class ThemeViewState implements SpecialVisualizationState {
|
|||
this.userRelatedState.preferredBackgroundLayer
|
||||
)
|
||||
}
|
||||
|
||||
public selectCurrentView(){
|
||||
this.guistate.closeAll()
|
||||
this.selectedElement.setData(this.currentView.features?.data?.[0])
|
||||
}
|
||||
}
|
||||
|
|
|
@ -100,7 +100,7 @@
|
|||
<input
|
||||
autofocus
|
||||
bind:value={$themeSearchText}
|
||||
class="mr-4 w-full"
|
||||
class="mr-4 w-full outline-none"
|
||||
id="theme-search"
|
||||
type="search"
|
||||
use:placeholder={tr.searchForATheme}
|
||||
|
|
49
src/UI/Base/CloseAnimation.svelte
Normal file
49
src/UI/Base/CloseAnimation.svelte
Normal file
|
@ -0,0 +1,49 @@
|
|||
<script lang="ts">
|
||||
import { Store } from "../../Logic/UIEventSource"
|
||||
import { onDestroy, onMount } from "svelte"
|
||||
|
||||
let elem: HTMLElement
|
||||
let targetOuter: HTMLElement
|
||||
export let isOpened: Store<boolean>
|
||||
export let moveTo: Store<HTMLElement>
|
||||
|
||||
export let debug : string
|
||||
function copySizeOf(htmlElem: HTMLElement) {
|
||||
const target = htmlElem.getBoundingClientRect()
|
||||
elem.style.left = target.x + "px"
|
||||
elem.style.top = target.y + "px"
|
||||
elem.style.width = target.width + "px"
|
||||
elem.style.height = target.height + "px"
|
||||
}
|
||||
|
||||
function animate(opened: boolean) {
|
||||
const moveToElem = moveTo.data
|
||||
console.log("Animating", debug," to", opened)
|
||||
if (opened) {
|
||||
copySizeOf(targetOuter)
|
||||
elem.style.background = "var(--background-color)"
|
||||
} else if (moveToElem !== undefined) {
|
||||
copySizeOf(moveToElem)
|
||||
elem.style.background = "#ffffff00"
|
||||
} else {
|
||||
elem.style.left = "0px"
|
||||
elem.style.top = "0px"
|
||||
elem.style.background = "#ffffff00"
|
||||
}
|
||||
}
|
||||
|
||||
onDestroy(isOpened.addCallback(opened => animate(opened)))
|
||||
onMount(() => requestAnimationFrame(() => animate(isOpened.data)))
|
||||
|
||||
|
||||
</script>
|
||||
<div class={"absolute bottom-0 right-0 h-full w-screen p-4 md:p-6 pointer-events-none invisible"}>
|
||||
<div class="content h-full" bind:this={targetOuter} style="background: red" />
|
||||
</div>
|
||||
|
||||
<div bind:this={elem} class="pointer-events-none absolute bottom-0 right-0 low-interaction rounded-2xl"
|
||||
style="transition: all 0.5s ease-out, background-color 1.4s ease-out; background: var(--background-color);">
|
||||
<!-- Classes should be the same as the 'floatoaver' -->
|
||||
</div>
|
||||
|
||||
|
|
@ -11,7 +11,6 @@
|
|||
*/
|
||||
const dispatch = createEventDispatcher<{ close }>()
|
||||
|
||||
export let extraClasses = "p-4 md:p-6"
|
||||
</script>
|
||||
|
||||
<!-- Draw the background over the total screen -->
|
||||
|
@ -24,7 +23,7 @@
|
|||
/>
|
||||
<!-- draw a _second_ absolute div, placed using 'bottom' which will be above the navigation bar on mobile browsers -->
|
||||
<div
|
||||
class={twMerge("absolute bottom-0 right-0 h-full w-screen", extraClasses)}
|
||||
class={"absolute bottom-0 right-0 h-full w-screen p-4 md:p-6"}
|
||||
style="z-index: 21"
|
||||
use:trapFocus
|
||||
>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
import { twJoin } from "tailwind-merge"
|
||||
import { Translation } from "../i18n/Translation"
|
||||
import { ariaLabel } from "../../Utils/ariaLabel"
|
||||
import { ImmutableStore, Store } from "../../Logic/UIEventSource"
|
||||
import { ImmutableStore, Store, UIEventSource } from "../../Logic/UIEventSource"
|
||||
|
||||
/**
|
||||
* A round button with an icon and possible a small text, which hovers above the map
|
||||
|
@ -12,9 +12,15 @@
|
|||
export let cls = "m-0.5 p-0.5 sm:p-1 md:m-1"
|
||||
export let enabled: Store<boolean> = new ImmutableStore(true)
|
||||
export let arialabel: Translation = undefined
|
||||
export let htmlElem: UIEventSource<HTMLElement> = undefined
|
||||
let _htmlElem : HTMLElement
|
||||
$: {
|
||||
htmlElem?.setData(_htmlElem)
|
||||
}
|
||||
</script>
|
||||
|
||||
<button
|
||||
bind:this={_htmlElem}
|
||||
on:click={(e) => dispatch("click", e)}
|
||||
on:keydown
|
||||
use:ariaLabel={arialabel}
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
import Combine from "./Combine"
|
||||
import BaseUIElement from "../BaseUIElement"
|
||||
import Title from "./Title"
|
||||
import List from "./List"
|
||||
import Link from "./Link"
|
||||
import { marked } from "marked"
|
||||
import { parse as parse_html } from "node-html-parser"
|
||||
import {default as turndown} from "turndown"
|
||||
import { default as turndown } from "turndown"
|
||||
import { Utils } from "../../Utils"
|
||||
|
||||
export default class TableOfContents {
|
||||
|
@ -56,7 +53,7 @@ export default class TableOfContents {
|
|||
const htmlSource = <string>marked.parse(md)
|
||||
const el = parse_html(htmlSource)
|
||||
const structure = TableOfContents.generateStructure(<any>el)
|
||||
let firstTitle = structure[1]
|
||||
const firstTitle = structure[1]
|
||||
let minDepth = undefined
|
||||
do {
|
||||
minDepth = Math.min(...structure.map(s => s.depth))
|
||||
|
@ -81,7 +78,7 @@ export default class TableOfContents {
|
|||
let topLevelCount = 0
|
||||
for (const el of structure) {
|
||||
const depthDiff = el.depth - minDepth
|
||||
let link = `[${el.title}](#${TableOfContents.asLinkableId(el.title)})`
|
||||
const link = `[${el.title}](#${TableOfContents.asLinkableId(el.title)})`
|
||||
if (depthDiff === 0) {
|
||||
topLevelCount++
|
||||
toc += `${topLevelCount}. ${link}\n`
|
||||
|
@ -91,16 +88,14 @@ export default class TableOfContents {
|
|||
}
|
||||
|
||||
const heading = Utils.Times(() => "#", firstTitle.depth)
|
||||
toc = heading +" Table of contents\n\n"+toc
|
||||
toc = heading + " Table of contents\n\n" + toc
|
||||
|
||||
const original = el.outerHTML
|
||||
const firstTitleIndex = original.indexOf(firstTitle.el.outerHTML)
|
||||
const tocHtml = (<string>marked.parse(toc))
|
||||
const withToc = original.substring(0, firstTitleIndex) + tocHtml + original.substring(firstTitleIndex)
|
||||
const firstTitleIndex = md.indexOf(firstTitle.title)
|
||||
|
||||
const htmlToMd = new turndown()
|
||||
return htmlToMd.turndown(withToc)
|
||||
const intro = md.substring(0, firstTitleIndex)
|
||||
const splitPoint = intro.lastIndexOf("\n")
|
||||
|
||||
return md.substring(0, splitPoint) + toc + md.substring(splitPoint)
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
export let state: SpecialVisualizationState
|
||||
let theme = state.layout?.id ?? ""
|
||||
let config: ExtraLinkConfig = state.layout.extraLink
|
||||
console.log(">>>",config)
|
||||
const isIframe = window !== window.top
|
||||
let basepath = window.location.host
|
||||
let showWelcomeMessageSwitch = state.featureSwitches.featureSwitchWelcomeMessage
|
||||
|
|
|
@ -113,7 +113,7 @@
|
|||
{:else}
|
||||
<input
|
||||
type="search"
|
||||
class="w-full"
|
||||
class="w-full outline-none"
|
||||
bind:this={inputElement}
|
||||
on:keypress={(keypr) => {
|
||||
feedback = undefined
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
* Even though the component is very small, it gets its own class as it is often reused
|
||||
*/
|
||||
import { Square3Stack3dIcon } from "@babeard/svelte-heroicons/solid"
|
||||
import type { SpecialVisualizationState } from "../SpecialVisualization"
|
||||
import Translations from "../i18n/Translations"
|
||||
import MapControlButton from "../Base/MapControlButton.svelte"
|
||||
import Tr from "../Base/Tr.svelte"
|
||||
|
@ -16,11 +15,13 @@
|
|||
export let state: ThemeViewState
|
||||
export let map: Store<MlMap> = undefined
|
||||
export let hideTooltip = false
|
||||
export let htmlElem : UIEventSource<HTMLElement> = undefined
|
||||
</script>
|
||||
|
||||
<MapControlButton
|
||||
arialabel={Translations.t.general.labels.background}
|
||||
on:click={() => state.guistate.backgroundLayerSelectionIsOpened.setData(true)}
|
||||
{htmlElem}
|
||||
>
|
||||
<StyleLoadingIndicator map={map ?? state.map} rasterLayer={state.mapProperties.rasterLayer}>
|
||||
<Square3Stack3dIcon class="h-6 w-6" />
|
||||
|
|
|
@ -1,8 +1,15 @@
|
|||
<script lang="ts">
|
||||
import Tr from "../Base/Tr.svelte"
|
||||
import Translations from "../i18n/Translations"
|
||||
import TagRenderingEditable from "../Popup/TagRendering/TagRenderingEditable.svelte"
|
||||
import type { SpecialVisualizationState } from "../SpecialVisualization"
|
||||
import UserRelatedState from "../../Logic/State/UserRelatedState"
|
||||
|
||||
const t = Translations.t.privacy
|
||||
export let state: SpecialVisualizationState
|
||||
const usersettings = UserRelatedState.usersettingsConfig
|
||||
const editPrivacy = usersettings.tagRenderings.find(tr => tr.id === "more_privacy")
|
||||
const isLoggedIn = state.osmConnection.isLoggedIn
|
||||
</script>
|
||||
|
||||
<div class="link-underline flex flex-col">
|
||||
|
@ -20,7 +27,41 @@
|
|||
<h3>
|
||||
<Tr t={t.editingTitle} />
|
||||
</h3>
|
||||
<Tr t={t.editing} />
|
||||
<Tr t={t.editingIntro} />
|
||||
<Tr t={t.editingIntro} />
|
||||
<ul>
|
||||
<li>
|
||||
<Tr t={t.items.changesYouMake} />
|
||||
</li>
|
||||
<li>
|
||||
<Tr t={t.items.username} />
|
||||
</li>
|
||||
<li>
|
||||
<Tr t={t.items.date} />
|
||||
</li>
|
||||
<li>
|
||||
<Tr t={t.items.theme} />
|
||||
</li>
|
||||
<li>
|
||||
<Tr t={t.items.language} />
|
||||
</li>
|
||||
|
||||
<li>
|
||||
{#if $isLoggedIn}
|
||||
<TagRenderingEditable config={editPrivacy} selectedElement={{
|
||||
type: "Feature",
|
||||
properties: { id: "settings" },
|
||||
geometry: { type: "Point", coordinates: [0, 0] },
|
||||
}}
|
||||
{state}
|
||||
tags={state.userRelatedState.preferencesAsTags} />
|
||||
{:else}
|
||||
<Tr t={t.items.distanceIndicator} />
|
||||
{/if}
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<Tr t={t.editingOutro} />
|
||||
|
||||
<h3>
|
||||
<Tr t={t.miscCookiesTitle} />
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
import Add from "../../assets/svg/Add.svelte"
|
||||
import Location_refused from "../../assets/svg/Location_refused.svelte"
|
||||
import Location from "../../assets/svg/Location.svelte"
|
||||
import SpecialTranslation from "../Popup/TagRendering/SpecialTranslation.svelte"
|
||||
|
||||
/**
|
||||
* The theme introduction panel
|
||||
|
@ -48,6 +49,7 @@
|
|||
<div class="flex h-full flex-col justify-between">
|
||||
<div>
|
||||
<!-- Intro, description, ... -->
|
||||
|
||||
<Tr t={layout.description} />
|
||||
<Tr t={Translations.t.general.welcomeExplanation.general} />
|
||||
{#if layout.layers.some((l) => l.presets?.length > 0)}
|
||||
|
|
|
@ -109,16 +109,17 @@
|
|||
<div class="low-interaction border-interactive p-1">
|
||||
{#if !readonly}
|
||||
<Tr t={t.loadedFrom.Subs({ url: sourceUrl, source: sourceUrl })} />
|
||||
<h3>
|
||||
<Tr t={t.conflicting.title} />
|
||||
</h3>
|
||||
{/if}
|
||||
|
||||
<div class="flex flex-col" class:gap-y-8={!readonly}>
|
||||
{#if !readonly}
|
||||
<Tr t={t.conflicting.intro} />
|
||||
{/if}
|
||||
|
||||
{#if $different.length > 0}
|
||||
{#if !readonly}
|
||||
<h3>
|
||||
<Tr t={t.conflicting.title} />
|
||||
</h3>
|
||||
<Tr t={t.conflicting.intro} />
|
||||
{/if}
|
||||
{#each $different as key (key)}
|
||||
<div class="mx-2 rounded-2xl">
|
||||
<ComparisonAction
|
||||
|
@ -135,6 +136,13 @@
|
|||
{/if}
|
||||
|
||||
{#if $missing.length > 0}
|
||||
{#if !readonly}
|
||||
<h3 class="m-0">
|
||||
<Tr t={t.missing.title} />
|
||||
</h3>
|
||||
|
||||
<Tr t={t.missing.intro} />
|
||||
{/if}
|
||||
{#if currentStep === "init"}
|
||||
{#each $missing as key (key)}
|
||||
<div class:glowing-shadow={applyAllHovered} class="mx-2 rounded-2xl">
|
||||
|
|
|
@ -27,9 +27,9 @@
|
|||
addExtraTags = helperArgs[1].split(";")
|
||||
}
|
||||
|
||||
const path = `${key}s/${maintag.split("=")[0]}/${maintag.split("=")[1]}`
|
||||
const [k, v] = maintag.split("=")
|
||||
|
||||
let items: NSIItem[] = NameSuggestionIndex.getSuggestionsFor(path, feature.properties["_country"], GeoOperations.centerpointCoordinates(feature))
|
||||
let items: NSIItem[] = NameSuggestionIndex.getSuggestionsFor(key, k, v, feature.properties["_country"], GeoOperations.centerpointCoordinates(feature))
|
||||
|
||||
let selectedItem: NSIItem = items.find((item) => item.tags[key] === value.data)
|
||||
|
||||
|
@ -113,10 +113,10 @@
|
|||
})
|
||||
</script>
|
||||
|
||||
|
||||
{#if items?.length >= 0}
|
||||
<div>
|
||||
<div class="normal-background my-2 flex w-5/6 justify-between rounded-full pl-2">
|
||||
<!-- TODO translate placeholder -->
|
||||
<input type="text" placeholder="Filter entries" bind:value={filter} class="outline-none" />
|
||||
<SearchIcon aria-hidden="true" class="h-6 w-6 self-end" />
|
||||
</div>
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
import OpeningHoursInput from "./Helpers/OpeningHoursInput.svelte"
|
||||
import SlopeInput from "./Helpers/SlopeInput.svelte"
|
||||
import type { SpecialVisualizationState } from "../SpecialVisualization"
|
||||
import NameSuggestionIndexInput from "./Helpers/NameSuggestionIndexInput.svelte"
|
||||
|
||||
export let type: ValidatorType
|
||||
export let value: UIEventSource<string | object>
|
||||
|
@ -26,6 +27,9 @@
|
|||
export let feature: Feature
|
||||
export let args: (string | number | boolean)[] = undefined
|
||||
export let state: SpecialVisualizationState
|
||||
export let helperArgs: (string | number | boolean)[]
|
||||
export let key: string
|
||||
export let extraTags: UIEventSource<Record<string, string>>
|
||||
|
||||
let properties = { feature, args: args ?? [] }
|
||||
</script>
|
||||
|
@ -50,4 +54,6 @@
|
|||
<SlopeInput {value} {feature} {state} />
|
||||
{:else if type === "wikidata"}
|
||||
<ToSvelte construct={() => InputHelpers.constructWikidataHelper(value, properties)} />
|
||||
{:else if type === "nsi"}
|
||||
<NameSuggestionIndexInput {value} {feature} {helperArgs} {key} {extraTags} />
|
||||
{/if}
|
||||
|
|
|
@ -28,6 +28,7 @@ import TagValidator from "./Validators/TagValidator"
|
|||
import IdValidator from "./Validators/IdValidator"
|
||||
import SlopeValidator from "./Validators/SlopeValidator"
|
||||
import VeloparkValidator from "./Validators/VeloparkValidator"
|
||||
import NameSuggestionIndexValidator from "./Validators/NameSuggestionIndexValidator"
|
||||
import CurrencyValidator from "./Validators/CurrencyValidator"
|
||||
|
||||
export type ValidatorType = (typeof Validators.availableTypes)[number]
|
||||
|
@ -61,6 +62,7 @@ export default class Validators {
|
|||
"id",
|
||||
"slope",
|
||||
"velopark",
|
||||
"nsi",
|
||||
"currency"
|
||||
] as const
|
||||
|
||||
|
@ -91,6 +93,7 @@ export default class Validators {
|
|||
new IdValidator(),
|
||||
new SlopeValidator(),
|
||||
new VeloparkValidator(),
|
||||
new NameSuggestionIndexValidator(),
|
||||
new CurrencyValidator()
|
||||
]
|
||||
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
import Title from "../../Base/Title"
|
||||
import Combine from "../../Base/Combine"
|
||||
import { Validator } from "../Validator"
|
||||
import Table from "../../Base/Table"
|
||||
|
||||
export default class NameSuggestionIndexValidator extends Validator {
|
||||
constructor() {
|
||||
super(
|
||||
"nsi",
|
||||
new Combine([
|
||||
"Gives a list of possible suggestions for a brand or operator tag.",
|
||||
new Title("Helper arguments"),
|
||||
new Table(
|
||||
["name", "doc"],
|
||||
[
|
||||
[
|
||||
"options",
|
||||
new Combine([
|
||||
"A JSON-object of type `{ main: string, key: string }`. ",
|
||||
new Table(
|
||||
["subarg", "doc"],
|
||||
[
|
||||
[
|
||||
"main",
|
||||
"The main tag to give suggestions for, e.g. `amenity=restaurant`.",
|
||||
],
|
||||
[
|
||||
"addExtraTags",
|
||||
"Extra tags to add to the suggestions, e.g. `nobrand=yes`.",
|
||||
],
|
||||
]
|
||||
),
|
||||
]),
|
||||
],
|
||||
]
|
||||
),
|
||||
])
|
||||
)
|
||||
}
|
||||
}
|
|
@ -1,11 +1,11 @@
|
|||
<script lang="ts">
|
||||
import Loading from "../Base/Loading.svelte"
|
||||
import { Stores, UIEventSource } from "../../Logic/UIEventSource"
|
||||
import { Store, Stores, UIEventSource } from "../../Logic/UIEventSource"
|
||||
import { Map as MlMap } from "maplibre-gl"
|
||||
import { onDestroy } from "svelte"
|
||||
|
||||
let isLoading = false
|
||||
export let map: UIEventSource<MlMap>
|
||||
export let map: Store<MlMap>
|
||||
/**
|
||||
* Optional. Only used for the 'global' change indicator so that it won't spin on pan/zoom but only when a change _actually_ occured
|
||||
*/
|
||||
|
|
|
@ -216,7 +216,7 @@ class ApplyButton extends UIElement {
|
|||
}
|
||||
|
||||
export default class AutoApplyButton implements SpecialVisualization {
|
||||
public readonly docs: BaseUIElement
|
||||
public readonly docs: string
|
||||
public readonly funcName: string = "auto_apply"
|
||||
public readonly needsUrls = []
|
||||
|
||||
|
@ -273,7 +273,7 @@ export default class AutoApplyButton implements SpecialVisualization {
|
|||
"Then, use a calculated tag on the host feature to determine the overlapping object ids",
|
||||
"At last, add this component",
|
||||
]),
|
||||
])
|
||||
]).AsMarkdown()
|
||||
}
|
||||
|
||||
constr(
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
export let unvalidatedText: UIEventSource<string> = new UIEventSource<string>(value.data)
|
||||
export let config: TagRenderingConfig
|
||||
export let tags: UIEventSource<Record<string, string>>
|
||||
export let extraTags: UIEventSource<Record<string, string>>
|
||||
|
||||
export let feature: Feature = undefined
|
||||
export let state: SpecialVisualizationState
|
||||
|
@ -27,6 +28,8 @@
|
|||
inline = false
|
||||
inline = config.freeform?.inline
|
||||
}
|
||||
let helperArgs = config.freeform?.helperArgs
|
||||
let key = config.freeform?.key
|
||||
|
||||
const dispatch = createEventDispatcher<{ selected }>()
|
||||
export let feedback: UIEventSource<Translation>
|
||||
|
@ -75,6 +78,9 @@
|
|||
type={config.freeform.type}
|
||||
{value}
|
||||
{state}
|
||||
{helperArgs}
|
||||
{key}
|
||||
{extraTags}
|
||||
on:submit
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -79,7 +79,7 @@
|
|||
console.log("Applying questions to ask")
|
||||
const qta = questionsToAsk.data
|
||||
firstQuestion.setData(undefined)
|
||||
allQuestionsToAsk.setData([])
|
||||
//allQuestionsToAsk.setData([])
|
||||
await Utils.awaitAnimationFrame()
|
||||
firstQuestion.setData(qta[0])
|
||||
allQuestionsToAsk.setData(qta)
|
||||
|
|
|
@ -30,15 +30,18 @@
|
|||
import { placeholder } from "../../../Utils/placeholder"
|
||||
import { TrashIcon } from "@rgossiaux/svelte-heroicons/solid"
|
||||
import { Tag } from "../../../Logic/Tags/Tag"
|
||||
import { And } from "../../../Logic/Tags/And"
|
||||
import { get } from "svelte/store"
|
||||
import Markdown from "../../Base/Markdown.svelte"
|
||||
|
||||
export let config: TagRenderingConfig
|
||||
export let tags: UIEventSource<Record<string, string>>
|
||||
|
||||
export let selectedElement: Feature
|
||||
export let state: SpecialVisualizationState
|
||||
export let layer: LayerConfig | undefined
|
||||
export let selectedTags: UploadableTag = undefined
|
||||
export let extraTags: UIEventSource<Record<string, string>> = new UIEventSource({})
|
||||
|
||||
export let allowDeleteOfFreeform: boolean = false
|
||||
|
||||
|
@ -69,6 +72,8 @@
|
|||
/**
|
||||
* Prepares and fills the checkedMappings
|
||||
*/
|
||||
console.log("Initing ", config.id)
|
||||
|
||||
function initialize(tgs: Record<string, string>, confg: TagRenderingConfig): void {
|
||||
mappings = confg.mappings?.filter((m) => {
|
||||
if (typeof m.hideInAnswer === "boolean") {
|
||||
|
@ -76,8 +81,10 @@
|
|||
}
|
||||
return !m.hideInAnswer.matchesProperties(tgs)
|
||||
})
|
||||
selectedMapping = mappings?.findIndex(mapping => mapping.if.matchesProperties(tgs) || mapping.alsoShowIf?.matchesProperties(tgs))
|
||||
if(selectedMapping < 0){
|
||||
selectedMapping = mappings?.findIndex(
|
||||
(mapping) => mapping.if.matchesProperties(tgs) || mapping.alsoShowIf?.matchesProperties(tgs)
|
||||
)
|
||||
if (selectedMapping < 0) {
|
||||
selectedMapping = undefined
|
||||
}
|
||||
// We received a new config -> reinit
|
||||
|
@ -102,7 +109,7 @@
|
|||
seenFreeforms.push(newProps[confg.freeform.key])
|
||||
}
|
||||
return matches
|
||||
})
|
||||
}),
|
||||
]
|
||||
|
||||
if (tgs !== undefined && confg.freeform) {
|
||||
|
@ -133,15 +140,35 @@
|
|||
freeformInput.set(undefined)
|
||||
}
|
||||
feedback.setData(undefined)
|
||||
|
||||
|
||||
}
|
||||
|
||||
$: {
|
||||
// Even though 'config' is not declared as a store, Svelte uses it as one to update the component
|
||||
// We want to (re)-initialize whenever the 'tags' or 'config' change - but not when 'checkedConfig' changes
|
||||
initialize($tags, config)
|
||||
}
|
||||
let usedKeys: string[] = config.usedTags().flatMap((t) => t.usedKeys())
|
||||
/**
|
||||
* The 'minimalTags' is a subset of the tags of the feature, only containing the values relevant for this object.
|
||||
* The main goal is to be stable and only 'ping' when an actual change is relevant
|
||||
*/
|
||||
let minimalTags = new UIEventSource<Record<string, string>>(undefined)
|
||||
tags.addCallbackAndRunD((tags) => {
|
||||
const previousMinimal = minimalTags.data
|
||||
const newMinimal: Record<string, string> = {}
|
||||
let somethingChanged = previousMinimal === undefined
|
||||
for (const key of usedKeys) {
|
||||
const newValue = tags[key]
|
||||
somethingChanged ||= previousMinimal?.[key] !== newValue
|
||||
if (newValue !== undefined && newValue !== null) {
|
||||
newMinimal[key] = newValue
|
||||
}
|
||||
}
|
||||
if (somethingChanged) {
|
||||
console.log("Updating minimal tags to", newMinimal, "of", config.id)
|
||||
minimalTags.setData(newMinimal)
|
||||
}
|
||||
})
|
||||
|
||||
minimalTags.addCallbackAndRunD((tgs) => {
|
||||
initialize(tgs, config)
|
||||
})
|
||||
|
||||
onDestroy(
|
||||
freeformInput.subscribe((freeformValue) => {
|
||||
if (!mappings || mappings?.length == 0 || config.freeform?.key === undefined) {
|
||||
|
@ -178,23 +205,50 @@
|
|||
checkedMappings,
|
||||
tags.data
|
||||
)
|
||||
if(state.featureSwitches.featureSwitchIsDebugging.data){
|
||||
console.log("Constructing change spec from", {freeform: $freeformInput, selectedMapping, checkedMappings, currentTags: tags.data}, " --> ", selectedTags)
|
||||
if (featureSwitchIsDebugging?.data) {
|
||||
console.log(
|
||||
"Constructing change spec from",
|
||||
{
|
||||
freeform: $freeformInput,
|
||||
selectedMapping,
|
||||
checkedMappings,
|
||||
currentTags: tags.data,
|
||||
},
|
||||
" --> ",
|
||||
selectedTags
|
||||
)
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Could not calculate changeSpecification:", e)
|
||||
selectedTags = undefined
|
||||
}
|
||||
}
|
||||
|
||||
if (extraTags.data) {
|
||||
// Map the extraTags into an array of Tag objects
|
||||
const extraTagsArray = Object.entries(extraTags.data).map(([k, v]) => new Tag(k, v))
|
||||
|
||||
// Check the type of selectedTags
|
||||
if (selectedTags instanceof Tag) {
|
||||
// Re-define selectedTags as an And
|
||||
selectedTags = new And([selectedTags, ...extraTagsArray])
|
||||
} else if (selectedTags instanceof And) {
|
||||
// Add the extraTags to the existing And
|
||||
selectedTags = new And([...selectedTags.and, ...extraTagsArray])
|
||||
} else {
|
||||
console.error("selectedTags is not of type Tag or And")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onSave(_ = undefined) {
|
||||
if (selectedTags === undefined) {
|
||||
return
|
||||
}
|
||||
|
||||
if (layer === undefined || (layer?.source === null && layer.id !== "favourite")) {
|
||||
/**
|
||||
* This is a special, priviliged layer.
|
||||
* This is a special, privileged layer.
|
||||
* We simply apply the tags onto the records
|
||||
*/
|
||||
const kv = selectedTags.asChange(tags.data)
|
||||
|
@ -213,7 +267,7 @@
|
|||
dispatch("saved", { config, applied: selectedTags })
|
||||
const change = new ChangeTagAction(tags.data.id, selectedTags, tags.data, {
|
||||
theme: tags.data["_orig_theme"] ?? state.layout.id,
|
||||
changeType: "answer"
|
||||
changeType: "answer",
|
||||
})
|
||||
freeformInput.set(undefined)
|
||||
selectedMapping = undefined
|
||||
|
@ -266,7 +320,7 @@
|
|||
|
||||
{#if config.questionhint}
|
||||
{#if config.questionHintIsMd}
|
||||
<Markdown srcWritable={ config.questionhint.current} />
|
||||
<Markdown srcWritable={config.questionhint.current} />
|
||||
{:else}
|
||||
<div class="max-h-60 overflow-y-auto">
|
||||
<SpecialTranslation
|
||||
|
@ -277,7 +331,7 @@
|
|||
feature={selectedElement}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
{/if}
|
||||
</legend>
|
||||
|
||||
|
@ -301,6 +355,7 @@
|
|||
{feedback}
|
||||
{unit}
|
||||
{state}
|
||||
{extraTags}
|
||||
feature={selectedElement}
|
||||
value={freeformInput}
|
||||
unvalidatedText={freeformInputUnvalidated}
|
||||
|
@ -344,6 +399,7 @@
|
|||
{feedback}
|
||||
{unit}
|
||||
{state}
|
||||
{extraTags}
|
||||
feature={selectedElement}
|
||||
value={freeformInput}
|
||||
unvalidatedText={freeformInputUnvalidated}
|
||||
|
@ -388,6 +444,7 @@
|
|||
{feedback}
|
||||
{unit}
|
||||
{state}
|
||||
{extraTags}
|
||||
feature={selectedElement}
|
||||
value={freeformInput}
|
||||
unvalidatedText={freeformInputUnvalidated}
|
||||
|
|
|
@ -6,6 +6,15 @@
|
|||
import { Utils } from "../Utils"
|
||||
import Add from "../assets/svg/Add.svelte"
|
||||
import LanguagePicker from "./InputElement/LanguagePicker.svelte"
|
||||
import type { SpecialVisualizationState } from "./SpecialVisualization"
|
||||
import { OsmConnection } from "../Logic/Osm/OsmConnection"
|
||||
import UserRelatedState from "../Logic/State/UserRelatedState"
|
||||
|
||||
const osmConnection = new OsmConnection()
|
||||
let state: SpecialVisualizationState = {
|
||||
osmConnection,
|
||||
userRelatedState: new UserRelatedState(osmConnection)
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="flex h-screen flex-col overflow-hidden px-4">
|
||||
|
@ -17,7 +26,7 @@
|
|||
<LanguagePicker availableLanguages={Translations.t.privacy.intro.SupportedLanguages()} />
|
||||
</div>
|
||||
<div class="h-full overflow-auto border border-gray-500 p-4">
|
||||
<PrivacyPolicy />
|
||||
<PrivacyPolicy {state} />
|
||||
</div>
|
||||
<a class="button flex" href={Utils.HomepageLink()}>
|
||||
<Add class="h-6 w-6" />
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import { Store, UIEventSource } from "../Logic/UIEventSource"
|
||||
import BaseUIElement from "./BaseUIElement"
|
||||
import LayoutConfig from "../Models/ThemeConfig/LayoutConfig"
|
||||
import { IndexedFeatureSource, WritableFeatureSource } from "../Logic/FeatureSource/FeatureSource"
|
||||
import { FeatureSource, IndexedFeatureSource, WritableFeatureSource } from "../Logic/FeatureSource/FeatureSource"
|
||||
import { OsmConnection } from "../Logic/Osm/OsmConnection"
|
||||
import { Changes } from "../Logic/Osm/Changes"
|
||||
import { ExportableMap, MapProperties } from "../Models/MapProperties"
|
||||
import LayerState from "../Logic/State/LayerState"
|
||||
import { Feature, Geometry, Point } from "geojson"
|
||||
import { Feature, Geometry, Point, Polygon } from "geojson"
|
||||
import FullNodeDatabaseSource from "../Logic/FeatureSource/TiledFeatureSource/FullNodeDatabaseSource"
|
||||
import { MangroveIdentity } from "../Logic/Web/MangroveReviews"
|
||||
import { GeoIndexedStoreForLayer } from "../Logic/FeatureSource/Actors/GeoIndexedStore"
|
||||
|
@ -61,8 +61,10 @@ export interface SpecialVisualizationState {
|
|||
|
||||
readonly selectedElement: UIEventSource<Feature>
|
||||
|
||||
readonly currentView: FeatureSource<Feature<Polygon>>
|
||||
readonly favourites: FavouritesFeatureSource
|
||||
|
||||
|
||||
/**
|
||||
* If data is currently being fetched from external sources
|
||||
*/
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -11,7 +11,7 @@
|
|||
export let configs: ConfigMeta[]
|
||||
export let title: string | undefined = undefined
|
||||
|
||||
export let path: (string | number)[] = []
|
||||
export let path: readonly (string | number)[] = []
|
||||
|
||||
let expertMode = state.expertMode
|
||||
let configsNoHidden = configs.filter((schema) => schema.hints?.group !== "hidden")
|
||||
|
@ -21,9 +21,9 @@
|
|||
</script>
|
||||
|
||||
{#if configs === undefined}
|
||||
Bug: 'Region' received 'undefined'
|
||||
Bug: 'Region' received 'undefined' at {path.join(".")}
|
||||
{:else if configs.length === 0}
|
||||
Bug: Region received empty list as configuration
|
||||
Bug: Region received empty list as configuration at {path.join(".")}
|
||||
{:else if title}
|
||||
<div class="flex w-full flex-col">
|
||||
<h3>{title}</h3>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
import type { ConfigMeta } from "./configMeta"
|
||||
import type {
|
||||
MappingConfigJson,
|
||||
QuestionableTagRenderingConfigJson,
|
||||
QuestionableTagRenderingConfigJson
|
||||
} from "../../Models/ThemeConfig/Json/QuestionableTagRenderingConfigJson"
|
||||
import TagRenderingConfig from "../../Models/ThemeConfig/TagRenderingConfig"
|
||||
import TagRenderingEditable from "../Popup/TagRendering/TagRenderingEditable.svelte"
|
||||
|
@ -59,8 +59,8 @@
|
|||
labelMapping = {
|
||||
if: "value=" + label,
|
||||
then: {
|
||||
en: "Builtin collection <b>" + label + "</b>:",
|
||||
},
|
||||
en: "Builtin collection <b>" + label + "</b>:"
|
||||
}
|
||||
}
|
||||
perLabel[label] = labelMapping
|
||||
mappingsBuiltin.push(labelMapping)
|
||||
|
@ -72,14 +72,14 @@
|
|||
mappingsBuiltin.push({
|
||||
if: "value=" + tr["id"],
|
||||
then: {
|
||||
en: "Builtin <b>" + tr["id"] + "</b> <div class='subtle'>" + description + "</div>",
|
||||
},
|
||||
en: "Builtin <b>" + tr["id"] + "</b> <div class='subtle'>" + description + "</div>"
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const configBuiltin = new TagRenderingConfig(<QuestionableTagRenderingConfigJson>{
|
||||
question: "Which builtin element should be shown?",
|
||||
mappings: mappingsBuiltin,
|
||||
mappings: mappingsBuiltin
|
||||
})
|
||||
|
||||
const tags = new UIEventSource({ value })
|
||||
|
@ -112,7 +112,7 @@
|
|||
"condition",
|
||||
"metacondition",
|
||||
"mappings",
|
||||
"icon",
|
||||
"icon"
|
||||
])
|
||||
const ignored = new Set(["labels", "description", "classes"])
|
||||
|
||||
|
@ -196,7 +196,10 @@
|
|||
<h3>Text field and input element configuration</h3>
|
||||
<div class="border-l border-dashed border-gray-800 pl-2">
|
||||
<SchemaBasedField {state} path={[...path, "render"]} schema={topLevelItems["render"]} />
|
||||
<Region {state} {path} configs={freeformSchema} />
|
||||
{#if freeformSchema?.length > 0}
|
||||
<!-- In read-only cases, (e.g. popup title) there will be no freeform-schema to set and thus freeformSchema will be undefined -->
|
||||
<Region {state} {path} configs={freeformSchema} />
|
||||
{/if}
|
||||
<SchemaBasedField {state} path={[...path, "icon"]} schema={topLevelItems["icon"]} />
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
<script lang="ts">
|
||||
</script>
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
EyeIcon,
|
||||
HeartIcon,
|
||||
MenuIcon,
|
||||
XCircleIcon,
|
||||
XCircleIcon
|
||||
} from "@rgossiaux/svelte-heroicons/solid"
|
||||
import Tr from "./Base/Tr.svelte"
|
||||
import CommunityIndexView from "./BigComponents/CommunityIndexView.svelte"
|
||||
|
@ -73,6 +73,8 @@
|
|||
import { BBox } from "../Logic/BBox"
|
||||
import ReviewsOverview from "./Reviews/ReviewsOverview.svelte"
|
||||
import ExtraLinkButton from "./BigComponents/ExtraLinkButton.svelte"
|
||||
import CloseAnimation from "./Base/CloseAnimation.svelte"
|
||||
import { LastClickFeatureSource } from "../Logic/FeatureSource/Sources/LastClickFeatureSource"
|
||||
|
||||
export let state: ThemeViewState
|
||||
let layout = state.layout
|
||||
|
@ -138,7 +140,7 @@
|
|||
const bottomRight = mlmap.unproject([rect.right, rect.bottom])
|
||||
const bbox = new BBox([
|
||||
[topLeft.lng, topLeft.lat],
|
||||
[bottomRight.lng, bottomRight.lat],
|
||||
[bottomRight.lng, bottomRight.lat]
|
||||
])
|
||||
state.visualFeedbackViewportBounds.setData(bbox)
|
||||
}
|
||||
|
@ -151,7 +153,7 @@
|
|||
})
|
||||
let featureSwitches: FeatureSwitchState = state.featureSwitches
|
||||
let availableLayers = state.availableLayers
|
||||
let currentViewLayer = layout.layers.find((l) => l.id === "current_view")
|
||||
let currentViewLayer: LayerConfig = layout.layers.find((l) => l.id === "current_view")
|
||||
let rasterLayer: Store<RasterLayerPolygon> = state.mapProperties.rasterLayer
|
||||
let rasterLayerName =
|
||||
rasterLayer.data?.properties?.name ??
|
||||
|
@ -183,6 +185,22 @@
|
|||
const animation = mlmap.keyboard?.keydown(e)
|
||||
animation?.cameraAnimation(mlmap)
|
||||
}
|
||||
|
||||
/**
|
||||
* Needed for the animations
|
||||
*/
|
||||
let openMapButton : UIEventSource<HTMLElement> = new UIEventSource<HTMLElement>(undefined)
|
||||
let openMenuButton : UIEventSource<HTMLElement> = new UIEventSource<HTMLElement>(undefined)
|
||||
let openCurrentViewLayerButton : UIEventSource<HTMLElement> = new UIEventSource<HTMLElement>(undefined)
|
||||
let _openNewElementButton: HTMLButtonElement
|
||||
let openNewElementButton : UIEventSource<HTMLElement> = new UIEventSource<HTMLElement>(undefined)
|
||||
|
||||
$: {
|
||||
openNewElementButton.setData(_openNewElementButton)
|
||||
}
|
||||
let openFilterButton : UIEventSource<HTMLElement> = new UIEventSource<HTMLElement>(undefined)
|
||||
let openBackgroundButton : UIEventSource<HTMLElement> = new UIEventSource<HTMLElement>(undefined)
|
||||
|
||||
</script>
|
||||
|
||||
<div class="absolute top-0 left-0 h-screen w-screen overflow-hidden">
|
||||
|
@ -228,6 +246,7 @@
|
|||
<MapControlButton
|
||||
on:click={() => state.guistate.themeIsOpened.setData(true)}
|
||||
on:keydown={forwardEventToMap}
|
||||
htmlElem={openMapButton}
|
||||
>
|
||||
<div class="m-0.5 mx-1 flex cursor-pointer items-center max-[480px]:w-full sm:mx-1 md:mx-2">
|
||||
<img
|
||||
|
@ -245,15 +264,17 @@
|
|||
arialabel={Translations.t.general.labels.menu}
|
||||
on:click={() => state.guistate.menuIsOpened.setData(true)}
|
||||
on:keydown={forwardEventToMap}
|
||||
htmlElem={openMenuButton}
|
||||
>
|
||||
<MenuIcon class="h-8 w-8 cursor-pointer" />
|
||||
</MapControlButton>
|
||||
{#if currentViewLayer?.tagRenderings && currentViewLayer.defaultIcon()}
|
||||
<MapControlButton
|
||||
on:click={() => {
|
||||
state.selectedElement.setData(state.currentView.features?.data?.[0])
|
||||
state.selectCurrentView()
|
||||
}}
|
||||
on:keydown={forwardEventToMap}
|
||||
htmlElem={openCurrentViewLayerButton}
|
||||
>
|
||||
<ToSvelte
|
||||
construct={() => currentViewLayer.defaultIcon().SetClass("w-8 h-8 cursor-pointer")}
|
||||
|
@ -287,6 +308,7 @@
|
|||
<button
|
||||
class="pointer-events-auto w-fit low-interaction"
|
||||
class:disabled={$currentZoom < Constants.minZoomLevelToAddNewPoint}
|
||||
bind:this={_openNewElementButton}
|
||||
on:click={() => {
|
||||
state.openNewDialog()
|
||||
}}
|
||||
|
@ -310,12 +332,13 @@
|
|||
arialabel={Translations.t.general.labels.filter}
|
||||
on:click={() => state.guistate.openFilterView()}
|
||||
on:keydown={forwardEventToMap}
|
||||
htmlElem={openFilterButton}
|
||||
>
|
||||
<Filter class="h-6 w-6" />
|
||||
</MapControlButton>
|
||||
</If>
|
||||
<If condition={state.featureSwitches.featureSwitchBackgroundSelection}>
|
||||
<OpenBackgroundSelectorButton hideTooltip={true} {state} />
|
||||
<OpenBackgroundSelectorButton hideTooltip={true} {state} htmlElem={openBackgroundButton} />
|
||||
</If>
|
||||
<a
|
||||
class="bg-black-transparent pointer-events-auto h-fit max-h-12 cursor-pointer self-end overflow-hidden rounded-2xl pl-1 pr-2 text-white opacity-50 hover:opacity-100"
|
||||
|
@ -638,7 +661,7 @@
|
|||
<Tr t={Translations.t.privacy.title} />
|
||||
</h2>
|
||||
<div class="overflow-auto p-4">
|
||||
<PrivacyPolicy />
|
||||
<PrivacyPolicy {state}/>
|
||||
</div>
|
||||
</div>
|
||||
</FloatOver>
|
||||
|
@ -657,3 +680,11 @@
|
|||
</div>
|
||||
</FloatOver>
|
||||
</If>
|
||||
|
||||
|
||||
<CloseAnimation isOpened={state.guistate.themeIsOpened} moveTo={openMapButton} debug="theme"/>
|
||||
<CloseAnimation isOpened={state.guistate.menuIsOpened} moveTo={openMenuButton} debug="menu"/>
|
||||
<CloseAnimation isOpened={selectedLayer.map(sl => (sl !== undefined && sl === currentViewLayer))} moveTo={openCurrentViewLayerButton} debug="currentViewLayer"/>
|
||||
<CloseAnimation isOpened={selectedElement.map(sl =>{ console.log("SE is", sl); return sl !== undefined && sl?.properties?.id === LastClickFeatureSource.newPointElementId })} moveTo={openNewElementButton} debug="newElement"/>
|
||||
<CloseAnimation isOpened={state.guistate.filtersPanelIsOpened} moveTo={openFilterButton} debug="filter"/>
|
||||
<CloseAnimation isOpened={state.guistate.backgroundLayerSelectionIsOpened} moveTo={openBackgroundButton} debug="bg"/>
|
||||
|
|
|
@ -70,8 +70,7 @@ export default class Locale {
|
|||
}
|
||||
|
||||
if (!Utils.runningFromConsole) {
|
||||
// @ts-ignore
|
||||
window.setLanguage = function (language: string) {
|
||||
window["setLanguage"] = function (language: string) {
|
||||
source.setData(language)
|
||||
}
|
||||
}
|
||||
|
|
12
src/Utils.ts
12
src/Utils.ts
|
@ -1011,11 +1011,11 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
|
|||
})
|
||||
}
|
||||
|
||||
public static async downloadJsonCached(
|
||||
public static async downloadJsonCached<T = object | []>(
|
||||
url: string,
|
||||
maxCacheTimeMs: number,
|
||||
headers?: Record<string, string>
|
||||
): Promise<object> {
|
||||
): Promise<T> {
|
||||
const result = await Utils.downloadJsonCachedAdvanced(url, maxCacheTimeMs, headers)
|
||||
if (result["content"]) {
|
||||
return result["content"]
|
||||
|
@ -1023,11 +1023,11 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
|
|||
throw result["error"]
|
||||
}
|
||||
|
||||
public static async downloadJsonCachedAdvanced(
|
||||
public static async downloadJsonCachedAdvanced<T = object | []>(
|
||||
url: string,
|
||||
maxCacheTimeMs: number,
|
||||
headers?: Record<string, string>
|
||||
): Promise<{ content: object | [] } | { error: string; url: string; statuscode?: number }> {
|
||||
): Promise<{ content: T } | { error: string; url: string; statuscode?: number }> {
|
||||
const cached = Utils._download_cache.get(url)
|
||||
if (cached !== undefined) {
|
||||
if (new Date().getTime() - cached.timestamp <= maxCacheTimeMs) {
|
||||
|
@ -1042,10 +1042,10 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
|
|||
Utils._download_cache.set(url, { promise, timestamp: new Date().getTime() })
|
||||
return await promise
|
||||
}
|
||||
public static async downloadJson(
|
||||
public static async downloadJson<T = object | []>(
|
||||
url: string,
|
||||
headers?: Record<string, string>
|
||||
): Promise<object | []>
|
||||
): Promise<T>
|
||||
public static async downloadJson<T>(
|
||||
url: string,
|
||||
headers?: Record<string, string>
|
||||
|
|
19
src/Utils/MarkdownUtils.ts
Normal file
19
src/Utils/MarkdownUtils.ts
Normal file
|
@ -0,0 +1,19 @@
|
|||
|
||||
export default class MarkdownUtils {
|
||||
|
||||
public static table(header: string[], contents: string[][]){
|
||||
let result = ""
|
||||
|
||||
result += "\n\n| "+header.join(" | ") + " |\n"
|
||||
result += header.map(() => "-----").join("|") + " |\n"
|
||||
for (const line of contents) {
|
||||
if(!line){
|
||||
continue
|
||||
}
|
||||
result += "| " + line.map(x => x ?? "").join(" | ") + " |\n"
|
||||
}
|
||||
result += "\n\n"
|
||||
return result
|
||||
}
|
||||
|
||||
}
|
|
@ -445,7 +445,7 @@
|
|||
]
|
||||
},
|
||||
"condition": {
|
||||
"description": "question: When should this item be shown?\ntype: tag\nifunset: No specific condition set; always show this tagRendering or ask the question if unkown\n\nOnly show this tagrendering (or ask the question) if the selected object also matches the tags specified as `condition`.\n\nThis is useful to ask a follow-up question.\nFor example, within toilets, asking _where_ the diaper changing table is is only useful _if_ there is one.\nThis can be done by adding `\"condition\": \"changing_table=yes\"`\n\nA full example would be:\n```json\n {\n \"question\": \"Where is the changing table located?\",\n \"render\": \"The changing table is located at {changing_table:location}\",\n \"condition\": \"changing_table=yes\",\n \"freeform\": {\n \"key\": \"changing_table:location\",\n \"inline\": true\n },\n \"mappings\": [\n {\n \"then\": \"The changing table is in the toilet for women.\",\n \"if\": \"changing_table:location=female_toilet\"\n },\n {\n \"then\": \"The changing table is in the toilet for men.\",\n \"if\": \"changing_table:location=male_toilet\"\n },\n {\n \"if\": \"changing_table:location=wheelchair_toilet\",\n \"then\": \"The changing table is in the toilet for wheelchair users.\",\n },\n {\n \"if\": \"changing_table:location=dedicated_room\",\n \"then\": \"The changing table is in a dedicated room. \",\n }\n ],\n \"id\": \"toilet-changing_table:location\"\n },\n```",
|
||||
"description": "question: When should this item be shown?\ntype: tag\nifunset: No specific condition set; always show this tagRendering or show this question if unknown\n\nOnly show this tagrendering (or ask the question) if the selected object also matches the tags specified as `condition`.\n\nThis is useful to ask a follow-up question.\nFor example, within toilets, asking _where_ the diaper changing table is is only useful _if_ there is one.\nThis can be done by adding `\"condition\": \"changing_table=yes\"`\n\nA full example would be:\n```json\n {\n \"question\": \"Where is the changing table located?\",\n \"render\": \"The changing table is located at {changing_table:location}\",\n \"condition\": \"changing_table=yes\",\n \"freeform\": {\n \"key\": \"changing_table:location\",\n \"inline\": true\n },\n \"mappings\": [\n {\n \"then\": \"The changing table is in the toilet for women.\",\n \"if\": \"changing_table:location=female_toilet\"\n },\n {\n \"then\": \"The changing table is in the toilet for men.\",\n \"if\": \"changing_table:location=male_toilet\"\n },\n {\n \"if\": \"changing_table:location=wheelchair_toilet\",\n \"then\": \"The changing table is in the toilet for wheelchair users.\",\n },\n {\n \"if\": \"changing_table:location=dedicated_room\",\n \"then\": \"The changing table is in a dedicated room. \",\n }\n ],\n \"id\": \"toilet-changing_table:location\"\n },\n```",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/{and:TagConfigJson[];}"
|
||||
|
@ -459,7 +459,7 @@
|
|||
]
|
||||
},
|
||||
"metacondition": {
|
||||
"description": "question: When should this item be shown (including special conditions)?\ntype: tag\n\nIf set, this tag will be evaluated agains the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options.\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_",
|
||||
"description": "question: When should this item be shown (including special conditions)?\ntype: tag\nifunset: No specific metacondition set which is evaluated against the <i>usersettings/application state</i>; always show this tagRendering or show this question if unknown\n\nIf set, this tag will be evaluated against the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options (at the settings-tab).\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/{and:TagConfigJson[];}"
|
||||
|
@ -672,7 +672,7 @@
|
|||
"hints": {
|
||||
"typehint": "tag",
|
||||
"question": "When should this item be shown?",
|
||||
"ifunset": "No specific condition set; always show this tagRendering or ask the question if unkown"
|
||||
"ifunset": "No specific condition set; always show this tagRendering or show this question if unknown"
|
||||
},
|
||||
"type": [
|
||||
{
|
||||
|
@ -763,7 +763,8 @@
|
|||
"required": false,
|
||||
"hints": {
|
||||
"typehint": "tag",
|
||||
"question": "When should this item be shown (including special conditions)?"
|
||||
"question": "When should this item be shown (including special conditions)?",
|
||||
"ifunset": "No specific metacondition set which is evaluated against the <i>usersettings/application state</i>; always show this tagRendering or show this question if unknown"
|
||||
},
|
||||
"type": [
|
||||
{
|
||||
|
@ -776,7 +777,7 @@
|
|||
"type": "string"
|
||||
}
|
||||
],
|
||||
"description": "If set, this tag will be evaluated agains the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options.\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_"
|
||||
"description": "If set, this tag will be evaluated against the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options (at the settings-tab).\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_"
|
||||
},
|
||||
{
|
||||
"path": [
|
||||
|
@ -1225,7 +1226,7 @@
|
|||
"hints": {
|
||||
"typehint": "tag",
|
||||
"question": "When should this item be shown?",
|
||||
"ifunset": "No specific condition set; always show this tagRendering or ask the question if unkown"
|
||||
"ifunset": "No specific condition set; always show this tagRendering or show this question if unknown"
|
||||
},
|
||||
"type": [
|
||||
{
|
||||
|
@ -1316,7 +1317,8 @@
|
|||
"required": false,
|
||||
"hints": {
|
||||
"typehint": "tag",
|
||||
"question": "When should this item be shown (including special conditions)?"
|
||||
"question": "When should this item be shown (including special conditions)?",
|
||||
"ifunset": "No specific metacondition set which is evaluated against the <i>usersettings/application state</i>; always show this tagRendering or show this question if unknown"
|
||||
},
|
||||
"type": [
|
||||
{
|
||||
|
@ -1329,7 +1331,7 @@
|
|||
"type": "string"
|
||||
}
|
||||
],
|
||||
"description": "If set, this tag will be evaluated agains the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options.\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_"
|
||||
"description": "If set, this tag will be evaluated against the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options (at the settings-tab).\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_"
|
||||
},
|
||||
{
|
||||
"path": [
|
||||
|
@ -2373,7 +2375,7 @@
|
|||
]
|
||||
},
|
||||
"condition": {
|
||||
"description": "question: When should this item be shown?\ntype: tag\nifunset: No specific condition set; always show this tagRendering or ask the question if unkown\n\nOnly show this tagrendering (or ask the question) if the selected object also matches the tags specified as `condition`.\n\nThis is useful to ask a follow-up question.\nFor example, within toilets, asking _where_ the diaper changing table is is only useful _if_ there is one.\nThis can be done by adding `\"condition\": \"changing_table=yes\"`\n\nA full example would be:\n```json\n {\n \"question\": \"Where is the changing table located?\",\n \"render\": \"The changing table is located at {changing_table:location}\",\n \"condition\": \"changing_table=yes\",\n \"freeform\": {\n \"key\": \"changing_table:location\",\n \"inline\": true\n },\n \"mappings\": [\n {\n \"then\": \"The changing table is in the toilet for women.\",\n \"if\": \"changing_table:location=female_toilet\"\n },\n {\n \"then\": \"The changing table is in the toilet for men.\",\n \"if\": \"changing_table:location=male_toilet\"\n },\n {\n \"if\": \"changing_table:location=wheelchair_toilet\",\n \"then\": \"The changing table is in the toilet for wheelchair users.\",\n },\n {\n \"if\": \"changing_table:location=dedicated_room\",\n \"then\": \"The changing table is in a dedicated room. \",\n }\n ],\n \"id\": \"toilet-changing_table:location\"\n },\n```",
|
||||
"description": "question: When should this item be shown?\ntype: tag\nifunset: No specific condition set; always show this tagRendering or show this question if unknown\n\nOnly show this tagrendering (or ask the question) if the selected object also matches the tags specified as `condition`.\n\nThis is useful to ask a follow-up question.\nFor example, within toilets, asking _where_ the diaper changing table is is only useful _if_ there is one.\nThis can be done by adding `\"condition\": \"changing_table=yes\"`\n\nA full example would be:\n```json\n {\n \"question\": \"Where is the changing table located?\",\n \"render\": \"The changing table is located at {changing_table:location}\",\n \"condition\": \"changing_table=yes\",\n \"freeform\": {\n \"key\": \"changing_table:location\",\n \"inline\": true\n },\n \"mappings\": [\n {\n \"then\": \"The changing table is in the toilet for women.\",\n \"if\": \"changing_table:location=female_toilet\"\n },\n {\n \"then\": \"The changing table is in the toilet for men.\",\n \"if\": \"changing_table:location=male_toilet\"\n },\n {\n \"if\": \"changing_table:location=wheelchair_toilet\",\n \"then\": \"The changing table is in the toilet for wheelchair users.\",\n },\n {\n \"if\": \"changing_table:location=dedicated_room\",\n \"then\": \"The changing table is in a dedicated room. \",\n }\n ],\n \"id\": \"toilet-changing_table:location\"\n },\n```",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/{and:TagConfigJson[];}"
|
||||
|
@ -2387,7 +2389,7 @@
|
|||
]
|
||||
},
|
||||
"metacondition": {
|
||||
"description": "question: When should this item be shown (including special conditions)?\ntype: tag\n\nIf set, this tag will be evaluated agains the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options.\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_",
|
||||
"description": "question: When should this item be shown (including special conditions)?\ntype: tag\nifunset: No specific metacondition set which is evaluated against the <i>usersettings/application state</i>; always show this tagRendering or show this question if unknown\n\nIf set, this tag will be evaluated against the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options (at the settings-tab).\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/{and:TagConfigJson[];}"
|
||||
|
@ -2605,7 +2607,7 @@
|
|||
"hints": {
|
||||
"typehint": "tag",
|
||||
"question": "When should this item be shown?",
|
||||
"ifunset": "No specific condition set; always show this tagRendering or ask the question if unkown"
|
||||
"ifunset": "No specific condition set; always show this tagRendering or show this question if unknown"
|
||||
},
|
||||
"type": [
|
||||
{
|
||||
|
@ -2699,7 +2701,8 @@
|
|||
"required": false,
|
||||
"hints": {
|
||||
"typehint": "tag",
|
||||
"question": "When should this item be shown (including special conditions)?"
|
||||
"question": "When should this item be shown (including special conditions)?",
|
||||
"ifunset": "No specific metacondition set which is evaluated against the <i>usersettings/application state</i>; always show this tagRendering or show this question if unknown"
|
||||
},
|
||||
"type": [
|
||||
{
|
||||
|
@ -2712,7 +2715,7 @@
|
|||
"type": "string"
|
||||
}
|
||||
],
|
||||
"description": "If set, this tag will be evaluated agains the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options.\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_"
|
||||
"description": "If set, this tag will be evaluated against the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options (at the settings-tab).\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_"
|
||||
},
|
||||
{
|
||||
"path": [
|
||||
|
@ -3074,7 +3077,7 @@
|
|||
]
|
||||
},
|
||||
"condition": {
|
||||
"description": "question: When should this item be shown?\ntype: tag\nifunset: No specific condition set; always show this tagRendering or ask the question if unkown\n\nOnly show this tagrendering (or ask the question) if the selected object also matches the tags specified as `condition`.\n\nThis is useful to ask a follow-up question.\nFor example, within toilets, asking _where_ the diaper changing table is is only useful _if_ there is one.\nThis can be done by adding `\"condition\": \"changing_table=yes\"`\n\nA full example would be:\n```json\n {\n \"question\": \"Where is the changing table located?\",\n \"render\": \"The changing table is located at {changing_table:location}\",\n \"condition\": \"changing_table=yes\",\n \"freeform\": {\n \"key\": \"changing_table:location\",\n \"inline\": true\n },\n \"mappings\": [\n {\n \"then\": \"The changing table is in the toilet for women.\",\n \"if\": \"changing_table:location=female_toilet\"\n },\n {\n \"then\": \"The changing table is in the toilet for men.\",\n \"if\": \"changing_table:location=male_toilet\"\n },\n {\n \"if\": \"changing_table:location=wheelchair_toilet\",\n \"then\": \"The changing table is in the toilet for wheelchair users.\",\n },\n {\n \"if\": \"changing_table:location=dedicated_room\",\n \"then\": \"The changing table is in a dedicated room. \",\n }\n ],\n \"id\": \"toilet-changing_table:location\"\n },\n```",
|
||||
"description": "question: When should this item be shown?\ntype: tag\nifunset: No specific condition set; always show this tagRendering or show this question if unknown\n\nOnly show this tagrendering (or ask the question) if the selected object also matches the tags specified as `condition`.\n\nThis is useful to ask a follow-up question.\nFor example, within toilets, asking _where_ the diaper changing table is is only useful _if_ there is one.\nThis can be done by adding `\"condition\": \"changing_table=yes\"`\n\nA full example would be:\n```json\n {\n \"question\": \"Where is the changing table located?\",\n \"render\": \"The changing table is located at {changing_table:location}\",\n \"condition\": \"changing_table=yes\",\n \"freeform\": {\n \"key\": \"changing_table:location\",\n \"inline\": true\n },\n \"mappings\": [\n {\n \"then\": \"The changing table is in the toilet for women.\",\n \"if\": \"changing_table:location=female_toilet\"\n },\n {\n \"then\": \"The changing table is in the toilet for men.\",\n \"if\": \"changing_table:location=male_toilet\"\n },\n {\n \"if\": \"changing_table:location=wheelchair_toilet\",\n \"then\": \"The changing table is in the toilet for wheelchair users.\",\n },\n {\n \"if\": \"changing_table:location=dedicated_room\",\n \"then\": \"The changing table is in a dedicated room. \",\n }\n ],\n \"id\": \"toilet-changing_table:location\"\n },\n```",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/{and:TagConfigJson[];}"
|
||||
|
@ -3088,7 +3091,7 @@
|
|||
]
|
||||
},
|
||||
"metacondition": {
|
||||
"description": "question: When should this item be shown (including special conditions)?\ntype: tag\n\nIf set, this tag will be evaluated agains the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options.\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_",
|
||||
"description": "question: When should this item be shown (including special conditions)?\ntype: tag\nifunset: No specific metacondition set which is evaluated against the <i>usersettings/application state</i>; always show this tagRendering or show this question if unknown\n\nIf set, this tag will be evaluated against the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options (at the settings-tab).\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/{and:TagConfigJson[];}"
|
||||
|
@ -3306,7 +3309,7 @@
|
|||
"hints": {
|
||||
"typehint": "tag",
|
||||
"question": "When should this item be shown?",
|
||||
"ifunset": "No specific condition set; always show this tagRendering or ask the question if unkown"
|
||||
"ifunset": "No specific condition set; always show this tagRendering or show this question if unknown"
|
||||
},
|
||||
"type": [
|
||||
{
|
||||
|
@ -3400,7 +3403,8 @@
|
|||
"required": false,
|
||||
"hints": {
|
||||
"typehint": "tag",
|
||||
"question": "When should this item be shown (including special conditions)?"
|
||||
"question": "When should this item be shown (including special conditions)?",
|
||||
"ifunset": "No specific metacondition set which is evaluated against the <i>usersettings/application state</i>; always show this tagRendering or show this question if unknown"
|
||||
},
|
||||
"type": [
|
||||
{
|
||||
|
@ -3413,7 +3417,7 @@
|
|||
"type": "string"
|
||||
}
|
||||
],
|
||||
"description": "If set, this tag will be evaluated agains the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options.\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_"
|
||||
"description": "If set, this tag will be evaluated against the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options (at the settings-tab).\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_"
|
||||
},
|
||||
{
|
||||
"path": [
|
||||
|
@ -3753,7 +3757,7 @@
|
|||
]
|
||||
},
|
||||
"condition": {
|
||||
"description": "question: When should this item be shown?\ntype: tag\nifunset: No specific condition set; always show this tagRendering or ask the question if unkown\n\nOnly show this tagrendering (or ask the question) if the selected object also matches the tags specified as `condition`.\n\nThis is useful to ask a follow-up question.\nFor example, within toilets, asking _where_ the diaper changing table is is only useful _if_ there is one.\nThis can be done by adding `\"condition\": \"changing_table=yes\"`\n\nA full example would be:\n```json\n {\n \"question\": \"Where is the changing table located?\",\n \"render\": \"The changing table is located at {changing_table:location}\",\n \"condition\": \"changing_table=yes\",\n \"freeform\": {\n \"key\": \"changing_table:location\",\n \"inline\": true\n },\n \"mappings\": [\n {\n \"then\": \"The changing table is in the toilet for women.\",\n \"if\": \"changing_table:location=female_toilet\"\n },\n {\n \"then\": \"The changing table is in the toilet for men.\",\n \"if\": \"changing_table:location=male_toilet\"\n },\n {\n \"if\": \"changing_table:location=wheelchair_toilet\",\n \"then\": \"The changing table is in the toilet for wheelchair users.\",\n },\n {\n \"if\": \"changing_table:location=dedicated_room\",\n \"then\": \"The changing table is in a dedicated room. \",\n }\n ],\n \"id\": \"toilet-changing_table:location\"\n },\n```",
|
||||
"description": "question: When should this item be shown?\ntype: tag\nifunset: No specific condition set; always show this tagRendering or show this question if unknown\n\nOnly show this tagrendering (or ask the question) if the selected object also matches the tags specified as `condition`.\n\nThis is useful to ask a follow-up question.\nFor example, within toilets, asking _where_ the diaper changing table is is only useful _if_ there is one.\nThis can be done by adding `\"condition\": \"changing_table=yes\"`\n\nA full example would be:\n```json\n {\n \"question\": \"Where is the changing table located?\",\n \"render\": \"The changing table is located at {changing_table:location}\",\n \"condition\": \"changing_table=yes\",\n \"freeform\": {\n \"key\": \"changing_table:location\",\n \"inline\": true\n },\n \"mappings\": [\n {\n \"then\": \"The changing table is in the toilet for women.\",\n \"if\": \"changing_table:location=female_toilet\"\n },\n {\n \"then\": \"The changing table is in the toilet for men.\",\n \"if\": \"changing_table:location=male_toilet\"\n },\n {\n \"if\": \"changing_table:location=wheelchair_toilet\",\n \"then\": \"The changing table is in the toilet for wheelchair users.\",\n },\n {\n \"if\": \"changing_table:location=dedicated_room\",\n \"then\": \"The changing table is in a dedicated room. \",\n }\n ],\n \"id\": \"toilet-changing_table:location\"\n },\n```",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/{and:TagConfigJson[];}"
|
||||
|
@ -3767,7 +3771,7 @@
|
|||
]
|
||||
},
|
||||
"metacondition": {
|
||||
"description": "question: When should this item be shown (including special conditions)?\ntype: tag\n\nIf set, this tag will be evaluated agains the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options.\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_",
|
||||
"description": "question: When should this item be shown (including special conditions)?\ntype: tag\nifunset: No specific metacondition set which is evaluated against the <i>usersettings/application state</i>; always show this tagRendering or show this question if unknown\n\nIf set, this tag will be evaluated against the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options (at the settings-tab).\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/{and:TagConfigJson[];}"
|
||||
|
@ -3985,7 +3989,7 @@
|
|||
"hints": {
|
||||
"typehint": "tag",
|
||||
"question": "When should this item be shown?",
|
||||
"ifunset": "No specific condition set; always show this tagRendering or ask the question if unkown"
|
||||
"ifunset": "No specific condition set; always show this tagRendering or show this question if unknown"
|
||||
},
|
||||
"type": [
|
||||
{
|
||||
|
@ -4079,7 +4083,8 @@
|
|||
"required": false,
|
||||
"hints": {
|
||||
"typehint": "tag",
|
||||
"question": "When should this item be shown (including special conditions)?"
|
||||
"question": "When should this item be shown (including special conditions)?",
|
||||
"ifunset": "No specific metacondition set which is evaluated against the <i>usersettings/application state</i>; always show this tagRendering or show this question if unknown"
|
||||
},
|
||||
"type": [
|
||||
{
|
||||
|
@ -4092,7 +4097,7 @@
|
|||
"type": "string"
|
||||
}
|
||||
],
|
||||
"description": "If set, this tag will be evaluated agains the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options.\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_"
|
||||
"description": "If set, this tag will be evaluated against the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options (at the settings-tab).\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_"
|
||||
},
|
||||
{
|
||||
"path": [
|
||||
|
@ -4434,7 +4439,7 @@
|
|||
]
|
||||
},
|
||||
"condition": {
|
||||
"description": "question: When should this item be shown?\ntype: tag\nifunset: No specific condition set; always show this tagRendering or ask the question if unkown\n\nOnly show this tagrendering (or ask the question) if the selected object also matches the tags specified as `condition`.\n\nThis is useful to ask a follow-up question.\nFor example, within toilets, asking _where_ the diaper changing table is is only useful _if_ there is one.\nThis can be done by adding `\"condition\": \"changing_table=yes\"`\n\nA full example would be:\n```json\n {\n \"question\": \"Where is the changing table located?\",\n \"render\": \"The changing table is located at {changing_table:location}\",\n \"condition\": \"changing_table=yes\",\n \"freeform\": {\n \"key\": \"changing_table:location\",\n \"inline\": true\n },\n \"mappings\": [\n {\n \"then\": \"The changing table is in the toilet for women.\",\n \"if\": \"changing_table:location=female_toilet\"\n },\n {\n \"then\": \"The changing table is in the toilet for men.\",\n \"if\": \"changing_table:location=male_toilet\"\n },\n {\n \"if\": \"changing_table:location=wheelchair_toilet\",\n \"then\": \"The changing table is in the toilet for wheelchair users.\",\n },\n {\n \"if\": \"changing_table:location=dedicated_room\",\n \"then\": \"The changing table is in a dedicated room. \",\n }\n ],\n \"id\": \"toilet-changing_table:location\"\n },\n```",
|
||||
"description": "question: When should this item be shown?\ntype: tag\nifunset: No specific condition set; always show this tagRendering or show this question if unknown\n\nOnly show this tagrendering (or ask the question) if the selected object also matches the tags specified as `condition`.\n\nThis is useful to ask a follow-up question.\nFor example, within toilets, asking _where_ the diaper changing table is is only useful _if_ there is one.\nThis can be done by adding `\"condition\": \"changing_table=yes\"`\n\nA full example would be:\n```json\n {\n \"question\": \"Where is the changing table located?\",\n \"render\": \"The changing table is located at {changing_table:location}\",\n \"condition\": \"changing_table=yes\",\n \"freeform\": {\n \"key\": \"changing_table:location\",\n \"inline\": true\n },\n \"mappings\": [\n {\n \"then\": \"The changing table is in the toilet for women.\",\n \"if\": \"changing_table:location=female_toilet\"\n },\n {\n \"then\": \"The changing table is in the toilet for men.\",\n \"if\": \"changing_table:location=male_toilet\"\n },\n {\n \"if\": \"changing_table:location=wheelchair_toilet\",\n \"then\": \"The changing table is in the toilet for wheelchair users.\",\n },\n {\n \"if\": \"changing_table:location=dedicated_room\",\n \"then\": \"The changing table is in a dedicated room. \",\n }\n ],\n \"id\": \"toilet-changing_table:location\"\n },\n```",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/{and:TagConfigJson[];}"
|
||||
|
@ -4448,7 +4453,7 @@
|
|||
]
|
||||
},
|
||||
"metacondition": {
|
||||
"description": "question: When should this item be shown (including special conditions)?\ntype: tag\n\nIf set, this tag will be evaluated agains the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options.\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_",
|
||||
"description": "question: When should this item be shown (including special conditions)?\ntype: tag\nifunset: No specific metacondition set which is evaluated against the <i>usersettings/application state</i>; always show this tagRendering or show this question if unknown\n\nIf set, this tag will be evaluated against the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options (at the settings-tab).\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/{and:TagConfigJson[];}"
|
||||
|
@ -4666,7 +4671,7 @@
|
|||
"hints": {
|
||||
"typehint": "tag",
|
||||
"question": "When should this item be shown?",
|
||||
"ifunset": "No specific condition set; always show this tagRendering or ask the question if unkown"
|
||||
"ifunset": "No specific condition set; always show this tagRendering or show this question if unknown"
|
||||
},
|
||||
"type": [
|
||||
{
|
||||
|
@ -4760,7 +4765,8 @@
|
|||
"required": false,
|
||||
"hints": {
|
||||
"typehint": "tag",
|
||||
"question": "When should this item be shown (including special conditions)?"
|
||||
"question": "When should this item be shown (including special conditions)?",
|
||||
"ifunset": "No specific metacondition set which is evaluated against the <i>usersettings/application state</i>; always show this tagRendering or show this question if unknown"
|
||||
},
|
||||
"type": [
|
||||
{
|
||||
|
@ -4773,7 +4779,7 @@
|
|||
"type": "string"
|
||||
}
|
||||
],
|
||||
"description": "If set, this tag will be evaluated agains the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options.\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_"
|
||||
"description": "If set, this tag will be evaluated against the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options (at the settings-tab).\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_"
|
||||
},
|
||||
{
|
||||
"path": [
|
||||
|
@ -5116,7 +5122,7 @@
|
|||
]
|
||||
},
|
||||
"condition": {
|
||||
"description": "question: When should this item be shown?\ntype: tag\nifunset: No specific condition set; always show this tagRendering or ask the question if unkown\n\nOnly show this tagrendering (or ask the question) if the selected object also matches the tags specified as `condition`.\n\nThis is useful to ask a follow-up question.\nFor example, within toilets, asking _where_ the diaper changing table is is only useful _if_ there is one.\nThis can be done by adding `\"condition\": \"changing_table=yes\"`\n\nA full example would be:\n```json\n {\n \"question\": \"Where is the changing table located?\",\n \"render\": \"The changing table is located at {changing_table:location}\",\n \"condition\": \"changing_table=yes\",\n \"freeform\": {\n \"key\": \"changing_table:location\",\n \"inline\": true\n },\n \"mappings\": [\n {\n \"then\": \"The changing table is in the toilet for women.\",\n \"if\": \"changing_table:location=female_toilet\"\n },\n {\n \"then\": \"The changing table is in the toilet for men.\",\n \"if\": \"changing_table:location=male_toilet\"\n },\n {\n \"if\": \"changing_table:location=wheelchair_toilet\",\n \"then\": \"The changing table is in the toilet for wheelchair users.\",\n },\n {\n \"if\": \"changing_table:location=dedicated_room\",\n \"then\": \"The changing table is in a dedicated room. \",\n }\n ],\n \"id\": \"toilet-changing_table:location\"\n },\n```",
|
||||
"description": "question: When should this item be shown?\ntype: tag\nifunset: No specific condition set; always show this tagRendering or show this question if unknown\n\nOnly show this tagrendering (or ask the question) if the selected object also matches the tags specified as `condition`.\n\nThis is useful to ask a follow-up question.\nFor example, within toilets, asking _where_ the diaper changing table is is only useful _if_ there is one.\nThis can be done by adding `\"condition\": \"changing_table=yes\"`\n\nA full example would be:\n```json\n {\n \"question\": \"Where is the changing table located?\",\n \"render\": \"The changing table is located at {changing_table:location}\",\n \"condition\": \"changing_table=yes\",\n \"freeform\": {\n \"key\": \"changing_table:location\",\n \"inline\": true\n },\n \"mappings\": [\n {\n \"then\": \"The changing table is in the toilet for women.\",\n \"if\": \"changing_table:location=female_toilet\"\n },\n {\n \"then\": \"The changing table is in the toilet for men.\",\n \"if\": \"changing_table:location=male_toilet\"\n },\n {\n \"if\": \"changing_table:location=wheelchair_toilet\",\n \"then\": \"The changing table is in the toilet for wheelchair users.\",\n },\n {\n \"if\": \"changing_table:location=dedicated_room\",\n \"then\": \"The changing table is in a dedicated room. \",\n }\n ],\n \"id\": \"toilet-changing_table:location\"\n },\n```",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/{and:TagConfigJson[];}"
|
||||
|
@ -5130,7 +5136,7 @@
|
|||
]
|
||||
},
|
||||
"metacondition": {
|
||||
"description": "question: When should this item be shown (including special conditions)?\ntype: tag\n\nIf set, this tag will be evaluated agains the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options.\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_",
|
||||
"description": "question: When should this item be shown (including special conditions)?\ntype: tag\nifunset: No specific metacondition set which is evaluated against the <i>usersettings/application state</i>; always show this tagRendering or show this question if unknown\n\nIf set, this tag will be evaluated against the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options (at the settings-tab).\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/{and:TagConfigJson[];}"
|
||||
|
@ -5348,7 +5354,7 @@
|
|||
"hints": {
|
||||
"typehint": "tag",
|
||||
"question": "When should this item be shown?",
|
||||
"ifunset": "No specific condition set; always show this tagRendering or ask the question if unkown"
|
||||
"ifunset": "No specific condition set; always show this tagRendering or show this question if unknown"
|
||||
},
|
||||
"type": [
|
||||
{
|
||||
|
@ -5442,7 +5448,8 @@
|
|||
"required": false,
|
||||
"hints": {
|
||||
"typehint": "tag",
|
||||
"question": "When should this item be shown (including special conditions)?"
|
||||
"question": "When should this item be shown (including special conditions)?",
|
||||
"ifunset": "No specific metacondition set which is evaluated against the <i>usersettings/application state</i>; always show this tagRendering or show this question if unknown"
|
||||
},
|
||||
"type": [
|
||||
{
|
||||
|
@ -5455,7 +5462,7 @@
|
|||
"type": "string"
|
||||
}
|
||||
],
|
||||
"description": "If set, this tag will be evaluated agains the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options.\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_"
|
||||
"description": "If set, this tag will be evaluated against the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options (at the settings-tab).\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_"
|
||||
},
|
||||
{
|
||||
"path": [
|
||||
|
@ -5803,7 +5810,7 @@
|
|||
]
|
||||
},
|
||||
"condition": {
|
||||
"description": "question: When should this item be shown?\ntype: tag\nifunset: No specific condition set; always show this tagRendering or ask the question if unkown\n\nOnly show this tagrendering (or ask the question) if the selected object also matches the tags specified as `condition`.\n\nThis is useful to ask a follow-up question.\nFor example, within toilets, asking _where_ the diaper changing table is is only useful _if_ there is one.\nThis can be done by adding `\"condition\": \"changing_table=yes\"`\n\nA full example would be:\n```json\n {\n \"question\": \"Where is the changing table located?\",\n \"render\": \"The changing table is located at {changing_table:location}\",\n \"condition\": \"changing_table=yes\",\n \"freeform\": {\n \"key\": \"changing_table:location\",\n \"inline\": true\n },\n \"mappings\": [\n {\n \"then\": \"The changing table is in the toilet for women.\",\n \"if\": \"changing_table:location=female_toilet\"\n },\n {\n \"then\": \"The changing table is in the toilet for men.\",\n \"if\": \"changing_table:location=male_toilet\"\n },\n {\n \"if\": \"changing_table:location=wheelchair_toilet\",\n \"then\": \"The changing table is in the toilet for wheelchair users.\",\n },\n {\n \"if\": \"changing_table:location=dedicated_room\",\n \"then\": \"The changing table is in a dedicated room. \",\n }\n ],\n \"id\": \"toilet-changing_table:location\"\n },\n```",
|
||||
"description": "question: When should this item be shown?\ntype: tag\nifunset: No specific condition set; always show this tagRendering or show this question if unknown\n\nOnly show this tagrendering (or ask the question) if the selected object also matches the tags specified as `condition`.\n\nThis is useful to ask a follow-up question.\nFor example, within toilets, asking _where_ the diaper changing table is is only useful _if_ there is one.\nThis can be done by adding `\"condition\": \"changing_table=yes\"`\n\nA full example would be:\n```json\n {\n \"question\": \"Where is the changing table located?\",\n \"render\": \"The changing table is located at {changing_table:location}\",\n \"condition\": \"changing_table=yes\",\n \"freeform\": {\n \"key\": \"changing_table:location\",\n \"inline\": true\n },\n \"mappings\": [\n {\n \"then\": \"The changing table is in the toilet for women.\",\n \"if\": \"changing_table:location=female_toilet\"\n },\n {\n \"then\": \"The changing table is in the toilet for men.\",\n \"if\": \"changing_table:location=male_toilet\"\n },\n {\n \"if\": \"changing_table:location=wheelchair_toilet\",\n \"then\": \"The changing table is in the toilet for wheelchair users.\",\n },\n {\n \"if\": \"changing_table:location=dedicated_room\",\n \"then\": \"The changing table is in a dedicated room. \",\n }\n ],\n \"id\": \"toilet-changing_table:location\"\n },\n```",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/{and:TagConfigJson[];}"
|
||||
|
@ -5817,7 +5824,7 @@
|
|||
]
|
||||
},
|
||||
"metacondition": {
|
||||
"description": "question: When should this item be shown (including special conditions)?\ntype: tag\n\nIf set, this tag will be evaluated agains the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options.\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_",
|
||||
"description": "question: When should this item be shown (including special conditions)?\ntype: tag\nifunset: No specific metacondition set which is evaluated against the <i>usersettings/application state</i>; always show this tagRendering or show this question if unknown\n\nIf set, this tag will be evaluated against the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options (at the settings-tab).\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/{and:TagConfigJson[];}"
|
||||
|
@ -6035,7 +6042,7 @@
|
|||
"hints": {
|
||||
"typehint": "tag",
|
||||
"question": "When should this item be shown?",
|
||||
"ifunset": "No specific condition set; always show this tagRendering or ask the question if unkown"
|
||||
"ifunset": "No specific condition set; always show this tagRendering or show this question if unknown"
|
||||
},
|
||||
"type": [
|
||||
{
|
||||
|
@ -6129,7 +6136,8 @@
|
|||
"required": false,
|
||||
"hints": {
|
||||
"typehint": "tag",
|
||||
"question": "When should this item be shown (including special conditions)?"
|
||||
"question": "When should this item be shown (including special conditions)?",
|
||||
"ifunset": "No specific metacondition set which is evaluated against the <i>usersettings/application state</i>; always show this tagRendering or show this question if unknown"
|
||||
},
|
||||
"type": [
|
||||
{
|
||||
|
@ -6142,7 +6150,7 @@
|
|||
"type": "string"
|
||||
}
|
||||
],
|
||||
"description": "If set, this tag will be evaluated agains the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options.\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_"
|
||||
"description": "If set, this tag will be evaluated against the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options (at the settings-tab).\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_"
|
||||
},
|
||||
{
|
||||
"path": [
|
||||
|
@ -6485,7 +6493,7 @@
|
|||
]
|
||||
},
|
||||
"condition": {
|
||||
"description": "question: When should this item be shown?\ntype: tag\nifunset: No specific condition set; always show this tagRendering or ask the question if unkown\n\nOnly show this tagrendering (or ask the question) if the selected object also matches the tags specified as `condition`.\n\nThis is useful to ask a follow-up question.\nFor example, within toilets, asking _where_ the diaper changing table is is only useful _if_ there is one.\nThis can be done by adding `\"condition\": \"changing_table=yes\"`\n\nA full example would be:\n```json\n {\n \"question\": \"Where is the changing table located?\",\n \"render\": \"The changing table is located at {changing_table:location}\",\n \"condition\": \"changing_table=yes\",\n \"freeform\": {\n \"key\": \"changing_table:location\",\n \"inline\": true\n },\n \"mappings\": [\n {\n \"then\": \"The changing table is in the toilet for women.\",\n \"if\": \"changing_table:location=female_toilet\"\n },\n {\n \"then\": \"The changing table is in the toilet for men.\",\n \"if\": \"changing_table:location=male_toilet\"\n },\n {\n \"if\": \"changing_table:location=wheelchair_toilet\",\n \"then\": \"The changing table is in the toilet for wheelchair users.\",\n },\n {\n \"if\": \"changing_table:location=dedicated_room\",\n \"then\": \"The changing table is in a dedicated room. \",\n }\n ],\n \"id\": \"toilet-changing_table:location\"\n },\n```",
|
||||
"description": "question: When should this item be shown?\ntype: tag\nifunset: No specific condition set; always show this tagRendering or show this question if unknown\n\nOnly show this tagrendering (or ask the question) if the selected object also matches the tags specified as `condition`.\n\nThis is useful to ask a follow-up question.\nFor example, within toilets, asking _where_ the diaper changing table is is only useful _if_ there is one.\nThis can be done by adding `\"condition\": \"changing_table=yes\"`\n\nA full example would be:\n```json\n {\n \"question\": \"Where is the changing table located?\",\n \"render\": \"The changing table is located at {changing_table:location}\",\n \"condition\": \"changing_table=yes\",\n \"freeform\": {\n \"key\": \"changing_table:location\",\n \"inline\": true\n },\n \"mappings\": [\n {\n \"then\": \"The changing table is in the toilet for women.\",\n \"if\": \"changing_table:location=female_toilet\"\n },\n {\n \"then\": \"The changing table is in the toilet for men.\",\n \"if\": \"changing_table:location=male_toilet\"\n },\n {\n \"if\": \"changing_table:location=wheelchair_toilet\",\n \"then\": \"The changing table is in the toilet for wheelchair users.\",\n },\n {\n \"if\": \"changing_table:location=dedicated_room\",\n \"then\": \"The changing table is in a dedicated room. \",\n }\n ],\n \"id\": \"toilet-changing_table:location\"\n },\n```",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/{and:TagConfigJson[];}"
|
||||
|
@ -6499,7 +6507,7 @@
|
|||
]
|
||||
},
|
||||
"metacondition": {
|
||||
"description": "question: When should this item be shown (including special conditions)?\ntype: tag\n\nIf set, this tag will be evaluated agains the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options.\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_",
|
||||
"description": "question: When should this item be shown (including special conditions)?\ntype: tag\nifunset: No specific metacondition set which is evaluated against the <i>usersettings/application state</i>; always show this tagRendering or show this question if unknown\n\nIf set, this tag will be evaluated against the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options (at the settings-tab).\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/{and:TagConfigJson[];}"
|
||||
|
@ -6717,7 +6725,7 @@
|
|||
"hints": {
|
||||
"typehint": "tag",
|
||||
"question": "When should this item be shown?",
|
||||
"ifunset": "No specific condition set; always show this tagRendering or ask the question if unkown"
|
||||
"ifunset": "No specific condition set; always show this tagRendering or show this question if unknown"
|
||||
},
|
||||
"type": [
|
||||
{
|
||||
|
@ -6811,7 +6819,8 @@
|
|||
"required": false,
|
||||
"hints": {
|
||||
"typehint": "tag",
|
||||
"question": "When should this item be shown (including special conditions)?"
|
||||
"question": "When should this item be shown (including special conditions)?",
|
||||
"ifunset": "No specific metacondition set which is evaluated against the <i>usersettings/application state</i>; always show this tagRendering or show this question if unknown"
|
||||
},
|
||||
"type": [
|
||||
{
|
||||
|
@ -6824,7 +6833,7 @@
|
|||
"type": "string"
|
||||
}
|
||||
],
|
||||
"description": "If set, this tag will be evaluated agains the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options.\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_"
|
||||
"description": "If set, this tag will be evaluated against the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options (at the settings-tab).\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_"
|
||||
},
|
||||
{
|
||||
"path": [
|
||||
|
@ -7167,7 +7176,7 @@
|
|||
]
|
||||
},
|
||||
"condition": {
|
||||
"description": "question: When should this item be shown?\ntype: tag\nifunset: No specific condition set; always show this tagRendering or ask the question if unkown\n\nOnly show this tagrendering (or ask the question) if the selected object also matches the tags specified as `condition`.\n\nThis is useful to ask a follow-up question.\nFor example, within toilets, asking _where_ the diaper changing table is is only useful _if_ there is one.\nThis can be done by adding `\"condition\": \"changing_table=yes\"`\n\nA full example would be:\n```json\n {\n \"question\": \"Where is the changing table located?\",\n \"render\": \"The changing table is located at {changing_table:location}\",\n \"condition\": \"changing_table=yes\",\n \"freeform\": {\n \"key\": \"changing_table:location\",\n \"inline\": true\n },\n \"mappings\": [\n {\n \"then\": \"The changing table is in the toilet for women.\",\n \"if\": \"changing_table:location=female_toilet\"\n },\n {\n \"then\": \"The changing table is in the toilet for men.\",\n \"if\": \"changing_table:location=male_toilet\"\n },\n {\n \"if\": \"changing_table:location=wheelchair_toilet\",\n \"then\": \"The changing table is in the toilet for wheelchair users.\",\n },\n {\n \"if\": \"changing_table:location=dedicated_room\",\n \"then\": \"The changing table is in a dedicated room. \",\n }\n ],\n \"id\": \"toilet-changing_table:location\"\n },\n```",
|
||||
"description": "question: When should this item be shown?\ntype: tag\nifunset: No specific condition set; always show this tagRendering or show this question if unknown\n\nOnly show this tagrendering (or ask the question) if the selected object also matches the tags specified as `condition`.\n\nThis is useful to ask a follow-up question.\nFor example, within toilets, asking _where_ the diaper changing table is is only useful _if_ there is one.\nThis can be done by adding `\"condition\": \"changing_table=yes\"`\n\nA full example would be:\n```json\n {\n \"question\": \"Where is the changing table located?\",\n \"render\": \"The changing table is located at {changing_table:location}\",\n \"condition\": \"changing_table=yes\",\n \"freeform\": {\n \"key\": \"changing_table:location\",\n \"inline\": true\n },\n \"mappings\": [\n {\n \"then\": \"The changing table is in the toilet for women.\",\n \"if\": \"changing_table:location=female_toilet\"\n },\n {\n \"then\": \"The changing table is in the toilet for men.\",\n \"if\": \"changing_table:location=male_toilet\"\n },\n {\n \"if\": \"changing_table:location=wheelchair_toilet\",\n \"then\": \"The changing table is in the toilet for wheelchair users.\",\n },\n {\n \"if\": \"changing_table:location=dedicated_room\",\n \"then\": \"The changing table is in a dedicated room. \",\n }\n ],\n \"id\": \"toilet-changing_table:location\"\n },\n```",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/{and:TagConfigJson[];}"
|
||||
|
@ -7181,7 +7190,7 @@
|
|||
]
|
||||
},
|
||||
"metacondition": {
|
||||
"description": "question: When should this item be shown (including special conditions)?\ntype: tag\n\nIf set, this tag will be evaluated agains the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options.\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_",
|
||||
"description": "question: When should this item be shown (including special conditions)?\ntype: tag\nifunset: No specific metacondition set which is evaluated against the <i>usersettings/application state</i>; always show this tagRendering or show this question if unknown\n\nIf set, this tag will be evaluated against the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options (at the settings-tab).\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/{and:TagConfigJson[];}"
|
||||
|
@ -7399,7 +7408,7 @@
|
|||
"hints": {
|
||||
"typehint": "tag",
|
||||
"question": "When should this item be shown?",
|
||||
"ifunset": "No specific condition set; always show this tagRendering or ask the question if unkown"
|
||||
"ifunset": "No specific condition set; always show this tagRendering or show this question if unknown"
|
||||
},
|
||||
"type": [
|
||||
{
|
||||
|
@ -7493,7 +7502,8 @@
|
|||
"required": false,
|
||||
"hints": {
|
||||
"typehint": "tag",
|
||||
"question": "When should this item be shown (including special conditions)?"
|
||||
"question": "When should this item be shown (including special conditions)?",
|
||||
"ifunset": "No specific metacondition set which is evaluated against the <i>usersettings/application state</i>; always show this tagRendering or show this question if unknown"
|
||||
},
|
||||
"type": [
|
||||
{
|
||||
|
@ -7506,7 +7516,7 @@
|
|||
"type": "string"
|
||||
}
|
||||
],
|
||||
"description": "If set, this tag will be evaluated agains the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options.\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_"
|
||||
"description": "If set, this tag will be evaluated against the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options (at the settings-tab).\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_"
|
||||
},
|
||||
{
|
||||
"path": [
|
||||
|
@ -7856,7 +7866,7 @@
|
|||
]
|
||||
},
|
||||
"condition": {
|
||||
"description": "question: When should this item be shown?\ntype: tag\nifunset: No specific condition set; always show this tagRendering or ask the question if unkown\n\nOnly show this tagrendering (or ask the question) if the selected object also matches the tags specified as `condition`.\n\nThis is useful to ask a follow-up question.\nFor example, within toilets, asking _where_ the diaper changing table is is only useful _if_ there is one.\nThis can be done by adding `\"condition\": \"changing_table=yes\"`\n\nA full example would be:\n```json\n {\n \"question\": \"Where is the changing table located?\",\n \"render\": \"The changing table is located at {changing_table:location}\",\n \"condition\": \"changing_table=yes\",\n \"freeform\": {\n \"key\": \"changing_table:location\",\n \"inline\": true\n },\n \"mappings\": [\n {\n \"then\": \"The changing table is in the toilet for women.\",\n \"if\": \"changing_table:location=female_toilet\"\n },\n {\n \"then\": \"The changing table is in the toilet for men.\",\n \"if\": \"changing_table:location=male_toilet\"\n },\n {\n \"if\": \"changing_table:location=wheelchair_toilet\",\n \"then\": \"The changing table is in the toilet for wheelchair users.\",\n },\n {\n \"if\": \"changing_table:location=dedicated_room\",\n \"then\": \"The changing table is in a dedicated room. \",\n }\n ],\n \"id\": \"toilet-changing_table:location\"\n },\n```",
|
||||
"description": "question: When should this item be shown?\ntype: tag\nifunset: No specific condition set; always show this tagRendering or show this question if unknown\n\nOnly show this tagrendering (or ask the question) if the selected object also matches the tags specified as `condition`.\n\nThis is useful to ask a follow-up question.\nFor example, within toilets, asking _where_ the diaper changing table is is only useful _if_ there is one.\nThis can be done by adding `\"condition\": \"changing_table=yes\"`\n\nA full example would be:\n```json\n {\n \"question\": \"Where is the changing table located?\",\n \"render\": \"The changing table is located at {changing_table:location}\",\n \"condition\": \"changing_table=yes\",\n \"freeform\": {\n \"key\": \"changing_table:location\",\n \"inline\": true\n },\n \"mappings\": [\n {\n \"then\": \"The changing table is in the toilet for women.\",\n \"if\": \"changing_table:location=female_toilet\"\n },\n {\n \"then\": \"The changing table is in the toilet for men.\",\n \"if\": \"changing_table:location=male_toilet\"\n },\n {\n \"if\": \"changing_table:location=wheelchair_toilet\",\n \"then\": \"The changing table is in the toilet for wheelchair users.\",\n },\n {\n \"if\": \"changing_table:location=dedicated_room\",\n \"then\": \"The changing table is in a dedicated room. \",\n }\n ],\n \"id\": \"toilet-changing_table:location\"\n },\n```",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/{and:TagConfigJson[];}"
|
||||
|
@ -7870,7 +7880,7 @@
|
|||
]
|
||||
},
|
||||
"metacondition": {
|
||||
"description": "question: When should this item be shown (including special conditions)?\ntype: tag\n\nIf set, this tag will be evaluated agains the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options.\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_",
|
||||
"description": "question: When should this item be shown (including special conditions)?\ntype: tag\nifunset: No specific metacondition set which is evaluated against the <i>usersettings/application state</i>; always show this tagRendering or show this question if unknown\n\nIf set, this tag will be evaluated against the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options (at the settings-tab).\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/{and:TagConfigJson[];}"
|
||||
|
@ -8092,7 +8102,7 @@
|
|||
"hints": {
|
||||
"typehint": "tag",
|
||||
"question": "When should this item be shown?",
|
||||
"ifunset": "No specific condition set; always show this tagRendering or ask the question if unkown"
|
||||
"ifunset": "No specific condition set; always show this tagRendering or show this question if unknown"
|
||||
},
|
||||
"type": [
|
||||
{
|
||||
|
@ -8186,7 +8196,8 @@
|
|||
"required": false,
|
||||
"hints": {
|
||||
"typehint": "tag",
|
||||
"question": "When should this item be shown (including special conditions)?"
|
||||
"question": "When should this item be shown (including special conditions)?",
|
||||
"ifunset": "No specific metacondition set which is evaluated against the <i>usersettings/application state</i>; always show this tagRendering or show this question if unknown"
|
||||
},
|
||||
"type": [
|
||||
{
|
||||
|
@ -8199,7 +8210,7 @@
|
|||
"type": "string"
|
||||
}
|
||||
],
|
||||
"description": "If set, this tag will be evaluated agains the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options.\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_"
|
||||
"description": "If set, this tag will be evaluated against the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options (at the settings-tab).\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_"
|
||||
},
|
||||
{
|
||||
"path": [
|
||||
|
@ -8550,7 +8561,7 @@
|
|||
]
|
||||
},
|
||||
"condition": {
|
||||
"description": "question: When should this item be shown?\ntype: tag\nifunset: No specific condition set; always show this tagRendering or ask the question if unkown\n\nOnly show this tagrendering (or ask the question) if the selected object also matches the tags specified as `condition`.\n\nThis is useful to ask a follow-up question.\nFor example, within toilets, asking _where_ the diaper changing table is is only useful _if_ there is one.\nThis can be done by adding `\"condition\": \"changing_table=yes\"`\n\nA full example would be:\n```json\n {\n \"question\": \"Where is the changing table located?\",\n \"render\": \"The changing table is located at {changing_table:location}\",\n \"condition\": \"changing_table=yes\",\n \"freeform\": {\n \"key\": \"changing_table:location\",\n \"inline\": true\n },\n \"mappings\": [\n {\n \"then\": \"The changing table is in the toilet for women.\",\n \"if\": \"changing_table:location=female_toilet\"\n },\n {\n \"then\": \"The changing table is in the toilet for men.\",\n \"if\": \"changing_table:location=male_toilet\"\n },\n {\n \"if\": \"changing_table:location=wheelchair_toilet\",\n \"then\": \"The changing table is in the toilet for wheelchair users.\",\n },\n {\n \"if\": \"changing_table:location=dedicated_room\",\n \"then\": \"The changing table is in a dedicated room. \",\n }\n ],\n \"id\": \"toilet-changing_table:location\"\n },\n```",
|
||||
"description": "question: When should this item be shown?\ntype: tag\nifunset: No specific condition set; always show this tagRendering or show this question if unknown\n\nOnly show this tagrendering (or ask the question) if the selected object also matches the tags specified as `condition`.\n\nThis is useful to ask a follow-up question.\nFor example, within toilets, asking _where_ the diaper changing table is is only useful _if_ there is one.\nThis can be done by adding `\"condition\": \"changing_table=yes\"`\n\nA full example would be:\n```json\n {\n \"question\": \"Where is the changing table located?\",\n \"render\": \"The changing table is located at {changing_table:location}\",\n \"condition\": \"changing_table=yes\",\n \"freeform\": {\n \"key\": \"changing_table:location\",\n \"inline\": true\n },\n \"mappings\": [\n {\n \"then\": \"The changing table is in the toilet for women.\",\n \"if\": \"changing_table:location=female_toilet\"\n },\n {\n \"then\": \"The changing table is in the toilet for men.\",\n \"if\": \"changing_table:location=male_toilet\"\n },\n {\n \"if\": \"changing_table:location=wheelchair_toilet\",\n \"then\": \"The changing table is in the toilet for wheelchair users.\",\n },\n {\n \"if\": \"changing_table:location=dedicated_room\",\n \"then\": \"The changing table is in a dedicated room. \",\n }\n ],\n \"id\": \"toilet-changing_table:location\"\n },\n```",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/{and:TagConfigJson[];}"
|
||||
|
@ -8564,7 +8575,7 @@
|
|||
]
|
||||
},
|
||||
"metacondition": {
|
||||
"description": "question: When should this item be shown (including special conditions)?\ntype: tag\n\nIf set, this tag will be evaluated agains the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options.\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_",
|
||||
"description": "question: When should this item be shown (including special conditions)?\ntype: tag\nifunset: No specific metacondition set which is evaluated against the <i>usersettings/application state</i>; always show this tagRendering or show this question if unknown\n\nIf set, this tag will be evaluated against the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options (at the settings-tab).\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/{and:TagConfigJson[];}"
|
||||
|
@ -8786,7 +8797,7 @@
|
|||
"hints": {
|
||||
"typehint": "tag",
|
||||
"question": "When should this item be shown?",
|
||||
"ifunset": "No specific condition set; always show this tagRendering or ask the question if unkown"
|
||||
"ifunset": "No specific condition set; always show this tagRendering or show this question if unknown"
|
||||
},
|
||||
"type": [
|
||||
{
|
||||
|
@ -8880,7 +8891,8 @@
|
|||
"required": false,
|
||||
"hints": {
|
||||
"typehint": "tag",
|
||||
"question": "When should this item be shown (including special conditions)?"
|
||||
"question": "When should this item be shown (including special conditions)?",
|
||||
"ifunset": "No specific metacondition set which is evaluated against the <i>usersettings/application state</i>; always show this tagRendering or show this question if unknown"
|
||||
},
|
||||
"type": [
|
||||
{
|
||||
|
@ -8893,7 +8905,7 @@
|
|||
"type": "string"
|
||||
}
|
||||
],
|
||||
"description": "If set, this tag will be evaluated agains the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options.\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_"
|
||||
"description": "If set, this tag will be evaluated against the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options (at the settings-tab).\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_"
|
||||
},
|
||||
{
|
||||
"path": [
|
||||
|
@ -9965,7 +9977,7 @@
|
|||
"group": "presets"
|
||||
},
|
||||
"type": "array",
|
||||
"description": "<div class='flex'>\n <div>\nPresets for this layer.\nA preset consists of one or more attributes (tags), a title and optionally a description and optionally example images.\nWhen the contributor wishes to add a point to OpenStreetMap, they'll:\n1. Press the 'add new point'-button\n2. Choose a preset from the list of all presets\n3. Confirm the choice. In this step, the `description` (if set) and `exampleImages` (if given) will be shown\n4. Confirm the location\n5. A new point will be created with the attributes that were defined in the preset\nIf no presets are defined, the button which invites to add a new preset will not be shown.\n</div>\n<a class='block m-2 min-w-64' href='./Docs/Screenshots/AddNewItemScreencast.webm' target='_blank'> <video controls autoplay muted src='./Docs/Screenshots/AddNewItemScreencast.webm' class='w-64'/></a>\n</div>"
|
||||
"description": "<div class='flex'>\n <div>\nPresets for this layer.\nA preset consists of one or more attributes (tags), a title and optionally a description and optionally example images.\nWhen the contributor wishes to add a point to OpenStreetMap, they'll:\n1. Press the 'add new point'-button\n2. Choose a preset from the list of all presets\n3. Confirm the choice. In this step, the `description` (if set) and `exampleImages` (if given) will be shown\n4. Confirm the location\n5. A new point will be created with the attributes that were defined in the preset\nIf no presets are defined, the button which invites to add a new preset will not be shown.\n</div>\n<video controls autoplay muted src='./Docs/Screenshots/AddNewItemScreencast.webm' class='w-64'/>\n</div>"
|
||||
},
|
||||
{
|
||||
"path": [
|
||||
|
@ -10724,7 +10736,7 @@
|
|||
"type": "string"
|
||||
},
|
||||
"placeholder": {
|
||||
"description": "question: What placeholder text should be shown in the input-element if there is no input?\nA (translated) text that is shown (as gray text) within the textfield\ntype: translation\ngroup: expert",
|
||||
"description": "question: What placeholder text should be shown in the input-element if there is no input?\nA (translated) text that is shown (as gray text) within the textfield\ntype: translation\ngroup: expert\nifunset: No specific placeholder is set, show the type of the textfield",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/Record<string,string>"
|
||||
|
@ -10872,7 +10884,7 @@
|
|||
]
|
||||
},
|
||||
"condition": {
|
||||
"description": "question: When should this item be shown?\ntype: tag\nifunset: No specific condition set; always show this tagRendering or ask the question if unkown\n\nOnly show this tagrendering (or ask the question) if the selected object also matches the tags specified as `condition`.\n\nThis is useful to ask a follow-up question.\nFor example, within toilets, asking _where_ the diaper changing table is is only useful _if_ there is one.\nThis can be done by adding `\"condition\": \"changing_table=yes\"`\n\nA full example would be:\n```json\n {\n \"question\": \"Where is the changing table located?\",\n \"render\": \"The changing table is located at {changing_table:location}\",\n \"condition\": \"changing_table=yes\",\n \"freeform\": {\n \"key\": \"changing_table:location\",\n \"inline\": true\n },\n \"mappings\": [\n {\n \"then\": \"The changing table is in the toilet for women.\",\n \"if\": \"changing_table:location=female_toilet\"\n },\n {\n \"then\": \"The changing table is in the toilet for men.\",\n \"if\": \"changing_table:location=male_toilet\"\n },\n {\n \"if\": \"changing_table:location=wheelchair_toilet\",\n \"then\": \"The changing table is in the toilet for wheelchair users.\",\n },\n {\n \"if\": \"changing_table:location=dedicated_room\",\n \"then\": \"The changing table is in a dedicated room. \",\n }\n ],\n \"id\": \"toilet-changing_table:location\"\n },\n```",
|
||||
"description": "question: When should this item be shown?\ntype: tag\nifunset: No specific condition set; always show this tagRendering or show this question if unknown\n\nOnly show this tagrendering (or ask the question) if the selected object also matches the tags specified as `condition`.\n\nThis is useful to ask a follow-up question.\nFor example, within toilets, asking _where_ the diaper changing table is is only useful _if_ there is one.\nThis can be done by adding `\"condition\": \"changing_table=yes\"`\n\nA full example would be:\n```json\n {\n \"question\": \"Where is the changing table located?\",\n \"render\": \"The changing table is located at {changing_table:location}\",\n \"condition\": \"changing_table=yes\",\n \"freeform\": {\n \"key\": \"changing_table:location\",\n \"inline\": true\n },\n \"mappings\": [\n {\n \"then\": \"The changing table is in the toilet for women.\",\n \"if\": \"changing_table:location=female_toilet\"\n },\n {\n \"then\": \"The changing table is in the toilet for men.\",\n \"if\": \"changing_table:location=male_toilet\"\n },\n {\n \"if\": \"changing_table:location=wheelchair_toilet\",\n \"then\": \"The changing table is in the toilet for wheelchair users.\",\n },\n {\n \"if\": \"changing_table:location=dedicated_room\",\n \"then\": \"The changing table is in a dedicated room. \",\n }\n ],\n \"id\": \"toilet-changing_table:location\"\n },\n```",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/{and:TagConfigJson[];}"
|
||||
|
@ -10886,7 +10898,7 @@
|
|||
]
|
||||
},
|
||||
"metacondition": {
|
||||
"description": "question: When should this item be shown (including special conditions)?\ntype: tag\n\nIf set, this tag will be evaluated agains the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options.\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_",
|
||||
"description": "question: When should this item be shown (including special conditions)?\ntype: tag\nifunset: No specific metacondition set which is evaluated against the <i>usersettings/application state</i>; always show this tagRendering or show this question if unknown\n\nIf set, this tag will be evaluated against the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options (at the settings-tab).\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/{and:TagConfigJson[];}"
|
||||
|
@ -11675,7 +11687,8 @@
|
|||
"hints": {
|
||||
"typehint": "translation",
|
||||
"group": "expert",
|
||||
"question": "What placeholder text should be shown in the input-element if there is no input?"
|
||||
"question": "What placeholder text should be shown in the input-element if there is no input?",
|
||||
"ifunset": "No specific placeholder is set, show the type of the textfield"
|
||||
},
|
||||
"type": [
|
||||
{
|
||||
|
@ -12020,7 +12033,7 @@
|
|||
"hints": {
|
||||
"typehint": "tag",
|
||||
"question": "When should this item be shown?",
|
||||
"ifunset": "No specific condition set; always show this tagRendering or ask the question if unkown"
|
||||
"ifunset": "No specific condition set; always show this tagRendering or show this question if unknown"
|
||||
},
|
||||
"type": [
|
||||
{
|
||||
|
@ -12111,7 +12124,8 @@
|
|||
"required": false,
|
||||
"hints": {
|
||||
"typehint": "tag",
|
||||
"question": "When should this item be shown (including special conditions)?"
|
||||
"question": "When should this item be shown (including special conditions)?",
|
||||
"ifunset": "No specific metacondition set which is evaluated against the <i>usersettings/application state</i>; always show this tagRendering or show this question if unknown"
|
||||
},
|
||||
"type": [
|
||||
{
|
||||
|
@ -12124,7 +12138,7 @@
|
|||
"type": "string"
|
||||
}
|
||||
],
|
||||
"description": "If set, this tag will be evaluated agains the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options.\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_"
|
||||
"description": "If set, this tag will be evaluated against the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options (at the settings-tab).\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_"
|
||||
},
|
||||
{
|
||||
"path": [
|
||||
|
@ -12952,7 +12966,8 @@
|
|||
"hints": {
|
||||
"typehint": "translation",
|
||||
"group": "expert",
|
||||
"question": "What placeholder text should be shown in the input-element if there is no input?"
|
||||
"question": "What placeholder text should be shown in the input-element if there is no input?",
|
||||
"ifunset": "No specific placeholder is set, show the type of the textfield"
|
||||
},
|
||||
"type": [
|
||||
{
|
||||
|
@ -13313,7 +13328,7 @@
|
|||
"hints": {
|
||||
"typehint": "tag",
|
||||
"question": "When should this item be shown?",
|
||||
"ifunset": "No specific condition set; always show this tagRendering or ask the question if unkown"
|
||||
"ifunset": "No specific condition set; always show this tagRendering or show this question if unknown"
|
||||
},
|
||||
"type": [
|
||||
{
|
||||
|
@ -13407,7 +13422,8 @@
|
|||
"required": false,
|
||||
"hints": {
|
||||
"typehint": "tag",
|
||||
"question": "When should this item be shown (including special conditions)?"
|
||||
"question": "When should this item be shown (including special conditions)?",
|
||||
"ifunset": "No specific metacondition set which is evaluated against the <i>usersettings/application state</i>; always show this tagRendering or show this question if unknown"
|
||||
},
|
||||
"type": [
|
||||
{
|
||||
|
@ -13420,7 +13436,7 @@
|
|||
"type": "string"
|
||||
}
|
||||
],
|
||||
"description": "If set, this tag will be evaluated agains the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options.\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_"
|
||||
"description": "If set, this tag will be evaluated against the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options (at the settings-tab).\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_"
|
||||
},
|
||||
{
|
||||
"path": [
|
||||
|
@ -14261,7 +14277,8 @@
|
|||
"hints": {
|
||||
"typehint": "translation",
|
||||
"group": "expert",
|
||||
"question": "What placeholder text should be shown in the input-element if there is no input?"
|
||||
"question": "What placeholder text should be shown in the input-element if there is no input?",
|
||||
"ifunset": "No specific placeholder is set, show the type of the textfield"
|
||||
},
|
||||
"type": [
|
||||
{
|
||||
|
@ -14622,7 +14639,7 @@
|
|||
"hints": {
|
||||
"typehint": "tag",
|
||||
"question": "When should this item be shown?",
|
||||
"ifunset": "No specific condition set; always show this tagRendering or ask the question if unkown"
|
||||
"ifunset": "No specific condition set; always show this tagRendering or show this question if unknown"
|
||||
},
|
||||
"type": [
|
||||
{
|
||||
|
@ -14716,7 +14733,8 @@
|
|||
"required": false,
|
||||
"hints": {
|
||||
"typehint": "tag",
|
||||
"question": "When should this item be shown (including special conditions)?"
|
||||
"question": "When should this item be shown (including special conditions)?",
|
||||
"ifunset": "No specific metacondition set which is evaluated against the <i>usersettings/application state</i>; always show this tagRendering or show this question if unknown"
|
||||
},
|
||||
"type": [
|
||||
{
|
||||
|
@ -14729,7 +14747,7 @@
|
|||
"type": "string"
|
||||
}
|
||||
],
|
||||
"description": "If set, this tag will be evaluated agains the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options.\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_"
|
||||
"description": "If set, this tag will be evaluated against the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options (at the settings-tab).\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_"
|
||||
},
|
||||
{
|
||||
"path": [
|
||||
|
@ -15587,7 +15605,8 @@
|
|||
"hints": {
|
||||
"typehint": "translation",
|
||||
"group": "expert",
|
||||
"question": "What placeholder text should be shown in the input-element if there is no input?"
|
||||
"question": "What placeholder text should be shown in the input-element if there is no input?",
|
||||
"ifunset": "No specific placeholder is set, show the type of the textfield"
|
||||
},
|
||||
"type": [
|
||||
{
|
||||
|
@ -15964,7 +15983,7 @@
|
|||
"hints": {
|
||||
"typehint": "tag",
|
||||
"question": "When should this item be shown?",
|
||||
"ifunset": "No specific condition set; always show this tagRendering or ask the question if unkown"
|
||||
"ifunset": "No specific condition set; always show this tagRendering or show this question if unknown"
|
||||
},
|
||||
"type": [
|
||||
{
|
||||
|
@ -16061,7 +16080,8 @@
|
|||
"required": false,
|
||||
"hints": {
|
||||
"typehint": "tag",
|
||||
"question": "When should this item be shown (including special conditions)?"
|
||||
"question": "When should this item be shown (including special conditions)?",
|
||||
"ifunset": "No specific metacondition set which is evaluated against the <i>usersettings/application state</i>; always show this tagRendering or show this question if unknown"
|
||||
},
|
||||
"type": [
|
||||
{
|
||||
|
@ -16074,7 +16094,7 @@
|
|||
"type": "string"
|
||||
}
|
||||
],
|
||||
"description": "If set, this tag will be evaluated agains the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options.\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_"
|
||||
"description": "If set, this tag will be evaluated against the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options (at the settings-tab).\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_"
|
||||
},
|
||||
{
|
||||
"path": [
|
||||
|
@ -16910,7 +16930,8 @@
|
|||
"hints": {
|
||||
"typehint": "translation",
|
||||
"group": "expert",
|
||||
"question": "What placeholder text should be shown in the input-element if there is no input?"
|
||||
"question": "What placeholder text should be shown in the input-element if there is no input?",
|
||||
"ifunset": "No specific placeholder is set, show the type of the textfield"
|
||||
},
|
||||
"type": [
|
||||
{
|
||||
|
@ -17271,7 +17292,7 @@
|
|||
"hints": {
|
||||
"typehint": "tag",
|
||||
"question": "When should this item be shown?",
|
||||
"ifunset": "No specific condition set; always show this tagRendering or ask the question if unkown"
|
||||
"ifunset": "No specific condition set; always show this tagRendering or show this question if unknown"
|
||||
},
|
||||
"type": [
|
||||
{
|
||||
|
@ -17365,7 +17386,8 @@
|
|||
"required": false,
|
||||
"hints": {
|
||||
"typehint": "tag",
|
||||
"question": "When should this item be shown (including special conditions)?"
|
||||
"question": "When should this item be shown (including special conditions)?",
|
||||
"ifunset": "No specific metacondition set which is evaluated against the <i>usersettings/application state</i>; always show this tagRendering or show this question if unknown"
|
||||
},
|
||||
"type": [
|
||||
{
|
||||
|
@ -17378,7 +17400,7 @@
|
|||
"type": "string"
|
||||
}
|
||||
],
|
||||
"description": "If set, this tag will be evaluated agains the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options.\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_"
|
||||
"description": "If set, this tag will be evaluated against the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options (at the settings-tab).\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_"
|
||||
},
|
||||
{
|
||||
"path": [
|
||||
|
@ -18236,7 +18258,8 @@
|
|||
"hints": {
|
||||
"typehint": "translation",
|
||||
"group": "expert",
|
||||
"question": "What placeholder text should be shown in the input-element if there is no input?"
|
||||
"question": "What placeholder text should be shown in the input-element if there is no input?",
|
||||
"ifunset": "No specific placeholder is set, show the type of the textfield"
|
||||
},
|
||||
"type": [
|
||||
{
|
||||
|
@ -18613,7 +18636,7 @@
|
|||
"hints": {
|
||||
"typehint": "tag",
|
||||
"question": "When should this item be shown?",
|
||||
"ifunset": "No specific condition set; always show this tagRendering or ask the question if unkown"
|
||||
"ifunset": "No specific condition set; always show this tagRendering or show this question if unknown"
|
||||
},
|
||||
"type": [
|
||||
{
|
||||
|
@ -18710,7 +18733,8 @@
|
|||
"required": false,
|
||||
"hints": {
|
||||
"typehint": "tag",
|
||||
"question": "When should this item be shown (including special conditions)?"
|
||||
"question": "When should this item be shown (including special conditions)?",
|
||||
"ifunset": "No specific metacondition set which is evaluated against the <i>usersettings/application state</i>; always show this tagRendering or show this question if unknown"
|
||||
},
|
||||
"type": [
|
||||
{
|
||||
|
@ -18723,7 +18747,7 @@
|
|||
"type": "string"
|
||||
}
|
||||
],
|
||||
"description": "If set, this tag will be evaluated agains the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options.\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_"
|
||||
"description": "If set, this tag will be evaluated against the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options (at the settings-tab).\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_"
|
||||
},
|
||||
{
|
||||
"path": [
|
||||
|
@ -19442,10 +19466,10 @@
|
|||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/Record<string,string|{quantity:string;denominations:string[];canonical?:string|undefined;}>"
|
||||
"$ref": "#/definitions/Record<string,string|{quantity:string;denominations:string[];canonical?:string|undefined;inverted?:boolean|undefined;}>"
|
||||
}
|
||||
],
|
||||
"description": "Either a list with [{\"key\": \"unitname\", \"key2\": {\"quantity\": \"unitname\", \"denominations\": [\"denom\", \"denom\"]}}]"
|
||||
"description": "Either a list with [{\"key\": \"unitname\", \"key2\": {\"quantity\": \"unitname\", \"denominations\": [\"denom\", \"denom\"]}}]\nUse `\"inverted\": true` if the amount should be _divided_ by the denomination, e.g. for charge over time (`€5/day`)"
|
||||
},
|
||||
{
|
||||
"path": [
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -683,7 +683,8 @@
|
|||
"hints": {
|
||||
"typehint": "translation",
|
||||
"group": "expert",
|
||||
"question": "What placeholder text should be shown in the input-element if there is no input?"
|
||||
"question": "What placeholder text should be shown in the input-element if there is no input?",
|
||||
"ifunset": "No specific placeholder is set, show the type of the textfield"
|
||||
},
|
||||
"type": [
|
||||
{
|
||||
|
@ -1012,7 +1013,7 @@
|
|||
"hints": {
|
||||
"typehint": "tag",
|
||||
"question": "When should this item be shown?",
|
||||
"ifunset": "No specific condition set; always show this tagRendering or ask the question if unkown"
|
||||
"ifunset": "No specific condition set; always show this tagRendering or show this question if unknown"
|
||||
},
|
||||
"type": [
|
||||
{
|
||||
|
@ -1100,7 +1101,8 @@
|
|||
"required": false,
|
||||
"hints": {
|
||||
"typehint": "tag",
|
||||
"question": "When should this item be shown (including special conditions)?"
|
||||
"question": "When should this item be shown (including special conditions)?",
|
||||
"ifunset": "No specific metacondition set which is evaluated against the <i>usersettings/application state</i>; always show this tagRendering or show this question if unknown"
|
||||
},
|
||||
"type": [
|
||||
{
|
||||
|
@ -1113,7 +1115,7 @@
|
|||
"type": "string"
|
||||
}
|
||||
],
|
||||
"description": "If set, this tag will be evaluated agains the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options.\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_"
|
||||
"description": "If set, this tag will be evaluated against the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options (at the settings-tab).\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_"
|
||||
},
|
||||
{
|
||||
"path": [
|
||||
|
|
|
@ -115,7 +115,7 @@
|
|||
"hints": {
|
||||
"typehint": "tag",
|
||||
"question": "When should this item be shown?",
|
||||
"ifunset": "No specific condition set; always show this tagRendering or ask the question if unkown"
|
||||
"ifunset": "No specific condition set; always show this tagRendering or show this question if unknown"
|
||||
},
|
||||
"type": [
|
||||
{
|
||||
|
@ -203,7 +203,8 @@
|
|||
"required": false,
|
||||
"hints": {
|
||||
"typehint": "tag",
|
||||
"question": "When should this item be shown (including special conditions)?"
|
||||
"question": "When should this item be shown (including special conditions)?",
|
||||
"ifunset": "No specific metacondition set which is evaluated against the <i>usersettings/application state</i>; always show this tagRendering or show this question if unknown"
|
||||
},
|
||||
"type": [
|
||||
{
|
||||
|
@ -216,7 +217,7 @@
|
|||
"type": "string"
|
||||
}
|
||||
],
|
||||
"description": "If set, this tag will be evaluated agains the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options.\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_"
|
||||
"description": "If set, this tag will be evaluated against the _usersettings/application state_ table.\nEnable 'show debug info' in user settings to see available options (at the settings-tab).\nNote that values with an underscore depicts _application state_ (including metainfo about the user) whereas values without an underscore depict _user settings_"
|
||||
},
|
||||
{
|
||||
"path": [
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
import SvelteUIElement from "./UI/Base/SvelteUIElement"
|
||||
import Test from "./UI/Test.svelte"
|
||||
import NameSuggestionIndex from "./Logic/Web/NameSuggestionIndex"
|
||||
|
||||
const nsi = NameSuggestionIndex.get()
|
||||
const secondhandshops = nsi.getSuggestionsFor("brands/shop/second_hand", ["be"])
|
||||
console.log(secondhandshops)
|
||||
new SvelteUIElement(Test).AttachTo("maindiv")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue