Your message dated Sat, 14 Oct 2023 10:07:41 +0100
with message-id 
<0f3a80cec30d0f4e94cb0f6ee19cca0dd7a412a7.ca...@adam-barratt.org.uk>
and subject line Re: Bug#1053919: bookworm-pu: package tbsync
has caused the Debian Bug report #1053919,
regarding bookworm-pu: package tbsync
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact ow...@bugs.debian.org
immediately.)


-- 
1053919: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1053919
Debian Bug Tracking System
Contact ow...@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
Tags: bookworm
User: release.debian....@packages.debian.org
Usertags: pu
X-Debbugs-Cc: tbs...@packages.debian.org, mechti...@debian.org
Control: affects -1 + src:tbsync

[ Reason ]

This package is an extension to thunderbird. After thunderbird is updated to version 115.* in bookwork it is necessary to update this extension too.

[ Impact ]

Otherwise this extension doesn't work anymore

[ Risks ]

Only dav4tbsync and eas4tbsync are affected and will be updated too

[ Checklist ]
  [X] *all* changes are documented in the d/changelog
  [X] I reviewed all changes and I approve them
  [X] attach debdiff against the package in (old)stable
  [X] the issue is verified as fixed in unstable

[ Changes ]

There is a new version of tbsync to work with thunderbird 115.x

[ Other info ]

The output von debdiff (stable vs stable-pu is attached)

dav4tbsync and eas4tbsync will follow

Kind regards to the release team

Mechtilde


--
Mechtilde Stehmann
## Debian Developer
## PGP encryption welcome
## F0E3 7F3D C87A 4998 2899  39E7 F287 7BBA 141A AD7F
diffstat for tbsync-4.3 tbsync-4.7

 _locales/bg/messages.json                     |    7 
 _locales/cs/messages.json                     |    7 
 _locales/de/messages.json                     |   91 +--
 _locales/en-US/messages.json                  |    7 
 _locales/es/messages.json                     |    7 
 _locales/et/messages.json                     |    7 
 _locales/fr/messages.json                     |    7 
 _locales/gl/messages.json                     |    9 
 _locales/hu/messages.json                     |    7 
 _locales/it/messages.json                     |    7 
 _locales/ja/messages.json                     |    7 
 _locales/ko/messages.json                     |    7 
 _locales/pl/messages.json                     |    7 
 _locales/pt_BR/messages.json                  |    7 
 _locales/ro/messages.json                     |    7 
 _locales/ru/messages.json                     |    7 
 _locales/sv/messages.json                     |    7 
 content/api/BootstrapLoader/CHANGELOG.md      |   15 
 content/api/BootstrapLoader/implementation.js |  676 ++++++++++++++++++++------
 content/api/BootstrapLoader/schema.json       |    4 
 content/manager/accounts.js                   |   12 
 content/manager/accounts.xhtml                |    4 
 content/manager/editAccount.js                |    3 
 content/manager/editAccount.xhtml             |    7 
 content/manager/eventlog/eventlog.js          |    9 
 content/manager/eventlog/eventlog.xhtml       |   14 
 content/modules/db.js                         |   13 
 content/modules/io.js                         |    4 
 content/modules/lightning.js                  |    2 
 content/modules/manager.js                    |   11 
 content/passwordPrompt/passwordPrompt.css     |   13 
 content/passwordPrompt/passwordPrompt.js      |    8 
 content/passwordPrompt/passwordPrompt.xhtml   |   44 -
 content/tbsync.jsm                            |    3 
 debian/changelog                              |   26 +
 debian/control                                |    6 
 debian/gbp.conf                               |    2 
 manifest.json                                 |    4 
 38 files changed, 800 insertions(+), 285 deletions(-)

diff -Nru tbsync-4.3/content/api/BootstrapLoader/CHANGELOG.md tbsync-4.7/content/api/BootstrapLoader/CHANGELOG.md
--- tbsync-4.3/content/api/BootstrapLoader/CHANGELOG.md	2022-10-12 21:40:25.000000000 +0200
+++ tbsync-4.7/content/api/BootstrapLoader/CHANGELOG.md	2023-08-29 22:22:49.000000000 +0200
@@ -1,3 +1,18 @@
+Version: 1.21
+-------------
+- Explicitly set hasAddonManagerEventListeners flag to false on uninstall
+
+Version: 1.20
+-------------
+- hard fork BootstrapLoader v1.19 implementation and continue to serve it for
+  Thunderbird 111 and older
+- BootstrapLoader v1.20 has removed a lot of unnecessary code used for backward
+  compatibility
+
+Version: 1.19
+-------------
+- fix race condition which could prevent the AOM tab to be monkey patched correctly
+
 Version: 1.18
 -------------
 - be precise on which revision the wrench symbol should be displayed, instead of
diff -Nru tbsync-4.3/content/api/BootstrapLoader/implementation.js tbsync-4.7/content/api/BootstrapLoader/implementation.js
--- tbsync-4.3/content/api/BootstrapLoader/implementation.js	2022-10-12 21:40:25.000000000 +0200
+++ tbsync-4.7/content/api/BootstrapLoader/implementation.js	2023-08-29 22:22:49.000000000 +0200
@@ -2,7 +2,7 @@
  * This file is provided by the addon-developer-support repository at
  * https://github.com/thundernest/addon-developer-support
  *
- * Version: 1.18
+ * Version: 1.21
  *
  * Author: John Bieling (j...@thunderbird.net)
  *
