arelle-release 2.37.12__py3-none-any.whl → 2.37.13__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of arelle-release might be problematic. Click here for more details.

Files changed (27) hide show
  1. arelle/CntlrCmdLine.py +1 -66
  2. arelle/ModelDtsObject.py +1 -1
  3. arelle/ModelInstanceObject.py +9 -0
  4. arelle/ModelTestcaseObject.py +1 -1
  5. arelle/Validate.py +44 -21
  6. arelle/_version.py +2 -2
  7. arelle/formula/XPathParser.py +9 -3
  8. arelle/packages/report/ReportPackage.py +7 -3
  9. arelle/packages/report/ReportPackageValidator.py +4 -3
  10. arelle/plugin/inlineXbrlDocumentSet.py +1 -1
  11. arelle/plugin/validate/ESEF/ESEF_2021/ValidateXbrlFinally.py +3 -3
  12. arelle/plugin/validate/ESEF/ESEF_Current/ValidateXbrlFinally.py +4 -5
  13. arelle/plugin/validate/NL/PluginValidationDataExtension.py +21 -18
  14. arelle/plugin/validate/NL/__init__.py +0 -11
  15. arelle/plugin/validate/NL/rules/nl_kvk.py +60 -0
  16. arelle/plugin/validate/ROS/rules/ros.py +1 -1
  17. arelle/typing.py +8 -1
  18. arelle/utils/EntryPointDetection.py +73 -0
  19. {arelle_release-2.37.12.dist-info → arelle_release-2.37.13.dist-info}/METADATA +1 -1
  20. {arelle_release-2.37.12.dist-info → arelle_release-2.37.13.dist-info}/RECORD +27 -26
  21. {arelle_release-2.37.12.dist-info → arelle_release-2.37.13.dist-info}/WHEEL +1 -1
  22. tests/integration_tests/ui_tests/ArelleGUITest/ArelleGUITest/ArelleGUITest.csproj +1 -1
  23. tests/integration_tests/validation/conformance_suite_configurations/nl_inline_2024.py +4 -7
  24. tests/integration_tests/validation/conformance_suite_configurations/xbrl_report_packages_1_0.py +3 -1
  25. {arelle_release-2.37.12.dist-info → arelle_release-2.37.13.dist-info}/entry_points.txt +0 -0
  26. {arelle_release-2.37.12.dist-info → arelle_release-2.37.13.dist-info}/licenses/LICENSE.md +0 -0
  27. {arelle_release-2.37.12.dist-info → arelle_release-2.37.13.dist-info}/top_level.txt +0 -0
arelle/CntlrCmdLine.py CHANGED
@@ -56,6 +56,7 @@ from arelle.RuntimeOptions import RuntimeOptions, RuntimeOptionsException
56
56
  from arelle.SocketUtils import INTERNET_CONNECTIVITY, OFFLINE
57
57
  from arelle.SystemInfo import PlatformOS, getSystemInfo, getSystemWordSize, hasWebServer, isCGI, isGAE
58
58
  from arelle.typing import TypeGetText
59
+ from arelle.utils.EntryPointDetection import filesourceEntrypointFiles
59
60
  from arelle.UrlUtil import isHttpUrl
60
61
  from arelle.ValidateXbrlDTS import ValidateBaseTaxonomiesMode
61
62
  from arelle.WebCache import proxyTuple
@@ -585,72 +586,6 @@ def configAndRunCntlr(options, arellePluginModules):
585
586
  return cntlr
586
587
 
587
588
 
588
- def filesourceEntrypointFiles(filesource, entrypointFiles=None, inlineOnly=False):
589
- if entrypointFiles is None:
590
- entrypointFiles = []
591
- if filesource.isArchive:
592
- if filesource.isTaxonomyPackage: # if archive is also a taxonomy package, activate mappings
593
- filesource.loadTaxonomyPackageMappings()
594
- # HF note: a web api request to load a specific file from archive is ignored, is this right?
595
- del entrypointFiles[:] # clear out archive from entrypointFiles
596
- if reportPackage := filesource.reportPackage:
597
- assert isinstance(filesource.basefile, str)
598
- for report in reportPackage.reports or []:
599
- if report.isInline:
600
- reportEntries = [{"file": f} for f in report.fullPathFiles]
601
- ixdsDiscovered = False
602
- for pluginXbrlMethod in PluginManager.pluginClassMethods("InlineDocumentSet.Discovery"):
603
- pluginXbrlMethod(filesource, reportEntries)
604
- ixdsDiscovered = True
605
- if not ixdsDiscovered and len(reportEntries) > 1:
606
- raise RuntimeError(_("Loading error. Inline document set encountered. Enable 'InlineXbrlDocumentSet' plug-in to load this filing: {0}").format(filesource.url))
607
- entrypointFiles.extend(reportEntries)
608
- elif not inlineOnly:
609
- entrypointFiles.append({"file": report.fullPathPrimary})
610
- else:
611
- # attempt to find inline XBRL files before instance files, .xhtml before probing others (ESMA)
612
- urlsByType = {}
613
- for _archiveFile in (filesource.dir or ()): # .dir might be none if IOerror
614
- filesource.select(_archiveFile)
615
- identifiedType = ModelDocument.Type.identify(filesource, filesource.url)
616
- if identifiedType in (ModelDocument.Type.INSTANCE, ModelDocument.Type.INLINEXBRL, ModelDocument.Type.HTML):
617
- urlsByType.setdefault(identifiedType, []).append(filesource.url)
618
- # use inline instances, if any, else non-inline instances
619
- for identifiedType in ((ModelDocument.Type.INLINEXBRL,) if inlineOnly else (ModelDocument.Type.INLINEXBRL, ModelDocument.Type.INSTANCE)):
620
- for url in urlsByType.get(identifiedType, []):
621
- entrypointFiles.append({"file":url})
622
- if entrypointFiles:
623
- if identifiedType == ModelDocument.Type.INLINEXBRL:
624
- for pluginXbrlMethod in PluginManager.pluginClassMethods("InlineDocumentSet.Discovery"):
625
- pluginXbrlMethod(filesource, entrypointFiles) # group into IXDS if plugin feature is available
626
- break # found inline (or non-inline) entrypoint files, don't look for any other type
627
- # for ESEF non-consolidated xhtml documents accept an xhtml entry point
628
- if not entrypointFiles and not inlineOnly:
629
- for url in urlsByType.get(ModelDocument.Type.HTML, []):
630
- entrypointFiles.append({"file":url})
631
- if not entrypointFiles and filesource.taxonomyPackage is not None:
632
- for packageEntry in filesource.taxonomyPackage.get('entryPoints', {}).values():
633
- for _resolvedUrl, remappedUrl, _closest in packageEntry:
634
- entrypointFiles.append({"file": remappedUrl})
635
-
636
-
637
- elif os.path.isdir(filesource.url):
638
- del entrypointFiles[:] # clear list
639
- hasInline = False
640
- for _file in os.listdir(filesource.url):
641
- _path = os.path.join(filesource.url, _file)
642
- if os.path.isfile(_path):
643
- identifiedType = ModelDocument.Type.identify(filesource, _path)
644
- if identifiedType == ModelDocument.Type.INLINEXBRL:
645
- hasInline = True
646
- if identifiedType in (ModelDocument.Type.INSTANCE, ModelDocument.Type.INLINEXBRL):
647
- entrypointFiles.append({"file":_path})
648
- if hasInline: # group into IXDS if plugin feature is available
649
- for pluginXbrlMethod in PluginManager.pluginClassMethods("InlineDocumentSet.Discovery"):
650
- pluginXbrlMethod(filesource, entrypointFiles)
651
-
652
- return entrypointFiles
653
-
654
589
  class ParserForDynamicPlugins:
655
590
  def __init__(self, options):
656
591
  self._long_opt = {}
arelle/ModelDtsObject.py CHANGED
@@ -1846,7 +1846,7 @@ class ModelRelationship(ModelObject):
1846
1846
 
1847
1847
  @property
1848
1848
  def orderDecimal(self):
1849
- """(decimal) -- Value of xlink:order attribute, NaN if not convertable to float, or None if not specified"""
1849
+ """(decimal) -- Value of xlink:order attribute, NaN if not convertible to float, or None if not specified"""
1850
1850
  try:
1851
1851
  return decimal.Decimal(self.order)
1852
1852
  except decimal.InvalidOperation:
