Fix bugs with themes, add movement of tag renderings in custom theme generator
|  | @ -57,7 +57,7 @@ export class FromJSON { | |||
|         const layout = new Layout( | ||||
|             json.id, | ||||
|             typeof (json.language) === "string" ? [json.language] : json.language, | ||||
|             tr(json.title), | ||||
|             tr(json.title ?? "Title not defined"), | ||||
|             layers, | ||||
|             json.startZoom, | ||||
|             json.startLat, | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| import {LayerDefinition} from "../LayerDefinition"; | ||||
| import {And, Or, Tag} from "../../Logic/Tags"; | ||||
| import {And, Or, RegexTag, Tag} from "../../Logic/Tags"; | ||||
| import {TagRenderingOptions} from "../TagRenderingOptions"; | ||||
| import {FromJSON} from "../JSON/FromJSON"; | ||||
| 
 | ||||
|  | @ -36,10 +36,6 @@ export class Widths extends LayerDefinition { | |||
| 
 | ||||
|     private readonly _oneSideParking = new Or([this._leftSideParking, this._rightSideParking]); | ||||
| 
 | ||||
|     private readonly _carfree = new And( | ||||
|         [new Tag("highway", "pedestrian"), new Tag("highway", "living_street"), | ||||
|         new Tag("access","destination"), new Tag("motor_vehicle", "destination")]) | ||||
| 
 | ||||
|     private readonly _notCarfree = | ||||
|         FromJSON.Tag({"and":[ | ||||
|             "highway!~pedestrian|living_street", | ||||
|  | @ -130,7 +126,7 @@ export class Widths extends LayerDefinition { | |||
|         } | ||||
| 
 | ||||
|         this.name = "widths"; | ||||
|         this.overpassFilter = new Tag("width:carriageway", "*"); | ||||
|         this.overpassFilter = new RegexTag("width:carriageway", /.*/); | ||||
| 
 | ||||
|         this.title = new TagRenderingOptions({ | ||||
|             freeform: { | ||||
|  | @ -140,6 +136,8 @@ export class Widths extends LayerDefinition { | |||
|             } | ||||
|         }) | ||||
| 
 | ||||
|         console.log("Not car free: ", this._notCarfree) | ||||
|          | ||||
|         const self = this; | ||||
|         this.style = (properties) => { | ||||
| 
 | ||||
|  | @ -158,7 +156,7 @@ export class Widths extends LayerDefinition { | |||
|                 c = "#f0f" | ||||
|             } | ||||
|              | ||||
|             if (this._carfree.matchesProperties(properties)) { | ||||
|             if (!this._notCarfree.matchesProperties(properties)) { | ||||
|                 c = "#aaa"; | ||||
|             } | ||||
| 
 | ||||
|  | @ -196,7 +194,6 @@ export class Widths extends LayerDefinition { | |||
|                         txt: "Deze straat heeft dwarsparkeren of diagonaalparkeren aan minstens één zijde. Deze parkeerruimte is niet opgenomen in de straatbreedte." | ||||
|                     }, | ||||
|                     {k: this._noSideParking, txt: "Auto's mogen hier niet parkeren"}, | ||||
|                     // {k: null, txt: "Nog geen parkeerinformatie bekend"}
 | ||||
|                 ], | ||||
|                 freeform: { | ||||
|                     key: "note:width:carriageway", | ||||
|  |  | |||
|  | @ -127,6 +127,10 @@ export class InitUiElements { | |||
|      | ||||
|     static CreateLanguagePicker(label: string | UIElement = "") { | ||||
| 
 | ||||
|         if (State.state.layoutToUse.data.supportedLanguages.length <= 1) { | ||||
|             return undefined; | ||||
|         } | ||||
| 
 | ||||
|         return new DropDown(label, State.state.layoutToUse.data.supportedLanguages.map(lang => { | ||||
|                 return {value: lang, shown: lang} | ||||
|             } | ||||
|  | @ -203,10 +207,11 @@ export class InitUiElements { | |||
|         const presets: Preset[] = []; | ||||
| 
 | ||||
|         const state = State.state; | ||||
| 
 | ||||
|         for (const layer of state.layoutToUse.data.layers) { | ||||
|              | ||||
|             if(typeof (layer) === "string"){ | ||||
|                 throw "Layer "+layer+" was not substituted"; | ||||
| 
 | ||||
|             if (typeof (layer) === "string") { | ||||
|                 throw "Layer " + layer + " was not substituted"; | ||||
|             } | ||||
| 
 | ||||
|             const generateInfo = (tagsES, feature) => { | ||||
|  |  | |||
|  | @ -34,7 +34,7 @@ export class StrayClickHandler { | |||
|             uiElement.Update(); | ||||
|             uiElement.Activate(); | ||||
|             self._lastMarker.addTo(map); | ||||
|             self._lastMarker.bindPopup(popup).openPopup(); | ||||
|             self._lastMarker.bindPopup(popup); | ||||
| 
 | ||||
|             self._lastMarker.on("click", () => { | ||||
|                 State.state.fullScreenMessage.setData(self._uiToShow()); | ||||
|  |  | |||
|  | @ -49,7 +49,8 @@ export class RegexTag extends TagsFilter { | |||
|                 return RegexTag.doesMatch(tag.v, this.value) != this.invert; | ||||
|             } | ||||
|         } | ||||
|         return false; | ||||
|         // The matching key was not found
 | ||||
|         return this.invert; | ||||
|     } | ||||
| 
 | ||||
|     substituteValues(tags: any) : TagsFilter{ | ||||
|  |  | |||
							
								
								
									
										2
									
								
								State.ts
									
										
									
									
									
								
							
							
						
						|  | @ -23,7 +23,7 @@ export class State { | |||
|     // The singleton of the global state
 | ||||
|     public static state: State; | ||||
|      | ||||
|     public static vNumber = "0.0.7f"; | ||||
|     public static vNumber = "0.0.7g"; | ||||
|      | ||||
|     // The user journey states thresholds when a new feature gets unlocked
 | ||||
|     public static userJourney = { | ||||
|  |  | |||
|  | @ -18,6 +18,10 @@ export default class Combine extends UIElement { | |||
|     InnerRender(): string { | ||||
|         let elements = ""; | ||||
|         for (const element of this.uiElements) { | ||||
|             if(element === undefined){ | ||||
|                 continue; | ||||
|             } | ||||
|              | ||||
|             if (element instanceof UIElement) { | ||||
|                 elements += element.Render(); | ||||
|             } else { | ||||
|  |  | |||
|  | @ -7,6 +7,9 @@ import Combine from "../Base/Combine"; | |||
| import {GenerateEmpty} from "./GenerateEmpty"; | ||||
| import LayerPanelWithPreview from "./LayerPanelWithPreview"; | ||||
| import {UserDetails} from "../../Logic/Osm/OsmConnection"; | ||||
| import {MultiInput} from "../Input/MultiInput"; | ||||
| import TagRenderingPanel from "./TagRenderingPanel"; | ||||
| import SingleSetting from "./SingleSetting"; | ||||
| 
 | ||||
| export default class AllLayersPanel extends UIElement { | ||||
| 
 | ||||
|  | @ -14,10 +17,13 @@ export default class AllLayersPanel extends UIElement { | |||
|     private panel: UIElement; | ||||
|     private readonly _config: UIEventSource<LayoutConfigJson>; | ||||
|     private readonly languages: UIEventSource<string[]>; | ||||
|     private readonly userDetails: UserDetails; | ||||
|     private readonly currentlySelected: UIEventSource<SingleSetting<any>>; | ||||
| 
 | ||||
|     constructor(config: UIEventSource<LayoutConfigJson>, | ||||
|                 languages: UIEventSource<any>, userDetails: UserDetails) { | ||||
|         super(undefined); | ||||
|         this.userDetails = userDetails; | ||||
|         this._config = config; | ||||
|         this.languages = languages; | ||||
| 
 | ||||
|  | @ -32,6 +38,15 @@ export default class AllLayersPanel extends UIElement { | |||
|         const self = this; | ||||
|         const tabs = []; | ||||
| 
 | ||||
| 
 | ||||
|         const roamingTags = new MultiInput("Add a tagrendering", | ||||
|             () => GenerateEmpty.createEmptyTagRendering(), | ||||
|             () => { | ||||
|                 return new TagRenderingPanel(self.languages, self.currentlySelected, self.userDetails) | ||||
| 
 | ||||
|             }, undefined, {allowMovement: true}); | ||||
|         new SingleSetting(this._config, roamingTags, "roamingRenderings", "Roaming Renderings", "These tagrenderings are shown everywhere"); | ||||
| 
 | ||||
|         const layers = this._config.data.layers; | ||||
|         for (let i = 0; i < layers.length; i++) { | ||||
| 
 | ||||
|  | @ -43,15 +58,20 @@ export default class AllLayersPanel extends UIElement { | |||
|         tabs.push({ | ||||
|             header: "<img src='./assets/layersAdd.svg'>", | ||||
|             content: new Combine([ | ||||
|                 "<h2>Layer editor</h2>", | ||||
|                 "In this tab page, you can add and edit the layers of the theme. Click the layers above or add a new layer to get started.", | ||||
|                 new SubtleButton( | ||||
|                     "./assets/layersAdd.svg", | ||||
|                     "Add a new layer" | ||||
|                 ).onClick(() => { | ||||
|                     self._config.data.layers.push(GenerateEmpty.createEmptyLayer()) | ||||
|                     self._config.ping(); | ||||
|                 })]) | ||||
|                     "<h2>Layer editor</h2>", | ||||
|                     "In this tab page, you can add and edit the layers of the theme. Click the layers above or add a new layer to get started.", | ||||
|                     new SubtleButton( | ||||
|                         "./assets/layersAdd.svg", | ||||
|                         "Add a new layer" | ||||
|                     ).onClick(() => { | ||||
|                         self._config.data.layers.push(GenerateEmpty.createEmptyLayer()) | ||||
|                         self._config.ping(); | ||||
|                     }), | ||||
|                     "<h2>TagRenderings for every layer</h2>", | ||||
|                     "Define tag renderings and questions here that should be shown on every layer of the theme.", | ||||
|                     roamingTags | ||||
|                 ] | ||||
|             ), | ||||
|         }) | ||||
| 
 | ||||
|         this.panel = new TabbedComponent(tabs, new UIEventSource<number>(Math.max(0, layers.length - 1))); | ||||
|  |  | |||
|  | @ -120,7 +120,7 @@ export default class LayerPanel extends UIElement { | |||
|                 const tagPanel = new TagRenderingPanel(languages, currentlySelected, userDetails) | ||||
|                 self.registerTagRendering(tagPanel); | ||||
|                 return tagPanel; | ||||
|             }); | ||||
|             }, undefined, {allowMovement:true}); | ||||
|         tagRenderings.GetValue().addCallback( | ||||
|             tagRenderings => { | ||||
|                 (config.data.layers[index] as LayerConfigJson).tagRenderings = tagRenderings; | ||||
|  | @ -132,7 +132,8 @@ export default class LayerPanel extends UIElement { | |||
| 
 | ||||
|             const presetPanel = new MultiInput("Add a preset", | ||||
|                 () => ({tags: [], title: {}}), | ||||
|                 () => new PresetInputPanel(currentlySelected, languages)); | ||||
|                 () => new PresetInputPanel(currentlySelected, languages), | ||||
|                 undefined, {allowMovement: true}); | ||||
|             new SingleSetting(config, presetPanel, ["layers", index, "presets"], "Presets", "") | ||||
|             this.presetsPanel = presetPanel; | ||||
|         } else { | ||||
|  |  | |||
|  | @ -33,7 +33,7 @@ export default class PresetInputPanel extends InputElement<{ | |||
|             s(new MultiTagInput(), "tags","Preset tags","These tags will be applied on the newly created point"), | ||||
|             s(new MultiLingualTextFields(languages), "title","Preset title","This little text is shown in bold on the 'create new point'-button" ), | ||||
|             s(new MultiLingualTextFields(languages), "description","Description", "This text is shown in the button as description when creating a new point") | ||||
|         ], currentlySelected); | ||||
|         ], currentlySelected).SetStyle("display: block; border: 1px solid black; border-radius: 1em;padding: 1em;"); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -12,14 +12,20 @@ export class MultiInput<T> extends InputElement<T[]> { | |||
|     private elements: UIElement[] = []; | ||||
|     private inputELements: InputElement<T>[] = []; | ||||
|     private addTag: UIElement; | ||||
|     private _options: { allowMovement?: boolean }; | ||||
| 
 | ||||
|     constructor( | ||||
|         addAElement: string, | ||||
|         newElement: (() => T), | ||||
|         createInput: (() => InputElement<T>), | ||||
|         value: UIEventSource<T[]> = new UIEventSource<T[]>([])) { | ||||
|         value: UIEventSource<T[]> = undefined, | ||||
|         options?: { | ||||
|             allowMovement?: boolean | ||||
|         }) { | ||||
|         super(undefined); | ||||
|         this._value = value; | ||||
|         this._value = value ?? new UIEventSource<T[]>([]); | ||||
|         value = this._value; | ||||
|         this._options = options ?? {}; | ||||
| 
 | ||||
|         this.addTag = new SubtleButton("./assets/addSmall.svg", addAElement) | ||||
|             .SetClass("small-button") | ||||
|  | @ -54,7 +60,6 @@ export class MultiInput<T> extends InputElement<T[]> { | |||
|         this.elements = []; | ||||
|         const self = this; | ||||
|         for (let i = 0; i < this._value.data.length; i++) { | ||||
|             let tag = this._value.data[i]; | ||||
|             const input = createInput(); | ||||
|             input.GetValue().addCallback(tag => { | ||||
|                     self._value.data[i] = tag; | ||||
|  | @ -63,12 +68,40 @@ export class MultiInput<T> extends InputElement<T[]> { | |||
|             ); | ||||
|             this.inputELements.push(input); | ||||
|             input.IsSelected.addCallback(() => this.UpdateIsSelected()); | ||||
|             const deleteBtn = new FixedUiElement("<img src='./assets/delete.svg' style='max-width: 1.5em; margin-left: 5px;'>") | ||||
| 
 | ||||
|             const moveUpBtn = new FixedUiElement("<img src='./assets/up.svg' style='max-width: 1.5em; margin-left: 5px;'>") | ||||
|                 .onClick(() => { | ||||
|                     const v = self._value.data[i]; | ||||
|                     self._value.data[i] = self._value.data[i - 1]; | ||||
|                     self._value.data[i - 1] = v; | ||||
|                     self._value.ping(); | ||||
|                 }); | ||||
| 
 | ||||
|             const moveDownBtn = new FixedUiElement("<img src='./assets/down.svg' style='max-width: 1.5em; margin-left: 5px;'>") | ||||
|                 .onClick(() => { | ||||
|                     const v = self._value.data[i]; | ||||
|                     self._value.data[i] = self._value.data[i + 1]; | ||||
|                     self._value.data[i + 1] = v; | ||||
|                     self._value.ping(); | ||||
|                 }); | ||||
| 
 | ||||
|             const controls = []; | ||||
|             if (i > 0 && this._options.allowMovement) { | ||||
|                 controls.push(moveUpBtn); | ||||
|             } | ||||
| 
 | ||||
|             if (i + 1 < this._value.data.length && this._options.allowMovement) { | ||||
|                 controls.push(moveDownBtn); | ||||
|             } | ||||
| 
 | ||||
| 
 | ||||
|             const deleteBtn = new FixedUiElement("<img src='./assets/delete.svg' style='max-width: 1.5em;width:1.5em; margin-left: 5px;'>") | ||||
|                 .onClick(() => { | ||||
|                     self._value.data.splice(i, 1); | ||||
|                     self._value.ping(); | ||||
|                 }); | ||||
|             this.elements.push(new Combine([input, deleteBtn, "<br/>"]).SetClass("tag-input-row")) | ||||
|             controls.push(deleteBtn); | ||||
|             this.elements.push(new Combine([input.SetStyle("width: calc(100% - 2em - 5px)"), new Combine(controls).SetStyle("display:flex;flex-direction:column;width:min-content;")]).SetClass("tag-input-row")) | ||||
|         } | ||||
|          | ||||
|         this.Update(); | ||||
|  |  | |||
|  | @ -176,7 +176,7 @@ export class ShareScreen extends UIElement { | |||
|                 new VariableUiElement( | ||||
|                     State.state.osmConnection.userDetails.map( | ||||
|                         userDetails => { | ||||
|                             if (userDetails.csCount <= State.userJourney.themeGeneratorUnlock) { | ||||
|                             if (userDetails.csCount <= State.userJourney.themeGeneratorReadOnlyUnlock) { | ||||
|                                 return ""; | ||||
|                             } | ||||
| 
 | ||||
|  |  | |||
|  | @ -9,6 +9,7 @@ import {Utils} from "../Utils"; | |||
| import {UIEventSource} from "../Logic/UIEventSource"; | ||||
| import {SubtleButton} from "./Base/SubtleButton"; | ||||
| import {InitUiElements} from "../InitUiElements"; | ||||
| import Combine from "./Base/Combine"; | ||||
| 
 | ||||
| /** | ||||
|  * Handles and updates the user badge | ||||
|  | @ -110,14 +111,14 @@ export class UserBadge extends UIElement { | |||
|             "   <a href='https://www.openstreetmap.org/user/" + user.name + "/history' target='_blank'><img class='small-userbadge-icon' src='./assets/star.svg' alt='star'/> " + user.csCount + | ||||
|             "</a></span> "; | ||||
| 
 | ||||
|         const userStats = "<div id='userstats'>" + | ||||
|             this._homeButton.Render() + | ||||
|             settings + | ||||
|             messageSpan + | ||||
|             csCount + | ||||
|             this._logout.Render() + | ||||
|             this._languagePicker.Render() + | ||||
|             "</div>"; | ||||
|         const userStats = new Combine(["<div id='userstats'>", | ||||
|             this._homeButton, | ||||
|             settings, | ||||
|             messageSpan, | ||||
|             csCount, | ||||
|             this._logout, | ||||
|             this._languagePicker, | ||||
|             "</div>"]).Render(); | ||||
| 
 | ||||
|         return userIcon + "<div id='usertext'>" + userName + userStats + "</div>"; | ||||
| 
 | ||||
|  |  | |||
|  | @ -41,8 +41,7 @@ export class WelcomeMessage extends UIElement { | |||
| 
 | ||||
|         return new Combine([ | ||||
|             this.description, | ||||
|             "<br/></br>", | ||||
|             // TODO this button is broken - figure out why loginStatus,
 | ||||
|             "<br/><br/>", | ||||
|             loginStatus, | ||||
|             this.tail, | ||||
|             "<br/>", | ||||
|  |  | |||
|  | @ -874,7 +874,7 @@ export default class Translations { | |||
|                     en: "<h2>Add a point?</h2>You clicked somewhere where no data is known yet.<br/>", | ||||
|                     ca: "<h2>Vols afegir un punt?</h2>Has marcat un lloc on no coneixem les dades.<br/>", | ||||
|                     es: "<h2>Quieres añadir un punto?</h2>Has marcado un lugar del que no conocemos los datos.<br/>", | ||||
|                     nl: "<h2>Punt toevoegen?</h2>Je klikte ergens waar er nog geen data is.<br/>", | ||||
|                     nl: "<h2>Punt toevoegen?</h2>Je klikte ergens waar er nog geen data is. Kies hieronder welk punt je wilt toevoegen<br/>", | ||||
|                     fr: "<h2>Pas de données</h2>Vous avez cliqué sur un endroit ou il n'y a pas encore de données. <br/>", | ||||
|                     gl: "<h2>Queres engadir un punto?</h2>Marcaches un lugar onde non coñecemos os datos.<br/>" | ||||
|                 }), | ||||
|  |  | |||
							
								
								
									
										70
									
								
								aed.html
									
										
									
									
									
								
							
							
						
						|  | @ -1,70 +0,0 @@ | |||
| <!DOCTYPE html>     | ||||
| <!-- WARNING: index.html serves as a template. If you want to change something, change it there --> | ||||
| <html lang="en"> | ||||
| <head> | ||||
|     <meta charset="UTF-8"> | ||||
|     <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"> | ||||
|     <title>MapComplete</title> | ||||
|     <link rel="stylesheet" href="./vendor/leaflet.css"/> | ||||
|     <link rel="stylesheet" href="./index.css"/> | ||||
|     <link rel="stylesheet" href="./css/userbadge.css"/> | ||||
|     <link rel="stylesheet" href="./css/slideshow.css"/> | ||||
|     <link rel="manifest" href="./aed.webmanifest"> | ||||
|     <link rel="icon" href="./assets/themes/aed/aed.svg" sizes="any" type="image/svg+xml"> | ||||
|      | ||||
|     <meta property="og:type" content="website"> | ||||
|      | ||||
|     <meta property="og:image" content="./assets/add.svg"> | ||||
|     <meta property="og:title" content="Open AED Map"> | ||||
|     <meta property="og:description" content="Easily add and edit geodata with OpenStreetMap"> | ||||
| 
 | ||||
|     <style> | ||||
|         #decoration-desktop img { | ||||
|             width: 100%; | ||||
|             height: 100%; | ||||
|         } | ||||
|     </style> | ||||
|      | ||||
| </head> | ||||
| <body> | ||||
| 
 | ||||
| <div style="position: absolute; left: 1em; bottom: 1em; width:35vh; height:35vh;" | ||||
|      id="decoration-desktop"> | ||||
|     <!-- A nice decoration while loading or on errors --> | ||||
|     <img src='./assets/themes/aed/aed.svg' width="100%" height="100%"> | ||||
| </div> | ||||
| 
 | ||||
| <div id="hidden-on-mobile"> | ||||
|     <div id="messagesboxmobile"> | ||||
|     </div> | ||||
| </div> | ||||
| 
 | ||||
| <div id="topleft-tools"> | ||||
|     <div id="userbadge-and-search"> | ||||
|         <div id="userbadge" class="shadow"> | ||||
|         </div> | ||||
|         <div id="searchbox" class="shadow"></div> | ||||
|     </div> | ||||
|     <div id="messagesbox"></div> | ||||
|     <br/> | ||||
|     <div id="help-button-mobile"></div> | ||||
| </div> | ||||
| 
 | ||||
| <div id="filter__popup" class="filter__popup"> | ||||
|     <div id="filter__selection"></div> | ||||
| </div> | ||||
| 
 | ||||
| <div id="centermessage">Loading MapComplete, hang on...</div> | ||||
| <div id="top-right"></div> | ||||
| 
 | ||||
| <div id="geolocate-button"></div> | ||||
| <div id="leafletDiv"></div> | ||||
| 
 | ||||
| <script src="./index.ts"></script> | ||||
| <script src="./vendor/Leaflet.AccuratePosition.js"></script> | ||||
| 
 | ||||
| <script data-goatcounter="https://pietervdvn.goatcounter.com/count" | ||||
|         async src="//gc.zgo.at/count.js"></script> | ||||
| 
 | ||||
| </body> | ||||
| </html> | ||||
|  | @ -1 +0,0 @@ | |||
| {"name":"aed","short_name":"Open AED Map","start_url":"/MapComplete/aed.html","display":"standalone","background_color":"#fff","description":"","orientation":"portrait-primary, landscape-primary","icons":[{"src":"assets/generated/themes_aed_aed72.png","sizes":"72x72","type":"image/png"},{"src":"assets/generated/themes_aed_aed96.png","sizes":"96x96","type":"image/png"},{"src":"assets/generated/themes_aed_aed120.png","sizes":"120x120","type":"image/png"},{"src":"assets/generated/themes_aed_aed128.png","sizes":"128x128","type":"image/png"},{"src":"assets/generated/themes_aed_aed144.png","sizes":"144x144","type":"image/png"},{"src":"assets/generated/themes_aed_aed152.png","sizes":"152x152","type":"image/png"},{"src":"assets/generated/themes_aed_aed180.png","sizes":"180x180","type":"image/png"},{"src":"assets/generated/themes_aed_aed192.png","sizes":"192x192","type":"image/png"},{"src":"assets/generated/themes_aed_aed384.png","sizes":"384x384","type":"image/png"},{"src":"assets/generated/themes_aed_aed512.png","sizes":"512x512","type":"image/png"},{"src":"./assets/themes/aed/aed.svg","sizes":"513x513","type":"image/svg"}]} | ||||
|  | @ -1,70 +0,0 @@ | |||
| <!DOCTYPE html>     | ||||
| <!-- WARNING: index.html serves as a template. If you want to change something, change it there --> | ||||
| <html lang="en"> | ||||
| <head> | ||||
|     <meta charset="UTF-8"> | ||||
|     <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"> | ||||
|     <title>MapComplete</title> | ||||
|     <link rel="stylesheet" href="./vendor/leaflet.css"/> | ||||
|     <link rel="stylesheet" href="./index.css"/> | ||||
|     <link rel="stylesheet" href="./css/userbadge.css"/> | ||||
|     <link rel="stylesheet" href="./css/slideshow.css"/> | ||||
|     <link rel="manifest" href="./artworks.webmanifest"> | ||||
|     <link rel="icon" href="./assets/themes/artwork/artwork.svg" sizes="any" type="image/svg+xml"> | ||||
|      | ||||
|     <meta property="og:type" content="website"> | ||||
|      | ||||
|     <meta property="og:image" content="./assets/add.svg"> | ||||
|     <meta property="og:title" content="Open Artwork Map"> | ||||
|     <meta property="og:description" content="Easily add and edit geodata with OpenStreetMap"> | ||||
| 
 | ||||
|     <style> | ||||
|         #decoration-desktop img { | ||||
|             width: 100%; | ||||
|             height: 100%; | ||||
|         } | ||||
|     </style> | ||||
|      | ||||
| </head> | ||||
| <body> | ||||
| 
 | ||||
| <div style="position: absolute; left: 1em; bottom: 1em; width:35vh; height:35vh;" | ||||
|      id="decoration-desktop"> | ||||
|     <!-- A nice decoration while loading or on errors --> | ||||
|     <img src='./assets/themes/artwork/artwork.svg' width="100%" height="100%"> | ||||
| </div> | ||||
| 
 | ||||
| <div id="hidden-on-mobile"> | ||||
|     <div id="messagesboxmobile"> | ||||
|     </div> | ||||
| </div> | ||||
| 
 | ||||
| <div id="topleft-tools"> | ||||
|     <div id="userbadge-and-search"> | ||||
|         <div id="userbadge" class="shadow"> | ||||
|         </div> | ||||
|         <div id="searchbox" class="shadow"></div> | ||||
|     </div> | ||||
|     <div id="messagesbox"></div> | ||||
|     <br/> | ||||
|     <div id="help-button-mobile"></div> | ||||
| </div> | ||||
| 
 | ||||
| <div id="filter__popup" class="filter__popup"> | ||||
|     <div id="filter__selection"></div> | ||||
| </div> | ||||
| 
 | ||||
| <div id="centermessage">Loading MapComplete, hang on...</div> | ||||
| <div id="top-right"></div> | ||||
| 
 | ||||
| <div id="geolocate-button"></div> | ||||
| <div id="leafletDiv"></div> | ||||
| 
 | ||||
| <script src="./index.ts"></script> | ||||
| <script src="./vendor/Leaflet.AccuratePosition.js"></script> | ||||
| 
 | ||||
| <script data-goatcounter="https://pietervdvn.goatcounter.com/count" | ||||
|         async src="//gc.zgo.at/count.js"></script> | ||||
| 
 | ||||
| </body> | ||||
| </html> | ||||
|  | @ -1 +0,0 @@ | |||
| {"name":"artworks","short_name":"Open Artwork Map","start_url":"/MapComplete/artworks.html","display":"standalone","background_color":"#fff","description":"","orientation":"portrait-primary, landscape-primary","icons":[{"src":"assets/generated/themes_artwork_artwork72.png","sizes":"72x72","type":"image/png"},{"src":"assets/generated/themes_artwork_artwork96.png","sizes":"96x96","type":"image/png"},{"src":"assets/generated/themes_artwork_artwork120.png","sizes":"120x120","type":"image/png"},{"src":"assets/generated/themes_artwork_artwork128.png","sizes":"128x128","type":"image/png"},{"src":"assets/generated/themes_artwork_artwork144.png","sizes":"144x144","type":"image/png"},{"src":"assets/generated/themes_artwork_artwork152.png","sizes":"152x152","type":"image/png"},{"src":"assets/generated/themes_artwork_artwork180.png","sizes":"180x180","type":"image/png"},{"src":"assets/generated/themes_artwork_artwork192.png","sizes":"192x192","type":"image/png"},{"src":"assets/generated/themes_artwork_artwork384.png","sizes":"384x384","type":"image/png"},{"src":"assets/generated/themes_artwork_artwork512.png","sizes":"512x512","type":"image/png"},{"src":"./assets/themes/artwork/artwork.svg","sizes":"513x513","type":"image/svg"}]} | ||||
							
								
								
									
										58
									
								
								assets/down.svg
									
										
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,58 @@ | |||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <svg | ||||
|    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||
|    xmlns:cc="http://creativecommons.org/ns#" | ||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||
|    xmlns:svg="http://www.w3.org/2000/svg" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||
|    version="1.0" | ||||
|    width="700" | ||||
|    height="700" | ||||
|    id="svg6" | ||||
|    sodipodi:docname="down.svg" | ||||
|    inkscape:version="0.92.4 (5da689c313, 2019-01-14)"> | ||||
|   <metadata | ||||
|      id="metadata12"> | ||||
|     <rdf:RDF> | ||||
|       <cc:Work | ||||
|          rdf:about=""> | ||||
|         <dc:format>image/svg+xml</dc:format> | ||||
|         <dc:type | ||||
|            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||||
|       </cc:Work> | ||||
|     </rdf:RDF> | ||||
|   </metadata> | ||||
|   <defs | ||||
|      id="defs10" /> | ||||
|   <sodipodi:namedview | ||||
|      pagecolor="#ffffff" | ||||
|      bordercolor="#666666" | ||||
|      borderopacity="1" | ||||
|      objecttolerance="10" | ||||
|      gridtolerance="10" | ||||
|      guidetolerance="10" | ||||
|      inkscape:pageopacity="0" | ||||
|      inkscape:pageshadow="2" | ||||
|      inkscape:window-width="1920" | ||||
|      inkscape:window-height="1001" | ||||
|      id="namedview8" | ||||
|      showgrid="false" | ||||
|      inkscape:zoom="0.33714286" | ||||
|      inkscape:cx="477.91309" | ||||
|      inkscape:cy="350" | ||||
|      inkscape:window-x="0" | ||||
|      inkscape:window-y="0" | ||||
|      inkscape:window-maximized="1" | ||||
|      inkscape:current-layer="svg6" /> | ||||
|   <g | ||||
|      transform="rotate(-180,342.1439,335.17672)" | ||||
|      id="g4"> | ||||
|     <path | ||||
|        d="m -20,670.71582 c 0,-1.85843 349.99229,-699.98853 350.57213,-699.28671 1.94549,2.35478 350.06752,699.46087 349.427,699.71927 -0.41837,0.16878 -79.29725,-33.69092 -175.2864,-75.24377 l -174.52574,-75.55065 -174.2421,75.53732 c -95.83317,41.54551 -174.625237,75.5373 -175.093498,75.5373 -0.46826,0 -0.851382,-0.32075 -0.851382,-0.71276 z" | ||||
|        style="fill:#00ff00;stroke:none" | ||||
|        id="path2" | ||||
|        inkscape:connector-curvature="0" /> | ||||
|   </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 1.9 KiB | 
| Before Width: | Height: | Size: 3.6 KiB | 
| Before Width: | Height: | Size: 3.8 KiB | 
| Before Width: | Height: | Size: 4.4 KiB | 
| Before Width: | Height: | Size: 4.7 KiB | 
| Before Width: | Height: | Size: 5.5 KiB | 
| Before Width: | Height: | Size: 5.8 KiB | 
| Before Width: | Height: | Size: 12 KiB | 
| Before Width: | Height: | Size: 16 KiB | 
| Before Width: | Height: | Size: 2.2 KiB | 
| Before Width: | Height: | Size: 3 KiB | 
| Before Width: | Height: | Size: 2.4 KiB | 
| Before Width: | Height: | Size: 2.6 KiB | 
| Before Width: | Height: | Size: 3 KiB | 
| Before Width: | Height: | Size: 3.1 KiB | 
| Before Width: | Height: | Size: 3.7 KiB | 
| Before Width: | Height: | Size: 3.9 KiB | 
| Before Width: | Height: | Size: 8.7 KiB | 
| Before Width: | Height: | Size: 12 KiB | 
| Before Width: | Height: | Size: 1.4 KiB | 
| Before Width: | Height: | Size: 1.9 KiB | 
| Before Width: | Height: | Size: 3.1 KiB | 
| Before Width: | Height: | Size: 3.3 KiB | 
| Before Width: | Height: | Size: 3.6 KiB | 
| Before Width: | Height: | Size: 3.8 KiB | 
| Before Width: | Height: | Size: 4.6 KiB | 
| Before Width: | Height: | Size: 4.9 KiB | 
| Before Width: | Height: | Size: 10 KiB | 
| Before Width: | Height: | Size: 14 KiB | 
| Before Width: | Height: | Size: 1.9 KiB | 
| Before Width: | Height: | Size: 2.5 KiB | 
| Before Width: | Height: | Size: 4.5 KiB | 
| Before Width: | Height: | Size: 5 KiB | 
| Before Width: | Height: | Size: 5.6 KiB | 
| Before Width: | Height: | Size: 6 KiB | 
| Before Width: | Height: | Size: 7.3 KiB | 
| Before Width: | Height: | Size: 8 KiB | 
| Before Width: | Height: | Size: 19 KiB | 
| Before Width: | Height: | Size: 26 KiB | 
| Before Width: | Height: | Size: 2.6 KiB | 
| Before Width: | Height: | Size: 3.4 KiB | 
| Before Width: | Height: | Size: 3.4 KiB | 
| Before Width: | Height: | Size: 3.6 KiB | 
| Before Width: | Height: | Size: 4.2 KiB | 
| Before Width: | Height: | Size: 4.4 KiB | 
| Before Width: | Height: | Size: 5.2 KiB | 
| Before Width: | Height: | Size: 5.5 KiB | 
| Before Width: | Height: | Size: 12 KiB | 
| Before Width: | Height: | Size: 16 KiB | 
| Before Width: | Height: | Size: 2.2 KiB | 
| Before Width: | Height: | Size: 2.7 KiB | 
| Before Width: | Height: | Size: 18 KiB | 
| Before Width: | Height: | Size: 20 KiB | 
| Before Width: | Height: | Size: 24 KiB | 
| Before Width: | Height: | Size: 26 KiB | 
| Before Width: | Height: | Size: 33 KiB | 
| Before Width: | Height: | Size: 36 KiB | 
| Before Width: | Height: | Size: 91 KiB | 
| Before Width: | Height: | Size: 133 KiB | 
| Before Width: | Height: | Size: 8.3 KiB | 
| Before Width: | Height: | Size: 13 KiB | 
| Before Width: | Height: | Size: 2 KiB | 
| Before Width: | Height: | Size: 2.1 KiB | 
| Before Width: | Height: | Size: 2.4 KiB | 
| Before Width: | Height: | Size: 2.5 KiB | 
| Before Width: | Height: | Size: 3 KiB | 
| Before Width: | Height: | Size: 3.3 KiB | 
| Before Width: | Height: | Size: 7.4 KiB | 
| Before Width: | Height: | Size: 10 KiB | 
| Before Width: | Height: | Size: 1.1 KiB | 
| Before Width: | Height: | Size: 1.6 KiB | 
| Before Width: | Height: | Size: 3.4 KiB | 
| Before Width: | Height: | Size: 3.7 KiB | 
| Before Width: | Height: | Size: 4.2 KiB | 
| Before Width: | Height: | Size: 4.4 KiB | 
| Before Width: | Height: | Size: 5.1 KiB | 
| Before Width: | Height: | Size: 5.5 KiB | 
| Before Width: | Height: | Size: 12 KiB | 
| Before Width: | Height: | Size: 16 KiB | 
| Before Width: | Height: | Size: 2.1 KiB | 
| Before Width: | Height: | Size: 2.8 KiB |