@@ -17,70 +17,65 @@
 var { AddonManager } = ChromeUtils.import("resource://gre/modules/AddonManager.jsm");
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
-var BootstrapLoader = class extends ExtensionCommon.ExtensionAPI {
-  getMessenger(context) {   
-    let apis = [
-      "storage",
-      "runtime",
-      "extension",
-      "i18n",
-    ];
-
-    function getStorage() {
-      let localstorage = null;
-      try {
-        localstorage = context.apiCan.findAPIPath("storage");
-        localstorage.local.get = (...args) =>
-          localstorage.local.callMethodInParentProcess("get", args);
-        localstorage.local.set = (...args) =>
-          localstorage.local.callMethodInParentProcess("set", args);
-        localstorage.local.remove = (...args) =>
-          localstorage.local.callMethodInParentProcess("remove", args);
-        localstorage.local.clear = (...args) =>
-          localstorage.local.callMethodInParentProcess("clear", args);
-      } catch (e) {
-        console.info("Storage permission is missing");
-      }
-      return localstorage;
-    }
-    
-    let messenger = {};    
-    for (let api of apis) {
-      switch (api) {
-        case "storage":
-          XPCOMUtils.defineLazyGetter(messenger, "storage", () =>
-            getStorage()
-          );
-        break;
+function getThunderbirdVersion() {
+  let parts = Services.appinfo.version.split(".");
+  return {
+    major: parseInt(parts[0]),
+    minor: parseInt(parts[1]),
+    revision: parts.length > 2 ? parseInt(parts[2]) : 0,
+  }
+}
 
-        default:
-          XPCOMUtils.defineLazyGetter(messenger, api, () =>
-            context.apiCan.findAPIPath(api)
-          );
-      }
+function getMessenger(context) {
+  let apis = ["storage", "runtime", "extension", "i18n"];
+
+  function getStorage() {
+    let localstorage = null;
+    try {
+      localstorage = context.apiCan.findAPIPath("storage");
+      localstorage.local.get = (...args) =>
+        localstorage.local.callMethodInParentProcess("get", args);
+      localstorage.local.set = (...args) =>
+        localstorage.local.callMethodInParentProcess("set", args);
+      localstorage.local.remove = (...args) =>
+        localstorage.local.callMethodInParentProcess("remove", args);
+      localstorage.local.clear = (...args) =>
+        localstorage.local.callMethodInParentProcess("clear", args);
+    } catch (e) {
+      console.info("Storage permission is missing");
     }
-    return messenger;
+    return localstorage;
   }
 
-  getThunderbirdVersion() {
-    let parts = Services.appinfo.version.split(".");
-    return {
-      major: parseInt(parts[0]),
-      minor: parseInt(parts[1]),
-      revision: parts.length > 2 ? parseInt(parts[2]) : 0,
+  let messenger = {};
+  for (let api of apis) {
+    switch (api) {
+      case "storage":
+        XPCOMUtils.defineLazyGetter(messenger, "storage", () =>
+          getStorage()
+        );
+        break;
+
+      default:
+        XPCOMUtils.defineLazyGetter(messenger, api, () =>
+          context.apiCan.findAPIPath(api)
+        );
     }
   }
-  
+  return messenger;
+}
+
+var BootstrapLoader_102 = class extends ExtensionCommon.ExtensionAPI {
   getCards(e) {
     // This gets triggered by real events but also manually by providing the outer window.
     // The event is attached to the outer browser, get the inner one.
     let doc;
-    
+
     // 78,86, and 87+ need special handholding. *Yeah*.
-    if (this.getThunderbirdVersion().major < 86) {
+    if (getThunderbirdVersion().major < 86) {
       let ownerDoc = e.document || e.target.ownerDocument;
       doc = ownerDoc.getElementById("html-view-browser").contentDocument;
-    } else if (this.getThunderbirdVersion().major < 87) {
+    } else if (getThunderbirdVersion().major < 87) {
       let ownerDoc = e.document || e.target;
       doc = ownerDoc.getElementById("html-view-browser").contentDocument;
     } else {
@@ -88,42 +83,42 @@
     }
     return doc.querySelectorAll("addon-card");
   }
-  
+
   // Add pref entry to 68
   add68PrefsEntry(event) {
     let id = this.menu_addonPrefs_id + "_" + this.uniqueRandomID;
 
     // Get the best size of the icon (16px or bigger)
-    let iconSizes = this.extension.manifest.icons 
+    let iconSizes = this.extension.manifest.icons
       ? Object.keys(this.extension.manifest.icons)
       : [];
-    iconSizes.sort((a,b)=>a-b);
+    iconSizes.sort((a, b) => a - b);
     let bestSize = iconSizes.filter(e => parseInt(e) >= 16).shift();
     let icon = bestSize ? this.extension.manifest.icons[bestSize] : "";
 
     let name = this.extension.manifest.name;
     let entry = icon
       ? event.target.ownerGlobal.MozXULElement.parseXULToFragment(
-          `<menuitem class="menuitem-iconic" id="${id}" image="${icon}" label="${name}" />`)
-      :  event.target.ownerGlobal.MozXULElement.parseXULToFragment(
-          `<menuitem id="${id}" label="${name}" />`);
-    
+        `<menuitem class="menuitem-iconic" id="${id}" image="${icon}" label="${name}" />`)
+      : event.target.ownerGlobal.MozXULElement.parseXULToFragment(
+        `<menuitem id="${id}" label="${name}" />`);
+
     event.target.appendChild(entry);
     let noPrefsElem = event.target.querySelector('[disabled="true"]');
     // using collapse could be undone by core, so we use display none
     // noPrefsElem.setAttribute("collapsed", "true");
     noPrefsElem.style.display = "none";
     event.target.ownerGlobal.document.getElementById(id).addEventListener("command", this);
-  }   
+  }
 
   // Event handler for the addon manager, to update the state of the options button.
-  handleEvent(e) {   
+  handleEvent(e) {
     switch (e.type) {
       // 68 add-on options menu showing
       case "popupshowing": {
         this.add68PrefsEntry(e);
       }
-      break;
+        break;
 
       // 78/88 add-on options menu/button click
       case "click": {
@@ -131,31 +126,31 @@
         e.stopPropagation();
         let BL = {}
         BL.extension = this.extension;
-        BL.messenger = this.getMessenger(this.context);
+        BL.messenger = getMessenger(this.context);
         let w = Services.wm.getMostRecentWindow("mail:3pane");
-        w.openDialog(this.pathToOptionsPage, "AddonOptions", "chrome,resizable,centerscreen", BL);        
+        w.openDialog(this.pathToOptionsPage, "AddonOptions", "chrome,resizable,centerscreen", BL);
       }
-      break;
-      
+        break;
+
       // 68 add-on options menu command
       case "command": {
         let BL = {}
         BL.extension = this.extension;
-        BL.messenger = this.getMessenger(this.context);
+        BL.messenger = getMessenger(this.context);
         e.target.ownerGlobal.openDialog(this.pathToOptionsPage, "AddonOptions", "chrome,resizable,centerscreen", BL);
       }
-      break;
-      
+        break;
+
       // update, ViewChanged and manual call for add-on manager options overlay
       default: {
         let cards = this.getCards(e);
         for (let card of cards) {
           // Setup either the options entry in the menu or the button
           if (card.addon.id == this.extension.id) {
-            let optionsMenu = 
-              (this.getThunderbirdVersion().major > 78 && this.getThunderbirdVersion().major < 88) ||
-              (this.getThunderbirdVersion().major == 78 && this.getThunderbirdVersion().minor < 10) ||
-              (this.getThunderbirdVersion().major == 78 && this.getThunderbirdVersion().minor == 10 && this.getThunderbirdVersion().revision < 2);
+            let optionsMenu =
+              (getThunderbirdVersion().major > 78 && getThunderbirdVersion().major < 88) ||
+              (getThunderbirdVersion().major == 78 && getThunderbirdVersion().minor < 10) ||
+              (getThunderbirdVersion().major == 78 && getThunderbirdVersion().minor == 10 && getThunderbirdVersion().revision < 2);
             if (optionsMenu) {
               // Options menu in 78.0-78.10 and 79-87
               let addonOptionsLegacyEntry = card.querySelector(".extension-options-legacy");
@@ -204,10 +199,10 @@
           }
         }
       }
-    }      
-  }  
-  
-// Some tab/add-on-manager related functions
+    }
+  }
+
+  // Some tab/add-on-manager related functions
   getTabMail(window) {
     return window.document.getElementById("tabmail");
   }
@@ -215,7 +210,7 @@
   // returns the outer browser, not the nested browser of the add-on manager
   // events must be attached to the outer browser
   getAddonManagerFromTab(tab) {
-    if (tab.browser) {
+    if (tab.browser && tab.mode.name == "contentTab") {
       let win = tab.browser.contentWindow;
       if (win && win.location.href == "about:addons") {
         return win;
@@ -226,9 +221,28 @@
   getAddonManagerFromWindow(window) {
     let tabMail = this.getTabMail(window);
     for (let tab of tabMail.tabInfo) {
-      let win = this.getAddonManagerFromTab(tab)
-      if (win) {
-        return win;
+      let managerWindow = this.getAddonManagerFromTab(tab);
+      if (managerWindow) {
+        return managerWindow;
+      }
+    }
+  }
+
+  async getAddonManagerFromWindowWaitForLoad(window) {
+    let { setTimeout } = Services.wm.getMostRecentWindow("mail:3pane");
+
+    let tabMail = this.getTabMail(window);
+    for (let tab of tabMail.tabInfo) {
+      if (tab.browser && tab.mode.name == "contentTab") {
+        // Instead of registering a load observer, wait until its loaded. Not nice,
+        // but gets aroud a lot of edge cases.
+        while (!tab.pageLoaded) {
+          await new Promise(r => setTimeout(r, 150));
+        }
+        let managerWindow = this.getAddonManagerFromTab(tab);
+        if (managerWindow) {
+          return managerWindow;
+        }
       }
     }
   }
@@ -237,15 +251,16 @@
     if (!managerWindow) {
       return;
     }
-    if (managerWindow 
-          && managerWindow[this.uniqueRandomID]
-          && managerWindow[this.uniqueRandomID].hasAddonManagerEventListeners
+    if (
+      managerWindow &&
+      managerWindow[this.uniqueRandomID] &&
+      managerWindow[this.uniqueRandomID].hasAddonManagerEventListeners
     ) {
       return;
     }
     managerWindow.document.addEventListener("ViewChanged", this);
     managerWindow.document.addEventListener("update", this);
-    managerWindow.document.addEventListener("view-loaded", this);    
+    managerWindow.document.addEventListener("view-loaded", this);
     managerWindow[this.uniqueRandomID] = {};
     managerWindow[this.uniqueRandomID].hasAddonManagerEventListeners = true;
     if (forceLoad) {
@@ -262,13 +277,13 @@
     this.pathToOptionsPage = null;
     this.chromeHandle = null;
     this.chromeData = null;
-    this.resourceData = null;    
+    this.resourceData = null;
     this.bootstrappedObj = {};
 
     // make the extension object and the messenger object available inside
     // the bootstrapped scope
     this.bootstrappedObj.extension = context.extension;
-    this.bootstrappedObj.messenger = this.getMessenger(this.context);
+    this.bootstrappedObj.messenger = getMessenger(this.context);
 
     this.BOOTSTRAP_REASONS = {
       APP_STARTUP: 1,
@@ -283,49 +298,413 @@
 
     const aomStartup = Cc["@mozilla.org/addons/addon-manager-startup;1"].getService(Ci.amIAddonManagerStartup);
     const resProto = Cc["@mozilla.org/network/protocol;1?name=resource"].getService(Ci.nsISubstitutingProtocolHandler);
-    
+
     let self = this;
 
     // TabMonitor to detect opening of tabs, to setup the options button in the add-on manager.
     this.tabMonitor = {
-      onTabTitleChanged(aTab) {},
-      onTabClosing(aTab) {},
-      onTabPersist(aTab) {},
-      onTabRestored(aTab) {},
-      onTabSwitched(aNewTab, aOldTab) {
-        //self.setupAddonManager(self.getAddonManagerFromTab(aNewTab));
+      onTabTitleChanged(tab) { },
+      onTabClosing(tab) { },
+      onTabPersist(tab) { },
+      onTabRestored(tab) { },
+      onTabSwitched(aNewTab, aOldTab) { },
+      async onTabOpened(tab) {
+        if (tab.browser && tab.mode.name == "contentTab") {
+          let { setTimeout } = Services.wm.getMostRecentWindow("mail:3pane");
+          // Instead of registering a load observer, wait until its loaded. Not nice,
+          // but gets aroud a lot of edge cases.
+          while (!tab.pageLoaded) {
+            await new Promise(r => setTimeout(r, 150));
+          }
+          self.setupAddonManager(self.getAddonManagerFromTab(tab));
+        }
       },
-      async onTabOpened(aTab) {
-        if (aTab.browser) {
-          if (!aTab.pageLoaded) {
-            // await a location change if browser is not loaded yet
-            await new Promise(resolve => {
-              let reporterListener = {
-                QueryInterface: ChromeUtils.generateQI([
-                  "nsIWebProgressListener",
-                  "nsISupportsWeakReference",
-                ]),
-                onStateChange() {},
-                onProgressChange() {},
-                onLocationChange(
-                    /* in nsIWebProgress*/ aWebProgress,
-                    /* in nsIRequest*/ aRequest,
-                    /* in nsIURI*/ aLocation
-                ) {
-                  aTab.browser.removeProgressListener(reporterListener);  
-                  resolve();
-                },
-                onStatusChange() {},
-                onSecurityChange() {},
-                onContentBlockingEvent() {}
-              }          
-              aTab.browser.addProgressListener(reporterListener);  
+    };
+
+    return {
+      BootstrapLoader: {
+
+        registerOptionsPage(optionsUrl) {
+          self.pathToOptionsPage = optionsUrl.startsWith("chrome://")
+            ? optionsUrl
+            : context.extension.rootURI.resolve(optionsUrl);
+        },
+
+        openOptionsDialog(windowId) {
+          let window = context.extension.windowManager.get(windowId, context).window
+          let BL = {}
+          BL.extension = self.extension;
+          BL.messenger = getMessenger(self.context);
+          window.openDialog(self.pathToOptionsPage, "AddonOptions", "chrome,resizable,centerscreen", BL);
+        },
+
+        registerChromeUrl(data) {
+          let chromeData = [];
+          let resourceData = [];
+          for (let entry of data) {
+            if (entry[0] == "resource") resourceData.push(entry);
+            else chromeData.push(entry)
+          }
+
+          if (chromeData.length > 0) {
+            const manifestURI = Services.io.newURI(
+              "manifest.json",
+              null,
+              context.extension.rootURI
+            );
+            self.chromeHandle = aomStartup.registerChrome(manifestURI, chromeData);
+          }
+
+          for (let res of resourceData) {
+            // [ "resource", "shortname" , "path" ]
+            let uri = Services.io.newURI(
+              res[2],
+              null,
+              context.extension.rootURI
+            );
+            resProto.setSubstitutionWithFlags(
+              res[1],
+              uri,
+              resProto.ALLOW_CONTENT_ACCESS
+            );
+          }
+
+          self.chromeData = chromeData;
+          self.resourceData = resourceData;
+        },
+
+        registerBootstrapScript: async function (aPath) {
+          self.pathToBootstrapScript = aPath.startsWith("chrome://")
+            ? aPath
+            : context.extension.rootURI.resolve(aPath);
+
+          // Get the addon object belonging to this extension.
+          let addon = await AddonManager.getAddonByID(context.extension.id);
+          //make the addon globally available in the bootstrapped scope
+          self.bootstrappedObj.addon = addon;
+
+          // add BOOTSTRAP_REASONS to scope
+          for (let reason of Object.keys(self.BOOTSTRAP_REASONS)) {
+            self.bootstrappedObj[reason] = self.BOOTSTRAP_REASONS[reason];
+          }
+
+          // Load registered bootstrap scripts and execute its startup() function.
+          try {
+            if (self.pathToBootstrapScript) Services.scriptloader.loadSubScript(self.pathToBootstrapScript, self.bootstrappedObj, "UTF-8");
+            if (self.bootstrappedObj.startup) self.bootstrappedObj.startup.call(self.bootstrappedObj, self.extension.addonData, self.BOOTSTRAP_REASONS[self.extension.startupReason]);
+          } catch (e) {
+            Components.utils.reportError(e)
+          }
+
+          // Register window listener for main TB window
+          if (self.pathToOptionsPage) {
+            ExtensionSupport.registerWindowListener("injectListener_" + self.uniqueRandomID, {
+              chromeURLs: [
+                "chrome://messenger/content/messenger.xul",
+                "chrome://messenger/content/messenger.xhtml",
+              ],
+              async onLoadWindow(window) {
+                if (getThunderbirdVersion().major < 78) {
+                  let element_addonPrefs = window.document.getElementById(self.menu_addonPrefs_id);
+                  element_addonPrefs.addEventListener("popupshowing", self);
+                } else {
+                  // Add a tabmonitor, to be able to setup the options button/menu in the add-on manager.
+                  self.getTabMail(window).registerTabMonitor(self.tabMonitor);
+                  window[self.uniqueRandomID] = {};
+                  window[self.uniqueRandomID].hasTabMonitor = true;
+                  // Setup the options button/menu in the add-on manager, if it is already open.
+                  let managerWindow = await self.getAddonManagerFromWindowWaitForLoad(window);
+                  self.setupAddonManager(managerWindow, true);
+                }
+              },
+
+              onUnloadWindow(window) {
+              }
             });
           }
-          // Setup the ViewChange event listener in the outer browser of the add-on,
-          // but do not actually add the button/menu, as the inner browser is not yet ready,
-          // let the ViewChange event do it
-          self.setupAddonManager(self.getAddonManagerFromTab(aTab));
+        }
+      }
+    };
+  }
+
+  onShutdown(isAppShutdown) {
+    if (isAppShutdown) {
+      return; // the application gets unloaded anyway
+    }
+
+    //remove our entry in the add-on options menu
+    if (this.pathToOptionsPage) {
+      for (let window of Services.wm.getEnumerator("mail:3pane")) {
+        if (getThunderbirdVersion().major < 78) {
+          let element_addonPrefs = window.document.getElementById(this.menu_addonPrefs_id);
+          element_addonPrefs.removeEventListener("popupshowing", this);
+          // Remove our entry.
+          let entry = window.document.getElementById(this.menu_addonPrefs_id + "_" + this.uniqueRandomID);
+          if (entry) entry.remove();
+          // Do we have to unhide the noPrefsElement?
+          if (element_addonPrefs.children.length == 1) {
+            let noPrefsElem = element_addonPrefs.querySelector('[disabled="true"]');
+            noPrefsElem.style.display = "inline";
+          }
+        } else {
+          // Remove event listener for addon manager view changes
+          let managerWindow = this.getAddonManagerFromWindow(window);
+          if (
+            managerWindow && 
+            managerWindow[this.uniqueRandomID] && 
+            managerWindow[this.uniqueRandomID].hasAddonManagerEventListeners
+          ) {
+            managerWindow.document.removeEventListener("ViewChanged", this);
+            managerWindow.document.removeEventListener("update", this);
+            managerWindow.document.removeEventListener("view-loaded", this);
+            managerWindow[this.uniqueRandomID].hasAddonManagerEventListeners = false;
+
+            let cards = this.getCards(managerWindow);
+            if (getThunderbirdVersion().major < 88) {
+              // Remove options menu in 78-87
+              for (let card of cards) {
+                let addonOptionsLegacyEntry = card.querySelector(".extension-options-legacy");
+                if (addonOptionsLegacyEntry) addonOptionsLegacyEntry.remove();
+              }
+            } else {
+              // Remove options button in 88
+              for (let card of cards) {
+                if (card.addon.id == this.extension.id) {
+                  let addonOptionsButton = card.querySelector(".extension-options-button2");
+                  if (addonOptionsButton) addonOptionsButton.remove();
+                  break;
+                }
+              }
+            }
+          }
+
+          // Remove tabmonitor
+          if (window[this.uniqueRandomID].hasTabMonitor) {
+            this.getTabMail(window).unregisterTabMonitor(this.tabMonitor);
+            window[this.uniqueRandomID].hasTabMonitor = false;
+          }
+
+        }
+      }
+      // Stop listening for new windows.
+      ExtensionSupport.unregisterWindowListener("injectListener_" + this.uniqueRandomID);
+    }
+
+    // Execute registered shutdown()
+    try {
+      if (this.bootstrappedObj.shutdown) {
+        this.bootstrappedObj.shutdown(
+          this.extension.addonData,
+          isAppShutdown
+            ? this.BOOTSTRAP_REASONS.APP_SHUTDOWN
+            : this.BOOTSTRAP_REASONS.ADDON_DISABLE);
+      }
+    } catch (e) {
+      Components.utils.reportError(e)
+    }
+
+    if (this.resourceData) {
+      const resProto = Cc["@mozilla.org/network/protocol;1?name=resource"].getService(Ci.nsISubstitutingProtocolHandler);
+      for (let res of this.resourceData) {
+        // [ "resource", "shortname" , "path" ]
+        resProto.setSubstitution(
+          res[1],
+          null,
+        );
+      }
+    }
+
+    if (this.chromeHandle) {
+      this.chromeHandle.destruct();
+      this.chromeHandle = null;
+    }
+    // Flush all caches
+    Services.obs.notifyObservers(null, "startupcache-invalidate");
+    console.log("BootstrapLoader for " + this.extension.id + " unloaded!");
+  }
+};
+
+// Removed all extra code for backward compatibility for better maintainability.
+var BootstrapLoader_115 = class extends ExtensionCommon.ExtensionAPI {
+  getCards(e) {
+    // This gets triggered by real events but also manually by providing the outer window.
+    // The event is attached to the outer browser, get the inner one.
+    let doc = e.document || e.target;
+    return doc.querySelectorAll("addon-card");
+  }
+
+  // Event handler for the addon manager, to update the state of the options button.
+  handleEvent(e) {
+    switch (e.type) {
+      case "click": {
+        e.preventDefault();
+        e.stopPropagation();
+        let BL = {}
+        BL.extension = this.extension;
+        BL.messenger = getMessenger(this.context);
+        let w = Services.wm.getMostRecentWindow("mail:3pane");
+        w.openDialog(
+          this.pathToOptionsPage,
+          "AddonOptions",
+          "chrome,resizable,centerscreen",
+          BL
+        );
+      }
+        break;
+
+
+      // update, ViewChanged and manual call for add-on manager options overlay
+      default: {
+        let cards = this.getCards(e);
+        for (let card of cards) {
+          // Setup either the options entry in the menu or the button
+          if (card.addon.id == this.extension.id) {
+            // Add-on button
+            let addonOptionsButton = card.querySelector(
+              ".windowlistener-options-button"
+            );
+            if (card.addon.isActive && !addonOptionsButton) {
+              let origAddonOptionsButton = card.querySelector(".extension-options-button")
+              origAddonOptionsButton.setAttribute("hidden", "true");
+
+              addonOptionsButton = card.ownerDocument.createElement("button");
+              addonOptionsButton.classList.add("windowlistener-options-button");
+              addonOptionsButton.classList.add("extension-options-button");
+              card.optionsButton.parentNode.insertBefore(
+                addonOptionsButton,
+                card.optionsButton
+              );
+              card
+                .querySelector(".windowlistener-options-button")
+                .addEventListener("click", this);
+            } else if (!card.addon.isActive && addonOptionsButton) {
+              addonOptionsButton.remove();
+            }
+          }
+        }
+      }
+    }
+  }
+
+  // Some tab/add-on-manager related functions
+  getTabMail(window) {
+    return window.document.getElementById("tabmail");
+  }
+
+  // returns the outer browser, not the nested browser of the add-on manager
+  // events must be attached to the outer browser
+  getAddonManagerFromTab(tab) {
+    if (tab.browser && tab.mode.name == "contentTab") {
+      let win = tab.browser.contentWindow;
+      if (win && win.location.href == "about:addons") {
+        return win;
+      }
+    }
+  }
+
+  getAddonManagerFromWindow(window) {
+    let tabMail = this.getTabMail(window);
+    for (let tab of tabMail.tabInfo) {
+      let managerWindow = this.getAddonManagerFromTab(tab);
+      if (managerWindow) {
+        return managerWindow;
+      }
+    }
+  }
+
+  async getAddonManagerFromWindowWaitForLoad(window) {
+    let { setTimeout } = Services.wm.getMostRecentWindow("mail:3pane");
+
+    let tabMail = this.getTabMail(window);
+    for (let tab of tabMail.tabInfo) {
+      if (tab.browser && tab.mode.name == "contentTab") {
+        // Instead of registering a load observer, wait until its loaded. Not nice,
+        // but gets aroud a lot of edge cases.
+        while (!tab.pageLoaded) {
+          await new Promise(r => setTimeout(r, 150));
+        }
+        let managerWindow = this.getAddonManagerFromTab(tab);
+        if (managerWindow) {
+          return managerWindow;
+        }
+      }
+    }
+  }
+
+  setupAddonManager(managerWindow, forceLoad = false) {
+    if (!managerWindow) {
+      return;
+    }
+    if (!this.pathToOptionsPage) {
+      return;
+    }
+    if (
+      managerWindow &&
+      managerWindow[this.uniqueRandomID] &&
+      managerWindow[this.uniqueRandomID].hasAddonManagerEventListeners
+    ) {
+      return;
+    }
+    
+    managerWindow.document.addEventListener("ViewChanged", this);
+    managerWindow.document.addEventListener("update", this);
+    managerWindow.document.addEventListener("view-loaded", this);
+    managerWindow[this.uniqueRandomID] = {};
+    managerWindow[this.uniqueRandomID].hasAddonManagerEventListeners = true;
+    if (forceLoad) {
+      this.handleEvent(managerWindow);
+    }
+  }
+
+  getAPI(context) {
+    this.uniqueRandomID = "AddOnNS" + context.extension.instanceId;
+    this.menu_addonPrefs_id = "addonPrefs";
+
+
+    this.pathToBootstrapScript = null;
+    this.pathToOptionsPage = null;
+    this.chromeHandle = null;
+    this.chromeData = null;
+    this.resourceData = null;
+    this.bootstrappedObj = {};
+
+    // make the extension object and the messenger object available inside
+    // the bootstrapped scope
+    this.bootstrappedObj.extension = context.extension;
+    this.bootstrappedObj.messenger = getMessenger(this.context);
+
+    this.BOOTSTRAP_REASONS = {
+      APP_STARTUP: 1,
+      APP_SHUTDOWN: 2,
+      ADDON_ENABLE: 3,
+      ADDON_DISABLE: 4,
+      ADDON_INSTALL: 5,
+      ADDON_UNINSTALL: 6, // not supported
+      ADDON_UPGRADE: 7,
+      ADDON_DOWNGRADE: 8,
+    };
+
+    const aomStartup = Cc["@mozilla.org/addons/addon-manager-startup;1"].getService(Ci.amIAddonManagerStartup);
+    const resProto = Cc["@mozilla.org/network/protocol;1?name=resource"].getService(Ci.nsISubstitutingProtocolHandler);
+
+    let self = this;
+
+    // TabMonitor to detect opening of tabs, to setup the options button in the add-on manager.
+    this.tabMonitor = {
+      onTabTitleChanged(tab) { },
+      onTabClosing(tab) { },
+      onTabPersist(tab) { },
+      onTabRestored(tab) { },
+      onTabSwitched(aNewTab, aOldTab) { },
+      async onTabOpened(tab) {
+        if (tab.browser && tab.mode.name == "contentTab") {
+          let { setTimeout } = Services.wm.getMostRecentWindow("mail:3pane");
+          // Instead of registering a load observer, wait until its loaded. Not nice,
+          // but gets aroud a lot of edge cases.
+          while (!tab.pageLoaded) {
+            await new Promise(r => setTimeout(r, 150));
+          }
+          self.setupAddonManager(self.getAddonManagerFromTab(tab));
         }
       },
     };
@@ -343,8 +722,8 @@
           let window = context.extension.windowManager.get(windowId, context).window
           let BL = {}
           BL.extension = self.extension;
-          BL.messenger = self.getMessenger(self.context);
-          window.openDialog(self.pathToOptionsPage, "AddonOptions", "chrome,resizable,centerscreen", BL);        
+          BL.messenger = getMessenger(self.context);
+          window.openDialog(self.pathToOptionsPage, "AddonOptions", "chrome,resizable,centerscreen", BL);
         },
 
         registerChromeUrl(data) {
@@ -382,7 +761,7 @@
           self.resourceData = resourceData;
         },
 
-        registerBootstrapScript: async function(aPath) {
+        registerBootstrapScript: async function (aPath) {
           self.pathToBootstrapScript = aPath.startsWith("chrome://")
             ? aPath
             : context.extension.rootURI.resolve(aPath);
@@ -404,32 +783,30 @@
           } catch (e) {
             Components.utils.reportError(e)
           }
-          
+
           // Register window listener for main TB window
           if (self.pathToOptionsPage) {
             ExtensionSupport.registerWindowListener("injectListener_" + self.uniqueRandomID, {
               chromeURLs: [
                 "chrome://messenger/content/messenger.xul",
-                "chrome://messenger/content/messenger.xhtml",              
+                "chrome://messenger/content/messenger.xhtml",
               ],
               async onLoadWindow(window) {
-                if (self.getThunderbirdVersion().major < 78) {
+                if (getThunderbirdVersion().major < 78) {
                   let element_addonPrefs = window.document.getElementById(self.menu_addonPrefs_id);
                   element_addonPrefs.addEventListener("popupshowing", self);
                 } else {
-                  // Setup the options button/menu in the add-on manager, if it is already open.
-                  self.setupAddonManager(
-                    self.getAddonManagerFromWindow(window),
-                    true
-                  );
                   // Add a tabmonitor, to be able to setup the options button/menu in the add-on manager.
                   self.getTabMail(window).registerTabMonitor(self.tabMonitor);
                   window[self.uniqueRandomID] = {};
                   window[self.uniqueRandomID].hasTabMonitor = true;
+                  // Setup the options button/menu in the add-on manager, if it is already open.
+                  let managerWindow = await self.getAddonManagerFromWindowWaitForLoad(window);
+                  self.setupAddonManager(managerWindow, true);
                 }
               },
 
-              onUnloadWindow(window) {          
+              onUnloadWindow(window) {
               }
             });
           }
@@ -442,11 +819,11 @@
     if (isAppShutdown) {
       return; // the application gets unloaded anyway
     }
-    
+
     //remove our entry in the add-on options menu
     if (this.pathToOptionsPage) {
       for (let window of Services.wm.getEnumerator("mail:3pane")) {
-        if (this.getThunderbirdVersion().major < 78) {
+        if (getThunderbirdVersion().major < 78) {
           let element_addonPrefs = window.document.getElementById(this.menu_addonPrefs_id);
           element_addonPrefs.removeEventListener("popupshowing", this);
           // Remove our entry.
@@ -454,19 +831,24 @@
           if (entry) entry.remove();
           // Do we have to unhide the noPrefsElement?
           if (element_addonPrefs.children.length == 1) {
-              let noPrefsElem = element_addonPrefs.querySelector('[disabled="true"]');
-              noPrefsElem.style.display = "inline";
-          }              
+            let noPrefsElem = element_addonPrefs.querySelector('[disabled="true"]');
+            noPrefsElem.style.display = "inline";
+          }
         } else {
           // Remove event listener for addon manager view changes
           let managerWindow = this.getAddonManagerFromWindow(window);
-          if (managerWindow && managerWindow[this.uniqueRandomID] && managerWindow[this.uniqueRandomID].hasAddonManagerEventListeners) {
+          if (
+            managerWindow && 
+            managerWindow[this.uniqueRandomID] && 
+            managerWindow[this.uniqueRandomID].hasAddonManagerEventListeners
+          ) {
             managerWindow.document.removeEventListener("ViewChanged", this);
             managerWindow.document.removeEventListener("update", this);
             managerWindow.document.removeEventListener("view-loaded", this);
-            
+            managerWindow[this.uniqueRandomID].hasAddonManagerEventListeners = false;
+
             let cards = this.getCards(managerWindow);
-            if (this.getThunderbirdVersion().major < 88) {
+            if (getThunderbirdVersion().major < 88) {
               // Remove options menu in 78-87
               for (let card of cards) {
                 let addonOptionsLegacyEntry = card.querySelector(".extension-options-legacy");
@@ -483,13 +865,13 @@
               }
             }
           }
-          
+
           // Remove tabmonitor
           if (window[this.uniqueRandomID].hasTabMonitor) {
             this.getTabMail(window).unregisterTabMonitor(this.tabMonitor);
             window[this.uniqueRandomID].hasTabMonitor = false;
           }
-                    
+
         }
       }
       // Stop listening for new windows.
@@ -529,3 +911,7 @@
     console.log("BootstrapLoader for " + this.extension.id + " unloaded!");
   }
 };
+
+var BootstrapLoader = getThunderbirdVersion().major < 111
+  ? BootstrapLoader_102
+  : BootstrapLoader_115;
diff -Nru tbsync-4.3/content/api/BootstrapLoader/schema.json tbsync-4.7/content/api/BootstrapLoader/schema.json
--- tbsync-4.3/content/api/BootstrapLoader/schema.json	2022-10-12 21:40:25.000000000 +0200
+++ tbsync-4.7/content/api/BootstrapLoader/schema.json	2023-08-29 22:22:49.000000000 +0200
@@ -35,7 +35,7 @@
             "type": "array",
             "items": {
               "type": "array",
-              "items" : {
+              "items": {
                 "type": "string"
               }
             },
@@ -58,4 +58,4 @@
       }
     ]
   }
-]
+]
\ Kein Zeilenumbruch am Dateiende.
diff -Nru tbsync-4.3/content/manager/accounts.js tbsync-4.7/content/manager/accounts.js
--- tbsync-4.3/content/manager/accounts.js	2022-10-12 21:40:25.000000000 +0200
+++ tbsync-4.7/content/manager/accounts.js	2023-08-29 22:22:49.000000000 +0200
@@ -370,9 +370,9 @@
           
           //add icon (use "install provider" icon, if provider not installed)
           let itemType = document.createXULElement("image");
-          itemType.setAttribute("width", "16");
-          itemType.setAttribute("height", "16");
-          itemType.setAttribute("style", "margin: 0px 0px 0px 5px;");
+          //itemType.setAttribute("width", "16");
+          //itemType.setAttribute("height", "16");
+          itemType.setAttribute("style", "margin: 0px 0px 0px 5px; width:16px; height:16px");
           newListItem.appendChild(itemType);
 
           //add account name
@@ -382,9 +382,9 @@
 
           //add account status
           let itemStatus = document.createXULElement("image");
-          itemStatus.setAttribute("width", "16");
-          itemStatus.setAttribute("height", "16");
-          itemStatus.setAttribute("style", "margin: 0px 5px;");
+          //itemStatus.setAttribute("width", "16");
+          //itemStatus.setAttribute("height", "16");
+          itemStatus.setAttribute("style", "margin: 0px 5px; width:16px; height:16px");
           newListItem.appendChild(itemStatus);
           
           accountsList.appendChild(newListItem);
diff -Nru tbsync-4.3/content/manager/accounts.xhtml tbsync-4.7/content/manager/accounts.xhtml
--- tbsync-4.3/content/manager/accounts.xhtml	2022-10-12 21:40:25.000000000 +0200
+++ tbsync-4.7/content/manager/accounts.xhtml	2023-08-29 22:22:49.000000000 +0200
@@ -45,9 +45,9 @@
             <richlistbox 
                 id="tbSyncAccounts.accounts"
                 flex="1"
-                style="margin: 0 1px"
+                style="margin: 0 1px; width: 200px;"
                 seltype="single"
-                context="tbsync.accountmanger.ContextMenu"                
+                context="tbsync.accountmanger.ContextMenu"
                 onkeypress="if (event.keyCode == 46) {tbSyncAccounts.deleteAccount();}"
                 onselect="tbSyncAccounts.loadSelectedAccount();">
                 <listheader style="border-bottom: 1px solid lightgrey;">
diff -Nru tbsync-4.3/content/manager/editAccount.js tbsync-4.7/content/manager/editAccount.js
--- tbsync-4.3/content/manager/editAccount.js	2022-10-12 21:40:25.000000000 +0200
+++ tbsync-4.7/content/manager/editAccount.js	2023-08-29 22:22:49.000000000 +0200
@@ -9,7 +9,6 @@
  "use strict";
 
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-var { OS }  =ChromeUtils.import("resource://gre/modules/osfile.jsm");
 var { TbSync } = ChromeUtils.import("chrome://tbsync/content/tbsync.jsm");
 
 var tbSyncAccountSettings = {
@@ -104,7 +103,7 @@
     document.getElementById('tbsync.accountsettings.frame').hidden = false;	    
     tbSyncAccountSettings.updateFolderList();      
 
-    if (OS.Constants.Sys.Name == "Darwin") { //we might need to find a way to detect MacOS like styling, other themes move the header bar into the tabpanel as well
+    if (Services.appinfo.OS == "Darwin") { //we might need to find a way to detect MacOS like styling, other themes move the header bar into the tabpanel as well
       document.getElementById('manager.tabpanels').style["padding-top"] = "3ex";
     }
   },
diff -Nru tbsync-4.3/content/manager/editAccount.xhtml tbsync-4.7/content/manager/editAccount.xhtml
--- tbsync-4.3/content/manager/editAccount.xhtml	2022-10-12 21:40:25.000000000 +0200
+++ tbsync-4.7/content/manager/editAccount.xhtml	2023-08-29 22:22:49.000000000 +0200
@@ -39,11 +39,11 @@
                     <label class="header" style="margin-left:0; margin-bottom:1ex;" value="__TBSYNCMSG_manager.tabs.status.general__" />
                     <checkbox id="tbsync.accountsettings.enabled" oncommand="tbSyncAccountSettings.toggleEnableState(this);" label="__TBSYNCMSG_manager.tabs.status.enableThisAccount__"  />
 
-                    <vbox class="showIfEnabled">
+                    <vbox class="showIfEnabled" style="height:100px; overflow-x: hidden; overflow-y:hidden">
                         <hbox flex="1">
                             <vbox flex="1">
                                 <label class="header" style="margin-left:0; margin-bottom:1ex; margin-top:2ex;" value="__TBSYNCMSG_manager.status__" />
-                                <description flex="1" id="syncstate"></description>
+                                <description id="syncstate"></description>
                             </vbox>
                             <vbox flex="0">
                                 <label class="header" style="margin-left:0; margin-bottom:1ex; margin-top:1ex; visibility: hidden" value="nix" />
@@ -58,8 +58,7 @@
                             <description>__TBSYNCMSG_manager.tabs.status.resources.intro__</description>
                             <richlistbox 
                               id="tbsync.accountsettings.folderlist"
-                              flex="1"
-                              style="margin: 0 1px 1px 1ex;padding:0;"
+                              style="margin: 0 1px 1px 1ex;padding:0; height:225px; overflow-x: hidden;"
                               context="tbsync.accountsettings.FolderListContextMenu"
                               seltype="single">
                                 <listheader id="tbsync.accountsettings.folderlist.header" style="border-bottom: 1px solid lightgrey;">
diff -Nru tbsync-4.3/content/manager/eventlog/eventlog.js tbsync-4.7/content/manager/eventlog/eventlog.js
--- tbsync-4.3/content/manager/eventlog/eventlog.js	2022-10-12 21:40:25.000000000 +0200
+++ tbsync-4.7/content/manager/eventlog/eventlog.js	2023-08-29 22:22:49.000000000 +0200
@@ -25,12 +25,10 @@
       let item = tbSyncEventLog.addLogEntry(events[i]);
       eventlog.appendChild(item);
     }
-
     eventlog.hidden = false;
     eventlog.ensureIndexIsVisible(eventlog.getRowCount()-1);
-    document.documentElement.getButton("extra1").onclick = tbSyncEventLog.onclear;
-    document.documentElement.getButton("extra1").label = TbSync.getString("eventlog.clear");
-    document.documentElement.getButton("cancel").label = TbSync.getString("eventlog.close");
+    document.getElementById("tbsync.eventlog.clear").addEventListener("click", tbSyncEventLog.onclear);
+    document.getElementById("tbsync.eventlog.close").addEventListener("click", () => window.close());
   },
 
   onclear: function () {
@@ -71,7 +69,8 @@
     
     //left column
     let leftColumn = document.createXULElement("vbox");
-    leftColumn.setAttribute("width", "24");
+    //leftColumn.setAttribute("width", "24");
+    leftColumn.setAttribute("style", "width: 24px;");
 
     let image = document.createXULElement("image");
     let src = entry.type.endsWith("_rerun") ? "sync" : entry.type;
diff -Nru tbsync-4.3/content/manager/eventlog/eventlog.xhtml tbsync-4.7/content/manager/eventlog/eventlog.xhtml
--- tbsync-4.3/content/manager/eventlog/eventlog.xhtml	2022-10-12 21:40:25.000000000 +0200
+++ tbsync-4.7/content/manager/eventlog/eventlog.xhtml	2023-08-29 22:22:49.000000000 +0200
@@ -1,11 +1,8 @@
 <?xml version="1.0"?>
 <?xml-stylesheet href="chrome://global/skin/global.css" type="text/css"?>
 
-<dialog
-    width="600"
-    height="400"
+<window
     title="__TBSYNCMSG_eventlog.title__"
-    buttons="cancel, extra1"
     onload="tbSyncEventLog.onload();"
     onunload="tbSyncEventLog.onunload();"
     xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; >
@@ -14,6 +11,11 @@
     <script type="text/javascript" src="chrome://tbsync/content/scripts/locales.js" /> 
 
     <vbox flex="1">
-        <richlistbox id="tbsync.eventlog" flex="1" seltype="single" disabled="true"/>
+        <richlistbox id="tbsync.eventlog" style="padding:5px; height:360px" seltype="single" disabled="true"/>
+        <hbox style="padding: 5px">
+            <vbox flex="1"></vbox>
+            <button id="tbsync.eventlog.clear" label="__TBSYNCMSG_eventlog.clear__" />
+            <button id="tbsync.eventlog.close" label="__TBSYNCMSG_eventlog.close__" />
+        </hbox>
     </vbox>
-</dialog>
+</window>
diff -Nru tbsync-4.3/content/modules/db.js tbsync-4.7/content/modules/db.js
--- tbsync-4.3/content/modules/db.js	2022-10-12 21:40:25.000000000 +0200
+++ tbsync-4.7/content/modules/db.js	2023-08-29 22:22:49.000000000 +0200
@@ -41,12 +41,11 @@
       this.files[f].write = new DeferredTask(() => this.writeAsync(f), 6000);
       
       try {
-        let data = await OS.File.read(TbSync.io.getAbsolutePath(this.files[f].name));
-        this[f] = JSON.parse(TbSync.decoder.decode(data));
+        this[f] = await IOUtils.readJSON(TbSync.io.getAbsolutePath(this.files[f].name));
         this.files[f].found = true;
       } catch (e) {
         //if there is no file, there is no file...
-        this[f] = JSON.parse(this.files[f].default);                
+        this[f] = JSON.parse(this.files[f].default);
         this.files[f].found = false;
         Components.utils.reportError(e);
       }
@@ -66,8 +65,7 @@
     // try to migrate old accounts file from TB60
     if (!this.files["accounts"].found) {
       try {
-        let data = await OS.File.read(TbSync.io.getAbsolutePath("accounts.json"));
-        let accounts = JSON.parse(TbSync.decoder.decode(data));
+        let accounts = await IOUtils.readJSON(TbSync.io.getAbsolutePath("accounts.json"));
         for (let d of Object.values(accounts.data)) {
           console.log("Migrating: " + JSON.stringify(d));
           
@@ -141,10 +139,7 @@
     }
     
     let filepath = TbSync.io.getAbsolutePath(this.files[f].name);
-    let json = TbSync.encoder.encode(JSON.stringify(this[f]));
-    
-    await OS.File.makeDir(TbSync.io.storageDirectory);
-    await OS.File.writeAtomic(filepath, json, {tmpPath: filepath + ".tmp"});
+    await IOUtils.writeJSON(filepath, this[f]);
   },
 
 
diff -Nru tbsync-4.3/content/modules/io.js tbsync-4.7/content/modules/io.js
--- tbsync-4.3/content/modules/io.js	2022-10-12 21:40:25.000000000 +0200
+++ tbsync-4.7/content/modules/io.js	2023-08-29 22:22:49.000000000 +0200
@@ -10,7 +10,7 @@
  
 var io = {
 
-  storageDirectory : OS.Path.join(OS.Constants.Path.profileDir, "TbSync"),
+  storageDirectory : PathUtils.join(PathUtils.profileDir, "TbSync"),
 
   load: async function () {
   },
@@ -19,7 +19,7 @@
   },
 
   getAbsolutePath: function(filename) {
-    return OS.Path.join(this.storageDirectory, filename);
+    return PathUtils.join(this.storageDirectory, filename);
   },
   
   initFile: function (filename) {
diff -Nru tbsync-4.3/content/modules/lightning.js tbsync-4.7/content/modules/lightning.js
--- tbsync-4.3/content/modules/lightning.js	2022-10-12 21:40:25.000000000 +0200
+++ tbsync-4.7/content/modules/lightning.js	2023-08-29 22:22:49.000000000 +0200
@@ -387,7 +387,7 @@
       if (pretagChangelogWithByServerEntry) {
         tbItem.changelogStatus = "added_by_server";
       }
-      return await this._calendar.adoptItem(tbItem._item);
+      return await this._calendar.addItem(tbItem._item);
     }
     
     async modifyItem(tbNewItem, tbOldItem, pretagChangelogWithByServerEntry = true) {
diff -Nru tbsync-4.3/content/modules/manager.js tbsync-4.7/content/modules/manager.js
--- tbsync-4.3/content/modules/manager.js	2022-10-12 21:40:25.000000000 +0200
+++ tbsync-4.7/content/modules/manager.js	2023-08-29 22:22:49.000000000 +0200
@@ -236,7 +236,8 @@
     if (itemACL) itemHGroup1.appendChild(itemACL);
 
     let itemVGroup1 = document.createXULElement("vbox");
-    itemVGroup1.setAttribute("width", "93");
+    //itemVGroup1.setAttribute("width", "93");
+    itemVGroup1.setAttribute("style", "width: 93px");
     itemVGroup1.appendChild(itemHGroup1);
 
     //group2
@@ -246,8 +247,8 @@
     itemHGroup2.appendChild(itemLabel);
 
     let itemVGroup2 = document.createXULElement("vbox");
-    itemVGroup2.setAttribute("width", "150");
-    itemVGroup2.setAttribute("style", "padding: 3px");
+    //itemVGroup2.setAttribute("width", "150");
+    itemVGroup2.setAttribute("style", "padding: 3px; width: 150px");
     itemVGroup2.appendChild(itemHGroup2);
 
     //group3
@@ -256,8 +257,8 @@
     itemHGroup3.appendChild(itemStatus);
 
     let itemVGroup3 = document.createXULElement("vbox");
-    itemVGroup3.setAttribute("width", "250");
-    itemVGroup3.setAttribute("style", "padding: 3px");
+    //itemVGroup3.setAttribute("width", "250");
+    itemVGroup3.setAttribute("style", "padding: 3px; width: 250px");
     itemVGroup3.appendChild(itemHGroup3);
 
     //final row
diff -Nru tbsync-4.3/content/passwordPrompt/passwordPrompt.css tbsync-4.7/content/passwordPrompt/passwordPrompt.css
--- tbsync-4.3/content/passwordPrompt/passwordPrompt.css	1970-01-01 01:00:00.000000000 +0100
+++ tbsync-4.7/content/passwordPrompt/passwordPrompt.css	2023-08-29 22:22:49.000000000 +0200
@@ -0,0 +1,13 @@
+  .grid-container {
+    display: grid;
+    grid-template-columns: auto 1fr;
+    grid-template-rows: auto auto auto;
+    gap: 1px;
+    width: 250px;
+    margin: 2ex auto;
+  }
+
+  .grid-item {
+    padding: 2px;
+    text-align: left;
+  }
diff -Nru tbsync-4.3/content/passwordPrompt/passwordPrompt.js tbsync-4.7/content/passwordPrompt/passwordPrompt.js
--- tbsync-4.3/content/passwordPrompt/passwordPrompt.js	2022-10-12 21:40:25.000000000 +0200
+++ tbsync-4.7/content/passwordPrompt/passwordPrompt.js	2023-08-29 22:22:49.000000000 +0200
@@ -23,19 +23,21 @@
     this.userfield.value = data.username;
     this.userfield.disabled = data.usernameLocked;
 
-    document.addEventListener("dialogaccept",  tbSyncPassword.doOK.bind(this));
     window.addEventListener("unload", tbSyncPassword.doCANCEL.bind(this));
     document.getElementById("tbsync.password").focus();
+    document.getElementById("tbsync.password.ok").addEventListener("click", tbSyncPassword.doOK.bind(this));
+    document.getElementById("tbsync.password.cancel").addEventListener("click", () => window.close());
   },
 
-  doOK: function (event) {        
+  doOK: function (event) {
     if (!this.resolved) {
       this.resolved = true
       this.resolve({username: this.userfield.value, password: this.passfield.value});
+      window.close();
     }
   },
   
-  doCANCEL: function (event) {        
+  doCANCEL: function (event) {
     if (!this.resolved) {
       this.resolved = true
       this.resolve(false);
diff -Nru tbsync-4.3/content/passwordPrompt/passwordPrompt.xhtml tbsync-4.7/content/passwordPrompt/passwordPrompt.xhtml
--- tbsync-4.3/content/passwordPrompt/passwordPrompt.xhtml	2022-10-12 21:40:25.000000000 +0200
+++ tbsync-4.7/content/passwordPrompt/passwordPrompt.xhtml	2023-08-29 22:22:49.000000000 +0200
@@ -1,38 +1,32 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <?xml-stylesheet href="chrome://global/skin/global.css" type="text/css"?>
+<?xml-stylesheet href="chrome://tbsync/content/passwordPrompt/passwordPrompt.css" type="text/css"?>
 
-<dialog
+<window
     xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
     xmlns:html="http://www.w3.org/1999/xhtml";
     title="__TBSYNCMSG_password.title__"
-    buttons="accept,cancel"
     onload="tbSyncPassword.onload();">
 
     <script type="application/javascript" src="chrome://tbsync/content/passwordPrompt/passwordPrompt.js"/>
     <script type="text/javascript" src="chrome://tbsync/content/scripts/locales.js" /> 
 
-    <vbox>
-        <description style="width: 350px;">__TBSYNCMSG_password.description__</description>
-        <grid style="margin:1ex;">
-            <columns>
-                <column flex="0"/>
-                <column flex="1"/>
-            </columns>
-            <rows>
-                <row style="margin-bottom:1ex;">
-                    <label value="__TBSYNCMSG_password.account__"/>
-                    <label class="header"  id="tbsync.account" />
-                </row>
-                <row align="center">
-                    <label value="__TBSYNCMSG_password.user__"/>
-                    <html:input id="tbsync.user" />
-                </row>
-                <row align="center">
-                    <label value="__TBSYNCMSG_password.password__"/>
-                    <html:input type="password" id="tbsync.password"/>
-                </row>
-            </rows>
-        </grid>
+    <vbox flex="1">
+        <description style="padding: 5px; width: 350px;">__TBSYNCMSG_password.description__</description>
+
+        <html:div class="grid-container">
+            <html:div class="grid-item"><label value="__TBSYNCMSG_password.account__"/></html:div>
+            <html:div class="grid-item"><label class="header"  id="tbsync.account" /></html:div>
+            <html:div class="grid-item"><label value="__TBSYNCMSG_password.user__"/></html:div>
+            <html:div class="grid-item"><html:input id="tbsync.user" /></html:div>
+            <html:div class="grid-item"><label value="__TBSYNCMSG_password.password__"/></html:div>
+            <html:div class="grid-item"><html:input type="password" id="tbsync.password"/></html:div>
+        </html:div>
+        <hbox style="padding: 5px">
+            <vbox flex="1"></vbox>
+            <button id="tbsync.password.ok" label="__TBSYNCMSG_password.ok__" />
+            <button id="tbsync.password.cancel" label="__TBSYNCMSG_password.cancel__" />
+        </hbox>
     </vbox>
 
-</dialog>
+</window>
diff -Nru tbsync-4.3/content/tbsync.jsm tbsync-4.7/content/tbsync.jsm
--- tbsync-4.3/content/tbsync.jsm	2022-10-12 21:40:25.000000000 +0200
+++ tbsync-4.7/content/tbsync.jsm	2023-08-29 22:22:49.000000000 +0200
@@ -12,7 +12,6 @@
 
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 var { FileUtils } = ChromeUtils.import("resource://gre/modules/FileUtils.jsm");
-var { OS }  =ChromeUtils.import("resource://gre/modules/osfile.jsm");
 var { AddonManager } = ChromeUtils.import("resource://gre/modules/AddonManager.jsm");
 var { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
 var { MailServices } = ChromeUtils.import("resource:///modules/MailServices.jsm");
@@ -53,7 +52,7 @@
     this.dump("TbSync init","Start (" + this.addon.version.toString() + ")");
 
     //print information about Thunderbird version and OS
-    this.dump(Services.appinfo.name, Services.appinfo.version + " on " + OS.Constants.Sys.Name);
+    this.dump(Services.appinfo.name, Services.appinfo.version + " on " + Services.appinfo.OS);
 
     // register modules to be used by TbSync
     this.modules.push({name: "db", state: 0});
diff -Nru tbsync-4.3/debian/changelog tbsync-4.7/debian/changelog
--- tbsync-4.3/debian/changelog	2022-10-14 13:32:30.000000000 +0200
+++ tbsync-4.7/debian/changelog	2023-10-14 09:22:21.000000000 +0200
@@ -1,3 +1,29 @@
+tbsync (4.7-1~deb12u1) bookworm; urgency=medium
+
+  [ Mechtilde ]
+  * [f9e272f] Adjust version of dependencies
+  * Prepared for release in bookworm (proposed-updates)
+
+ -- Mechtilde Stehmann <mechti...@debian.org>  Sat, 14 Oct 2023 09:22:21 +0200
+
+tbsync (4.7-1) unstable; urgency=medium
+
+  [ Mechtilde ]
+  * [c727b2e] New upstream version 4.7
+  * [3187154] Compression is now tar.gz
+
+ -- Mechtilde Stehmann <mechti...@debian.org>  Tue, 12 Sep 2023 19:31:30 +0200
+
+tbsync (4.3+git20230524+9459652-1) experimental; urgency=medium
+
+  [ Mechtilde ]
+  * [70d9fd8] New upstream version 4.3+git20230524+9459652
+              Made it fit for thunderbird 115.*
+  * [70d9fd8] New upstream version 4.3+git20230524+9459652
+  * [6321440] Changed coompression for zip file
+
+ -- Mechtilde Stehmann <mechti...@debian.org>  Wed, 26 Jul 2023 18:08:25 +0200
+
 tbsync (4.3-1) unstable; urgency=medium
 
   [ Mechtilde ]
diff -Nru tbsync-4.3/debian/control tbsync-4.7/debian/control
--- tbsync-4.3/debian/control	2022-09-22 19:40:48.000000000 +0200
+++ tbsync-4.7/debian/control	2023-10-11 20:36:34.000000000 +0200
@@ -13,9 +13,9 @@
 Package: webext-tbsync
 Architecture: all
 Depends: ${misc:Depends}
- , thunderbird (>= 1:102.2)
-Recommends: webext-dav4tbsync (>= 4.0)
- , webext-eas4tbsync (>= 2.0)
+ , thunderbird (>= 1:115.3)
+Recommends: webext-dav4tbsync (>= 4.7)
+ , webext-eas4tbsync (>= 4.7)
 Description: Thunderbird/Lightning Add-On to support MS Exchange Calendar etc.
  Synchronize Exchange ActiveSync accounts (contacts, tasks and
  calendars) to Thunderbird, supports Office 365, Outlook.com,
diff -Nru tbsync-4.3/debian/gbp.conf tbsync-4.7/debian/gbp.conf
--- tbsync-4.3/debian/gbp.conf	2022-04-17 13:18:05.000000000 +0200
+++ tbsync-4.7/debian/gbp.conf	2023-09-12 19:11:02.000000000 +0200
@@ -4,7 +4,7 @@
 # use pristine-tar:
 pristine-tar = True
 # generate gz compressed orig file
-compression = gz
+# compression = xz
 debian-branch = debian/sid
 upstream-branch = upstream
 
diff -Nru tbsync-4.3/_locales/bg/messages.json tbsync-4.7/_locales/bg/messages.json
--- tbsync-4.3/_locales/bg/messages.json	2022-10-12 21:40:25.000000000 +0200
+++ tbsync-4.7/_locales/bg/messages.json	2023-08-29 22:22:49.000000000 +0200
@@ -355,5 +355,11 @@
     },
     "toolbar.tooltiptext": {
         "message": "Синхронизирай информацията от всички TbSync регистрации със сървърите"
+    },
+    "password.ok": {
+        "message": "ОК"
+    },
+    "password.cancel": {
+        "message": "Отказ"
     }
-}
\ Kein Zeilenumbruch am Dateiende.
+}
diff -Nru tbsync-4.3/_locales/cs/messages.json tbsync-4.7/_locales/cs/messages.json
--- tbsync-4.3/_locales/cs/messages.json	2022-10-12 21:40:25.000000000 +0200
+++ tbsync-4.7/_locales/cs/messages.json	2023-08-29 22:22:49.000000000 +0200
@@ -355,5 +355,11 @@
     },
     "toolbar.tooltiptext": {
         "message": "Synchronizovat poslední změny"
+    },
+    "password.ok": {
+        "message": "OK"
+    },
+    "password.cancel": {
+        "message": "Zrušit"
     }
-}
\ Kein Zeilenumbruch am Dateiende.
+}
diff -Nru tbsync-4.3/_locales/de/messages.json tbsync-4.7/_locales/de/messages.json
--- tbsync-4.3/_locales/de/messages.json	2022-10-12 21:40:25.000000000 +0200
+++ tbsync-4.7/_locales/de/messages.json	2023-08-29 22:22:49.000000000 +0200
@@ -3,28 +3,28 @@
         "message": "Um diesen Fehler zu beheben, können Sie einen Fehlerbericht an den Entwickler von TbSync schicken. Soll der Fehlerbericht jetzt angefertigt werden?"
     },
     "NoDebugLog": {
-        "message": "Es liegen keine aussagekräftigen Debug-Meldungen vor. Bitte aktivieren Sie den Debug-Modus, starten Thunderbird neu und wiederholen dann alle Schritte um das fehlerhafte Verhalten zu reproduzieren."
+        "message": "Es liegen keine aussagekräftigen Debug-Meldungen vor. Bitte aktivieren Sie den Debug-Modus, starten Thunderbird neu und wiederholen dann alle Schritte, um das fehlerhafte Verhalten zu reproduzieren."
     },
     "OopsMessage": {
-        "message": "Oops! TbSync konnte nicht starten!"
+        "message": "Hoppla! TbSync konnte nicht starten!"
     },
     "RestartThunderbirdAndTryAgain": {
-        "message": "Der TbSync Debug-Modus wurde aktiviert, bitte starten Sie Thunderbird neu und versuchen Sie dann noch einmal TbSync zu öffnen."
+        "message": "Das TbSync-Debug-Protokoll wurde eingeschaltet. Bitte starten Sie Thunderbird neu, und versuchen Sie dann noch einmal, TbSync zu öffnen!"
     },
     "UnableToTraceError": {
-        "message": "Es ist im Augenblick nicht möglich, diesen Fehler zu untersuchen, da der TbSync Debug-Modus nicht aktiviert ist. Soll der Debug-Modus aktiviert werden, damit dieser Fehler untersucht und behoben werden kann?"
+        "message": "Dieser Fehler kann nicht untersucht werden, solange das Debug-Protokoll deaktiviert ist. Soll das Protokoll jetzt aktiviert werden, damit dieser Fehler untersucht und behoben werden kann?"
     },
     "accountacctions.delete": {
-        "message": "Konto '##accountname##' löschen"
+        "message": "Konto „##accountname##” löschen"
     },
     "accountacctions.disable": {
         "message": "Konto '##accountname##' deaktivieren"
     },
     "accountacctions.enable": {
-        "message": "Konto '##accountname##' aktivieren & Server kontaktieren"
+        "message": "Konto „##accountname##” aktivieren und Server kontaktieren"
     },
     "accountacctions.sync": {
-        "message": "Konto '##accountname##' synchronisieren"
+        "message": "Konto „##accountname##” synchronisieren"
     },
     "addressbook.searchall": {
         "message": "Alle Adressbücher durchsuchen"
@@ -60,25 +60,25 @@
         "message": "Leerlauf"
     },
     "installProvider.header": {
-        "message": "Provider '##replace.1##' für TbSync ist noch nicht installiert."
+        "message": "Provider „##replace.1##” für TbSync ist noch nicht installiert."
     },
     "manager.AccountActions": {
-        "message": "Konto Aktionen"
+        "message": "Konto-Aktionen"
     },
     "manager.AddAccount": {
-        "message": "Neues Konto hinzufügen"
+        "message": "Konto hinzufügen"
     },
     "manager.DeleteAccount": {
-        "message": "Konto löschen"
+        "message": "Konto entfernen"
     },
     "manager.DisableAccount": {
         "message": "Konto deaktivieren"
     },
     "manager.EnableAccount": {
-        "message": "Konto aktivieren & mit dem Server verbinden"
+        "message": "Konto aktivieren und mit dem Server verbinden"
     },
     "manager.RetryConnectAccount": {
-        "message": "Erneut versuchen mit dem Server zu verbinden"
+        "message": "Erneut versuchen, mit dem Server zu verbinden"
     },
     "manager.ShowEventLog": {
         "message": "Ereignisprotokoll anzeigen"
@@ -96,10 +96,10 @@
         "message": "Kontoeinstellungen"
     },
     "manager.catman.text": {
-        "message": "TbSync synchronisiert auch Kontaktkategorien, die einen effizienten Ersatz für die nicht synchronisierbaren Kontaktlisten darstellen. Um diese im Thunderbird Adressbuch zu nutzen, können Sie das Add-On 'Category Manager' installieren. Dieses Add-On ermöglicht die Verwaltung überlappender kategoriebasierter Kontaktgruppen und stellt eine Reihe anderer kategoriespezifischer Funktionen bereit. Es kann aus dem offiziellen Mozilla Add-On Repository heruntergeladen werden:"
+        "message": "TbSync synchronisiert auch Kontaktkategorien, die einen effizienten Ersatz für die nicht synchronisierbaren Kontaktlisten darstellen. Um diese im Thunderbird-Adressbuch zu nutzen, können Sie das Add-On „Category Manager” installieren. Dieses Add-On ermöglicht die Verwaltung überlappender kategoriebasierter Kontaktgruppen und stellt eine Reihe anderer kategoriespezifischer Funktionen bereit. Es kann aus dem offiziellen Mozilla Add-On Repository heruntergeladen werden:"
     },
     "manager.community": {
-        "message": "Community"
+        "message": "Nutzergemeinschaft"
     },
     "manager.connecting": {
         "message": "Verbindung wird hergestellt"
@@ -120,7 +120,7 @@
         "message": "Aktiviert: Protokolliert alle Fehler"
     },
     "manager.help.debuglevel.2": {
-        "message": "Aktiviert: Protokolliert alle gesendeten & empfangenen Daten"
+        "message": "Aktiviert: Protokolliert alle gesendeten und empfangenen Daten"
     },
     "manager.help.debuglevel.3": {
         "message": "Aktiviert: Protokolliert alle Daten und einige interne Debug-Werte"
@@ -138,25 +138,25 @@
         "message": "Benötigen Sie Hilfe?"
     },
     "manager.help.viewdebuglog": {
-        "message": "Debug-Log anzeigen"
+        "message": "Debug-Protokoll anzeigen"
     },
     "manager.help.wiki": {
-        "message": "Besuchen Sie die Wikiseiten des TbSync Projektes, diese beinhalten zusätzliche Informationen, Benutzeranleitungen und detaillierte Konfigurationsbeschreibungen."
+        "message": "Besuchen Sie die Wikiseiten des TbSync-Projekts, diese enthalten zusätzliche Informationen, Benutzeranleitungen und detaillierte Konfigurationsbeschreibungen."
     },
     "manager.installprovider.link": {
-        "message": "Klicken Sie auf den folgenden Link, um die Informationsseite des fehlenden Provider aufzurufen. Auf dieser Seite finden Sie weitere Informationen zu dem Provider und haben die Möglichkeit, diesen zu installieren:"
+        "message": "Klicken Sie auf den folgenden Link, um die Informationsseite des fehlenden Synchronisations-Providers aufzurufen. Dort finden Sie weitere Informationen dazu und haben die Möglichkeit, diesen zu installieren:"
     },
     "manager.installprovider.warning": {
-        "message": "Dieser Provider stammt nicht aus dem offiziellen Thunderbird Add-On Verzeichnis und wurde demnach nicht von Thunderbird-Mitarbeitern überprüft. Dieser Provider könnte schlimme Dinge mit Ihrem System anstellen. Benutzung auf eigene Gefahr."
+        "message": "Dieser Provider stammt nicht aus der offiziellen Thunderbird-Add-On-Sammlung und wurde demnach nicht von Thunderbird-Mitarbeitern überprüft. Es könnte sich um Schad-Software handeln, deshalb verwenden Sie es auf eigene Gefahr."
     },
     "manager.lockedsettings.description": {
         "message": "Um Synchronisierungsfehler zu vermeiden, können einige Einstellungen nicht bearbeitet werden, während das Konto aktiviert ist."
     },
     "manager.missingprovider": {
-        "message": "Dieses Konto benötigt den ##provider## Synchronisationsprovider, der zur Zeit aber nicht installiert ist."
+        "message": "Dieses Konto benötigt den ##provider##-Synchronisations-Provider, noch nicht installiert ist."
     },
     "manager.noaccounts": {
-        "message": "Es sind aktuell noch keine Konten konfiguriert."
+        "message": "Es sind noch keine Konten definiert."
     },
     "manager.provider": {
         "message": "Provider installieren"
@@ -174,13 +174,13 @@
         "message": "Status"
     },
     "manager.supporter.contributors": {
-        "message": "Mitwirkende & Übersetzer"
+        "message": "Mitwirkende und Übersetzer"
     },
     "manager.supporter.details": {
         "message": "Details"
     },
     "manager.supporter.sponsors": {
-        "message": "Sponsoren von Test-Accounts"
+        "message": "Sponsoren von Testkonten"
     },
     "manager.tabs.status": {
         "message": "Synchronisationsstatus"
@@ -195,7 +195,7 @@
         "message": "Allgemein"
     },
     "manager.tabs.status.never": {
-        "message": "Eine Einstellung von 0 deaktiviert periodische Synchronisation. Push Synchronisation wird noch nicht unterstützt."
+        "message": "Eine Einstellung von 0 deaktiviert periodische Synchronisation. Push-Synchronisation wird noch nicht unterstützt."
     },
     "manager.tabs.status.resources": {
         "message": "Verfügbare Ressourcen"
@@ -207,13 +207,13 @@
         "message": "Jetzt synchronisieren"
     },
     "manager.tabs.status.tryagain": {
-        "message": "Erneut versuchen mit dem Server zu verbinden"
+        "message": "Erneut versuchen, mit dem Server zu verbinden"
     },
     "manager.title": {
         "message": "TbSync Kontoverwaltung"
     },
     "manager.tryagain": {
-        "message": "Erneut versuchen mit dem Server zu verbinden"
+        "message": "Erneut versuchen, mit dem Server zu verbinden"
     },
     "menu.settingslabel": {
         "message": "Synchronisationseinstellungen (TbSync)"
@@ -228,13 +228,13 @@
         "message": "Passwort:"
     },
     "password.title": {
-        "message": "TbSync Anmeldeinformationen"
+        "message": "TbSync-Anmeldeinformationen"
     },
     "password.user": {
-        "message": "Benutzer:"
+        "message": "Nutzer:"
     },
     "popup.opensettings": {
-        "message": "TbSync Kontoverwaltung öffnen"
+        "message": "TbSync-Kontoverwaltung öffnen"
     },
     "prompt.DeleteAccount": {
         "message": "Sind Sie sicher, dass Sie das Konto ##accountName## löschen möchten?"
@@ -243,37 +243,37 @@
         "message": "Sind Sie sicher, dass Sie dieses Konto deaktivieren möchten? Alle lokalen Veränderungen, die noch nicht synchronisiert wurden, gehen dabei verloren!"
     },
     "prompt.Erase": {
-        "message": "Sind Sie sicher, dass Sie dieses Konto eines unbekannten Providers aus der Kontoliste entfernen möchten?"
+        "message": "Sind Sie sicher, dass Sie dieses Konto eines unbekannten Anbieters aus der Kontoliste entfernen möchten?"
     },
     "prompt.Unsubscribe": {
         "message": "Sind Sie sicher, dass Sie dieses Element nicht länger abonnieren möchten? Alle lokalen Veränderungen, die noch nicht synchronisiert wurden, gehen dabei verloren!"
     },
     "status.JavaScriptError": {
-        "message": "Javascript Fehler! Bitte prüfen Sie das Ereignisprotokoll für weitere Details."
+        "message": "Javascript-Fehler! Bitte prüfen Sie das Ereignisprotokoll für weitere Details!"
     },
     "status.OAuthAbortError": {
-        "message": "OAuth 2.0 Authentifizierungsprozess vom Benutzer abgebrochen."
+        "message": "OAuth 2.0-Authentifizierungsprozess vom Nutzer abgebrochen."
     },
     "status.OAuthHttpError": {
-        "message": "OAuth 2.0 Authentifizierungsprozess fehlgeschlagen (HTTP Error ##replace.1##)."
+        "message": "OAuth-2.0-Authentifizierungsprozess fehlgeschlagen (HTTP Error ##replace.1##)."
     },
     "status.OAuthNetworkError": {
-        "message": "Verbindung zum OAuth 2.0 Authentifizierungsserver nicht möglich."
+        "message": "Verbindung zum OAuth-2.0-Authentifizierungsserver nicht möglich."
     },
     "status.OAuthServerError": {
-        "message": " OAuth 2.0 Authentifizierungsserver meldet: ##replace.1##"
+        "message": " OAuth-2.0-Authentifizierungsserver meldet: ##replace.1##"
     },
     "status.aborted": {
         "message": "Nicht synchronisiert"
     },
     "status.apiError": {
-        "message": "API Implementierungsfehler"
+        "message": "API-Implementierungsfehler"
     },
     "status.disabled": {
         "message": "Konto ist deaktiviert, Synchronisation ist ausgeschaltet."
     },
     "status.foldererror": {
-        "message": "Bei mindestens einer Resource trat ein Synchronisationsfehler auf. Bitte prüfen sie das Ereignisprotokoll für weitere Details."
+        "message": "Bei mindestens einer Ressource trat ein Synchronisationsfehler auf. Bitte prüfen Sie das Ereignisprotokoll für weitere Details!"
     },
     "status.modified": {
         "message": "Lokale Änderungen"
@@ -282,10 +282,10 @@
         "message": "Verbindung zum Server fehlgeschlagen (##replace.1##)."
     },
     "status.no-folders-found-on-server": {
-        "message": "Auf dem Server wurden keine Resourcen gefunden."
+        "message": "Auf dem Server wurden keine Ressourcen gefunden."
     },
     "status.notargets": {
-        "message": "Synchronisation abgebrochen da die Elemente zum Synchronisieren nicht erstellt werden konnten."
+        "message": "Synchronisation abgebrochen, da die Elemente zum Synchronisieren nicht erstellt werden konnten."
     },
     "status.notsyncronized": {
         "message": "Konto muss synchronisiert werden."
@@ -294,7 +294,7 @@
         "message": "Warten auf Synchronisation"
     },
     "status.security": {
-        "message": "Fehler beim Aufbau einer sicherern Verbindung. Benutzen Sie eventuell ein selbst signiertes Zertifikat oder ein andersartiges nicht vertrauenswürdiges Zertifikat welches nicht in Thunderbird importiert ist? (##replace.1##)"
+        "message": "Fehler beim Aufbau einer sicheren Verbindung. Benutzen Sie eventuell ein selbst signiertes oder anderweitig nicht vertrauenswürdiges Zertifikat, das nicht in Thunderbird importiert ist? (##replace.1##)"
     },
     "status.skipped": {
         "message": "Nicht unterstützt"
@@ -354,6 +354,12 @@
         "message": "Synchronisiere alle TbSync Konten"
     },
     "toolbar.tooltiptext": {
-        "message": "Gleiche alle TbSync Konten mit den Servern ab"
+        "message": "Gleiche alle TbSync-Konten mit den Servern ab"
+    },
+    "password.ok": {
+        "message": "OK"
+    },
+    "password.cancel": {
+        "message": "Abbrechen"
     }
-}
\ Kein Zeilenumbruch am Dateiende.
+}
diff -Nru tbsync-4.3/_locales/en-US/messages.json tbsync-4.7/_locales/en-US/messages.json
--- tbsync-4.3/_locales/en-US/messages.json	2022-10-12 21:40:25.000000000 +0200
+++ tbsync-4.7/_locales/en-US/messages.json	2023-08-29 22:22:49.000000000 +0200
@@ -355,5 +355,11 @@
     },
     "toolbar.tooltiptext": {
         "message": "Synchronize latest changes"
+    },
+    "password.ok": {
+        "message": "OK"
+    },
+    "password.cancel": {
+        "message": "Cancel"
     }
-}
\ Kein Zeilenumbruch am Dateiende.
+}
diff -Nru tbsync-4.3/_locales/es/messages.json tbsync-4.7/_locales/es/messages.json
--- tbsync-4.3/_locales/es/messages.json	2022-10-12 21:40:25.000000000 +0200
+++ tbsync-4.7/_locales/es/messages.json	2023-08-29 22:22:49.000000000 +0200
@@ -355,5 +355,11 @@
     },
     "toolbar.tooltiptext": {
         "message": "Sincronizar los últimos cambios"
+    },
+    "password.ok": {
+        "message": "Aceptar"
+    },
+    "password.cancel": {
+        "message": "Cancelar"
     }
-}
\ Kein Zeilenumbruch am Dateiende.
+}
diff -Nru tbsync-4.3/_locales/et/messages.json tbsync-4.7/_locales/et/messages.json
--- tbsync-4.3/_locales/et/messages.json	2022-10-12 21:40:25.000000000 +0200
+++ tbsync-4.7/_locales/et/messages.json	2023-08-29 22:22:49.000000000 +0200
@@ -355,5 +355,11 @@
     },
     "toolbar.tooltiptext": {
         "message": "Synchronize latest changes"
+    },
+    "password.ok": {
+        "message": "OK"
+    },
+    "password.cancel": {
+        "message": "Tühista"
     }
-}
\ Kein Zeilenumbruch am Dateiende.
+}
diff -Nru tbsync-4.3/_locales/fr/messages.json tbsync-4.7/_locales/fr/messages.json
--- tbsync-4.3/_locales/fr/messages.json	2022-10-12 21:40:25.000000000 +0200
+++ tbsync-4.7/_locales/fr/messages.json	2023-08-29 22:22:49.000000000 +0200
@@ -355,5 +355,11 @@
     },
     "toolbar.tooltiptext": {
         "message": "Synchroniser les dernières modifications"
+    },
+    "password.ok": {
+        "message": "OK"
+    },
+    "password.cancel": {
+        "message": "Annuler"
     }
-}
\ Kein Zeilenumbruch am Dateiende.
+}
diff -Nru tbsync-4.3/_locales/gl/messages.json tbsync-4.7/_locales/gl/messages.json
--- tbsync-4.3/_locales/gl/messages.json	2022-10-12 21:40:25.000000000 +0200
+++ tbsync-4.7/_locales/gl/messages.json	2023-08-29 22:22:49.000000000 +0200
@@ -141,7 +141,7 @@
         "message": "Ver rexistro de depuración"
     },
     "manager.help.wiki": {
-        "message": "Abrir as páxinas wiki do proxecto TbSync nas que facilitan información adicional, guías e descricións detalladas da configuración."
+        "message": "Abre o wiki do proxecto TbSync no que se facilita información adicional, guías e descricións detalladas da configuración."
     },
     "manager.installprovider.link": {
         "message": "Preme no seguinte enlace para abrir a páxina de información do provedor de sincronización que falta. Aí atoparás máis información sobre o provedor e terás a opción de instalalo:"
@@ -355,5 +355,11 @@
     },
     "toolbar.tooltiptext": {
         "message": "Sincronizar os últimos cambios"
+    },
+    "password.ok": {
+        "message": "Aceptar"
+    },
+    "password.cancel": {
+        "message": "Cancelar"
     }
-}
\ Kein Zeilenumbruch am Dateiende.
+}
diff -Nru tbsync-4.3/_locales/hu/messages.json tbsync-4.7/_locales/hu/messages.json
--- tbsync-4.3/_locales/hu/messages.json	2022-10-12 21:40:25.000000000 +0200
+++ tbsync-4.7/_locales/hu/messages.json	2023-08-29 22:22:49.000000000 +0200
@@ -355,5 +355,11 @@
     },
     "toolbar.tooltiptext": {
         "message": "A legújabb változtatások szinkronizálása"
+    },
+    "password.ok": {
+        "message": "Rendben"
+    },
+    "password.cancel": {
+        "message": "Mégse"
     }