@@ -795,6 +795,15 @@ class ModelInlineFact(ModelInlineValueObject, ModelFact):
795
795
  for inline root element, the xbrli:xbrl element is substituted for by the inline root element"""
796
796
  return getattr(self, "_ixFactParent") # set by ModelDocument locateFactInTuple for the inline target's root element
797
797
 
798
+ @property
799
+ def isEscaped(self):
800
+ """(bool) -- if true, the fact is escaped"""
801
+ try:
802
+ return self._isEscaped
803
+ except AttributeError:
804
+ self._isEscaped = self.get("escape") in ("true", "1")
805
+ return self._isEscaped
806
+
798
807
  def ixIter(self, childOnly=False):
799
808
  """(ModelObject) -- child elements (tuple facts) of the inline target instance document"""
800
809
  for fact in self.modelTupleFacts:
@@ -158,7 +158,7 @@ class ModelTestcaseVariation(ModelObject):
158
158
  except AttributeError:
159
159
  self._dataUris = defaultdict(list) # may contain instances, schemas, linkbases
160
160
  for dataElement in XmlUtil.descendants(self, None, ("data", "input")):
161
- for elt in XmlUtil.descendants(dataElement, None, ("xsd", "schema", "linkbase", "instance")):
161
+ for elt in XmlUtil.descendants(dataElement, None, ("xsd", "schema", "linkbase", "instance", "taxonomyPackage")):
162
162
  self._dataUris["schema" if elt.localName == "xsd" else elt.localName].append(elt.textValue.strip())
163
163
  return self._dataUris
164
164
 
arelle/Validate.py CHANGED
@@ -1,6 +1,7 @@
1
1
  '''
2
2
  See COPYRIGHT.md for copyright information.
3
3
  '''
4
+ import bisect
4
5
  import fnmatch
5
6
  import os, sys, traceback, logging
6
7
  import time
@@ -25,6 +26,7 @@ from arelle.PluginManager import pluginClassMethods
25
26
  from arelle.packages.report.DetectReportPackage import isReportPackageExtension
26
27
  from arelle.packages.report.ReportPackageValidator import ReportPackageValidator
27
28
  from arelle.rendering import RenderingEvaluator
29
+ from arelle.utils.EntryPointDetection import filesourceEntrypointFiles
28
30
  from arelle.XmlUtil import collapseWhitespace, xmlstring
29
31
 
30
32
  def validate(modelXbrl):
@@ -166,7 +168,6 @@ class Validate:
166
168
  filesource = FileSource.openFileSource(rssItemUrl, self.modelXbrl.modelManager.cntlr)
167
169
  if filesource and not filesource.selection and filesource.isArchive:
168
170
  try:
169
- from arelle.CntlrCmdLine import filesourceEntrypointFiles
170
171
  entrypoints = filesourceEntrypointFiles(filesource)
171
172
  if entrypoints:
172
173
  # resolve an IXDS in entrypoints
@@ -394,13 +395,12 @@ class Validate:
394
395
  filesource.loadTaxonomyPackageMappings(errors=preLoadingErrors, expectTaxonomyPackage=expectTaxonomyPackage)
395
396
  filesource.select(None) # must select loadable reports (not the taxonomy package itself)
396
397
  elif not filesource.isReportPackage:
397
- from arelle.CntlrCmdLine import filesourceEntrypointFiles
398
398
  entrypoints = filesourceEntrypointFiles(filesource)
399
399
  if entrypoints:
400
400
  # resolve an IXDS in entrypoints
401
401
  for pluginXbrlMethod in pluginClassMethods("ModelTestcaseVariation.ArchiveIxds"):
402
402
  pluginXbrlMethod(self, filesource,entrypoints)
403
- filesource.select(entrypoints[0].get("file", None) )
403
+ filesource.select(entrypoints[0].get("file", None))
404
404
  except Exception as err:
405
405
  self.modelXbrl.error("exception:" + type(err).__name__,
406
406
  _("Testcase variation validation exception: %(error)s, entry URL: %(instance)s"),
@@ -408,17 +408,20 @@ class Validate:
408
408
  return [] # don't try to load this entry URL
409
409
  if filesource and filesource.isReportPackage and not _rptPkgIxdsOptions:
410
410
  if not reportPackageErrors:
411
- for report in filesource.reportPackage.reports or []:
412
- assert isinstance(filesource.basefile, str)
413
- modelXbrl = ModelXbrl.load(self.modelXbrl.modelManager,
414
- report.primary,
415
- _("validating"),
416
- useFileSource=filesource,
417
- base=filesource.basefile + "/",
418
- errorCaptureLevel=errorCaptureLevel,
419
- ixdsTarget=modelTestcaseVariation.ixdsTarget,
420
- errors=preLoadingErrors)
421
- loadedModels.append(modelXbrl)
411
+ assert isinstance(filesource.basefile, str)
412
+ if entrypoints := filesourceEntrypointFiles(filesource):
413
+ for pluginXbrlMethod in pluginClassMethods("ModelTestcaseVariation.ArchiveIxds"):
414
+ pluginXbrlMethod(self, filesource, entrypoints)
415
+ for entrypoint in entrypoints:
416
+ filesource.select(entrypoint.get("file", None))
417
+ modelXbrl = ModelXbrl.load(self.modelXbrl.modelManager,
418
+ filesource,
419
+ _("validating"),
420
+ base=filesource.basefile + "/",
421
+ errorCaptureLevel=errorCaptureLevel,
422
+ ixdsTarget=modelTestcaseVariation.ixdsTarget,
423
+ errors=preLoadingErrors)
424
+ loadedModels.append(modelXbrl)
422
425
  else:
423
426
  if _rptPkgIxdsOptions and filesource.isTaxonomyPackage:
424
427
  # Legacy ESEF conformance suite logic.
@@ -492,9 +495,17 @@ class Validate:
492
495
  # validate schema, linkbase, or instance
493
496
  formulaOutputInstance = None
494
497
  modelXbrl = inputDTSes[None][0]
495
- expectedDataFiles = set(modelXbrl.modelManager.cntlr.webCache.normalizeUrl(uri, baseForElement)
496
- for d in modelTestcaseVariation.dataUris.values() for uri in d
497
- if not UrlUtil.isAbsolute(uri))
498
+ expectedDataFiles = set()
499
+ expectedTaxonomyPackages = []
500
+ for localName, d in modelTestcaseVariation.dataUris.items():
501
+ for uri in d:
502
+ if not UrlUtil.isAbsolute(uri):
503
+ normalizedUri = self.modelXbrl.modelManager.cntlr.webCache.normalizeUrl(uri, baseForElement)
504
+ if localName == "taxonomyPackage":
505
+ expectedTaxonomyPackages.append(normalizedUri)
506
+ else:
507
+ expectedDataFiles.add(normalizedUri)
508
+ expectedTaxonomyPackages.sort()
498
509
  foundDataFiles = set()
499
510
  variationBase = os.path.dirname(baseForElement)
500
511
  for dtsName, inputDTS in inputDTSes.items(): # input instances are also parameters
@@ -509,16 +520,28 @@ class Validate:
509
520
  if docUrl.replace("-formula.xml", ".xf") in expectedDataFiles:
510
521
  docUrl = docUrl.replace("-formula.xml", ".xf")
511
522
  foundDataFiles.add(docUrl)
512
- if expectedDataFiles - foundDataFiles:
523
+
524
+ foundDataFilesInTaxonomyPackages = set()
525
+ foundTaxonomyPackages = set()
526
+ for f in foundDataFiles:
527
+ if i := bisect.bisect(expectedTaxonomyPackages, f):
528
+ package = expectedTaxonomyPackages[i-1]
529
+ if f.startswith(package + "/"):
530
+ foundDataFilesInTaxonomyPackages.add(f)
531
+ foundTaxonomyPackages.add(package)
532
+
533
+ expectedNotFound = expectedDataFiles.union(expectedTaxonomyPackages) - foundDataFiles - foundTaxonomyPackages
534
+ if expectedNotFound:
513
535
  modelXbrl.info("arelle:testcaseDataNotUsed",
514
536
  _("Variation %(id)s %(name)s data files not used: %(missingDataFiles)s"),
515
537
  modelObject=modelTestcaseVariation, name=modelTestcaseVariation.name, id=modelTestcaseVariation.id,
516
- missingDataFiles=", ".join(sorted(os.path.basename(f) for f in expectedDataFiles - foundDataFiles)))
517
- if foundDataFiles - expectedDataFiles:
538
+ missingDataFiles=", ".join(sorted(os.path.basename(f) for f in expectedNotFound)))
539
+ foundNotExpected = foundDataFiles - expectedDataFiles - foundDataFilesInTaxonomyPackages
540
+ if foundNotExpected:
518
541
  modelXbrl.info("arelle:testcaseDataUnexpected",
519
542
  _("Variation %(id)s %(name)s files not in variation data: %(unexpectedDataFiles)s"),
520
543
  modelObject=modelTestcaseVariation, name=modelTestcaseVariation.name, id=modelTestcaseVariation.id,
521
- unexpectedDataFiles=", ".join(sorted(os.path.basename(f) for f in foundDataFiles - expectedDataFiles)))
544
+ unexpectedDataFiles=", ".join(sorted(os.path.basename(f) for f in foundNotExpected)))
522
545
  if modelXbrl.hasTableRendering or modelTestcaseVariation.resultIsTable:
523
546
  try:
524
547
  RenderingEvaluator.init(modelXbrl)
arelle/_version.py CHANGED
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '2.37.12'
21
- __version_tuple__ = version_tuple = (2, 37, 12)
20
+ __version__ = version = '2.37.13'
21
+ __version_tuple__ = version_tuple = (2, 37, 13)
@@ -3,6 +3,7 @@ See COPYRIGHT.md for copyright information.
3
3
  '''
4
4
  from __future__ import annotations
5
5
 
6
+ import logging
6
7
  import sys
7
8
  import time
8
9
  import traceback
@@ -906,9 +907,14 @@ def initializeParser(modelManager: ModelManager) -> bool:
906
907
  modelManager.showStatus(_("initializing formula xpath2 grammar"))
907
908
  startedAt = time.time()
908
909
  xpathExpr.parse_string("0", parseAll=True)
909
- modelManager.addToLog(format_string(modelManager.locale,
910
- _("Formula xpath2 grammar initialized in %.2f secs"),
911
- time.time() - startedAt))
910
+ modelManager.addToLog(
911
+ format_string(
912
+ modelManager.locale,
913
+ _("Formula xpath2 grammar initialized in %.2f secs"),
914
+ time.time() - startedAt
915
+ ),
916
+ level=logging.DEBUG
917
+ )
912
918
  modelManager.showStatus(None)
913
919
  isInitialized = True
914
920
  return True # was initialized on this call
@@ -7,10 +7,10 @@ from __future__ import annotations
7
7
  import json
8
8
  import os
9
9
  import zipfile
10
- from collections import defaultdict
10
+ from collections import Counter, defaultdict
11
11
  from dataclasses import dataclass
12
12
  from pathlib import Path, PurePosixPath
13
- from typing import TYPE_CHECKING, Any, Counter, cast
13
+ from typing import TYPE_CHECKING, Any, cast
14
14
 
15
15
  from arelle.packages import PackageUtils
16
16
  from arelle.packages.report import ReportPackageConst as Const
@@ -162,6 +162,10 @@ class ReportEntry:
162
162
  def isTopLevel(self) -> bool:
163
163
  return len(PurePosixPath(self.primary).parts) == 3
164
164
 
165
+ @property
166
+ def dir(self) -> str:
167
+ return PurePosixPath(self.primary).parent.name
168
+
165
169
 
166
170
  class ReportPackage:
167
171
  def __init__(
@@ -204,7 +208,7 @@ class ReportPackage:
204
208
  reports = getAllReportEntries(filesource, stld)
205
209
  if reportPackageJsonFile is None and reports is None:
206
210
  return None
207
- reportEntriesBySubDir = Counter(dir for report in reports or [] if not report.isTopLevel)
211
+ reportEntriesBySubDir = Counter(report.dir for report in reports or [] if not report.isTopLevel)
208
212
  if reports is not None and any(report.isTopLevel for report in reports):
209
213
  reports = [report for report in reports if report.isTopLevel]
210
214
  if any(subdirCount > 1 for subdirCount in reportEntriesBySubDir.values()):
@@ -4,9 +4,10 @@ See COPYRIGHT.md for copyright information.
4
4
 
5
5
  from __future__ import annotations
6
6
 
7
+ from collections import Counter
7
8
  from collections.abc import Generator
8
9
  from pathlib import Path, PurePosixPath
9
- from typing import TYPE_CHECKING, Counter
10
+ from typing import TYPE_CHECKING
10
11
 
11
12
  from arelle.packages import PackageValidation
12
13
  from arelle.packages.PackageType import PackageType
@@ -146,8 +147,8 @@ class ReportPackageValidator:
146
147
  _("Report package must contain at least one report"),
147
148
  )
148
149
  if len(reportEntries) > 1 and not any(report.isTopLevel for report in reportEntries):
149
- byBaseDir = Counter(report.baseDir for report in reportEntries)
150
- if byBaseDir:
150
+ reportEntriesBySubDir = Counter(report.dir for report in reportEntries or [] if not report.isTopLevel)
151
+ if any(subdirCount > 1 for subdirCount in reportEntriesBySubDir.values()):
151
152
  return Validation.error(
152
153
  "rpe:multipleReportsInSubdirectory",
153
154
  _("Report package must contain only one report"),
@@ -131,7 +131,6 @@ import regex as re
131
131
  from lxml.etree import XML, XMLSyntaxError
132
132
 
133
133
  from arelle import FileSource, ModelXbrl, ValidateDuplicateFacts, ValidateXbrlDimensions, XbrlConst
134
- from arelle.CntlrCmdLine import filesourceEntrypointFiles
135
134
  from arelle.FileSource import archiveFilenameParts, archiveFilenameSuffixes
136
135
  from arelle.ModelDocument import ModelDocument, ModelDocumentReference, Type, create, inlineIxdsDiscover, load
137
136
  from arelle.ModelInstanceObject import ModelInlineFootnote
@@ -142,6 +141,7 @@ from arelle.PrototypeDtsObject import ArcPrototype, LocPrototype
142
141
  from arelle.PythonUtil import attrdict, isLegacyAbs
143
142
  from arelle.RuntimeOptions import RuntimeOptions
144
143
  from arelle.UrlUtil import isHttpUrl
144
+ from arelle.utils.EntryPointDetection import filesourceEntrypointFiles
145
145
  from arelle.ValidateDuplicateFacts import DeduplicationType
146
146
  from arelle.ValidateFilingText import CDATApattern
147
147
  from arelle.Version import authorLabel, copyrightLabel
@@ -188,12 +188,12 @@ def validateXbrlFinally(val: ValidateXbrl, *args: Any, **kwargs: Any) -> None:
188
188
  _baseName, _baseExt = os.path.splitext(doc.basename)
189
189
  if _baseExt not in (".xhtml",".html"):
190
190
  if val.consolidated:
191
- XHTMLExtensionGuidance = "2.6.1"
191
+ errorCode = "ESEF.2.6.1.incorrectFileExtension"
192
192
  reportType = _("Inline XBRL document included within a ESEF report package")
193
193
  else:
194
- XHTMLExtensionGuidance = "4.1.1"
194
+ errorCode = "ESEF.4.1.1.incorrectFileExtension"
195
195
  reportType = _("Stand-alone XHTML document")
196
- modelXbrl.error(f"ESEF.{XHTMLExtensionGuidance}.incorrectFileExtension",
196
+ modelXbrl.error(errorCode,
197
197
  _("%(reportType)s MUST have a .html or .xhtml extension: %(fileName)s"),
198
198
  modelObject=doc, fileName=doc.basename, reportType=reportType)
199
199
  docinfo = doc.xmlRootElement.getroottree().docinfo
@@ -228,12 +228,12 @@ def validateXbrlFinally(val: ValidateXbrl, *args: Any, **kwargs: Any) -> None:
228
228
  _baseName, _baseExt = os.path.splitext(doc.basename)
229
229
  if _baseExt not in (".xhtml",".html"):
230
230
  if val.consolidated:
231
- XHTMLExtensionGuidance = "2.6.1"
231
+ errorCode = "ESEF.2.6.1.incorrectFileExtension"
232
232
  reportType = _("Inline XBRL document included within a ESEF report package")
233
233
  else:
234
- XHTMLExtensionGuidance = "4.1.1"
234
+ errorCode = "ESEF.4.1.1.incorrectFileExtension"
235
235
  reportType = _("Stand-alone XHTML document")
236
- modelXbrl.error(f"ESEF.{XHTMLExtensionGuidance}.incorrectFileExtension",
236
+ modelXbrl.error(errorCode,
237
237
  _("%(reportType)s MUST have a .html or .xhtml extension: %(fileName)s"),
238
238
  modelObject=doc, fileName=doc.basename, reportType=reportType)
239
239
  docinfo = doc.xmlRootElement.getroottree().docinfo
@@ -664,8 +664,7 @@ def validateXbrlFinally(val: ValidateXbrl, *args: Any, **kwargs: Any) -> None:
664
664
  if esefDisclosureSystemYear >= 2024:
665
665
  if not f.id:
666
666
  factsMissingId.append(f)
667
- escaped = f.get("escape") in ("true", "1")
668
- if f.concept is not None and escaped != f.concept.isTextBlock:
667
+ if isinstance(f, ModelInlineFact) and f.concept is not None and f.isEscaped != f.concept.isTextBlock:
669
668
  modelXbrl.error("ESEF.2.2.7.improperApplicationOfEscapeAttribute",
670
669
  _("Facts with datatype 'dtr-types:textBlockItemType' MUST use the 'escape' attribute set to 'true'. Facts with any other datatype MUST use the 'escape' attribute set to 'false' - fact %(conceptName)s"),
671
670
  modelObject=f, conceptName=f.concept.qname)
@@ -6,15 +6,17 @@ from __future__ import annotations
6
6
  from collections import defaultdict
7
7
  from dataclasses import dataclass
8
8
  from functools import lru_cache
9
- from typing import Any, cast
9
+ from typing import Any, TYPE_CHECKING, cast
10
10
 
11
11
  import regex as re
12
12
  from lxml.etree import _Comment, _ElementTree, _Entity, _ProcessingInstruction
13
13
 
14
14
  from arelle.FunctionIxt import ixtNamespaces
15
15
  from arelle.ModelInstanceObject import ModelContext, ModelFact, ModelInlineFootnote, ModelUnit
16
+ from arelle.ModelObject import ModelObject
16
17
  from arelle.ModelValue import QName
17
18
  from arelle.ModelXbrl import ModelXbrl
19
+ from arelle.typing import assert_type
18
20
  from arelle.utils.PluginData import PluginData
19
21
  from arelle.utils.validate.ValidationUtil import etreeIterWithDepth
20
22
  from arelle.XmlValidate import lexicalPatterns
@@ -37,9 +39,9 @@ class ContextData:
37
39
 
38
40
  @dataclass(frozen=True)
39
41
  class FootnoteData:
42
+ factLangFootnotes: dict[ModelObject, set[str]]
40
43
  noMatchLangFootnotes: set[ModelInlineFootnote]
41
44
  orphanedFootnotes: set[ModelInlineFootnote]
42
- factLangFootnotes: dict[ModelInlineFootnote, set[str]]
43
45
 
44
46
  @dataclass
45
47
  class PluginValidationDataExtension(PluginData):
@@ -104,9 +106,9 @@ class PluginValidationDataExtension(PluginData):
104
106
  def checkFootnotes(self, modelXbrl: ModelXbrl) -> FootnoteData:
105
107
  factLangs = self.factLangs(modelXbrl)
106
108
  footnotesRelationshipSet = modelXbrl.relationshipSet("XBRL-footnotes")
109
+ factLangFootnotes = defaultdict(set)
107
110
  orphanedFootnotes = set()
108
111
  noMatchLangFootnotes = set()
109
- factLangFootnotes = defaultdict(set)
110
112
  for elts in modelXbrl.ixdsEltById.values(): # type: ignore[attr-defined]
111
113
  for elt in elts:
112
114
  if isinstance(elt, ModelInlineFootnote):
@@ -116,14 +118,18 @@ class PluginValidationDataExtension(PluginData):
116
118
  orphanedFootnotes.add(elt)
117
119
  if elt.xmlLang not in factLangs:
118
120
  noMatchLangFootnotes.add(elt)
119
- for rel in footnotesRelationshipSet.toModelObject(elt):
120
- if rel.fromModelObject is not None:
121
- factLangFootnotes[rel.fromModelObject].add(elt.xmlLang)
121
+ if elt.xmlLang is not None:
122
+ for rel in footnotesRelationshipSet.toModelObject(elt):
123
+ if rel.fromModelObject is not None:
124
+ fromObj = cast(ModelObject, rel.fromModelObject)
125
+ lang = cast(str, elt.xmlLang)
126
+ factLangFootnotes[fromObj].add(lang)
122
127
  factLangFootnotes.default_factory = None
128
+ assert_type(factLangFootnotes, defaultdict[ModelObject, set[str]])
123
129
  return FootnoteData(
130
+ factLangFootnotes=cast(dict[ModelObject, set[str]], factLangFootnotes),
124
131
  noMatchLangFootnotes=noMatchLangFootnotes,
125
132
  orphanedFootnotes=orphanedFootnotes,
126
- factLangFootnotes=dict(factLangFootnotes),
127
133
  )
128
134
 
129
135
  @lru_cache(1)
@@ -158,31 +164,28 @@ class PluginValidationDataExtension(PluginData):
158
164
  def getContextsWithSegments(self, modelXbrl: ModelXbrl) -> list[ModelContext | None]:
159
165
  return self.checkContexts(modelXbrl).contextsWithSegments
160
166
 
167
+ def getFactLangFootnotes(self, modelXbrl: ModelXbrl) -> dict[ModelObject, set[str]]:
168
+ return self.checkFootnotes(modelXbrl).factLangFootnotes
169
+
161
170
  def getNoMatchLangFootnotes(self, modelXbrl: ModelXbrl) -> set[ModelInlineFootnote]:
162
171
  return self.checkFootnotes(modelXbrl).noMatchLangFootnotes
163
172
 
164
173
  def getOrphanedFootnotes(self, modelXbrl: ModelXbrl) -> set[ModelInlineFootnote]:
165
174
  return self.checkFootnotes(modelXbrl).orphanedFootnotes
166
175
 
167
- def getFactLangFootnotes(self, modelXbrl: ModelXbrl) -> dict[ModelInlineFootnote, set[str]]:
168
- return self.checkFootnotes(modelXbrl).factLangFootnotes
169
-
170
176
  @lru_cache(1)
171
177
  def getReportXmlLang(self, modelXbrl: ModelXbrl) -> str | None:
172
- firstIxdsDoc = True
173
178
  reportXmlLang = None
174
179
  firstRootmostXmlLangDepth = 9999999
175
- for ixdsHtmlRootElt in modelXbrl.ixdsHtmlElements:
176
- for uncast_elt, depth in etreeIterWithDepth(ixdsHtmlRootElt):
177
- elt = cast(Any, uncast_elt)
180
+ if modelXbrl.ixdsHtmlElements:
181
+ ixdsHtmlRootElt = modelXbrl.ixdsHtmlElements[0]
182
+ for elt, depth in etreeIterWithDepth(ixdsHtmlRootElt):
178
183
  if isinstance(elt, (_Comment, _ElementTree, _Entity, _ProcessingInstruction)):
179
184
  continue
180
- if firstIxdsDoc and (not reportXmlLang or depth < firstRootmostXmlLangDepth):
181
- xmlLang = elt.get("{http://www.w3.org/XML/1998/namespace}lang")
182
- if xmlLang:
185
+ if not reportXmlLang or depth < firstRootmostXmlLangDepth:
186
+ if xmlLang := elt.get("{http://www.w3.org/XML/1998/namespace}lang"):
183
187
  reportXmlLang = xmlLang
184
188
  firstRootmostXmlLangDepth = depth
185
- firstIxdsDoc = False
186
189
  return reportXmlLang
187
190
 
188
191
  @lru_cache(1)
@@ -48,16 +48,6 @@ def validateXbrlFinally(*args: Any, **kwargs: Any) -> None:
48
48
  return validationPlugin.validateXbrlFinally(*args, **kwargs)
49
49
 
50
50
 
51
- def modelTestcaseVariationReportPackageIxdsOptions(
52
- val: ValidateXbrl,
53
- rptPkgIxdsOptions: dict[str, bool],
54
- *args: Any,
55
- **kwargs: Any,
56
- ) -> None:
57
- rptPkgIxdsOptions["lookOutsideReportsDirectory"] = True
58
- rptPkgIxdsOptions["combineIntoSingleIxds"] = True
59
-
60
-
61
51
  __pluginInfo__ = {
62
52
  "name": PLUGIN_NAME,
63
53
  "version": "0.0.1",
@@ -70,5 +60,4 @@ __pluginInfo__ = {
70
60
  "DisclosureSystem.ConfigURL": disclosureSystemConfigURL,
71
61
  "ModelXbrl.LoadComplete": modelXbrlLoadComplete,
72
62
  "Validate.XBRL.Finally": validateXbrlFinally,
73
- "ModelTestcaseVariation.ReportPackageIxdsOptions": modelTestcaseVariationReportPackageIxdsOptions,
74
63
  }
@@ -356,6 +356,35 @@ def rule_nl_kvk_3_2_4_2 (
356
356
  )
357
357
 
358
358
 
359
+ @validation(
360
+ hook=ValidationHook.XBRL_FINALLY,
361
+ disclosureSystems=[
362
+ DISCLOSURE_SYSTEM_NL_INLINE_2024
363
+ ],
364
+ )
365
+ def rule_nl_kvk_3_2_7_1 (
366
+ pluginData: PluginValidationDataExtension,
367
+ val: ValidateXbrl,
368
+ *args: Any,
369
+ **kwargs: Any,
370
+ ) -> Iterable[Validation]:
371
+ """
372
+ NL-KVK.3.2.7.1: Ensure that any block-tagged facts of type textBlockItemType are assigned @escape="true",
373
+ while other data types (e.g., xbrli:stringItemType) are assigned @escape="false".
374
+ """
375
+ improperlyEscapedFacts = []
376
+ for fact in val.modelXbrl.facts:
377
+ if isinstance(fact, ModelInlineFact) and fact.concept is not None and fact.isEscaped != fact.concept.isTextBlock:
378
+ improperlyEscapedFacts.append(fact)
379
+ if len(improperlyEscapedFacts) >0:
380
+ yield Validation.error(
381
+ codes='NL.NL-KVK.3.2.7.1.improperApplicationOfEscapeAttribute',
382
+ msg=_('Ensure that any block-tagged facts of type textBlockItemType are assigned @escape="true",'
383
+ 'while other data types (e.g., xbrli:stringItemType) are assigned @escape="false".'),
384
+ modelObject = improperlyEscapedFacts
385
+ )
386
+
387
+
359
388
  @validation(
360
389
  hook=ValidationHook.XBRL_FINALLY,
361
390
  disclosureSystems=[
@@ -429,6 +458,37 @@ def rule_nl_kvk_3_3_1_3 (
429
458
  )
430
459
 
431
460
 
461
+ @validation(
462
+ hook=ValidationHook.XBRL_FINALLY,
463
+ disclosureSystems=[
464
+ DISCLOSURE_SYSTEM_NL_INLINE_2024
465
+ ],
466
+ )
467
+ def rule_nl_kvk_3_5_2_1(
468
+ pluginData: PluginValidationDataExtension,
469
+ val: ValidateXbrl,
470
+ *args: Any,
471
+ **kwargs: Any,
472
+ ) -> Iterable[Validation]:
473
+ """
474
+ NL-KVK.3.5.2.1: Each tagged text fact MUST have the ‘xml:lang’ attribute assigned or inherited.
475
+ """
476
+ factsWithoutLang = []
477
+ for fact in val.modelXbrl.facts:
478
+ if (fact is not None and
479
+ fact.concept is not None and
480
+ fact.concept.type is not None and
481
+ fact.concept.type.isOimTextFactType and
482
+ not fact.xmlLang):
483
+ factsWithoutLang.append(fact)
484
+ if len(factsWithoutLang) > 0:
485
+ yield Validation.error(
486
+ codes='NL.NL-KVK.3.5.2.1.undefinedLanguageForTextFact',
487
+ msg=_('Each tagged text fact MUST have the ‘xml:lang’ attribute assigned or inherited.'),
488
+ modelObject=factsWithoutLang
489
+ )
490
+
491
+
432
492
  @validation(
433
493
  hook=ValidationHook.XBRL_FINALLY,
434
494
  disclosureSystems=[
@@ -91,7 +91,7 @@ def rule_main(
91
91
  if isinstance(elt, ModelInlineFact):
92
92
  if elt.format is not None and elt.format.namespaceURI not in TR_NAMESPACES:
93
93
  transformRegistryErrors.add(elt)
94
- if elt.get("escape") in ("true","1"):
94
+ if elt.isEscaped:
95
95
  modelXbrl.error("ROS.escapedHTML",
96
96
  _("Escaped (x)html fact content is not supported: %(element)s"),
97
97
  modelObject=elt, element=eltTag)
arelle/typing.py CHANGED
@@ -5,7 +5,14 @@ Type hints for Arelle.
5
5
  from __future__ import annotations
6
6
 
7
7
  from collections.abc import Callable
8
- from typing import TypedDict, TypeVar # pylint: disable=no-name-in-module
8
+ from typing import Any, TypedDict, TypeVar # pylint: disable=no-name-in-module
9
+
10
+ try:
11
+ from typing import assert_type as assert_type
12
+ except ImportError:
13
+ T = TypeVar('T')
14
+ def assert_type(x: T, _: Any, /) -> T:
15
+ return x
9
16
 
10
17
  TypeGetText = Callable[[str], str]
11
18
 
@@ -0,0 +1,73 @@
1
+ import os
2
+
3
+ from arelle import (
4
+ ModelDocument,
5
+ PluginManager,
6
+ )
7
+
8
+
9
+ def filesourceEntrypointFiles(filesource, entrypointFiles=None, inlineOnly=False):
10
+ if entrypointFiles is None:
11
+ entrypointFiles = []
12
+ if filesource.isArchive:
13
+ if filesource.isTaxonomyPackage: # if archive is also a taxonomy package, activate mappings
14
+ filesource.loadTaxonomyPackageMappings()
15
+ # HF note: a web api request to load a specific file from archive is ignored, is this right?
16
+ del entrypointFiles[:] # clear out archive from entrypointFiles
17
+ if reportPackage := filesource.reportPackage:
18
+ assert isinstance(filesource.basefile, str)
19
+ for report in reportPackage.reports or []:
20
+ if report.isInline:
21
+ reportEntries = [{"file": f} for f in report.fullPathFiles]
22
+ ixdsDiscovered = False
23
+ for pluginXbrlMethod in PluginManager.pluginClassMethods("InlineDocumentSet.Discovery"):
24
+ pluginXbrlMethod(filesource, reportEntries)
25
+ ixdsDiscovered = True
26
+ if not ixdsDiscovered and len(reportEntries) > 1:
27
+ raise RuntimeError(_("Loading error. Inline document set encountered. Enable 'InlineXbrlDocumentSet' plug-in to load this filing: {0}").format(filesource.url))
28
+ entrypointFiles.extend(reportEntries)
29
+ elif not inlineOnly:
30
+ entrypointFiles.append({"file": report.fullPathPrimary})
31
+ else:
32
+ # attempt to find inline XBRL files before instance files, .xhtml before probing others (ESMA)
33
+ urlsByType = {}
34
+ for _archiveFile in (filesource.dir or ()): # .dir might be none if IOerror
35
+ filesource.select(_archiveFile)
36
+ identifiedType = ModelDocument.Type.identify(filesource, filesource.url)
37
+ if identifiedType in (ModelDocument.Type.INSTANCE, ModelDocument.Type.INLINEXBRL, ModelDocument.Type.HTML):
38
+ urlsByType.setdefault(identifiedType, []).append(filesource.url)
39
+ # use inline instances, if any, else non-inline instances
40
+ for identifiedType in ((ModelDocument.Type.INLINEXBRL,) if inlineOnly else (ModelDocument.Type.INLINEXBRL, ModelDocument.Type.INSTANCE)):
41
+ for url in urlsByType.get(identifiedType, []):
42
+ entrypointFiles.append({"file":url})
43
+ if entrypointFiles:
44
+ if identifiedType == ModelDocument.Type.INLINEXBRL:
45
+ for pluginXbrlMethod in PluginManager.pluginClassMethods("InlineDocumentSet.Discovery"):
46
+ pluginXbrlMethod(filesource, entrypointFiles) # group into IXDS if plugin feature is available
47
+ break # found inline (or non-inline) entrypoint files, don't look for any other type
48
+ # for ESEF non-consolidated xhtml documents accept an xhtml entry point
49
+ if not entrypointFiles and not inlineOnly:
50
+ for url in urlsByType.get(ModelDocument.Type.HTML, []):
51
+ entrypointFiles.append({"file":url})
52
+ if not entrypointFiles and filesource.taxonomyPackage is not None:
53
+ for packageEntry in filesource.taxonomyPackage.get('entryPoints', {}).values():
54
+ for _resolvedUrl, remappedUrl, _closest in packageEntry:
55
+ entrypointFiles.append({"file": remappedUrl})
56
+
57
+
58
+ elif os.path.isdir(filesource.url):
59
+ del entrypointFiles[:] # clear list
60
+ hasInline = False
61
+ for _file in os.listdir(filesource.url):
62
+ _path = os.path.join(filesource.url, _file)
63
+ if os.path.isfile(_path):
64
+ identifiedType = ModelDocument.Type.identify(filesource, _path)
65
+ if identifiedType == ModelDocument.Type.INLINEXBRL:
66
+ hasInline = True
67
+ if identifiedType in (ModelDocument.Type.INSTANCE, ModelDocument.Type.INLINEXBRL):
68
+ entrypointFiles.append({"file":_path})
69
+ if hasInline: # group into IXDS if plugin feature is available
70
+ for pluginXbrlMethod in PluginManager.pluginClassMethods("InlineDocumentSet.Discovery"):
71
+ pluginXbrlMethod(filesource, entrypointFiles)
72
+
73
+ return entrypointFiles
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: arelle-release
3
- Version: 2.37.12
3
+ Version: 2.37.13
4
4
  Summary: An open source XBRL platform.
5
5
  Author-email: "arelle.org" <support@arelle.org>
6
6
  License: Apache-2.0
@@ -1,7 +1,7 @@
1
1
  arelle/Aspect.py,sha256=Pn9I91D1os1RTVj6htuxTfRzVMhmVDtrbKvV_zy9xMI,5470
2
2
  arelle/BetaFeatures.py,sha256=T_tPac-FiozHyYLCemt0RoHJ1JahUE71L-0tHmIRKpE,858
3
3
  arelle/Cntlr.py,sha256=sf5Xe19t5E0wKzhdlXl1p5r6gMtCmPhYAi8RVY0jz7Y,30449
4
- arelle/CntlrCmdLine.py,sha256=-V3daLdYaDRqLTnJ8VYHkaYfvFEZURodCuh1kqNcPO0,94194
4
+ arelle/CntlrCmdLine.py,sha256=sax5n2qmqaTgucMc6TqDlSzNSWJLgzZqrh34B076faE,89969
5
5
  arelle/CntlrComServer.py,sha256=h1KPf31uMbErpxTZn_iklDqUMGFgQnjZkFkFjd8gtLQ,1888
6
6
  arelle/CntlrProfiler.py,sha256=2VQJudiUhxryVypxjODx2ccP1-n60icTiWs5lSEokhQ,972
7
7
  arelle/CntlrQuickBooks.py,sha256=BMqd5nkNQOZyNFPefkTeWUUDCYNS6BQavaG8k1Lepu4,31543
@@ -35,9 +35,9 @@ arelle/LeiUtil.py,sha256=tSPrbQrXEeH5pXgGA_6MAdgMZp20NaW5izJglIXyEQk,5095
35
35
  arelle/LocalViewer.py,sha256=WVrfek_bLeFFxgWITi1EQb6xCQN8O9Ks-ZL16vRncSk,3080
36
36
  arelle/Locale.py,sha256=aKC1Uaen_dbPGb92kZa_yUoo7On_QtWlvr5H_F9BNXg,33008
37
37
  arelle/ModelDocument.py,sha256=Sq6umEdn-aNHjxIpEsXTT7A4V25nGY0JiylSnhr9zSI,130749
38
- arelle/ModelDtsObject.py,sha256=JXPRiFOsbB5tZjEDc6rECuUtXMbF4oxfnwrQvKo-i5U,88656
38
+ arelle/ModelDtsObject.py,sha256=nvHQs4BDmPxY6mqLiBuqIGRJXyA1EqOEGB2f3S6A6w4,88656
39
39
  arelle/ModelFormulaObject.py,sha256=beUSxEFm7aoa9iimmvXLYCHdizAtOmhDqk6wmvbc9Zg,122537
40
- arelle/ModelInstanceObject.py,sha256=pAcwQBr85_fQCGT18JSOGGwzAZ3J-oWIU9sj9UUXLOk,73928
40
+ arelle/ModelInstanceObject.py,sha256=JqULoUliBscwWJa7NskIhNVxBqax2ImOSIh0tH6_7q0,74201
41
41
  arelle/ModelManager.py,sha256=QUNcD2LC_YyyGFU8bFTSuzIGI1qpOK55KBlQ697Ep1I,11075
42
42
  arelle/ModelObject.py,sha256=Rttkhv-PtfneZyDYsG5FDh98BzT97ameTmwNdqFaOv0,18657
43
43
  arelle/ModelObjectFactory.py,sha256=XuNF4Re3p00tODCdyspfar_DNCXfARqCaLEkntgAZ0g,8750
@@ -45,7 +45,7 @@ arelle/ModelRelationshipSet.py,sha256=_1T3NAS0IRgK8IWFe7nh-qxXZ7htA80i_dueyU8JYa
45
45
  arelle/ModelRenderingObject.py,sha256=iPhSUlSBG-FLzAfIdUW06UZDgTCaZJ4K2mxvAtSe2BU,76021
46
46
  arelle/ModelRssItem.py,sha256=GzFkmluOlFsVcrxn9HAyOAcuE7rcHUOGkp4Q6F2IlT8,7713
47
47
  arelle/ModelRssObject.py,sha256=xjuwyJ8pU5sQmNPJFQakDEEnujZg2bMCTaj3zVezHL8,992
48
- arelle/ModelTestcaseObject.py,sha256=qWSphg4BX8HMcmEt_IJ8pS_uU1G7XeIldTshEpAi0GY,21873
48
+ arelle/ModelTestcaseObject.py,sha256=zXaN5IbrbnGhuZOcc6JpJmJaMZlpcHYmb4yA7TTto_I,21892
49
49
  arelle/ModelValue.py,sha256=6Vko4aytXg2Ajv7rI6houQb-ZX39-tcjQ4N90ZxZvE8,39430
50
50
  arelle/ModelVersObject.py,sha256=cPD1IzhkCfuV1eMgVFWes88DH_6WkUj5kj7sgGF2M0I,26062
51
51
  arelle/ModelVersReport.py,sha256=bXEA9K3qkH57aABn5l-m3CTY0FAcF1yX6O4fo-URjl8,73326
@@ -65,7 +65,7 @@ arelle/UITkTable.py,sha256=N83cXi5c0lLZLsDbwSKcPrlYoUoGsNavGN5YRx6d9XY,39810
65
65
  arelle/UiUtil.py,sha256=3G0xPclZI8xW_XQDbiFrmylB7Nd5muqi5n2x2oMkMZU,34218
66
66
  arelle/Updater.py,sha256=ho8Z_9GOL39H1jHL3Gaw5uc6av7J8ZBB6dR_X-nF_e0,7124
67
67
  arelle/UrlUtil.py,sha256=HrxZSG59EUMGMMGmWPuZkPi5-0BGqY3jAMkp7V4IdZo,32400
68
- arelle/Validate.py,sha256=_7lDoGtUCyHgWK1Ak375D-kuPBZmDCNfSr_wsTLq10k,55328
68
+ arelle/Validate.py,sha256=PWTfO6YpF2KMdImnqSLTQ1WBSMJjAonaNNM3ZdeV_Dk,56380
69
69
  arelle/ValidateDuplicateFacts.py,sha256=074y-VWCOBHoi6iV6wDL_IXBtdz9oeI1uPvjEcC1oDs,21717
70
70
  arelle/ValidateFilingText.py,sha256=xnXc0xgdNiHQk0eyP7VSSpvw7qr-pRFRwqqoUb569is,54051
71
71
  arelle/ValidateInfoset.py,sha256=Rz_XBi5Ha43KpxXYhjLolURcWVx5qmqyjLxw48Yt9Dg,20396
@@ -123,8 +123,8 @@ arelle/XmlValidateConst.py,sha256=U_wN0Q-nWKwf6dKJtcu_83FXPn9c6P8JjzGA5b0w7P0,33
123
123
  arelle/XmlValidateParticles.py,sha256=Mn6vhFl0ZKC_vag1mBwn1rH_x2jmlusJYqOOuxFPO2k,9231
124
124
  arelle/XmlValidateSchema.py,sha256=6frtZOc1Yrx_5yYF6V6oHbScnglWrVbWr6xW4EHtLQI,7428
125
125
  arelle/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
126
- arelle/_version.py,sha256=cinilF0XSPQghRi3cWKXaBHJTfQDo12BMn5RYEOmz6Q,515
127
- arelle/typing.py,sha256=Ct5lrNKRow_o9CraMEXNza8nFsJ_iGIKoUeGfPs2dxI,1084
126
+ arelle/_version.py,sha256=dKIkYkYWE9hq9__IcXa7wxMMqFtErf0UfXfBI2C4PIM,515
127
+ arelle/typing.py,sha256=PRe-Fxwr2SBqYYUVPCJ3E7ddDX0_oOISNdT5Q97EbRM,1246
128
128
  arelle/api/Session.py,sha256=O8zpg7MJys9uxwwHf8OsSlZxpPdq7A3ONyY39Q4A3Kc,6218
129
129
  arelle/archive/CustomLogger.py,sha256=v_JXOCQLDZcfaFWzxC9FRcEf9tQi4rCI4Sx7jCuAVQI,1231
130
130
  arelle/archive/LoadEFMvalidate.py,sha256=HR1ZJmOvWGUlWEsWd0tGCa2TTtZSNzeL6tgN1TFfrl0,986
@@ -231,7 +231,7 @@ arelle/formula/FormulaConsisAsser.py,sha256=hO4GZwozM5cGl1xTU6OwoF3LlaMxAEB5Oy0r
231
231
  arelle/formula/FormulaEvaluator.py,sha256=WKNyJz1Os9gsKedJXLNC9y9u11Ea4_JQ-RAI7gSFmPU,82600
232
232
  arelle/formula/ValidateFormula.py,sha256=b_stG7h8RhaSsPt07_x-GRBHOl2uy-JNSMd6v-jkg_w,95942
233
233
  arelle/formula/XPathContext.py,sha256=JerF1suUL9RcKRFeF6kXZXGkuw6yaMb6gijNacrqugU,49386
234
- arelle/formula/XPathParser.py,sha256=vqG2dj0yXVPZpIBsY2rxDIAFC376GSye4CLHfjVyhyM,50321
234
+ arelle/formula/XPathParser.py,sha256=GWQuxrMzMl5uNMSZEnNHPFaynZljxkpYsJdRZiz2jB0,50381
235
235
  arelle/formula/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
236
236
  arelle/images/arelle-full-word.ico,sha256=jsAzyAJZTtVPafxhgFQtdWJj7r_r0YhX_iWvWnZ4QKg,2430
237
237
  arelle/images/arelle-mac-icon-4.gif,sha256=jTXc1dBEgZuXuZVd1XOuLuXfpjNW_pusn0mPhHhkOtk,2619
@@ -302,9 +302,9 @@ arelle/packages/PackageType.py,sha256=2s29OWZ-XpKW1bPJ1kVBcpKMDBr9gzLe25Cukg-YTE
302
302
  arelle/packages/PackageUtils.py,sha256=uraFfkyYQVlY8YdK4j-HgxhkIAOsEaU5Mk4To0ymKxE,575
303
303
  arelle/packages/PackageValidation.py,sha256=y0J6EAR5O8fF51vIrj-2Ur42TObIMvHVFtPXTR-GGOc,7408
304
304
  arelle/packages/report/DetectReportPackage.py,sha256=AemOF0eDbnCR3n6cNTWDb93FttQ18s3jsNQuA-37zM4,305
305
- arelle/packages/report/ReportPackage.py,sha256=8Bwg5scZTjv4qhI6aXCjrR-Mzg8iyAMiNoqeSZVRSAs,9836
305
+ arelle/packages/report/ReportPackage.py,sha256=_W9Z3u9WEBFJhQAgMAW4Y06bOTydk9F-Il-YNmvWBvc,9939
306
306
  arelle/packages/report/ReportPackageConst.py,sha256=nmHRfMZDc1PzxjTlOUi6SVp0QWxI62cywCY2q6CNadQ,2682
307
- arelle/packages/report/ReportPackageValidator.py,sha256=qsFLUYSMscv7w4khjGHO5n9dT3iMMM9aj2cWmANVGwA,10199
307
+ arelle/packages/report/ReportPackageValidator.py,sha256=3Ur_CXUtCPtXzUgDi9t3VI3vcew0I9pq2B-cn_rIkX4,10322
308
308
  arelle/plugin/CacheBuilder.py,sha256=-aDFD3rx83glOprQYO-8gsaIEXcdwB6PFfIq7jy20lo,4489
309
309
  arelle/plugin/EdgarRendererAllReports.py,sha256=V3AeDj29U1XbnFGUO30kAvZtWzDH5G-teyzoJE0HDU0,5031
310
310
  arelle/plugin/SECCorrespondenceLoader.py,sha256=dX3k4uI5SOKR-8zpv1Xk4X34eDQMPaWFS8R2wf8WTNs,9561
@@ -314,7 +314,7 @@ arelle/plugin/formulaLoader.py,sha256=_pPZQPAZeNjGj85rvH7QRl4gEjYD7Yhxl1JhuV9wOo
314
314
  arelle/plugin/formulaSaver.py,sha256=STlKyDA-pVUxZoEW57MSu74RdpyHVTxaHvOZyOt0cyg,31385
315
315
  arelle/plugin/formulaXPathChecker.py,sha256=sEEeLHx17XSj8eOgFdzYLBp9ZFk2UUYLOEKtaF_pq34,18795
316
316
  arelle/plugin/functionsMath.py,sha256=Z8N7ok3w1aOusCQA9QvqYwQ8W1j80bb-_4lVclBnNQM,9037
317
- arelle/plugin/inlineXbrlDocumentSet.py,sha256=wdlEg9OLm81E_aOINeDsPVHi03_v-dC7F9HrqmrF9e8,55256
317
+ arelle/plugin/inlineXbrlDocumentSet.py,sha256=mXQkqKhwizuQsXPzXsdHMxKVayQxCA86MF0gITogplI,55269
318
318
  arelle/plugin/loadFromExcel.py,sha256=galvvaj9jTKMMRUasCSh1SQnCCBzoN_HEpYWv0fmUdM,124407
319
319
  arelle/plugin/loadFromOIM.py,sha256=dJHnX56bmuY40f6vRMsQ7pJmIWcB5N_3jmYWGGnZSdM,903
320
320
  arelle/plugin/profileCmdLine.py,sha256=uLL0fGshpiwtzyLKAtW0WuXAvcRtZgxQG6swM0e4BHA,2370
@@ -366,11 +366,11 @@ arelle/plugin/validate/ESEF/Util.py,sha256=QH3btcGqBpr42M7WSKZLSdNXygZaZLfEiEjlx
366
366
  arelle/plugin/validate/ESEF/__init__.py,sha256=LL7uYOcGPHgjwTlcfW2oWMqWiqrZ5yABzcKkJZFrZis,20391
367
367
  arelle/plugin/validate/ESEF/ESEF_2021/DTS.py,sha256=6Za7BANwwc_egxLCgbgWzwUGOXZv9IF1I7JCkDNt2Tw,26277
368
368
  arelle/plugin/validate/ESEF/ESEF_2021/Image.py,sha256=4bnhuy5viBU0viPjb4FhcRRjVVKlNdnKLFdSGg3sZvs,4871
369
- arelle/plugin/validate/ESEF/ESEF_2021/ValidateXbrlFinally.py,sha256=k3-7Htx0V8VGlqLnzVVwsR-QoPtNn5VJSgKjCwqRQBs,62900
369
+ arelle/plugin/validate/ESEF/ESEF_2021/ValidateXbrlFinally.py,sha256=v7T51hIWHIFYHnf6RrstnZOTVUUfMaibbXUxoBJK-yc,62884
370
370
  arelle/plugin/validate/ESEF/ESEF_2021/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
371
371
  arelle/plugin/validate/ESEF/ESEF_Current/DTS.py,sha256=epp-PBh1NJzQqgxUE6C468HmoDc2w3j54rMwfiOAry4,29334
372
372
  arelle/plugin/validate/ESEF/ESEF_Current/Image.py,sha256=w36sCTy8QbsuKABjkK6PTWce2A4zFN_rMnEM2wi5WEc,11364
373
- arelle/plugin/validate/ESEF/ESEF_Current/ValidateXbrlFinally.py,sha256=PjdUCKrUBXkDdOUdzdhT10UhcqE-JeCQnILz2F_zhpE,73186
373
+ arelle/plugin/validate/ESEF/ESEF_Current/ValidateXbrlFinally.py,sha256=EJF5dKLPntwYdLUBqwKJ0-A22zhSVDKmDwYb9r8zCA4,73146
374
374
  arelle/plugin/validate/ESEF/ESEF_Current/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
375
375
  arelle/plugin/validate/ESEF/resources/authority-validations.json,sha256=JriLZ45KmUYlQiPbXJCAahobqdrst64Ay77bofZhB5Q,14940
376
376
  arelle/plugin/validate/ESEF/resources/config.xml,sha256=t3STU_-QYM7Ay8YwZRPapnohiWVWhjfr4L2Rjx9xN9U,3902
@@ -378,16 +378,16 @@ arelle/plugin/validate/FERC/__init__.py,sha256=V4fXcFKBsjFFPs9_1NhvDjWpEQCoQM0tR
378
378
  arelle/plugin/validate/FERC/config.xml,sha256=bn9b8eCqJA1J62rYq1Nz85wJrMGAahVmmnIUQZyerjo,1919
379
379
  arelle/plugin/validate/FERC/resources/ferc-utr.xml,sha256=OCRj9IUpdXATCBXKbB71apYx9kxcNtZW-Hq4s-avsRY,2663
380
380
  arelle/plugin/validate/NL/DisclosureSystems.py,sha256=kTjpxkgwn58wHCbaLRBInirOy-2cpK9MLWEFJ_193y4,180
381
- arelle/plugin/validate/NL/PluginValidationDataExtension.py,sha256=pbFSndg59-l6SS708c1zXFLgTJ9sVD82XU4YakU0uA0,8690
381
+ arelle/plugin/validate/NL/PluginValidationDataExtension.py,sha256=G5sLghJcG43yLyZrGM4qhok3IchbeeZDKiGKjolOQGs,8952
382
382
  arelle/plugin/validate/NL/ValidationPluginExtension.py,sha256=2qvvOqBkgk2LwERTHDuxtrRupYz3yRyhH71XQLbl9F4,15507
383
- arelle/plugin/validate/NL/__init__.py,sha256=99uMv4ESHwyJqA-Xq_hBvHygm0BQ3NxcmAJnVYUkSgg,3104
383
+ arelle/plugin/validate/NL/__init__.py,sha256=GFM77Mv7OJkLKrZUEB_LmF5x3h4U5J9NsD1lven0N9o,2708
384
384
  arelle/plugin/validate/NL/resources/config.xml,sha256=i_ns2wHmQYjhkRItevRR8tzfkl31ASfbWlc5t6pDB-w,1117
385
385
  arelle/plugin/validate/NL/rules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
386
386
  arelle/plugin/validate/NL/rules/br_kvk.py,sha256=0SwKieWzTDm3YMsXPS6zTdgbk7_Z9CzqRkRmCRz1OiQ,15789
387
387
  arelle/plugin/validate/NL/rules/fg_nl.py,sha256=4Puq5wAjtK_iNd4wisH_R0Z_EKJ7MT2OCai5g4t1MPE,10714
388
388
  arelle/plugin/validate/NL/rules/fr_kvk.py,sha256=-_BLeWGoZ_f56p5VO4X40S45Ny3Ej-WK6Srei1KVSxU,8170
389
389
  arelle/plugin/validate/NL/rules/fr_nl.py,sha256=-M1WtXp06khhtkfOVPCa-b8UbC281gk4YfDhvtAVlnI,31424
390
- arelle/plugin/validate/NL/rules/nl_kvk.py,sha256=gCmOZP3sYJBBzuFoZSg4T4M5bB2MnThduS1no4BWSqc,16062
390
+ arelle/plugin/validate/NL/rules/nl_kvk.py,sha256=Q95o159XeA29g34ZeQHL113TV9KmKeVk1RzTHNsK5W8,18270
391
391
  arelle/plugin/validate/ROS/DisclosureSystems.py,sha256=rJ81mwQDYTi6JecFZ_zhqjjz3VNQRgjHNSh0wcQWAQE,18
392
392
  arelle/plugin/validate/ROS/PluginValidationDataExtension.py,sha256=IV7ILhNvgKwQXqbpSA6HRNt9kEnejCyMADI3wyyIgk0,4036
393
393
  arelle/plugin/validate/ROS/ValidationPluginExtension.py,sha256=FBhEp8t396vGdvCbMEimfcxmGiGnhXMen-yVLWnkFaI,758
@@ -395,7 +395,7 @@ arelle/plugin/validate/ROS/__init__.py,sha256=KuWg1MHVzA2S6eaHFptvP3Vu_5gQWf3OUY
395
395
  arelle/plugin/validate/ROS/config.xml,sha256=ZCpCFgr1ZAjoUuhb1eRpDnmKrae-sXA9yl6SOWnrfm8,654
396
396
  arelle/plugin/validate/ROS/resources/config.xml,sha256=HXWume5HlrAqOx5AtiWWqgADbRatA8YSfm_JvZGwdgQ,657
397
397
  arelle/plugin/validate/ROS/rules/__init__.py,sha256=wW7BUAIb7sRkOxC1Amc_ZKrz03FM-Qh1TyZe6wxYaAU,1567
398
- arelle/plugin/validate/ROS/rules/ros.py,sha256=se4i-wTVGecXgK6EXrP_FSDau0O4KNsp9lq1h4k5KkM,19941
398
+ arelle/plugin/validate/ROS/rules/ros.py,sha256=6DciQvv3H9QCEaDgINfHejZd196pEulUcQHk2qqMWhs,19921
399
399
  arelle/plugin/validate/UK/ValidateUK.py,sha256=0UhSwsY1lrY-EAEBJJR9QY38YXGBZ6PEgmuC5gQfBlI,57813
400
400
  arelle/plugin/validate/UK/__init__.py,sha256=WOAbzcogxP2hD3HmNnVIrvUO4w0Cv36447AoPrMa7KU,30548
401
401
  arelle/plugin/validate/UK/config.xml,sha256=mUFhWDfBzGTn7v0ZSmf4HaweQTMJh_4ZcJmD9mzCHrA,1547
@@ -697,6 +697,7 @@ arelle/resources/libs/Tktable2.11/win-x86_64/tkTable.tcl,sha256=JrSZRngZFHtw8Svp
697
697
  arelle/scripts-macOS/startWebServer.command,sha256=KXLSwAwchDZBlL-k9PYXdf39RNBtte4vV076_kIz2Ow,91
698
698
  arelle/scripts-unix/startWebServer.sh,sha256=_0puRzaGkdMZoFn3R7hDti9a3ryN6kTZAXwLweeZU1s,42
699
699
  arelle/scripts-windows/startWebServer.bat,sha256=qmnF1yrjNo__bi4QodONWlN0qHShVLTKptJQYyZtgcY,122
700
+ arelle/utils/EntryPointDetection.py,sha256=S85pXfCdrxLiX_L5rYVmlGwTNhwqlIE0L7c2g7UUeDc,4369
700
701
  arelle/utils/PluginData.py,sha256=GUnuZaApm1J4Xm9ZA1U2M1aask-AaNGviLtc0fgXbFg,265
701
702
  arelle/utils/PluginHooks.py,sha256=CeVxti23VjERQl4xWFucDVTW63TCG2PUdnxpjd3x_Ms,31170
702
703
  arelle/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -708,7 +709,7 @@ arelle/utils/validate/ValidationUtil.py,sha256=9vmSvShn-EdQy56dfesyV8JjSRVPj7txr
708
709
  arelle/utils/validate/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
709
710
  arelle/webserver/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
710
711
  arelle/webserver/bottle.py,sha256=P-JECd9MCTNcxCnKoDUvGcoi03ezYVOgoWgv2_uH-6M,362
711
- arelle_release-2.37.12.dist-info/licenses/LICENSE.md,sha256=Q0tn6q0VUbr-NM8916513NCIG8MNzo24Ev-sxMUBRZc,3959
712
+ arelle_release-2.37.13.dist-info/licenses/LICENSE.md,sha256=Q0tn6q0VUbr-NM8916513NCIG8MNzo24Ev-sxMUBRZc,3959
712
713
  tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
713
714
  tests/integration_tests/download_cache.py,sha256=jVMIVICsZjcVc9DCPPu3fCjF9_cWSS3tqSynhFs3oAM,4097
714
715
  tests/integration_tests/integration_test_util.py,sha256=H7mncbv0T9ZeVyrtk9Hohe3k6jgcYykHkt-LGE-Q9aQ,10270
@@ -730,7 +731,7 @@ tests/integration_tests/scripts/tests/python_api_query_model.py,sha256=Ut87tvE-h
730
731
  tests/integration_tests/scripts/tests/python_api_taxonomy_service.py,sha256=C6j7BB9h7CX_dUmVFkpnqElShffRSmCI-TMJkueztGM,2711
731
732
  tests/integration_tests/scripts/tests/python_api_validate_esef.py,sha256=Qzi2RRGWjkTVhAjBB18DeJ3X_M9hJYH1TAk7j_RVv5Q,2423
732
733
  tests/integration_tests/ui_tests/ArelleGUITest/ArelleGUITest.sln,sha256=uzzvHUtKpmBPpoxdfHd7cCmAkdvjs7mMehO6YHebdTY,1499
733
- tests/integration_tests/ui_tests/ArelleGUITest/ArelleGUITest/ArelleGUITest.csproj,sha256=_MqHWdpSGWqbmEnccKPDPCvUsB-uHH6GXkA5ZPD7gD8,1387
734
+ tests/integration_tests/ui_tests/ArelleGUITest/ArelleGUITest/ArelleGUITest.csproj,sha256=TW3UoKU77nleFIjyKhtXOEuhaaBjD9201ie80UIT10Y,1387
734
735
  tests/integration_tests/ui_tests/ArelleGUITest/ArelleGUITest/Tests.cs,sha256=_0TvabpERmrfaoDSazN-xQAH0qzO3cAnuFHLGLRJnGU,20334
735
736
  tests/integration_tests/ui_tests/ArelleGUITest/ArelleGUITest/Usings.cs,sha256=0IC7tQ27uAqlt8ZGBrJPK7BPj3kjiodPcHWB3v_JT-o,29
736
737
  tests/integration_tests/ui_tests/resources/workiva.zip,sha256=QtZzi1VcKkHhVa8J-I1wVpQFy-p6tsV95Z0HmI6XbXc,223544
@@ -763,7 +764,7 @@ tests/integration_tests/validation/conformance_suite_configurations/kvk_nt16.py,
763
764
  tests/integration_tests/validation/conformance_suite_configurations/kvk_nt17.py,sha256=lmEZonthFm0YKFmp1dwXtdJ2T7txUeSpL4mbAo8fl4Y,1292
764
765
  tests/integration_tests/validation/conformance_suite_configurations/kvk_nt18.py,sha256=EG2RQVkvFENhzUF3fl3QvDnH7ZPYS1n1Fo8bhfmSczM,1205
765
766
  tests/integration_tests/validation/conformance_suite_configurations/kvk_nt19.py,sha256=FAzf9RhRmn_8yowpplJho2zEspX9FxJiVq8SjZT3Dsc,1199
766
- tests/integration_tests/validation/conformance_suite_configurations/nl_inline_2024.py,sha256=5WbjM571b4Va8JbW8nuBp_XU7K-LecvNxFfpVyKfVM0,11095
767
+ tests/integration_tests/validation/conformance_suite_configurations/nl_inline_2024.py,sha256=fXxnPmGE2IepTcsowV_-OxqkPwU12QDbnvaQN5aV6Qk,10601
767
768
  tests/integration_tests/validation/conformance_suite_configurations/nl_nt16.py,sha256=O_LFVBZPkjxmbrU7_C7VTLtrdoCUx2bYXOXw6_MlRtQ,846
768
769
  tests/integration_tests/validation/conformance_suite_configurations/nl_nt17.py,sha256=aTN3Ez6lPsZsuypHZP84DneOtYxUZSjUiGypHy6ofHQ,846
769
770
  tests/integration_tests/validation/conformance_suite_configurations/nl_nt18.py,sha256=sqHLjrHc95dTu0guTgKkphaKM1zNfKGnN4GKkZDLzeU,845
@@ -781,7 +782,7 @@ tests/integration_tests/validation/conformance_suite_configurations/xbrl_formula
781
782
  tests/integration_tests/validation/conformance_suite_configurations/xbrl_ixbrl_1_1.py,sha256=Upsc9Nx0eHJQlVL9p77GamTCUpIqjexnRShe9F0b9NM,1366
782
783
  tests/integration_tests/validation/conformance_suite_configurations/xbrl_link_role_registry_1_0.py,sha256=NQfri9MXCDSvNy7kahf4iXZaBUPey9-FYKlchg-Uw4I,633
783
784
  tests/integration_tests/validation/conformance_suite_configurations/xbrl_oim_1_0.py,sha256=s5tcH5fgzNwLQR1iWxCjuyij4Rxjq8XrmGDIptAbfGE,906
784
- tests/integration_tests/validation/conformance_suite_configurations/xbrl_report_packages_1_0.py,sha256=roUdlY_cOYFp5gSyiDoYUP_OHRCjJyReTv-dNorI72g,1799
785
+ tests/integration_tests/validation/conformance_suite_configurations/xbrl_report_packages_1_0.py,sha256=C4-DkdYT4A4qeohf71P6of4NfLgqLQ4w04VYmWWeBTM,1954
785
786
  tests/integration_tests/validation/conformance_suite_configurations/xbrl_table_linkbase_1_0.py,sha256=6zWp8Bt_X4QHDKeJo4NHOgu2OwMpc8-Qb0VZULWcn6M,844
786
787
  tests/integration_tests/validation/conformance_suite_configurations/xbrl_taxonomy_packages_1_0.py,sha256=rw1QLcQBKIlwtQ3XhNJqAXxYgmWZm_4wGbwck2UZg_8,651
787
788
  tests/integration_tests/validation/conformance_suite_configurations/xbrl_transformation_registry_3.py,sha256=ORho6dzIyaUOgm6v9YjViMAk3MzOK40U8AX2V0Eg5t4,591
@@ -1557,8 +1558,8 @@ tests/unit_tests/arelle/oim/test_load.py,sha256=NxiUauQwJVfWAHbbpsMHGSU2d3Br8Pki
1557
1558
  tests/unit_tests/arelle/plugin/test_plugin_imports.py,sha256=bdhIs9frAnFsdGU113yBk09_jis-z43dwUItMFYuSYM,1064
1558
1559
  tests/unit_tests/arelle/plugin/validate/ESEF/ESEF_Current/test_validate_css_url.py,sha256=XHABmejQt7RlZ0udh7v42f2Xb2STGk_fSaIaJ9i2xo0,878
1559
1560
  tests/unit_tests/arelle/utils/validate/test_decorator.py,sha256=ZS8FqIY1g-2FCbjF4UYm609dwViax6qBMRJSi0vfuhY,2482
1560
- arelle_release-2.37.12.dist-info/METADATA,sha256=HRYC-wPK2dvdAehLuqUvqbFGfsljI-F9gHXbwTH5qXA,9065
1561
- arelle_release-2.37.12.dist-info/WHEEL,sha256=Nw36Djuh_5VDukK0H78QzOX-_FQEo6V37m3nkm96gtU,91
1562
- arelle_release-2.37.12.dist-info/entry_points.txt,sha256=Uj5niwfwVsx3vaQ3fYj8hrZ1xpfCJyTUA09tYKWbzpo,111
1563
- arelle_release-2.37.12.dist-info/top_level.txt,sha256=ZYmYGmhW5Jvo3vJ4iXBZPUI29LvYhntom04w90esJvU,13
1564
- arelle_release-2.37.12.dist-info/RECORD,,
1561
+ arelle_release-2.37.13.dist-info/METADATA,sha256=Ol2iYu-MT8cf22xuvNMIWt8qxYNedUq6E8sdaeEdGKU,9065
1562
+ arelle_release-2.37.13.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
1563
+ arelle_release-2.37.13.dist-info/entry_points.txt,sha256=Uj5niwfwVsx3vaQ3fYj8hrZ1xpfCJyTUA09tYKWbzpo,111
1564
+ arelle_release-2.37.13.dist-info/top_level.txt,sha256=ZYmYGmhW5Jvo3vJ4iXBZPUI29LvYhntom04w90esJvU,13
1565
+ arelle_release-2.37.13.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.7.1)
2
+ Generator: setuptools (80.8.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -16,7 +16,7 @@
16
16
  <PackageReference Include="JUnitTestLogger" Version="1.1.0" />
17
17
  <PackageReference Include="JunitXml.TestLogger" Version="6.1.0" />
18
18
  <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />
19
- <PackageReference Include="Microsoft.Windows.Compatibility" Version="9.0.4" />
19
+ <PackageReference Include="Microsoft.Windows.Compatibility" Version="9.0.5" />
20
20
  <PackageReference Include="NUnit" Version="4.3.2" />
21
21
  <PackageReference Include="NUnit3TestAdapter" Version="5.0.0" />
22
22
  <PackageReference Include="NUnit.Analyzers" Version="4.7.0">
@@ -22,12 +22,15 @@ config = ConformanceSuiteConfig(
22
22
  'taggedTextFactOnlyInLanguagesOtherThanLanguageOfAReport': 1,
23
23
  },
24
24
  'G4-1-2_1/index.xml:TC2_valid': {
25
+ 'undefinedLanguageForTextFact': 1,
25
26
  'taggedTextFactOnlyInLanguagesOtherThanLanguageOfAReport': 1,
26
27
  },
27
28
  'RTS_Annex_II_Par_1_RTS_Annex_IV_par_7/index.xml:TC2_valid': {
29
+ 'undefinedLanguageForTextFact': 1,
28
30
  'taggedTextFactOnlyInLanguagesOtherThanLanguageOfAReport': 1,
29
31
  },
30
32
  'RTS_Annex_II_Par_1_RTS_Annex_IV_par_7/index.xml:TC4_invalid': {
33
+ 'undefinedLanguageForTextFact': 1,
31
34
  'taggedTextFactOnlyInLanguagesOtherThanLanguageOfAReport': 1,
32
35
  },
33
36
  'RTS_Annex_IV_Par_1_G3-1-4_1/index.xml:TC2_invalid': {
@@ -42,6 +45,7 @@ config = ConformanceSuiteConfig(
42
45
  'message:valueKvKIdentifierScheme': 105,
43
46
  },
44
47
  'RTS_Annex_IV_Par_6/index.xml:TC2_valid': {
48
+ 'undefinedLanguageForTextFact': 1,
45
49
  'taggedTextFactOnlyInLanguagesOtherThanLanguageOfAReport': 1,
46
50
  },
47
51
  }.items()},
@@ -52,10 +56,6 @@ config = ConformanceSuiteConfig(
52
56
 
53
57
 
54
58
  # Not Implemented
55
- 'conformance-suite-2024-sbr-domein-handelsregister/tests/G3-2-7_1/index.xml:TC4_invalid',
56
- 'conformance-suite-2024-sbr-domein-handelsregister/tests/G3-2-7_1/index.xml:TC5_invalid',
57
- 'conformance-suite-2024-sbr-domein-handelsregister/tests/G3-2-7_1/index.xml:TC6_invalid',
58
- 'conformance-suite-2024-sbr-domein-handelsregister/tests/G3-2-7_1/index.xml:TC7_invalid',
59
59
  'conformance-suite-2024-sbr-domein-handelsregister/tests/G3-4-1_1/index.xml:TC2_invalid',
60
60
  'conformance-suite-2024-sbr-domein-handelsregister/tests/G3-4-1_2/index.xml:TC2_invalid',
61
61
  'conformance-suite-2024-sbr-domein-handelsregister/tests/G3-4-1_3/index.xml:TC2_invalid',
@@ -70,7 +70,6 @@ config = ConformanceSuiteConfig(
70
70
  'conformance-suite-2024-sbr-domein-handelsregister/tests/G3-5-1_4/index.xml:TC2_invalid',
71
71
  'conformance-suite-2024-sbr-domein-handelsregister/tests/G3-5-1_5/index.xml:TC2_invalid',
72
72
  'conformance-suite-2024-sbr-domein-handelsregister/tests/G3-5-1_5/index.xml:TC3_invalid',
73
- 'conformance-suite-2024-sbr-domein-handelsregister/tests/G3-5-2_1/index.xml:TC3_invalid',
74
73
  'conformance-suite-2024-sbr-domein-handelsregister/tests/G3-5-3_1/index.xml:TC2_invalid',
75
74
  'conformance-suite-2024-sbr-domein-handelsregister/tests/G3-5-4_1/index.xml:TC2_invalid',
76
75
  'conformance-suite-2024-sbr-domein-handelsregister/tests/G3-6-2_1/index.xml:TC2_invalid',
@@ -105,9 +104,7 @@ config = ConformanceSuiteConfig(
105
104
  'conformance-suite-2024-sbr-domein-handelsregister/tests/G4-4-3_2/index.xml:TC3_invalid',
106
105
  'conformance-suite-2024-sbr-domein-handelsregister/tests/G4-4-5_2/index.xml:TC2_invalid',
107
106
  'conformance-suite-2024-sbr-domein-handelsregister/tests/G4-4-5_2/index.xml:TC3_invalid',
108
- 'conformance-suite-2024-sbr-domein-handelsregister/tests/G5-1-3_1/index.xml:TC1_valid',
109
107
  'conformance-suite-2024-sbr-domein-handelsregister/tests/G5-1-3_1/index.xml:TC2_invalid',
110
- 'conformance-suite-2024-sbr-domein-handelsregister/tests/G5-1-3_2/index.xml:TC1_valid',
111
108
  'conformance-suite-2024-sbr-domein-handelsregister/tests/G5-1-3_2/index.xml:TC2_invalid',
112
109
  'conformance-suite-2024-sbr-domein-handelsregister/tests/G6-1-1_1/index.xml:TC2_invalid',
113
110
  'conformance-suite-2024-sbr-domein-handelsregister/tests/RTS_Annex_II_Par_1/index.xml:TC3_invalid',
@@ -18,7 +18,9 @@ config = ConformanceSuiteConfig(
18
18
  expected_additional_testcase_errors={f"report-package-conformance/index.csv:{s}": val for s, val in {
19
19
  # "Empty" iXBRL docs are missing schema required elements.
20
20
  "V-301-xbri-with-single-ixds": {
21
- "lxml.SCHEMAV_ELEMENT_CONTENT": 1,
21
+ # There are two documents in the package, empty1.xhtml and empty2.xhtml,
22
+ # each missing a title, so we must see two schema errors.
23
+ "lxml.SCHEMAV_ELEMENT_CONTENT": 2,
22
24
  "ix11.14.1.2:missingResources": 1,
23
25
  },
24
26
  "V-302-xbri-with-single-html": {