diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000..fa2de5e5 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,11 @@ +## Launch Checklist + + + + + - [ ] Briefly describe the changes in this PR. + - [ ] Link to related issues. + - [ ] Include before/after visuals or gifs if this PR includes visual changes. + - [ ] Write tests for all new functionality. + - [ ] Add an entry to `CHANGELOG.md` under the `## main` section. + diff --git a/.github/workflows/ci-desktop.yml b/.github/workflows/ci-desktop.yml deleted file mode 100644 index eb25689b..00000000 --- a/.github/workflows/ci-desktop.yml +++ /dev/null @@ -1,52 +0,0 @@ -name: ci-desktop - -on: [ push ] - -jobs: - build: - - runs-on: ubuntu-latest - defaults: - run: - working-directory: ./desktop - - steps: - - uses: actions/checkout@v3 - - - name: Set up Go - uses: actions/setup-go@v3 - with: - go-version: 1.18 - - - name: Make - run: make - - - name: Test --help - run: ./bin/linux/maputnik --help - - - name: Test --version - run: ./bin/linux/maputnik --version - - - name: Get style - run: wget https://maputnik.github.io/osm-liberty/style.json - - - name: Test --watch - run: ./bin/linux/maputnik --watch --file style.json & sleep 5; kill $! - - - name: Artifacts/linux - uses: actions/upload-artifact@v3 - with: - name: maputnik-linux - path: ./desktop/bin/linux/ - - - name: Artifacts/darwin - uses: actions/upload-artifact@v3 - with: - name: maputnik-darwin - path: ./desktop/bin/darwin/ - - - name: Artifacts/windows - uses: actions/upload-artifact@v3 - with: - name: maputnik-windows - path: ./desktop/bin/windows/ diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3492bcc2..49e0e500 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -54,45 +54,39 @@ jobs: - run: npm ci - run: npm run build - name: artifacts/maputnik - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v4 with: name: maputnik path: dist # Build and upload desktop CLI artifacts - name: Set up Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v5 with: - go-version: ^1.19.x + go-version: ^1.23.x + cache-dependency-path: desktop/go.sum id: go - - name: Check out code into the Go module directory - uses: actions/checkout@v4 - with: - repository: maputnik/desktop - ref: master - path: ./src/github.com/maputnik/desktop/ - - - name: Make - run: cd src/github.com/maputnik/desktop/ && make + - name: Build desktop artifacts + run: npm run build-desktop - name: Artifacts/linux - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v4 with: name: maputnik-linux - path: ./src/github.com/maputnik/desktop/bin/linux/ + path: ./desktop/bin/linux/ - name: Artifacts/darwin - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v4 with: name: maputnik-darwin - path: ./src/github.com/maputnik/desktop/bin/darwin/ + path: ./desktop/bin/darwin/ - name: Artifacts/windows - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v4 with: name: maputnik-windows - path: ./src/github.com/maputnik/desktop/bin/windows/ + path: ./desktop/bin/windows/ e2e-tests: name: "E2E tests using ${{ matrix.browser }}" diff --git a/.github/workflows/create-bump-version-pr.yml b/.github/workflows/create-bump-version-pr.yml new file mode 100644 index 00000000..468b5b1f --- /dev/null +++ b/.github/workflows/create-bump-version-pr.yml @@ -0,0 +1,39 @@ +name: Create bump version PR + +on: + workflow_dispatch: + inputs: + version: + description: Version to change to. + required: true + type: string + +jobs: + bump-version-pr: + name: Bump version PR + runs-on: ubuntu-latest + defaults: + run: + shell: bash + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + ref: main + + - name: Use Node.js from nvmrc + uses: actions/setup-node@v4 + with: + node-version-file: ".nvmrc" + + - name: Bump version + run: | + npm version --commit-hooks false --git-tag-version false ${{ inputs.version }} + ./build/bump-version-changelog.js ${{ inputs.version }} + + - name: Create Pull Request + uses: peter-evans/create-pull-request@v6 + with: + commit-message: Bump version to ${{ inputs.version }} + branch: bump-version-to-${{ inputs.version }} + title: Bump version to ${{ inputs.version }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..944304e9 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,102 @@ +name: Release + +on: + push: + branches: [main] + workflow_dispatch: + +jobs: + release-check: + name: Check if version changed + runs-on: ubuntu-latest + defaults: + run: + shell: bash + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + ref: main + + - name: Use Node.js from nvmrc + uses: actions/setup-node@v4 + with: + node-version-file: ".nvmrc" + + - name: Check if version has been updated + id: check + uses: EndBug/version-check@v2 + + outputs: + publish: ${{ steps.check.outputs.changed }} + + release: + name: Release + needs: release-check + if: ${{ needs.release-check.outputs.publish == 'true' }} + runs-on: ubuntu-latest + defaults: + run: + shell: bash + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + ref: main + + - name: Use Node.js from nvmrc + uses: actions/setup-node@v4 + with: + node-version-file: ".nvmrc" + registry-url: "https://registry.npmjs.org" + + - name: Set up Go for desktop build + uses: actions/setup-go@v5 + with: + go-version: ^1.23.x + cache-dependency-path: desktop/go.sum + id: go + + - name: Get version + id: package-version + uses: martinbeentjes/npm-get-version-action@v1.3.1 + + - name: Install + run: npm ci + + - name: Build + run: | + npm run build-desktop + + - name: Tag commit and push + id: tag_version + uses: mathieudutour/github-tag-action@v6.2 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + custom_tag: ${{ steps.package-version.outputs.current-version }} + + - name: Create Archives + run: | + zip -r "desktop-${{ steps.package-version.outputs.current-version }}" desktop/bin/ + + - name: Build Release Notes + id: release_notes + run: | + RELEASE_NOTES_PATH="${PWD}/release_notes.txt" + ./build/release-notes.js > ${RELEASE_NOTES_PATH} + echo "release_notes=${RELEASE_NOTES_PATH}" >> $GITHUB_OUTPUT + + - name: Create GitHub Release + id: create_regular_release + uses: ncipollo/release-action@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag: ${{ steps.tag_version.outputs.new_tag }} + name: ${{ steps.tag_version.outputs.new_tag }} + bodyFile: ${{ steps.release_notes.outputs.release_notes }} + artifacts: "desktop-${{ steps.package-version.outputs.current-version }}.zip" + allowUpdates: true + draft: false + prerelease: false + diff --git a/.gitignore b/.gitignore index d465cc0c..dba2935c 100644 --- a/.gitignore +++ b/.gitignore @@ -33,6 +33,14 @@ node_modules public /errorShots /old -/build /cypress/screenshots /dist/ +/desktop/version.go + +# IDE +.vscode/ +.idea/ + +# Window metadata files +/desktop/winres/winres.json +/desktop/*.syso diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..704319a4 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,26 @@ +## main + +### ✨ Features and improvements +- Add german translation +- Use same version number for web and desktop versions +- _...Add new stuff here..._ + +### 🐞 Bug fixes +- _...Add new stuff here..._ + +## 2.1.1 + +### ✨ Features and improvements + +- Add GitHub workflows for releasing new versions +- Update desktop build to pull from this repo (#922) + +## 2.0.0 + +- Update MapLibre to version 4 (#872) +- Start continuous deployment of maputnik website + +## 1.7.0 + +- See release notes at https://maputnik.github.io/blog/2020/04/23/release-v1.7.0 + diff --git a/README.md b/README.md index 785e546a..10f9ce88 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,8 @@ Maputnik is written in typescript and is using [React](https://github.com/facebo We ensure building and developing Maputnik works with the [current active LTS Node.js version and above](https://github.com/nodejs/Release#release-schedule). +Check out our [Internationalization guide](./src/locales/README.md) for UI text related changes. + ### Getting Involved Join the #maplibre or #maputnik slack channel at OSMUS: get an invite at https://slack.openstreetmap.us/ Read the the below guide in order to get familiar with how we do things around here. @@ -70,17 +72,6 @@ npm run lint-css npm run sort-styles ``` -Update the translation files (run this whenever touching user-facing strings). -After running, check your working copy for files and add/correct as needed. - -``` -npm run i18n:refresh -``` - -You can test the UI in different languages using the dropdown in the top menu -(Maputnik does not automatically localize based on browser language settings -at the moment). - ## Tests For E2E testing we use [Cypress](https://www.cypress.io/) @@ -104,6 +95,16 @@ You can also see the tests as they run or select which suites to run by executin npm run cy:open ``` +## Release process + +1. Review [`CHANGELOG.md`](/CHANGELOG.md) + - Double-check that all changes included in the release are appropriately documented. + - To-be-released changes should be under the "main" header. + - Commit any final changes to the changelog. +2. Run [Create bump version PR](https://github.com/maplibre/maputnik/actions/workflows/create-bump-version-pr.yml) by manual workflow dispatch and set the version number in the input. This will create a PR that changes the changelog and `package.json` file to review and merge. +3. Once merged, an automatic process will kick in and creates a GitHub release and uploads release assets. + + ## Sponsors Thanks to the supporters of the **[Kickstarter campaign](https://www.kickstarter.com/projects/174808720/maputnik-visual-map-editor-for-mapbox-gl)**. This project would not be possible without these commercial and individual sponsors. diff --git a/build/README.md b/build/README.md new file mode 100644 index 00000000..9cf562fc --- /dev/null +++ b/build/README.md @@ -0,0 +1,11 @@ +# Build Scripts + +This folder holds common build scripts used by some of the Github workflows. + +The scripts are borrowed from [maplibre/maplibre-gl-js](https://github.com/maplibre/maplibre-gl-js/tree/bc70bc559cea5c987fa1b79fd44766cef68bbe28/build). + +## Generate Release Notes + +`bump-version-changelog.js` Used to update the changelog with the current notes, and set up a space for new notes + +`release-notes.js` Used to generate release notes when releasing a new version diff --git a/build/bump-version-changelog.js b/build/bump-version-changelog.js new file mode 100755 index 00000000..1c9795b8 --- /dev/null +++ b/build/bump-version-changelog.js @@ -0,0 +1,29 @@ +#!/usr/bin/env node + +/** + * This script updates the changelog.md file with the version given in the arguments + * It replaces ## main with ## + * Removes _...Add new stuff here..._ + * And adds on top a ## main with add stuff here. + * + * Copied from maplibre/maplibre-gl-js + * https://github.com/maplibre/maplibre-gl-js/blob/bc70bc559cea5c987fa1b79fd44766cef68bbe28/build/release-notes.js + */ + +import * as fs from 'fs'; + +const changelogPath = 'CHANGELOG.md'; +let changelog = fs.readFileSync(changelogPath, 'utf8'); +changelog = changelog.replace('## main', `## ${process.argv[2]}`); +changelog = changelog.replaceAll('- _...Add new stuff here..._\n', ''); +changelog = `## main + +### ✨ Features and improvements +- _...Add new stuff here..._ + +### 🐞 Bug fixes +- _...Add new stuff here..._ + +` + changelog; + +fs.writeFileSync(changelogPath, changelog, 'utf8'); diff --git a/build/release-notes.js b/build/release-notes.js new file mode 100755 index 00000000..8e2e372a --- /dev/null +++ b/build/release-notes.js @@ -0,0 +1,48 @@ +#!/usr/bin/env node + +// Copied from maplibre/maplibre-gl-js +// https://github.com/maplibre/maplibre-gl-js/blob/bc70bc559cea5c987fa1b79fd44766cef68bbe28/build/release-notes.js + +import * as fs from 'fs'; + +const changelogPath = 'CHANGELOG.md'; +const changelog = fs.readFileSync(changelogPath, 'utf8'); + +/* + Parse the raw changelog text and split it into individual releases. + + This regular expression: + - Matches lines starting with "## x.x.x". + - Groups the version number. + - Skips the (optional) release date. + - Groups the changelog content. + - Ends when another "## x.x.x" is found. +*/ +const regex = /^## (\d+\.\d+\.\d+.*?)\n(.+?)(?=\n^## \d+\.\d+\.\d+.*?\n)/gms; + +let releaseNotes = []; +let match; +// eslint-disable-next-line no-cond-assign +while (match = regex.exec(changelog)) { + releaseNotes.push({ + 'version': match[1], + 'changelog': match[2].trim(), + }); +} + +const latest = releaseNotes[0]; +const previous = releaseNotes[1]; + +// Print the release notes template. + +let header = 'Changes since previous version' +if (previous) { + header = `https://github.com/maplibre/maputnik + [Changes](https://github.com/maplibre/maputnik/compare/v${previous.version}...v${latest.version}) since [Maputnik v${previous.version}](https://github.com/maplibre/maputnik/releases/tag/v${previous.version})` +} +const templatedReleaseNotes = `${header} + +${latest.changelog}`; + +// eslint-disable-next-line eol-last +process.stdout.write(templatedReleaseNotes.trimEnd()); diff --git a/desktop/Makefile b/desktop/Makefile index 140d9d6b..85d30c8c 100644 --- a/desktop/Makefile +++ b/desktop/Makefile @@ -1,21 +1,27 @@ SOURCEDIR=. SOURCES := $(shell find $(SOURCEDIR) -name '*.go') BINARY=maputnik -EDITOR_VERSION ?= v1.7.0 +VERSION := $(shell node -p "require('../package.json').version") GOPATH := $(if $(GOPATH),$(GOPATH),$(HOME)/go) GOBIN := $(if $(GOBIN),$(GOBIN),$(HOME)/go/bin) all: $(BINARY) -$(BINARY): $(GOBIN)/gox $(SOURCES) rice-box.go +$(BINARY): $(GOBIN)/gox $(GOBIN)/go-winres $(SOURCES) version.go rice-box.go winres/winres.json + $(GOBIN)/go-winres make --product-version=$(VERSION) $(GOBIN)/gox -osarch "windows/amd64 linux/amd64 darwin/amd64" -output "bin/{{.OS}}/${BINARY}" -editor/create_folder: - mkdir -p editor +winres/winres.json: winres/winres_template.json + sed 's/{{.Version}}/$(VERSION)/g' winres/winres_template.json > $@ + +$(GOBIN)/go-winres: + go install github.com/tc-hib/go-winres@latest -editor/pull_release: editor/create_folder - # if the directory /home/runner/work/editor/editor/build/build exists, we assume that we are are running the makefile within the editor ci workflow - test -d /home/runner/work/editor/editor/build/build && echo "exists" && cd editor && cp -R /home/runner/work/editor/editor/build/build public/ || (echo "does not exist" && cd editor && rm -rf public && curl -L https://github.com/maputnik/editor/releases/download/$(EDITOR_VERSION)/public.zip --output public.zip && unzip public.zip && rm public.zip) +# Copy the current release into ./editor/maputnik so it can be +# embedded in the binary +editor/pull_release: + mkdir -p editor + cp -r ../dist/* editor $(GOBIN)/gox: go install github.com/mitchellh/gox@v1.0.1 @@ -23,9 +29,16 @@ $(GOBIN)/gox: $(GOBIN)/rice: go install github.com/GeertJohan/go.rice/rice@v1.0.3 +# Embed the current version number in the executable by writing version.go +.PHONY: version.go +version.go: + @echo "// DO NOT EDIT: Autogenerated by Makefile\n" > version.go + @echo "package main\n" >> version.go + @echo "const Version = \"$(VERSION)\"" >> version.go + rice-box.go: $(GOBIN)/rice editor/pull_release $(GOBIN)/rice embed-go .PHONY: clean clean: - rm -rf editor/public && rm -f rice-box.go && rm -rf bin + rm -rf editor && rm -f rice-box.go && rm -rf bin diff --git a/desktop/README.md b/desktop/README.md index b6b8baa6..803e840f 100644 --- a/desktop/README.md +++ b/desktop/README.md @@ -1,18 +1,18 @@ -# Maputnik Desktop [![GitHub CI status](https://github.com/maputnik/desktop/workflows/ci/badge.svg)](https://github.com/maputnik/desktop/actions?query=workflow%3Aci) +# Maputnik Desktop [![GitHub CI status](https://github.com/maplibre/maputnik/workflows/ci/badge.svg)][github-action-ci] --- A Golang based cross platform executable for integrating Maputnik locally. -This binary packages up the JavaScript and CSS bundle produced by [maputnik/editor](https://github.com/maputnik/desktop) +This binary packages up the JavaScript and CSS bundle produced by maputnik and embeds it in the program for easy distribution. It also allows exposing a local style file and work on it both in Maputnik and with your favorite editor. -Report issues on [maputnik/editor](https://github.com/maputnik/editor). +Report issues on [maplibre/maputnik](https://github.com/maplibre/maputnik). ## Install -You can download a single binary for Linux, OSX or Windows from [the latest releases of **maputnik/editor**](https://github.com/maputnik/editor/releases/latest). +You can download a zip file containing desktop binaries for Linux, OSX and Windows from [the latest releases of **maplibre/maputnik**](https://github.com/maplibre/maputnik/releases/latest). ### Usage @@ -54,25 +54,20 @@ maputnik --static ./localFolder `maputnik` exposes the configured styles via a HTTP API. -| Method | Description -|---------------------------------|--------------------------------------- -| `GET /styles` | List the ID of all configured style files -| `GET /styles/{filename}` | Get contents of a single style file -| `PUT /styles/{filename}` | Update contents of a style file -| `WEBSOCKET /ws` | Listen to change events for the configured style files +| Method | Description | +| ------------------------ | ------------------------------------------------------ | +| `GET /styles` | List the ID of all configured style files | +| `GET /styles/{filename}` | Get contents of a single style file | +| `PUT /styles/{filename}` | Update contents of a style file | +| `WEBSOCKET /ws` | Listen to change events for the configured style files | ### Build -Clone the repository. Make sure you clone it into the correct directory `$GOPATH/src/github.com/maputnik`. +From the root of the [maplibre/maputnik](https://github.com/maplibre/maputnik) project, install the deps and run the desktop-build command. ``` -git clone git@github.com:maputnik/desktop.git +npm install +npm run build-desktop ``` -Run `make` to install the 3rd party dependencies and build the `maputnik` binary embedding the editor. - -``` -make -``` - -You should now find the `maputnik` binary in your `bin` directory. +You should now find the `maputnik` binary in your `desktop/bin` directory. diff --git a/desktop/maputnik.go b/desktop/maputnik.go index 1442cb44..ee61a1b1 100644 --- a/desktop/maputnik.go +++ b/desktop/maputnik.go @@ -17,7 +17,7 @@ func main() { app := cli.NewApp() app.Name = "maputnik" app.Usage = "Server for integrating Maputnik locally" - app.Version = "Editor: 1.7.0; Desktop: 1.1.0" + app.Version = Version app.Flags = []cli.Flag{ &cli.StringFlag{ @@ -40,7 +40,7 @@ func main() { } app.Action = func(c *cli.Context) error { - gui := http.FileServer(rice.MustFindBox("editor/public").HTTPBox()) + gui := http.FileServer(rice.MustFindBox("editor").HTTPBox()) router := mux.NewRouter().StrictSlash(true) diff --git a/desktop/winres/winres_template.json b/desktop/winres/winres_template.json new file mode 100644 index 00000000..e57ce4de --- /dev/null +++ b/desktop/winres/winres_template.json @@ -0,0 +1,60 @@ +{ + "RT_GROUP_ICON": { + "APP": { + "0000": [ + "../../src/img/maputnik.png" + ] + } + }, + "RT_MANIFEST": { + "#1": { + "0409": { + "identity": { + "name": "Maputnik", + "version": "{{.Version}}" + }, + "description": "A MapLibre GL visual style editor", + "minimum-os": "win7", + "execution-level": "as invoker", + "ui-access": false, + "auto-elevate": false, + "dpi-awareness": "system", + "disable-theming": false, + "disable-window-filtering": false, + "high-resolution-scrolling-aware": false, + "ultra-high-resolution-scrolling-aware": false, + "long-path-aware": false, + "printer-driver-isolation": false, + "gdi-scaling": false, + "segment-heap": false, + "use-common-controls-v6": false + } + } + }, + "RT_VERSION": { + "#1": { + "0000": { + "fixed": { + "file_version": "{{.Version}}", + "product_version": "{{.Version}}" + }, + "info": { + "0409": { + "Comments": "https://github.com/maplibre/maputnik", + "CompanyName": "Maputnik", + "FileDescription": "A MapLibre GL visual style editor", + "FileVersion": "{{.Version}}", + "InternalName": "Maputnik", + "LegalCopyright": "MIT License", + "LegalTrademarks": "", + "OriginalFilename": "Maputnik.exe", + "PrivateBuild": "", + "ProductName": "Maputnik", + "ProductVersion": "{{.Version}}", + "SpecialBuild": "" + } + } + } + } + } +} diff --git a/i18next-parser.config.ts b/i18next-parser.config.ts index 02551f08..7701b911 100644 --- a/i18next-parser.config.ts +++ b/i18next-parser.config.ts @@ -1,6 +1,6 @@ export default { output: 'src/locales/$LOCALE/$NAMESPACE.json', - locales: [ 'ja', 'he','zh' ], + locales: [ 'de', 'fr', 'he', 'ja', 'zh' ], // Because some keys are dynamically generated, i18next-parser can't detect them. // We add these keys manually, so we don't want to remove them. diff --git a/package-lock.json b/package-lock.json index 2231de0c..29f4ef3e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,16 +1,16 @@ { "name": "maputnik", - "version": "2.0.0", + "version": "2.1.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "maputnik", - "version": "2.0.0", + "version": "2.1.1", "license": "MIT", "dependencies": { "@mapbox/mapbox-gl-rtl-text": "^0.2.3", - "@maplibre/maplibre-gl-geocoder": "^1.5.0", + "@maplibre/maplibre-gl-geocoder": "^1.6.0", "@maplibre/maplibre-gl-inspect": "^1.6.3", "@maplibre/maplibre-gl-style-spec": "^20.1.1", "@mdi/js": "^7.4.47", @@ -112,7 +112,7 @@ "stylelint-scss": "^6.2.1", "typescript": "^5.4.3", "uuid": "^9.0.1", - "vite": "^5.2.6", + "vite": "^5.4.6", "vite-plugin-istanbul": "^6.0.0" } }, @@ -1626,20 +1626,21 @@ } }, "node_modules/@maplibre/maplibre-gl-geocoder": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@maplibre/maplibre-gl-geocoder/-/maplibre-gl-geocoder-1.5.0.tgz", - "integrity": "sha512-PsAbV7WFIOu5QYZne95FiXoV7AV1/6ULMjQxgInhZ5DdB0hDLjciQPegnyDgkzI8JfeqoUMZVS/MglZnSZYhyQ==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@maplibre/maplibre-gl-geocoder/-/maplibre-gl-geocoder-1.6.0.tgz", + "integrity": "sha512-SU4cv1P+8ALZlGYLPNvlENadH4zzn8Lw5ajmhbmJgWdC/NzxGFS+u4TITSL8tjzhMFU4jepo42HvNmGtDJjFuQ==", "dependencies": { + "events": "^3.3.0", "lodash.debounce": "^4.0.6", "subtag": "^0.5.0", "suggestions-list": "^0.0.2", "xtend": "^4.0.1" }, "engines": { - "node": ">=6" + "node": ">=18" }, "peerDependencies": { - "maplibre-gl": ">=1.14.0" + "maplibre-gl": ">=4.0.0" } }, "node_modules/@maplibre/maplibre-gl-inspect": { @@ -1766,9 +1767,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.13.0.tgz", - "integrity": "sha512-5ZYPOuaAqEH/W3gYsRkxQATBW3Ii1MfaT4EQstTnLKViLi2gLSQmlmtTpGucNP3sXEpOiI5tdGhjdE111ekyEg==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.21.3.tgz", + "integrity": "sha512-MmKSfaB9GX+zXl6E8z4koOr/xU63AMVleLEa64v7R0QF/ZloMs5vcD1sHgM64GXXS1csaJutG+ddtzcueI/BLg==", "cpu": [ "arm" ], @@ -1779,9 +1780,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.13.0.tgz", - "integrity": "sha512-BSbaCmn8ZadK3UAQdlauSvtaJjhlDEjS5hEVVIN3A4bbl3X+otyf/kOJV08bYiRxfejP3DXFzO2jz3G20107+Q==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.21.3.tgz", + "integrity": "sha512-zrt8ecH07PE3sB4jPOggweBjJMzI1JG5xI2DIsUbkA+7K+Gkjys6eV7i9pOenNSDJH3eOr/jLb/PzqtmdwDq5g==", "cpu": [ "arm64" ], @@ -1792,9 +1793,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.13.0.tgz", - "integrity": "sha512-Ovf2evVaP6sW5Ut0GHyUSOqA6tVKfrTHddtmxGQc1CTQa1Cw3/KMCDEEICZBbyppcwnhMwcDce9ZRxdWRpVd6g==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.21.3.tgz", + "integrity": "sha512-P0UxIOrKNBFTQaXTxOH4RxuEBVCgEA5UTNV6Yz7z9QHnUJ7eLX9reOd/NYMO3+XZO2cco19mXTxDMXxit4R/eQ==", "cpu": [ "arm64" ], @@ -1805,9 +1806,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.13.0.tgz", - "integrity": "sha512-U+Jcxm89UTK592vZ2J9st9ajRv/hrwHdnvyuJpa5A2ngGSVHypigidkQJP+YiGL6JODiUeMzkqQzbCG3At81Gg==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.21.3.tgz", + "integrity": "sha512-L1M0vKGO5ASKntqtsFEjTq/fD91vAqnzeaF6sfNAy55aD+Hi2pBI5DKwCO+UNDQHWsDViJLqshxOahXyLSh3EA==", "cpu": [ "x64" ], @@ -1818,9 +1819,22 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.13.0.tgz", - "integrity": "sha512-8wZidaUJUTIR5T4vRS22VkSMOVooG0F4N+JSwQXWSRiC6yfEsFMLTYRFHvby5mFFuExHa/yAp9juSphQQJAijQ==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.21.3.tgz", + "integrity": "sha512-btVgIsCjuYFKUjopPoWiDqmoUXQDiW2A4C3Mtmp5vACm7/GnyuprqIDPNczeyR5W8rTXEbkmrJux7cJmD99D2g==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.21.3.tgz", + "integrity": "sha512-zmjbSphplZlau6ZTkxd3+NMtE4UKVy7U4aVFMmHcgO5CUbw17ZP6QCgyxhzGaU/wFFdTfiojjbLG3/0p9HhAqA==", "cpu": [ "arm" ], @@ -1831,9 +1845,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.13.0.tgz", - "integrity": "sha512-Iu0Kno1vrD7zHQDxOmvweqLkAzjxEVqNhUIXBsZ8hu8Oak7/5VTPrxOEZXYC1nmrBVJp0ZcL2E7lSuuOVaE3+w==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.21.3.tgz", + "integrity": "sha512-nSZfcZtAnQPRZmUkUQwZq2OjQciR6tEoJaZVFvLHsj0MF6QhNMg0fQ6mUOsiCUpTqxTx0/O6gX0V/nYc7LrgPw==", "cpu": [ "arm64" ], @@ -1844,9 +1858,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.13.0.tgz", - "integrity": "sha512-C31QrW47llgVyrRjIwiOwsHFcaIwmkKi3PCroQY5aVq4H0A5v/vVVAtFsI1nfBngtoRpeREvZOkIhmRwUKkAdw==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.21.3.tgz", + "integrity": "sha512-MnvSPGO8KJXIMGlQDYfvYS3IosFN2rKsvxRpPO2l2cum+Z3exiExLwVU+GExL96pn8IP+GdH8Tz70EpBhO0sIQ==", "cpu": [ "arm64" ], @@ -1856,10 +1870,23 @@ "linux" ] }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.21.3.tgz", + "integrity": "sha512-+W+p/9QNDr2vE2AXU0qIy0qQE75E8RTwTwgqS2G5CRQ11vzq0tbnfBd6brWhS9bCRjAjepJe2fvvkvS3dno+iw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.13.0.tgz", - "integrity": "sha512-Oq90dtMHvthFOPMl7pt7KmxzX7E71AfyIhh+cPhLY9oko97Zf2C9tt/XJD4RgxhaGeAraAXDtqxvKE1y/j35lA==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.21.3.tgz", + "integrity": "sha512-yXH6K6KfqGXaxHrtr+Uoy+JpNlUlI46BKVyonGiaD74ravdnF9BUNC+vV+SIuB96hUMGShhKV693rF9QDfO6nQ==", "cpu": [ "riscv64" ], @@ -1869,10 +1896,23 @@ "linux" ] }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.21.3.tgz", + "integrity": "sha512-R8cwY9wcnApN/KDYWTH4gV/ypvy9yZUHlbJvfaiXSB48JO3KpwSpjOGqO4jnGkLDSk1hgjYkTbTt6Q7uvPf8eg==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.13.0.tgz", - "integrity": "sha512-yUD/8wMffnTKuiIsl6xU+4IA8UNhQ/f1sAnQebmE/lyQ8abjsVyDkyRkWop0kdMhKMprpNIhPmYlCxgHrPoXoA==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.21.3.tgz", + "integrity": "sha512-kZPbX/NOPh0vhS5sI+dR8L1bU2cSO9FgxwM8r7wHzGydzfSjLRCFAT87GR5U9scj2rhzN3JPYVC7NoBbl4FZ0g==", "cpu": [ "x64" ], @@ -1883,9 +1923,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.13.0.tgz", - "integrity": "sha512-9RyNqoFNdF0vu/qqX63fKotBh43fJQeYC98hCaf89DYQpv+xu0D8QFSOS0biA7cGuqJFOc1bJ+m2rhhsKcw1hw==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.21.3.tgz", + "integrity": "sha512-S0Yq+xA1VEH66uiMNhijsWAafffydd2X5b77eLHfRmfLsRSpbiAWiRHV6DEpz6aOToPsgid7TI9rGd6zB1rhbg==", "cpu": [ "x64" ], @@ -1896,9 +1936,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.13.0.tgz", - "integrity": "sha512-46ue8ymtm/5PUU6pCvjlic0z82qWkxv54GTJZgHrQUuZnVH+tvvSP0LsozIDsCBFO4VjJ13N68wqrKSeScUKdA==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.21.3.tgz", + "integrity": "sha512-9isNzeL34yquCPyerog+IMCNxKR8XYmGd0tHSV+OVx0TmE0aJOo9uw4fZfUuk2qxobP5sug6vNdZR6u7Mw7Q+Q==", "cpu": [ "arm64" ], @@ -1909,9 +1949,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.13.0.tgz", - "integrity": "sha512-P5/MqLdLSlqxbeuJ3YDeX37srC8mCflSyTrUsgbU1c/U9j6l2g2GiIdYaGD9QjdMQPMSgYm7hgg0551wHyIluw==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.21.3.tgz", + "integrity": "sha512-nMIdKnfZfzn1Vsk+RuOvl43ONTZXoAPUUxgcU0tXooqg4YrAqzfKzVenqqk2g5efWh46/D28cKFrOzDSW28gTA==", "cpu": [ "ia32" ], @@ -1922,9 +1962,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.13.0.tgz", - "integrity": "sha512-UKXUQNbO3DOhzLRwHSpa0HnhhCgNODvfoPWv2FCXme8N/ANFfhIPMGuOT+QuKd16+B5yxZ0HdpNlqPvTMS1qfw==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.21.3.tgz", + "integrity": "sha512-fOvu7PCQjAj4eWDEuD8Xz5gpzFqXzGlxHZozHP4b9Jxv9APtdxL6STqztDzMLuRXEc4UpXGGhx029Xgm91QBeA==", "cpu": [ "x64" ], @@ -7733,11 +7773,11 @@ } }, "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { @@ -8702,9 +8742,9 @@ "dev": true }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", "dev": true }, "node_modules/picomatch": { @@ -8806,9 +8846,9 @@ } }, "node_modules/postcss": { - "version": "8.4.38", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", - "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "version": "8.4.47", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", + "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", "dev": true, "funding": [ { @@ -8826,8 +8866,8 @@ ], "dependencies": { "nanoid": "^3.3.7", - "picocolors": "^1.0.0", - "source-map-js": "^1.2.0" + "picocolors": "^1.1.0", + "source-map-js": "^1.2.1" }, "engines": { "node": "^10 || ^12 || >=14" @@ -9678,9 +9718,9 @@ } }, "node_modules/rollup": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.13.0.tgz", - "integrity": "sha512-3YegKemjoQnYKmsBlOHfMLVPPA5xLkQ8MHLLSw/fBrFaVkEayL51DilPpNNLq1exr98F2B1TzrV0FUlN3gWRPg==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.21.3.tgz", + "integrity": "sha512-7sqRtBNnEbcBtMeRVc6VRsJMmpI+JU1z9VTvW8D4gXIYQFz0aLcsE6rRkyghZkLfEgUZgVvOG7A5CVz/VW5GIA==", "dev": true, "dependencies": { "@types/estree": "1.0.5" @@ -9693,19 +9733,22 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.13.0", - "@rollup/rollup-android-arm64": "4.13.0", - "@rollup/rollup-darwin-arm64": "4.13.0", - "@rollup/rollup-darwin-x64": "4.13.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.13.0", - "@rollup/rollup-linux-arm64-gnu": "4.13.0", - "@rollup/rollup-linux-arm64-musl": "4.13.0", - "@rollup/rollup-linux-riscv64-gnu": "4.13.0", - "@rollup/rollup-linux-x64-gnu": "4.13.0", - "@rollup/rollup-linux-x64-musl": "4.13.0", - "@rollup/rollup-win32-arm64-msvc": "4.13.0", - "@rollup/rollup-win32-ia32-msvc": "4.13.0", - "@rollup/rollup-win32-x64-msvc": "4.13.0", + "@rollup/rollup-android-arm-eabi": "4.21.3", + "@rollup/rollup-android-arm64": "4.21.3", + "@rollup/rollup-darwin-arm64": "4.21.3", + "@rollup/rollup-darwin-x64": "4.21.3", + "@rollup/rollup-linux-arm-gnueabihf": "4.21.3", + "@rollup/rollup-linux-arm-musleabihf": "4.21.3", + "@rollup/rollup-linux-arm64-gnu": "4.21.3", + "@rollup/rollup-linux-arm64-musl": "4.21.3", + "@rollup/rollup-linux-powerpc64le-gnu": "4.21.3", + "@rollup/rollup-linux-riscv64-gnu": "4.21.3", + "@rollup/rollup-linux-s390x-gnu": "4.21.3", + "@rollup/rollup-linux-x64-gnu": "4.21.3", + "@rollup/rollup-linux-x64-musl": "4.21.3", + "@rollup/rollup-win32-arm64-msvc": "4.21.3", + "@rollup/rollup-win32-ia32-msvc": "4.21.3", + "@rollup/rollup-win32-x64-msvc": "4.21.3", "fsevents": "~2.3.2" } }, @@ -10101,9 +10144,9 @@ } }, "node_modules/source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "engines": { "node": ">=0.10.0" } @@ -11357,14 +11400,14 @@ } }, "node_modules/vite": { - "version": "5.2.6", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.6.tgz", - "integrity": "sha512-FPtnxFlSIKYjZ2eosBQamz4CbyrTizbZ3hnGJlh/wMtCrlp1Hah6AzBLjGI5I2urTfNnpovpHdrL6YRuBOPnCA==", + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.6.tgz", + "integrity": "sha512-IeL5f8OO5nylsgzd9tq4qD2QqI0k2CQLGrWD0rCN0EQJZpBK5vJAx0I+GDkMOXxQX/OfFHMuLIx6ddAxGX/k+Q==", "dev": true, "dependencies": { - "esbuild": "^0.20.1", - "postcss": "^8.4.36", - "rollup": "^4.13.0" + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" }, "bin": { "vite": "bin/vite.js" @@ -11383,6 +11426,7 @@ "less": "*", "lightningcss": "^1.21.0", "sass": "*", + "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.4.0" @@ -11400,6 +11444,9 @@ "sass": { "optional": true }, + "sass-embedded": { + "optional": true + }, "stylus": { "optional": true }, @@ -11482,6 +11529,412 @@ "node": ">= 8" } }, + "node_modules/vite/node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, "node_modules/void-elements": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", diff --git a/package.json b/package.json index dc8858ff..fd307127 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,13 @@ { "name": "maputnik", - "version": "2.0.0", + "version": "2.1.1", "description": "A MapLibre GL visual style editor", "type": "module", "main": "''", "scripts": { "start": "vite", "build": "tsc && vite build --base=/maputnik/", + "build-desktop": "tsc && vite build --base=/ && cd desktop && make", "i18n:refresh": "i18next 'src/**/*.{ts,tsx,js,jsx}'", "lint": "eslint ./src ./cypress --ext ts,tsx,js,jsx --report-unused-disable-directives --max-warnings 0", "test": "cypress run", @@ -23,7 +24,7 @@ "homepage": "https://github.com/maplibre/maputnik#readme", "dependencies": { "@mapbox/mapbox-gl-rtl-text": "^0.2.3", - "@maplibre/maplibre-gl-geocoder": "^1.5.0", + "@maplibre/maplibre-gl-geocoder": "^1.6.0", "@maplibre/maplibre-gl-inspect": "^1.6.3", "@maplibre/maplibre-gl-style-spec": "^20.1.1", "@mdi/js": "^7.4.47", @@ -142,7 +143,7 @@ "stylelint-scss": "^6.2.1", "typescript": "^5.4.3", "uuid": "^9.0.1", - "vite": "^5.2.6", + "vite": "^5.4.6", "vite-plugin-istanbul": "^6.0.0" } } diff --git a/src/components/AppToolbar.tsx b/src/components/AppToolbar.tsx index 30eb4497..6765be44 100644 --- a/src/components/AppToolbar.tsx +++ b/src/components/AppToolbar.tsx @@ -230,7 +230,7 @@ class AppToolbarInternal extends React.Component { - + - + diff --git a/src/components/MapMaplibreGl.tsx b/src/components/MapMaplibreGl.tsx index 6a987ca5..87a2ad23 100644 --- a/src/components/MapMaplibreGl.tsx +++ b/src/components/MapMaplibreGl.tsx @@ -11,10 +11,10 @@ import { HighlightedLayer, colorHighlightedLayer } from '../libs/highlight' import 'maplibre-gl/dist/maplibre-gl.css' import '../maplibregl.css' import '../libs/maplibre-rtl' -//@ts-ignore -import MaplibreGeocoder from '@maplibre/maplibre-gl-geocoder'; +import MaplibreGeocoder, { MaplibreGeocoderApi, MaplibreGeocoderApiConfig } from '@maplibre/maplibre-gl-geocoder'; import '@maplibre/maplibre-gl-geocoder/dist/maplibre-gl-geocoder.css'; import { withTranslation, WithTranslation } from 'react-i18next' +import i18next from 'i18next' function renderPopup(popup: JSX.Element, mountNode: ReactDOM.Container): HTMLElement { ReactDOM.render(popup, mountNode); @@ -68,9 +68,11 @@ type MapMaplibreGlInternalProps = { } & WithTranslation; type MapMaplibreGlState = { - map: Map | null - inspect: MaplibreInspect | null - zoom?: number + map: Map | null; + inspect: MaplibreInspect | null; + geocoder: MaplibreGeocoder | null; + zoomControl: ZoomControl | null; + zoom?: number; }; class MapMaplibreGlInternal extends React.Component { @@ -88,7 +90,12 @@ class MapMaplibreGlInternal extends React.Component { + this.forceUpdate(); + }) } @@ -126,6 +133,7 @@ class MapMaplibreGlInternal extends React.Component { + forwardGeocode: async (config: MaplibreGeocoderApiConfig) => { const features = []; try { const request = `https://nominatim.openstreetmap.org/search?q=${config.query}&format=geojson&polygon_geojson=1&addressdetails=1`; @@ -255,17 +265,20 @@ class MapMaplibreGlInternal extends React.Component - `; - this._textEl = this._container.querySelector("span"); - + this.setLabel("Zoom:"); this.addEventListeners(); return this._container; @@ -25,6 +21,14 @@ export default class ZoomControl { updateZoomLevel() { this._textEl!.innerHTML = this._map!.getZoom().toFixed(2); } + + setLabel(label: string) { + this._container!.innerHTML = ` + ${label} + `; + this._textEl = this._container!.querySelector("span"); + this.updateZoomLevel(); + } addEventListeners (){ this._map!.on('render', () => this.updateZoomLevel()); diff --git a/src/locales/README.md b/src/locales/README.md new file mode 100644 index 00000000..6e456701 --- /dev/null +++ b/src/locales/README.md @@ -0,0 +1,60 @@ +## Internationalization + +The process of internationlization is pretty straight forward for Maputnik. + +## Add a new language + +#### 1. Edit configuration + +In order to add a new translation you'll need to add it to the configuration files. Please put it in alphabetical order. + +- Open [/i18next-parser.config.ts](/i18next-parser.config.ts) and add the ISO Code of your language to the `locales` array. +- Now, open [/src/i18n.ts](/src/i18n.ts) and add the ISO Code and localized name to the supported languages. + +#### 2. Add the localized strings + +Refresh the localization to generate a new directory under `/src/locales/` for your new language. + +```bash +npm install +npm run i18n:refresh +``` + +Replace every `__STRING_NOT_TRANSLATED__` value in the newly generated `translation.json` file with the according translation. +Make sure all the keys are translated. + +#### 3. Test your new locale + +Finally, test your language locally by starting a local instance of Maputnik. + +```bash +npm run start +``` + +Consider adding your name as a helping person for the translation of new features. + +## Add localization for a new feature + +If you happen to add a feature which needs some text to be translated, update the translation files. +After running, check your working copy for files and add/correct as needed. + +```bash +npm run i18n:refresh +``` + +The following users can help you with the relevant languages: + +| ISO Code | Language | User | +|----------|--------------------|--------------------------------------------| +| de | German | [@josxha](https://github.com/josxha) | +| en | English | [@HarelM](https://github.com/HarelM) | +| fr | French | [@lhapaipai](https://github.com/lhapaipai) | +| hr | Hebrew | [@HarelM](https://github.com/HarelM) | +| ja | Japanese | [@keichan34](https://github.com/keichan34) | +| zh | Simplified Chinese | [@jieme](https://github.com/jieme) | + +You can test the UI in different languages using the dropdown in the top menu +Note that Maputnik automatically localize based on browser language settings and stores this language in local storage. +You can use incognito mode to check a first time usage. + + diff --git a/src/locales/de/translation.json b/src/locales/de/translation.json new file mode 100644 index 00000000..f7f88f22 --- /dev/null +++ b/src/locales/de/translation.json @@ -0,0 +1,185 @@ +{ + "Input value": "Eingabewert", + "Data value": "Datenwert", + "Output value": "Ausgabewert", + "Function": "Funktion", + "Select a type of data scale (default is 'categorical').": "Wähle eine Art Datenskala (Standard ist 'kategorisch').", + "Base": "Basis", + "Input a data property to base styles off of.": "Gib eine Dateneigenschaft ein, um Stile darauf zu basieren.", + "Default": "Standard", + "Stops": "Stopps", + "Zoom": "Zoom", + "Add stop": "Stopp hinzufügen", + "Convert to expression": "In Ausdruck umwandeln", + "Remove zoom level from stop": "Zoom-Stufe vom Stopp entfernen", + "Revert from expression": "Vom Ausdruck zurücksetzen", + "Delete expression": "Ausdruck löschen", + "Convert property into a zoom function": "Eigenschaft in eine Zoom-Funktion umwandeln", + "Convert property to data function": "Eigenschaft in eine Datenfunktion umwandeln", + "Layer <1>{formatLayerId(layerId)}: {parsed.data.message}": "Ebene <1>{formatLayerId(layerId)}: {parsed.data.message}", + "switch to layer": "zur Ebene wechseln", + "Map": "Karte", + "Inspect": "Untersuchen", + "Deuteranopia filter": "Deuteranopie-Filter", + "Protanopia filter": "Protanopie-Filter", + "Tritanopia filter": "Tritanopie-Filter", + "Achromatopsia filter": "Achromatopsie-Filter", + "Layers list": "Ebenenliste", + "Layer editor": "Ebenen-Editor", + "Map view": "Kartenansicht", + "Maputnik on GitHub": "Maputnik auf GitHub", + "Open": "Öffnen", + "Export": "Exportieren", + "Data Sources": "Datenquellen", + "Style Settings": "Stileinstellungen", + "View": "Ansicht", + "Color accessibility": "Farbzugänglichkeit", + "Help": "Hilfe", + "Comments for the current layer. This is non-standard and not in the spec.": "Kommentare zur aktuellen Ebene. Das ist nicht standardmäßig und nicht in der Spezifikation.", + "Comments": "Kommentare", + "Comment...": "Dein Kommentar...", + "Max Zoom": "Max-Zoom", + "Min Zoom": "Min-Zoom", + "Source": "Quelle", + "Source Layer": "Quellenebene", + "Type": "Typ", + "Nested filters are not supported.": "Verschachtelte Filter werden nicht unterstützt.", + "Upgrade to expression": "Aufrüsten zu Ausdruck", + "Filter": "Filter", + "every filter matches": "alle Filter passen", + "no filter matches": "kein Filter passt", + "any filter matches": "irgendein Filter passt", + "Add filter": "Filter hinzufügen", + "You've entered an old style filter.": "Du hast einen alten Filter-Stil eingegeben.", + "Switch to filter editor.": "Zum Filter-Editor wechseln.", + "Delete filter block": "Filterblock löschen", + "Add value": "Wert hinzufügen", + "Remove array item": "Element aus Array entfernen", + "Press <1>ESC to lose focus": "Drück <1>ESC, um den Fokus zu verlieren", + "Must provide protocol: <1>https://": "Protokoll erforderlich: <1>https://", + "Must provide protocol: <1>http:// or <3>https://": "Protokoll erforderlich: <1>http:// oder <3>https://", + "CORS policy won't allow fetching resources served over http from https, use a <1>https:// domain": "Die CORS-Politik erlaubt es nicht, Ressourcen über http von https zu laden, benutze eine <1>https://-Domain", + "Layer": "Ebene", + "JSON Editor": "JSON-Editor", + "Delete": "Löschen", + "Duplicate": "Duplizieren", + "Show": "Anzeigen", + "Hide": "Verstecken", + "Move layer up": "Ebene nach oben verschieben", + "Move layer down": "Ebene nach unten verschieben", + "Layer: {{layerId}}": "Ebene: {{layerId}}", + "Layers": "Ebenen", + "Collapse": "Einklappen", + "Expand": "Ausklappen", + "Add Layer": "Ebene hinzufügen", + "Search": "Suche", + "Zoom:": "Zoom:", + "Close popup": "Popup schließen", + "cursor:": "Mauszeiger:", + "center:": "Zentrum:", + "rotation:": "Rotation:", + "Close modal": "Modale Fenster schließen", + "Debug": "Debug", + "Options": "Optionen", + "<0>Open in OSM — Opens the current view on openstreetmap.org": "<0>In OSM öffnen — Öffnet die aktuelle Ansicht auf openstreetmap.org", + "Export Style": "Stil exportieren", + "Download Style": "Stil herunterladen", + "Download a JSON style to your computer.": "Lade einen JSON-Stil auf deinen Computer herunter.", + "Download HTML": "HTML herunterladen", + "Cancel": "Abbrechen", + "Open Style": "Stil öffnen", + "Upload Style": "Stil hochladen", + "Upload a JSON style from your computer.": "Lade einen JSON-Stil von deinem Computer hoch.", + "Style file": "Stildatei", + "Upload": "Hochladen", + "Load from URL": "Von URL laden", + "Load from a URL. Note that the URL must have <1>CORS enabled.": "Von einer URL laden. Beachte, dass die URL <1>CORS aktiviert haben muss.", + "Style URL": "Stil-URL", + "Enter URL...": "URL eingeben...", + "Gallery Styles": "Galerie-Stile", + "Open one of the publicly available styles to start from.": "Öffne einen der öffentlich verfügbaren Stile, um zu starten.", + "Loading style": "Stil wird geladen", + "Loading: {{requestUrl}}": "Lädt: {{requestUrl}}", + "Name": "Name", + "Owner": "Besitzer", + "Owner ID of the style. Used by Mapbox or future style APIs.": "Besitzer-ID des Stils. Wird von Mapbox oder zukünftigen Style-APIs verwendet.", + "Sprite URL": "Sprite-URL", + "Glyphs URL": "Glyphen-URL", + "Center": "Mittelpunkt", + "Bearing": "Ausrichtung", + "Pitch": "Neigung", + "Light anchor": "Lichtanker", + "Light color": "Lichtfarbe", + "Light intensity": "Lichtintensität", + "Light position": "Lichtposition", + "Terrain source": "Geländequelle", + "Terrain exaggeration": "Gelände-Übertreibung", + "Transition delay": "Übergangsverzögerung", + "Transition duration": "Übergangsdauer", + "Open Layers (experimental)": "Ebenen öffnen (experimentell)", + "Shortcuts menu": "Shortcuts-Menü", + "Open modal": "Modale Fenster öffnen", + "Export modal": "Modale Fenster exportieren", + "Data Sources modal": "Modale Datenquellen", + "Style Settings modal": "Modale Stileinstellungen", + "Toggle inspect": "Inspektion umschalten", + "Focus map": "Karte fokussieren", + "Debug modal": "Debug (modale Fenster)", + "Increase the zoom level by 1.": "Zoom-Stufe um 1 erhöhen.", + "Increase the zoom level by 2.": "Zoom-Stufe um 2 erhöhen.", + "Decrease the zoom level by 1.": "Zoom-Stufe um 1 verringern.", + "Decrease the zoom level by 2.": "Zoom-Stufe um 2 verringern.", + "Pan up by 100 pixels.": "Um 100 Pixel nach oben schwenken.", + "Pan down by 100 pixels.": "Um 100 Pixel nach unten schwenken.", + "Pan left by 100 pixels.": "Um 100 Pixel nach links schwenken.", + "Pan right by 100 pixels.": "Um 100 Pixel nach rechts schwenken.", + "Increase the rotation by 15 degrees.": "Rotation um 15 Grad erhöhen.", + "Decrease the rotation by 15 degrees.": "Rotation um 15 Grad verringern.", + "Increase the pitch by 10 degrees.": "Neigung um 10 Grad erhöhen.", + "Decrease the pitch by 10 degrees.": "Neigung um 10 Grad verringern.", + "Shortcuts": "Shortcuts", + "Press <1>ESC to lose focus of any active elements, then press one of:": "Drück <1>ESC, um den Fokus von aktiven Elementen zu verlieren, und dann drück eine der folgenden Tasten:", + "If the Map is in focused you can use the following shortcuts": "Wenn die Karte fokussiert ist, kannst du die folgenden Shortcuts benutzen", + "Remove '{{sourceId}}' source": "Quelle '{{sourceId}}' entfernen", + "Source ID": "Quellen-ID", + "Unique ID that identifies the source and is used in the layer to reference the source.": "Eindeutige ID, die die Quelle identifiziert und in der Ebene verwendet wird, um auf die Quelle zu verweisen.", + "Source Type": "Quellentyp", + "GeoJSON (JSON)": "GeoJSON (JSON)", + "GeoJSON (URL)": "GeoJSON (URL)", + "Vector (TileJSON URL)": "Vektor (TileJSON URL)", + "Vector (XYZ URLs)": "Vektor (XYZ URLs)", + "Raster (TileJSON URL)": "Raster (TileJSON URL)", + "Raster (XYZ URL)": "Raster (XYZ URL)", + "Raster DEM (TileJSON URL)": "Raster DEM (TileJSON URL)", + "Raster DEM (XYZ URLs)": "Raster DEM (XYZ URLs)", + "Image": "Bild", + "Video": "Video", + "Add Source": "Quelle hinzufügen", + "Sources": "Quellen", + "Active Sources": "Aktive Quellen", + "Choose Public Source": "Öffentliche Quelle auswählen", + "Add one of the publicly available sources to your style.": "Füge eine der öffentlich verfügbaren Quellen zu deinem Stil hinzu.", + "Add New Source": "Neue Quelle hinzufügen", + "Add a new source to your style. You can only choose the source type and id at creation time!": "Füge eine neue Quelle zu deinem Stil hinzu. Du kannst den Quellentyp und die ID nur bei der Erstellung auswählen!", + "TileJSON URL": "TileJSON URL", + "Tile URL": "Kachel-URL", + "Coord top left": "Koordinate oben links", + "Coord top right": "Koordinate oben rechts", + "Coord bottom right": "Koordinate unten rechts", + "Coord bottom left": "Koordinate unten links", + "Image URL": "Bild-URL", + "Video URL": "Video-URL", + "GeoJSON URL": "GeoJSON URL", + "GeoJSON": "GeoJSON", + "Cluster": "Cluster", + "Encoding": "Kodierung", + "Error:": "Fehler:", + "MapTiler Access Token": "MapTiler Zugriffstoken", + "Public access token for MapTiler Cloud.": "Öffentlicher Zugriffstoken für MapTiler Cloud.", + "Thunderforest Access Token": "Thunderforest Zugriffstoken", + "Public access token for Thunderforest services.": "Öffentlicher Zugriffstoken für Thunderforest-Dienste.", + "Style Renderer": "Stil-Renderer", + "Choose the default Maputnik renderer for this style.": "Wähle den Standard-Renderer für diesen Stil aus.", + "Language": "Sprache", + "Press <1>ESC to lose focus of any input box": "Drück <1>ESC, um den Fokus von jedem Eingabefeld zu verlieren" +} diff --git a/src/locales/fr/translation.json b/src/locales/fr/translation.json new file mode 100644 index 00000000..6852a3e0 --- /dev/null +++ b/src/locales/fr/translation.json @@ -0,0 +1,192 @@ +{ + "Input value": "Valeur d'entrée", + "Data value": "Valeur des données", + "Output value": "Valeur de sortie", + "Function": "Fonction", + "Select a type of data scale (default is 'categorical').": "Sélectionnez un type d'échelle de données (par défaut 'categorical').", + "Base": "Base", + "Input a data property to base styles off of.": "Entrez une propriété de données pour baser les styles.", + "Default": "Par défaut", + "Stops": "Arrêts", + "Zoom": "Zoom", + "Add stop": "Ajouter un arrêt", + "Convert to expression": "Convertir en expression", + "Remove zoom level from stop": "Supprimer le niveau de zoom de l'arrêt", + "Revert from expression": "Annuler l'expression", + "Delete expression": "Supprimer l'expression", + "Convert property into a zoom function": "Convertir la propriété en fonction de zoom", + "Convert property to data function": "Convertir la propriété en fonction de données", + "Layer <1>{formatLayerId(layerId)}: {parsed.data.message}": "Calque <1>{formatLayerId(layerId)} : {parsed.data.message}", + "switch to layer": "changer de calque", + "Map": "Carte", + "Inspect": "Inspecter", + "Deuteranopia filter": "Filtre Deutéranopie", + "Protanopia filter": "Filtre Protanopie", + "Tritanopia filter": "Filtre Tritanopie", + "Achromatopsia filter": "Filtre Achromatopsie", + "Layers list": "Liste des calques", + "Layer editor": "Éditeur de calque", + "Map view": "Vue de la carte", + "Maputnik on GitHub": "Maputnik sur GitHub", + "Open": "Ouvrir", + "Export": "Exporter", + "Data Sources": "Sources de données", + "Style Settings": "Paramètres du style", + "View": "Vue", + "Color accessibility": "Accessibilité des couleurs", + "Language": "Langue", + "Help": "Aide", + "Comments for the current layer. This is non-standard and not in the spec.": "Commentaires pour le calque actuel. Ceci n'est pas standard et n'est pas dans la spécification.", + "Comments": "Commentaires", + "Comment...": "Votre commentaire...", + "Max Zoom": "Zoom max", + "Min Zoom": "Zoom min", + "Source": "Source", + "Source Layer": "Calque Source", + "Type": "Type", + "Nested filters are not supported.": "Les filtres imbriqués ne sont pas pris en charge.", + "Upgrade to expression": "Mettre à niveau vers une expression", + "Filter": "Filtre", + "every filter matches": "tous les filtres correspondent", + "no filter matches": "aucun filtre ne correspond", + "any filter matches": "l'un des filtres correspond", + "Add filter": "Ajouter un filtre", + "You've entered an old style filter.": "Vous avez entré un ancien style de filtre.", + "Switch to filter editor.": "Passer à l'éditeur de filtre.", + "Delete filter block": "Supprimer le bloc de filtre", + "Add value": "Ajouter une valeur", + "Remove array item": "Supprimer l'élément de tableau", + "Press <1>ESC to lose focus": "Appuyez sur <1>Échap pour perdre le focus", + "Must provide protocol: <1>https://": "Protocole requis : <1>https://", + "Must provide protocol: <1>http:// or <3>https://": "Protocole requis : <1>http:// ou <3>https://", + "CORS policy won't allow fetching resources served over http from https, use a <1>https:// domain": "La politique CORS ne permet pas de récupérer des ressources servies sur http depuis https, utilisez un protocole <1>https://", + "Layer": "Calque", + "JSON Editor": "Éditeur JSON", + "Delete": "Supprimer", + "Duplicate": "Dupliquer", + "Show": "Afficher", + "Hide": "Cacher", + "Move layer up": "Monter le calque", + "Move layer down": "Descendre le calque", + "Layer: {{layerId}}": "Calque : {{layerId}}", + "Layers": "Calques", + "Collapse": "Réduire", + "Expand": "Développer", + "Add Layer": "Ajouter un calque", + "Zoom:": "Zoom :", + "Search": "Recherche", + "Close popup": "Fermer la fenêtre", + "cursor:": "curseur :", + "center:": "centre :", + "rotation:": "rotation :", + "Close modal": "Fermer la fenêtre modale", + "Debug": "Déboguer", + "Options": "Options", + "<0>Open in OSM — Opens the current view on openstreetmap.org": "<0>Ouvrir dans OSM — Ouvre la vue actuelle sur openstreetmap.org", + "Export Style": "Exporter le style", + "Download Style": "Télécharger le style", + "Download a JSON style to your computer.": "Téléchargez un style JSON sur votre ordinateur.", + "Download HTML": "Télécharger HTML", + "Cancel": "Annuler", + "Open Style": "Ouvrir le style", + "Upload Style": "Transférer un style", + "Upload a JSON style from your computer.": "Transférer un style JSON depuis votre ordinateur.", + "Style file": "Fichier de style", + "Upload": "Transférer", + "Load from URL": "Charger depuis une URL", + "Load from a URL. Note that the URL must have <1>CORS enabled.": "Charger depuis une URL. Notez que l'URL doit avoir les <1>CORS activés.", + "Style URL": "URL du style", + "Enter URL...": "Entrez l'URL...", + "Gallery Styles": "Styles de la galerie", + "Open one of the publicly available styles to start from.": "Ouvrez l'un des styles publics disponibles pour commencer.", + "Loading style": "Chargement du style", + "Loading: {{requestUrl}}": "Chargement : {{requestUrl}}", + "Name": "Nom", + "Owner": "Propriétaire", + "Owner ID of the style. Used by Mapbox or future style APIs.": "ID du propriétaire du style. Utilisé par Mapbox ou les futures API de style.", + "Sprite URL": "URL du sprite", + "Glyphs URL": "URL des glyphes", + "Center": "Centre", + "Bearing": "Orientation", + "Pitch": "Inclinaison", + "Light anchor": "Ancrage de la lumière", + "Light color": "Couleur de la lumière", + "Light intensity": "Intensité de la lumière", + "Light position": "Position de la lumière", + "Terrain source": "Source du terrain", + "Terrain exaggeration": "Exagération du terrain", + "Transition delay": "Délai de transition", + "Transition duration": "Durée de transition", + "Open Layers (experimental)": "Open Layers (expérimental)", + "Shortcuts menu": "Menu des raccourcis", + "Open modal": "Ouvrir (modale)", + "Export modal": "Exporter (modale)", + "Data Sources modal": "Sources de données (modale)", + "Style Settings modal": "Paramètres de style (modale)", + "Toggle inspect": "Activer/désactiver l'inspection", + "Focus map": "Focus sur la carte", + "Debug modal": "Déboguer (modale)", + "Increase the zoom level by 1.": "Augmenter le niveau de zoom de 1.", + "Increase the zoom level by 2.": "Augmenter le niveau de zoom de 2.", + "Decrease the zoom level by 1.": "Diminuer le niveau de zoom de 1.", + "Decrease the zoom level by 2.": "Diminuer le niveau de zoom de 2.", + "Pan up by 100 pixels.": "Déplacer vers le haut de 100 pixels.", + "Pan down by 100 pixels.": "Déplacer vers le bas de 100 pixels.", + "Pan left by 100 pixels.": "Déplacer vers la gauche de 100 pixels.", + "Pan right by 100 pixels.": "Déplacer vers la droite de 100 pixels.", + "Increase the rotation by 15 degrees.": "Augmenter l'angle de rotation de 15 degrés.", + "Decrease the rotation by 15 degrees.": "Diminuer l'angle de rotation de 15 degrés.", + "Increase the pitch by 10 degrees.": "Augmenter l'inclinaison de 10 degrés.", + "Decrease the pitch by 10 degrees.": "Diminuer l'inclinaison de 10 degrés.", + "Shortcuts": "Raccourcis", + "Press <1>ESC to lose focus of any active elements, then press one of:": "Appuyez sur <1>Échap pour perdre le focus des éléments actifs, puis appuyez sur l'un des éléments suivants :", + "If the Map is in focused you can use the following shortcuts": "Si la carte a le focus, vous pouvez utiliser les raccourcis suivants", + "Remove '{{sourceId}}' source": "Supprimer la source '{{sourceId}}'", + "Source ID": "ID de la source", + "Unique ID that identifies the source and is used in the layer to reference the source.": "ID unique qui identifie la source et est utilisé dans le calque pour référencer la source.", + "Source Type": "Type de source", + "GeoJSON (JSON)": "GeoJSON (JSON)", + "GeoJSON (URL)": "GeoJSON (URL)", + "Vector (TileJSON URL)": "Vecteur (URL TileJSON)", + "Vector (XYZ URLs)": "Vecteur (URLs XYZ)", + "Raster (TileJSON URL)": "Raster (URL TileJSON)", + "Raster (XYZ URL)": "Raster (URL XYZ)", + "Raster DEM (TileJSON URL)": "Raster DEM (URL TileJSON)", + "Raster DEM (XYZ URLs)": "Raster DEM (URLs XYZ)", + "Image": "Image", + "Video": "Vidéo", + "Add Source": "Ajouter une source", + "Sources": "Sources", + "Active Sources": "Sources actives", + "Choose Public Source": "Choisir une source publique", + "Add one of the publicly available sources to your style.": "Ajoutez l'une des sources publiques disponibles à votre style.", + "Add New Source": "Ajouter une nouvelle source", + "Add a new source to your style. You can only choose the source type and id at creation time!": "Ajoutez une nouvelle source à votre style. Vous ne pouvez choisir le type et l'ID de la source qu'au moment de la création !", + "TileJSON URL": "URL TileJSON", + "Tile URL": "URL de la tuile", + "Coord top left": "Coordonnée en haut à gauche", + "Coord top right": "Coordonnée en haut à droite", + "Coord bottom right": "Coordonnée en bas à droite", + "Coord bottom left": "Coordonnée en bas à gauche", + "Image URL": "URL de l'image", + "Video URL": "URL de la vidéo", + "GeoJSON URL": "URL GeoJSON", + "GeoJSON": "GeoJSON", + "Cluster": "Cluster", + "Encoding": "Encodage", + "Error:": "Erreur :", + "MapTiler Access Token": "Jeton d'accès MapTiler", + "Public access token for MapTiler Cloud.": "Jeton d'accès public pour MapTiler Cloud.", + "Thunderforest Access Token": "Jeton d'accès Thunderforest", + "Public access token for Thunderforest services.": "Jeton d'accès public pour les services Thunderforest.", + "Style Renderer": "Moteur de rendu pour le style", + "Choose the default Maputnik renderer for this style.": "Choisissez le moteur de rendu Maputnik par défaut pour ce style.", + "Layer options": "Options du calque", + "Paint properties": "Propriétés de peinture", + "Layout properties": "Propriétés de mise en page", + "General layout properties": "Propriétés générales de mise en page", + "Text layout properties": "Propriétés de mise en page du texte", + "Icon layout properties": "Propriétés de mise en page de l'icône", + "Text paint properties": "Propriétés de peinture du texte", + "Icon paint properties": "Propriétés de peinture de l'icône" +} diff --git a/src/styles/_export.scss b/src/styles/_export.scss index ce000ec0..d14e0f3c 100644 --- a/src/styles/_export.scss +++ b/src/styles/_export.scss @@ -10,7 +10,7 @@ } input.maputnik-string { - margin-left: 5px; + margin: 0 5px; width: 60%; display: inline-block; } diff --git a/src/styles/_filtereditor.scss b/src/styles/_filtereditor.scss index f2219ded..b8d4fd7d 100644 --- a/src/styles/_filtereditor.scss +++ b/src/styles/_filtereditor.scss @@ -18,7 +18,7 @@ } .maputnik-filter-editor-operator { - margin-left: 2%; + margin: 0 2%; display: inline-block; width: 17%; @@ -30,7 +30,7 @@ .maputnik-filter-editor-args { display: inline-block; width: 54%; - margin-left: 2%; + margin: 0 2%; .maputnik-string, .maputnik-number { diff --git a/src/styles/_input.scss b/src/styles/_input.scss index 5af49891..e6e5b890 100644 --- a/src/styles/_input.scss +++ b/src/styles/_input.scss @@ -107,6 +107,9 @@ height: 24px; } +[dir="rtl"] .maputnik-select { + background: $color-gray url("#{$icon-down-arrow}") left center no-repeat; +} // MULTIBUTTON .maputnik-multibutton { diff --git a/src/styles/_layer.scss b/src/styles/_layer.scss index 5dc9bf36..bba1b881 100644 --- a/src/styles/_layer.scss +++ b/src/styles/_layer.scss @@ -178,7 +178,7 @@ } &-group-content { - margin-left: $margin-3; + margin: 0 $margin-3; } } diff --git a/src/styles/_popup.scss b/src/styles/_popup.scss index a500efb5..91f104fa 100644 --- a/src/styles/_popup.scss +++ b/src/styles/_popup.scss @@ -22,7 +22,7 @@ .maputnik-popup-layer-id { padding-left: $margin-2; - padding-right: 1.6em; + padding-right: $margin-2; background-color: $color-midgray; color: $color-white; } @@ -33,6 +33,7 @@ .maputnik-input-block { margin: 0; margin-left: $margin-2; + margin-right: $margin-2; margin-top: $margin-2; } } @@ -44,4 +45,5 @@ .maputnik-popup-table-cell { color: $color-lowgray; padding-left: $margin-2; + padding-right: $margin-2; } diff --git a/src/styles/_toolbar.scss b/src/styles/_toolbar.scss index 7d515f96..7ca45914 100644 --- a/src/styles/_toolbar.scss +++ b/src/styles/_toolbar.scss @@ -87,7 +87,7 @@ .maputnik-toolbar-version { font-size: 10px; - margin-left: 4px; + margin: 0 4px; white-space: nowrap; } @@ -103,7 +103,7 @@ @extend .maputnik-toolbar-link; /* stylelint-disable-line */ select { - margin-left: 6px; + margin: 0 6px; border-width: 0; display: inline; width: auto; @@ -114,12 +114,12 @@ } .maputnik-icon-text { - padding-left: $margin-1; + padding: 0 $margin-1; } .maputnik-icon-action { display: inline; - margin-left: $margin-1; + margin: 0 $margin-1; } .maputnik-toolbar__inner { diff --git a/src/styles/index.scss b/src/styles/index.scss index 865cf994..29dad048 100644 --- a/src/styles/index.scss +++ b/src/styles/index.scss @@ -102,8 +102,7 @@ &:not(:first-child) { - padding-top: $margin-1; - padding-left: $margin-2; + padding: $margin-1; } &:nth-child(1) {