arelle-release 2.37.49__py3-none-any.whl → 2.37.50__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.

arelle/ModelDocument.py CHANGED
@@ -1579,12 +1579,6 @@ def inlineIxdsDiscover(modelXbrl, modelIxdsDocument, setTargetModelXbrl=False, *
1579
1579
  modelXbrl.targetRoleRefs = {} # roleRefs used by selected target
1580
1580
  modelXbrl.targetArcroleRefs = {} # arcroleRefs used by selected target
1581
1581
  modelXbrl.targetRelationships = set() # relationship elements used by selected target
1582
- targetModelXbrl = modelXbrl if setTargetModelXbrl else None # modelXbrl of target for contexts/units in multi-target/multi-instance situation
1583
- assignUnusedContextsUnits = (not setTargetModelXbrl and not ixdsTarget and
1584
- not getattr(modelXbrl, "supplementalModelXbrls", ()) and (
1585
- not getattr(modelXbrl, "targetIXDSesToLoad", ()) or
1586
- set(e.modelDocument for e in modelXbrl.ixdsHtmlElements) ==
1587
- set(x.modelDocument for e in getattr(modelXbrl, "targetIXDSesToLoad", ()) for x in e[1])))
1588
1582
  hasResources = hasHeader = False
1589
1583
  for htmlElement in modelXbrl.ixdsHtmlElements:
1590
1584
  mdlDoc = htmlElement.modelDocument
@@ -1611,8 +1605,12 @@ def inlineIxdsDiscover(modelXbrl, modelIxdsDocument, setTargetModelXbrl=False, *
1611
1605
  for modelInlineFact in htmlElement.iterdescendants(ixNStag + "nonNumeric", ixNStag + "nonFraction", ixNStag + "fraction"):
1612
1606
  if isinstance(modelInlineFact,ModelObject):
1613
1607
  _target = modelInlineFact.get("target")
1614
- factTargetContextRefs[_target].add(modelInlineFact.get("contextRef"))
1615
- factTargetUnitRefs[_target].add(modelInlineFact.get("unitRef"))
1608
+ contextRef = modelInlineFact.get("contextRef")
1609
+ if contextRef is not None:
1610
+ factTargetContextRefs[_target].add(contextRef.strip())
1611
+ unitRef = modelInlineFact.get("unitRef")
1612
+ if unitRef is not None:
1613
+ factTargetUnitRefs[_target].add(unitRef.strip())
1616
1614
  if modelInlineFact.id:
1617
1615
  factsByFactID[modelInlineFact.id] = modelInlineFact
1618
1616
  for elt in htmlElement.iterdescendants(tag=ixNStag + "continuation"):
@@ -1734,9 +1732,9 @@ def inlineIxdsDiscover(modelXbrl, modelIxdsDocument, setTargetModelXbrl=False, *
1734
1732
  targetRoleUris[_target].add(footnoteRole)
1735
1733
 
1736
1734
  contextRefs = factTargetContextRefs[ixdsTarget]
1735
+ contextRefsForAllTargets = {ref for refs in factTargetContextRefs.values() for ref in refs}
1737
1736
  unitRefs = factTargetUnitRefs[ixdsTarget]
1738
- allContextRefs = set.union(*factTargetContextRefs.values())
1739
- allUnitRefs = set.union(*factTargetUnitRefs.values())
1737
+ unitRefsForAllTargets = {ref for refs in factTargetUnitRefs.values() for ref in refs}
1740
1738
 
1741
1739
  # discovery of contexts, units and roles which are used by target document
1742
1740
  for htmlElement in modelXbrl.ixdsHtmlElements:
@@ -1745,13 +1743,17 @@ def inlineIxdsDiscover(modelXbrl, modelIxdsDocument, setTargetModelXbrl=False, *
1745
1743
 
1746
1744
  for inlineElement in htmlElement.iterdescendants(tag=ixNStag + "resources"):
1747
1745
  for elt in inlineElement.iterchildren("{http://www.xbrl.org/2003/instance}context"):
1748
- id = elt.get("id")
1749
- if id in contextRefs or (assignUnusedContextsUnits and id not in allContextRefs):
1746
+ contextId = elt.get("id")
1747
+ if contextId in contextRefs:
1750
1748
  modelIxdsDocument.contextDiscover(elt, setTargetModelXbrl)
1749
+ elif contextId not in contextRefsForAllTargets:
1750
+ modelXbrl.ixdsUnmappedContexts[contextId] = elt
1751
1751
  for elt in inlineElement.iterchildren("{http://www.xbrl.org/2003/instance}unit"):
1752
- id = elt.get("id")
1753
- if id in unitRefs or (assignUnusedContextsUnits and id not in allUnitRefs):
1752
+ unitId = elt.get("id")
1753
+ if unitId in unitRefs:
1754
1754
  modelIxdsDocument.unitDiscover(elt, setTargetModelXbrl)
1755
+ elif unitId not in unitRefsForAllTargets:
1756
+ modelXbrl.ixdsUnmappedUnits[unitId] = elt
1755
1757
  for refElement in inlineElement.iterchildren("{http://www.xbrl.org/2003/linkbase}roleRef"):
1756
1758
  r = refElement.get("roleURI")
1757
1759
  if r in targetRoleUris[ixdsTarget]:
@@ -1159,7 +1159,7 @@ class ModelContext(ModelObject):
1159
1159
  self._dimsHash = hash( frozenset(self.qnameDims.values()) )
1160
1160
  return self._dimsHash
1161
1161
 
1162
- def nonDimValues(self, contextElement):
1162
+ def nonDimValues(self, contextElement: str | int) -> list[ModelObject]:
1163
1163
  """([ModelObject]) -- ContextElement is either string or Aspect code for segment or scenario, returns nonXDT ModelObject children of context element.
1164
1164
 
1165
1165
  :param contextElement: one of 'segment', 'scenario', Aspect.NON_XDT_SEGMENT, Aspect.NON_XDT_SCENARIO, Aspect.COMPLETE_SEGMENT, Aspect.COMPLETE_SCENARIO
arelle/ModelXbrl.py CHANGED
@@ -12,7 +12,7 @@ from collections import defaultdict
12
12
  from typing import TYPE_CHECKING, Any, TypeVar, Union, cast, Optional
13
13
 
14
14
  import regex as re
15
- from collections.abc import Iterable
15
+ from collections.abc import Iterable, Iterator
16
16
 
17
17
  import arelle
18
18
  from arelle import FileSource, ModelRelationshipSet, XmlUtil, ModelValue, XbrlConst, XmlValidate
@@ -335,8 +335,12 @@ class ModelXbrl:
335
335
  self.facts: list[ModelFact] = []
336
336
  self.factsInInstance: set[ModelFact] = set()
337
337
  self.undefinedFacts: list[ModelFact] = [] # elements presumed to be facts but not defined
338
- self.contexts: dict[str, ModelDocumentClass.xmlRootElement] = {}
338
+ self.contexts: dict[str, ModelContext] = {}
339
+ self.ixdsUnmappedContexts: dict[str, ModelContext] = {}
340
+ self._contextsInUseMarked = False
339
341
  self.units: dict[str, ModelUnit] = {}
342
+ self.ixdsUnmappedUnits: dict[str, ModelUnit] = {}
343
+ self._unitsInUseMarked = False
340
344
  self.modelObjects: list[ModelObject] = []
341
345
  self.qnameParameters: dict[QName, Any] = {}
342
346
  self.modelVariableSets: set[ModelVariableSet] = set()
@@ -604,7 +608,7 @@ class ModelXbrl:
604
608
  for cOCCs,mOCCs in ((c.nonDimValues(segAspect),segOCCs),
605
609
  (c.nonDimValues(scenAspect),scenOCCs)))
606
610
  ):
607
- return cast('ModelContext', c)
611
+ return c
608
612
  return None
609
613
 
610
614
  def createContext(
@@ -868,17 +872,24 @@ class ModelXbrl:
868
872
  return fbdq[memQname]
869
873
 
870
874
  @property
871
- def contextsInUse(self) -> Any:
872
- try:
873
- if self._contextsInUseMarked:
874
- return (cntx for cntx in self.contexts.values() if getattr(cntx, "_inUse", False))
875
- except AttributeError:
875
+ def contextsInUse(self) -> Iterator[ModelContext]:
876
+ if not self._contextsInUseMarked:
876
877
  for fact in self.factsInInstance:
877
878
  cntx = fact.context
878
879
  if cntx is not None:
879
880
  cntx._inUse = True
880
- self._contextsInUseMarked: bool = True
881
- return self.contextsInUse
881
+ self._contextsInUseMarked = True
882
+ return (cntx for cntx in self.contexts.values() if getattr(cntx, "_inUse", False))
883
+
884
+ @property
885
+ def unitsInUse(self) -> Iterator[ModelUnit]:
886
+ if not self._unitsInUseMarked:
887
+ for fact in self.factsInInstance:
888
+ unit = fact.unit
889
+ if unit is not None:
890
+ unit._inUse = True
891
+ self._unitsInUseMarked = True
892
+ return (unit for unit in self.units.values() if getattr(unit, "_inUse", False))
882
893
 
883
894
  @property
884
895
  def dimensionsInUse(self) -> set[Any]:
arelle/WebCache.py CHANGED
@@ -6,20 +6,28 @@ e.g., User-Agent: Sample Company Name AdminContact@<sample company domain>.com
6
6
 
7
7
  '''
8
8
  from __future__ import annotations
9
- import contextlib
10
-
11
9
 
12
- from filelock import FileLock, Timeout
10
+ import calendar
11
+ import contextlib
12
+ import io
13
+ import json
14
+ import logging
15
+ import os
16
+ import posixpath
17
+ import shutil
18
+ import sys
19
+ import time
20
+ import zlib
21
+ from http.client import IncompleteRead
13
22
  from pathlib import Path
14
23
  from typing import TYPE_CHECKING, Any
15
- import os, posixpath, sys, time, calendar, io, json, logging, shutil, zlib
16
- import regex as re
17
- from urllib.parse import quote, unquote
18
- from urllib.error import URLError, HTTPError, ContentTooShortError
19
- from http.client import IncompleteRead
20
24
  from urllib import request as proxyhandlers
25
+ from urllib.error import ContentTooShortError, HTTPError, URLError
26
+ from urllib.parse import quote, unquote, urlsplit, urlunsplit
21
27
 
22
28
  import certifi
29
+ import regex as re
30
+ from filelock import FileLock, Timeout
23
31
 
24
32
  from arelle.PythonUtil import isLegacyAbs
25
33
 
@@ -567,14 +575,16 @@ class WebCache:
567
575
  :param url:
568
576
  :return: `url` with scheme-specific-part quoted except for parameter separators
569
577
  """
570
- urlScheme, schemeSep, urlSchemeSpecificPart = url.partition("://")
571
- urlPath, querySep, query = urlSchemeSpecificPart.partition("?")
572
- # RFC 3986: https://www.ietf.org/rfc/rfc3986.txt
573
- querySafeChars = ';/?'
574
- pathSafeChars = querySafeChars + ':@&=+$,'
575
- quotedUrlPath = quote(urlPath, safe=pathSafeChars)
576
- quotedQuery = quote(query, safe=querySafeChars)
577
- return urlScheme + schemeSep + quotedUrlPath + querySep + quotedQuery
578
+ parts = urlsplit(url)
579
+
580
+ # RFC 3986 safe characters: https://www.ietf.org/rfc/rfc3986.txt
581
+ pathSafe = "/:@!$&'()*+,;=" # path allows sub-delims, ":" and "@"
582
+ querySafe = "&=:/?@!$'()*+,;[]" # query allows pchar + "/" + "?"
583
+
584
+ quotedPath = quote(parts.path, safe=pathSafe)
585
+ quotedQuery = quote(parts.query, safe=querySafe)
586
+
587
+ return urlunsplit((parts.scheme, parts.netloc, quotedPath, quotedQuery, parts.fragment))
578
588
 
579
589
  @staticmethod
580
590
  def _getFileTimestamp(path: str) -> float:
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.49'
21
- __version_tuple__ = version_tuple = (2, 37, 49)
20
+ __version__ = version = '2.37.50'
21
+ __version_tuple__ = version_tuple = (2, 37, 50)
arelle/api/Session.py CHANGED
@@ -8,7 +8,7 @@ from __future__ import annotations
8
8
  import logging
9
9
  import threading
10
10
  from types import TracebackType
11
- from typing import Any, BinaryIO
11
+ from typing import Any, BinaryIO, TypeVar
12
12
 
13
13
  from arelle import PackageManager, PluginManager
14
14
  from arelle.CntlrCmdLine import CntlrCmdLine, createCntlrAndPreloadPlugins
@@ -18,6 +18,9 @@ from arelle.RuntimeOptions import RuntimeOptions
18
18
 
19
19
  _session_lock = threading.Lock()
20
20
 
21
+ # typing.Self can be used once Python 3.10 support is dropped.
22
+ Self = TypeVar("Self", bound="Session")
23
+
21
24
 
22
25
  class Session:
23
26
  """
@@ -46,7 +49,7 @@ class Session:
46
49
  "Session objects cannot be shared between threads. Create a new Session instance in each thread."
47
50
  )
48
51
 
49
- def __enter__(self) -> Any:
52
+ def __enter__(self: Self) -> Self:
50
53
  return self
51
54
 
52
55
  def __exit__(
@@ -146,7 +146,6 @@ class PluginValidationDataExtension(PluginData):
146
146
  return self._reportingPeriodContexts
147
147
  contexts = []
148
148
  for context in modelXbrl.contexts.values():
149
- context = cast(ModelContext, context)
150
149
  if context.isInstantPeriod or context.isForeverPeriod:
151
150
  continue # Reporting period contexts can't be instant/forever contexts
152
151
  if len(context.qnameDims) > 0:
@@ -14,12 +14,21 @@ class FormType(Enum):
14
14
  FORM_2_4 = '第二号の四様式'
15
15
  FORM_2_7 = '第二号の七様式'
16
16
  FORM_3 = '第三号様式'
17
+ FORM_4 = '第四号様式'
18
+
19
+ @property
20
+ def isStockReport(self) -> bool:
21
+ return self in STOCK_REPORT_FORMS
17
22
 
18
23
  CORPORATE_FORMS =frozenset([
19
24
  FormType.FORM_2_4,
20
25
  FormType.FORM_2_7,
21
26
  FormType.FORM_3,
22
27
  ])
28
+ STOCK_REPORT_FORMS = frozenset([
29
+ FormType.FORM_3,
30
+ FormType.FORM_4,
31
+ ])
23
32
  qnEdinetManifestInsert = qname("{http://disclosure.edinet-fsa.go.jp/2013/manifest}insert")
24
33
  qnEdinetManifestInstance = qname("{http://disclosure.edinet-fsa.go.jp/2013/manifest}instance")
25
34
  qnEdinetManifestItem = qname("{http://disclosure.edinet-fsa.go.jp/2013/manifest}item")
@@ -24,7 +24,7 @@ from arelle.ValidateDuplicateFacts import getDeduplicatedFacts, DeduplicationTyp
24
24
  from arelle.XmlValidate import VALID
25
25
  from arelle.typing import TypeGetText
26
26
  from arelle.utils.PluginData import PluginData
27
- from .Constants import CORPORATE_FORMS
27
+ from .Constants import CORPORATE_FORMS, FormType
28
28
  from .ControllerPluginData import ControllerPluginData
29
29
  from .ManifestInstance import ManifestInstance
30
30
  from .Statement import Statement, STATEMENTS, BalanceSheet, StatementInstance, StatementType
@@ -54,7 +54,7 @@ class PluginValidationDataExtension(PluginData):
54
54
  def __init__(self, name: str):
55
55
  super().__init__(name)
56
56
  jpcrpEsrNamespace = "http://disclosure.edinet-fsa.go.jp/taxonomy/jpcrp-esr/2024-11-01/jpcrp-esr_cor"
57
- jpcrpNamespace = 'http://disclosure.edinet-fsa.go.jp/taxonomy/jpcrp/2024-11-01/jpcrp_cor'
57
+ self.jpcrpNamespace = 'http://disclosure.edinet-fsa.go.jp/taxonomy/jpcrp/2024-11-01/jpcrp_cor'
58
58
  jpdeiNamespace = 'http://disclosure.edinet-fsa.go.jp/taxonomy/jpdei/2013-08-31/jpdei_cor'
59
59
  jpigpNamespace = "http://disclosure.edinet-fsa.go.jp/taxonomy/jpigp/2024-11-01/jpigp_cor"
60
60
  jppfsNamespace = "http://disclosure.edinet-fsa.go.jp/taxonomy/jppfs/2024-11-01/jppfs_cor"
@@ -63,11 +63,12 @@ class PluginValidationDataExtension(PluginData):
63
63
  self.assetsIfrsQn = qname(jpigpNamespace, 'AssetsIFRS')
64
64
  self.consolidatedOrNonConsolidatedAxisQn = qname(jppfsNamespace, 'ConsolidatedOrNonConsolidatedAxis')
65
65
  self.documentTypeDeiQn = qname(jpdeiNamespace, 'DocumentTypeDEI')
66
+ self.issuedSharesTotalNumberOfSharesEtcQn = qname(self.jpcrpNamespace, 'IssuedSharesTotalNumberOfSharesEtcTextBlock')
66
67
  self.jpcrpEsrFilingDateCoverPageQn = qname(jpcrpEsrNamespace, 'FilingDateCoverPage')
67
- self.jpcrpFilingDateCoverPageQn = qname(jpcrpNamespace, 'FilingDateCoverPage')
68
+ self.jpcrpFilingDateCoverPageQn = qname(self.jpcrpNamespace, 'FilingDateCoverPage')
68
69
  self.jpspsFilingDateCoverPageQn = qname(jpspsNamespace, 'FilingDateCoverPage')
69
70
  self.nonConsolidatedMemberQn = qname(jppfsNamespace, "NonConsolidatedMember")
70
- self.ratioOfFemaleDirectorsAndOtherOfficersQn = qname(jpcrpNamespace, "RatioOfFemaleDirectorsAndOtherOfficers")
71
+ self.ratioOfFemaleDirectorsAndOtherOfficersQn = qname(self.jpcrpNamespace, "RatioOfFemaleDirectorsAndOtherOfficers")
71
72
 
72
73
  self.contextIdPattern = regex.compile(r'(Prior[1-9]Year|CurrentYear|Prior[1-9]Interim|Interim)(Duration|Instant)')
73
74
 
@@ -103,6 +104,12 @@ class PluginValidationDataExtension(PluginData):
103
104
  return True
104
105
  return False
105
106
 
107
+ def isCorporateReport(self, modelXbrl: ModelXbrl) -> bool:
108
+ return self.jpcrpNamespace in modelXbrl.namespaceDocs
109
+
110
+ def isStockForm(self, modelXbrl: ModelXbrl) -> bool:
111
+ documentTypes = self.getDocumentTypes(modelXbrl)
112
+ return any(documentType == form.value for form in FormType if form.isStockReport for documentType in documentTypes)
106
113
 
107
114
  def getBalanceSheets(self, modelXbrl: ModelXbrl, statement: Statement) -> list[BalanceSheet]:
108
115
  """
@@ -4,6 +4,7 @@ See COPYRIGHT.md for copyright information.
4
4
  from __future__ import annotations
5
5
 
6
6
  from collections import defaultdict
7
+ from itertools import chain
7
8
  from typing import Any, Iterable
8
9
 
9
10
  from arelle import XbrlConst
@@ -161,8 +162,9 @@ def rule_EC8054W(
161
162
  EDINET.EC8054W: For any context with ID containing "NonConsolidatedMember",
162
163
  the scenario element within must be set to "NonConsolidatedMember".
163
164
  """
164
- for context in val.modelXbrl.contexts.values():
165
- if pluginData.nonConsolidatedMemberQn.localName not in context.id:
165
+ allContexts = chain(val.modelXbrl.contexts.values(), val.modelXbrl.ixdsUnmappedContexts.values())
166
+ for context in allContexts:
167
+ if context.id is None or pluginData.nonConsolidatedMemberQn.localName not in context.id:
166
168
  continue
167
169
  member = context.dimMemberQname(
168
170
  pluginData.consolidatedOrNonConsolidatedAxisQn,
@@ -281,3 +281,25 @@ def rule_EC8075W(
281
281
  codes='EDINET.EC8075W',
282
282
  msg=_("The percentage of female executives has not been tagged in detail."),
283
283
  )
284
+
285
+
286
+ @validation(
287
+ hook=ValidationHook.XBRL_FINALLY,
288
+ disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
289
+ )
290
+ def rule_EC8076W(
291
+ pluginData: PluginValidationDataExtension,
292
+ val: ValidateXbrl,
293
+ *args: Any,
294
+ **kwargs: Any,
295
+ ) -> Iterable[Validation]:
296
+ """
297
+ EDINET.EC8076W: "Issued Shares, Total Number of Shares, etc. [Text Block]" (IssuedSharesTotalNumberOfSharesEtcTextBlock) is not tagged.
298
+ Applies to forms 3 and 4.
299
+ """
300
+ if pluginData.isStockForm(val.modelXbrl) and pluginData.isCorporateReport(val.modelXbrl):
301
+ if not pluginData.hasValidNonNilFact(val.modelXbrl, pluginData.issuedSharesTotalNumberOfSharesEtcQn):
302
+ yield Validation.warning(
303
+ codes='EDINET.EC8076W',
304
+ msg=_('"Issued Shares, Total Number of Shares, etc. [Text Block]" (IssuedSharesTotalNumberOfSharesEtcTextBlock) is not tagged.'),
305
+ )
@@ -257,13 +257,14 @@ def rule_gfm_1_2_8(
257
257
  EDINET.EC5700W: [GFM 1.2.8] Every xbrli:context element must appear in at least one
258
258
  contextRef attribute in the same instance.
259
259
  """
260
- unused_contexts = list(set(val.modelXbrl.contexts.values()) - set(val.modelXbrl.contextsInUse))
261
- unused_contexts.sort(key=lambda x: x.id)
262
- for context in unused_contexts:
260
+ unusedContexts = list(set(val.modelXbrl.contexts.values()) - set(val.modelXbrl.contextsInUse))
261
+ unusedContexts.extend(val.modelXbrl.ixdsUnmappedContexts.values())
262
+ unusedContexts.sort(key=lambda x: x.id if x.id is not None else "")
263
+ for context in unusedContexts:
263
264
  yield Validation.warning(
264
265
  codes='EDINET.EC5700W.GFM.1.2.8',
265
266
  msg=_('If you are not using a context, delete it if it is not needed.'),
266
- modelObject = context
267
+ modelObject=context
267
268
  )
268
269
 
269
270
 
@@ -484,6 +485,7 @@ def rule_gfm_1_2_25(
484
485
  XbrlConst.qnXbrliEndDate.clarkNotation,
485
486
  XbrlConst.qnXbrliInstant.clarkNotation
486
487
  ):
488
+ elt = cast(ModelObject, elt)
487
489
  dateText = XmlUtil.text(elt)
488
490
  if not GFM_CONTEXT_DATE_PATTERN.match(dateText):
489
491
  errors.append(elt)
@@ -558,12 +560,14 @@ def rule_gfm_1_2_27(
558
560
  EDINET.EC5700W: [GFM 1.2.27] An instance must not contain unused units.
559
561
  """
560
562
  # TODO: Consolidate validations involving unused units
561
- unusedUnits = set(val.modelXbrl.units.values()) - {fact.unit for fact in val.modelXbrl.facts if fact.unit is not None}
563
+ unusedUnits = list(set(val.modelXbrl.units.values()) - set(val.modelXbrl.unitsInUse))
564
+ unusedUnits.extend(val.modelXbrl.ixdsUnmappedUnits.values())
565
+ unusedUnits.sort(key=lambda x: x.hash)
562
566
  if len(unusedUnits) > 0:
563
567
  yield Validation.warning(
564
568
  codes='EDINET.EC5700W.GFM.1.2.27',
565
569
  msg=_("Delete unused units from the instance."),
566
- modelObject=list(unusedUnits)
570
+ modelObject=unusedUnits
567
571
  )
568
572
 
569
573
 
@@ -529,11 +529,11 @@ def validateXbrlFinally(val: ValidateXbrl, *args: Any, **kwargs: Any) -> None:
529
529
  if contextsWithDisallowedOCEs:
530
530
  modelXbrl.error("ESEF.2.1.3.segmentUsed",
531
531
  _("xbrli:segment container MUST NOT be used in contexts: %(contextIds)s"),
532
- modelObject=contextsWithDisallowedOCEs, contextIds=", ".join(c.id for c in contextsWithDisallowedOCEs))
532
+ modelObject=contextsWithDisallowedOCEs, contextIds=", ".join(c.id for c in contextsWithDisallowedOCEs if c.id is not None))
533
533
  if contextsWithDisallowedOCEcontent:
534
534
  modelXbrl.error("ESEF.2.1.3.scenarioContainsNonDimensionalContent",
535
535
  _("xbrli:scenario in contexts MUST NOT contain any other content than defined in XBRL Dimensions specification: %(contextIds)s"),
536
- modelObject=contextsWithDisallowedOCEcontent, contextIds=", ".join(c.id for c in contextsWithDisallowedOCEcontent))
536
+ modelObject=contextsWithDisallowedOCEcontent, contextIds=", ".join(c.id for c in contextsWithDisallowedOCEcontent if c.id is not None))
537
537
  if len(contextIdentifiers) > 1:
538
538
  modelXbrl.error("ESEF.2.1.4.multipleIdentifiers",
539
539
  _("All entity identifiers in contexts MUST have identical content: %(contextIds)s"),
@@ -589,11 +589,11 @@ def validateXbrlFinally(val: ValidateXbrl, *args: Any, **kwargs: Any) -> None:
589
589
  if contextsWithDisallowedOCEs:
590
590
  modelXbrl.error("ESEF.2.1.3.segmentUsed",
591
591
  _("xbrli:segment container MUST NOT be used in contexts: %(contextIds)s"),
592
- modelObject=contextsWithDisallowedOCEs, contextIds=", ".join(c.id for c in contextsWithDisallowedOCEs))
592
+ modelObject=contextsWithDisallowedOCEs, contextIds=", ".join(c.id for c in contextsWithDisallowedOCEs if c.id is not None))
593
593
  if contextsWithDisallowedOCEcontent:
594
594
  modelXbrl.error("ESEF.2.1.3.scenarioContainsNonDimensionalContent",
595
595
  _("xbrli:scenario in contexts MUST NOT contain any other content than defined in XBRL Dimensions specification: %(contextIds)s"),
596
- modelObject=contextsWithDisallowedOCEcontent, contextIds=", ".join(c.id for c in contextsWithDisallowedOCEcontent))
596
+ modelObject=contextsWithDisallowedOCEcontent, contextIds=", ".join(c.id for c in contextsWithDisallowedOCEcontent if c.id is not None))
597
597
  if len(contextIdentifiers) > 1:
598
598
  modelXbrl.error("ESEF.2.1.4.multipleIdentifiers",
599
599
  _("All entity identifiers in contexts MUST have identical content: %(contextIds)s"),
@@ -265,7 +265,7 @@ class PluginValidationDataExtension(PluginData):
265
265
  contextsWithPeriodTimeZone.append(context)
266
266
  if context.hasSegment:
267
267
  contextsWithSegments.append(context)
268
- if context.nonDimValues("scenario"): # type: ignore[no-untyped-call]
268
+ if context.nonDimValues("scenario"):
269
269
  contextsWithImproperContent.append(context)
270
270
  return ContextData(
271
271
  contextsWithImproperContent=contextsWithImproperContent,
@@ -552,9 +552,9 @@ def rule_fr_nl_3_03(
552
552
  """
553
553
  FR-NL-3.03: An XBRL instance document MUST NOT contain unused contexts
554
554
  """
555
- unused_contexts = list(set(val.modelXbrl.contexts.values()) - set(val.modelXbrl.contextsInUse))
556
- unused_contexts.sort(key=lambda x: x.id)
557
- for context in unused_contexts:
555
+ unusedContexts = list(set(val.modelXbrl.contexts.values()) - set(val.modelXbrl.contextsInUse))
556
+ unusedContexts.sort(key=lambda x: x.id if x.id is not None else "")
557
+ for context in unusedContexts:
558
558
  yield Validation.error(
559
559
  codes='NL.FR-NL-3.03',
560
560
  msg=_('Unused context must not exist in XBRL instance document'),
@@ -637,10 +637,9 @@ def rule_fr_nl_4_02(
637
637
  """
638
638
  FR-NL-4.02: An XBRL instance document MUST NOT contain unused 'xbrli:unit' elements
639
639
  """
640
- unused_units_set = set(val.modelXbrl.units.values()) - {fact.unit for fact in val.modelXbrl.facts if fact.unit is not None}
641
- unused_units = list(unused_units_set)
642
- unused_units.sort(key=lambda x: x.hash)
643
- for unit in unused_units:
640
+ unusedUnits = list(set(val.modelXbrl.units.values()) - set(val.modelXbrl.unitsInUse))
641
+ unusedUnits.sort(key=lambda x: x.hash)
642
+ for unit in unusedUnits:
644
643
  yield Validation.error(
645
644
  codes='NL.FR-NL-4.02',
646
645
  msg=_('Unused unit must not exist in the XBRL instance document'),
@@ -7,12 +7,13 @@ from dataclasses import dataclass
7
7
  from dataclasses import field
8
8
  from enum import Enum
9
9
  from functools import cached_property
10
- from typing import Any, cast
10
+ from typing import Any, cast, Iterable
11
11
 
12
12
  import regex as re
13
13
 
14
14
  from arelle.ModelInstanceObject import ModelFact
15
15
  from arelle.ModelXbrl import ModelXbrl
16
+ from arelle.XmlValidateConst import VALID
16
17
 
17
18
  # Error codes
18
19
  CH_AUDIT = 'Char.Audit'
@@ -430,10 +431,11 @@ class ValidateUK:
430
431
  _codeResultMap: dict[str, CodeResult] = field(default_factory=dict)
431
432
 
432
433
  def _checkValidFact(self, fact: ModelFact ) -> bool:
433
- if fact is not None:
434
- if not fact.isNil:
435
- return True
436
- return False
434
+ return (
435
+ fact is not None and
436
+ not fact.isNil and
437
+ fact.context is not None
438
+ )
437
439
 
438
440
  def _errorOnMissingFact(self, conceptLocalName: str) -> None:
439
441
  """
@@ -628,16 +630,12 @@ class ValidateUK:
628
630
  elif code == CH_CHAR_FUND:
629
631
  concept = CONCEPT_CHARITY_FUNDS
630
632
  trading = False
631
- for fact in self._getFacts(CONCEPT_ENTITY_TRADING_STATUS):
632
- if fact is None or fact.context is None:
633
- continue
634
- for qname, value in fact.context.qnameDims.items():
635
- if qname.localName == CONCEPT_ENTITY_TRADING_STATUS_DIMENSION:
636
- if value.xValue.localName in {
637
- NotTrading.CONCEPT_ENTITY_NO_LONGER_TRADING.value,
638
- NotTrading.CONCEPT_ENTITY_HAS_NEVER_TRADED.value,
639
- }:
640
- trading = True
633
+ for value in self._getDimensionValues(CONCEPT_ENTITY_TRADING_STATUS, CONCEPT_ENTITY_TRADING_STATUS_DIMENSION):
634
+ if value in {
635
+ NotTrading.CONCEPT_ENTITY_NO_LONGER_TRADING.value,
636
+ NotTrading.CONCEPT_ENTITY_HAS_NEVER_TRADED.value,
637
+ }:
638
+ trading = True
641
639
  if not self._getAndCheckValidFacts([concept]) and not trading:
642
640
  return CodeResult(
643
641
  conceptLocalName=concept,
@@ -686,13 +684,11 @@ class ValidateUK:
686
684
  """
687
685
  Determines if the language is set to Welsh, otherwise defaults to English.
688
686
  """
689
- for fact in self._getFacts(CONCEPT_REPORT_PRINCIPAL_LANGUAGE):
690
- if fact is None or fact.context is None:
691
- continue
692
- for qname, value in fact.context.qnameDims.items():
693
- if qname.localName == CONCEPT_LANGUAGES_DIMENSION:
694
- if value.xValue.localName == CONCEPT_WELSH:
695
- return HmrcLang.WELSH
687
+ if any(
688
+ lang == CONCEPT_WELSH
689
+ for lang in self._getDimensionValues(CONCEPT_REPORT_PRINCIPAL_LANGUAGE, CONCEPT_LANGUAGES_DIMENSION)
690
+ ):
691
+ return HmrcLang.WELSH
696
692
  return HmrcLang.ENGLISH
697
693
 
698
694
  def _yieldErrorOrWarning(self, code: str, result: CodeResult) -> None:
@@ -725,47 +721,19 @@ class ValidateUK:
725
721
 
726
722
  @cached_property
727
723
  def accountStatus(self) -> str | None:
728
- facts = self._getFacts(CONCEPT_ACCOUNTS_STATUS)
729
- for fact in facts:
730
- if not self._checkValidFact(fact):
731
- continue
732
- for qname, value in fact.context.qnameDims.items():
733
- if qname.localName == CONCEPT_ACCOUNTS_STATUS_DIMENSION:
734
- return cast(str, value.xValue.localName)
735
- return None
724
+ return next(iter(self._getDimensionValues(CONCEPT_ACCOUNTS_STATUS, CONCEPT_ACCOUNTS_STATUS_DIMENSION)), None)
736
725
 
737
726
  @cached_property
738
727
  def accountsType(self) -> str | None:
739
- facts = self._getFacts(CONCEPT_ACCOUNTS_TYPE_FULL_OR_ABBREVIATED)
740
- for fact in facts:
741
- if not self._checkValidFact(fact):
742
- continue
743
- for qname, value in fact.context.qnameDims.items():
744
- if qname.localName == CONCEPT_ACCOUNTS_TYPE_DIMENSION:
745
- return cast(str, value.xValue.localName)
746
- return None
728
+ return next(iter(self._getDimensionValues(CONCEPT_ACCOUNTS_TYPE_FULL_OR_ABBREVIATED, CONCEPT_ACCOUNTS_TYPE_DIMENSION)), None)
747
729
 
748
730
  @cached_property
749
731
  def accountingStandardsApplied(self) -> str | None:
750
- facts = self._getFacts(CONCEPT_ACCOUNTING_STANDARDS_APPLIED)
751
- for fact in facts:
752
- if not self._checkValidFact(fact):
753
- continue
754
- for qname, value in fact.context.qnameDims.items():
755
- if qname.localName == CONCEPT_ACCOUNTING_STANDARDS_DIMENSION:
756
- return cast(str, value.xValue.localName)
757
- return None
732
+ return next(iter(self._getDimensionValues(CONCEPT_ACCOUNTING_STANDARDS_APPLIED, CONCEPT_ACCOUNTING_STANDARDS_DIMENSION)), None)
758
733
 
759
734
  @cached_property
760
735
  def applicableLegislation(self) -> str | None:
761
- facts = self._getFacts(CONCEPT_APPLICABLE_LEGISLATION)
762
- for fact in facts:
763
- if not self._checkValidFact(fact):
764
- continue
765
- for qname, value in fact.context.qnameDims.items():
766
- if qname.localName == CONCEPT_APPLICABLE_LEGISLATION_DIMENSION:
767
- return cast(str, value.xValue.localName)
768
- return None
736
+ return next(iter(self._getDimensionValues(CONCEPT_APPLICABLE_LEGISLATION, CONCEPT_APPLICABLE_LEGISLATION_DIMENSION)), None)
769
737
 
770
738
  @cached_property
771
739
  def isEntityDormant(self) -> bool:
@@ -776,25 +744,22 @@ class ValidateUK:
776
744
 
777
745
  @cached_property
778
746
  def legalFormEntity(self) -> str | None:
779
- facts = self._getFacts(CONCEPT_LEGAL_FORM_ENTIY)
780
- for fact in facts:
781
- if not self._checkValidFact(fact):
782
- continue
783
- for qname, value in fact.context.qnameDims.items():
784
- if qname.localName == CONCEPT_LEGAL_FORM_ENTIY_DIMENSION:
785
- return cast(str, value.xValue.localName)
786
- return None
747
+ return next(iter(self._getDimensionValues(CONCEPT_LEGAL_FORM_ENTIY, CONCEPT_LEGAL_FORM_ENTIY_DIMENSION)), None)
787
748
 
788
749
  @cached_property
789
750
  def scopeAccounts(self) -> str | None:
790
- facts = self._getFacts(CONCEPT_SCOPE_ACCOUNTS)
751
+ return next(iter(self._getDimensionValues(CONCEPT_SCOPE_ACCOUNTS, CONCEPT_SCOPE_ACCOUNTS_DIMENSION)), None)
752
+
753
+ def _getDimensionValues(self, conceptLocalName: str, dimensionLocalName: str) -> Iterable[str]:
754
+ facts = self._getFacts(conceptLocalName)
791
755
  for fact in facts:
792
756
  if not self._checkValidFact(fact):
793
757
  continue
794
758
  for qname, value in fact.context.qnameDims.items():
795
- if qname.localName == CONCEPT_SCOPE_ACCOUNTS_DIMENSION:
796
- return cast(str, value.xValue.localName)
797
- return None
759
+ if value.xValid < VALID:
760
+ continue
761
+ if qname.localName == dimensionLocalName:
762
+ yield cast(str, value.xValue.localName)
798
763
 
799
764
  def validate(self) -> None:
800
765
  """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: arelle-release
3
- Version: 2.37.49
3
+ Version: 2.37.50
4
4
  Summary: An open source XBRL platform.
5
5
  Author-email: "arelle.org" <support@arelle.org>
6
6
  License-Expression: Apache-2.0
@@ -31,36 +31,38 @@ License-File: LICENSE.md
31
31
  Requires-Dist: bottle<0.14,>=0.13
32
32
  Requires-Dist: certifi
33
33
  Requires-Dist: filelock
34
- Requires-Dist: jsonschema==4.*
35
- Requires-Dist: isodate==0.*
36
- Requires-Dist: lxml<6,>=4
34
+ Requires-Dist: isodate<1,>=0
35
+ Requires-Dist: jsonschema<5,>=4
36
+ Requires-Dist: lxml!=6.0.0,<7,>=4
37
37
  Requires-Dist: numpy<3,>=1
38
- Requires-Dist: openpyxl==3.*
38
+ Requires-Dist: openpyxl<4,>=3
39
39
  Requires-Dist: pillow<12,>=10
40
- Requires-Dist: pyparsing==3.*
41
- Requires-Dist: python-dateutil==2.*
40
+ Requires-Dist: pyparsing<4,>=3
41
+ Requires-Dist: python-dateutil<3,>=2
42
42
  Requires-Dist: regex
43
- Requires-Dist: truststore==0.*; python_version > "3.9"
44
- Requires-Dist: typing-extensions==4.*
43
+ Requires-Dist: truststore<1,>=0; python_version > "3.9"
44
+ Requires-Dist: typing-extensions<5,>=4
45
45
  Provides-Extra: crypto
46
- Requires-Dist: pycryptodome==3.*; extra == "crypto"
46
+ Requires-Dist: pycryptodome<4,>=3; extra == "crypto"
47
47
  Provides-Extra: db
48
- Requires-Dist: pg8000==1.*; extra == "db"
49
- Requires-Dist: PyMySQL==1.*; extra == "db"
48
+ Requires-Dist: pg8000<2,>=1; extra == "db"
49
+ Requires-Dist: PyMySQL<2,>=1; extra == "db"
50
50
  Requires-Dist: pyodbc<6,>=4; extra == "db"
51
51
  Requires-Dist: rdflib<8,>=5; extra == "db"
52
52
  Provides-Extra: efm
53
- Requires-Dist: aniso8601==10.*; extra == "efm"
54
- Requires-Dist: holidays==0.*; extra == "efm"
55
- Requires-Dist: Matplotlib==3.*; extra == "efm"
53
+ Requires-Dist: aniso8601<11,>=10; extra == "efm"
54
+ Requires-Dist: holidays<1,>=0; extra == "efm"
55
+ Requires-Dist: matplotlib<4,>=3; extra == "efm"
56
56
  Requires-Dist: pytz; extra == "efm"
57
57
  Provides-Extra: esef
58
- Requires-Dist: tinycss2==1.*; extra == "esef"
58
+ Requires-Dist: tinycss2<2,>=1; extra == "esef"
59
59
  Provides-Extra: objectmaker
60
- Requires-Dist: graphviz==0.*; extra == "objectmaker"
60
+ Requires-Dist: graphviz<1,>=0; extra == "objectmaker"
61
61
  Provides-Extra: webserver
62
62
  Requires-Dist: cheroot<11,>=8; extra == "webserver"
63
- Requires-Dist: tornado==6.*; extra == "webserver"
63
+ Requires-Dist: tornado<7,>=6; extra == "webserver"
64
+ Provides-Extra: xule
65
+ Requires-Dist: aniso8601<11,>=10; extra == "xule"
64
66
  Dynamic: license-file
65
67
 
66
68
  # Arelle
@@ -36,10 +36,10 @@ arelle/LeiUtil.py,sha256=tSPrbQrXEeH5pXgGA_6MAdgMZp20NaW5izJglIXyEQk,5095
36
36
  arelle/LinkbaseType.py,sha256=BwRQl4XZFFCopufC2FEMLhYENNTk2JUWVQvnIUsaqtI,3108
37
37
  arelle/LocalViewer.py,sha256=WVrfek_bLeFFxgWITi1EQb6xCQN8O9Ks-ZL16vRncSk,3080
38
38
  arelle/Locale.py,sha256=07IDxv8nIfvhyRRllFdEAKRI3yo1D2v781cTrjb_RoQ,33193
39
- arelle/ModelDocument.py,sha256=Sq6umEdn-aNHjxIpEsXTT7A4V25nGY0JiylSnhr9zSI,130749
39
+ arelle/ModelDocument.py,sha256=t8fcz5vIj6mNclzaf2kKIz9IJxYi23QoLaW2Av-CmB0,130523
40
40
  arelle/ModelDtsObject.py,sha256=nvHQs4BDmPxY6mqLiBuqIGRJXyA1EqOEGB2f3S6A6w4,88656
41
41
  arelle/ModelFormulaObject.py,sha256=-eb0lBYciEeAvvGduIs3AHGNGrxge9_0g1cVT6UUgvc,122560
42
- arelle/ModelInstanceObject.py,sha256=fUiDb6aS2ls0GkrVxxkPyZqEr-RI4qsGQJjKkAK2tUk,74246
42
+ arelle/ModelInstanceObject.py,sha256=77rkxl1FK8OyJhTXkrNv6B_4oEK6IZm9eRQdFDxslGk,74278
43
43
  arelle/ModelManager.py,sha256=QUNcD2LC_YyyGFU8bFTSuzIGI1qpOK55KBlQ697Ep1I,11075
44
44
  arelle/ModelObject.py,sha256=Rttkhv-PtfneZyDYsG5FDh98BzT97ameTmwNdqFaOv0,18657
45
45
  arelle/ModelObjectFactory.py,sha256=0yEtkmyOmSjhUK1I4b3eINxtYKsysakntoWn4VAqLeg,9172
@@ -51,7 +51,7 @@ arelle/ModelTestcaseObject.py,sha256=2hFrl1tdDAxPZpZCEJdYUzti-HFLGgDgCNp6lEBPvqs
51
51
  arelle/ModelValue.py,sha256=0sr7njFjGI2W3Bct2dxf2LoG_fLerHQouQtM0v0ZY2E,39573
52
52
  arelle/ModelVersObject.py,sha256=cPD1IzhkCfuV1eMgVFWes88DH_6WkUj5kj7sgGF2M0I,26062
53
53
  arelle/ModelVersReport.py,sha256=bXEA9K3qkH57aABn5l-m3CTY0FAcF1yX6O4fo-URjl8,73326
54
- arelle/ModelXbrl.py,sha256=w7x74hBV-Ub4gRQ-iT4lIC13KCxp699W2FJ-AO7cebw,60639
54
+ arelle/ModelXbrl.py,sha256=oEEP-whMGZjG45BXeXabXcD_IzBp7yA-21gW6zlGe2U,61120
55
55
  arelle/PackageManager.py,sha256=BvPExMcxh8rHMxogOag-PGbX6vXdhCiXAHcDLA6Ypsc,32592
56
56
  arelle/PluginManager.py,sha256=Gnh7xmvyIQX2PyCwjDMFZVanCM9KW09I-x5x8YfDpJs,42220
57
57
  arelle/PluginUtils.py,sha256=0vFQ29wVVpU0cTY3YOBL6FhNQhhCTwShBH4qTJGLnvc,2426
@@ -115,7 +115,7 @@ arelle/ViewWinTupleGrid.py,sha256=Li21jmMSZP3xIkpg8eY8Sq7KTIuAgM57wHu7i7Nu3P0,89
115
115
  arelle/ViewWinVersReport.py,sha256=aYfsOgynVZpMzl6f2EzQCBLzdihYGycwb5SiTghkgMQ,9344
116
116
  arelle/ViewWinXml.py,sha256=4ZGKtjaoCwU9etKYm9ZAS7jSmUxba1rqNEdv0OIyjTY,1250
117
117
  arelle/WatchRss.py,sha256=5Ih4igH2MM4hpOuAXy9eO0QAyZ7jZR3S5bPzo2sdFpw,14097
118
- arelle/WebCache.py,sha256=HlF4vfjxO0bSFHqMPfjnmkrzc7RK9XT714a7g3XFTDY,45192
118
+ arelle/WebCache.py,sha256=SLk-S5StYUIucm5bd2BqT-o8ZA0NdYw2Xl4O9vIt7O8,45257
119
119
  arelle/XbrlConst.py,sha256=_K3__pmzcJKvSt72n4Vybo2qUaKeOGP-HbiiqCoBpqQ,58491
120
120
  arelle/XbrlUtil.py,sha256=s2Vmrh-sZI5TeuqsziKignOc3ao-uUgnCNoelP4dDj0,9212
121
121
  arelle/XhtmlValidate.py,sha256=0gtm7N-kXK0RB5o3c1AQXjfFuRp1w2fKZZAeyruNANw,5727
@@ -125,9 +125,9 @@ arelle/XmlValidateConst.py,sha256=U_wN0Q-nWKwf6dKJtcu_83FXPn9c6P8JjzGA5b0w7P0,33
125
125
  arelle/XmlValidateParticles.py,sha256=Mn6vhFl0ZKC_vag1mBwn1rH_x2jmlusJYqOOuxFPO2k,9231
126
126
  arelle/XmlValidateSchema.py,sha256=6frtZOc1Yrx_5yYF6V6oHbScnglWrVbWr6xW4EHtLQI,7428
127
127
  arelle/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
128
- arelle/_version.py,sha256=Ee0guntzPFkQ3dVGjmJhql2UxZBI6xicDkHrMXRgOlk,515
128
+ arelle/_version.py,sha256=njDexQGIu5W1_Bx2XXI0APU6EFVbL-MHc7OHXGD6xDg,515
129
129
  arelle/typing.py,sha256=PRe-Fxwr2SBqYYUVPCJ3E7ddDX0_oOISNdT5Q97EbRM,1246
130
- arelle/api/Session.py,sha256=27HVuK3Bz1_21l4_RLn1IQg6v0MNsUEYrHajymyWwxI,7429
130
+ arelle/api/Session.py,sha256=kgSxS7VckA1sQ7xp0pJiK7IK-vRxAdAZKUo8gEx27s8,7549
131
131
  arelle/config/creationSoftwareNames.json,sha256=5MK7XUjfDJ9OpRCCHXeOErJ1SlTBZji4WEcEOdOacx0,3128
132
132
  arelle/config/disclosuresystems.xml,sha256=8lBSGCOuVsVxttmpqkPlURBzaiGpPm8b8aYtxKRsKnk,16617
133
133
  arelle/config/disclosuresystems.xsd,sha256=_b7Fy3-R4L7oVouwokSrUOtswjoas1yuCo4czKL7sKc,4212
@@ -300,7 +300,7 @@ arelle/plugin/validate/CIPC/Const.py,sha256=GSiODyiK8V9P-pV0_DPEKYAhe2wqgcYJP2Qt
300
300
  arelle/plugin/validate/CIPC/__init__.py,sha256=R6KVETICUpfW--TvVkFNDo-67Kq_KpWz3my2ECkiKxM,14699
301
301
  arelle/plugin/validate/CIPC/config.xml,sha256=4pyn40JAvQQeoRC8I046gZ4ZcmUnekX3TNfYpC5yonI,667
302
302
  arelle/plugin/validate/DBA/DisclosureSystems.py,sha256=Dp_r-Pa3tahtCfDha2Zc97N0iyrY4Zagb8w2D9ErILg,294
303
- arelle/plugin/validate/DBA/PluginValidationDataExtension.py,sha256=R0lNf-3-lKHlnCy4ByU1TT1lVImMe35KeV-mbDxeaco,7290
303
+ arelle/plugin/validate/DBA/PluginValidationDataExtension.py,sha256=y9W5S5QeuBoDkZra7fFp3gHQhB8R0cPifbs21QlHQQI,7240
304
304
  arelle/plugin/validate/DBA/ValidationPluginExtension.py,sha256=UygF7oELnPJcP6Ta0ncy3dy5fnJq-Mz6N2-gEaVhigo,48690
305
305
  arelle/plugin/validate/DBA/__init__.py,sha256=KhmlUkqgsRtEXpu5DZBXFzv43nUTvi-0sdDNRfw5Up4,1564
306
306
  arelle/plugin/validate/DBA/resources/config.xml,sha256=KHfo7SrjzmjHbfwIJBmESvOOjdIv4Av26BCcZxfn3Pg,875
@@ -312,12 +312,12 @@ arelle/plugin/validate/DBA/rules/tm.py,sha256=ui9oKBqlAForwkQ9kk9KBiUogTJE5pv1Rb
312
312
  arelle/plugin/validate/DBA/rules/tr.py,sha256=4TootFjl0HXsKZk1XNBCyj-vnjRs4lg35hfiz_b_4wU,14684
313
313
  arelle/plugin/validate/EBA/__init__.py,sha256=x3zXNcdSDJ3kHfL7kMs0Ve0Vs9oWbzNFVf1TK4Avmy8,45924
314
314
  arelle/plugin/validate/EBA/config.xml,sha256=37wMVUAObK-XEqakqD8zPNog20emYt4a_yfL1AKubF8,2022
315
- arelle/plugin/validate/EDINET/Constants.py,sha256=QgNO3ZcTfJPMIGogS4Xuyz2BtISJ_PxYP2GmNbshx8c,1136
315
+ arelle/plugin/validate/EDINET/Constants.py,sha256=bYLMdzEFw6X1jchW5iN5pUAQ8K7-cGtiZRN22r1LP6g,1339
316
316
  arelle/plugin/validate/EDINET/ControllerPluginData.py,sha256=PrEhllue_lh-sLeUy9w8I9XLMLgpo5eW-c7ZKgNyGLE,6256
317
317
  arelle/plugin/validate/EDINET/DisclosureSystems.py,sha256=3rKG42Eg-17Xx_KXU_V5yHW6I3LTwQunvf4a44C9k_4,36
318
318
  arelle/plugin/validate/EDINET/InstanceType.py,sha256=aLKb4-AJ6nDZKMOLCp7u08E9VD64ExeZy9_oGth-LTk,3207
319
319
  arelle/plugin/validate/EDINET/ManifestInstance.py,sha256=SkQV-aOsYn3CTgCkH4IXNdM3QKoiz8okwb29ftMtV3Q,6882
320
- arelle/plugin/validate/EDINET/PluginValidationDataExtension.py,sha256=3EhtXN_7q3SBgqiHNzuGwlEe-yT4x1hL1t1jtZG9cYE,10983
320
+ arelle/plugin/validate/EDINET/PluginValidationDataExtension.py,sha256=NBCXANYep0AvQVe2zm2eaKzklvLCC1zeQ_oa8L6cryM,11498
321
321
  arelle/plugin/validate/EDINET/Statement.py,sha256=0Mw5IB7LMtvUZ-2xKZfxmq67xF_dCgJo3eNLweLFRHU,9350
322
322
  arelle/plugin/validate/EDINET/UploadContents.py,sha256=L0u5171cLBKX7NT-_szRqOfkiy4Gv1xPsfpPVgPhtu0,409
323
323
  arelle/plugin/validate/EDINET/ValidationPluginExtension.py,sha256=oMY0ntLr1qIh3uMi1W_M-bT5bhXPDx048X3oDFP5zOY,2042
@@ -325,10 +325,10 @@ arelle/plugin/validate/EDINET/__init__.py,sha256=OZ7gMknCHd0M-9nt8UOmjEZW50YQzbv
325
325
  arelle/plugin/validate/EDINET/resources/config.xml,sha256=7uT4GcRgk5veMLpFhPPQJxbGKiQvM52P8EMrjn0qd0g,646
326
326
  arelle/plugin/validate/EDINET/resources/edinet-taxonomies.xml,sha256=997I3RGTLg5OY3vn5hQxVFAAxOmDSOYpuyQe6VnWSY0,16285
327
327
  arelle/plugin/validate/EDINET/rules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
328
- arelle/plugin/validate/EDINET/rules/contexts.py,sha256=anmkmrrb8kSZRYhrgkh1dlZC1rpCgCtJqZ2TnsBMP5s,7458
329
- arelle/plugin/validate/EDINET/rules/edinet.py,sha256=pgTmG32uEG8dDPVaBIYE_wN-hKV5AFZL0_wB11L0xHQ,11733
328
+ arelle/plugin/validate/EDINET/rules/contexts.py,sha256=KPoyWfRaURvxoGVcWP64mTMTAKPMSmQSX06RClCLddw,7590
329
+ arelle/plugin/validate/EDINET/rules/edinet.py,sha256=VYrDZaKbsQuQEvOY5F0Pv4Jzk9YZ4iETOkAFOggrhEY,12632
330
330
  arelle/plugin/validate/EDINET/rules/frta.py,sha256=N0YglHYZuLD2IuwE26viR2ViwUYjneBuMFU9vlrS0aQ,7616
331
- arelle/plugin/validate/EDINET/rules/gfm.py,sha256=udaGzYmKiCudXGE7yA_ej-Tcs3JDaUxHbR87ZITUPLA,24568
331
+ arelle/plugin/validate/EDINET/rules/gfm.py,sha256=Ty5zDqIRkXwnOQTzK5JD2F6jbK1xEiseltosVfYUrVM,24772
332
332
  arelle/plugin/validate/EDINET/rules/manifests.py,sha256=MoT9R_a4BzuYdQVbF7RC5wz134Ve68svSdJ3NlpO_AU,4026
333
333
  arelle/plugin/validate/EDINET/rules/upload.py,sha256=k1o12K_vMN2N5bAXPxLRwyKjghoOGrgfLijE_j_5ilQ,19811
334
334
  arelle/plugin/validate/ESEF/Const.py,sha256=JujF_XV-_TNsxjGbF-8SQS4OOZIcJ8zhCMnr-C1O5Ho,22660
@@ -337,10 +337,10 @@ arelle/plugin/validate/ESEF/Util.py,sha256=QH3btcGqBpr42M7WSKZLSdNXygZaZLfEiEjlx
337
337
  arelle/plugin/validate/ESEF/__init__.py,sha256=LL7uYOcGPHgjwTlcfW2oWMqWiqrZ5yABzcKkJZFrZis,20391
338
338
  arelle/plugin/validate/ESEF/ESEF_2021/DTS.py,sha256=6Za7BANwwc_egxLCgbgWzwUGOXZv9IF1I7JCkDNt2Tw,26277
339
339
  arelle/plugin/validate/ESEF/ESEF_2021/Image.py,sha256=4bnhuy5viBU0viPjb4FhcRRjVVKlNdnKLFdSGg3sZvs,4871
340
- arelle/plugin/validate/ESEF/ESEF_2021/ValidateXbrlFinally.py,sha256=R3cVpiq3x0YyH5cT1L_CfAR_8onn0nHVuruFSFsszCk,63675
340
+ arelle/plugin/validate/ESEF/ESEF_2021/ValidateXbrlFinally.py,sha256=YhjHL3vo07ZtdCwUsOeTTKdiU8fmDyO9L4gbQ6nBSi4,63715
341
341
  arelle/plugin/validate/ESEF/ESEF_2021/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
342
342
  arelle/plugin/validate/ESEF/ESEF_Current/DTS.py,sha256=epp-PBh1NJzQqgxUE6C468HmoDc2w3j54rMwfiOAry4,29334
343
- arelle/plugin/validate/ESEF/ESEF_Current/ValidateXbrlFinally.py,sha256=J9hJcLlE6FA84Ppgthiu4ju0KHJ-JdmVub2qKAKm3as,74985
343
+ arelle/plugin/validate/ESEF/ESEF_Current/ValidateXbrlFinally.py,sha256=FmdnPircIKOO9EvFGzlAeRJGmMLnDHPpALM0-8zfKIs,75025
344
344
  arelle/plugin/validate/ESEF/ESEF_Current/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
345
345
  arelle/plugin/validate/ESEF/resources/authority-validations.json,sha256=_Xnqaj0pdw2QM3LhOguBHnEqbo1eutm643_SO18UJls,15487
346
346
  arelle/plugin/validate/ESEF/resources/config.xml,sha256=t3STU_-QYM7Ay8YwZRPapnohiWVWhjfr4L2Rjx9xN9U,3902
@@ -348,7 +348,7 @@ arelle/plugin/validate/FERC/__init__.py,sha256=rC1OYNBWnoXowEohiR9yagHtAi_NPAlma
348
348
  arelle/plugin/validate/FERC/config.xml,sha256=bn9b8eCqJA1J62rYq1Nz85wJrMGAahVmmnIUQZyerjo,1919
349
349
  arelle/plugin/validate/FERC/resources/ferc-utr.xml,sha256=OCRj9IUpdXATCBXKbB71apYx9kxcNtZW-Hq4s-avsRY,2663
350
350
  arelle/plugin/validate/NL/DisclosureSystems.py,sha256=urRmYJ8RnGPlTgSVKW7zGN4_4CtL3OVKlcI3LwTpBz4,561
351
- arelle/plugin/validate/NL/PluginValidationDataExtension.py,sha256=OswvJzy5AdvIDw1N_IeWDehKbUHdOFnipy0qhjAaImw,33678
351
+ arelle/plugin/validate/NL/PluginValidationDataExtension.py,sha256=YMhmcAJm3Z0UfOQehM7a204GXUY8E8AGAM1Cbe1aCXg,33645
352
352
  arelle/plugin/validate/NL/ValidationPluginExtension.py,sha256=GCeR6xh1Dd7IhFoQk5XD6Hg2bg9PyyWEWp5GzxUdUq4,18070
353
353
  arelle/plugin/validate/NL/__init__.py,sha256=W-SHohiAWM7Yi77gAbt-D3vvZNAB5s1j16mHCTFta6w,3158
354
354
  arelle/plugin/validate/NL/resources/config.xml,sha256=qBE6zywFSmemBSWonuTII5iuOCUlNb1nvkpMbsZb5PM,1853
@@ -356,7 +356,7 @@ arelle/plugin/validate/NL/rules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm
356
356
  arelle/plugin/validate/NL/rules/br_kvk.py,sha256=0SwKieWzTDm3YMsXPS6zTdgbk7_Z9CzqRkRmCRz1OiQ,15789
357
357
  arelle/plugin/validate/NL/rules/fg_nl.py,sha256=OJF2EYx4KDTdNggHiw5Trq5S5g7WGpbb7YvO6_IrrGU,10704
358
358
  arelle/plugin/validate/NL/rules/fr_kvk.py,sha256=kYqXt45S6eM32Yg9ii7pUhOMfJaHurgYqQ73FyQALs8,8171
359
- arelle/plugin/validate/NL/rules/fr_nl.py,sha256=vwzk6_P6jhszpeboTM09uOHtm-Lijzz7Iqu7NsYKyaE,31444
359
+ arelle/plugin/validate/NL/rules/fr_nl.py,sha256=ZoyiRsTyqTNZB_VgcdabmeNi6v7DY6jMxzaP6ppLtIU,31387
360
360
  arelle/plugin/validate/NL/rules/nl_kvk.py,sha256=bPD5lfr6dxdVGPZ2D_bEZtbz02tzsX_BZ5kC-CZJNwc,90170
361
361
  arelle/plugin/validate/ROS/DisclosureSystems.py,sha256=rJ81mwQDYTi6JecFZ_zhqjjz3VNQRgjHNSh0wcQWAQE,18
362
362
  arelle/plugin/validate/ROS/PluginValidationDataExtension.py,sha256=nCZoGWNX4aUN5oQBJqa8UrG9tElPW906xkfzRlbjBB8,4285
@@ -366,7 +366,7 @@ arelle/plugin/validate/ROS/config.xml,sha256=ZCpCFgr1ZAjoUuhb1eRpDnmKrae-sXA9yl6
366
366
  arelle/plugin/validate/ROS/resources/config.xml,sha256=HXWume5HlrAqOx5AtiWWqgADbRatA8YSfm_JvZGwdgQ,657
367
367
  arelle/plugin/validate/ROS/rules/__init__.py,sha256=wW7BUAIb7sRkOxC1Amc_ZKrz03FM-Qh1TyZe6wxYaAU,1567
368
368
  arelle/plugin/validate/ROS/rules/ros.py,sha256=Dk5BkfKQYItImdx5FcFvkMWT5BlJ1r_L7Vn-EsCG85A,19870
369
- arelle/plugin/validate/UK/ValidateUK.py,sha256=0UhSwsY1lrY-EAEBJJR9QY38YXGBZ6PEgmuC5gQfBlI,57813
369
+ arelle/plugin/validate/UK/ValidateUK.py,sha256=h7-tnCubHme8Meaif-o55TV2rCfMWuikfpZCcK6NNDs,56447
370
370
  arelle/plugin/validate/UK/__init__.py,sha256=KE6s_B-EvrHDCtWQz2N_wQwyx_ZbWhYNV2GfQnluxMw,30655
371
371
  arelle/plugin/validate/UK/config.xml,sha256=mUFhWDfBzGTn7v0ZSmf4HaweQTMJh_4ZcJmD9mzCHrA,1547
372
372
  arelle/plugin/validate/UK/consistencyChecksByName.json,sha256=BgB9YAWzmcsX-_rU74RBkABwEsS75vrMlwBHsYCz2R0,25247
@@ -680,9 +680,9 @@ arelle/utils/validate/ValidationUtil.py,sha256=9vmSvShn-EdQy56dfesyV8JjSRVPj7txr
680
680
  arelle/utils/validate/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
681
681
  arelle/webserver/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
682
682
  arelle/webserver/bottle.py,sha256=P-JECd9MCTNcxCnKoDUvGcoi03ezYVOgoWgv2_uH-6M,362
683
- arelle_release-2.37.49.dist-info/licenses/LICENSE.md,sha256=Q0tn6q0VUbr-NM8916513NCIG8MNzo24Ev-sxMUBRZc,3959
684
- arelle_release-2.37.49.dist-info/METADATA,sha256=l7IqnpMRntF6T7qKQ6jhMMGggWKen61_a-bAVs7PI6Y,9231
685
- arelle_release-2.37.49.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
686
- arelle_release-2.37.49.dist-info/entry_points.txt,sha256=Uj5niwfwVsx3vaQ3fYj8hrZ1xpfCJyTUA09tYKWbzpo,111
687
- arelle_release-2.37.49.dist-info/top_level.txt,sha256=fwU7SYawL4_r-sUMRg7r1nYVGjFMSDvRWx8VGAXEw7w,7
688
- arelle_release-2.37.49.dist-info/RECORD,,
683
+ arelle_release-2.37.50.dist-info/licenses/LICENSE.md,sha256=Q0tn6q0VUbr-NM8916513NCIG8MNzo24Ev-sxMUBRZc,3959
684
+ arelle_release-2.37.50.dist-info/METADATA,sha256=4w922-d1vIeCmfCpQ18ImtcI_0C7_qguifO2WlU-yYo,9327
685
+ arelle_release-2.37.50.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
686
+ arelle_release-2.37.50.dist-info/entry_points.txt,sha256=Uj5niwfwVsx3vaQ3fYj8hrZ1xpfCJyTUA09tYKWbzpo,111
687
+ arelle_release-2.37.50.dist-info/top_level.txt,sha256=fwU7SYawL4_r-sUMRg7r1nYVGjFMSDvRWx8VGAXEw7w,7
688
+ arelle_release-2.37.50.dist-info/RECORD,,