arelle-release 2.37.34__py3-none-any.whl → 2.37.36__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/FileSource.py +4 -2
- arelle/ModelValue.py +4 -3
- arelle/Validate.py +1 -1
- arelle/XbrlConst.py +3 -0
- arelle/_version.py +2 -2
- arelle/plugin/validate/EDINET/Constants.py +12 -0
- arelle/plugin/validate/EDINET/Manifest.py +124 -0
- arelle/plugin/validate/EDINET/PluginValidationDataExtension.py +26 -0
- arelle/plugin/validate/EDINET/__init__.py +10 -47
- arelle/plugin/validate/EDINET/rules/gfm.py +197 -3
- arelle/plugin/validate/EDINET/rules/upload.py +72 -2
- arelle/plugin/validate/ROS/rules/ros.py +4 -50
- {arelle_release-2.37.34.dist-info → arelle_release-2.37.36.dist-info}/METADATA +1 -1
- {arelle_release-2.37.34.dist-info → arelle_release-2.37.36.dist-info}/RECORD +18 -16
- {arelle_release-2.37.34.dist-info → arelle_release-2.37.36.dist-info}/WHEEL +0 -0
- {arelle_release-2.37.34.dist-info → arelle_release-2.37.36.dist-info}/entry_points.txt +0 -0
- {arelle_release-2.37.34.dist-info → arelle_release-2.37.36.dist-info}/licenses/LICENSE.md +0 -0
- {arelle_release-2.37.34.dist-info → arelle_release-2.37.36.dist-info}/top_level.txt +0 -0
arelle/FileSource.py
CHANGED
|
@@ -119,7 +119,8 @@ class FileNamedStringIO(io.StringIO): # provide string IO in memory but behave
|
|
|
119
119
|
self.fileName = fileName
|
|
120
120
|
|
|
121
121
|
def close(self) -> None:
|
|
122
|
-
|
|
122
|
+
if hasattr(self, 'fileName'):
|
|
123
|
+
del self.fileName
|
|
123
124
|
super().close()
|
|
124
125
|
|
|
125
126
|
def __str__(self) -> str:
|
|
@@ -139,7 +140,8 @@ class FileNamedBytesIO(io.BytesIO): # provide Bytes IO in memory but behave as
|
|
|
139
140
|
self.fileName = fileName
|
|
140
141
|
|
|
141
142
|
def close(self) -> None:
|
|
142
|
-
|
|
143
|
+
if hasattr(self, 'fileName'):
|
|
144
|
+
del self.fileName
|
|
143
145
|
super().close()
|
|
144
146
|
|
|
145
147
|
def __str__(self) -> str:
|
arelle/ModelValue.py
CHANGED
|
@@ -35,11 +35,11 @@ def qname(value: ModelObject | str | QName, name: str | ModelObject | None = Non
|
|
|
35
35
|
def qname(value: ModelObject, name: QName, noPrefixIsNoNamespace: bool) -> QName: ...
|
|
36
36
|
|
|
37
37
|
@overload
|
|
38
|
-
def qname(value: ModelObject | str | QName | Any | None, name: str | ModelObject | dict[str, str] | None) -> QName | None : ...
|
|
38
|
+
def qname(value: ModelObject | str | QName | Any | None, name: str | ModelObject | dict[str, str] | dict[str | None, str] | None) -> QName | None : ...
|
|
39
39
|
|
|
40
40
|
def qname(
|
|
41
41
|
value: ModelObject | str | QName | Any | None,
|
|
42
|
-
name: str | QName | ModelObject | dict[str, str] | None = None,
|
|
42
|
+
name: str | QName | ModelObject | dict[str, str] | dict[str | None, str] | None = None,
|
|
43
43
|
noPrefixIsNoNamespace: bool = False,
|
|
44
44
|
castException: Exception | None = None,
|
|
45
45
|
prefixException: Exception | None = None,
|
|
@@ -66,6 +66,7 @@ def qname(
|
|
|
66
66
|
elif not isinstance(value, str):
|
|
67
67
|
if castException: raise castException
|
|
68
68
|
return None
|
|
69
|
+
namespaceDict: dict[str | None, str] | None
|
|
69
70
|
if value and value[0] == '{': # clark notation (with optional prefix)
|
|
70
71
|
namespaceURI,sep,prefixedLocalName = value[1:].rpartition('}')
|
|
71
72
|
prefix: str | None
|
|
@@ -85,7 +86,7 @@ def qname(
|
|
|
85
86
|
else:
|
|
86
87
|
if isinstance(name, dict):
|
|
87
88
|
namespaceURI = None
|
|
88
|
-
namespaceDict = name
|
|
89
|
+
namespaceDict = cast(dict[str | None, str], name) # note that default prefix must be None, not '', in dict
|
|
89
90
|
elif name is not None:
|
|
90
91
|
if name: # len > 0
|
|
91
92
|
namespaceURI = value
|
arelle/Validate.py
CHANGED
|
@@ -764,7 +764,7 @@ class Validate:
|
|
|
764
764
|
status = "pass" if numErrors == 0 else "fail"
|
|
765
765
|
elif expected == "invalid":
|
|
766
766
|
status = "fail" if numErrors == 0 else "pass"
|
|
767
|
-
elif expected in (None, []) and numErrors == 0:
|
|
767
|
+
elif expected in (None, []) and numErrors == 0 and not expectedWarnings:
|
|
768
768
|
status = "pass"
|
|
769
769
|
elif isinstance(expected, (QName, str, dict, list)) or expectedWarnings:
|
|
770
770
|
status = "fail"
|
arelle/XbrlConst.py
CHANGED
|
@@ -55,6 +55,9 @@ qnXbrliDenominator = qname("{http://www.xbrl.org/2003/instance}xbrli:denominator
|
|
|
55
55
|
qnXbrliTuple = qname("{http://www.xbrl.org/2003/instance}xbrli:tuple")
|
|
56
56
|
qnXbrliContext = qname("{http://www.xbrl.org/2003/instance}xbrli:context")
|
|
57
57
|
qnXbrliPeriod = qname("{http://www.xbrl.org/2003/instance}xbrli:period")
|
|
58
|
+
qnXbrliStartDate = qname("{http://www.xbrl.org/2003/instance}xbrli:startDate")
|
|
59
|
+
qnXbrliEndDate = qname("{http://www.xbrl.org/2003/instance}xbrli:endDate")
|
|
60
|
+
qnXbrliInstant = qname("{http://www.xbrl.org/2003/instance}xbrli:instant")
|
|
58
61
|
qnXbrliIdentifier = qname("{http://www.xbrl.org/2003/instance}xbrli:identifier")
|
|
59
62
|
qnXbrliUnit = qname("{http://www.xbrl.org/2003/instance}xbrli:unit")
|
|
60
63
|
qnXbrliStringItemType = qname("{http://www.xbrl.org/2003/instance}xbrli:stringItemType")
|
arelle/_version.py
CHANGED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"""
|
|
2
|
+
See COPYRIGHT.md for copyright information.
|
|
3
|
+
"""
|
|
4
|
+
from arelle.ModelValue import qname
|
|
5
|
+
|
|
6
|
+
qnEdinetManifestInsert = qname("{http://disclosure.edinet-fsa.go.jp/2013/manifest}insert")
|
|
7
|
+
qnEdinetManifestInstance = qname("{http://disclosure.edinet-fsa.go.jp/2013/manifest}instance")
|
|
8
|
+
qnEdinetManifestItem = qname("{http://disclosure.edinet-fsa.go.jp/2013/manifest}item")
|
|
9
|
+
qnEdinetManifestIxbrl = qname("{http://disclosure.edinet-fsa.go.jp/2013/manifest}ixbrl")
|
|
10
|
+
qnEdinetManifestList = qname("{http://disclosure.edinet-fsa.go.jp/2013/manifest}list")
|
|
11
|
+
qnEdinetManifestTitle = qname("{http://disclosure.edinet-fsa.go.jp/2013/manifest}title")
|
|
12
|
+
qnEdinetManifestTocComposition = qname("{http://disclosure.edinet-fsa.go.jp/2013/manifest}tocComposition")
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"""
|
|
2
|
+
See COPYRIGHT.md for copyright information.
|
|
3
|
+
"""
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
import zipfile
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
from functools import lru_cache
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
from lxml import etree
|
|
12
|
+
from lxml.etree import _Element
|
|
13
|
+
|
|
14
|
+
from arelle import XbrlConst
|
|
15
|
+
from arelle.FileSource import FileSource
|
|
16
|
+
from arelle.ModelValue import QName, qname
|
|
17
|
+
from . import Constants
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@dataclass(frozen=True)
|
|
21
|
+
class Manifest:
|
|
22
|
+
instances: list[ManifestInstance]
|
|
23
|
+
path: Path
|
|
24
|
+
titlesByLang: dict[str, str]
|
|
25
|
+
tocItems: list[ManifestTocItem]
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@dataclass(frozen=True)
|
|
29
|
+
class ManifestTocItem:
|
|
30
|
+
extrole: str
|
|
31
|
+
childItems: list[ManifestTocItem]
|
|
32
|
+
itemIn: str
|
|
33
|
+
parent: QName | None
|
|
34
|
+
ref: str
|
|
35
|
+
start: QName | None
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@dataclass(frozen=True)
|
|
39
|
+
class ManifestInstance:
|
|
40
|
+
id: str
|
|
41
|
+
ixbrlFiles: list[Path]
|
|
42
|
+
preferredFilename: str
|
|
43
|
+
type: str
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def _parseManifestTocItems(parentElt: _Element, parentQName: QName | None) -> list[ManifestTocItem]:
|
|
47
|
+
tocItems = []
|
|
48
|
+
for itemElt in parentElt.iterchildren(tag=Constants.qnEdinetManifestItem.clarkNotation):
|
|
49
|
+
childTocItems = []
|
|
50
|
+
for insertElt in itemElt.iterchildren(tag=Constants.qnEdinetManifestInsert.clarkNotation):
|
|
51
|
+
childParentQName = qname(insertElt.attrib.get("parent"), insertElt.nsmap) if insertElt.attrib.get("parent") else None
|
|
52
|
+
childTocItems.extend(_parseManifestTocItems(insertElt, childParentQName))
|
|
53
|
+
tocItems.append(ManifestTocItem(
|
|
54
|
+
extrole=itemElt.attrib.get("extrole", ""),
|
|
55
|
+
childItems=childTocItems,
|
|
56
|
+
parent=parentQName,
|
|
57
|
+
itemIn=itemElt.attrib.get("in", ""),
|
|
58
|
+
ref=itemElt.attrib.get("ref", ""),
|
|
59
|
+
start=qname(itemElt.attrib.get("start"), itemElt.nsmap) if itemElt.attrib.get("start") else None,
|
|
60
|
+
))
|
|
61
|
+
return tocItems
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def _parseManifestDoc(xmlRootElement: _Element, path: Path) -> Manifest:
|
|
65
|
+
instances = []
|
|
66
|
+
titlesByLang = {}
|
|
67
|
+
base = path.parent
|
|
68
|
+
tocElts = list(xmlRootElement.iterchildren(tag=Constants.qnEdinetManifestTocComposition.clarkNotation))
|
|
69
|
+
assert len(tocElts) == 1, 'There should be exactly one tocComposition element in the manifest.'
|
|
70
|
+
for titleElt in tocElts[0].iterchildren(tag=Constants.qnEdinetManifestTitle.clarkNotation):
|
|
71
|
+
lang = titleElt.attrib.get(XbrlConst.qnXmlLang.clarkNotation, "")
|
|
72
|
+
titlesByLang[lang] = titleElt.text.strip() if titleElt.text else ""
|
|
73
|
+
tocItems = _parseManifestTocItems(tocElts[0], None)
|
|
74
|
+
listElts = list(xmlRootElement.iterchildren(tag=Constants.qnEdinetManifestList.clarkNotation))
|
|
75
|
+
assert len(listElts) == 1, 'There should be exactly one list element in the manifest.'
|
|
76
|
+
for instanceElt in listElts[0].iterchildren(tag=Constants.qnEdinetManifestInstance.clarkNotation):
|
|
77
|
+
instanceId = str(instanceElt.attrib.get("id", ""))
|
|
78
|
+
instanceType = str(instanceElt.attrib.get("type", ""))
|
|
79
|
+
preferredFilename = str(instanceElt.attrib.get("preferredFilename", ""))
|
|
80
|
+
ixbrlFiles = []
|
|
81
|
+
for ixbrlElt in instanceElt.iterchildren(tag=Constants.qnEdinetManifestIxbrl.clarkNotation):
|
|
82
|
+
uri = ixbrlElt.text.strip() if ixbrlElt.text is not None else None
|
|
83
|
+
if uri is not None and len(uri) > 0:
|
|
84
|
+
ixbrlFiles.append(base / uri)
|
|
85
|
+
instances.append(ManifestInstance(
|
|
86
|
+
id=instanceId,
|
|
87
|
+
ixbrlFiles=ixbrlFiles,
|
|
88
|
+
preferredFilename=preferredFilename,
|
|
89
|
+
type=instanceType,
|
|
90
|
+
))
|
|
91
|
+
return Manifest(
|
|
92
|
+
instances=instances,
|
|
93
|
+
path=path,
|
|
94
|
+
titlesByLang=titlesByLang,
|
|
95
|
+
tocItems=tocItems,
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
@lru_cache(1)
|
|
100
|
+
def parseManifests(filesource: FileSource) -> list[Manifest]:
|
|
101
|
+
manifests: list[Manifest] = []
|
|
102
|
+
if filesource.isArchive:
|
|
103
|
+
if filesource.isTaxonomyPackage:
|
|
104
|
+
return manifests
|
|
105
|
+
if filesource.reportPackage is not None:
|
|
106
|
+
return manifests
|
|
107
|
+
for _archiveFile in (filesource.dir or ()):
|
|
108
|
+
if not Path(_archiveFile).stem.startswith('manifest'):
|
|
109
|
+
continue
|
|
110
|
+
assert isinstance(filesource.fs, zipfile.ZipFile), \
|
|
111
|
+
"The EDINET plugin only supports archives in .zip format."
|
|
112
|
+
with filesource.fs.open(_archiveFile) as manifestDoc:
|
|
113
|
+
xmlRootElement = etree.fromstring(manifestDoc.read())
|
|
114
|
+
manifests.append(_parseManifestDoc(xmlRootElement, Path(_archiveFile)))
|
|
115
|
+
elif (dirpath := Path(str(filesource.url))).is_dir():
|
|
116
|
+
for file in dirpath.rglob("*"):
|
|
117
|
+
if not file.is_file():
|
|
118
|
+
continue
|
|
119
|
+
if not file.stem.startswith('manifest'):
|
|
120
|
+
continue
|
|
121
|
+
with open(file, 'rb') as manifestDoc:
|
|
122
|
+
xmlRootElement = etree.fromstring(manifestDoc.read())
|
|
123
|
+
manifests.append(_parseManifestDoc(xmlRootElement, file))
|
|
124
|
+
return manifests
|
|
@@ -9,7 +9,10 @@ from dataclasses import dataclass
|
|
|
9
9
|
from functools import lru_cache
|
|
10
10
|
from pathlib import Path
|
|
11
11
|
|
|
12
|
+
from arelle.ModelDocument import Type as ModelDocumentType
|
|
13
|
+
from arelle.ModelObject import ModelObject
|
|
12
14
|
from arelle.ModelXbrl import ModelXbrl
|
|
15
|
+
from arelle.PrototypeDtsObject import LinkPrototype
|
|
13
16
|
from arelle.ValidateXbrl import ValidateXbrl
|
|
14
17
|
from arelle.typing import TypeGetText
|
|
15
18
|
from arelle.utils.PluginData import PluginData
|
|
@@ -60,6 +63,29 @@ class PluginValidationDataExtension(PluginData):
|
|
|
60
63
|
return False # Not a zipfile
|
|
61
64
|
return True
|
|
62
65
|
|
|
66
|
+
@lru_cache(1)
|
|
67
|
+
def getFootnoteLinkElements(self, modelXbrl: ModelXbrl) -> list[ModelObject | LinkPrototype]:
|
|
68
|
+
# TODO: Consolidate with similar implementations in EDGAR and FERC
|
|
69
|
+
doc = modelXbrl.modelDocument
|
|
70
|
+
if doc is None:
|
|
71
|
+
return []
|
|
72
|
+
if doc.type in (ModelDocumentType.INLINEXBRL, ModelDocumentType.INLINEXBRLDOCUMENTSET):
|
|
73
|
+
elts = (linkPrototype
|
|
74
|
+
for linkKey, links in modelXbrl.baseSets.items()
|
|
75
|
+
for linkPrototype in links
|
|
76
|
+
if linkPrototype.modelDocument.type in (ModelDocumentType.INLINEXBRL, ModelDocumentType.INLINEXBRLDOCUMENTSET)
|
|
77
|
+
and linkKey[1] and linkKey[2] and linkKey[3] # fully specified roles
|
|
78
|
+
and linkKey[0] != "XBRL-footnotes")
|
|
79
|
+
else:
|
|
80
|
+
rootElt = doc.xmlDocument.getroot()
|
|
81
|
+
elts = rootElt.iterdescendants(tag="{http://www.xbrl.org/2003/linkbase}footnoteLink")
|
|
82
|
+
return [
|
|
83
|
+
elt
|
|
84
|
+
for elt in elts
|
|
85
|
+
if isinstance(elt, (ModelObject, LinkPrototype))
|
|
86
|
+
]
|
|
87
|
+
|
|
88
|
+
|
|
63
89
|
def getUploadFileSizes(self, modelXbrl: ModelXbrl) -> dict[Path, int]:
|
|
64
90
|
"""
|
|
65
91
|
Get the sizes of files in the upload directory.
|
|
@@ -5,17 +5,15 @@ See COPYRIGHT.md for copyright information.
|
|
|
5
5
|
"""
|
|
6
6
|
from __future__ import annotations
|
|
7
7
|
|
|
8
|
-
import zipfile
|
|
9
8
|
from collections import defaultdict
|
|
10
9
|
from pathlib import Path
|
|
11
10
|
from typing import Any
|
|
12
11
|
|
|
13
|
-
from lxml import etree
|
|
14
|
-
from lxml.etree import _Element
|
|
15
|
-
|
|
16
12
|
from arelle.FileSource import FileSource
|
|
17
13
|
from arelle.ModelXbrl import ModelXbrl
|
|
18
14
|
from arelle.Version import authorLabel, copyrightLabel
|
|
15
|
+
from . import Constants
|
|
16
|
+
from .Manifest import Manifest, ManifestInstance, parseManifests
|
|
19
17
|
from .ValidationPluginExtension import ValidationPluginExtension
|
|
20
18
|
from .rules import edinet, frta, gfm, upload
|
|
21
19
|
|
|
@@ -52,53 +50,18 @@ def disclosureSystemConfigURL(*args: Any, **kwargs: Any) -> str:
|
|
|
52
50
|
return validationPlugin.disclosureSystemConfigURL
|
|
53
51
|
|
|
54
52
|
|
|
55
|
-
def _parseManifestDoc(xmlRootElement: _Element, base: Path) -> dict[str, list[Path]]:
|
|
56
|
-
sets = defaultdict(list)
|
|
57
|
-
for instanceElt in xmlRootElement.iter(tag="{http://disclosure.edinet-fsa.go.jp/2013/manifest}instance"):
|
|
58
|
-
instanceId = str(instanceElt.attrib["id"])
|
|
59
|
-
for ixbrlElt in instanceElt.iter(tag="{http://disclosure.edinet-fsa.go.jp/2013/manifest}ixbrl"):
|
|
60
|
-
uri = ixbrlElt.text.strip() if ixbrlElt.text is not None else None
|
|
61
|
-
if uri:
|
|
62
|
-
sets[instanceId].append(base / uri)
|
|
63
|
-
return sets
|
|
64
|
-
|
|
65
|
-
|
|
66
53
|
def fileSourceEntrypointFiles(filesource: FileSource, inlineOnly: bool, *args: Any, **kwargs: Any) -> list[dict[str, Any]] | None:
|
|
67
|
-
manifests =
|
|
68
|
-
if filesource.isArchive:
|
|
69
|
-
if filesource.isTaxonomyPackage:
|
|
70
|
-
return None
|
|
71
|
-
if filesource.reportPackage is not None:
|
|
72
|
-
return None
|
|
73
|
-
for _archiveFile in (filesource.dir or ()):
|
|
74
|
-
if not Path(_archiveFile).stem.startswith('manifest'):
|
|
75
|
-
continue
|
|
76
|
-
assert isinstance(filesource.fs, zipfile.ZipFile), \
|
|
77
|
-
"The EDINET plugin only supports archives in .zip format."
|
|
78
|
-
with filesource.fs.open(_archiveFile) as manifestDoc:
|
|
79
|
-
base = Path(_archiveFile).parent
|
|
80
|
-
xmlRootElement = etree.fromstring(manifestDoc.read())
|
|
81
|
-
manifests.update(_parseManifestDoc(xmlRootElement, base))
|
|
82
|
-
elif (dirpath := Path(str(filesource.url))).is_dir():
|
|
83
|
-
for file in dirpath.rglob("*"):
|
|
84
|
-
if not file.is_file():
|
|
85
|
-
continue
|
|
86
|
-
if not file.stem.startswith('manifest'):
|
|
87
|
-
continue
|
|
88
|
-
with open(file, 'rb') as manifestDoc:
|
|
89
|
-
base = file.parent
|
|
90
|
-
xmlRootElement = etree.fromstring(manifestDoc.read())
|
|
91
|
-
manifests.update(_parseManifestDoc(xmlRootElement, base))
|
|
54
|
+
manifests = parseManifests(filesource)
|
|
92
55
|
if len(manifests) == 0:
|
|
93
56
|
return None
|
|
94
|
-
|
|
95
57
|
entrypointFiles = []
|
|
96
|
-
for
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
58
|
+
for manifest in manifests:
|
|
59
|
+
for instance in manifest.instances:
|
|
60
|
+
entrypoints = []
|
|
61
|
+
for ixbrlFile in instance.ixbrlFiles:
|
|
62
|
+
filesource.select(str(ixbrlFile))
|
|
63
|
+
entrypoints.append({"file": filesource.url})
|
|
64
|
+
entrypointFiles.append({'ixds': entrypoints})
|
|
102
65
|
return entrypointFiles
|
|
103
66
|
|
|
104
67
|
|
|
@@ -3,21 +3,30 @@ See COPYRIGHT.md for copyright information.
|
|
|
3
3
|
"""
|
|
4
4
|
from __future__ import annotations
|
|
5
5
|
|
|
6
|
-
from
|
|
7
|
-
|
|
6
|
+
from typing import Any, cast, Iterable
|
|
7
|
+
|
|
8
|
+
import regex
|
|
8
9
|
|
|
9
10
|
from arelle import XbrlConst, XmlUtil
|
|
11
|
+
from arelle.ModelObject import ModelObject
|
|
12
|
+
from arelle.PrototypeDtsObject import LocPrototype, ArcPrototype
|
|
10
13
|
from arelle.UrlUtil import isHttpUrl, splitDecodeFragment
|
|
11
14
|
from arelle.ValidateXbrl import ValidateXbrl
|
|
15
|
+
from arelle.ValidateXbrlCalcs import insignificantDigits
|
|
16
|
+
from arelle.XbrlConst import xhtmlBaseIdentifier, xmlBaseIdentifier
|
|
17
|
+
from arelle.XmlValidate import VALID
|
|
12
18
|
from arelle.typing import TypeGetText
|
|
13
19
|
from arelle.utils.PluginHooks import ValidationHook
|
|
14
20
|
from arelle.utils.validate.Decorator import validation
|
|
15
21
|
from arelle.utils.validate.Validation import Validation
|
|
22
|
+
from arelle.utils.validate.ValidationUtil import etreeIterWithDepth
|
|
16
23
|
from ..DisclosureSystems import (DISCLOSURE_SYSTEM_EDINET)
|
|
17
24
|
from ..PluginValidationDataExtension import PluginValidationDataExtension
|
|
18
25
|
|
|
19
26
|
_: TypeGetText
|
|
20
27
|
|
|
28
|
+
GFM_CONTEXT_DATE_PATTERN = regex.compile(r"^[12][0-9]{3}-[01][0-9]-[0-3][0-9]$")
|
|
29
|
+
|
|
21
30
|
|
|
22
31
|
@validation(
|
|
23
32
|
hook=ValidationHook.XBRL_FINALLY,
|
|
@@ -64,7 +73,7 @@ def rule_gfm_1_1_3(
|
|
|
64
73
|
continue # Valid external URL
|
|
65
74
|
if not any(scheme == "element" for scheme, __ in XmlUtil.xpointerSchemes(hrefId)):
|
|
66
75
|
continue # Valid shorthand xpointer
|
|
67
|
-
yield Validation.
|
|
76
|
+
yield Validation.warning(
|
|
68
77
|
codes='EDINET.EC5700W.GFM.1.1.3',
|
|
69
78
|
msg=_("The URI content of the xlink:href attribute, the xsi:schemaLocation "
|
|
70
79
|
"attribute and the schemaLocation attribute must be relative and "
|
|
@@ -74,3 +83,188 @@ def rule_gfm_1_1_3(
|
|
|
74
83
|
uri=uri,
|
|
75
84
|
modelObject=elt,
|
|
76
85
|
)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
@validation(
|
|
89
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
90
|
+
disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
|
|
91
|
+
)
|
|
92
|
+
def rule_gfm_1_1_7(
|
|
93
|
+
pluginData: PluginValidationDataExtension,
|
|
94
|
+
val: ValidateXbrl,
|
|
95
|
+
*args: Any,
|
|
96
|
+
**kwargs: Any,
|
|
97
|
+
) -> Iterable[Validation]:
|
|
98
|
+
"""
|
|
99
|
+
EDINET.EC5700W: [GFM 1.1.7] Attribute xml:base must not appear in any filing document.
|
|
100
|
+
This check has been updated to check for the xhtml:base attribute in order to account for iXBRL filings.
|
|
101
|
+
|
|
102
|
+
Original GFM text: Attribute xml:base must not appear in any filing document.
|
|
103
|
+
"""
|
|
104
|
+
baseElements = []
|
|
105
|
+
for rootElt in val.modelXbrl.ixdsHtmlElements:
|
|
106
|
+
for uncast_elt, depth in etreeIterWithDepth(rootElt):
|
|
107
|
+
elt = cast(Any, uncast_elt)
|
|
108
|
+
if elt.get(xmlBaseIdentifier) is not None:
|
|
109
|
+
baseElements.append(elt)
|
|
110
|
+
if elt.tag == xhtmlBaseIdentifier:
|
|
111
|
+
baseElements.append(elt)
|
|
112
|
+
if len(baseElements) > 0:
|
|
113
|
+
yield Validation.warning(
|
|
114
|
+
codes='EDINET.EC5700W.GFM.1.1.7',
|
|
115
|
+
msg=_("Attribute xml:base must not appear in any filing document."),
|
|
116
|
+
modelObject=baseElements,
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
@validation(
|
|
121
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
122
|
+
disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
|
|
123
|
+
)
|
|
124
|
+
def rule_gfm_1_2_16(
|
|
125
|
+
pluginData: PluginValidationDataExtension,
|
|
126
|
+
val: ValidateXbrl,
|
|
127
|
+
*args: Any,
|
|
128
|
+
**kwargs: Any,
|
|
129
|
+
) -> Iterable[Validation]:
|
|
130
|
+
"""
|
|
131
|
+
EDINET.EC5700W: [GFM 1.2.16] Use the decimals attribute instead of the precision attribute.
|
|
132
|
+
|
|
133
|
+
Original GFM text: The xbrli:xbrl element must not have any facts with the precision attribute.
|
|
134
|
+
"""
|
|
135
|
+
errors = []
|
|
136
|
+
for fact in val.modelXbrl.facts:
|
|
137
|
+
concept = fact.concept
|
|
138
|
+
if concept is None:
|
|
139
|
+
continue
|
|
140
|
+
if not concept.isNumeric:
|
|
141
|
+
continue
|
|
142
|
+
if fact.precision is not None:
|
|
143
|
+
errors.append(fact)
|
|
144
|
+
if len(errors) > 0:
|
|
145
|
+
yield Validation.warning(
|
|
146
|
+
codes='EDINET.EC5700W.GFM.1.2.16',
|
|
147
|
+
msg=_("Use the decimals attribute instead of the precision attribute."),
|
|
148
|
+
modelObject=errors,
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
@validation(
|
|
153
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
154
|
+
disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
|
|
155
|
+
)
|
|
156
|
+
def rule_gfm_1_2_22(
|
|
157
|
+
pluginData: PluginValidationDataExtension,
|
|
158
|
+
val: ValidateXbrl,
|
|
159
|
+
*args: Any,
|
|
160
|
+
**kwargs: Any,
|
|
161
|
+
) -> Iterable[Validation]:
|
|
162
|
+
"""
|
|
163
|
+
EDINET.EC5700W: [GFM 1.2.22] In your taxonomy, do not expand the
|
|
164
|
+
xlink:arcrole attribute of the link:footnoteArc element. Modify the value
|
|
165
|
+
of the xlink:arcrole attribute to "http://www.xbrl.org/2003/arcrole/fact-footnote".
|
|
166
|
+
|
|
167
|
+
Original GFM text: The xlink:arcrole attribute of a link:footnoteArc element must
|
|
168
|
+
be defined in the XBRL Specification 2.1 or declared in a standard taxonomy schema.
|
|
169
|
+
"""
|
|
170
|
+
errors = []
|
|
171
|
+
for elt in pluginData.getFootnoteLinkElements(val.modelXbrl):
|
|
172
|
+
for child in elt:
|
|
173
|
+
if not isinstance(child, (ModelObject, LocPrototype, ArcPrototype)):
|
|
174
|
+
continue
|
|
175
|
+
xlinkType = child.get(XbrlConst.qnXlinkType.clarkNotation)
|
|
176
|
+
if xlinkType == "arc":
|
|
177
|
+
arcrole = child.get(XbrlConst.qnXlinkArcRole.clarkNotation)
|
|
178
|
+
if arcrole != XbrlConst.factFootnote:
|
|
179
|
+
errors.append(child)
|
|
180
|
+
if len(errors) > 0:
|
|
181
|
+
yield Validation.warning(
|
|
182
|
+
codes='EDINET.EC5700W.GFM.1.2.22',
|
|
183
|
+
msg=_("Do not use extension arcroles for the link:footnoteArc element. "
|
|
184
|
+
"Use the standard 'http://www.xbrl.org/2003/arcrole/fact-footnote' arcrole instead."),
|
|
185
|
+
modelObject=errors,
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
@validation(
|
|
190
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
191
|
+
disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
|
|
192
|
+
)
|
|
193
|
+
def rule_gfm_1_2_25(
|
|
194
|
+
pluginData: PluginValidationDataExtension,
|
|
195
|
+
val: ValidateXbrl,
|
|
196
|
+
*args: Any,
|
|
197
|
+
**kwargs: Any,
|
|
198
|
+
) -> Iterable[Validation]:
|
|
199
|
+
"""
|
|
200
|
+
EDINET.EC5700W: [GFM 1.2.25] Set the date in the period element in the
|
|
201
|
+
following format: YYYY-MM-DD.
|
|
202
|
+
|
|
203
|
+
Original GFM text: Dates in period element of the context must comply with
|
|
204
|
+
yyyy-mm-dd format. No time is allowed in the value for dates.
|
|
205
|
+
"""
|
|
206
|
+
errors = []
|
|
207
|
+
for context in val.modelXbrl.contexts.values():
|
|
208
|
+
for elt in context.iterdescendants(
|
|
209
|
+
XbrlConst.qnXbrliStartDate.clarkNotation,
|
|
210
|
+
XbrlConst.qnXbrliEndDate.clarkNotation,
|
|
211
|
+
XbrlConst.qnXbrliInstant.clarkNotation
|
|
212
|
+
):
|
|
213
|
+
dateText = XmlUtil.text(elt)
|
|
214
|
+
if not GFM_CONTEXT_DATE_PATTERN.match(dateText):
|
|
215
|
+
errors.append(elt)
|
|
216
|
+
if len(errors) > 0:
|
|
217
|
+
yield Validation.warning(
|
|
218
|
+
codes='EDINET.EC5700W.GFM.1.2.25',
|
|
219
|
+
msg=_("Set the date in the period element in the following "
|
|
220
|
+
"format: YYYY-MM-DD."),
|
|
221
|
+
modelObject=errors,
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
@validation(
|
|
226
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
227
|
+
disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
|
|
228
|
+
)
|
|
229
|
+
def rule_gfm_1_2_26(
|
|
230
|
+
pluginData: PluginValidationDataExtension,
|
|
231
|
+
val: ValidateXbrl,
|
|
232
|
+
*args: Any,
|
|
233
|
+
**kwargs: Any,
|
|
234
|
+
) -> Iterable[Validation]:
|
|
235
|
+
"""
|
|
236
|
+
EDINET.EC5700W: [GFM 1.2.26] The decimals attribute value must not cause truncation of
|
|
237
|
+
non-zero digits in the fact value. Update the fact value to match the precision of
|
|
238
|
+
the decimals attribute, or update the decimals attribute.
|
|
239
|
+
|
|
240
|
+
Original GFM text: The decimals attribute value must not cause non-zero digits in
|
|
241
|
+
the fact value to be changed to zero.
|
|
242
|
+
"""
|
|
243
|
+
errors = []
|
|
244
|
+
for fact in val.modelXbrl.facts:
|
|
245
|
+
if (
|
|
246
|
+
fact.context is None or
|
|
247
|
+
fact.concept is None or
|
|
248
|
+
fact.concept.type is None or
|
|
249
|
+
getattr(fact,"xValid", 0) < VALID or
|
|
250
|
+
fact.isNil or
|
|
251
|
+
not fact.isNumeric or
|
|
252
|
+
not fact.decimals or
|
|
253
|
+
fact.decimals == "INF"
|
|
254
|
+
):
|
|
255
|
+
continue
|
|
256
|
+
try:
|
|
257
|
+
insignificance = insignificantDigits(fact.xValue, decimals=fact.decimals)
|
|
258
|
+
if insignificance is not None:
|
|
259
|
+
errors.append(fact)
|
|
260
|
+
except (ValueError,TypeError):
|
|
261
|
+
errors.append(fact)
|
|
262
|
+
if len(errors) > 0:
|
|
263
|
+
yield Validation.warning(
|
|
264
|
+
codes='EDINET.EC5700W.GFM.1.2.26',
|
|
265
|
+
msg=_("The decimals attribute value must not cause truncation of "
|
|
266
|
+
"non-zero digits in the fact value. Update the fact value to "
|
|
267
|
+
"match the precision of the decimals attribute, or update the"
|
|
268
|
+
"decimals attribute."),
|
|
269
|
+
modelObject=errors,
|
|
270
|
+
)
|
|
@@ -4,11 +4,10 @@ See COPYRIGHT.md for copyright information.
|
|
|
4
4
|
from __future__ import annotations
|
|
5
5
|
|
|
6
6
|
import re
|
|
7
|
-
import zipfile
|
|
8
7
|
from collections import defaultdict
|
|
9
8
|
from collections.abc import Iterable
|
|
10
9
|
from pathlib import Path
|
|
11
|
-
from typing import Any
|
|
10
|
+
from typing import Any
|
|
12
11
|
|
|
13
12
|
from arelle.ValidateXbrl import ValidateXbrl
|
|
14
13
|
from arelle.typing import TypeGetText
|
|
@@ -17,6 +16,7 @@ from arelle.utils.validate.Decorator import validation
|
|
|
17
16
|
from arelle.utils.validate.Validation import Validation
|
|
18
17
|
from ..DisclosureSystems import (DISCLOSURE_SYSTEM_EDINET)
|
|
19
18
|
from ..FormType import FormType, HTML_EXTENSIONS, IMAGE_EXTENSIONS
|
|
19
|
+
from ..Manifest import parseManifests
|
|
20
20
|
from ..PluginValidationDataExtension import PluginValidationDataExtension
|
|
21
21
|
|
|
22
22
|
_: TypeGetText
|
|
@@ -452,3 +452,73 @@ def rule_EC1020E(
|
|
|
452
452
|
path=str(path),
|
|
453
453
|
file=str(path),
|
|
454
454
|
)
|
|
455
|
+
|
|
456
|
+
|
|
457
|
+
@validation(
|
|
458
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
459
|
+
disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
|
|
460
|
+
)
|
|
461
|
+
def rule_manifest_preferredFilename(
|
|
462
|
+
pluginData: PluginValidationDataExtension,
|
|
463
|
+
val: ValidateXbrl,
|
|
464
|
+
*args: Any,
|
|
465
|
+
**kwargs: Any,
|
|
466
|
+
) -> Iterable[Validation]:
|
|
467
|
+
"""
|
|
468
|
+
EDINET.EC5804E: The preferredFilename attribute must be set on the instance
|
|
469
|
+
element in the manifest file.
|
|
470
|
+
|
|
471
|
+
EDINET.EC5805E: The instance file extension is not ".xbrl". File name: xxx
|
|
472
|
+
Please change the extension of the instance name set in the preferredFilename
|
|
473
|
+
attribute value of the instance element in the manifest file to ".xbrl".
|
|
474
|
+
|
|
475
|
+
EDINET.EC5806E: The same instance file name is set multiple times. File name: xxx
|
|
476
|
+
The preferredFilename attribute value of the instance element in the manifest
|
|
477
|
+
file must be unique within the same file.
|
|
478
|
+
"""
|
|
479
|
+
if not pluginData.shouldValidateUpload(val):
|
|
480
|
+
return
|
|
481
|
+
manifests = parseManifests(val.modelXbrl.fileSource)
|
|
482
|
+
for manifest in manifests:
|
|
483
|
+
preferredFilenames = set()
|
|
484
|
+
duplicateFilenames = set()
|
|
485
|
+
for instance in manifest.instances:
|
|
486
|
+
if len(instance.preferredFilename) == 0:
|
|
487
|
+
yield Validation.error(
|
|
488
|
+
codes='EDINET.EC5804E',
|
|
489
|
+
msg=_("The instance file name is not set. "
|
|
490
|
+
"Set the instance name as the preferredFilename attribute value "
|
|
491
|
+
"of the instance element in the manifest file. (manifest: '%(manifest)s', id: %(id)s)"),
|
|
492
|
+
manifest=str(manifest.path),
|
|
493
|
+
id=instance.id,
|
|
494
|
+
)
|
|
495
|
+
continue
|
|
496
|
+
preferredFilename = Path(instance.preferredFilename)
|
|
497
|
+
if preferredFilename.suffix != '.xbrl':
|
|
498
|
+
yield Validation.error(
|
|
499
|
+
codes='EDINET.EC5805E',
|
|
500
|
+
msg=_("The instance file extension is not '.xbrl'. "
|
|
501
|
+
"File name: '%(preferredFilename)s'. "
|
|
502
|
+
"Please change the extension of the instance name set in the "
|
|
503
|
+
"preferredFilename attribute value of the instance element in "
|
|
504
|
+
"the manifest file to '.xbrl'. (manifest: '%(manifest)s', id: %(id)s)"),
|
|
505
|
+
preferredFilename=instance.preferredFilename,
|
|
506
|
+
manifest=str(manifest.path),
|
|
507
|
+
id=instance.id,
|
|
508
|
+
)
|
|
509
|
+
continue
|
|
510
|
+
if instance.preferredFilename in preferredFilenames:
|
|
511
|
+
duplicateFilenames.add(instance.preferredFilename)
|
|
512
|
+
continue
|
|
513
|
+
preferredFilenames.add(instance.preferredFilename)
|
|
514
|
+
for duplicateFilename in duplicateFilenames:
|
|
515
|
+
yield Validation.error(
|
|
516
|
+
codes='EDINET.EC5806E',
|
|
517
|
+
msg=_("The same instance file name is set multiple times. "
|
|
518
|
+
"File name: '%(preferredFilename)s'. "
|
|
519
|
+
"The preferredFilename attribute value of the instance "
|
|
520
|
+
"element in the manifest file must be unique within the "
|
|
521
|
+
"same file. (manifest: '%(manifest)s')"),
|
|
522
|
+
manifest=str(manifest.path),
|
|
523
|
+
preferredFilename=duplicateFilename,
|
|
524
|
+
)
|
|
@@ -296,67 +296,21 @@ def rule_main(
|
|
|
296
296
|
@validation(
|
|
297
297
|
hook=ValidationHook.XBRL_FINALLY,
|
|
298
298
|
)
|
|
299
|
-
def
|
|
299
|
+
def rule_ros20(
|
|
300
300
|
pluginData: PluginValidationDataExtension,
|
|
301
301
|
val: ValidateXbrl,
|
|
302
302
|
*args: Any,
|
|
303
303
|
**kwargs: Any,
|
|
304
304
|
) -> Iterable[Validation]:
|
|
305
305
|
"""
|
|
306
|
-
ROS: Rule
|
|
307
|
-
"""
|
|
308
|
-
non_nil_profit_loss_fact_exists = any(
|
|
309
|
-
not fact.isNil for fact in val.modelXbrl.factsByLocalName.get(IE_PROFIT_LOSS, set())
|
|
310
|
-
)
|
|
311
|
-
non_nil_profit_loss_ordinary_fact_exists = any(
|
|
312
|
-
not fact.isNil for fact in val.modelXbrl.factsByLocalName.get(IE_PROFIT_LOSS_ORDINARY, set())
|
|
313
|
-
)
|
|
314
|
-
if not non_nil_profit_loss_fact_exists and not non_nil_profit_loss_ordinary_fact_exists:
|
|
315
|
-
yield Validation.error(
|
|
316
|
-
codes='ROS.6',
|
|
317
|
-
msg=_("Profit or Loss Before Tax (uk gaap:ProfitLossOnOrdinaryActivitiesBeforeTax) is missing."),
|
|
318
|
-
modelObject=val.modelXbrl
|
|
319
|
-
)
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
@validation(
|
|
323
|
-
hook=ValidationHook.XBRL_FINALLY,
|
|
324
|
-
)
|
|
325
|
-
def rule_ros18(
|
|
326
|
-
pluginData: PluginValidationDataExtension,
|
|
327
|
-
val: ValidateXbrl,
|
|
328
|
-
*args: Any,
|
|
329
|
-
**kwargs: Any,
|
|
330
|
-
) -> Iterable[Validation]:
|
|
331
|
-
"""
|
|
332
|
-
ROS: Rule 18: DPLTurnoverRevenue cannot be a negative value.
|
|
333
|
-
"""
|
|
334
|
-
return errorOnNegativeFact(
|
|
335
|
-
val.modelXbrl,
|
|
336
|
-
conceptLn=TURNOVER_REVENUE,
|
|
337
|
-
code='ROS.18',
|
|
338
|
-
message=_("Turnover / Revenue cannot be a negative value.")
|
|
339
|
-
)
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
@validation(
|
|
343
|
-
hook=ValidationHook.XBRL_FINALLY,
|
|
344
|
-
)
|
|
345
|
-
def rule_ros19(
|
|
346
|
-
pluginData: PluginValidationDataExtension,
|
|
347
|
-
val: ValidateXbrl,
|
|
348
|
-
*args: Any,
|
|
349
|
-
**kwargs: Any,
|
|
350
|
-
) -> Iterable[Validation]:
|
|
351
|
-
"""
|
|
352
|
-
ROS: Rule 19:PrincipalCurrencyUsedInBusinessReport must exist and its value must match the unit
|
|
306
|
+
ROS: Rule 20:PrincipalCurrencyUsedInBusinessReport must exist and its value must match the unit
|
|
353
307
|
used for the majority of monetary facts.
|
|
354
308
|
"""
|
|
355
309
|
principal_currency_facts = val.modelXbrl.factsByLocalName.get(PRINCIPAL_CURRENCY, set())
|
|
356
310
|
principal_currency_values = set(fact.text for fact in principal_currency_facts)
|
|
357
311
|
if len(principal_currency_values) != 1:
|
|
358
312
|
yield Validation.error(
|
|
359
|
-
"ROS.
|
|
313
|
+
"ROS.20",
|
|
360
314
|
_("'PrincipalCurrencyUsedInBusinessReport' must exist and have a single value. Values found: %(principal_currency_values)s."),
|
|
361
315
|
modelObject=principal_currency_facts,
|
|
362
316
|
principal_currency_values=principal_currency_values,
|
|
@@ -370,7 +324,7 @@ def rule_ros19(
|
|
|
370
324
|
for unit, count in unit_counts.items():
|
|
371
325
|
if count > principal_currency_value_count:
|
|
372
326
|
yield Validation.warning(
|
|
373
|
-
"ROS.
|
|
327
|
+
"ROS.20",
|
|
374
328
|
_("'PrincipalCurrencyUsedInBusinessReport' has a value of %(principal_currency_value)s, "
|
|
375
329
|
"which must match the functional(majority) unit of the financial statement."),
|
|
376
330
|
modelObject=principal_currency_facts,
|
|
@@ -21,7 +21,7 @@ arelle/DialogRssWatch.py,sha256=mjc4pqyFDISY4tQtME0uSRQ3NlcWnNsOsMu9Zj8tTd0,1378
|
|
|
21
21
|
arelle/DialogURL.py,sha256=JH88OPFf588E8RW90uMaieok7A_4kOAURQ8kHWVhnao,4354
|
|
22
22
|
arelle/DialogUserPassword.py,sha256=kWPlCCihhwvsykDjanME9qBDtv6cxZlsrJyoMqiRep4,13769
|
|
23
23
|
arelle/DisclosureSystem.py,sha256=mQlz8eezPpJuG6gHBV-x4-5Hne3LVh8TQf-Qm9jiFxI,24757
|
|
24
|
-
arelle/FileSource.py,sha256=
|
|
24
|
+
arelle/FileSource.py,sha256=asaX2wM47T7S6kELwmXm-YjGIoV6poWz_YdYThY0lpk,47983
|
|
25
25
|
arelle/FunctionCustom.py,sha256=d1FsBG14eykvpLpgaXpN8IdxnlG54dfGcsXPYfdpA9Q,5880
|
|
26
26
|
arelle/FunctionFn.py,sha256=BcZKah1rpfquSVPwjvknM1pgFXOnK4Hr1e_ArG_mcJY,38058
|
|
27
27
|
arelle/FunctionIxt.py,sha256=8JELGh1l4o8Ul4_G7JgwX8Ebch9it2DblI6OkfL33Cw,80082
|
|
@@ -46,7 +46,7 @@ arelle/ModelRenderingObject.py,sha256=iPhSUlSBG-FLzAfIdUW06UZDgTCaZJ4K2mxvAtSe2B
|
|
|
46
46
|
arelle/ModelRssItem.py,sha256=GzFkmluOlFsVcrxn9HAyOAcuE7rcHUOGkp4Q6F2IlT8,7713
|
|
47
47
|
arelle/ModelRssObject.py,sha256=xjuwyJ8pU5sQmNPJFQakDEEnujZg2bMCTaj3zVezHL8,992
|
|
48
48
|
arelle/ModelTestcaseObject.py,sha256=dnCxatJcFPlu5BgTuToqgrQowYNx4YtA5KrmW4vHko4,22432
|
|
49
|
-
arelle/ModelValue.py,sha256=
|
|
49
|
+
arelle/ModelValue.py,sha256=0sr7njFjGI2W3Bct2dxf2LoG_fLerHQouQtM0v0ZY2E,39573
|
|
50
50
|
arelle/ModelVersObject.py,sha256=cPD1IzhkCfuV1eMgVFWes88DH_6WkUj5kj7sgGF2M0I,26062
|
|
51
51
|
arelle/ModelVersReport.py,sha256=bXEA9K3qkH57aABn5l-m3CTY0FAcF1yX6O4fo-URjl8,73326
|
|
52
52
|
arelle/ModelXbrl.py,sha256=bj-_enkb2AV2KVCRrRf2YPGxOoO9cdqKnVqfy3bGFZk,72125
|
|
@@ -65,7 +65,7 @@ arelle/UITkTable.py,sha256=N83cXi5c0lLZLsDbwSKcPrlYoUoGsNavGN5YRx6d9XY,39810
|
|
|
65
65
|
arelle/UiUtil.py,sha256=3G0xPclZI8xW_XQDbiFrmylB7Nd5muqi5n2x2oMkMZU,34218
|
|
66
66
|
arelle/Updater.py,sha256=IZ8cq44Rq88WbQcB1VOpMA6bxdfZxfYQ8rgu9Ehpbes,7448
|
|
67
67
|
arelle/UrlUtil.py,sha256=HrxZSG59EUMGMMGmWPuZkPi5-0BGqY3jAMkp7V4IdZo,32400
|
|
68
|
-
arelle/Validate.py,sha256=
|
|
68
|
+
arelle/Validate.py,sha256=YQUr2t2lyuQJD4ygfKgbj7grON-Od5pYfkjFVS5XuDM,58049
|
|
69
69
|
arelle/ValidateDuplicateFacts.py,sha256=L556J1Dhz4ZmsMlRNoDCMpFgDQYiryd9vuBYDvE0Aq8,21769
|
|
70
70
|
arelle/ValidateFilingText.py,sha256=xnXc0xgdNiHQk0eyP7VSSpvw7qr-pRFRwqqoUb569is,54051
|
|
71
71
|
arelle/ValidateInfoset.py,sha256=Rz_XBi5Ha43KpxXYhjLolURcWVx5qmqyjLxw48Yt9Dg,20396
|
|
@@ -114,7 +114,7 @@ arelle/ViewWinVersReport.py,sha256=aYfsOgynVZpMzl6f2EzQCBLzdihYGycwb5SiTghkgMQ,9
|
|
|
114
114
|
arelle/ViewWinXml.py,sha256=4ZGKtjaoCwU9etKYm9ZAS7jSmUxba1rqNEdv0OIyjTY,1250
|
|
115
115
|
arelle/WatchRss.py,sha256=5Ih4igH2MM4hpOuAXy9eO0QAyZ7jZR3S5bPzo2sdFpw,14097
|
|
116
116
|
arelle/WebCache.py,sha256=HlF4vfjxO0bSFHqMPfjnmkrzc7RK9XT714a7g3XFTDY,45192
|
|
117
|
-
arelle/XbrlConst.py,sha256=
|
|
117
|
+
arelle/XbrlConst.py,sha256=T8Cvogf1j2I5aws7ZDwLmCj6zcYwxUZIk9ZXDYwHfxU,58164
|
|
118
118
|
arelle/XbrlUtil.py,sha256=s2Vmrh-sZI5TeuqsziKignOc3ao-uUgnCNoelP4dDj0,9212
|
|
119
119
|
arelle/XhtmlValidate.py,sha256=0gtm7N-kXK0RB5o3c1AQXjfFuRp1w2fKZZAeyruNANw,5727
|
|
120
120
|
arelle/XmlUtil.py,sha256=1VToOOylF8kbEorEdZLThmq35j9bmuF_DS2q9NthnHU,58774
|
|
@@ -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=qE1JoU23iZVZMuNLXnlDRaP4Udr6pvevq0c9sMilUZ4,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
|
|
@@ -392,18 +392,20 @@ arelle/plugin/validate/DBA/rules/tm.py,sha256=ui9oKBqlAForwkQ9kk9KBiUogTJE5pv1Rb
|
|
|
392
392
|
arelle/plugin/validate/DBA/rules/tr.py,sha256=zdi3kQ82whmweVWRLbMvcNpM8sqtUliPsGfd81rgZws,14671
|
|
393
393
|
arelle/plugin/validate/EBA/__init__.py,sha256=1kW-04W32sStSAL8wvW1ZpXnjlFv6KLbfE4aifYUB2A,46000
|
|
394
394
|
arelle/plugin/validate/EBA/config.xml,sha256=37wMVUAObK-XEqakqD8zPNog20emYt4a_yfL1AKubF8,2022
|
|
395
|
+
arelle/plugin/validate/EDINET/Constants.py,sha256=QG69rWdpIrpQzZQkRcDWk2i3rlBVohr4VtSdW-IS5_w,734
|
|
395
396
|
arelle/plugin/validate/EDINET/DisclosureSystems.py,sha256=3rKG42Eg-17Xx_KXU_V5yHW6I3LTwQunvf4a44C9k_4,36
|
|
396
397
|
arelle/plugin/validate/EDINET/FormType.py,sha256=pJfKjdjqFcRLFgH6xbEixvpwatZBBHI8uI3xjjhaPI0,3175
|
|
397
|
-
arelle/plugin/validate/EDINET/
|
|
398
|
+
arelle/plugin/validate/EDINET/Manifest.py,sha256=VWenzA1ndOp802zpTELSLREbCrzrA-nM1UCRpRf1Q3M,4849
|
|
399
|
+
arelle/plugin/validate/EDINET/PluginValidationDataExtension.py,sha256=vJPs5GgNJbRUBTKP0ULMb4UqvDoGATPC9dTFsKG4HyI,6347
|
|
398
400
|
arelle/plugin/validate/EDINET/ValidationPluginExtension.py,sha256=HIGOpBOyuVs5SEh573M3IzdouRdEuNIBkdumieZi8r0,959
|
|
399
|
-
arelle/plugin/validate/EDINET/__init__.py,sha256=
|
|
401
|
+
arelle/plugin/validate/EDINET/__init__.py,sha256=ew9Rc2qJe5d3XvOOFzhX6MfzxNUtxIYfxRGX-wkfR1c,3555
|
|
400
402
|
arelle/plugin/validate/EDINET/resources/config.xml,sha256=GmLcW7UIj5koXJkN19P6Nq5EZJcs6gKQLQ5f2V6u78w,614
|
|
401
403
|
arelle/plugin/validate/EDINET/resources/edinet-taxonomies.xml,sha256=997I3RGTLg5OY3vn5hQxVFAAxOmDSOYpuyQe6VnWSY0,16285
|
|
402
404
|
arelle/plugin/validate/EDINET/rules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
403
405
|
arelle/plugin/validate/EDINET/rules/edinet.py,sha256=hm5T8PiQbOKP58BiSV9UFvKQX10uNBpxUZ06ORSU1cE,2117
|
|
404
406
|
arelle/plugin/validate/EDINET/rules/frta.py,sha256=l7BQHOenDjYrpCX6bsXyUHgyvkjbfvJWfbpBthCHmBI,1713
|
|
405
|
-
arelle/plugin/validate/EDINET/rules/gfm.py,sha256=
|
|
406
|
-
arelle/plugin/validate/EDINET/rules/upload.py,sha256=
|
|
407
|
+
arelle/plugin/validate/EDINET/rules/gfm.py,sha256=EYOPRzJrjp9taPFm53vn7e4CEq0rgIps4_bEslSZJWo,10392
|
|
408
|
+
arelle/plugin/validate/EDINET/rules/upload.py,sha256=HZ-9Gk6WtIichTGcSsSGIrMXNgsgJYQYwfUKeLs1XWU,20369
|
|
407
409
|
arelle/plugin/validate/ESEF/Const.py,sha256=JujF_XV-_TNsxjGbF-8SQS4OOZIcJ8zhCMnr-C1O5Ho,22660
|
|
408
410
|
arelle/plugin/validate/ESEF/Dimensions.py,sha256=MOJM7vwNPEmV5cu-ZzPrhx3347ZvxgD6643OB2HRnIk,10597
|
|
409
411
|
arelle/plugin/validate/ESEF/Util.py,sha256=QH3btcGqBpr42M7WSKZLSdNXygZaZLfEiEjlxoG21jE,7950
|
|
@@ -439,7 +441,7 @@ arelle/plugin/validate/ROS/__init__.py,sha256=KuWg1MHVzA2S6eaHFptvP3Vu_5gQWf3OUY
|
|
|
439
441
|
arelle/plugin/validate/ROS/config.xml,sha256=ZCpCFgr1ZAjoUuhb1eRpDnmKrae-sXA9yl6SOWnrfm8,654
|
|
440
442
|
arelle/plugin/validate/ROS/resources/config.xml,sha256=HXWume5HlrAqOx5AtiWWqgADbRatA8YSfm_JvZGwdgQ,657
|
|
441
443
|
arelle/plugin/validate/ROS/rules/__init__.py,sha256=wW7BUAIb7sRkOxC1Amc_ZKrz03FM-Qh1TyZe6wxYaAU,1567
|
|
442
|
-
arelle/plugin/validate/ROS/rules/ros.py,sha256=
|
|
444
|
+
arelle/plugin/validate/ROS/rules/ros.py,sha256=Vv7qKMmhBEuPu7y_g0sjiDLnm5VXXz6EVdzonJbCUtg,18436
|
|
443
445
|
arelle/plugin/validate/UK/ValidateUK.py,sha256=0UhSwsY1lrY-EAEBJJR9QY38YXGBZ6PEgmuC5gQfBlI,57813
|
|
444
446
|
arelle/plugin/validate/UK/__init__.py,sha256=KE6s_B-EvrHDCtWQz2N_wQwyx_ZbWhYNV2GfQnluxMw,30655
|
|
445
447
|
arelle/plugin/validate/UK/config.xml,sha256=mUFhWDfBzGTn7v0ZSmf4HaweQTMJh_4ZcJmD9mzCHrA,1547
|
|
@@ -754,9 +756,9 @@ arelle/utils/validate/ValidationUtil.py,sha256=9vmSvShn-EdQy56dfesyV8JjSRVPj7txr
|
|
|
754
756
|
arelle/utils/validate/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
755
757
|
arelle/webserver/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
756
758
|
arelle/webserver/bottle.py,sha256=P-JECd9MCTNcxCnKoDUvGcoi03ezYVOgoWgv2_uH-6M,362
|
|
757
|
-
arelle_release-2.37.
|
|
758
|
-
arelle_release-2.37.
|
|
759
|
-
arelle_release-2.37.
|
|
760
|
-
arelle_release-2.37.
|
|
761
|
-
arelle_release-2.37.
|
|
762
|
-
arelle_release-2.37.
|
|
759
|
+
arelle_release-2.37.36.dist-info/licenses/LICENSE.md,sha256=Q0tn6q0VUbr-NM8916513NCIG8MNzo24Ev-sxMUBRZc,3959
|
|
760
|
+
arelle_release-2.37.36.dist-info/METADATA,sha256=O21K0JV03vScH1fAs0RomXYXTEyz-r135EHcUNJbaI8,9137
|
|
761
|
+
arelle_release-2.37.36.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
762
|
+
arelle_release-2.37.36.dist-info/entry_points.txt,sha256=Uj5niwfwVsx3vaQ3fYj8hrZ1xpfCJyTUA09tYKWbzpo,111
|
|
763
|
+
arelle_release-2.37.36.dist-info/top_level.txt,sha256=fwU7SYawL4_r-sUMRg7r1nYVGjFMSDvRWx8VGAXEw7w,7
|
|
764
|
+
arelle_release-2.37.36.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|