chore: automated housekeeping...

This commit is contained in:
Pieter Vander Vennet 2025-01-02 15:34:59 +01:00
parent 432122c7a0
commit 2f53b55faa
268 changed files with 5707 additions and 3555 deletions

View file

@ -48,13 +48,17 @@ export class OsmPreferences {
private setPreferencesAll(key: string, value: string, deferping = false) {
if (this._allPreferences.data[key] !== value) {
this._allPreferences.data[key] = value
if(!deferping){
if (!deferping) {
this._allPreferences.ping()
}
}
}
private initPreference(key: string, value: string = undefined, deferPing = false): UIEventSource<string> {
private initPreference(
key: string,
value: string = undefined,
deferPing = false
): UIEventSource<string> {
if (this.preferences[key] !== undefined) {
if (value !== undefined) {
this.preferences[key].set(value)

View file

@ -53,10 +53,7 @@ export interface NSIItem {
}
export default class NameSuggestionIndex {
public static readonly supportedTypes = ["brand",
"flag",
"operator",
"transit"] as const
public static readonly supportedTypes = ["brand", "flag", "operator", "transit"] as const
private readonly nsiFile: Readonly<NSIFile>
private readonly nsiWdFile: Readonly<
Record<
@ -71,13 +68,17 @@ export default class NameSuggestionIndex {
private _supportedTypes: string[]
constructor(nsiFile: Readonly<NSIFile>, nsiWdFile: Readonly<
Record<
string,
{
logos: { wikidata?: string; facebook?: string }
}
>>) {
constructor(
nsiFile: Readonly<NSIFile>,
nsiWdFile: Readonly<
Record<
string,
{
logos: { wikidata?: string; facebook?: string }
}
>
>
) {
this.nsiFile = nsiFile
this.nsiWdFile = nsiWdFile
}
@ -88,7 +89,11 @@ export default class NameSuggestionIndex {
if (NameSuggestionIndex.inited) {
return NameSuggestionIndex.inited
}
const [nsi, nsiWd] = await Promise.all(["assets/data/nsi/nsi.json", "assets/data/nsi/wikidata.min.json"].map(url => Utils.downloadJsonCached(url, 1000 * 60 * 60 * 24 * 30)))
const [nsi, nsiWd] = await Promise.all(
["assets/data/nsi/nsi.json", "assets/data/nsi/wikidata.min.json"].map((url) =>
Utils.downloadJsonCached(url, 1000 * 60 * 60 * 24 * 30)
)
)
NameSuggestionIndex.inited = new NameSuggestionIndex(<any>nsi, <any>nsiWd["wikidata"])
return NameSuggestionIndex.inited
}
@ -98,9 +103,7 @@ export default class NameSuggestionIndex {
return this._supportedTypes
}
const keys = Object.keys(this.nsiFile.nsi)
const all = keys.map(
(k) => this.nsiFile.nsi[k].properties.path.split("/")[0],
)
const all = keys.map((k) => this.nsiFile.nsi[k].properties.path.split("/")[0])
this._supportedTypes = Utils.Dedup(all).map((s) => {
if (s.endsWith("s")) {
s = s.substring(0, s.length - 1)
@ -122,13 +125,13 @@ export default class NameSuggestionIndex {
try {
return Utils.downloadJsonCached<Record<string, number>>(
`./assets/data/nsi/stats/${type}.${c.toUpperCase()}.json`,
24 * 60 * 60 * 1000,
24 * 60 * 60 * 1000
)
} catch (e) {
console.error("Could not fetch " + type + " statistics due to", e)
return undefined
}
}),
})
)
stats = Utils.NoNull(stats)
if (stats.length === 1) {
@ -148,7 +151,9 @@ export default class NameSuggestionIndex {
public isSvg(nsiItem: NSIItem, type: string): boolean | undefined {
if (this.nsiWdFile === undefined) {
throw "nsiWdi file is not loaded, cannot determine if " + nsiItem.id + " has an SVG image"
throw (
"nsiWdi file is not loaded, cannot determine if " + nsiItem.id + " has an SVG image"
)
}
const logos = this.nsiWdFile[nsiItem?.tags?.[type + ":wikidata"]]?.logos
if (!logos) {
@ -174,7 +179,7 @@ export default class NameSuggestionIndex {
* If set, sort by frequency instead of alphabetically
*/
sortByFrequency: boolean
},
}
): Promise<Mapping[]> {
const mappings: (Mapping & { frequency: number })[] = []
const frequencies = await NameSuggestionIndex.fetchFrequenciesFor(type, country)
@ -188,7 +193,7 @@ export default class NameSuggestionIndex {
key,
value,
country.join(";"),
location,
location
)
if (!actualBrands) {
continue
@ -234,7 +239,7 @@ export default class NameSuggestionIndex {
}
public supportedTags(
type: "operator" | "brand" | "flag" | "transit" | string,
type: "operator" | "brand" | "flag" | "transit" | string
): Record<string, string[]> {
const tags: Record<string, string[]> = {}
const keys = Object.keys(this.nsiFile.nsi)
@ -279,10 +284,10 @@ export default class NameSuggestionIndex {
type: string,
tags: { key: string; value: string }[],
country: string = undefined,
location: [number, number] = undefined,
location: [number, number] = undefined
): NSIItem[] {
return tags.flatMap((tag) =>
this.getSuggestionsForKV(type, tag.key, tag.value, country, location),
this.getSuggestionsForKV(type, tag.key, tag.value, country, location)
)
}
@ -305,7 +310,7 @@ export default class NameSuggestionIndex {
key: string,
value: string,
country: string = undefined,
location: [number, number] = undefined,
location: [number, number] = undefined
): NSIItem[] {
const path = `${type}s/${key}/${value}`
const entry = this.nsiFile.nsi[path]
@ -362,9 +367,15 @@ export default class NameSuggestionIndex {
})
}
public static async generateMappings(key: string, tags: Exclude<Record<string, string>, undefined | null>, country: string[], center: [number, number], options: {
sortByFrequency: boolean
}): Promise<Mapping[]> {
public static async generateMappings(
key: string,
tags: Exclude<Record<string, string>, undefined | null>,
country: string[],
center: [number, number],
options: {
sortByFrequency: boolean
}
): Promise<Mapping[]> {
const nsi = await NameSuggestionIndex.getNsiIndex()
return nsi.generateMappings(key, tags, country, center, options)
}

View file

@ -1,7 +1,10 @@
import { DesugaringStep } from "./Conversion"
import { TagRenderingConfigJson } from "../Json/TagRenderingConfigJson"
import { LayerConfigJson } from "../Json/LayerConfigJson"
import { MappingConfigJson, QuestionableTagRenderingConfigJson } from "../Json/QuestionableTagRenderingConfigJson"
import {
MappingConfigJson,
QuestionableTagRenderingConfigJson,
} from "../Json/QuestionableTagRenderingConfigJson"
import { ConversionContext } from "./ConversionContext"
import { Translation } from "../../../UI/i18n/Translation"
import { TagUtils } from "../../../Logic/Tags/TagUtils"
@ -194,10 +197,10 @@ export class MiscTagRenderingChecks extends DesugaringStep<TagRenderingConfigJso
}
if (
this._layerConfig?.source?.["osmTags"] &&
NameSuggestionIndex.supportedTypes.indexOf(<any> json.freeform.key) >= 0
NameSuggestionIndex.supportedTypes.indexOf(<any>json.freeform.key) >= 0
) {
const tags = TagUtils.TagD(this._layerConfig?.source?.["osmTags"])?.usedTags()
/* const suggestions = nameSuggestionIndexBundled.getSuggestionsFor(json.freeform.key, tags)
/* const suggestions = nameSuggestionIndexBundled.getSuggestionsFor(json.freeform.key, tags)
if (suggestions === undefined) {
context
.enters("freeform", "type")

View file

@ -109,7 +109,7 @@ export default class LayerConfig extends WithContextLoader {
mercatorCrs: json.source["mercatorCrs"],
idKey: json.source["idKey"],
},
json.id,
json.id
)
}
@ -129,7 +129,7 @@ export default class LayerConfig extends WithContextLoader {
if (json.calculatedTags !== undefined) {
if (!official) {
console.warn(
`Unofficial theme ${this.id} with custom javascript! This is a security risk`,
`Unofficial theme ${this.id} with custom javascript! This is a security risk`
)
}
this.calculatedTags = []
@ -199,7 +199,7 @@ export default class LayerConfig extends WithContextLoader {
tags: pr.tags.map((t) => TagUtils.SimpleTag(t)),
description: Translations.T(
pr.description,
`${translationContext}.presets.${i}.description`,
`${translationContext}.presets.${i}.description`
),
preciseInput: preciseInput,
exampleImages: pr.exampleImages,
@ -213,7 +213,7 @@ export default class LayerConfig extends WithContextLoader {
if (json.lineRendering) {
this.lineRendering = Utils.NoNull(json.lineRendering).map(
(r, i) => new LineRenderingConfig(r, `${context}[${i}]`),
(r, i) => new LineRenderingConfig(r, `${context}[${i}]`)
)
} else {
this.lineRendering = []
@ -221,7 +221,7 @@ export default class LayerConfig extends WithContextLoader {
if (json.pointRendering) {
this.mapRendering = Utils.NoNull(json.pointRendering).map(
(r, i) => new PointRenderingConfig(r, `${context}[${i}](${this.id})`),
(r, i) => new PointRenderingConfig(r, `${context}[${i}](${this.id})`)
)
} else {
this.mapRendering = []
@ -233,7 +233,7 @@ export default class LayerConfig extends WithContextLoader {
r.location.has("centroid") ||
r.location.has("projected_centerpoint") ||
r.location.has("start") ||
r.location.has("end"),
r.location.has("end")
)
if (
@ -255,7 +255,7 @@ export default class LayerConfig extends WithContextLoader {
Constants.priviliged_layers.indexOf(<any>this.id) < 0 &&
this.source !== null /*library layer*/ &&
!this.source?.geojsonSource?.startsWith(
"https://api.openstreetmap.org/api/0.6/notes.json",
"https://api.openstreetmap.org/api/0.6/notes.json"
)
) {
throw (
@ -274,7 +274,7 @@ export default class LayerConfig extends WithContextLoader {
typeof tr !== "string" &&
tr["builtin"] === undefined &&
tr["id"] === undefined &&
tr["rewrite"] === undefined,
tr["rewrite"] === undefined
) ?? []
if (missingIds?.length > 0 && official) {
console.error("Some tagRenderings of", this.id, "are missing an id:", missingIds)
@ -285,8 +285,8 @@ export default class LayerConfig extends WithContextLoader {
(tr, i) =>
new TagRenderingConfig(
<QuestionableTagRenderingConfigJson>tr,
this.id + ".tagRenderings[" + i + "]",
),
this.id + ".tagRenderings[" + i + "]"
)
)
if (json.units !== undefined && !Array.isArray(json.units)) {
throw (
@ -296,7 +296,7 @@ export default class LayerConfig extends WithContextLoader {
)
}
this.units = (json.units ?? []).flatMap((unitJson, i) =>
Unit.fromJson(unitJson, this.tagRenderings, `${context}.unit[${i}]`),
Unit.fromJson(unitJson, this.tagRenderings, `${context}.unit[${i}]`)
)
if (
@ -358,11 +358,10 @@ export default class LayerConfig extends WithContextLoader {
}
this.popupInFloatover = json.popupInFloatover ?? false
this.baseTags = TagUtils.changeAsProperties(
this.source?.osmTags?.asChange({ id: "node/-1" }) ?? [{ k: "id", v: "node/-1" }],
this.source?.osmTags?.asChange({ id: "node/-1" }) ?? [{ k: "id", v: "node/-1" }]
)
}
public hasDefaultIcon() {
if (this.mapRendering === undefined || this.mapRendering === null) {
return false
@ -378,7 +377,7 @@ export default class LayerConfig extends WithContextLoader {
neededLayer: string
}[] = [],
addedByDefault = false,
canBeIncluded = true,
canBeIncluded = true
): string {
const extraProps: string[] = []
extraProps.push("This layer is shown at zoomlevel **" + this.minzoom + "** and higher")
@ -386,32 +385,32 @@ export default class LayerConfig extends WithContextLoader {
if (canBeIncluded) {
if (addedByDefault) {
extraProps.push(
"**This layer is included automatically in every theme. This layer might contain no points**",
"**This layer is included automatically in every theme. This layer might contain no points**"
)
}
if (this.shownByDefault === false) {
extraProps.push(
"This layer is not visible by default and must be enabled in the filter by the user. ",
"This layer is not visible by default and must be enabled in the filter by the user. "
)
}
if (this.title === undefined) {
extraProps.push(
"Elements don't have a title set and cannot be toggled nor will they show up in the dashboard. If you import this layer in your theme, override `title` to make this toggleable.",
"Elements don't have a title set and cannot be toggled nor will they show up in the dashboard. If you import this layer in your theme, override `title` to make this toggleable."
)
}
if (this.name === undefined && this.shownByDefault === false) {
extraProps.push(
"This layer is not visible by default and the visibility cannot be toggled, effectively resulting in a fully hidden layer. This can be useful, e.g. to calculate some metatags. If you want to render this layer (e.g. for debugging), enable it by setting the URL-parameter layer-<id>=true",
"This layer is not visible by default and the visibility cannot be toggled, effectively resulting in a fully hidden layer. This can be useful, e.g. to calculate some metatags. If you want to render this layer (e.g. for debugging), enable it by setting the URL-parameter layer-<id>=true"
)
}
if (this.name === undefined) {
extraProps.push(
"Not visible in the layer selection by default. If you want to make this layer toggable, override `name`",
"Not visible in the layer selection by default. If you want to make this layer toggable, override `name`"
)
}
if (this.mapRendering.length === 0) {
extraProps.push(
"Not rendered on the map by default. If you want to rendering this on the map, override `mapRenderings`",
"Not rendered on the map by default. If you want to rendering this on the map, override `mapRenderings`"
)
}
@ -421,12 +420,12 @@ export default class LayerConfig extends WithContextLoader {
"<img src='../warning.svg' height='1rem'/>",
"This layer is loaded from an external source, namely ",
"`" + this.source.geojsonSource + "`",
].join("\n\n"),
].join("\n\n")
)
}
} else {
extraProps.push(
"This layer can **not** be included in a theme. It is solely used by [special renderings](SpecialRenderings.md) showing a minimap with custom data.",
"This layer can **not** be included in a theme. It is solely used by [special renderings](SpecialRenderings.md) showing a minimap with custom data."
)
}
@ -436,7 +435,7 @@ export default class LayerConfig extends WithContextLoader {
usingLayer = [
"## Themes using this layer",
MarkdownUtils.list(
(usedInThemes ?? []).map((id) => `[${id}](https://mapcomplete.org/${id})`),
(usedInThemes ?? []).map((id) => `[${id}](https://mapcomplete.org/${id})`)
),
]
} else if (this.source !== null) {
@ -452,7 +451,7 @@ export default class LayerConfig extends WithContextLoader {
" into the layout as it depends on it: ",
dep.reason,
"(" + dep.context + ")",
].join(" "),
].join(" ")
)
}
@ -479,7 +478,7 @@ export default class LayerConfig extends WithContextLoader {
new And(preset.tags).asHumanString(true) +
snaps
)
}),
})
),
]
}
@ -487,8 +486,8 @@ export default class LayerConfig extends WithContextLoader {
for (const revDep of Utils.Dedup(layerIsNeededBy?.get(this.id) ?? [])) {
extraProps.push(
["This layer is needed as dependency for layer", `[${revDep}](#${revDep})`].join(
" ",
),
" "
)
)
}
@ -499,10 +498,10 @@ export default class LayerConfig extends WithContextLoader {
.filter((values) => values.key !== "id")
.map((values) => {
const embedded: string[] = values.values?.map((v) =>
Link.OsmWiki(values.key, v, true).SetClass("mr-2").AsMarkdown(),
Link.OsmWiki(values.key, v, true).SetClass("mr-2").AsMarkdown()
) ?? ["_no preset options defined, or no values in them_"]
const statistics = `https://taghistory.raifer.tech/?#***/${encodeURIComponent(
values.key,
values.key
)}/`
const tagInfo = `https://taginfo.openstreetmap.org/keys/${values.key}#values`
return [
@ -517,7 +516,7 @@ export default class LayerConfig extends WithContextLoader {
: `[${values.type}](../SpecialInputElements.md#${values.type})`,
embedded.join(" "),
]
}),
})
)
let quickOverview: string[] = []
@ -527,7 +526,7 @@ export default class LayerConfig extends WithContextLoader {
"this quick overview is incomplete",
MarkdownUtils.table(
["attribute", "type", "values which are supported by this layer"],
tableRows,
tableRows
),
]
}
@ -561,19 +560,19 @@ export default class LayerConfig extends WithContextLoader {
const parts = neededTags["and"]
tagsDescription.push(
"Elements must match **all** of the following expressions:",
parts.map((p, i) => i + ". " + p.asHumanString(true, false, {})).join("\n"),
parts.map((p, i) => i + ". " + p.asHumanString(true, false, {})).join("\n")
)
} else if (neededTags["or"]) {
const parts = neededTags["or"]
tagsDescription.push(
"Elements must match **any** of the following expressions:",
parts.map((p) => " - " + p.asHumanString(true, false, {})).join("\n"),
parts.map((p) => " - " + p.asHumanString(true, false, {})).join("\n")
)
} else {
tagsDescription.push(
"Elements must match the expression **" +
neededTags.asHumanString(true, false, {}) +
"**",
neededTags.asHumanString(true, false, {}) +
"**"
)
}

View file

@ -999,7 +999,7 @@ export class TagRenderingConfigUtils {
tags: UIEventSource<Record<string, string>>,
feature?: Feature
): Store<TagRenderingConfig> {
const isNSI = NameSuggestionIndex.supportedTypes.indexOf(<any> config.freeform?.key) >= 0
const isNSI = NameSuggestionIndex.supportedTypes.indexOf(<any>config.freeform?.key) >= 0
if (!isNSI) {
return new ImmutableStore(config)
}

View file

@ -89,7 +89,9 @@
}
let officialSearched: Store<MinimalThemeInformation[]> = filtered(
osmConnection.isLoggedIn.map(loggedIn => loggedIn ? officialThemes : officialThemes.filter(th => th.id !== "personal"))
osmConnection.isLoggedIn.map((loggedIn) =>
loggedIn ? officialThemes : officialThemes.filter((th) => th.id !== "personal")
)
)
let hiddenSearched: Store<MinimalThemeInformation[]> = filtered(visitedHiddenThemes)
let customSearched: Store<MinimalThemeInformation[]> = filtered(customThemes)

View file

@ -29,7 +29,6 @@
html?.remove()
uiElement?.Destroy()
})
</script>
{#if isSvelte}

View file

@ -59,7 +59,7 @@
{#if showLayerTitle}
<Checkbox selected={isDisplayed}>
<div class="no-image-background block h-6 w-6" class:opacity-50={!$isDisplayed}>
<DefaultIcon {layer}/>
<DefaultIcon {layer} />
</div>
<Tr t={filteredLayer.layerDef.name} />

View file

@ -57,7 +57,6 @@
<td>
<button class="as-link cursor-pointer" on:click={() => sort("visitedTime")}>
<Tr t={t.time} />
</button>
</td>
<td>
@ -96,7 +95,6 @@
<div slot="header">Labels</div>
{#if $labels.length === 0}
<Tr t={t.noLabels} />
{:else}
{#each $labels as label}
<div class="mx-2">

View file

@ -3,5 +3,5 @@ import InspectorGUI from "./InspectorGUI.svelte"
const target = document.getElementById("main")
target.innerHTML = ""
new InspectorGUI({
target
target,
})

View file

@ -1,6 +1,4 @@
<script lang="ts">
import LayerConfig from "../../Models/ThemeConfig/LayerConfig"
import DynamicIcon from "./DynamicIcon.svelte"
import DynamicMarker from "./DynamicMarker.svelte"
@ -13,13 +11,13 @@
*/
export let layer: LayerConfig
export let properties: Readonly<Record<string, string>> = layer.baseTags
export let clss= ""
export let clss = ""
let tags = new ImmutableStore(properties)
let mapRenderings = layer.mapRendering?.filter((r) => r.location.has("point"))
</script>
{#if mapRenderings?.length > 0}
<div class={"relative block w-full h-full "+clss}>
<div class={"relative block h-full w-full " + clss}>
{#each mapRenderings as mr}
<DynamicMarker marker={mr.marker} rotation={mr.rotation} {tags} />
{/each}

View file

@ -8,7 +8,7 @@
console.log("???")
</script>
<div class="flex flex-col items-center justify-center w-full h-full p-8">
<div class="flex h-full w-full flex-col items-center justify-center p-8">
<div class="flex flex-col items-center">
<World style="height: 200px" />
<h1>
@ -17,8 +17,8 @@
</div>
<BackButton
on:click={() => {
window.location = "index.html"
}}
window.location = "index.html"
}}
>
<div class="flex w-full justify-center">
<Tr t={Translations.t.general.backToIndex} />

View file

@ -95,13 +95,13 @@ export class DeleteFlowState {
if (allByMyself.data === null && useTheInternet) {
// We kickoff the download here as it hasn't yet been downloaded. Note that this is mapped onto 'all by myself' above
UIEventSource.FromPromise(this.objectDownloader
.downloadHistory(id))
UIEventSource.FromPromise(this.objectDownloader.downloadHistory(id))
.mapD((versions) =>
versions.map((version) =>
Number(version.tags["_last_edit:contributor:uid"])
)
).addCallbackAndRunD((hist) => previousEditors.setData(hist))
)
.addCallbackAndRunD((hist) => previousEditors.setData(hist))
}
if (allByMyself.data === true) {

View file

@ -29,7 +29,7 @@
<div class="low-interaction p-2">
<h4 class="my-2 flex">
<div class="no-image-background block h-6 w-6">
<DefaultIcon {layer}/>
<DefaultIcon {layer} />
</div>
<Tr t={layer.name} />
</h4>

View file

@ -64,7 +64,7 @@
<div class="inline-flex items-center">
{#if mapping.icon === "auto"}
<div class="mr-2 h-8 w-8 shrink-0">
<DefaultIcon {layer} properties={getAutoIcon(mapping)}/>
<DefaultIcon {layer} properties={getAutoIcon(mapping)} />
</div>
{:else}
<Marker

View file

@ -340,7 +340,9 @@
.catch(console.error)
}
let disabledInTheme = state.userRelatedState?.getThemeDisabled(state.theme.id, layer?.id) ?? new UIEventSource<string[]>([])
let disabledInTheme =
state.userRelatedState?.getThemeDisabled(state.theme.id, layer?.id) ??
new UIEventSource<string[]>([])
let menuIsOpened = new UIEventSource(false)
function disableQuestion() {

View file

@ -32,7 +32,7 @@
let dynamicConfig = TagRenderingConfigUtils.withNameSuggestionIndex(config, tags, selectedElement)
</script>
{#if $dynamicConfig }
{#if $dynamicConfig}
<TagRenderingQuestion
{tags}
config={$dynamicConfig}

View file

@ -73,7 +73,7 @@
{#if $activeLayers.length === 1}
<FilterToggle on:click={() => enableAllLayers()}>
<div class="h-8 w-8 p-1">
<DefaultIcon layer={$activeLayers[0].layerDef}/>
<DefaultIcon layer={$activeLayers[0].layerDef} />
</div>
<b>
<Tr t={$activeLayers[0].layerDef.name} />
@ -83,7 +83,7 @@
{#each $nonactiveLayers as nonActive (nonActive.layerDef.id)}
<FilterToggle on:click={() => nonActive.isDisplayed.set(true)}>
<div class="h-8 w-8 p-1">
<DefaultIcon layer={nonActive.layerDef}/>
<DefaultIcon layer={nonActive.layerDef} />
</div>
<del class="block-ruby">
<Tr t={nonActive.layerDef.name} />

View file

@ -42,7 +42,7 @@
<div class="flex items-center gap-x-1">
{#if asLayer}
<div class="h-8 w-8 p-1">
<DefaultIcon layer={asLayer}/>
<DefaultIcon layer={asLayer} />
</div>
<b>
<Tr t={asLayer.name} />

View file

@ -63,7 +63,7 @@
<div class="flex w-full items-center gap-y-2 p-2">
{#if layer}
<div class="h-6">
<DefaultIcon {layer} properties={entry.feature.properties} clss="w-6 h-6"/>
<DefaultIcon {layer} properties={entry.feature.properties} clss="w-6 h-6" />
</div>
{:else if entry.category}
<Icon

View file

@ -125,7 +125,7 @@ class NearbyImageVis implements SpecialVisualization {
tags: UIEventSource<Record<string, string>>,
args: string[],
feature: Feature,
layer: LayerConfig,
layer: LayerConfig
): SvelteUIElement {
const isOpen = args[0] === "open"
const readonly = args[1] === "readonly" || args[1] === "yes"
@ -192,7 +192,7 @@ class StealViz implements SpecialVisualization {
selectedElement: otherFeature,
state,
layer,
}),
})
)
}
if (elements.length === 1) {
@ -200,8 +200,8 @@ class StealViz implements SpecialVisualization {
}
return new Combine(elements).SetClass("flex flex-col")
},
[state.indexedFeatures.featuresById],
),
[state.indexedFeatures.featuresById]
)
)
}
@ -253,11 +253,11 @@ class CloseNoteViz implements SpecialVisualization {
public constr(
state: SpecialVisualizationState,
tags: UIEventSource<Record<string, string>>,
args: string[],
args: string[]
): SvelteUIElement {
const { text, icon, idkey, comment, minZoom, zoomButton } = Utils.ParseVisArgs(
this.args,
args,
args
)
return new SvelteUIElement(CloseNoteButton, {
@ -298,7 +298,7 @@ export class QuestionViz implements SpecialVisualization {
tags: UIEventSource<Record<string, string>>,
args: string[],
feature: Feature,
layer: LayerConfig,
layer: LayerConfig
): SvelteUIElement {
const labels = args[0]
?.split(";")
@ -330,7 +330,7 @@ export default class SpecialVisualizations {
for (const specialVisualization of SpecialVisualizations.specialVisualizations) {
SpecialVisualizations.specialVisualisationsDict.set(
specialVisualization.funcName,
specialVisualization,
specialVisualization
)
}
}
@ -350,15 +350,15 @@ export default class SpecialVisualizations {
viz.docs,
viz.args.length > 0
? MarkdownUtils.table(
["name", "default", "description"],
viz.args.map((arg) => {
let defaultArg = arg.defaultValue ?? "_undefined_"
if (defaultArg == "") {
defaultArg = "_empty string_"
}
return [arg.name, defaultArg, arg.doc]
}),
)
["name", "default", "description"],
viz.args.map((arg) => {
let defaultArg = arg.defaultValue ?? "_undefined_"
if (defaultArg == "") {
defaultArg = "_empty string_"
}
return [arg.name, defaultArg, arg.doc]
})
)
: undefined,
"#### Example usage of " + viz.funcName,
"<code>" + example + "</code>",
@ -367,18 +367,18 @@ export default class SpecialVisualizations {
public static constructSpecification(
template: string,
extraMappings: SpecialVisualization[] = [],
extraMappings: SpecialVisualization[] = []
): RenderingSpecification[] {
return SpecialVisualisationUtils.constructSpecification(
template,
SpecialVisualizations.specialVisualisationsDict,
extraMappings,
extraMappings
)
}
public static HelpMessage(): string {
const helpTexts: string[] = SpecialVisualizations.specialVisualizations.map((viz) =>
SpecialVisualizations.DocumentationFor(viz),
SpecialVisualizations.DocumentationFor(viz)
)
const firstPart = new Combine([
@ -411,10 +411,10 @@ export default class SpecialVisualizations {
},
},
null,
" ",
),
" "
)
).SetClass("code"),
"In other words: use `{ \"before\": ..., \"after\": ..., \"special\": {\"type\": ..., \"argname\": ...argvalue...}`. The args are in the `special` block; an argvalue can be a string, a translation or another value. (Refer to class `RewriteSpecial` in case of problems)",
'In other words: use `{ "before": ..., "after": ..., "special": {"type": ..., "argname": ...argvalue...}`. The args are in the `special` block; an argvalue can be a string, a translation or another value. (Refer to class `RewriteSpecial` in case of problems)',
])
.SetClass("flex flex-col")
.AsMarkdown()
@ -452,10 +452,10 @@ export default class SpecialVisualizations {
assignTo: state.userRelatedState.language,
availableLanguages: languages,
preferredLanguages: state.osmConnection.userDetails.map(
(ud) => ud.languages,
(ud) => ud.languages
),
})
}),
})
)
},
},
@ -494,7 +494,7 @@ export default class SpecialVisualizations {
state: SpecialVisualizationState,
tagSource: UIEventSource<Record<string, string>>,
args: string[],
feature: Feature,
feature: Feature
): SvelteUIElement {
return new SvelteUIElement(MinimapViz, { state, args, feature, tagSource })
},
@ -506,7 +506,7 @@ export default class SpecialVisualizations {
constr(
state: SpecialVisualizationState,
tagSource: UIEventSource<Record<string, string>>,
tagSource: UIEventSource<Record<string, string>>
): BaseUIElement {
return new VariableUiElement(
tagSource
@ -516,7 +516,7 @@ export default class SpecialVisualizations {
return new SvelteUIElement(SplitRoadWizard, { id, state })
}
return undefined
}),
})
)
},
},
@ -530,7 +530,7 @@ export default class SpecialVisualizations {
tagSource: UIEventSource<Record<string, string>>,
argument: string[],
feature: Feature,
layer: LayerConfig,
layer: LayerConfig
): BaseUIElement {
if (feature.geometry.type !== "Point") {
return undefined
@ -553,7 +553,7 @@ export default class SpecialVisualizations {
tagSource: UIEventSource<Record<string, string>>,
argument: string[],
feature: Feature,
layer: LayerConfig,
layer: LayerConfig
): BaseUIElement {
if (!layer.deletion) {
return undefined
@ -579,7 +579,7 @@ export default class SpecialVisualizations {
tags: UIEventSource<Record<string, string>>,
argument: string[],
feature: Feature,
layer: LayerConfig,
layer: LayerConfig
) {
if (feature.geometry.type !== "LineString") {
return undefined
@ -611,7 +611,7 @@ export default class SpecialVisualizations {
state: SpecialVisualizationState,
tagSource: UIEventSource<Record<string, string>>,
argument: string[],
feature: Feature,
feature: Feature
): BaseUIElement {
const [lon, lat] = GeoOperations.centerpointCoordinates(feature)
return new SvelteUIElement(CreateNewNote, {
@ -674,7 +674,7 @@ export default class SpecialVisualizations {
.map((tags) => tags[args[0]])
.map((wikidata) => {
wikidata = Utils.NoEmpty(
wikidata?.split(";")?.map((wd) => wd.trim()) ?? [],
wikidata?.split(";")?.map((wd) => wd.trim()) ?? []
)[0]
const entry = Wikidata.LoadWikidataEntry(wikidata)
return new VariableUiElement(
@ -684,9 +684,9 @@ export default class SpecialVisualizations {
}
const response = <WikidataResponse>e["success"]
return Translation.fromMap(response.labels)
}),
})
)
}),
})
),
},
new MapillaryLinkVis(),
@ -700,7 +700,7 @@ export default class SpecialVisualizations {
tags: UIEventSource<Record<string, string>>,
_,
__,
layer: LayerConfig,
layer: LayerConfig
) => new SvelteUIElement(AllTagsPanel, { tags, layer }),
},
{
@ -784,7 +784,7 @@ export default class SpecialVisualizations {
nameKey: nameKey,
fallbackName,
},
state.featureSwitchIsTesting,
state.featureSwitchIsTesting
)
return new SvelteUIElement(StarsBarIcon, {
score: reviews.average,
@ -818,7 +818,7 @@ export default class SpecialVisualizations {
nameKey: nameKey,
fallbackName,
},
state.featureSwitchIsTesting,
state.featureSwitchIsTesting
)
return new SvelteUIElement(ReviewForm, { reviews, state, tags, feature, layer })
},
@ -849,7 +849,7 @@ export default class SpecialVisualizations {
nameKey: nameKey,
fallbackName,
},
state.featureSwitchIsTesting,
state.featureSwitchIsTesting
)
return new SvelteUIElement(AllReviews, { reviews, state, tags, feature, layer })
},
@ -875,7 +875,7 @@ export default class SpecialVisualizations {
tagSource: UIEventSource<Record<string, string>>,
args: string[],
feature: Feature,
layer: LayerConfig,
layer: LayerConfig
): BaseUIElement {
return new Combine([
SpecialVisualizations.specialVisualisationsDict["create_review"].constr(
@ -883,14 +883,14 @@ export default class SpecialVisualizations {
tagSource,
args,
feature,
layer,
layer
),
SpecialVisualizations.specialVisualisationsDict["list_reviews"].constr(
state,
tagSource,
args,
feature,
layer,
layer
),
])
},
@ -908,7 +908,7 @@ export default class SpecialVisualizations {
constr(
state: SpecialVisualizationState,
_: UIEventSource<Record<string, string>>,
argument: string[],
argument: string[]
): BaseUIElement {
const [text] = argument
return new SvelteUIElement(ImportReviewIdentity, { state, text })
@ -965,7 +965,7 @@ export default class SpecialVisualizations {
constr(
state: SpecialVisualizationState,
tags: UIEventSource<Record<string, string>>,
args: string[],
args: string[]
): SvelteUIElement {
const keyToUse = args[0]
const prefix = args[1]
@ -1002,17 +1002,17 @@ export default class SpecialVisualizations {
return undefined
}
const allUnits: Unit[] = [].concat(
...(state?.theme?.layers?.map((lyr) => lyr.units) ?? []),
...(state?.theme?.layers?.map((lyr) => lyr.units) ?? [])
)
const unit = allUnits.filter((unit) =>
unit.isApplicableToKey(key),
unit.isApplicableToKey(key)
)[0]
if (unit === undefined) {
return value
}
const getCountry = () => tagSource.data._country
return unit.asHumanLongValue(value, getCountry)
}),
})
)
},
},
@ -1066,7 +1066,7 @@ export default class SpecialVisualizations {
constr: (state) => {
return new SubtleButton(
new SvelteUIElement(Trash),
Translations.t.general.removeLocationHistory,
Translations.t.general.removeLocationHistory
).onClick(() => {
state.historicalUserLocations.features.setData([])
state.selectedElement.setData(undefined)
@ -1107,10 +1107,10 @@ export default class SpecialVisualizations {
new SvelteUIElement(NoteCommentElement, {
comment,
state,
}),
),
})
)
).SetClass("flex flex-col")
}),
})
),
},
{
@ -1143,7 +1143,7 @@ export default class SpecialVisualizations {
tagsSource: UIEventSource<Record<string, string>>,
_: string[],
feature: Feature,
layer: LayerConfig,
layer: LayerConfig
) =>
new VariableUiElement(
tagsSource.map((tags) => {
@ -1161,7 +1161,7 @@ export default class SpecialVisualizations {
feature,
layer,
})
}),
})
),
},
{
@ -1177,8 +1177,8 @@ export default class SpecialVisualizations {
const challenge = Stores.FromPromise(
Utils.downloadJsonCached<MaprouletteTask>(
`${Maproulette.defaultEndpoint}/challenge/${parentId}`,
24 * 60 * 60 * 1000,
),
24 * 60 * 60 * 1000
)
)
return new VariableUiElement(
@ -1203,7 +1203,7 @@ export default class SpecialVisualizations {
} else {
return [title, new List(listItems)]
}
}),
})
)
},
docs: "Fetches the metadata of MapRoulette campaign that this task is part of and shows those details (namely `title`, `description` and `instruction`).\n\nThis reads the property `mr_challengeId` to detect the parent campaign.",
@ -1217,15 +1217,15 @@ export default class SpecialVisualizations {
"\n" +
"```json\n" +
"{\n" +
" \"id\": \"mark_duplicate\",\n" +
" \"render\": {\n" +
" \"special\": {\n" +
" \"type\": \"maproulette_set_status\",\n" +
" \"message\": {\n" +
" \"en\": \"Mark as not found or false positive\"\n" +
' "id": "mark_duplicate",\n' +
' "render": {\n' +
' "special": {\n' +
' "type": "maproulette_set_status",\n' +
' "message": {\n' +
' "en": "Mark as not found or false positive"\n' +
" },\n" +
" \"status\": \"2\",\n" +
" \"image\": \"close\"\n" +
' "status": "2",\n' +
' "image": "close"\n' +
" }\n" +
" }\n" +
"}\n" +
@ -1301,7 +1301,7 @@ export default class SpecialVisualizations {
(l) =>
l.name !== null &&
l.title &&
state.perLayer.get(l.id) !== undefined,
state.perLayer.get(l.id) !== undefined
)
.map(
(l) => {
@ -1311,8 +1311,8 @@ export default class SpecialVisualizations {
const fsBboxed = new BBoxFeatureSourceForLayer(fs, bbox)
return new StatisticsPanel(fsBboxed)
},
[state.mapProperties.bounds],
),
[state.mapProperties.bounds]
)
)
},
},
@ -1382,7 +1382,7 @@ export default class SpecialVisualizations {
constr(
state: SpecialVisualizationState,
tagSource: UIEventSource<Record<string, string>>,
args: string[],
args: string[]
): SvelteUIElement {
let [text, href, classnames, download, ariaLabel, icon] = args
if (download === "") {
@ -1420,7 +1420,7 @@ export default class SpecialVisualizations {
},
},
null,
" ",
" "
) +
"\n```",
args: [
@ -1444,7 +1444,7 @@ export default class SpecialVisualizations {
featureTags: UIEventSource<Record<string, string>>,
args: string[],
feature: Feature,
layer: LayerConfig,
layer: LayerConfig
) {
const [key, tr, classesRaw] = args
let classes = classesRaw ?? ""
@ -1462,7 +1462,7 @@ export default class SpecialVisualizations {
"Could not create a special visualization for multi(",
args.join(", ") + ")",
"no properties found for object",
feature.properties.id,
feature.properties.id
)
return undefined
}
@ -1475,11 +1475,11 @@ export default class SpecialVisualizations {
feature,
layer,
// clss: classes ?? "",
}) .SetClass(classes)
}).SetClass(classes)
elements.push(subsTr)
}
return elements
}),
})
)
},
},
@ -1499,7 +1499,7 @@ export default class SpecialVisualizations {
tagSource: UIEventSource<Record<string, string>>,
argument: string[],
feature: Feature,
layer: LayerConfig,
layer: LayerConfig
): BaseUIElement {
return new VariableUiElement(
tagSource.map((tags) => {
@ -1511,7 +1511,7 @@ export default class SpecialVisualizations {
console.error("Cannot create a translation for", v, "due to", e)
return JSON.stringify(v)
}
}),
})
)
},
},
@ -1531,7 +1531,7 @@ export default class SpecialVisualizations {
tags: UIEventSource<Record<string, string>>,
argument: string[],
feature: Feature,
layer: LayerConfig,
layer: LayerConfig
): BaseUIElement {
const key = argument[0]
return new SvelteUIElement(FediverseLink, { key, tags, state })
@ -1553,7 +1553,7 @@ export default class SpecialVisualizations {
tagSource: UIEventSource<Record<string, string>>,
args: string[],
feature: Feature,
layer: LayerConfig,
layer: LayerConfig
): BaseUIElement {
return new FixedUiElement("{" + args[0] + "}")
},
@ -1574,7 +1574,7 @@ export default class SpecialVisualizations {
tagSource: UIEventSource<Record<string, string>>,
argument: string[],
feature: Feature,
layer: LayerConfig,
layer: LayerConfig
): BaseUIElement {
const key = argument[0] ?? "value"
return new VariableUiElement(
@ -1592,12 +1592,12 @@ export default class SpecialVisualizations {
} catch (e) {
return new FixedUiElement(
"Could not parse this tag: " +
JSON.stringify(value) +
" due to " +
e,
JSON.stringify(value) +
" due to " +
e
).SetClass("alert")
}
}),
})
)
},
},
@ -1618,7 +1618,7 @@ export default class SpecialVisualizations {
tagSource: UIEventSource<Record<string, string>>,
argument: string[],
feature: Feature,
layer: LayerConfig,
layer: LayerConfig
): BaseUIElement {
const giggityUrl = argument[0]
return new SvelteUIElement(Giggity, { tags: tagSource, state, giggityUrl })
@ -1634,12 +1634,12 @@ export default class SpecialVisualizations {
_: UIEventSource<Record<string, string>>,
argument: string[],
feature: Feature,
layer: LayerConfig,
layer: LayerConfig
): BaseUIElement {
const tags = (<ThemeViewState>(
state
)).geolocation.currentUserLocation.features.map(
(features) => features[0]?.properties,
(features) => features[0]?.properties
)
return new Combine([
new SvelteUIElement(OrientationDebugPanel, {}),
@ -1661,7 +1661,7 @@ export default class SpecialVisualizations {
tagSource: UIEventSource<Record<string, string>>,
argument: string[],
feature: Feature,
layer: LayerConfig,
layer: LayerConfig
): BaseUIElement {
return new SvelteUIElement(MarkAsFavourite, {
tags: tagSource,
@ -1681,7 +1681,7 @@ export default class SpecialVisualizations {
tagSource: UIEventSource<Record<string, string>>,
argument: string[],
feature: Feature,
layer: LayerConfig,
layer: LayerConfig
): BaseUIElement {
return new SvelteUIElement(MarkAsFavouriteMini, {
tags: tagSource,
@ -1701,7 +1701,7 @@ export default class SpecialVisualizations {
tagSource: UIEventSource<Record<string, string>>,
argument: string[],
feature: Feature,
layer: LayerConfig,
layer: LayerConfig
): BaseUIElement {
return new SvelteUIElement(DirectionIndicator, { state, feature })
},
@ -1714,7 +1714,7 @@ export default class SpecialVisualizations {
state: SpecialVisualizationState,
tags: UIEventSource<Record<string, string>>,
argument: string[],
feature: Feature,
feature: Feature
): SvelteUIElement {
return new SvelteUIElement(QrCode, { state, tags, feature })
},
@ -1733,7 +1733,7 @@ export default class SpecialVisualizations {
constr(
state: SpecialVisualizationState,
tagSource: UIEventSource<Record<string, string>>,
args: string[],
args: string[]
): BaseUIElement {
const key = args[0] === "" ? "_direction:centerpoint" : args[0]
return new VariableUiElement(
@ -1744,11 +1744,11 @@ export default class SpecialVisualizations {
})
.mapD((value) => {
const dir = GeoOperations.bearingToHuman(
GeoOperations.parseBearing(value),
GeoOperations.parseBearing(value)
)
console.log("Human dir", dir)
return Translations.t.general.visualFeedback.directionsAbsolute[dir]
}),
})
)
},
},
@ -1778,7 +1778,7 @@ export default class SpecialVisualizations {
tagSource: UIEventSource<Record<string, string>>,
args: string[],
feature: Feature,
layer: LayerConfig,
layer: LayerConfig
): BaseUIElement {
const url = args[0]
const readonly = args[3] === "yes"
@ -1804,12 +1804,12 @@ export default class SpecialVisualizations {
tagSource: UIEventSource<Record<string, string>>,
args: string[],
feature: Feature,
layer: LayerConfig,
layer: LayerConfig
): BaseUIElement {
return new Toggle(
undefined,
new SvelteUIElement(LoginButton, { osmConnection: state.osmConnection }),
state.osmConnection.isLoggedIn,
state.osmConnection.isLoggedIn
)
},
},
@ -1847,7 +1847,7 @@ export default class SpecialVisualizations {
tags: UIEventSource<Record<string, string>>,
argument: string[],
feature: Feature,
layer: LayerConfig,
layer: LayerConfig
): BaseUIElement {
const key = argument[0] ?? "website"
const useProxy = argument[1] !== "no"
@ -1855,7 +1855,7 @@ export default class SpecialVisualizations {
const isClosed = (argument[4] ?? "yes") === "yes"
const countryStore: Store<string | undefined> = tags.mapD(
(tags) => tags._country,
(tags) => tags._country
)
const sourceUrl: Store<string | undefined> = tags.mapD((tags) => {
if (!tags[key] || tags[key] === "undefined") {
@ -1877,24 +1877,24 @@ export default class SpecialVisualizations {
const features =
await LinkedDataLoader.fetchVeloparkEntry(
url,
loadAll,
loadAll
)
const feature =
features.find(
(f) => f.properties["ref:velopark"] === url,
(f) => f.properties["ref:velopark"] === url
) ?? features[0]
const properties = feature.properties
properties["ref:velopark"] = url
console.log(
"Got properties from velopark:",
properties,
properties
)
return properties
} catch (e) {
console.error(e)
throw e
}
})(),
})()
)
}
if (country === undefined) {
@ -1906,29 +1906,29 @@ export default class SpecialVisualizations {
return await LinkedDataLoader.fetchJsonLd(
url,
{ country },
useProxy ? "proxy" : "fetch-lod",
useProxy ? "proxy" : "fetch-lod"
)
} catch (e) {
console.log(
"Could not get with proxy/download LOD, attempting to download directly. Error for ",
url,
"is",
e,
e
)
return await LinkedDataLoader.fetchJsonLd(
url,
{ country },
"fetch-raw",
"fetch-raw"
)
}
})(),
})()
)
},
[countryStore],
[countryStore]
)
externalData.addCallbackAndRunD((lod) =>
console.log("linked_data_from_website received the following data:", lod),
console.log("linked_data_from_website received the following data:", lod)
)
return new Toggle(
@ -1943,7 +1943,7 @@ export default class SpecialVisualizations {
collapsed: isClosed,
}),
undefined,
sourceUrl.map((url) => !!url),
sourceUrl.map((url) => !!url)
)
},
},
@ -1963,7 +1963,7 @@ export default class SpecialVisualizations {
tagSource: UIEventSource<Record<string, string>>,
argument: string[],
feature: Feature,
layer: LayerConfig,
layer: LayerConfig
): BaseUIElement {
const text = argument[0]
const cssClasses = argument[1]
@ -1985,7 +1985,7 @@ export default class SpecialVisualizations {
tagSource: UIEventSource<Record<string, string>>,
argument: string[],
feature: Feature,
layer: LayerConfig,
layer: LayerConfig
): BaseUIElement {
const translation = tagSource.map((tags) => {
const layer = state.theme.getMatchingLayer(tags)
@ -2017,7 +2017,7 @@ export default class SpecialVisualizations {
tagSource: UIEventSource<Record<string, string>>,
argument: string[],
feature: Feature,
layer: LayerConfig,
layer: LayerConfig
): SvelteUIElement {
return new SvelteUIElement<any, any, any>(ClearCaches, {
msg: argument[0] ?? "Clear local caches",
@ -2042,7 +2042,7 @@ export default class SpecialVisualizations {
tags: UIEventSource<Record<string, string>>,
argument: string[],
selectedElement: Feature,
layer: LayerConfig,
layer: LayerConfig
): SvelteUIElement {
const [header, labelsStr] = argument
const labels = labelsStr.split(";").map((x) => x.trim())
@ -2065,7 +2065,7 @@ export default class SpecialVisualizations {
tags: UIEventSource<Record<string, string>>,
argument: string[],
selectedElement: Feature,
layer: LayerConfig,
layer: LayerConfig
): SvelteUIElement {
const t = Translations.t.preset_type
const question: QuestionableTagRenderingConfigJson = {
@ -2105,7 +2105,7 @@ export default class SpecialVisualizations {
tagSource: UIEventSource<Record<string, string>>,
argument: string[],
feature: Feature,
layer: LayerConfig,
layer: LayerConfig
): BaseUIElement {
const text = argument[0]
return new SubtleButton(undefined, text).onClick(() => {
@ -2136,7 +2136,7 @@ export default class SpecialVisualizations {
"Invalid special visualisation found: funcName is undefined or doesn't match " +
regex +
invalid.map((sp) => sp.i).join(", ") +
". Did you perhaps type \n funcName: \"funcname\" // type declaration uses COLON\ninstead of:\n funcName = \"funcName\" // value definition uses EQUAL"
'. Did you perhaps type \n funcName: "funcname" // type declaration uses COLON\ninstead of:\n funcName = "funcName" // value definition uses EQUAL'
)
}

View file

@ -404,7 +404,7 @@
on:keydown={forwardEventToMap}
>
<div class="h-8 w-8 cursor-pointer">
<DefaultIcon layer={currentViewLayer}/>
<DefaultIcon layer={currentViewLayer} />
</div>
</MapControlButton>
{/if}

View file

@ -1 +1 @@
{"properties":{"name":"Bing Maps Aerial","id":"Bing","url":"https://ecn.t3.tiles.virtualearth.net/tiles/a{quadkey}.jpeg?g=14738&pr=odbl&n=f","type":"bing","category":"photo","min_zoom":1,"max_zoom":22},"type":"Feature","geometry":null}
{"properties":{"name":"Bing Maps Aerial","id":"Bing","url":"https://ecn.t0.tiles.virtualearth.net/tiles/a{quadkey}.jpeg?g=14875&pr=odbl&n=f","type":"bing","category":"photo","min_zoom":1,"max_zoom":22},"type":"Feature","geometry":null}

View file

@ -1,11 +1,11 @@
{
"contributors": [
{
"commits": 8786,
"commits": 8826,
"contributor": "Pieter Vander Vennet"
},
{
"commits": 505,
"commits": 506,
"contributor": "Robin van der Linde"
},
{
@ -56,6 +56,10 @@
"commits": 24,
"contributor": "Ward"
},
{
"commits": 23,
"contributor": "Midgard"
},
{
"commits": 21,
"contributor": "wjtje"
@ -80,10 +84,6 @@
"commits": 18,
"contributor": "Arno Deceuninck"
},
{
"commits": 17,
"contributor": "Midgard"
},
{
"commits": 17,
"contributor": "pgm-chardelv1"

View file

@ -1,5 +1,6 @@
{
"ca": "català",
"cs": "čeština",
"da": "dansk",
"de": "Deutsch",
"en": "English",
@ -14,6 +15,7 @@
"id": "bahasa Indonesia",
"it": "italiano",
"ja": "日本語",
"ko": "한국어",
"nb_NO": "bokmål",
"nl": "Nederlands",
"pl": "język polski",
@ -23,7 +25,6 @@
"sl": "slovenščina",
"sv": "svenska",
"uk": "українська мова",
"zgh": "ⵜⴰⵎⴰⵣⵉⵖⵜ ⵜⴰⵏⴰⵡⴰⵢⵜ ⵜⴰⵎⵖⵔⵉⴱⵉⵜ",
"zh_Hans": "简体中文",
"zh_Hant": "繁體中文"
}

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -29,7 +29,7 @@
"contributor": "Robin van der Linde"
},
{
"commits": 76,
"commits": 78,
"contributor": "mike140"
},
{
@ -41,7 +41,7 @@
"contributor": "Midgard"
},
{
"commits": 54,
"commits": 56,
"contributor": "Jiří Podhorecký"
},
{
@ -53,7 +53,7 @@
"contributor": "gallegonovato"
},
{
"commits": 49,
"commits": 50,
"contributor": "Supaplex"
},
{
@ -156,6 +156,10 @@
"commits": 11,
"contributor": "Túllio Franca"
},
{
"commits": 10,
"contributor": "JiwonShin"
},
{
"commits": 10,
"contributor": "Jeff Huang"
@ -584,6 +588,10 @@
"commits": 2,
"contributor": "Leo Alcaraz"
},
{
"commits": 1,
"contributor": "Moimoi Ty"
},
{
"commits": 1,
"contributor": "Roger"
@ -741,4 +749,4 @@
"contributor": "Carlos Ramos Carreño"
}
]
}
}

View file

@ -1 +1 @@
{"languages":["ca","cs","da","de","en","eo","es","eu","fi","fil","fr","gl","he","hu","id","it","ja","nb_NO","nl","pa_PK","pl","pt","pt_BR","ru","sl","sv","uk","zgh","zh_Hans","zh_Hant"]}
{"languages":["ca","cs","da","de","en","eo","es","eu","fi","fil","fr","gl","he","hu","id","it","ja","ko","nb_NO","nl","pa_PK","pl","pt","pt_BR","ru","sl","sv","uk","zgh","zh_Hans","zh_Hant"]}