12 次代碼提交 690913b1cc ... fb1ffcb32b

作者 SHA1 備註 提交日期
  gc-server3 fb1ffcb32b db_create mit einem Vorschlag für Mandanten 2 周之前
  gc-server3 40dfd806cc bcp-log verfeinert und an db_run angehängt 2 周之前
  gc-server3 79174cfc42 Neuer Versuch mit status-client 2 月之前
  gc-server3 4cf869d826 bcp csv-trim 2 月之前
  gc-server3 596465b5f1 LDAP-Funktionen über gctools ldap 2 月之前
  gc-server3 781e025d01 db_schema mit SQL-Anywhere 2 月之前
  gc-server3 b100a9daf8 Fehler bei Bereinigung - Carriage Return ohne New Line 2 月之前
  gc-server3 33b4a7cbb8 Problem mit Grad-Zeichen 2 月之前
  gc-server3 b63f07e23d Enhance report output functionality and improve log file handling 5 月之前
  gc-server3 c1d926a0bc Ordner wegen Mehrdeutigkeit umbenannt 5 月之前
  gc-server3 a6a8db6f2f C11 auch remote erreichbar, Export mit retry 5 月之前
  gc-server3 64a5ee52b9 MDL-SQL angepasst - berechnete Felder und eckige Klammern 5 月之前
共有 49 個文件被更改,包括 2726 次插入2542 次删除
  1. 1 0
      .gitignore
  2. 85 5
      c11.py
  3. 20 6
      cognos11/c11_api.py
  4. 34 28
      cognos11/c11_export.py
  5. 67 130
      cognos7/data/mdl/F_Belege_SKR_SKR_Boettche.json
  6. 67 130
      cognos7/data/mdl/F_Belege_SKR_SKR_Boettche_ori.json
  7. 506 506
      cognos7/data/mdl/F_Belege_SKR_SKR_Boettche_queries.sql
  8. 50 131
      cognos7/data/mdl/Fin_Belege_SKR.json
  9. 50 131
      cognos7/data/mdl/Fin_Belege_SKR_ori.json
  10. 638 638
      cognos7/data/mdl/Fin_Belege_SKR_queries.sql
  11. 39 96
      cognos7/data/mdl/S_Aftersales.json
  12. 39 96
      cognos7/data/mdl/S_Aftersales_ori.json
  13. 201 201
      cognos7/data/mdl/S_Aftersales_queries.sql
  14. 6 9
      cognos7/data/mdl/S_Offene_Auftraege.json
  15. 6 9
      cognos7/data/mdl/S_Offene_Auftraege_ori.json
  16. 34 34
      cognos7/data/mdl/S_Offene_Auftraege_queries.sql
  17. 13 4
      cognos7/mdl_convert.py
  18. 1 1
      config/config.py
  19. 0 0
      config/config2/Aufgaben.py
  20. 0 0
      config/config2/Gruppen.json
  21. 0 0
      config/config2/Intervalle.json
  22. 0 0
      config/config2/Reports.csv
  23. 35 16
      database/bcp_log.py
  24. 37 9
      database/db_create.py
  25. 70 4
      database/db_schema.py
  26. 6 5
      database/db_to_parquet.py
  27. 94 53
      database/model.py
  28. 15 1
      db.py
  29. 二進制
      dist/gctools.exe
  30. 1 1
      gctools.bat
  31. 4 2
      gctools.py
  32. 1 1
      gctools.spec
  33. 30 0
      ldap.py
  34. 31 0
      misc/apache_ldap.py
  35. 2 1
      misc/csv_cleanup.py
  36. 31 0
      misc/csv_trim.py
  37. 11 1
      misc/file_move.py
  38. 11 1
      misc2.py
  39. 14 8
      pdf/pdf_test.py
  40. 1 0
      pyproject.toml
  41. 4 6
      status_client/db_info.py
  42. 5 4
      status_client/ftp_client.py
  43. 4 3
      status_client/path_info.py
  44. 4 4
      status_client/process_monitor.py
  45. 37 15
      status_client/status_client.py
  46. 15 0
      tests/test_c11_api.py
  47. 7 0
      tests/test_csv_cleanup.py
  48. 112 0
      tests/test_mdl_convert.py
  49. 287 252
      uv.lock

+ 1 - 0
.gitignore

@@ -4,3 +4,4 @@ venv/
 .venv/
 cognos7/data/mdl/F_Belege_SKR_SKR_Boettche.mdl
 dist/gctools.7z
+cognos7/data/SQL/*

+ 85 - 5
c11.py

@@ -1,6 +1,9 @@
 import os
 import re
+import time
+from datetime import datetime
 from enum import Enum
+from itertools import chain
 from pathlib import Path
 
 import typer
@@ -11,6 +14,10 @@ import config
 from pdf import pdf_merge, pdf_test
 
 
+def flatten_chain(list_of_lists):
+    return list(chain.from_iterable(list_of_lists))
+
+
 class ExportFormat(Enum):
     PDF = "PDF"
     XML = "XML"
@@ -27,15 +34,35 @@ def export(folder="", overwrite="0"):
 
 
 @app.command()
-def reportoutput(folder="", mailcsv=""):
-    exp = cognos11.c11_export(cfg)
+def reportoutput(folder="", mailcsv="", exp=None):
+
+    if re.match(r"^[\d\.\-\/]+$", folder):
+        return reportoutput_by_date(folder, mailcsv)
+
+    if exp is None:
+        exp = cognos11.c11_export(cfg)
+
     # folder2 = exp.get_folder(folder)
     req_plan = exp.get_folder_pdf_request_plan(folder)
     merge_group = exp.get_merge_group(req_plan)
     exp.template(req_plan, merge_group)
 
     req_plan_filtered = exp.filter_request_plan(req_plan, f"{cfg.xml_dir}\\{mailcsv}")
-    exp.execute_request_plan(req_plan_filtered)
+    req_plan_flat = flatten_chain(req_plan_filtered)
+    print("Exportiere Reports...")
+    for i in range(1, 6):
+        print(f"Durchlauf {i}...")
+        req_plan_flat = exp.execute_request_plan(req_plan_flat)
+        if not req_plan_flat:
+            break
+        time.sleep(20)
+        exp.api.login()
+
+    if req_plan_flat:
+        print("!! Fehler: Einige Reports konnten nicht exportiert werden !!")
+        for report_req in req_plan_flat:
+            print(Path(report_req.filename).relative_to(cfg.cognos11.reportoutput_dir))
+
     if mailcsv == "":
         pdf_test.missing_data(f"{cfg.cognos11.reportoutput_dir}\\{folder}")
 
@@ -44,6 +71,59 @@ def reportoutput(folder="", mailcsv=""):
     # pdf_merge.merge_reports_in_folder(self.cfg, folder2)
 
 
+def reportoutput_by_date(date_str: str, mailcsv: str = "") -> None:
+    current_date = None
+    if re.match(r"^\d{4}-\d{2}-\d{2}$", date_str):
+        current_date = datetime.strptime(date_str, "%Y-%m-%d")
+    elif re.match(r"^\d{2}\.\d{2}\.\d{4}$", date_str):
+        current_date = datetime.strptime(date_str, "%d.%m.%Y")
+    elif re.match(r"^\d{2}\/\d{2}\/\d{4}$", date_str):
+        current_date = datetime.strptime(date_str, "%m/%d/%Y")
+
+    if current_date is None:
+        print(f"Ungültiges Datumsformat: {date_str}")
+        return
+
+    exp = cognos11.c11_export(cfg)
+    folders = [f["name"] for f in exp.api.get_folders()]
+    # for f in folders:
+    #     print(f)
+
+    weekdays = ["Mo", "Di", "Mi", "Do", "Fr", "Sa", "So"]
+    current_weekday = weekdays[current_date.weekday()]
+    print(f"Berichte für {current_weekday}, {current_date.strftime('%d.%m.%Y')}...")
+    # taeglich
+    daily_interval = ["Mo-Fr", "Mo-Sa", "Mo-So", "Di-So"]
+    daily_interval_special = {
+        "Mo": ["Mo-Fr", "Mo-Sa", "Mo-So"],
+        "Sa": ["Mo-Sa", "Di-So"],
+        "So": ["Mo-So", "Di-So"]
+    }
+    current_interval = daily_interval_special.get(current_weekday, daily_interval)
+    for c in current_interval:
+        search = f"Team Content/ReportOutput/taeglich/{c}"
+        for f in folders:
+            if search in f:
+                print(f)
+    # woechentlich
+    search = f"Team Content/ReportOutput/woechentlich/{current_weekday}"
+    for f in folders:
+        if search in f:
+            print(f)
+    # 14-taeglich
+    week = (int(current_date.strftime("%W")) % 2) + 1
+    search = f"Team Content/ReportOutput/14-taeglich/{current_weekday}{week}"
+    for f in folders:
+        if search in f:
+            print(f)
+    # monatlich
+    day_of_month = current_date.strftime("%d")
+    search = f"Team Content/ReportOutput/monatlich/{day_of_month}"
+    for f in folders:
+        if search in f:
+            print(f)
+
+
 @app.command()
 def merge(folder="", config=""):
     folder2 = cognos11.c11_export.get_folder(folder)
@@ -115,6 +195,6 @@ def version():
 
 
 if __name__ == "__main__":
-    # app()
+    app()
     # reportoutput()
-    version()
+    # reportoutput("2023-10-02")

+ 20 - 6
cognos11/c11_api.py

@@ -14,6 +14,13 @@ import config
 from cognos11.xml_prettify import prettify_xml
 
 
+def convert_filename(filename: str) -> str:
+    # Entferne ungültige Zeichen
+    filename = re.sub(r'[<>"/|?*]', "", filename)
+    filename = filename.replace("\u2013", "")  # Grad-Zeichen
+    return re.sub(r"[^\x00-\x7F]äöüÄÖÜß", "", filename)
+
+
 class c11_api:
     webservice = ""
     templates_dir = ""
@@ -273,11 +280,16 @@ class c11_api:
             res = [r for r in self.reports if r["path"] == folder]
 
         if specs:
-            return [self.get_report_specs(r) for r in res]
+            for _ in range(5):
+                res = [self.get_report_specs(r) for r in res]
         return res
 
     def get_report_specs(self, report):
+        if "spec" in report:
+            return report
+
         report = self.get_report_filename(report)
+
         headers = {
             "Content-Type": "text/xml; charset=UTF-8",
             "X-XSRF-TOKEN": self.headers["X-XSRF-TOKEN"],
@@ -331,7 +343,7 @@ class c11_api:
 
         for sv in bs.find_all("selectvalue"):
             k = sv["parameter"]
-            v = dict([(opt["usevalue"], opt.get("displayvalue", "")) for opt in sv.find_all("selectoption")])
+            v = dict([(opt.get("usevalue", ""), opt.get("displayvalue", "")) for opt in sv.find_all("selectoption")])
             meta["optional"][k] = v
 
         for sv in bs.find_all("selectdate"):
@@ -343,7 +355,8 @@ class c11_api:
         json.dump(meta, open(filename, "w"), indent=2)
         report["cube"] = self.get_cube_name(meta)
         report["meta"] = meta
-        report["spec"] = parts[2].text
+        if len(meta["optional"]) > 0:
+            report["spec"] = parts[2].text
         return report
 
     @staticmethod
@@ -355,8 +368,8 @@ class c11_api:
                     return res.group(1)
 
     def get_report_filename(self, report):
-        path = report["path"].replace("Team Content/ReportOutput", "")
-        report["filename"] = f"{self.cfg.cognos11.reportoutput_dir}/{path}/{report['name']}.pdf"
+        path = report["path"].replace("Team Content/ReportOutput", "").replace("/", "\\")
+        report["filename"] = f"{self.cfg.cognos11.reportoutput_dir}\\{path}\\{report['name']}.pdf"
         report["format"] = "PDF"
         if report["name"][-5:].lower() == ".xlsx":
             report["format"] = "spreadsheetML"
@@ -365,6 +378,7 @@ class c11_api:
         report["params"] = list(re.findall(r"\[([^\]]+)\]", report["filename"]))
         for i, p in enumerate(report["params"]):
             report["filename"] = report["filename"].replace("[" + p + "]", "{" + str(i) + "}")
+        report["filename"] = convert_filename(report["filename"])
         return report
 
     def request_unstubbed(self, report_id):
@@ -451,7 +465,7 @@ class c11_api:
             return 200, parts[1].content
 
         error = bs.find_all("messageString")[0].string
-        logging.debug(error)
+        logging.info(error)
         return r.status_code, error
 
     def get_users(self, export_dir):

+ 34 - 28
cognos11/c11_export.py

@@ -7,7 +7,7 @@ from datetime import datetime
 from pathlib import Path
 
 import config
-from cognos11.c11_api import c11_api
+from cognos11.c11_api import c11_api, convert_filename
 
 
 @dataclass
@@ -32,7 +32,7 @@ class c11_export:
             self.api = c11_api(cfg).login()
 
         now = datetime.now().strftime("%Y%m%d_%H%M%S")
-        prot_file = f"{self.cfg.cognos11.logs_dir}/c11_export_{now}.log"
+        prot_file = f"{self.cfg.cognos11.logs_dir}\\c11_export_{now}.log"
         os.makedirs(self.cfg.cognos11.logs_dir, exist_ok=True)
         logging.basicConfig(
             filename=prot_file,
@@ -83,7 +83,7 @@ class c11_export:
         # test if execution of report is possible
         self.request_and_save_file(request, save=False)
 
-        filename = f"{self.cfg.cognos11.specs_dir}/{report['path']}/{report['name']}.xml"
+        filename = f"{self.cfg.cognos11.specs_dir}\\{report['path']}\\{report['name']}.xml"
         modified = datetime.fromisoformat(report["modified"]).timestamp()
         if not overwrite and Path(filename).exists() and Path(filename).stat().st_mtime > modified:
             return
@@ -113,34 +113,34 @@ class c11_export:
             return []
 
         if len(report["params"]) == 0:
-            filename = report["filename"]
+            filename = convert_filename(report["filename"])
             params = self.get_params(report, {})
             return [ReportRequest(report["id"], params, filename, report["format"])]
         result = []
         if len(report["params"]) == 1:
-            filename = report["filename"].format("_Summe")
+            filename = convert_filename(report["filename"].format("_Summe"))
             params = self.get_params(report, {})
             result.append(ReportRequest(report["id"], params, filename, report["format"]))
 
             key1 = report["params"][0]
             for k1, v1 in report["meta"]["optional"][key1].items():
-                filename = report["filename"].format(v1)
+                filename = convert_filename(report["filename"].format(v1))
                 params = self.get_params(report, {key1: {k1: v1}})
                 result.append(ReportRequest(report["id"], params, filename, report["format"]))
             return result
         if len(report["params"]) == 2:
-            filename = report["filename"].format("_Summe", "").replace("_.", ".")
+            filename = convert_filename(report["filename"].format("_Summe", "").replace("_.", "."))
             params = self.get_params(report, {})
             result.append(ReportRequest(report["id"], params, filename, report["format"]))
 
             key1, key2 = report["params"]
             for k1, v1 in report["meta"]["optional"][key1].items():
-                filename = report["filename"].format(v1, "_Summe")
+                filename = convert_filename(report["filename"].format(v1, "_Summe"))
                 params = self.get_params(report, {key1: {k1: v1}})
                 result.append(ReportRequest(report["id"], params, filename, report["format"]))
 
                 for k2, v2 in report["meta"]["optional"][key2].items():
-                    filename = report["filename"].format(v1, v2)
+                    filename = convert_filename(report["filename"].format(v1, v2))
                     params = self.get_params(report, {key1: {k1: v1}, key2: {k2: v2}})
                     result.append(ReportRequest(report["id"], params, filename, report["format"]))
             return result
@@ -163,13 +163,13 @@ class c11_export:
                 filename, mailto = row.split(";", 2)
                 if "@" not in mailto:
                     continue
-                required_files.append(str(Path(self.cfg.cognos11.reportoutput_dir + "/" + filename).resolve()))
+                required_files.append(str(Path(self.cfg.cognos11.reportoutput_dir + "\\" + filename).resolve()))
                 if "_Schichten." in filename and "erstellte_Schichten" not in filename:
                     filename2 = filename.replace("__Summe_und_Schichten", "__Summe").replace(
                         "__nur_Schichten", "__Summe"
                     )
                     required_full_export.append(
-                        str(Path(self.cfg.cognos11.reportoutput_dir + "/" + filename2).resolve())
+                        str(Path(self.cfg.cognos11.reportoutput_dir + "\\" + filename2).resolve())
                     )
         res = []
         for req_group in req_plan:
@@ -179,31 +179,37 @@ class c11_export:
                 res.append([req for req in req_group if str(Path(req.filename).resolve()) in required_files])
         return res
 
-    def execute_request_plan(self, req_plan: list[list[ReportRequest]]):
-        for req_group in req_plan:
-            for report_req in req_group:
-                print(Path(report_req.filename).relative_to(self.cfg.cognos11.reportoutput_dir))
-                self.request_and_save_file(report_req)
+    def execute_request_plan(self, req_plan: list[ReportRequest]) -> list[ReportRequest]:
+        failed_requests = []
+        for report_req in req_plan:
+            print(Path(report_req.filename).relative_to(self.cfg.cognos11.reportoutput_dir))
+            if not self.request_and_save_file(report_req):
+                failed_requests.append(report_req)
+        return failed_requests
 
     def request_and_save_file(self, report_request: ReportRequest, save=True):
         logging.debug(report_request.filename)
         logging.debug(report_request.params)
+
+        os.makedirs(os.path.dirname(report_request.filename), exist_ok=True)
+        Path(report_request.filename).unlink(missing_ok=True)
+
         status_code, content = self.api.request_file(
             report_request.report_id,
             report_request.params,
             report_request.report_format,
         )
         if status_code != 200:
-            return
-
-        if not save:
-            return
-        os.makedirs(os.path.dirname(report_request.filename), exist_ok=True)
-        try:
-            with open(report_request.filename, "wb") as f:
-                f.write(content)
-        except PermissionError:
-            print("--> not accessible!")
+            return False
+
+        if save:
+            try:
+                with open(report_request.filename, "wb") as f:
+                    f.write(content)
+            except PermissionError:
+                print("--> not accessible!")
+                return False
+        return True
 
     def get_merge_group(self, req_plan: list[list[ReportRequest]]):
         res = {}
@@ -225,7 +231,7 @@ class c11_export:
     def export_errors(self):
         reports = self.api.get_reports_in_folder("Team Content", recursive=True, specs=True)
         errors = [r for r in reports if "error" in r and not self.is_obsolete_or_ignored(r)]
-        filename = self.cfg.cognos11.logs_dir + "/c11_report_errors.json"
+        filename = self.cfg.cognos11.logs_dir + "\\c11_report_errors.json"
         json.dump(errors, open(filename, "w"), indent=2)
 
     def template(self, req_plan: list[list[ReportRequest]], merge_group: dict[str, list[str]]):
@@ -242,7 +248,7 @@ class c11_export:
                 mail_groups[folder].append(filename)
         for group, file_list in mail_groups.items():
             with open(
-                self.cfg.cognos11.config_dir + f"/{group}.template.csv",
+                self.cfg.cognos11.config_dir + f"\\{group}.template.csv",
                 "w",
                 encoding="latin-1",
             ) as fwh:

+ 67 - 130
cognos7/data/mdl/F_Belege_SKR_SKR_Boettche.json

@@ -389,7 +389,7 @@
           "InputScale": "0",
           "TimeArray": "Off",
           "ColSrcType": "None",
-          "Calc": "month",
+          "Calc": "month ( \"Bookkeep Date@9238295\" )",
           "Associations": [
             {
               "Type": "Associations",
@@ -9124,7 +9124,7 @@
           "InputScale": "0",
           "TimeArray": "Off",
           "ColSrcType": "None",
-          "Calc": "month",
+          "Calc": "month ( \"Bookkeep Date@9239639\" )",
           "Associations": [
             {
               "Type": "Associations",
@@ -10467,7 +10467,7 @@
           "InputScale": "0",
           "TimeArray": "Off",
           "ColSrcType": "None",
-          "Calc": "month",
+          "Calc": "month ( \"Bookkeep Date@9239641\" )",
           "Associations": [
             {
               "Type": "Associations",
@@ -11811,7 +11811,7 @@
           "InputScale": "0",
           "TimeArray": "Off",
           "ColSrcType": "None",
-          "Calc": "month",
+          "Calc": "month ( \"Bookkeep Date@9239643\" )",
           "Associations": [
             {
               "Type": "Associations",
@@ -12143,7 +12143,7 @@
           "Label": "M bisher \u00c4nderung",
           "Rollup": "False",
           "TimeAggregate": "None",
-          "Calc": "change \"M bisher gruppiert~Voriger M bisher@11635\" \"M bisher gruppiert~M bisher@11633\""
+          "Calc": "change ( \"M bisher gruppiert~Voriger M bisher@11635\" , \"M bisher gruppiert~M bisher@11633\" )"
         },
         {
           "Type": "SpecialCategory",
@@ -12153,8 +12153,7 @@
           "Label": "M bisher Zuwachs",
           "Rollup": "False",
           "TimeAggregate": "None",
-          "Calc": "growth \"M bisher gruppiert~Voriger M bisher@11635\" \"M bisher gruppiert~M bisher@11633\"",
-          "\"0%~2\"": "Sign"
+          "Calc": "percent-growth ( \"M bisher gruppiert~Voriger M bisher@11635\" , \"M bisher gruppiert~M bisher@11633\" )"
         },
         {
           "Type": "SpecialCategory",
@@ -12282,7 +12281,7 @@
           "Label": "Q bisher \u00c4nderung",
           "Rollup": "False",
           "TimeAggregate": "None",
-          "Calc": "change \"Q bisher gruppiert~Voriges Q bisher@11649\" \"Q bisher gruppiert~Q bisher@11645\""
+          "Calc": "change ( \"Q bisher gruppiert~Voriges Q bisher@11649\" , \"Q bisher gruppiert~Q bisher@11645\" )"
         },
         {
           "Type": "SpecialCategory",
@@ -12292,8 +12291,7 @@
           "Label": "Q bisher Zuwachs",
           "Rollup": "False",
           "TimeAggregate": "None",
-          "Calc": "growth \"Q bisher gruppiert~Voriges Q bisher@11649\" \"Q bisher gruppiert~Q bisher@11645\"",
-          "\"0%~2\"": "Sign"
+          "Calc": "percent-growth ( \"Q bisher gruppiert~Voriges Q bisher@11649\" , \"Q bisher gruppiert~Q bisher@11645\" )"
         },
         {
           "Type": "SpecialCategory",
@@ -12461,7 +12459,7 @@
           "Label": "J bisher \u00c4nderung",
           "Rollup": "False",
           "TimeAggregate": "None",
-          "Calc": "change \"J bisher gruppiert~Voriges J bisher@11667\" \"J bisher gruppiert~J bisher@11661\""
+          "Calc": "change ( \"J bisher gruppiert~Voriges J bisher@11667\" , \"J bisher gruppiert~J bisher@11661\" )"
         },
         {
           "Type": "SpecialCategory",
@@ -12471,8 +12469,7 @@
           "Label": "J bisher Zuwachs",
           "Rollup": "False",
           "TimeAggregate": "None",
-          "Calc": "growth \"J bisher gruppiert~Voriges J bisher@11667\" \"J bisher gruppiert~J bisher@11661\"",
-          "\"0%~2\"": "Sign"
+          "Calc": "percent-growth ( \"J bisher gruppiert~Voriges J bisher@11667\" , \"J bisher gruppiert~J bisher@11661\" )"
         }
       ]
     },
@@ -13386,8 +13383,7 @@
           "Levels": "Ebene1",
           "Label": "Rohertrag",
           "SourceValue": "9210395",
-          "Calc": "\"Umsatzerl\u00f6se@28389\" 1 \"Einsatzwerte@24713\"",
-          "False": "Blanks"
+          "Calc": "( \"Umsatzerl\u00f6se@28389\" * - 1 ) - \"Einsatzwerte@24713\""
         },
         {
           "Type": "Category",
@@ -13396,9 +13392,7 @@
           "Levels": "Ebene1",
           "Label": "Rohertrag in %",
           "SourceValue": "9210397",
-          "Calc": "\"9210395@9210395\" \"Umsatzerl\u00f6se@28389\" 1 100",
-          "\"#,##0~1\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "\"9210395@9210395\" / ( \"Umsatzerl\u00f6se@28389\" * - 1 ) * 100"
         },
         {
           "Type": "Category",
@@ -13437,9 +13431,7 @@
           "Levels": "Ebene1",
           "Label": "Bruttoertrag",
           "SourceValue": "2029389",
-          "Calc": "\"Umsatzerl\u00f6se@28389\" 1 \"Einsatzwerte@24713\" \"Zusch\u00fcsse / Provisionen / Boni@9210389\" 1 \"Sonstige Ertr\u00e4ge_1@9210393\" 1",
-          "\"#,##0~0\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "( \"Umsatzerl\u00f6se@28389\" * - 1 ) - \"Einsatzwerte@24713\" + ( \"Zusch\u00fcsse / Provisionen / Boni@9210389\" * - 1 ) + ( \"Sonstige Ertr\u00e4ge_1@9210393\" * - 1 )"
         },
         {
           "Type": "Category",
@@ -13448,9 +13440,7 @@
           "Levels": "Ebene1",
           "Label": "Bruttoertrag in %",
           "SourceValue": "2029391",
-          "Calc": "\"2029389@2029389\" \"Umsatzerl\u00f6se@28389\" 1 100",
-          "\"#,##0~1\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "\"2029389@2029389\" / ( \"Umsatzerl\u00f6se@28389\" * - 1 ) * 100"
         },
         {
           "Type": "Category",
@@ -13488,9 +13478,7 @@
           "Levels": "Ebene2",
           "Label": "Bruttoertrag II",
           "SourceValue": "3377987",
-          "Calc": "\"2029389@2029389\" \"Variable Kosten@24089\"",
-          "\"#,##0~0\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "\"2029389@2029389\" - \"Variable Kosten@24089\""
         },
         {
           "Type": "Category",
@@ -13499,9 +13487,7 @@
           "Levels": "Ebene2",
           "Label": "Bruttoertrag II in %",
           "SourceValue": "3377989",
-          "Calc": "\"3377987@3377987\" \"Umsatzerl\u00f6se@28389\" 1 100",
-          "\"#,##0~1\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "\"3377987@3377987\" / ( \"Umsatzerl\u00f6se@28389\" * - 1 ) * 100"
         },
         {
           "Type": "Category",
@@ -13525,9 +13511,7 @@
           "Levels": "Ebene2",
           "Label": "Deckungsbeitrag",
           "SourceValue": "2227701",
-          "Calc": "\"2029389@2029389\" \"Variable Kosten@24089\" \"Direkte Kosten@22415\"",
-          "\"#,##0~0\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "\"2029389@2029389\" - ( \"Variable Kosten@24089\" + \"Direkte Kosten@22415\" )"
         },
         {
           "Type": "Category",
@@ -13536,9 +13520,7 @@
           "Levels": "Ebene2",
           "Label": "Deckungsbeitrag in %",
           "SourceValue": "2227703",
-          "Calc": "\"2227701@2227701\" \"Umsatzerl\u00f6se@28389\" 1 100",
-          "\"#,##0~1\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "\"2227701@2227701\" / ( \"Umsatzerl\u00f6se@28389\" * - 1 ) * 100"
         },
         {
           "Type": "Category",
@@ -13562,9 +13544,7 @@
           "Levels": "Ebene1",
           "Label": "Betriebsergebnis",
           "SourceValue": "2734471",
-          "Calc": "\"2227701@2227701\" \"Indirekte Kosten@22403\"",
-          "\"#,##0~0\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "\"2227701@2227701\" - \"Indirekte Kosten@22403\""
         },
         {
           "Type": "Category",
@@ -13573,9 +13553,7 @@
           "Levels": "Ebene1",
           "Label": "Betriebsergebnis in %",
           "SourceValue": "2734473",
-          "Calc": "\"2734471@2734471\" \"Umsatzerl\u00f6se@28389\" 1 100",
-          "\"#,##0~1\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "\"2734471@2734471\" / ( \"Umsatzerl\u00f6se@28389\" * - 1 ) * 100"
         },
         {
           "Type": "Category",
@@ -13612,8 +13590,7 @@
           "Levels": "Ebene1",
           "Label": "UN-Ergebnis v. St.",
           "SourceValue": "7653815",
-          "Calc": "\"2734471@2734471\" \"Neutrales Ergebnis@2226211\"",
-          "False": "Blanks"
+          "Calc": "\"2734471@2734471\" - \"Neutrales Ergebnis@2226211\""
         },
         {
           "Type": "Category",
@@ -13622,8 +13599,7 @@
           "Levels": "Ebene1",
           "Label": "UN-Ergebnis v. St.  in %",
           "SourceValue": "7653817",
-          "Calc": "\"2734475@7653815\" \"Umsatzerl\u00f6se@28389\" 1 100",
-          "False": "Blanks"
+          "Calc": "\"2734475@7653815\" / ( \"Umsatzerl\u00f6se@28389\" * - 1 ) * 100"
         },
         {
           "Type": "Category",
@@ -14197,8 +14173,7 @@
           "Levels": "Ebene1",
           "Label": "Nettogewinn",
           "SourceValue": "8795175",
-          "Calc": "\"2734475@7653815\" \"Einkommens- und Gewerbesteuer@8792563\"",
-          "False": "Blanks"
+          "Calc": "\"2734475@7653815\" - \"Einkommens- und Gewerbesteuer@8792563\""
         },
         {
           "Type": "Category",
@@ -14207,8 +14182,7 @@
           "Levels": "Ebene1",
           "Label": "Nettogewinn in %",
           "SourceValue": "8795177",
-          "Calc": "\"8795175@8795175\" \"Umsatzerl\u00f6se@28389\" 1 100",
-          "False": "Blanks"
+          "Calc": "\"8795175@8795175\" / ( \"Umsatzerl\u00f6se@28389\" * - 1 ) * 100"
         },
         {
           "Type": "Category",
@@ -14608,7 +14582,7 @@
           "Levels": "0",
           "Label": "Bruttoertrag",
           "Rollup": "True",
-          "Calc": "\"8850385@8850385\" 1 \"8850387@8850387\""
+          "Calc": "( \"8850385@8850385\" * - 1 ) - \"8850387@8850387\""
         },
         {
           "Type": "SpecialCategory",
@@ -14617,8 +14591,7 @@
           "Levels": "0",
           "Label": "Bruttoertrag in %",
           "Rollup": "True",
-          "Calc": "\"8850389@8850389\" \"8850385@8850385\" 1 100",
-          "\"#,##0~1\"": "Sign"
+          "Calc": "\"8850389@8850389\" / ( \"8850385@8850385\" * - 1 ) * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -14663,7 +14636,7 @@
           "Levels": "0",
           "Label": "Gesamtbruttoertrag",
           "Rollup": "True",
-          "Calc": "\"8850389@8850389\" \"8850393@8850393\" \"8850395@8850395\" \"8850401@8850401\" 1 \"8850399@8850399\" 1"
+          "Calc": "\"8850389@8850389\" - \"8850393@8850393\" - \"8850395@8850395\" + ( \"8850401@8850401\" * - 1 ) + ( \"8850399@8850399\" * - 1 )"
         },
         {
           "Type": "SpecialCategory",
@@ -14672,8 +14645,7 @@
           "Levels": "0",
           "Label": "Gesamtbruttoertrag in %",
           "Rollup": "True",
-          "Calc": "\"8850403@8850403\" \"8850385@8850385\" 1 100",
-          "\"#,##0~1\"": "Sign"
+          "Calc": "\"8850403@8850403\" / ( \"8850385@8850385\" * - 1 ) * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -14727,7 +14699,7 @@
           "Levels": "0",
           "Label": "Deckungsbeitrag 1",
           "Rollup": "True",
-          "Calc": "\"8850403@8850403\" \"8850737@8850737\""
+          "Calc": "\"8850403@8850403\" - \"8850737@8850737\""
         },
         {
           "Type": "SpecialCategory",
@@ -14736,8 +14708,7 @@
           "Levels": "0",
           "Label": "Deckungsbeitrag 1 in %",
           "Rollup": "True",
-          "Calc": "\"8850739@8850739\" \"8850385@8850385\" 1 100",
-          "\"#,##0~1\"": "Sign"
+          "Calc": "\"8850739@8850739\" / ( \"8850385@8850385\" * - 1 ) * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -14818,7 +14789,7 @@
           "Levels": "0",
           "Label": "Deckungsbeitrag 2",
           "Rollup": "True",
-          "Calc": "\"8850739@8850739\" \"8850741@8850741\""
+          "Calc": "\"8850739@8850739\" - \"8850741@8850741\""
         },
         {
           "Type": "SpecialCategory",
@@ -14827,8 +14798,7 @@
           "Levels": "0",
           "Label": "Deckungsbeitrag 2 in %",
           "Rollup": "True",
-          "Calc": "\"8876091@8876091\" \"8850385@8850385\" 1 100",
-          "\"#,##0~1\"": "Sign"
+          "Calc": "\"8876091@8876091\" / ( \"8850385@8850385\" * - 1 ) * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -14855,7 +14825,7 @@
           "Levels": "0",
           "Label": "Betriebsergebnis 1",
           "Rollup": "True",
-          "Calc": "\"8876091@8876091\" \"8876815@8876815\""
+          "Calc": "\"8876091@8876091\" - \"8876815@8876815\""
         },
         {
           "Type": "SpecialCategory",
@@ -14864,8 +14834,7 @@
           "Levels": "0",
           "Label": "Betriebsergebnis 1 in %",
           "Rollup": "True",
-          "Calc": "\"8880475@8880475\" \"8850385@8850385\" 1 100",
-          "\"#,##0~1\"": "Sign"
+          "Calc": "\"8880475@8880475\" / ( \"8850385@8850385\" * - 1 ) * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -14883,7 +14852,7 @@
           "Levels": "0",
           "Label": "Betriebsergebnis 2",
           "Rollup": "True",
-          "Calc": "\"8880475@8880475\" \"8880471@8880471\""
+          "Calc": "\"8880475@8880475\" - \"8880471@8880471\""
         },
         {
           "Type": "SpecialCategory",
@@ -14892,8 +14861,7 @@
           "Levels": "0",
           "Label": "Betriebsergebnis 2 in %",
           "Rollup": "True",
-          "Calc": "\"8880477@8880477\" \"8850385@8850385\" 1 100",
-          "\"#,##0~1\"": "Sign"
+          "Calc": "\"8880477@8880477\" / ( \"8850385@8850385\" * - 1 ) * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -14920,7 +14888,7 @@
           "Levels": "0",
           "Label": "Gesamterg. vor Steuern",
           "Rollup": "True",
-          "Calc": "\"8880477@8880477\" \"8876807@8876807\" \"8876809@8876809\""
+          "Calc": "\"8880477@8880477\" - \"8876807@8876807\" - \"8876809@8876809\""
         },
         {
           "Type": "SpecialCategory",
@@ -14929,8 +14897,7 @@
           "Levels": "0",
           "Label": "Gesamterg. vor Steuern in %",
           "Rollup": "True",
-          "Calc": "\"8876811@8876811\" \"8850385@8850385\" 1 100",
-          "\"#,##0~1\"": "Sign"
+          "Calc": "\"8876811@8876811\" / ( \"8850385@8850385\" * - 1 ) * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -14948,8 +14915,7 @@
           "Levels": "0",
           "Label": "Pers. kostenquote %",
           "Rollup": "False",
-          "Calc": "\"9210289@9210289\" \"Umsatzerl\u00f6se@28389\" 1 100",
-          "\"#,##0~2\"": "Sign"
+          "Calc": "\"9210289@9210289\" / ( \"Umsatzerl\u00f6se@28389\" * - 1 ) * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -14967,8 +14933,7 @@
           "Levels": "0",
           "Label": "Werbekostenquote %",
           "Rollup": "False",
-          "Calc": "\"9210293@9210293\" \"Umsatzerl\u00f6se@28389\" 1 100",
-          "\"#,##0~2\"": "Sign"
+          "Calc": "\"9210293@9210293\" / ( \"Umsatzerl\u00f6se@28389\" * - 1 ) * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -15040,7 +15005,7 @@
           "Levels": "0",
           "Label": "Gesamt BE Verkauf",
           "Rollup": "True",
-          "Calc": "\"9629087@9629087\" \"9629089@9629089\" \"9629091@9629091\" \"9629093@9629093\" \"9629095@9629095\" \"9629097@9629097\" 1"
+          "Calc": "( \"9629087@9629087\" + \"9629089@9629089\" + \"9629091@9629091\" + \"9629093@9629093\" + \"9629095@9629095\" + \"9629097@9629097\" ) * - 1"
         },
         {
           "Type": "SpecialCategory",
@@ -15076,7 +15041,7 @@
           "Levels": "0",
           "Label": "Gesamt KD",
           "Rollup": "True",
-          "Calc": "\"9629101@9629101\" \"9629103@9629103\" \"9629105@9629105\" 1"
+          "Calc": "( \"9629101@9629101\" + \"9629103@9629103\" + \"9629105@9629105\" ) * - 1"
         },
         {
           "Type": "SpecialCategory",
@@ -15112,7 +15077,7 @@
           "Levels": "0",
           "Label": "Gesamt",
           "Rollup": "True",
-          "Calc": "\"9629099@9629099\" \"9629107@9629107\" \"9629109@9629109\" \"9629111@9629111\" \"9629113@9629113\" 1"
+          "Calc": "\"9629099@9629099\" + \"9629107@9629107\" + ( ( \"9629109@9629109\" + \"9629111@9629111\" + \"9629113@9629113\" ) * - 1 )"
         },
         {
           "Type": "SpecialCategory",
@@ -15130,8 +15095,7 @@
           "Levels": "0",
           "Label": "NW %",
           "Rollup": "True",
-          "Calc": "\"9629087@9629087\" \"NW~21012@9543583\" 100",
-          "\"#,##0~2\"": "Sign"
+          "Calc": "\"9629087@9629087\" / \"NW~21012@9543583\" * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -15140,8 +15104,7 @@
           "Levels": "0",
           "Label": "sonst. BE NW %",
           "Rollup": "True",
-          "Calc": "\"9629091@9629091\" \"sonst Erl\u00f6se NW@9565389\" 100",
-          "\"#,##0~2\"": "Sign"
+          "Calc": "\"9629091@9629091\" / \"sonst Erl\u00f6se NW@9565389\" * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -15150,8 +15113,7 @@
           "Levels": "0",
           "Label": "GW %",
           "Rollup": "True",
-          "Calc": "\"9629093@9629093\" \"GW~21017@9561545\" 100",
-          "\"#,##0~2\"": "Sign"
+          "Calc": "\"9629093@9629093\" / \"GW~21017@9561545\" * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -15160,8 +15122,7 @@
           "Levels": "0",
           "Label": "sonst. BE GW %",
           "Rollup": "True",
-          "Calc": "\"9629097@9629097\" \"sonst Erl\u00f6se GW@9565363\" 100",
-          "\"#,##0~2\"": "Sign"
+          "Calc": "\"9629097@9629097\" / \"sonst Erl\u00f6se GW@9565363\" * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -15170,8 +15131,7 @@
           "Levels": "0",
           "Label": "Gesamt BE Verkauf %",
           "Rollup": "True",
-          "Calc": "\"9629099@9629099\" \"NW~21012@9543583\" \"GW~21017@9561545\" \"Prov NW@9600789\" \"Prov GW@9600763\" \"sonst Erl\u00f6se NW@9565389\" \"sonst Erl\u00f6se GW@9565363\" 1 100",
-          "\"#,##0~2\"": "Sign"
+          "Calc": "\"9629099@9629099\" / ( ( \"NW~21012@9543583\" + \"GW~21017@9561545\" + \"Prov NW@9600789\" + \"Prov GW@9600763\" + \"sonst Erl\u00f6se NW@9565389\" + \"sonst Erl\u00f6se GW@9565363\" ) * - 1 ) * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -15180,8 +15140,7 @@
           "Levels": "0",
           "Label": "T+Z %",
           "Rollup": "True",
-          "Calc": "\"9629101@9629101\" \"T+Z~20978@9476799\" 100",
-          "\"#,##0~2\"": "Sign"
+          "Calc": "\"9629101@9629101\" / \"T+Z~20978@9476799\" * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -15190,8 +15149,7 @@
           "Levels": "0",
           "Label": "Service %",
           "Rollup": "True",
-          "Calc": "\"9629103@9629103\" \"Service~20983@9476873\" 100",
-          "\"#,##0~2\"": "Sign"
+          "Calc": "\"9629103@9629103\" / \"Service~20983@9476873\" * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -15200,8 +15158,7 @@
           "Levels": "0",
           "Label": "Fremdl. %",
           "Rollup": "True",
-          "Calc": "\"9629105@9629105\" \"Fremdleistung~21030@9586055\" 100",
-          "\"#,##0~2\"": "Sign"
+          "Calc": "\"9629105@9629105\" / \"Fremdleistung~21030@9586055\" * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -15210,8 +15167,7 @@
           "Levels": "0",
           "Label": "Gesamt KD %",
           "Rollup": "True",
-          "Calc": "\"9629107@9629107\" \"T+Z~20978@9476799\" \"Service~20983@9476873\" \"Fremdleistung~21030@9586055\" 1 100",
-          "\"#,##0~2\"": "Sign"
+          "Calc": "\"9629107@9629107\" / ( ( \"T+Z~20978@9476799\" + \"Service~20983@9476873\" + \"Fremdleistung~21030@9586055\" ) * - 1 ) * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -15220,8 +15176,7 @@
           "Levels": "0",
           "Label": "sonstige %",
           "Rollup": "True",
-          "Calc": "\"9629111@9629111\" \"sonstige@9602415\" 100",
-          "\"#,##0~2\"": "Sign"
+          "Calc": "\"9629111@9629111\" / \"sonstige@9602415\" * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -15230,8 +15185,7 @@
           "Levels": "0",
           "Label": "intern %",
           "Rollup": "True",
-          "Calc": "\"9629113@9629113\" \"interne Erl\u00f6se@9476597\" 100",
-          "\"#,##0~2\"": "Sign"
+          "Calc": "\"9629113@9629113\" / \"interne Erl\u00f6se@9476597\" * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -15240,8 +15194,7 @@
           "Levels": "0",
           "Label": "Gesamt %",
           "Rollup": "True",
-          "Calc": "\"2029391@2029391\"",
-          "\"#,##0~2\"": "Sign"
+          "Calc": "\"2029391@2029391\""
         }
       ]
     },
@@ -16153,8 +16106,7 @@
           "Levels": "Kostenstelle",
           "Label": "Sales",
           "SourceValue": "8795215",
-          "Calc": "\"Neuwagen@8795199\" \"Gebrauchtwagen@8795201\"",
-          "False": "Blanks"
+          "Calc": "\"Neuwagen@8795199\" + \"Gebrauchtwagen@8795201\""
         },
         {
           "Type": "Category",
@@ -16163,8 +16115,7 @@
           "Levels": "Kostenstelle",
           "Label": "Aftersales",
           "SourceValue": "8795217",
-          "Calc": "\"Teile & Zubeh\u00f6r@8795203\" \"Service@8795205\"",
-          "False": "Blanks"
+          "Calc": "\"Teile & Zubeh\u00f6r@8795203\" + \"Service@8795205\""
         },
         {
           "Type": "Category",
@@ -16173,8 +16124,7 @@
           "Levels": "Kostenstelle",
           "Label": "Service",
           "SourceValue": "8795219",
-          "Calc": "\"Service@8795205\"",
-          "False": "Blanks"
+          "Calc": "\"Service@8795205\""
         },
         {
           "Type": "Category",
@@ -20511,8 +20461,7 @@
           "Label": "Bilanzgewinn",
           "Inclusion": "Generate",
           "SourceValue": "8813525",
-          "Calc": "\"Aktiva@8804271\" \"Passiva@8805279\"",
-          "False": "Blanks"
+          "Calc": "\"Aktiva@8804271\" + \"Passiva@8805279\""
         },
         {
           "Type": "Category",
@@ -20522,8 +20471,7 @@
           "Label": "Passiva I",
           "Inclusion": "Generate",
           "SourceValue": "8813527",
-          "Calc": "\"Passiva@8805279\" 1 \"3377991@8813525\"",
-          "False": "Blanks"
+          "Calc": "( \"Passiva@8805279\" * - 1 ) + \"3377991@8813525\""
         },
         {
           "Type": "Category",
@@ -21121,8 +21069,7 @@
           "Label": "Gesamtleistung",
           "Inclusion": "Generate",
           "SourceValue": "8813537",
-          "Calc": "\"1. Umsatzerl\u00f6se@8812359\" 1 \"8813529@8813529\" 1 \"3. Sonstige betriebliche Ertr\u00e4ge@8809953\" 1",
-          "False": "Blanks"
+          "Calc": "( \"1. Umsatzerl\u00f6se@8812359\" * - 1 ) + ( \"8813529@8813529\" * - 1 ) + ( \"3. Sonstige betriebliche Ertr\u00e4ge@8809953\" * - 1 )"
         },
         {
           "Type": "Category",
@@ -21448,8 +21395,7 @@
           "Label": "12. Ergebnis der gew\u00f6hnlichen Gesch\u00e4ftst\u00e4tigkeit",
           "Inclusion": "Generate",
           "SourceValue": "8813539",
-          "Calc": "\"6293933@8813537\" \"4. Materialaufwand@8812179\" \"5. Personalaufwand@8809329\" \"6. Abschreibungen@8809293\" \"7. Sonst. betriebl. Aufwendungen@8809661\" \"8. Ertr\u00e4ge aus Beteiligungen@8810133\" 1 \"9. Sonst.Zinsen u.\u00e4hnl.Ertr\u00e4ge@8810225\" 1 \"10. Aufw. aus Verlust\u00fcbernahme@8809989\" \"11. Zinsen u.\u00e4hnl.Aufwendungen@8809081\"",
-          "False": "Blanks"
+          "Calc": "\"6293933@8813537\" - \"4. Materialaufwand@8812179\" - \"5. Personalaufwand@8809329\" - \"6. Abschreibungen@8809293\" - \"7. Sonst. betriebl. Aufwendungen@8809661\" + ( \"8. Ertr\u00e4ge aus Beteiligungen@8810133\" * - 1 ) + ( \"9. Sonst.Zinsen u.\u00e4hnl.Ertr\u00e4ge@8810225\" * - 1 ) - \"10. Aufw. aus Verlust\u00fcbernahme@8809989\" - \"11. Zinsen u.\u00e4hnl.Aufwendungen@8809081\""
         },
         {
           "Type": "Category",
@@ -21519,8 +21465,7 @@
           "Label": "Jahres\u00fcberschuss",
           "Inclusion": "Generate",
           "SourceValue": "8813541",
-          "Calc": "\"6293935@8813539\" \"13. Au\u00dferordentliche Ertr\u00e4ge@8810073\" 1 \"14. Steuern vom Einkommen u.Ertrag@8809489\" \"15. Sonstige Steuern@8809453\" \"16. Ertr\u00e4ge aus Verlust\u00fcbernahme@8810641\" 1",
-          "False": "Blanks"
+          "Calc": "\"6293935@8813539\" + ( \"13. Au\u00dferordentliche Ertr\u00e4ge@8810073\" * - 1 ) - \"14. Steuern vom Einkommen u.Ertrag@8809489\" - \"15. Sonstige Steuern@8809453\" + ( \"16. Ertr\u00e4ge aus Verlust\u00fcbernahme@8810641\" * - 1 )"
         },
         {
           "Type": "Category",
@@ -23362,9 +23307,7 @@
     {
       "Type": "Measure",
       "Name": "Ist",
-      "Calc": "\"Ist_Euro@399\" \"Ist_Stk@9629119\" Missing Zero IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 5 ReverseSign True IsCurrency False IsFolder False",
-      "\"#,##0~0\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "\"Ist_Euro@399\" + \"Ist_Stk@9629119\"  Missing Zero IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 5 Reverse",
       "Associations": []
     },
     {
@@ -23394,9 +23337,7 @@
     {
       "Type": "Measure",
       "Name": "Plan",
-      "Calc": "0 Missing Zero Timing After_Rollup IgnoreMissingValue False Storage Float64 OutPutScale 0 Decimals 3 ReverseSign True IsCurrency False IsFolder False",
-      "\"#,##0~0\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "0  Missing Zero Timing After_Rollup IgnoreMissingValue False Storage Float64 OutPutScale 0 Decimals 3 Reverse",
       "Associations": []
     },
     {
@@ -23562,17 +23503,13 @@
     {
       "Type": "Measure",
       "Name": "EW Lohn Plan Tag",
-      "Calc": "0 Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 0 Decimals 4 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~0\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "0  Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 0 Decimals 4 Reverse",
       "Associations": []
     },
     {
       "Type": "Measure",
       "Name": "Bruttoertrag Soll Tag",
-      "Calc": "0 Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 0 Decimals 5 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~0\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "0  Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 0 Decimals 5 Reverse",
       "Associations": []
     }
   ],

+ 67 - 130
cognos7/data/mdl/F_Belege_SKR_SKR_Boettche_ori.json

@@ -425,7 +425,7 @@
           "InputScale": "0",
           "TimeArray": "Off",
           "ColSrcType": "None",
-          "Calc": "month",
+          "Calc": "month ( \"Bookkeep Date@9238295\" )",
           "Associations": [
             {
               "Type": "Associations",
@@ -9801,7 +9801,7 @@
           "InputScale": "0",
           "TimeArray": "Off",
           "ColSrcType": "None",
-          "Calc": "month",
+          "Calc": "month ( \"Bookkeep Date@9239639\" )",
           "Associations": [
             {
               "Type": "Associations",
@@ -11268,7 +11268,7 @@
           "InputScale": "0",
           "TimeArray": "Off",
           "ColSrcType": "None",
-          "Calc": "month",
+          "Calc": "month ( \"Bookkeep Date@9239641\" )",
           "Associations": [
             {
               "Type": "Associations",
@@ -12736,7 +12736,7 @@
           "InputScale": "0",
           "TimeArray": "Off",
           "ColSrcType": "None",
-          "Calc": "month",
+          "Calc": "month ( \"Bookkeep Date@9239643\" )",
           "Associations": [
             {
               "Type": "Associations",
@@ -13122,7 +13122,7 @@
           "Lastuse": "20210106",
           "Rollup": "False",
           "TimeAggregate": "None",
-          "Calc": "change \"M bisher gruppiert~Voriger M bisher@11635\" \"M bisher gruppiert~M bisher@11633\""
+          "Calc": "change ( \"M bisher gruppiert~Voriger M bisher@11635\" , \"M bisher gruppiert~M bisher@11633\" )"
         },
         {
           "Type": "SpecialCategory",
@@ -13134,8 +13134,7 @@
           "Lastuse": "20210106",
           "Rollup": "False",
           "TimeAggregate": "None",
-          "Calc": "growth \"M bisher gruppiert~Voriger M bisher@11635\" \"M bisher gruppiert~M bisher@11633\"",
-          "\"0%~2\"": "Sign"
+          "Calc": "percent-growth ( \"M bisher gruppiert~Voriger M bisher@11635\" , \"M bisher gruppiert~M bisher@11633\" )"
         },
         {
           "Type": "SpecialCategory",
@@ -13301,7 +13300,7 @@
           "Lastuse": "20210106",
           "Rollup": "False",
           "TimeAggregate": "None",
-          "Calc": "change \"Q bisher gruppiert~Voriges Q bisher@11649\" \"Q bisher gruppiert~Q bisher@11645\""
+          "Calc": "change ( \"Q bisher gruppiert~Voriges Q bisher@11649\" , \"Q bisher gruppiert~Q bisher@11645\" )"
         },
         {
           "Type": "SpecialCategory",
@@ -13313,8 +13312,7 @@
           "Lastuse": "20210106",
           "Rollup": "False",
           "TimeAggregate": "None",
-          "Calc": "growth \"Q bisher gruppiert~Voriges Q bisher@11649\" \"Q bisher gruppiert~Q bisher@11645\"",
-          "\"0%~2\"": "Sign"
+          "Calc": "percent-growth ( \"Q bisher gruppiert~Voriges Q bisher@11649\" , \"Q bisher gruppiert~Q bisher@11645\" )"
         },
         {
           "Type": "SpecialCategory",
@@ -13536,7 +13534,7 @@
           "Lastuse": "20210106",
           "Rollup": "False",
           "TimeAggregate": "None",
-          "Calc": "change \"J bisher gruppiert~Voriges J bisher@11667\" \"J bisher gruppiert~J bisher@11661\""
+          "Calc": "change ( \"J bisher gruppiert~Voriges J bisher@11667\" , \"J bisher gruppiert~J bisher@11661\" )"
         },
         {
           "Type": "SpecialCategory",
@@ -13548,8 +13546,7 @@
           "Lastuse": "20210106",
           "Rollup": "False",
           "TimeAggregate": "None",
-          "Calc": "growth \"J bisher gruppiert~Voriges J bisher@11667\" \"J bisher gruppiert~J bisher@11661\"",
-          "\"0%~2\"": "Sign"
+          "Calc": "percent-growth ( \"J bisher gruppiert~Voriges J bisher@11667\" , \"J bisher gruppiert~J bisher@11661\" )"
         }
       ]
     },
@@ -14563,8 +14560,7 @@
           "Label": "Rohertrag",
           "Lastuse": "20191029",
           "SourceValue": "9210395",
-          "Calc": "\"Umsatzerl\u00f6se@28389\" 1 \"Einsatzwerte@24713\"",
-          "False": "Blanks"
+          "Calc": "( \"Umsatzerl\u00f6se@28389\" * - 1 ) - \"Einsatzwerte@24713\""
         },
         {
           "Type": "Category",
@@ -14575,9 +14571,7 @@
           "Label": "Rohertrag in %",
           "Lastuse": "20191029",
           "SourceValue": "9210397",
-          "Calc": "\"9210395@9210395\" \"Umsatzerl\u00f6se@28389\" 1 100",
-          "\"#,##0~1\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "\"9210395@9210395\" / ( \"Umsatzerl\u00f6se@28389\" * - 1 ) * 100"
         },
         {
           "Type": "Category",
@@ -14622,9 +14616,7 @@
           "Label": "Bruttoertrag",
           "Lastuse": "20191119",
           "SourceValue": "2029389",
-          "Calc": "\"Umsatzerl\u00f6se@28389\" 1 \"Einsatzwerte@24713\" \"Zusch\u00fcsse / Provisionen / Boni@9210389\" 1 \"Sonstige Ertr\u00e4ge_1@9210393\" 1",
-          "\"#,##0~0\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "( \"Umsatzerl\u00f6se@28389\" * - 1 ) - \"Einsatzwerte@24713\" + ( \"Zusch\u00fcsse / Provisionen / Boni@9210389\" * - 1 ) + ( \"Sonstige Ertr\u00e4ge_1@9210393\" * - 1 )"
         },
         {
           "Type": "Category",
@@ -14635,9 +14627,7 @@
           "Label": "Bruttoertrag in %",
           "Lastuse": "20191029",
           "SourceValue": "2029391",
-          "Calc": "\"2029389@2029389\" \"Umsatzerl\u00f6se@28389\" 1 100",
-          "\"#,##0~1\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "\"2029389@2029389\" / ( \"Umsatzerl\u00f6se@28389\" * - 1 ) * 100"
         },
         {
           "Type": "Category",
@@ -14681,9 +14671,7 @@
           "Label": "Bruttoertrag II",
           "Lastuse": "20191029",
           "SourceValue": "3377987",
-          "Calc": "\"2029389@2029389\" \"Variable Kosten@24089\"",
-          "\"#,##0~0\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "\"2029389@2029389\" - \"Variable Kosten@24089\""
         },
         {
           "Type": "Category",
@@ -14694,9 +14682,7 @@
           "Label": "Bruttoertrag II in %",
           "Lastuse": "20101018",
           "SourceValue": "3377989",
-          "Calc": "\"3377987@3377987\" \"Umsatzerl\u00f6se@28389\" 1 100",
-          "\"#,##0~1\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "\"3377987@3377987\" / ( \"Umsatzerl\u00f6se@28389\" * - 1 ) * 100"
         },
         {
           "Type": "Category",
@@ -14724,9 +14710,7 @@
           "Label": "Deckungsbeitrag",
           "Lastuse": "20100814",
           "SourceValue": "2227701",
-          "Calc": "\"2029389@2029389\" \"Variable Kosten@24089\" \"Direkte Kosten@22415\"",
-          "\"#,##0~0\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "\"2029389@2029389\" - ( \"Variable Kosten@24089\" + \"Direkte Kosten@22415\" )"
         },
         {
           "Type": "Category",
@@ -14737,9 +14721,7 @@
           "Label": "Deckungsbeitrag in %",
           "Lastuse": "20100814",
           "SourceValue": "2227703",
-          "Calc": "\"2227701@2227701\" \"Umsatzerl\u00f6se@28389\" 1 100",
-          "\"#,##0~1\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "\"2227701@2227701\" / ( \"Umsatzerl\u00f6se@28389\" * - 1 ) * 100"
         },
         {
           "Type": "Category",
@@ -14767,9 +14749,7 @@
           "Label": "Betriebsergebnis",
           "Lastuse": "20201116",
           "SourceValue": "2734471",
-          "Calc": "\"2227701@2227701\" \"Indirekte Kosten@22403\"",
-          "\"#,##0~0\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "\"2227701@2227701\" - \"Indirekte Kosten@22403\""
         },
         {
           "Type": "Category",
@@ -14780,9 +14760,7 @@
           "Label": "Betriebsergebnis in %",
           "Lastuse": "20201116",
           "SourceValue": "2734473",
-          "Calc": "\"2734471@2734471\" \"Umsatzerl\u00f6se@28389\" 1 100",
-          "\"#,##0~1\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "\"2734471@2734471\" / ( \"Umsatzerl\u00f6se@28389\" * - 1 ) * 100"
         },
         {
           "Type": "Category",
@@ -14825,8 +14803,7 @@
           "Label": "UN-Ergebnis v. St.",
           "Lastuse": "20201116",
           "SourceValue": "7653815",
-          "Calc": "\"2734471@2734471\" \"Neutrales Ergebnis@2226211\"",
-          "False": "Blanks"
+          "Calc": "\"2734471@2734471\" - \"Neutrales Ergebnis@2226211\""
         },
         {
           "Type": "Category",
@@ -14837,8 +14814,7 @@
           "Label": "UN-Ergebnis v. St.  in %",
           "Lastuse": "20201116",
           "SourceValue": "7653817",
-          "Calc": "\"2734475@7653815\" \"Umsatzerl\u00f6se@28389\" 1 100",
-          "False": "Blanks"
+          "Calc": "\"2734475@7653815\" / ( \"Umsatzerl\u00f6se@28389\" * - 1 ) * 100"
         },
         {
           "Type": "Category",
@@ -15490,8 +15466,7 @@
           "Label": "Nettogewinn",
           "Lastuse": "20191119",
           "SourceValue": "8795175",
-          "Calc": "\"2734475@7653815\" \"Einkommens- und Gewerbesteuer@8792563\"",
-          "False": "Blanks"
+          "Calc": "\"2734475@7653815\" - \"Einkommens- und Gewerbesteuer@8792563\""
         },
         {
           "Type": "Category",
@@ -15502,8 +15477,7 @@
           "Label": "Nettogewinn in %",
           "Lastuse": "20191119",
           "SourceValue": "8795177",
-          "Calc": "\"8795175@8795175\" \"Umsatzerl\u00f6se@28389\" 1 100",
-          "False": "Blanks"
+          "Calc": "\"8795175@8795175\" / ( \"Umsatzerl\u00f6se@28389\" * - 1 ) * 100"
         },
         {
           "Type": "Category",
@@ -15966,7 +15940,7 @@
           "Label": "Bruttoertrag",
           "Lastuse": "20210106",
           "Rollup": "True",
-          "Calc": "\"8850385@8850385\" 1 \"8850387@8850387\""
+          "Calc": "( \"8850385@8850385\" * - 1 ) - \"8850387@8850387\""
         },
         {
           "Type": "SpecialCategory",
@@ -15977,8 +15951,7 @@
           "Label": "Bruttoertrag in %",
           "Lastuse": "20210106",
           "Rollup": "True",
-          "Calc": "\"8850389@8850389\" \"8850385@8850385\" 1 100",
-          "\"#,##0~1\"": "Sign"
+          "Calc": "\"8850389@8850389\" / ( \"8850385@8850385\" * - 1 ) * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -16033,7 +16006,7 @@
           "Label": "Gesamtbruttoertrag",
           "Lastuse": "20210106",
           "Rollup": "True",
-          "Calc": "\"8850389@8850389\" \"8850393@8850393\" \"8850395@8850395\" \"8850401@8850401\" 1 \"8850399@8850399\" 1"
+          "Calc": "\"8850389@8850389\" - \"8850393@8850393\" - \"8850395@8850395\" + ( \"8850401@8850401\" * - 1 ) + ( \"8850399@8850399\" * - 1 )"
         },
         {
           "Type": "SpecialCategory",
@@ -16044,8 +16017,7 @@
           "Label": "Gesamtbruttoertrag in %",
           "Lastuse": "20210106",
           "Rollup": "True",
-          "Calc": "\"8850403@8850403\" \"8850385@8850385\" 1 100",
-          "\"#,##0~1\"": "Sign"
+          "Calc": "\"8850403@8850403\" / ( \"8850385@8850385\" * - 1 ) * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -16112,7 +16084,7 @@
           "Label": "Deckungsbeitrag 1",
           "Lastuse": "20210106",
           "Rollup": "True",
-          "Calc": "\"8850403@8850403\" \"8850737@8850737\""
+          "Calc": "\"8850403@8850403\" - \"8850737@8850737\""
         },
         {
           "Type": "SpecialCategory",
@@ -16123,8 +16095,7 @@
           "Label": "Deckungsbeitrag 1 in %",
           "Lastuse": "20210106",
           "Rollup": "True",
-          "Calc": "\"8850739@8850739\" \"8850385@8850385\" 1 100",
-          "\"#,##0~1\"": "Sign"
+          "Calc": "\"8850739@8850739\" / ( \"8850385@8850385\" * - 1 ) * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -16225,7 +16196,7 @@
           "Label": "Deckungsbeitrag 2",
           "Lastuse": "20210106",
           "Rollup": "True",
-          "Calc": "\"8850739@8850739\" \"8850741@8850741\""
+          "Calc": "\"8850739@8850739\" - \"8850741@8850741\""
         },
         {
           "Type": "SpecialCategory",
@@ -16236,8 +16207,7 @@
           "Label": "Deckungsbeitrag 2 in %",
           "Lastuse": "20210106",
           "Rollup": "True",
-          "Calc": "\"8876091@8876091\" \"8850385@8850385\" 1 100",
-          "\"#,##0~1\"": "Sign"
+          "Calc": "\"8876091@8876091\" / ( \"8850385@8850385\" * - 1 ) * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -16271,7 +16241,7 @@
           "Label": "Betriebsergebnis 1",
           "Lastuse": "20210106",
           "Rollup": "True",
-          "Calc": "\"8876091@8876091\" \"8876815@8876815\""
+          "Calc": "\"8876091@8876091\" - \"8876815@8876815\""
         },
         {
           "Type": "SpecialCategory",
@@ -16282,8 +16252,7 @@
           "Label": "Betriebsergebnis 1 in %",
           "Lastuse": "20210106",
           "Rollup": "True",
-          "Calc": "\"8880475@8880475\" \"8850385@8850385\" 1 100",
-          "\"#,##0~1\"": "Sign"
+          "Calc": "\"8880475@8880475\" / ( \"8850385@8850385\" * - 1 ) * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -16305,7 +16274,7 @@
           "Label": "Betriebsergebnis 2",
           "Lastuse": "20210106",
           "Rollup": "True",
-          "Calc": "\"8880475@8880475\" \"8880471@8880471\""
+          "Calc": "\"8880475@8880475\" - \"8880471@8880471\""
         },
         {
           "Type": "SpecialCategory",
@@ -16316,8 +16285,7 @@
           "Label": "Betriebsergebnis 2 in %",
           "Lastuse": "20210106",
           "Rollup": "True",
-          "Calc": "\"8880477@8880477\" \"8850385@8850385\" 1 100",
-          "\"#,##0~1\"": "Sign"
+          "Calc": "\"8880477@8880477\" / ( \"8850385@8850385\" * - 1 ) * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -16350,7 +16318,7 @@
           "Label": "Gesamterg. vor Steuern",
           "Lastuse": "20210106",
           "Rollup": "True",
-          "Calc": "\"8880477@8880477\" \"8876807@8876807\" \"8876809@8876809\""
+          "Calc": "\"8880477@8880477\" - \"8876807@8876807\" - \"8876809@8876809\""
         },
         {
           "Type": "SpecialCategory",
@@ -16361,8 +16329,7 @@
           "Label": "Gesamterg. vor Steuern in %",
           "Lastuse": "20210106",
           "Rollup": "True",
-          "Calc": "\"8876811@8876811\" \"8850385@8850385\" 1 100",
-          "\"#,##0~1\"": "Sign"
+          "Calc": "\"8876811@8876811\" / ( \"8850385@8850385\" * - 1 ) * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -16384,8 +16351,7 @@
           "Label": "Pers. kostenquote %",
           "Lastuse": "20210106",
           "Rollup": "False",
-          "Calc": "\"9210289@9210289\" \"Umsatzerl\u00f6se@28389\" 1 100",
-          "\"#,##0~2\"": "Sign"
+          "Calc": "\"9210289@9210289\" / ( \"Umsatzerl\u00f6se@28389\" * - 1 ) * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -16407,8 +16373,7 @@
           "Label": "Werbekostenquote %",
           "Lastuse": "20210106",
           "Rollup": "False",
-          "Calc": "\"9210293@9210293\" \"Umsatzerl\u00f6se@28389\" 1 100",
-          "\"#,##0~2\"": "Sign"
+          "Calc": "\"9210293@9210293\" / ( \"Umsatzerl\u00f6se@28389\" * - 1 ) * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -16503,7 +16468,7 @@
           "Label": "Gesamt BE Verkauf",
           "Lastuse": "20210106",
           "Rollup": "True",
-          "Calc": "\"9629087@9629087\" \"9629089@9629089\" \"9629091@9629091\" \"9629093@9629093\" \"9629095@9629095\" \"9629097@9629097\" 1"
+          "Calc": "( \"9629087@9629087\" + \"9629089@9629089\" + \"9629091@9629091\" + \"9629093@9629093\" + \"9629095@9629095\" + \"9629097@9629097\" ) * - 1"
         },
         {
           "Type": "SpecialCategory",
@@ -16550,7 +16515,7 @@
           "Label": "Gesamt KD",
           "Lastuse": "20210106",
           "Rollup": "True",
-          "Calc": "\"9629101@9629101\" \"9629103@9629103\" \"9629105@9629105\" 1"
+          "Calc": "( \"9629101@9629101\" + \"9629103@9629103\" + \"9629105@9629105\" ) * - 1"
         },
         {
           "Type": "SpecialCategory",
@@ -16597,7 +16562,7 @@
           "Label": "Gesamt",
           "Lastuse": "20210106",
           "Rollup": "True",
-          "Calc": "\"9629099@9629099\" \"9629107@9629107\" \"9629109@9629109\" \"9629111@9629111\" \"9629113@9629113\" 1"
+          "Calc": "\"9629099@9629099\" + \"9629107@9629107\" + ( ( \"9629109@9629109\" + \"9629111@9629111\" + \"9629113@9629113\" ) * - 1 )"
         },
         {
           "Type": "SpecialCategory",
@@ -16620,8 +16585,7 @@
           "Label": "NW %",
           "Lastuse": "20210106",
           "Rollup": "True",
-          "Calc": "\"9629087@9629087\" \"NW~21012@9543583\" 100",
-          "\"#,##0~2\"": "Sign"
+          "Calc": "\"9629087@9629087\" / \"NW~21012@9543583\" * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -16632,8 +16596,7 @@
           "Label": "sonst. BE NW %",
           "Lastuse": "20210106",
           "Rollup": "True",
-          "Calc": "\"9629091@9629091\" \"sonst Erl\u00f6se NW@9565389\" 100",
-          "\"#,##0~2\"": "Sign"
+          "Calc": "\"9629091@9629091\" / \"sonst Erl\u00f6se NW@9565389\" * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -16644,8 +16607,7 @@
           "Label": "GW %",
           "Lastuse": "20210106",
           "Rollup": "True",
-          "Calc": "\"9629093@9629093\" \"GW~21017@9561545\" 100",
-          "\"#,##0~2\"": "Sign"
+          "Calc": "\"9629093@9629093\" / \"GW~21017@9561545\" * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -16656,8 +16618,7 @@
           "Label": "sonst. BE GW %",
           "Lastuse": "20210106",
           "Rollup": "True",
-          "Calc": "\"9629097@9629097\" \"sonst Erl\u00f6se GW@9565363\" 100",
-          "\"#,##0~2\"": "Sign"
+          "Calc": "\"9629097@9629097\" / \"sonst Erl\u00f6se GW@9565363\" * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -16668,8 +16629,7 @@
           "Label": "Gesamt BE Verkauf %",
           "Lastuse": "20210106",
           "Rollup": "True",
-          "Calc": "\"9629099@9629099\" \"NW~21012@9543583\" \"GW~21017@9561545\" \"Prov NW@9600789\" \"Prov GW@9600763\" \"sonst Erl\u00f6se NW@9565389\" \"sonst Erl\u00f6se GW@9565363\" 1 100",
-          "\"#,##0~2\"": "Sign"
+          "Calc": "\"9629099@9629099\" / ( ( \"NW~21012@9543583\" + \"GW~21017@9561545\" + \"Prov NW@9600789\" + \"Prov GW@9600763\" + \"sonst Erl\u00f6se NW@9565389\" + \"sonst Erl\u00f6se GW@9565363\" ) * - 1 ) * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -16680,8 +16640,7 @@
           "Label": "T+Z %",
           "Lastuse": "20210106",
           "Rollup": "True",
-          "Calc": "\"9629101@9629101\" \"T+Z~20978@9476799\" 100",
-          "\"#,##0~2\"": "Sign"
+          "Calc": "\"9629101@9629101\" / \"T+Z~20978@9476799\" * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -16692,8 +16651,7 @@
           "Label": "Service %",
           "Lastuse": "20210106",
           "Rollup": "True",
-          "Calc": "\"9629103@9629103\" \"Service~20983@9476873\" 100",
-          "\"#,##0~2\"": "Sign"
+          "Calc": "\"9629103@9629103\" / \"Service~20983@9476873\" * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -16704,8 +16662,7 @@
           "Label": "Fremdl. %",
           "Lastuse": "20210106",
           "Rollup": "True",
-          "Calc": "\"9629105@9629105\" \"Fremdleistung~21030@9586055\" 100",
-          "\"#,##0~2\"": "Sign"
+          "Calc": "\"9629105@9629105\" / \"Fremdleistung~21030@9586055\" * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -16716,8 +16673,7 @@
           "Label": "Gesamt KD %",
           "Lastuse": "20210106",
           "Rollup": "True",
-          "Calc": "\"9629107@9629107\" \"T+Z~20978@9476799\" \"Service~20983@9476873\" \"Fremdleistung~21030@9586055\" 1 100",
-          "\"#,##0~2\"": "Sign"
+          "Calc": "\"9629107@9629107\" / ( ( \"T+Z~20978@9476799\" + \"Service~20983@9476873\" + \"Fremdleistung~21030@9586055\" ) * - 1 ) * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -16728,8 +16684,7 @@
           "Label": "sonstige %",
           "Lastuse": "20210106",
           "Rollup": "True",
-          "Calc": "\"9629111@9629111\" \"sonstige@9602415\" 100",
-          "\"#,##0~2\"": "Sign"
+          "Calc": "\"9629111@9629111\" / \"sonstige@9602415\" * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -16740,8 +16695,7 @@
           "Label": "intern %",
           "Lastuse": "20210106",
           "Rollup": "True",
-          "Calc": "\"9629113@9629113\" \"interne Erl\u00f6se@9476597\" 100",
-          "\"#,##0~2\"": "Sign"
+          "Calc": "\"9629113@9629113\" / \"interne Erl\u00f6se@9476597\" * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -16752,8 +16706,7 @@
           "Label": "Gesamt %",
           "Lastuse": "20210106",
           "Rollup": "True",
-          "Calc": "\"2029391@2029391\"",
-          "\"#,##0~2\"": "Sign"
+          "Calc": "\"2029391@2029391\""
         }
       ]
     },
@@ -17785,8 +17738,7 @@
           "Label": "Sales",
           "Lastuse": "20140226",
           "SourceValue": "8795215",
-          "Calc": "\"Neuwagen@8795199\" \"Gebrauchtwagen@8795201\"",
-          "False": "Blanks"
+          "Calc": "\"Neuwagen@8795199\" + \"Gebrauchtwagen@8795201\""
         },
         {
           "Type": "Category",
@@ -17797,8 +17749,7 @@
           "Label": "Aftersales",
           "Lastuse": "20140226",
           "SourceValue": "8795217",
-          "Calc": "\"Teile & Zubeh\u00f6r@8795203\" \"Service@8795205\"",
-          "False": "Blanks"
+          "Calc": "\"Teile & Zubeh\u00f6r@8795203\" + \"Service@8795205\""
         },
         {
           "Type": "Category",
@@ -17809,8 +17760,7 @@
           "Label": "Service",
           "Lastuse": "20140226",
           "SourceValue": "8795219",
-          "Calc": "\"Service@8795205\"",
-          "False": "Blanks"
+          "Calc": "\"Service@8795205\""
         },
         {
           "Type": "Category",
@@ -22616,8 +22566,7 @@
           "Inclusion": "Generate",
           "Lastuse": "20140331",
           "SourceValue": "8813525",
-          "Calc": "\"Aktiva@8804271\" \"Passiva@8805279\"",
-          "False": "Blanks"
+          "Calc": "\"Aktiva@8804271\" + \"Passiva@8805279\""
         },
         {
           "Type": "Category",
@@ -22629,8 +22578,7 @@
           "Inclusion": "Generate",
           "Lastuse": "20140331",
           "SourceValue": "8813527",
-          "Calc": "\"Passiva@8805279\" 1 \"3377991@8813525\"",
-          "False": "Blanks"
+          "Calc": "( \"Passiva@8805279\" * - 1 ) + \"3377991@8813525\""
         },
         {
           "Type": "Category",
@@ -23300,8 +23248,7 @@
           "Inclusion": "Generate",
           "Lastuse": "20140331",
           "SourceValue": "8813537",
-          "Calc": "\"1. Umsatzerl\u00f6se@8812359\" 1 \"8813529@8813529\" 1 \"3. Sonstige betriebliche Ertr\u00e4ge@8809953\" 1",
-          "False": "Blanks"
+          "Calc": "( \"1. Umsatzerl\u00f6se@8812359\" * - 1 ) + ( \"8813529@8813529\" * - 1 ) + ( \"3. Sonstige betriebliche Ertr\u00e4ge@8809953\" * - 1 )"
         },
         {
           "Type": "Category",
@@ -23673,8 +23620,7 @@
           "Inclusion": "Generate",
           "Lastuse": "20140402",
           "SourceValue": "8813539",
-          "Calc": "\"6293933@8813537\" \"4. Materialaufwand@8812179\" \"5. Personalaufwand@8809329\" \"6. Abschreibungen@8809293\" \"7. Sonst. betriebl. Aufwendungen@8809661\" \"8. Ertr\u00e4ge aus Beteiligungen@8810133\" 1 \"9. Sonst.Zinsen u.\u00e4hnl.Ertr\u00e4ge@8810225\" 1 \"10. Aufw. aus Verlust\u00fcbernahme@8809989\" \"11. Zinsen u.\u00e4hnl.Aufwendungen@8809081\"",
-          "False": "Blanks"
+          "Calc": "\"6293933@8813537\" - \"4. Materialaufwand@8812179\" - \"5. Personalaufwand@8809329\" - \"6. Abschreibungen@8809293\" - \"7. Sonst. betriebl. Aufwendungen@8809661\" + ( \"8. Ertr\u00e4ge aus Beteiligungen@8810133\" * - 1 ) + ( \"9. Sonst.Zinsen u.\u00e4hnl.Ertr\u00e4ge@8810225\" * - 1 ) - \"10. Aufw. aus Verlust\u00fcbernahme@8809989\" - \"11. Zinsen u.\u00e4hnl.Aufwendungen@8809081\""
         },
         {
           "Type": "Category",
@@ -23754,8 +23700,7 @@
           "Inclusion": "Generate",
           "Lastuse": "20140331",
           "SourceValue": "8813541",
-          "Calc": "\"6293935@8813539\" \"13. Au\u00dferordentliche Ertr\u00e4ge@8810073\" 1 \"14. Steuern vom Einkommen u.Ertrag@8809489\" \"15. Sonstige Steuern@8809453\" \"16. Ertr\u00e4ge aus Verlust\u00fcbernahme@8810641\" 1",
-          "False": "Blanks"
+          "Calc": "\"6293935@8813539\" + ( \"13. Au\u00dferordentliche Ertr\u00e4ge@8810073\" * - 1 ) - \"14. Steuern vom Einkommen u.Ertrag@8809489\" - \"15. Sonstige Steuern@8809453\" + ( \"16. Ertr\u00e4ge aus Verlust\u00fcbernahme@8810641\" * - 1 )"
         },
         {
           "Type": "Category",
@@ -25828,9 +25773,7 @@
       "Type": "Measure",
       "ID": "9629123",
       "Name": "Ist",
-      "Calc": "\"Ist_Euro@399\" \"Ist_Stk@9629119\" Missing Zero IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 5 ReverseSign True IsCurrency False IsFolder False",
-      "\"#,##0~0\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "\"Ist_Euro@399\" + \"Ist_Stk@9629119\"  Missing Zero IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 5 Reverse",
       "Associations": []
     },
     {
@@ -25863,9 +25806,7 @@
       "Type": "Measure",
       "ID": "315031",
       "Name": "Plan",
-      "Calc": "0 Missing Zero Timing After_Rollup IgnoreMissingValue False Storage Float64 OutPutScale 0 Decimals 3 ReverseSign True IsCurrency False IsFolder False",
-      "\"#,##0~0\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "0  Missing Zero Timing After_Rollup IgnoreMissingValue False Storage Float64 OutPutScale 0 Decimals 3 Reverse",
       "Associations": []
     },
     {
@@ -26045,18 +25986,14 @@
       "Type": "Measure",
       "ID": "9629223",
       "Name": "EW Lohn Plan Tag",
-      "Calc": "0 Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 0 Decimals 4 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~0\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "0  Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 0 Decimals 4 Reverse",
       "Associations": []
     },
     {
       "Type": "Measure",
       "ID": "9629293",
       "Name": "Bruttoertrag Soll Tag",
-      "Calc": "0 Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 0 Decimals 5 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~0\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "0  Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 0 Decimals 5 Reverse",
       "Associations": []
     }
   ],

File diff suppressed because it is too large
+ 506 - 506
cognos7/data/mdl/F_Belege_SKR_SKR_Boettche_queries.sql


+ 50 - 131
cognos7/data/mdl/Fin_Belege_SKR.json

@@ -16514,7 +16514,7 @@
           "Class": "Description",
           "InputScale": "0",
           "TimeArray": "Off",
-          "Calc": "\"Nr@9698829\"",
+          "Calc": "\"Nr@9698829\" + ' - ' + \"Name@9698831\"",
           "Associations": []
         }
       ],
@@ -16950,8 +16950,7 @@
           "RunningPeriods": "0",
           "TargetOffset": "0",
           "ContextOffset": "0",
-          "Calc": "change \"M bisher gruppiert~Voriger M bisher@11635\" \"M bisher gruppiert~M bisher@11633\"",
-          "False": "Blanks"
+          "Calc": "change ( \"M bisher gruppiert~Voriger M bisher@11635\" , \"M bisher gruppiert~M bisher@11633\" )"
         },
         {
           "Type": "SpecialCategory",
@@ -16965,9 +16964,7 @@
           "RunningPeriods": "0",
           "TargetOffset": "0",
           "ContextOffset": "0",
-          "Calc": "growth \"M bisher gruppiert~Voriger M bisher@11635\" \"M bisher gruppiert~M bisher@11633\"",
-          "\"0%~2\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "percent-growth ( \"M bisher gruppiert~Voriger M bisher@11635\" , \"M bisher gruppiert~M bisher@11633\" )"
         },
         {
           "Type": "SpecialCategory",
@@ -17149,8 +17146,7 @@
           "RunningPeriods": "0",
           "TargetOffset": "0",
           "ContextOffset": "0",
-          "Calc": "change \"Q bisher gruppiert~Voriges Q bisher@11649\" \"Q bisher gruppiert~Q bisher@11645\"",
-          "False": "Blanks"
+          "Calc": "change ( \"Q bisher gruppiert~Voriges Q bisher@11649\" , \"Q bisher gruppiert~Q bisher@11645\" )"
         },
         {
           "Type": "SpecialCategory",
@@ -17164,9 +17160,7 @@
           "RunningPeriods": "0",
           "TargetOffset": "0",
           "ContextOffset": "0",
-          "Calc": "growth \"Q bisher gruppiert~Voriges Q bisher@11649\" \"Q bisher gruppiert~Q bisher@11645\"",
-          "\"0%~2\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "percent-growth ( \"Q bisher gruppiert~Voriges Q bisher@11649\" , \"Q bisher gruppiert~Q bisher@11645\" )"
         },
         {
           "Type": "SpecialCategory",
@@ -17416,8 +17410,7 @@
           "RunningPeriods": "0",
           "TargetOffset": "0",
           "ContextOffset": "0",
-          "Calc": "change \"J bisher gruppiert~Voriges J bisher@11667\" \"J bisher gruppiert~J bisher@11661\"",
-          "False": "Blanks"
+          "Calc": "change ( \"J bisher gruppiert~Voriges J bisher@11667\" , \"J bisher gruppiert~J bisher@11661\" )"
         },
         {
           "Type": "SpecialCategory",
@@ -17431,9 +17424,7 @@
           "RunningPeriods": "0",
           "TargetOffset": "0",
           "ContextOffset": "0",
-          "Calc": "growth \"J bisher gruppiert~Voriges J bisher@11667\" \"J bisher gruppiert~J bisher@11661\"",
-          "\"0%~2\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "percent-growth ( \"J bisher gruppiert~Voriges J bisher@11667\" , \"J bisher gruppiert~J bisher@11661\" )"
         }
       ]
     },
@@ -18099,9 +18090,7 @@
           "Levels": "Ebene1",
           "Label": "Bruttoertrag",
           "SourceValue": "2029389",
-          "Calc": "\"Umsatzerl\u00f6se@28389\" 1 \"Einsatzwerte@24713\"",
-          "\"#,##0~0\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "( \"Umsatzerl\u00f6se@28389\" * - 1 ) - \"Einsatzwerte@24713\""
         },
         {
           "Type": "Category",
@@ -18110,9 +18099,7 @@
           "Levels": "Ebene1",
           "Label": "Bruttoertrag in %",
           "SourceValue": "2029391",
-          "Calc": "\"2029389@2029389\" \"Umsatzerl\u00f6se@28389\" 1 100",
-          "\"#,##0~1\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "\"2029389@2029389\" / ( \"Umsatzerl\u00f6se@28389\" * - 1 ) * 100"
         },
         {
           "Type": "Category",
@@ -18150,9 +18137,7 @@
           "Levels": "Ebene2",
           "Label": "Bruttoertrag II",
           "SourceValue": "3377987",
-          "Calc": "\"2029389@2029389\" \"Variable Kosten@24089\"",
-          "\"#,##0~0\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "\"2029389@2029389\" - \"Variable Kosten@24089\""
         },
         {
           "Type": "Category",
@@ -18161,9 +18146,7 @@
           "Levels": "Ebene2",
           "Label": "Bruttoertrag II in %",
           "SourceValue": "3377989",
-          "Calc": "\"3377987@3377987\" \"Umsatzerl\u00f6se@28389\" 1 100",
-          "\"#,##0~1\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "\"3377987@3377987\" / ( \"Umsatzerl\u00f6se@28389\" * - 1 ) * 100"
         },
         {
           "Type": "Category",
@@ -18187,9 +18170,7 @@
           "Levels": "Ebene2",
           "Label": "Deckungsbeitrag",
           "SourceValue": "2227701",
-          "Calc": "\"2029389@2029389\" \"Variable Kosten@24089\" \"Direkte Kosten@22415\"",
-          "\"#,##0~0\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "\"2029389@2029389\" - ( \"Variable Kosten@24089\" + \"Direkte Kosten@22415\" )"
         },
         {
           "Type": "Category",
@@ -18198,9 +18179,7 @@
           "Levels": "Ebene2",
           "Label": "Deckungsbeitrag in %",
           "SourceValue": "2227703",
-          "Calc": "\"2227701@2227701\" \"Umsatzerl\u00f6se@28389\" 1 100",
-          "\"#,##0~1\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "\"2227701@2227701\" / ( \"Umsatzerl\u00f6se@28389\" * - 1 ) * 100"
         },
         {
           "Type": "Category",
@@ -18224,9 +18203,7 @@
           "Levels": "Ebene1",
           "Label": "Betriebsergebnis",
           "SourceValue": "2734471",
-          "Calc": "\"2227701@2227701\" \"Indirekte Kosten@22403\"",
-          "\"#,##0~0\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "\"2227701@2227701\" - \"Indirekte Kosten@22403\""
         },
         {
           "Type": "Category",
@@ -18235,9 +18212,7 @@
           "Levels": "Ebene1",
           "Label": "Betriebsergebnis in %",
           "SourceValue": "2734473",
-          "Calc": "\"2734471@2734471\" \"Umsatzerl\u00f6se@28389\" 1 100",
-          "\"#,##0~1\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "\"2734471@2734471\" / ( \"Umsatzerl\u00f6se@28389\" * - 1 ) * 100"
         },
         {
           "Type": "Category",
@@ -18288,8 +18263,7 @@
           "Levels": "Ebene1",
           "Label": "UN-Ergebnis v. St.",
           "SourceValue": "7653815",
-          "Calc": "\"2734471@2734471\" \"Neutrales Ergebnis@2226211\"",
-          "False": "Blanks"
+          "Calc": "\"2734471@2734471\" - \"Neutrales Ergebnis@2226211\""
         },
         {
           "Type": "Category",
@@ -18298,8 +18272,7 @@
           "Levels": "Ebene1",
           "Label": "UN-Ergebnis v. St. in %",
           "SourceValue": "7653817",
-          "Calc": "\"2734475@7653815\" \"Umsatzerl\u00f6se@28389\" 1 100",
-          "False": "Blanks"
+          "Calc": "\"2734475@7653815\" / ( \"Umsatzerl\u00f6se@28389\" * - 1 ) * 100"
         },
         {
           "Type": "Category",
@@ -19087,8 +19060,7 @@
           "Levels": "Ebene1",
           "Label": "UN-Ergebnis n. St.",
           "SourceValue": "8795175",
-          "Calc": "\"2734475@7653815\" \"Einkommens- und Gewerbesteuer@8792563\"",
-          "False": "Blanks"
+          "Calc": "\"2734475@7653815\" - \"Einkommens- und Gewerbesteuer@8792563\""
         },
         {
           "Type": "Category",
@@ -19097,8 +19069,7 @@
           "Levels": "Ebene1",
           "Label": "UN-Ergebnis n. St. in %",
           "SourceValue": "8795177",
-          "Calc": "\"8795175@8795175\" \"Umsatzerl\u00f6se@28389\" 1 100",
-          "False": "Blanks"
+          "Calc": "\"8795175@8795175\" / ( \"Umsatzerl\u00f6se@28389\" * - 1 ) * 100"
         },
         {
           "Type": "Category",
@@ -19200,8 +19171,7 @@
           "Label": "Kostendeckungspunkt",
           "Inclusion": "Generate",
           "SourceValue": "8845677",
-          "Calc": "\"L\u00f6hne produktiv und Nebenkosten@8793757\" \"Variable Kosten@24089\" \"Direkte Kosten@22415\" \"Indirekte Kosten@22403\"",
-          "False": "Blanks"
+          "Calc": "\"L\u00f6hne produktiv und Nebenkosten@8793757\" + \"Variable Kosten@24089\" + \"Direkte Kosten@22415\" + \"Indirekte Kosten@22403\""
         },
         {
           "Type": "Category",
@@ -20309,8 +20279,7 @@
           "Label": "KD Gesamt",
           "Inclusion": "Generate",
           "Rollup": "True",
-          "Calc": "\"9442183@9442183\" \"9442185@9442185\" \"9442187@9442187\"",
-          "False": "Blanks"
+          "Calc": "\"9442183@9442183\" + \"9442185@9442185\" + \"9442187@9442187\""
         },
         {
           "Type": "SpecialCategory",
@@ -20674,9 +20643,7 @@
           "Levels": "0",
           "Label": "Gesamt BE Verkauf",
           "Rollup": "True",
-          "Calc": "\"9442235@9442235\" \"9442237@9442237\" \"9442239@9442239\" \"9442241@9442241\" \"9695241@9695241\" \"9695243@9695243\" 1",
-          "False": "Blanks",
-          "True": "IsKeyOrphanage"
+          "Calc": "( \"9442235@9442235\" + \"9442237@9442237\" + \"9442239@9442239\" + \"9442241@9442241\" + \"9695241@9695241\" + \"9695243@9695243\" ) * - 1"
         },
         {
           "Type": "SpecialCategory",
@@ -20727,9 +20694,7 @@
           "Levels": "0",
           "Label": "Gesamt KD",
           "Rollup": "True",
-          "Calc": "\"9695249@9695249\" \"9695251@9695251\" \"9695253@9695253\" 1",
-          "False": "Blanks",
-          "True": "IsKeyOrphanage"
+          "Calc": "( \"9695249@9695249\" + \"9695251@9695251\" + \"9695253@9695253\" ) * - 1"
         },
         {
           "Type": "SpecialCategory",
@@ -20794,10 +20759,7 @@
           "Levels": "0",
           "Label": "NW",
           "Rollup": "True",
-          "Calc": "\"9442235@9442235\" \"9442171@9442171\" 100",
-          "\"#,##0~1\"": "Filtered",
-          "False": "Blanks",
-          "True": "IsKeyOrphanage"
+          "Calc": "\"9442235@9442235\" / \"9442171@9442171\" * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -20806,9 +20768,7 @@
           "Levels": "0",
           "Label": "GW",
           "Rollup": "True",
-          "Calc": "\"9442237@9442237\" \"Erl\u00f6se Gebrauchtwagen@8794779\" 100",
-          "\"#,##0~1\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "\"9442237@9442237\" / \"Erl\u00f6se Gebrauchtwagen@8794779\" * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -20817,9 +20777,7 @@
           "Levels": "0",
           "Label": "sonst BE NW",
           "Rollup": "True",
-          "Calc": "\"9695241@9695241\" \"9442179@9442179\" 100",
-          "\"#,##0~1\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "( \"9695241@9695241\" / \"9442179@9442179\" ) * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -20828,9 +20786,7 @@
           "Levels": "0",
           "Label": "sonst BE GW",
           "Rollup": "True",
-          "Calc": "\"9695243@9695243\" \"9442181@9442181\" 100",
-          "\"#,##0~1\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "( \"9695243@9695243\" / \"9442181@9442181\" ) * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -20839,9 +20795,7 @@
           "Levels": "0",
           "Label": "Gesamt BE Verkauf",
           "Rollup": "True",
-          "Calc": "\"9695247@9695247\" \"9442171@9442171\" \"9442173@9442173\" \"9442175@9442175\" \"9442177@9442177\" \"9442179@9442179\" \"9442181@9442181\" 100 1",
-          "\"#,##0~1\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "\"9695247@9695247\" / ( \"9442171@9442171\" + \"9442173@9442173\" + \"9442175@9442175\" + \"9442177@9442177\" + \"9442179@9442179\" + \"9442181@9442181\" ) * 100 * - 1"
         },
         {
           "Type": "SpecialCategory",
@@ -20850,9 +20804,7 @@
           "Levels": "0",
           "Label": "T+Z",
           "Rollup": "True",
-          "Calc": "\"9695249@9695249\" \"9442183@9442183\" 100",
-          "\"#,##0~1\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "\"9695249@9695249\" / \"9442183@9442183\" * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -20861,9 +20813,7 @@
           "Levels": "0",
           "Label": "Service",
           "Rollup": "True",
-          "Calc": "\"9695251@9695251\" \"9442185@9442185\" 100",
-          "\"#,##0~1\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "( \"9695251@9695251\" / \"9442185@9442185\" ) * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -20872,9 +20822,7 @@
           "Levels": "0",
           "Label": "Fremdleistung",
           "Rollup": "True",
-          "Calc": "\"9695253@9695253\" \"9442187@9442187\" 100",
-          "\"#,##0~1\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "( \"9695253@9695253\" / \"9442187@9442187\" ) * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -20883,9 +20831,7 @@
           "Levels": "0",
           "Label": "Gesamt KD",
           "Rollup": "True",
-          "Calc": "\"9695255@9695255\" \"9442183@9442183\" \"9442185@9442185\" \"9442187@9442187\" 100 1",
-          "\"#,##0~1\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "( \"9695255@9695255\" / ( \"9442183@9442183\" + \"9442185@9442185\" + \"9442187@9442187\" ) ) * 100 * - 1"
         },
         {
           "Type": "SpecialCategory",
@@ -20894,9 +20840,7 @@
           "Levels": "0",
           "Label": "Rent",
           "Rollup": "True",
-          "Calc": "\"9695257@9695257\" \"9442197@9442197\" 100",
-          "\"#,##0~1\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "\"9695257@9695257\" / \"9442197@9442197\" * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -20905,9 +20849,7 @@
           "Levels": "0",
           "Label": "sonstige",
           "Rollup": "True",
-          "Calc": "\"9695259@9695259\" \"Sonstige Erl\u00f6se@8794927\" 100",
-          "\"#,##0~1\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "\"9695259@9695259\" / \"Sonstige Erl\u00f6se@8794927\" * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -20916,9 +20858,7 @@
           "Levels": "0",
           "Label": "intern",
           "Rollup": "True",
-          "Calc": "\"9695261@9695261\" \"9442201@9442201\" 100",
-          "\"#,##0~1\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "( \"9695261@9695261\" / \"9442201@9442201\" ) * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -20927,9 +20867,7 @@
           "Levels": "0",
           "Label": "Gesamt",
           "Rollup": "True",
-          "Calc": "\"9442233@9442233\" \"9442169@9442169\" 100",
-          "\"#,##0~1\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "( \"9442233@9442233\" / \"9442169@9442169\" ) * 100"
         }
       ]
     },
@@ -21751,8 +21689,7 @@
           "Levels": "Ebene11",
           "Label": "Sales",
           "SourceValue": "8795215",
-          "Calc": "\"Neuwagen@8795199\" \"Gebrauchtwagen@8795201\"",
-          "False": "Blanks"
+          "Calc": "\"Neuwagen@8795199\" + \"Gebrauchtwagen@8795201\""
         },
         {
           "Type": "Category",
@@ -21761,8 +21698,7 @@
           "Levels": "Ebene11",
           "Label": "Aftersales",
           "SourceValue": "8795217",
-          "Calc": "\"Teile & Zubeh\u00f6r@8795203\" \"Service@8795205\"",
-          "False": "Blanks"
+          "Calc": "\"Teile & Zubeh\u00f6r@8795203\" + \"Service@8795205\""
         },
         {
           "Type": "Category",
@@ -21771,8 +21707,7 @@
           "Levels": "Ebene11",
           "Label": "Service",
           "SourceValue": "8795219",
-          "Calc": "\"Service@8795205\"",
-          "False": "Blanks"
+          "Calc": "\"Service@8795205\""
         },
         {
           "Type": "Category",
@@ -25798,8 +25733,7 @@
           "Label": "Bilanzgewinn",
           "Inclusion": "Generate",
           "SourceValue": "8813525",
-          "Calc": "\"Aktiva@8804271\" \"Passiva@8805279\"",
-          "False": "Blanks"
+          "Calc": "\"Aktiva@8804271\" + \"Passiva@8805279\""
         },
         {
           "Type": "Category",
@@ -25809,8 +25743,7 @@
           "Label": "Passiva I",
           "Inclusion": "Generate",
           "SourceValue": "8813527",
-          "Calc": "\"Passiva@8805279\" 1 \"3377991@8813525\"",
-          "False": "Blanks"
+          "Calc": "( \"Passiva@8805279\" * - 1 ) + \"3377991@8813525\""
         },
         {
           "Type": "Category",
@@ -25919,9 +25852,7 @@
           "Levels": "0",
           "Label": "Liquidit\u00e4t ( > 1,5)",
           "Rollup": "True",
-          "Calc": "\"B. Umlaufverm\u00f6gen@8806653\" \"D. Verbindlichkeiten@8805281\" 1",
-          "\"#,##0~2\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "\"B. Umlaufverm\u00f6gen@8806653\" / ( \"D. Verbindlichkeiten@8805281\" * - 1 )"
         },
         {
           "Type": "SpecialCategory",
@@ -25930,8 +25861,7 @@
           "Levels": "0",
           "Label": "Eigenkapital (> 33 %)",
           "Rollup": "True",
-          "Calc": "\"A. Eigenkapital@8805937\" 1 \"3377991@8813525\" 100 \"3377993@8813527\"",
-          "False": "Blanks"
+          "Calc": "( \"A. Eigenkapital@8805937\" * - 1 + \"3377991@8813525\" ) * 100 / \"3377993@8813527\""
         }
       ]
     },
@@ -26415,8 +26345,7 @@
           "Label": "Gesamtleistung",
           "Inclusion": "Generate",
           "SourceValue": "8813537",
-          "Calc": "\"1. Umsatzerl\u00f6se@8812359\" 1 \"8813529@8813529\" 1 \"3. Sonstige betriebliche Ertr\u00e4ge@8809953\" 1",
-          "False": "Blanks"
+          "Calc": "( \"1. Umsatzerl\u00f6se@8812359\" * - 1 ) + ( \"8813529@8813529\" * - 1 ) + ( \"3. Sonstige betriebliche Ertr\u00e4ge@8809953\" * - 1 )"
         },
         {
           "Type": "Category",
@@ -26747,8 +26676,7 @@
           "Label": "12. Ergebnis der gew\u00f6hnlichen Gesch\u00e4ftst\u00e4tigkeit",
           "Inclusion": "Generate",
           "SourceValue": "8813539",
-          "Calc": "\"6293933@8813537\" \"4. Materialaufwand@8812179\" \"5. Personalaufwand@8809329\" \"6. Abschreibungen@8809293\" \"7. Sonst. betriebl. Aufwendungen@8809661\" \"8. Ertr\u00e4ge aus Beteiligungen@8810133\" 1 \"9. Sonst.Zinsen u.\u00e4hnl.Ertr\u00e4ge@8810225\" 1 \"10. Aufw. aus Verlust\u00fcbernahme@8809989\" \"11. Zinsen u.\u00e4hnl.Aufwendungen@8809081\"",
-          "False": "Blanks"
+          "Calc": "\"6293933@8813537\" - \"4. Materialaufwand@8812179\" - \"5. Personalaufwand@8809329\" - \"6. Abschreibungen@8809293\" - \"7. Sonst. betriebl. Aufwendungen@8809661\" + ( \"8. Ertr\u00e4ge aus Beteiligungen@8810133\" * - 1 ) + ( \"9. Sonst.Zinsen u.\u00e4hnl.Ertr\u00e4ge@8810225\" * - 1 ) - \"10. Aufw. aus Verlust\u00fcbernahme@8809989\" - \"11. Zinsen u.\u00e4hnl.Aufwendungen@8809081\""
         },
         {
           "Type": "Category",
@@ -26878,8 +26806,7 @@
           "Label": "Jahres\u00fcberschuss",
           "Inclusion": "Generate",
           "SourceValue": "8813541",
-          "Calc": "\"6293935@8813539\" \"13. Au\u00dferordentliche Ertr\u00e4ge@8810073\" 1 \"14. Steuern vom Einkommen u.Ertrag@8809489\" \"15. Sonstige Steuern@8809453\" \"16. Ertr\u00e4ge aus Verlust\u00fcbernahme@8810641\" 1",
-          "False": "Blanks"
+          "Calc": "\"6293935@8813539\" + ( \"13. Au\u00dferordentliche Ertr\u00e4ge@8810073\" * - 1 ) - \"14. Steuern vom Einkommen u.Ertrag@8809489\" - \"15. Sonstige Steuern@8809453\" + ( \"16. Ertr\u00e4ge aus Verlust\u00fcbernahme@8810641\" * - 1 )"
         },
         {
           "Type": "Category",
@@ -28210,9 +28137,7 @@
     {
       "Type": "Measure",
       "Name": "Ist",
-      "Calc": "\"Ist_ori@399\" \"verk. Stunden@8944853\" \"Menge_Fibu@8945231\" \"EW Lohn Plan Tag@8971879\" \"Bruttoertrag Soll Tag@8972787\" Timing After_Rollup IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 4 ReverseSign True IsCurrency False IsFolder False",
-      "\"#,##0~0\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "\"Ist_ori@399\" + \"verk. Stunden@8944853\" + \"Menge_Fibu@8945231\" + \"EW Lohn Plan Tag@8971879\" + \"Bruttoertrag Soll Tag@8972787\"  Timing After_Rollup IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 4 Reverse",
       "Associations": []
     },
     {
@@ -28241,9 +28166,7 @@
     {
       "Type": "Measure",
       "Name": "Plan",
-      "Calc": "0 IgnoreMissingValue False Storage Float64 OutPutScale 0 Decimals 3 ReverseSign True IsCurrency False IsFolder False",
-      "\"#,##0~0\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "0  IgnoreMissingValue False Storage Float64 OutPutScale 0 Decimals 3 Reverse",
       "Associations": []
     },
     {
@@ -28356,9 +28279,7 @@
     {
       "Type": "Measure",
       "Name": "Betrag_HU",
-      "Calc": "0 IgnoreMissingValue False Storage Float64 OutPutScale 2 Decimals 2 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~2\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "0  IgnoreMissingValue False Storage Float64 OutPutScale 2 Decimals 2 Reverse",
       "Associations": []
     },
     {
@@ -28410,9 +28331,7 @@
     {
       "Type": "Measure",
       "Name": "Menge_Fibu",
-      "Calc": "0 IgnoreMissingValue False Storage Float64 OutPutScale 0 Decimals 6 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~0\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "0  IgnoreMissingValue False Storage Float64 OutPutScale 0 Decimals 6 Reverse",
       "Associations": []
     },
     {

+ 50 - 131
cognos7/data/mdl/Fin_Belege_SKR_ori.json

@@ -17703,7 +17703,7 @@
           "Class": "Description",
           "InputScale": "0",
           "TimeArray": "Off",
-          "Calc": "\"Nr@9698829\"",
+          "Calc": "\"Nr@9698829\" + ' - ' + \"Name@9698831\"",
           "Associations": []
         }
       ],
@@ -18190,8 +18190,7 @@
           "TargetOffset": "0",
           "ContextOffset": "0",
           "DateDrill": "0",
-          "Calc": "change \"M bisher gruppiert~Voriger M bisher@11635\" \"M bisher gruppiert~M bisher@11633\"",
-          "False": "Blanks"
+          "Calc": "change ( \"M bisher gruppiert~Voriger M bisher@11635\" , \"M bisher gruppiert~M bisher@11633\" )"
         },
         {
           "Type": "SpecialCategory",
@@ -18208,9 +18207,7 @@
           "TargetOffset": "0",
           "ContextOffset": "0",
           "DateDrill": "0",
-          "Calc": "growth \"M bisher gruppiert~Voriger M bisher@11635\" \"M bisher gruppiert~M bisher@11633\"",
-          "\"0%~2\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "percent-growth ( \"M bisher gruppiert~Voriger M bisher@11635\" , \"M bisher gruppiert~M bisher@11633\" )"
         },
         {
           "Type": "SpecialCategory",
@@ -18431,8 +18428,7 @@
           "TargetOffset": "0",
           "ContextOffset": "0",
           "DateDrill": "0",
-          "Calc": "change \"Q bisher gruppiert~Voriges Q bisher@11649\" \"Q bisher gruppiert~Q bisher@11645\"",
-          "False": "Blanks"
+          "Calc": "change ( \"Q bisher gruppiert~Voriges Q bisher@11649\" , \"Q bisher gruppiert~Q bisher@11645\" )"
         },
         {
           "Type": "SpecialCategory",
@@ -18449,9 +18445,7 @@
           "TargetOffset": "0",
           "ContextOffset": "0",
           "DateDrill": "0",
-          "Calc": "growth \"Q bisher gruppiert~Voriges Q bisher@11649\" \"Q bisher gruppiert~Q bisher@11645\"",
-          "\"0%~2\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "percent-growth ( \"Q bisher gruppiert~Voriges Q bisher@11649\" , \"Q bisher gruppiert~Q bisher@11645\" )"
         },
         {
           "Type": "SpecialCategory",
@@ -18756,8 +18750,7 @@
           "TargetOffset": "0",
           "ContextOffset": "0",
           "DateDrill": "0",
-          "Calc": "change \"J bisher gruppiert~Voriges J bisher@11667\" \"J bisher gruppiert~J bisher@11661\"",
-          "False": "Blanks"
+          "Calc": "change ( \"J bisher gruppiert~Voriges J bisher@11667\" , \"J bisher gruppiert~J bisher@11661\" )"
         },
         {
           "Type": "SpecialCategory",
@@ -18774,9 +18767,7 @@
           "TargetOffset": "0",
           "ContextOffset": "0",
           "DateDrill": "0",
-          "Calc": "growth \"J bisher gruppiert~Voriges J bisher@11667\" \"J bisher gruppiert~J bisher@11661\"",
-          "\"0%~2\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "percent-growth ( \"J bisher gruppiert~Voriges J bisher@11667\" , \"J bisher gruppiert~J bisher@11661\" )"
         }
       ]
     },
@@ -19516,9 +19507,7 @@
           "Label": "Bruttoertrag",
           "Lastuse": "20100814",
           "SourceValue": "2029389",
-          "Calc": "\"Umsatzerl\u00f6se@28389\" 1 \"Einsatzwerte@24713\"",
-          "\"#,##0~0\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "( \"Umsatzerl\u00f6se@28389\" * - 1 ) - \"Einsatzwerte@24713\""
         },
         {
           "Type": "Category",
@@ -19529,9 +19518,7 @@
           "Label": "Bruttoertrag in %",
           "Lastuse": "20100814",
           "SourceValue": "2029391",
-          "Calc": "\"2029389@2029389\" \"Umsatzerl\u00f6se@28389\" 1 100",
-          "\"#,##0~1\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "\"2029389@2029389\" / ( \"Umsatzerl\u00f6se@28389\" * - 1 ) * 100"
         },
         {
           "Type": "Category",
@@ -19575,9 +19562,7 @@
           "Label": "Bruttoertrag II",
           "Lastuse": "20101018",
           "SourceValue": "3377987",
-          "Calc": "\"2029389@2029389\" \"Variable Kosten@24089\"",
-          "\"#,##0~0\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "\"2029389@2029389\" - \"Variable Kosten@24089\""
         },
         {
           "Type": "Category",
@@ -19588,9 +19573,7 @@
           "Label": "Bruttoertrag II in %",
           "Lastuse": "20101018",
           "SourceValue": "3377989",
-          "Calc": "\"3377987@3377987\" \"Umsatzerl\u00f6se@28389\" 1 100",
-          "\"#,##0~1\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "\"3377987@3377987\" / ( \"Umsatzerl\u00f6se@28389\" * - 1 ) * 100"
         },
         {
           "Type": "Category",
@@ -19618,9 +19601,7 @@
           "Label": "Deckungsbeitrag",
           "Lastuse": "20100814",
           "SourceValue": "2227701",
-          "Calc": "\"2029389@2029389\" \"Variable Kosten@24089\" \"Direkte Kosten@22415\"",
-          "\"#,##0~0\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "\"2029389@2029389\" - ( \"Variable Kosten@24089\" + \"Direkte Kosten@22415\" )"
         },
         {
           "Type": "Category",
@@ -19631,9 +19612,7 @@
           "Label": "Deckungsbeitrag in %",
           "Lastuse": "20100814",
           "SourceValue": "2227703",
-          "Calc": "\"2227701@2227701\" \"Umsatzerl\u00f6se@28389\" 1 100",
-          "\"#,##0~1\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "\"2227701@2227701\" / ( \"Umsatzerl\u00f6se@28389\" * - 1 ) * 100"
         },
         {
           "Type": "Category",
@@ -19661,9 +19640,7 @@
           "Label": "Betriebsergebnis",
           "Lastuse": "20100819",
           "SourceValue": "2734471",
-          "Calc": "\"2227701@2227701\" \"Indirekte Kosten@22403\"",
-          "\"#,##0~0\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "\"2227701@2227701\" - \"Indirekte Kosten@22403\""
         },
         {
           "Type": "Category",
@@ -19674,9 +19651,7 @@
           "Label": "Betriebsergebnis in %",
           "Lastuse": "20100819",
           "SourceValue": "2734473",
-          "Calc": "\"2734471@2734471\" \"Umsatzerl\u00f6se@28389\" 1 100",
-          "\"#,##0~1\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "\"2734471@2734471\" / ( \"Umsatzerl\u00f6se@28389\" * - 1 ) * 100"
         },
         {
           "Type": "Category",
@@ -19735,8 +19710,7 @@
           "Label": "UN-Ergebnis v. St.",
           "Lastuse": "20140226",
           "SourceValue": "7653815",
-          "Calc": "\"2734471@2734471\" \"Neutrales Ergebnis@2226211\"",
-          "False": "Blanks"
+          "Calc": "\"2734471@2734471\" - \"Neutrales Ergebnis@2226211\""
         },
         {
           "Type": "Category",
@@ -19747,8 +19721,7 @@
           "Label": "UN-Ergebnis v. St. in %",
           "Lastuse": "20150521",
           "SourceValue": "7653817",
-          "Calc": "\"2734475@7653815\" \"Umsatzerl\u00f6se@28389\" 1 100",
-          "False": "Blanks"
+          "Calc": "\"2734475@7653815\" / ( \"Umsatzerl\u00f6se@28389\" * - 1 ) * 100"
         },
         {
           "Type": "Category",
@@ -20642,8 +20615,7 @@
           "Label": "UN-Ergebnis n. St.",
           "Lastuse": "20140226",
           "SourceValue": "8795175",
-          "Calc": "\"2734475@7653815\" \"Einkommens- und Gewerbesteuer@8792563\"",
-          "False": "Blanks"
+          "Calc": "\"2734475@7653815\" - \"Einkommens- und Gewerbesteuer@8792563\""
         },
         {
           "Type": "Category",
@@ -20654,8 +20626,7 @@
           "Label": "UN-Ergebnis n. St. in %",
           "Lastuse": "20150521",
           "SourceValue": "8795177",
-          "Calc": "\"8795175@8795175\" \"Umsatzerl\u00f6se@28389\" 1 100",
-          "False": "Blanks"
+          "Calc": "\"8795175@8795175\" / ( \"Umsatzerl\u00f6se@28389\" * - 1 ) * 100"
         },
         {
           "Type": "Category",
@@ -20771,8 +20742,7 @@
           "Inclusion": "Generate",
           "Lastuse": "20140403",
           "SourceValue": "8845677",
-          "Calc": "\"L\u00f6hne produktiv und Nebenkosten@8793757\" \"Variable Kosten@24089\" \"Direkte Kosten@22415\" \"Indirekte Kosten@22403\"",
-          "False": "Blanks"
+          "Calc": "\"L\u00f6hne produktiv und Nebenkosten@8793757\" + \"Variable Kosten@24089\" + \"Direkte Kosten@22415\" + \"Indirekte Kosten@22403\""
         },
         {
           "Type": "Category",
@@ -22075,8 +22045,7 @@
           "Inclusion": "Generate",
           "Lastuse": "20190506",
           "Rollup": "True",
-          "Calc": "\"9442183@9442183\" \"9442185@9442185\" \"9442187@9442187\"",
-          "False": "Blanks"
+          "Calc": "\"9442183@9442183\" + \"9442185@9442185\" + \"9442187@9442187\""
         },
         {
           "Type": "SpecialCategory",
@@ -22512,9 +22481,7 @@
           "Label": "Gesamt BE Verkauf",
           "Lastuse": "20190506",
           "Rollup": "True",
-          "Calc": "\"9442235@9442235\" \"9442237@9442237\" \"9442239@9442239\" \"9442241@9442241\" \"9695241@9695241\" \"9695243@9695243\" 1",
-          "False": "Blanks",
-          "True": "IsKeyOrphanage"
+          "Calc": "( \"9442235@9442235\" + \"9442237@9442237\" + \"9442239@9442239\" + \"9442241@9442241\" + \"9695241@9695241\" + \"9695243@9695243\" ) * - 1"
         },
         {
           "Type": "SpecialCategory",
@@ -22576,9 +22543,7 @@
           "Label": "Gesamt KD",
           "Lastuse": "20190506",
           "Rollup": "True",
-          "Calc": "\"9695249@9695249\" \"9695251@9695251\" \"9695253@9695253\" 1",
-          "False": "Blanks",
-          "True": "IsKeyOrphanage"
+          "Calc": "( \"9695249@9695249\" + \"9695251@9695251\" + \"9695253@9695253\" ) * - 1"
         },
         {
           "Type": "SpecialCategory",
@@ -22657,10 +22622,7 @@
           "Label": "NW",
           "Lastuse": "20190506",
           "Rollup": "True",
-          "Calc": "\"9442235@9442235\" \"9442171@9442171\" 100",
-          "\"#,##0~1\"": "Filtered",
-          "False": "Blanks",
-          "True": "IsKeyOrphanage"
+          "Calc": "\"9442235@9442235\" / \"9442171@9442171\" * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -22671,9 +22633,7 @@
           "Label": "GW",
           "Lastuse": "20181120",
           "Rollup": "True",
-          "Calc": "\"9442237@9442237\" \"Erl\u00f6se Gebrauchtwagen@8794779\" 100",
-          "\"#,##0~1\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "\"9442237@9442237\" / \"Erl\u00f6se Gebrauchtwagen@8794779\" * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -22684,9 +22644,7 @@
           "Label": "sonst BE NW",
           "Lastuse": "20190506",
           "Rollup": "True",
-          "Calc": "\"9695241@9695241\" \"9442179@9442179\" 100",
-          "\"#,##0~1\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "( \"9695241@9695241\" / \"9442179@9442179\" ) * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -22697,9 +22655,7 @@
           "Label": "sonst BE GW",
           "Lastuse": "20190506",
           "Rollup": "True",
-          "Calc": "\"9695243@9695243\" \"9442181@9442181\" 100",
-          "\"#,##0~1\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "( \"9695243@9695243\" / \"9442181@9442181\" ) * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -22710,9 +22666,7 @@
           "Label": "Gesamt BE Verkauf",
           "Lastuse": "20190506",
           "Rollup": "True",
-          "Calc": "\"9695247@9695247\" \"9442171@9442171\" \"9442173@9442173\" \"9442175@9442175\" \"9442177@9442177\" \"9442179@9442179\" \"9442181@9442181\" 100 1",
-          "\"#,##0~1\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "\"9695247@9695247\" / ( \"9442171@9442171\" + \"9442173@9442173\" + \"9442175@9442175\" + \"9442177@9442177\" + \"9442179@9442179\" + \"9442181@9442181\" ) * 100 * - 1"
         },
         {
           "Type": "SpecialCategory",
@@ -22723,9 +22677,7 @@
           "Label": "T+Z",
           "Lastuse": "20190507",
           "Rollup": "True",
-          "Calc": "\"9695249@9695249\" \"9442183@9442183\" 100",
-          "\"#,##0~1\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "\"9695249@9695249\" / \"9442183@9442183\" * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -22736,9 +22688,7 @@
           "Label": "Service",
           "Lastuse": "20190507",
           "Rollup": "True",
-          "Calc": "\"9695251@9695251\" \"9442185@9442185\" 100",
-          "\"#,##0~1\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "( \"9695251@9695251\" / \"9442185@9442185\" ) * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -22749,9 +22699,7 @@
           "Label": "Fremdleistung",
           "Lastuse": "20190506",
           "Rollup": "True",
-          "Calc": "\"9695253@9695253\" \"9442187@9442187\" 100",
-          "\"#,##0~1\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "( \"9695253@9695253\" / \"9442187@9442187\" ) * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -22762,9 +22710,7 @@
           "Label": "Gesamt KD",
           "Lastuse": "20190506",
           "Rollup": "True",
-          "Calc": "\"9695255@9695255\" \"9442183@9442183\" \"9442185@9442185\" \"9442187@9442187\" 100 1",
-          "\"#,##0~1\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "( \"9695255@9695255\" / ( \"9442183@9442183\" + \"9442185@9442185\" + \"9442187@9442187\" ) ) * 100 * - 1"
         },
         {
           "Type": "SpecialCategory",
@@ -22775,9 +22721,7 @@
           "Label": "Rent",
           "Lastuse": "20190506",
           "Rollup": "True",
-          "Calc": "\"9695257@9695257\" \"9442197@9442197\" 100",
-          "\"#,##0~1\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "\"9695257@9695257\" / \"9442197@9442197\" * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -22788,9 +22732,7 @@
           "Label": "sonstige",
           "Lastuse": "20181120",
           "Rollup": "True",
-          "Calc": "\"9695259@9695259\" \"Sonstige Erl\u00f6se@8794927\" 100",
-          "\"#,##0~1\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "\"9695259@9695259\" / \"Sonstige Erl\u00f6se@8794927\" * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -22801,9 +22743,7 @@
           "Label": "intern",
           "Lastuse": "20190507",
           "Rollup": "True",
-          "Calc": "\"9695261@9695261\" \"9442201@9442201\" 100",
-          "\"#,##0~1\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "( \"9695261@9695261\" / \"9442201@9442201\" ) * 100"
         },
         {
           "Type": "SpecialCategory",
@@ -22814,9 +22754,7 @@
           "Label": "Gesamt",
           "Lastuse": "20190507",
           "Rollup": "True",
-          "Calc": "\"9442233@9442233\" \"9442169@9442169\" 100",
-          "\"#,##0~1\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "( \"9442233@9442233\" / \"9442169@9442169\" ) * 100"
         }
       ]
     },
@@ -23747,8 +23685,7 @@
           "Label": "Sales",
           "Lastuse": "20181027",
           "SourceValue": "8795215",
-          "Calc": "\"Neuwagen@8795199\" \"Gebrauchtwagen@8795201\"",
-          "False": "Blanks"
+          "Calc": "\"Neuwagen@8795199\" + \"Gebrauchtwagen@8795201\""
         },
         {
           "Type": "Category",
@@ -23759,8 +23696,7 @@
           "Label": "Aftersales",
           "Lastuse": "20181027",
           "SourceValue": "8795217",
-          "Calc": "\"Teile & Zubeh\u00f6r@8795203\" \"Service@8795205\"",
-          "False": "Blanks"
+          "Calc": "\"Teile & Zubeh\u00f6r@8795203\" + \"Service@8795205\""
         },
         {
           "Type": "Category",
@@ -23771,8 +23707,7 @@
           "Label": "Service",
           "Lastuse": "20181027",
           "SourceValue": "8795219",
-          "Calc": "\"Service@8795205\"",
-          "False": "Blanks"
+          "Calc": "\"Service@8795205\""
         },
         {
           "Type": "Category",
@@ -28205,8 +28140,7 @@
           "Inclusion": "Generate",
           "Lastuse": "20140331",
           "SourceValue": "8813525",
-          "Calc": "\"Aktiva@8804271\" \"Passiva@8805279\"",
-          "False": "Blanks"
+          "Calc": "\"Aktiva@8804271\" + \"Passiva@8805279\""
         },
         {
           "Type": "Category",
@@ -28218,8 +28152,7 @@
           "Inclusion": "Generate",
           "Lastuse": "20140331",
           "SourceValue": "8813527",
-          "Calc": "\"Passiva@8805279\" 1 \"3377991@8813525\"",
-          "False": "Blanks"
+          "Calc": "( \"Passiva@8805279\" * - 1 ) + \"3377991@8813525\""
         },
         {
           "Type": "Category",
@@ -28345,9 +28278,7 @@
           "Label": "Liquidit\u00e4t ( > 1,5)",
           "Lastuse": "20190506",
           "Rollup": "True",
-          "Calc": "\"B. Umlaufverm\u00f6gen@8806653\" \"D. Verbindlichkeiten@8805281\" 1",
-          "\"#,##0~2\"": "Filtered",
-          "False": "Blanks"
+          "Calc": "\"B. Umlaufverm\u00f6gen@8806653\" / ( \"D. Verbindlichkeiten@8805281\" * - 1 )"
         },
         {
           "Type": "SpecialCategory",
@@ -28358,8 +28289,7 @@
           "Label": "Eigenkapital (> 33 %)",
           "Lastuse": "20190506",
           "Rollup": "True",
-          "Calc": "\"A. Eigenkapital@8805937\" 1 \"3377991@8813525\" 100 \"3377993@8813527\"",
-          "False": "Blanks"
+          "Calc": "( \"A. Eigenkapital@8805937\" * - 1 + \"3377991@8813525\" ) * 100 / \"3377993@8813527\""
         }
       ]
     },
@@ -28899,8 +28829,7 @@
           "Inclusion": "Generate",
           "Lastuse": "20140331",
           "SourceValue": "8813537",
-          "Calc": "\"1. Umsatzerl\u00f6se@8812359\" 1 \"8813529@8813529\" 1 \"3. Sonstige betriebliche Ertr\u00e4ge@8809953\" 1",
-          "False": "Blanks"
+          "Calc": "( \"1. Umsatzerl\u00f6se@8812359\" * - 1 ) + ( \"8813529@8813529\" * - 1 ) + ( \"3. Sonstige betriebliche Ertr\u00e4ge@8809953\" * - 1 )"
         },
         {
           "Type": "Category",
@@ -29277,8 +29206,7 @@
           "Inclusion": "Generate",
           "Lastuse": "20140402",
           "SourceValue": "8813539",
-          "Calc": "\"6293933@8813537\" \"4. Materialaufwand@8812179\" \"5. Personalaufwand@8809329\" \"6. Abschreibungen@8809293\" \"7. Sonst. betriebl. Aufwendungen@8809661\" \"8. Ertr\u00e4ge aus Beteiligungen@8810133\" 1 \"9. Sonst.Zinsen u.\u00e4hnl.Ertr\u00e4ge@8810225\" 1 \"10. Aufw. aus Verlust\u00fcbernahme@8809989\" \"11. Zinsen u.\u00e4hnl.Aufwendungen@8809081\"",
-          "False": "Blanks"
+          "Calc": "\"6293933@8813537\" - \"4. Materialaufwand@8812179\" - \"5. Personalaufwand@8809329\" - \"6. Abschreibungen@8809293\" - \"7. Sonst. betriebl. Aufwendungen@8809661\" + ( \"8. Ertr\u00e4ge aus Beteiligungen@8810133\" * - 1 ) + ( \"9. Sonst.Zinsen u.\u00e4hnl.Ertr\u00e4ge@8810225\" * - 1 ) - \"10. Aufw. aus Verlust\u00fcbernahme@8809989\" - \"11. Zinsen u.\u00e4hnl.Aufwendungen@8809081\""
         },
         {
           "Type": "Category",
@@ -29426,8 +29354,7 @@
           "Inclusion": "Generate",
           "Lastuse": "20140331",
           "SourceValue": "8813541",
-          "Calc": "\"6293935@8813539\" \"13. Au\u00dferordentliche Ertr\u00e4ge@8810073\" 1 \"14. Steuern vom Einkommen u.Ertrag@8809489\" \"15. Sonstige Steuern@8809453\" \"16. Ertr\u00e4ge aus Verlust\u00fcbernahme@8810641\" 1",
-          "False": "Blanks"
+          "Calc": "\"6293935@8813539\" + ( \"13. Au\u00dferordentliche Ertr\u00e4ge@8810073\" * - 1 ) - \"14. Steuern vom Einkommen u.Ertrag@8809489\" - \"15. Sonstige Steuern@8809453\" + ( \"16. Ertr\u00e4ge aus Verlust\u00fcbernahme@8810641\" * - 1 )"
         },
         {
           "Type": "Category",
@@ -30967,9 +30894,7 @@
       "Type": "Measure",
       "ID": "8944867",
       "Name": "Ist",
-      "Calc": "\"Ist_ori@399\" \"verk. Stunden@8944853\" \"Menge_Fibu@8945231\" \"EW Lohn Plan Tag@8971879\" \"Bruttoertrag Soll Tag@8972787\" Timing After_Rollup IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 4 ReverseSign True IsCurrency False IsFolder False",
-      "\"#,##0~0\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "\"Ist_ori@399\" + \"verk. Stunden@8944853\" + \"Menge_Fibu@8945231\" + \"EW Lohn Plan Tag@8971879\" + \"Bruttoertrag Soll Tag@8972787\"  Timing After_Rollup IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 4 Reverse",
       "Associations": []
     },
     {
@@ -31001,9 +30926,7 @@
       "Type": "Measure",
       "ID": "315031",
       "Name": "Plan",
-      "Calc": "0 IgnoreMissingValue False Storage Float64 OutPutScale 0 Decimals 3 ReverseSign True IsCurrency False IsFolder False",
-      "\"#,##0~0\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "0  IgnoreMissingValue False Storage Float64 OutPutScale 0 Decimals 3 Reverse",
       "Associations": []
     },
     {
@@ -31126,9 +31049,7 @@
       "Type": "Measure",
       "ID": "8943679",
       "Name": "Betrag_HU",
-      "Calc": "0 IgnoreMissingValue False Storage Float64 OutPutScale 2 Decimals 2 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~2\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "0  IgnoreMissingValue False Storage Float64 OutPutScale 2 Decimals 2 Reverse",
       "Associations": []
     },
     {
@@ -31185,9 +31106,7 @@
       "Type": "Measure",
       "ID": "8945231",
       "Name": "Menge_Fibu",
-      "Calc": "0 IgnoreMissingValue False Storage Float64 OutPutScale 0 Decimals 6 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~0\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "0  IgnoreMissingValue False Storage Float64 OutPutScale 0 Decimals 6 Reverse",
       "Associations": []
     },
     {

File diff suppressed because it is too large
+ 638 - 638
cognos7/data/mdl/Fin_Belege_SKR_queries.sql


+ 39 - 96
cognos7/data/mdl/S_Aftersales.json

@@ -6958,7 +6958,7 @@
           "Label": "M bisher \u00c4nderung",
           "Rollup": "False",
           "TimeAggregate": "None",
-          "Calc": "change \"M bisher gruppiert~Voriger M bisher@31631\" \"M bisher gruppiert~M bisher@31629\""
+          "Calc": "change ( \"M bisher gruppiert~Voriger M bisher@31631\" , \"M bisher gruppiert~M bisher@31629\" )"
         },
         {
           "Type": "SpecialCategory",
@@ -6968,8 +6968,7 @@
           "Label": "M bisher Zuwachs",
           "Rollup": "False",
           "TimeAggregate": "None",
-          "Calc": "growth \"M bisher gruppiert~Voriger M bisher@31631\" \"M bisher gruppiert~M bisher@31629\"",
-          "\"0%~2\"": "Sign"
+          "Calc": "percent-growth ( \"M bisher gruppiert~Voriger M bisher@31631\" , \"M bisher gruppiert~M bisher@31629\" )"
         },
         {
           "Type": "SpecialCategory",
@@ -7137,7 +7136,7 @@
           "Label": "Q bisher \u00c4nderung",
           "Rollup": "False",
           "TimeAggregate": "None",
-          "Calc": "change \"Q bisher gruppiert~Voriges Q bisher@31645\" \"Q bisher gruppiert~Q bisher@31641\""
+          "Calc": "change ( \"Q bisher gruppiert~Voriges Q bisher@31645\" , \"Q bisher gruppiert~Q bisher@31641\" )"
         },
         {
           "Type": "SpecialCategory",
@@ -7147,8 +7146,7 @@
           "Label": "Q bisher Zuwachs",
           "Rollup": "False",
           "TimeAggregate": "None",
-          "Calc": "growth \"Q bisher gruppiert~Voriges Q bisher@31645\" \"Q bisher gruppiert~Q bisher@31641\"",
-          "\"0%~2\"": "Sign"
+          "Calc": "percent-growth ( \"Q bisher gruppiert~Voriges Q bisher@31645\" , \"Q bisher gruppiert~Q bisher@31641\" )"
         },
         {
           "Type": "SpecialCategory",
@@ -7356,7 +7354,7 @@
           "Label": "J bisher \u00c4nderung",
           "Rollup": "False",
           "TimeAggregate": "None",
-          "Calc": "change \"J bisher gruppiert~Voriges J bisher@31663\" \"J bisher gruppiert~J bisher@31657\""
+          "Calc": "change ( \"J bisher gruppiert~Voriges J bisher@31663\" , \"J bisher gruppiert~J bisher@31657\" )"
         },
         {
           "Type": "SpecialCategory",
@@ -7366,8 +7364,7 @@
           "Label": "J bisher Zuwachs",
           "Rollup": "False",
           "TimeAggregate": "None",
-          "Calc": "growth \"J bisher gruppiert~Voriges J bisher@31663\" \"J bisher gruppiert~J bisher@31657\"",
-          "\"0%~2\"": "Sign"
+          "Calc": "percent-growth ( \"J bisher gruppiert~Voriges J bisher@31663\" , \"J bisher gruppiert~J bisher@31657\" )"
         }
       ]
     },
@@ -12559,25 +12556,19 @@
     {
       "Type": "Measure",
       "Name": "Gesamt",
-      "Calc": "\"Lohn@823\" \"Teile@819\" \"Sonst.@62243\" \"R\u00e4dereinl.@719229\" \"T\u00dcV@1518365\" \"Fremdl.@1518369\" \"Mietw.@1700013\" Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 0 Decimals 3 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~2\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "\"Lohn@823\" + \"Teile@819\" + \"Sonst.@62243\" + \"R\u00e4dereinl.@719229\" + \"T\u00dcV@1518365\" + \"Fremdl.@1518369\" + \"Mietw.@1700013\"  Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 0 Decimals 3 Reverse",
       "Associations": []
     },
     {
       "Type": "Measure",
       "Name": "Lohn",
-      "Calc": "\"Lohn_Umsatz@1700181\" \"NL Lohn@1428547\" Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 0 Decimals 3 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~2\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "\"Lohn_Umsatz@1700181\" + \"NL Lohn@1428547\"  Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 0 Decimals 3 Reverse",
       "Associations": []
     },
     {
       "Type": "Measure",
       "Name": "Teile",
-      "Calc": "\"Teile_Umsatz@1700185\" \"NL Teile@1428549\" Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 0 Decimals 3 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~2\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "\"Teile_Umsatz@1700185\" + \"NL Teile@1428549\"  Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 0 Decimals 3 Reverse",
       "Associations": []
     },
     {
@@ -12607,17 +12598,13 @@
     {
       "Type": "Measure",
       "Name": "DB1 Teile",
-      "Calc": "\"Teile@819\" \"EW Teile@98221\" Missing Zero Timing After_Rollup IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 0 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~2\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "\"Teile@819\" - \"EW Teile@98221\"  Missing Zero Timing After_Rollup IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 0 Reverse",
       "Associations": []
     },
     {
       "Type": "Measure",
       "Name": "DB1 Teile %",
-      "Calc": "\"DB1 Teile@98229\" \"Teile@819\" 100 Missing Zero Timing After_Rollup IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 0 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~1\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "\"DB1 Teile@98229\" / \"Teile@819\" * 100  Missing Zero Timing After_Rollup IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 0 Reverse",
       "Associations": []
     },
     {
@@ -12743,17 +12730,13 @@
     {
       "Type": "Measure",
       "Name": "DB1 Fremdl.",
-      "Calc": "\"Fremdl.@1518369\" \"EW Fremdl.@1700171\" IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 0 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~0\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "\"Fremdl.@1518369\" - \"EW Fremdl.@1700171\"  IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 0 Reverse",
       "Associations": []
     },
     {
       "Type": "Measure",
       "Name": "DB1 Fremdl. %",
-      "Calc": "\"DB1 Fremdl.@1700175\" \"Fremdl.@1518369\" 100 Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 0 Decimals 5 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~1\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "\"DB1 Fremdl.@1700175\" / \"Fremdl.@1518369\" * 100  Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 0 Decimals 5 Reverse",
       "Associations": []
     },
     {
@@ -12783,13 +12766,13 @@
     {
       "Type": "Measure",
       "Name": "DB1 Sonst.",
-      "Calc": "0 IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 0 ReverseSign False IsCurrency False IsFolder False DrillThrough False",
+      "Calc": "0  IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 0 Reverse",
       "Associations": []
     },
     {
       "Type": "Measure",
       "Name": "DB1 Sonst. %",
-      "Calc": "0 IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 0 ReverseSign False IsCurrency False IsFolder False DrillThrough False",
+      "Calc": "0  IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 0 Reverse",
       "Associations": []
     },
     {
@@ -12843,15 +12826,13 @@
     {
       "Type": "Measure",
       "Name": "Soll Std.",
-      "Calc": "0 Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 8 Decimals 3 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~2\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "0  Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 8 Decimals 3 Reverse",
       "Associations": []
     },
     {
       "Type": "Measure",
       "Name": "Menge",
-      "Calc": "0 IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 0 ReverseSign False IsCurrency False IsFolder False DrillThrough False",
+      "Calc": "0  IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 0 Reverse",
       "Associations": []
     },
     {
@@ -12881,9 +12862,7 @@
     {
       "Type": "Measure",
       "Name": "NL Lohn %",
-      "Calc": "\"NL Lohn@1428547\" \"Lohn@823\" \"NL Lohn@1428547\" 100 Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 0 Decimals 8 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~1\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "\"NL Lohn@1428547\" / ( \"Lohn@823\" + \"NL Lohn@1428547\" ) * 100  Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 0 Decimals 8 Reverse",
       "Associations": []
     },
     {
@@ -12913,9 +12892,7 @@
     {
       "Type": "Measure",
       "Name": "NL Teile %",
-      "Calc": "\"NL Teile@1428549\" \"Teile@819\" \"NL Teile@1428549\" 100 Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 0 Decimals 8 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~1\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "\"NL Teile@1428549\" / ( \"Teile@819\" + \"NL Teile@1428549\" ) * 100  Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 0 Decimals 8 Reverse",
       "Associations": []
     },
     {
@@ -12996,55 +12973,43 @@
     {
       "Type": "Measure",
       "Name": "LG %",
-      "Calc": "\"verk. Std.@62285\" \"ben. Std.@1518045\" 100 Missing Zero Timing After_Rollup IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 0 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~2\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "\"verk. Std.@62285\" / \"ben. Std.@1518045\" * 100  Missing Zero Timing After_Rollup IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 0 Reverse",
       "Associations": []
     },
     {
       "Type": "Measure",
       "Name": "Ums. ges. / DG",
-      "Calc": "\"Gesamt@31677\" \"DG@62529\" Missing Zero Timing After_Rollup IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 3 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~0\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "\"Gesamt@31677\" / \"DG@62529\"  Missing Zero Timing After_Rollup IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 3 Reverse",
       "Associations": []
     },
     {
       "Type": "Measure",
       "Name": "Lohn / DG",
-      "Calc": "\"Lohn@823\" \"DG@62529\" Missing Zero Timing After_Rollup IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 3 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~0\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "\"Lohn@823\" / \"DG@62529\"  Missing Zero Timing After_Rollup IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 3 Reverse",
       "Associations": []
     },
     {
       "Type": "Measure",
       "Name": "Teile / DG",
-      "Calc": "\"Teile@819\" \"DG@62529\" Missing Zero Timing After_Rollup IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 3 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~0\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "\"Teile@819\" / \"DG@62529\"  Missing Zero Timing After_Rollup IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 3 Reverse",
       "Associations": []
     },
     {
       "Type": "Measure",
       "Name": "Sonst. / DG",
-      "Calc": "0 IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 0 ReverseSign False IsCurrency False IsFolder False DrillThrough False",
+      "Calc": "0  IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 0 Reverse",
       "Associations": []
     },
     {
       "Type": "Measure",
       "Name": "verk. Std / DG",
-      "Calc": "\"verk. Std.@62285\" \"DG@62529\" Missing Zero Timing After_Rollup IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 3 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~1\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "\"verk. Std.@62285\" / \"DG@62529\"  Missing Zero Timing After_Rollup IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 3 Reverse",
       "Associations": []
     },
     {
       "Type": "Measure",
       "Name": "Std.-Satz",
-      "Calc": "\"Lohn@823\" \"verk. Std.@62285\" Missing Zero Timing After_Rollup IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 3 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~2\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "\"Lohn@823\" / \"verk. Std.@62285\"  Missing Zero Timing After_Rollup IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 3 Reverse",
       "Associations": []
     },
     {
@@ -13074,61 +13039,49 @@
     {
       "Type": "Measure",
       "Name": "DG / AT",
-      "Calc": "0 IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 0 ReverseSign False IsCurrency False IsFolder False DrillThrough False",
+      "Calc": "0  IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 0 Reverse",
       "Associations": []
     },
     {
       "Type": "Measure",
       "Name": "Menge Focus",
-      "Calc": "0 IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 0 ReverseSign False IsCurrency False IsFolder False DrillThrough False",
+      "Calc": "0  IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 0 Reverse",
       "Associations": []
     },
     {
       "Type": "Measure",
       "Name": "Urlaubstage",
-      "Calc": "0 Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 1 Decimals 3 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~1\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "0  Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 1 Decimals 3 Reverse",
       "Associations": []
     },
     {
       "Type": "Measure",
       "Name": "Kranktage",
-      "Calc": "0 Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 1 Decimals 3 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~1\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "0  Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 1 Decimals 3 Reverse",
       "Associations": []
     },
     {
       "Type": "Measure",
       "Name": "Schultage",
-      "Calc": "0 Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 1 Decimals 3 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~1\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "0  Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 1 Decimals 3 Reverse",
       "Associations": []
     },
     {
       "Type": "Measure",
       "Name": "Arbeitstag Mofr_Ges.Jahr",
-      "Calc": "0 Missing Zero Timing After_Rollup IgnoreMissingValue False Storage Int32 OutPutScale 0 Decimals 0 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~0\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "0  Missing Zero Timing After_Rollup IgnoreMissingValue False Storage Int32 OutPutScale 0 Decimals 0 Reverse",
       "Associations": []
     },
     {
       "Type": "Measure",
       "Name": "Tage bis Rechnung",
-      "Calc": "0 Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 0 Decimals 6 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~0\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "0  Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 0 Decimals 6 Reverse",
       "Associations": []
     },
     {
       "Type": "Measure",
       "Name": "Tage bis Rechnung Durchschnitt",
-      "Calc": "average \"Tage bis Rechnung@714005\" Missing Zero Timing After_Rollup IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 0 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~0\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "average ( \"Tage bis Rechnung@714005\" )  Missing Zero Timing After_Rollup IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 0 Reverse",
       "Associations": []
     },
     {
@@ -13201,41 +13154,31 @@
     {
       "Type": "Measure",
       "Name": "Umsatz Teile",
-      "Calc": "\"Teile@819\" Missing Zero IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 5 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~0\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "\"Teile@819\"  Missing Zero IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 5 Reverse",
       "Associations": []
     },
     {
       "Type": "Measure",
       "Name": "Einsatz Teile",
-      "Calc": "\"EW Teile@98221\" Missing Zero IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 5 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~0\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "\"EW Teile@98221\"  Missing Zero IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 5 Reverse",
       "Associations": []
     },
     {
       "Type": "Measure",
       "Name": "DB 1 Teile-Rg.",
-      "Calc": "\"Umsatz Teile@1700143\" \"Einsatz Teile@1700145\" Missing Zero IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 5 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~0\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "\"Umsatz Teile@1700143\" - \"Einsatz Teile@1700145\"  Missing Zero IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 5 Reverse",
       "Associations": []
     },
     {
       "Type": "Measure",
       "Name": "DB 1 Teile-Rg. %",
-      "Calc": "\"DB 1 Teile-Rg.@1700147\" \"Umsatz Teile@1700143\" 100 Missing Zero IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 5 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~1\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "\"DB 1 Teile-Rg.@1700147\" / \"Umsatz Teile@1700143\" * 100  Missing Zero IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 5 Reverse",
       "Associations": []
     },
     {
       "Type": "Measure",
       "Name": "Umsatz Sonst.",
-      "Calc": "\"Sonst.@62243\" Missing Zero IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 5 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~0\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "\"Sonst.@62243\"  Missing Zero IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 5 Reverse",
       "Associations": []
     },
     {

+ 39 - 96
cognos7/data/mdl/S_Aftersales_ori.json

@@ -7698,7 +7698,7 @@
           "Lastuse": "20230202",
           "Rollup": "False",
           "TimeAggregate": "None",
-          "Calc": "change \"M bisher gruppiert~Voriger M bisher@31631\" \"M bisher gruppiert~M bisher@31629\""
+          "Calc": "change ( \"M bisher gruppiert~Voriger M bisher@31631\" , \"M bisher gruppiert~M bisher@31629\" )"
         },
         {
           "Type": "SpecialCategory",
@@ -7710,8 +7710,7 @@
           "Lastuse": "20230202",
           "Rollup": "False",
           "TimeAggregate": "None",
-          "Calc": "growth \"M bisher gruppiert~Voriger M bisher@31631\" \"M bisher gruppiert~M bisher@31629\"",
-          "\"0%~2\"": "Sign"
+          "Calc": "percent-growth ( \"M bisher gruppiert~Voriger M bisher@31631\" , \"M bisher gruppiert~M bisher@31629\" )"
         },
         {
           "Type": "SpecialCategory",
@@ -7933,7 +7932,7 @@
           "Lastuse": "20230202",
           "Rollup": "False",
           "TimeAggregate": "None",
-          "Calc": "change \"Q bisher gruppiert~Voriges Q bisher@31645\" \"Q bisher gruppiert~Q bisher@31641\""
+          "Calc": "change ( \"Q bisher gruppiert~Voriges Q bisher@31645\" , \"Q bisher gruppiert~Q bisher@31641\" )"
         },
         {
           "Type": "SpecialCategory",
@@ -7945,8 +7944,7 @@
           "Lastuse": "20230202",
           "Rollup": "False",
           "TimeAggregate": "None",
-          "Calc": "growth \"Q bisher gruppiert~Voriges Q bisher@31645\" \"Q bisher gruppiert~Q bisher@31641\"",
-          "\"0%~2\"": "Sign"
+          "Calc": "percent-growth ( \"Q bisher gruppiert~Voriges Q bisher@31645\" , \"Q bisher gruppiert~Q bisher@31641\" )"
         },
         {
           "Type": "SpecialCategory",
@@ -8224,7 +8222,7 @@
           "Lastuse": "20230202",
           "Rollup": "False",
           "TimeAggregate": "None",
-          "Calc": "change \"J bisher gruppiert~Voriges J bisher@31663\" \"J bisher gruppiert~J bisher@31657\""
+          "Calc": "change ( \"J bisher gruppiert~Voriges J bisher@31663\" , \"J bisher gruppiert~J bisher@31657\" )"
         },
         {
           "Type": "SpecialCategory",
@@ -8236,8 +8234,7 @@
           "Lastuse": "20230202",
           "Rollup": "False",
           "TimeAggregate": "None",
-          "Calc": "growth \"J bisher gruppiert~Voriges J bisher@31663\" \"J bisher gruppiert~J bisher@31657\"",
-          "\"0%~2\"": "Sign"
+          "Calc": "percent-growth ( \"J bisher gruppiert~Voriges J bisher@31663\" , \"J bisher gruppiert~J bisher@31657\" )"
         }
       ]
     },
@@ -13992,27 +13989,21 @@
       "Type": "Measure",
       "ID": "31677",
       "Name": "Gesamt",
-      "Calc": "\"Lohn@823\" \"Teile@819\" \"Sonst.@62243\" \"R\u00e4dereinl.@719229\" \"T\u00dcV@1518365\" \"Fremdl.@1518369\" \"Mietw.@1700013\" Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 0 Decimals 3 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~2\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "\"Lohn@823\" + \"Teile@819\" + \"Sonst.@62243\" + \"R\u00e4dereinl.@719229\" + \"T\u00dcV@1518365\" + \"Fremdl.@1518369\" + \"Mietw.@1700013\"  Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 0 Decimals 3 Reverse",
       "Associations": []
     },
     {
       "Type": "Measure",
       "ID": "823",
       "Name": "Lohn",
-      "Calc": "\"Lohn_Umsatz@1700181\" \"NL Lohn@1428547\" Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 0 Decimals 3 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~2\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "\"Lohn_Umsatz@1700181\" + \"NL Lohn@1428547\"  Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 0 Decimals 3 Reverse",
       "Associations": []
     },
     {
       "Type": "Measure",
       "ID": "819",
       "Name": "Teile",
-      "Calc": "\"Teile_Umsatz@1700185\" \"NL Teile@1428549\" Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 0 Decimals 3 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~2\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "\"Teile_Umsatz@1700185\" + \"NL Teile@1428549\"  Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 0 Decimals 3 Reverse",
       "Associations": []
     },
     {
@@ -14045,18 +14036,14 @@
       "Type": "Measure",
       "ID": "98229",
       "Name": "DB1 Teile",
-      "Calc": "\"Teile@819\" \"EW Teile@98221\" Missing Zero Timing After_Rollup IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 0 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~2\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "\"Teile@819\" - \"EW Teile@98221\"  Missing Zero Timing After_Rollup IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 0 Reverse",
       "Associations": []
     },
     {
       "Type": "Measure",
       "ID": "98233",
       "Name": "DB1 Teile %",
-      "Calc": "\"DB1 Teile@98229\" \"Teile@819\" 100 Missing Zero Timing After_Rollup IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 0 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~1\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "\"DB1 Teile@98229\" / \"Teile@819\" * 100  Missing Zero Timing After_Rollup IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 0 Reverse",
       "Associations": []
     },
     {
@@ -14193,18 +14180,14 @@
       "Type": "Measure",
       "ID": "1700175",
       "Name": "DB1 Fremdl.",
-      "Calc": "\"Fremdl.@1518369\" \"EW Fremdl.@1700171\" IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 0 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~0\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "\"Fremdl.@1518369\" - \"EW Fremdl.@1700171\"  IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 0 Reverse",
       "Associations": []
     },
     {
       "Type": "Measure",
       "ID": "1700177",
       "Name": "DB1 Fremdl. %",
-      "Calc": "\"DB1 Fremdl.@1700175\" \"Fremdl.@1518369\" 100 Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 0 Decimals 5 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~1\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "\"DB1 Fremdl.@1700175\" / \"Fremdl.@1518369\" * 100  Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 0 Decimals 5 Reverse",
       "Associations": []
     },
     {
@@ -14237,14 +14220,14 @@
       "Type": "Measure",
       "ID": "1428541",
       "Name": "DB1 Sonst.",
-      "Calc": "0 IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 0 ReverseSign False IsCurrency False IsFolder False DrillThrough False",
+      "Calc": "0  IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 0 Reverse",
       "Associations": []
     },
     {
       "Type": "Measure",
       "ID": "1428543",
       "Name": "DB1 Sonst. %",
-      "Calc": "0 IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 0 ReverseSign False IsCurrency False IsFolder False DrillThrough False",
+      "Calc": "0  IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 0 Reverse",
       "Associations": []
     },
     {
@@ -14303,16 +14286,14 @@
       "Type": "Measure",
       "ID": "62289",
       "Name": "Soll Std.",
-      "Calc": "0 Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 8 Decimals 3 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~2\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "0  Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 8 Decimals 3 Reverse",
       "Associations": []
     },
     {
       "Type": "Measure",
       "ID": "1428545",
       "Name": "Menge",
-      "Calc": "0 IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 0 ReverseSign False IsCurrency False IsFolder False DrillThrough False",
+      "Calc": "0  IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 0 Reverse",
       "Associations": []
     },
     {
@@ -14345,9 +14326,7 @@
       "Type": "Measure",
       "ID": "1517969",
       "Name": "NL Lohn %",
-      "Calc": "\"NL Lohn@1428547\" \"Lohn@823\" \"NL Lohn@1428547\" 100 Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 0 Decimals 8 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~1\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "\"NL Lohn@1428547\" / ( \"Lohn@823\" + \"NL Lohn@1428547\" ) * 100  Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 0 Decimals 8 Reverse",
       "Associations": []
     },
     {
@@ -14380,9 +14359,7 @@
       "Type": "Measure",
       "ID": "1517973",
       "Name": "NL Teile %",
-      "Calc": "\"NL Teile@1428549\" \"Teile@819\" \"NL Teile@1428549\" 100 Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 0 Decimals 8 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~1\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "\"NL Teile@1428549\" / ( \"Teile@819\" + \"NL Teile@1428549\" ) * 100  Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 0 Decimals 8 Reverse",
       "Associations": []
     },
     {
@@ -14470,61 +14447,49 @@
       "Type": "Measure",
       "ID": "219963",
       "Name": "LG %",
-      "Calc": "\"verk. Std.@62285\" \"ben. Std.@1518045\" 100 Missing Zero Timing After_Rollup IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 0 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~2\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "\"verk. Std.@62285\" / \"ben. Std.@1518045\" * 100  Missing Zero Timing After_Rollup IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 0 Reverse",
       "Associations": []
     },
     {
       "Type": "Measure",
       "ID": "712013",
       "Name": "Ums. ges. / DG",
-      "Calc": "\"Gesamt@31677\" \"DG@62529\" Missing Zero Timing After_Rollup IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 3 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~0\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "\"Gesamt@31677\" / \"DG@62529\"  Missing Zero Timing After_Rollup IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 3 Reverse",
       "Associations": []
     },
     {
       "Type": "Measure",
       "ID": "712007",
       "Name": "Lohn / DG",
-      "Calc": "\"Lohn@823\" \"DG@62529\" Missing Zero Timing After_Rollup IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 3 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~0\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "\"Lohn@823\" / \"DG@62529\"  Missing Zero Timing After_Rollup IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 3 Reverse",
       "Associations": []
     },
     {
       "Type": "Measure",
       "ID": "712009",
       "Name": "Teile / DG",
-      "Calc": "\"Teile@819\" \"DG@62529\" Missing Zero Timing After_Rollup IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 3 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~0\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "\"Teile@819\" / \"DG@62529\"  Missing Zero Timing After_Rollup IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 3 Reverse",
       "Associations": []
     },
     {
       "Type": "Measure",
       "ID": "1428553",
       "Name": "Sonst. / DG",
-      "Calc": "0 IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 0 ReverseSign False IsCurrency False IsFolder False DrillThrough False",
+      "Calc": "0  IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 0 Reverse",
       "Associations": []
     },
     {
       "Type": "Measure",
       "ID": "712011",
       "Name": "verk. Std / DG",
-      "Calc": "\"verk. Std.@62285\" \"DG@62529\" Missing Zero Timing After_Rollup IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 3 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~1\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "\"verk. Std.@62285\" / \"DG@62529\"  Missing Zero Timing After_Rollup IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 3 Reverse",
       "Associations": []
     },
     {
       "Type": "Measure",
       "ID": "712015",
       "Name": "Std.-Satz",
-      "Calc": "\"Lohn@823\" \"verk. Std.@62285\" Missing Zero Timing After_Rollup IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 3 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~2\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "\"Lohn@823\" / \"verk. Std.@62285\"  Missing Zero Timing After_Rollup IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 3 Reverse",
       "Associations": []
     },
     {
@@ -14557,68 +14522,56 @@
       "Type": "Measure",
       "ID": "1428555",
       "Name": "DG / AT",
-      "Calc": "0 IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 0 ReverseSign False IsCurrency False IsFolder False DrillThrough False",
+      "Calc": "0  IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 0 Reverse",
       "Associations": []
     },
     {
       "Type": "Measure",
       "ID": "1428557",
       "Name": "Menge Focus",
-      "Calc": "0 IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 0 ReverseSign False IsCurrency False IsFolder False DrillThrough False",
+      "Calc": "0  IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 0 Reverse",
       "Associations": []
     },
     {
       "Type": "Measure",
       "ID": "712157",
       "Name": "Urlaubstage",
-      "Calc": "0 Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 1 Decimals 3 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~1\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "0  Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 1 Decimals 3 Reverse",
       "Associations": []
     },
     {
       "Type": "Measure",
       "ID": "712161",
       "Name": "Kranktage",
-      "Calc": "0 Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 1 Decimals 3 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~1\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "0  Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 1 Decimals 3 Reverse",
       "Associations": []
     },
     {
       "Type": "Measure",
       "ID": "712165",
       "Name": "Schultage",
-      "Calc": "0 Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 1 Decimals 3 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~1\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "0  Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 1 Decimals 3 Reverse",
       "Associations": []
     },
     {
       "Type": "Measure",
       "ID": "714133",
       "Name": "Arbeitstag Mofr_Ges.Jahr",
-      "Calc": "0 Missing Zero Timing After_Rollup IgnoreMissingValue False Storage Int32 OutPutScale 0 Decimals 0 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~0\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "0  Missing Zero Timing After_Rollup IgnoreMissingValue False Storage Int32 OutPutScale 0 Decimals 0 Reverse",
       "Associations": []
     },
     {
       "Type": "Measure",
       "ID": "714005",
       "Name": "Tage bis Rechnung",
-      "Calc": "0 Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 0 Decimals 6 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~0\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "0  Missing Zero IgnoreMissingValue False Storage Float64 OutPutScale 0 Decimals 6 Reverse",
       "Associations": []
     },
     {
       "Type": "Measure",
       "ID": "714009",
       "Name": "Tage bis Rechnung Durchschnitt",
-      "Calc": "average \"Tage bis Rechnung@714005\" Missing Zero Timing After_Rollup IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 0 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~0\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "average ( \"Tage bis Rechnung@714005\" )  Missing Zero Timing After_Rollup IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 0 Reverse",
       "Associations": []
     },
     {
@@ -14697,45 +14650,35 @@
       "Type": "Measure",
       "ID": "1700143",
       "Name": "Umsatz Teile",
-      "Calc": "\"Teile@819\" Missing Zero IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 5 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~0\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "\"Teile@819\"  Missing Zero IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 5 Reverse",
       "Associations": []
     },
     {
       "Type": "Measure",
       "ID": "1700145",
       "Name": "Einsatz Teile",
-      "Calc": "\"EW Teile@98221\" Missing Zero IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 5 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~0\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "\"EW Teile@98221\"  Missing Zero IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 5 Reverse",
       "Associations": []
     },
     {
       "Type": "Measure",
       "ID": "1700147",
       "Name": "DB 1 Teile-Rg.",
-      "Calc": "\"Umsatz Teile@1700143\" \"Einsatz Teile@1700145\" Missing Zero IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 5 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~0\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "\"Umsatz Teile@1700143\" - \"Einsatz Teile@1700145\"  Missing Zero IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 5 Reverse",
       "Associations": []
     },
     {
       "Type": "Measure",
       "ID": "1700149",
       "Name": "DB 1 Teile-Rg. %",
-      "Calc": "\"DB 1 Teile-Rg.@1700147\" \"Umsatz Teile@1700143\" 100 Missing Zero IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 5 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~1\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "\"DB 1 Teile-Rg.@1700147\" / \"Umsatz Teile@1700143\" * 100  Missing Zero IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 5 Reverse",
       "Associations": []
     },
     {
       "Type": "Measure",
       "ID": "1700151",
       "Name": "Umsatz Sonst.",
-      "Calc": "\"Sonst.@62243\" Missing Zero IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 5 ReverseSign False IsCurrency False IsFolder False",
-      "\"#,##0~0\"": "DrillThrough",
-      "False": "EndList",
+      "Calc": "\"Sonst.@62243\"  Missing Zero IgnoreMissingValue False Storage Default OutPutScale 0 Decimals 5 Reverse",
       "Associations": []
     },
     {

+ 201 - 201
cognos7/data/mdl/S_Aftersales_queries.sql

@@ -3,19 +3,19 @@ CREATE
 
 ALTER VIEW [load].[current_date_Prognose_operativ]
 AS
-SELECT --[Bundeslaender Id] AS "Bundeslaender Id",
-	[Invoice Date] AS "Invoice Date",
-	--[Wochentage Id] AS "Wochentage Id",
-	[Arbeitstag Mofr] AS "Arbeitstag Mofr",
-	--[Zaehler Mofr] AS "Zaehler Mofr",
-	--[Summe Mofr] AS "Summe Mofr",
-	--[Arbeitstag Mosa] AS "Arbeitstag Mosa",
-	--[Zaehler Mosa] AS "Zaehler Mosa",
-	--[Summe Mosa] AS "Summe Mosa",
-	--[Feiertage Id] AS "Feiertage Id",
-	--[Jahr] AS "Jahr",
-	--[Arbeitstag Nr Jahr] AS "Arbeitstag Nr Jahr",
-	--[Gesamt Arbeitstage] AS "Gesamt Arbeitstage" 
+SELECT --[Bundeslaender Id] AS [Bundeslaender Id],
+	[Invoice Date] AS [Invoice Date],
+	--[Wochentage Id] AS [Wochentage Id],
+	[Arbeitstag Mofr] AS [Arbeitstag Mofr],
+	--[Zaehler Mofr] AS [Zaehler Mofr],
+	--[Summe Mofr] AS [Summe Mofr],
+	--[Arbeitstag Mosa] AS [Arbeitstag Mosa],
+	--[Zaehler Mosa] AS [Zaehler Mosa],
+	--[Summe Mosa] AS [Summe Mosa],
+	--[Feiertage Id] AS [Feiertage Id],
+	--[Jahr] AS [Jahr],
+	--[Arbeitstag Nr Jahr] AS [Arbeitstag Nr Jahr],
+	--[Gesamt Arbeitstage] AS [Gesamt Arbeitstage] 
 FROM [export_csv].[current_date_Prognose_operativ]
 GO
 
@@ -24,19 +24,19 @@ CREATE
 
 ALTER VIEW [load].[current_date_Prognose_operativ_VJ]
 AS
-SELECT --[Bundeslaender Id] AS "Bundeslaender Id",
-	[Invoice Date] AS "Invoice Date",
-	--[Wochentage Id] AS "Wochentage Id",
-	[Arbeitstag Mofr] AS "Arbeitstag Mofr",
-	--[Zaehler Mofr] AS "Zaehler Mofr",
-	--[Summe Mofr] AS "Summe Mofr",
-	--[Arbeitstag Mosa] AS "Arbeitstag Mosa",
-	--[Zaehler Mosa] AS "Zaehler Mosa",
-	--[Summe Mosa] AS "Summe Mosa",
-	--[Feiertage Id] AS "Feiertage Id",
-	--[Jahr] AS "Jahr",
-	--[Arbeitstag Nr Jahr] AS "Arbeitstag Nr Jahr",
-	--[Gesamt Arbeitstage] AS "Gesamt Arbeitstage" 
+SELECT --[Bundeslaender Id] AS [Bundeslaender Id],
+	[Invoice Date] AS [Invoice Date],
+	--[Wochentage Id] AS [Wochentage Id],
+	[Arbeitstag Mofr] AS [Arbeitstag Mofr],
+	--[Zaehler Mofr] AS [Zaehler Mofr],
+	--[Summe Mofr] AS [Summe Mofr],
+	--[Arbeitstag Mosa] AS [Arbeitstag Mosa],
+	--[Zaehler Mosa] AS [Zaehler Mosa],
+	--[Summe Mosa] AS [Summe Mosa],
+	--[Feiertage Id] AS [Feiertage Id],
+	--[Jahr] AS [Jahr],
+	--[Arbeitstag Nr Jahr] AS [Arbeitstag Nr Jahr],
+	--[Gesamt Arbeitstage] AS [Gesamt Arbeitstage] 
 FROM [export_csv].[current_date_Prognose_operativ_VJ]
 GO
 
@@ -45,64 +45,64 @@ CREATE
 
 ALTER VIEW [load].[Aftersales_Rechnungen_ben_AW_final]
 AS
-SELECT [Hauptbetrieb_ID] AS "Hauptbetrieb_ID",
-	[Hauptbetrieb_Name] AS "Hauptbetrieb_Name",
-	[Standort_ID] AS "Standort_ID",
-	[Standort_Name] AS "Standort_Name",
-	[Employee_Function] AS "Employee_Function",
-	[Serviceberater] AS "Serviceberater",
-	[Order Number] AS "Order Number",
-	[Invoice_Desc_100] AS "Invoice_Desc_100",
-	[Fabrikat] AS "Fabrikat",
-	[Model] AS "Model",
-	[Fahrzeug] AS "Fahrzeug",
-	[Kostenstelle] AS "Kostenstelle",
-	--[Marke] AS "Marke",
-	[Umsatzart] AS "Umsatzart",
-	[Auftragsart] AS "Auftragsart",
-	[Auftragsposition] AS "Auftragsposition",
-	[Kundenart] AS "Kundenart",
-	[Kunde] AS "Kunde",
-	--[Order_Desc_30] AS "Order_Desc_30",
-	[Invoice_Desc_30] AS "Invoice_Desc_30",
-	[Zuordnung_Produktbuchungsgruppe] AS "Zuordnung_Produktbuchungsgruppe",
-	[Produktbuchungsgruppe] AS "Produktbuchungsgruppe",
-	[FZG-Altersstaffel] AS "FZG-Altersstaffel",
-	[Repair_Group_Desc] AS "Repair_Group_Desc",
-	[DB1_><_EK] AS "DB1_><_EK",
-	[Rechnung_Gutschrift] AS "Rechnung_Gutschrift",
-	[Parts_Focus_Group] AS "Parts_Focus_Group",
-	[Parts_Make_Desc] AS "Parts_Make_Desc",
-	[Parts_Group_Desc] AS "Parts_Group_Desc",
-	[PLZ_1_Stelle] AS "PLZ_1_Stelle",
-	[PLZ_2_Stelle] AS "PLZ_2_Stelle",
-	[PLZ_3_Stelle] AS "PLZ_3_Stelle",
-	[PLZ_4_Stelle] AS "PLZ_4_Stelle",
-	[PLZ] AS "PLZ",
-	[Zuordnung_Funktion] AS "Zuordnung_Funktion",
-	[Order_Desc_100] AS "Order_Desc_100",
-	[Lohn] AS "Lohn_Umsatz",
-	[Teile] AS "Teile_Umsatz",
-	[EW Teile] AS "EW Teile",
-	[Sonst.] AS "Sonst.",
-	[TÜV] AS "TÜV",
-	[Fremdl.] AS "Fremdl.",
-	[Mietw.] AS "Mietw.",
-	[Rädereinl.] AS "Rädereinl.",
-	[verk. Std.] AS "verk. Std.",
-	[ben. Std.] AS "ben. Std.",
-	[NL Lohn] AS "NL Lohn",
-	[NL Teile] AS "NL Teile",
-	[NL Sonst.] AS "NL Sonst.",
-	[DG] AS "DG",
-	[NL Sonst %] AS "NL Sonst %",
-	--[Anz. AT] AS "Anz. AT",
-	[Anwesenheit Mech Karo Lack] AS "Anwesenheit Mech Karo Lack",
-	[Anwesenheit Meister] AS "Anwesenheit Meister",
-	[Invoice Date] AS "Invoice Date",
-	[Rechnungsausgang] AS "Rechnungsausgang",
-	[Fabrikat_Order_By] AS "Fabrikat_Order_By",
-	[Serviceberater_Rg_Steller] AS "Serviceberater_Rg_Steller" 
+SELECT [Hauptbetrieb_ID] AS [Hauptbetrieb_ID],
+	[Hauptbetrieb_Name] AS [Hauptbetrieb_Name],
+	[Standort_ID] AS [Standort_ID],
+	[Standort_Name] AS [Standort_Name],
+	[Employee_Function] AS [Employee_Function],
+	[Serviceberater] AS [Serviceberater],
+	[Order Number] AS [Order Number],
+	[Invoice_Desc_100] AS [Invoice_Desc_100],
+	[Fabrikat] AS [Fabrikat],
+	[Model] AS [Model],
+	[Fahrzeug] AS [Fahrzeug],
+	[Kostenstelle] AS [Kostenstelle],
+	--[Marke] AS [Marke],
+	[Umsatzart] AS [Umsatzart],
+	[Auftragsart] AS [Auftragsart],
+	[Auftragsposition] AS [Auftragsposition],
+	[Kundenart] AS [Kundenart],
+	[Kunde] AS [Kunde],
+	--[Order_Desc_30] AS [Order_Desc_30],
+	[Invoice_Desc_30] AS [Invoice_Desc_30],
+	[Zuordnung_Produktbuchungsgruppe] AS [Zuordnung_Produktbuchungsgruppe],
+	[Produktbuchungsgruppe] AS [Produktbuchungsgruppe],
+	[FZG-Altersstaffel] AS [FZG-Altersstaffel],
+	[Repair_Group_Desc] AS [Repair_Group_Desc],
+	[DB1_><_EK] AS [DB1_><_EK],
+	[Rechnung_Gutschrift] AS [Rechnung_Gutschrift],
+	[Parts_Focus_Group] AS [Parts_Focus_Group],
+	[Parts_Make_Desc] AS [Parts_Make_Desc],
+	[Parts_Group_Desc] AS [Parts_Group_Desc],
+	[PLZ_1_Stelle] AS [PLZ_1_Stelle],
+	[PLZ_2_Stelle] AS [PLZ_2_Stelle],
+	[PLZ_3_Stelle] AS [PLZ_3_Stelle],
+	[PLZ_4_Stelle] AS [PLZ_4_Stelle],
+	[PLZ] AS [PLZ],
+	[Zuordnung_Funktion] AS [Zuordnung_Funktion],
+	[Order_Desc_100] AS [Order_Desc_100],
+	[Lohn] AS [Lohn_Umsatz],
+	[Teile] AS [Teile_Umsatz],
+	[EW Teile] AS [EW Teile],
+	[Sonst.] AS [Sonst.],
+	[TÜV] AS [TÜV],
+	[Fremdl.] AS [Fremdl.],
+	[Mietw.] AS [Mietw.],
+	[Rädereinl.] AS [Rädereinl.],
+	[verk. Std.] AS [verk. Std.],
+	[ben. Std.] AS [ben. Std.],
+	[NL Lohn] AS [NL Lohn],
+	[NL Teile] AS [NL Teile],
+	[NL Sonst.] AS [NL Sonst.],
+	[DG] AS [DG],
+	[NL Sonst %] AS [NL Sonst %],
+	--[Anz. AT] AS [Anz. AT],
+	[Anwesenheit Mech Karo Lack] AS [Anwesenheit Mech Karo Lack],
+	[Anwesenheit Meister] AS [Anwesenheit Meister],
+	[Invoice Date] AS [Invoice Date],
+	[Rechnungsausgang] AS [Rechnungsausgang],
+	[Fabrikat_Order_By] AS [Fabrikat_Order_By],
+	[Serviceberater_Rg_Steller] AS [Serviceberater_Rg_Steller] 
 FROM [export_csv].[Aftersales_Rechnungen_ben_AW_final]
 GO
 
@@ -111,65 +111,65 @@ CREATE
 
 ALTER VIEW [load].[Aftersales_Rechnungen_neu]
 AS
-SELECT [Hauptbetrieb_ID] AS "Hauptbetrieb_ID",
-	[Hauptbetrieb_Name] AS "Hauptbetrieb_Name",
-	[Standort_ID] AS "Standort_ID",
-	[Standort_Name] AS "Standort_Name",
-	[Employee_Function] AS "Employee_Function",
-	[Serviceberater] AS "Serviceberater",
-	[Order Number] AS "Order Number",
-	[Invoice_Desc_100] AS "Invoice_Desc_100",
-	[Fabrikat] AS "Fabrikat",
-	[Fabrikat_Order_By] AS "Fabrikat_Order_By",
-	[Model] AS "Model",
-	[Fahrzeug] AS "Fahrzeug",
-	[Kostenstelle] AS "Kostenstelle",
-	--[Marke] AS "Marke",
-	[Umsatzart] AS "Umsatzart",
-	[Auftragsart] AS "Auftragsart",
-	[Auftragsposition] AS "Auftragsposition",
-	[Kundenart] AS "Kundenart",
-	[Kunde] AS "Kunde",
-	--[Order_Desc_30] AS "Order_Desc_30",
-	[Invoice_Desc_30] AS "Invoice_Desc_30",
-	[Zuordnung_Produktbuchungsgruppe] AS "Zuordnung_Produktbuchungsgruppe",
-	[Produktbuchungsgruppe] AS "Produktbuchungsgruppe",
-	[FZG-Altersstaffel] AS "FZG-Altersstaffel",
-	[Repair_Group_Desc] AS "Repair_Group_Desc",
-	[DB1_><_EK] AS "DB1_><_EK",
-	[Rechnung_Gutschrift] AS "Rechnung_Gutschrift",
-	[Parts_Focus_Group] AS "Parts_Focus_Group",
-	[Parts_Make_Desc] AS "Parts_Make_Desc",
-	[Parts_Group_Desc] AS "Parts_Group_Desc",
-	[PLZ_1_Stelle] AS "PLZ_1_Stelle",
-	[PLZ_2_Stelle] AS "PLZ_2_Stelle",
-	[PLZ_3_Stelle] AS "PLZ_3_Stelle",
-	[PLZ_4_Stelle] AS "PLZ_4_Stelle",
-	[PLZ] AS "PLZ",
-	[Zuordnung_Funktion] AS "Zuordnung_Funktion",
-	[Order_Desc_100] AS "Order_Desc_100",
-	[Lohn] AS "Lohn_Umsatz",
-	[Teile] AS "Teile_Umsatz",
-	[EW Teile] AS "EW Teile",
-	[Sonst.] AS "Sonst.",
-	[TÜV] AS "TÜV",
-	[Fremdl.] AS "Fremdl.",
-	[Mietw.] AS "Mietw.",
-	[Rädereinl.] AS "Rädereinl.",
-	[verk. Std.] AS "verk. Std.",
-	[ben. Std.] AS "ben. Std.",
-	[NL Lohn] AS "NL Lohn",
-	[NL Teile] AS "NL Teile",
-	[NL Sonst.] AS "NL Sonst.",
-	[DG] AS "DG",
-	[NL Sonst %] AS "NL Sonst %",
-	--[Anz. AT] AS "Anz. AT",
-	[Anwesenheit Mech Karo Lack] AS "Anwesenheit Mech Karo Lack",
-	[Anwesenheit Meister] AS "Anwesenheit Meister",
-	[Invoice Date] AS "Invoice Date",
-	[Rechnungsausgang] AS "Rechnungsausgang",
-	[EW Fremdl.] AS "EW Fremdl.",
-	[Serviceberater_Rg_Steller] AS "Serviceberater_Rg_Steller" 
+SELECT [Hauptbetrieb_ID] AS [Hauptbetrieb_ID],
+	[Hauptbetrieb_Name] AS [Hauptbetrieb_Name],
+	[Standort_ID] AS [Standort_ID],
+	[Standort_Name] AS [Standort_Name],
+	[Employee_Function] AS [Employee_Function],
+	[Serviceberater] AS [Serviceberater],
+	[Order Number] AS [Order Number],
+	[Invoice_Desc_100] AS [Invoice_Desc_100],
+	[Fabrikat] AS [Fabrikat],
+	[Fabrikat_Order_By] AS [Fabrikat_Order_By],
+	[Model] AS [Model],
+	[Fahrzeug] AS [Fahrzeug],
+	[Kostenstelle] AS [Kostenstelle],
+	--[Marke] AS [Marke],
+	[Umsatzart] AS [Umsatzart],
+	[Auftragsart] AS [Auftragsart],
+	[Auftragsposition] AS [Auftragsposition],
+	[Kundenart] AS [Kundenart],
+	[Kunde] AS [Kunde],
+	--[Order_Desc_30] AS [Order_Desc_30],
+	[Invoice_Desc_30] AS [Invoice_Desc_30],
+	[Zuordnung_Produktbuchungsgruppe] AS [Zuordnung_Produktbuchungsgruppe],
+	[Produktbuchungsgruppe] AS [Produktbuchungsgruppe],
+	[FZG-Altersstaffel] AS [FZG-Altersstaffel],
+	[Repair_Group_Desc] AS [Repair_Group_Desc],
+	[DB1_><_EK] AS [DB1_><_EK],
+	[Rechnung_Gutschrift] AS [Rechnung_Gutschrift],
+	[Parts_Focus_Group] AS [Parts_Focus_Group],
+	[Parts_Make_Desc] AS [Parts_Make_Desc],
+	[Parts_Group_Desc] AS [Parts_Group_Desc],
+	[PLZ_1_Stelle] AS [PLZ_1_Stelle],
+	[PLZ_2_Stelle] AS [PLZ_2_Stelle],
+	[PLZ_3_Stelle] AS [PLZ_3_Stelle],
+	[PLZ_4_Stelle] AS [PLZ_4_Stelle],
+	[PLZ] AS [PLZ],
+	[Zuordnung_Funktion] AS [Zuordnung_Funktion],
+	[Order_Desc_100] AS [Order_Desc_100],
+	[Lohn] AS [Lohn_Umsatz],
+	[Teile] AS [Teile_Umsatz],
+	[EW Teile] AS [EW Teile],
+	[Sonst.] AS [Sonst.],
+	[TÜV] AS [TÜV],
+	[Fremdl.] AS [Fremdl.],
+	[Mietw.] AS [Mietw.],
+	[Rädereinl.] AS [Rädereinl.],
+	[verk. Std.] AS [verk. Std.],
+	[ben. Std.] AS [ben. Std.],
+	[NL Lohn] AS [NL Lohn],
+	[NL Teile] AS [NL Teile],
+	[NL Sonst.] AS [NL Sonst.],
+	[DG] AS [DG],
+	[NL Sonst %] AS [NL Sonst %],
+	--[Anz. AT] AS [Anz. AT],
+	[Anwesenheit Mech Karo Lack] AS [Anwesenheit Mech Karo Lack],
+	[Anwesenheit Meister] AS [Anwesenheit Meister],
+	[Invoice Date] AS [Invoice Date],
+	[Rechnungsausgang] AS [Rechnungsausgang],
+	[EW Fremdl.] AS [EW Fremdl.],
+	[Serviceberater_Rg_Steller] AS [Serviceberater_Rg_Steller] 
 FROM [export_csv].[Aftersales_Rechnungen_neu]
 GO
 
@@ -178,64 +178,64 @@ CREATE
 
 ALTER VIEW [load].[Aftersales_Rechnungen_verk_AW_final]
 AS
-SELECT [Hauptbetrieb_ID] AS "Hauptbetrieb_ID",
-	[Hauptbetrieb_Name] AS "Hauptbetrieb_Name",
-	[Standort_ID] AS "Standort_ID",
-	[Standort_Name] AS "Standort_Name",
-	[Employee_Function] AS "Employee_Function",
-	[Serviceberater] AS "Serviceberater",
-	[Order Number] AS "Order Number",
-	[Invoice_Desc_100] AS "Invoice_Desc_100",
-	[Fabrikat] AS "Fabrikat",
-	[Model] AS "Model",
-	[Fahrzeug] AS "Fahrzeug",
-	[Kostenstelle] AS "Kostenstelle",
-	--[Marke] AS "Marke",
-	[Umsatzart] AS "Umsatzart",
-	[Auftragsart] AS "Auftragsart",
-	[Auftragsposition] AS "Auftragsposition",
-	[Kundenart] AS "Kundenart",
-	[Kunde] AS "Kunde",
-	--[Order_Desc_30] AS "Order_Desc_30",
-	[Invoice_Desc_30] AS "Invoice_Desc_30",
-	[Zuordnung_Produktbuchungsgruppe] AS "Zuordnung_Produktbuchungsgruppe",
-	[Produktbuchungsgruppe] AS "Produktbuchungsgruppe",
-	[FZG-Altersstaffel] AS "FZG-Altersstaffel",
-	[Repair_Group_Desc] AS "Repair_Group_Desc",
-	[DB1_><_EK] AS "DB1_><_EK",
-	[Rechnung_Gutschrift] AS "Rechnung_Gutschrift",
-	[Parts_Focus_Group] AS "Parts_Focus_Group",
-	[Parts_Make_Desc] AS "Parts_Make_Desc",
-	[Parts_Group_Desc] AS "Parts_Group_Desc",
-	[PLZ_1_Stelle] AS "PLZ_1_Stelle",
-	[PLZ_2_Stelle] AS "PLZ_2_Stelle",
-	[PLZ_3_Stelle] AS "PLZ_3_Stelle",
-	[PLZ_4_Stelle] AS "PLZ_4_Stelle",
-	[PLZ] AS "PLZ",
-	[Zuordnung_Funktion] AS "Zuordnung_Funktion",
-	[Order_Desc_100] AS "Order_Desc_100",
-	[Lohn] AS "Lohn_Umsatz",
-	[Teile] AS "Teile_Umsatz",
-	[EW Teile] AS "EW Teile",
-	[Sonst.] AS "Sonst.",
-	[TÜV] AS "TÜV",
-	[Fremdl.] AS "Fremdl.",
-	[Mietw.] AS "Mietw.",
-	[Rädereinl.] AS "Rädereinl.",
-	[verk. Std.] AS "verk. Std.",
-	[ben. Std.] AS "ben. Std.",
-	[NL Lohn] AS "NL Lohn",
-	[NL Teile] AS "NL Teile",
-	[NL Sonst.] AS "NL Sonst.",
-	[DG] AS "DG",
-	[NL Sonst %] AS "NL Sonst %",
-	--[Anz. AT] AS "Anz. AT",
-	[Anwesenheit Mech Karo Lack] AS "Anwesenheit Mech Karo Lack",
-	[Anwesenheit Meister] AS "Anwesenheit Meister",
-	[Invoice Date] AS "Invoice Date",
-	[Rechnungsausgang] AS "Rechnungsausgang",
-	[Fabrikat_Order_By] AS "Fabrikat_Order_By",
-	[Serviceberater_Rg_Steller] AS "Serviceberater_Rg_Steller" 
+SELECT [Hauptbetrieb_ID] AS [Hauptbetrieb_ID],
+	[Hauptbetrieb_Name] AS [Hauptbetrieb_Name],
+	[Standort_ID] AS [Standort_ID],
+	[Standort_Name] AS [Standort_Name],
+	[Employee_Function] AS [Employee_Function],
+	[Serviceberater] AS [Serviceberater],
+	[Order Number] AS [Order Number],
+	[Invoice_Desc_100] AS [Invoice_Desc_100],
+	[Fabrikat] AS [Fabrikat],
+	[Model] AS [Model],
+	[Fahrzeug] AS [Fahrzeug],
+	[Kostenstelle] AS [Kostenstelle],
+	--[Marke] AS [Marke],
+	[Umsatzart] AS [Umsatzart],
+	[Auftragsart] AS [Auftragsart],
+	[Auftragsposition] AS [Auftragsposition],
+	[Kundenart] AS [Kundenart],
+	[Kunde] AS [Kunde],
+	--[Order_Desc_30] AS [Order_Desc_30],
+	[Invoice_Desc_30] AS [Invoice_Desc_30],
+	[Zuordnung_Produktbuchungsgruppe] AS [Zuordnung_Produktbuchungsgruppe],
+	[Produktbuchungsgruppe] AS [Produktbuchungsgruppe],
+	[FZG-Altersstaffel] AS [FZG-Altersstaffel],
+	[Repair_Group_Desc] AS [Repair_Group_Desc],
+	[DB1_><_EK] AS [DB1_><_EK],
+	[Rechnung_Gutschrift] AS [Rechnung_Gutschrift],
+	[Parts_Focus_Group] AS [Parts_Focus_Group],
+	[Parts_Make_Desc] AS [Parts_Make_Desc],
+	[Parts_Group_Desc] AS [Parts_Group_Desc],
+	[PLZ_1_Stelle] AS [PLZ_1_Stelle],
+	[PLZ_2_Stelle] AS [PLZ_2_Stelle],
+	[PLZ_3_Stelle] AS [PLZ_3_Stelle],
+	[PLZ_4_Stelle] AS [PLZ_4_Stelle],
+	[PLZ] AS [PLZ],
+	[Zuordnung_Funktion] AS [Zuordnung_Funktion],
+	[Order_Desc_100] AS [Order_Desc_100],
+	[Lohn] AS [Lohn_Umsatz],
+	[Teile] AS [Teile_Umsatz],
+	[EW Teile] AS [EW Teile],
+	[Sonst.] AS [Sonst.],
+	[TÜV] AS [TÜV],
+	[Fremdl.] AS [Fremdl.],
+	[Mietw.] AS [Mietw.],
+	[Rädereinl.] AS [Rädereinl.],
+	[verk. Std.] AS [verk. Std.],
+	[ben. Std.] AS [ben. Std.],
+	[NL Lohn] AS [NL Lohn],
+	[NL Teile] AS [NL Teile],
+	[NL Sonst.] AS [NL Sonst.],
+	[DG] AS [DG],
+	[NL Sonst %] AS [NL Sonst %],
+	--[Anz. AT] AS [Anz. AT],
+	[Anwesenheit Mech Karo Lack] AS [Anwesenheit Mech Karo Lack],
+	[Anwesenheit Meister] AS [Anwesenheit Meister],
+	[Invoice Date] AS [Invoice Date],
+	[Rechnungsausgang] AS [Rechnungsausgang],
+	[Fabrikat_Order_By] AS [Fabrikat_Order_By],
+	[Serviceberater_Rg_Steller] AS [Serviceberater_Rg_Steller] 
 FROM [export_csv].[Aftersales_Rechnungen_verk_AW_final]
 GO
 

+ 6 - 9
cognos7/data/mdl/S_Offene_Auftraege.json

@@ -1374,7 +1374,7 @@
           "Label": "M bisher \u00c4nderung",
           "Rollup": "False",
           "TimeAggregate": "None",
-          "Calc": "change \"M bisher gruppiert~Voriger M bisher@13825\" \"M bisher gruppiert~M bisher@13823\""
+          "Calc": "change ( \"M bisher gruppiert~Voriger M bisher@13825\" , \"M bisher gruppiert~M bisher@13823\" )"
         },
         {
           "Type": "SpecialCategory",
@@ -1384,8 +1384,7 @@
           "Label": "M bisher Zuwachs",
           "Rollup": "False",
           "TimeAggregate": "None",
-          "Calc": "growth \"M bisher gruppiert~Voriger M bisher@13825\" \"M bisher gruppiert~M bisher@13823\"",
-          "\"0%~2\"": "Sign"
+          "Calc": "percent-growth ( \"M bisher gruppiert~Voriger M bisher@13825\" , \"M bisher gruppiert~M bisher@13823\" )"
         },
         {
           "Type": "SpecialCategory",
@@ -1513,7 +1512,7 @@
           "Label": "Q bisher \u00c4nderung",
           "Rollup": "False",
           "TimeAggregate": "None",
-          "Calc": "change \"Q bisher gruppiert~Voriges Q bisher@13847\" \"Q bisher gruppiert~Q bisher@13841\""
+          "Calc": "change ( \"Q bisher gruppiert~Voriges Q bisher@13847\" , \"Q bisher gruppiert~Q bisher@13841\" )"
         },
         {
           "Type": "SpecialCategory",
@@ -1523,8 +1522,7 @@
           "Label": "Q bisher Zuwachs",
           "Rollup": "False",
           "TimeAggregate": "None",
-          "Calc": "growth \"Q bisher gruppiert~Voriges Q bisher@13847\" \"Q bisher gruppiert~Q bisher@13841\"",
-          "\"0%~2\"": "Sign"
+          "Calc": "percent-growth ( \"Q bisher gruppiert~Voriges Q bisher@13847\" , \"Q bisher gruppiert~Q bisher@13841\" )"
         },
         {
           "Type": "SpecialCategory",
@@ -2012,7 +2010,7 @@
           "Label": "J bisher \u00c4nderung",
           "Rollup": "False",
           "TimeAggregate": "None",
-          "Calc": "change \"J bisher gruppiert~Voriges J bisher@13931\" \"J bisher gruppiert~J bisher@13905\""
+          "Calc": "change ( \"J bisher gruppiert~Voriges J bisher@13931\" , \"J bisher gruppiert~J bisher@13905\" )"
         },
         {
           "Type": "SpecialCategory",
@@ -2022,8 +2020,7 @@
           "Label": "J bisher Zuwachs",
           "Rollup": "False",
           "TimeAggregate": "None",
-          "Calc": "growth \"J bisher gruppiert~Voriges J bisher@13931\" \"J bisher gruppiert~J bisher@13905\"",
-          "\"0%~2\"": "Sign"
+          "Calc": "percent-growth ( \"J bisher gruppiert~Voriges J bisher@13931\" , \"J bisher gruppiert~J bisher@13905\" )"
         }
       ]
     },

+ 6 - 9
cognos7/data/mdl/S_Offene_Auftraege_ori.json

@@ -1533,7 +1533,7 @@
           "Lastuse": "20180820",
           "Rollup": "False",
           "TimeAggregate": "None",
-          "Calc": "change \"M bisher gruppiert~Voriger M bisher@13825\" \"M bisher gruppiert~M bisher@13823\""
+          "Calc": "change ( \"M bisher gruppiert~Voriger M bisher@13825\" , \"M bisher gruppiert~M bisher@13823\" )"
         },
         {
           "Type": "SpecialCategory",
@@ -1545,8 +1545,7 @@
           "Lastuse": "20180820",
           "Rollup": "False",
           "TimeAggregate": "None",
-          "Calc": "growth \"M bisher gruppiert~Voriger M bisher@13825\" \"M bisher gruppiert~M bisher@13823\"",
-          "\"0%~2\"": "Sign"
+          "Calc": "percent-growth ( \"M bisher gruppiert~Voriger M bisher@13825\" , \"M bisher gruppiert~M bisher@13823\" )"
         },
         {
           "Type": "SpecialCategory",
@@ -1712,7 +1711,7 @@
           "Lastuse": "20180820",
           "Rollup": "False",
           "TimeAggregate": "None",
-          "Calc": "change \"Q bisher gruppiert~Voriges Q bisher@13847\" \"Q bisher gruppiert~Q bisher@13841\""
+          "Calc": "change ( \"Q bisher gruppiert~Voriges Q bisher@13847\" , \"Q bisher gruppiert~Q bisher@13841\" )"
         },
         {
           "Type": "SpecialCategory",
@@ -1724,8 +1723,7 @@
           "Lastuse": "20180820",
           "Rollup": "False",
           "TimeAggregate": "None",
-          "Calc": "growth \"Q bisher gruppiert~Voriges Q bisher@13847\" \"Q bisher gruppiert~Q bisher@13841\"",
-          "\"0%~2\"": "Sign"
+          "Calc": "percent-growth ( \"Q bisher gruppiert~Voriges Q bisher@13847\" , \"Q bisher gruppiert~Q bisher@13841\" )"
         },
         {
           "Type": "SpecialCategory",
@@ -2395,7 +2393,7 @@
           "Lastuse": "20180820",
           "Rollup": "False",
           "TimeAggregate": "None",
-          "Calc": "change \"J bisher gruppiert~Voriges J bisher@13931\" \"J bisher gruppiert~J bisher@13905\""
+          "Calc": "change ( \"J bisher gruppiert~Voriges J bisher@13931\" , \"J bisher gruppiert~J bisher@13905\" )"
         },
         {
           "Type": "SpecialCategory",
@@ -2407,8 +2405,7 @@
           "Lastuse": "20180820",
           "Rollup": "False",
           "TimeAggregate": "None",
-          "Calc": "growth \"J bisher gruppiert~Voriges J bisher@13931\" \"J bisher gruppiert~J bisher@13905\"",
-          "\"0%~2\"": "Sign"
+          "Calc": "percent-growth ( \"J bisher gruppiert~Voriges J bisher@13931\" , \"J bisher gruppiert~J bisher@13905\" )"
         }
       ]
     },

+ 34 - 34
cognos7/data/mdl/S_Offene_Auftraege_queries.sql

@@ -3,19 +3,19 @@ CREATE
 
 ALTER VIEW [load].[current_date_Prognose_operativ]
 AS
-SELECT --[Bundeslaender Id] AS "Bundeslaender Id",
-	[Invoice Date] AS "Order Date",
-	--[Wochentage Id] AS "Wochentage Id",
-	--[Arbeitstag Mofr] AS "Arbeitstag Mofr",
-	--[Zaehler Mofr] AS "Zaehler Mofr",
-	--[Summe Mofr] AS "Summe Mofr",
-	--[Arbeitstag Mosa] AS "Arbeitstag Mosa",
-	--[Zaehler Mosa] AS "Zaehler Mosa",
-	--[Summe Mosa] AS "Summe Mosa",
-	--[Feiertage Id] AS "Feiertage Id",
-	--[Jahr] AS "Jahr",
-	--[Arbeitstag Nr Jahr] AS "Arbeitstag Nr Jahr",
-	--[Gesamt Arbeitstage] AS "Gesamt Arbeitstage" 
+SELECT --[Bundeslaender Id] AS [Bundeslaender Id],
+	[Invoice Date] AS [Order Date],
+	--[Wochentage Id] AS [Wochentage Id],
+	--[Arbeitstag Mofr] AS [Arbeitstag Mofr],
+	--[Zaehler Mofr] AS [Zaehler Mofr],
+	--[Summe Mofr] AS [Summe Mofr],
+	--[Arbeitstag Mosa] AS [Arbeitstag Mosa],
+	--[Zaehler Mosa] AS [Zaehler Mosa],
+	--[Summe Mosa] AS [Summe Mosa],
+	--[Feiertage Id] AS [Feiertage Id],
+	--[Jahr] AS [Jahr],
+	--[Arbeitstag Nr Jahr] AS [Arbeitstag Nr Jahr],
+	--[Gesamt Arbeitstage] AS [Gesamt Arbeitstage] 
 FROM [export_csv].[current_date_Prognose_operativ]
 GO
 
@@ -24,27 +24,27 @@ CREATE
 
 ALTER VIEW [load].[Offene_Auftraege]
 AS
-SELECT [Hauptbetrieb_ID] AS "Hauptbetrieb_ID",
-	[Hauptbetrieb_Name] AS "Hauptbetrieb_Name",
-	[Standort_ID] AS "Standort_ID",
-	[Standort_Name] AS "Standort_Name",
-	[Serviceberater] AS "Serviceberater",
-	[Order Number] AS "Order Number",
-	[Fabrikat] AS "Fabrikat",
-	[Model] AS "Model",
-	[Fahrzeug] AS "Fahrzeug",
-	[Kostenstelle] AS "Kostenstelle",
-	--[Marke] AS "Marke",
-	[Kunde] AS "Kunde",
-	--[Turnover_Type_Desc] AS "Turnover_Type_Desc",
-	[Tage offen] AS "Tage offen",
-	[DG] AS "DG",
-	[Lohn] AS "Lohn",
-	[Teile] AS "Teile",
-	[Sonst.] AS "Sonst.",
-	[Auftragsart] AS "Auftragsart",
-	[Order Date] AS "Order Date",
-	[Tage seit letzt. Stemp.] AS "Tage seit letzt. Stemp." 
+SELECT [Hauptbetrieb_ID] AS [Hauptbetrieb_ID],
+	[Hauptbetrieb_Name] AS [Hauptbetrieb_Name],
+	[Standort_ID] AS [Standort_ID],
+	[Standort_Name] AS [Standort_Name],
+	[Serviceberater] AS [Serviceberater],
+	[Order Number] AS [Order Number],
+	[Fabrikat] AS [Fabrikat],
+	[Model] AS [Model],
+	[Fahrzeug] AS [Fahrzeug],
+	[Kostenstelle] AS [Kostenstelle],
+	--[Marke] AS [Marke],
+	[Kunde] AS [Kunde],
+	--[Turnover_Type_Desc] AS [Turnover_Type_Desc],
+	[Tage offen] AS [Tage offen],
+	[DG] AS [DG],
+	[Lohn] AS [Lohn],
+	[Teile] AS [Teile],
+	[Sonst.] AS [Sonst.],
+	[Auftragsart] AS [Auftragsart],
+	[Order Date] AS [Order Date],
+	[Tage seit letzt. Stemp.] AS [Tage seit letzt. Stemp.] 
 FROM [export_csv].[Offene_Auftraege]
 GO
 

+ 13 - 4
cognos7/mdl_convert.py

@@ -63,11 +63,15 @@ def convert_block(block):
             result[key + "s"].append({"ID": words[i + offset + 1], "Include": words[i + offset + 2]})
             offset += 1
         elif key == "Calc":
+            match = re.search(r"Calc (.*)", block)
+            if match:
+                calc_split = re.split(r"(Sign|Filtered|Format)", match[1])
+                result["Calc"] = calc_split[0].strip()
             for j in range(i + offset + 1, len(words)):
                 if words[j] in ["Sign", "Format", "Filtered"] or j == len(words) - 1:
-                    result["Calc"] = " ".join(words[i + offset + 1 : j])
-                    offset = j - i - 1
-                    break  # for
+                    # result["Calc"] = " ".join(words[i + offset + 1 : j])
+                    offset = j
+                    break
         elif key == "EncryptedPW":
             result["EncryptedPW"] = words[i + offset + 1].strip('"')
             result["Salt"] = words[i + offset + 2].strip('"')
@@ -247,9 +251,14 @@ def extract_column(col):
     name = col["Name"]
     if "]." in name:
         name = name.split("].")[-1]
+    else:
+        name = f"[{name}]"
     alias = col["Column"]
     is_used = "" if len(col["Associations"]) > 0 else "--"
-    return f"{is_used}[{name}] AS [{alias}]"
+    if col.get("Origin") == "Calculated" and "Calc" in col:
+        name = col["Calc"]
+        name = re.sub(r"\"([^\"]+)@\d+\"", r"[\1]", name)
+    return f"{is_used}{name} AS [{alias}]"
 
 
 def convert_file(filename: str) -> None:

+ 1 - 1
config/config.py

@@ -138,7 +138,7 @@ class Config:
             logs_dir=joinpath(self.log_dir, "c11"),
             reportoutput_dir=joinpath(self.portal_dir, "ReportOutput"),
             specs_dir=joinpath(self.portal_dir, "Content", "Reports"),
-            webservice="http://localhost:9300/bi/",
+            webservice=self._cfg.get("C11_URL", "http://localhost:9300/bi/"),
             config_dir=joinpath(self.xml_dir, "c11"),
             folders_file=joinpath(self.xml_dir, "c11", "folders.json"),
             reports_file=joinpath(self.xml_dir, "c11", "reports.json"),

+ 0 - 0
config/config/Aufgaben.py → config/config2/Aufgaben.py


+ 0 - 0
config/config/Gruppen.json → config/config2/Gruppen.json


+ 0 - 0
config/config/Intervalle.json → config/config2/Intervalle.json


+ 0 - 0
config/config/Reports.csv → config/config2/Reports.csv


+ 35 - 16
database/bcp_log.py

@@ -8,11 +8,13 @@ from pathlib import Path
 class BulkcopyResult:
     file_name: str
     timestamp: datetime
-    imported: int = -1
     exported: int = -1
+    imported: int = -1
     ignored: int = 0
-    import_duration: float = 0.0
     export_duration: float = 0.0
+    import_duration: float = 0.0
+    export_errors: str = ""
+    import_errors: str = ""
     file_size: int = -1
 
     @property
@@ -24,7 +26,7 @@ class BulkcopyResult:
             f"{self.file_name};{self.timestamp.strftime('%Y-%m-%dT%H:%M:%S')};"
             + f"{self.exported};{self.imported};{self.ignored};{self.missing};"
             + f"{self.export_duration};{self.import_duration};"
-            + f"{self.file_size}"
+            + f"{self.export_errors};{self.import_errors};{self.file_size}"
         )
 
     def __str__(self) -> str:
@@ -50,22 +52,30 @@ def check_logfiles(prefix: str, base_dir: str) -> BulkcopyResult:
     ts = datetime.fromtimestamp(Path(f"{base_dir}/{prefix}.bcp2.log").stat().st_mtime)
     result = BulkcopyResult(file_name=prefix, timestamp=ts)
 
-    with open(f"{base_dir}/{prefix}.in.log", "r") as frh:
-        result.ignored = len(frh.readlines()) // 2
+    in_log = Path(f"{base_dir}\\{prefix}.in.log")
+    if in_log.exists():
+        with in_log.open("r") as frh:
+            result.ignored = len(frh.readlines()) // 2
 
     # info output of export
-    with open(f"{base_dir}/{prefix}.bcp1.log", "r", encoding="cp850", errors="ignore") as frh:
-        raw_logs = frh.read()
-        result.exported = rows_copied(raw_logs)
-        result.export_duration = total_time(raw_logs)
+    bcp1_log = Path(f"{base_dir}\\{prefix}.bcp1.log")
+    if bcp1_log.exists():
+        with bcp1_log.open("r", encoding="cp850", errors="ignore") as frh:
+            raw_logs = frh.read()
+            result.exported = rows_copied(raw_logs)
+            result.export_duration = total_time(raw_logs)
+            result.export_errors = sql_errors(raw_logs)
 
     # info output of import
-    with open(f"{base_dir}/{prefix}.bcp2.log", "r", encoding="cp850", errors="ignore") as frh:
-        raw_logs = frh.read()
-        result.imported = rows_copied(raw_logs)
-        result.import_duration = total_time(raw_logs)
-
-    csv_file = Path(f"{base_dir}/{prefix}.csv")
+    bcp2_log = Path(f"{base_dir}\\{prefix}.bcp2.log")
+    if bcp2_log.exists():
+        with bcp2_log.open("r", encoding="cp850", errors="ignore") as frh:
+            raw_logs = frh.read()
+            result.imported = rows_copied(raw_logs)
+            result.import_duration = total_time(raw_logs)
+            result.import_errors = sql_errors(raw_logs)
+
+    csv_file = Path(f"{base_dir}\\{prefix}.csv")
     if csv_file.exists():
         result.file_size = csv_file.stat().st_size
     return result
@@ -91,6 +101,13 @@ def total_time(raw_logs: str) -> float:
     return 0.0
 
 
+def sql_errors(raw_logs: str) -> str:
+    match = re.findall(r"SQLState = (\w+),", raw_logs)
+    if match:
+        return ",".join(set(match).difference({"S1000", "22001", "22003", "22005"}))
+    return ""
+
+
 def check_directory(base_dir: str, res: list[BulkcopyResult] | None = None) -> list[BulkcopyResult]:
     if res is None:
         res = []
@@ -107,7 +124,9 @@ def check_directory(base_dir: str, res: list[BulkcopyResult] | None = None) -> l
 
 def export_log_csv(res: list[BulkcopyResult], output_file: str):
     with open(output_file, "w") as fwh:
-        fwh.write("filename;timestamp;imported;exported;ignored;missing;import_duration;export_duration;file_size\n")
+        fwh.write(
+            "filename;timestamp;exported;imported;ignored;missing;export_duration;import_duration;export_errors;import_errors;file_size\n"
+        )
         for log in res:
             fwh.write(log.to_csv() + "\n")
 

+ 37 - 9
database/db_create.py

@@ -1,9 +1,7 @@
 import json
-import sys
 
 import pandas as pd
 
-sys.path.insert(0, "C:\\Projekte\\tools")
 from database.model import DbCreateConfig, DestTable, SourceTable2  # noqa:E402
 
 
@@ -38,10 +36,44 @@ def get_table_config(cfg: DbCreateConfig) -> list[DestTable]:
 def create(config_file: str = "database/CARLO.json"):
     cfg = DbCreateConfig.load_config(config_file)
     cfg.create_db_ini()
+    print("Clients:")
+    print(json.dumps(cfg.clients, indent=2))
+    print("Vorschlaege fuer Clients:")
     print(json.dumps(cfg.source_inspect.get_prefix(), indent=2))
 
     table_config = get_table_config(cfg)
 
+    for dest_table in table_config:
+        with open(f"{cfg.sql_import_full_dir}\\{dest_table.dest}.sql", "w", encoding="latin-1") as f:
+            if dest_table.dest not in cfg.dest_inspect.tables_list:
+                f.write(f"-- Ziel-Tabelle '{dest_table.dest}' existiert nicht!\n")
+                continue
+
+            f.write(f"TRUNCATE TABLE {dest_table.full_table_name}\nGO\n\n")
+
+            for source_table in dest_table.source_tables:
+                if source_table.table_name not in cfg.source_inspect.tables_list:
+                    source_table_str = cfg.source_inspect.convert_table(source_table.table_name)
+                    if source_table_str not in cfg.source_inspect.tables_list:
+                        f.write(f"-- Quell-Tabelle '{source_table.table_name}' existiert nicht!\n")
+                        continue
+
+                select_query = source_table.select_query_with_columns.replace(
+                    "[dbo]", f"[{cfg.source_inspect.dsn.server}].[{cfg.source_inspect.dsn.database}].[dbo]"
+                ).replace(",", "\n" + " " * 5 + ",")
+                for tag in ["SELECT", "FROM", "INNER", "LEFT", "WHERE", "ORDER BY"]:
+                    select_query = select_query.replace(tag, "\n" + tag)
+                for tag in ["AND", "ON"]:
+                    select_query = select_query.replace(tag, "\n      " + tag)
+                f.write(source_table.info.replace("rem ", "-- "))
+                if select_query == "":
+                    f.write(f"-- Ziel-Tabelle '{dest_table.dest}' Spalte 'Client_DB' fehlt!\n")
+                    continue
+
+                f.write(
+                    f"INSERT INTO [{cfg.dest_dsn.schema}].[{dest_table.dest}]\nWITH (TABLOCK)\n{select_query}\nGO\n"
+                )
+
     for dest_table in table_config:
         with open(dest_table.table_batch_file, "w", encoding="cp850") as f:
             f.write("@echo off\n")
@@ -60,8 +92,8 @@ def create(config_file: str = "database/CARLO.json"):
 
             for source_table in dest_table.source_tables:
                 if source_table.table_name not in cfg.source_inspect.tables_list:
-                    source_table2 = cfg.source_inspect.convert_table(source_table.table_name)
-                    if source_table2 not in cfg.source_inspect.tables_list:
+                    source_table_str = cfg.source_inspect.convert_table(source_table.table_name)
+                    if source_table_str not in cfg.source_inspect.tables_list:
                         f.write(f"echo Quell-Tabelle '{source_table.table_name}' existiert nicht!\n")
                         print(f"Quell-Tabelle '{source_table.table_name}' existiert nicht!")
                         continue
@@ -83,7 +115,7 @@ def create(config_file: str = "database/CARLO.json"):
 
             f.write(f'  call sql_query.bat "TRUNCATE TABLE {dest_table.temp_table_name}"\n\n')
             for source_table in dest_table.source_tables:
-                select_query = source_table.select_query_with_columns
+                select_query = source_table.select_query_with_columns.replace("%", "%%%%")  # batch-Problem
                 convert_timestamp = "T1.[timestamp] > convert(binary(8), '%TS%', 1)"
                 if "WHERE" in select_query:
                     select_query = select_query.replace("WHERE", f"WHERE {convert_timestamp} AND")
@@ -124,7 +156,3 @@ def create(config_file: str = "database/CARLO.json"):
             f.write(f"echo =={dest_table.dest}==\n")
             f.write(f"echo {dest_table.dest} >CON\n")
             f.write(f"call {cfg.batch_dir}\\{dest_table.dest}.bat\n\n")
-
-
-if __name__ == "__main__":
-    create()

+ 70 - 4
database/db_schema.py

@@ -1,6 +1,7 @@
-import pyodbc
 import json
 
+import pyodbc
+
 
 def connect():
     c = pyodbc.connect("DSN=Autoline_direkt64;UID=kcc;PWD=kcc123")
@@ -26,6 +27,73 @@ def convert_desc(col):
     return ", ".join(list(map(str, col)))
 
 
+def convert_desc_sql_anywhere(col):
+    nullable = "NULL" if col.nullable == 1 else "NOT NULL"
+
+    if col.type_name in (
+        "char",
+        "varchar",
+        "long varchar",
+        "long nvarchar",
+        "nvarchar",
+    ):
+        sizes = [20, 50, 100, 255]
+        length = "MAX"
+        for s in sizes:
+            if col.length < s:
+                length = s
+                break
+        return f"   [{col.column_name}] [varchar]({length}) {nullable}"
+
+    if col.type_name in (
+        "binary",
+        "long binary",
+        "varbinary",
+    ):
+        return f"   [{col.column_name}] [binary]({col.length}) {nullable}"
+
+    if col.type_name in (
+        "bit",
+        "tinyint",
+    ):
+        return f"   [{col.column_name}] [tinyint] {nullable}"
+
+    if col.type_name in (
+        "integer",
+        "smallint",
+        "unsigned smallint",
+        "unsigned int",
+    ):
+        return f"   [{col.column_name}] [int] {nullable}"
+
+    if col.type_name in (
+        "bigint",
+        "unsigned bigint",
+        "long varbit",
+    ):
+        return f"   [{col.column_name}] [bigint] {nullable}"
+
+    if col.type_name in (
+        "date",
+        "timestamp",
+        "timestamp with time zone",
+    ):
+        return f"   [{col.column_name}] [datetime] {nullable}"
+
+    if col.type_name in (
+        "decimal",
+        "float",
+        "double",
+        "numeric",
+    ):
+        return f"   [{col.column_name}] [decimal](28,8) {nullable}"
+
+    if col.type_name in ("time"):
+        return f"   [{col.column_name}] [time] {nullable}"
+
+    return ", ".join(list(map(str, col)))
+
+
 def convert_desc2(col):
     return ", ".join(list(map(str, col)))
 
@@ -62,9 +130,7 @@ def pkeys():
             if res.get(t) is None:
                 res[t] = []
             res[t].append(
-                f"   CONSTRAINT [{t}$0] PRIMARY KEY CLUSTERED (["
-                + "], [".join([c.column_name for c in cols])
-                + "])"
+                f"   CONSTRAINT [{t}$0] PRIMARY KEY CLUSTERED ([" + "], [".join([c.column_name for c in cols]) + "])"
             )
             crsr.cancel()
         except pyodbc.Error as e:

+ 6 - 5
database/db_to_parquet.py

@@ -1,15 +1,16 @@
-from database import conn_string
-import pandas as pd
-import numpy as np
 import fastparquet
-from sqlalchemy import create_engine, inspect, schema, Table
+import numpy as np
+import pandas as pd
+from sqlalchemy import Table, create_engine, inspect, schema
+
+from database import conn_string
 
 # Copied from pandas with modifications
 
 
 def __get_dtype(column, sqltype):
     import sqlalchemy.dialects as sqld
-    from sqlalchemy.types import Integer, Float, Boolean, DateTime, Date, TIMESTAMP
+    from sqlalchemy.types import TIMESTAMP, Boolean, Date, DateTime, Float, Integer
 
     if isinstance(sqltype, Float):
         return float

+ 94 - 53
database/model.py

@@ -1,6 +1,7 @@
 import io
 import json
 import os
+from collections import Counter
 from dataclasses import dataclass, field
 from functools import cached_property
 from pathlib import Path
@@ -29,55 +30,67 @@ class DsnConfig:
             ]
         )
 
-
-class DatabaseInspect:
-    _cursor: pyodbc.Cursor = None
-    _sqlalchemy_engine: Engine = None
-
-    def __init__(self, dsn: DsnConfig, source=False):
-        self.dsn = dsn
-        self.type = "SOURCE" if source else "DEST"
-
     @property
-    def conn_string(self) -> str:
-        if self.dsn.driver == "mssql":
+    def conn_string_pyodbc(self) -> str:
+        if self.driver == "mssql":
             return ";".join(
                 [
                     "Driver={SQL Server Native Client 11.0}",
-                    f"Server={self.dsn.server}",
-                    f"Database={self.dsn.database}",
-                    f"Uid={self.dsn.user}",
-                    f"Pwd={self.dsn.password}",
+                    f"Server={self.server}",
+                    f"Database={self.database}",
+                    f"Uid={self.user}",
+                    f"Pwd={self.password}",
                 ]
             )
-        if self.dsn.driver == "mysql":
-            return f"mysql+pymysql://{self.dsn.user}:{self.dsn.password}@{self.dsn.server}/{self.dsn.database}?charset=utf8mb4"
+        if self.driver == "mysql":
+            return f"mysql+pymysql://{self.user}:{self.password}@{self.server}/{self.database}?charset=utf8mb4"
         return ";".join(
             [
                 "Driver={PostgreSQL Unicode}",
-                f"Server={self.dsn.server}",
+                f"Server={self.server}",
                 "Port=5432",
-                f"Database={self.dsn.database}",
-                f"Uid={self.dsn.user}",
-                f"Pwd={self.dsn.password}",
+                f"Database={self.database}",
+                f"Uid={self.user}",
+                f"Pwd={self.password}",
             ]
         )
-        # f"DSN={self.dsn.server};UID={self.dsn.user};PWD={self.dsn.password}"
+        # f"DSN={self.server};UID={self.user};PWD={self.password}"
 
     @property
     def conn_string_sqlalchemy(self) -> str:
-        if self.dsn.driver == "mssql":
+        if self.driver == "mssql":
             return (
-                f"mssql+pyodbc://{self.dsn.user}:{self.dsn.password}@{self.dsn.server}/{self.dsn.database}?"
+                f"mssql+pyodbc://{self.user}:{self.password}@{self.server}/{self.database}?"
                 "driver=SQL+Server+Native+Client+11.0"
             )
-        if self.dsn.driver == "mysql":
-            return f"mysql+pymysql://{self.dsn.user}:{self.dsn.password}@{self.dsn.server}/{self.dsn.database}?charset=utf8mb4"
-        return f"pyodbc://{self.dsn.user}:{self.dsn.password}@{self.dsn.server}/{self.dsn.database}?driver={self.dsn.driver}"
+        if self.driver == "mysql":
+            return f"mysql+pymysql://{self.user}:{self.password}@{self.server}/{self.database}?charset=utf8mb4"
+        return f"pyodbc://{self.user}:{self.password}@{self.server}/{self.database}?driver={self.driver}"
 
     @property
     def bcp_conn_params(self) -> str:
-        return f"-S {self.dsn.server} -d {self.dsn.database} -U {self.dsn.user} -P {self.dsn.password}"
+        return f"-S {self.server} -d {self.database} -U {self.user} -P {self.password}"
+
+
+class DatabaseInspect:
+    _cursor: pyodbc.Cursor = None
+    _sqlalchemy_engine: Engine = None
+
+    def __init__(self, dsn: DsnConfig, source=False):
+        self.dsn = dsn
+        self.type = "SOURCE" if source else "DEST"
+
+    @property
+    def conn_string(self) -> str:
+        return self.dsn.conn_string_pyodbc
+
+    @property
+    def conn_string_sqlalchemy(self) -> str:
+        return self.dsn.conn_string_sqlalchemy
+
+    @property
+    def bcp_conn_params(self) -> str:
+        return self.dsn.bcp_conn_params
 
     @property
     def cursor(self) -> pyodbc.Cursor:
@@ -102,12 +115,26 @@ class DatabaseInspect:
         return tables + views
 
     def get_prefix(self) -> dict[str, str]:
-        source_tables_prefix = dict(
-            enumerate(sorted(list(set([t.split("$")[0] for t in self.tables_list if "$" in t]))), 1)
-        )
-        if len(source_tables_prefix) == 0:
-            q = self.cursor.execute("select name FROM sys.databases")
-            source_tables_prefix = [x[0] for x in q.fetchall()]
+        prefix_count = Counter([t.split("$")[0] for t in self.tables_list if "$" in t])
+        source_tables_prefix = {}
+        for i, p in enumerate(prefix_count.most_common(), 1):
+            if p[1] > 10 and len(p[0]) > 0:
+                source_tables_prefix[str(i)] = p[0]
+
+        if len(source_tables_prefix) > 0:
+            return source_tables_prefix
+
+        q = self.cursor.execute("select name FROM sys.databases")
+        databases = list(sorted([x[0] for x in q.fetchall()]))
+        if "deop00" in databases:
+            # Special case for OPTIMA
+            databases.remove("deop00")
+            for i, p in enumerate(databases, 1):
+                if p.startswith("deop"):
+                    source_tables_prefix[str(i)] = p
+            for i, p in enumerate(databases, len(source_tables_prefix.keys()) + 1):
+                if p.startswith("de") and p not in source_tables_prefix.values():
+                    source_tables_prefix[str(i)] = p
         return source_tables_prefix
 
     def get_columns(self, table: str) -> list[str]:
@@ -166,6 +193,8 @@ class DbCreateConfig:
     stage_dir: str = "..\\temp"
     batch_dir: str = "..\\batch"
     logs_dir: str = "..\\logs"
+    sql_import_full_dir: str = "..\\exec\\import_full"
+    sql_import_inc_dir: str = "..\\exec\\import_inc"
     scripts_dir: str = "C:\\GlobalCube\\Tasks\\scripts"
 
     source_inspect: DatabaseInspect = None
@@ -206,8 +235,19 @@ class DbCreateConfig:
         if "target_dsn" in cfg_import:
             cfg_import["dest_dsn"] = cfg_import["target_dsn"]
             del cfg_import["target_dsn"]
-
-        for folder in ["stage_dir", "batch_dir", "logs_dir", "scripts_dir"]:
+        if "sql_import_full_dir" not in cfg_import:
+            cfg_import["sql_import_full_dir"] = "..\\exec\\import_full"
+        if "sql_import_inc_dir" not in cfg_import:
+            cfg_import["sql_import_inc_dir"] = "..\\exec\\import_inc"
+
+        for folder in [
+            "stage_dir",
+            "batch_dir",
+            "logs_dir",
+            "scripts_dir",
+            "sql_import_full_dir",
+            "sql_import_inc_dir",
+        ]:
             if cfg_import[folder].startswith(".."):
                 cfg_import[folder] = str(base_dir.joinpath(cfg_import[folder]).resolve())
             os.makedirs(cfg_import[folder], exist_ok=True)
@@ -321,7 +361,22 @@ class SourceTable2(SourceTable):
 
     _select_query: str = None
     source_inspect: DatabaseInspect = None
-    info: str = ""
+
+    @cached_property
+    def info(self) -> str:
+        f = io.StringIO()
+        # print("Auf beiden Seiten: " + ";".join(intersect))
+        diff1 = self.source_columns.difference(self.dest_table.columns_list)
+        if len(diff1) > 0:
+            f.write("rem Nur in Quelle: " + ";".join(diff1) + "\n")
+        diff2 = set(self.dest_table.columns_list).difference(self.source_columns)
+        if "Client_DB" not in diff2:
+            f.write("echo Spalte 'Client_DB' fehlt!\n")
+            return
+        diff2.remove("Client_DB")
+        if len(diff2) > 0:
+            f.write("rem Nur in Ziel:   " + ";".join(diff2) + "\n")
+        return f.getvalue()
 
     @property
     def table_client(self) -> str:
@@ -341,19 +396,6 @@ class SourceTable2(SourceTable):
 
     @cached_property
     def select_query(self):
-        f = io.StringIO()
-        # print("Auf beiden Seiten: " + ";".join(intersect))
-        diff1 = self.source_columns.difference(self.dest_table.columns_list)
-        if len(diff1) > 0:
-            f.write("rem Nur in Quelle: " + ";".join(diff1) + "\n")
-        diff2 = set(self.dest_table.columns_list).difference(self.source_columns)
-        if "Client_DB" not in diff2:
-            f.write("echo Spalte 'Client_DB' fehlt!\n")
-            return
-        diff2.remove("Client_DB")
-        if len(diff2) > 0:
-            f.write("rem Nur in Ziel:   " + ";".join(diff2) + "\n")
-
         if not pd.isnull(self.dest_table.query):
             select_query = self.dest_table.query.format(self.prefix, self.cfg.filter[0], self.cfg.filter[1])
         elif "." in self.table_name or self.cfg.source_dsn.schema == "":
@@ -370,14 +412,13 @@ class SourceTable2(SourceTable):
 
         if "timestamp" not in self.source_columns:
             print(self.dest_table.dest + " hat kein timestamp-Feld")
-        self.info = f.getvalue()
         return select_query
 
     @property
     def select_query_with_columns(self) -> str:
         res = self.select_query.replace("T1.*", self.select_columns)
-        if "timestamp" in self.source_columns:
-            res += " ORDER BY T1.[timestamp] "
+        # if "timestamp" in self.source_columns:
+        #     res += " ORDER BY T1.[timestamp] "
         return res
 
     @property

+ 15 - 1
db.py

@@ -23,8 +23,20 @@ def compare(config_file: str):
 
 @app.command()
 def run(config_file: str, increment: str = "1", max: int = 5):
+    """
+    Executes a database operation using a specified configuration file.
+
+    Args:
+        config_file (str): The name of the configuration file (without extension) to use, located in the SQL config directory.
+        increment (str, optional): Determines whether to increment; treated as True if "1", otherwise False. Defaults to "1".
+        max (int, optional): The maximum number of operations to perform. Defaults to 5.
+
+    Returns:
+        None
+    """
     config_file = cfg.system_dir + f"\\SQL\\config\\{config_file}.json"
     database.run(config_file, increment == "1", max)
+    bcp_log()
 
 
 @app.command()
@@ -50,7 +62,9 @@ def schema():
 
 @app.command()
 def bcp_log():
-    logs_dir = cfg.system_dir + "\\SQL\\temp"
+    logs_dir = cfg.system_dir + "\\SQL\\logs"
+    if not Path(logs_dir).exists():
+        logs_dir = cfg.system_dir + "\\SQL\\temp"
     output_file = cfg.log_dir + "\\bcp.csv.log"
     database.bcp_log(logs_dir, output_file)
 

二進制
dist/gctools.exe


+ 1 - 1
gctools.bat

@@ -1,5 +1,5 @@
 cd /d %~dp0
-call venv\Scripts\activate.bat
+call .venv\Scripts\activate.bat
 pyinstaller -F --path %~dp0 --icon favicon.ico gctools.py
 copy /Y %~dp0\dist\gctools.exe P:\GCTools
 pause

+ 4 - 2
gctools.py

@@ -4,12 +4,13 @@ import backup
 import c7
 import c11
 import db
+import ldap
 import misc2
 import status
 import xls
 
-version = "1.0"
-version_date = "25.02.2025"
+version = "1.1.2"
+version_date = "28.10.2025"
 
 app = typer.Typer(
     help=(
@@ -26,6 +27,7 @@ app.add_typer(db.app, name="db")
 app.add_typer(misc2.app, name="misc")
 app.add_typer(xls.app, name="excel")
 app.add_typer(status.app, name="status")
+app.add_typer(ldap.app, name="ldap")
 
 
 if __name__ == "__main__":

+ 1 - 1
gctools.spec

@@ -3,7 +3,7 @@
 
 a = Analysis(
     ['gctools.py'],
-    pathex=['C:\\Projekte\\tools\\'],
+    pathex=['C:\\Projekte\\gctools\\'],
     binaries=[],
     datas=[],
     hiddenimports=[],

+ 30 - 0
ldap.py

@@ -0,0 +1,30 @@
+import typer
+
+import config
+from misc import apache_ldap
+
+app = typer.Typer()
+cfg = config.Config()
+
+
+@app.command()
+def backup():
+    cred = cfg.cognos11.credentials
+    apache_ldap.ldap_backup(cred.username, cred.password, f"{cfg.cognos11.config_dir}\\apacheds_backup.ldif")
+
+
+@app.command()
+def restore(backup_file: str):
+    cred = cfg.cognos11.credentials
+    apache_ldap.restore_ldap(cred.username, cred.password, backup_file)
+
+
+@app.command()
+def admin_password(old_password: str, new_password: str) -> bool:
+    return apache_ldap.ldap_change_admin_password(old_password, new_password)
+
+
+@app.command()
+def create_user(new_username: str, new_password: str) -> bool:
+    cred = cfg.cognos11.credentials
+    return apache_ldap.ldap_create_user(cred.username, cred.password, new_username, new_password, "")

+ 31 - 0
misc/apache_ldap.py

@@ -71,6 +71,37 @@ def ldap_restore(username: str, password: str, backup_file: str):
     conn.unbind()
 
 
+def ldap_create_user(admin_username: str, admin_password: str, new_username: str, new_password: str, email: str):
+    conn = ldap_connect(admin_username, admin_password)
+    if not conn:
+        return False
+
+    user_dn = f"uid={new_username},{LDAP_BASE_DN}"
+    ssha_password = create_ssha_password(new_password)
+    attributes = {
+        "objectClass": ["top", "person", "organizationalPerson", "inetOrgPerson"],
+        "sn": new_username,
+        "cn": new_username,
+        "uid": new_username,
+        "userPassword": ssha_password,
+        "mail": email,
+    }
+
+    if conn.search(user_dn, "(objectClass=*)", search_scope=ldap3.BASE):
+        print(f"Benutzer {new_username} existiert bereits.")
+        conn.unbind()
+        return False
+
+    if not conn.add(user_dn, attributes=attributes):
+        print(f"Fehler beim Erstellen des Benutzers {new_username}: {conn.result}")
+        conn.unbind()
+        return False
+
+    print(f"Benutzer {new_username} erfolgreich erstellt.")
+    conn.unbind()
+    return True
+
+
 def ldap_change_admin_password(old_password: str, new_password: str):
     admin_user = "uid=admin,ou=system"
     conn = ldap_connect(admin_user, old_password)

+ 2 - 1
misc/csv_cleanup.py

@@ -78,7 +78,7 @@ def cleanup_line(line):
     res = []
     buffer = ""
 
-    line_iter = iter(line.strip("\r\n").split(";"))
+    line_iter = iter(line.strip("\r\n").replace("\r", "").split(";"))
 
     for col in line_iter:
         if '"' not in col:
@@ -89,6 +89,7 @@ def cleanup_line(line):
         buffer = col
         while buffer == '"' or buffer[-1] != '"':
             buffer += next(line_iter)
+        buffer = '"' + buffer.replace('"', "") + '"'
         res.append(buffer)
 
     return ";".join(res) + "\n"

+ 31 - 0
misc/csv_trim.py

@@ -0,0 +1,31 @@
+import os
+import re
+from datetime import datetime
+from pathlib import Path
+
+MAX_AGE = datetime.now().timestamp() - 12 * 60 * 60
+
+
+def csv_trim(dirname: str = "misc/data"):
+    if Path(dirname).is_file():
+        csv_trim_file(Path(dirname), True)
+    else:
+        for csv_file in Path(dirname).glob("*.csv"):
+            csv_trim_file(csv_file)
+
+
+def csv_trim_file(csv_file: Path, ignore_age: bool = False):
+    temp_file = Path(str(csv_file) + ".tmp")
+    file_mtime = csv_file.stat().st_mtime
+    if not ignore_age and file_mtime < MAX_AGE:
+        return
+    print(csv_file.name)
+    with open(csv_file, "r", encoding="latin-1", errors="ignore") as frh:
+        with open(temp_file, "w", encoding="latin-1") as fwh:
+            for line in frh.readlines():
+                fwh.write(re.sub(r"[ ]+\t", "\t", line))
+
+    os.utime(temp_file, (file_mtime, file_mtime))
+
+    csv_file.unlink()
+    temp_file.rename(csv_file)

+ 11 - 1
misc/file_move.py

@@ -2,7 +2,7 @@ import os
 from datetime import datetime
 from pathlib import Path
 
-blacklist = ["_\\", "_ori", "_.csv", "Kopie", "copy", "_sich"]
+blacklist = ["_\\", "_ori", "_.csv", "Kopie", "copy", "_sich", "Plan"]
 
 
 def move(system_dir: str):
@@ -17,6 +17,9 @@ def move(system_dir: str):
         if source.name in ignore_list:
             continue
 
+        if ignore_any_parent_folder(source, ignore_list):
+            continue
+
         full_file = str(source)
         blacklisted = [pattern in full_file for pattern in blacklist]
         if any(blacklisted):
@@ -52,6 +55,13 @@ def move(system_dir: str):
     return no_files
 
 
+def ignore_any_parent_folder(source: Path, ignore_list: list[str]):
+    for p in source.parents:
+        if p.name + "\\" in ignore_list:
+            return True
+    return False
+
+
 def check(system_dir: str):
     max_age_ts = datetime.now().timestamp() - 24 * 60 * 60
     ignore_file = Path(f"{system_dir}\\Export\\ignoriert.txt")

+ 11 - 1
misc2.py

@@ -6,6 +6,7 @@ import config
 from misc import apache_ldap
 from misc.convert_mail_csv import convert_folder_to_combined_csv
 from misc.csv_cleanup import csv_cleanup
+from misc.csv_trim import csv_trim
 from misc.datev_status import print_all_mdb_files
 from misc.headers import create_headerfiles
 
@@ -39,8 +40,10 @@ def ldap_password(old_password: str, new_password: str) -> bool:
 def ldap_admin():
     if ldap_password("gc01gapsC$", ""):
         print("Passwort ist bereits aktuell.")
-    for p in ["Cognos#11Cognos#11", "mEn$q3b%P9p1j!A-ku", "Never4getpw#!!##"]:
+        return
+    for p in ["Cognos#11Cognos#11", "mEn$q3b%P9p1j!A-ku", "Never4getpw#!!##", "Cognos#11"]:
         if ldap_password(p, "gc01gapsC$"):
+            print("Passwort erfolgreich geaendert.")
             break
 
 
@@ -51,6 +54,13 @@ def csv_check(path: str = ""):
     csv_cleanup(path)
 
 
+@app.command()
+def bcp_csv_trim(path: str = ""):
+    if path == "":
+        path = f"{cfg.system_dir}\\SQL\\temp"
+    csv_trim(path)
+
+
 @app.command()
 def combine_csv(path: str = ""):
     if path == "":

+ 14 - 8
pdf/pdf_test.py

@@ -1,10 +1,12 @@
+import json
 import os
-import pdfplumber
-from pdfminer.pdfparser import PDFSyntaxError
 import re
-import json
-from pathlib import Path
 from datetime import datetime, timedelta
+from pathlib import Path
+
+import pdfplumber
+from pdfminer.pdfparser import PDFSyntaxError
+from pdfplumber.utils.exceptions import PdfminerException
 
 
 def current_date_test(base_dir: str):
@@ -37,10 +39,14 @@ def current_date_test(base_dir: str):
 
 def missing_data(base_dir: str):
     for f in Path(base_dir).iterdir():
-        if f.is_dir() and f.name not in [".", "..", "leer"]:
+        if f.is_dir() and f.name not in [".", "..", "leer", "_leer"]:
             missing_data(str(f))
     print(base_dir)
-    os.makedirs(base_dir + "/leer", exist_ok=True)
+    try:
+        Path(base_dir + "/leer").unlink(missing_ok=True)
+    except Exception:
+        pass
+    os.makedirs(base_dir + "/_leer", exist_ok=True)
 
     errors = []
     for f in Path(base_dir).glob("*.pdf"):
@@ -48,7 +54,7 @@ def missing_data(base_dir: str):
             with pdfplumber.open(str(f)) as pdf:
                 pages = len(pdf.pages)
                 text = pdf.pages[0].extract_text()
-        except PDFSyntaxError:
+        except (PDFSyntaxError, PdfminerException):
             pages = 0
             text = ""
 
@@ -61,7 +67,7 @@ def missing_data(base_dir: str):
             ]
         ):
             errors.append(f.name)
-            target = Path(base_dir + "/leer/" + f.name)
+            target = Path(base_dir + "/_leer/" + f.name)
             target.unlink(missing_ok=True)
             f.rename(target)
 

+ 1 - 0
pyproject.toml

@@ -6,6 +6,7 @@ readme = "README.md"
 requires-python = ">=3.13"
 dependencies = [
     "beautifulsoup4>=4.13.3",
+    "black>=25.1.0",
     "crontab>=1.0.1",
     "flask>=2.2.0",
     "jinja2>=3.1.5",

+ 4 - 6
status_client/db_info.py

@@ -1,11 +1,11 @@
 import pyodbc
 
+from database.model import DsnConfig
 
-class DatabaseInfo:
-    conn: pyodbc.Connection
 
+class DatabaseInfo:
     def __init__(self):
-        self._conn = pyodbc.connect("DSN=GC;UID=sa;PWD=Mffu3011#")
+        self._conn = pyodbc.connect(DsnConfig().conn_string_pyodbc)
 
     def databases(self):
         res = self._conn.execute(
@@ -19,8 +19,6 @@ class DatabaseInfo:
             """
             SELECT db_name() as DatabaseName, s.name AS SchemaName, t.name AS TableName, p.rows AS RowCounts,
                 SUM(a.total_pages) * 8 AS TotalSpaceKB,
-                SUM(a.used_pages) * 8 AS UsedSpaceKB,
-                (SUM(a.total_pages) - SUM(a.used_pages)) * 8 AS UnusedSpaceKB,
                 u.last_user_update AS LastChanged
             FROM sys.tables AS t
             INNER JOIN sys.indexes AS i ON t.object_id = i.object_id
@@ -29,7 +27,7 @@ class DatabaseInfo:
             LEFT OUTER JOIN sys.schemas AS s ON t.schema_id = s.schema_id
             LEFT OUTER JOIN sys.dm_db_index_usage_stats AS u ON t.object_id = u.object_id
             WHERE (t.name NOT LIKE 'dt%') AND (t.is_ms_shipped = 0) AND (i.object_id > 255)
-            GROUP BY s.name, t.name, p.rows
+            GROUP BY s.name, t.name, p.rows, u.last_user_update
             ORDER BY 1, 2, 3"""
         )
         return res.fetchall()

+ 5 - 4
status_client/ftp_client.py

@@ -1,8 +1,9 @@
+import warnings
+from dataclasses import dataclass
+from pathlib import Path
+
 import plac
 import pysftp
-from pathlib import Path
-from dataclasses import dataclass
-import warnings
 
 
 @dataclass
@@ -21,7 +22,7 @@ class FtpClient:
         # cfg = json.load(open(self.base_dir.joinpath('ftp_config.json'), 'r'))
         # self.ftp_cfg = FtpConfig(**cfg)
         # self.ftp_cfg = FtpConfig("ftp.global-cube.com", "p33781016-vm", "Gcbs12ma-vm2020!!", "/")
-        self.ftp_cfg = FtpConfig("ftp.global-cube.com", "u1339416173", "dihob#ratuy5kub%", "/")
+        self.ftp_cfg = FtpConfig("ftp1.global-cube.com", "u1339416173", "dihob#ratuy5kub%", "/")
         warnings.filterwarnings("ignore")
 
     @plac.pos("filename", "", type=str)

+ 4 - 3
status_client/path_info.py

@@ -1,8 +1,9 @@
-from datetime import datetime
 import os
 import zipfile
-from pathlib import Path
+from datetime import datetime
 from os import path
+from pathlib import Path
+
 import psutil
 
 
@@ -59,7 +60,7 @@ class PathInfo:
         file_info = [
             str(filename),
             str(st.st_size),
-            datetime.fromtimestamp(st.st_ctime).isoformat(timespec="seconds"),
+            datetime.fromtimestamp(st.st_birthtime).isoformat(timespec="seconds"),
             datetime.fromtimestamp(st.st_mtime).isoformat(timespec="seconds"),
             readable,
             writable,

+ 4 - 4
status_client/process_monitor.py

@@ -1,9 +1,9 @@
-import psutil
-from datetime import datetime
-import pandas as pd
-import time
 import os
+import time
+from datetime import datetime
 
+import pandas as pd
+import psutil
 
 sort_by = "memory_usage"
 columns = [

+ 37 - 15
status_client/status_client.py

@@ -1,5 +1,6 @@
 import csv
 import os
+import re
 import subprocess
 import zipfile
 from datetime import datetime
@@ -17,12 +18,27 @@ def run_command(cmd, logfile):
         p.wait()
 
 
-def task_scheduler(logfile):
-    run_command('schtasks /query /v /fo CSV | find ".bat"', logfile)
+def task_scheduler(logfile, portal_dir):
+    run_command("schtasks /query /v /fo CSV", logfile)
+    logfile_filter = lambda line: portal_dir.lower() in line.lower()  # noqa: E731
+    filter_logfile(logfile, logfile_filter)
+
+
+def filter_logfile(logfile, logfile_filter):
+    logfile_temp = logfile + ".temp"
+    Path(logfile_temp).unlink(missing_ok=True)
+    Path(logfile).rename(logfile_temp)
+    with open(logfile_temp, "r", encoding="cp850") as frh:
+        with open(logfile, "w", encoding="latin-1", newline="") as fwh:
+            fwh.write(frh.readline())  # header
+            fwh.writelines(line for line in frh.readlines() if logfile_filter(line))
+    # os.remove(logfile_temp)
 
 
 def task_manager(logfile):
     run_command("tasklist /fo CSV", logfile)
+    logfile_filter = lambda line: not re.search(r"chrome|msedge|svchost|conhost", line, re.IGNORECASE)  # noqa: E731
+    filter_logfile(logfile, logfile_filter)
 
 
 def shared_files(logfile):
@@ -54,14 +70,12 @@ def database_info(cfg: config.Config, csv_file):
         wr = csv.writer(fwh, delimiter=";")
         wr.writerow(
             [
-                "DatabaseName",
-                "SchemaName",
-                "TableName",
-                "RowCounts",
-                "TotalSpaceKB",
-                "UsedSpaceKB",
-                "UnusedSpaceKB",
-                "LastChanged",
+                "database_name",
+                "schema_name",
+                "table_name",
+                "row_count",
+                "total_space_kb",
+                "last_changed",
             ]
         )
         for row in result:
@@ -70,12 +84,19 @@ def database_info(cfg: config.Config, csv_file):
 
 
 def zip_to_file(base_dir, zip_file):
-    filter = ["config/*", "config/info/*", "config/models/*", "logs/*", "*.ini", "*.bat"]
+    filter = [
+        "Tasks/config/*",
+        "Tasks/config/info/*",
+        "Tasks/config/models/*",
+        "Tasks/logs/*",
+        "Tasks/*.ini",
+        "Tasks/*.bat",
+    ]
 
     with zipfile.ZipFile(zip_file, "w", compression=zipfile.ZIP_DEFLATED, compresslevel=9) as zip:
         for f in filter:
             for e in Path(base_dir).glob(f):
-                if ".zip" not in e.name:
+                if e.is_file() and ".zip" not in e.name:
                     zip.write(e, e.relative_to(base_dir))
 
 
@@ -83,11 +104,11 @@ def system_check():
     cfg = config.Config()
 
     # Aufgabenplanung aktueller Stand
-    task_scheduler(cfg.log_dir + "\\schtasks.csv.log")
+    task_scheduler(cfg.log_dir + "\\schtasks.csv.log", cfg.portal_dir)
     # Laufende Prozesse
     task_manager(cfg.log_dir + "\\tasklist.csv.log")
     # aktuelle Freigabe-Sessions
-    shared_files(cfg.log_dir + "\\openfiles.csv.log")
+    # shared_files(cfg.log_dir + "\\openfiles.csv.log")
     # Tabellengrößen
     database_info(cfg, cfg.log_dir + "\\db_info.csv.log")
 
@@ -101,7 +122,8 @@ def system_check():
     # Logdateien aus Tasks/logs und System/prot
     timestamp = datetime.now().strftime("%Y-%m-%d_%H%M%S")
     zip_file = f"{cfg.tasks_dir}\\logs\\zip\\{cfg.kunde_safe}_{timestamp}.zip"
-    zip_to_file(cfg.tasks_dir, zip_file)
+    os.makedirs(Path(zip_file).parent, exist_ok=True)
+    zip_to_file(cfg.portal_dir, zip_file)
 
     # Upload auf FTP
     FtpClient().upload(zip_file)

+ 15 - 0
tests/test_c11_api.py

@@ -0,0 +1,15 @@
+import unittest
+
+from cognos11.c11_api import convert_filename
+
+
+class TestC11Api(unittest.TestCase):
+
+    def test_convert_filename(self):
+        unicode_chars = "360\u2013 Rundum"
+        simple_float = "1,20;2,322;3,434\n"
+        simple_string = '"Test";"Default";"Simple Test"\n'
+
+        self.assertEqual(convert_filename(unicode_chars), "360 Rundum")
+        self.assertEqual(convert_filename(simple_float), simple_float)
+        self.assertEqual(convert_filename(simple_string), "Test;Default;Simple Test\n")

File diff suppressed because it is too large
+ 7 - 0
tests/test_csv_cleanup.py


+ 112 - 0
tests/test_mdl_convert.py

@@ -0,0 +1,112 @@
+import unittest
+
+from cognos7.mdl_convert import convert_block
+
+org_name_1 = """OrgName 11201687 "Monat_Belege" Origin Calculated Offset 0 Column "Monat_Belege" 
+Storage Default Scale 0 Size 1 Decimals 0 Class Quantity InputScale 0 TimeArray Off 
+ColSrcType None Calc month ( "Bookkeep Date@9238295" )  
+"""
+
+org_name_2 = """
+OrgName 10440931 "Konto" Origin Calculated Offset 62 Column "Konto" Storage Default 
+Scale 0 Size 1 Decimals 0 Class Description InputScale 0 TimeArray Off 
+ColSrcType None Calc "Acct Nr@10440811" + ' - ' + "Konto Bezeichnung@10440813"  
+"""
+
+
+special_cat_1 = """SpecialCategory 11637 "M bisher gruppiert~ÄNDERUNG ( ""Voriger M bisher"" , ""M bisher"" )" 
+Parent 299 Levels 0 Label "M bisher Änderung" Lastuse 20210106 Rollup False 
+TimeAggregate None Calc change ( "M bisher gruppiert~Voriger M bisher@11635" , "M bisher gruppiert~M bisher@11633" )  Sign False 
+"""
+
+special_cat_2 = """SpecialCategory 11655 "Q bisher gruppiert~PROZENTZUWACHS ( ""Voriges Q bisher"" , ""Q bisher"" )" 
+Parent 305 Levels 0 Label "Q bisher Zuwachs" Lastuse 20210106 Rollup False 
+TimeAggregate None Calc percent-growth ( "Q bisher gruppiert~Voriges Q bisher@11649" , "Q bisher gruppiert~Q bisher@11645" )  Format "0%~2" 
+Sign False 
+"""
+
+
+class TestMdlConvert(unittest.TestCase):
+
+    def test_convert_block_org_name(self):
+        self.assertEqual(
+            convert_block(org_name_1),
+            {
+                "Associations": [],
+                "Calc": 'month ( "Bookkeep Date@9238295" )',
+                "Class": "Quantity",
+                "ColSrcType": "None",
+                "Column": "Monat_Belege",
+                "Decimals": "0",
+                "ID": "11201687",
+                "InputScale": "0",
+                "Name": "Monat_Belege",
+                "Offset": "0",
+                "Origin": "Calculated",
+                "Scale": "0",
+                "Size": "1",
+                "Storage": "Default",
+                "TimeArray": "Off",
+                "Type": "OrgName",
+            },
+        )
+        self.assertEqual(
+            convert_block(org_name_2),
+            {
+                "Associations": [],
+                "Calc": '"Acct Nr@10440811" + \' - \' + "Konto Bezeichnung@10440813"',
+                "Class": "Description",
+                "ColSrcType": "None",
+                "Column": "Konto",
+                "Decimals": "0",
+                "ID": "10440931",
+                "InputScale": "0",
+                "Name": "Konto",
+                "Offset": "62",
+                "Origin": "Calculated",
+                "Scale": "0",
+                "Size": "1",
+                "Storage": "Default",
+                "TimeArray": "Off",
+                "Type": "OrgName",
+            },
+        )
+
+    def test_convert_block_special_category(self):
+        self.maxDiff = None
+        self.assertEqual(
+            convert_block(special_cat_1),
+            {
+                "Calc": 'change ( "M bisher gruppiert~Voriger M bisher@11635" , "M bisher gruppiert~M bisher@11633" )',
+                "ID": "11637",
+                "Label": "M bisher Änderung",
+                "Lastuse": "20210106",
+                "Levels": "0",
+                "M": " )",
+                "Name": "M",
+                "Parent": "299",
+                "Rollup": "False",
+                "TimeAggregate": "None",
+                "Type": "SpecialCategory",
+                "Voriger": "M",
+                "bisher": "ÄNDERUNG",
+            },
+        )
+        self.assertEqual(
+            convert_block(special_cat_2),
+            {
+                "Calc": 'percent-growth ( "Q bisher gruppiert~Voriges Q bisher@11649" , "Q bisher gruppiert~Q bisher@11645" )',
+                "ID": "11655",
+                "Label": "Q bisher Zuwachs",
+                "Lastuse": "20210106",
+                "Levels": "0",
+                "Name": "Q",
+                "Parent": "305",
+                "Q": " )",
+                "Rollup": "False",
+                "TimeAggregate": "None",
+                "Type": "SpecialCategory",
+                "Voriges": "Q",
+                "bisher": "PROZENTZUWACHS",
+            },
+        )

+ 287 - 252
uv.lock

@@ -98,15 +98,35 @@ wheels = [
 
 [[package]]
 name = "beautifulsoup4"
-version = "4.13.3"
+version = "4.13.4"
 source = { registry = "https://pypi.org/simple" }
 dependencies = [
     { name = "soupsieve" },
     { name = "typing-extensions" },
 ]
-sdist = { url = "https://files.pythonhosted.org/packages/f0/3c/adaf39ce1fb4afdd21b611e3d530b183bb7759c9b673d60db0e347fd4439/beautifulsoup4-4.13.3.tar.gz", hash = "sha256:1bd32405dacc920b42b83ba01644747ed77456a65760e285fbc47633ceddaf8b", size = 619516 }
+sdist = { url = "https://files.pythonhosted.org/packages/d8/e4/0c4c39e18fd76d6a628d4dd8da40543d136ce2d1752bd6eeeab0791f4d6b/beautifulsoup4-4.13.4.tar.gz", hash = "sha256:dbb3c4e1ceae6aefebdaf2423247260cd062430a410e38c66f2baa50a8437195", size = 621067 }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/f9/49/6abb616eb3cbab6a7cca303dc02fdf3836de2e0b834bf966a7f5271a34d8/beautifulsoup4-4.13.3-py3-none-any.whl", hash = "sha256:99045d7d3f08f91f0d656bc9b7efbae189426cd913d830294a15eefa0ea4df16", size = 186015 },
+    { url = "https://files.pythonhosted.org/packages/50/cd/30110dc0ffcf3b131156077b90e9f60ed75711223f306da4db08eff8403b/beautifulsoup4-4.13.4-py3-none-any.whl", hash = "sha256:9bbbb14bfde9d79f38b8cd5f8c7c85f4b8f2523190ebed90e950a8dea4cb1c4b", size = 187285 },
+]
+
+[[package]]
+name = "black"
+version = "25.1.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+    { name = "click" },
+    { name = "mypy-extensions" },
+    { name = "packaging" },
+    { name = "pathspec" },
+    { name = "platformdirs" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/94/49/26a7b0f3f35da4b5a65f081943b7bcd22d7002f5f0fb8098ec1ff21cb6ef/black-25.1.0.tar.gz", hash = "sha256:33496d5cd1222ad73391352b4ae8da15253c5de89b93a80b3e2c8d9a19ec2666", size = 649449 }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/98/87/0edf98916640efa5d0696e1abb0a8357b52e69e82322628f25bf14d263d1/black-25.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8f0b18a02996a836cc9c9c78e5babec10930862827b1b724ddfe98ccf2f2fe4f", size = 1650673 },
+    { url = "https://files.pythonhosted.org/packages/52/e5/f7bf17207cf87fa6e9b676576749c6b6ed0d70f179a3d812c997870291c3/black-25.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:afebb7098bfbc70037a053b91ae8437c3857482d3a690fefc03e9ff7aa9a5fd3", size = 1453190 },
+    { url = "https://files.pythonhosted.org/packages/e3/ee/adda3d46d4a9120772fae6de454c8495603c37c4c3b9c60f25b1ab6401fe/black-25.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:030b9759066a4ee5e5aca28c3c77f9c64789cdd4de8ac1df642c40b708be6171", size = 1782926 },
+    { url = "https://files.pythonhosted.org/packages/cc/64/94eb5f45dcb997d2082f097a3944cfc7fe87e071907f677e80788a2d7b7a/black-25.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:a22f402b410566e2d1c950708c77ebf5ebd5d0d88a6a2e87c86d9fb48afa0d18", size = 1442613 },
+    { url = "https://files.pythonhosted.org/packages/09/71/54e999902aed72baf26bca0d50781b01838251a462612966e9fc4891eadd/black-25.1.0-py3-none-any.whl", hash = "sha256:95e8176dae143ba9097f351d174fdaf0ccd29efb414b362ae3fd72bf0f710717", size = 207646 },
 ]
 
 [[package]]
@@ -120,11 +140,11 @@ wheels = [
 
 [[package]]
 name = "certifi"
-version = "2025.1.31"
+version = "2025.4.26"
 source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/1c/ab/c9f1e32b7b1bf505bf26f0ef697775960db7932abeb7b516de930ba2705f/certifi-2025.1.31.tar.gz", hash = "sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651", size = 167577 }
+sdist = { url = "https://files.pythonhosted.org/packages/e8/9e/c05b3920a3b7d20d3d3310465f50348e5b3694f4f88c6daf736eef3024c4/certifi-2025.4.26.tar.gz", hash = "sha256:0a816057ea3cdefcef70270d2c515e4506bbc954f417fa5ade2021213bb8f0c6", size = 160705 }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/38/fc/bce832fd4fd99766c04d1ee0eead6b0ec6486fb100ae5e74c1d91292b982/certifi-2025.1.31-py3-none-any.whl", hash = "sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe", size = 166393 },
+    { url = "https://files.pythonhosted.org/packages/4a/7e/3db2bd1b1f9e95f7cddca6d6e75e2f2bd9f51b1246e546d88addca0106bd/certifi-2025.4.26-py3-none-any.whl", hash = "sha256:30350364dfe371162649852c63336a15c70c6510c2ad5015b21c2345311805f3", size = 159618 },
 ]
 
 [[package]]
@@ -151,24 +171,24 @@ wheels = [
 
 [[package]]
 name = "charset-normalizer"
-version = "3.4.1"
+version = "3.4.2"
 source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/16/b0/572805e227f01586461c80e0fd25d65a2115599cc9dad142fee4b747c357/charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3", size = 123188 }
+sdist = { url = "https://files.pythonhosted.org/packages/e4/33/89c2ced2b67d1c2a61c19c6751aa8902d46ce3dacb23600a283619f5a12d/charset_normalizer-3.4.2.tar.gz", hash = "sha256:5baececa9ecba31eff645232d59845c07aa030f0c81ee70184a90d35099a0e63", size = 126367 }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/38/94/ce8e6f63d18049672c76d07d119304e1e2d7c6098f0841b51c666e9f44a0/charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda", size = 195698 },
-    { url = "https://files.pythonhosted.org/packages/24/2e/dfdd9770664aae179a96561cc6952ff08f9a8cd09a908f259a9dfa063568/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313", size = 140162 },
-    { url = "https://files.pythonhosted.org/packages/24/4e/f646b9093cff8fc86f2d60af2de4dc17c759de9d554f130b140ea4738ca6/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9", size = 150263 },
-    { url = "https://files.pythonhosted.org/packages/5e/67/2937f8d548c3ef6e2f9aab0f6e21001056f692d43282b165e7c56023e6dd/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b", size = 142966 },
-    { url = "https://files.pythonhosted.org/packages/52/ed/b7f4f07de100bdb95c1756d3a4d17b90c1a3c53715c1a476f8738058e0fa/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11", size = 144992 },
-    { url = "https://files.pythonhosted.org/packages/96/2c/d49710a6dbcd3776265f4c923bb73ebe83933dfbaa841c5da850fe0fd20b/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f", size = 147162 },
-    { url = "https://files.pythonhosted.org/packages/b4/41/35ff1f9a6bd380303dea55e44c4933b4cc3c4850988927d4082ada230273/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd", size = 140972 },
-    { url = "https://files.pythonhosted.org/packages/fb/43/c6a0b685fe6910d08ba971f62cd9c3e862a85770395ba5d9cad4fede33ab/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2", size = 149095 },
-    { url = "https://files.pythonhosted.org/packages/4c/ff/a9a504662452e2d2878512115638966e75633519ec11f25fca3d2049a94a/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886", size = 152668 },
-    { url = "https://files.pythonhosted.org/packages/6c/71/189996b6d9a4b932564701628af5cee6716733e9165af1d5e1b285c530ed/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601", size = 150073 },
-    { url = "https://files.pythonhosted.org/packages/e4/93/946a86ce20790e11312c87c75ba68d5f6ad2208cfb52b2d6a2c32840d922/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd", size = 145732 },
-    { url = "https://files.pythonhosted.org/packages/cd/e5/131d2fb1b0dddafc37be4f3a2fa79aa4c037368be9423061dccadfd90091/charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407", size = 95391 },
-    { url = "https://files.pythonhosted.org/packages/27/f2/4f9a69cc7712b9b5ad8fdb87039fd89abba997ad5cbe690d1835d40405b0/charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971", size = 102702 },
-    { url = "https://files.pythonhosted.org/packages/0e/f6/65ecc6878a89bb1c23a086ea335ad4bf21a588990c3f535a227b9eea9108/charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85", size = 49767 },
+    { url = "https://files.pythonhosted.org/packages/ea/12/a93df3366ed32db1d907d7593a94f1fe6293903e3e92967bebd6950ed12c/charset_normalizer-3.4.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:926ca93accd5d36ccdabd803392ddc3e03e6d4cd1cf17deff3b989ab8e9dbcf0", size = 199622 },
+    { url = "https://files.pythonhosted.org/packages/04/93/bf204e6f344c39d9937d3c13c8cd5bbfc266472e51fc8c07cb7f64fcd2de/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eba9904b0f38a143592d9fc0e19e2df0fa2e41c3c3745554761c5f6447eedabf", size = 143435 },
+    { url = "https://files.pythonhosted.org/packages/22/2a/ea8a2095b0bafa6c5b5a55ffdc2f924455233ee7b91c69b7edfcc9e02284/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3fddb7e2c84ac87ac3a947cb4e66d143ca5863ef48e4a5ecb83bd48619e4634e", size = 153653 },
+    { url = "https://files.pythonhosted.org/packages/b6/57/1b090ff183d13cef485dfbe272e2fe57622a76694061353c59da52c9a659/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98f862da73774290f251b9df8d11161b6cf25b599a66baf087c1ffe340e9bfd1", size = 146231 },
+    { url = "https://files.pythonhosted.org/packages/e2/28/ffc026b26f441fc67bd21ab7f03b313ab3fe46714a14b516f931abe1a2d8/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c9379d65defcab82d07b2a9dfbfc2e95bc8fe0ebb1b176a3190230a3ef0e07c", size = 148243 },
+    { url = "https://files.pythonhosted.org/packages/c0/0f/9abe9bd191629c33e69e47c6ef45ef99773320e9ad8e9cb08b8ab4a8d4cb/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e635b87f01ebc977342e2697d05b56632f5f879a4f15955dfe8cef2448b51691", size = 150442 },
+    { url = "https://files.pythonhosted.org/packages/67/7c/a123bbcedca91d5916c056407f89a7f5e8fdfce12ba825d7d6b9954a1a3c/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1c95a1e2902a8b722868587c0e1184ad5c55631de5afc0eb96bc4b0d738092c0", size = 145147 },
+    { url = "https://files.pythonhosted.org/packages/ec/fe/1ac556fa4899d967b83e9893788e86b6af4d83e4726511eaaad035e36595/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ef8de666d6179b009dce7bcb2ad4c4a779f113f12caf8dc77f0162c29d20490b", size = 153057 },
+    { url = "https://files.pythonhosted.org/packages/2b/ff/acfc0b0a70b19e3e54febdd5301a98b72fa07635e56f24f60502e954c461/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:32fc0341d72e0f73f80acb0a2c94216bd704f4f0bce10aedea38f30502b271ff", size = 156454 },
+    { url = "https://files.pythonhosted.org/packages/92/08/95b458ce9c740d0645feb0e96cea1f5ec946ea9c580a94adfe0b617f3573/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:289200a18fa698949d2b39c671c2cc7a24d44096784e76614899a7ccf2574b7b", size = 154174 },
+    { url = "https://files.pythonhosted.org/packages/78/be/8392efc43487ac051eee6c36d5fbd63032d78f7728cb37aebcc98191f1ff/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4a476b06fbcf359ad25d34a057b7219281286ae2477cc5ff5e3f70a246971148", size = 149166 },
+    { url = "https://files.pythonhosted.org/packages/44/96/392abd49b094d30b91d9fbda6a69519e95802250b777841cf3bda8fe136c/charset_normalizer-3.4.2-cp313-cp313-win32.whl", hash = "sha256:aaeeb6a479c7667fbe1099af9617c83aaca22182d6cf8c53966491a0f1b7ffb7", size = 98064 },
+    { url = "https://files.pythonhosted.org/packages/e9/b0/0200da600134e001d91851ddc797809e2fe0ea72de90e09bec5a2fbdaccb/charset_normalizer-3.4.2-cp313-cp313-win_amd64.whl", hash = "sha256:aa6af9e7d59f9c12b33ae4e9450619cf2488e2bbe9b44030905877f0b2324980", size = 105641 },
+    { url = "https://files.pythonhosted.org/packages/20/94/c5790835a017658cbfabd07f3bfb549140c3ac458cfc196323996b10095a/charset_normalizer-3.4.2-py3-none-any.whl", hash = "sha256:7f56930ab0abd1c45cd15be65cc741c28b1c9a34876ce8c17a2fa107810c0af0", size = 52626 },
 ]
 
 [[package]]
@@ -194,43 +214,43 @@ wheels = [
 
 [[package]]
 name = "crontab"
-version = "1.0.1"
+version = "1.0.4"
 source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/ae/13/696cac391e97fa47ec7323936838a540a610894a1d516a6b0cefbb1e495b/crontab-1.0.1.tar.gz", hash = "sha256:89477e3f93c81365e738d5ee2659509e6373bb2846de13922663e79aa74c6b91", size = 19616 }
+sdist = { url = "https://files.pythonhosted.org/packages/1e/8b/3ea72ac8e26090b63779b4e0074af79b02bbbab7ddd01b36109bc0892d31/crontab-1.0.4.tar.gz", hash = "sha256:715b0e5e105bc62c9683cbb93c1cc5821e07a3e28d17404576d22dba7a896c92", size = 21677 }
 
 [[package]]
 name = "cryptography"
-version = "44.0.2"
+version = "45.0.2"
 source = { registry = "https://pypi.org/simple" }
 dependencies = [
     { name = "cffi", marker = "platform_python_implementation != 'PyPy'" },
 ]
-sdist = { url = "https://files.pythonhosted.org/packages/cd/25/4ce80c78963834b8a9fd1cc1266be5ed8d1840785c0f2e1b73b8d128d505/cryptography-44.0.2.tar.gz", hash = "sha256:c63454aa261a0cf0c5b4718349629793e9e634993538db841165b3df74f37ec0", size = 710807 }
-wheels = [
-    { url = "https://files.pythonhosted.org/packages/92/ef/83e632cfa801b221570c5f58c0369db6fa6cef7d9ff859feab1aae1a8a0f/cryptography-44.0.2-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:efcfe97d1b3c79e486554efddeb8f6f53a4cdd4cf6086642784fa31fc384e1d7", size = 6676361 },
-    { url = "https://files.pythonhosted.org/packages/30/ec/7ea7c1e4c8fc8329506b46c6c4a52e2f20318425d48e0fe597977c71dbce/cryptography-44.0.2-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29ecec49f3ba3f3849362854b7253a9f59799e3763b0c9d0826259a88efa02f1", size = 3952350 },
-    { url = "https://files.pythonhosted.org/packages/27/61/72e3afdb3c5ac510330feba4fc1faa0fe62e070592d6ad00c40bb69165e5/cryptography-44.0.2-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc821e161ae88bfe8088d11bb39caf2916562e0a2dc7b6d56714a48b784ef0bb", size = 4166572 },
-    { url = "https://files.pythonhosted.org/packages/26/e4/ba680f0b35ed4a07d87f9e98f3ebccb05091f3bf6b5a478b943253b3bbd5/cryptography-44.0.2-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:3c00b6b757b32ce0f62c574b78b939afab9eecaf597c4d624caca4f9e71e7843", size = 3958124 },
-    { url = "https://files.pythonhosted.org/packages/9c/e8/44ae3e68c8b6d1cbc59040288056df2ad7f7f03bbcaca6b503c737ab8e73/cryptography-44.0.2-cp37-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7bdcd82189759aba3816d1f729ce42ffded1ac304c151d0a8e89b9996ab863d5", size = 3678122 },
-    { url = "https://files.pythonhosted.org/packages/27/7b/664ea5e0d1eab511a10e480baf1c5d3e681c7d91718f60e149cec09edf01/cryptography-44.0.2-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:4973da6ca3db4405c54cd0b26d328be54c7747e89e284fcff166132eb7bccc9c", size = 4191831 },
-    { url = "https://files.pythonhosted.org/packages/2a/07/79554a9c40eb11345e1861f46f845fa71c9e25bf66d132e123d9feb8e7f9/cryptography-44.0.2-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:4e389622b6927d8133f314949a9812972711a111d577a5d1f4bee5e58736b80a", size = 3960583 },
-    { url = "https://files.pythonhosted.org/packages/bb/6d/858e356a49a4f0b591bd6789d821427de18432212e137290b6d8a817e9bf/cryptography-44.0.2-cp37-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:f514ef4cd14bb6fb484b4a60203e912cfcb64f2ab139e88c2274511514bf7308", size = 4191753 },
-    { url = "https://files.pythonhosted.org/packages/b2/80/62df41ba4916067fa6b125aa8c14d7e9181773f0d5d0bd4dcef580d8b7c6/cryptography-44.0.2-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:1bc312dfb7a6e5d66082c87c34c8a62176e684b6fe3d90fcfe1568de675e6688", size = 4079550 },
-    { url = "https://files.pythonhosted.org/packages/f3/cd/2558cc08f7b1bb40683f99ff4327f8dcfc7de3affc669e9065e14824511b/cryptography-44.0.2-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:3b721b8b4d948b218c88cb8c45a01793483821e709afe5f622861fc6182b20a7", size = 4298367 },
-    { url = "https://files.pythonhosted.org/packages/71/59/94ccc74788945bc3bd4cf355d19867e8057ff5fdbcac781b1ff95b700fb1/cryptography-44.0.2-cp37-abi3-win32.whl", hash = "sha256:51e4de3af4ec3899d6d178a8c005226491c27c4ba84101bfb59c901e10ca9f79", size = 2772843 },
-    { url = "https://files.pythonhosted.org/packages/ca/2c/0d0bbaf61ba05acb32f0841853cfa33ebb7a9ab3d9ed8bb004bd39f2da6a/cryptography-44.0.2-cp37-abi3-win_amd64.whl", hash = "sha256:c505d61b6176aaf982c5717ce04e87da5abc9a36a5b39ac03905c4aafe8de7aa", size = 3209057 },
-    { url = "https://files.pythonhosted.org/packages/9e/be/7a26142e6d0f7683d8a382dd963745e65db895a79a280a30525ec92be890/cryptography-44.0.2-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:8e0ddd63e6bf1161800592c71ac794d3fb8001f2caebe0966e77c5234fa9efc3", size = 6677789 },
-    { url = "https://files.pythonhosted.org/packages/06/88/638865be7198a84a7713950b1db7343391c6066a20e614f8fa286eb178ed/cryptography-44.0.2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81276f0ea79a208d961c433a947029e1a15948966658cf6710bbabb60fcc2639", size = 3951919 },
-    { url = "https://files.pythonhosted.org/packages/d7/fc/99fe639bcdf58561dfad1faa8a7369d1dc13f20acd78371bb97a01613585/cryptography-44.0.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a1e657c0f4ea2a23304ee3f964db058c9e9e635cc7019c4aa21c330755ef6fd", size = 4167812 },
-    { url = "https://files.pythonhosted.org/packages/53/7b/aafe60210ec93d5d7f552592a28192e51d3c6b6be449e7fd0a91399b5d07/cryptography-44.0.2-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:6210c05941994290f3f7f175a4a57dbbb2afd9273657614c506d5976db061181", size = 3958571 },
-    { url = "https://files.pythonhosted.org/packages/16/32/051f7ce79ad5a6ef5e26a92b37f172ee2d6e1cce09931646eef8de1e9827/cryptography-44.0.2-cp39-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d1c3572526997b36f245a96a2b1713bf79ce99b271bbcf084beb6b9b075f29ea", size = 3679832 },
-    { url = "https://files.pythonhosted.org/packages/78/2b/999b2a1e1ba2206f2d3bca267d68f350beb2b048a41ea827e08ce7260098/cryptography-44.0.2-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:b042d2a275c8cee83a4b7ae30c45a15e6a4baa65a179a0ec2d78ebb90e4f6699", size = 4193719 },
-    { url = "https://files.pythonhosted.org/packages/72/97/430e56e39a1356e8e8f10f723211a0e256e11895ef1a135f30d7d40f2540/cryptography-44.0.2-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:d03806036b4f89e3b13b6218fefea8d5312e450935b1a2d55f0524e2ed7c59d9", size = 3960852 },
-    { url = "https://files.pythonhosted.org/packages/89/33/c1cf182c152e1d262cac56850939530c05ca6c8d149aa0dcee490b417e99/cryptography-44.0.2-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:c7362add18b416b69d58c910caa217f980c5ef39b23a38a0880dfd87bdf8cd23", size = 4193906 },
-    { url = "https://files.pythonhosted.org/packages/e1/99/87cf26d4f125380dc674233971069bc28d19b07f7755b29861570e513650/cryptography-44.0.2-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:8cadc6e3b5a1f144a039ea08a0bdb03a2a92e19c46be3285123d32029f40a922", size = 4081572 },
-    { url = "https://files.pythonhosted.org/packages/b3/9f/6a3e0391957cc0c5f84aef9fbdd763035f2b52e998a53f99345e3ac69312/cryptography-44.0.2-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:6f101b1f780f7fc613d040ca4bdf835c6ef3b00e9bd7125a4255ec574c7916e4", size = 4298631 },
-    { url = "https://files.pythonhosted.org/packages/e2/a5/5bc097adb4b6d22a24dea53c51f37e480aaec3465285c253098642696423/cryptography-44.0.2-cp39-abi3-win32.whl", hash = "sha256:3dc62975e31617badc19a906481deacdeb80b4bb454394b4098e3f2525a488c5", size = 2773792 },
-    { url = "https://files.pythonhosted.org/packages/33/cf/1f7649b8b9a3543e042d3f348e398a061923ac05b507f3f4d95f11938aa9/cryptography-44.0.2-cp39-abi3-win_amd64.whl", hash = "sha256:5f6f90b72d8ccadb9c6e311c775c8305381db88374c65fa1a68250aa8a9cb3a6", size = 3210957 },
+sdist = { url = "https://files.pythonhosted.org/packages/f6/47/92a8914716f2405f33f1814b97353e3cfa223cd94a77104075d42de3099e/cryptography-45.0.2.tar.gz", hash = "sha256:d784d57b958ffd07e9e226d17272f9af0c41572557604ca7554214def32c26bf", size = 743865 }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/3d/2f/46b9e715157643ad16f039ec3c3c47d174da6f825bf5034b1c5f692ab9e2/cryptography-45.0.2-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:61a8b1bbddd9332917485b2453d1de49f142e6334ce1d97b7916d5a85d179c84", size = 7043448 },
+    { url = "https://files.pythonhosted.org/packages/90/52/49e6c86278e1b5ec226e96b62322538ccc466306517bf9aad8854116a088/cryptography-45.0.2-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4cc31c66411e14dd70e2f384a9204a859dc25b05e1f303df0f5326691061b839", size = 4201098 },
+    { url = "https://files.pythonhosted.org/packages/7b/3a/201272539ac5b66b4cb1af89021e423fc0bfacb73498950280c51695fb78/cryptography-45.0.2-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:463096533acd5097f8751115bc600b0b64620c4aafcac10c6d0041e6e68f88fe", size = 4429839 },
+    { url = "https://files.pythonhosted.org/packages/99/89/fa1a84832b8f8f3917875cb15324bba98def5a70175a889df7d21a45dc75/cryptography-45.0.2-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:cdafb86eb673c3211accffbffdb3cdffa3aaafacd14819e0898d23696d18e4d3", size = 4205154 },
+    { url = "https://files.pythonhosted.org/packages/1c/c5/5225d5230d538ab461725711cf5220560a813d1eb68bafcfb00131b8f631/cryptography-45.0.2-cp311-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:05c2385b1f5c89a17df19900cfb1345115a77168f5ed44bdf6fd3de1ce5cc65b", size = 3897145 },
+    { url = "https://files.pythonhosted.org/packages/fe/24/f19aae32526cc55ae17d473bc4588b1234af2979483d99cbfc57e55ffea6/cryptography-45.0.2-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:e9e4bdcd70216b08801e267c0b563316b787f957a46e215249921f99288456f9", size = 4462192 },
+    { url = "https://files.pythonhosted.org/packages/19/18/4a69ac95b0b3f03355970baa6c3f9502bbfc54e7df81fdb179654a00f48e/cryptography-45.0.2-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:b2de529027579e43b6dc1f805f467b102fb7d13c1e54c334f1403ee2b37d0059", size = 4208093 },
+    { url = "https://files.pythonhosted.org/packages/7c/54/2dea55ccc9558b8fa14f67156250b6ee231e31765601524e4757d0b5db6b/cryptography-45.0.2-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:10d68763892a7b19c22508ab57799c4423c7c8cd61d7eee4c5a6a55a46511949", size = 4461819 },
+    { url = "https://files.pythonhosted.org/packages/37/f1/1b220fcd5ef4b1f0ff3e59e733b61597505e47f945606cc877adab2c1a17/cryptography-45.0.2-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:d2a90ce2f0f5b695e4785ac07c19a58244092f3c85d57db6d8eb1a2b26d2aad6", size = 4329202 },
+    { url = "https://files.pythonhosted.org/packages/6d/e0/51d1dc4f96f819a56db70f0b4039b4185055bbb8616135884c3c3acc4c6d/cryptography-45.0.2-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:59c0c8f043dd376bbd9d4f636223836aed50431af4c5a467ed9bf61520294627", size = 4570412 },
+    { url = "https://files.pythonhosted.org/packages/dc/44/88efb40a3600d15277a77cdc69eeeab45a98532078d2a36cffd9325d3b3f/cryptography-45.0.2-cp311-abi3-win32.whl", hash = "sha256:80303ee6a02ef38c4253160446cbeb5c400c07e01d4ddbd4ff722a89b736d95a", size = 2933584 },
+    { url = "https://files.pythonhosted.org/packages/d9/a1/bc9f82ba08760442cc8346d1b4e7b769b86d197193c45b42b3595d231e84/cryptography-45.0.2-cp311-abi3-win_amd64.whl", hash = "sha256:7429936146063bd1b2cfc54f0e04016b90ee9b1c908a7bed0800049cbace70eb", size = 3408537 },
+    { url = "https://files.pythonhosted.org/packages/59/bc/1b6acb1dca366f9c0b3880888ecd7fcfb68023930d57df854847c6da1d10/cryptography-45.0.2-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:e86c8d54cd19a13e9081898b3c24351683fd39d726ecf8e774aaa9d8d96f5f3a", size = 7025581 },
+    { url = "https://files.pythonhosted.org/packages/31/a3/a3e4a298d3db4a04085728f5ae6c8cda157e49c5bb784886d463b9fbff70/cryptography-45.0.2-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e328357b6bbf79928363dbf13f4635b7aac0306afb7e5ad24d21d0c5761c3253", size = 4189148 },
+    { url = "https://files.pythonhosted.org/packages/53/90/100dfadd4663b389cb56972541ec1103490a19ebad0132af284114ba0868/cryptography-45.0.2-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49af56491473231159c98c2c26f1a8f3799a60e5cf0e872d00745b858ddac9d2", size = 4424113 },
+    { url = "https://files.pythonhosted.org/packages/0d/40/e2b9177dbed6f3fcbbf1942e1acea2fd15b17007204b79d675540dd053af/cryptography-45.0.2-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:f169469d04a23282de9d0be349499cb6683b6ff1b68901210faacac9b0c24b7d", size = 4189696 },
+    { url = "https://files.pythonhosted.org/packages/70/ae/ec29c79f481e1767c2ff916424ba36f3cf7774de93bbd60428a3c52d1357/cryptography-45.0.2-cp37-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:9cfd1399064b13043082c660ddd97a0358e41c8b0dc7b77c1243e013d305c344", size = 3881498 },
+    { url = "https://files.pythonhosted.org/packages/5f/4a/72937090e5637a232b2f73801c9361cd08404a2d4e620ca4ec58c7ea4b70/cryptography-45.0.2-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:18f8084b7ca3ce1b8d38bdfe33c48116edf9a08b4d056ef4a96dceaa36d8d965", size = 4451678 },
+    { url = "https://files.pythonhosted.org/packages/d3/fa/1377fced81fd67a4a27514248261bb0d45c3c1e02169411fe231583088c8/cryptography-45.0.2-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:2cb03a944a1a412724d15a7c051d50e63a868031f26b6a312f2016965b661942", size = 4192296 },
+    { url = "https://files.pythonhosted.org/packages/d1/cf/b6fe837c83a08b9df81e63299d75fc5b3c6d82cf24b3e1e0e331050e9e5c/cryptography-45.0.2-cp37-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:a9727a21957d3327cf6b7eb5ffc9e4b663909a25fea158e3fcbc49d4cdd7881b", size = 4451749 },
+    { url = "https://files.pythonhosted.org/packages/af/d8/5a655675cc635c7190bfc8cffb84bcdc44fc62ce945ad1d844adaa884252/cryptography-45.0.2-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ddb8d01aa900b741d6b7cc585a97aff787175f160ab975e21f880e89d810781a", size = 4317601 },
+    { url = "https://files.pythonhosted.org/packages/b9/d4/75d2375a20d80aa262a8adee77bf56950e9292929e394b9fae2481803f11/cryptography-45.0.2-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:c0c000c1a09f069632d8a9eb3b610ac029fcc682f1d69b758e625d6ee713f4ed", size = 4560535 },
+    { url = "https://files.pythonhosted.org/packages/aa/18/c3a94474987ebcfb88692036b2ec44880d243fefa73794bdcbf748679a6e/cryptography-45.0.2-cp37-abi3-win32.whl", hash = "sha256:08281de408e7eb71ba3cd5098709a356bfdf65eebd7ee7633c3610f0aa80d79b", size = 2922045 },
+    { url = "https://files.pythonhosted.org/packages/63/63/fb28b30c144182fd44ce93d13ab859791adbf923e43bdfb610024bfecda1/cryptography-45.0.2-cp37-abi3-win_amd64.whl", hash = "sha256:48caa55c528617fa6db1a9c3bf2e37ccb31b73e098ac2b71408d1f2db551dde4", size = 3393321 },
 ]
 
 [[package]]
@@ -244,18 +264,19 @@ wheels = [
 
 [[package]]
 name = "flask"
-version = "3.1.0"
+version = "3.1.1"
 source = { registry = "https://pypi.org/simple" }
 dependencies = [
     { name = "blinker" },
     { name = "click" },
     { name = "itsdangerous" },
     { name = "jinja2" },
+    { name = "markupsafe" },
     { name = "werkzeug" },
 ]
-sdist = { url = "https://files.pythonhosted.org/packages/89/50/dff6380f1c7f84135484e176e0cac8690af72fa90e932ad2a0a60e28c69b/flask-3.1.0.tar.gz", hash = "sha256:5f873c5184c897c8d9d1b05df1e3d01b14910ce69607a117bd3277098a5836ac", size = 680824 }
+sdist = { url = "https://files.pythonhosted.org/packages/c0/de/e47735752347f4128bcf354e0da07ef311a78244eba9e3dc1d4a5ab21a98/flask-3.1.1.tar.gz", hash = "sha256:284c7b8f2f58cb737f0cf1c30fd7eaf0ccfcde196099d24ecede3fc2005aa59e", size = 753440 }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/af/47/93213ee66ef8fae3b93b3e29206f6b251e65c97bd91d8e1c5596ef15af0a/flask-3.1.0-py3-none-any.whl", hash = "sha256:d667207822eb83f1c4b50949b1623c8fc8d51f2341d65f72e1a1815397551136", size = 102979 },
+    { url = "https://files.pythonhosted.org/packages/3d/68/9d4508e893976286d2ead7f8f571314af6c2037af34853a30fd769c02e9d/flask-3.1.1-py3-none-any.whl", hash = "sha256:07aae2bb5eaf77993ef57e357491839f5fd9f4dc281593a81a9e4d79a24f295c", size = 103305 },
 ]
 
 [[package]]
@@ -264,6 +285,7 @@ version = "0.1.0"
 source = { virtual = "." }
 dependencies = [
     { name = "beautifulsoup4" },
+    { name = "black" },
     { name = "crontab" },
     { name = "flask" },
     { name = "jinja2" },
@@ -296,6 +318,7 @@ dependencies = [
 [package.metadata]
 requires-dist = [
     { name = "beautifulsoup4", specifier = ">=4.13.3" },
+    { name = "black", specifier = ">=25.1.0" },
     { name = "crontab", specifier = ">=1.0.1" },
     { name = "flask", specifier = ">=2.2.0" },
     { name = "jinja2", specifier = ">=3.1.5" },
@@ -339,38 +362,39 @@ wheels = [
 
 [[package]]
 name = "greenlet"
-version = "3.1.1"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/2f/ff/df5fede753cc10f6a5be0931204ea30c35fa2f2ea7a35b25bdaf4fe40e46/greenlet-3.1.1.tar.gz", hash = "sha256:4ce3ac6cdb6adf7946475d7ef31777c26d94bccc377e070a7986bd2d5c515467", size = 186022 }
-wheels = [
-    { url = "https://files.pythonhosted.org/packages/f3/57/0db4940cd7bb461365ca8d6fd53e68254c9dbbcc2b452e69d0d41f10a85e/greenlet-3.1.1-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:05175c27cb459dcfc05d026c4232f9de8913ed006d42713cb8a5137bd49375f1", size = 272990 },
-    { url = "https://files.pythonhosted.org/packages/1c/ec/423d113c9f74e5e402e175b157203e9102feeb7088cee844d735b28ef963/greenlet-3.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:935e943ec47c4afab8965954bf49bfa639c05d4ccf9ef6e924188f762145c0ff", size = 649175 },
-    { url = "https://files.pythonhosted.org/packages/a9/46/ddbd2db9ff209186b7b7c621d1432e2f21714adc988703dbdd0e65155c77/greenlet-3.1.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:667a9706c970cb552ede35aee17339a18e8f2a87a51fba2ed39ceeeb1004798a", size = 663425 },
-    { url = "https://files.pythonhosted.org/packages/bc/f9/9c82d6b2b04aa37e38e74f0c429aece5eeb02bab6e3b98e7db89b23d94c6/greenlet-3.1.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b8a678974d1f3aa55f6cc34dc480169d58f2e6d8958895d68845fa4ab566509e", size = 657736 },
-    { url = "https://files.pythonhosted.org/packages/d9/42/b87bc2a81e3a62c3de2b0d550bf91a86939442b7ff85abb94eec3fc0e6aa/greenlet-3.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efc0f674aa41b92da8c49e0346318c6075d734994c3c4e4430b1c3f853e498e4", size = 660347 },
-    { url = "https://files.pythonhosted.org/packages/37/fa/71599c3fd06336cdc3eac52e6871cfebab4d9d70674a9a9e7a482c318e99/greenlet-3.1.1-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0153404a4bb921f0ff1abeb5ce8a5131da56b953eda6e14b88dc6bbc04d2049e", size = 615583 },
-    { url = "https://files.pythonhosted.org/packages/4e/96/e9ef85de031703ee7a4483489b40cf307f93c1824a02e903106f2ea315fe/greenlet-3.1.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:275f72decf9932639c1c6dd1013a1bc266438eb32710016a1c742df5da6e60a1", size = 1133039 },
-    { url = "https://files.pythonhosted.org/packages/87/76/b2b6362accd69f2d1889db61a18c94bc743e961e3cab344c2effaa4b4a25/greenlet-3.1.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c4aab7f6381f38a4b42f269057aee279ab0fc7bf2e929e3d4abfae97b682a12c", size = 1160716 },
-    { url = "https://files.pythonhosted.org/packages/1f/1b/54336d876186920e185066d8c3024ad55f21d7cc3683c856127ddb7b13ce/greenlet-3.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:b42703b1cf69f2aa1df7d1030b9d77d3e584a70755674d60e710f0af570f3761", size = 299490 },
-    { url = "https://files.pythonhosted.org/packages/5f/17/bea55bf36990e1638a2af5ba10c1640273ef20f627962cf97107f1e5d637/greenlet-3.1.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f1695e76146579f8c06c1509c7ce4dfe0706f49c6831a817ac04eebb2fd02011", size = 643731 },
-    { url = "https://files.pythonhosted.org/packages/78/d2/aa3d2157f9ab742a08e0fd8f77d4699f37c22adfbfeb0c610a186b5f75e0/greenlet-3.1.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7876452af029456b3f3549b696bb36a06db7c90747740c5302f74a9e9fa14b13", size = 649304 },
-    { url = "https://files.pythonhosted.org/packages/f1/8e/d0aeffe69e53ccff5a28fa86f07ad1d2d2d6537a9506229431a2a02e2f15/greenlet-3.1.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4ead44c85f8ab905852d3de8d86f6f8baf77109f9da589cb4fa142bd3b57b475", size = 646537 },
-    { url = "https://files.pythonhosted.org/packages/05/79/e15408220bbb989469c8871062c97c6c9136770657ba779711b90870d867/greenlet-3.1.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8320f64b777d00dd7ccdade271eaf0cad6636343293a25074cc5566160e4de7b", size = 642506 },
-    { url = "https://files.pythonhosted.org/packages/18/87/470e01a940307796f1d25f8167b551a968540fbe0551c0ebb853cb527dd6/greenlet-3.1.1-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6510bf84a6b643dabba74d3049ead221257603a253d0a9873f55f6a59a65f822", size = 602753 },
-    { url = "https://files.pythonhosted.org/packages/e2/72/576815ba674eddc3c25028238f74d7b8068902b3968cbe456771b166455e/greenlet-3.1.1-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:04b013dc07c96f83134b1e99888e7a79979f1a247e2a9f59697fa14b5862ed01", size = 1122731 },
-    { url = "https://files.pythonhosted.org/packages/ac/38/08cc303ddddc4b3d7c628c3039a61a3aae36c241ed01393d00c2fd663473/greenlet-3.1.1-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:411f015496fec93c1c8cd4e5238da364e1da7a124bcb293f085bf2860c32c6f6", size = 1142112 },
+version = "3.2.2"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/34/c1/a82edae11d46c0d83481aacaa1e578fea21d94a1ef400afd734d47ad95ad/greenlet-3.2.2.tar.gz", hash = "sha256:ad053d34421a2debba45aa3cc39acf454acbcd025b3fc1a9f8a0dee237abd485", size = 185797 }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/89/30/97b49779fff8601af20972a62cc4af0c497c1504dfbb3e93be218e093f21/greenlet-3.2.2-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:3ab7194ee290302ca15449f601036007873028712e92ca15fc76597a0aeb4c59", size = 269150 },
+    { url = "https://files.pythonhosted.org/packages/21/30/877245def4220f684bc2e01df1c2e782c164e84b32e07373992f14a2d107/greenlet-3.2.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2dc5c43bb65ec3669452af0ab10729e8fdc17f87a1f2ad7ec65d4aaaefabf6bf", size = 637381 },
+    { url = "https://files.pythonhosted.org/packages/8e/16/adf937908e1f913856b5371c1d8bdaef5f58f251d714085abeea73ecc471/greenlet-3.2.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:decb0658ec19e5c1f519faa9a160c0fc85a41a7e6654b3ce1b44b939f8bf1325", size = 651427 },
+    { url = "https://files.pythonhosted.org/packages/ad/49/6d79f58fa695b618654adac64e56aff2eeb13344dc28259af8f505662bb1/greenlet-3.2.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6fadd183186db360b61cb34e81117a096bff91c072929cd1b529eb20dd46e6c5", size = 645795 },
+    { url = "https://files.pythonhosted.org/packages/5a/e6/28ed5cb929c6b2f001e96b1d0698c622976cd8f1e41fe7ebc047fa7c6dd4/greenlet-3.2.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1919cbdc1c53ef739c94cf2985056bcc0838c1f217b57647cbf4578576c63825", size = 648398 },
+    { url = "https://files.pythonhosted.org/packages/9d/70/b200194e25ae86bc57077f695b6cc47ee3118becf54130c5514456cf8dac/greenlet-3.2.2-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3885f85b61798f4192d544aac7b25a04ece5fe2704670b4ab73c2d2c14ab740d", size = 606795 },
+    { url = "https://files.pythonhosted.org/packages/f8/c8/ba1def67513a941154ed8f9477ae6e5a03f645be6b507d3930f72ed508d3/greenlet-3.2.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:85f3e248507125bf4af607a26fd6cb8578776197bd4b66e35229cdf5acf1dfbf", size = 1117976 },
+    { url = "https://files.pythonhosted.org/packages/c3/30/d0e88c1cfcc1b3331d63c2b54a0a3a4a950ef202fb8b92e772ca714a9221/greenlet-3.2.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:1e76106b6fc55fa3d6fe1c527f95ee65e324a13b62e243f77b48317346559708", size = 1145509 },
+    { url = "https://files.pythonhosted.org/packages/90/2e/59d6491834b6e289051b252cf4776d16da51c7c6ca6a87ff97e3a50aa0cd/greenlet-3.2.2-cp313-cp313-win_amd64.whl", hash = "sha256:fe46d4f8e94e637634d54477b0cfabcf93c53f29eedcbdeecaf2af32029b4421", size = 296023 },
+    { url = "https://files.pythonhosted.org/packages/65/66/8a73aace5a5335a1cba56d0da71b7bd93e450f17d372c5b7c5fa547557e9/greenlet-3.2.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba30e88607fb6990544d84caf3c706c4b48f629e18853fc6a646f82db9629418", size = 629911 },
+    { url = "https://files.pythonhosted.org/packages/48/08/c8b8ebac4e0c95dcc68ec99198842e7db53eda4ab3fb0a4e785690883991/greenlet-3.2.2-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:055916fafad3e3388d27dd68517478933a97edc2fc54ae79d3bec827de2c64c4", size = 635251 },
+    { url = "https://files.pythonhosted.org/packages/37/26/7db30868f73e86b9125264d2959acabea132b444b88185ba5c462cb8e571/greenlet-3.2.2-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2593283bf81ca37d27d110956b79e8723f9aa50c4bcdc29d3c0543d4743d2763", size = 632620 },
+    { url = "https://files.pythonhosted.org/packages/10/ec/718a3bd56249e729016b0b69bee4adea0dfccf6ca43d147ef3b21edbca16/greenlet-3.2.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89c69e9a10670eb7a66b8cef6354c24671ba241f46152dd3eed447f79c29fb5b", size = 628851 },
+    { url = "https://files.pythonhosted.org/packages/9b/9d/d1c79286a76bc62ccdc1387291464af16a4204ea717f24e77b0acd623b99/greenlet-3.2.2-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:02a98600899ca1ca5d3a2590974c9e3ec259503b2d6ba6527605fcd74e08e207", size = 593718 },
+    { url = "https://files.pythonhosted.org/packages/cd/41/96ba2bf948f67b245784cd294b84e3d17933597dffd3acdb367a210d1949/greenlet-3.2.2-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:b50a8c5c162469c3209e5ec92ee4f95c8231b11db6a04db09bbe338176723bb8", size = 1105752 },
+    { url = "https://files.pythonhosted.org/packages/68/3b/3b97f9d33c1f2eb081759da62bd6162159db260f602f048bc2f36b4c453e/greenlet-3.2.2-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:45f9f4853fb4cc46783085261c9ec4706628f3b57de3e68bae03e8f8b3c0de51", size = 1125170 },
+    { url = "https://files.pythonhosted.org/packages/31/df/b7d17d66c8d0f578d2885a3d8f565e9e4725eacc9d3fdc946d0031c055c4/greenlet-3.2.2-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:9ea5231428af34226c05f927e16fc7f6fa5e39e3ad3cd24ffa48ba53a47f4240", size = 269899 },
 ]
 
 [[package]]
 name = "griffe"
-version = "1.6.0"
+version = "1.7.3"
 source = { registry = "https://pypi.org/simple" }
 dependencies = [
     { name = "colorama" },
 ]
-sdist = { url = "https://files.pythonhosted.org/packages/a0/1a/d467b93f5e0ea4edf3c1caef44cfdd53a4a498cb3a6bb722df4dd0fdd66a/griffe-1.6.0.tar.gz", hash = "sha256:eb5758088b9c73ad61c7ac014f3cdfb4c57b5c2fcbfca69996584b702aefa354", size = 391819 }
+sdist = { url = "https://files.pythonhosted.org/packages/a9/3e/5aa9a61f7c3c47b0b52a1d930302992229d191bf4bc76447b324b731510a/griffe-1.7.3.tar.gz", hash = "sha256:52ee893c6a3a968b639ace8015bec9d36594961e156e23315c8e8e51401fa50b", size = 395137 }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/bf/02/5a22bc98d0aebb68c15ba70d2da1c84a5ef56048d79634e5f96cd2ba96e9/griffe-1.6.0-py3-none-any.whl", hash = "sha256:9f1dfe035d4715a244ed2050dfbceb05b1f470809ed4f6bb10ece5a7302f8dd1", size = 128470 },
+    { url = "https://files.pythonhosted.org/packages/58/c6/5c20af38c2a57c15d87f7f38bee77d63c1d2a3689f74fefaf35915dd12b2/griffe-1.7.3-py3-none-any.whl", hash = "sha256:c6b3ee30c2f0f17f30bcdef5068d6ab7a2a4f1b8bf1a3e74b56fffd21e1c5f75", size = 129303 },
 ]
 
 [[package]]
@@ -393,14 +417,14 @@ wheels = [
 
 [[package]]
 name = "jinja2"
-version = "3.1.5"
+version = "3.1.6"
 source = { registry = "https://pypi.org/simple" }
 dependencies = [
     { name = "markupsafe" },
 ]
-sdist = { url = "https://files.pythonhosted.org/packages/af/92/b3130cbbf5591acf9ade8708c365f3238046ac7cb8ccba6e81abccb0ccff/jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb", size = 244674 }
+sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115 }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/bd/0f/2ba5fbcd631e3e88689309dbe978c5769e883e4b84ebfe7da30b43275c5a/jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb", size = 134596 },
+    { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899 },
 ]
 
 [[package]]
@@ -417,27 +441,27 @@ wheels = [
 
 [[package]]
 name = "lxml"
-version = "5.3.1"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/ef/f6/c15ca8e5646e937c148e147244817672cf920b56ac0bf2cc1512ae674be8/lxml-5.3.1.tar.gz", hash = "sha256:106b7b5d2977b339f1e97efe2778e2ab20e99994cbb0ec5e55771ed0795920c8", size = 3678591 }
-wheels = [
-    { url = "https://files.pythonhosted.org/packages/94/1c/724931daa1ace168e0237b929e44062545bf1551974102a5762c349c668d/lxml-5.3.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c093c7088b40d8266f57ed71d93112bd64c6724d31f0794c1e52cc4857c28e0e", size = 8171881 },
-    { url = "https://files.pythonhosted.org/packages/67/0c/857b8fb6010c4246e66abeebb8639eaabba60a6d9b7c606554ecc5cbf1ee/lxml-5.3.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b0884e3f22d87c30694e625b1e62e6f30d39782c806287450d9dc2fdf07692fd", size = 4440394 },
-    { url = "https://files.pythonhosted.org/packages/61/72/c9e81de6a000f9682ccdd13503db26e973b24c68ac45a7029173237e3eed/lxml-5.3.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1637fa31ec682cd5760092adfabe86d9b718a75d43e65e211d5931809bc111e7", size = 5037860 },
-    { url = "https://files.pythonhosted.org/packages/24/26/942048c4b14835711b583b48cd7209bd2b5f0b6939ceed2381a494138b14/lxml-5.3.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a364e8e944d92dcbf33b6b494d4e0fb3499dcc3bd9485beb701aa4b4201fa414", size = 4782513 },
-    { url = "https://files.pythonhosted.org/packages/e2/65/27792339caf00f610cc5be32b940ba1e3009b7054feb0c4527cebac228d4/lxml-5.3.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:779e851fd0e19795ccc8a9bb4d705d6baa0ef475329fe44a13cf1e962f18ff1e", size = 5305227 },
-    { url = "https://files.pythonhosted.org/packages/18/e1/25f7aa434a4d0d8e8420580af05ea49c3e12db6d297cf5435ac0a054df56/lxml-5.3.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c4393600915c308e546dc7003d74371744234e8444a28622d76fe19b98fa59d1", size = 4829846 },
-    { url = "https://files.pythonhosted.org/packages/fe/ed/faf235e0792547d24f61ee1448159325448a7e4f2ab706503049d8e5df19/lxml-5.3.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:673b9d8e780f455091200bba8534d5f4f465944cbdd61f31dc832d70e29064a5", size = 4949495 },
-    { url = "https://files.pythonhosted.org/packages/e5/e1/8f572ad9ed6039ba30f26dd4c2c58fb90f79362d2ee35ca3820284767672/lxml-5.3.1-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:2e4a570f6a99e96c457f7bec5ad459c9c420ee80b99eb04cbfcfe3fc18ec6423", size = 4773415 },
-    { url = "https://files.pythonhosted.org/packages/a3/75/6b57166b9d1983dac8f28f354e38bff8d6bcab013a241989c4d54c72701b/lxml-5.3.1-cp313-cp313-manylinux_2_28_ppc64le.whl", hash = "sha256:71f31eda4e370f46af42fc9f264fafa1b09f46ba07bdbee98f25689a04b81c20", size = 5337710 },
-    { url = "https://files.pythonhosted.org/packages/cc/71/4aa56e2daa83bbcc66ca27b5155be2f900d996f5d0c51078eaaac8df9547/lxml-5.3.1-cp313-cp313-manylinux_2_28_s390x.whl", hash = "sha256:42978a68d3825eaac55399eb37a4d52012a205c0c6262199b8b44fcc6fd686e8", size = 4897362 },
-    { url = "https://files.pythonhosted.org/packages/65/10/3fa2da152cd9b49332fd23356ed7643c9b74cad636ddd5b2400a9730d12b/lxml-5.3.1-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:8b1942b3e4ed9ed551ed3083a2e6e0772de1e5e3aca872d955e2e86385fb7ff9", size = 4977795 },
-    { url = "https://files.pythonhosted.org/packages/de/d2/e1da0f7b20827e7b0ce934963cb6334c1b02cf1bb4aecd218c4496880cb3/lxml-5.3.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:85c4f11be9cf08917ac2a5a8b6e1ef63b2f8e3799cec194417e76826e5f1de9c", size = 4858104 },
-    { url = "https://files.pythonhosted.org/packages/a5/35/063420e1b33d3308f5aa7fcbdd19ef6c036f741c9a7a4bd5dc8032486b27/lxml-5.3.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:231cf4d140b22a923b1d0a0a4e0b4f972e5893efcdec188934cc65888fd0227b", size = 5416531 },
-    { url = "https://files.pythonhosted.org/packages/c3/83/93a6457d291d1e37adfb54df23498101a4701834258c840381dd2f6a030e/lxml-5.3.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:5865b270b420eda7b68928d70bb517ccbe045e53b1a428129bb44372bf3d7dd5", size = 5273040 },
-    { url = "https://files.pythonhosted.org/packages/39/25/ad4ac8fac488505a2702656550e63c2a8db3a4fd63db82a20dad5689cecb/lxml-5.3.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:dbf7bebc2275016cddf3c997bf8a0f7044160714c64a9b83975670a04e6d2252", size = 5050951 },
-    { url = "https://files.pythonhosted.org/packages/82/74/f7d223c704c87e44b3d27b5e0dde173a2fcf2e89c0524c8015c2b3554876/lxml-5.3.1-cp313-cp313-win32.whl", hash = "sha256:d0751528b97d2b19a388b302be2a0ee05817097bab46ff0ed76feeec24951f78", size = 3485357 },
-    { url = "https://files.pythonhosted.org/packages/80/83/8c54533b3576f4391eebea88454738978669a6cad0d8e23266224007939d/lxml-5.3.1-cp313-cp313-win_amd64.whl", hash = "sha256:91fb6a43d72b4f8863d21f347a9163eecbf36e76e2f51068d59cd004c506f332", size = 3814484 },
+version = "5.4.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/76/3d/14e82fc7c8fb1b7761f7e748fd47e2ec8276d137b6acfe5a4bb73853e08f/lxml-5.4.0.tar.gz", hash = "sha256:d12832e1dbea4be280b22fd0ea7c9b87f0d8fc51ba06e92dc62d52f804f78ebd", size = 3679479 }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/87/cb/2ba1e9dd953415f58548506fa5549a7f373ae55e80c61c9041b7fd09a38a/lxml-5.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:773e27b62920199c6197130632c18fb7ead3257fce1ffb7d286912e56ddb79e0", size = 8110086 },
+    { url = "https://files.pythonhosted.org/packages/b5/3e/6602a4dca3ae344e8609914d6ab22e52ce42e3e1638c10967568c5c1450d/lxml-5.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ce9c671845de9699904b1e9df95acfe8dfc183f2310f163cdaa91a3535af95de", size = 4404613 },
+    { url = "https://files.pythonhosted.org/packages/4c/72/bf00988477d3bb452bef9436e45aeea82bb40cdfb4684b83c967c53909c7/lxml-5.4.0-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9454b8d8200ec99a224df8854786262b1bd6461f4280064c807303c642c05e76", size = 5012008 },
+    { url = "https://files.pythonhosted.org/packages/92/1f/93e42d93e9e7a44b2d3354c462cd784dbaaf350f7976b5d7c3f85d68d1b1/lxml-5.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cccd007d5c95279e529c146d095f1d39ac05139de26c098166c4beb9374b0f4d", size = 4760915 },
+    { url = "https://files.pythonhosted.org/packages/45/0b/363009390d0b461cf9976a499e83b68f792e4c32ecef092f3f9ef9c4ba54/lxml-5.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0fce1294a0497edb034cb416ad3e77ecc89b313cff7adbee5334e4dc0d11f422", size = 5283890 },
+    { url = "https://files.pythonhosted.org/packages/19/dc/6056c332f9378ab476c88e301e6549a0454dbee8f0ae16847414f0eccb74/lxml-5.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:24974f774f3a78ac12b95e3a20ef0931795ff04dbb16db81a90c37f589819551", size = 4812644 },
+    { url = "https://files.pythonhosted.org/packages/ee/8a/f8c66bbb23ecb9048a46a5ef9b495fd23f7543df642dabeebcb2eeb66592/lxml-5.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:497cab4d8254c2a90bf988f162ace2ddbfdd806fce3bda3f581b9d24c852e03c", size = 4921817 },
+    { url = "https://files.pythonhosted.org/packages/04/57/2e537083c3f381f83d05d9b176f0d838a9e8961f7ed8ddce3f0217179ce3/lxml-5.4.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:e794f698ae4c5084414efea0f5cc9f4ac562ec02d66e1484ff822ef97c2cadff", size = 4753916 },
+    { url = "https://files.pythonhosted.org/packages/d8/80/ea8c4072109a350848f1157ce83ccd9439601274035cd045ac31f47f3417/lxml-5.4.0-cp313-cp313-manylinux_2_28_ppc64le.whl", hash = "sha256:2c62891b1ea3094bb12097822b3d44b93fc6c325f2043c4d2736a8ff09e65f60", size = 5289274 },
+    { url = "https://files.pythonhosted.org/packages/b3/47/c4be287c48cdc304483457878a3f22999098b9a95f455e3c4bda7ec7fc72/lxml-5.4.0-cp313-cp313-manylinux_2_28_s390x.whl", hash = "sha256:142accb3e4d1edae4b392bd165a9abdee8a3c432a2cca193df995bc3886249c8", size = 4874757 },
+    { url = "https://files.pythonhosted.org/packages/2f/04/6ef935dc74e729932e39478e44d8cfe6a83550552eaa072b7c05f6f22488/lxml-5.4.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:1a42b3a19346e5601d1b8296ff6ef3d76038058f311902edd574461e9c036982", size = 4947028 },
+    { url = "https://files.pythonhosted.org/packages/cb/f9/c33fc8daa373ef8a7daddb53175289024512b6619bc9de36d77dca3df44b/lxml-5.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4291d3c409a17febf817259cb37bc62cb7eb398bcc95c1356947e2871911ae61", size = 4834487 },
+    { url = "https://files.pythonhosted.org/packages/8d/30/fc92bb595bcb878311e01b418b57d13900f84c2b94f6eca9e5073ea756e6/lxml-5.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4f5322cf38fe0e21c2d73901abf68e6329dc02a4994e483adbcf92b568a09a54", size = 5381688 },
+    { url = "https://files.pythonhosted.org/packages/43/d1/3ba7bd978ce28bba8e3da2c2e9d5ae3f8f521ad3f0ca6ea4788d086ba00d/lxml-5.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:0be91891bdb06ebe65122aa6bf3fc94489960cf7e03033c6f83a90863b23c58b", size = 5242043 },
+    { url = "https://files.pythonhosted.org/packages/ee/cd/95fa2201041a610c4d08ddaf31d43b98ecc4b1d74b1e7245b1abdab443cb/lxml-5.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:15a665ad90054a3d4f397bc40f73948d48e36e4c09f9bcffc7d90c87410e478a", size = 5021569 },
+    { url = "https://files.pythonhosted.org/packages/2d/a6/31da006fead660b9512d08d23d31e93ad3477dd47cc42e3285f143443176/lxml-5.4.0-cp313-cp313-win32.whl", hash = "sha256:d5663bc1b471c79f5c833cffbc9b87d7bf13f87e055a5c86c363ccd2348d7e82", size = 3485270 },
+    { url = "https://files.pythonhosted.org/packages/fc/14/c115516c62a7d2499781d2d3d7215218c0731b2c940753bf9f9b7b73924d/lxml-5.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:bcb7a1096b4b6b24ce1ac24d4942ad98f983cd3810f9711bcd0293f43a9d8b9f", size = 3814606 },
 ]
 
 [[package]]
@@ -454,11 +478,11 @@ wheels = [
 
 [[package]]
 name = "markdown"
-version = "3.7"
+version = "3.8"
 source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/54/28/3af612670f82f4c056911fbbbb42760255801b3068c48de792d354ff4472/markdown-3.7.tar.gz", hash = "sha256:2ae2471477cfd02dbbf038d5d9bc226d40def84b4fe2986e49b59b6b472bbed2", size = 357086 }
+sdist = { url = "https://files.pythonhosted.org/packages/2f/15/222b423b0b88689c266d9eac4e61396fe2cc53464459d6a37618ac863b24/markdown-3.8.tar.gz", hash = "sha256:7df81e63f0df5c4b24b7d156eb81e4690595239b7d70937d0409f1b0de319c6f", size = 360906 }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/3f/08/83871f3c50fc983b88547c196d11cf8c3340e37c32d2e9d6152abe2c61f7/Markdown-3.7-py3-none-any.whl", hash = "sha256:7eb6df5690b81a1d7942992c97fad2938e956e79df20cbc6186e9c3a77b1c803", size = 106349 },
+    { url = "https://files.pythonhosted.org/packages/51/3f/afe76f8e2246ffbc867440cbcf90525264df0e658f8a5ca1f872b3f6192a/markdown-3.8-py3-none-any.whl", hash = "sha256:794a929b79c5af141ef5ab0f2f642d0f7b1872981250230e72682346f7cc90dc", size = 106210 },
 ]
 
 [[package]]
@@ -545,16 +569,16 @@ wheels = [
 
 [[package]]
 name = "mkdocs-autorefs"
-version = "1.4.0"
+version = "1.4.2"
 source = { registry = "https://pypi.org/simple" }
 dependencies = [
     { name = "markdown" },
     { name = "markupsafe" },
     { name = "mkdocs" },
 ]
-sdist = { url = "https://files.pythonhosted.org/packages/83/79/e846eb3323d1546b25d2ae4c957f5edf1bdfb7e0b695d43feae034c61553/mkdocs_autorefs-1.4.0.tar.gz", hash = "sha256:a9c0aa9c90edbce302c09d050a3c4cb7c76f8b7b2c98f84a7a05f53d00392156", size = 3128903 }
+sdist = { url = "https://files.pythonhosted.org/packages/47/0c/c9826f35b99c67fa3a7cddfa094c1a6c43fafde558c309c6e4403e5b37dc/mkdocs_autorefs-1.4.2.tar.gz", hash = "sha256:e2ebe1abd2b67d597ed19378c0fff84d73d1dbce411fce7a7cc6f161888b6749", size = 54961 }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/33/0e/a6ff5d3b3ac428fa8c43a356df449f366ff0dbe242dac9f87fa9d20515ed/mkdocs_autorefs-1.4.0-py3-none-any.whl", hash = "sha256:bad19f69655878d20194acd0162e29a89c3f7e6365ffe54e72aa3fd1072f240d", size = 4368332 },
+    { url = "https://files.pythonhosted.org/packages/87/dc/fc063b78f4b769d1956319351704e23ebeba1e9e1d6a41b4b602325fd7e4/mkdocs_autorefs-1.4.2-py3-none-any.whl", hash = "sha256:83d6d777b66ec3c372a1aad4ae0cf77c243ba5bcda5bf0c6b8a2c5e7a3d89f13", size = 24969 },
 ]
 
 [[package]]
@@ -573,7 +597,7 @@ wheels = [
 
 [[package]]
 name = "mkdocs-material"
-version = "9.6.7"
+version = "9.6.14"
 source = { registry = "https://pypi.org/simple" }
 dependencies = [
     { name = "babel" },
@@ -588,9 +612,9 @@ dependencies = [
     { name = "pymdown-extensions" },
     { name = "requests" },
 ]
-sdist = { url = "https://files.pythonhosted.org/packages/9b/d7/93e19c9587e5f4ed25647890555d58cf484a4d412be7037dc17b9c9179d9/mkdocs_material-9.6.7.tar.gz", hash = "sha256:3e2c1fceb9410056c2d91f334a00cdea3215c28750e00c691c1e46b2a33309b4", size = 3947458 }
+sdist = { url = "https://files.pythonhosted.org/packages/b3/fa/0101de32af88f87cf5cc23ad5f2e2030d00995f74e616306513431b8ab4b/mkdocs_material-9.6.14.tar.gz", hash = "sha256:39d795e90dce6b531387c255bd07e866e027828b7346d3eba5ac3de265053754", size = 3951707 }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/aa/d3/12f22de41bdd9e576ddc459b38c651d68edfb840b32acaa1f46ae36845e3/mkdocs_material-9.6.7-py3-none-any.whl", hash = "sha256:8a159e45e80fcaadd9fbeef62cbf928569b93df954d4dc5ba76d46820caf7b47", size = 8696755 },
+    { url = "https://files.pythonhosted.org/packages/3a/a1/7fdb959ad592e013c01558822fd3c22931a95a0f08cf0a7c36da13a5b2b5/mkdocs_material-9.6.14-py3-none-any.whl", hash = "sha256:3b9cee6d3688551bf7a8e8f41afda97a3c39a12f0325436d76c86706114b721b", size = 8703767 },
 ]
 
 [[package]]
@@ -604,7 +628,7 @@ wheels = [
 
 [[package]]
 name = "mkdocstrings"
-version = "0.28.2"
+version = "0.29.1"
 source = { registry = "https://pypi.org/simple" }
 dependencies = [
     { name = "jinja2" },
@@ -612,54 +636,62 @@ dependencies = [
     { name = "markupsafe" },
     { name = "mkdocs" },
     { name = "mkdocs-autorefs" },
-    { name = "mkdocs-get-deps" },
     { name = "pymdown-extensions" },
 ]
-sdist = { url = "https://files.pythonhosted.org/packages/e8/83/5eab81d31953c725942eb663b6a4cf36ad06d803633c8e1c6ddc708af62d/mkdocstrings-0.28.2.tar.gz", hash = "sha256:9b847266d7a588ea76a8385eaebe1538278b4361c0d1ce48ed005be59f053569", size = 5691916 }
+sdist = { url = "https://files.pythonhosted.org/packages/41/e8/d22922664a627a0d3d7ff4a6ca95800f5dde54f411982591b4621a76225d/mkdocstrings-0.29.1.tar.gz", hash = "sha256:8722f8f8c5cd75da56671e0a0c1bbed1df9946c0cef74794d6141b34011abd42", size = 1212686 }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/32/60/15ef9759431cf8e60ffda7d5bba3914cc764f2bd8e7f62e1bd301ea292e0/mkdocstrings-0.28.2-py3-none-any.whl", hash = "sha256:57f79c557e2718d217d6f6a81bf75a0de097f10e922e7e5e00f085c3f0ff6895", size = 8056702 },
+    { url = "https://files.pythonhosted.org/packages/98/14/22533a578bf8b187e05d67e2c1721ce10e3f526610eebaf7a149d557ea7a/mkdocstrings-0.29.1-py3-none-any.whl", hash = "sha256:37a9736134934eea89cbd055a513d40a020d87dfcae9e3052c2a6b8cd4af09b6", size = 1631075 },
 ]
 
 [[package]]
 name = "mkdocstrings-python"
-version = "1.16.2"
+version = "1.16.10"
 source = { registry = "https://pypi.org/simple" }
 dependencies = [
     { name = "griffe" },
     { name = "mkdocs-autorefs" },
     { name = "mkdocstrings" },
 ]
-sdist = { url = "https://files.pythonhosted.org/packages/ed/a9/5990642e1bb2d90b049f655b92f46d0a77acb76ed59ef3233d5a6934312e/mkdocstrings_python-1.16.2.tar.gz", hash = "sha256:942ec1a2e0481d28f96f93be3d6e343cab92a21e5baf01c37dd2d7236c4d0bd7", size = 423492 }
+sdist = { url = "https://files.pythonhosted.org/packages/44/c8/600c4201b6b9e72bab16802316d0c90ce04089f8e6bb5e064cd2a5abba7e/mkdocstrings_python-1.16.10.tar.gz", hash = "sha256:f9eedfd98effb612ab4d0ed6dd2b73aff6eba5215e0a65cea6d877717f75502e", size = 205771 }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/82/a2/60be7e17a2f2a9d4bfb7273cdb2071eeeb65bdca5c0d07ff16df63221ca2/mkdocstrings_python-1.16.2-py3-none-any.whl", hash = "sha256:ff7e719404e59ad1a72f1afbe854769984c889b8fa043c160f6c988e1ad9e966", size = 449141 },
+    { url = "https://files.pythonhosted.org/packages/53/37/19549c5e0179785308cc988a68e16aa7550e4e270ec8a9878334e86070c6/mkdocstrings_python-1.16.10-py3-none-any.whl", hash = "sha256:63bb9f01f8848a644bdb6289e86dc38ceddeaa63ecc2e291e3b2ca52702a6643", size = 124112 },
 ]
 
 [[package]]
-name = "numpy"
-version = "2.2.3"
+name = "mypy-extensions"
+version = "1.1.0"
 source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/fb/90/8956572f5c4ae52201fdec7ba2044b2c882832dcec7d5d0922c9e9acf2de/numpy-2.2.3.tar.gz", hash = "sha256:dbdc15f0c81611925f382dfa97b3bd0bc2c1ce19d4fe50482cb0ddc12ba30020", size = 20262700 }
-wheels = [
-    { url = "https://files.pythonhosted.org/packages/0e/8b/88b98ed534d6a03ba8cddb316950fe80842885709b58501233c29dfa24a9/numpy-2.2.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7bfdb06b395385ea9b91bf55c1adf1b297c9fdb531552845ff1d3ea6e40d5aba", size = 20916001 },
-    { url = "https://files.pythonhosted.org/packages/d9/b4/def6ec32c725cc5fbd8bdf8af80f616acf075fe752d8a23e895da8c67b70/numpy-2.2.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:23c9f4edbf4c065fddb10a4f6e8b6a244342d95966a48820c614891e5059bb50", size = 14130721 },
-    { url = "https://files.pythonhosted.org/packages/20/60/70af0acc86495b25b672d403e12cb25448d79a2b9658f4fc45e845c397a8/numpy-2.2.3-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:a0c03b6be48aaf92525cccf393265e02773be8fd9551a2f9adbe7db1fa2b60f1", size = 5130999 },
-    { url = "https://files.pythonhosted.org/packages/2e/69/d96c006fb73c9a47bcb3611417cf178049aae159afae47c48bd66df9c536/numpy-2.2.3-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:2376e317111daa0a6739e50f7ee2a6353f768489102308b0d98fcf4a04f7f3b5", size = 6665299 },
-    { url = "https://files.pythonhosted.org/packages/5a/3f/d8a877b6e48103733ac224ffa26b30887dc9944ff95dffdfa6c4ce3d7df3/numpy-2.2.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8fb62fe3d206d72fe1cfe31c4a1106ad2b136fcc1606093aeab314f02930fdf2", size = 14064096 },
-    { url = "https://files.pythonhosted.org/packages/e4/43/619c2c7a0665aafc80efca465ddb1f260287266bdbdce517396f2f145d49/numpy-2.2.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:52659ad2534427dffcc36aac76bebdd02b67e3b7a619ac67543bc9bfe6b7cdb1", size = 16114758 },
-    { url = "https://files.pythonhosted.org/packages/d9/79/ee4fe4f60967ccd3897aa71ae14cdee9e3c097e3256975cc9575d393cb42/numpy-2.2.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1b416af7d0ed3271cad0f0a0d0bee0911ed7eba23e66f8424d9f3dfcdcae1304", size = 15259880 },
-    { url = "https://files.pythonhosted.org/packages/fb/c8/8b55cf05db6d85b7a7d414b3d1bd5a740706df00bfa0824a08bf041e52ee/numpy-2.2.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1402da8e0f435991983d0a9708b779f95a8c98c6b18a171b9f1be09005e64d9d", size = 17876721 },
-    { url = "https://files.pythonhosted.org/packages/21/d6/b4c2f0564b7dcc413117b0ffbb818d837e4b29996b9234e38b2025ed24e7/numpy-2.2.3-cp313-cp313-win32.whl", hash = "sha256:136553f123ee2951bfcfbc264acd34a2fc2f29d7cdf610ce7daf672b6fbaa693", size = 6290195 },
-    { url = "https://files.pythonhosted.org/packages/97/e7/7d55a86719d0de7a6a597949f3febefb1009435b79ba510ff32f05a8c1d7/numpy-2.2.3-cp313-cp313-win_amd64.whl", hash = "sha256:5b732c8beef1d7bc2d9e476dbba20aaff6167bf205ad9aa8d30913859e82884b", size = 12619013 },
-    { url = "https://files.pythonhosted.org/packages/a6/1f/0b863d5528b9048fd486a56e0b97c18bf705e88736c8cea7239012119a54/numpy-2.2.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:435e7a933b9fda8126130b046975a968cc2d833b505475e588339e09f7672890", size = 20944621 },
-    { url = "https://files.pythonhosted.org/packages/aa/99/b478c384f7a0a2e0736177aafc97dc9152fc036a3fdb13f5a3ab225f1494/numpy-2.2.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:7678556eeb0152cbd1522b684dcd215250885993dd00adb93679ec3c0e6e091c", size = 14142502 },
-    { url = "https://files.pythonhosted.org/packages/fb/61/2d9a694a0f9cd0a839501d362de2a18de75e3004576a3008e56bdd60fcdb/numpy-2.2.3-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:2e8da03bd561504d9b20e7a12340870dfc206c64ea59b4cfee9fceb95070ee94", size = 5176293 },
-    { url = "https://files.pythonhosted.org/packages/33/35/51e94011b23e753fa33f891f601e5c1c9a3d515448659b06df9d40c0aa6e/numpy-2.2.3-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:c9aa4496fd0e17e3843399f533d62857cef5900facf93e735ef65aa4bbc90ef0", size = 6691874 },
-    { url = "https://files.pythonhosted.org/packages/ff/cf/06e37619aad98a9d03bd8d65b8e3041c3a639be0f5f6b0a0e2da544538d4/numpy-2.2.3-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f4ca91d61a4bf61b0f2228f24bbfa6a9facd5f8af03759fe2a655c50ae2c6610", size = 14036826 },
-    { url = "https://files.pythonhosted.org/packages/0c/93/5d7d19955abd4d6099ef4a8ee006f9ce258166c38af259f9e5558a172e3e/numpy-2.2.3-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:deaa09cd492e24fd9b15296844c0ad1b3c976da7907e1c1ed3a0ad21dded6f76", size = 16096567 },
-    { url = "https://files.pythonhosted.org/packages/af/53/d1c599acf7732d81f46a93621dab6aa8daad914b502a7a115b3f17288ab2/numpy-2.2.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:246535e2f7496b7ac85deffe932896a3577be7af8fb7eebe7146444680297e9a", size = 15242514 },
-    { url = "https://files.pythonhosted.org/packages/53/43/c0f5411c7b3ea90adf341d05ace762dad8cb9819ef26093e27b15dd121ac/numpy-2.2.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:daf43a3d1ea699402c5a850e5313680ac355b4adc9770cd5cfc2940e7861f1bf", size = 17872920 },
-    { url = "https://files.pythonhosted.org/packages/5b/57/6dbdd45ab277aff62021cafa1e15f9644a52f5b5fc840bc7591b4079fb58/numpy-2.2.3-cp313-cp313t-win32.whl", hash = "sha256:cf802eef1f0134afb81fef94020351be4fe1d6681aadf9c5e862af6602af64ef", size = 6346584 },
-    { url = "https://files.pythonhosted.org/packages/97/9b/484f7d04b537d0a1202a5ba81c6f53f1846ae6c63c2127f8df869ed31342/numpy-2.2.3-cp313-cp313t-win_amd64.whl", hash = "sha256:aee2512827ceb6d7f517c8b85aa5d3923afe8fc7a57d028cffcd522f1c6fd082", size = 12706784 },
+sdist = { url = "https://files.pythonhosted.org/packages/a2/6e/371856a3fb9d31ca8dac321cda606860fa4548858c0cc45d9d1d4ca2628b/mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558", size = 6343 }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", size = 4963 },
+]
+
+[[package]]
+name = "numpy"
+version = "2.2.6"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/76/21/7d2a95e4bba9dc13d043ee156a356c0a8f0c6309dff6b21b4d71a073b8a8/numpy-2.2.6.tar.gz", hash = "sha256:e29554e2bef54a90aa5cc07da6ce955accb83f21ab5de01a62c8478897b264fd", size = 20276440 }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/f9/5c/6657823f4f594f72b5471f1db1ab12e26e890bb2e41897522d134d2a3e81/numpy-2.2.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0811bb762109d9708cca4d0b13c4f67146e3c3b7cf8d34018c722adb2d957c84", size = 20867828 },
+    { url = "https://files.pythonhosted.org/packages/dc/9e/14520dc3dadf3c803473bd07e9b2bd1b69bc583cb2497b47000fed2fa92f/numpy-2.2.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:287cc3162b6f01463ccd86be154f284d0893d2b3ed7292439ea97eafa8170e0b", size = 14143006 },
+    { url = "https://files.pythonhosted.org/packages/4f/06/7e96c57d90bebdce9918412087fc22ca9851cceaf5567a45c1f404480e9e/numpy-2.2.6-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:f1372f041402e37e5e633e586f62aa53de2eac8d98cbfb822806ce4bbefcb74d", size = 5076765 },
+    { url = "https://files.pythonhosted.org/packages/73/ed/63d920c23b4289fdac96ddbdd6132e9427790977d5457cd132f18e76eae0/numpy-2.2.6-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:55a4d33fa519660d69614a9fad433be87e5252f4b03850642f88993f7b2ca566", size = 6617736 },
+    { url = "https://files.pythonhosted.org/packages/85/c5/e19c8f99d83fd377ec8c7e0cf627a8049746da54afc24ef0a0cb73d5dfb5/numpy-2.2.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f92729c95468a2f4f15e9bb94c432a9229d0d50de67304399627a943201baa2f", size = 14010719 },
+    { url = "https://files.pythonhosted.org/packages/19/49/4df9123aafa7b539317bf6d342cb6d227e49f7a35b99c287a6109b13dd93/numpy-2.2.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1bc23a79bfabc5d056d106f9befb8d50c31ced2fbc70eedb8155aec74a45798f", size = 16526072 },
+    { url = "https://files.pythonhosted.org/packages/b2/6c/04b5f47f4f32f7c2b0e7260442a8cbcf8168b0e1a41ff1495da42f42a14f/numpy-2.2.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e3143e4451880bed956e706a3220b4e5cf6172ef05fcc397f6f36a550b1dd868", size = 15503213 },
+    { url = "https://files.pythonhosted.org/packages/17/0a/5cd92e352c1307640d5b6fec1b2ffb06cd0dabe7d7b8227f97933d378422/numpy-2.2.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b4f13750ce79751586ae2eb824ba7e1e8dba64784086c98cdbbcc6a42112ce0d", size = 18316632 },
+    { url = "https://files.pythonhosted.org/packages/f0/3b/5cba2b1d88760ef86596ad0f3d484b1cbff7c115ae2429678465057c5155/numpy-2.2.6-cp313-cp313-win32.whl", hash = "sha256:5beb72339d9d4fa36522fc63802f469b13cdbe4fdab4a288f0c441b74272ebfd", size = 6244532 },
+    { url = "https://files.pythonhosted.org/packages/cb/3b/d58c12eafcb298d4e6d0d40216866ab15f59e55d148a5658bb3132311fcf/numpy-2.2.6-cp313-cp313-win_amd64.whl", hash = "sha256:b0544343a702fa80c95ad5d3d608ea3599dd54d4632df855e4c8d24eb6ecfa1c", size = 12610885 },
+    { url = "https://files.pythonhosted.org/packages/6b/9e/4bf918b818e516322db999ac25d00c75788ddfd2d2ade4fa66f1f38097e1/numpy-2.2.6-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0bca768cd85ae743b2affdc762d617eddf3bcf8724435498a1e80132d04879e6", size = 20963467 },
+    { url = "https://files.pythonhosted.org/packages/61/66/d2de6b291507517ff2e438e13ff7b1e2cdbdb7cb40b3ed475377aece69f9/numpy-2.2.6-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:fc0c5673685c508a142ca65209b4e79ed6740a4ed6b2267dbba90f34b0b3cfda", size = 14225144 },
+    { url = "https://files.pythonhosted.org/packages/e4/25/480387655407ead912e28ba3a820bc69af9adf13bcbe40b299d454ec011f/numpy-2.2.6-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:5bd4fc3ac8926b3819797a7c0e2631eb889b4118a9898c84f585a54d475b7e40", size = 5200217 },
+    { url = "https://files.pythonhosted.org/packages/aa/4a/6e313b5108f53dcbf3aca0c0f3e9c92f4c10ce57a0a721851f9785872895/numpy-2.2.6-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:fee4236c876c4e8369388054d02d0e9bb84821feb1a64dd59e137e6511a551f8", size = 6712014 },
+    { url = "https://files.pythonhosted.org/packages/b7/30/172c2d5c4be71fdf476e9de553443cf8e25feddbe185e0bd88b096915bcc/numpy-2.2.6-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e1dda9c7e08dc141e0247a5b8f49cf05984955246a327d4c48bda16821947b2f", size = 14077935 },
+    { url = "https://files.pythonhosted.org/packages/12/fb/9e743f8d4e4d3c710902cf87af3512082ae3d43b945d5d16563f26ec251d/numpy-2.2.6-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f447e6acb680fd307f40d3da4852208af94afdfab89cf850986c3ca00562f4fa", size = 16600122 },
+    { url = "https://files.pythonhosted.org/packages/12/75/ee20da0e58d3a66f204f38916757e01e33a9737d0b22373b3eb5a27358f9/numpy-2.2.6-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:389d771b1623ec92636b0786bc4ae56abafad4a4c513d36a55dce14bd9ce8571", size = 15586143 },
+    { url = "https://files.pythonhosted.org/packages/76/95/bef5b37f29fc5e739947e9ce5179ad402875633308504a52d188302319c8/numpy-2.2.6-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8e9ace4a37db23421249ed236fdcdd457d671e25146786dfc96835cd951aa7c1", size = 18385260 },
+    { url = "https://files.pythonhosted.org/packages/09/04/f2f83279d287407cf36a7a8053a5abe7be3622a4363337338f2585e4afda/numpy-2.2.6-cp313-cp313t-win32.whl", hash = "sha256:038613e9fb8c72b0a41f025a7e4c3f0b7a1b5d768ece4796b674c8f3fe13efff", size = 6377225 },
+    { url = "https://files.pythonhosted.org/packages/67/0e/35082d13c09c02c011cf21570543d202ad929d961c02a147493cb0c2bdf5/numpy-2.2.6-cp313-cp313t-win_amd64.whl", hash = "sha256:6031dd6dfecc0cf9f668681a37648373bddd6421fff6c66ec1624eed0180ee06", size = 12771374 },
 ]
 
 [[package]]
@@ -676,11 +708,11 @@ wheels = [
 
 [[package]]
 name = "packaging"
-version = "24.2"
+version = "25.0"
 source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/d0/63/68dbb6eb2de9cb10ee4c9c14a0148804425e13c4fb20d61cce69f53106da/packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f", size = 163950 }
+sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727 }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451 },
+    { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469 },
 ]
 
 [[package]]
@@ -744,29 +776,29 @@ wheels = [
 
 [[package]]
 name = "pdfminer-six"
-version = "20231228"
+version = "20250327"
 source = { registry = "https://pypi.org/simple" }
 dependencies = [
     { name = "charset-normalizer" },
     { name = "cryptography" },
 ]
-sdist = { url = "https://files.pythonhosted.org/packages/31/b1/a43e3bd872ded4deea4f8efc7aff1703fca8c5455d0c06e20506a06a44ff/pdfminer.six-20231228.tar.gz", hash = "sha256:6004da3ad1a7a4d45930cb950393df89b068e73be365a6ff64a838d37bcb08c4", size = 7362505 }
+sdist = { url = "https://files.pythonhosted.org/packages/08/e9/4688ff2dd985f21380b9c8cd2fa8004bc0f2691f2c301082d767caea7136/pdfminer_six-20250327.tar.gz", hash = "sha256:57f6c34c2702df04cfa3191622a3db0a922ced686d35283232b00094f8914aa1", size = 7381506 }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/eb/9c/e46fe7502b32d7db6af6e36a9105abb93301fa1ec475b5ddcba8b35ae23a/pdfminer.six-20231228-py3-none-any.whl", hash = "sha256:e8d3c3310e6fbc1fe414090123ab01351634b4ecb021232206c4c9a8ca3e3b8f", size = 5614515 },
+    { url = "https://files.pythonhosted.org/packages/29/2f/409e174b5a0195aa6a814c7359a1285f1c887a4c84aff17ed03f607c06ba/pdfminer_six-20250327-py3-none-any.whl", hash = "sha256:5af494c85b1ecb7c28df5e3a26bb5234a8226a307503d9a09f4958bc154b16a9", size = 5617445 },
 ]
 
 [[package]]
 name = "pdfplumber"
-version = "0.11.5"
+version = "0.11.6"
 source = { registry = "https://pypi.org/simple" }
 dependencies = [
     { name = "pdfminer-six" },
     { name = "pillow" },
     { name = "pypdfium2" },
 ]
-sdist = { url = "https://files.pythonhosted.org/packages/28/55/33d265185b4e7e6ac81e64478750ea26310055b1b5b278851b981a1c57e5/pdfplumber-0.11.5.tar.gz", hash = "sha256:dadd81b62a0b23e078cdd89de26e013850d4daf5690fcf46dec396b07e6737d6", size = 114626 }
+sdist = { url = "https://files.pythonhosted.org/packages/ce/37/dca4c8290c252f530e52e758f58e211bb047b34e15d52703355a357524f4/pdfplumber-0.11.6.tar.gz", hash = "sha256:d0f419e031641d9eac70dc18c60e1fc3ca2ec28cce7e149644923c030a0003ff", size = 115611 }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/18/fe/eebf169301bd1c1c69d639e81ba226d333d35c5ad105b7cd3cfc40a44862/pdfplumber-0.11.5-py3-none-any.whl", hash = "sha256:a6e0921a57e0ef7356001a0fd811250b0e37a0b42630a922ee48f55cdd534070", size = 59515 },
+    { url = "https://files.pythonhosted.org/packages/e6/c4/d2e09fbc937d1f76baae34e526662cc718e23a904321bf4a40282d190033/pdfplumber-0.11.6-py3-none-any.whl", hash = "sha256:169fc2b8dbf328c81a4e9bab30af0c304ad4b472fd7816616eabdb79dc5d9d17", size = 60233 },
 ]
 
 [[package]]
@@ -780,47 +812,50 @@ wheels = [
 
 [[package]]
 name = "pillow"
-version = "11.1.0"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/f3/af/c097e544e7bd278333db77933e535098c259609c4eb3b85381109602fb5b/pillow-11.1.0.tar.gz", hash = "sha256:368da70808b36d73b4b390a8ffac11069f8a5c85f29eff1f1b01bcf3ef5b2a20", size = 46742715 }
-wheels = [
-    { url = "https://files.pythonhosted.org/packages/b3/31/9ca79cafdce364fd5c980cd3416c20ce1bebd235b470d262f9d24d810184/pillow-11.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ae98e14432d458fc3de11a77ccb3ae65ddce70f730e7c76140653048c71bfcbc", size = 3226640 },
-    { url = "https://files.pythonhosted.org/packages/ac/0f/ff07ad45a1f172a497aa393b13a9d81a32e1477ef0e869d030e3c1532521/pillow-11.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cc1331b6d5a6e144aeb5e626f4375f5b7ae9934ba620c0ac6b3e43d5e683a0f0", size = 3101437 },
-    { url = "https://files.pythonhosted.org/packages/08/2f/9906fca87a68d29ec4530be1f893149e0cb64a86d1f9f70a7cfcdfe8ae44/pillow-11.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:758e9d4ef15d3560214cddbc97b8ef3ef86ce04d62ddac17ad39ba87e89bd3b1", size = 4326605 },
-    { url = "https://files.pythonhosted.org/packages/b0/0f/f3547ee15b145bc5c8b336401b2d4c9d9da67da9dcb572d7c0d4103d2c69/pillow-11.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b523466b1a31d0dcef7c5be1f20b942919b62fd6e9a9be199d035509cbefc0ec", size = 4411173 },
-    { url = "https://files.pythonhosted.org/packages/b1/df/bf8176aa5db515c5de584c5e00df9bab0713548fd780c82a86cba2c2fedb/pillow-11.1.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:9044b5e4f7083f209c4e35aa5dd54b1dd5b112b108648f5c902ad586d4f945c5", size = 4369145 },
-    { url = "https://files.pythonhosted.org/packages/de/7c/7433122d1cfadc740f577cb55526fdc39129a648ac65ce64db2eb7209277/pillow-11.1.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:3764d53e09cdedd91bee65c2527815d315c6b90d7b8b79759cc48d7bf5d4f114", size = 4496340 },
-    { url = "https://files.pythonhosted.org/packages/25/46/dd94b93ca6bd555588835f2504bd90c00d5438fe131cf01cfa0c5131a19d/pillow-11.1.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:31eba6bbdd27dde97b0174ddf0297d7a9c3a507a8a1480e1e60ef914fe23d352", size = 4296906 },
-    { url = "https://files.pythonhosted.org/packages/a8/28/2f9d32014dfc7753e586db9add35b8a41b7a3b46540e965cb6d6bc607bd2/pillow-11.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b5d658fbd9f0d6eea113aea286b21d3cd4d3fd978157cbf2447a6035916506d3", size = 4431759 },
-    { url = "https://files.pythonhosted.org/packages/33/48/19c2cbe7403870fbe8b7737d19eb013f46299cdfe4501573367f6396c775/pillow-11.1.0-cp313-cp313-win32.whl", hash = "sha256:f86d3a7a9af5d826744fabf4afd15b9dfef44fe69a98541f666f66fbb8d3fef9", size = 2291657 },
-    { url = "https://files.pythonhosted.org/packages/3b/ad/285c556747d34c399f332ba7c1a595ba245796ef3e22eae190f5364bb62b/pillow-11.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:593c5fd6be85da83656b93ffcccc2312d2d149d251e98588b14fbc288fd8909c", size = 2626304 },
-    { url = "https://files.pythonhosted.org/packages/e5/7b/ef35a71163bf36db06e9c8729608f78dedf032fc8313d19bd4be5c2588f3/pillow-11.1.0-cp313-cp313-win_arm64.whl", hash = "sha256:11633d58b6ee5733bde153a8dafd25e505ea3d32e261accd388827ee987baf65", size = 2375117 },
-    { url = "https://files.pythonhosted.org/packages/79/30/77f54228401e84d6791354888549b45824ab0ffde659bafa67956303a09f/pillow-11.1.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:70ca5ef3b3b1c4a0812b5c63c57c23b63e53bc38e758b37a951e5bc466449861", size = 3230060 },
-    { url = "https://files.pythonhosted.org/packages/ce/b1/56723b74b07dd64c1010fee011951ea9c35a43d8020acd03111f14298225/pillow-11.1.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:8000376f139d4d38d6851eb149b321a52bb8893a88dae8ee7d95840431977081", size = 3106192 },
-    { url = "https://files.pythonhosted.org/packages/e1/cd/7bf7180e08f80a4dcc6b4c3a0aa9e0b0ae57168562726a05dc8aa8fa66b0/pillow-11.1.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ee85f0696a17dd28fbcfceb59f9510aa71934b483d1f5601d1030c3c8304f3c", size = 4446805 },
-    { url = "https://files.pythonhosted.org/packages/97/42/87c856ea30c8ed97e8efbe672b58c8304dee0573f8c7cab62ae9e31db6ae/pillow-11.1.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:dd0e081319328928531df7a0e63621caf67652c8464303fd102141b785ef9547", size = 4530623 },
-    { url = "https://files.pythonhosted.org/packages/ff/41/026879e90c84a88e33fb00cc6bd915ac2743c67e87a18f80270dfe3c2041/pillow-11.1.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:e63e4e5081de46517099dc30abe418122f54531a6ae2ebc8680bcd7096860eab", size = 4465191 },
-    { url = "https://files.pythonhosted.org/packages/e5/fb/a7960e838bc5df57a2ce23183bfd2290d97c33028b96bde332a9057834d3/pillow-11.1.0-cp313-cp313t-win32.whl", hash = "sha256:dda60aa465b861324e65a78c9f5cf0f4bc713e4309f83bc387be158b077963d9", size = 2295494 },
-    { url = "https://files.pythonhosted.org/packages/d7/6c/6ec83ee2f6f0fda8d4cf89045c6be4b0373ebfc363ba8538f8c999f63fcd/pillow-11.1.0-cp313-cp313t-win_amd64.whl", hash = "sha256:ad5db5781c774ab9a9b2c4302bbf0c1014960a0a7be63278d13ae6fdf88126fe", size = 2631595 },
-    { url = "https://files.pythonhosted.org/packages/cf/6c/41c21c6c8af92b9fea313aa47c75de49e2f9a467964ee33eb0135d47eb64/pillow-11.1.0-cp313-cp313t-win_arm64.whl", hash = "sha256:67cd427c68926108778a9005f2a04adbd5e67c442ed21d95389fe1d595458756", size = 2377651 },
+version = "11.2.1"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/af/cb/bb5c01fcd2a69335b86c22142b2bccfc3464087efb7fd382eee5ffc7fdf7/pillow-11.2.1.tar.gz", hash = "sha256:a64dd61998416367b7ef979b73d3a85853ba9bec4c2925f74e588879a58716b6", size = 47026707 }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/36/9c/447528ee3776e7ab8897fe33697a7ff3f0475bb490c5ac1456a03dc57956/pillow-11.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:fdec757fea0b793056419bca3e9932eb2b0ceec90ef4813ea4c1e072c389eb28", size = 3190098 },
+    { url = "https://files.pythonhosted.org/packages/b5/09/29d5cd052f7566a63e5b506fac9c60526e9ecc553825551333e1e18a4858/pillow-11.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b0e130705d568e2f43a17bcbe74d90958e8a16263868a12c3e0d9c8162690830", size = 3030166 },
+    { url = "https://files.pythonhosted.org/packages/71/5d/446ee132ad35e7600652133f9c2840b4799bbd8e4adba881284860da0a36/pillow-11.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bdb5e09068332578214cadd9c05e3d64d99e0e87591be22a324bdbc18925be0", size = 4408674 },
+    { url = "https://files.pythonhosted.org/packages/69/5f/cbe509c0ddf91cc3a03bbacf40e5c2339c4912d16458fcb797bb47bcb269/pillow-11.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d189ba1bebfbc0c0e529159631ec72bb9e9bc041f01ec6d3233d6d82eb823bc1", size = 4496005 },
+    { url = "https://files.pythonhosted.org/packages/f9/b3/dd4338d8fb8a5f312021f2977fb8198a1184893f9b00b02b75d565c33b51/pillow-11.2.1-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:191955c55d8a712fab8934a42bfefbf99dd0b5875078240943f913bb66d46d9f", size = 4518707 },
+    { url = "https://files.pythonhosted.org/packages/13/eb/2552ecebc0b887f539111c2cd241f538b8ff5891b8903dfe672e997529be/pillow-11.2.1-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:ad275964d52e2243430472fc5d2c2334b4fc3ff9c16cb0a19254e25efa03a155", size = 4610008 },
+    { url = "https://files.pythonhosted.org/packages/72/d1/924ce51bea494cb6e7959522d69d7b1c7e74f6821d84c63c3dc430cbbf3b/pillow-11.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:750f96efe0597382660d8b53e90dd1dd44568a8edb51cb7f9d5d918b80d4de14", size = 4585420 },
+    { url = "https://files.pythonhosted.org/packages/43/ab/8f81312d255d713b99ca37479a4cb4b0f48195e530cdc1611990eb8fd04b/pillow-11.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fe15238d3798788d00716637b3d4e7bb6bde18b26e5d08335a96e88564a36b6b", size = 4667655 },
+    { url = "https://files.pythonhosted.org/packages/94/86/8f2e9d2dc3d308dfd137a07fe1cc478df0a23d42a6c4093b087e738e4827/pillow-11.2.1-cp313-cp313-win32.whl", hash = "sha256:3fe735ced9a607fee4f481423a9c36701a39719252a9bb251679635f99d0f7d2", size = 2332329 },
+    { url = "https://files.pythonhosted.org/packages/6d/ec/1179083b8d6067a613e4d595359b5fdea65d0a3b7ad623fee906e1b3c4d2/pillow-11.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:74ee3d7ecb3f3c05459ba95eed5efa28d6092d751ce9bf20e3e253a4e497e691", size = 2676388 },
+    { url = "https://files.pythonhosted.org/packages/23/f1/2fc1e1e294de897df39fa8622d829b8828ddad938b0eaea256d65b84dd72/pillow-11.2.1-cp313-cp313-win_arm64.whl", hash = "sha256:5119225c622403afb4b44bad4c1ca6c1f98eed79db8d3bc6e4e160fc6339d66c", size = 2414950 },
+    { url = "https://files.pythonhosted.org/packages/c4/3e/c328c48b3f0ead7bab765a84b4977acb29f101d10e4ef57a5e3400447c03/pillow-11.2.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:8ce2e8411c7aaef53e6bb29fe98f28cd4fbd9a1d9be2eeea434331aac0536b22", size = 3192759 },
+    { url = "https://files.pythonhosted.org/packages/18/0e/1c68532d833fc8b9f404d3a642991441d9058eccd5606eab31617f29b6d4/pillow-11.2.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:9ee66787e095127116d91dea2143db65c7bb1e232f617aa5957c0d9d2a3f23a7", size = 3033284 },
+    { url = "https://files.pythonhosted.org/packages/b7/cb/6faf3fb1e7705fd2db74e070f3bf6f88693601b0ed8e81049a8266de4754/pillow-11.2.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9622e3b6c1d8b551b6e6f21873bdcc55762b4b2126633014cea1803368a9aa16", size = 4445826 },
+    { url = "https://files.pythonhosted.org/packages/07/94/8be03d50b70ca47fb434a358919d6a8d6580f282bbb7af7e4aa40103461d/pillow-11.2.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63b5dff3a68f371ea06025a1a6966c9a1e1ee452fc8020c2cd0ea41b83e9037b", size = 4527329 },
+    { url = "https://files.pythonhosted.org/packages/fd/a4/bfe78777076dc405e3bd2080bc32da5ab3945b5a25dc5d8acaa9de64a162/pillow-11.2.1-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:31df6e2d3d8fc99f993fd253e97fae451a8db2e7207acf97859732273e108406", size = 4549049 },
+    { url = "https://files.pythonhosted.org/packages/65/4d/eaf9068dc687c24979e977ce5677e253624bd8b616b286f543f0c1b91662/pillow-11.2.1-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:062b7a42d672c45a70fa1f8b43d1d38ff76b63421cbbe7f88146b39e8a558d91", size = 4635408 },
+    { url = "https://files.pythonhosted.org/packages/1d/26/0fd443365d9c63bc79feb219f97d935cd4b93af28353cba78d8e77b61719/pillow-11.2.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4eb92eca2711ef8be42fd3f67533765d9fd043b8c80db204f16c8ea62ee1a751", size = 4614863 },
+    { url = "https://files.pythonhosted.org/packages/49/65/dca4d2506be482c2c6641cacdba5c602bc76d8ceb618fd37de855653a419/pillow-11.2.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f91ebf30830a48c825590aede79376cb40f110b387c17ee9bd59932c961044f9", size = 4692938 },
+    { url = "https://files.pythonhosted.org/packages/b3/92/1ca0c3f09233bd7decf8f7105a1c4e3162fb9142128c74adad0fb361b7eb/pillow-11.2.1-cp313-cp313t-win32.whl", hash = "sha256:e0b55f27f584ed623221cfe995c912c61606be8513bfa0e07d2c674b4516d9dd", size = 2335774 },
+    { url = "https://files.pythonhosted.org/packages/a5/ac/77525347cb43b83ae905ffe257bbe2cc6fd23acb9796639a1f56aa59d191/pillow-11.2.1-cp313-cp313t-win_amd64.whl", hash = "sha256:36d6b82164c39ce5482f649b437382c0fb2395eabc1e2b1702a6deb8ad647d6e", size = 2681895 },
+    { url = "https://files.pythonhosted.org/packages/67/32/32dc030cfa91ca0fc52baebbba2e009bb001122a1daa8b6a79ad830b38d3/pillow-11.2.1-cp313-cp313t-win_arm64.whl", hash = "sha256:225c832a13326e34f212d2072982bb1adb210e0cc0b153e688743018c94a2681", size = 2417234 },
 ]
 
 [[package]]
 name = "plac"
-version = "1.4.3"
+version = "1.4.5"
 source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/9b/79/1edb4c836c69306d0ecb0865f46d62ea7e28ef16b3f95bb394e4f2a46330/plac-1.4.3.tar.gz", hash = "sha256:d4cb3387b2113a28aebd509433d0264a4e5d9bb7c1a86db4fbd0a8f11af74eb3", size = 38984 }
+sdist = { url = "https://files.pythonhosted.org/packages/23/09/26ef2d614cabdcc52a7f383d0dc7967bf46be3c9700898c594e37b710c3d/plac-1.4.5.tar.gz", hash = "sha256:5f05bf85235c017fcd76c73c8101d4ff8e96beb3dc58b9a37de49cac7de82d14", size = 38988 }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/8f/af/4c61d2ac0d589719f548f5a1ba919738e44bac7b0c723ce147de5556d233/plac-1.4.3-py2.py3-none-any.whl", hash = "sha256:8a84fde8f950c9de6588a2d53c9deeac3ba1ddb456d887a33228460cf6549750", size = 22458 },
+    { url = "https://files.pythonhosted.org/packages/15/36/38676114a0dbee137ec366daa86603d667a07e9a52667d5ebf5c580100ba/plac-1.4.5-py2.py3-none-any.whl", hash = "sha256:87187786b4e446688b1cf5112e18fed8a23ab3b316c25fe91266a10bd1736b16", size = 22468 },
 ]
 
 [[package]]
 name = "platformdirs"
-version = "4.3.6"
+version = "4.3.8"
 source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/13/fc/128cc9cb8f03208bdbf93d3aa862e16d376844a14f9a0ce5cf4507372de4/platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907", size = 21302 }
+sdist = { url = "https://files.pythonhosted.org/packages/fe/8b/3c73abc9c759ecd3f1f7ceff6685840859e8070c4d947c93fae71f6a0bf2/platformdirs-4.3.8.tar.gz", hash = "sha256:3d512d96e16bcb959a814c9f348431070822a6496326a4be0911c40b5a74c2bc", size = 21362 }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/3c/a6/bc1012356d8ece4d66dd75c4b9fc6c1f6650ddd5991e421177d9f8f671be/platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb", size = 18439 },
+    { url = "https://files.pythonhosted.org/packages/fe/39/979e8e21520d4e47a0bbe349e2713c0aac6f3d853d0e5b34d76206c439aa/platformdirs-4.3.8-py3-none-any.whl", hash = "sha256:ff7059bb7eb1179e2685604f4aaf157cfd9535242bd23742eadc3c13542139b4", size = 18567 },
 ]
 
 [[package]]
@@ -867,7 +902,7 @@ wheels = [
 
 [[package]]
 name = "pyinstaller"
-version = "6.12.0"
+version = "6.13.0"
 source = { registry = "https://pypi.org/simple" }
 dependencies = [
     { name = "altgraph" },
@@ -878,45 +913,45 @@ dependencies = [
     { name = "pywin32-ctypes", marker = "sys_platform == 'win32'" },
     { name = "setuptools" },
 ]
-sdist = { url = "https://files.pythonhosted.org/packages/10/c0/001e86a13f9f6104613f198721c72d377fa1fc2a09550cfe1ac9a1d12406/pyinstaller-6.12.0.tar.gz", hash = "sha256:1834797be48ce1b26015af68bdeb3c61a6c7500136f04e0fc65e468115dec777", size = 4267132 }
+sdist = { url = "https://files.pythonhosted.org/packages/a8/b1/2949fe6d3874e961898ca5cfc1bf2cf13bdeea488b302e74a745bc28c8ba/pyinstaller-6.13.0.tar.gz", hash = "sha256:38911feec2c5e215e5159a7e66fdb12400168bd116143b54a8a7a37f08733456", size = 4276427 }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/b2/73/b897a3fda99a14130111abdb978d63da14cbc9932497b5e5064c5fe28187/pyinstaller-6.12.0-py3-none-macosx_10_13_universal2.whl", hash = "sha256:68f1e4cecf88a6272063977fa2a2c69ad37cf568e5901769d7206d0314c74f47", size = 997954 },
-    { url = "https://files.pythonhosted.org/packages/4a/bc/0929ed6aca3c5ff3f20f8cfd4f2f7e90f18c9465440e0d151d56d8170851/pyinstaller-6.12.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:fea76fc9b55ffa730fcf90beb897cce4399938460b0b6f40507fbebfc752c753", size = 714097 },
-    { url = "https://files.pythonhosted.org/packages/e1/9a/422d5eb04132e4a4735ca9099a53511324ff7d387b80231fe8dbd67bf322/pyinstaller-6.12.0-py3-none-manylinux2014_i686.whl", hash = "sha256:dac8a27988dbc33cdc34f2046803258bc3f6829de24de52745a5daa22bdba0f1", size = 724471 },
-    { url = "https://files.pythonhosted.org/packages/64/1c/5028ba2e09f5b57f6792e9d88e888725224f8f016a07666e48664f6a9fcf/pyinstaller-6.12.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:83c7f3bde9871b4a6aa71c66a96e8ba5c21668ce711ed97f510b9382d10aac6c", size = 722753 },
-    { url = "https://files.pythonhosted.org/packages/6f/d9/e7742caf4c4dc07d13e355ad2c14c7844c9bb2e66dea4f3386b4644bd106/pyinstaller-6.12.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:a69818815c6e0711c727edc30680cb1f81c691b59de35db81a2d9e0ae26a9ef1", size = 720906 },
-    { url = "https://files.pythonhosted.org/packages/80/2b/14404f2dc95d1ec94d08879c62a76d5f26a176fab99fb023c2c70d2ff500/pyinstaller-6.12.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:a2abf5fde31a8b38b6df7939bcef8ac1d0c51e97e25317ce3555cd675259750f", size = 716959 },
-    { url = "https://files.pythonhosted.org/packages/11/a6/5c3a233cf19aa6d4caacf62f7ee1c728486cc20b73f5817be17485d7b7ff/pyinstaller-6.12.0-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:8e92e9873a616547bbabbb5a3a9843d5f2ab40c3d8b26810acdf0fe257bee4cf", size = 719414 },
-    { url = "https://files.pythonhosted.org/packages/24/57/069d35236806b281a3331ef00ff94e43f3b91e4b36350de8b40b4baf9fd3/pyinstaller-6.12.0-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:aefe502d55c9cf6aeaed7feba80b5f8491ce43f8f2b5fe2d9aadca3ee5a05bc4", size = 715903 },
-    { url = "https://files.pythonhosted.org/packages/4d/5f/857de8798836f9d16a620bd0a7c8899bba05b5fda7b3b4432762f148a86d/pyinstaller-6.12.0-py3-none-win32.whl", hash = "sha256:138856a5a503bb69c066377e0a22671b0db063e9cc14d5cf5c798a53561200d3", size = 1290980 },
-    { url = "https://files.pythonhosted.org/packages/99/6e/d7d76d4d15f6351f1f942256633b795eec3d6c691d985869df1bf319cd9d/pyinstaller-6.12.0-py3-none-win_amd64.whl", hash = "sha256:0e62d3906309248409f215b386f33afec845214e69cc0f296b93222b26a88f43", size = 1348786 },
-    { url = "https://files.pythonhosted.org/packages/47/c2/298ad6a3aa2cacb55cbc1f845068dc1e4a6c966082ffa0e19c69084cbc42/pyinstaller-6.12.0-py3-none-win_arm64.whl", hash = "sha256:0c271896a3a168f4f91827145702543db9c5427f4c7372a6df8c75925a3ac18a", size = 1289617 },
+    { url = "https://files.pythonhosted.org/packages/b4/02/d1a347d35b1b627da1e148159e617576555619ac3bb8bbd5fed661fc7bb5/pyinstaller-6.13.0-py3-none-macosx_10_13_universal2.whl", hash = "sha256:aa404f0b02cd57948098055e76ee190b8e65ccf7a2a3f048e5000f668317069f", size = 1001923 },
+    { url = "https://files.pythonhosted.org/packages/6b/80/6da39f7aeac65c9ca5afad0fac37887d75fdfd480178a7077c9d30b0704c/pyinstaller-6.13.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:92efcf2f09e78f07b568c5cb7ed48c9940f5dad627af4b49bede6320fab2a06e", size = 718135 },
+    { url = "https://files.pythonhosted.org/packages/05/2c/d21d31f780a489609e7bf6385c0f7635238dc98b37cba8645b53322b7450/pyinstaller-6.13.0-py3-none-manylinux2014_i686.whl", hash = "sha256:9f82f113c463f012faa0e323d952ca30a6f922685d9636e754bd3a256c7ed200", size = 728543 },
+    { url = "https://files.pythonhosted.org/packages/e1/20/e6ca87bbed6c0163533195707f820f05e10b8da1223fc6972cfe3c3c50c7/pyinstaller-6.13.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:db0e7945ebe276f604eb7c36e536479556ab32853412095e19172a5ec8fca1c5", size = 726868 },
+    { url = "https://files.pythonhosted.org/packages/20/d5/53b19285f8817ab6c4b07c570208d62606bab0e5a049d50c93710a1d9dc6/pyinstaller-6.13.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:92fe7337c5aa08d42b38d7a79614492cb571489f2cb0a8f91dc9ef9ccbe01ed3", size = 725037 },
+    { url = "https://files.pythonhosted.org/packages/84/5b/08e0b305ba71e6d7cb247e27d714da7536895b0283132d74d249bf662366/pyinstaller-6.13.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:bc09795f5954135dd4486c1535650958c8218acb954f43860e4b05fb515a21c0", size = 721027 },
+    { url = "https://files.pythonhosted.org/packages/1f/9c/d8d0a7120103471be8dbe1c5419542aa794b9b9ec2ef628b542f9e6f9ef0/pyinstaller-6.13.0-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:589937548d34978c568cfdc39f31cf386f45202bc27fdb8facb989c79dfb4c02", size = 723443 },
+    { url = "https://files.pythonhosted.org/packages/52/c7/8a9d81569dda2352068ecc6ee779d5feff6729569dd1b4ffd1236ecd38fe/pyinstaller-6.13.0-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:b7260832f7501ba1d2ce1834d4cddc0f2b94315282bc89c59333433715015447", size = 719915 },
+    { url = "https://files.pythonhosted.org/packages/d5/e6/cccadb02b90198c7ed4ffb8bc34d420efb72b996f47cbd4738067a602d65/pyinstaller-6.13.0-py3-none-win32.whl", hash = "sha256:80c568848529635aa7ca46d8d525f68486d53e03f68b7bb5eba2c88d742e302c", size = 1294997 },
+    { url = "https://files.pythonhosted.org/packages/1a/06/15cbe0e25d1e73d5b981fa41ff0bb02b15e924e30b8c61256f4a28c4c837/pyinstaller-6.13.0-py3-none-win_amd64.whl", hash = "sha256:8d4296236b85aae570379488c2da833b28828b17c57c2cc21fccd7e3811fe372", size = 1352714 },
+    { url = "https://files.pythonhosted.org/packages/83/ef/74379298d46e7caa6aa7ceccc865106d3d4b15ac487ffdda2a35bfb6fe79/pyinstaller-6.13.0-py3-none-win_arm64.whl", hash = "sha256:d9f21d56ca2443aa6a1e255e7ad285c76453893a454105abe1b4d45e92bb9a20", size = 1293589 },
 ]
 
 [[package]]
 name = "pyinstaller-hooks-contrib"
-version = "2025.1"
+version = "2025.4"
 source = { registry = "https://pypi.org/simple" }
 dependencies = [
     { name = "packaging" },
     { name = "setuptools" },
 ]
-sdist = { url = "https://files.pythonhosted.org/packages/2f/1b/dc256d42f4217db99b50d6d32dbbf841a41b9615506cde77d2345d94f4a5/pyinstaller_hooks_contrib-2025.1.tar.gz", hash = "sha256:130818f9e9a0a7f2261f1fd66054966a3a50c99d000981c5d1db11d3ad0c6ab2", size = 147043 }
+sdist = { url = "https://files.pythonhosted.org/packages/e3/94/dfc5c7903306211798f990e6794c2eb7b8685ac487b26979e9255790419c/pyinstaller_hooks_contrib-2025.4.tar.gz", hash = "sha256:5ce1afd1997b03e70f546207031cfdf2782030aabacc102190677059e2856446", size = 162628 }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/b7/48/833d67a585275e395f351e5787b4b7a8d462d87bca22a8c038f6ffdc2b3c/pyinstaller_hooks_contrib-2025.1-py3-none-any.whl", hash = "sha256:d3c799470cbc0bda60dcc8e6b4ab976777532b77621337f2037f558905e3a8e9", size = 346409 },
+    { url = "https://files.pythonhosted.org/packages/d3/e1/ed48c7074145898e5c5b0072e87be975c5bd6a1d0f08c27a1daa7064fca0/pyinstaller_hooks_contrib-2025.4-py3-none-any.whl", hash = "sha256:6c2d73269b4c484eb40051fc1acee0beb113c2cfb3b37437b8394faae6f0d072", size = 434451 },
 ]
 
 [[package]]
 name = "pymdown-extensions"
-version = "10.14.3"
+version = "10.15"
 source = { registry = "https://pypi.org/simple" }
 dependencies = [
     { name = "markdown" },
     { name = "pyyaml" },
 ]
-sdist = { url = "https://files.pythonhosted.org/packages/7c/44/e6de2fdc880ad0ec7547ca2e087212be815efbc9a425a8d5ba9ede602cbb/pymdown_extensions-10.14.3.tar.gz", hash = "sha256:41e576ce3f5d650be59e900e4ceff231e0aed2a88cf30acaee41e02f063a061b", size = 846846 }
+sdist = { url = "https://files.pythonhosted.org/packages/08/92/a7296491dbf5585b3a987f3f3fc87af0e632121ff3e490c14b5f2d2b4eb5/pymdown_extensions-10.15.tar.gz", hash = "sha256:0e5994e32155f4b03504f939e501b981d306daf7ec2aa1cd2eb6bd300784f8f7", size = 852320 }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/eb/f5/b9e2a42aa8f9e34d52d66de87941ecd236570c7ed2e87775ed23bbe4e224/pymdown_extensions-10.14.3-py3-none-any.whl", hash = "sha256:05e0bee73d64b9c71a4ae17c72abc2f700e8bc8403755a00580b49a4e9f189e9", size = 264467 },
+    { url = "https://files.pythonhosted.org/packages/a7/d1/c54e608505776ce4e7966d03358ae635cfd51dff1da6ee421c090dbc797b/pymdown_extensions-10.15-py3-none-any.whl", hash = "sha256:46e99bb272612b0de3b7e7caf6da8dd5f4ca5212c0b273feb9304e236c484e5f", size = 265845 },
 ]
 
 [[package]]
@@ -1005,21 +1040,21 @@ wheels = [
 
 [[package]]
 name = "pytz"
-version = "2025.1"
+version = "2025.2"
 source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/5f/57/df1c9157c8d5a05117e455d66fd7cf6dbc46974f832b1058ed4856785d8a/pytz-2025.1.tar.gz", hash = "sha256:c2db42be2a2518b28e65f9207c4d05e6ff547d1efa4086469ef855e4ab70178e", size = 319617 }
+sdist = { url = "https://files.pythonhosted.org/packages/f8/bf/abbd3cdfb8fbc7fb3d4d38d320f2441b1e7cbe29be4f23797b4a2b5d8aac/pytz-2025.2.tar.gz", hash = "sha256:360b9e3dbb49a209c21ad61809c7fb453643e048b38924c765813546746e81c3", size = 320884 }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/eb/38/ac33370d784287baa1c3d538978b5e2ea064d4c1b93ffbd12826c190dd10/pytz-2025.1-py2.py3-none-any.whl", hash = "sha256:89dd22dca55b46eac6eda23b2d72721bf1bdfef212645d81513ef5d03038de57", size = 507930 },
+    { url = "https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl", hash = "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00", size = 509225 },
 ]
 
 [[package]]
 name = "pywin32"
-version = "308"
+version = "310"
 source = { registry = "https://pypi.org/simple" }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/a9/a4/aa562d8935e3df5e49c161b427a3a2efad2ed4e9cf81c3de636f1fdddfd0/pywin32-308-cp313-cp313-win32.whl", hash = "sha256:1c44539a37a5b7b21d02ab34e6a4d314e0788f1690d65b48e9b0b89f31abbbed", size = 5938579 },
-    { url = "https://files.pythonhosted.org/packages/c7/50/b0efb8bb66210da67a53ab95fd7a98826a97ee21f1d22949863e6d588b22/pywin32-308-cp313-cp313-win_amd64.whl", hash = "sha256:fd380990e792eaf6827fcb7e187b2b4b1cede0585e3d0c9e84201ec27b9905e4", size = 6542056 },
-    { url = "https://files.pythonhosted.org/packages/26/df/2b63e3e4f2df0224f8aaf6d131f54fe4e8c96400eb9df563e2aae2e1a1f9/pywin32-308-cp313-cp313-win_arm64.whl", hash = "sha256:ef313c46d4c18dfb82a2431e3051ac8f112ccee1a34f29c263c583c568db63cd", size = 7974986 },
+    { url = "https://files.pythonhosted.org/packages/1c/09/9c1b978ffc4ae53999e89c19c77ba882d9fce476729f23ef55211ea1c034/pywin32-310-cp313-cp313-win32.whl", hash = "sha256:5d241a659c496ada3253cd01cfaa779b048e90ce4b2b38cd44168ad555ce74ab", size = 8794384 },
+    { url = "https://files.pythonhosted.org/packages/45/3c/b4640f740ffebadd5d34df35fecba0e1cfef8fde9f3e594df91c28ad9b50/pywin32-310-cp313-cp313-win_amd64.whl", hash = "sha256:667827eb3a90208ddbdcc9e860c81bde63a135710e21e4cb3348968e4bd5249e", size = 9503039 },
+    { url = "https://files.pythonhosted.org/packages/b4/f4/f785020090fb050e7fb6d34b780f2231f302609dc964672f72bfaeb59a28/pywin32-310-cp313-cp313-win_arm64.whl", hash = "sha256:e308f831de771482b7cf692a1f308f8fca701b2d8f9dde6cc440c7da17e47b33", size = 8458152 },
 ]
 
 [[package]]
@@ -1050,14 +1085,14 @@ wheels = [
 
 [[package]]
 name = "pyyaml-env-tag"
-version = "0.1"
+version = "1.1"
 source = { registry = "https://pypi.org/simple" }
 dependencies = [
     { name = "pyyaml" },
 ]
-sdist = { url = "https://files.pythonhosted.org/packages/fb/8e/da1c6c58f751b70f8ceb1eb25bc25d524e8f14fe16edcce3f4e3ba08629c/pyyaml_env_tag-0.1.tar.gz", hash = "sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb", size = 5631 }
+sdist = { url = "https://files.pythonhosted.org/packages/eb/2e/79c822141bfd05a853236b504869ebc6b70159afc570e1d5a20641782eaa/pyyaml_env_tag-1.1.tar.gz", hash = "sha256:2eb38b75a2d21ee0475d6d97ec19c63287a7e140231e4214969d0eac923cd7ff", size = 5737 }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/5a/66/bbb1dd374f5c870f59c5bb1db0e18cbe7fa739415a24cbd95b2d1f5ae0c4/pyyaml_env_tag-0.1-py3-none-any.whl", hash = "sha256:af31106dec8a4d68c60207c1886031cbf839b68aa7abccdb19868200532c2069", size = 3911 },
+    { url = "https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl", hash = "sha256:17109e1a528561e32f026364712fee1264bc2ea6715120891174ed1b980d2e04", size = 4722 },
 ]
 
 [[package]]
@@ -1089,15 +1124,15 @@ wheels = [
 
 [[package]]
 name = "rich"
-version = "13.9.4"
+version = "14.0.0"
 source = { registry = "https://pypi.org/simple" }
 dependencies = [
     { name = "markdown-it-py" },
     { name = "pygments" },
 ]
-sdist = { url = "https://files.pythonhosted.org/packages/ab/3a/0316b28d0761c6734d6bc14e770d85506c986c85ffb239e688eeaab2c2bc/rich-13.9.4.tar.gz", hash = "sha256:439594978a49a09530cff7ebc4b5c7103ef57baf48d5ea3184f21d9a2befa098", size = 223149 }
+sdist = { url = "https://files.pythonhosted.org/packages/a1/53/830aa4c3066a8ab0ae9a9955976fb770fe9c6102117c8ec4ab3ea62d89e8/rich-14.0.0.tar.gz", hash = "sha256:82f1bc23a6a21ebca4ae0c45af9bdbc492ed20231dcb63f297d6d1021a9d5725", size = 224078 }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/19/71/39c7c0d87f8d4e6c020a393182060eaefeeae6c01dab6a84ec346f2567df/rich-13.9.4-py3-none-any.whl", hash = "sha256:6049d5e6ec054bf2779ab3358186963bac2ea89175919d699e378b99738c2a90", size = 242424 },
+    { url = "https://files.pythonhosted.org/packages/0d/9b/63f4c7ebc259242c89b3acafdb37b41d1185c07ff0011164674e9076b491/rich-14.0.0-py3-none-any.whl", hash = "sha256:1c9491e1951aac09caffd42f448ee3d04e58923ffe14993f6e83068dc395d7e0", size = 243229 },
 ]
 
 [[package]]
@@ -1111,11 +1146,11 @@ wheels = [
 
 [[package]]
 name = "setuptools"
-version = "75.8.2"
+version = "80.8.0"
 source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/d1/53/43d99d7687e8cdef5ab5f9ec5eaf2c0423c2b35133a2b7e7bc276fc32b21/setuptools-75.8.2.tar.gz", hash = "sha256:4880473a969e5f23f2a2be3646b2dfd84af9028716d398e46192f84bc36900d2", size = 1344083 }
+sdist = { url = "https://files.pythonhosted.org/packages/8d/d2/ec1acaaff45caed5c2dedb33b67055ba9d4e96b091094df90762e60135fe/setuptools-80.8.0.tar.gz", hash = "sha256:49f7af965996f26d43c8ae34539c8d99c5042fbff34302ea151eaa9c207cd257", size = 1319720 }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/a9/38/7d7362e031bd6dc121e5081d8cb6aa6f6fedf2b67bf889962134c6da4705/setuptools-75.8.2-py3-none-any.whl", hash = "sha256:558e47c15f1811c1fa7adbd0096669bf76c1d3f433f58324df69f3f5ecac4e8f", size = 1229385 },
+    { url = "https://files.pythonhosted.org/packages/58/29/93c53c098d301132196c3238c312825324740851d77a8500a2462c0fd888/setuptools-80.8.0-py3-none-any.whl", hash = "sha256:95a60484590d24103af13b686121328cc2736bee85de8936383111e421b9edc0", size = 1201470 },
 ]
 
 [[package]]
@@ -1138,37 +1173,37 @@ wheels = [
 
 [[package]]
 name = "soupsieve"
-version = "2.6"
+version = "2.7"
 source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/d7/ce/fbaeed4f9fb8b2daa961f90591662df6a86c1abf25c548329a86920aedfb/soupsieve-2.6.tar.gz", hash = "sha256:e2e68417777af359ec65daac1057404a3c8a5455bb8abc36f1a9866ab1a51abb", size = 101569 }
+sdist = { url = "https://files.pythonhosted.org/packages/3f/f4/4a80cd6ef364b2e8b65b15816a843c0980f7a5a2b4dc701fc574952aa19f/soupsieve-2.7.tar.gz", hash = "sha256:ad282f9b6926286d2ead4750552c8a6142bc4c783fd66b0293547c8fe6ae126a", size = 103418 }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/d1/c2/fe97d779f3ef3b15f05c94a2f1e3d21732574ed441687474db9d342a7315/soupsieve-2.6-py3-none-any.whl", hash = "sha256:e72c4ff06e4fb6e4b5a9f0f55fe6e81514581fca1515028625d0f299c602ccc9", size = 36186 },
+    { url = "https://files.pythonhosted.org/packages/e7/9c/0e6afc12c269578be5c0c1c9f4b49a8d32770a080260c333ac04cc1c832d/soupsieve-2.7-py3-none-any.whl", hash = "sha256:6e60cc5c1ffaf1cebcc12e8188320b72071e922c2e897f737cadce79ad5d30c4", size = 36677 },
 ]
 
 [[package]]
 name = "sqlalchemy"
-version = "2.0.38"
+version = "2.0.41"
 source = { registry = "https://pypi.org/simple" }
 dependencies = [
     { name = "greenlet", marker = "(python_full_version < '3.14' and platform_machine == 'AMD64') or (python_full_version < '3.14' and platform_machine == 'WIN32') or (python_full_version < '3.14' and platform_machine == 'aarch64') or (python_full_version < '3.14' and platform_machine == 'amd64') or (python_full_version < '3.14' and platform_machine == 'ppc64le') or (python_full_version < '3.14' and platform_machine == 'win32') or (python_full_version < '3.14' and platform_machine == 'x86_64')" },
     { name = "typing-extensions" },
 ]
-sdist = { url = "https://files.pythonhosted.org/packages/e4/08/9a90962ea72acd532bda71249a626344d855c4032603924b1b547694b837/sqlalchemy-2.0.38.tar.gz", hash = "sha256:e5a4d82bdb4bf1ac1285a68eab02d253ab73355d9f0fe725a97e1e0fa689decb", size = 9634782 }
+sdist = { url = "https://files.pythonhosted.org/packages/63/66/45b165c595ec89aa7dcc2c1cd222ab269bc753f1fc7a1e68f8481bd957bf/sqlalchemy-2.0.41.tar.gz", hash = "sha256:edba70118c4be3c2b1f90754d308d0b79c6fe2c0fdc52d8ddf603916f83f4db9", size = 9689424 }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/21/77/caa875a1f5a8a8980b564cc0e6fee1bc992d62d29101252561d0a5e9719c/SQLAlchemy-2.0.38-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ecef029b69843b82048c5b347d8e6049356aa24ed644006c9a9d7098c3bd3bfd", size = 2100201 },
-    { url = "https://files.pythonhosted.org/packages/f4/ec/94bb036ec78bf9a20f8010c807105da9152dd84f72e8c51681ad2f30b3fd/SQLAlchemy-2.0.38-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9c8bcad7fc12f0cc5896d8e10fdf703c45bd487294a986903fe032c72201596b", size = 2090678 },
-    { url = "https://files.pythonhosted.org/packages/7b/61/63ff1893f146e34d3934c0860209fdd3925c25ee064330e6c2152bacc335/SQLAlchemy-2.0.38-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2a0ef3f98175d77180ffdc623d38e9f1736e8d86b6ba70bff182a7e68bed7727", size = 3177107 },
-    { url = "https://files.pythonhosted.org/packages/a9/4f/b933bea41a602b5f274065cc824fae25780ed38664d735575192490a021b/SQLAlchemy-2.0.38-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b0ac78898c50e2574e9f938d2e5caa8fe187d7a5b69b65faa1ea4648925b096", size = 3190435 },
-    { url = "https://files.pythonhosted.org/packages/f5/23/9e654b4059e385988de08c5d3b38a369ea042f4c4d7c8902376fd737096a/SQLAlchemy-2.0.38-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9eb4fa13c8c7a2404b6a8e3772c17a55b1ba18bc711e25e4d6c0c9f5f541b02a", size = 3123648 },
-    { url = "https://files.pythonhosted.org/packages/83/59/94c6d804e76ebc6412a08d2b086a8cb3e5a056cd61508e18ddaf3ec70100/SQLAlchemy-2.0.38-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5dba1cdb8f319084f5b00d41207b2079822aa8d6a4667c0f369fce85e34b0c86", size = 3151789 },
-    { url = "https://files.pythonhosted.org/packages/b2/27/17f143013aabbe1256dce19061eafdce0b0142465ce32168cdb9a18c04b1/SQLAlchemy-2.0.38-cp313-cp313-win32.whl", hash = "sha256:eae27ad7580529a427cfdd52c87abb2dfb15ce2b7a3e0fc29fbb63e2ed6f8120", size = 2073023 },
-    { url = "https://files.pythonhosted.org/packages/e2/3e/259404b03c3ed2e7eee4c179e001a07d9b61070334be91124cf4ad32eec7/SQLAlchemy-2.0.38-cp313-cp313-win_amd64.whl", hash = "sha256:b335a7c958bc945e10c522c069cd6e5804f4ff20f9a744dd38e748eb602cbbda", size = 2096908 },
-    { url = "https://files.pythonhosted.org/packages/aa/e4/592120713a314621c692211eba034d09becaf6bc8848fabc1dc2a54d8c16/SQLAlchemy-2.0.38-py3-none-any.whl", hash = "sha256:63178c675d4c80def39f1febd625a6333f44c0ba269edd8a468b156394b27753", size = 1896347 },
+    { url = "https://files.pythonhosted.org/packages/d3/ad/2e1c6d4f235a97eeef52d0200d8ddda16f6c4dd70ae5ad88c46963440480/sqlalchemy-2.0.41-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4eeb195cdedaf17aab6b247894ff2734dcead6c08f748e617bfe05bd5a218443", size = 2115491 },
+    { url = "https://files.pythonhosted.org/packages/cf/8d/be490e5db8400dacc89056f78a52d44b04fbf75e8439569d5b879623a53b/sqlalchemy-2.0.41-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d4ae769b9c1c7757e4ccce94b0641bc203bbdf43ba7a2413ab2523d8d047d8dc", size = 2102827 },
+    { url = "https://files.pythonhosted.org/packages/a0/72/c97ad430f0b0e78efaf2791342e13ffeafcbb3c06242f01a3bb8fe44f65d/sqlalchemy-2.0.41-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a62448526dd9ed3e3beedc93df9bb6b55a436ed1474db31a2af13b313a70a7e1", size = 3225224 },
+    { url = "https://files.pythonhosted.org/packages/5e/51/5ba9ea3246ea068630acf35a6ba0d181e99f1af1afd17e159eac7e8bc2b8/sqlalchemy-2.0.41-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc56c9788617b8964ad02e8fcfeed4001c1f8ba91a9e1f31483c0dffb207002a", size = 3230045 },
+    { url = "https://files.pythonhosted.org/packages/78/2f/8c14443b2acea700c62f9b4a8bad9e49fc1b65cfb260edead71fd38e9f19/sqlalchemy-2.0.41-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c153265408d18de4cc5ded1941dcd8315894572cddd3c58df5d5b5705b3fa28d", size = 3159357 },
+    { url = "https://files.pythonhosted.org/packages/fc/b2/43eacbf6ccc5276d76cea18cb7c3d73e294d6fb21f9ff8b4eef9b42bbfd5/sqlalchemy-2.0.41-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f67766965996e63bb46cfbf2ce5355fc32d9dd3b8ad7e536a920ff9ee422e23", size = 3197511 },
+    { url = "https://files.pythonhosted.org/packages/fa/2e/677c17c5d6a004c3c45334ab1dbe7b7deb834430b282b8a0f75ae220c8eb/sqlalchemy-2.0.41-cp313-cp313-win32.whl", hash = "sha256:bfc9064f6658a3d1cadeaa0ba07570b83ce6801a1314985bf98ec9b95d74e15f", size = 2082420 },
+    { url = "https://files.pythonhosted.org/packages/e9/61/e8c1b9b6307c57157d328dd8b8348ddc4c47ffdf1279365a13b2b98b8049/sqlalchemy-2.0.41-cp313-cp313-win_amd64.whl", hash = "sha256:82ca366a844eb551daff9d2e6e7a9e5e76d2612c8564f58db6c19a726869c1df", size = 2108329 },
+    { url = "https://files.pythonhosted.org/packages/1c/fc/9ba22f01b5cdacc8f5ed0d22304718d2c758fce3fd49a5372b886a86f37c/sqlalchemy-2.0.41-py3-none-any.whl", hash = "sha256:57df5dc6fdb5ed1a88a1ed2195fd31927e705cad62dedd86b46972752a80f576", size = 1911224 },
 ]
 
 [[package]]
 name = "typer"
-version = "0.15.2"
+version = "0.15.4"
 source = { registry = "https://pypi.org/simple" }
 dependencies = [
     { name = "click" },
@@ -1176,27 +1211,27 @@ dependencies = [
     { name = "shellingham" },
     { name = "typing-extensions" },
 ]
-sdist = { url = "https://files.pythonhosted.org/packages/8b/6f/3991f0f1c7fcb2df31aef28e0594d8d54b05393a0e4e34c65e475c2a5d41/typer-0.15.2.tar.gz", hash = "sha256:ab2fab47533a813c49fe1f16b1a370fd5819099c00b119e0633df65f22144ba5", size = 100711 }
+sdist = { url = "https://files.pythonhosted.org/packages/6c/89/c527e6c848739be8ceb5c44eb8208c52ea3515c6cf6406aa61932887bf58/typer-0.15.4.tar.gz", hash = "sha256:89507b104f9b6a0730354f27c39fae5b63ccd0c95b1ce1f1a6ba0cfd329997c3", size = 101559 }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/7f/fc/5b29fea8cee020515ca82cc68e3b8e1e34bb19a3535ad854cac9257b414c/typer-0.15.2-py3-none-any.whl", hash = "sha256:46a499c6107d645a9c13f7ee46c5d5096cae6f5fc57dd11eccbbb9ae3e44ddfc", size = 45061 },
+    { url = "https://files.pythonhosted.org/packages/c9/62/d4ba7afe2096d5659ec3db8b15d8665bdcb92a3c6ff0b95e99895b335a9c/typer-0.15.4-py3-none-any.whl", hash = "sha256:eb0651654dcdea706780c466cf06d8f174405a659ffff8f163cfbfee98c0e173", size = 45258 },
 ]
 
 [[package]]
 name = "typing-extensions"
-version = "4.12.2"
+version = "4.13.2"
 source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321 }
+sdist = { url = "https://files.pythonhosted.org/packages/f6/37/23083fcd6e35492953e8d2aaaa68b860eb422b34627b13f2ce3eb6106061/typing_extensions-4.13.2.tar.gz", hash = "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef", size = 106967 }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438 },
+    { url = "https://files.pythonhosted.org/packages/8b/54/b1ae86c0973cc6f0210b53d508ca3641fb6d0c56823f288d108bc7ab3cc8/typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c", size = 45806 },
 ]
 
 [[package]]
 name = "tzdata"
-version = "2025.1"
+version = "2025.2"
 source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/43/0f/fa4723f22942480be4ca9527bbde8d43f6c3f2fe8412f00e7f5f6746bc8b/tzdata-2025.1.tar.gz", hash = "sha256:24894909e88cdb28bd1636c6887801df64cb485bd593f2fd83ef29075a81d694", size = 194950 }
+sdist = { url = "https://files.pythonhosted.org/packages/95/32/1a225d6164441be760d75c2c42e2780dc0873fe382da3e98a2e1e48361e5/tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9", size = 196380 }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/0f/dd/84f10e23edd882c6f968c21c2434fe67bd4a528967067515feca9e611e5e/tzdata-2025.1-py2.py3-none-any.whl", hash = "sha256:7e127113816800496f027041c570f50bcd464a020098a3b6b199517772303639", size = 346762 },
+    { url = "https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8", size = 347839 },
 ]
 
 [[package]]
@@ -1207,11 +1242,11 @@ sdist = { url = "https://files.pythonhosted.org/packages/ad/53/6c420ddf6949097d6
 
 [[package]]
 name = "urllib3"
-version = "2.3.0"
+version = "2.4.0"
 source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/aa/63/e53da845320b757bf29ef6a9062f5c669fe997973f966045cb019c3f4b66/urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d", size = 307268 }
+sdist = { url = "https://files.pythonhosted.org/packages/8a/78/16493d9c386d8e60e442a35feac5e00f0913c0f4b7c217c11e8ec2ff53e0/urllib3-2.4.0.tar.gz", hash = "sha256:414bc6535b787febd7567804cc015fee39daab8ad86268f1310a9250697de466", size = 390672 }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/c8/19/4ec628951a74043532ca2cf5d97b7b14863931476d117c471e8e2b1eb39f/urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df", size = 128369 },
+    { url = "https://files.pythonhosted.org/packages/6b/11/cc635220681e93a0183390e26485430ca2c7b5f9d33b15c74c2861cb8091/urllib3-2.4.0-py3-none-any.whl", hash = "sha256:4e16665048960a0900c702d4a66415956a584919c03361cac9f1df5c5dd7e813", size = 128680 },
 ]
 
 [[package]]
@@ -1258,22 +1293,22 @@ wheels = [
 
 [[package]]
 name = "xlwings"
-version = "0.33.9"
+version = "0.33.15"
 source = { registry = "https://pypi.org/simple" }
 dependencies = [
     { name = "appscript", marker = "sys_platform == 'darwin'" },
     { name = "psutil", marker = "sys_platform == 'darwin'" },
     { name = "pywin32", marker = "sys_platform == 'win32'" },
 ]
-sdist = { url = "https://files.pythonhosted.org/packages/f8/58/f40549d71c56a1891a03ecbdacdca38c4cffde7f781f97e2019b88129328/xlwings-0.33.9.tar.gz", hash = "sha256:3c2f73abf482c54b09280e17d8fb342a911a6d97628085d20bbf4cc9dbf413bc", size = 15701028 }
-wheels = [
-    { url = "https://files.pythonhosted.org/packages/ed/3a/9958c66ed82f1e817bd6cbdb9448d6b7c484012f54f8de07cb9452ce4d27/xlwings-0.33.9-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7891788ff7362afc6bda5df95e2c1c7ad4340fe04928aecb7e085766b0065fa9", size = 1420788 },
-    { url = "https://files.pythonhosted.org/packages/1c/df/fd1ab2b9ed33b55d6920531ab4517f3a40ddcd61cd4a579ebf7541104702/xlwings-0.33.9-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c804bf4c012f71291c8a76c06b2f0cdfcabc4eb308c98f99e0867c96f2d2ee8c", size = 1408728 },
-    { url = "https://files.pythonhosted.org/packages/db/08/ab9fdaa34c23a95cc3428afd2401601c92d47562157906be40bf4c58598e/xlwings-0.33.9-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b42d3c933d757835b27c4d0ba654b5e50460d30bae7dadfa19de8d333c21c04", size = 1465318 },
-    { url = "https://files.pythonhosted.org/packages/0d/94/a714aeaf9af9a6d834578f2970bfad2e27b1a3dc8fab968adefaa68cc665/xlwings-0.33.9-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8095a309015ff21aff6d4d9215be84e7ea6f01d22b1c95b37f5fa5f64213c710", size = 1474147 },
-    { url = "https://files.pythonhosted.org/packages/c6/82/87fe5698f85d3adb9c8c9f6cbdaf6509ae4f4fcdcb86b425e8c0a2d2d7a2/xlwings-0.33.9-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c8934c6a3c88b4af264611249077fa6cb4c2cbb8c4a4a854c523e136e86fc61", size = 1476157 },
-    { url = "https://files.pythonhosted.org/packages/ed/d4/1b2fefc67f55a46510751991129bd86d27b99895430a16f01aff1b79bdff/xlwings-0.33.9-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:62b5b4036b711b49ca941f045aa12fbabd0dde01837ec089829edd6d936c0e31", size = 1634407 },
-    { url = "https://files.pythonhosted.org/packages/17/16/45f673e97aa6e574b8bd7000d78f016c37aef29b8087dddd56bec7da6bf3/xlwings-0.33.9-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ec6bc7fae95299c4e3ef2a9f99c0b8a5b24a900f9a163a9e1cee0299c47f2a60", size = 1636806 },
-    { url = "https://files.pythonhosted.org/packages/67/86/13435c6127772d2636035d25374145442c0140bc2e7641280b1bb33821a1/xlwings-0.33.9-cp313-cp313-win_amd64.whl", hash = "sha256:85c293996fc07cbe1daebf514d525fb098b340c895f8e6206a6545b9ac20c253", size = 1630512 },
-    { url = "https://files.pythonhosted.org/packages/f5/c0/2a33917a2aa6524c1e12b5496de9fb3653c263dbfe83efc7765ed36a0efc/xlwings-0.33.9-py3-none-any.whl", hash = "sha256:228bdc4e90938ca2a87917b095883b96ce3dc68d610871034590638cd8688e59", size = 729924 },
+sdist = { url = "https://files.pythonhosted.org/packages/ba/02/15d3d2f5c1ad526a925fe0549a7f0ae35e19ca9cfecf94e61b0891ce5e3d/xlwings-0.33.15.tar.gz", hash = "sha256:c3fdeda516d87cfda0316daf3b97b49e31bde577007cefb6b6a245850546daa6", size = 15703229 }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/b9/dd/c45acbe75fae1ec825e0da8e00d320398f960343927ec7eb6020254b51e8/xlwings-0.33.15-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:6042c620283325c80ba1341e59c1d128291df0bf4b8cb0b8e77d6ab9ac4fa5ee", size = 1414871 },
+    { url = "https://files.pythonhosted.org/packages/63/19/0d4c458c0d2f7124849fd06acc5ce6010090280dbf0f99a36845b5901238/xlwings-0.33.15-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:48aba2431f7b470e838fac6d79e8a030cf98939e48b127e248ea79a5f21bb4e9", size = 1401453 },
+    { url = "https://files.pythonhosted.org/packages/ef/6b/9556746939f655d51d60d4ccfd04502d8460d0e872220c3df6bcd41d14c8/xlwings-0.33.15-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a81589fcabe92bf5a79aa7fc01221074b6c50e5a8b69a27e8fc28df365bd398b", size = 1459079 },
+    { url = "https://files.pythonhosted.org/packages/29/c6/fad054ed257f8a12e34ded0f629c413d1d52bd95d17cd0ab2560364622a4/xlwings-0.33.15-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:106b0e33a8e2459c3cd76e3bba5f938876dc75c8a03aadd2f226ce3c6f9fe95b", size = 1464481 },
+    { url = "https://files.pythonhosted.org/packages/ed/32/7ba3cdb4d9c6df4657f160900ed609e7be718417ca24ff18fa40d97350e2/xlwings-0.33.15-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aea8fdfbf340d68b0c1f96abf6cd5688cb0d243df0893627a6c66283babda365", size = 1466001 },
+    { url = "https://files.pythonhosted.org/packages/d6/ee/85b28c143da1834215b5f0b0525c5d99fd01f0096f027e8f97d163c825d9/xlwings-0.33.15-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:09c0090ae5ac42845430c1370d4798a882bbfdae6e36186918824b3b392da5d9", size = 1638238 },
+    { url = "https://files.pythonhosted.org/packages/43/8a/78275c61601b682ec69db0ec7c05e1b1043da729017c5a1ac2769787df81/xlwings-0.33.15-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:390b9753040a44db35eb473cf818ae57145c49a9e7e5cb02c9fd750bdf3da583", size = 1637256 },
+    { url = "https://files.pythonhosted.org/packages/76/43/ed764fab5455676138578d6905c59674acf7f45eed3d451e8faf48c7c4b5/xlwings-0.33.15-cp313-cp313-win_amd64.whl", hash = "sha256:75b0dba6fea351421be00afcb00e218d7370c3e62c92c8207db2ca95500f5589", size = 1630573 },
+    { url = "https://files.pythonhosted.org/packages/db/5f/7a1cbfe8ff468efdcb6222ebb46ec606a209740b6d680f78ca2fa2114909/xlwings-0.33.15-py3-none-any.whl", hash = "sha256:84f1bf30bbb3f28dfab7140667cd1575efa016969a8a37e56a0cd7d77ee152e4", size = 732584 },
 ]

Some files were not shown because too many files changed in this diff