Package: release.debian.org
Severity: normal
Tags: bookworm
User: release.debian....@packages.debian.org
Usertags: pu
X-Debbugs-Cc: dav4tbs...@packages.debian.org, mechti...@debian.org
Control: affects -1 + src:dav4tbsync

[ Reason ]

This package is a dependency of the extension tbsync 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 tbsync, 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 dav4tbsync to work with thunderbird 115.x

[ Other info ]

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

eas4tbsync will follow. Tbsync is already updated

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 dav4tbsync-4.3 dav4tbsync-4.7

 _locales/bg/messages.json                     |    6 
 _locales/cs/messages.json                     |    6 
 _locales/es/messages.json                     |    8 
 _locales/fr/messages.json                     |    8 
 _locales/gl/messages.json                     |  347 +++++++++++++
 _locales/hu/messages.json                     |    6 
 _locales/it/messages.json                     |    6 
 _locales/ja/messages.json                     |    6 
 _locales/pl/messages.json                     |    6 
 _locales/pt_BR/messages.json                  |    6 
 _locales/ro/messages.json                     |  347 +++++++++++++
 content/api/BootstrapLoader/CHANGELOG.md      |   15 
 content/api/BootstrapLoader/implementation.js |  676 ++++++++++++++++++++------
 content/api/BootstrapLoader/schema.json       |    4 
 content/bootstrap.js                          |   12 
 content/manager/createAccount.xhtml           |   25 
 debian/changelog                              |   22 
 debian/control                                |    4 
 debian/gbp.conf                               |    2 
 manifest.json                                 |    4 
 20 files changed, 1341 insertions(+), 175 deletions(-)

diff -Nru dav4tbsync-4.3/content/api/BootstrapLoader/CHANGELOG.md dav4tbsync-4.7/content/api/BootstrapLoader/CHANGELOG.md
--- dav4tbsync-4.3/content/api/BootstrapLoader/CHANGELOG.md	2022-10-12 21:39:58.000000000 +0200
+++ dav4tbsync-4.7/content/api/BootstrapLoader/CHANGELOG.md	2023-08-18 16:52:10.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 dav4tbsync-4.3/content/api/BootstrapLoader/implementation.js dav4tbsync-4.7/content/api/BootstrapLoader/implementation.js
--- dav4tbsync-4.3/content/api/BootstrapLoader/implementation.js	2022-10-12 21:39:58.000000000 +0200
+++ dav4tbsync-4.7/content/api/BootstrapLoader/implementation.js	2023-08-18 16:52:10.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 dav4tbsync-4.3/content/api/BootstrapLoader/schema.json dav4tbsync-4.7/content/api/BootstrapLoader/schema.json
--- dav4tbsync-4.3/content/api/BootstrapLoader/schema.json	2022-10-12 21:39:58.000000000 +0200
+++ dav4tbsync-4.7/content/api/BootstrapLoader/schema.json	2023-08-18 16:52:10.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 dav4tbsync-4.3/content/bootstrap.js dav4tbsync-4.7/content/bootstrap.js
--- dav4tbsync-4.3/content/bootstrap.js	2022-10-12 21:39:58.000000000 +0200
+++ dav4tbsync-4.7/content/bootstrap.js	2023-08-18 16:52:10.000000000 +0200
@@ -35,15 +35,9 @@
     // Possible reasons: APP_STARTUP, ADDON_ENABLE, ADDON_INSTALL, ADDON_UPGRADE, or ADDON_DOWNGRADE.
 
     Services.obs.addObserver(onInitDoneObserver, "tbsync.observer.initialized", false);
