arelle-release 2.37.39__py3-none-any.whl → 2.37.40__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/ModelInstanceObject.py +1 -1
- arelle/ValidateXbrlCalcs.py +8 -18
- arelle/_version.py +2 -2
- arelle/plugin/validate/DBA/rules/__init__.py +9 -8
- arelle/plugin/validate/DBA/rules/fr.py +3 -3
- arelle/plugin/validate/DBA/rules/tr.py +4 -2
- arelle/plugin/validate/EBA/__init__.py +7 -10
- arelle/plugin/validate/EDINET/rules/gfm.py +97 -0
- arelle/plugin/validate/ESEF/ESEF_2021/ValidateXbrlFinally.py +8 -17
- arelle/plugin/validate/ESEF/ESEF_Current/ValidateXbrlFinally.py +8 -17
- arelle/plugin/validate/FERC/__init__.py +6 -10
- arelle/plugin/validate/NL/PluginValidationDataExtension.py +0 -12
- arelle/plugin/validate/NL/rules/fr_nl.py +2 -4
- arelle/plugin/validate/NL/rules/nl_kvk.py +3 -3
- arelle/plugin/validate/ROS/rules/ros.py +9 -17
- arelle/utils/Contexts.py +38 -0
- arelle/utils/Equivalence.py +22 -0
- arelle/utils/Units.py +36 -0
- {arelle_release-2.37.39.dist-info → arelle_release-2.37.40.dist-info}/METADATA +1 -1
- {arelle_release-2.37.39.dist-info → arelle_release-2.37.40.dist-info}/RECORD +24 -21
- {arelle_release-2.37.39.dist-info → arelle_release-2.37.40.dist-info}/WHEEL +0 -0
- {arelle_release-2.37.39.dist-info → arelle_release-2.37.40.dist-info}/entry_points.txt +0 -0
- {arelle_release-2.37.39.dist-info → arelle_release-2.37.40.dist-info}/licenses/LICENSE.md +0 -0
- {arelle_release-2.37.39.dist-info → arelle_release-2.37.40.dist-info}/top_level.txt +0 -0
arelle/ModelInstanceObject.py
CHANGED
|
@@ -1266,7 +1266,7 @@ class ModelContext(ModelObject):
|
|
|
1266
1266
|
|
|
1267
1267
|
def isEntityIdentifierEqualTo(self, cntx2):
|
|
1268
1268
|
"""(bool) -- True if entityIdentifier values are equal (scheme and text value)"""
|
|
1269
|
-
return self.
|
|
1269
|
+
return self.entityIdentifier == cntx2.entityIdentifier
|
|
1270
1270
|
|
|
1271
1271
|
def isEqualTo(self, cntx2, dimensionalAspectModel=None) -> bool:
|
|
1272
1272
|
if dimensionalAspectModel is None: dimensionalAspectModel = self.modelXbrl.hasXDT
|
arelle/ValidateXbrlCalcs.py
CHANGED
|
@@ -12,6 +12,8 @@ from arelle import Locale, XbrlConst, XbrlUtil
|
|
|
12
12
|
from arelle.ModelObject import ObjectPropertyViewWrapper
|
|
13
13
|
from arelle.PythonUtil import flattenSequence, strTruncate
|
|
14
14
|
from arelle.XmlValidateConst import UNVALIDATED, VALID
|
|
15
|
+
from arelle.utils.Contexts import partitionModelXbrlContexts
|
|
16
|
+
from arelle.utils.Units import partitionModelXbrlUnits
|
|
15
17
|
|
|
16
18
|
if TYPE_CHECKING:
|
|
17
19
|
from _decimal import Decimal
|
|
@@ -147,27 +149,15 @@ class ValidateXbrlCalcs:
|
|
|
147
149
|
|
|
148
150
|
# identify equal contexts
|
|
149
151
|
modelXbrl.profileActivity()
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
if h in uniqueContextHashes:
|
|
154
|
-
if context.isEqualTo(uniqueContextHashes[h]):
|
|
155
|
-
self.mapContext[context] = uniqueContextHashes[h]
|
|
156
|
-
else:
|
|
157
|
-
uniqueContextHashes[h] = context
|
|
158
|
-
del uniqueContextHashes
|
|
152
|
+
for exemplar_context, *contexts in partitionModelXbrlContexts(modelXbrl).values():
|
|
153
|
+
for context in contexts:
|
|
154
|
+
self.mapContext[context] = exemplar_context
|
|
159
155
|
modelXbrl.profileActivity("... identify equal contexts", minTimeToShow=1.0)
|
|
160
156
|
|
|
161
157
|
# identify equal units
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
if h in uniqueUnitHashes:
|
|
166
|
-
if unit.isEqualTo(uniqueUnitHashes[h]):
|
|
167
|
-
self.mapUnit[unit] = uniqueUnitHashes[h]
|
|
168
|
-
else:
|
|
169
|
-
uniqueUnitHashes[h] = unit
|
|
170
|
-
del uniqueUnitHashes
|
|
158
|
+
for exemplar_unit, *units in partitionModelXbrlUnits(modelXbrl).values():
|
|
159
|
+
for unit in units:
|
|
160
|
+
self.mapUnit[unit] = exemplar_unit
|
|
171
161
|
modelXbrl.profileActivity("... identify equal units", minTimeToShow=1.0)
|
|
172
162
|
|
|
173
163
|
# identify concepts participating in essence-alias relationships
|
arelle/_version.py
CHANGED
|
@@ -5,6 +5,7 @@ from __future__ import annotations
|
|
|
5
5
|
|
|
6
6
|
import datetime
|
|
7
7
|
import itertools
|
|
8
|
+
from collections import defaultdict
|
|
8
9
|
from collections.abc import Callable, Iterable
|
|
9
10
|
from typing import Optional, cast
|
|
10
11
|
|
|
@@ -14,6 +15,7 @@ from arelle.ModelValue import QName
|
|
|
14
15
|
from arelle.ModelXbrl import ModelXbrl
|
|
15
16
|
from arelle.typing import TypeGetText
|
|
16
17
|
from arelle.UrlUtil import scheme
|
|
18
|
+
from arelle.utils.Contexts import ContextHashKey
|
|
17
19
|
from arelle.utils.validate.Validation import Validation
|
|
18
20
|
from arelle.ValidateFilingText import parseImageDataURL
|
|
19
21
|
from arelle.ValidateXbrl import ValidateXbrl
|
|
@@ -266,19 +268,18 @@ def getFactsGroupedByContextId(modelXbrl: ModelXbrl, *conceptQns: QName) -> dict
|
|
|
266
268
|
return dict(sorted(groupedFacts.items()))
|
|
267
269
|
|
|
268
270
|
|
|
269
|
-
def groupFactsByContextHash(facts: set[ModelFact]
|
|
271
|
+
def groupFactsByContextHash(facts: set[ModelFact]) -> dict[ContextHashKey, list[ModelFact]]:
|
|
270
272
|
"""
|
|
271
|
-
Groups facts by their
|
|
272
|
-
:return: A dictionary of
|
|
273
|
+
Groups facts by their context hash key.
|
|
274
|
+
:return: A dictionary of context hash keys to list of facts.
|
|
273
275
|
"""
|
|
274
|
-
groupedFacts:
|
|
276
|
+
groupedFacts: defaultdict[ContextHashKey, list[ModelFact]] = defaultdict(list)
|
|
275
277
|
for fact in facts:
|
|
276
278
|
if fact.xValid >= VALID:
|
|
277
|
-
contextHash = fact.context
|
|
278
|
-
if contextHash not in groupedFacts:
|
|
279
|
-
groupedFacts[contextHash] = []
|
|
279
|
+
contextHash = ContextHashKey(fact.context, dimensionalAspectModel=True)
|
|
280
280
|
groupedFacts[contextHash].append(fact)
|
|
281
|
-
|
|
281
|
+
groupedFacts.default_factory = None
|
|
282
|
+
return groupedFacts
|
|
282
283
|
|
|
283
284
|
|
|
284
285
|
def lookup_namespaced_facts(modelXbrl: ModelXbrl, namespaceURI: str) -> set[ModelFact]:
|
|
@@ -602,9 +602,9 @@ def rule_fr57(
|
|
|
602
602
|
DBA.FR57.Equality(Error):
|
|
603
603
|
Assets (fsa:Assets) must equal Liabilities (fsa:LiabilitiesAndEquity)
|
|
604
604
|
"""
|
|
605
|
-
|
|
605
|
+
currentStartDateFacts = getFactsWithDimension(val, pluginData.reportingPeriodStartDateQn, pluginData.consolidatedSoloDimensionQn, [pluginData.consolidatedMemberQn, pluginData.soloMemberQn])
|
|
606
606
|
currentEndDateFacts = getFactsWithDimension(val, pluginData.reportingPeriodEndDateQn, pluginData.consolidatedSoloDimensionQn, [pluginData.consolidatedMemberQn, pluginData.soloMemberQn])
|
|
607
|
-
currentGroupedFacts = groupFactsByContextHash(
|
|
607
|
+
currentGroupedFacts = groupFactsByContextHash(currentStartDateFacts.union(currentEndDateFacts))
|
|
608
608
|
precedingEndDateFacts = getFactsWithDimension(val, pluginData.precedingReportingPeriodEndDateQn, pluginData.consolidatedSoloDimensionQn, [pluginData.consolidatedMemberQn, pluginData.soloMemberQn])
|
|
609
609
|
precedingStartDateFacts = getFactsWithDimension(val, pluginData.precedingReportingPeriodStartDateQn, pluginData.consolidatedSoloDimensionQn, [pluginData.consolidatedMemberQn, pluginData.soloMemberQn])
|
|
610
610
|
precedingGroupedFacts = groupFactsByContextHash(precedingEndDateFacts.union(precedingStartDateFacts))
|
|
@@ -635,7 +635,7 @@ def rule_fr57(
|
|
|
635
635
|
equityFacts = getFactsWithoutDimension(val, pluginData.equityQn)
|
|
636
636
|
profitLossFacts = getFactsWithoutDimension(val, pluginData.profitLossQn)
|
|
637
637
|
liabilitiesAndEquityFacts = getFactsWithoutDimension(val, pluginData.liabilitiesAndEquityQn)
|
|
638
|
-
for
|
|
638
|
+
for facts in currentGroupedFacts.values():
|
|
639
639
|
if len(facts) == 2:
|
|
640
640
|
for fact in facts:
|
|
641
641
|
if fact.qname == pluginData.reportingPeriodStartDateQn:
|
|
@@ -42,8 +42,10 @@ def rule_tr01(
|
|
|
42
42
|
gsd_facts = lookup_namespaced_facts(val.modelXbrl, NAMESPACE_GSD)
|
|
43
43
|
facts_in_error = []
|
|
44
44
|
for fact in gsd_facts:
|
|
45
|
-
if (
|
|
46
|
-
|
|
45
|
+
if not (
|
|
46
|
+
fact.context.isEntityIdentifierEqualTo(cvr_fact.context) and
|
|
47
|
+
fact.context.isPeriodEqualTo(cvr_fact.context)
|
|
48
|
+
):
|
|
47
49
|
facts_in_error.append(fact)
|
|
48
50
|
if len(facts_in_error) > 0:
|
|
49
51
|
yield Validation.error(
|
|
@@ -17,6 +17,7 @@ from arelle.ValidateUtr import ValidateUtr
|
|
|
17
17
|
from arelle.Version import authorLabel, copyrightLabel
|
|
18
18
|
from arelle.XbrlConst import qnEnumerationItemTypes
|
|
19
19
|
from arelle.ModelInstanceObject import ModelFact
|
|
20
|
+
from arelle.utils.Contexts import getDuplicateContextGroups
|
|
20
21
|
import regex as re
|
|
21
22
|
from lxml import etree
|
|
22
23
|
from collections import defaultdict
|
|
@@ -484,17 +485,13 @@ def validateFacts(val, factsToCheck):
|
|
|
484
485
|
|
|
485
486
|
del unitHashes
|
|
486
487
|
|
|
487
|
-
|
|
488
|
+
if not getattr(modelXbrl, "isStreamingMode", False):
|
|
489
|
+
for contexts in getDuplicateContextGroups(modelXbrl):
|
|
490
|
+
modelXbrl.log("WARNING" if val.isEIOPAfullVersion else "ERROR",
|
|
491
|
+
"EIOPA.S.2.7.b",
|
|
492
|
+
_("Duplicate contexts MUST NOT be reported, contexts %(cntx1)s and %(cntx2)s are equivalent.'"),
|
|
493
|
+
modelObject=contexts, cntx1=contexts[0].id, cntx2=contexts[1].id)
|
|
488
494
|
for cntx in modelXbrl.contexts.values():
|
|
489
|
-
h = cntx.contextDimAwareHash
|
|
490
|
-
if h in cntxHashes and cntx.isEqualTo(cntxHashes[h]):
|
|
491
|
-
if not getattr(modelXbrl, "isStreamingMode", False):
|
|
492
|
-
modelXbrl.log("WARNING" if val.isEIOPAfullVersion else "ERROR",
|
|
493
|
-
"EIOPA.S.2.7.b",
|
|
494
|
-
_("Duplicate contexts MUST NOT be reported, contexts %(cntx1)s and %(cntx2)s are equivalent.'"),
|
|
495
|
-
modelObject=(cntx, cntxHashes[h]), cntx1=cntx.id, cntx2=cntxHashes[h].id)
|
|
496
|
-
else:
|
|
497
|
-
cntxHashes[h] = cntx
|
|
498
495
|
for _dim in cntx.qnameDims.values():
|
|
499
496
|
_dimQn = _dim.dimensionQname
|
|
500
497
|
prefixUsed(val, _dimQn.namespaceURI, _dimQn.prefix)
|
|
@@ -3,6 +3,7 @@ See COPYRIGHT.md for copyright information.
|
|
|
3
3
|
"""
|
|
4
4
|
from __future__ import annotations
|
|
5
5
|
|
|
6
|
+
from datetime import timedelta
|
|
6
7
|
from typing import Any, cast, Iterable
|
|
7
8
|
|
|
8
9
|
import regex
|
|
@@ -16,7 +17,9 @@ from arelle.ValidateXbrlCalcs import insignificantDigits
|
|
|
16
17
|
from arelle.XbrlConst import qnXbrlScenario, qnXbrldiExplicitMember, xhtmlBaseIdentifier, xmlBaseIdentifier
|
|
17
18
|
from arelle.XmlValidate import VALID
|
|
18
19
|
from arelle.typing import TypeGetText
|
|
20
|
+
from arelle.utils.Contexts import getDuplicateContextGroups
|
|
19
21
|
from arelle.utils.PluginHooks import ValidationHook
|
|
22
|
+
from arelle.utils.Units import getDuplicateUnitGroups
|
|
20
23
|
from arelle.utils.validate.Decorator import validation
|
|
21
24
|
from arelle.utils.validate.Validation import Validation
|
|
22
25
|
from arelle.utils.validate.ValidationUtil import etreeIterWithDepth
|
|
@@ -213,6 +216,100 @@ def rule_gfm_1_2_5(
|
|
|
213
216
|
)
|
|
214
217
|
|
|
215
218
|
|
|
219
|
+
@validation(
|
|
220
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
221
|
+
disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
|
|
222
|
+
)
|
|
223
|
+
def rule_gfm_1_2_7(
|
|
224
|
+
pluginData: PluginValidationDataExtension,
|
|
225
|
+
val: ValidateXbrl,
|
|
226
|
+
*args: Any,
|
|
227
|
+
**kwargs: Any,
|
|
228
|
+
) -> Iterable[Validation]:
|
|
229
|
+
"""
|
|
230
|
+
EDINET.EC5700W: [GFM 1.2.7] An instance must not contain duplicate xbrli:context elements.
|
|
231
|
+
"""
|
|
232
|
+
for contexts in getDuplicateContextGroups(val.modelXbrl):
|
|
233
|
+
yield Validation.warning(
|
|
234
|
+
codes='EDINET.EC5700W.GFM.1.2.7',
|
|
235
|
+
msg=_('Duplicate context. Remove the duplicate.'),
|
|
236
|
+
modelObject = contexts
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
@validation(
|
|
241
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
242
|
+
disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
|
|
243
|
+
)
|
|
244
|
+
def rule_gfm_1_2_8(
|
|
245
|
+
pluginData: PluginValidationDataExtension,
|
|
246
|
+
val: ValidateXbrl,
|
|
247
|
+
*args: Any,
|
|
248
|
+
**kwargs: Any,
|
|
249
|
+
) -> Iterable[Validation]:
|
|
250
|
+
"""
|
|
251
|
+
EDINET.EC5700W: [GFM 1.2.8] Every xbrli:context element must appear in at least one
|
|
252
|
+
contextRef attribute in the same instance.
|
|
253
|
+
"""
|
|
254
|
+
unused_contexts = list(set(val.modelXbrl.contexts.values()) - set(val.modelXbrl.contextsInUse))
|
|
255
|
+
unused_contexts.sort(key=lambda x: x.id)
|
|
256
|
+
for context in unused_contexts:
|
|
257
|
+
yield Validation.warning(
|
|
258
|
+
codes='EDINET.EC5700W.GFM.1.2.8',
|
|
259
|
+
msg=_('If you are not using a context, delete it if it is not needed.'),
|
|
260
|
+
modelObject = context
|
|
261
|
+
)
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
@validation(
|
|
265
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
266
|
+
disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
|
|
267
|
+
)
|
|
268
|
+
def rule_gfm_1_2_9(
|
|
269
|
+
pluginData: PluginValidationDataExtension,
|
|
270
|
+
val: ValidateXbrl,
|
|
271
|
+
*args: Any,
|
|
272
|
+
**kwargs: Any,
|
|
273
|
+
) -> Iterable[Validation]:
|
|
274
|
+
"""
|
|
275
|
+
EDINET.EC5700W: [GFM 1.2.9] The same date must not appear as the content of both an xbrli:startDate and
|
|
276
|
+
an xbrli:endDate in an instance.
|
|
277
|
+
"""
|
|
278
|
+
invalidDurationContexts = []
|
|
279
|
+
for contexts in val.modelXbrl.contextsByDocument().values():
|
|
280
|
+
for context in contexts:
|
|
281
|
+
if not context.isInstantPeriod:
|
|
282
|
+
if context.endDatetime and context.startDatetime and context.startDatetime == context.endDatetime - timedelta(days=1):
|
|
283
|
+
invalidDurationContexts.append(context)
|
|
284
|
+
if len(invalidDurationContexts) > 0:
|
|
285
|
+
for context in invalidDurationContexts:
|
|
286
|
+
yield Validation.warning(
|
|
287
|
+
codes='EDINET.EC5700W.GFM.1.2.9',
|
|
288
|
+
msg=_("Set the context's startDate and endDate elements to different dates."),
|
|
289
|
+
modelObject=context
|
|
290
|
+
)
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
@validation(
|
|
294
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
295
|
+
disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
|
|
296
|
+
)
|
|
297
|
+
def rule_gfm_1_2_10(
|
|
298
|
+
pluginData: PluginValidationDataExtension,
|
|
299
|
+
val: ValidateXbrl,
|
|
300
|
+
*args: Any,
|
|
301
|
+
**kwargs: Any,
|
|
302
|
+
) -> Iterable[Validation]:
|
|
303
|
+
"""
|
|
304
|
+
EDINET.EC5700W: [GFM 1.2.10] Element xbrli:xbrl must not have duplicate child xbrli:unit elements.
|
|
305
|
+
"""
|
|
306
|
+
for duplicateUnits in getDuplicateUnitGroups(val.modelXbrl):
|
|
307
|
+
yield Validation.warning(
|
|
308
|
+
codes='EDINET.EC5700W.GFM.1.2.10',
|
|
309
|
+
msg=_('The unit element contains duplicate content. Please remove the duplicates.'),
|
|
310
|
+
modelObject = duplicateUnits
|
|
311
|
+
)
|
|
312
|
+
|
|
216
313
|
|
|
217
314
|
@validation(
|
|
218
315
|
hook=ValidationHook.XBRL_FINALLY,
|
|
@@ -24,6 +24,8 @@ from arelle.ModelRelationshipSet import ModelRelationshipSet
|
|
|
24
24
|
from arelle.ModelValue import QName, qname
|
|
25
25
|
from arelle.utils.validate.ValidationUtil import etreeIterWithDepth
|
|
26
26
|
from arelle.PythonUtil import isLegacyAbs, strTruncate
|
|
27
|
+
from arelle.utils.Contexts import partitionModelXbrlContexts
|
|
28
|
+
from arelle.utils.Units import partitionModelXbrlUnits
|
|
27
29
|
from arelle.utils.validate.DetectScriptsInXhtml import containsScriptMarkers
|
|
28
30
|
from arelle.UrlUtil import decodeBase64DataImage, isHttpUrl, scheme
|
|
29
31
|
from arelle.ValidateFilingText import parseImageDataURL
|
|
@@ -564,27 +566,17 @@ def validateXbrlFinally(val: ValidateXbrl, *args: Any, **kwargs: Any) -> None:
|
|
|
564
566
|
# identify unique contexts and units
|
|
565
567
|
mapContext = {}
|
|
566
568
|
mapUnit = {}
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
if h in uniqueContextHashes:
|
|
571
|
-
if context.isEqualTo(uniqueContextHashes[h]):
|
|
572
|
-
mapContext[context] = uniqueContextHashes[h]
|
|
573
|
-
else:
|
|
574
|
-
uniqueContextHashes[h] = context
|
|
575
|
-
del uniqueContextHashes
|
|
576
|
-
uniqueUnitHashes: dict[Any, Any] = {}
|
|
569
|
+
for exemplar_context, *contexts in partitionModelXbrlContexts(modelXbrl).values():
|
|
570
|
+
for context in contexts:
|
|
571
|
+
mapContext[context] = exemplar_context
|
|
577
572
|
utrValidator = ValidateUtr(modelXbrl)
|
|
578
573
|
utrUnitIds = set(u.unitId
|
|
579
574
|
for unitItemType in utrValidator.utrItemTypeEntries.values()
|
|
580
575
|
for u in unitItemType.values())
|
|
576
|
+
for exemplar_unit, *units in partitionModelXbrlUnits(modelXbrl).values():
|
|
577
|
+
for unit in units:
|
|
578
|
+
mapUnit[unit] = exemplar_unit
|
|
581
579
|
for unit in modelXbrl.units.values():
|
|
582
|
-
h = unit.hash
|
|
583
|
-
if h in uniqueUnitHashes:
|
|
584
|
-
if unit.isEqualTo(uniqueUnitHashes[h]):
|
|
585
|
-
mapUnit[unit] = uniqueUnitHashes[h]
|
|
586
|
-
else:
|
|
587
|
-
uniqueUnitHashes[h] = unit
|
|
588
580
|
# check if any custom measure is in UTR
|
|
589
581
|
for measureTerm in unit.measures:
|
|
590
582
|
for measure in measureTerm:
|
|
@@ -594,7 +586,6 @@ def validateXbrlFinally(val: ValidateXbrl, *args: Any, **kwargs: Any) -> None:
|
|
|
594
586
|
modelXbrl.warning("ESEF.RTS.III.1.G1-7-1.customUnitInUtr",
|
|
595
587
|
_("Custom measure SHOULD NOT duplicate a UnitID of UTR: %(measure)s"),
|
|
596
588
|
modelObject=unit, measure=measure)
|
|
597
|
-
del uniqueUnitHashes
|
|
598
589
|
|
|
599
590
|
reportedMandatory: set[QName] = set()
|
|
600
591
|
precisionFacts = set()
|
|
@@ -30,6 +30,8 @@ from arelle.utils.validate.ESEFImage import ImageValidationParameters, checkSVGC
|
|
|
30
30
|
from arelle.utils.validate.ValidationUtil import etreeIterWithDepth
|
|
31
31
|
from arelle.PythonUtil import isLegacyAbs, normalizeSpace
|
|
32
32
|
from arelle.PythonUtil import strTruncate
|
|
33
|
+
from arelle.utils.Contexts import partitionModelXbrlContexts
|
|
34
|
+
from arelle.utils.Units import partitionModelXbrlUnits
|
|
33
35
|
from arelle.utils.validate.DetectScriptsInXhtml import containsScriptMarkers
|
|
34
36
|
from arelle.UrlUtil import isHttpUrl
|
|
35
37
|
from arelle.ValidateUtr import ValidateUtr
|
|
@@ -629,27 +631,17 @@ def validateXbrlFinally(val: ValidateXbrl, *args: Any, **kwargs: Any) -> None:
|
|
|
629
631
|
# identify unique contexts and units
|
|
630
632
|
mapContext = {}
|
|
631
633
|
mapUnit = {}
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
if h in uniqueContextHashes:
|
|
636
|
-
if context.isEqualTo(uniqueContextHashes[h]):
|
|
637
|
-
mapContext[context] = uniqueContextHashes[h]
|
|
638
|
-
else:
|
|
639
|
-
uniqueContextHashes[h] = context
|
|
640
|
-
del uniqueContextHashes
|
|
641
|
-
uniqueUnitHashes: dict[Any, Any] = {}
|
|
634
|
+
for exemplar_context, *contexts in partitionModelXbrlContexts(modelXbrl).values():
|
|
635
|
+
for context in contexts:
|
|
636
|
+
mapContext[context] = exemplar_context
|
|
642
637
|
utrValidator = ValidateUtr(modelXbrl)
|
|
643
638
|
utrUnitIds = set(u.unitId
|
|
644
639
|
for unitItemType in utrValidator.utrItemTypeEntries.values()
|
|
645
640
|
for u in unitItemType.values())
|
|
641
|
+
for exemplar_unit, *units in partitionModelXbrlUnits(modelXbrl).values():
|
|
642
|
+
for unit in units:
|
|
643
|
+
mapUnit[unit] = exemplar_unit
|
|
646
644
|
for unit in modelXbrl.units.values():
|
|
647
|
-
h = unit.hash
|
|
648
|
-
if h in uniqueUnitHashes:
|
|
649
|
-
if unit.isEqualTo(uniqueUnitHashes[h]):
|
|
650
|
-
mapUnit[unit] = uniqueUnitHashes[h]
|
|
651
|
-
else:
|
|
652
|
-
uniqueUnitHashes[h] = unit
|
|
653
645
|
# check if any custom measure is in UTR
|
|
654
646
|
for measureTerm in unit.measures:
|
|
655
647
|
for measure in measureTerm:
|
|
@@ -659,7 +651,6 @@ def validateXbrlFinally(val: ValidateXbrl, *args: Any, **kwargs: Any) -> None:
|
|
|
659
651
|
modelXbrl.warning("ESEF.RTS.III.1.G1-7-1.customUnitInUtr",
|
|
660
652
|
_("Custom measure SHOULD NOT duplicate a UnitID of UTR: %(measure)s"),
|
|
661
653
|
modelObject=unit, measure=measure)
|
|
662
|
-
del uniqueUnitHashes
|
|
663
654
|
|
|
664
655
|
reportedMandatory: set[QName] = set()
|
|
665
656
|
precisionFacts = set()
|
|
@@ -33,6 +33,7 @@ from arelle.PrototypeDtsObject import LinkPrototype, LocPrototype, ArcPrototype
|
|
|
33
33
|
from arelle.Version import authorLabel, copyrightLabel
|
|
34
34
|
from arelle.XbrlConst import xbrli, xhtml
|
|
35
35
|
from arelle.XmlValidateConst import VALID
|
|
36
|
+
from arelle.utils.Contexts import getDuplicateContextGroups
|
|
36
37
|
|
|
37
38
|
def dislosureSystemTypes(disclosureSystem, *args, **kwargs):
|
|
38
39
|
# return ((disclosure system name, variable name), ...)
|
|
@@ -121,7 +122,6 @@ def validateXbrlFinally(val, *args, **kwargs):
|
|
|
121
122
|
|
|
122
123
|
#6.5.4 scenario
|
|
123
124
|
segContexts = set()
|
|
124
|
-
uniqueContextHashes = {}
|
|
125
125
|
contextIDs = set()
|
|
126
126
|
precisionFacts = set()
|
|
127
127
|
formType = None
|
|
@@ -133,16 +133,12 @@ def validateXbrlFinally(val, *args, **kwargs):
|
|
|
133
133
|
for c in modelXbrl.contexts.values():
|
|
134
134
|
if XmlUtil.hasChild(c, xbrli, "segment"):
|
|
135
135
|
segContexts.add(c)
|
|
136
|
-
h = c.contextDimAwareHash
|
|
137
|
-
if h in uniqueContextHashes:
|
|
138
|
-
if c.isEqualTo(uniqueContextHashes[h]):
|
|
139
|
-
modelXbrl.error("FERC.6.05.07",
|
|
140
|
-
_("The instance document contained more than one context equivalent to %(context)s (%(context2)s). "
|
|
141
|
-
"Please remove duplicate contexts from the instance."),
|
|
142
|
-
modelObject=(c, uniqueContextHashes[h]), context=c.id, context2=uniqueContextHashes[h].id)
|
|
143
|
-
else:
|
|
144
|
-
uniqueContextHashes[h] = c
|
|
145
136
|
contextIDs.add(c.id)
|
|
137
|
+
for contexts in getDuplicateContextGroups(modelXbrl):
|
|
138
|
+
modelXbrl.error("FERC.6.05.07",
|
|
139
|
+
_("The instance document contained more than one context equivalent to %(context)s (%(context2)s). "
|
|
140
|
+
"Please remove duplicate contexts from the instance."),
|
|
141
|
+
modelObject=contexts, context=contexts[0].id, context2=contexts[1].id)
|
|
146
142
|
|
|
147
143
|
if segContexts:
|
|
148
144
|
modelXbrl.error("FERC.6.05.04",
|
|
@@ -414,25 +414,13 @@ class PluginValidationDataExtension(PluginData):
|
|
|
414
414
|
calcRelSet = modelXbrl.relationshipSet(XbrlConst.summationItems)
|
|
415
415
|
dimensionalData = self.getDimensionalData(modelXbrl)
|
|
416
416
|
primaryItems = dimensionalData.primaryItems
|
|
417
|
-
domainMembers = dimensionalData.domainMembers
|
|
418
417
|
extensionData = self.getExtensionData(modelXbrl)
|
|
419
418
|
for concept in extensionData.extensionConcepts:
|
|
420
|
-
extLineItem = False
|
|
421
419
|
if concept.isPrimaryItem and \
|
|
422
420
|
not concept.isAbstract and \
|
|
423
421
|
concept in primaryItems and \
|
|
424
422
|
not widerNarrowerRelSet.contains(concept) and \
|
|
425
423
|
not calcRelSet.fromModelObject(concept):
|
|
426
|
-
extLineItem = True
|
|
427
|
-
elif concept.isAbstract and \
|
|
428
|
-
concept not in domainMembers and \
|
|
429
|
-
concept.type is not None and \
|
|
430
|
-
not concept.type.isDomainItemType and \
|
|
431
|
-
not concept.isHypercubeItem and \
|
|
432
|
-
not concept.isDimensionItem and \
|
|
433
|
-
not widerNarrowerRelSet.contains(concept):
|
|
434
|
-
extLineItem = True
|
|
435
|
-
if extLineItem:
|
|
436
424
|
if not generalSpecialRelSet.contains(concept):
|
|
437
425
|
extLineItemsNotAnchored.add(concept)
|
|
438
426
|
else:
|
|
@@ -18,6 +18,7 @@ from arelle.ModelObject import ModelObject, ModelComment
|
|
|
18
18
|
from arelle.ModelValue import QName, qname
|
|
19
19
|
from arelle.ValidateXbrl import ValidateXbrl
|
|
20
20
|
from arelle.typing import TypeGetText
|
|
21
|
+
from arelle.utils.Contexts import partitionModelXbrlContexts
|
|
21
22
|
from arelle.utils.PluginHooks import ValidationHook
|
|
22
23
|
from arelle.utils.validate.Decorator import validation
|
|
23
24
|
from arelle.utils.validate.Validation import Validation
|
|
@@ -579,10 +580,7 @@ def rule_fr_nl_3_04(
|
|
|
579
580
|
"""
|
|
580
581
|
FR-NL-3.04: An XBRL instance document MUST NOT contain duplicate 'xbrli:context' elements
|
|
581
582
|
"""
|
|
582
|
-
|
|
583
|
-
for context in val.modelXbrl.contexts.values():
|
|
584
|
-
duplicates[context.contextDimAwareHash].append(context)
|
|
585
|
-
for duplicate_contexts in duplicates.values():
|
|
583
|
+
for duplicate_contexts in partitionModelXbrlContexts(val.modelXbrl).values():
|
|
586
584
|
if len(duplicate_contexts) > 1:
|
|
587
585
|
yield Validation.error(
|
|
588
586
|
codes='NL.FR-NL-3.04',
|
|
@@ -1711,11 +1711,11 @@ def rule_nl_kvk_4_4_6_1(
|
|
|
1711
1711
|
unreportedLbLocs.add(rel.fromLocator)
|
|
1712
1712
|
if len(unreportedLbLocs) > 0:
|
|
1713
1713
|
yield Validation.warning(
|
|
1714
|
-
# Subtitle is capitalized inconsistently here because
|
|
1714
|
+
# Subtitle is capitalized inconsistently here because it matches the conformance suite. This may change in the future.
|
|
1715
1715
|
codes='NL.NL-KVK.4.4.6.1.UsableConceptsNotAppliedByTaggedFacts',
|
|
1716
1716
|
modelObject=unreportedLbLocs,
|
|
1717
|
-
msg=_('
|
|
1718
|
-
'
|
|
1717
|
+
msg=_('Concept was found but not reported on any facts. '
|
|
1718
|
+
'Remove any unused concepts or ensure concept is applied to applicable facts.'),
|
|
1719
1719
|
)
|
|
1720
1720
|
|
|
1721
1721
|
|
|
@@ -19,6 +19,8 @@ from arelle.ModelInstanceObject import ModelInlineFact, ModelUnit
|
|
|
19
19
|
from arelle.ModelValue import qname
|
|
20
20
|
from arelle.ModelXbrl import ModelXbrl
|
|
21
21
|
from arelle.PythonUtil import strTruncate
|
|
22
|
+
from arelle.utils.Contexts import partitionModelXbrlContexts
|
|
23
|
+
from arelle.utils.Units import partitionModelXbrlUnits
|
|
22
24
|
from arelle.utils.PluginHooks import ValidationHook
|
|
23
25
|
from arelle.utils.validate.Decorator import validation
|
|
24
26
|
from arelle.utils.validate.Validation import Validation
|
|
@@ -166,7 +168,6 @@ def rule_main(
|
|
|
166
168
|
schemeEntityIds = set()
|
|
167
169
|
mapContext = {} # identify unique contexts and units
|
|
168
170
|
mapUnit = {}
|
|
169
|
-
uniqueContextHashes: dict[str, str] = {}
|
|
170
171
|
hasCRO = False
|
|
171
172
|
unsupportedSchemeContexts = []
|
|
172
173
|
mismatchIdentifierContexts = []
|
|
@@ -179,13 +180,10 @@ def rule_main(
|
|
|
179
180
|
mismatchIdentifierContexts.append(context)
|
|
180
181
|
if scheme == "http://www.cro.ie/":
|
|
181
182
|
hasCRO = True
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
else:
|
|
187
|
-
uniqueContextHashes[h] = context
|
|
188
|
-
del uniqueContextHashes
|
|
183
|
+
for exemplar_context, *contexts in partitionModelXbrlContexts(modelXbrl).values():
|
|
184
|
+
for context in contexts:
|
|
185
|
+
mapContext[context] = exemplar_context
|
|
186
|
+
|
|
189
187
|
if len(schemeEntityIds) > 1:
|
|
190
188
|
modelXbrl.error("ROS:differentContextEntityIdentifiers",
|
|
191
189
|
_("Context entity identifier not all the same: %(schemeEntityIds)s."),
|
|
@@ -201,15 +199,9 @@ def rule_main(
|
|
|
201
199
|
modelObject=mismatchIdentifierContexts,
|
|
202
200
|
identifiers=", ".join(sorted(set(c.entityIdentifier[1] for c in mismatchIdentifierContexts))))
|
|
203
201
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
if h in uniqueUnitHashes:
|
|
208
|
-
if unit.isEqualTo(uniqueUnitHashes[h]):
|
|
209
|
-
mapUnit[unit] = uniqueUnitHashes[h]
|
|
210
|
-
else:
|
|
211
|
-
uniqueUnitHashes[h] = unit
|
|
212
|
-
del uniqueUnitHashes
|
|
202
|
+
for exemplar_unit, *units in partitionModelXbrlUnits(modelXbrl).values():
|
|
203
|
+
for unit in units:
|
|
204
|
+
mapUnit[unit] = exemplar_unit
|
|
213
205
|
|
|
214
206
|
if hasCRO and "ie-common" in nsMap:
|
|
215
207
|
mandatory.add(qname("ie-common:CompaniesRegistrationOfficeNumber", nsMap)) # type-ignore[arg-type]
|
arelle/utils/Contexts.py
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, Any
|
|
4
|
+
|
|
5
|
+
from arelle.utils.Equivalence import partitionIntoEquivalenceClasses
|
|
6
|
+
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from collections.abc import Iterable
|
|
9
|
+
from arelle.ModelXbrl import ModelXbrl
|
|
10
|
+
from arelle.ModelInstanceObject import ModelContext
|
|
11
|
+
|
|
12
|
+
class ContextHashKey:
|
|
13
|
+
__slots__ = ('context', 'dimensionalAspectModel', 'hash')
|
|
14
|
+
context: ModelContext
|
|
15
|
+
dimensionalAspectModel: bool
|
|
16
|
+
hash: int
|
|
17
|
+
|
|
18
|
+
def __init__(self, context: ModelContext, dimensionalAspectModel: bool) -> None:
|
|
19
|
+
self.context = context
|
|
20
|
+
self.dimensionalAspectModel = dimensionalAspectModel
|
|
21
|
+
self.hash = self.context.contextDimAwareHash if dimensionalAspectModel else self.context.contextNonDimAwareHash
|
|
22
|
+
|
|
23
|
+
def __eq__(self, o: Any) -> bool:
|
|
24
|
+
if isinstance(o, ContextHashKey):
|
|
25
|
+
return self.dimensionalAspectModel == o.dimensionalAspectModel and self.context.isEqualTo(o.context, self.dimensionalAspectModel)
|
|
26
|
+
return NotImplemented
|
|
27
|
+
|
|
28
|
+
def __hash__(self) -> int:
|
|
29
|
+
return self.hash
|
|
30
|
+
|
|
31
|
+
def partitionContexts(contexts: Iterable[ModelContext], dimensionalAspectModel: bool) -> dict[ContextHashKey, tuple[ModelContext, ...]]:
|
|
32
|
+
return partitionIntoEquivalenceClasses(contexts, lambda c: ContextHashKey(c, dimensionalAspectModel))
|
|
33
|
+
|
|
34
|
+
def partitionModelXbrlContexts(modelXbrl: ModelXbrl) -> dict[ContextHashKey, tuple[ModelContext, ...]]:
|
|
35
|
+
return partitionContexts(modelXbrl.contexts.values(), dimensionalAspectModel=modelXbrl.hasXDT)
|
|
36
|
+
|
|
37
|
+
def getDuplicateContextGroups(modelXbrl: ModelXbrl) -> list[tuple[ModelContext, ...]]:
|
|
38
|
+
return [partition for partition in partitionModelXbrlContexts(modelXbrl).values() if len(partition) > 1]
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from collections import defaultdict
|
|
4
|
+
from typing import (
|
|
5
|
+
TYPE_CHECKING,
|
|
6
|
+
Any,
|
|
7
|
+
Callable,
|
|
8
|
+
TypeVar,
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from collections.abc import Iterable
|
|
13
|
+
from arelle.ModelXbrl import ModelXbrl
|
|
14
|
+
|
|
15
|
+
T = TypeVar('T')
|
|
16
|
+
K = TypeVar('K')
|
|
17
|
+
|
|
18
|
+
def partitionIntoEquivalenceClasses(items: Iterable[T], key: Callable[[T], K]) -> dict[K, tuple[T, ...]]:
|
|
19
|
+
d = defaultdict(list)
|
|
20
|
+
for item in items:
|
|
21
|
+
d[key(item)].append(item)
|
|
22
|
+
return {k: tuple(v) for k, v in d.items()}
|
arelle/utils/Units.py
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, Any
|
|
4
|
+
|
|
5
|
+
from arelle.utils.Equivalence import partitionIntoEquivalenceClasses
|
|
6
|
+
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from collections.abc import Iterable
|
|
9
|
+
from arelle.ModelXbrl import ModelXbrl
|
|
10
|
+
from arelle.ModelInstanceObject import ModelUnit
|
|
11
|
+
|
|
12
|
+
class UnitHashKey:
|
|
13
|
+
__slots__ = ('unit', 'hash')
|
|
14
|
+
unit: ModelUnit
|
|
15
|
+
hash: int
|
|
16
|
+
|
|
17
|
+
def __init__(self, unit: ModelUnit) -> None:
|
|
18
|
+
self.unit = unit
|
|
19
|
+
self.hash = self.unit.hash
|
|
20
|
+
|
|
21
|
+
def __eq__(self, o: Any) -> bool:
|
|
22
|
+
if isinstance(o, UnitHashKey):
|
|
23
|
+
return self.unit.isEqualTo(o.unit)
|
|
24
|
+
return NotImplemented
|
|
25
|
+
|
|
26
|
+
def __hash__(self) -> int:
|
|
27
|
+
return self.hash
|
|
28
|
+
|
|
29
|
+
def partitionUnits(units: Iterable[ModelUnit]) -> dict[UnitHashKey, tuple[ModelUnit, ...]]:
|
|
30
|
+
return partitionIntoEquivalenceClasses(units, UnitHashKey)
|
|
31
|
+
|
|
32
|
+
def partitionModelXbrlUnits(modelXbrl: ModelXbrl) -> dict[UnitHashKey, tuple[ModelUnit, ...]]:
|
|
33
|
+
return partitionUnits(modelXbrl.units.values())
|
|
34
|
+
|
|
35
|
+
def getDuplicateUnitGroups(modelXbrl: ModelXbrl) -> list[tuple[ModelUnit, ...]]:
|
|
36
|
+
return [partition for partition in partitionModelXbrlUnits(modelXbrl).values() if len(partition) > 1]
|
|
@@ -37,7 +37,7 @@ arelle/Locale.py,sha256=07IDxv8nIfvhyRRllFdEAKRI3yo1D2v781cTrjb_RoQ,33193
|
|
|
37
37
|
arelle/ModelDocument.py,sha256=Sq6umEdn-aNHjxIpEsXTT7A4V25nGY0JiylSnhr9zSI,130749
|
|
38
38
|
arelle/ModelDtsObject.py,sha256=nvHQs4BDmPxY6mqLiBuqIGRJXyA1EqOEGB2f3S6A6w4,88656
|
|
39
39
|
arelle/ModelFormulaObject.py,sha256=-eb0lBYciEeAvvGduIs3AHGNGrxge9_0g1cVT6UUgvc,122560
|
|
40
|
-
arelle/ModelInstanceObject.py,sha256=
|
|
40
|
+
arelle/ModelInstanceObject.py,sha256=fUiDb6aS2ls0GkrVxxkPyZqEr-RI4qsGQJjKkAK2tUk,74246
|
|
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
|
|
@@ -72,7 +72,7 @@ arelle/ValidateInfoset.py,sha256=Rz_XBi5Ha43KpxXYhjLolURcWVx5qmqyjLxw48Yt9Dg,203
|
|
|
72
72
|
arelle/ValidateUtr.py,sha256=oxOPrOa1XEzBay4miXvx6eRLTnVFYUIJC9ueWUk4EkI,13633
|
|
73
73
|
arelle/ValidateVersReport.py,sha256=RMe7GlcyZV0HoVFHL0qOGrKm4et-6yPq5dmikkhnvoU,43196
|
|
74
74
|
arelle/ValidateXbrl.py,sha256=kBiY_q9QmORwC8VxGpRq9mfufknt08nEAeSgNh1ov-M,78005
|
|
75
|
-
arelle/ValidateXbrlCalcs.py,sha256=
|
|
75
|
+
arelle/ValidateXbrlCalcs.py,sha256=6OMjIef6ixJGkxH-hgIRbMRJ46e52KEo-8vDyM97krc,44028
|
|
76
76
|
arelle/ValidateXbrlDTS.py,sha256=yxvpTpImEbrQuLJ2aJf38FjA-OEznpWWdsDK0GtLXIU,104003
|
|
77
77
|
arelle/ValidateXbrlDimensions.py,sha256=Qv7_CI65SiUcpgsnEc86XuMjKz81-170wE5dmZqnvHc,38373
|
|
78
78
|
arelle/Version.py,sha256=RjbPSSiH57VzZFhhUmEmvLsL8uSb5VwEIj2zq-krhsY,934
|
|
@@ -123,7 +123,7 @@ 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=
|
|
126
|
+
arelle/_version.py,sha256=rxJ_q4vyjbOfPG_eNhLacH0vqtMeCXGlM6EfD3QLIcE,515
|
|
127
127
|
arelle/typing.py,sha256=PRe-Fxwr2SBqYYUVPCJ3E7ddDX0_oOISNdT5Q97EbRM,1246
|
|
128
128
|
arelle/api/Session.py,sha256=27HVuK3Bz1_21l4_RLn1IQg6v0MNsUEYrHajymyWwxI,7429
|
|
129
129
|
arelle/archive/CustomLogger.py,sha256=v_JXOCQLDZcfaFWzxC9FRcEf9tQi4rCI4Sx7jCuAVQI,1231
|
|
@@ -384,13 +384,13 @@ arelle/plugin/validate/DBA/PluginValidationDataExtension.py,sha256=R0lNf-3-lKHln
|
|
|
384
384
|
arelle/plugin/validate/DBA/ValidationPluginExtension.py,sha256=JozGD4LqGn8zbc_-BhZOPMJl0PSboloS6oG8UwwTz6I,48638
|
|
385
385
|
arelle/plugin/validate/DBA/__init__.py,sha256=KhmlUkqgsRtEXpu5DZBXFzv43nUTvi-0sdDNRfw5Up4,1564
|
|
386
386
|
arelle/plugin/validate/DBA/resources/config.xml,sha256=KHfo7SrjzmjHbfwIJBmESvOOjdIv4Av26BCcZxfn3Pg,875
|
|
387
|
-
arelle/plugin/validate/DBA/rules/__init__.py,sha256=
|
|
388
|
-
arelle/plugin/validate/DBA/rules/fr.py,sha256=
|
|
387
|
+
arelle/plugin/validate/DBA/rules/__init__.py,sha256=eBm6FAb_WnBBYfgLSwsO30gVjpWaHxLqRHRJAIBj7oo,10418
|
|
388
|
+
arelle/plugin/validate/DBA/rules/fr.py,sha256=IAegA_Fc-Zkjj8qlzFuo_52gNVHW-lAddBFCQw8W8P4,71318
|
|
389
389
|
arelle/plugin/validate/DBA/rules/tc.py,sha256=CXPOGHpab9Y-iV84wDXrsE-rPe_d6Uhw4HjEyTBEzq4,1572
|
|
390
390
|
arelle/plugin/validate/DBA/rules/th.py,sha256=mDrjescz6106jBGjdH6bipqx48BnxcjHSkNL1qQf0QE,6227
|
|
391
391
|
arelle/plugin/validate/DBA/rules/tm.py,sha256=ui9oKBqlAForwkQ9kk9KBiUogTJE5pv1RbIejKASprY,11797
|
|
392
|
-
arelle/plugin/validate/DBA/rules/tr.py,sha256=
|
|
393
|
-
arelle/plugin/validate/EBA/__init__.py,sha256=
|
|
392
|
+
arelle/plugin/validate/DBA/rules/tr.py,sha256=4TootFjl0HXsKZk1XNBCyj-vnjRs4lg35hfiz_b_4wU,14684
|
|
393
|
+
arelle/plugin/validate/EBA/__init__.py,sha256=x3zXNcdSDJ3kHfL7kMs0Ve0Vs9oWbzNFVf1TK4Avmy8,45924
|
|
394
394
|
arelle/plugin/validate/EBA/config.xml,sha256=37wMVUAObK-XEqakqD8zPNog20emYt4a_yfL1AKubF8,2022
|
|
395
395
|
arelle/plugin/validate/EDINET/Constants.py,sha256=QG69rWdpIrpQzZQkRcDWk2i3rlBVohr4VtSdW-IS5_w,734
|
|
396
396
|
arelle/plugin/validate/EDINET/DisclosureSystems.py,sha256=3rKG42Eg-17Xx_KXU_V5yHW6I3LTwQunvf4a44C9k_4,36
|
|
@@ -404,7 +404,7 @@ arelle/plugin/validate/EDINET/resources/edinet-taxonomies.xml,sha256=997I3RGTLg5
|
|
|
404
404
|
arelle/plugin/validate/EDINET/rules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
405
405
|
arelle/plugin/validate/EDINET/rules/edinet.py,sha256=PKbylqzhbi2ItMCW-eliaQysCzYg_rAkWzwRJmX1RtQ,4180
|
|
406
406
|
arelle/plugin/validate/EDINET/rules/frta.py,sha256=N0YglHYZuLD2IuwE26viR2ViwUYjneBuMFU9vlrS0aQ,7616
|
|
407
|
-
arelle/plugin/validate/EDINET/rules/gfm.py,sha256=
|
|
407
|
+
arelle/plugin/validate/EDINET/rules/gfm.py,sha256=Zn803dztEEVAFqOdOnbkWTPt3h6e7DXAulc68U14ylc,20062
|
|
408
408
|
arelle/plugin/validate/EDINET/rules/upload.py,sha256=HZ-9Gk6WtIichTGcSsSGIrMXNgsgJYQYwfUKeLs1XWU,20369
|
|
409
409
|
arelle/plugin/validate/ESEF/Const.py,sha256=JujF_XV-_TNsxjGbF-8SQS4OOZIcJ8zhCMnr-C1O5Ho,22660
|
|
410
410
|
arelle/plugin/validate/ESEF/Dimensions.py,sha256=MOJM7vwNPEmV5cu-ZzPrhx3347ZvxgD6643OB2HRnIk,10597
|
|
@@ -412,19 +412,19 @@ arelle/plugin/validate/ESEF/Util.py,sha256=QH3btcGqBpr42M7WSKZLSdNXygZaZLfEiEjlx
|
|
|
412
412
|
arelle/plugin/validate/ESEF/__init__.py,sha256=LL7uYOcGPHgjwTlcfW2oWMqWiqrZ5yABzcKkJZFrZis,20391
|
|
413
413
|
arelle/plugin/validate/ESEF/ESEF_2021/DTS.py,sha256=6Za7BANwwc_egxLCgbgWzwUGOXZv9IF1I7JCkDNt2Tw,26277
|
|
414
414
|
arelle/plugin/validate/ESEF/ESEF_2021/Image.py,sha256=4bnhuy5viBU0viPjb4FhcRRjVVKlNdnKLFdSGg3sZvs,4871
|
|
415
|
-
arelle/plugin/validate/ESEF/ESEF_2021/ValidateXbrlFinally.py,sha256=
|
|
415
|
+
arelle/plugin/validate/ESEF/ESEF_2021/ValidateXbrlFinally.py,sha256=R3cVpiq3x0YyH5cT1L_CfAR_8onn0nHVuruFSFsszCk,63675
|
|
416
416
|
arelle/plugin/validate/ESEF/ESEF_2021/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
417
417
|
arelle/plugin/validate/ESEF/ESEF_Current/DTS.py,sha256=epp-PBh1NJzQqgxUE6C468HmoDc2w3j54rMwfiOAry4,29334
|
|
418
|
-
arelle/plugin/validate/ESEF/ESEF_Current/ValidateXbrlFinally.py,sha256=
|
|
418
|
+
arelle/plugin/validate/ESEF/ESEF_Current/ValidateXbrlFinally.py,sha256=J9hJcLlE6FA84Ppgthiu4ju0KHJ-JdmVub2qKAKm3as,74985
|
|
419
419
|
arelle/plugin/validate/ESEF/ESEF_Current/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
420
420
|
arelle/plugin/validate/ESEF/resources/authority-validations.json,sha256=bR0ZMpiQL9LqiyzrjhAGMDLEHBHimsDuDu9SQY5xofA,15503
|
|
421
421
|
arelle/plugin/validate/ESEF/resources/config.xml,sha256=t3STU_-QYM7Ay8YwZRPapnohiWVWhjfr4L2Rjx9xN9U,3902
|
|
422
|
-
arelle/plugin/validate/FERC/__init__.py,sha256=
|
|
422
|
+
arelle/plugin/validate/FERC/__init__.py,sha256=rC1OYNBWnoXowEohiR9yagHtAi_NPAlmaahRSQhSdS4,11325
|
|
423
423
|
arelle/plugin/validate/FERC/config.xml,sha256=bn9b8eCqJA1J62rYq1Nz85wJrMGAahVmmnIUQZyerjo,1919
|
|
424
424
|
arelle/plugin/validate/FERC/resources/ferc-utr.xml,sha256=OCRj9IUpdXATCBXKbB71apYx9kxcNtZW-Hq4s-avsRY,2663
|
|
425
425
|
arelle/plugin/validate/NL/DisclosureSystems.py,sha256=urRmYJ8RnGPlTgSVKW7zGN4_4CtL3OVKlcI3LwTpBz4,561
|
|
426
426
|
arelle/plugin/validate/NL/LinkbaseType.py,sha256=BwRQl4XZFFCopufC2FEMLhYENNTk2JUWVQvnIUsaqtI,3108
|
|
427
|
-
arelle/plugin/validate/NL/PluginValidationDataExtension.py,sha256=
|
|
427
|
+
arelle/plugin/validate/NL/PluginValidationDataExtension.py,sha256=4yO0UlShSFk_iWxLbCZ9SHB1wuJQMcKcDGmVkHcltIY,33672
|
|
428
428
|
arelle/plugin/validate/NL/ValidationPluginExtension.py,sha256=h6CjGJJkE8YqrzPiA8uNaCzn_P6HspH-6ja89tLCXxY,17978
|
|
429
429
|
arelle/plugin/validate/NL/__init__.py,sha256=W-SHohiAWM7Yi77gAbt-D3vvZNAB5s1j16mHCTFta6w,3158
|
|
430
430
|
arelle/plugin/validate/NL/resources/config.xml,sha256=qBE6zywFSmemBSWonuTII5iuOCUlNb1nvkpMbsZb5PM,1853
|
|
@@ -432,8 +432,8 @@ arelle/plugin/validate/NL/rules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm
|
|
|
432
432
|
arelle/plugin/validate/NL/rules/br_kvk.py,sha256=0SwKieWzTDm3YMsXPS6zTdgbk7_Z9CzqRkRmCRz1OiQ,15789
|
|
433
433
|
arelle/plugin/validate/NL/rules/fg_nl.py,sha256=OJF2EYx4KDTdNggHiw5Trq5S5g7WGpbb7YvO6_IrrGU,10704
|
|
434
434
|
arelle/plugin/validate/NL/rules/fr_kvk.py,sha256=kYqXt45S6eM32Yg9ii7pUhOMfJaHurgYqQ73FyQALs8,8171
|
|
435
|
-
arelle/plugin/validate/NL/rules/fr_nl.py,sha256=
|
|
436
|
-
arelle/plugin/validate/NL/rules/nl_kvk.py,sha256=
|
|
435
|
+
arelle/plugin/validate/NL/rules/fr_nl.py,sha256=vwzk6_P6jhszpeboTM09uOHtm-Lijzz7Iqu7NsYKyaE,31444
|
|
436
|
+
arelle/plugin/validate/NL/rules/nl_kvk.py,sha256=KE2bOX1eQWxW1cVzMGR-HLgJ36zUq77D9DpA9-GvwNk,90165
|
|
437
437
|
arelle/plugin/validate/ROS/DisclosureSystems.py,sha256=rJ81mwQDYTi6JecFZ_zhqjjz3VNQRgjHNSh0wcQWAQE,18
|
|
438
438
|
arelle/plugin/validate/ROS/PluginValidationDataExtension.py,sha256=IV7ILhNvgKwQXqbpSA6HRNt9kEnejCyMADI3wyyIgk0,4036
|
|
439
439
|
arelle/plugin/validate/ROS/ValidationPluginExtension.py,sha256=HrLoJWHMFjou3j7ro6Ajrcab1JOgi505ZFPEM5a3QOY,776
|
|
@@ -441,7 +441,7 @@ arelle/plugin/validate/ROS/__init__.py,sha256=KuWg1MHVzA2S6eaHFptvP3Vu_5gQWf3OUY
|
|
|
441
441
|
arelle/plugin/validate/ROS/config.xml,sha256=ZCpCFgr1ZAjoUuhb1eRpDnmKrae-sXA9yl6SOWnrfm8,654
|
|
442
442
|
arelle/plugin/validate/ROS/resources/config.xml,sha256=HXWume5HlrAqOx5AtiWWqgADbRatA8YSfm_JvZGwdgQ,657
|
|
443
443
|
arelle/plugin/validate/ROS/rules/__init__.py,sha256=wW7BUAIb7sRkOxC1Amc_ZKrz03FM-Qh1TyZe6wxYaAU,1567
|
|
444
|
-
arelle/plugin/validate/ROS/rules/ros.py,sha256=
|
|
444
|
+
arelle/plugin/validate/ROS/rules/ros.py,sha256=pkEDeMeDibxGO597VWQrp4sz7JAxttWbKkn-ncKHvus,19635
|
|
445
445
|
arelle/plugin/validate/UK/ValidateUK.py,sha256=0UhSwsY1lrY-EAEBJJR9QY38YXGBZ6PEgmuC5gQfBlI,57813
|
|
446
446
|
arelle/plugin/validate/UK/__init__.py,sha256=KE6s_B-EvrHDCtWQz2N_wQwyx_ZbWhYNV2GfQnluxMw,30655
|
|
447
447
|
arelle/plugin/validate/UK/config.xml,sha256=mUFhWDfBzGTn7v0ZSmf4HaweQTMJh_4ZcJmD9mzCHrA,1547
|
|
@@ -743,9 +743,12 @@ arelle/resources/libs/Tktable2.11/win-x86_64/tkTable.tcl,sha256=JrSZRngZFHtw8Svp
|
|
|
743
743
|
arelle/scripts-macOS/startWebServer.command,sha256=KXLSwAwchDZBlL-k9PYXdf39RNBtte4vV076_kIz2Ow,91
|
|
744
744
|
arelle/scripts-unix/startWebServer.sh,sha256=_0puRzaGkdMZoFn3R7hDti9a3ryN6kTZAXwLweeZU1s,42
|
|
745
745
|
arelle/scripts-windows/startWebServer.bat,sha256=qmnF1yrjNo__bi4QodONWlN0qHShVLTKptJQYyZtgcY,122
|
|
746
|
+
arelle/utils/Contexts.py,sha256=j9uSBAXGkunlJGC9SscCbb1cj3oU_J3b_yjdhj2B4a4,1714
|
|
746
747
|
arelle/utils/EntryPointDetection.py,sha256=4RzercL0xE4PJrwoeUYq3S-E7PMSD-IspyS9bwK2RYM,4722
|
|
748
|
+
arelle/utils/Equivalence.py,sha256=Ac6sENvh-WHJlBJneV_-6n_MF2C1filHETkUEiucLJg,525
|
|
747
749
|
arelle/utils/PluginData.py,sha256=GUnuZaApm1J4Xm9ZA1U2M1aask-AaNGviLtc0fgXbFg,265
|
|
748
750
|
arelle/utils/PluginHooks.py,sha256=CeVxti23VjERQl4xWFucDVTW63TCG2PUdnxpjd3x_Ms,31170
|
|
751
|
+
arelle/utils/Units.py,sha256=c9bwnu9Xnm00gC9Q6qQ1ogsEeTEXGRH7rahlEbrEWnQ,1201
|
|
749
752
|
arelle/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
750
753
|
arelle/utils/validate/Decorator.py,sha256=8LGmA171HZgKrALtsMKyHqMNM-XCdwJOv6KpZz4pC2c,3161
|
|
751
754
|
arelle/utils/validate/DetectScriptsInXhtml.py,sha256=RFBh_Z24OjR69s71qQzSzbxdU-WCTWuvYlONN-BgpZ0,2098
|
|
@@ -756,9 +759,9 @@ arelle/utils/validate/ValidationUtil.py,sha256=9vmSvShn-EdQy56dfesyV8JjSRVPj7txr
|
|
|
756
759
|
arelle/utils/validate/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
757
760
|
arelle/webserver/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
758
761
|
arelle/webserver/bottle.py,sha256=P-JECd9MCTNcxCnKoDUvGcoi03ezYVOgoWgv2_uH-6M,362
|
|
759
|
-
arelle_release-2.37.
|
|
760
|
-
arelle_release-2.37.
|
|
761
|
-
arelle_release-2.37.
|
|
762
|
-
arelle_release-2.37.
|
|
763
|
-
arelle_release-2.37.
|
|
764
|
-
arelle_release-2.37.
|
|
762
|
+
arelle_release-2.37.40.dist-info/licenses/LICENSE.md,sha256=Q0tn6q0VUbr-NM8916513NCIG8MNzo24Ev-sxMUBRZc,3959
|
|
763
|
+
arelle_release-2.37.40.dist-info/METADATA,sha256=APvbQz9C9vSm13meJ_BiDNePwH_bHMXmYHcrFeemYbo,9137
|
|
764
|
+
arelle_release-2.37.40.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
765
|
+
arelle_release-2.37.40.dist-info/entry_points.txt,sha256=Uj5niwfwVsx3vaQ3fYj8hrZ1xpfCJyTUA09tYKWbzpo,111
|
|
766
|
+
arelle_release-2.37.40.dist-info/top_level.txt,sha256=fwU7SYawL4_r-sUMRg7r1nYVGjFMSDvRWx8VGAXEw7w,7
|
|
767
|
+
arelle_release-2.37.40.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|