-}
\ Kein Zeilenumbruch am Dateiende.
+}
diff -Nru tbsync-4.3/_locales/it/messages.json tbsync-4.7/_locales/it/messages.json
--- tbsync-4.3/_locales/it/messages.json	2022-10-12 21:40:25.000000000 +0200
+++ tbsync-4.7/_locales/it/messages.json	2023-08-29 22:22:49.000000000 +0200
@@ -355,5 +355,11 @@
     },
     "toolbar.tooltiptext": {
         "message": "Sincronizza le ultime modifiche"
+    },
+    "password.ok": {
+        "message": "OK"
+    },
+    "password.cancel": {
+        "message": "Annulla"
     }
-}
\ Kein Zeilenumbruch am Dateiende.
+}
diff -Nru tbsync-4.3/_locales/ja/messages.json tbsync-4.7/_locales/ja/messages.json
--- tbsync-4.3/_locales/ja/messages.json	2022-10-12 21:40:25.000000000 +0200
+++ tbsync-4.7/_locales/ja/messages.json	2023-08-29 22:22:49.000000000 +0200
@@ -355,5 +355,11 @@
     },
     "toolbar.tooltiptext": {
         "message": "最新の変更を同期"
+    },
+    "password.ok": {
+        "message": "OK"
+    },
+    "password.cancel": {
+        "message": "キャンセル"
     }