-     
-    // The startup of TbSync is delayed until all add-ons have called their startup(),
-    // so all providers have registered the "tbsync.observer.initialized" observer.
-    // Once TbSync has finished its startup, all providers will be notified (also if
-    // TbSync itself is restarted) to load themself.
-    // If this is not startup, we need load manually.
-    if (reason != APP_STARTUP) {
-        onInitDoneObserver.observe();
-    }
+
+    // Did we miss the observer?
+    onInitDoneObserver.observe();
 }
 
 function shutdown(data, reason)  {
diff -Nru dav4tbsync-4.3/content/manager/createAccount.xhtml dav4tbsync-4.7/content/manager/createAccount.xhtml
--- dav4tbsync-4.3/content/manager/createAccount.xhtml	2022-10-12 21:39:58.000000000 +0200
+++ dav4tbsync-4.7/content/manager/createAccount.xhtml	2023-08-18 16:52:10.000000000 +0200
@@ -1,7 +1,7 @@
 <?xml version="1.0"?>
 <?xml-stylesheet href="chrome://global/skin/global.css" type="text/css"?>
 
-<window width="500" height="600" onload="tbSyncDavNewAccount.onLoad();" onunload="tbSyncDavNewAccount.onUnload();"
+<window onload="tbSyncDavNewAccount.onLoad();" onunload="tbSyncDavNewAccount.onUnload();"
     onclose="return tbSyncDavNewAccount.onClose()" xmlns:html="http://www.w3.org/1999/xhtml";
     xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";>
 
@@ -12,20 +12,21 @@
     <script type="application/javascript" src="chrome://dav4tbsync/content/manager/createAccount.js" />
     <script type="application/javascript" src="chrome://dav4tbsync/content/locales.js" />
 
-    <wizard title="__DAV4TBSYNCMSG_add.title__" id="tbsync.newaccount.wizard">
+    <wizard title="__DAV4TBSYNCMSG_add.title__" id="tbsync.newaccount.wizard" >
 
         <wizardpage id="firstPage" onFirstPage="true" label="__DAV4TBSYNCMSG_add.serverprofile.title__">
             <vbox flex="1">
-                <description style="width: 450px; margin-top:1em;">__DAV4TBSYNCMSG_add.serverprofile.description__
+                <description style="width: auto; margin-top:1em;">__DAV4TBSYNCMSG_add.serverprofile.description__
                 </description>
-                <richlistbox id="tbsync.newaccount.serviceproviderlist" flex="1" seltype="single" style="margin-top:1ex"
-                    onselect="tbSyncDavNewAccount.clearValues();" ondblclick="tbSyncDavNewAccount.advance()" />
+                <richlistbox id="tbsync.newaccount.serviceproviderlist" seltype="single"
+                    style="width: auto; height: 400px; margin-top:1ex" onselect="tbSyncDavNewAccount.clearValues();"
+                    ondblclick="tbSyncDavNewAccount.advance()" />
             </vbox>
         </wizardpage>
 
         <wizardpage id="secondPage" label="__DAV4TBSYNCMSG_add.data.title__">
             <vbox flex="1">
-                <description style="width: 450px; margin-top:1em;">__DAV4TBSYNCMSG_add.data.description__</description>
+                <description style="width: auto; margin-top:1em;">__DAV4TBSYNCMSG_add.data.description__</description>
                 <html:table style="margin-top:1ex">
                     <html:tr id="tbsync.newaccount.name.row" width="100%">
                         <html:td width="33%">
@@ -84,9 +85,9 @@
                 </html:table>
                 <label class="header" id="tbsync.newaccount.details.header" value="__DAV4TBSYNCMSG_add.data.notes__"
                     style="margin-top:2em" />
-                <description id="tbsync.newaccount.details1" style="width: 450px; margin-top:1ex;"></description>
-                <description id="tbsync.newaccount.details2" style="width: 450px; margin-top:1ex;"></description>
-                <description id="tbsync.newaccount.details3" style="width: 450px; margin-top:1ex;"></description>
+                <description id="tbsync.newaccount.details1" style="width: auto; margin-top:1ex;"></description>
+                <description id="tbsync.newaccount.details2" style="width: auto; margin-top:1ex;"></description>
+                <description id="tbsync.newaccount.details3" style="width: auto; margin-top:1ex;"></description>
                 <vbox flex="1">
                 </vbox>
                 <hbox id="tbsync.spinner">
@@ -94,7 +95,7 @@
                     <image src="chrome://tbsync/content/skin/spinner.gif" style="margin-left:1em" width="16"
                         height="16" />
                 </hbox>
-                <vbox id="tbsync.error" style="width: 450px;">
+                <vbox id="tbsync.error" style="width: auto;">
                     <description id="tbsync.error.message" flex="1" style="font-weight: bold;"></description>
                     <vbox>
                         <button id="tbsync.error.link" label="__DAV4TBSYNCMSG_manager.ShowEventLog__"
@@ -106,7 +107,7 @@
 
         <wizardpage id="thirdPage" label="__DAV4TBSYNCMSG_add.finish.title__">
             <vbox flex="1">
-                <description style="width: 450px; margin-top:1em;">__DAV4TBSYNCMSG_add.finish.description__
+                <description style="width: auto; margin-top:1em;">__DAV4TBSYNCMSG_add.finish.description__
                 </description>
                 <html:table style="margin-top:1ex">
                     <html:tr flex="1">
@@ -147,7 +148,7 @@
                         </html:td>
                     </html:tr>
                 </html:table>
-                <description id="tbsync.finalaccount.details1" style="width: 450px; margin-top:2em;">
+                <description id="tbsync.finalaccount.details1" style="width: auto; margin-top:2em;">
                     __DAV4TBSYNCMSG_add.finish.details__</description>
             </vbox>
         </wizardpage>
diff -Nru dav4tbsync-4.3/debian/changelog dav4tbsync-4.7/debian/changelog
--- dav4tbsync-4.3/debian/changelog	2022-10-14 14:16:53.000000000 +0200
+++ dav4tbsync-4.7/debian/changelog	2023-10-22 10:04:59.000000000 +0200
@@ -1,3 +1,25 @@
+dav4tbsync (4.7-1~deb12u1) bookworm; urgency=medium
+
+  * [1bbfecd] Adjust version of dependencies
+  *     Prepared for release in bookworm (proposed-updates)
+
+ -- Mechtilde Stehmann <mechti...@debian.org>  Sun, 22 Oct 2023 10:04:59 +0200
+
+dav4tbsync (4.7-1) unstable; urgency=medium
+
+  * [c9b557c] Changed compression for tar.gz
+  * [5609063] New upstream version 4.7
+  *     Removed double entries in the version before
+
+ -- Mechtilde Stehmann <mechti...@debian.org>  Tue, 12 Sep 2023 19:56:58 +0200
+
+dav4tbsync (4.3+git20230524+b777de8-1) experimental; urgency=medium
+
+  * [adccff6] Changed compression because of the zip file
+  * [6f38e59] New upstream version 4.3+git20230524+b777de8
+
+ -- Mechtilde Stehmann <mechti...@debian.org>  Sat, 29 Jul 2023 20:32:09 +0200
+
 dav4tbsync (4.3-1) unstable; urgency=medium
 
   * [56c466a] New upstream version 4.3
diff -Nru dav4tbsync-4.3/debian/control dav4tbsync-4.7/debian/control
--- dav4tbsync-4.3/debian/control	2022-09-24 09:58:34.000000000 +0200
+++ dav4tbsync-4.7/debian/control	2023-10-14 11:53:50.000000000 +0200
@@ -15,8 +15,8 @@
 Package: webext-dav4tbsync
 Architecture: all
 Depends: ${misc:Depends}
- , thunderbird (>= 1:102.2)
- , webext-tbsync (>= 4.0)
+ , thunderbird (>= 1:115.3)
+ , webext-tbsync (>= 4.7)
 Description: Provide CalDAV & CardDAV for TbSync
  The CalDAV & CardDAV Provider for TbSync to sync contacts, tasks and
  calendars to Thunderbird.
diff -Nru dav4tbsync-4.3/debian/gbp.conf dav4tbsync-4.7/debian/gbp.conf
--- dav4tbsync-4.3/debian/gbp.conf	2022-09-24 09:44:56.000000000 +0200
+++ dav4tbsync-4.7/debian/gbp.conf	2023-09-12 19:48:41.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 dav4tbsync-4.3/_locales/bg/messages.json dav4tbsync-4.7/_locales/bg/messages.json
--- dav4tbsync-4.3/_locales/bg/messages.json	2022-10-12 21:39:58.000000000 +0200
+++ dav4tbsync-4.7/_locales/bg/messages.json	2023-08-18 16:52:10.000000000 +0200
@@ -317,6 +317,12 @@
     "status.success.managed-by-thunderbird": {
         "message": "Ok"
     },
+    "status.non-carddav-addrbook": {
+        "message": "This is an older TbSync-CardDAV address book, which cannot be synced anymore. Disable and re-enable the address book, to create a fresh Thunderbird-CardDAV address book."
+    },
+    "helplink.non-carddav-addrbook": {
+        "message": "https://github.com/jobisoft/DAV-4-TbSync/wiki/Since-Thunderbird-102,-TbSync-DAV-is-using-native-CardDAV-sync";
+    },
     "syncstate.eval.folders": {
         "message": "Обновяване на списъка с ресурсите"
     },
diff -Nru dav4tbsync-4.3/_locales/cs/messages.json dav4tbsync-4.7/_locales/cs/messages.json
--- dav4tbsync-4.3/_locales/cs/messages.json	2022-10-12 21:39:58.000000000 +0200
+++ dav4tbsync-4.7/_locales/cs/messages.json	2023-08-18 16:52:10.000000000 +0200
@@ -317,6 +317,12 @@
     "status.success.managed-by-thunderbird": {
         "message": "Ok"
     },
+    "status.non-carddav-addrbook": {
+        "message": "Toto je starší adresář TbSync-CardDAV, který již nelze synchronizovat. Zakažte a znovu povolte adresář, pro vytvoření nového adresáře Thunderbird-CardDAV."
+    },
+    "helplink.non-carddav-addrbook": {
+        "message": "https://github.com/jobisoft/DAV-4-TbSync/wiki/Since-Thunderbird-102,-TbSync-DAV-is-using-native-CardDAV-sync";
+    },
     "syncstate.eval.folders": {
         "message": "Aktualizace seznamu složek"
     },
diff -Nru dav4tbsync-4.3/_locales/es/messages.json dav4tbsync-4.7/_locales/es/messages.json
--- dav4tbsync-4.3/_locales/es/messages.json	2022-10-12 21:39:58.000000000 +0200
+++ dav4tbsync-4.7/_locales/es/messages.json	2023-08-18 16:52:10.000000000 +0200
@@ -315,7 +315,13 @@
         "message": "Error no fatal (##replace.1##)"
     },
     "status.success.managed-by-thunderbird": {
-        "message": "Ok"
+        "message": "OK"
+    },
+    "status.non-carddav-addrbook": {
+        "message": "Esta es una libreta de direcciones TbSync-CardDAV que ya no se puede sincronizar. Deshabilita y vuelve a habilitar la libreta de direcciones para crear una libreta de direcciones de Thunderbird-CardDAV."
+    },
+    "helplink.non-carddav-addrbook": {
+        "message": "https://github.com/jobisoft/DAV-4-TbSync/wiki/Since-Thunderbird-102,-TbSync-DAV-is-using-native-CardDAV-sync";
     },
     "syncstate.eval.folders": {
         "message": "Actualizando la lista de carpetas"
diff -Nru dav4tbsync-4.3/_locales/fr/messages.json dav4tbsync-4.7/_locales/fr/messages.json
--- dav4tbsync-4.3/_locales/fr/messages.json	2022-10-12 21:39:58.000000000 +0200
+++ dav4tbsync-4.7/_locales/fr/messages.json	2023-08-18 16:52:10.000000000 +0200
@@ -315,7 +315,13 @@
         "message": "Erreur non critique (##replace.1##)"
     },
     "status.success.managed-by-thunderbird": {
-        "message": "Ok"
+        "message": "OK"
+    },
+    "status.non-carddav-addrbook": {
+        "message": "Ceci est un carnet d'adresses CardDAV issu d'une ancienne version de Tbsync et qui ne peut plus être synchronisé. Désactivez et réactivez le carnet d'adresses pour créer un nouveau carnet d'adresses CardDAV, utilisant la fonctionnalité intégrée dans Thunberbird."
+    },
+    "helplink.non-carddav-addrbook": {
+        "message": "https://github.com/jobisoft/DAV-4-TbSync/wiki/Since-Thunderbird-102,-TbSync-DAV-is-using-native-CardDAV-sync";
     },
     "syncstate.eval.folders": {
         "message": "Mise à jour de la liste des dossiers"
diff -Nru dav4tbsync-4.3/_locales/gl/messages.json dav4tbsync-4.7/_locales/gl/messages.json
--- dav4tbsync-4.3/_locales/gl/messages.json	1970-01-01 01:00:00.000000000 +0100
+++ dav4tbsync-4.7/_locales/gl/messages.json	2023-08-18 16:52:10.000000000 +0200
@@ -0,0 +1,347 @@
+{
+    "abCard.ContactDetails": {
+        "message": "Propiedades do contacto (CardDAV)"
+    },
+    "abCard.EmailAddresses": {
+        "message": "Enderezos de correo electrónico"
+    },
+    "abCard.MiddleName": {
+        "message": "Segundo nome:"
+    },
+    "abCard.Phone": {
+        "message": "Número de teléfono"
+    },
+    "abCard.PrefixName": {
+        "message": "Prefixo:"
+    },
+    "abCard.SuffixName": {
+        "message": "Sufixo:"
+    },
+    "abCard.emailtypes.car": {
+        "message": "Coche"
+    },
+    "abCard.emailtypes.cell": {
+        "message": "Móbil"
+    },
+    "abCard.emailtypes.description": {
+        "message": "O primeiro enderezo de correo electrónico da lista usarase como enderezo principal."
+    },
+    "abCard.emailtypes.fax": {
+        "message": "Fax"
+    },
+    "abCard.emailtypes.home": {
+        "message": "Casa"
+    },
+    "abCard.emailtypes.other": {
+        "message": "Outro"
+    },
+    "abCard.emailtypes.pager": {
+        "message": "Buscapersoas"
+    },
+    "abCard.emailtypes.video": {
+        "message": "Vídeo"
+    },
+    "abCard.emailtypes.voice": {
+        "message": "Teléfono"
+    },
+    "abCard.emailtypes.work": {
+        "message": "Traballo"
+    },
+    "acl.add": {
+        "message": "engadir"
+    },
+    "acl.delete": {
+        "message": "eliminar"
+    },
+    "acl.modify": {
+        "message": "modificar"
+    },
+    "acl.none": {
+        "message": "ningún"
+    },
+    "acl.readonly": {
+        "message": "Acceso ao servidor só de lectura (reverter cambios locais)"
+    },
+    "acl.readwrite": {
+        "message": "Permisos de escritura do servidor: ##replace.1##"
+    },
+    "add.caldavserver": {
+        "message": "Enderezo do servidor CalDAV:"
+    },
+    "add.carddavserver": {
+        "message": "Enderezo do servidor CardDAV:"
+    },
+    "add.data.description": {
+        "message": "Por favor, facilita un nome amigable para a nova conta de TbSync e as credenciais do teu servidor:"
+    },
+    "add.data.notes": {
+        "message": "Notas:"
+    },
+    "add.data.title": {
+        "message": "Insire información da conta"
+    },
+    "add.finish.description": {
+        "message": "Verificáronse correctamente os seguintes axustes:"
+    },
+    "add.finish.details": {
+        "message": "Preme en \"Rematar\" para crear a nova conta de TbSync con estes axustes."
+    },
+    "add.finish.title": {
+        "message": "Confirma a creación da conta"
+    },
+    "add.name": {
+        "message": "Nome da conta:"
+    },
+    "add.ok": {
+        "message": "Engadir conta"
+    },
+    "add.password": {
+        "message": "Contrasinal:"
+    },
+    "add.server": {
+        "message": "URL do servidor:"
+    },
+    "add.serverprofile.custom": {
+        "message": "Configuración manual"
+    },
+    "add.serverprofile.custom.description": {
+        "message": "Podes configurar manualmente os extremos dos servizos CalDAV e CardDAV."
+    },
+    "add.serverprofile.custom.details1": {
+        "message": "Os extremos dos servizos CalDAV e CardDAV, ou os chamados enderezos principais, ten que proporcionalos o teu provedor de servizo."
+    },
+    "add.serverprofile.custom.details2": {
+        "message": "Se deixas baleiro algún destes enderezos non se activará o servizo correspondente nesta conta."
+    },
+    "add.serverprofile.description": {
+        "message": "Por favor, selecciona un dos perfís de servidor dispoñibles:"
+    },
+    "add.serverprofile.discovery": {
+        "message": "Configuración automática"
+    },
+    "add.serverprofile.discovery.description": {
+        "message": "Moitos servidores e provedores de servizo admiten un proceso automático de configuración que só precisa dun enderezo de correo electrónico ou dun nome de usuario, e do enderezo do servidor."
+    },
+    "add.serverprofile.discovery.details1": {
+        "message": "Para o descubrimento automático dos extremos dos servizos CalDAV e CardDAV tes que facilitar as túas credenciais e o nome de equipo do teu servidor (por exemplo, nube.dominio.gal)."
+    },
+    "add.serverprofile.discovery.details2": {
+        "message": "Se o teu nome de usuario é un enderezo de correo é opcional que especifiques o nome do servidor xa que a información sobre os extremos do servizo poden obterse de forma automática do teu provedor de servizo mediante unha solicitude RFC6764 (se é que a admite)."
+    },
+    "add.serverprofile.discovery.server-optional": {
+        "message": "opcional"
+    },
+    "add.serverprofile.fruux": {
+        "message": "fruux"
+    },
+    "add.serverprofile.fruux.description": {
+        "message": "fruux é un servizo que sincroniza contactos, calendarios e tarefas. Ofréceo a mesma compañía que desenvolve sabre/dav e ten sede en Alemaña."
+    },
+    "add.serverprofile.gmx.com": {
+        "message": "GMX.com (EEUU de América)"
+    },
+    "add.serverprofile.gmx.com.description": {
+        "message": "https://www.gmx.com";
+    },
+    "add.serverprofile.gmx.net": {
+        "message": "GMX.net (Europa)"
+    },
+    "add.serverprofile.gmx.net.description": {
+        "message": "https://www.gmx.net";
+    },
+    "add.serverprofile.icloud": {
+        "message": "iCloud"
+    },
+    "add.serverprofile.icloud.description": {
+        "message": "https://www.icloud.com";
+    },
+    "add.serverprofile.icloud.details1": {
+        "message": "O nome de usuario que precisas é o teu Apple ID. Por favor, ten en conta que non podes usar o contrasinal de Apple ID aquí. Tes que activar a autenticación de doble factor (2FA) na túa conta de iCloud e crear un contrasinal de aplicación específico para usar con TbSync."
+    },
+    "add.serverprofile.icloud.details2": {
+        "message": "Esta é unha capa de seguridade imposta por Apple para que os clientes de terceiros non teñan acceso á túa conta Apple."
+    },
+    "add.serverprofile.mbo": {
+        "message": "mailbox.org"
+    },
+    "add.serverprofile.mbo.description": {
+        "message": "mailbox.org é un provedor alemán de correo electrónico para empresas e clientes privados que ofrece calendarios, contactos e almacenamento na nube."
+    },
+    "add.serverprofile.posteo": {
+        "message": "Posteo"
+    },
+    "add.serverprofile.posteo.description": {
+        "message": "https://www.posteo.de";
+    },
+    "add.serverprofile.title": {
+        "message": "Selecciona un perfil de servidor"
+    },
+    "add.serverprofile.web.de": {
+        "message": "WEB.de"
+    },
+    "add.serverprofile.web.de.description": {
+        "message": "https://www.web.de";
+    },
+    "add.serverprofile.yahoo": {
+        "message": "Yahoo!"
+    },
+    "add.serverprofile.yahoo.description": {
+        "message": "https://www.yahoo.com";
+    },
+    "add.serverprofile.yahoo.details1": {
+        "message": "O contrasinal que se solicita é un contrasinal de aplicación para TbSync que podes crear no teu portal web de Yahoo! Non é o teu contrasinal normal de Yahoo!"
+    },
+    "add.spinner.query": {
+        "message": "Enviando unha solicitude RFC6764 a “##replace.1##”"
+    },
+    "add.spinner.validating": {
+        "message": "Verificando a conexión ao servidor"
+    },
+    "add.title": {
+        "message": "Engadindo a conta CalDAV e CardDAV a TbSync"
+    },
+    "add.user": {
+        "message": "Nome de usuario:"
+    },
+    "autocomplete.HOME": {
+        "message": "privado"
+    },
+    "autocomplete.PREF": {
+        "message": "preferido"
+    },
+    "autocomplete.WORK": {
+        "message": "profesional"
+    },
+    "config.custom": {
+        "message": "Configuración do servidor CalDAV e CardDAV"
+    },
+    "defaultname.calendar": {
+        "message": "Calendario"
+    },
+    "defaultname.contacts": {
+        "message": "Contactos"
+    },
+    "extensionDescription": {
+        "message": "Engadir a TbSync soporte para a sincronización de contas CalDAV e CardDAV."
+    },
+    "extensionName": {
+        "message": "Provedor de CalDAV e CardDAV"
+    },
+    "helplink.malformed-xml": {
+        "message": "https://github.com/jobisoft/DAV-4-TbSync/issues/104";
+    },
+    "manager.tabs.accountsettings": {
+        "message": "Axustes da conta"
+    },
+    "manager.tabs.syncsettings": {
+        "message": "Opcións"
+    },
+    "menu.name": {
+        "message": "CalDAV e CardDAV"
+    },
+    "pref.AccountName": {
+        "message": "Nome da conta"
+    },
+    "pref.CalDavServer": {
+        "message": "Enderezo do servidor CalDAV:"
+    },
+    "pref.CardDavServer": {
+        "message": "Enderezo do servidor CardDAV:"
+    },
+    "pref.UserName": {
+        "message": "Nome de usuario"
+    },
+    "pref.calendaroptions": {
+        "message": "Opcións do calendario"
+    },
+    "pref.contactoptions": {
+        "message": "Opcións do contacto"
+    },
+    "pref.downloadonly": {
+        "message": "Reverter os cambios locais (sincronización nun sentido)"
+    },
+    "pref.generaloptions": {
+        "message": "Opcións xerais"
+    },
+    "pref.useCalendarCache": {
+        "message": "Soporte sen conexión"
+    },
+    "pref.useCardBook": {
+        "message": "Crear libretas de enderezos de CardBook en vez das predeterminadas de Thunderbird"
+    },
+    "status.401": {
+        "message": "Non se puido autenticar, comproba o nome de usuario e contrasinal."
+    },
+    "status.403": {
+        "message": "O servidor rexeitou a conexión (prohibida)."
+    },
+    "status.404": {
+        "message": "Erro HTTP 404 (non se atopou o recurso solicitado)."
+    },
+    "status.500": {
+        "message": "Erro descoñecido do servidor (erro HTTP 500)."
+    },
+    "status.503": {
+        "message": "Servizo non dispoñible."
+    },
+    "status.caldavservernotfound": {
+        "message": "Non se puido atopar un servidor CalDAV."
+    },
+    "status.carddavservernotfound": {
+        "message": "Non se puido atopar un servidor CardDAV."
+    },
+    "status.gContactSync": {
+        "message": "gContactSync é incompatible coa activación da sincronización de grupos de contactos. Por favor, desactiva un deles ata que se solucione este erro."
+    },
+    "status.info.restored": {
+        "message": "Algunas accións foron rexeitadas polo servidor e revertéronse en local debido á ausencia parcial de permisos de escritura."
+    },
+    "status.malformed-xml": {
+        "message": "Non se puido analizar o XML. Revisa o rexistro de eventos para dispor de máis detalles."
+    },
+    "status.missing-permission": {
+        "message": "Falta o permiso: ##replace.1##"
+    },
+    "status.networkerror": {
+        "message": "Non se puido conectar ao servidor."
+    },
+    "status.rfc6764-lookup-failed": {
+        "message": "A consulta “##replace.1##” non devolveu a información necesaria sobre os extremos do servizos CalDAV e CardDAV. Por favor, insire o nome do equipo do teu servidor para continuar coa configuración automática."
+    },
+    "status.service-discovery-failed": {
+        "message": "Fallou o descubrimento automático dos extremos dos servizos CalDAV e CardDAV de “##replace.1##”. Proba de novo especificando un enderezo do servidor diferente ou cambia a configuración personalizada para especificar os extremos do servizo."
+    },
+    "status.softerror": {
+        "message": "Erro non fatal (##replace.1##)"
+    },
+    "status.success.managed-by-thunderbird": {
+        "message": "OK"
+    },
+    "status.non-carddav-addrbook": {
+        "message": "Esta é unha versión vella do caderno de enderezos de TbSync-CardDAV que xa non se pode sincronizar. Desactívao e volve a activalo para crear un novo caderno de enderezos Thunderbird-CardDAV."
+    },
+    "helplink.non-carddav-addrbook": {
+        "message": "https://github.com/jobisoft/DAV-4-TbSync/wiki/Since-Thunderbird-102,-TbSync-DAV-is-using-native-CardDAV-sync";
+    },
+    "syncstate.eval.folders": {
+        "message": "Actualizando a lista de cartafois"
+    },
+    "syncstate.eval.response.localchanges": {
+        "message": "Procesando o recoñecemento de cambios locais"
+    },
+    "syncstate.eval.response.remotechanges": {
+        "message": "Procesando os cambios remotos"
+    },
+    "syncstate.prepare.request.localchanges": {
+        "message": "Enviando cambios locais"
+    },
+    "syncstate.send.getfolders": {
+        "message": "Solicitando a lista de cartafoles"
+    },
+    "syncstate.send.request.localchanges": {
+        "message": "Esperando polo recoñecemento dos cambios locais"
+    },
+    "syncstate.send.request.remotechanges": {
+        "message": "Esperando polos cambios remotos"
+    }
+}
diff -Nru dav4tbsync-4.3/_locales/hu/messages.json dav4tbsync-4.7/_locales/hu/messages.json
--- dav4tbsync-4.3/_locales/hu/messages.json	2022-10-12 21:39:58.000000000 +0200
+++ dav4tbsync-4.7/_locales/hu/messages.json	2023-08-18 16:52:10.000000000 +0200
@@ -317,6 +317,12 @@
     "status.success.managed-by-thunderbird": {
         "message": "Ok"
     },
+    "status.non-carddav-addrbook": {
+        "message": "This is an older TbSync-CardDAV address book, which cannot be synced anymore. Disable and re-enable the address book, to create a fresh Thunderbird-CardDAV address book."
+    },
+    "helplink.non-carddav-addrbook": {
+        "message": "https://github.com/jobisoft/DAV-4-TbSync/wiki/Since-Thunderbird-102,-TbSync-DAV-is-using-native-CardDAV-sync";
+    },
     "syncstate.eval.folders": {
         "message": "Mappalista frissítése"
     },
diff -Nru dav4tbsync-4.3/_locales/it/messages.json dav4tbsync-4.7/_locales/it/messages.json
--- dav4tbsync-4.3/_locales/it/messages.json	2022-10-12 21:39:58.000000000 +0200
+++ dav4tbsync-4.7/_locales/it/messages.json	2023-08-18 16:52:10.000000000 +0200
@@ -317,6 +317,12 @@
     "status.success.managed-by-thunderbird": {
         "message": "Ok"
     },
+    "status.non-carddav-addrbook": {
+        "message": "This is an older TbSync-CardDAV address book, which cannot be synced anymore. Disable and re-enable the address book, to create a fresh Thunderbird-CardDAV address book."
+    },
+    "helplink.non-carddav-addrbook": {
+        "message": "https://github.com/jobisoft/DAV-4-TbSync/wiki/Since-Thunderbird-102,-TbSync-DAV-is-using-native-CardDAV-sync";
+    },
     "syncstate.eval.folders": {
         "message": "Aggiornamento elenco cartelle in corso"
     },
diff -Nru dav4tbsync-4.3/_locales/ja/messages.json dav4tbsync-4.7/_locales/ja/messages.json
--- dav4tbsync-4.3/_locales/ja/messages.json	2022-10-12 21:39:58.000000000 +0200
+++ dav4tbsync-4.7/_locales/ja/messages.json	2023-08-18 16:52:10.000000000 +0200
@@ -317,6 +317,12 @@
     "status.success.managed-by-thunderbird": {
         "message": "Ok"
     },
+    "status.non-carddav-addrbook": {
+        "message": "This is an older TbSync-CardDAV address book, which cannot be synced anymore. Disable and re-enable the address book, to create a fresh Thunderbird-CardDAV address book."
+    },
+    "helplink.non-carddav-addrbook": {
+        "message": "https://github.com/jobisoft/DAV-4-TbSync/wiki/Since-Thunderbird-102,-TbSync-DAV-is-using-native-CardDAV-sync";
+    },
     "syncstate.eval.folders": {
         "message": "Updating folder list"
     },
diff -Nru dav4tbsync-4.3/_locales/pl/messages.json dav4tbsync-4.7/_locales/pl/messages.json
--- dav4tbsync-4.3/_locales/pl/messages.json	2022-10-12 21:39:58.000000000 +0200
+++ dav4tbsync-4.7/_locales/pl/messages.json	2023-08-18 16:52:10.000000000 +0200
@@ -317,6 +317,12 @@
     "status.success.managed-by-thunderbird": {
         "message": "Ok"
     },
+    "status.non-carddav-addrbook": {
+        "message": "To jest starsza książka adresowa TbSync-CardDAV, która nie może być już synchronizowana. Wyłącz i ponownie włącz książkę adresową, aby stworzyć nową książkę adresową Thunderbird-CardDAV."
+    },
+    "helplink.non-carddav-addrbook": {
+        "message": "https://github.com/jobisoft/DAV-4-TbSync/wiki/Since-Thunderbird-102,-TbSync-DAV-is-using-native-CardDAV-sync";
+    },
     "syncstate.eval.folders": {
         "message": "Aktualizowanie listy folderów"
     },
diff -Nru dav4tbsync-4.3/_locales/pt_BR/messages.json dav4tbsync-4.7/_locales/pt_BR/messages.json
--- dav4tbsync-4.3/_locales/pt_BR/messages.json	2022-10-12 21:39:58.000000000 +0200
+++ dav4tbsync-4.7/_locales/pt_BR/messages.json	2023-08-18 16:52:10.000000000 +0200
@@ -317,6 +317,12 @@
     "status.success.managed-by-thunderbird": {
         "message": "Ok"
     },
+    "status.non-carddav-addrbook": {
+        "message": "This is an older TbSync-CardDAV address book, which cannot be synced anymore. Disable and re-enable the address book, to create a fresh Thunderbird-CardDAV address book."
+    },
+    "helplink.non-carddav-addrbook": {
+        "message": "https://github.com/jobisoft/DAV-4-TbSync/wiki/Since-Thunderbird-102,-TbSync-DAV-is-using-native-CardDAV-sync";
+    },
     "syncstate.eval.folders": {
         "message": "Atualizando lista de pastas"
     },
diff -Nru dav4tbsync-4.3/_locales/ro/messages.json dav4tbsync-4.7/_locales/ro/messages.json
--- dav4tbsync-4.3/_locales/ro/messages.json	1970-01-01 01:00:00.000000000 +0100
+++ dav4tbsync-4.7/_locales/ro/messages.json	2023-08-18 16:52:10.000000000 +0200
@@ -0,0 +1,347 @@
+{
+    "abCard.ContactDetails": {
+        "message": "Proprietăți de contact (CardDAV)"
+    },
+    "abCard.EmailAddresses": {
+        "message": "Adresele de poştă electronică"
+    },
+    "abCard.MiddleName": {
+        "message": "Mijlociu:"
+    },
+    "abCard.Phone": {
+        "message": "Numere de telefon"
+    },
+    "abCard.PrefixName": {
+        "message": "Prefix:"
+    },
+    "abCard.SuffixName": {
+        "message": "Sufix:"
+    },
+    "abCard.emailtypes.car": {
+        "message": "Maşină"
+    },
+    "abCard.emailtypes.cell": {
+        "message": "Mobil"
+    },
+    "abCard.emailtypes.description": {
+        "message": "Prima adresă de e-mail din listă va fi utilizată ca adresă de e-mail principală."
+    },
+    "abCard.emailtypes.fax": {
+        "message": "Fax"
+    },
+    "abCard.emailtypes.home": {
+        "message": "Acasă"
+    },
+    "abCard.emailtypes.other": {
+        "message": "Altele"
+    },
+    "abCard.emailtypes.pager": {
+        "message": "Pager"
+    },
+    "abCard.emailtypes.video": {
+        "message": "Videoclip"
+    },
+    "abCard.emailtypes.voice": {
+        "message": "Telefon"
+    },
+    "abCard.emailtypes.work": {
+        "message": "Lucru"
+    },
+    "acl.add": {
+        "message": "adaugă"
+    },
+    "acl.delete": {
+        "message": "șterge"
+    },
+    "acl.modify": {
+        "message": "modifică"
+    },
+    "acl.none": {
+        "message": "niciuna"
+    },
+    "acl.readonly": {
+        "message": "Acces doar pentru citire pe server (revenire la modificările locale)"
+    },
+    "acl.readwrite": {
+        "message": "Permisiuni de scriere pe server: ##replace.1##"
+    },
+    "add.caldavserver": {
+        "message": "Adresa serverului CalDAV:"
+    },
+    "add.carddavserver": {
+        "message": "Adresa serverului CardDAV:"
+    },
+    "add.data.description": {
+        "message": "Vă rugăm să furnizați un nume prietenos pentru noul cont TbSync și acreditările pentru serverul dumneavoastră:"
+    },
+    "add.data.notes": {
+        "message": "Note:"
+    },
+    "add.data.title": {
+        "message": "Introduceți informații despre cont"
+    },
+    "add.finish.description": {
+        "message": "Următoarele setări au fost verificate cu succes:"
+    },
+    "add.finish.details": {
+        "message": "Faceți clic pe \" Terminare \" pentru a crea un nou cont TbSync cu aceste setări."
+    },
+    "add.finish.title": {
+        "message": "Confirmați crearea contului"
+    },
+    "add.name": {
+        "message": "Numele contului:"
+    },
+    "add.ok": {
+        "message": "Adăugaţi un cont"
+    },
+    "add.password": {
+        "message": "Parolă:"
+    },
+    "add.server": {
+        "message": "URL-ul serverului:"
+    },
+    "add.serverprofile.custom": {
+        "message": "Configurație manuală"
+    },
+    "add.serverprofile.custom.description": {
+        "message": "Punctele finale ale serviciilor CalDAV și CardDAV pot fi configurate manual."
+    },
+    "add.serverprofile.custom.details1": {
+        "message": "Punctele finale necesare ale serviciilor CalDAV și CardDAV sau așa-numitele adrese principale ar trebui să fie furnizate de furnizorul dumneavoastră de servicii."
+    },
+    "add.serverprofile.custom.details2": {
+        "message": "Dacă lăsați oricare dintre adrese goală, serviciul corespunzător va fi dezactivat pentru acest cont."
+    },
+    "add.serverprofile.description": {
+        "message": "Vă rugăm să selectați unul dintre profilurile de server disponibile:"
+    },
+    "add.serverprofile.discovery": {
+        "message": "Configurație automată"
+    },
+    "add.serverprofile.discovery.description": {
+        "message": "Mulți furnizori de servicii și servere acceptă un proces de configurare automată, care necesită doar o adresă de e-mail sau un nume de utilizator și o adresă de server."
+    },
+    "add.serverprofile.discovery.details1": {
+        "message": "Pentru descoperirea automată a punctelor finale ale serviciului CalDAV & CardDAV, vă rugăm să introduceți acreditările dumneavoastră și numele de gazdă al serverului dumneavoastră (de exemplu, \"cloud.myserver.ro\")."
+    },
+    "add.serverprofile.discovery.details2": {
+        "message": "În cazul în care numele de utilizator este o adresă de e-mail, specificarea serverului devine opțională, deoarece informațiile despre punctele finale ale serviciului pot fi obținute direct de la furnizorul de servicii prin intermediul unei cereri RFC6764 (dacă este acceptată)."
+    },
+    "add.serverprofile.discovery.server-optional": {
+        "message": "optional"
+    },
+    "add.serverprofile.fruux": {
+        "message": "fruux"
+    },
+    "add.serverprofile.fruux.description": {
+        "message": "fruux este un serviciu care sincronizează contactele, calendarele și sarcinile. Este pus la dispoziție de compania din spatele sabre/dav și are sediul în Germania."
+    },
+    "add.serverprofile.gmx.com": {
+        "message": "GMX.com (SUA)"
+    },
+    "add.serverprofile.gmx.com.description": {
+        "message": "https://www.gmx.com";
+    },
+    "add.serverprofile.gmx.net": {
+        "message": "GMX.net (Europa)"
+    },
+    "add.serverprofile.gmx.net.description": {
+        "message": "https://www.gmx.net";
+    },
+    "add.serverprofile.icloud": {
+        "message": "iCloud"
+    },
+    "add.serverprofile.icloud.description": {
+        "message": "https://www.icloud.com";
+    },
+    "add.serverprofile.icloud.details1": {
+        "message": "Numele de utilizator solicitat este ID-ul dumneavoastră Apple. Vă rugăm să rețineți că nu puteți utiliza aici parola ID-ului Apple. TREBUIE să activați autentificarea cu doi factori (2FA) pentru contul dumneavoastră iCloud și să creați o parolă separată specifică aplicației pentru TbSync."
+    },
+    "add.serverprofile.icloud.details2": {
+        "message": "Acesta este un nivel de securitate impus de Apple, astfel încât clienții terți să nu obțină acces la contul dumneavoastră Apple."
+    },
+    "add.serverprofile.mbo": {
+        "message": "mailbox.org"
+    },
+    "add.serverprofile.mbo.description": {
+        "message": "mailbox.org este un furnizor german de e-mail securizat pentru clienți privați și companii, care oferă, de asemenea, calendare, contacte și stocare în cloud."
+    },
+    "add.serverprofile.posteo": {
+        "message": "Posteo"
+    },
+    "add.serverprofile.posteo.description": {
+        "message": "https://www.posteo.de";
+    },
+    "add.serverprofile.title": {
+        "message": "Selectați un profil de server"
+    },
+    "add.serverprofile.web.de": {
+        "message": "WEB.de"
+    },
+    "add.serverprofile.web.de.description": {
+        "message": "https://www.web.de";
+    },
+    "add.serverprofile.yahoo": {
+        "message": "Yahoo!"
+    },
+    "add.serverprofile.yahoo.description": {
+        "message": "https://www.yahoo.com";
+    },
+    "add.serverprofile.yahoo.details1": {
+        "message": "Parola solicitată este o parolă specifică aplicației TbSync, pe care o puteți crea în portalul web Yahoo! Nu este o parolă Yahoo! standard."
+    },
+    "add.spinner.query": {
+        "message": "Se trimite solicitarea RFC6764 către „##substitui.1##”"
+    },
+    "add.spinner.validating": {
+        "message": "Verificarea conexiunii la server"
+    },
+    "add.title": {
+        "message": "Adăugarea unui cont CalDAV și CardDAV la TbSync"
+    },
+    "add.user": {
+        "message": "Utilizator:"
+    },
+    "autocomplete.HOME": {
+        "message": "personal"
+    },
+    "autocomplete.PREF": {
+        "message": "preferat"
+    },
+    "autocomplete.WORK": {
+        "message": "de afaceri"
+    },
+    "config.custom": {
+        "message": "Configurarea serverului CalDAV & CardDAV"
+    },
+    "defaultname.calendar": {
+        "message": "Calendar"
+    },
+    "defaultname.contacts": {
+        "message": "Contacte"
+    },
+    "extensionDescription": {
+        "message": "Adăugarea suportului de sincronizare pentru conturile CalDAV și CardDAV în TbSync."
+    },
+    "extensionName": {
+        "message": "Furnizor pentru CalDAV & CardDAV"
+    },
+    "helplink.malformed-xml": {
+        "message": "https://github.com/jobisoft/DAV-4-TbSync/issues/104";
+    },
+    "manager.tabs.accountsettings": {
+        "message": "Setările contului"
+    },
+    "manager.tabs.syncsettings": {
+        "message": "Opţiuni"
+    },
+    "menu.name": {
+        "message": "CalDAV & CardDAV"
+    },
+    "pref.AccountName": {
+        "message": "Denumire cont"
+    },
+    "pref.CalDavServer": {
+        "message": "Adresa serverului CalDAV:"
+    },
+    "pref.CardDavServer": {
+        "message": "Adresa serverului CardDAV:"
+    },
+    "pref.UserName": {
+        "message": "Nume utilizator"
+    },
+    "pref.calendaroptions": {
+        "message": "Opțiuni calendar"
+    },
+    "pref.contactoptions": {
+        "message": "Opțiuni contact"
+    },
+    "pref.downloadonly": {
+        "message": "Anularea modificărilor locale (sincronizare unidirecțională)"
+    },
+    "pref.generaloptions": {
+        "message": "Opţiuni generale"
+    },
+    "pref.useCalendarCache": {
+        "message": "Suport offline"
+    },
+    "pref.useCardBook": {
+        "message": "Creați cărți de adrese CardBook în locul cărților de adrese implicite din Thunderbird"
+    },
+    "status.401": {
+        "message": "Nu s-a putut autentifica, verificați numele de utilizator și parola."
+    },
+    "status.403": {
+        "message": "Serverul a respins conexiunea (interzisă)."
+    },
+    "status.404": {
+        "message": "Eroare HTTP 404 (resursa solicitată nu a fost găsită)."
+    },
+    "status.500": {
+        "message": "Eroare de server necunoscută (HTTP Error 500)."
+    },
+    "status.503": {
+        "message": "Serviciu indisponibil."
+    },
+    "status.caldavservernotfound": {
+        "message": "Nu s-a putut găsi un server CalDAV."
+    },
+    "status.carddavservernotfound": {
+        "message": "Nu s-a putut găsi un server CardDAV."
+    },
+    "status.gContactSync": {
+        "message": "Există o incompatibilitate cu gContactSync în cazul sincronizării grupurilor de contacte activate. Vă rugăm să dezactivați unul dintre ele atâta timp cât eroarea nu este rezolvată."
+    },
+    "status.info.restored": {
+        "message": "Din cauza lipsei parțiale a permisiunilor de scriere, unele acțiuni au fost respinse de server și inversate la nivel local."
+    },
+    "status.malformed-xml": {
+        "message": "Nu s-a putut analiza XML. Verificați jurnalul de evenimente pentru detalii."
+    },
+    "status.missing-permission": {
+        "message": "Permisiune lipsă: ##replace.1##"
+    },
+    "status.networkerror": {
+        "message": "Nu s-a putut conecta la server."
+    },
+    "status.rfc6764-lookup-failed": {
+        "message": "Interogarea \"##replace.1##\" nu a furnizat informațiile necesare cu privire la punctele finale ale serviciilor CalDAV și CardDAV. Vă rugăm să introduceți numele de gazdă al serverului dumneavoastră pentru a continua cu configurarea automată."
+    },
+    "status.service-discovery-failed": {
+        "message": "Descoperirea automată a punctelor finale ale serviciului CalDAV & CardDAV din \"##replace.1##\" a eșuat. Încercați din nou, specificând o altă adresă de server, sau treceți la configurația personalizată pentru a specifica manual punctele finale ale serviciului."
+    },
+    "status.softerror": {
+        "message": "Eroare non fatală (##replace.1##)"
+    },
+    "status.success.managed-by-thunderbird": {
+        "message": "Ok"
+    },
+    "status.non-carddav-addrbook": {
+        "message": "Aceasta este o carte de adrese TbSync-CardDAV mai veche, care nu mai poate fi sincronizată. Dezactivați și reactivați cartea de adrese pentru a crea o nouă carte de adrese Thunderbird-CardDAV."
+    },
+    "helplink.non-carddav-addrbook": {
+        "message": "https://github.com/jobisoft/DAV-4-TbSync/wiki/Since-Thunderbird-102,-TbSync-DAV-is-using-native-CardDAV-sync";
+    },
+    "syncstate.eval.folders": {
+        "message": "Actualizarea listei de foldere"
+    },
+    "syncstate.eval.response.localchanges": {
+        "message": "Procesarea confirmării modificărilor locale"
+    },
+    "syncstate.eval.response.remotechanges": {
+        "message": "Prelucrarea modificărilor la distanță"
+    },
+    "syncstate.prepare.request.localchanges": {
+        "message": "Trimiterea modificărilor locale"
+    },
+    "syncstate.send.getfolders": {
+        "message": "Solicitarea listei de foldere"
+    },
+    "syncstate.send.request.localchanges": {
+        "message": "Așteptarea confirmării modificărilor locale"
+    },
+    "syncstate.send.request.remotechanges": {
+        "message": "Așteptarea modificărilor la distanță"
+    }
+}
diff -Nru dav4tbsync-4.3/manifest.json dav4tbsync-4.7/manifest.json
--- dav4tbsync-4.3/manifest.json	2022-10-12 21:39:58.000000000 +0200
+++ dav4tbsync-4.7/manifest.json	2023-08-18 16:52:10.000000000 +0200
@@ -3,12 +3,12 @@
     "gecko": {
       "id": "dav4tbs...@jobisoft.de",
       "strict_min_version": "102.3.0",
-      "strict_max_version": "102.*"
+      "strict_max_version": "115.*"
     }
   },
   "manifest_version": 2,
   "name": "__MSG_extensionName__",
-  "version": "4.3",
+  "version": "4.7",
   "author": "John Bieling",
   "homepage_url": "https://github.com/jobisoft/DAV-4-TbSync/";,
   "default_locale": "en-US",

Attachment: OpenPGP_signature.asc
Description: OpenPGP digital signature

Reply via email to