From 97369a1928c3a4a169d97d9e2302afd99b860ad1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gergely=20M=C3=A9sz=C3=A1ros=2C=20Ph=2ED?= Date: Wed, 27 Apr 2022 12:59:16 +0200 Subject: [PATCH 001/501] add missing religion layer (#786) Co-authored-by: GoteGuru --- modules/ui/layers.js | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/ui/layers.js b/modules/ui/layers.js index 009828c4..3e53c2f2 100644 --- a/modules/ui/layers.js +++ b/modules/ui/layers.js @@ -1802,6 +1802,7 @@ function getLayer(id) { if (id === "toggleCompass") return $("#compass"); if (id === "toggleRivers") return $("#rivers"); if (id === "toggleRelief") return $("#terrain"); + if (id === "toggleReligions") return $("#relig"); if (id === "toggleCultures") return $("#cults"); if (id === "toggleStates") return $("#regions"); if (id === "toggleProvinces") return $("#provs"); From a99c0be62374475a1c71dcd6ffaadc42fdf75474 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Anna=20Veronika?= <39062493+annapanni@users.noreply.github.com> Date: Sun, 1 May 2022 20:42:59 +0200 Subject: [PATCH 002/501] restoring inappropriate fix (#785) * restoring inappropriate fix * removing culture cell data on import --- modules/ui/cultures-editor.js | 50 ++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/modules/ui/cultures-editor.js b/modules/ui/cultures-editor.js index 484346cc..d87d935f 100644 --- a/modules/ui/cultures-editor.js +++ b/modules/ui/cultures-editor.js @@ -417,6 +417,26 @@ function editCultures() { tip(`Names for ${cBurgs.length} burgs are regenerated`, false, "success"); } + function removeCultureModel(culture) { + cults.select("#culture" + culture).remove(); + debug.select("#cultureCenter" + culture).remove(); + + pack.burgs.filter(b => b.culture == culture).forEach(b => (b.culture = 0)); + pack.states.forEach((s, i) => { + if (s.culture === culture) s.culture = 0; + }); + pack.cells.culture.forEach((c, i) => { + if (c === culture) pack.cells.culture[i] = 0; + }); + pack.cultures[culture].removed = true; + + const origin = pack.cultures[culture].origin; + pack.cultures.forEach(c => { + if (c.origin === culture) c.origin = origin; + }); + refreshCulturesEditor(); + } + function cultureRemove() { if (customization === 4) return; const culture = +this.parentNode.dataset.id; @@ -427,23 +447,7 @@ function editCultures() { title: "Remove culture", buttons: { Remove: function () { - cults.select("#culture" + culture).remove(); - debug.select("#cultureCenter" + culture).remove(); - - pack.burgs.filter(b => b.culture == culture).forEach(b => (b.culture = 0)); - pack.states.forEach((s, i) => { - if (s.culture === culture) s.culture = 0; - }); - pack.cells.culture.forEach((c, i) => { - if (c === culture) pack.cells.culture[i] = 0; - }); - pack.cultures[culture].removed = true; - - const origin = pack.cultures[culture].origin; - pack.cultures.forEach(c => { - if (c.origin === culture) c.origin = origin; - }); - refreshCulturesEditor(); + removeCultureModel(culture); $(this).dialog("close"); }, Cancel: function () { @@ -894,14 +898,13 @@ function editCultures() { const shapes = Object.keys(COA.shields.types) .map(type => Object.keys(COA.shields[type])) .flat(); - - const populated = pack.cells.pop.map((c, i) => (c ? i : null)).filter(c => c); - + const populated = pack.cells.pop.map((c, i) => c? i: null).filter(c => c); + cultures.forEach((item) => {if (item.i) item.removed = true}); for (const c of csv.iterator((a, b) => +a[0] > +b[0])) { let current; if (+c.id < cultures.length) { current = cultures[c.id]; - current.removed = false; + const ratio = current.urban / (current.rural + current.urban); applyPopulationChange(current.rural, current.urban, c.population * (1 - ratio), c.population * ratio, +c.id); } else { @@ -909,6 +912,7 @@ function editCultures() { cultures.push(current); } + current.removed = false; current.name = c.culture; current.code = abbreviate( current.name, @@ -930,9 +934,7 @@ function editCultures() { current.base = nameBaseIndex === -1 ? 0 : nameBaseIndex; } - const validId = cultures.filter(c => !c.removed).map(c => c.i); - cultures.forEach(item => (item.origin = validId.includes(item.origin) ? item.origin : 0)); - cultures[0].origin = null; + cultures.filter(c => c.removed).forEach(c => removeCultureModel(c.i)) drawCultures(); refreshCulturesEditor(); From cea549ed97cfc920c68fd3169e55c16daeefb8cd Mon Sep 17 00:00:00 2001 From: Azgaar Date: Sun, 1 May 2022 21:44:08 +0300 Subject: [PATCH 003/501] supporters update --- modules/ui/options.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ui/options.js b/modules/ui/options.js index fde657c1..09f5bee9 100644 --- a/modules/ui/options.js +++ b/modules/ui/options.js @@ -106,7 +106,7 @@ function showSupporters() { Frank Fewkes,jason baldrick,Game Master Pro,Andrew Kircher,Preston Mitchell,Chris Kohut,Emarandzeb,Trentin Bergeron,Damon Gallaty,Pleaseworkforonce, Jordan,William Markus,Sidr Dim,Alexander Whittaker,The Next Level,Patrick Valverde,Markus Peham,Daniel Cooper,the Beagles of Neorbus,Marley Moule, Maximilian Schielke,Johnathan Xavier Hutchinson,Ele,Rita,Randy Ross,John Wick,RedSpaz,cameron cannon,Ian Grau-Fay,Kyle Barrett,Charlotte Wiland, - David Kaul,E. Jason Davis,Cyberate,Atenfox,Sea Wolf,Holly Loveless`; + David Kaul,E. Jason Davis,Cyberate,Atenfox,Sea Wolf,Holly Loveless,Roekai,Alden Z,angel carrillo,Sam Spoerle`; const array = supporters .replace(/(?:\r\n|\r|\n)/g, "") From d12e22aa5c946f5071b2833eb246dd65abb6224e Mon Sep 17 00:00:00 2001 From: Azgaar Date: Thu, 5 May 2022 16:30:09 +0300 Subject: [PATCH 004/501] allow spellcheck in notes editor --- modules/ui/notes-editor.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/ui/notes-editor.js b/modules/ui/notes-editor.js index b985a5e8..62000acf 100644 --- a/modules/ui/notes-editor.js +++ b/modules/ui/notes-editor.js @@ -90,6 +90,8 @@ function editNotes(id, name) { toolbar: `code | undo redo | removeformat | bold italic strikethrough | forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image media table | fontselect fontsizeselect | blockquote hr charmap | print fullscreen`, media_alt_source: false, media_poster: false, + browser_spellcheck: true, + contextmenu: false, setup: editor => { editor.on("Change", updateLegend); } From 67f8c689831ebd502c0f2614651c146d08fba024 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Gergely?= Date: Sat, 7 May 2022 10:13:42 +0200 Subject: [PATCH 005/501] FIX: #791 Added markers block exporting markers --- modules/ui/markers-overview.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/ui/markers-overview.js b/modules/ui/markers-overview.js index 10ac506d..8ed5bba5 100644 --- a/modules/ui/markers-overview.js +++ b/modules/ui/markers-overview.js @@ -171,13 +171,15 @@ function overviewMarkers() { function exportMarkers() { const headers = "Id,Type,Icon,Name,Note,X,Y\n"; + const quote = s => '"' + s.replace('"', "'") + '"'; const body = pack.markers.map(marker => { const {i, type, icon, x, y} = marker; const id = `marker${i}`; const note = notes.find(note => note.id === id); - const legend = escape(note.legend); - return [id, type, icon, note.name, legend, x, y].join(","); + const name = note ? quote(note.name) : 'Unknown'; + const legend = note ? quote(note.legend) : ''; + return [id, type, icon, name, legend, x, y].join(","); }); const data = headers + body.join("\n"); From 5a35f0d320ffe12245a2f7bcbe9c752620484f00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Gergely?= Date: Sat, 7 May 2022 11:30:33 +0200 Subject: [PATCH 006/501] FIX: CSV export quote should comply rfc4180. Related to #791. --- modules/ui/markers-overview.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ui/markers-overview.js b/modules/ui/markers-overview.js index 8ed5bba5..5570ffb9 100644 --- a/modules/ui/markers-overview.js +++ b/modules/ui/markers-overview.js @@ -171,7 +171,7 @@ function overviewMarkers() { function exportMarkers() { const headers = "Id,Type,Icon,Name,Note,X,Y\n"; - const quote = s => '"' + s.replace('"', "'") + '"'; + const quote = s => '"' + s.replaceAll('"', '""') + '"'; const body = pack.markers.map(marker => { const {i, type, icon, x, y} = marker; From bd21aa6d8ead310811dab09eaa09e80feb021b5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Gergely?= Date: Sat, 7 May 2022 18:00:12 +0200 Subject: [PATCH 007/501] FIX: keep original burg population after submapping --- modules/submap.js | 1 + modules/ui/submap.js | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/submap.js b/modules/submap.js index 6ec6d2e9..dde13a19 100644 --- a/modules/submap.js +++ b/modules/submap.js @@ -367,6 +367,7 @@ window.Submap = (function () { pack.burgs.forEach((b, id) => { if (id == 0) return; // skip empty city of neturals [b.x, b.y] = projection(b.x, b.y); + b.population = b.population * options.scale; // adjust for populationRate change // disable out-of-map (removed) burgs if (!inMap(b.x, b.y)) { diff --git a/modules/ui/submap.js b/modules/ui/submap.js index a2fae5f7..1ed9847b 100644 --- a/modules/ui/submap.js +++ b/modules/ui/submap.js @@ -120,7 +120,8 @@ window.UISubmap = (function () { rescaleStyles: checked("submapRescaleStyles"), smoothHeightMap: scale > 2, inverse: (x, y) => [x / origScale + x0, y / origScale + y0], - projection: (x, y) => [(x - x0) * origScale, (y - y0) * origScale] + projection: (x, y) => [(x - x0) * origScale, (y - y0) * origScale], + scale: origScale, }; // converting map position on the planet From f53d5810d586f2cb7696e4eca143e7caf73d038e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Gergely?= Date: Sat, 7 May 2022 18:43:47 +0200 Subject: [PATCH 008/501] FIX: avoid redirect at watabou --- modules/ui/editors.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ui/editors.js b/modules/ui/editors.js index 819a2637..e3cd8668 100644 --- a/modules/ui/editors.js +++ b/modules/ui/editors.js @@ -320,7 +320,7 @@ function getMFCGlink(burg) { } const parameters = {name, population, size, seed, river, coast, farms, citadel, urban_castle, hub, plaza, temple, walls, shantytown, gates: -1}; - const url = new URL("https://watabou.github.io/city-generator"); + const url = new URL("https://watabou.github.io/city-generator/"); url.search = new URLSearchParams(parameters); if (sea) url.searchParams.append("sea", sea); From 1573fad58d3ddbc9051cd4ba8d44782af2157220 Mon Sep 17 00:00:00 2001 From: Azgaar Date: Sun, 8 May 2022 19:22:15 +0300 Subject: [PATCH 009/501] annotate template strings for syntax hightlight and format --- components/fill-box.js | 10 +- main.js | 14 +- modules/burgs-and-states.js | 4 +- modules/cultures-generator.js | 10 +- modules/io/auto-update.js | 4 +- modules/io/load.js | 14 +- modules/ui/biomes-editor.js | 49 ++++-- modules/ui/burg-editor.js | 10 +- modules/ui/burgs-overview.js | 46 +++--- modules/ui/coastline-editor.js | 79 ++++++--- modules/ui/cultures-editor.js | 81 +++++++--- modules/ui/diplomacy-editor.js | 6 +- modules/ui/editors.js | 50 +++--- modules/ui/emblems-editor.js | 264 ++++++++++++++++++++----------- modules/ui/general.js | 19 ++- modules/ui/heightmap-editor.js | 21 ++- modules/ui/ice-editor.js | 41 +++-- modules/ui/labels-editor.js | 7 +- modules/ui/lakes-editor.js | 73 ++++++--- modules/ui/military-overview.js | 60 ++++--- modules/ui/namesbase-editor.js | 8 +- modules/ui/options.js | 16 +- modules/ui/provinces-editor.js | 49 +++--- modules/ui/regiments-overview.js | 8 +- modules/ui/relief-editor.js | 2 +- modules/ui/religions-editor.js | 65 +++++--- modules/ui/rivers-overview.js | 18 ++- modules/ui/routes-editor.js | 130 +++++++++------ modules/ui/states-editor.js | 87 +++++++--- modules/ui/style.js | 4 +- modules/ui/submap.js | 3 +- modules/ui/tools.js | 2 +- modules/ui/units-editor.js | 5 +- modules/ui/world-configurator.js | 8 +- modules/ui/zones-editor.js | 9 +- 35 files changed, 816 insertions(+), 460 deletions(-) diff --git a/components/fill-box.js b/components/fill-box.js index 02912f3b..b4d075c3 100644 --- a/components/fill-box.js +++ b/components/fill-box.js @@ -1,7 +1,5 @@ -// fill-box cannot use Shadow DOM as it needs access to svg hatches -// append stylesheet { - const style = ` + const style = /* css */ ` fill-box:not([disabled]) { cursor: pointer; } @@ -14,7 +12,8 @@ fill-box > svg > rect { stroke: #666666; stroke-width: 2; - }`; + } + `; const styleElement = document.createElement("style"); styleElement.setAttribute("type", "text/css"); @@ -24,7 +23,7 @@ { const template = document.createElement("template"); - template.innerHTML = ` + template.innerHTML = /* html */ ` @@ -70,5 +69,6 @@ } } + // cannot use Shadow DOM here as need an access to svg hatches customElements.define("fill-box", FillBox); } diff --git a/main.js b/main.js index cdb329af..39a70d29 100644 --- a/main.js +++ b/main.js @@ -176,8 +176,8 @@ oceanLayers.append("rect").attr("id", "oceanBase").attr("x", 0).attr("y", 0).att document.addEventListener("DOMContentLoaded", async () => { if (!location.hostname) { const wiki = "https://github.com/Azgaar/Fantasy-Map-Generator/wiki/Run-FMG-locally"; - alertMessage.innerHTML = `Fantasy Map Generator cannot run serverless. - Follow the instructions on how you can easily run a local web-server`; + alertMessage.innerHTML = /* html */ `Fantasy Map Generator cannot run serverless. Follow the instructions on how you can + easily run a local web-server`; $("#alert").dialog({ resizable: false, @@ -455,9 +455,10 @@ function showWelcomeMessage() { const discord = link("https://discordapp.com/invite/X7E84HU", "Discord server"); const patreon = link("https://www.patreon.com/azgaar", "Patreon"); - alertMessage.innerHTML = `The Fantasy Map Generator is updated up to version ${version}. - This version is compatible with ${changelog}, loaded .map files will be auto-updated. -
    Latest changes: + alertMessage.innerHTML = /* html */ `The Fantasy Map Generator is updated up to version ${version}. This version is compatible with ${changelog}, + loaded .map files will be auto-updated. +
      + Latest changes:
    • Submap tool by Goteguru
    • Resample tool by Goteguru
    • Pre-defined heightmaps
    • @@ -713,8 +714,7 @@ async function generate() { const parsedError = parseError(error); clearMainTip(); - alertMessage.innerHTML = `An error has occurred on map generation. Please retry. -
      If error is critical, clear the stored data and try again. + alertMessage.innerHTML = /* html */ `An error has occurred on map generation. Please retry.
      If error is critical, clear the stored data and try again.

      ${parsedError}

      `; $("#alert").dialog({ resizable: false, diff --git a/modules/burgs-and-states.js b/modules/burgs-and-states.js index e64e3e77..f3f5164e 100644 --- a/modules/burgs-and-states.js +++ b/modules/burgs-and-states.js @@ -41,7 +41,7 @@ window.BurgsAndStates = (function () { if (sorted.length < count * 10) { count = Math.floor(sorted.length / 10); if (!count) { - WARN && console.warn(`There is no populated cells. Cannot generate states`); + WARN && console.warn("There is no populated cells. Cannot generate states"); return burgs; } else { WARN && console.warn(`Not enough populated cells (${sorted.length}). Will generate only ${count} states`); @@ -883,7 +883,7 @@ window.BurgsAndStates = (function () { dd.forEach((r, d) => { if (r !== "Ally" || states[d].diplomacy.includes("Vassal")) return; if (states[d].diplomacy[attacker] !== "Rival" && ap / dp > 2 * gauss(1.6, 0.8, 0, 10, 2)) { - const reason = states[d].diplomacy.includes("Enemy") ? `Being already at war,` : `Frightened by ${an},`; + const reason = states[d].diplomacy.includes("Enemy") ? "Being already at war," : `Frightened by ${an},`; war.push(`${reason} ${states[d].name} severed the defense pact with ${dn}`); dd[d] = states[d].diplomacy[defender] = "Suspicion"; return; diff --git a/modules/cultures-generator.js b/modules/cultures-generator.js index b4733260..37f5bc93 100644 --- a/modules/cultures-generator.js +++ b/modules/cultures-generator.js @@ -15,9 +15,8 @@ window.Cultures = (function () { if (!count) { WARN && console.warn(`There are no populated cells. Cannot generate cultures`); pack.cultures = [{name: "Wildlands", i: 0, base: 1, shield: "round"}]; - alertMessage.innerHTML = ` - The climate is harsh and people cannot live in this world.
      - No cultures, states and burgs will be created.
      + alertMessage.innerHTML = /* html */ ` The climate is harsh and people cannot live in this world.
      + No cultures, states and burgs will be created.
      Please consider changing climate settings in the World Configurator`; $("#alert").dialog({ resizable: false, @@ -31,9 +30,8 @@ window.Cultures = (function () { return; } else { WARN && console.warn(`Not enough populated cells (${populated.length}). Will generate only ${count} cultures`); - alertMessage.innerHTML = ` - There are only ${populated.length} populated cells and it's insufficient livable area.
      - Only ${count} out of ${culturesInput.value} requested cultures will be generated.
      + alertMessage.innerHTML = /* html */ ` There are only ${populated.length} populated cells and it's insufficient livable area.
      + Only ${count} out of ${culturesInput.value} requested cultures will be generated.
      Please consider changing climate settings in the World Configurator`; $("#alert").dialog({ resizable: false, diff --git a/modules/io/auto-update.js b/modules/io/auto-update.js index 064af0ad..08b9c056 100644 --- a/modules/io/auto-update.js +++ b/modules/io/auto-update.js @@ -69,7 +69,7 @@ export function resolveVersionConflicts(version) { labels.selectAll("textPath").each(function () { const text = this.textContent; const shift = this.getComputedTextLength() / -1.5; - this.innerHTML = `${text}`; + this.innerHTML = /* html */ `${text}`; }); // v1.0 added new biome - Wetland @@ -362,7 +362,7 @@ export function resolveVersionConflicts(version) { const pattern = document.getElementById("oceanic"); const filter = pattern.firstElementChild.getAttribute("filter"); const href = filter ? "./images/" + filter.replace("url(#", "").replace(")", "") + ".png" : ""; - pattern.innerHTML = ``; + pattern.innerHTML = /* html */ ``; } if (version < 1.62) { diff --git a/modules/io/load.js b/modules/io/load.js index 75687c05..f031e69f 100644 --- a/modules/io/load.js +++ b/modules/io/load.js @@ -50,8 +50,8 @@ function loadMapPrompt(blob) { return; } - alertMessage.innerHTML = `Are you sure you want to load saved map?
      - All unsaved changes made to the current map will be lost`; + alertMessage.innerHTML = /* html */ `Are you sure you want to load saved map?
      + All unsaved changes made to the current map will be lost`; $("#alert").dialog({ resizable: false, title: "Load saved map", @@ -94,9 +94,10 @@ function loadMapFromURL(maplink, random) { function showUploadErrorMessage(error, URL, random) { ERROR && console.error(error); - alertMessage.innerHTML = `Cannot load map from the ${link(URL, "link provided")}. - ${random ? `A new random map is generated. ` : ""} - Please ensure the linked file is reachable and CORS is allowed on server side`; + alertMessage.innerHTML = /* html */ `Cannot load map from the ${link(URL, "link provided")}. ${ + random ? `A new random map is generated. ` : "" + } Please ensure the + linked file is reachable and CORS is allowed on server side`; $("#alert").dialog({ title: "Loading error", width: "32em", @@ -563,8 +564,7 @@ async function parseLoadedData(data) { ERROR && console.error(error); clearMainTip(); - alertMessage.innerHTML = `An error is occured on map loading. Select a different file to load, -
      generate a new random map or cancel the loading + alertMessage.innerHTML = /* html */ `An error is occured on map loading. Select a different file to load,
      generate a new random map or cancel the loading

      ${parseError(error)}

      `; $("#alert").dialog({ diff --git a/modules/ui/biomes-editor.js b/modules/ui/biomes-editor.js index 527e0b08..868a2505 100644 --- a/modules/ui/biomes-editor.js +++ b/modules/ui/biomes-editor.js @@ -92,23 +92,38 @@ function editBiomes() { totalArea += area; totalPopulation += population; - lines += `
      - - - % - - -
      ${b.cells[i]}
      - -
      ${si(area) + unit}
      - -
      ${si(population)}
      - - ${i > 12 && !b.cells[i] ? '' : ""} -
      `; + lines += /* html */ ` +
      + + + % + + +
      ${b.cells[i]}
      + +
      ${si(area) + unit}
      + +
      ${si(population)}
      + + ${i > 12 && !b.cells[i] ? '' : ""} +
      + `; } body.innerHTML = lines; diff --git a/modules/ui/burg-editor.js b/modules/ui/burg-editor.js index 0e7aacf0..ea3a76f2 100644 --- a/modules/ui/burg-editor.js +++ b/modules/ui/burg-editor.js @@ -281,10 +281,10 @@ function editBurg(id) { const burgsToRemove = burgsInGroup.filter(b => !(pack.burgs[b].capital || pack.burgs[b].lock)); const capital = burgsToRemove.length < burgsInGroup.length; - alertMessage.innerHTML = `Are you sure you want to remove - ${basic || capital ? "all unlocked elements in the burg group" : "the entire burg group"}? -
      Please note that capital or locked burgs will not be deleted. -

      Burgs to be removed: ${burgsToRemove.length}`; + alertMessage.innerHTML = /* html */ `Are you sure you want to remove ${ + basic || capital ? "all unlocked elements in the burg group" : "the entire burg group" + }? +
      Please note that capital or locked burgs will not be deleted.

      Burgs to be removed: ${burgsToRemove.length}`; $("#alert").dialog({ resizable: false, title: "Remove burg group", @@ -545,7 +545,7 @@ function editBurg(id) { function removeSelectedBurg() { const id = +elSelected.attr("data-id"); if (pack.burgs[id].capital) { - alertMessage.innerHTML = `You cannot remove the burg as it is a state capital.

      + alertMessage.innerHTML = /* html */ `You cannot remove the burg as it is a state capital.

      You can change the capital using Burgs Editor (shift + T)`; $("#alert").dialog({ resizable: false, diff --git a/modules/ui/burgs-overview.js b/modules/ui/burgs-overview.js index 454671cb..bf819465 100644 --- a/modules/ui/burgs-overview.js +++ b/modules/ui/burgs-overview.js @@ -82,22 +82,30 @@ function overviewBurgs() { const province = prov ? pack.provinces[prov].name : ""; const culture = pack.cultures[b.culture].name; - lines += `
      + lines += /* html */ `
      - - - - + + + + - +
      - +
      @@ -312,11 +320,12 @@ function overviewBurgs() { const treeLayout = d3.pack().size([w, h]).padding(3); // prepare svg - alertMessage.innerHTML = ` - `; + + `; alertMessage.innerHTML += `
      `; const svg = d3 .select("#alertMessage") @@ -349,7 +358,7 @@ function overviewBurgs() { const parent = d.parent.data.name; const population = si(d.value * populationRate * urbanization); - burgsInfo.innerHTML = `${name}. ${parent}. Population: ${population}`; + burgsInfo.innerHTML = /* html */ `${name}. ${parent}. Population: ${population}`; burgHighlightOn(ev); tip("Click to zoom into view"); } @@ -483,9 +492,8 @@ function overviewBurgs() { } function renameBurgsInBulk() { - alertMessage.innerHTML = `Download burgs list as a text file, make changes and re-upload the file. - Make sure the file is a plain text document with each name on its own line (the dilimiter is CRLF). - If you do not want to change the name, just leave it as is`; + alertMessage.innerHTML = /* html */ `Download burgs list as a text file, make changes and re-upload the file. Make sure the file is a plain text document with each + name on its own line (the dilimiter is CRLF). If you do not want to change the name, just leave it as is`; $("#alert").dialog({ title: "Burgs bulk renaming", diff --git a/modules/ui/coastline-editor.js b/modules/ui/coastline-editor.js index b1c357a9..faa50b8d 100644 --- a/modules/ui/coastline-editor.js +++ b/modules/ui/coastline-editor.js @@ -5,7 +5,8 @@ function editCoastline(node = d3.event.target) { if (layerIsOn("toggleCells")) toggleCells(); $("#coastlineEditor").dialog({ - title: "Edit Coastline", resizable: false, + title: "Edit Coastline", + resizable: false, position: {my: "center top+20", at: "top", of: d3.event, collision: "fit"}, close: closeCoastlineEditor }); @@ -33,13 +34,27 @@ function editCoastline(node = d3.event.target) { const v = pack.features[f].vertices; // coastline outer vertices const l = pack.cells.i.length; - const c = [... new Set(v.map(v => pack.vertices.c[v]).flat())].filter(c => c < l); - debug.select("#vertices").selectAll("polygon").data(c).enter().append("polygon") - .attr("points", d => getPackPolygon(d)).attr("data-c", d => d); + const c = [...new Set(v.map(v => pack.vertices.c[v]).flat())].filter(c => c < l); + debug + .select("#vertices") + .selectAll("polygon") + .data(c) + .enter() + .append("polygon") + .attr("points", d => getPackPolygon(d)) + .attr("data-c", d => d); - debug.select("#vertices").selectAll("circle").data(v).enter().append("circle") - .attr("cx", d => pack.vertices.p[d][0]).attr("cy", d => pack.vertices.p[d][1]) - .attr("r", .4).attr("data-v", d => d).call(d3.drag().on("drag", dragVertex)) + debug + .select("#vertices") + .selectAll("circle") + .data(v) + .enter() + .append("circle") + .attr("cx", d => pack.vertices.p[d][0]) + .attr("cy", d => pack.vertices.p[d][1]) + .attr("r", 0.4) + .attr("data-v", d => d) + .call(d3.drag().on("drag", dragVertex)) .on("mousemove", () => tip("Drag to move the vertex, please use for fine-tuning only. Edit heightmap to change actual cell heights")); const unit = areaUnit.value === "square" ? " " + distanceUnitInput.value + "²" : " " + areaUnit.value; @@ -48,12 +63,16 @@ function editCoastline(node = d3.event.target) { } function dragVertex() { - const x = rn(d3.event.x, 2), y = rn(d3.event.y, 2); + const x = rn(d3.event.x, 2), + y = rn(d3.event.y, 2); this.setAttribute("cx", x); this.setAttribute("cy", y); const v = +this.dataset.v; pack.vertices.p[v] = [x, y]; - debug.select("#vertices").selectAll("polygon").attr("points", d => getPackPolygon(d)); + debug + .select("#vertices") + .selectAll("polygon") + .attr("points", d => getPackPolygon(d)); redrawCoastline(); } @@ -61,11 +80,14 @@ function editCoastline(node = d3.event.target) { lineGen.curve(d3.curveBasisClosed); const f = +elSelected.attr("data-f"); const vertices = pack.features[f].vertices; - const points = clipPoly(vertices.map(v => pack.vertices.p[v]), 1); + const points = clipPoly( + vertices.map(v => pack.vertices.p[v]), + 1 + ); const d = round(lineGen(points)); elSelected.attr("d", d); - defs.select("mask#land > path#land_"+f).attr("d", d); // update land mask - defs.select("mask#water > path#water_"+f).attr("d", d); // update water mask + defs.select("mask#land > path#land_" + f).attr("d", d); // update land mask + defs.select("mask#water > path#water_" + f).attr("d", d); // update water mask const unit = areaUnit.value === "square" ? " " + distanceUnitInput.value + "²" : " " + areaUnit.value; const area = Math.abs(d3.polygonArea(points)); @@ -73,12 +95,12 @@ function editCoastline(node = d3.event.target) { } function showGroupSection() { - document.querySelectorAll("#coastlineEditor > button").forEach(el => el.style.display = "none"); + document.querySelectorAll("#coastlineEditor > button").forEach(el => (el.style.display = "none")); document.getElementById("coastlineGroupsSelection").style.display = "inline-block"; } function hideGroupSection() { - document.querySelectorAll("#coastlineEditor > button").forEach(el => el.style.display = "inline-block"); + document.querySelectorAll("#coastlineEditor > button").forEach(el => (el.style.display = "inline-block")); document.getElementById("coastlineGroupsSelection").style.display = "none"; document.getElementById("coastlineGroupName").style.display = "none"; document.getElementById("coastlineGroupName").value = ""; @@ -90,7 +112,7 @@ function editCoastline(node = d3.event.target) { const select = document.getElementById("coastlineGroup"); select.options.length = 0; // remove all options - coastline.selectAll("g").each(function() { + coastline.selectAll("g").each(function () { select.options.add(new Option(this.id, this.id, false, this.id === group)); }); } @@ -111,8 +133,14 @@ function editCoastline(node = d3.event.target) { } function createNewGroup() { - if (!this.value) {tip("Please provide a valid group name"); return;} - const group = this.value.toLowerCase().replace(/ /g, "_").replace(/[^\w\s]/gi, ""); + if (!this.value) { + tip("Please provide a valid group name"); + return; + } + const group = this.value + .toLowerCase() + .replace(/ /g, "_") + .replace(/[^\w\s]/gi, ""); if (document.getElementById(group)) { tip("Element with this id already exists. Please provide a unique name", false, "error"); @@ -155,11 +183,14 @@ function editCoastline(node = d3.event.target) { } const count = elSelected.node().parentNode.childElementCount; - alertMessage.innerHTML = `Are you sure you want to remove the group? - All coastline elements of the group (${count}) will be moved under sea_island group`; - $("#alert").dialog({resizable: false, title: "Remove coastline group", width:"26em", + alertMessage.innerHTML = /* html */ `Are you sure you want to remove the group? All coastline elements of the group (${count}) will be moved under + sea_island group`; + $("#alert").dialog({ + resizable: false, + title: "Remove coastline group", + width: "26em", buttons: { - Remove: function() { + Remove: function () { $(this).dialog("close"); const sea = document.getElementById("sea_island"); const groupEl = document.getElementById(group); @@ -170,7 +201,9 @@ function editCoastline(node = d3.event.target) { document.getElementById("coastlineGroup").selectedOptions[0].remove(); document.getElementById("coastlineGroup").value = "sea_island"; }, - Cancel: function() {$(this).dialog("close");} + Cancel: function () { + $(this).dialog("close"); + } } }); } @@ -184,4 +217,4 @@ function editCoastline(node = d3.event.target) { debug.select("#vertices").remove(); unselect(); } -} \ No newline at end of file +} diff --git a/modules/ui/cultures-editor.js b/modules/ui/cultures-editor.js index d87d935f..1b869c78 100644 --- a/modules/ui/cultures-editor.js +++ b/modules/ui/cultures-editor.js @@ -84,22 +84,37 @@ function editCultures() { if (!c.i) { // Uncultured (neutral) line - lines += `
      + lines += /* html */ `
      - +
      ${c.cells}
      - - + +
      ${si(area) + unit}
      ${si(population)}
      - + ${ selectShape ? `` @@ -109,24 +124,45 @@ function editCultures() { continue; } - lines += `
      + lines += /* html */ `
      - +
      ${c.cells}
      - - + +
      ${si(area) + unit}
      ${si(population)}
      - + ${ selectShape ? `` @@ -200,7 +236,7 @@ function editCultures() { const rural = c.rural * populationRate; const urban = c.urban * populationRate * urbanization; const population = rural + urban > 0 ? si(rn(rural + urban)) + " people" : "Extinct"; - info.innerHTML = `${c.name} culture. ${c.type}. ${population}`; + info.innerHTML = /* html */ `${c.name} culture. ${c.type}. ${population}`; tip("Drag to change parent, drag to itself to move to the top level. Hold CTRL and click to change abbreviation"); } @@ -347,10 +383,9 @@ function editCultures() { const l = n => Number(n).toLocaleString(); const burgs = pack.burgs.filter(b => !b.removed && b.culture === culture); - alertMessage.innerHTML = ` - Rural: - Urban: -

      Total population: ${l(total)} ⇒ ${l(total)} (100%)

      `; + alertMessage.innerHTML = /* html */ ` Rural: Urban: + +

      Total population: ${l(total)} ⇒ ${l(total)} (100%)

      `; const update = function () { const totalNew = ruralPop.valueAsNumber + urbanPop.valueAsNumber; @@ -898,8 +933,10 @@ function editCultures() { const shapes = Object.keys(COA.shields.types) .map(type => Object.keys(COA.shields[type])) .flat(); - const populated = pack.cells.pop.map((c, i) => c? i: null).filter(c => c); - cultures.forEach((item) => {if (item.i) item.removed = true}); + const populated = pack.cells.pop.map((c, i) => (c ? i : null)).filter(c => c); + cultures.forEach(item => { + if (item.i) item.removed = true; + }); for (const c of csv.iterator((a, b) => +a[0] > +b[0])) { let current; if (+c.id < cultures.length) { @@ -934,7 +971,7 @@ function editCultures() { current.base = nameBaseIndex === -1 ? 0 : nameBaseIndex; } - cultures.filter(c => c.removed).forEach(c => removeCultureModel(c.i)) + cultures.filter(c => c.removed).forEach(c => removeCultureModel(c.i)); drawCultures(); refreshCulturesEditor(); diff --git a/modules/ui/diplomacy-editor.js b/modules/ui/diplomacy-editor.js index bed60a3b..c4e546c7 100644 --- a/modules/ui/diplomacy-editor.js +++ b/modules/ui/diplomacy-editor.js @@ -81,7 +81,7 @@ function editDiplomacy() { const selectedName = states[selectedId].name; COArenderer.trigger("stateCOA" + selectedId, states[selectedId].coa); - let lines = `
      + let lines = /* html */ `
      ${states[selectedId].fullName}
      `; @@ -98,7 +98,7 @@ function editDiplomacy() { const name = state.fullName.length < 23 ? state.fullName : state.name; COArenderer.trigger("stateCOA" + state.i, state.coa); - lines += `
      + lines += /* html */ `
      ${name}
      @@ -202,7 +202,7 @@ function editDiplomacy() { const object = states[objectId]; const footer = `
      ${object.fullName}
      `; - alertMessage.innerHTML = `
      ${header} ${options} ${footer}
      `; + alertMessage.innerHTML = /* html */ `
      ${header} ${options} ${footer}
      `; $("#alert").dialog({ width: fitContent(), diff --git a/modules/ui/editors.js b/modules/ui/editors.js index 819a2637..aef76a8b 100644 --- a/modules/ui/editors.js +++ b/modules/ui/editors.js @@ -60,7 +60,7 @@ function closeDialogs(except = "#except") { function moveCircle(x, y, r = 20) { let circle = document.getElementById("brushCircle"); if (!circle) { - const html = ``; + const html = /* html */ ``; document.getElementById("debug").insertAdjacentHTML("afterBegin", html); } else { circle.setAttribute("cx", x); @@ -192,9 +192,9 @@ function moveBurgToGroup(id, g) { function moveAllBurgsToGroup(fromGroup, toGroup) { const groupToMove = document.querySelector(`#burgIcons #${fromGroup}`); - const burgsToMove = Array.from(groupToMove.children).map(x=>x.dataset.id); - addBurgsGroup(toGroup) - burgsToMove.forEach(x=>moveBurgToGroup(x, toGroup)); + const burgsToMove = Array.from(groupToMove.children).map(x => x.dataset.id); + addBurgsGroup(toGroup); + burgsToMove.forEach(x => moveBurgToGroup(x, toGroup)); } function addBurgsGroup(group) { @@ -495,18 +495,17 @@ function createPicker() { .attr("width", 303) .attr("height", 20) .on("mousemove", () => tip("Color value in different color spaces. Edit to change")); - const html = ` - - - `; + const html = /* html */ ` + + `; spaces.node().insertAdjacentHTML("beforeend", html); spaces.selectAll("input").on("change", changePickerSpace); @@ -523,7 +522,7 @@ function createPicker() { .attr("fill", d) .attr("class", i ? "" : "selected") .attr("x", (i % 14) * 22 + 4) - .attr("y", 40 + Math.floor(i / 14)*20) + .attr("y", 40 + Math.floor(i / 14) * 20) .attr("width", 16) .attr("height", 16); }); @@ -534,9 +533,9 @@ function createPicker() { .attr("id", "picker_" + this.id) .attr("fill", "url(#" + this.id + ")") .attr("x", (i % 14) * 22 + 4) - .attr("y", Math.floor(i / 14)*20 + 20 + (number * 2)) + .attr("y", Math.floor(i / 14) * 20 + 20 + number * 2) .attr("width", 16) - .attr("height", 16) + .attr("height", 16); }); colors @@ -546,7 +545,9 @@ function createPicker() { hatches .selectAll("rect") .on("click", pickerFillClicked) - .on("mouseover", function() { tip("Click to fill with the hatching " + this.id) }); + .on("mouseover", function () { + tip("Click to fill with the hatching " + this.id); + }); // append box const bbox = picker.node().getBBox(); @@ -562,10 +563,15 @@ function createPicker() { .attr("fill", "#ffffff") .attr("stroke", "#5d4651") .on("mousemove", pos); - picker.insert("text", ":first-child").attr("x", width-20).attr("y", -10).attr("id", "pickerCloseText").text("✕"); + picker + .insert("text", ":first-child") + .attr("x", width - 20) + .attr("y", -10) + .attr("id", "pickerCloseText") + .text("✕"); picker .insert("rect", ":first-child") - .attr("x", width-23) + .attr("x", width - 23) .attr("y", -21) .attr("id", "pickerCloseRect") .attr("width", 14) diff --git a/modules/ui/emblems-editor.js b/modules/ui/emblems-editor.js index 5b74f58a..3ab3335a 100644 --- a/modules/ui/emblems-editor.js +++ b/modules/ui/emblems-editor.js @@ -13,7 +13,10 @@ function editEmblem(type, id, el) { updateElementSelectors(type, id, el); $("#emblemEditor").dialog({ - title: "Edit Emblem", resizable: true, width: "18.2em", height: "auto", + title: "Edit Emblem", + resizable: true, + width: "18.2em", + height: "auto", position: {my: "left top", at: "left+10 top+10", of: "svg", collision: "fit"}, close: closeEmblemEditor }); @@ -41,17 +44,17 @@ function editEmblem(type, id, el) { function defineEmblemData(e) { const parent = e.target.parentNode; - const [g, t] = parent.id === "burgEmblems" ? [pack.burgs, "burg"] : - parent.id === "provinceEmblems" ? [pack.provinces, "province"] : - [pack.states, "state"]; + const [g, t] = parent.id === "burgEmblems" ? [pack.burgs, "burg"] : parent.id === "provinceEmblems" ? [pack.provinces, "province"] : [pack.states, "state"]; const i = +e.target.dataset.i; type = t; - id = type+"COA"+i; + id = type + "COA" + i; el = g[i]; } function updateElementSelectors(type, id, el) { - let state = 0, province = 0, burg = 0; + let state = 0, + province = 0, + burg = 0; // set active type emblemStates.parentElement.className = type === "state" ? "active" : ""; @@ -61,7 +64,7 @@ function editEmblem(type, id, el) { // define selected values if (type === "state") state = el.i; else if (type === "province") { - province = el.i + province = el.i; state = pack.states[el.state].i; } else { burg = el.i; @@ -85,7 +88,7 @@ function editEmblem(type, id, el) { emblemBurgs.options.length = 0; emblemBurgs.options.add(new Option("", 0, false, !burg)); - const burgList = validBurgs.filter(burg => province ? pack.cells.province[burg.cell] === province : burg.state === state); + const burgList = validBurgs.filter(burg => (province ? pack.cells.province[burg.cell] === province : burg.state === state)); burgList.forEach(b => emblemBurgs.options.add(new Option(b.capital ? "👑 " + b.name : b.name, b.i, false, b.i === burg))); emblemBurgs.options[0].disabled = true; @@ -116,14 +119,14 @@ function editEmblem(type, id, el) { if (state) { type = "state"; el = pack.states[state]; - id = "stateCOA"+ state; + id = "stateCOA" + state; } else { // select neutral burg if state is changed to Neutrals const neutralBurgs = pack.burgs.filter(burg => burg.i && !burg.removed && !burg.state); if (!neutralBurgs.length) return; type = "burg"; el = neutralBurgs[0]; - id = "burgCOA"+ neutralBurgs[0].i; + id = "burgCOA" + neutralBurgs[0].i; } updateElementSelectors(type, id, el); } @@ -134,13 +137,13 @@ function editEmblem(type, id, el) { if (province) { type = "province"; el = pack.provinces[province]; - id = "provinceCOA"+ province; + id = "provinceCOA" + province; } else { // select state if province is changed to null value const state = +emblemStates.value; type = "state"; el = pack.states[state]; - id = "stateCOA"+ state; + id = "stateCOA" + state; } updateElementSelectors(type, id, el); @@ -150,7 +153,7 @@ function editEmblem(type, id, el) { const burg = +this.value; type = "burg"; el = pack.burgs[burg]; - id = "burgCOA"+ burg; + id = "burgCOA" + burg; updateElementSelectors(type, id, el); } @@ -166,23 +169,26 @@ function editEmblem(type, id, el) { } function changeSize() { - const size = el.coaSize = +this.value; + const size = (el.coaSize = +this.value); document.getElementById("emblemSizeSlider").value = size; document.getElementById("emblemSizeNumber").value = size; - const g = emblems.select("#"+type+"Emblems"); - g.select("[data-i='"+el.i+"']").remove(); + const g = emblems.select("#" + type + "Emblems"); + g.select("[data-i='" + el.i + "']").remove(); if (!size) return; // re-append use element const categotySize = +g.attr("font-size"); - const shift = categotySize * size / 2; + const shift = (categotySize * size) / 2; const x = el.x || el.pole[0]; const y = el.y || el.pole[1]; - g.append("use").attr("data-i", el.i) - .attr("x", rn(x - shift), 2).attr("y", rn(y - shift), 2) - .attr("width", size+"em").attr("height", size+"em") - .attr("href", "#"+id); + g.append("use") + .attr("data-i", el.i) + .attr("x", rn(x - shift), 2) + .attr("y", rn(y - shift), 2) + .attr("width", size + "em") + .attr("height", size + "em") + .attr("href", "#" + id); } function regenerate() { @@ -194,7 +200,7 @@ function editEmblem(type, id, el) { } const shield = el.coa.shield || COA.getShield(el.culture || parent?.culture || 0, el.state); - el.coa = COA.generate(parent ? parent.coa : null, .3, .1, null); + el.coa = COA.generate(parent ? parent.coa : null, 0.3, 0.1, null); el.coa.shield = shield; emblemShapeSelector.disabled = false; emblemShapeSelector.value = el.coa.shield; @@ -228,8 +234,8 @@ function editEmblem(type, id, el) { } const reader = new FileReader(); - - reader.onload = function(readerEvent) { + + reader.onload = function (readerEvent) { const result = readerEvent.target.result; const defs = document.getElementById("defs-emblems"); const coa = document.getElementById(id); // old emblem @@ -240,7 +246,7 @@ function editEmblem(type, id, el) { } else { const el = document.createElement("html"); el.innerHTML = result; - + // remove sodipodi and inkscape attributes el.querySelectorAll("*").forEach(el => { const attributes = el.getAttributeNames(); @@ -266,7 +272,8 @@ function editEmblem(type, id, el) { emblemShapeSelector.disabled = true; }; - if (type === "image") reader.readAsDataURL(file); else reader.readAsText(file); + if (type === "image") reader.readAsDataURL(file); + else reader.readAsText(file); } function toggleDownload() { @@ -282,7 +289,8 @@ function editEmblem(type, id, el) { const link = document.createElement("a"); link.download = getFileName(`Emblem ${el.fullName || el.name}`) + "." + format; - if (format === "svg") downloadSVG(url, link); else downloadRaster(format, url, link, size); + if (format === "svg") downloadSVG(url, link); + else downloadRaster(format, url, link, size); document.getElementById("emblemDownloadControl").classList.add("hidden"); } @@ -299,22 +307,22 @@ function editEmblem(type, id, el) { const img = new Image(); img.src = url; - img.onload = function() { + img.onload = function () { if (format === "jpeg") { ctx.fillStyle = "#fff"; ctx.fillRect(0, 0, canvas.width, canvas.height); } ctx.drawImage(img, 0, 0, canvas.width, canvas.height); - const dataURL = canvas.toDataURL("image/" + format, .92); + const dataURL = canvas.toDataURL("image/" + format, 0.92); link.href = dataURL; link.click(); window.setTimeout(() => window.URL.revokeObjectURL(dataURL), 6000); - } + }; } async function getURL(svg, size) { const serialized = getSVG(svg, size); - const blob = new Blob([serialized], {type: 'image/svg+xml;charset=utf-8'}); + const blob = new Blob([serialized], {type: "image/svg+xml;charset=utf-8"}); const url = window.URL.createObjectURL(blob); window.setTimeout(() => window.URL.revokeObjectURL(url), 6000); return url; @@ -324,7 +332,7 @@ function editEmblem(type, id, el) { const clone = svg.cloneNode(true); clone.setAttribute("width", size); clone.setAttribute("height", size); - return (new XMLSerializer()).serializeToString(clone); + return new XMLSerializer().serializeToString(clone); } async function downloadGallery() { @@ -338,70 +346,135 @@ function editEmblem(type, id, el) { function runDownload() { const back = `Go Back`; - const stateSection = `

      States

      ` + validStates.map(state => { - const el = document.getElementById("stateCOA"+state.i); - return `
      ${state.fullName}
      ${getSVG(el, 200)}
      `; - }).join("") + `
      `; + const stateSection = + `

      States

      ` + + validStates + .map(state => { + const el = document.getElementById("stateCOA" + state.i); + return `
      ${state.fullName}
      ${getSVG(el, 200)}
      `; + }) + .join("") + + `
      `; - const provinceSections = validStates.map(state => { - const stateProvinces = validProvinces.filter(p => p.state === state.i); - const figures = stateProvinces.map(province => { - const el = document.getElementById("provinceCOA"+province.i); - return `
      ${province.fullName}
      ${getSVG(el, 200)}
      `; - }).join(""); - return stateProvinces.length ? `
      ${back}

      ${state.fullName} provinces

      ${figures}
      ` : ""; - }).join(""); + const provinceSections = validStates + .map(state => { + const stateProvinces = validProvinces.filter(p => p.state === state.i); + const figures = stateProvinces + .map(province => { + const el = document.getElementById("provinceCOA" + province.i); + return `
      ${province.fullName}
      ${getSVG( + el, + 200 + )}
      `; + }) + .join(""); + return stateProvinces.length ? `
      ${back}

      ${state.fullName} provinces

      ${figures}
      ` : ""; + }) + .join(""); - const burgSections = validStates.map(state => { - const stateBurgs = validBurgs.filter(b => b.state === state.i); - let stateBurgSections = validProvinces.filter(p => p.state === state.i).map(province => { - const provinceBurgs = stateBurgs.filter(b => pack.cells.province[b.cell] === province.i); - const provinceBurgFigures = provinceBurgs.map(burg => { - const el = document.getElementById("burgCOA"+burg.i); - return `
      ${burg.name}
      ${getSVG(el, 200)}
      `; - }).join(""); - return provinceBurgs.length ? `
      ${back}

      ${province.fullName} burgs

      ${provinceBurgFigures}
      ` : ""; - }).join(""); + const burgSections = validStates + .map(state => { + const stateBurgs = validBurgs.filter(b => b.state === state.i); + let stateBurgSections = validProvinces + .filter(p => p.state === state.i) + .map(province => { + const provinceBurgs = stateBurgs.filter(b => pack.cells.province[b.cell] === province.i); + const provinceBurgFigures = provinceBurgs + .map(burg => { + const el = document.getElementById("burgCOA" + burg.i); + return `
      ${burg.name}
      ${getSVG(el, 200)}
      `; + }) + .join(""); + return provinceBurgs.length ? `
      ${back}

      ${province.fullName} burgs

      ${provinceBurgFigures}
      ` : ""; + }) + .join(""); - const stateBurgOutOfProvinces = stateBurgs.filter(b => !pack.cells.province[b.cell]); - const stateBurgOutOfProvincesFigures = stateBurgOutOfProvinces.map(burg => { - const el = document.getElementById("burgCOA"+burg.i); - return `
      ${burg.name}
      ${getSVG(el, 200)}
      `; - }).join(""); - if (stateBurgOutOfProvincesFigures) stateBurgSections += `

      ${state.fullName} burgs under direct control

      ${stateBurgOutOfProvincesFigures}
      `; - return stateBurgSections; - }).join(""); + const stateBurgOutOfProvinces = stateBurgs.filter(b => !pack.cells.province[b.cell]); + const stateBurgOutOfProvincesFigures = stateBurgOutOfProvinces + .map(burg => { + const el = document.getElementById("burgCOA" + burg.i); + return `
      ${burg.name}
      ${getSVG(el, 200)}
      `; + }) + .join(""); + if (stateBurgOutOfProvincesFigures) + stateBurgSections += `

      ${state.fullName} burgs under direct control

      ${stateBurgOutOfProvincesFigures}
      `; + return stateBurgSections; + }) + .join(""); const neutralBurgs = validBurgs.filter(b => !b.state); - const neutralsSection = neutralBurgs.length ? "

      Independent burgs

      " + neutralBurgs.map(burg => { - const el = document.getElementById("burgCOA"+burg.i); - return `
      ${burg.name}
      ${getSVG(el, 200)}
      `; - }).join("") + "
      " : ""; + const neutralsSection = neutralBurgs.length + ? "

      Independent burgs

      " + + neutralBurgs + .map(burg => { + const el = document.getElementById("burgCOA" + burg.i); + return `
      ${burg.name}
      ${getSVG(el, 200)}
      `; + }) + .join("") + + "
      " + : ""; const FMG = `Azgaar's Fantasy Map Generator`; const license = `the license`; - const html = `${mapName.value} Emblems Gallery - - - -

      ${mapName.value} Emblems Gallery

      - ${stateSection} - ${provinceSections} - ${burgSections} - ${neutralsSection} -
      Generated by ${FMG}. The tool is free, but images may be copyrighted, see ${license}
      - `; + const html = /* html */ ` + + + ${mapName.value} Emblems Gallery + + + + +

      ${mapName.value} Emblems Gallery

      + ${stateSection} ${provinceSections} ${burgSections} ${neutralsSection} +
      Generated by ${FMG}. The tool is free, but images may be copyrighted, see ${license}
      + + `; downloadFile(html, name + ".html", "text/plain"); } } @@ -409,9 +482,9 @@ function editEmblem(type, id, el) { async function renderAllEmblems(states, provinces, burgs) { tip("Preparing for download...", true, "warn"); - const statePromises = states.map(state => COArenderer.trigger("stateCOA"+state.i, state.coa)); - const provincePromises = provinces.map(province => COArenderer.trigger("provinceCOA"+province.i, province.coa)); - const burgPromises = burgs.map(burg => COArenderer.trigger("burgCOA"+burg.i, burg.coa)); + const statePromises = states.map(state => COArenderer.trigger("stateCOA" + state.i, state.coa)); + const provincePromises = provinces.map(province => COArenderer.trigger("provinceCOA" + province.i, province.coa)); + const burgPromises = burgs.map(burg => COArenderer.trigger("burgCOA" + burg.i, burg.coa)); const promises = [...statePromises, ...provincePromises, ...burgPromises]; return Promise.allSettled(promises).then(res => clearMainTip()); @@ -419,10 +492,11 @@ function editEmblem(type, id, el) { function dragEmblem() { const tr = parseTransform(this.getAttribute("transform")); - const x = +tr[0] - d3.event.x, y = +tr[1] - d3.event.y; + const x = +tr[0] - d3.event.x, + y = +tr[1] - d3.event.y; - d3.event.on("drag", function() { - const transform = `translate(${(x + d3.event.x)},${(y + d3.event.y)})`; + d3.event.on("drag", function () { + const transform = `translate(${x + d3.event.x},${y + d3.event.y})`; this.setAttribute("transform", transform); }); } @@ -430,4 +504,4 @@ function editEmblem(type, id, el) { function closeEmblemEditor() { emblems.selectAll("use").call(d3.drag().on("drag", null)).attr("class", null); } -} \ No newline at end of file +} diff --git a/modules/ui/general.js b/modules/ui/general.js index 91605161..db08473e 100644 --- a/modules/ui/general.js +++ b/modules/ui/general.js @@ -405,7 +405,7 @@ document.querySelectorAll("[data-locked]").forEach(function (e) { // lock option function lock(id) { - const input = document.querySelector("[data-stored=\"" + id + "\"]"); + const input = document.querySelector('[data-stored="' + id + '"]'); if (input) localStorage.setItem(id, input.value); const el = document.getElementById("lock_" + id); if (!el) return; @@ -467,15 +467,18 @@ function showInfo() { const QAA = link("https://github.com/Azgaar/Fantasy-Map-Generator/wiki/Q&A", "Q&A page"); const VideoTutorial = link("https://youtube.com/playlist?list=PLtgiuDC8iVR2gIG8zMTRn7T_L0arl9h1C", "Video tutorial"); - alertMessage.innerHTML = ` - Fantasy Map Generator (FMG) is a free open-source application. - It means that you own all created maps and can use them as you wish. + alertMessage.innerHTML = /* html */ `Fantasy Map Generator (FMG) is a free open-source application. It means that you own all created maps and can use them as + you wish. -

      The development is community-backed, you can donate on ${Patreon}. - You can also help creating overviews, tutorials and spreding the word about the Generator.

      +

      + The development is community-backed, you can donate on ${Patreon}. You can also help creating overviews, tutorials and spreding the word about the + Generator. +

      -

      The best way to get help is to contact the community on ${Discord} and ${Reddit}. - Before asking questions, please check out the ${QuickStart}, the ${QAA}, and ${VideoTutorial}.

      +

      + The best way to get help is to contact the community on ${Discord} and ${Reddit}. Before asking questions, please check out the ${QuickStart}, the ${QAA}, + and ${VideoTutorial}. +

      Check out our another project: ${Armoria} — heraldry generator and editor.

      diff --git a/modules/ui/heightmap-editor.js b/modules/ui/heightmap-editor.js index effb81c7..fae944f3 100644 --- a/modules/ui/heightmap-editor.js +++ b/modules/ui/heightmap-editor.js @@ -2,12 +2,14 @@ function editHeightmap() { void (function selectEditMode() { - alertMessage.innerHTML = `Heightmap is a core element on which all other data (rivers, burgs, states etc) is based. - So the best edit approach is to erase the secondary data and let the system automatically regenerate it on edit completion. + alertMessage.innerHTML = /* html */ `Heightmap is a core element on which all other data (rivers, burgs, states etc) is based. So the best edit approach is to + erase the secondary data and let the system automatically regenerate it on edit completion.

      Erase mode also allows you Convert an Image into a heightmap or use Template Editor.

      You can keep the data, but you won't be able to change the coastline.

      -

      Try risk mode to change the coastline and keep the data. The data will be restored as much as possible, but it can cause unpredictable errors.

      -

      Please save the map before editing the heightmap!

      +

      + Try risk mode to change the coastline and keep the data. The data will be restored as much as possible, but it can cause unpredictable errors. +

      +

      Please save the map before editing the heightmap!

      Check out ${link("https://github.com/Azgaar/Fantasy-Map-Generator/wiki/Heightmap-customization", "wiki")} for guidance.

      `; $("#alert").dialog({ @@ -107,7 +109,7 @@ function editHeightmap() { heightmapInfoX.innerHTML = rn(p[0]); heightmapInfoY.innerHTML = rn(p[1]); heightmapInfoCell.innerHTML = cell; - heightmapInfoHeight.innerHTML = `${grid.cells.h[cell]} (${getHeight(grid.cells.h[cell])})`; + heightmapInfoHeight.innerHTML = /* html */ `${grid.cells.h[cell]} (${getHeight(grid.cells.h[cell])})`; if (tooltip.dataset.main) showMainTip(); // move radius circle if drag mode is active @@ -485,7 +487,7 @@ function editHeightmap() { function updateStatistics() { const landCells = grid.cells.h.reduce((s, h) => (h >= 20 ? s + 1 : s)); - landmassCounter.innerHTML = `${landCells} (${rn((landCells / grid.cells.i.length) * 100)}%)`; + landmassCounter.innerHTML = /* html */ `${landCells} (${rn((landCells / grid.cells.i.length) * 100)}%)`; landmassAverage.innerHTML = rn(d3.mean(grid.cells.h)); } @@ -1247,11 +1249,8 @@ function editHeightmap() { function closeImageConverter(event) { event.preventDefault(); event.stopPropagation(); - alertMessage.innerHTML = ` - Are you sure you want to close the Image Converter? - Click "Cancel" to geck back to convertion. - Click "Complete" to apply the conversion. - Click "Close" to exit conversion mode and restore previous heightmap`; + alertMessage.innerHTML = /* html */ ` Are you sure you want to close the Image Converter? Click "Cancel" to geck back to convertion. Click "Complete" to apply + the conversion. Click "Close" to exit conversion mode and restore previous heightmap`; $("#alert").dialog({ resizable: false, diff --git a/modules/ui/ice-editor.js b/modules/ui/ice-editor.js index f6648f48..5951e7aa 100644 --- a/modules/ui/ice-editor.js +++ b/modules/ui/ice-editor.js @@ -12,7 +12,8 @@ function editIce() { ice.selectAll("*").classed("draggable", true).call(d3.drag().on("drag", dragElement)); $("#iceEditor").dialog({ - title: "Edit "+type, resizable: false, + title: "Edit " + type, + resizable: false, position: {my: "center top+60", at: "top", of: d3.event, collision: "fit"}, close: closeEditor }); @@ -30,8 +31,9 @@ function editIce() { function randomizeShape() { const c = grid.points[+elSelected.attr("cell")]; const s = +elSelected.attr("size"); - const i = ra(grid.cells.i), cn = grid.points[i]; - const poly = getGridPolygon(i).map(p => [p[0]-cn[0], p[1]-cn[1]]); + const i = ra(grid.cells.i), + cn = grid.points[i]; + const poly = getGridPolygon(i).map(p => [p[0] - cn[0], p[1] - cn[1]]); const points = poly.map(p => [rn(c[0] + p[0] * s, 2), rn(c[1] + p[1] * s, 2)]); elSelected.attr("points", points); } @@ -39,10 +41,13 @@ function editIce() { function changeSize() { const c = grid.points[+elSelected.attr("cell")]; const s = +elSelected.attr("size"); - const flat = elSelected.attr("points").split(",").map(el => +el); + const flat = elSelected + .attr("points") + .split(",") + .map(el => +el); const pairs = []; - while (flat.length) pairs.push(flat.splice(0,2)); - const poly = pairs.map(p => [(p[0]-c[0]) / s, (p[1]-c[1]) / s]); + while (flat.length) pairs.push(flat.splice(0, 2)); + const poly = pairs.map(p => [(p[0] - c[0]) / s, (p[1] - c[1]) / s]); const size = +this.value; const points = poly.map(p => [rn(c[0] + p[0] * size, 2), rn(c[1] + p[1] * size, 2)]); elSelected.attr("points", points).attr("size", size); @@ -65,7 +70,7 @@ function editIce() { const c = grid.points[i]; const s = +document.getElementById("iceSize").value; - const points = getGridPolygon(i).map(p => [(p[0] + (c[0]-p[0]) / s)|0, (p[1] + (c[1]-p[1]) / s)|0]); + const points = getGridPolygon(i).map(p => [(p[0] + (c[0] - p[0]) / s) | 0, (p[1] + (c[1] - p[1]) / s) | 0]); const iceberg = ice.append("polygon").attr("points", points).attr("cell", i).attr("size", s); iceberg.call(d3.drag().on("drag", dragElement)); if (d3.event.shiftKey === false) toggleAdd(); @@ -73,26 +78,32 @@ function editIce() { function removeIce() { const type = elSelected.attr("type") ? "Glacier" : "Iceberg"; - alertMessage.innerHTML = `Are you sure you want to remove the ${type}?`; - $("#alert").dialog({resizable: false, title: "Remove "+type, + alertMessage.innerHTML = /* html */ `Are you sure you want to remove the ${type}?`; + $("#alert").dialog({ + resizable: false, + title: "Remove " + type, buttons: { - Remove: function() { + Remove: function () { $(this).dialog("close"); elSelected.remove(); $("#iceEditor").dialog("close"); }, - Cancel: function() {$(this).dialog("close");} + Cancel: function () { + $(this).dialog("close"); + } } }); } function dragElement() { const tr = parseTransform(this.getAttribute("transform")); - const dx = +tr[0] - d3.event.x, dy = +tr[1] - d3.event.y; + const dx = +tr[0] - d3.event.x, + dy = +tr[1] - d3.event.y; - d3.event.on("drag", function() { - const x = d3.event.x, y = d3.event.y; - this.setAttribute("transform", `translate(${(dx+x)},${(dy+y)})`); + d3.event.on("drag", function () { + const x = d3.event.x, + y = d3.event.y; + this.setAttribute("transform", `translate(${dx + x},${dy + y})`); }); } diff --git a/modules/ui/labels-editor.js b/modules/ui/labels-editor.js index 3d7a3b7f..8bd04cdd 100644 --- a/modules/ui/labels-editor.js +++ b/modules/ui/labels-editor.js @@ -257,9 +257,10 @@ function editLabel() { const group = elSelected.node().parentNode.id; const basic = group === "states" || group === "addedLabels"; const count = elSelected.node().parentNode.childElementCount; - alertMessage.innerHTML = `Are you sure you want to remove - ${basic ? "all elements in the group" : "the entire label group"}? -

      Labels to be removed: ${count}`; + alertMessage.innerHTML = /* html */ `Are you sure you want to remove ${ + basic ? "all elements in the group" : "the entire label group" + }?

      Labels to be + removed: ${count}`; $("#alert").dialog({ resizable: false, title: "Remove route group", diff --git a/modules/ui/lakes-editor.js b/modules/ui/lakes-editor.js index 3f1e4d60..eba1bd0d 100644 --- a/modules/ui/lakes-editor.js +++ b/modules/ui/lakes-editor.js @@ -5,7 +5,8 @@ function editLake() { if (layerIsOn("toggleCells")) toggleCells(); $("#lakeEditor").dialog({ - title: "Edit Lake", resizable: false, + title: "Edit Lake", + resizable: false, position: {my: "center top+20", at: "top", of: d3.event, collision: "fit"}, close: closeLakesEditor }); @@ -71,23 +72,41 @@ function editLake() { function drawLakeVertices() { const v = getLake().vertices; // lake outer vertices - const c = [... new Set(v.map(v => pack.vertices.c[v]).flat())]; - debug.select("#vertices").selectAll("polygon").data(c).enter().append("polygon") - .attr("points", d => getPackPolygon(d)).attr("data-c", d => d); + const c = [...new Set(v.map(v => pack.vertices.c[v]).flat())]; + debug + .select("#vertices") + .selectAll("polygon") + .data(c) + .enter() + .append("polygon") + .attr("points", d => getPackPolygon(d)) + .attr("data-c", d => d); - debug.select("#vertices").selectAll("circle").data(v).enter().append("circle") - .attr("cx", d => pack.vertices.p[d][0]).attr("cy", d => pack.vertices.p[d][1]) - .attr("r", .4).attr("data-v", d => d).call(d3.drag().on("drag", dragVertex)) + debug + .select("#vertices") + .selectAll("circle") + .data(v) + .enter() + .append("circle") + .attr("cx", d => pack.vertices.p[d][0]) + .attr("cy", d => pack.vertices.p[d][1]) + .attr("r", 0.4) + .attr("data-v", d => d) + .call(d3.drag().on("drag", dragVertex)) .on("mousemove", () => tip("Drag to move the vertex, please use for fine-tuning only. Edit heightmap to change actual cell heights")); } function dragVertex() { - const x = rn(d3.event.x, 2), y = rn(d3.event.y, 2); + const x = rn(d3.event.x, 2), + y = rn(d3.event.y, 2); this.setAttribute("cx", x); this.setAttribute("cy", y); const v = +this.dataset.v; pack.vertices.p[v] = [x, y]; - debug.select("#vertices").selectAll("polygon").attr("points", d => getPackPolygon(d)); + debug + .select("#vertices") + .selectAll("polygon") + .attr("points", d => getPackPolygon(d)); redrawLake(); } @@ -97,7 +116,7 @@ function editLake() { const points = feature.vertices.map(v => pack.vertices.p[v]); const d = round(lineGen(points)); elSelected.attr("d", d); - defs.select("mask#land > path#land_"+feature.i).attr("d", d); // update land mask + defs.select("mask#land > path#land_" + feature.i).attr("d", d); // update land mask const unit = areaUnit.value === "square" ? " " + distanceUnitInput.value + "²" : " " + areaUnit.value; feature.area = Math.abs(d3.polygonArea(points)); @@ -115,7 +134,7 @@ function editLake() { function generateNameRandom() { const lake = getLake(); - lake.name = lakeName.value = Names.getBase(rand(nameBases.length-1)); + lake.name = lakeName.value = Names.getBase(rand(nameBases.length - 1)); } function selectLakeGroup(node) { @@ -123,7 +142,7 @@ function editLake() { const select = document.getElementById("lakeGroup"); select.options.length = 0; // remove all options - lakes.selectAll("g").each(function() { + lakes.selectAll("g").each(function () { select.options.add(new Option(this.id, this.id, false, this.id === group)); }); } @@ -141,12 +160,18 @@ function editLake() { } else { lakeGroupName.style.display = "none"; lakeGroup.style.display = "inline-block"; - } + } } function createNewGroup() { - if (!this.value) {tip("Please provide a valid group name"); return;} - const group = this.value.toLowerCase().replace(/ /g, "_").replace(/[^\w\s]/gi, ""); + if (!this.value) { + tip("Please provide a valid group name"); + return; + } + const group = this.value + .toLowerCase() + .replace(/ /g, "_") + .replace(/[^\w\s]/gi, ""); if (document.getElementById(group)) { tip("Element with this id already exists. Please provide a unique name", false, "error"); @@ -180,7 +205,7 @@ function editLake() { toggleNewGroupInput(); document.getElementById("lakeGroupName").value = ""; } - + function removeLakeGroup() { const group = elSelected.node().parentNode.id; if (["freshwater", "salt", "sinkhole", "frozen", "lava", "dry"].includes(group)) { @@ -189,11 +214,13 @@ function editLake() { } const count = elSelected.node().parentNode.childElementCount; - alertMessage.innerHTML = `Are you sure you want to remove the group? - All lakes of the group (${count}) will be turned into Freshwater`; - $("#alert").dialog({resizable: false, title: "Remove lake group", width:"26em", + alertMessage.innerHTML = /* html */ `Are you sure you want to remove the group? All lakes of the group (${count}) will be turned into Freshwater`; + $("#alert").dialog({ + resizable: false, + title: "Remove lake group", + width: "26em", buttons: { - Remove: function() { + Remove: function () { $(this).dialog("close"); const freshwater = document.getElementById("freshwater"); const groupEl = document.getElementById(group); @@ -204,7 +231,9 @@ function editLake() { document.getElementById("lakeGroup").selectedOptions[0].remove(); document.getElementById("lakeGroup").value = "freshwater"; }, - Cancel: function() {$(this).dialog("close");} + Cancel: function () { + $(this).dialog("close"); + } } }); } @@ -223,4 +252,4 @@ function editLake() { debug.select("#vertices").remove(); unselect(); } -} \ No newline at end of file +} diff --git a/modules/ui/military-overview.js b/modules/ui/military-overview.js index 0d244314..24cf9367 100644 --- a/modules/ui/military-overview.js +++ b/modules/ui/military-overview.js @@ -75,18 +75,30 @@ function overviewMilitary() { const sortData = options.military.map(u => `data-${u.name}="${getForces(u)}"`).join(" "); const lineData = options.military.map(u => `
      ${getForces(u)}
      `).join(" "); - lines += `
      + lines += /* html */ `
      - + ${lineData}
      ${si(total)}
      ${si(population)}
      ${rn(rate, 2)}%
      - +
      `; } @@ -290,21 +302,28 @@ function overviewMilitary() { ${getLimitText(unit[attr])} `; - row.innerHTML = ` - + row.innerHTML = /* html */ ` + ${getLimitButton("biomes")} ${getLimitButton("states")} ${getLimitButton("cultures")} ${getLimitButton("religions")} - - - - - + + + + + + + - - - `; + + + + + + `; tableBody.appendChild(row); } @@ -326,7 +345,12 @@ function overviewMilitary() { ` ); - alertMessage.innerHTML = `Limit unit by ${type}:${lines.join("")}
      `; + alertMessage.innerHTML = /* html */ `Limit unit by ${type}: + + + ${lines.join("")} + +
      `; $("#alert").dialog({ width: fitContent(), diff --git a/modules/ui/namesbase-editor.js b/modules/ui/namesbase-editor.js index d347c498..74ddb793 100644 --- a/modules/ui/namesbase-editor.js +++ b/modules/ui/namesbase-editor.js @@ -154,15 +154,15 @@ function editNamesbase() { return "[good]"; }; - alertMessage.innerHTML = `
      + alertMessage.innerHTML = /* html */ `
      Namesbase length: ${length} ${getLengthQuality()}
      Namesbase variety: ${variety} ${getVarietyLevel()}
      -
      +
      Min name length: ${d3.min(wordsLength)}
      Max name length: ${d3.max(wordsLength)}
      Mean name length: ${rn(d3.mean(wordsLength), 1)}
      Median name length: ${d3.median(wordsLength)}
      -
      +
      Non-basic chars: ${nonBasicLatinChars}
      Doubled chars: ${doubled.join("")}
      Duplicates: ${duplicates}
      @@ -196,7 +196,7 @@ function editNamesbase() { } function namesbaseRestoreDefault() { - alertMessage.innerHTML = `Are you sure you want to restore default namesbase?`; + alertMessage.innerHTML = /* html */ `Are you sure you want to restore default namesbase?`; $("#alert").dialog({ resizable: false, title: "Restore default data", diff --git a/modules/ui/options.js b/modules/ui/options.js index 09f5bee9..3ce6e00c 100644 --- a/modules/ui/options.js +++ b/modules/ui/options.js @@ -296,7 +296,9 @@ function showSeedHistoryDialog() { const button = ``; return `
    • Seed: ${h.seed} ${button}. Size: ${h.width}x${h.height}. Template: ${h.template}. Created: ${created}
    • `; }); - alertMessage.innerHTML = `
        ${lines.join("")}
      `; + alertMessage.innerHTML = /* html */ `
        + ${lines.join("")} +
      `; $("#alert").dialog({ resizable: false, @@ -677,8 +679,8 @@ function regeneratePrompt(source) { const workingTime = (Date.now() - last(mapHistory).created) / 60000; // minutes if (workingTime < 5) return regenerateMap(source); - alertMessage.innerHTML = `Are you sure you want to generate a new map?
      - All unsaved changes made to the current map will be lost`; + alertMessage.innerHTML = /* html */ `Are you sure you want to generate a new map?
      + All unsaved changes made to the current map will be lost`; $("#alert").dialog({ resizable: false, title: "Generate new map", @@ -752,13 +754,13 @@ async function showLoadPane() { document.getElementById("loadFromDropboxSelect").style.display = "block"; const loadFromDropboxButtons = document.getElementById("loadFromDropboxButtons"); const fileSelect = document.getElementById("loadFromDropboxSelect"); - fileSelect.innerHTML = ``; + fileSelect.innerHTML = /* html */ ``; const files = await Cloud.providers.dropbox.list(); if (!files) { loadFromDropboxButtons.style.display = "none"; - fileSelect.innerHTML = ``; + fileSelect.innerHTML = /* html */ ``; return; } @@ -841,7 +843,7 @@ function openSaveTiles() { loading = setInterval(() => (status.innerHTML += "."), 1000); saveTiles().then(() => { clearInterval(loading); - status.innerHTML = `Done. Check file in "Downloads" (crtl + J)`; + status.innerHTML = /* html */ `Done. Check file in "Downloads" (crtl + J)`; setTimeout(() => (status.innerHTML = ""), 8000); }); }, @@ -874,7 +876,7 @@ function updateTilesOptions() { const sizeY = graphHeight * scale * tilesY; const totalSize = sizeX * sizeY; - tileSize.innerHTML = `${sizeX} x ${sizeY} px`; + tileSize.innerHTML = /* html */ `${sizeX} x ${sizeY} px`; tileSize.style.color = totalSize > 1e9 ? "#d00b0b" : totalSize > 1e8 ? "#9e6409" : "#1a941a"; // draw tiles diff --git a/modules/ui/provinces-editor.js b/modules/ui/provinces-editor.js index 045505ee..33ef6dc2 100644 --- a/modules/ui/provinces-editor.js +++ b/modules/ui/provinces-editor.js @@ -131,25 +131,37 @@ function editProvinces() { const separable = p.burg && p.burg !== pack.states[p.state].capital; const focused = defs.select("#fog #focusProvince" + p.i).size(); COArenderer.trigger("provinceCOA" + p.i, p.coa); - lines += `
      + lines += /* html */ `
      - + - + - +
      ${si(area) + unit}
      ${si(population)}
      - +
      `; @@ -360,10 +372,9 @@ function editProvinces() { const total = rural + urban; const l = n => Number(n).toLocaleString(); - alertMessage.innerHTML = ` - Rural: - Urban: -

      Total population: ${l(total)} ⇒ ${l(total)} (100%)

      `; + alertMessage.innerHTML = /* html */ ` Rural: Urban: + +

      Total population: ${l(total)} ⇒ ${l(total)} (100%)

      `; const update = function () { const totalNew = ruralPop.valueAsNumber + urbanPop.valueAsNumber; @@ -424,7 +435,7 @@ function editProvinces() { } function removeProvince(p) { - alertMessage.innerHTML = `Are you sure you want to remove the province?
      This action cannot be reverted`; + alertMessage.innerHTML = /* html */ `Are you sure you want to remove the province?
      This action cannot be reverted`; $("#alert").dialog({ resizable: false, title: "Remove province", @@ -588,7 +599,7 @@ function editProvinces() { const treeLayout = d3.treemap().size([w, h]).padding(2); // prepare svg - alertMessage.innerHTML = ` @@ -635,7 +646,7 @@ function editProvinces() { ? "Urban population: " + si(urban) : "Population: " + si(rural + urban); - provinceInfo.innerHTML = `${name}. ${state}. ${value}`; + provinceInfo.innerHTML = /* html */ `${name}. ${state}. ${value}`; provinceHighlightOn(ev); } @@ -1027,7 +1038,7 @@ function editProvinces() { } function removeAllProvinces() { - alertMessage.innerHTML = `Are you sure you want to remove all provinces?
      This action cannot be reverted`; + alertMessage.innerHTML = /* html */ `Are you sure you want to remove all provinces?
      This action cannot be reverted`; $("#alert").dialog({ resizable: false, title: "Remove all provinces", diff --git a/modules/ui/regiments-overview.js b/modules/ui/regiments-overview.js index 42a9f4e0..d243b34d 100644 --- a/modules/ui/regiments-overview.js +++ b/modules/ui/regiments-overview.js @@ -60,11 +60,11 @@ function overviewRegiments(state) { .map(u => `
      ${r.u[u.name] || 0}
      `) .join(" "); - lines += `
      + lines += /* html */ `
      - + ${r.icon} - + ${lineData}
      ${r.a}
      @@ -74,7 +74,7 @@ function overviewRegiments(state) { } } - lines += `
      + lines += /* html */ `
      Regiments: ${regiments.length}
      ${options.military.map(u => `
      ${si(d3.sum(regiments.map(r => r.u[u.name] || 0)))}
      `).join(" ")}
      ${si(d3.sum(regiments.map(r => r.a)))}
      diff --git a/modules/ui/relief-editor.js b/modules/ui/relief-editor.js index ae924d49..abb800cd 100644 --- a/modules/ui/relief-editor.js +++ b/modules/ui/relief-editor.js @@ -254,7 +254,7 @@ function editReliefIcon() { let selection = null; const pressed = reliefTools.querySelector("button.pressed"); if (pressed.id === "reliefIndividual") { - alertMessage.innerHTML = `Are you sure you want to remove the icon?`; + alertMessage.innerHTML = "Are you sure you want to remove the icon?"; selection = elSelected; } else { const type = reliefIconsDiv.querySelector("svg.pressed")?.dataset.type; diff --git a/modules/ui/religions-editor.js b/modules/ui/religions-editor.js index 98a4d40d..f0f55921 100644 --- a/modules/ui/religions-editor.js +++ b/modules/ui/religions-editor.js @@ -77,14 +77,26 @@ function editReligions() { totalPopulation += population; if (r.i) { - lines += `
      + lines += /* html */ `
      - - - + + + - +
      ${si(area) + unit}
      @@ -93,15 +105,26 @@ function editReligions() {
      `; } else { // No religion (neutral) line - lines += `
      + lines += /* html */ `
      - - - + + + - +
      ${si(area) + unit}
      @@ -163,7 +186,7 @@ function editReligions() { const rural = r.rural * populationRate; const urban = r.urban * populationRate * urbanization; const population = rural + urban > 0 ? ". " + si(rn(rural + urban)) + " believers" : ". Extinct"; - info.innerHTML = `${r.name}${type}${form}${population}`; + info.innerHTML = /* html */ `${r.name}${type}${form}${population}`; tip("Drag to change parent, drag to itself to move to the top level. Hold CTRL and click to change abbreviation"); } @@ -279,11 +302,15 @@ function editReligions() { const l = n => Number(n).toLocaleString(); const burgs = pack.burgs.filter(b => !b.removed && pack.cells.religion[b.cell] === religion); - alertMessage.innerHTML = `

      Please note all population of religion territory is considered - believers of this religion. It means believers number change will directly change population

      - Rural: - Urban: -

      Total believers: ${l(total)} ⇒ ${l(total)} (100%)

      `; + alertMessage.innerHTML = /* html */ `

      + Please note all population of religion territory is considered believers of this religion. It means believers number change will directly change + population +

      + Rural: Urban: + +

      Total believers: ${l(total)} ⇒ ${l(total)} (100%)

      `; const update = function () { const totalNew = ruralPop.valueAsNumber + urbanPop.valueAsNumber; diff --git a/modules/ui/rivers-overview.js b/modules/ui/rivers-overview.js index 4c19bf35..e9045fd5 100644 --- a/modules/ui/rivers-overview.js +++ b/modules/ui/rivers-overview.js @@ -38,14 +38,23 @@ function overviewRivers() { const width = rn(r.width * distanceScaleInput.value, 3) + " " + unit; const basin = pack.rivers.find(river => river.i === r.basin)?.name; - lines += `
      + lines += /* html */ `
      ${r.name}
      ${r.type}
      ${discharge}
      ${length}
      ${width}
      - +
      `; @@ -136,8 +145,7 @@ function overviewRivers() { function triggerRiverRemove() { const river = +this.parentNode.dataset.id; - alertMessage.innerHTML = `Are you sure you want to remove the river? - All tributaries will be auto-removed`; + alertMessage.innerHTML = /* html */ `Are you sure you want to remove the river? All tributaries will be auto-removed`; $("#alert").dialog({ resizable: false, @@ -157,7 +165,7 @@ function overviewRivers() { } function triggerAllRiversRemove() { - alertMessage.innerHTML = `Are you sure you want to remove all rivers?`; + alertMessage.innerHTML = /* html */ `Are you sure you want to remove all rivers?`; $("#alert").dialog({ resizable: false, title: "Remove all rivers", diff --git a/modules/ui/routes-editor.js b/modules/ui/routes-editor.js index 0b743652..785c22a9 100644 --- a/modules/ui/routes-editor.js +++ b/modules/ui/routes-editor.js @@ -6,7 +6,8 @@ function editRoute(onClick) { if (!layerIsOn("toggleRoutes")) toggleRoutes(); $("#routeEditor").dialog({ - title: "Edit Route", resizable: false, + title: "Edit Route", + resizable: false, position: {my: "center top+60", at: "top", of: d3.event, collision: "fit"}, close: closeRoutesEditor }); @@ -41,23 +42,27 @@ function editRoute(onClick) { function showEditorTips() { showMainTip(); if (routeNew.classList.contains("pressed")) return; - if (d3.event.target.id === elSelected.attr("id")) tip("Click to add a control point"); else - if (d3.event.target.parentNode.id === "controlPoints") tip("Drag to move, click to delete the control point"); + if (d3.event.target.id === elSelected.attr("id")) tip("Click to add a control point"); + else if (d3.event.target.parentNode.id === "controlPoints") tip("Drag to move, click to delete the control point"); } function drawControlPoints(node) { const l = node.getTotalLength(); const increment = l / Math.ceil(l / 4); - for (let i=0; i <= l; i += increment) { + for (let i = 0; i <= l; i += increment) { const point = node.getPointAtLength(i); addControlPoint([point.x, point.y]); } routeLength.innerHTML = rn(l * distanceScaleInput.value) + " " + distanceUnitInput.value; } - + function addControlPoint(point, before = null) { - debug.select("#controlPoints").insert("circle", before) - .attr("cx", point[0]).attr("cy", point[1]).attr("r", .6) + debug + .select("#controlPoints") + .insert("circle", before) + .attr("cx", point[0]) + .attr("cy", point[1]) + .attr("r", 0.6) .call(d3.drag().on("drag", dragControlPoint)) .on("click", clickControlPoint); } @@ -67,11 +72,11 @@ function editRoute(onClick) { const controls = document.getElementById("controlPoints").querySelectorAll("circle"); const points = Array.from(controls).map(circle => [+circle.getAttribute("cx"), +circle.getAttribute("cy")]); const index = getSegmentId(points, point, 2); - addControlPoint(point, ":nth-child(" + (index+1) + ")"); + addControlPoint(point, ":nth-child(" + (index + 1) + ")"); redrawRoute(); } - + function dragControlPoint() { this.setAttribute("cx", d3.event.x); this.setAttribute("cy", d3.event.y); @@ -79,11 +84,14 @@ function editRoute(onClick) { } function redrawRoute() { - lineGen.curve(d3.curveCatmullRom.alpha(.1)); + lineGen.curve(d3.curveCatmullRom.alpha(0.1)); const points = []; - debug.select("#controlPoints").selectAll("circle").each(function() { - points.push([this.getAttribute("cx"), this.getAttribute("cy")]); - }); + debug + .select("#controlPoints") + .selectAll("circle") + .each(function () { + points.push([this.getAttribute("cx"), this.getAttribute("cy")]); + }); elSelected.attr("d", round(lineGen(points))); const l = elSelected.node().getTotalLength(); @@ -98,16 +106,16 @@ function editRoute(onClick) { } function showGroupSection() { - document.querySelectorAll("#routeEditor > button").forEach(el => el.style.display = "none"); + document.querySelectorAll("#routeEditor > button").forEach(el => (el.style.display = "none")); document.getElementById("routeGroupsSelection").style.display = "inline-block"; } function hideGroupSection() { - document.querySelectorAll("#routeEditor > button").forEach(el => el.style.display = "inline-block"); + document.querySelectorAll("#routeEditor > button").forEach(el => (el.style.display = "inline-block")); document.getElementById("routeGroupsSelection").style.display = "none"; document.getElementById("routeGroupName").style.display = "none"; document.getElementById("routeGroupName").value = ""; - document.getElementById("routeGroup").style.display = "inline-block"; + document.getElementById("routeGroup").style.display = "inline-block"; } function selectRouteGroup(node) { @@ -115,15 +123,15 @@ function editRoute(onClick) { const select = document.getElementById("routeGroup"); select.options.length = 0; // remove all options - routes.selectAll("g").each(function() { + routes.selectAll("g").each(function () { select.options.add(new Option(this.id, this.id, false, this.id === group)); }); } - + function changeRouteGroup() { document.getElementById(this.value).appendChild(elSelected.node()); } - + function toggleNewGroupInput() { if (routeGroupName.style.display === "none") { routeGroupName.style.display = "inline-block"; @@ -132,12 +140,18 @@ function editRoute(onClick) { } else { routeGroupName.style.display = "none"; routeGroup.style.display = "inline-block"; - } + } } - + function createNewGroup() { - if (!this.value) {tip("Please provide a valid group name"); return;} - const group = this.value.toLowerCase().replace(/ /g, "_").replace(/[^\w\s]/gi, ""); + if (!this.value) { + tip("Please provide a valid group name"); + return; + } + const group = this.value + .toLowerCase() + .replace(/ /g, "_") + .replace(/[^\w\s]/gi, ""); if (document.getElementById(group)) { tip("Element with this id already exists. Please provide a unique name", false, "error"); @@ -152,11 +166,11 @@ function editRoute(onClick) { const oldGroup = elSelected.node().parentNode; const basic = ["roads", "trails", "searoutes"].includes(oldGroup.id); if (!basic && oldGroup.childElementCount === 1) { - document.getElementById("routeGroup").selectedOptions[0].remove(); + document.getElementById("routeGroup").selectedOptions[0].remove(); document.getElementById("routeGroup").options.add(new Option(group, group, false, true)); oldGroup.id = group; toggleNewGroupInput(); - document.getElementById("routeGroupName").value = ""; + document.getElementById("routeGroupName").value = ""; return; } @@ -169,24 +183,33 @@ function editRoute(onClick) { toggleNewGroupInput(); document.getElementById("routeGroupName").value = ""; } - + function removeRouteGroup() { const group = elSelected.node().parentNode.id; const basic = ["roads", "trails", "searoutes"].includes(group); const count = elSelected.node().parentNode.childElementCount; - alertMessage.innerHTML = `Are you sure you want to remove - ${basic ? "all elements in the group" : "the entire route group"}? -

      Routes to be removed: ${count}`; - $("#alert").dialog({resizable: false, title: "Remove route group", + alertMessage.innerHTML = /* html */ `Are you sure you want to remove ${ + basic ? "all elements in the group" : "the entire route group" + }?

      Routes to be + removed: ${count}`; + $("#alert").dialog({ + resizable: false, + title: "Remove route group", buttons: { - Remove: function() { + Remove: function () { $(this).dialog("close"); $("#routeEditor").dialog("close"); hideGroupSection(); - if (basic) routes.select("#"+group).selectAll("path").remove(); - else routes.select("#"+group).remove(); + if (basic) + routes + .select("#" + group) + .selectAll("path") + .remove(); + else routes.select("#" + group).remove(); }, - Cancel: function() {$(this).dialog("close");} + Cancel: function () { + $(this).dialog("close"); + } } }); } @@ -203,24 +226,31 @@ function editRoute(onClick) { function clickControlPoint() { if (routeSplit.classList.contains("pressed")) splitRoute(this); - else {this.remove(); redrawRoute();} + else { + this.remove(); + redrawRoute(); + } } - + function splitRoute(clicked) { - lineGen.curve(d3.curveCatmullRom.alpha(.1)); + lineGen.curve(d3.curveCatmullRom.alpha(0.1)); const group = d3.select(elSelected.node().parentNode); routeSplit.classList.remove("pressed"); - const points1 = [], points2 = []; + const points1 = [], + points2 = []; let points = points1; - debug.select("#controlPoints").selectAll("circle").each(function() { - points.push([this.getAttribute("cx"), this.getAttribute("cy")]); - if (this === clicked) { - points = points2; + debug + .select("#controlPoints") + .selectAll("circle") + .each(function () { points.push([this.getAttribute("cx"), this.getAttribute("cy")]); - } - this.remove(); - }); + if (this === clicked) { + points = points2; + points.push([this.getAttribute("cx"), this.getAttribute("cy")]); + } + this.remove(); + }); elSelected.attr("d", round(lineGen(points1))); const id = getNextId("route"); @@ -263,14 +293,18 @@ function editRoute(onClick) { function removeRoute() { alertMessage.innerHTML = "Are you sure you want to remove the route?"; - $("#alert").dialog({resizable: false, title: "Remove route", + $("#alert").dialog({ + resizable: false, + title: "Remove route", buttons: { - Remove: function() { + Remove: function () { $(this).dialog("close"); elSelected.remove(); $("#routeEditor").dialog("close"); }, - Cancel: function() {$(this).dialog("close");} + Cancel: function () { + $(this).dialog("close"); + } } }); } diff --git a/modules/ui/states-editor.js b/modules/ui/states-editor.js index d7909614..8fd12945 100644 --- a/modules/ui/states-editor.js +++ b/modules/ui/states-editor.js @@ -100,24 +100,41 @@ function editStates() { if (!s.i) { // Neutral line - lines += `
      + lines += /* html */ `
      - + - + - - + +
      ${s.burgs}
      ${si(area) + unit}
      ${si(population)}
      - + - +
      ${s.cells}
      `; @@ -126,26 +143,49 @@ function editStates() { const capital = pack.burgs[s.capital].name; COArenderer.trigger("stateCOA" + s.i, s.coa); - lines += `
      + lines += /* html */ `
      - + - + - - + +
      ${s.burgs}
      ${si(area) + unit}
      ${si(population)}
      - + - +
      ${s.cells}
      @@ -373,10 +413,9 @@ function editStates() { const total = rural + urban; const l = n => Number(n).toLocaleString(); - alertMessage.innerHTML = ` - Rural: - Urban: -

      Total population: ${l(total)} ⇒ ${l(total)} (100%)

      `; + alertMessage.innerHTML = /* html */ ` Rural: Urban: + +

      Total population: ${l(total)} ⇒ ${l(total)} (100%)

      `; const update = function () { const totalNew = ruralPop.valueAsNumber + urbanPop.valueAsNumber; @@ -592,7 +631,7 @@ function editStates() { const treeLayout = d3.pack().size([w, h]).padding(3); // prepare svg - alertMessage.innerHTML = ` @@ -664,7 +703,7 @@ function editStates() { ? "Burgs number: " + d.data.burgs : "Population: " + si(rural + urban); - statesInfo.innerHTML = `${state}. ${value}`; + statesInfo.innerHTML = /* html */ `${state}. ${value}`; stateHighlightOn(ev); } diff --git a/modules/ui/style.js b/modules/ui/style.js index f1586f35..9e39ae6f 100644 --- a/modules/ui/style.js +++ b/modules/ui/style.js @@ -712,8 +712,8 @@ emblemsBurgSizeInput.addEventListener("change", drawEmblems); // request a URL to image to be used as a texture function textureProvideURL() { - alertMessage.innerHTML = `Provide an image URL to be used as a texture: - + alertMessage.innerHTML = /* html */ `Provide an image URL to be used as a texture: + `; $("#alert").dialog({ resizable: false, diff --git a/modules/ui/submap.js b/modules/ui/submap.js index a2fae5f7..e987cba0 100644 --- a/modules/ui/submap.js +++ b/modules/ui/submap.js @@ -203,8 +203,7 @@ window.UISubmap = (function () { ERROR && console.error(error); clearMainTip(); - alertMessage.innerHTML = `Map resampling failed: -
      You may retry after clearing stored data or contact us at discord. + alertMessage.innerHTML = /* html */ `Map resampling failed:
      You may retry after clearing stored data or contact us at discord.

      ${parseError(error)}

      `; $("#alert").dialog({ resizable: false, diff --git a/modules/ui/tools.js b/modules/ui/tools.js index ea297ddd..46e75586 100644 --- a/modules/ui/tools.js +++ b/modules/ui/tools.js @@ -35,7 +35,7 @@ toolsContent.addEventListener("click", function (event) { return; } - alertMessage.innerHTML = `Regeneration will remove all the custom changes for the element.

      Are you sure you want to proceed?`; + alertMessage.innerHTML = /* html */ `Regeneration will remove all the custom changes for the element.

      Are you sure you want to proceed?`; $("#alert").dialog({ resizable: false, title: "Regenerate element", diff --git a/modules/ui/units-editor.js b/modules/ui/units-editor.js index 0f1345e0..37645978 100644 --- a/modules/ui/units-editor.js +++ b/modules/ui/units-editor.js @@ -277,9 +277,8 @@ function editUnits() { function removeAllRulers() { if (!rulers.data.length) return; - alertMessage.innerHTML = ` - Are you sure you want to remove all placed rulers? -
      If you just want to hide rulers, toggle the Rulers layer off in Menu`; + alertMessage.innerHTML = /* html */ ` Are you sure you want to remove all placed rulers? +
      If you just want to hide rulers, toggle the Rulers layer off in Menu`; $("#alert").dialog({ resizable: false, title: "Remove all rulers", diff --git a/modules/ui/world-configurator.js b/modules/ui/world-configurator.js index 22dccacb..bfd28964 100644 --- a/modules/ui/world-configurator.js +++ b/modules/ui/world-configurator.js @@ -77,12 +77,12 @@ function editWorld() { const scale = +distanceScaleInput.value, unit = distanceUnitInput.value; const meridian = toKilometer(eqD * 2 * scale); - document.getElementById("mapSize").innerHTML = `${graphWidth}x${graphHeight}`; - document.getElementById("mapSizeFriendly").innerHTML = `${rn(graphWidth * scale)}x${rn(graphHeight * scale)} ${unit}`; + document.getElementById("mapSize").innerHTML = /* html */ `${graphWidth}x${graphHeight}`; + document.getElementById("mapSizeFriendly").innerHTML = /* html */ `${rn(graphWidth * scale)}x${rn(graphHeight * scale)} ${unit}`; document.getElementById("meridianLength").innerHTML = rn(eqD * 2); - document.getElementById("meridianLengthFriendly").innerHTML = `${rn(eqD * 2 * scale)} ${unit}`; + document.getElementById("meridianLengthFriendly").innerHTML = /* html */ `${rn(eqD * 2 * scale)} ${unit}`; document.getElementById("meridianLengthEarth").innerHTML = meridian ? " = " + rn(meridian / 200) + "%🌏" : ""; - document.getElementById("mapCoordinates").innerHTML = `${lat(mc.latN)} ${Math.abs(rn(mc.lonW))}°W; ${lat(mc.latS)} ${rn(mc.lonE)}°E`; + document.getElementById("mapCoordinates").innerHTML = /* html */ `${lat(mc.latN)} ${Math.abs(rn(mc.lonW))}°W; ${lat(mc.latS)} ${rn(mc.lonE)}°E`; function toKilometer(v) { if (unit === "km") return v; diff --git a/modules/ui/zones-editor.js b/modules/ui/zones-editor.js index 122ea083..bd27840c 100644 --- a/modules/ui/zones-editor.js +++ b/modules/ui/zones-editor.js @@ -110,7 +110,7 @@ function editZones() { const totalArea = (zonesFooterArea.dataset.area = graphWidth * graphHeight * distanceScaleInput.value ** 2); const totalPop = (d3.sum(pack.cells.pop) + d3.sum(pack.burgs.filter(b => !b.removed).map(b => b.population)) * urbanization) * populationRate; zonesFooterPopulation.dataset.population = totalPop; - zonesFooterNumber.innerHTML = `${filteredZones.length} of ${zones.length}`; + zonesFooterNumber.innerHTML = /* html */ `${filteredZones.length} of ${zones.length}`; zonesFooterCells.innerHTML = pack.cells.i.length; zonesFooterArea.innerHTML = si(totalArea) + unit; zonesFooterPopulation.innerHTML = si(totalPop); @@ -414,10 +414,9 @@ function editZones() { const total = rural + urban; const l = n => Number(n).toLocaleString(); - alertMessage.innerHTML = ` - Rural: - Urban: -

      Total population: ${l(total)} ⇒ ${l(total)} (100%)

      `; + alertMessage.innerHTML = /* html */ `Rural: Urban: + +

      Total population: ${l(total)} ⇒ ${l(total)} (100%)

      `; const update = function () { const totalNew = ruralPop.valueAsNumber + urbanPop.valueAsNumber; From f5cb8002956a034bf466922df439cf89e4e12cb8 Mon Sep 17 00:00:00 2001 From: Azgaar Date: Mon, 9 May 2022 17:50:07 +0300 Subject: [PATCH 010/501] Caching service worker (#794) * register service worker * versioning code * cleanup * cache in Prod only --- index.html | 11 ++++---- main.js | 54 ++++++------------------------------- sw.js | 68 +++++++++++++++++++++++++++++++++++++++++++++++ versioning.js | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 155 insertions(+), 51 deletions(-) create mode 100644 sw.js create mode 100644 versioning.js diff --git a/index.html b/index.html index 4071ba58..71f39eb7 100644 --- a/index.html +++ b/index.html @@ -15,6 +15,7 @@ + - + @@ -6237,7 +6237,7 @@ - + diff --git a/modules/io/load.js b/modules/io/load.js index c650b3b2..30736043 100644 --- a/modules/io/load.js +++ b/modules/io/load.js @@ -124,9 +124,8 @@ function uploadMap(file, callback) { const isInvalid = !mapData || isNaN(mapVersion) || mapData.length < 26 || !mapData[5]; const isUpdated = mapVersion === currentVersion; const isAncient = mapVersion < OLDEST_SUPPORTED_VERSION; - // TODO: temp condition for 1.811, remove when 1.82 is released - const isNewer = mapVersion > currentVersion && mapVersion !== 1.811; - const isOutdated = mapVersion < currentVersion || mapVersion === 1.811; + const isNewer = mapVersion > currentVersion; + const isOutdated = mapVersion < currentVersion; if (isInvalid) return showUploadMessage("invalid", mapData, mapVersion); if (isUpdated) return parseLoadedData(mapData); diff --git a/versioning.js b/versioning.js index ed988f51..7b0a06dc 100644 --- a/versioning.js +++ b/versioning.js @@ -1,7 +1,7 @@ "use strict"; // version and caching control -const version = "1.81.11"; // generator version, update each time +const version = "1.82.0"; // generator version, update each time { document.title += " v" + version; From 01b0daf0d18b7178b6c61fe13a9e897b8e73f6dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Gergely?= Date: Sun, 15 May 2022 18:43:33 +0200 Subject: [PATCH 048/501] Extend namebases instead of override on ctr+click --- index.html | 2 +- modules/ui/namesbase-editor.js | 14 +++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/index.html b/index.html index b1238018..6514c754 100644 --- a/index.html +++ b/index.html @@ -3455,7 +3455,7 @@ - + diff --git a/modules/ui/namesbase-editor.js b/modules/ui/namesbase-editor.js index 74ddb793..4a0db66d 100644 --- a/modules/ui/namesbase-editor.js +++ b/modules/ui/namesbase-editor.js @@ -20,9 +20,13 @@ function editNamesbase() { document.getElementById("namesbaseAnalyze").addEventListener("click", analyzeNamesbase); document.getElementById("namesbaseDefault").addEventListener("click", namesbaseRestoreDefault); document.getElementById("namesbaseDownload").addEventListener("click", namesbaseDownload); - document.getElementById("namesbaseUpload").addEventListener("click", () => document.getElementById("namesbaseToLoad").click()); - document.getElementById("namesbaseToLoad").addEventListener("change", function () { - uploadFile(this, namesbaseUpload); + document.getElementById("namesbaseUpload").addEventListener("click", () => { + const uploader = document.getElementById("namesbaseToLoad"); + uploader.dataset.override = event.ctrlKey ? "no" : "yes"; + uploader.click(); + }); + document.getElementById("namesbaseToLoad").addEventListener("change", function (ev) { + uploadFile(this, d => namesbaseUpload(d, ev.target.dataset.override === "yes")); }); document.getElementById("namesbaseCA").addEventListener("click", () => { openURL("https://cartographyassets.com/asset-category/specific-assets/azgaars-generator/namebases/"); @@ -221,7 +225,7 @@ function editNamesbase() { downloadFile(data, name); } - function namesbaseUpload(dataLoaded) { + function namesbaseUpload(dataLoaded, override=true) { const data = dataLoaded.split("\r\n"); if (!data || !data[0]) { tip("Cannot load a namesbase. Please check the data format", false, "error"); @@ -229,7 +233,7 @@ function editNamesbase() { } Names.clearChains(); - nameBases = []; + if (override) nameBases = []; data.forEach(d => { const e = d.split("|"); nameBases.push({name: e[0], min: e[1], max: e[2], d: e[3], m: e[4], b: e[5]}); From e38113662e262287e9465d3870dcf28775155c5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gergely=20M=C3=A9sz=C3=A1ros=2C=20Ph=2ED?= Date: Mon, 16 May 2022 21:21:27 +0200 Subject: [PATCH 049/501] New button instead of control+click (namesbases) (#802) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Mészáros Gergely --- index.html | 3 ++- modules/ui/namesbase-editor.js | 15 +++++++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/index.html b/index.html index 6514c754..26d88b1e 100644 --- a/index.html +++ b/index.html @@ -3455,7 +3455,8 @@ - + + diff --git a/modules/ui/namesbase-editor.js b/modules/ui/namesbase-editor.js index 4a0db66d..1e08ad2a 100644 --- a/modules/ui/namesbase-editor.js +++ b/modules/ui/namesbase-editor.js @@ -20,14 +20,21 @@ function editNamesbase() { document.getElementById("namesbaseAnalyze").addEventListener("click", analyzeNamesbase); document.getElementById("namesbaseDefault").addEventListener("click", namesbaseRestoreDefault); document.getElementById("namesbaseDownload").addEventListener("click", namesbaseDownload); + + const uploader = document.getElementById("namesbaseToLoad"); document.getElementById("namesbaseUpload").addEventListener("click", () => { - const uploader = document.getElementById("namesbaseToLoad"); - uploader.dataset.override = event.ctrlKey ? "no" : "yes"; + uploader.addEventListener("change", function (event) { + uploadFile(event.target, d => namesbaseUpload(d, true)); + }, { once: true }); uploader.click(); }); - document.getElementById("namesbaseToLoad").addEventListener("change", function (ev) { - uploadFile(this, d => namesbaseUpload(d, ev.target.dataset.override === "yes")); + document.getElementById("namesbaseUploadExtend").addEventListener("click", () => { + uploader.addEventListener("change", function (event) { + uploadFile(event.target, d => namesbaseUpload(d, false)); + }, { once: true }); + uploader.click(); }); + document.getElementById("namesbaseCA").addEventListener("click", () => { openURL("https://cartographyassets.com/asset-category/specific-assets/azgaars-generator/namebases/"); }); From 6566adaeb69a4f5734c836229bc494ba7bead12e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A9sz=C3=A1ros=20Gergely?= Date: Tue, 17 May 2022 01:50:38 +0200 Subject: [PATCH 050/501] Scaling option for resample --- index.html | 6 ++++++ modules/ui/submap.js | 13 ++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/index.html b/index.html index 26d88b1e..2b724c8a 100644 --- a/index.html +++ b/index.html @@ -4380,6 +4380,12 @@ 0°
      +
      Scale
      +
      + + 1x +
      +
      Mirror
      diff --git a/modules/ui/submap.js b/modules/ui/submap.js index 3e8b8230..0a903443 100644 --- a/modules/ui/submap.js +++ b/modules/ui/submap.js @@ -10,6 +10,12 @@ window.UISubmap = (function () { output.style.color = getCellsDensityColor(cells); }); + document.getElementById("submapScaleInput").addEventListener("input", function (event) { + const exp = Math.pow(1.1, +event.target.value); + document.getElementById("submapScaleOutput").value = rn(exp,2); + event.stopPropagation(); + }); + function openSubmapMenu() { $("#submapOptionsDialog").dialog({ title: "Create a submap", @@ -32,7 +38,9 @@ window.UISubmap = (function () { resetZoom(0); document.getElementById("submapAngleInput").value = 0; - document.getElementById("submapAngleOutput").value = "0°"; + document.getElementById("submapAngleOutput").value = "0"; + document.getElementById("submapScaleInput").value = 1; + document.getElementById("submapScaleOutput").value = 1; document.getElementById("submapShiftX").value = 0; document.getElementById("submapShiftY").value = 0; document.getElementById("submapMirrorH").checked = false; @@ -64,11 +72,13 @@ window.UISubmap = (function () { const angle = (+document.getElementById("submapAngleInput").value / 180) * Math.PI; const shiftX = +document.getElementById("submapShiftX").value; const shiftY = +document.getElementById("submapShiftY").value; + const ratio = +document.getElementById("submapScaleInput").value; const mirrorH = document.getElementById("submapMirrorH").checked; const mirrorV = document.getElementById("submapMirrorV").checked; const [cx, cy] = [graphWidth / 2, graphHeight / 2]; const rot = alfa => (x, y) => [(x - cx) * Math.cos(alfa) - (y - cy) * Math.sin(alfa) + cx, (y - cy) * Math.cos(alfa) + (x - cx) * Math.sin(alfa) + cy]; + const scale = ratio => (x, y) => [(x-cx) * ratio + cx, (y-cy) * ratio + cy]; const shift = (dx, dy) => (x, y) => [x + dx, y + dy]; const flipH = (x, y) => [-x + 2 * cx, y]; const flipV = (x, y) => [x, -y + 2 * cy]; @@ -83,6 +93,7 @@ window.UISubmap = (function () { projection = app(shift(shiftX, shiftY), projection); inverse = app(inverse, shift(-shiftX, -shiftY)); } + if (ratio) [projection, inverse] = [app(scale(Math.pow(1.1,ratio)), projection), app(inverse, scale(Math.pow(1.1,-ratio)))]; if (mirrorH) [projection, inverse] = [app(flipH, projection), app(inverse, flipH)]; if (mirrorV) [projection, inverse] = [app(flipV, projection), app(inverse, flipV)]; From 58737b0244e18bff56cb34aaff348dde26c0c1d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gergely=20M=C3=A9sz=C3=A1ros=2C=20Ph=2ED?= Date: Tue, 17 May 2022 09:19:49 +0200 Subject: [PATCH 051/501] align with the spec: no implicit ids (#808) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Mészáros Gergely --- modules/ui/general.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/ui/general.js b/modules/ui/general.js index 357d9a57..f56a234d 100644 --- a/modules/ui/general.js +++ b/modules/ui/general.js @@ -202,10 +202,10 @@ function showMapTooltip(point, e, i, g) { const province = pack.cells.province[i]; const prov = province ? pack.provinces[province].fullName + ", " : ""; tip(prov + stateName); - if (statesEditor?.offsetParent) highlightEditorLine(statesEditor, state); - if (diplomacyEditor?.offsetParent) highlightEditorLine(diplomacyEditor, state); - if (militaryOverview?.offsetParent) highlightEditorLine(militaryOverview, state); - if (provincesEditor?.offsetParent) highlightEditorLine(provincesEditor, province); + if (document.getElementById('statesEditor')?.offsetParent) highlightEditorLine(statesEditor, state); + if (document.getElementById('diplomacyEditor')?.offsetParent) highlightEditorLine(diplomacyEditor, state); + if (document.getElementById('militaryOverview')?.offsetParent) highlightEditorLine(militaryOverview, state); + if (document.getElementById('provincesEditor')?.offsetParent) highlightEditorLine(provincesEditor, province); } else if (layerIsOn("toggleCultures") && pack.cells.culture[i]) { const culture = pack.cells.culture[i]; tip("Culture: " + pack.cultures[culture].name); From 3ec92a323d65bd1a6595b6a7751e2c0450335109 Mon Sep 17 00:00:00 2001 From: Azgaar Date: Tue, 17 May 2022 21:02:26 +0300 Subject: [PATCH 052/501] fix: + hotkey is not working --- index.html | 2 +- modules/ui/hotkeys.js | 20 ++++++++++---------- versioning.js | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/index.html b/index.html index 6514c754..ca8909b8 100644 --- a/index.html +++ b/index.html @@ -6230,7 +6230,7 @@ - + diff --git a/modules/ui/hotkeys.js b/modules/ui/hotkeys.js index 9081d002..d9f0e234 100644 --- a/modules/ui/hotkeys.js +++ b/modules/ui/hotkeys.js @@ -35,8 +35,8 @@ function handleKeyup(event) { else if (ctrl && code === "KeyQ") toggleSaveReminder(); else if (ctrl && code === "KeyS") dowloadMap(); else if (ctrl && code === "KeyC") saveToDropbox(); - else if (ctrl && code === "KeyZ" && undo.offsetParent) undo.click(); - else if (ctrl && code === "KeyY" && redo.offsetParent) redo.click(); + else if (ctrl && code === "KeyZ" && undo?.offsetParent) undo.click(); + else if (ctrl && code === "KeyY" && redo?.offsetParent) redo.click(); else if (shift && code === "KeyH") editHeightmap(); else if (shift && code === "KeyB") editBiomes(); else if (shift && code === "KeyS") editStates(); @@ -113,13 +113,13 @@ function pressNumpadSign(key) { const change = key === "+" ? 1 : -1; let brush = null; - if (brushRadius.offsetParent) brush = document.getElementById("brushRadius"); - else if (biomesManuallyBrush.offsetParent) brush = document.getElementById("biomesManuallyBrush"); - else if (statesManuallyBrush.offsetParent) brush = document.getElementById("statesManuallyBrush"); - else if (provincesManuallyBrush.offsetParent) brush = document.getElementById("provincesManuallyBrush"); - else if (culturesManuallyBrush.offsetParent) brush = document.getElementById("culturesManuallyBrush"); - else if (zonesBrush.offsetParent) brush = document.getElementById("zonesBrush"); - else if (religionsManuallyBrush.offsetParent) brush = document.getElementById("religionsManuallyBrush"); + if (document.getElementById("brushRadius")?.offsetParent) brush = document.getElementById("brushRadius"); + else if (document.getElementById("biomesManuallyBrush")?.offsetParent) brush = document.getElementById("biomesManuallyBrush"); + else if (document.getElementById("statesManuallyBrush")?.offsetParent) brush = document.getElementById("statesManuallyBrush"); + else if (document.getElementById("provincesManuallyBrush")?.offsetParent) brush = document.getElementById("provincesManuallyBrush"); + else if (document.getElementById("culturesManuallyBrush")?.offsetParent) brush = document.getElementById("culturesManuallyBrush"); + else if (document.getElementById("zonesBrush")?.offsetParent) brush = document.getElementById("zonesBrush"); + else if (document.getElementById("religionsManuallyBrush")?.offsetParent) brush = document.getElementById("religionsManuallyBrush"); if (brush) { const value = minmax(+brush.value + change, +brush.min, +brush.max); @@ -132,7 +132,7 @@ function pressNumpadSign(key) { } function toggleMode() { - if (zonesRemove.offsetParent) { + if (zonesRemove?.offsetParent) { zonesRemove.classList.contains("pressed") ? zonesRemove.classList.remove("pressed") : zonesRemove.classList.add("pressed"); } } diff --git a/versioning.js b/versioning.js index 7b0a06dc..07617b2a 100644 --- a/versioning.js +++ b/versioning.js @@ -1,7 +1,7 @@ "use strict"; // version and caching control -const version = "1.82.0"; // generator version, update each time +const version = "1.82.01"; // generator version, update each time { document.title += " v" + version; From fc62143eae97c6dfe45d8ba4b9bc51cbe3a846c4 Mon Sep 17 00:00:00 2001 From: Azgaar Date: Tue, 17 May 2022 22:34:14 +0300 Subject: [PATCH 053/501] add functional shorthands --- index.html | 3 +- modules/dynamic/editors/states-editor.js | 291 +++++++++++------------ modules/ui/editors.js | 2 +- utils/shorthands.js | 21 ++ versioning.js | 2 +- 5 files changed, 162 insertions(+), 157 deletions(-) create mode 100644 utils/shorthands.js diff --git a/index.html b/index.html index 6aac18d2..067ef552 100644 --- a/index.html +++ b/index.html @@ -6162,6 +6162,7 @@ + @@ -6202,7 +6203,7 @@ - + diff --git a/modules/dynamic/editors/states-editor.js b/modules/dynamic/editors/states-editor.js index a02076ea..f4c40901 100644 --- a/modules/dynamic/editors/states-editor.js +++ b/modules/dynamic/editors/states-editor.js @@ -1,4 +1,4 @@ -const body = insertEditorHtml(); +const $body = insertEditorHtml(); addListeners(); export function open() { @@ -119,45 +119,36 @@ function insertEditorHtml() {
      `; - const dialogs = document.getElementById("dialogs"); - dialogs.insertAdjacentHTML("beforeend", editorHtml); - - return document.getElementById("statesBodySection"); + byId("dialogs").insertAdjacentHTML("beforeend", editorHtml); + return byId("statesBodySection"); } function addListeners() { - document.getElementById("statesEditorRefresh").addEventListener("click", refreshStatesEditor); - document.getElementById("statesEditStyle").addEventListener("click", () => editStyle("regions")); - document.getElementById("statesLegend").addEventListener("click", toggleLegend); - document.getElementById("statesPercentage").addEventListener("click", togglePercentageMode); - document.getElementById("statesChart").addEventListener("click", showStatesChart); - document.getElementById("statesRegenerate").addEventListener("click", openRegenerationMenu); - document.getElementById("statesRegenerateBack").addEventListener("click", exitRegenerationMenu); - document.getElementById("statesRecalculate").addEventListener("click", () => recalculateStates(true)); - document.getElementById("statesRandomize").addEventListener("click", randomizeStatesExpansion); - document.getElementById("statesNeutral").addEventListener("input", changeStatesGrowthRate); - document.getElementById("statesNeutralNumber").addEventListener("change", changeStatesGrowthRate); - document.getElementById("statesManually").addEventListener("click", enterStatesManualAssignent); - document.getElementById("statesManuallyApply").addEventListener("click", applyStatesManualAssignent); - document.getElementById("statesManuallyCancel").addEventListener("click", () => exitStatesManualAssignment()); - document.getElementById("statesAdd").addEventListener("click", enterAddStateMode); - document.getElementById("statesExport").addEventListener("click", downloadStatesData); + byId("statesEditorRefresh").on("click", refreshStatesEditor); + byId("statesEditStyle").on("click", () => editStyle("regions")); + byId("statesLegend").on("click", toggleLegend); + byId("statesPercentage").on("click", togglePercentageMode); + byId("statesChart").on("click", showStatesChart); + byId("statesRegenerate").on("click", openRegenerationMenu); + byId("statesRegenerateBack").on("click", exitRegenerationMenu); + byId("statesRecalculate").on("click", () => recalculateStates(true)); + byId("statesRandomize").on("click", randomizeStatesExpansion); + byId("statesNeutral").on("input", changeStatesGrowthRate); + byId("statesNeutralNumber").on("change", changeStatesGrowthRate); + byId("statesManually").on("click", enterStatesManualAssignent); + byId("statesManuallyApply").on("click", applyStatesManualAssignent); + byId("statesManuallyCancel").on("click", () => exitStatesManualAssignment(false)); + byId("statesAdd").on("click", enterAddStateMode); + byId("statesExport").on("click", downloadStatesCsv); - document - .getElementById("statesHeader") - .querySelectorAll(".sortable") - .forEach(function (element) { - element.addEventListener("click", function () { - sortLines(this); - }); - }); + const $header = byId("statesHeader"); + $header.queryAll(".sortable").forEach(element => element.on("click", () => sortLines(element))); - body.addEventListener("click", function (event) { - const element = event.target; - const classList = element.classList; - const line = element.parentNode; - const state = +line.dataset.id; - if (element.tagName === "FILL-BOX") stateChangeFill(element); + $body.on("click", event => { + const $element = event.target; + const classList = $element.classList; + const state = +$element.parentNode?.dataset?.id; + if ($element.tagName === "FILL-BOX") stateChangeFill($element); else if (classList.contains("name")) editStateName(state); else if (classList.contains("coaIcon")) editEmblem("state", "stateCOA" + state, pack.states[state]); else if (classList.contains("icon-star-empty")) stateCapitalZoomIn(state); @@ -166,22 +157,22 @@ function addListeners() { else if (classList.contains("icon-trash-empty")) stateRemovePrompt(state); }); - body.addEventListener("input", function (ev) { - const element = ev.target; - const classList = element.classList; - const line = element.parentNode; + $body.on("input", function (ev) { + const $element = ev.target; + const classList = $element.classList; + const line = $element.parentNode; const state = +line.dataset.id; - if (classList.contains("stateCapital")) stateChangeCapitalName(state, line, element.value); - else if (classList.contains("cultureType")) stateChangeType(state, line, element.value); - else if (classList.contains("statePower")) stateChangeExpansionism(state, line, element.value); + if (classList.contains("stateCapital")) stateChangeCapitalName(state, line, $element.value); + else if (classList.contains("cultureType")) stateChangeType(state, line, $element.value); + else if (classList.contains("statePower")) stateChangeExpansionism(state, line, $element.value); }); - body.addEventListener("change", function (ev) { - const element = ev.target; - const classList = element.classList; - const line = element.parentNode; + $body.on("change", function (ev) { + const $element = ev.target; + const classList = $element.classList; + const line = $element.parentNode; const state = +line.dataset.id; - if (classList.contains("stateCulture")) stateChangeCulture(state, line, element.value); + if (classList.contains("stateCulture")) stateChangeCulture(state, line, $element.value); }); } @@ -194,10 +185,10 @@ function refreshStatesEditor() { function statesEditorAddLines() { const unit = areaUnit.value === "square" ? " " + distanceUnitInput.value + "²" : " " + areaUnit.value; const hidden = statesRegenerateButtons.style.display === "block" ? "" : "hidden"; // show/hide regenerate columns - let lines = "", - totalArea = 0, - totalPopulation = 0, - totalBurgs = 0; + let lines = ""; + let totalArea = 0; + let totalPopulation = 0; + let totalBurgs = 0; for (const s of pack.states) { if (s.removed) continue; @@ -290,25 +281,26 @@ function statesEditorAddLines() {
      `; } - body.innerHTML = lines; + $body.innerHTML = lines; // update footer - statesFooterStates.innerHTML = pack.states.filter(s => s.i && !s.removed).length; - statesFooterCells.innerHTML = pack.cells.h.filter(h => h >= 20).length; - statesFooterBurgs.innerHTML = totalBurgs; - statesFooterArea.innerHTML = si(totalArea) + unit; - statesFooterPopulation.innerHTML = si(totalPopulation); - statesFooterArea.dataset.area = totalArea; - statesFooterPopulation.dataset.population = totalPopulation; + byId("statesFooterStates").innerHTML = pack.states.filter(s => s.i && !s.removed).length; + byId("statesFooterCells").innerHTML = pack.cells.h.filter(h => h >= 20).length; + byId("statesFooterBurgs").innerHTML = totalBurgs; + byId("statesFooterArea").innerHTML = si(totalArea) + unit; + byId("statesFooterArea").dataset.area = totalArea; + byId("statesFooterPopulation").innerHTML = si(totalPopulation); + byId("statesFooterPopulation").dataset.population = totalPopulation; - body.querySelectorAll("div.states").forEach(el => { - el.addEventListener("click", selectStateOnLineClick); - el.addEventListener("mouseenter", ev => stateHighlightOn(ev)); - el.addEventListener("mouseleave", ev => stateHighlightOff(ev)); + // add listeners + $body.queryAll("div.states").forEach(el => { + el.on("click", selectStateOnLineClick); + el.on("mouseenter", stateHighlightOn); + el.on("mouseleave", stateHighlightOff); }); - if (body.dataset.type === "percentage") { - body.dataset.type = "absolute"; + if ($body.dataset.type === "percentage") { + $body.dataset.type = "absolute"; togglePercentageMode(); } applySorting(statesHeader); @@ -350,15 +342,13 @@ function stateHighlightOn(event) { .attr("opacity", 1) .attr("filter", "url(#blur1)"); - const l = path.node().getTotalLength(), - dur = (l + 5000) / 2; - const i = d3.interpolateString("0," + l, l + "," + l); + const totalLength = path.node().getTotalLength(); + const duration = (totalLength + 5000) / 2; + const interpolate = d3.interpolateString(`0, ${totalLength}`, `${totalLength}, ${totalLength}`); path .transition() - .duration(dur) - .attrTween("stroke-dasharray", function () { - return t => i(t); - }); + .duration(duration) + .attrTween("stroke-dasharray", () => interpolate); } function stateHighlightOff() { @@ -402,10 +392,10 @@ function editStateName(state) { } const s = pack.states[state]; - document.getElementById("stateNameEditor").dataset.state = state; - document.getElementById("stateNameEditorShort").value = s.name || ""; + byId("stateNameEditor").dataset.state = state; + byId("stateNameEditorShort").value = s.name || ""; applyOption(stateNameEditorSelectForm, s.formName); - document.getElementById("stateNameEditorFull").value = s.fullName || ""; + byId("stateNameEditorFull").value = s.fullName || ""; $("#stateNameEditor").dialog({ resizable: false, @@ -426,23 +416,23 @@ function editStateName(state) { modules.editStateName = true; // add listeners - document.getElementById("stateNameEditorShortCulture").addEventListener("click", regenerateShortNameCuture); - document.getElementById("stateNameEditorShortRandom").addEventListener("click", regenerateShortNameRandom); - document.getElementById("stateNameEditorAddForm").addEventListener("click", addCustomForm); - document.getElementById("stateNameEditorCustomForm").addEventListener("change", addCustomForm); - document.getElementById("stateNameEditorFullRegenerate").addEventListener("click", regenerateFullName); + byId("stateNameEditorShortCulture").on("click", regenerateShortNameCuture); + byId("stateNameEditorShortRandom").on("click", regenerateShortNameRandom); + byId("stateNameEditorAddForm").on("click", addCustomForm); + byId("stateNameEditorCustomForm").on("change", addCustomForm); + byId("stateNameEditorFullRegenerate").on("click", regenerateFullName); function regenerateShortNameCuture() { const state = +stateNameEditor.dataset.state; const culture = pack.states[state].culture; const name = Names.getState(Names.getCultureShort(culture), culture); - document.getElementById("stateNameEditorShort").value = name; + byId("stateNameEditorShort").value = name; } function regenerateShortNameRandom() { const base = rand(nameBases.length - 1); const name = Names.getState(Names.getBase(base), undefined, base); - document.getElementById("stateNameEditorShort").value = name; + byId("stateNameEditorShort").value = name; } function addCustomForm() { @@ -455,9 +445,9 @@ function editStateName(state) { } function regenerateFullName() { - const short = document.getElementById("stateNameEditorShort").value; - const form = document.getElementById("stateNameEditorSelectForm").value; - document.getElementById("stateNameEditorFull").value = getFullName(); + const short = byId("stateNameEditorShort").value; + const form = byId("stateNameEditorSelectForm").value; + byId("stateNameEditorFull").value = getFullName(); function getFullName() { if (!form) return short; @@ -469,9 +459,9 @@ function editStateName(state) { } function applyNameChange(s) { - const nameInput = document.getElementById("stateNameEditorShort"); - const formSelect = document.getElementById("stateNameEditorSelectForm"); - const fullNameInput = document.getElementById("stateNameEditorFull"); + const nameInput = byId("stateNameEditorShort"); + const formSelect = byId("stateNameEditorSelectForm"); + const fullNameInput = byId("stateNameEditorFull"); const nameChanged = nameInput.value !== s.name; const formChanged = formSelect.value !== s.formName; @@ -497,7 +487,7 @@ function stateChangeCapitalName(state, line, value) { const capital = pack.states[state].capital; if (!capital) return; pack.burgs[capital].name = value; - document.querySelector("#burgLabel" + capital).textContent = value; + query("#burgLabel" + capital).textContent = value; } function changePopulation(state) { @@ -636,7 +626,7 @@ function stateRemove(state) { // remove emblem const coaId = "stateCOA" + state; - document.getElementById(coaId).remove(); + byId(coaId).remove(); emblems.select(`#stateEmblems > use[data-i='${state}']`).remove(); // remove provinces @@ -647,7 +637,7 @@ function stateRemove(state) { }); const coaId = "provinceCOA" + p; - if (document.getElementById(coaId)) document.getElementById(coaId).remove(); + if (byId(coaId)) byId(coaId).remove(); emblems.select(`#provinceEmblems > use[data-i='${p}']`).remove(); const g = provs.select("#provincesBody"); g.select("#province" + p).remove(); @@ -691,21 +681,21 @@ function toggleLegend() { } function togglePercentageMode() { - if (body.dataset.type === "absolute") { - body.dataset.type = "percentage"; + if ($body.dataset.type === "absolute") { + $body.dataset.type = "percentage"; const totalCells = +statesFooterCells.innerHTML; const totalBurgs = +statesFooterBurgs.innerHTML; const totalArea = +statesFooterArea.dataset.area; const totalPopulation = +statesFooterPopulation.dataset.population; - body.querySelectorAll(":scope > div").forEach(function (el) { - el.querySelector(".stateCells").innerHTML = rn((+el.dataset.cells / totalCells) * 100) + "%"; - el.querySelector(".stateBurgs").innerHTML = rn((+el.dataset.burgs / totalBurgs) * 100) + "%"; - el.querySelector(".stateArea").innerHTML = rn((+el.dataset.area / totalArea) * 100) + "%"; - el.querySelector(".statePopulation").innerHTML = rn((+el.dataset.population / totalPopulation) * 100) + "%"; + $body.queryAll(":scope > div").forEach(function (el) { + el.query(".stateCells").innerHTML = rn((+el.dataset.cells / totalCells) * 100) + "%"; + el.query(".stateBurgs").innerHTML = rn((+el.dataset.burgs / totalBurgs) * 100) + "%"; + el.query(".stateArea").innerHTML = rn((+el.dataset.area / totalArea) * 100) + "%"; + el.query(".statePopulation").innerHTML = rn((+el.dataset.population / totalPopulation) * 100) + "%"; }); } else { - body.dataset.type = "absolute"; + $body.dataset.type = "absolute"; statesEditorAddLines(); } } @@ -748,7 +738,7 @@ function showStatesChart() { .attr("text-anchor", "middle") .attr("dominant-baseline", "central"); const graph = svg.append("g").attr("transform", `translate(-50, 0)`); - document.getElementById("statesTreeType").addEventListener("change", updateChart); + byId("statesTreeType").on("change", updateChart); treeLayout(root); @@ -807,7 +797,7 @@ function showStatesChart() { function hideInfo(ev) { stateHighlightOff(ev); - if (!document.getElementById("statesInfo")) return; + if (!byId("statesInfo")) return; statesInfo.innerHTML = "‍"; d3.select(ev.target).select("circle").classed("selected", 0); } @@ -855,10 +845,10 @@ function showStatesChart() { } function openRegenerationMenu() { - statesBottom.querySelectorAll(":scope > button").forEach(el => (el.style.display = "none")); + statesBottom.queryAll(":scope > button").forEach(el => (el.style.display = "none")); statesRegenerateButtons.style.display = "block"; - statesEditor.querySelectorAll(".show").forEach(el => el.classList.remove("hidden")); + statesEditor.queryAll(".show").forEach(el => el.classList.remove("hidden")); $("#statesEditor").dialog({position: {my: "right top", at: "right-10 top+10", of: "svg", collision: "fit"}}); } @@ -878,8 +868,8 @@ function recalculateStates(must) { function changeStatesGrowthRate() { const growthRate = +this.value; - document.getElementById("statesNeutral").value = growthRate; - document.getElementById("statesNeutralNumber").value = growthRate; + byId("statesNeutral").value = growthRate; + byId("statesNeutralNumber").value = growthRate; statesNeutral = growthRate; tip("Growth rate: " + growthRate); recalculateStates(false); @@ -890,15 +880,15 @@ function randomizeStatesExpansion() { if (!s.i || s.removed) return; const expansionism = rn(Math.random() * 4 + 1, 1); s.expansionism = expansionism; - body.querySelector("div.states[data-id='" + s.i + "'] > input.statePower").value = expansionism; + $body.query("div.states[data-id='" + s.i + "'] > input.statePower").value = expansionism; }); recalculateStates(true, true); } function exitRegenerationMenu() { - statesBottom.querySelectorAll(":scope > button").forEach(el => (el.style.display = "inline-block")); + statesBottom.queryAll(":scope > button").forEach(el => (el.style.display = "inline-block")); statesRegenerateButtons.style.display = "none"; - statesEditor.querySelectorAll(".show").forEach(el => el.classList.add("hidden")); + statesEditor.queryAll(".show").forEach(el => el.classList.add("hidden")); $("#statesEditor").dialog({position: {my: "right top", at: "right-10 top+10", of: "svg", collision: "fit"}}); } @@ -906,25 +896,29 @@ function enterStatesManualAssignent() { if (!layerIsOn("toggleStates")) toggleStates(); customization = 2; statesBody.append("g").attr("id", "temp"); - document.querySelectorAll("#statesBottom > button").forEach(el => (el.style.display = "none")); - document.getElementById("statesManuallyButtons").style.display = "inline-block"; - document.getElementById("statesHalo").style.display = "none"; + queryAll("#statesBottom > button").forEach(el => (el.style.display = "none")); + byId("statesManuallyButtons").style.display = "inline-block"; + byId("statesHalo").style.display = "none"; - statesEditor.querySelectorAll(".hide").forEach(el => el.classList.add("hidden")); + statesEditor.queryAll(".hide").forEach(el => el.classList.add("hidden")); statesFooter.style.display = "none"; - body.querySelectorAll("div > input, select, span, svg").forEach(e => (e.style.pointerEvents = "none")); + $body.queryAll("div > input, select, span, svg").forEach(e => (e.style.pointerEvents = "none")); $("#statesEditor").dialog({position: {my: "right top", at: "right-10 top+10", of: "svg", collision: "fit"}}); tip("Click on state to select, drag the circle to change state", true); - viewbox.style("cursor", "crosshair").on("click", selectStateOnMapClick).call(d3.drag().on("start", dragStateBrush)).on("touchmove mousemove", moveStateBrush); + byId("viewbox") + .style("cursor", "crosshair") + .on("click", selectStateOnMapClick) + .call(d3.drag().on("start", dragStateBrush)) + .on("touchmove mousemove", moveStateBrush); - body.querySelector("div").classList.add("selected"); + $body.query("div").classList.add("selected"); } function selectStateOnLineClick() { if (customization !== 2) return; if (this.parentNode.id !== "statesBodySection") return; - body.querySelector("div.selected").classList.remove("selected"); + $body.query("div.selected").classList.remove("selected"); this.classList.add("selected"); } @@ -936,8 +930,8 @@ function selectStateOnMapClick() { const assigned = statesBody.select("#temp").select("polygon[data-cell='" + i + "']"); const state = assigned.size() ? +assigned.attr("data-state") : pack.cells.state[i]; - body.querySelector("div.selected").classList.remove("selected"); - body.querySelector("div[data-id='" + state + "']").classList.add("selected"); + $body.query("div.selected").classList.remove("selected"); + $body.query("div[data-id='" + state + "']").classList.add("selected"); } function dragStateBrush() { @@ -957,9 +951,9 @@ function dragStateBrush() { // change state within selection function changeStateForSelection(selection) { const temp = statesBody.select("#temp"); - const selected = body.querySelector("div.selected"); - const stateNew = +selected.dataset.id; + const $selected = $body.query("div.selected"); + const stateNew = +$selected.dataset.id; const color = pack.states[stateNew].color || "#ffffff"; selection.forEach(function (i) { @@ -1007,7 +1001,7 @@ function applyStatesManualAssignent() { if (layerIsOn("toggleProvinces")) drawProvinces(); } - exitStatesManualAssignment(); + exitStatesManualAssignment(false); } function adjustProvinces(affectedProvinces) { @@ -1146,18 +1140,18 @@ function exitStatesManualAssignment(close) { customization = 0; statesBody.select("#temp").remove(); removeCircle(); - document.querySelectorAll("#statesBottom > button").forEach(el => (el.style.display = "inline-block")); - document.getElementById("statesManuallyButtons").style.display = "none"; - document.getElementById("statesHalo").style.display = "block"; + queryAll("#statesBottom > button").forEach(el => (el.style.display = "inline-block")); + byId("statesManuallyButtons").style.display = "none"; + byId("statesHalo").style.display = "block"; - statesEditor.querySelectorAll(".hide:not(.show)").forEach(el => el.classList.remove("hidden")); + statesEditor.queryAll(".hide:not(.show)").forEach(el => el.classList.remove("hidden")); statesFooter.style.display = "block"; - body.querySelectorAll("div > input, select, span, svg").forEach(e => (e.style.pointerEvents = "all")); + $body.queryAll("div > input, select, span, svg").forEach(e => (e.style.pointerEvents = "all")); if (!close) $("#statesEditor").dialog({position: {my: "right top", at: "right-10 top+10", of: "svg", collision: "fit"}}); restoreDefaultEvents(); clearMainTip(); - const selected = body.querySelector("div.selected"); + const selected = $body.query("div.selected"); if (selected) selected.classList.remove("selected"); } @@ -1170,7 +1164,7 @@ function enterAddStateMode() { this.classList.add("pressed"); tip("Click on the map to create a new capital or promote an existing burg", true); viewbox.style("cursor", "crosshair").on("click", addState); - body.querySelectorAll("div > input, select, span, svg").forEach(e => (e.style.pointerEvents = "none")); + $body.queryAll("div > input, select, span, svg").forEach(e => (e.style.pointerEvents = "none")); } function addState() { @@ -1284,41 +1278,30 @@ function exitAddStateMode() { customization = 0; restoreDefaultEvents(); clearMainTip(); - body.querySelectorAll("div > input, select, span, svg").forEach(e => (e.style.pointerEvents = "all")); + $body.queryAll("div > input, select, span, svg").forEach(e => (e.style.pointerEvents = "all")); if (statesAdd.classList.contains("pressed")) statesAdd.classList.remove("pressed"); } -function downloadStatesData() { - const unit = areaUnit.value === "square" ? distanceUnitInput.value + "2" : areaUnit.value; - let data = - "Id,State,Full Name,Form,Color,Capital,Culture,Type,Expansionism,Cells,Burgs,Area " + unit + ",Total Population,Rural Population,Urban Population\n"; // headers - body.querySelectorAll(":scope > div").forEach(function (el) { - const key = parseInt(el.dataset.id); - const statePack = pack.states[key]; - data += el.dataset.id + ","; - data += el.dataset.name + ","; - data += (statePack.fullName ? statePack.fullName : "") + ","; - data += el.dataset.form + ","; - data += el.dataset.color + ","; - data += el.dataset.capital + ","; - data += el.dataset.culture + ","; - data += el.dataset.type + ","; - data += el.dataset.expansionism + ","; - data += el.dataset.cells + ","; - data += el.dataset.burgs + ","; - data += el.dataset.area + ","; - data += el.dataset.population + ","; - data += `${Math.round(statePack.rural * populationRate)},`; - data += `${Math.round(statePack.urban * populationRate * urbanization)}\n`; +function downloadStatesCsv() { + const unit = byId("areaUnit").value === "square" ? byId("distanceUnitInput").value + "2" : byId("areaUnit").value; + const headers = `Id,State,Full Name,Form,Color,Capital,Culture,Type,Expansionism,Cells,Burgs,Area ${unit},Total Population,Rural Population,Urban Population`; + const lines = Array.from($body.queryAll(":scope > div")); + const statesData = lines.map($line => { + const {id, name, form, color, capital, culture, type, expansionism, cells, burgs, area, population} = $line.dataset; + const {fullName = "", rural, urban} = pack.states[+id]; + const ruralPopulation = Math.round(rural * populationRate); + const urbanPopulation = Math.round(urban * populationRate * urbanization); + return [id, name, fullName, form, color, capital, culture, type, expansionism, cells, burgs, area, population, ruralPopulation, urbanPopulation].join(","); }); + const csvData = [headers].concat(statesData).join("\n"); const name = getFileName("States") + ".csv"; - downloadFile(data, name); + downloadFile(csvData, name); } function closeStatesEditor() { - if (customization === 2) exitStatesManualAssignment("close"); + if (customization === 2) exitStatesManualAssignment(true); if (customization === 3) exitAddStateMode(); debug.selectAll(".highlight").remove(); - body.innerHTML = ""; + $body.innerHTML = ""; } diff --git a/modules/ui/editors.js b/modules/ui/editors.js index 8200607e..1984f9a2 100644 --- a/modules/ui/editors.js +++ b/modules/ui/editors.js @@ -1097,6 +1097,6 @@ function refreshAllEditors() { // dynamically loaded editors async function editStates() { if (customization) return; - const StateEditor = await import("../dynamic/editors/states-editor.js"); + const StateEditor = await import("../dynamic/editors/states-editor.js?v=17052022"); StateEditor.open(); } diff --git a/utils/shorthands.js b/utils/shorthands.js new file mode 100644 index 00000000..a82b1cd6 --- /dev/null +++ b/utils/shorthands.js @@ -0,0 +1,21 @@ +const query = document.querySelector.bind(document); +const queryAll = document.querySelectorAll.bind(document); +const byId = document.getElementById.bind(document); +const byClass = document.getElementsByClassName.bind(document); +const byTag = document.getElementsByTagName.bind(document); + +Node.prototype.query = function (selector) { + return this.querySelector(selector); +}; + +Node.prototype.queryAll = function (selector) { + return this.querySelectorAll(selector); +}; + +Node.prototype.on = function (name, fn, options) { + this.addEventListener(name, fn, options); +}; + +Node.prototype.off = function (name, fn) { + this.removeEventListener(name, fn); +}; diff --git a/versioning.js b/versioning.js index 07617b2a..bc71f893 100644 --- a/versioning.js +++ b/versioning.js @@ -1,7 +1,7 @@ "use strict"; // version and caching control -const version = "1.82.01"; // generator version, update each time +const version = "1.82.02"; // generator version, update each time { document.title += " v" + version; From 378d40de5b70661011b0c1410d32ab2505f3325b Mon Sep 17 00:00:00 2001 From: Azgaar Date: Tue, 17 May 2022 22:40:02 +0300 Subject: [PATCH 054/501] refactor states-editor --- modules/dynamic/editors/states-editor.js | 36 +++++++++++++++--------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/modules/dynamic/editors/states-editor.js b/modules/dynamic/editors/states-editor.js index f4c40901..d255f70b 100644 --- a/modules/dynamic/editors/states-editor.js +++ b/modules/dynamic/editors/states-editor.js @@ -184,7 +184,7 @@ function refreshStatesEditor() { // add line for each state function statesEditorAddLines() { const unit = areaUnit.value === "square" ? " " + distanceUnitInput.value + "²" : " " + areaUnit.value; - const hidden = statesRegenerateButtons.style.display === "block" ? "" : "hidden"; // show/hide regenerate columns + const hidden = byId("statesRegenerateButtons").style.display === "block" ? "" : "hidden"; // toggle regenerate columns let lines = ""; let totalArea = 0; let totalPopulation = 0; @@ -845,10 +845,14 @@ function showStatesChart() { } function openRegenerationMenu() { - statesBottom.queryAll(":scope > button").forEach(el => (el.style.display = "none")); - statesRegenerateButtons.style.display = "block"; + byId("statesBottom") + .queryAll(":scope > button") + .forEach(el => (el.style.display = "none")); + byId("statesRegenerateButtons").style.display = "block"; - statesEditor.queryAll(".show").forEach(el => el.classList.remove("hidden")); + byId("statesEditor") + .queryAll(".show") + .forEach(el => el.classList.remove("hidden")); $("#statesEditor").dialog({position: {my: "right top", at: "right-10 top+10", of: "svg", collision: "fit"}}); } @@ -886,9 +890,13 @@ function randomizeStatesExpansion() { } function exitRegenerationMenu() { - statesBottom.queryAll(":scope > button").forEach(el => (el.style.display = "inline-block")); - statesRegenerateButtons.style.display = "none"; - statesEditor.queryAll(".show").forEach(el => el.classList.add("hidden")); + byId("statesBottom") + .queryAll(":scope > button") + .forEach(el => (el.style.display = "inline-block")); + byId("statesRegenerateButtons").style.display = "none"; + byId("statesEditor") + .queryAll(".show") + .forEach(el => el.classList.add("hidden")); $("#statesEditor").dialog({position: {my: "right top", at: "right-10 top+10", of: "svg", collision: "fit"}}); } @@ -900,17 +908,15 @@ function enterStatesManualAssignent() { byId("statesManuallyButtons").style.display = "inline-block"; byId("statesHalo").style.display = "none"; - statesEditor.queryAll(".hide").forEach(el => el.classList.add("hidden")); + byId("statesEditor") + .queryAll(".hide") + .forEach(el => el.classList.add("hidden")); statesFooter.style.display = "none"; $body.queryAll("div > input, select, span, svg").forEach(e => (e.style.pointerEvents = "none")); $("#statesEditor").dialog({position: {my: "right top", at: "right-10 top+10", of: "svg", collision: "fit"}}); tip("Click on state to select, drag the circle to change state", true); - byId("viewbox") - .style("cursor", "crosshair") - .on("click", selectStateOnMapClick) - .call(d3.drag().on("start", dragStateBrush)) - .on("touchmove mousemove", moveStateBrush); + viewbox.style("cursor", "crosshair").on("click", selectStateOnMapClick).call(d3.drag().on("start", dragStateBrush)).on("touchmove mousemove", moveStateBrush); $body.query("div").classList.add("selected"); } @@ -1144,7 +1150,9 @@ function exitStatesManualAssignment(close) { byId("statesManuallyButtons").style.display = "none"; byId("statesHalo").style.display = "block"; - statesEditor.queryAll(".hide:not(.show)").forEach(el => el.classList.remove("hidden")); + byId("statesEditor") + .queryAll(".hide:not(.show)") + .forEach(el => el.classList.remove("hidden")); statesFooter.style.display = "block"; $body.queryAll("div > input, select, span, svg").forEach(e => (e.style.pointerEvents = "all")); if (!close) $("#statesEditor").dialog({position: {my: "right top", at: "right-10 top+10", of: "svg", collision: "fit"}}); From 0d71f10f05bfada9ee32c2f7b9b4b03f25a3da6b Mon Sep 17 00:00:00 2001 From: GoteGuru Date: Wed, 18 May 2022 11:56:44 +0200 Subject: [PATCH 055/501] Submap live preview. --- index.html | 5 +- modules/io/export.js | 8 ++- modules/ui/submap.js | 160 ++++++++++++++++++++++++++++++++++--------- 3 files changed, 137 insertions(+), 36 deletions(-) diff --git a/index.html b/index.html index 6aac18d2..6493e516 100644 --- a/index.html +++ b/index.html @@ -4370,8 +4370,8 @@
      Shift
      - - + +
      Rotate
      @@ -4395,6 +4395,7 @@
      +
      - - `; + return /* html */ `${common}to: + v:
      `; + if (type === "Multiply") - return `${common}to:v:
      `; + return /* html */ `${common}to: + v:
      `; + if (type === "Smooth") - return `${common}f:
      `; + return /* html */ `${common}f:
      `; } function setRange(event) { @@ -813,7 +827,7 @@ function editHeightmap() { } function selectTemplate(e) { - const body = document.getElementById("templateBody"); + const body = byId("templateBody"); const steps = body.querySelectorAll("div").length; const changed = +body.getAttribute("data-changed"); const template = e.target.value; @@ -839,7 +853,7 @@ function editHeightmap() { } function changeTemplate(template) { - const body = document.getElementById("templateBody"); + const body = byId("templateBody"); body.setAttribute("data-changed", 0); body.innerHTML = ""; @@ -856,11 +870,11 @@ function editHeightmap() { } function executeTemplate() { - const body = document.getElementById("templateBody"); + const body = byId("templateBody"); const steps = body.querySelectorAll("#templateBody > div"); if (!steps.length) return; - const {addHill, addPit, addRange, addTrough, addStrait, modify, smooth} = HeightmapGenerator; + const {addHill, addPit, addRange, addTrough, addStrait, modify, smooth, insulate} = HeightmapGenerator; grid.cells.h = new Uint8Array(grid.cells.i.length); // clean all heights for (const step of steps) { @@ -878,6 +892,7 @@ function editHeightmap() { else if (type === "Range") addRange(count, height, x, y); else if (type === "Trough") addTrough(count, height, x, y); else if (type === "Strait") addStrait(count, dist); + else if (type === "Insulate") insulate(+count); else if (type === "Add") modify(dist, +count, 1); else if (type === "Multiply") modify(dist, 0, +count); else if (type === "Smooth") smooth(+count); @@ -887,12 +902,12 @@ function editHeightmap() { updateStatistics(); mockHeightmap(); - if (document.getElementById("preview")) drawHeightmapPreview(); // update heightmap preview if opened - if (document.getElementById("canvas3d")) ThreeD.redraw(); // update 3d heightmap preview if opened + if (byId("preview")) drawHeightmapPreview(); // update heightmap preview if opened + if (byId("canvas3d")) ThreeD.redraw(); // update 3d heightmap preview if opened } function downloadTemplate() { - const body = document.getElementById("templateBody"); + const body = byId("templateBody"); body.dataset.changed = 0; const steps = body.querySelectorAll("#templateBody > div"); if (!steps.length) return; @@ -977,18 +992,18 @@ function editHeightmap() { })(); // add listeners - document.getElementById("convertImageLoad").addEventListener("click", () => imageToLoad.click()); - document.getElementById("imageToLoad").addEventListener("change", loadImage); - document.getElementById("convertAutoLum").addEventListener("click", () => autoAssing("lum")); - document.getElementById("convertAutoHue").addEventListener("click", () => autoAssing("hue")); - document.getElementById("convertAutoFMG").addEventListener("click", () => autoAssing("scheme")); - document.getElementById("convertColorsButton").addEventListener("click", setConvertColorsNumber); - document.getElementById("convertComplete").addEventListener("click", applyConversion); - document.getElementById("convertCancel").addEventListener("click", cancelConversion); - document.getElementById("convertOverlay").addEventListener("input", function () { + byId("convertImageLoad").on("click", () => imageToLoad.click()); + byId("imageToLoad").on("change", loadImage); + byId("convertAutoLum").on("click", () => autoAssing("lum")); + byId("convertAutoHue").on("click", () => autoAssing("hue")); + byId("convertAutoFMG").on("click", () => autoAssing("scheme")); + byId("convertColorsButton").on("click", setConvertColorsNumber); + byId("convertComplete").on("click", applyConversion); + byId("convertCancel").on("click", cancelConversion); + byId("convertOverlay").on("input", function () { setOverlayOpacity(this.value); }); - document.getElementById("convertOverlayNumber").addEventListener("input", function () { + byId("convertOverlayNumber").on("input", function () { setOverlayOpacity(this.value); }); @@ -1012,7 +1027,7 @@ function editHeightmap() { document.body.appendChild(img); img.onload = function () { - const ctx = document.getElementById("canvas").getContext("2d"); + const ctx = byId("canvas").getContext("2d"); ctx.drawImage(img, 0, 0, graphWidth, graphHeight); heightsFromImage(+convertColors.value); resetZoom(); @@ -1023,7 +1038,7 @@ function editHeightmap() { } function heightsFromImage(count) { - const sourceImage = document.getElementById("canvas"); + const sourceImage = byId("canvas"); const sampleCanvas = document.createElement("canvas"); sampleCanvas.width = grid.cellsX; sampleCanvas.height = grid.cellsY; @@ -1062,7 +1077,7 @@ function editHeightmap() { .attr("class", "color-div") .on("click", colorClicked); - document.getElementById("colorsUnassignedNumber").innerHTML = colors.length; + byId("colorsUnassignedNumber").innerHTML = colors.length; } function mapClicked() { @@ -1119,8 +1134,8 @@ function editHeightmap() { colorsAssigned.appendChild(selectedColor); colorsAssigned.style.display = "block"; - document.getElementById("colorsUnassignedNumber").innerHTML = colorsUnassigned.childElementCount - 2; - document.getElementById("colorsAssignedNumber").innerHTML = colorsAssigned.childElementCount - 2; + byId("colorsUnassignedNumber").innerHTML = colorsUnassigned.childElementCount - 2; + byId("colorsAssignedNumber").innerHTML = colorsAssigned.childElementCount - 2; } } @@ -1187,7 +1202,7 @@ function editHeightmap() { colorsAssigned.style.display = "block"; colorsUnassigned.style.display = "none"; - document.getElementById("colorsAssignedNumber").innerHTML = colorsAssigned.childElementCount - 2; + byId("colorsAssignedNumber").innerHTML = colorsAssigned.childElementCount - 2; } function setConvertColorsNumber() { @@ -1203,7 +1218,7 @@ function editHeightmap() { function setOverlayOpacity(v) { convertOverlay.value = convertOverlayNumber.value = v; - document.getElementById("canvas").style.opacity = v; + byId("canvas").style.opacity = v; } function applyConversion() { @@ -1230,10 +1245,10 @@ function editHeightmap() { } function restoreImageConverterState() { - const canvas = document.getElementById("canvas"); + const canvas = byId("canvas"); if (canvas) canvas.remove(); - const image = document.getElementById("imageToConvert"); + const image = byId("imageToConvert"); if (image) image.remove(); d3.select("#imageConverter").selectAll("div.color-div").remove(); @@ -1275,8 +1290,8 @@ function editHeightmap() { } function toggleHeightmapPreview() { - if (document.getElementById("preview")) { - document.getElementById("preview").remove(); + if (byId("preview")) { + byId("preview").remove(); return; } const preview = document.createElement("canvas"); @@ -1284,13 +1299,13 @@ function editHeightmap() { preview.width = grid.cellsX; preview.height = grid.cellsY; document.body.insertBefore(preview, optionsContainer); - preview.addEventListener("mouseover", () => tip("Heightmap preview. Click to download a screen-sized image")); - preview.addEventListener("click", downloadPreview); + preview.on("mouseover", () => tip("Heightmap preview. Click to download a screen-sized image")); + preview.on("click", downloadPreview); drawHeightmapPreview(); } function drawHeightmapPreview() { - const ctx = document.getElementById("preview").getContext("2d"); + const ctx = byId("preview").getContext("2d"); const imageData = ctx.createImageData(grid.cellsX, grid.cellsY); grid.cells.h.forEach((height, i) => { @@ -1306,7 +1321,7 @@ function editHeightmap() { } function downloadPreview() { - const preview = document.getElementById("preview"); + const preview = byId("preview"); const dataURL = preview.toDataURL("image/png"); const img = new Image(); From 51e467a646d9c5de5577a0bdd3dcb705656f6fbb Mon Sep 17 00:00:00 2001 From: Azgaar Date: Sat, 21 May 2022 12:30:14 +0300 Subject: [PATCH 068/501] Create codeql-analysis.yml --- .github/workflows/codeql-analysis.yml | 72 +++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 .github/workflows/codeql-analysis.yml diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 00000000..a6fef8bd --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,72 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL" + +on: + push: + branches: [ master ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ master ] + schedule: + - cron: '25 22 * * 5' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'javascript' ] + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] + # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + + # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs + # queries: security-extended,security-and-quality + + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + + # ℹ️ Command-line programs to run using the OS shell. + # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun + + # If the Autobuild fails above, remove it and uncomment the following three lines. + # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. + + # - run: | + # echo "Run, Build Application using script" + # ./location_of_script_within_repo/buildscript.sh + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 From a16e609696deb3c172f43bb98814be642a9f8b06 Mon Sep 17 00:00:00 2001 From: Azgaar Date: Sat, 21 May 2022 19:46:42 +0300 Subject: [PATCH 069/501] Fractious template --- index.css | 2 +- index.html | 33 ++++---- modules/heightmap-generator.js | 19 +++-- modules/heightmap-templates.js | 141 ++++++++++++++------------------- modules/ui/heightmap-editor.js | 58 ++++++++------ 5 files changed, 124 insertions(+), 129 deletions(-) diff --git a/index.css b/index.css index f070c939..1b7a983b 100644 --- a/index.css +++ b/index.css @@ -922,7 +922,7 @@ fieldset { display: inline-block; } -body button.noicon { +#templateTools > button { width: 1.8em; height: 1.6em; margin: 1px; diff --git a/index.html b/index.html index 214bfa9e..32c30825 100644 --- a/index.html +++ b/index.html @@ -1292,7 +1292,7 @@ - + @@ -1302,6 +1302,7 @@ + @@ -2932,13 +2933,13 @@ `; - if (type === "Insulate") - return /* html */ `${common}f:
      `; + if (type === "Mask") + return /* html */ `${common}f:
      `; if (type === "Add") return /* html */ `${common}to:
      `; + return /* html */ `${common}f:
      `; } function setRange(event) { @@ -870,34 +878,36 @@ function editHeightmap() { } function executeTemplate() { - const body = byId("templateBody"); - const steps = body.querySelectorAll("#templateBody > div"); + const steps = byId("templateBody").querySelectorAll("#templateBody > div"); if (!steps.length) return; - const {addHill, addPit, addRange, addTrough, addStrait, modify, smooth, insulate} = HeightmapGenerator; grid.cells.h = new Uint8Array(grid.cells.i.length); // clean all heights + const seed = byId("templateSeed").value; + if (seed) Math.random = aleaPRNG(seed); + restartHistory(); + for (const step of steps) { if (step.style.opacity === "0.5") continue; - const type = step.dataset.type; const count = step.querySelector(".templateCount")?.value || ""; const height = step.querySelector(".templateHeight")?.value || ""; const dist = step.querySelector(".templateDist")?.value || null; const x = step.querySelector(".templateX")?.value || null; const y = step.querySelector(".templateY")?.value || null; + const type = step.dataset.type; - if (type === "Hill") addHill(count, height, x, y); - else if (type === "Pit") addPit(count, height, x, y); - else if (type === "Range") addRange(count, height, x, y); - else if (type === "Trough") addTrough(count, height, x, y); - else if (type === "Strait") addStrait(count, dist); - else if (type === "Insulate") insulate(+count); - else if (type === "Add") modify(dist, +count, 1); - else if (type === "Multiply") modify(dist, 0, +count); - else if (type === "Smooth") smooth(+count); + if (type === "Hill") HeightmapGenerator.addHill(count, height, x, y); + else if (type === "Pit") HeightmapGenerator.addPit(count, height, x, y); + else if (type === "Range") HeightmapGenerator.addRange(count, height, x, y); + else if (type === "Trough") HeightmapGenerator.addTrough(count, height, x, y); + else if (type === "Strait") HeightmapGenerator.addStrait(count, dist); + else if (type === "Mask") HeightmapGenerator.mask(+count); + else if (type === "Add") HeightmapGenerator.modify(dist, +count, 1); + else if (type === "Multiply") HeightmapGenerator.modify(dist, 0, +count); + else if (type === "Smooth") HeightmapGenerator.smooth(+count); - updateHistory("noStat"); // update history every step + updateHistory("noStat"); // update history on every step } updateStatistics(); From 63db344e0610487a974108b462c8415b1fd4cb98 Mon Sep 17 00:00:00 2001 From: Azgaar Date: Sat, 21 May 2022 20:55:32 +0300 Subject: [PATCH 070/501] fix style --- index.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/index.html b/index.html index 32c30825..20704075 100644 --- a/index.html +++ b/index.html @@ -107,7 +107,7 @@ } } - + @@ -1759,13 +1759,13 @@
      - Depressions filling max iterations: +
      Depressions filling max iterations:
      - Depression depth threshold: +
      Depression depth threshold:
      @@ -2989,7 +2989,7 @@ >
      From 2713f6bfda97f140fdedfcde554f9ad481a760dc Mon Sep 17 00:00:00 2001 From: Azgaar Date: Sat, 21 May 2022 22:43:06 +0300 Subject: [PATCH 071/501] inversion tool --- index.html | 1 + modules/heightmap-generator.js | 26 +++++- modules/heightmap-templates.js | 8 +- modules/ui/heightmap-editor.js | 145 +++++++++++++++++++++------------ 4 files changed, 122 insertions(+), 58 deletions(-) diff --git a/index.html b/index.html index 20704075..577b4140 100644 --- a/index.html +++ b/index.html @@ -2959,6 +2959,7 @@ + diff --git a/modules/heightmap-generator.js b/modules/heightmap-generator.js index 80eecde1..762350ce 100644 --- a/modules/heightmap-generator.js +++ b/modules/heightmap-generator.js @@ -365,8 +365,8 @@ window.HeightmapGenerator = (function () { const endX = vert ? Math.floor(graphWidth - startX - graphWidth * 0.1 + Math.random() * graphWidth * 0.2) : graphWidth - 5; const endY = vert ? graphHeight - 5 : Math.floor(graphHeight - startY - graphHeight * 0.1 + Math.random() * graphHeight * 0.2); - const start = findGridCell(startX, startY), - end = findGridCell(endX, endY); + const start = findGridCell(startX, startY); + const end = findGridCell(endX, endY); let range = getRange(start, end); const query = []; @@ -446,6 +446,26 @@ window.HeightmapGenerator = (function () { }); }; + const invert = (count, axes) => { + if (!P(count)) return; + + const invertX = axes !== "y"; + const invertY = axes !== "x"; + const {cellsX, cellsY} = grid; + + const inverted = cells.h.map((h, i) => { + const x = i % cellsX; + const y = Math.floor(i / cellsX); + + const nx = invertX ? cellsX - x - 1 : x; + const ny = invertY ? cellsY - y - 1 : y; + const invertedI = nx + ny * cellsX; + return cells.h[invertedI]; + }); + + cells.h = inverted; + }; + function getPointInRange(range, length) { if (typeof range !== "string") { ERROR && console.error("Range should be a string"); @@ -465,5 +485,5 @@ window.HeightmapGenerator = (function () { } } - return {generate, addHill, addRange, addTrough, addStrait, addPit, smooth, modify, mask}; + return {generate, addHill, addRange, addTrough, addStrait, addPit, smooth, modify, mask, invert}; })(); diff --git a/modules/heightmap-templates.js b/modules/heightmap-templates.js index baff264c..7e0cd20c 100644 --- a/modules/heightmap-templates.js +++ b/modules/heightmap-templates.js @@ -69,7 +69,7 @@ window.HeightmapTemplates = (function () { Hill .5 30-50 25-35 30-70 Smooth 1 0 0 0 Multiply 0.2 25-100 0 0 - Hill .5 10-20 50-55 48-52`; + Hill 0.5 10-20 50-55 48-52`; const mediterranean = `Range 4-6 30-80 0-100 0-10 Range 4-6 30-80 0-100 90-100 @@ -90,7 +90,8 @@ window.HeightmapTemplates = (function () { Hill 3-4 3-5 5-95 80-100 Hill 1-2 3-5 5-95 40-60 Trough 5-6 10-25 5-95 5-95 - Smooth 3 0 0 0`; + Smooth 3 0 0 0 + Invert 0.4 both 0 0`; const pangea = `Hill 1-2 25-40 15-50 0-10 Hill 1-2 5-40 50-85 0-10 @@ -113,7 +114,8 @@ window.HeightmapTemplates = (function () { Trough 4-8 15-30 10-50 20-40 Trough 4-8 15-30 30-70 40-60 Trough 4-8 15-30 50-90 60-80 - Trough 4-8 15-30 70-100 80-100`; + Trough 4-8 15-30 70-100 80-100 + Invert 0.25 x 0 0`; const shattered = `Hill 8 35-40 15-85 30-70 Trough 10-20 40-50 5-95 5-95 diff --git a/modules/ui/heightmap-editor.js b/modules/ui/heightmap-editor.js index 14963745..12d8b283 100644 --- a/modules/ui/heightmap-editor.js +++ b/modules/ui/heightmap-editor.js @@ -613,9 +613,7 @@ function editHeightmap() { const power = brushPower.valueAsNumber; const interpolate = d3.interpolateRound(power, 1); const land = changeOnlyLand.checked; - function lim(v) { - return minmax(v, land ? 20 : 0, 100); - } + const lim = v => minmax(v, land ? 20 : 0, 100); const h = grid.cells.h; const brush = document.querySelector("#brushesButtons > button.pressed").id; @@ -674,15 +672,10 @@ function editHeightmap() { } function startFromScratch() { - if (changeOnlyLand.checked) { - tip("Not allowed when 'Change only land cells' mode is set", false, "error"); - return; - } + if (changeOnlyLand.checked) return tip("Not allowed when 'Change only land cells' mode is set", false, "error"); const someHeights = grid.cells.h.some(h => h); - if (!someHeights) { - tip("Heightmap is already cleared, please do not click twice if not required", false, "error"); - return; - } + if (!someHeights) return tip("Heightmap is already cleared, please do not click twice if not required", false, "error"); + grid.cells.h = new Uint8Array(grid.cells.i.length); viewbox.select("#heights").selectAll("*").remove(); updateHistory(); @@ -752,19 +745,21 @@ function editHeightmap() { } function addStep(type, count, dist, arg4, arg5) { - const body = byId("templateBody"); - body.insertAdjacentHTML("beforeend", getStepHTML(type, count, dist, arg4, arg5)); - const elDist = body.querySelector("div:last-child").querySelector(".templateDist"); - if (elDist) elDist.on("change", setRange); - if (dist && elDist && elDist.tagName === "SELECT") { - for (const o of elDist.options) { - if (o.value === dist) elDist.value = dist; + const $body = byId("templateBody"); + $body.insertAdjacentHTML("beforeend", getStepHTML(type, count, dist, arg4, arg5)); + + const $elDist = $body.querySelector("div:last-child > span > .templateDist"); + if ($elDist) $elDist.on("change", setRange); + + if (dist && $elDist && $elDist.tagName === "SELECT") { + for (const option of $elDist.options) { + if (option.value === dist) $elDist.value = dist; } - if (elDist.value !== dist) { + if ($elDist.value !== dist) { const opt = document.createElement("option"); opt.value = opt.innerHTML = dist; - elDist.add(opt); - elDist.value = dist; + $elDist.add(opt); + $elDist.value = dist; } } } @@ -775,52 +770,97 @@ function editHeightmap() { const Reorder = /* html */ ``; const common = /* html */ `
      ${Hide}
      ${type}
      ${Trash}${Reorder}`; - const TempY = /* html */ `y:`; + const TempY = /* html */ `y: + + `; - const TempX = /* html */ `x:`; + const TempX = /* html */ `x: + + `; - const Height = /* html */ `h:`; + const Height = /* html */ `h: + + `; - const Count = /* html */ `n:`; + const Count = /* html */ `n: + + `; if (type === "Hill" || type === "Pit" || type === "Range" || type === "Trough") return /* html */ `${common}${TempY}${TempX}${Height}${Count}
      `; if (type === "Strait") - return /* html */ `${common}d: - w:
      `; + return /* html */ `${common} + d: + + + w: + + +
      `; + + if (type === "Invert") + return /* html */ `${common} + by: + + + n: + + +
      `; if (type === "Mask") - return /* html */ `${common}f:
      `; + return /* html */ `${common} + f: + + +
      `; if (type === "Add") - return /* html */ `${common}to: - v:
      `; + return /* html */ `${common} + to: + + + v: + + + `; if (type === "Multiply") - return /* html */ `${common}to: - v:`; + return /* html */ `${common} + to: + + + v: + + + `; if (type === "Smooth") - return /* html */ `${common}f:`; + return /* html */ `${common} + f: + + + `; } function setRange(event) { @@ -903,6 +943,7 @@ function editHeightmap() { else if (type === "Trough") HeightmapGenerator.addTrough(count, height, x, y); else if (type === "Strait") HeightmapGenerator.addStrait(count, dist); else if (type === "Mask") HeightmapGenerator.mask(+count); + else if (type === "Invert") HeightmapGenerator.invert(+count, dist); else if (type === "Add") HeightmapGenerator.modify(dist, +count, 1); else if (type === "Multiply") HeightmapGenerator.modify(dist, 0, +count); else if (type === "Smooth") HeightmapGenerator.smooth(+count); From ceba329bd622878c7b45874bbaefc8c06f116a45 Mon Sep 17 00:00:00 2001 From: Azgaar Date: Sat, 21 May 2022 23:54:59 +0300 Subject: [PATCH 072/501] pump version to 1.83.0 --- index.html | 2 +- versioning.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/index.html b/index.html index 577b4140..e6883666 100644 --- a/index.html +++ b/index.html @@ -2977,7 +2977,7 @@
      - + diff --git a/versioning.js b/versioning.js index ee337422..bc450f65 100644 --- a/versioning.js +++ b/versioning.js @@ -1,7 +1,7 @@ "use strict"; // version and caching control -const version = "1.82.05"; // generator version, update each time +const version = "1.83.0"; // generator version, update each time { document.title += " v" + version; From 91c6a5aaec7fc621793c521578e2cc9c06720b09 Mon Sep 17 00:00:00 2001 From: Azgaar Date: Sat, 21 May 2022 23:58:44 +0300 Subject: [PATCH 073/501] add changes to updateWindow --- versioning.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/versioning.js b/versioning.js index bc450f65..54c53146 100644 --- a/versioning.js +++ b/versioning.js @@ -28,6 +28,8 @@ const version = "1.83.0"; // generator version, update each time
        Latest changes: +
      • New heightmap template: Fractious
      • +
      • Template Editor: mask and invert tools
      • Ability to install the App
      • 14 new default fonts
      • Caching for faster startup
      • @@ -35,8 +37,6 @@ const version = "1.83.0"; // generator version, update each time
      • Resample tool by Goteguru
      • Pre-defined heightmaps
      • Advanced notes editor
      • -
      • Zones editor: filter by type
      • -
      • Color picker: new hatchings

      Join our Discord server and Reddit community to ask questions, share maps, discuss the Generator and Worlbuilding, report bugs and propose new features.

      From 8cb556262b9b6b90abca184b40c573030d7eeb82 Mon Sep 17 00:00:00 2001 From: Azgaar Date: Mon, 23 May 2022 20:20:59 +0300 Subject: [PATCH 074/501] update supporters --- index.html | 2 +- modules/dynamic/supporters.js | 2 +- modules/ui/options.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/index.html b/index.html index e6883666..033b5720 100644 --- a/index.html +++ b/index.html @@ -6139,7 +6139,7 @@ - + diff --git a/modules/dynamic/supporters.js b/modules/dynamic/supporters.js index 13176f9a..bc60b37c 100644 --- a/modules/dynamic/supporters.js +++ b/modules/dynamic/supporters.js @@ -40,5 +40,5 @@ export const supporters = format(` Jordan,William Markus,Sidr Dim,Alexander Whittaker,The Next Level,Patrick Valverde,Markus Peham,Daniel Cooper,the Beagles of Neorbus,Marley Moule, Maximilian Schielke,Johnathan Xavier Hutchinson,Ele,Rita,Randy Ross,John Wick,RedSpaz,cameron cannon,Ian Grau-Fay,Kyle Barrett,Charlotte Wiland, David Kaul,E. Jason Davis,Cyberate,Atenfox,Sea Wolf,Holly Loveless,Roekai,Alden Z,angel carrillo,Sam Spoerle,S A Rudy,Bird Law Expert,Mira Cyr, - Aaron Blair + Aaron Blair,Neyimadd,RLKZ1022 `); diff --git a/modules/ui/options.js b/modules/ui/options.js index cbafda84..e9fdf849 100644 --- a/modules/ui/options.js +++ b/modules/ui/options.js @@ -75,7 +75,7 @@ document // show popup with a list of Patreon supportes (updated manually, to be replaced with API call) async function showSupporters() { - const {supporters} = await import("../dynamic/supporters.js"); + const {supporters} = await import("../dynamic/supporters.js?v=23052022"); alertMessage.innerHTML = "
        " + supporters.map(n => `
      • ${n}
      • `).join("") + "
      "; $("#alert").dialog({resizable: false, title: "Patreon Supporters", width: "54vw", position: {my: "center", at: "center", of: "svg"}}); } From c394534246c33600a85f84cf13943fd4a1a4f466 Mon Sep 17 00:00:00 2001 From: Azgaar Date: Mon, 23 May 2022 23:52:39 +0300 Subject: [PATCH 075/501] base dialog --- index.css | 13 ++ index.html | 4 +- modules/dynamic/editors/cultures-editor.js | 2 +- modules/dynamic/editors/states-editor.js | 2 +- modules/dynamic/heightmap-selection.js | 183 +++++++++++++++++++++ modules/ui/options.js | 6 + versioning.js | 2 +- 7 files changed, 208 insertions(+), 4 deletions(-) create mode 100644 modules/dynamic/heightmap-selection.js diff --git a/index.css b/index.css index 1b7a983b..05baf61c 100644 --- a/index.css +++ b/index.css @@ -1318,6 +1318,12 @@ div.slider .ui-slider-handle { scrollbar-width: thin; } +.dialog::-webkit-scrollbar { + width: 10px; + height: 10px; + background-color: transparent; +} + #alertMessage::-webkit-scrollbar, .table::-webkit-scrollbar, .matrix-table::-webkit-scrollbar { @@ -1326,6 +1332,7 @@ div.slider .ui-slider-handle { background-color: transparent; } +.dialog::-webkit-scrollbar-thumb, #alertMessage::-webkit-scrollbar-thumb, .table::-webkit-scrollbar-thumb, .matrix-table::-webkit-scrollbar-thumb { @@ -1333,6 +1340,7 @@ div.slider .ui-slider-handle { border-radius: 6px; } +.dialog::-webkit-scrollbar-thumb:hover, #alertMessage::-webkit-scrollbar-thumb:hover, .table::-webkit-scrollbar-thumb:hover, .matrix-table::-webkit-scrollbar-thumb:hover { @@ -2363,3 +2371,8 @@ svg.button { display: none; } } + + +img {} + +div {} \ No newline at end of file diff --git a/index.html b/index.html index 033b5720..873bd9e5 100644 --- a/index.html +++ b/index.html @@ -1331,7 +1331,9 @@ - + + + diff --git a/modules/dynamic/editors/cultures-editor.js b/modules/dynamic/editors/cultures-editor.js index 7ef8f1e3..0e4f9768 100644 --- a/modules/dynamic/editors/cultures-editor.js +++ b/modules/dynamic/editors/cultures-editor.js @@ -24,7 +24,7 @@ export function open() { } function insertEditorHtml() { - const editorHtml = /* html */ `