-}
\ Kein Zeilenumbruch am Dateiende.
+}
diff -Nru tbsync-4.3/_locales/ko/messages.json tbsync-4.7/_locales/ko/messages.json
--- tbsync-4.3/_locales/ko/messages.json	2022-10-12 21:40:25.000000000 +0200
+++ tbsync-4.7/_locales/ko/messages.json	2023-08-29 22:22:49.000000000 +0200
@@ -355,5 +355,11 @@
     },
     "toolbar.tooltiptext": {
         "message": "Synchronize latest changes"
+    },
+    "password.ok": {
+        "message": "확인"
+    },
+    "password.cancel": {
+        "message": "취소"
     }
-}
\ Kein Zeilenumbruch am Dateiende.
+}
diff -Nru tbsync-4.3/_locales/pl/messages.json tbsync-4.7/_locales/pl/messages.json
--- tbsync-4.3/_locales/pl/messages.json	2022-10-12 21:40:25.000000000 +0200
+++ tbsync-4.7/_locales/pl/messages.json	2023-08-29 22:22:49.000000000 +0200
@@ -355,5 +355,11 @@
     },
     "toolbar.tooltiptext": {
         "message": "Synchronizuj najnowsze zmiany"
+    },
+    "password.ok": {
+        "message": "OK"
+    },
+    "password.cancel": {
+        "message": "Anuluj"
     }
