comaps/comaps
42
1.9k
Fork
You've already forked comaps
161

Add support for generating context-free translation files #4433

Merged
pastk merged 5 commits from hackintosh5/comaps:patch-8 into main 2026年07月01日 12:18:23 +02:00

Per #4419, we need a way of handling context for translations.

This adds a script to convert translation files at compile time. This means that we can use Format.JS files which support storing descriptions in the <key>.description JSON key, and it will correspond with the <key>.defaultMessage translation value.

Example usage:

"unknown_camera": {
"defaultMessage": "Speed camera ahead",
"description": "TEST"
} 

image

No generative AI used.


I have linted the shell scripts with shellcheck and it's all false positives or preexisting warnings:

⬢ [toolbx comaps]$ shellcheck -o all migrate.sh 
⬢ [toolbx comaps]$ shellcheck -o all tools/unix/generate_json_strings.sh 
In tools/unix/generate_json_strings.sh line 19:
find translations/ -type f -name 'localize.json' -print0 | xargs -P"${JOBS}" -0 -I'{}' bash -c '
 ^-- SC2016 (info): Expressions don't expand in single quotes, use double quotes for that.
In tools/unix/generate_json_strings.sh line 21:
jq -c '"'"'map_values(.defaultMessage)'"'"' "1ドル" > "$(echo "1ドル" | sed "s|^translations/|data/|")"
 ^-- SC2016 (info): Expressions don't expand in single quotes, use double quotes for that.
For more information:
 https://www.shellcheck.net/wiki/SC2016 -- Expressions don't expand in singl...
⬢ [toolbx comaps]$ shellcheck -o all configure.sh 
... lots of style warnings that were already there
⬢ [toolbx comaps]$ 

Performance:

⬢ [toolbx comaps]$ time tools/unix/generate_json_strings.sh 
Starting...
Finished
real	0m0.485s
user	0m1.704s
sys	0m2.131s

Tested no regressions (~/comapsdata is post-migration and post generate_json_strings.sh, ~/comaps/data has a checkout of main):

