arelle-release 2.37.50__py3-none-any.whl → 2.37.51__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/_version.py +16 -3
- arelle/plugin/validate/EDINET/Constants.py +2 -0
- arelle/plugin/validate/EDINET/ControllerPluginData.py +40 -29
- arelle/plugin/validate/EDINET/PluginValidationDataExtension.py +20 -2
- arelle/plugin/validate/EDINET/{InstanceType.py → ReportFolderType.py} +11 -15
- arelle/plugin/validate/EDINET/UploadContents.py +20 -5
- arelle/plugin/validate/EDINET/rules/gfm.py +10 -23
- arelle/plugin/validate/EDINET/rules/upload.py +230 -57
- {arelle_release-2.37.50.dist-info → arelle_release-2.37.51.dist-info}/METADATA +1 -1
- {arelle_release-2.37.50.dist-info → arelle_release-2.37.51.dist-info}/RECORD +14 -14
- {arelle_release-2.37.50.dist-info → arelle_release-2.37.51.dist-info}/WHEEL +0 -0
- {arelle_release-2.37.50.dist-info → arelle_release-2.37.51.dist-info}/entry_points.txt +0 -0
- {arelle_release-2.37.50.dist-info → arelle_release-2.37.51.dist-info}/licenses/LICENSE.md +0 -0
- {arelle_release-2.37.50.dist-info → arelle_release-2.37.51.dist-info}/top_level.txt +0 -0
arelle/_version.py
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
# file generated by setuptools-scm
|
|
2
2
|
# don't change, don't track in version control
|
|
3
3
|
|
|
4
|
-
__all__ = [
|
|
4
|
+
__all__ = [
|
|
5
|
+
"__version__",
|
|
6
|
+
"__version_tuple__",
|
|
7
|
+
"version",
|
|
8
|
+
"version_tuple",
|
|
9
|
+
"__commit_id__",
|
|
10
|
+
"commit_id",
|
|
11
|
+
]
|
|
5
12
|
|
|
6
13
|
TYPE_CHECKING = False
|
|
7
14
|
if TYPE_CHECKING:
|
|
@@ -9,13 +16,19 @@ if TYPE_CHECKING:
|
|
|
9
16
|
from typing import Union
|
|
10
17
|
|
|
11
18
|
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
|
19
|
+
COMMIT_ID = Union[str, None]
|
|
12
20
|
else:
|
|
13
21
|
VERSION_TUPLE = object
|
|
22
|
+
COMMIT_ID = object
|
|
14
23
|
|
|
15
24
|
version: str
|
|
16
25
|
__version__: str
|
|
17
26
|
__version_tuple__: VERSION_TUPLE
|
|
18
27
|
version_tuple: VERSION_TUPLE
|
|
28
|
+
commit_id: COMMIT_ID
|
|
29
|
+
__commit_id__: COMMIT_ID
|
|
19
30
|
|
|
20
|
-
__version__ = version = '2.37.
|
|
21
|
-
__version_tuple__ = version_tuple = (2, 37,
|
|
31
|
+
__version__ = version = '2.37.51'
|
|
32
|
+
__version_tuple__ = version_tuple = (2, 37, 51)
|
|
33
|
+
|
|
34
|
+
__commit_id__ = commit_id = None
|
|
@@ -37,3 +37,5 @@ qnEdinetManifestList = qname("{http://disclosure.edinet-fsa.go.jp/2013/manifest}
|
|
|
37
37
|
qnEdinetManifestTitle = qname("{http://disclosure.edinet-fsa.go.jp/2013/manifest}title")
|
|
38
38
|
qnEdinetManifestTocComposition = qname("{http://disclosure.edinet-fsa.go.jp/2013/manifest}tocComposition")
|
|
39
39
|
xhtmlDtdExtension = "xhtml1-strict-ix.dtd"
|
|
40
|
+
|
|
41
|
+
COVER_PAGE_FILENAME_PREFIX = "0000000_header_"
|
|
@@ -12,11 +12,11 @@ from typing import TYPE_CHECKING
|
|
|
12
12
|
|
|
13
13
|
from arelle.Cntlr import Cntlr
|
|
14
14
|
from arelle.FileSource import FileSource
|
|
15
|
-
from arelle.ModelXbrl import ModelXbrl
|
|
16
15
|
from arelle.typing import TypeGetText
|
|
17
16
|
from arelle.utils.PluginData import PluginData
|
|
18
|
-
from .
|
|
19
|
-
from .
|
|
17
|
+
from . import Constants
|
|
18
|
+
from .ReportFolderType import ReportFolderType
|
|
19
|
+
from .UploadContents import UploadContents, UploadPathInfo
|
|
20
20
|
|
|
21
21
|
if TYPE_CHECKING:
|
|
22
22
|
from .ManifestInstance import ManifestInstance
|
|
@@ -50,35 +50,46 @@ class ControllerPluginData(PluginData):
|
|
|
50
50
|
@lru_cache(1)
|
|
51
51
|
def getUploadContents(self, fileSource: FileSource) -> UploadContents:
|
|
52
52
|
uploadFilepaths = self.getUploadFilepaths(fileSource)
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
directories = []
|
|
56
|
-
forms = defaultdict(list)
|
|
53
|
+
reports = defaultdict(list)
|
|
54
|
+
uploadPaths = {}
|
|
57
55
|
for path in uploadFilepaths:
|
|
58
|
-
|
|
59
|
-
if len(parents) == 0:
|
|
60
|
-
continue
|
|
61
|
-
if parents[0] == 'XBRL':
|
|
62
|
-
if len(parents) > 1:
|
|
63
|
-
formName = parents[1]
|
|
64
|
-
instanceType = InstanceType.parse(formName)
|
|
65
|
-
if instanceType is not None:
|
|
66
|
-
forms[instanceType].append(path)
|
|
67
|
-
continue
|
|
68
|
-
formName = parents[0]
|
|
69
|
-
instanceType = InstanceType.parse(formName)
|
|
70
|
-
if instanceType is not None:
|
|
71
|
-
amendmentPaths[instanceType].append(path)
|
|
56
|
+
if len(path.parts) == 0:
|
|
72
57
|
continue
|
|
73
|
-
if len(
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
58
|
+
parents = list(reversed([p.name for p in path.parents if len(p.name) > 0]))
|
|
59
|
+
reportFolderType = None
|
|
60
|
+
isCorrection = True
|
|
61
|
+
isDirectory = len(path.suffix) == 0
|
|
62
|
+
isInSubdirectory = False
|
|
63
|
+
reportPath = None
|
|
64
|
+
if len(parents) > 0:
|
|
65
|
+
isCorrection = parents[0] != 'XBRL'
|
|
66
|
+
if not isCorrection:
|
|
67
|
+
if len(parents) > 1:
|
|
68
|
+
formName = parents[1]
|
|
69
|
+
isInSubdirectory = len(parents) > 2
|
|
70
|
+
reportFolderType = ReportFolderType.parse(formName)
|
|
71
|
+
if reportFolderType is None:
|
|
72
|
+
formName = parents[0]
|
|
73
|
+
isInSubdirectory = len(parents) > 1
|
|
74
|
+
reportFolderType = ReportFolderType.parse(formName)
|
|
75
|
+
if reportFolderType is not None:
|
|
76
|
+
reportPath = Path(reportFolderType.value) if isCorrection else Path("XBRL") / reportFolderType.value
|
|
77
|
+
if not isCorrection:
|
|
78
|
+
reports[reportFolderType].append(path)
|
|
79
|
+
uploadPaths[path] = UploadPathInfo(
|
|
80
|
+
isAttachment=reportFolderType is not None and reportFolderType.isAttachment,
|
|
81
|
+
isCorrection=isCorrection,
|
|
82
|
+
isCoverPage=not isDirectory and path.stem.startswith(Constants.COVER_PAGE_FILENAME_PREFIX),
|
|
83
|
+
isDirectory=len(path.suffix) == 0,
|
|
84
|
+
isRoot=len(path.parts) == 1,
|
|
85
|
+
isSubdirectory=isInSubdirectory or (isDirectory and reportFolderType is not None),
|
|
86
|
+
path=path,
|
|
87
|
+
reportFolderType=reportFolderType,
|
|
88
|
+
reportPath=reportPath,
|
|
89
|
+
)
|
|
77
90
|
return UploadContents(
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
instances={k: frozenset(v) for k, v in forms.items() if len(v) > 0},
|
|
81
|
-
unknownPaths=frozenset(unknownPaths)
|
|
91
|
+
reports={k: frozenset(v) for k, v in reports.items() if len(v) > 0},
|
|
92
|
+
uploadPaths=uploadPaths
|
|
82
93
|
)
|
|
83
94
|
|
|
84
95
|
@lru_cache(1)
|
|
@@ -7,15 +7,17 @@ from collections import defaultdict
|
|
|
7
7
|
from dataclasses import dataclass
|
|
8
8
|
from decimal import Decimal
|
|
9
9
|
from functools import lru_cache
|
|
10
|
+
from lxml.etree import DTD, XML
|
|
10
11
|
from operator import attrgetter
|
|
11
12
|
from typing import Callable, Hashable, Iterable, cast
|
|
12
13
|
|
|
14
|
+
import os
|
|
13
15
|
import regex
|
|
14
16
|
|
|
15
17
|
from arelle.LinkbaseType import LinkbaseType
|
|
16
18
|
from arelle.ModelDocument import Type as ModelDocumentType
|
|
17
19
|
from arelle.ModelDtsObject import ModelConcept
|
|
18
|
-
from arelle.ModelInstanceObject import ModelFact, ModelUnit, ModelContext
|
|
20
|
+
from arelle.ModelInstanceObject import ModelFact, ModelUnit, ModelContext, ModelInlineFact
|
|
19
21
|
from arelle.ModelObject import ModelObject
|
|
20
22
|
from arelle.ModelValue import QName, qname
|
|
21
23
|
from arelle.ModelXbrl import ModelXbrl
|
|
@@ -24,7 +26,7 @@ from arelle.ValidateDuplicateFacts import getDeduplicatedFacts, DeduplicationTyp
|
|
|
24
26
|
from arelle.XmlValidate import VALID
|
|
25
27
|
from arelle.typing import TypeGetText
|
|
26
28
|
from arelle.utils.PluginData import PluginData
|
|
27
|
-
from .Constants import CORPORATE_FORMS, FormType
|
|
29
|
+
from .Constants import CORPORATE_FORMS, FormType, xhtmlDtdExtension
|
|
28
30
|
from .ControllerPluginData import ControllerPluginData
|
|
29
31
|
from .ManifestInstance import ManifestInstance
|
|
30
32
|
from .Statement import Statement, STATEMENTS, BalanceSheet, StatementInstance, StatementType
|
|
@@ -166,6 +168,22 @@ class PluginValidationDataExtension(PluginData):
|
|
|
166
168
|
)
|
|
167
169
|
return balanceSheets
|
|
168
170
|
|
|
171
|
+
def getProblematicTextBlocks(self, modelXbrl: ModelXbrl) -> list[ModelInlineFact]:
|
|
172
|
+
problematicTextBlocks: list[ModelInlineFact] = []
|
|
173
|
+
dtd = DTD(os.path.join(modelXbrl.modelManager.cntlr.configDir, xhtmlDtdExtension))
|
|
174
|
+
htmlBodyTemplate = "<body><div>\n{0}\n</div></body>\n"
|
|
175
|
+
for fact in modelXbrl.facts:
|
|
176
|
+
concept = fact.concept
|
|
177
|
+
if isinstance(fact, ModelInlineFact) and not fact.isNil and concept is not None and concept.isTextBlock and not fact.isEscaped:
|
|
178
|
+
xmlBody = htmlBodyTemplate.format(fact.value)
|
|
179
|
+
try:
|
|
180
|
+
textblockXml = XML(xmlBody)
|
|
181
|
+
if not dtd.validate(textblockXml):
|
|
182
|
+
problematicTextBlocks.append(fact)
|
|
183
|
+
except Exception:
|
|
184
|
+
problematicTextBlocks.append(fact)
|
|
185
|
+
return problematicTextBlocks
|
|
186
|
+
|
|
169
187
|
@lru_cache(1)
|
|
170
188
|
def getStatementInstance(self, modelXbrl: ModelXbrl, statement: Statement) -> StatementInstance | None:
|
|
171
189
|
if statement.roleUri not in modelXbrl.roleTypes:
|
|
@@ -8,16 +8,15 @@ from functools import cached_property, lru_cache
|
|
|
8
8
|
from pathlib import Path
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
class
|
|
11
|
+
class ReportFolderType(Enum):
|
|
12
12
|
ATTACH_DOC = "AttachDoc"
|
|
13
13
|
AUDIT_DOC = "AuditDoc"
|
|
14
|
-
ENGLISH_DOC = "EnglishDoc"
|
|
15
14
|
PRIVATE_ATTACH = "PrivateAttach"
|
|
16
15
|
PRIVATE_DOC = "PrivateDoc"
|
|
17
16
|
PUBLIC_DOC = "PublicDoc"
|
|
18
17
|
|
|
19
18
|
@classmethod
|
|
20
|
-
def parse(cls, value: str) ->
|
|
19
|
+
def parse(cls, value: str) -> ReportFolderType | None:
|
|
21
20
|
try:
|
|
22
21
|
return cls(value)
|
|
23
22
|
except ValueError:
|
|
@@ -27,6 +26,10 @@ class InstanceType(Enum):
|
|
|
27
26
|
def extensionCategory(self) -> ExtensionCategory | None:
|
|
28
27
|
return FORM_TYPE_EXTENSION_CATEGORIES.get(self, None)
|
|
29
28
|
|
|
29
|
+
@cached_property
|
|
30
|
+
def isAttachment(self) -> bool:
|
|
31
|
+
return "Attach" in self.value
|
|
32
|
+
|
|
30
33
|
@cached_property
|
|
31
34
|
def manifestName(self) -> str:
|
|
32
35
|
return f'manifest_{self.value}.xml'
|
|
@@ -49,7 +52,6 @@ class InstanceType(Enum):
|
|
|
49
52
|
class ExtensionCategory(Enum):
|
|
50
53
|
ATTACH = 'ATTACH'
|
|
51
54
|
DOC = 'DOC'
|
|
52
|
-
ENGLISH_DOC = 'ENGLISH_DOC'
|
|
53
55
|
|
|
54
56
|
def getValidExtensions(self, isAmendment: bool, isSubdirectory: bool) -> frozenset[str] | None:
|
|
55
57
|
amendmentMap = VALID_EXTENSIONS[isAmendment]
|
|
@@ -60,12 +62,11 @@ class ExtensionCategory(Enum):
|
|
|
60
62
|
|
|
61
63
|
|
|
62
64
|
FORM_TYPE_EXTENSION_CATEGORIES = {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
InstanceType.PUBLIC_DOC: ExtensionCategory.DOC,
|
|
65
|
+
ReportFolderType.ATTACH_DOC: ExtensionCategory.ATTACH,
|
|
66
|
+
ReportFolderType.AUDIT_DOC: ExtensionCategory.DOC,
|
|
67
|
+
ReportFolderType.PRIVATE_ATTACH: ExtensionCategory.ATTACH,
|
|
68
|
+
ReportFolderType.PRIVATE_DOC: ExtensionCategory.DOC,
|
|
69
|
+
ReportFolderType.PUBLIC_DOC: ExtensionCategory.DOC,
|
|
69
70
|
}
|
|
70
71
|
|
|
71
72
|
|
|
@@ -74,7 +75,6 @@ IMAGE_EXTENSIONS = frozenset({'.jpeg', '.jpg', '.gif', '.png'})
|
|
|
74
75
|
ASSET_EXTENSIONS = frozenset(HTML_EXTENSIONS | IMAGE_EXTENSIONS)
|
|
75
76
|
XBRL_EXTENSIONS = frozenset(HTML_EXTENSIONS | {'.xml', '.xsd'})
|
|
76
77
|
ATTACH_EXTENSIONS = frozenset(HTML_EXTENSIONS | {'.pdf', })
|
|
77
|
-
ENGLISH_DOC_EXTENSIONS = frozenset(ASSET_EXTENSIONS | frozenset({'.pdf', '.xml', '.txt'}))
|
|
78
78
|
|
|
79
79
|
# Is Amendment -> Category -> Is Subdirectory
|
|
80
80
|
VALID_EXTENSIONS = {
|
|
@@ -97,9 +97,5 @@ VALID_EXTENSIONS = {
|
|
|
97
97
|
False: HTML_EXTENSIONS,
|
|
98
98
|
True: ASSET_EXTENSIONS,
|
|
99
99
|
},
|
|
100
|
-
ExtensionCategory.ENGLISH_DOC: {
|
|
101
|
-
False: ENGLISH_DOC_EXTENSIONS,
|
|
102
|
-
True: ENGLISH_DOC_EXTENSIONS,
|
|
103
|
-
},
|
|
104
100
|
},
|
|
105
101
|
}
|
|
@@ -6,12 +6,27 @@ from __future__ import annotations
|
|
|
6
6
|
from dataclasses import dataclass
|
|
7
7
|
from pathlib import Path
|
|
8
8
|
|
|
9
|
-
from .
|
|
9
|
+
from .ReportFolderType import ReportFolderType
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
@dataclass(frozen=True)
|
|
13
13
|
class UploadContents:
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
reports: dict[ReportFolderType, frozenset[Path]]
|
|
15
|
+
uploadPaths: dict[Path, UploadPathInfo]
|
|
16
|
+
|
|
17
|
+
@property
|
|
18
|
+
def sortedPaths(self) -> list[Path]:
|
|
19
|
+
return sorted(self.uploadPaths.keys())
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@dataclass(frozen=True)
|
|
23
|
+
class UploadPathInfo:
|
|
24
|
+
isAttachment: bool
|
|
25
|
+
isCorrection: bool
|
|
26
|
+
isCoverPage: bool
|
|
27
|
+
isDirectory: bool
|
|
28
|
+
isRoot: bool
|
|
29
|
+
isSubdirectory: bool
|
|
30
|
+
path: Path
|
|
31
|
+
reportFolderType: ReportFolderType | None
|
|
32
|
+
reportPath: Path | None
|
|
@@ -30,7 +30,7 @@ from arelle.utils.validate.Validation import Validation
|
|
|
30
30
|
from arelle.utils.validate.ValidationUtil import etreeIterWithDepth
|
|
31
31
|
from ..DisclosureSystems import (DISCLOSURE_SYSTEM_EDINET)
|
|
32
32
|
from ..PluginValidationDataExtension import PluginValidationDataExtension
|
|
33
|
-
|
|
33
|
+
|
|
34
34
|
|
|
35
35
|
_: TypeGetText
|
|
36
36
|
|
|
@@ -368,28 +368,15 @@ def rule_gfm_1_2_14(
|
|
|
368
368
|
(a format that conforms to XML grammar, such as all start and end tags being paired, and the end tag of a nested tag not coming after the end tag of its parent tag, etc.).
|
|
369
369
|
Please modify it so that it is well-formed.
|
|
370
370
|
"""
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
concept = fact.concept
|
|
381
|
-
if not fact.isNil and concept is not None and concept.isTextBlock and XMLpattern.match(fact.value):
|
|
382
|
-
for xmlText in [fact.value] + CDATApattern.findall(fact.value):
|
|
383
|
-
xmlBodyWithoutEntities = htmlBodyTemplate.format(namedEntityPattern.sub("", xmlText).replace('&','&'))
|
|
384
|
-
textblockXml = XML(xmlBodyWithoutEntities)
|
|
385
|
-
if not dtd.validate(textblockXml):
|
|
386
|
-
yield Validation.warning(
|
|
387
|
-
codes='EDINET.EC5700W.GFM.1.2.14',
|
|
388
|
-
msg=_('The content of an element with a data type of nonnum:textBlockItemType is not well-formed XML (a format that conforms to XML grammar, '
|
|
389
|
-
'such as all start and end tags being in pairs, and the end tag of a nested tag not coming after the end tag of its parent tag). '
|
|
390
|
-
'Correct the content so that it is well-formed.'),
|
|
391
|
-
modelObject = fact
|
|
392
|
-
)
|
|
371
|
+
problematicFacts = pluginData.getProblematicTextBlocks(val.modelXbrl)
|
|
372
|
+
if len(problematicFacts) > 0:
|
|
373
|
+
yield Validation.warning(
|
|
374
|
+
codes='EDINET.EC5700W.GFM.1.2.14',
|
|
375
|
+
msg=_('The content of an element with a data type of nonnum:textBlockItemType is not well-formed XML (a format that conforms to XML grammar, '
|
|
376
|
+
'such as all start and end tags being in pairs, and the end tag of a nested tag not coming after the end tag of its parent tag). '
|
|
377
|
+
'Correct the content so that it is well-formed.'),
|
|
378
|
+
modelObject = problematicFacts
|
|
379
|
+
)
|
|
393
380
|
|
|
394
381
|
|
|
395
382
|
@validation(
|
|
@@ -16,7 +16,7 @@ from arelle.utils.PluginHooks import ValidationHook
|
|
|
16
16
|
from arelle.utils.validate.Decorator import validation
|
|
17
17
|
from arelle.utils.validate.Validation import Validation
|
|
18
18
|
from ..DisclosureSystems import (DISCLOSURE_SYSTEM_EDINET)
|
|
19
|
-
from ..
|
|
19
|
+
from ..ReportFolderType import ReportFolderType, HTML_EXTENSIONS, IMAGE_EXTENSIONS
|
|
20
20
|
from ..PluginValidationDataExtension import PluginValidationDataExtension
|
|
21
21
|
|
|
22
22
|
if TYPE_CHECKING:
|
|
@@ -24,6 +24,16 @@ if TYPE_CHECKING:
|
|
|
24
24
|
|
|
25
25
|
_: TypeGetText
|
|
26
26
|
|
|
27
|
+
ALLOWED_ROOT_FOLDERS = {
|
|
28
|
+
"AttachDoc",
|
|
29
|
+
"AuditDoc",
|
|
30
|
+
"PrivateAttach",
|
|
31
|
+
"PrivateDoc",
|
|
32
|
+
"PublicAttach",
|
|
33
|
+
"PublicDoc",
|
|
34
|
+
"XBRL",
|
|
35
|
+
}
|
|
36
|
+
|
|
27
37
|
FILE_COUNT_LIMITS = {
|
|
28
38
|
Path("AttachDoc"): 990,
|
|
29
39
|
Path("AuditDoc"): 990,
|
|
@@ -43,7 +53,7 @@ FILENAME_STEM_PATTERN = re.compile(r'[a-zA-Z0-9_-]*')
|
|
|
43
53
|
hook=ValidationHook.FILESOURCE,
|
|
44
54
|
disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
|
|
45
55
|
)
|
|
46
|
-
def
|
|
56
|
+
def rule_EC0100E(
|
|
47
57
|
pluginData: ControllerPluginData,
|
|
48
58
|
cntlr: Cntlr,
|
|
49
59
|
fileSource: FileSource,
|
|
@@ -51,30 +61,32 @@ def rule_EC0121E(
|
|
|
51
61
|
**kwargs: Any,
|
|
52
62
|
) -> Iterable[Validation]:
|
|
53
63
|
"""
|
|
54
|
-
EDINET.
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
64
|
+
EDINET.EC0100E: An illegal directory is found directly under the transferred directory.
|
|
65
|
+
Only the following root folders are allowed:
|
|
66
|
+
AttachDoc
|
|
67
|
+
AuditDoc*
|
|
68
|
+
PrivateAttach
|
|
69
|
+
PrivateDoc*
|
|
70
|
+
PublicAttach
|
|
71
|
+
PublicDoc*
|
|
72
|
+
XBRL
|
|
73
|
+
* Only when reporting corrections
|
|
74
|
+
|
|
75
|
+
NOTE: since we do not have access to the submission type, we can't determine if the submission is a correction or not.
|
|
76
|
+
For this implementation, we will allow all directories that may be valid for at least one submission type.
|
|
77
|
+
This allows for a false-negative outcome when a non-correction submission has a correction-only root directory.
|
|
61
78
|
"""
|
|
62
79
|
uploadContents = pluginData.getUploadContents(fileSource)
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
paths.update(amendmentPaths)
|
|
66
|
-
for path in paths:
|
|
67
|
-
if len(str(path.name)) > 31 or not FILENAME_STEM_PATTERN.match(path.stem):
|
|
80
|
+
for path, pathInfo in uploadContents.uploadPaths.items():
|
|
81
|
+
if pathInfo.isRoot and path.name not in ALLOWED_ROOT_FOLDERS:
|
|
68
82
|
yield Validation.error(
|
|
69
|
-
codes='EDINET.
|
|
70
|
-
msg=_("
|
|
71
|
-
"
|
|
72
|
-
"
|
|
73
|
-
"
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
basename=path.name,
|
|
77
|
-
file=str(path)
|
|
83
|
+
codes='EDINET.EC0100E',
|
|
84
|
+
msg=_("An illegal directory is found directly under the transferred directory. "
|
|
85
|
+
"Directory name or file name: '%(rootDirectory)s'. "
|
|
86
|
+
"Delete all folders except the following folders that exist directly "
|
|
87
|
+
"under the root folder, and then upload again: %(allowedDirectories)s."),
|
|
88
|
+
rootDirectory=path.name,
|
|
89
|
+
allowedDirectories=', '.join(f"'{d}'" for d in ALLOWED_ROOT_FOLDERS)
|
|
78
90
|
)
|
|
79
91
|
|
|
80
92
|
|
|
@@ -82,7 +94,7 @@ def rule_EC0121E(
|
|
|
82
94
|
hook=ValidationHook.FILESOURCE,
|
|
83
95
|
disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
|
|
84
96
|
)
|
|
85
|
-
def
|
|
97
|
+
def rule_EC0124E_EC0187E(
|
|
86
98
|
pluginData: ControllerPluginData,
|
|
87
99
|
cntlr: Cntlr,
|
|
88
100
|
fileSource: FileSource,
|
|
@@ -90,7 +102,8 @@ def rule_EC0124E(
|
|
|
90
102
|
**kwargs: Any,
|
|
91
103
|
) -> Iterable[Validation]:
|
|
92
104
|
"""
|
|
93
|
-
EDINET.EC0124E: There are no empty directories.
|
|
105
|
+
EDINET.EC0124E: There are no empty root directories.
|
|
106
|
+
EDINET.EC0187E: There are no empty subdirectories.
|
|
94
107
|
"""
|
|
95
108
|
uploadFilepaths = pluginData.getUploadFilepaths(fileSource)
|
|
96
109
|
emptyDirectories = []
|
|
@@ -98,15 +111,24 @@ def rule_EC0124E(
|
|
|
98
111
|
if path.suffix:
|
|
99
112
|
continue
|
|
100
113
|
if not any(path in p.parents for p in uploadFilepaths):
|
|
101
|
-
emptyDirectories.append(
|
|
114
|
+
emptyDirectories.append(path)
|
|
102
115
|
for emptyDirectory in emptyDirectories:
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
116
|
+
if len(emptyDirectory.parts) <= 1:
|
|
117
|
+
yield Validation.error(
|
|
118
|
+
codes='EDINET.EC0124E',
|
|
119
|
+
msg=_("There is no file directly under '%(emptyDirectory)s'. "
|
|
120
|
+
"No empty root folders. "
|
|
121
|
+
"Please store the file in the appropriate folder or delete the folder and upload again."),
|
|
122
|
+
emptyDirectory=str(emptyDirectory),
|
|
123
|
+
)
|
|
124
|
+
else:
|
|
125
|
+
yield Validation.error(
|
|
126
|
+
codes='EDINET.EC0187E',
|
|
127
|
+
msg=_("'%(parentDirectory)s' contains a subordinate directory ('%(emptyDirectory)s') with no files. "
|
|
128
|
+
"Please store the file in the corresponding subfolder or delete the subfolder and upload again."),
|
|
129
|
+
parentDirectory=str(emptyDirectory.parent),
|
|
130
|
+
emptyDirectory=str(emptyDirectory),
|
|
131
|
+
)
|
|
110
132
|
|
|
111
133
|
|
|
112
134
|
@validation(
|
|
@@ -160,22 +182,13 @@ def rule_EC0130E(
|
|
|
160
182
|
EDINET.EC0130E: File extensions must match the file extensions allowed in Figure 2-1-3 and Figure 2-1-5.
|
|
161
183
|
"""
|
|
162
184
|
uploadContents = pluginData.getUploadContents(fileSource)
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
for amendmentPath in amendmentPaths:
|
|
166
|
-
isSubdirectory = amendmentPath.parent.name != instanceType.value
|
|
167
|
-
checks.append((amendmentPath, True, instanceType, isSubdirectory))
|
|
168
|
-
for instanceType, formPaths in uploadContents.instances.items():
|
|
169
|
-
for amendmentPath in formPaths:
|
|
170
|
-
isSubdirectory = amendmentPath.parent.name != instanceType.value
|
|
171
|
-
checks.append((amendmentPath, False, instanceType, isSubdirectory))
|
|
172
|
-
for path, isAmendment, instanceType, isSubdirectory in checks:
|
|
173
|
-
ext = path.suffix
|
|
174
|
-
if len(ext) == 0:
|
|
185
|
+
for path, pathInfo in uploadContents.uploadPaths.items():
|
|
186
|
+
if pathInfo.reportFolderType is None or pathInfo.isDirectory:
|
|
175
187
|
continue
|
|
176
|
-
validExtensions =
|
|
188
|
+
validExtensions = pathInfo.reportFolderType.getValidExtensions(pathInfo.isCorrection, pathInfo.isSubdirectory)
|
|
177
189
|
if validExtensions is None:
|
|
178
190
|
continue
|
|
191
|
+
ext = path.suffix
|
|
179
192
|
if ext not in validExtensions:
|
|
180
193
|
yield Validation.error(
|
|
181
194
|
codes='EDINET.EC0130E',
|
|
@@ -207,18 +220,17 @@ def rule_EC0132E(
|
|
|
207
220
|
EDINET.EC0132E: Store the manifest file directly under the relevant folder.
|
|
208
221
|
"""
|
|
209
222
|
uploadContents = pluginData.getUploadContents(fileSource)
|
|
210
|
-
for
|
|
211
|
-
if
|
|
223
|
+
for reportFolderType, paths in uploadContents.reports.items():
|
|
224
|
+
if reportFolderType.isAttachment:
|
|
212
225
|
continue
|
|
213
|
-
if
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
)
|
|
226
|
+
if reportFolderType.manifestPath not in paths:
|
|
227
|
+
yield Validation.error(
|
|
228
|
+
codes='EDINET.EC0132E',
|
|
229
|
+
msg=_("'%(expectedManifestName)s' does not exist in '%(expectedManifestDirectory)s'. "
|
|
230
|
+
"Please store the manifest file (or cover file) directly under the relevant folder and upload it again. "),
|
|
231
|
+
expectedManifestName=reportFolderType.manifestPath.name,
|
|
232
|
+
expectedManifestDirectory=str(reportFolderType.manifestPath.parent),
|
|
233
|
+
)
|
|
222
234
|
|
|
223
235
|
|
|
224
236
|
@validation(
|
|
@@ -279,6 +291,36 @@ def rule_EC0188E(
|
|
|
279
291
|
)
|
|
280
292
|
|
|
281
293
|
|
|
294
|
+
@validation(
|
|
295
|
+
hook=ValidationHook.FILESOURCE,
|
|
296
|
+
disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
|
|
297
|
+
)
|
|
298
|
+
def rule_EC0192E(
|
|
299
|
+
pluginData: ControllerPluginData,
|
|
300
|
+
cntlr: Cntlr,
|
|
301
|
+
fileSource: FileSource,
|
|
302
|
+
*args: Any,
|
|
303
|
+
**kwargs: Any,
|
|
304
|
+
) -> Iterable[Validation]:
|
|
305
|
+
"""
|
|
306
|
+
EDINET.EC0192E: The cover file for PrivateDoc cannot be set because it uses a
|
|
307
|
+
PublicDoc cover file. Please delete the cover file from PrivateDoc and upload
|
|
308
|
+
it again.
|
|
309
|
+
"""
|
|
310
|
+
uploadContents = pluginData.getUploadContents(fileSource)
|
|
311
|
+
for path, pathInfo in uploadContents.uploadPaths.items():
|
|
312
|
+
if not pathInfo.isCoverPage:
|
|
313
|
+
continue
|
|
314
|
+
# Only applies to PrivateDoc correction reports
|
|
315
|
+
if pathInfo.isCorrection and pathInfo.reportFolderType == ReportFolderType.PRIVATE_DOC:
|
|
316
|
+
yield Validation.error(
|
|
317
|
+
codes='EDINET.EC0192E',
|
|
318
|
+
msg=_("The cover file for PrivateDoc ('%(file)s') cannot be set because it uses a PublicDoc cover file. "
|
|
319
|
+
"Please delete the cover file from PrivateDoc and upload it again."),
|
|
320
|
+
file=str(path),
|
|
321
|
+
)
|
|
322
|
+
|
|
323
|
+
|
|
282
324
|
@validation(
|
|
283
325
|
hook=ValidationHook.FILESOURCE,
|
|
284
326
|
disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
|
|
@@ -315,6 +357,82 @@ def rule_EC0198E(
|
|
|
315
357
|
)
|
|
316
358
|
|
|
317
359
|
|
|
360
|
+
@validation(
|
|
361
|
+
hook=ValidationHook.FILESOURCE,
|
|
362
|
+
disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
|
|
363
|
+
)
|
|
364
|
+
def rule_EC0233E(
|
|
365
|
+
pluginData: ControllerPluginData,
|
|
366
|
+
cntlr: Cntlr,
|
|
367
|
+
fileSource: FileSource,
|
|
368
|
+
*args: Any,
|
|
369
|
+
**kwargs: Any,
|
|
370
|
+
) -> Iterable[Validation]:
|
|
371
|
+
"""
|
|
372
|
+
EDINET.EC0233E: There is a file in the report directory that comes before the cover file
|
|
373
|
+
in file name sort order.
|
|
374
|
+
|
|
375
|
+
NOTE: This includes files in subdirectories. For example, PublicDoc/00000000_images/image.png
|
|
376
|
+
comes before PublicDoc/0000000_header_*.htm
|
|
377
|
+
"""
|
|
378
|
+
uploadContents = pluginData.getUploadContents(fileSource)
|
|
379
|
+
directories = defaultdict(list)
|
|
380
|
+
for path in uploadContents.sortedPaths:
|
|
381
|
+
pathInfo = uploadContents.uploadPaths[path]
|
|
382
|
+
if pathInfo.isDirectory:
|
|
383
|
+
continue
|
|
384
|
+
if pathInfo.reportFolderType in (ReportFolderType.PRIVATE_DOC, ReportFolderType.PUBLIC_DOC):
|
|
385
|
+
directories[pathInfo.reportPath].append(pathInfo)
|
|
386
|
+
for reportPath, pathInfos in directories.items():
|
|
387
|
+
coverPagePath = next(iter(p for p in pathInfos if p.isCoverPage), None)
|
|
388
|
+
if coverPagePath is None:
|
|
389
|
+
continue
|
|
390
|
+
errorPathInfos = pathInfos[:pathInfos.index(coverPagePath)]
|
|
391
|
+
for pathInfo in errorPathInfos:
|
|
392
|
+
yield Validation.error(
|
|
393
|
+
codes='EDINET.EC0233E',
|
|
394
|
+
msg=_("There is a file in the report directory in '%(reportPath)s' that comes before the cover "
|
|
395
|
+
"file ('%(coverPage)s') in file name sort order. "
|
|
396
|
+
"Directory name or file name: '%(path)s'. "
|
|
397
|
+
"Please make sure that there are no files that come before the cover file in the file "
|
|
398
|
+
"name sort order, and then upload again."),
|
|
399
|
+
reportPath=str(reportPath),
|
|
400
|
+
coverPage=str(coverPagePath.path.name),
|
|
401
|
+
path=str(pathInfo.path),
|
|
402
|
+
)
|
|
403
|
+
|
|
404
|
+
|
|
405
|
+
@validation(
|
|
406
|
+
hook=ValidationHook.FILESOURCE,
|
|
407
|
+
disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
|
|
408
|
+
)
|
|
409
|
+
def rule_EC0234E(
|
|
410
|
+
pluginData: ControllerPluginData,
|
|
411
|
+
cntlr: Cntlr,
|
|
412
|
+
fileSource: FileSource,
|
|
413
|
+
*args: Any,
|
|
414
|
+
**kwargs: Any,
|
|
415
|
+
) -> Iterable[Validation]:
|
|
416
|
+
"""
|
|
417
|
+
EDINET.EC0234E: A cover file exists in an unsupported subdirectory.
|
|
418
|
+
"""
|
|
419
|
+
uploadContents = pluginData.getUploadContents(fileSource)
|
|
420
|
+
for path, pathInfo in uploadContents.uploadPaths.items():
|
|
421
|
+
if pathInfo.isDirectory:
|
|
422
|
+
continue
|
|
423
|
+
if pathInfo.reportFolderType not in (ReportFolderType.PRIVATE_DOC, ReportFolderType.PUBLIC_DOC):
|
|
424
|
+
continue
|
|
425
|
+
if pathInfo.isSubdirectory and pathInfo.isCoverPage:
|
|
426
|
+
yield Validation.error(
|
|
427
|
+
codes='EDINET.EC0234E',
|
|
428
|
+
msg=_("A cover file ('%(coverPage)s') exists in an unsupported subdirectory. "
|
|
429
|
+
"Directory: '%(directory)s'. "
|
|
430
|
+
"Please make sure there is no cover file in the subfolder and upload again."),
|
|
431
|
+
coverPage=str(path.name),
|
|
432
|
+
directory=str(path.parent),
|
|
433
|
+
)
|
|
434
|
+
|
|
435
|
+
|
|
318
436
|
@validation(
|
|
319
437
|
hook=ValidationHook.FILESOURCE,
|
|
320
438
|
disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
|
|
@@ -444,6 +562,61 @@ def rule_EC1020E(
|
|
|
444
562
|
)
|
|
445
563
|
|
|
446
564
|
|
|
565
|
+
@validation(
|
|
566
|
+
hook=ValidationHook.FILESOURCE,
|
|
567
|
+
disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
|
|
568
|
+
)
|
|
569
|
+
def rule_filenames(
|
|
570
|
+
pluginData: ControllerPluginData,
|
|
571
|
+
cntlr: Cntlr,
|
|
572
|
+
fileSource: FileSource,
|
|
573
|
+
*args: Any,
|
|
574
|
+
**kwargs: Any,
|
|
575
|
+
) -> Iterable[Validation]:
|
|
576
|
+
"""
|
|
577
|
+
EDINET.EC0121E: There is a directory or file that contains
|
|
578
|
+
more than 31 characters or uses characters other than those allowed (alphanumeric characters,
|
|
579
|
+
'-' and '_').
|
|
580
|
+
Note: Applies to everything EXCEPT files directly beneath non-correction report folders.
|
|
581
|
+
|
|
582
|
+
EDINET.EC0200E: There is a file that uses characters other
|
|
583
|
+
than those allowed (alphanumeric characters, '-' and '_').
|
|
584
|
+
Note: Applies ONLY to files directly beneath non-correction report folders.
|
|
585
|
+
"""
|
|
586
|
+
for path, pathInfo in pluginData.getUploadContents(fileSource).uploadPaths.items():
|
|
587
|
+
isReportFile = (
|
|
588
|
+
not pathInfo.isAttachment and
|
|
589
|
+
not pathInfo.isCorrection and
|
|
590
|
+
not pathInfo.isDirectory and
|
|
591
|
+
not pathInfo.isSubdirectory
|
|
592
|
+
)
|
|
593
|
+
charactersAreValid = FILENAME_STEM_PATTERN.fullmatch(path.stem)
|
|
594
|
+
lengthIsValid = isReportFile or (len(path.name) <= 31)
|
|
595
|
+
if charactersAreValid and lengthIsValid:
|
|
596
|
+
continue
|
|
597
|
+
if isReportFile:
|
|
598
|
+
yield Validation.error(
|
|
599
|
+
codes='EDINET.EC0200E',
|
|
600
|
+
msg=_("There is a file inside the XBRL directory that uses characters "
|
|
601
|
+
"other than those allowed (alphanumeric characters, '-' and '_'). "
|
|
602
|
+
"File: '%(path)s'. "
|
|
603
|
+
"Please change the filename to usable characters, and upload again."),
|
|
604
|
+
path=str(path)
|
|
605
|
+
)
|
|
606
|
+
else:
|
|
607
|
+
yield Validation.error(
|
|
608
|
+
codes='EDINET.EC0121E',
|
|
609
|
+
msg=_("There is a directory or file in '%(directory)s' that contains more "
|
|
610
|
+
"than 31 characters or uses characters other than those allowed "
|
|
611
|
+
"(alphanumeric characters, '-' and '_'). "
|
|
612
|
+
"Directory or filename: '%(basename)s'. "
|
|
613
|
+
"Please change the file name (or folder name) to within 31 characters and to usable "
|
|
614
|
+
"characters, and upload again."),
|
|
615
|
+
directory=str(path.parent),
|
|
616
|
+
basename=path.name,
|
|
617
|
+
)
|
|
618
|
+
|
|
619
|
+
|
|
447
620
|
@validation(
|
|
448
621
|
hook=ValidationHook.FILESOURCE,
|
|
449
622
|
disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
|
|
@@ -125,7 +125,7 @@ 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=
|
|
128
|
+
arelle/_version.py,sha256=5ledvoDL_7HieaAt4kjZqd9TGIaAC8kJJgJuFA-vUT4,708
|
|
129
129
|
arelle/typing.py,sha256=PRe-Fxwr2SBqYYUVPCJ3E7ddDX0_oOISNdT5Q97EbRM,1246
|
|
130
130
|
arelle/api/Session.py,sha256=kgSxS7VckA1sQ7xp0pJiK7IK-vRxAdAZKUo8gEx27s8,7549
|
|
131
131
|
arelle/config/creationSoftwareNames.json,sha256=5MK7XUjfDJ9OpRCCHXeOErJ1SlTBZji4WEcEOdOacx0,3128
|
|
@@ -312,14 +312,14 @@ 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=
|
|
316
|
-
arelle/plugin/validate/EDINET/ControllerPluginData.py,sha256=
|
|
315
|
+
arelle/plugin/validate/EDINET/Constants.py,sha256=H_OX8hq7nns6TbKPpmDlg1_pNOd7P-XMFF03MMZBAuk,1387
|
|
316
|
+
arelle/plugin/validate/EDINET/ControllerPluginData.py,sha256=T4m8GFiVg9tNoLcC3HxeegNnKVqAqZdc6kNdxM5Vz1Y,7005
|
|
317
317
|
arelle/plugin/validate/EDINET/DisclosureSystems.py,sha256=3rKG42Eg-17Xx_KXU_V5yHW6I3LTwQunvf4a44C9k_4,36
|
|
318
|
-
arelle/plugin/validate/EDINET/InstanceType.py,sha256=aLKb4-AJ6nDZKMOLCp7u08E9VD64ExeZy9_oGth-LTk,3207
|
|
319
318
|
arelle/plugin/validate/EDINET/ManifestInstance.py,sha256=SkQV-aOsYn3CTgCkH4IXNdM3QKoiz8okwb29ftMtV3Q,6882
|
|
320
|
-
arelle/plugin/validate/EDINET/PluginValidationDataExtension.py,sha256=
|
|
319
|
+
arelle/plugin/validate/EDINET/PluginValidationDataExtension.py,sha256=4xGDhwLo_JOJSu16w_CkPCca1SYMu980bb2-r6sbI5s,12459
|
|
320
|
+
arelle/plugin/validate/EDINET/ReportFolderType.py,sha256=Q-9a-5tJfhK-cjY8WUB2AT1NI-Nn9cFtARVOIJoLRGU,2979
|
|
321
321
|
arelle/plugin/validate/EDINET/Statement.py,sha256=0Mw5IB7LMtvUZ-2xKZfxmq67xF_dCgJo3eNLweLFRHU,9350
|
|
322
|
-
arelle/plugin/validate/EDINET/UploadContents.py,sha256=
|
|
322
|
+
arelle/plugin/validate/EDINET/UploadContents.py,sha256=IKQYl6lXYTfAZKLIDzRRGSRt3FXoL2Eldbx3Dh7T2I4,712
|
|
323
323
|
arelle/plugin/validate/EDINET/ValidationPluginExtension.py,sha256=oMY0ntLr1qIh3uMi1W_M-bT5bhXPDx048X3oDFP5zOY,2042
|
|
324
324
|
arelle/plugin/validate/EDINET/__init__.py,sha256=OZ7gMknCHd0M-9nt8UOmjEZW50YQzbvSLongr9O7Yi0,3022
|
|
325
325
|
arelle/plugin/validate/EDINET/resources/config.xml,sha256=7uT4GcRgk5veMLpFhPPQJxbGKiQvM52P8EMrjn0qd0g,646
|
|
@@ -328,9 +328,9 @@ arelle/plugin/validate/EDINET/rules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQ
|
|
|
328
328
|
arelle/plugin/validate/EDINET/rules/contexts.py,sha256=KPoyWfRaURvxoGVcWP64mTMTAKPMSmQSX06RClCLddw,7590
|
|
329
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=
|
|
331
|
+
arelle/plugin/validate/EDINET/rules/gfm.py,sha256=vJz8OGbXQb1Lbp5tF6ObCifM3AuPB_PXTjSPU5WXYF4,23484
|
|
332
332
|
arelle/plugin/validate/EDINET/rules/manifests.py,sha256=MoT9R_a4BzuYdQVbF7RC5wz134Ve68svSdJ3NlpO_AU,4026
|
|
333
|
-
arelle/plugin/validate/EDINET/rules/upload.py,sha256=
|
|
333
|
+
arelle/plugin/validate/EDINET/rules/upload.py,sha256=VQKjuDxMAER14Cb0kymoc-xdnAqJ9l1ZaqlQNIEG8gU,26606
|
|
334
334
|
arelle/plugin/validate/ESEF/Const.py,sha256=JujF_XV-_TNsxjGbF-8SQS4OOZIcJ8zhCMnr-C1O5Ho,22660
|
|
335
335
|
arelle/plugin/validate/ESEF/Dimensions.py,sha256=MOJM7vwNPEmV5cu-ZzPrhx3347ZvxgD6643OB2HRnIk,10597
|
|
336
336
|
arelle/plugin/validate/ESEF/Util.py,sha256=QH3btcGqBpr42M7WSKZLSdNXygZaZLfEiEjlxoG21jE,7950
|
|
@@ -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.
|
|
684
|
-
arelle_release-2.37.
|
|
685
|
-
arelle_release-2.37.
|
|
686
|
-
arelle_release-2.37.
|
|
687
|
-
arelle_release-2.37.
|
|
688
|
-
arelle_release-2.37.
|
|
683
|
+
arelle_release-2.37.51.dist-info/licenses/LICENSE.md,sha256=Q0tn6q0VUbr-NM8916513NCIG8MNzo24Ev-sxMUBRZc,3959
|
|
684
|
+
arelle_release-2.37.51.dist-info/METADATA,sha256=BZlHz_pXjybuHYVwQ-qzY5TmwxoyNVIRhJTjBez0H6w,9327
|
|
685
|
+
arelle_release-2.37.51.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
686
|
+
arelle_release-2.37.51.dist-info/entry_points.txt,sha256=Uj5niwfwVsx3vaQ3fYj8hrZ1xpfCJyTUA09tYKWbzpo,111
|
|
687
|
+
arelle_release-2.37.51.dist-info/top_level.txt,sha256=fwU7SYawL4_r-sUMRg7r1nYVGjFMSDvRWx8VGAXEw7w,7
|
|
688
|
+
arelle_release-2.37.51.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|