-}
\ Kein Zeilenumbruch am Dateiende.
+}
diff -Nru tbsync-4.3/_locales/pt_BR/messages.json tbsync-4.7/_locales/pt_BR/messages.json
--- tbsync-4.3/_locales/pt_BR/messages.json	2022-10-12 21:40:25.000000000 +0200
+++ tbsync-4.7/_locales/pt_BR/messages.json	2023-08-29 22:22:49.000000000 +0200
@@ -355,5 +355,11 @@
     },
     "toolbar.tooltiptext": {
         "message": "Sincronizar as alterações mais recentes"
+    },
+    "password.ok": {
+        "message": "OK"
+    },
+    "password.cancel": {
+        "message": "Cancelar"
     }
-}
\ Kein Zeilenumbruch am Dateiende.
+}
diff -Nru tbsync-4.3/_locales/ro/messages.json tbsync-4.7/_locales/ro/messages.json
--- tbsync-4.3/_locales/ro/messages.json	2022-10-12 21:40:25.000000000 +0200
+++ tbsync-4.7/_locales/ro/messages.json	2023-08-29 22:22:49.000000000 +0200
@@ -355,5 +355,11 @@
     },
     "toolbar.tooltiptext": {
         "message": "Synchronize latest changes"
+    },
+    "password.ok": {
+        "message": "OK"
+    },
+    "password.cancel": {
+        "message": "Anulare"
     }