⬢ [toolbx data]$ pwd
~/comaps/data
⬢ [toolbx data]$ head -c50 ~/comapsdata/categories-strings/ar.json/localize.json; echo
{"@category_eat":"طعام|مكان لتناول �
⬢ [toolbx data]$ head -c50 categories-strings/ar.json/localize.json; echo
{
"@category_eat": "طعام|مكان لتناول
⬢ [toolbx data]$ head -c50 ~/comapsdata/categories-strings/zh-Hans.json/localize.json; echo
{"@category_eat":"在哪儿吃|食物","@category_
⬢ [toolbx data]$ head -c50 categories-strings/zh-Hans.json/localize.json; echo
{
"@category_eat": "在哪儿吃|食物",
"@catego
⬢ [toolbx data]$ head -c50 ~/comapsdata/categories-strings/en.json/localize.json; echo
{"@category_eat":"Where to eat|eat|Food","@categor
⬢ [toolbx data]$ head -c50 categories-strings/en.json/localize.json; echo
{
"@category_eat": "Where to eat|eat|Food",
"@cate
⬢ [toolbx data]$ find *-strings -type f -exec bash -c 'diff <(jq . {}) <(jq . ~/comapsdata/{})' \;
⬢ [toolbx data]$ find *-strings -type l -exec bash -c 'diff <(jq . {}) <(jq . ~/comapsdata/{})' \;
⬢ [toolbx data]$ cd ~/comapsdata
⬢ [toolbx comapsdata]$ find *-strings -type f -exec bash -c 'diff <(jq . {}) <(jq . ~/comaps/data/{})' \;
⬢ [toolbx comapsdata]$ find *-strings -type l -exec bash -c 'diff <(jq . {}) <(jq . ~/comaps/data/{})' \;
⬢ [toolbx comapsdata]$ sed -i -e 's/Abkhazia/Foo/' countries-strings/en.json/localize.json 
⬢ [toolbx comapsdata]$ find *-strings -type f -exec bash -c 'diff <(jq . {}) <(jq . ~/comaps/data/{})' \;
2c2
< "Foo": "Abkhazia",
---
> "Abkhazia": "Abkhazia",
⬢ [toolbx comapsdata]$ find *-strings -type l -exec bash -c 'diff <(jq . {}) <(jq . ~/comaps/data/{})' \;
2c2
< "Foo": "Abkhazia",
---
> "Abkhazia": "Abkhazia",
⬢ [toolbx comapsdata]$ 

Deployment steps:

  1. Make sure there are no unmerged translations and block new translations

  2. Rebase and run migrations

    Check out this branch, then run in the repository root directory:

    #!/usr/bin/env bash
    # === 1. Move translations to new path to ensure history is retained
    # porcelain, i know... sorry, linus.
    git fetch origin main
    git rebase origin/main
    # get rid of untracked and ignored files (these actually do exist)
    rm -rf data
    git checkout -- data
    # move data
    mkdir data/translations
    mv data/*-strings data/translations/
    # commit changes
    git add data
    git commit -m "[1/2] Migrate translations" -s
    # === 2. Delete everything from 1 and actually run the migration
    rm -rf data
    git restore --source=HEAD~ data
    tree data
    # copy symlinks verbatim (they are all relative)
    find data/ -type l -name 'localize.json' -exec bash -c '
    mkdir -p "$(dirname "$(echo "1ドル" | sed "s|^data/|data/translations/|")")"
    cp -d "1ドル" "$(echo "1ドル" | sed "s|^data/|data/translations/|")"
    ' inline-shell '{}' \;
    # convert and copy data
    find data/ -maxdepth 3 -type f -name 'localize.json' -exec bash -c '
    mkdir -p "$(dirname "$(echo "1ドル" | sed "s|^data/|data/translations/|")")"
    jq --indent 4 '"'"'map_values({defaultMessage:.})'"'"' "1ドル" > "$(echo "1ドル" | sed "s|^data/|data/translations/|")"
    ' inline-shell '{}' \;
    # commit changes
    git add data/translations
    git commit -m "[2/2] Migrate translations" -s
    
  3. Merge this PR

  4. In Codeberg Translate, go to the Operations -> Settings -> Files tab for each affected Component

  5. For each one:

    1. Set File format to Format.JS JSON file
    2. In Monolingual base language file, change data/ prefix to translations/
    3. Restore the old file-format-specific settings if needed: Sort JSON keys=off; JSON indentation=0; Avoid spaces after separators=off; DOS line endings=off
  6. Check that translations are synchronizing correctly.

Closes #4419

Per #4419, we need a way of handling context for translations. This adds a script to convert translation files at compile time. This means that we can use [Format.JS files](https://docs.weblate.org/en/weblate-2026.5/formats/formatjs.html) which support storing descriptions in the `<key>.description` JSON key, and it will correspond with the `<key>.defaultMessage` translation value. Example usage: ``` "unknown_camera": { "defaultMessage": "Speed camera ahead", "description": "TEST" } ``` ![image](/attachments/77de46b8-b444-4c06-9194-bfb74871e908) No generative AI used. <hr> I have linted the shell scripts with shellcheck and it's all false positives or preexisting warnings: ``` ⬢ [toolbx comaps]$ shellcheck -o all migrate.sh ⬢ [toolbx comaps]$ shellcheck -o all tools/unix/generate_json_strings.sh In tools/unix/generate_json_strings.sh line 19: find translations/ -type f -name 'localize.json' -print0 | xargs -P"${JOBS}" -0 -I'{}' bash -c ' ^-- SC2016 (info): Expressions don't expand in single quotes, use double quotes for that. In tools/unix/generate_json_strings.sh line 21: jq -c '"'"'map_values(.defaultMessage)'"'"' "1ドル" > "$(echo "1ドル" | sed "s|^translations/|data/|")" ^-- SC2016 (info): Expressions don't expand in single quotes, use double quotes for that. For more information: https://www.shellcheck.net/wiki/SC2016 -- Expressions don't expand in singl... ⬢ [toolbx comaps]$ shellcheck -o all configure.sh ... lots of style warnings that were already there ⬢ [toolbx comaps]$ ``` Performance: ``` ⬢ [toolbx comaps]$ time tools/unix/generate_json_strings.sh Starting... Finished real 0m0.485s user 0m1.704s sys 0m2.131s ``` Tested no regressions (`~/comapsdata` is post-migration and post `generate_json_strings.sh`, `~/comaps/data` has a checkout of main): ``` ⬢ [toolbx data]$ pwd ~/comaps/data ⬢ [toolbx data]$ head -c50 ~/comapsdata/categories-strings/ar.json/localize.json; echo {"@category_eat":"طعام|مكان لتناول � ⬢ [toolbx data]$ head -c50 categories-strings/ar.json/localize.json; echo { "@category_eat": "طعام|مكان لتناول ⬢ [toolbx data]$ head -c50 ~/comapsdata/categories-strings/zh-Hans.json/localize.json; echo {"@category_eat":"在哪儿吃|食物","@category_ ⬢ [toolbx data]$ head -c50 categories-strings/zh-Hans.json/localize.json; echo { "@category_eat": "在哪儿吃|食物", "@catego ⬢ [toolbx data]$ head -c50 ~/comapsdata/categories-strings/en.json/localize.json; echo {"@category_eat":"Where to eat|eat|Food","@categor ⬢ [toolbx data]$ head -c50 categories-strings/en.json/localize.json; echo { "@category_eat": "Where to eat|eat|Food", "@cate ⬢ [toolbx data]$ find *-strings -type f -exec bash -c 'diff <(jq . {}) <(jq . ~/comapsdata/{})' \; ⬢ [toolbx data]$ find *-strings -type l -exec bash -c 'diff <(jq . {}) <(jq . ~/comapsdata/{})' \; ⬢ [toolbx data]$ cd ~/comapsdata ⬢ [toolbx comapsdata]$ find *-strings -type f -exec bash -c 'diff <(jq . {}) <(jq . ~/comaps/data/{})' \; ⬢ [toolbx comapsdata]$ find *-strings -type l -exec bash -c 'diff <(jq . {}) <(jq . ~/comaps/data/{})' \; ⬢ [toolbx comapsdata]$ sed -i -e 's/Abkhazia/Foo/' countries-strings/en.json/localize.json ⬢ [toolbx comapsdata]$ find *-strings -type f -exec bash -c 'diff <(jq . {}) <(jq . ~/comaps/data/{})' \; 2c2 < "Foo": "Abkhazia", --- > "Abkhazia": "Abkhazia", ⬢ [toolbx comapsdata]$ find *-strings -type l -exec bash -c 'diff <(jq . {}) <(jq . ~/comaps/data/{})' \; 2c2 < "Foo": "Abkhazia", --- > "Abkhazia": "Abkhazia", ⬢ [toolbx comapsdata]$ ``` <hr> Deployment steps: 1. [ ] [Make sure there are no unmerged translations](https://codeberg.org/comaps/comaps/src/branch/main/docs/TRANSLATIONS.md#resolving-conflicts) and block new translations 2. [ ] Rebase and run migrations Check out this branch, then run in the repository root directory: ``` #!/usr/bin/env bash # === 1. Move translations to new path to ensure history is retained # porcelain, i know... sorry, linus. git fetch origin main git rebase origin/main # get rid of untracked and ignored files (these actually do exist) rm -rf data git checkout -- data # move data mkdir data/translations mv data/*-strings data/translations/ # commit changes git add data git commit -m "[1/2] Migrate translations" -s # === 2. Delete everything from 1 and actually run the migration rm -rf data git restore --source=HEAD~ data tree data # copy symlinks verbatim (they are all relative) find data/ -type l -name 'localize.json' -exec bash -c ' mkdir -p "$(dirname "$(echo "1ドル" | sed "s|^data/|data/translations/|")")" cp -d "1ドル" "$(echo "1ドル" | sed "s|^data/|data/translations/|")" ' inline-shell '{}' \; # convert and copy data find data/ -maxdepth 3 -type f -name 'localize.json' -exec bash -c ' mkdir -p "$(dirname "$(echo "1ドル" | sed "s|^data/|data/translations/|")")" jq --indent 4 '"'"'map_values({defaultMessage:.})'"'"' "1ドル" > "$(echo "1ドル" | sed "s|^data/|data/translations/|")" ' inline-shell '{}' \; # commit changes git add data/translations git commit -m "[2/2] Migrate translations" -s ``` 3. [ ] Merge this PR 4. [ ] In Codeberg Translate, go to the Operations -> Settings -> Files tab for each affected Component - https://translate.codeberg.org/projects/comaps/countries/ - https://translate.codeberg.org/projects/comaps/search-synonyms-aliases/ - https://translate.codeberg.org/projects/comaps/tts/ 5. For each one: 1. Set **File format** to **Format.JS JSON file** 2. In **Monolingual base language file**, change `data/` prefix to `translations/` 3. Restore the old file-format-specific settings if needed: Sort JSON keys=off; JSON indentation=0; Avoid spaces after separators=off; DOS line endings=off 6. Check that translations are synchronizing correctly. Closes #4419
134 KiB
hackintosh5 force-pushed patch-8 from 230aa087a8
Some checks failed
DCO / check (pull_request) Successful in 5s
Linux Check / Linux no unity build (pull_request) Failing after 5m26s
Android Check / Android Lint (pull_request) Failing after 5m32s
Android Check / Build Android Debug (pull_request) Failing after 5m18s
Linux Check / Linux builds and tests (pull_request) Failing after 5m29s
to c3f70de230
Some checks failed
DCO / check (pull_request) Successful in 5s
Linux Check / Linux no unity build (pull_request) Failing after 4m54s
Android Check / Android Lint (pull_request) Failing after 5m4s
Android Check / Build Android Debug (pull_request) Failing after 5m2s
Linux Check / Linux builds and tests (pull_request) Failing after 4m54s
2026年06月06日 00:41:22 +02:00
Compare
[docs] Update paths in translations instructions
Some checks failed
Android Check / Android Lint (pull_request) Failing after 3m28s
DCO / check (pull_request) Successful in 26s
Linux Check / Linux no unity build (pull_request) Failing after 15m17s
Android Check / Build Android Debug (pull_request) Failing after 3m25s
Linux Check / Linux builds and tests (pull_request) Failing after 34s
4d4943f937
Signed-off-by: Penn Mackintosh <git@pennmack.co.uk>

Are symlinks required to build i.e. the Android app with translated data after this change?

Are symlinks required to build i.e. the Android app with translated data after this change?
Author
Member
Copy link

Symlinks shouldn't be needed. Both before and after this change they are only used for default.json which is only used by CB Translate AFAIK. E.g. https://codeberg.org/comaps/comaps/src/branch/main/data/countries-strings/default.json/localize.json

However I don't know what the behaviour of ln -s is on WSL - that would be good to check. I don't have a Windows machine to hand. The safe option would be to totally ignore links but I feel like that's potentially setting things up for future confusion. It may be necessary to add some special handling to avoid breaking Windows. I'll ask someone to test, thanks for flagging.

Symlinks shouldn't be needed. Both before and after this change they are only used for default.json which is only used by CB Translate AFAIK. E.g. https://codeberg.org/comaps/comaps/src/branch/main/data/countries-strings/default.json/localize.json However I don't know what the behaviour of `ln -s` is on WSL - that would be good to check. I don't have a Windows machine to hand. The safe option would be to totally ignore links but I feel like that's potentially setting things up for future confusion. It may be necessary to add some special handling to avoid breaking Windows. I'll ask someone to test, thanks for flagging.

In wsl it's usually fine, moreso in windows native it requires some admin hoops that I just stopped requiring in my windows PR, opting to just copy things during compilation instead. I don't think we technically require wsl in our build process

In wsl it's usually fine, moreso in windows native it requires some admin hoops that I just stopped requiring in my windows PR, opting to just copy things during compilation instead. I don't think we technically require wsl in our build process
Author
Member
Copy link

Oh, in that case it should be fine barring the migration scripts.

The compile-time scripts will only attempt to create symlinks if they find existing symlinks!

Oh, in that case it should be fine barring the migration scripts. The compile-time scripts will only attempt to create symlinks if they find existing symlinks!
pastk left a comment
Copy link

LGTM overall, thanks!

Please let's continue keeping all data files in data/, i.e. move translations/ from repo root to e.g. data/translations/....

Instead of having an involved and risky deployment stage its better to

  1. halt Weblate translations, merge all pending ones
  2. migrate
  3. include all changes into the PR
  4. merge
  5. do Weblate config changes
  6. resume Weblate translations
LGTM overall, thanks! Please let's continue keeping all data files in `data/`, i.e. move `translations/` from repo root to e.g. `data/translations/`.... Instead of having an involved and risky deployment stage its better to 1. halt Weblate translations, merge all pending ones 2. migrate 3. include all changes into the PR 4. merge 5. do Weblate config changes 6. resume Weblate translations
Author
Member
Copy link

data/translations sounds good, I'll do that tomorrow.

Your migration steps sound good, thanks.

Cheers!

data/translations sounds good, I'll do that tomorrow. Your migration steps sound good, thanks. Cheers!
hackintosh5 force-pushed patch-8 from 4d4943f937
Some checks failed
Android Check / Android Lint (pull_request) Failing after 3m28s
DCO / check (pull_request) Successful in 26s
Linux Check / Linux no unity build (pull_request) Failing after 15m17s
Android Check / Build Android Debug (pull_request) Failing after 3m25s
Linux Check / Linux builds and tests (pull_request) Failing after 34s
to b483e1761b
Some checks failed
DCO / check (pull_request) Successful in 4s
Android Check / Android Lint (pull_request) Failing after 3m27s
Linux Check / Linux no unity build (pull_request) Failing after 3m52s
Linux Check / Linux builds and tests (pull_request) Failing after 3m51s
Android Check / Build Android Debug (pull_request) Failing after 3m54s
2026年07月01日 11:31:50 +02:00
Compare
hackintosh5 force-pushed patch-8 from b483e1761b
Some checks failed
DCO / check (pull_request) Successful in 4s
Android Check / Android Lint (pull_request) Failing after 3m27s
Linux Check / Linux no unity build (pull_request) Failing after 3m52s
Linux Check / Linux builds and tests (pull_request) Failing after 3m51s
Android Check / Build Android Debug (pull_request) Failing after 3m54s
to 28604a8e72
Some checks failed
DCO / check (pull_request) Successful in 5s
iOS Check metadata / Check app metadata (pull_request) Failing after 7s
Android Check Store Metadata / Check app metadata (pull_request) Failing after 10s
Linux Check / Linux builds and tests (pull_request) Has been cancelled
Linux Check / Linux no unity build (pull_request) Has been cancelled
Android Check / Build Android Debug (pull_request) Has been cancelled
Android Check / Android Lint (pull_request) Has been cancelled
2026年07月01日 12:06:54 +02:00
Compare
Signed-off-by: Penn Mackintosh <git@pennmack.co.uk>
[2/2] Migrate translations
Some checks failed
DCO / check (pull_request) Successful in 4s
Android Check / Android Lint (pull_request) Failing after 2m36s
Android Check / Build Android Debug (pull_request) Failing after 2m34s
Linux Check / Linux no unity build (pull_request) Failing after 2m8s
Linux Check / Linux builds and tests (pull_request) Failing after 3m27s
Linux Check / Linux no unity build (push) Failing after 11m41s
Android Check / Android Lint (push) Failing after 12m43s
Android Check / Build Android Debug (push) Failing after 12m40s
Linux Check / Linux builds and tests (push) Failing after 5m43s
7e7fe01a3c
Signed-off-by: Penn Mackintosh <git@pennmack.co.uk>
@ -94,3 +94,3 @@
Should you need to test/make your changes offline (like to use the emulator/a device to check your translation), here is what should be done:
1. Create a clone/branch of the code.
2. If a such file doesn't exist, create `data/sound-strings/[language code].json/localize.json`. Replace [language code] with the two letter code for your language (e.g. `ta` for Tamil).
2. If a such file doesn't exist, create `translations/sound-strings/[language code].json/localize.json`. Replace [language code] with the two letter code for your language (e.g. `ta` for Tamil).
Owner
Copy link

there are more paths which need to be updated, e.g. please check data/categories-strings

there are more paths which need to be updated, e.g. please check `data/categories-strings`
Sign in to join this conversation.
No reviewers
Labels
Clear labels
accessibility
Visual contrast, screen readers, etc.
addresses
Related to addresses, post codes, city/town/village borders
AI-assisted
AI-assisted PRs or issues
Android
Android app
Android Auto
Android Auto integration
Android Automotive
Android Automotive app
api
Deeplinks and URLs handled by the API
app stores
Google Play, App Store, F-Droid, Obtanium, Huawei Gallery, Acressent, Flathub, IzzyOnDroid, etc.
battery & performance
Performance and battery consumption-related problems and optimisations
borders
Related to borders between countries / regions
bug
Something is not working
build
building of apps
CarPlay
CarPlay integration
community
Community relations
contribution welcome
Contributions are very welcome, get started here
core
C++ core of the app
crash
Crash reporting
cycling
Specific to using a bicycle or similar vehicles
desktop
Qt desktop app incl. designer
devops
directions
Voice and visual turn-by-turn directions
docs
Documentation
downloader
Map downloader
drape
The C++ map rendering engine
driving
Specific to driving a car or similar vehicles
duplicate
This issue or pull request already exists
editor
Built-in OSM editor
elevation
Contour lines, elevation profiles, ...
enhancement
New feature
EPIC
A big idea or a piece of work that requires a lot of effort to implement
F-Droid
F-Droid platform
favorites
Places and GPS tracks
feature parity
A feature is implemented on one platform, but not on another
fonts
Fonts
good first issue
Interested in contributing? Get started here
help wanted
Need some help
icons
Map features icons
invalid
Something is wrong
iOS
iOS app
legal
Legal aspects
linux phone
LibreM, PinePhone and other mobile linuxes
location
Via GPS, network, etc.
macOS
Emulated iOS App or Qt Desktop App specifically related to macOS
map data
Related to OpenStreetMap data
mapgen needed
map generation is needed for PR to take full effect
maps compat
compatibility of newer maps with older apps; issues and PRs breaking or fixing compatibility
maps generator
Maps generator
navigation
The navigation turn-by-turn app mode
need feedback
Further information is requested
needs design
not planned
This is not planned at the moment
OM
Related to or references Organic Maps
opening hours
Related to Business Hours, off time, holidays, seasonal
outdoor
Hiking, backcountry cycling, 4WD, etc.
POI info
Various feature attributes usually displayed on the place page
priority
High
Seriously affects a lot of users or breaks the app severely
priority
Low
Not urgent or only happens in rare cases
priority
Medium
Happens enough to be a concern, but not app-breaking
privacy
Privacy aspects
public feedback needed
Experimental changes which requite explicit public feedback before continuing with them
public transport
Specific to public transport (busses, trams, subways, trains etc.)
question
Questions and Discussions
raw idea
Needs more discussion or to be further elaborated
refactoring
Improving the structure or simplifying the code, improving maintainability
regional
Different depending on the country or region
regression
Regression in the app
releases
Release management
route planning
Preview and plan your route
routing
Routing engine
search
Search inside of the app
security
Security improvements
source data
Related to OSM, SRTM, Tiger etc.
styles
Map styling, incl. mapping OSM tags
subway
The special subway layer
task
Internal things that have a clear way for implementation
tests
Unit tests
track recording
Track recording
traffic
Traffic information (still under development)
translations
Translations and all other kinds of localisation
TTS
Text-to-Speech
UI
User interface
UX
User experience
wait for upstream
Waiting for something to be done upstream
walking
Specific to walking
Wikipedia
Related to the embedded Wikipedia articles
Windows
Windows related
world map
The world overview map
No labels
accessibility
addresses
AI-assisted
Android
Android Auto
Android Automotive
api
app stores
battery & performance
borders
bug
build
CarPlay
community
contribution welcome
core
crash
cycling
desktop
devops
directions
docs
downloader
drape
driving
duplicate
editor
elevation
enhancement
EPIC
F-Droid
favorites
feature parity
fonts
good first issue
help wanted
icons
invalid
iOS
legal
linux phone
location
macOS
map data
mapgen needed
maps compat
maps generator
navigation
need feedback
needs design
not planned
OM
opening hours
outdoor
POI info
priority
High
priority
Low
priority
Medium
privacy
public feedback needed
public transport
question
raw idea
refactoring
regional
regression
releases
route planning
routing
search
security
source data
styles
subway
task
tests
track recording
traffic
translations
TTS
UI
UX
wait for upstream
walking
Wikipedia
Windows
world map
Milestone
Clear milestone
No items
No milestone
Projects
Clear projects
No items
No project
Assignees
Clear assignees
No assignees
3 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
comaps/comaps!4433
Reference in a new issue
comaps/comaps
No description provided.
Delete branch "hackintosh5/comaps:patch-8"

Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?