-}
\ Kein Zeilenumbruch am Dateiende.
+}
diff -Nru tbsync-4.3/_locales/ru/messages.json tbsync-4.7/_locales/ru/messages.json
--- tbsync-4.3/_locales/ru/messages.json	2022-10-12 21:40:25.000000000 +0200
+++ tbsync-4.7/_locales/ru/messages.json	2023-08-29 22:22:49.000000000 +0200
@@ -355,5 +355,11 @@
     },
     "toolbar.tooltiptext": {
         "message": "Синхронизировать последние изменения"
+    },
+    "password.ok": {
+        "message": "ОК"
+    },
+    "password.cancel": {
+        "message": "Отмена"
     }
-}
\ Kein Zeilenumbruch am Dateiende.
+}
diff -Nru tbsync-4.3/_locales/sv/messages.json tbsync-4.7/_locales/sv/messages.json
--- tbsync-4.3/_locales/sv/messages.json	2022-10-12 21:40:25.000000000 +0200
+++ tbsync-4.7/_locales/sv/messages.json	2023-08-29 22:22:49.000000000 +0200
@@ -355,5 +355,11 @@
     },
     "toolbar.tooltiptext": {
         "message": "Synchronize latest changes"
+    },
+    "password.ok": {
+        "message": "OK"
+    },
+    "password.cancel": {
+        "message": "Avbryt"
     }
-}
\ Kein Zeilenumbruch am Dateiende.
+}
diff -Nru tbsync-4.3/manifest.json tbsync-4.7/manifest.json
--- tbsync-4.3/manifest.json	2022-10-12 21:40:25.000000000 +0200
+++ tbsync-4.7/manifest.json	2023-08-29 22:22:49.000000000 +0200
@@ -3,12 +3,12 @@
     "gecko": {
       "id": "tbs...@jobisoft.de",
       "strict_min_version": "102.3.0",
-      "strict_max_version": "102.*"
+      "strict_max_version": "115.*"
     }
   },
   "manifest_version": 2,
   "name": "TbSync",
-  "version": "4.3",
+  "version": "4.7",
   "author": "John Bieling",
   "homepage_url": "https://github.com/jobisoft/TbSync";,
   "default_locale": "en-US",

Attachment: OpenPGP_signature.asc
Description: OpenPGP digital signature


--- End Message ---
--- Begin Message ---
On Sat, 2023-10-14 at 10:13 +0200, Mechtilde Stehmann wrote:
> This package is an extension to thunderbird. After thunderbird is 
> updated to version 115.* in bookwork it is necessary to update this 
> extension too.
> 

This appears to be the same as #1053918. Closing in favour of the
earlier (just) request.

Regards,

Adam

--- End Message ---

Reply via email to