arelle-release 2.17.1__py3-none-any.whl → 2.37.71__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.
- arelle/Aspect.py +6 -3
- arelle/BetaFeatures.py +3 -0
- arelle/Cntlr.py +117 -413
- arelle/CntlrCmdLine.py +364 -227
- arelle/CntlrQuickBooks.py +4 -2
- arelle/CntlrWebMain.py +179 -119
- arelle/CntlrWinMain.py +342 -124
- arelle/DialogAbout.py +1 -1
- arelle/DialogArcroleGroup.py +1 -1
- arelle/DialogFind.py +1 -1
- arelle/DialogFormulaParameters.py +2 -2
- arelle/DialogLanguage.py +45 -36
- arelle/DialogNewFactItem.py +1 -1
- arelle/DialogOpenArchive.py +30 -34
- arelle/DialogPackageManager.py +11 -8
- arelle/DialogPluginManager.py +43 -89
- arelle/DialogRssWatch.py +2 -2
- arelle/DialogURL.py +1 -1
- arelle/DialogUserPassword.py +1 -1
- arelle/DisclosureSystem.py +69 -1
- arelle/ErrorManager.py +321 -0
- arelle/FileSource.py +201 -99
- arelle/FunctionFn.py +44 -5
- arelle/FunctionIxt.py +16 -13
- arelle/FunctionUtil.py +1 -1
- arelle/FunctionXfi.py +68 -24
- arelle/FunctionXs.py +1 -1
- arelle/HtmlUtil.py +5 -4
- arelle/LeiUtil.py +63 -43
- arelle/LinkbaseType.py +94 -0
- arelle/LocalViewer.py +8 -2
- arelle/Locale.py +239 -79
- arelle/ModelDocument.py +180 -48
- arelle/ModelDtsObject.py +32 -27
- arelle/ModelFormulaObject.py +14 -6
- arelle/ModelInstanceObject.py +43 -14
- arelle/ModelManager.py +6 -1
- arelle/ModelObject.py +12 -8
- arelle/ModelObjectFactory.py +18 -2
- arelle/ModelRelationshipSet.py +46 -3
- arelle/ModelRenderingObject.py +899 -951
- arelle/ModelRssItem.py +2 -4
- arelle/ModelTestcaseObject.py +41 -4
- arelle/ModelValue.py +42 -14
- arelle/ModelVersReport.py +1 -1
- arelle/ModelXbrl.py +133 -273
- arelle/PackageManager.py +202 -176
- arelle/PluginManager.py +551 -239
- arelle/PluginUtils.py +54 -0
- arelle/PrototypeInstanceObject.py +53 -12
- arelle/PythonUtil.py +166 -25
- arelle/RuntimeOptions.py +32 -18
- arelle/SocketUtils.py +3 -0
- arelle/SystemInfo.py +1 -1
- arelle/TkTableWrapper.py +33 -5
- arelle/UITkTable.py +27 -21
- arelle/Updater.py +7 -3
- arelle/UrlUtil.py +6 -2
- arelle/Validate.py +596 -402
- arelle/ValidateDuplicateFacts.py +584 -0
- arelle/ValidateFileSource.py +38 -0
- arelle/ValidateFilingText.py +46 -29
- arelle/ValidateInfoset.py +104 -32
- arelle/ValidateUtr.py +31 -4
- arelle/ValidateXbrl.py +144 -120
- arelle/ValidateXbrlCalcs.py +51 -66
- arelle/ValidateXbrlDTS.py +98 -29
- arelle/Version.py +2 -7
- arelle/ViewFile.py +2 -0
- arelle/ViewFileDTS.py +7 -2
- arelle/ViewFileFactList.py +1 -1
- arelle/ViewFileFactTable.py +4 -4
- arelle/ViewFileRelationshipSet.py +36 -19
- arelle/ViewFileRenderedGrid.py +164 -753
- arelle/ViewFileRenderedLayout.py +174 -0
- arelle/ViewFileRenderedStructure.py +108 -0
- arelle/ViewWinDTS.py +4 -1
- arelle/ViewWinFactList.py +1 -1
- arelle/ViewWinFactTable.py +1 -1
- arelle/ViewWinRelationshipSet.py +14 -8
- arelle/ViewWinRenderedGrid.py +397 -287
- arelle/ViewWinRssFeed.py +4 -0
- arelle/ViewWinTree.py +15 -9
- arelle/ViewWinXml.py +1 -1
- arelle/WebCache.py +510 -272
- arelle/XbrlConst.py +202 -196
- arelle/XbrlUtil.py +2 -1
- arelle/XhtmlValidate.py +9 -23
- arelle/XmlUtil.py +24 -19
- arelle/XmlValidate.py +95 -67
- arelle/XmlValidateParticles.py +4 -4
- arelle/_version.py +33 -3
- arelle/api/Session.py +183 -0
- arelle/config/creationSoftwareNames.json +24 -10
- arelle/config/disclosuresystems.xml +1 -1
- arelle/config/disclosuresystems.xsd +3 -0
- arelle/config/sbr-text-formatting.xsd +737 -0
- arelle/conformance/CSVTestcaseLoader.py +102 -0
- arelle/formula/FactAspectsCache.py +10 -4
- arelle/formula/ValidateFormula.py +82 -194
- arelle/formula/XPathContext.py +42 -28
- arelle/formula/XPathParser.py +15 -9
- arelle/locale/ar_EG/LC_MESSAGES/ar_EG.po +3 -4
- arelle/locale/messages.pot +1 -2
- arelle/locale/ru/LC_MESSAGES/ru.po +2 -2
- arelle/logging/formatters/LogFormatter.py +47 -0
- arelle/logging/handlers/LogHandlerWithXml.py +94 -0
- arelle/logging/handlers/LogToBufferHandler.py +20 -0
- arelle/logging/handlers/LogToPrintHandler.py +41 -0
- arelle/logging/handlers/LogToXmlHandler.py +244 -0
- arelle/logging/handlers/StructuredMessageLogHandler.py +74 -0
- arelle/model/CommentBase.py +3 -0
- arelle/model/ElementBase.py +3 -0
- arelle/model/PIBase.py +3 -0
- arelle/model/__init__.py +3 -0
- arelle/oim/Load.py +2869 -0
- arelle/oim/Validate.py +155 -0
- arelle/oim/xml/Save.py +21 -0
- arelle/packages/PackageConst.py +7 -0
- arelle/packages/PackageType.py +13 -0
- arelle/packages/PackageUtils.py +22 -0
- arelle/packages/PackageValidation.py +200 -0
- arelle/packages/report/DetectReportPackage.py +13 -0
- arelle/packages/report/ReportPackage.py +265 -0
- arelle/packages/report/ReportPackageConst.py +79 -0
- arelle/packages/report/ReportPackageValidator.py +207 -0
- arelle/plugin/EdgarRendererAllReports.py +12 -12
- arelle/plugin/OimTaxonomy/ModelValueMore.py +15 -0
- arelle/plugin/OimTaxonomy/ValidateDTS.py +484 -0
- arelle/plugin/OimTaxonomy/ViewXbrlTxmyObj.py +239 -0
- arelle/plugin/OimTaxonomy/XbrlAbstract.py +16 -0
- arelle/plugin/OimTaxonomy/XbrlConcept.py +68 -0
- arelle/plugin/OimTaxonomy/XbrlConst.py +261 -0
- arelle/plugin/OimTaxonomy/XbrlCube.py +91 -0
- arelle/plugin/OimTaxonomy/XbrlDimension.py +38 -0
- arelle/plugin/OimTaxonomy/XbrlDts.py +152 -0
- arelle/plugin/OimTaxonomy/XbrlEntity.py +16 -0
- arelle/plugin/OimTaxonomy/XbrlGroup.py +22 -0
- arelle/plugin/OimTaxonomy/XbrlImportedTaxonomy.py +22 -0
- arelle/plugin/OimTaxonomy/XbrlLabel.py +31 -0
- arelle/plugin/OimTaxonomy/XbrlNetwork.py +100 -0
- arelle/plugin/OimTaxonomy/XbrlProperty.py +28 -0
- arelle/plugin/OimTaxonomy/XbrlReference.py +33 -0
- arelle/plugin/OimTaxonomy/XbrlReport.py +24 -0
- arelle/plugin/OimTaxonomy/XbrlTableTemplate.py +35 -0
- arelle/plugin/OimTaxonomy/XbrlTaxonomy.py +93 -0
- arelle/plugin/OimTaxonomy/XbrlTaxonomyObject.py +154 -0
- arelle/plugin/OimTaxonomy/XbrlTransform.py +17 -0
- arelle/plugin/OimTaxonomy/XbrlTypes.py +23 -0
- arelle/plugin/OimTaxonomy/XbrlUnit.py +17 -0
- arelle/plugin/OimTaxonomy/__init__.py +1037 -0
- arelle/plugin/OimTaxonomy/resources/iso4217.json +4479 -0
- arelle/plugin/OimTaxonomy/resources/oim-taxonomy-schema.json +935 -0
- arelle/plugin/OimTaxonomy/resources/ref.json +333 -0
- arelle/plugin/OimTaxonomy/resources/transform-types.json +2481 -0
- arelle/plugin/OimTaxonomy/resources/types.json +727 -0
- arelle/plugin/OimTaxonomy/resources/utr.json +3046 -0
- arelle/plugin/OimTaxonomy/resources/xbrlSpec.json +1082 -0
- arelle/plugin/formulaLoader.py +3 -3
- arelle/plugin/formulaSaver.py +4 -4
- arelle/plugin/inlineXbrlDocumentSet.py +331 -102
- arelle/plugin/internet/proxyNTLM/HTTPNtlmAuthHandler.py +1 -1
- arelle/plugin/loadFromExcel.py +13 -10
- arelle/plugin/loadFromOIM.py +16 -3096
- arelle/plugin/logging/saveMessages.py +1 -1
- arelle/plugin/saveHtmlEBAtables.py +293 -213
- arelle/plugin/saveLoadableOIM.py +652 -361
- arelle/plugin/saveOIMTaxonomy.py +311 -0
- arelle/plugin/streamingExtensions.py +1 -1
- arelle/plugin/systemInfo.py +46 -0
- arelle/plugin/transforms/tester.py +4 -4
- arelle/plugin/validate/CIPC/Const.py +18 -0
- arelle/plugin/validate/CIPC/__init__.py +34 -13
- arelle/plugin/validate/DBA/DisclosureSystems.py +12 -0
- arelle/plugin/validate/DBA/PluginValidationDataExtension.py +165 -0
- arelle/plugin/validate/DBA/ValidationPluginExtension.py +545 -0
- arelle/plugin/validate/DBA/__init__.py +49 -0
- arelle/plugin/validate/DBA/resources/config.xml +21 -0
- arelle/plugin/validate/DBA/rules/__init__.py +323 -0
- arelle/plugin/validate/DBA/rules/fr.py +1377 -0
- arelle/plugin/validate/DBA/rules/tc.py +45 -0
- arelle/plugin/validate/DBA/rules/th.py +172 -0
- arelle/plugin/validate/DBA/rules/tm.py +351 -0
- arelle/plugin/validate/DBA/rules/tr.py +373 -0
- arelle/plugin/validate/EBA/__init__.py +11 -12
- arelle/plugin/validate/EDINET/Constants.py +208 -0
- arelle/plugin/validate/EDINET/ContextRequirement.py +58 -0
- arelle/plugin/validate/EDINET/ControllerPluginData.py +298 -0
- arelle/plugin/validate/EDINET/CoverItemRequirements.py +42 -0
- arelle/plugin/validate/EDINET/DeiRequirements.py +118 -0
- arelle/plugin/validate/EDINET/DisclosureSystems.py +1 -0
- arelle/plugin/validate/EDINET/FilingFormat.py +275 -0
- arelle/plugin/validate/EDINET/FormType.py +134 -0
- arelle/plugin/validate/EDINET/ManifestInstance.py +236 -0
- arelle/plugin/validate/EDINET/PluginValidationDataExtension.py +640 -0
- arelle/plugin/validate/EDINET/ReportFolderType.py +162 -0
- arelle/plugin/validate/EDINET/Statement.py +139 -0
- arelle/plugin/validate/EDINET/TableOfContentsBuilder.py +493 -0
- arelle/plugin/validate/EDINET/UploadContents.py +48 -0
- arelle/plugin/validate/EDINET/ValidationPluginExtension.py +64 -0
- arelle/plugin/validate/EDINET/__init__.py +109 -0
- arelle/plugin/validate/EDINET/resources/config.xml +22 -0
- arelle/plugin/validate/EDINET/resources/cover-item-requirements.json +793 -0
- arelle/plugin/validate/EDINET/resources/dei-requirements.csv +27 -0
- arelle/plugin/validate/EDINET/resources/edinet-taxonomies.xml +62 -0
- arelle/plugin/validate/EDINET/rules/contexts.py +547 -0
- arelle/plugin/validate/EDINET/rules/edinet.py +1991 -0
- arelle/plugin/validate/EDINET/rules/frta.py +301 -0
- arelle/plugin/validate/EDINET/rules/gfm.py +2394 -0
- arelle/plugin/validate/EDINET/rules/manifests.py +88 -0
- arelle/plugin/validate/EDINET/rules/upload.py +1370 -0
- arelle/plugin/validate/ESEF/Const.py +16 -75
- arelle/plugin/validate/ESEF/Dimensions.py +2 -2
- arelle/plugin/validate/ESEF/ESEF_2021/DTS.py +6 -1
- arelle/plugin/validate/ESEF/ESEF_2021/Image.py +7 -4
- arelle/plugin/validate/ESEF/ESEF_2021/ValidateXbrlFinally.py +80 -57
- arelle/plugin/validate/ESEF/ESEF_Current/DTS.py +60 -22
- arelle/plugin/validate/ESEF/ESEF_Current/ValidateXbrlFinally.py +272 -133
- arelle/plugin/validate/ESEF/Util.py +5 -19
- arelle/plugin/validate/ESEF/__init__.py +61 -46
- arelle/plugin/validate/ESEF/resources/authority-validations.json +120 -10
- arelle/plugin/validate/ESEF/resources/config.xml +44 -3
- arelle/plugin/validate/FERC/__init__.py +31 -18
- arelle/plugin/validate/FERC/config.xml +18 -18
- arelle/plugin/validate/NL/DisclosureSystems.py +19 -3
- arelle/plugin/validate/NL/PluginValidationDataExtension.py +710 -7
- arelle/plugin/validate/NL/ValidationPluginExtension.py +117 -12
- arelle/plugin/validate/NL/__init__.py +21 -10
- arelle/plugin/validate/NL/resources/config.xml +27 -6
- arelle/plugin/validate/NL/rules/br_kvk.py +81 -21
- arelle/plugin/validate/NL/rules/fg_nl.py +292 -0
- arelle/plugin/validate/NL/rules/fr_kvk.py +60 -7
- arelle/plugin/validate/NL/rules/fr_nl.py +705 -24
- arelle/plugin/validate/NL/rules/nl_kvk.py +2182 -0
- arelle/plugin/validate/ROS/DisclosureSystems.py +1 -0
- arelle/plugin/validate/ROS/PluginValidationDataExtension.py +109 -0
- arelle/plugin/validate/ROS/ValidationPluginExtension.py +27 -0
- arelle/plugin/validate/ROS/__init__.py +28 -341
- arelle/plugin/validate/ROS/resources/config.xml +20 -0
- arelle/plugin/validate/ROS/rules/__init__.py +56 -0
- arelle/plugin/validate/ROS/rules/ros.py +393 -0
- arelle/plugin/validate/UK/ValidateUK.py +1372 -0
- arelle/plugin/validate/{HMRC → UK}/__init__.py +195 -189
- arelle/plugin/validate/{HMRC → UK}/config.xml +1 -1
- arelle/plugin/xbrlDB/SqlDb.py +1 -1
- arelle/plugin/xbrlDB/XbrlOpenSqlDB.py +5 -5
- arelle/plugin/xbrlDB/XbrlPublicPostgresDB.py +1 -1
- arelle/plugin/xbrlDB/XbrlSemanticJsonDB.py +1 -1
- arelle/plugin/xbrlDB/XbrlSemanticRdfDB.py +1 -1
- arelle/plugin/xbrlDB/__init__.py +4 -1
- arelle/{RenderingEvaluator.py → rendering/RenderingEvaluator.py} +120 -99
- arelle/rendering/RenderingLayout.py +476 -0
- arelle/rendering/RenderingResolution.py +814 -0
- arelle/resources/cache/http/www.eurofiling.info/eu/fr/xbrl/ext/filing-indicators.xsd +20 -0
- arelle/resources/cache/http/www.w3.org/2001/03/xml.xsd +117 -0
- arelle/resources/cache/http/www.w3.org/2001/XMLSchema.xsd +2534 -0
- arelle/resources/cache/http/www.w3.org/2001/xml.xsd +287 -0
- arelle/resources/cache/http/www.xbrl.org/2003/xbrl-instance-2003-12-31.xsd +779 -0
- arelle/resources/cache/http/www.xbrl.org/2003/xbrl-linkbase-2003-12-31.xsd +486 -0
- arelle/resources/cache/http/www.xbrl.org/2003/xl-2003-12-31.xsd +251 -0
- arelle/resources/cache/http/www.xbrl.org/2003/xlink-2003-12-31.xsd +121 -0
- arelle/resources/cache/http/www.xbrl.org/2004/ref-2004-08-10.xsd +129 -0
- arelle/resources/cache/http/www.xbrl.org/2005/xbrldt-2005.xsd +53 -0
- arelle/resources/cache/http/www.xbrl.org/2006/ref-2006-02-27.xsd +120 -0
- arelle/resources/cache/http/www.xbrl.org/2006/xbrldi-2006.xsd +41 -0
- arelle/resources/cache/http/www.xbrl.org/2008/boolean-filter.xsd +51 -0
- arelle/resources/cache/http/www.xbrl.org/2008/concept-filter.xsd +127 -0
- arelle/resources/cache/http/www.xbrl.org/2008/conformance.xsd +116 -0
- arelle/resources/cache/http/www.xbrl.org/2008/conformanceFunction.xsd +51 -0
- arelle/resources/cache/http/www.xbrl.org/2008/consistency-assertion.xsd +66 -0
- arelle/resources/cache/http/www.xbrl.org/2008/dimension-filter.xsd +86 -0
- arelle/resources/cache/http/www.xbrl.org/2008/entity-filter.xsd +92 -0
- arelle/resources/cache/http/www.xbrl.org/2008/existence-assertion.xsd +44 -0
- arelle/resources/cache/http/www.xbrl.org/2008/formula.xsd +261 -0
- arelle/resources/cache/http/www.xbrl.org/2008/function.xsd +90 -0
- arelle/resources/cache/http/www.xbrl.org/2008/general-filter.xsd +38 -0
- arelle/resources/cache/http/www.xbrl.org/2008/generic-label.xsd +80 -0
- arelle/resources/cache/http/www.xbrl.org/2008/generic-link.xsd +81 -0
- arelle/resources/cache/http/www.xbrl.org/2008/generic-reference.xsd +63 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xbrl/xbrl-instance-2003-12-31-ixmod.xsd +788 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xbrl/xbrl-linkbase-2003-12-31-ixmod.xsd +488 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xbrl/xl-2003-12-31.xsd +248 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xbrl/xlink-2003-12-31.xsd +117 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xframes-1.xsd +166 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-applet-1.xsd +66 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-attribs-1.xsd +72 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-base-1.xsd +36 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-basic-form-1.xsd +195 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-basic-table-1.xsd +169 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-basic10-model-1.xsd +376 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-basic10-module-redefines-1.xsd +61 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-basic10-modules-1.xsd +259 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-basic10.xsd +98 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-bdo-1.xsd +78 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-blkphras-1.xsd +161 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-blkpres-1.xsd +37 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-blkstruct-1.xsd +49 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-charent-1.xsd +38 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-copyright-1.xsd +29 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-csismap-1.xsd +96 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-datatypes-1.xsd +128 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-edit-1.xsd +39 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-events-1.xsd +130 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-form-1.xsd +326 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-frames-1.xsd +113 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-framework-1.xsd +66 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-hypertext-1.xsd +47 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-iframe-1.xsd +68 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-image-1.xsd +45 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-inlphras-1.xsd +163 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-inlpres-1.xsd +39 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-inlstruct-1.xsd +50 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-inlstyle-1.xsd +27 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-legacy-1.xsd +97 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-link-1.xsd +45 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-list-1.xsd +99 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-meta-1.xsd +42 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-misc-1.xsd +441 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-nameident-1.xsd +63 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-notations-1.xsd +69 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-object-1.xsd +76 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-param-1.xsd +51 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-pres-1.xsd +51 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-ruby-1.xsd +171 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-ruby-basic-1.xsd +89 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-script-1.xsd +70 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-ssismap-1.xsd +43 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-struct-1.xsd +112 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-style-1.xsd +52 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-table-1.xsd +272 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-target-1.xsd +53 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-text-1.xsd +67 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml11-model-1.xsd +677 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml11-module-redefines-1.xsd +335 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml11-modules-1.xsd +528 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml11.xsd +104 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml2.xsd +21 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xml-events-1.xsd +73 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xml-events-2.xsd +74 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xml-events-attribs-1.xsd +73 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xml-events-attribs-2.xsd +75 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xml-events-copyright-1.xsd +34 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xml-events-copyright-2.xsd +34 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xml-handlers-2.xsd +98 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml-inlinexbrl-1_0-definitions.xsd +225 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml-inlinexbrl-1_0-model.xsd +681 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml-inlinexbrl-1_0-modules.xsd +535 -0
- arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml-inlinexbrl-1_0.xsd +40 -0
- arelle/resources/cache/http/www.xbrl.org/2008/match-filter.xsd +94 -0
- arelle/resources/cache/http/www.xbrl.org/2008/period-filter.xsd +86 -0
- arelle/resources/cache/http/www.xbrl.org/2008/registry.xsd +145 -0
- arelle/resources/cache/http/www.xbrl.org/2008/relative-filter.xsd +38 -0
- arelle/resources/cache/http/www.xbrl.org/2008/segment-scenario-filter.xsd +41 -0
- arelle/resources/cache/http/www.xbrl.org/2008/tuple-filter.xsd +83 -0
- arelle/resources/cache/http/www.xbrl.org/2008/unit-filter.xsd +58 -0
- arelle/resources/cache/http/www.xbrl.org/2008/validation.xsd +78 -0
- arelle/resources/cache/http/www.xbrl.org/2008/value-assertion.xsd +43 -0
- arelle/resources/cache/http/www.xbrl.org/2008/value-filter.xsd +43 -0
- arelle/resources/cache/http/www.xbrl.org/2008/variable.xsd +240 -0
- arelle/resources/cache/http/www.xbrl.org/2010/aspect-cover-filter.xsd +67 -0
- arelle/resources/cache/http/www.xbrl.org/2010/concept-relation-filter.xsd +108 -0
- arelle/resources/cache/http/www.xbrl.org/2010/custom-function-implementation.xsd +71 -0
- arelle/resources/cache/http/www.xbrl.org/2010/generic-message.xsd +68 -0
- arelle/resources/cache/http/www.xbrl.org/2010/validation-message.xsd +50 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xbrl/xbrl-instance-2003-12-31-ixmod.xsd +788 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xbrl/xbrl-linkbase-2003-12-31-ixmod.xsd +488 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xbrl/xl-2003-12-31.xsd +248 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xbrl/xlink-2003-12-31.xsd +117 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xframes-1.xsd +166 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-applet-1.xsd +66 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-attribs-1.xsd +72 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-base-1.xsd +36 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-basic-form-1.xsd +195 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-basic-table-1.xsd +169 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-basic10-model-1.xsd +376 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-basic10-module-redefines-1.xsd +61 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-basic10-modules-1.xsd +259 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-basic10.xsd +98 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-bdo-1.xsd +78 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-blkphras-1.xsd +161 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-blkpres-1.xsd +37 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-blkstruct-1.xsd +49 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-charent-1.xsd +38 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-copyright-1.xsd +29 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-csismap-1.xsd +96 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-datatypes-1.xsd +128 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-edit-1.xsd +39 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-events-1.xsd +130 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-form-1.xsd +326 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-frames-1.xsd +113 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-framework-1.xsd +66 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-hypertext-1.xsd +47 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-iframe-1.xsd +68 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-image-1.xsd +45 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-inlphras-1.xsd +163 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-inlpres-1.xsd +39 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-inlstruct-1.xsd +50 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-inlstyle-1.xsd +27 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-legacy-1.xsd +97 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-link-1.xsd +45 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-list-1.xsd +99 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-meta-1.xsd +42 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-misc-1.xsd +441 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-nameident-1.xsd +63 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-notations-1.xsd +69 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-object-1.xsd +76 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-param-1.xsd +51 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-pres-1.xsd +51 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-ruby-1.xsd +171 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-ruby-basic-1.xsd +89 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-script-1.xsd +70 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-ssismap-1.xsd +43 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-struct-1.xsd +112 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-style-1.xsd +52 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-table-1.xsd +272 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-target-1.xsd +53 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-text-1.xsd +67 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml11-model-1.xsd +677 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml11-module-redefines-1.xsd +335 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml11-modules-1.xsd +528 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml11.xsd +104 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml2.xsd +21 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xml-events-1.xsd +73 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xml-events-2.xsd +74 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xml-events-attribs-1.xsd +73 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xml-events-attribs-2.xsd +75 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xml-events-copyright-1.xsd +34 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xml-events-copyright-2.xsd +34 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xml-handlers-2.xsd +98 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml-inlinexbrl-1_1-definitions.xsd +252 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml-inlinexbrl-1_1-model.xsd +681 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml-inlinexbrl-1_1-modules.xsd +535 -0
- arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml-inlinexbrl-1_1.xsd +40 -0
- arelle/resources/cache/http/www.xbrl.org/2013/match-filter.xsd +94 -0
- arelle/resources/cache/http/www.xbrl.org/2013/preferred-label.xsd +12 -0
- arelle/resources/cache/http/www.xbrl.org/2013/versioning-base.xsd +142 -0
- arelle/resources/cache/http/www.xbrl.org/2013/versioning-concept-details.xsd +143 -0
- arelle/resources/cache/http/www.xbrl.org/2013/versioning-concept-use.xsd +64 -0
- arelle/resources/cache/http/www.xbrl.org/2013/versioning-dimensions.xsd +162 -0
- arelle/resources/cache/http/www.xbrl.org/2014/extensible-enumerations.xsd +27 -0
- arelle/resources/cache/http/www.xbrl.org/2014/table.xsd +356 -0
- arelle/resources/cache/http/www.xbrl.org/2014/tablemodel.xsd +156 -0
- arelle/resources/cache/http/www.xbrl.org/2016/assertion-severity.xsd +29 -0
- arelle/resources/cache/http/www.xbrl.org/2016/severities.xml +21 -0
- arelle/resources/cache/http/www.xbrl.org/2016/taxonomy-package-catalog.xsd +38 -0
- arelle/resources/cache/http/www.xbrl.org/2016/taxonomy-package.xsd +154 -0
- arelle/resources/cache/http/www.xbrl.org/2022/assertion-severity.xsd +43 -0
- arelle/resources/cache/http/www.xbrl.org/2022/severities.xml +21 -0
- arelle/resources/cache/http/www.xbrl.org/dtr/type/nonNumeric-2009-12-16.xsd +76 -0
- arelle/resources/cache/http/www.xbrl.org/dtr/type/numeric-2009-12-16.xsd +78 -0
- arelle/resources/cache/http/www.xbrl.org/lrr/arcrole/accounting-arcrole-2023-01-04.xsd +39 -0
- arelle/resources/cache/http/www.xbrl.org/lrr/arcrole/deprecated-2009-12-16.xsd +29 -0
- arelle/resources/cache/http/www.xbrl.org/lrr/arcrole/esma-arcrole-2018-11-21.xsd +14 -0
- arelle/resources/cache/http/www.xbrl.org/lrr/arcrole/factExplanatory-2009-12-16.xsd +13 -0
- arelle/resources/cache/http/www.xbrl.org/lrr/arcrole/jpfr-arcrole-2007-11-07.xsd +27 -0
- arelle/resources/cache/http/www.xbrl.org/lrr/arcrole/parent-child-2013-09-19.xsd +12 -0
- arelle/resources/cache/http/www.xbrl.org/lrr/role/deprecated-2009-12-16.xsd +17 -0
- arelle/resources/cache/http/www.xbrl.org/lrr/role/jpfr-role-2007-11-07.xsd +47 -0
- arelle/resources/cache/http/www.xbrl.org/lrr/role/negated-2008-03-31.xsd +30 -0
- arelle/resources/cache/http/www.xbrl.org/lrr/role/negated-2009-12-16.xsd +33 -0
- arelle/resources/cache/http/www.xbrl.org/lrr/role/negative-2009-12-16.xsd +25 -0
- arelle/resources/cache/http/www.xbrl.org/lrr/role/net-2009-12-16.xsd +13 -0
- arelle/resources/cache/http/www.xbrl.org/lrr/role/positive-2009-12-16.xsd +25 -0
- arelle/resources/cache/http/www.xbrl.org/lrr/role/property-2022-09-28.xsd +15 -0
- arelle/resources/cache/http/www.xbrl.org/lrr/role/reference-2009-12-16.xsd +21 -0
- arelle/resources/cache/http/www.xbrl.org/lrr/role/restated-2006-02-21.xsd +19 -0
- arelle/resources/cache/http/www.xbrl.org/utr/2012-01-30/utr.xml +4543 -0
- arelle/resources/cache/http/www.xbrl.org/utr/2012-10-31/utr.xml +4510 -0
- arelle/resources/cache/http/www.xbrl.org/utr/2012-11-30/utr.xml +4567 -0
- arelle/resources/cache/http/www.xbrl.org/utr/2013-02-28/utr.xml +5180 -0
- arelle/resources/cache/http/www.xbrl.org/utr/2013-05-17/utr.xml +5349 -0
- arelle/resources/cache/http/www.xbrl.org/utr/2016-08-10/utr.xml +5363 -0
- arelle/resources/cache/http/www.xbrl.org/utr/2017-07-12/utr.xml +6164 -0
- arelle/resources/cache/http/www.xbrl.org/utr/2021-02-16/utr.xml +6370 -0
- arelle/resources/cache/http/www.xbrl.org/utr/2021-12-08/utr.xml +6493 -0
- arelle/resources/cache/http/www.xbrl.org/utr/2022-02-16/utr.xml +6551 -0
- arelle/resources/cache/http/www.xbrl.org/utr/2022-07-20/utr.xml +6638 -0
- arelle/resources/cache/http/www.xbrl.org/utr/2023-12-20/utr.xml +6680 -0
- arelle/resources/cache/http/www.xbrl.org/utr/2024-01-31/utr.xml +6680 -0
- arelle/resources/cache/http/www.xbrl.org/utr/2024-10-22/utr.xml +6693 -0
- arelle/resources/cache/http/www.xbrl.org/utr/utr.xml +6693 -0
- arelle/resources/cache/https/www.xbrl.org/2005/conformance.xsd +87 -0
- arelle/resources/cache/https/www.xbrl.org/2020/extensible-enumerations-2.0.xsd +51 -0
- arelle/resources/cache/https/www.xbrl.org/2023/calculation-1.1.xsd +27 -0
- arelle/resources/cache/https/www.xbrl.org/dtr/type/2020-01-21/types.xsd +812 -0
- arelle/resources/cache/https/www.xbrl.org/dtr/type/2022-03-31/types.xsd +847 -0
- arelle/resources/cache/https/www.xbrl.org/dtr/type/2024-01-31/types.xsd +897 -0
- arelle/resources/cache/https/www.xbrl.org/taxonomy/int/filing-indicators/REC/2021-02-03/filing-indicators-def.xml +68 -0
- arelle/resources/cache/https/www.xbrl.org/taxonomy/int/filing-indicators/REC/2021-02-03/filing-indicators-label.xml +84 -0
- arelle/resources/cache/https/www.xbrl.org/taxonomy/int/filing-indicators/REC/2021-02-03/filing-indicators.xsd +67 -0
- arelle/resources/libs/Tktable2.11/linux-x86_64/README.txt +149 -0
- arelle/resources/libs/Tktable2.11/linux-x86_64/html/tkTable.html +2039 -0
- arelle/resources/libs/Tktable2.11/linux-x86_64/libTktable2.11.so +0 -0
- arelle/resources/libs/Tktable2.11/linux-x86_64/license.txt +51 -0
- arelle/resources/libs/Tktable2.11/linux-x86_64/pkgIndex.tcl +3 -0
- arelle/resources/libs/Tktable2.11/linux-x86_64/tkTable.tcl +825 -0
- arelle/resources/libs/Tktable2.11/linux-x86_64/tktable.py +674 -0
- arelle/resources/libs/Tktable2.11/macos-arm64/README.txt +149 -0
- arelle/resources/libs/Tktable2.11/macos-arm64/html/tkTable.html +2039 -0
- arelle/resources/libs/Tktable2.11/macos-arm64/libTktable2.11.dylib +0 -0
- arelle/resources/libs/Tktable2.11/macos-arm64/license.txt +51 -0
- arelle/resources/libs/Tktable2.11/macos-arm64/pkgIndex.tcl +2 -0
- arelle/resources/libs/Tktable2.11/macos-arm64/tkTable.tcl +825 -0
- arelle/resources/libs/Tktable2.11/macos-arm64/tktable.py +674 -0
- arelle/resources/libs/Tktable2.11/macos-x86_64/README.txt +149 -0
- arelle/resources/libs/Tktable2.11/macos-x86_64/html/tkTable.html +2039 -0
- arelle/resources/libs/Tktable2.11/macos-x86_64/libTktable2.11.dylib +0 -0
- arelle/resources/libs/Tktable2.11/macos-x86_64/license.txt +51 -0
- arelle/resources/libs/Tktable2.11/macos-x86_64/pkgIndex.tcl +2 -0
- arelle/resources/libs/Tktable2.11/macos-x86_64/tkTable.tcl +825 -0
- arelle/resources/libs/Tktable2.11/macos-x86_64/tktable.py +674 -0
- arelle/resources/libs/Tktable2.11/win-x86_64/Tktable.dll +0 -0
- arelle/resources/libs/Tktable2.11/win-x86_64/pkgIndex.tcl +2 -0
- arelle/resources/libs/Tktable2.11/win-x86_64/tkTable.tcl +825 -0
- arelle/typing.py +9 -4
- arelle/utils/Contexts.py +38 -0
- arelle/utils/EntryPointDetection.py +139 -0
- arelle/utils/Equivalence.py +22 -0
- arelle/utils/{validate/PluginValidationData.py → PluginData.py} +5 -2
- arelle/utils/PluginHooks.py +256 -5
- arelle/utils/Units.py +36 -0
- arelle/utils/validate/Decorator.py +5 -3
- arelle/utils/validate/DetectScriptsInXhtml.py +99 -0
- arelle/utils/validate/ESEFImage.py +283 -0
- arelle/utils/validate/Validation.py +9 -1
- arelle/utils/validate/ValidationPlugin.py +74 -11
- arelle/utils/validate/ValidationUtil.py +55 -0
- arelle/webserver/bottle.py +5 -4424
- {arelle_release-2.17.1.dist-info → arelle_release-2.37.71.dist-info}/METADATA +51 -42
- arelle_release-2.37.71.dist-info/RECORD +697 -0
- {arelle_release-2.17.1.dist-info → arelle_release-2.37.71.dist-info}/WHEEL +1 -1
- {arelle_release-2.17.1.dist-info → arelle_release-2.37.71.dist-info/licenses}/LICENSE.md +1 -4
- {arelle_release-2.17.1.dist-info → arelle_release-2.37.71.dist-info}/top_level.txt +0 -1
- arelle/DialogOpenTaxonomyPackage.py +0 -1
- arelle/RenderingResolver.py +0 -624
- arelle/examples/.pydevproject +0 -5
- arelle/examples/CustomLogger.py +0 -43
- arelle/examples/LoadEFMvalidate.py +0 -32
- arelle/examples/LoadSavePreLbCsv.py +0 -26
- arelle/examples/LoadValidate.cs +0 -31
- arelle/examples/LoadValidate.py +0 -36
- arelle/examples/LoadValidateCmdLine.java +0 -69
- arelle/examples/LoadValidatePostedZip.java +0 -57
- arelle/examples/LoadValidateWebService.java +0 -34
- arelle/examples/SaveTableToExelle.py +0 -140
- arelle/examples/TR3toTR4.py +0 -88
- arelle/examples/plugin/bigInstance.py +0 -394
- arelle/examples/plugin/cmdWebServerExtension.py +0 -42
- arelle/examples/plugin/crashTest.py +0 -38
- arelle/examples/plugin/formulaSuiteConverter.py +0 -212
- arelle/examples/plugin/functionsCustom.py +0 -59
- arelle/examples/plugin/hello_dolly.py +0 -64
- arelle/examples/plugin/hello_i18n.pot +0 -26
- arelle/examples/plugin/hello_i18n.py +0 -32
- arelle/examples/plugin/importTestChild1.py +0 -21
- arelle/examples/plugin/importTestChild2.py +0 -22
- arelle/examples/plugin/importTestGrandchild1.py +0 -21
- arelle/examples/plugin/importTestGrandchild2.py +0 -21
- arelle/examples/plugin/importTestImported1.py +0 -23
- arelle/examples/plugin/importTestImported11.py +0 -22
- arelle/examples/plugin/importTestParent.py +0 -48
- arelle/examples/plugin/locale/fr/LC_MESSAGES/hello_i18n.po +0 -25
- arelle/examples/plugin/packagedImportTest/__init__.py +0 -47
- arelle/examples/plugin/packagedImportTest/importTestChild1.py +0 -21
- arelle/examples/plugin/packagedImportTest/importTestChild2.py +0 -22
- arelle/examples/plugin/packagedImportTest/importTestGrandchild1.py +0 -21
- arelle/examples/plugin/packagedImportTest/importTestGrandchild2.py +0 -21
- arelle/examples/plugin/packagedImportTest/importTestImported1.py +0 -24
- arelle/examples/plugin/packagedImportTest/importTestImported11.py +0 -21
- arelle/examples/plugin/packagedImportTest/subdir/importTestImported111.py +0 -21
- arelle/examples/plugin/packagedImportTest/subdir/subsubdir/importTestImported1111.py +0 -21
- arelle/examples/plugin/sakaCalendar.py +0 -215
- arelle/examples/plugin/saveInstanceInfoset.py +0 -121
- arelle/examples/plugin/streamingExtensions.py +0 -335
- arelle/examples/plugin/testcaseCalc11ValidateSetup.py +0 -32
- arelle/examples/plugin/testcaseIxExpectedHtmlFixup.py +0 -45
- arelle/examples/plugin/updateTableLB.py +0 -242
- arelle/examples/plugin/validate/XYZ/DisclosureSystems.py +0 -2
- arelle/examples/plugin/validate/XYZ/PluginValidationDataExtension.py +0 -10
- arelle/examples/plugin/validate/XYZ/ValidationPluginExtension.py +0 -49
- arelle/examples/plugin/validate/XYZ/__init__.py +0 -75
- arelle/examples/plugin/validate/XYZ/resources/config.xml +0 -16
- arelle/examples/plugin/validate/XYZ/rules/rules01.py +0 -109
- arelle/examples/plugin/validate/XYZ/rules/rules02.py +0 -58
- arelle/examples/plugin/validateSchemaLxml.py +0 -156
- arelle/examples/plugin/validateTableInfoset.py +0 -52
- arelle/examples/us-gaap-dei-docType-extraction-frm.xml +0 -90
- arelle/examples/us-gaap-dei-ratio-cash-frm.xml +0 -150
- arelle/plugin/functionsXmlCreation.py +0 -106
- arelle/plugin/instanceInfo.py +0 -306
- arelle/plugin/loadFromOIM-2018.py +0 -1282
- arelle/plugin/objectmaker.py +0 -285
- arelle/plugin/sphinx/FormulaGenerator.py +0 -823
- arelle/plugin/sphinx/SphinxContext.py +0 -404
- arelle/plugin/sphinx/SphinxEvaluator.py +0 -783
- arelle/plugin/sphinx/SphinxMethods.py +0 -1287
- arelle/plugin/sphinx/SphinxParser.py +0 -1093
- arelle/plugin/sphinx/SphinxValidator.py +0 -163
- arelle/plugin/sphinx/US-GAAP Ratios Example.xsr +0 -52
- arelle/plugin/sphinx/__init__.py +0 -285
- arelle/plugin/transforms/SEC/__init__.py +0 -308
- arelle/plugin/transforms/SEC/conf/README.md +0 -39
- arelle/plugin/transforms/SEC/conf/extractTestcase.sh +0 -2
- arelle/plugin/transforms/SEC/conf/extractTestcase.xsl +0 -109
- arelle/plugin/transforms/SEC/conf/runIxtSecTests.sh +0 -16
- arelle/plugin/transforms/SEC/conf/saxon9.jar +0 -0
- arelle/plugin/transforms/SEC/conf/testcase.xml +0 -7117
- arelle/plugin/transforms/SEC/conf/tests.xml +0 -848
- arelle/plugin/transforms/SEC/text2num.py +0 -110
- arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-boolballotbox.xml +0 -66
- arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-countrynameen.xml +0 -65
- arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-datequarterend.xml +0 -66
- arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-durday.xml +0 -61
- arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-durhour.xml +0 -69
- arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-durmonth.xml +0 -71
- arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-durweek.xml +0 -70
- arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-durwordsen.xml +0 -56
- arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-duryear.xml +0 -64
- arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-edgarprovcountryen.xml +0 -65
- arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-entityfilercategoryen.xml +0 -63
- arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-exchnameen.xml +0 -86
- arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-numwordsen.xml +0 -55
- arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-stateprovnameen.xml +0 -64
- arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-yesnoballotbox.xml +0 -66
- arelle/plugin/transforms/SEC/transformationRegistry/registry/transform-registry.xml +0 -314
- arelle/plugin/transforms/SEC/transformationRegistry/schema/inlinexbrl-sec-transformation.xsd +0 -418
- arelle/plugin/validate/EFM/Consts.py +0 -362
- arelle/plugin/validate/EFM/DTS.py +0 -569
- arelle/plugin/validate/EFM/Dimensions.py +0 -264
- arelle/plugin/validate/EFM/Document.py +0 -206
- arelle/plugin/validate/EFM/Filing.py +0 -4383
- arelle/plugin/validate/EFM/IsolateSeparateIXDSes.py +0 -19
- arelle/plugin/validate/EFM/MessageNumericId.py +0 -142
- arelle/plugin/validate/EFM/PreCalAlignment.py +0 -324
- arelle/plugin/validate/EFM/Util.py +0 -688
- arelle/plugin/validate/EFM/__init__.py +0 -843
- arelle/plugin/validate/EFM/config.xml +0 -333
- arelle/plugin/validate/EFM/resources/README.md +0 -57
- arelle/plugin/validate/EFM/resources/axiswarnings.json +0 -27
- arelle/plugin/validate/EFM/resources/cef-deprecated-concepts.json +0 -8
- arelle/plugin/validate/EFM/resources/country-deprecated-concepts.json +0 -19
- arelle/plugin/validate/EFM/resources/currency-deprecated-concepts.json +0 -7
- arelle/plugin/validate/EFM/resources/dei-deprecated-concepts.json +0 -8
- arelle/plugin/validate/EFM/resources/dei-validations.json +0 -2884
- arelle/plugin/validate/EFM/resources/dqc-us-rules.json +0 -1389
- arelle/plugin/validate/EFM/resources/ecd-deprecated-concepts.json +0 -1
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-16-4.xml +0 -115
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-17-0-4.xml +0 -300
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-17-1.xml +0 -304
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-17-2.xml +0 -290
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-17-3-1.xml +0 -294
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-18.1.xml +0 -549
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-18.2.xml +0 -506
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-18.3.xml +0 -496
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-19-1.xml +0 -662
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-19-2.xml +0 -3761
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-19-3.xml +0 -3577
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-20-1.xml +0 -4020
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-20-2.xml +0 -3320
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-20-3.xml +0 -2998
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-2012.xml +0 -957
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-2013.xml +0 -982
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-2014.xml +0 -1001
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-2015.xml +0 -1076
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-2016.xml +0 -120
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-21-1.xml +0 -3329
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-21-2.xml +0 -1230
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-21-3.xml +0 -1113
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-21-4.xml +0 -1321
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-22-1-preview.xml +0 -1721
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-22-1.xml +0 -1841
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-22-2-2.xml +0 -1450
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-22-2.xml +0 -1429
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-22-4.xml +0 -1527
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-23-1-1.xml +0 -2049
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-23-1.xml +0 -2065
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-23-2.xml +0 -1674
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-23-3.xml +0 -1715
- arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-all-years.xml +0 -10671
- arelle/plugin/validate/EFM/resources/edgartaxonomies/erxl.xsd +0 -69
- arelle/plugin/validate/EFM/resources/edgartaxonomies/extendedtaxonomies-all-years.xml +0 -18
- arelle/plugin/validate/EFM/resources/edgartaxonomies/ifrs-taxonomies.xml +0 -3126
- arelle/plugin/validate/EFM/resources/edgartaxonomies/ifrstaxonomies-all-years.xml +0 -22
- arelle/plugin/validate/EFM/resources/ex26-validations.json +0 -255
- arelle/plugin/validate/EFM/resources/exch-deprecated-concepts.json +0 -163
- arelle/plugin/validate/EFM/resources/ifrs-full-deprecated-concepts.json +0 -204
- arelle/plugin/validate/EFM/resources/invest-deprecated-concepts.json +0 -99
- arelle/plugin/validate/EFM/resources/ixbrl-transform-registries.json +0 -16
- arelle/plugin/validate/EFM/resources/naics-deprecated-concepts.json +0 -295
- arelle/plugin/validate/EFM/resources/oef-deprecated-concepts.json +0 -59
- arelle/plugin/validate/EFM/resources/other-standard-taxonomies.json +0 -12
- arelle/plugin/validate/EFM/resources/rr-deprecated-concepts.json +0 -14
- arelle/plugin/validate/EFM/resources/rxp-deprecated-concepts.json +0 -1
- arelle/plugin/validate/EFM/resources/shr-deprecated-concepts.json +0 -1
- arelle/plugin/validate/EFM/resources/sic-deprecated-concepts.json +0 -1
- arelle/plugin/validate/EFM/resources/signwarnings.json +0 -112
- arelle/plugin/validate/EFM/resources/srt-deprecated-concepts.json +0 -1
- arelle/plugin/validate/EFM/resources/stpr-deprecated-concepts.json +0 -1
- arelle/plugin/validate/EFM/resources/taxonomy-compatibility.json +0 -79
- arelle/plugin/validate/EFM/resources/us-gaap-deprecated-concepts.json +0 -2886
- arelle/plugin/validate/EFM/resources/us-gaap-rels-2020.json +0 -29068
- arelle/plugin/validate/EFM/resources/us-gaap-rels-2021.json +0 -29598
- arelle/plugin/validate/EFM/resources/us-gaap-rels-2022.json +0 -29141
- arelle/plugin/validate/EFM/resources/us-gaap-rels-2023.json +0 -29400
- arelle/plugin/validate/EFM/resources/vip-deprecated-concepts.json +0 -1
- arelle/plugin/validate/EFM/tools/CheckTxmyRefs.py +0 -180
- arelle/plugin/validate/EFM-htm/Const.py +0 -205
- arelle/plugin/validate/EFM-htm/__init__.py +0 -217
- arelle/plugin/validate/EFM-htm/config.xml +0 -17
- arelle/plugin/validate/EFM-htm/resources/efm-htm.dtd +0 -664
- arelle/plugin/validate/ESEF/ESEF_Current/Image.py +0 -199
- arelle/plugin/validate/ESEF_2022/__init__.py +0 -47
- arelle/plugin/validate/GFM/__init__.py +0 -59
- arelle/plugin/validate/GFM/config.xml +0 -82
- arelle/plugin/validate/SBRnl/CustomLoader.py +0 -19
- arelle/plugin/validate/SBRnl/DTS.py +0 -305
- arelle/plugin/validate/SBRnl/Dimensions.py +0 -357
- arelle/plugin/validate/SBRnl/Document.py +0 -799
- arelle/plugin/validate/SBRnl/Filing.py +0 -467
- arelle/plugin/validate/SBRnl/__init__.py +0 -75
- arelle/plugin/validate/SBRnl/config.xml +0 -26
- arelle/plugin/validate/SBRnl/sbr-nl-taxonomies.xml +0 -754
- arelle/plugin/validate/USBestPractices.py +0 -570
- arelle/plugin/validate/USCorpAction.py +0 -557
- arelle/plugin/validate/USSecTagging.py +0 -337
- arelle/plugin/validate/XDC/__init__.py +0 -77
- arelle/plugin/validate/XDC/config.xml +0 -20
- arelle/plugin/validate/XFsyntax/__init__.py +0 -64
- arelle/plugin/validate/XFsyntax/xf.py +0 -2227
- arelle/plugin/validate/__init__.py +0 -20
- arelle/plugin/validate/calc2.py +0 -536
- arelle/plugin/validateSBRnl.py +0 -530
- arelle/scripts-macOS/startWebServer.command +0 -3
- arelle/scripts-unix/startWebServer.sh +0 -1
- arelle/scripts-windows/startWebServer.bat +0 -5
- arelle_release-2.17.1.dist-info/RECORD +0 -676
- tests/__init__.py +0 -0
- tests/integration_tests/ui_tests/ArelleGUITest/ArelleGUITest/ArelleGUITest.csproj +0 -30
- tests/integration_tests/ui_tests/ArelleGUITest/ArelleGUITest/Tests.cs +0 -381
- tests/integration_tests/ui_tests/ArelleGUITest/ArelleGUITest/Usings.cs +0 -1
- tests/integration_tests/ui_tests/ArelleGUITest/ArelleGUITest.sln +0 -31
- tests/integration_tests/ui_tests/resources/workiva.zip +0 -0
- tests/integration_tests/validation/README.md +0 -50
- tests/integration_tests/validation/conformance_suite_config.py +0 -59
- tests/integration_tests/validation/conformance_suite_configs.py +0 -63
- tests/integration_tests/validation/conformance_suite_configurations/efm_current.py +0 -261
- tests/integration_tests/validation/conformance_suite_configurations/esef_ixbrl_2021.py +0 -85
- tests/integration_tests/validation/conformance_suite_configurations/esef_ixbrl_2022.py +0 -90
- tests/integration_tests/validation/conformance_suite_configurations/esef_xhtml_2021.py +0 -15
- tests/integration_tests/validation/conformance_suite_configurations/esef_xhtml_2022.py +0 -15
- tests/integration_tests/validation/conformance_suite_configurations/nl_nt16.py +0 -13
- tests/integration_tests/validation/conformance_suite_configurations/nl_nt17.py +0 -13
- tests/integration_tests/validation/conformance_suite_configurations/nl_nt18.py +0 -13
- tests/integration_tests/validation/conformance_suite_configurations/xbrl_2_1.py +0 -34
- tests/integration_tests/validation/conformance_suite_configurations/xbrl_calculations_1_1.py +0 -40
- tests/integration_tests/validation/conformance_suite_configurations/xbrl_dimensions_1_0.py +0 -28
- tests/integration_tests/validation/conformance_suite_configurations/xbrl_extensible_enumerations_1_0.py +0 -10
- tests/integration_tests/validation/conformance_suite_configurations/xbrl_extensible_enumerations_2_0.py +0 -10
- tests/integration_tests/validation/conformance_suite_configurations/xbrl_formula_1_0.py +0 -9
- tests/integration_tests/validation/conformance_suite_configurations/xbrl_formula_1_0_assertion_severity_2_0.py +0 -9
- tests/integration_tests/validation/conformance_suite_configurations/xbrl_formula_1_0_function_registry.py +0 -14
- tests/integration_tests/validation/conformance_suite_configurations/xbrl_ixbrl_1_1.py +0 -22
- tests/integration_tests/validation/conformance_suite_configurations/xbrl_link_role_registry_1_0.py +0 -11
- tests/integration_tests/validation/conformance_suite_configurations/xbrl_oim_1_0.py +0 -19
- tests/integration_tests/validation/conformance_suite_configurations/xbrl_table_linkbase_1_0.py +0 -296
- tests/integration_tests/validation/conformance_suite_configurations/xbrl_taxonomy_packages_1_0.py +0 -13
- tests/integration_tests/validation/conformance_suite_configurations/xbrl_transformation_registry_3.py +0 -13
- tests/integration_tests/validation/conformance_suite_configurations/xbrl_transformation_registry_4.py +0 -13
- tests/integration_tests/validation/conformance_suite_configurations/xbrl_transformation_registry_5.py +0 -13
- tests/integration_tests/validation/conformance_suite_configurations/xbrl_utr_malformed_1_0.py +0 -31
- tests/integration_tests/validation/conformance_suite_configurations/xbrl_utr_registry_1_0.py +0 -22
- tests/integration_tests/validation/conformance_suite_configurations/xbrl_utr_structure_1_0.py +0 -18
- tests/integration_tests/validation/conftest.py +0 -24
- tests/integration_tests/validation/discover_tests.py +0 -22
- tests/integration_tests/validation/download_conformance_suites.py +0 -47
- tests/integration_tests/validation/run_conformance_suites.py +0 -175
- tests/integration_tests/validation/test_conformance_suites.py +0 -14
- tests/integration_tests/validation/validation_util.py +0 -271
- tests/resources/conformance_suites/nl_nt16/br_kvk/2-04-invalid-period.xbrl +0 -63
- tests/resources/conformance_suites/nl_nt16/br_kvk/2-04-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt16/br_kvk/3-01-missing.xbrl +0 -53
- tests/resources/conformance_suites/nl_nt16/br_kvk/3-01-multiple.xbrl +0 -60
- tests/resources/conformance_suites/nl_nt16/br_kvk/3-01-testcase.xml +0 -33
- tests/resources/conformance_suites/nl_nt16/br_kvk/4-07-invalid.xbrl +0 -57
- tests/resources/conformance_suites/nl_nt16/br_kvk/4-07-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt16/br_kvk/4-10-invalid.xbrl +0 -58
- tests/resources/conformance_suites/nl_nt16/br_kvk/4-10-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt16/br_kvk/4-12-invalid.xbrl +0 -63
- tests/resources/conformance_suites/nl_nt16/br_kvk/4-12-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt16/br_kvk/4-16-missing.xbrl +0 -61
- tests/resources/conformance_suites/nl_nt16/br_kvk/4-16-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt16/br_kvk/4-20-invalid-date.xbrl +0 -89
- tests/resources/conformance_suites/nl_nt16/br_kvk/4-20-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt16/fr_kvk/1-01-invalid-file-extension.xml +0 -56
- tests/resources/conformance_suites/nl_nt16/fr_kvk/1-01-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt16/fr_kvk/2-01-invalid-lang.xbrl +0 -56
- tests/resources/conformance_suites/nl_nt16/fr_kvk/2-01-missing-lang.xbrl +0 -55
- tests/resources/conformance_suites/nl_nt16/fr_kvk/2-01-testcase.xml +0 -33
- tests/resources/conformance_suites/nl_nt16/fr_kvk/2-03-entrypoint.xsd +0 -6
- tests/resources/conformance_suites/nl_nt16/fr_kvk/2-03-invalid-entrypoint.xbrl +0 -63
- tests/resources/conformance_suites/nl_nt16/fr_kvk/2-03-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt16/fr_kvk/5-01-invalid-decimals.xbrl +0 -49
- tests/resources/conformance_suites/nl_nt16/fr_kvk/5-01-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt16/fr_kvk/5-02-invalid-decimals.xbrl +0 -49
- tests/resources/conformance_suites/nl_nt16/fr_kvk/5-02-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt16/fr_nl/1-01-invalid-file.xbrl +0 -2
- tests/resources/conformance_suites/nl_nt16/fr_nl/1-01-invalid-zip.zip +0 -0
- tests/resources/conformance_suites/nl_nt16/fr_nl/1-01-testcase.xml +0 -33
- tests/resources/conformance_suites/nl_nt16/fr_nl/1-03-invalid-doctype.xbrl +0 -4
- tests/resources/conformance_suites/nl_nt16/fr_nl/1-03-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt16/fr_nl/1-05-invalid-encoding.xbrl +0 -0
- tests/resources/conformance_suites/nl_nt16/fr_nl/1-05-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt16/fr_nl/1-06-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt16/fr_nl/1-06.invalid.xbrl +0 -2
- tests/resources/conformance_suites/nl_nt16/fr_nl/2-06-invalid-file.xbrl +0 -8
- tests/resources/conformance_suites/nl_nt16/fr_nl/2-06-invalid-zip.zip +0 -0
- tests/resources/conformance_suites/nl_nt16/fr_nl/2-06-testcase.xml +0 -33
- tests/resources/conformance_suites/nl_nt16/index.xml +0 -20
- tests/resources/conformance_suites/nl_nt17/br_kvk/2-04-invalid-period.xbrl +0 -63
- tests/resources/conformance_suites/nl_nt17/br_kvk/2-04-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt17/br_kvk/3-01-missing.xbrl +0 -53
- tests/resources/conformance_suites/nl_nt17/br_kvk/3-01-multiple.xbrl +0 -60
- tests/resources/conformance_suites/nl_nt17/br_kvk/3-01-testcase.xml +0 -33
- tests/resources/conformance_suites/nl_nt17/br_kvk/4-07-invalid.xbrl +0 -57
- tests/resources/conformance_suites/nl_nt17/br_kvk/4-07-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt17/br_kvk/4-10-invalid.xbrl +0 -58
- tests/resources/conformance_suites/nl_nt17/br_kvk/4-10-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt17/br_kvk/4-12-invalid.xbrl +0 -63
- tests/resources/conformance_suites/nl_nt17/br_kvk/4-12-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt17/br_kvk/4-16-missing.xbrl +0 -61
- tests/resources/conformance_suites/nl_nt17/br_kvk/4-16-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt17/br_kvk/4-20-invalid-date.xbrl +0 -89
- tests/resources/conformance_suites/nl_nt17/br_kvk/4-20-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt17/fr_kvk/1-01-invalid-file-extension.xml +0 -56
- tests/resources/conformance_suites/nl_nt17/fr_kvk/1-01-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt17/fr_kvk/2-01-invalid-lang.xbrl +0 -56
- tests/resources/conformance_suites/nl_nt17/fr_kvk/2-01-missing-lang.xbrl +0 -55
- tests/resources/conformance_suites/nl_nt17/fr_kvk/2-01-testcase.xml +0 -33
- tests/resources/conformance_suites/nl_nt17/fr_kvk/2-03-entrypoint.xsd +0 -6
- tests/resources/conformance_suites/nl_nt17/fr_kvk/2-03-invalid-entrypoint.xbrl +0 -63
- tests/resources/conformance_suites/nl_nt17/fr_kvk/2-03-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt17/fr_kvk/5-01-invalid-decimals.xbrl +0 -49
- tests/resources/conformance_suites/nl_nt17/fr_kvk/5-01-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt17/fr_kvk/5-02-invalid-decimals.xbrl +0 -49
- tests/resources/conformance_suites/nl_nt17/fr_kvk/5-02-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt17/fr_nl/1-01-invalid-file.xbrl +0 -2
- tests/resources/conformance_suites/nl_nt17/fr_nl/1-01-invalid-zip.zip +0 -0
- tests/resources/conformance_suites/nl_nt17/fr_nl/1-01-testcase.xml +0 -33
- tests/resources/conformance_suites/nl_nt17/fr_nl/1-03-invalid-doctype.xbrl +0 -4
- tests/resources/conformance_suites/nl_nt17/fr_nl/1-03-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt17/fr_nl/1-05-invalid-encoding.xbrl +0 -0
- tests/resources/conformance_suites/nl_nt17/fr_nl/1-05-testcases.xml +0 -22
- tests/resources/conformance_suites/nl_nt17/fr_nl/1-06-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt17/fr_nl/1-06.invalid.xbrl +0 -2
- tests/resources/conformance_suites/nl_nt17/fr_nl/2-06-invalid-file.xbrl +0 -8
- tests/resources/conformance_suites/nl_nt17/fr_nl/2-06-invalid-zip.zip +0 -0
- tests/resources/conformance_suites/nl_nt17/fr_nl/2-06-testcase.xml +0 -33
- tests/resources/conformance_suites/nl_nt17/index.xml +0 -20
- tests/resources/conformance_suites/nl_nt18/fr_nl/1-03-invalid-doctype.xbrl +0 -4
- tests/resources/conformance_suites/nl_nt18/fr_nl/1-03-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt18/fr_nl/1-05-invalid-encoding.xbrl +0 -0
- tests/resources/conformance_suites/nl_nt18/fr_nl/1-05-testcases.xml +0 -22
- tests/resources/conformance_suites/nl_nt18/fr_nl/1-06-testcase.xml +0 -22
- tests/resources/conformance_suites/nl_nt18/fr_nl/1-06.invalid.xbrl +0 -2
- tests/resources/conformance_suites/nl_nt18/fr_nl/1.01-invalid-file.xbrl +0 -2
- tests/resources/conformance_suites/nl_nt18/fr_nl/1.01-invalid-zip.zip +0 -0
- tests/resources/conformance_suites/nl_nt18/fr_nl/1.01-testcase.xml +0 -33
- tests/resources/conformance_suites/nl_nt18/fr_nl/2-06-invalid-file.xbrl +0 -8
- tests/resources/conformance_suites/nl_nt18/fr_nl/2-06-invalid-zip.zip +0 -0
- tests/resources/conformance_suites/nl_nt18/fr_nl/2-06-testcase.xml +0 -33
- tests/resources/conformance_suites/nl_nt18/index.xml +0 -8
- tests/unit_tests/arelle/conftest.py +0 -16
- tests/unit_tests/arelle/formula/test_fact_aspects_cache.py +0 -170
- tests/unit_tests/arelle/plugin/test_loadfromoim.py +0 -40
- tests/unit_tests/arelle/plugin/test_plugin_imports.py +0 -27
- tests/unit_tests/arelle/test_betafeatures.py +0 -81
- tests/unit_tests/arelle/test_cntlr.py +0 -28
- tests/unit_tests/arelle/test_import.py +0 -40
- tests/unit_tests/arelle/test_locale.py +0 -73
- tests/unit_tests/arelle/test_modelmanager.py +0 -15
- tests/unit_tests/arelle/test_packagemanager.py +0 -65
- tests/unit_tests/arelle/test_pluginmanager.py +0 -176
- tests/unit_tests/arelle/test_qname.py +0 -140
- tests/unit_tests/arelle/test_runtimeoptions.py +0 -56
- tests/unit_tests/arelle/test_system_info.py +0 -26
- tests/unit_tests/arelle/test_updater.py +0 -507
- tests/unit_tests/arelle/test_urlutil.py +0 -49
- tests/unit_tests/arelle/test_version.py +0 -46
- tests/unit_tests/arelle/utils/validate/test_decorator.py +0 -59
- /arelle/{examples/plugin/validate/XYZ → plugin/validate/EDINET}/rules/__init__.py +0 -0
- /arelle/plugin/validate/{HMRC → UK}/consistencyChecksByName.json +0 -0
- /arelle/plugin/validate/{HMRC → UK}/hmrc-taxonomies.xml +0 -0
- {arelle_release-2.17.1.dist-info → arelle_release-2.37.71.dist-info}/entry_points.txt +0 -0
arelle/plugin/saveLoadableOIM.py
CHANGED
|
@@ -1,46 +1,123 @@
|
|
|
1
|
-
|
|
1
|
+
"""
|
|
2
|
+
See COPYRIGHT.md for copyright information.
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
saveLoadableOIM.py is an example of a plug-in that will save a re-loadable JSON or CSV instance.
|
|
4
|
+
## Overview
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
The Save Loadable OIM plugin facilitates the saving of re-loadable instances in JSON or CSV formats, adhering to the
|
|
7
|
+
Open Information Model (OIM) XBRL Specification. It is designed to work seamlessly with the Load From OIM plugin,
|
|
8
|
+
allowing for efficient data handling in Arelle.
|
|
7
9
|
|
|
8
|
-
|
|
9
|
-
--saveLoadableOIM oim-file-path
|
|
10
|
-
specifies file name or full path to save with .json, .csv or .xlsx sufffix
|
|
11
|
-
When used to augment test case operation to save oim files when running a test suite
|
|
12
|
-
--saveTestcaseOimFileSuffix oim-file-suffix
|
|
13
|
-
specifies characters to add to read-me-first file when saving oim file
|
|
10
|
+
## Key Features
|
|
14
11
|
|
|
15
|
-
|
|
12
|
+
- **Multiple Formats**: Enables saving data in JSON and CSV OIM formats as well as XLSX.
|
|
13
|
+
- **Seamless Integration**: Compatible with the Load From OIM plugin for saving and loading reports.
|
|
14
|
+
- **GUI and CLI Compatibility**: Available for use in both GUI and CLI modes.
|
|
15
|
+
- **Test Case Augmentation**: Allows saving OIM files with a custom suffix during test suite runs.
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
## Usage Instructions
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
extensionReportObjects - optional dict of extension report objects
|
|
21
|
-
extensionFactPropertiesMethod - method to add extension properties to oimFact
|
|
22
|
-
extensionReportFinalizeMethod - (JSON only) method to finalize json object, for example change facts from object to array.
|
|
19
|
+
### Command Line Usage
|
|
23
20
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
21
|
+
- **Single-Instance Mode**:
|
|
22
|
+
Save a file in single-instance mode by specifying the file path and extension:
|
|
23
|
+
```bash
|
|
24
|
+
python arelleCmdLine.py --plugins saveLoadableOIM --file filing-documents.zip --saveLoadableOIM example.json
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
- **Test Case Operation**:
|
|
28
|
+
Augment test case operations by specifying a suffix for the read-me-first file in a test suite:
|
|
29
|
+
```bash
|
|
30
|
+
python arelleCmdLine.py --plugins saveLoadableOIM --file filing-documents.zip --saveTestcaseOimFileSuffix -savedOim.csv
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
- **Deduplicate facts**
|
|
34
|
+
To save an OIM instance with duplicate fact removed use the `--deduplicateOimFacts` argument with either `complete`,
|
|
35
|
+
`consistent-pairs`, or `consistent-sets` as the value.
|
|
36
|
+
For details on what eaxctly consitutes a duplicate fact and why there are multiple options read the
|
|
37
|
+
[Fact Deduplication][fact-deduplication] documentation.
|
|
38
|
+
```bash
|
|
39
|
+
python arelleCmdLine.py --plugins saveLoadableOIM --file filing-documents.zip --saveLoadableOIM example.json --deduplicateOimFacts complete
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
[fact-deduplication]: project:/user_guides/fact_deduplication.md
|
|
43
|
+
|
|
44
|
+
### GUI Usage
|
|
45
|
+
|
|
46
|
+
- **Save Re-Loadable Output**:
|
|
47
|
+
1. Load the desired report in Arelle.
|
|
48
|
+
2. Go to `Tools` > `Save Loadable OIM`.
|
|
49
|
+
3. Specify a filename and choose the desired file format (JSON, CSV, or XLSX).
|
|
50
|
+
|
|
51
|
+
## Additional Notes
|
|
52
|
+
|
|
53
|
+
If the loaded report refers to a taxonomy on the local file system, the OIM instance needs to be saved in the same
|
|
54
|
+
directory to maintain the validity of the relative file system path to the taxonomy.
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
from __future__ import annotations
|
|
58
|
+
|
|
59
|
+
import csv
|
|
60
|
+
import io
|
|
61
|
+
import json
|
|
62
|
+
import operator
|
|
63
|
+
import os
|
|
64
|
+
import threading
|
|
65
|
+
import zipfile
|
|
66
|
+
from collections.abc import Iterable
|
|
67
|
+
from dataclasses import dataclass
|
|
68
|
+
from datetime import datetime
|
|
28
69
|
from decimal import Decimal
|
|
29
70
|
from math import isinf, isnan
|
|
30
|
-
from
|
|
31
|
-
from
|
|
32
|
-
from
|
|
33
|
-
from
|
|
34
|
-
|
|
35
|
-
|
|
71
|
+
from numbers import Number
|
|
72
|
+
from optparse import OptionParser
|
|
73
|
+
from pathlib import Path
|
|
74
|
+
from typing import TYPE_CHECKING, Any, BinaryIO, Callable, Optional, cast
|
|
75
|
+
|
|
76
|
+
import regex as re
|
|
77
|
+
from openpyxl import Workbook
|
|
78
|
+
from openpyxl.cell.cell import WriteOnlyCell
|
|
79
|
+
from openpyxl.styles import Alignment, Color, PatternFill, fills
|
|
80
|
+
from openpyxl.worksheet.dimensions import ColumnDimension
|
|
81
|
+
|
|
82
|
+
from arelle import ModelDocument, ValidateDuplicateFacts, XbrlConst
|
|
83
|
+
from arelle.ModelInstanceObject import ModelContext, ModelFact
|
|
36
84
|
from arelle.ModelRelationshipSet import ModelRelationshipSet
|
|
85
|
+
from arelle.ModelValue import (
|
|
86
|
+
DateTime,
|
|
87
|
+
DayTimeDuration,
|
|
88
|
+
IsoDuration,
|
|
89
|
+
QName,
|
|
90
|
+
Time,
|
|
91
|
+
YearMonthDuration,
|
|
92
|
+
gDay,
|
|
93
|
+
gMonth,
|
|
94
|
+
gMonthDay,
|
|
95
|
+
gYear,
|
|
96
|
+
gYearMonth,
|
|
97
|
+
qname,
|
|
98
|
+
tzinfoStr,
|
|
99
|
+
)
|
|
100
|
+
from arelle.typing import TypeGetText
|
|
37
101
|
from arelle.UrlUtil import relativeUri
|
|
102
|
+
from arelle.utils.PluginData import PluginData
|
|
103
|
+
from arelle.utils.PluginHooks import PluginHooks
|
|
38
104
|
from arelle.ValidateXbrlCalcs import inferredDecimals
|
|
39
105
|
from arelle.Version import authorLabel, copyrightLabel
|
|
40
|
-
from arelle.XmlUtil import dateunionValue, elementIndex, xmlstring
|
|
41
|
-
from collections import defaultdict
|
|
42
|
-
from numbers import Number
|
|
43
106
|
|
|
107
|
+
if TYPE_CHECKING:
|
|
108
|
+
from tkinter import Menu
|
|
109
|
+
|
|
110
|
+
from arelle.Cntlr import Cntlr
|
|
111
|
+
from arelle.CntlrCmdLine import CntlrCmdLine
|
|
112
|
+
from arelle.CntlrWinMain import CntlrWinMain
|
|
113
|
+
from arelle.ModelXbrl import ModelXbrl
|
|
114
|
+
from arelle.RuntimeOptions import RuntimeOptions
|
|
115
|
+
|
|
116
|
+
_: TypeGetText
|
|
117
|
+
|
|
118
|
+
PLUGIN_NAME = "Save Loadable OIM"
|
|
119
|
+
|
|
120
|
+
oimErrorPattern = re.compile("oime|oimce|xbrlje|xbrlce")
|
|
44
121
|
nsOim = "https://xbrl.org/2021"
|
|
45
122
|
qnOimConceptAspect = qname("concept", noPrefixIsNoNamespace=True)
|
|
46
123
|
qnOimLangAspect = qname("language", noPrefixIsNoNamespace=True)
|
|
@@ -48,112 +125,178 @@ qnOimPeriodAspect = qname("period", noPrefixIsNoNamespace=True)
|
|
|
48
125
|
qnOimEntityAspect = qname("entity", noPrefixIsNoNamespace=True)
|
|
49
126
|
qnOimUnitAspect = qname("unit", noPrefixIsNoNamespace=True)
|
|
50
127
|
|
|
128
|
+
reservedUriAliases = {
|
|
129
|
+
nsOim: "xbrl",
|
|
130
|
+
XbrlConst.defaultLinkRole: "_",
|
|
131
|
+
XbrlConst.factExplanatoryFact: "explanatoryFact",
|
|
132
|
+
XbrlConst.factFootnote: "footnote",
|
|
133
|
+
XbrlConst.iso4217: "iso4217",
|
|
134
|
+
XbrlConst.utr: "utr",
|
|
135
|
+
XbrlConst.xbrli: "xbrli",
|
|
136
|
+
XbrlConst.xsd: "xs",
|
|
137
|
+
}
|
|
138
|
+
|
|
51
139
|
ONE = Decimal(1)
|
|
52
140
|
TEN = Decimal(10)
|
|
53
141
|
NILVALUE = "nil"
|
|
54
|
-
SCHEMA_LB_REFS = {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
142
|
+
SCHEMA_LB_REFS = {
|
|
143
|
+
qname("{http://www.xbrl.org/2003/linkbase}schemaRef"),
|
|
144
|
+
# qname("{http://www.xbrl.org/2003/linkbase}linkbaseRef")
|
|
145
|
+
}
|
|
146
|
+
ROLE_REFS = {
|
|
147
|
+
qname("{http://www.xbrl.org/2003/linkbase}roleRef"),
|
|
148
|
+
qname("{http://www.xbrl.org/2003/linkbase}arcroleRef"),
|
|
149
|
+
}
|
|
59
150
|
ENTITY_NA_QNAME = ("https://xbrl.org/entities", "NA")
|
|
60
|
-
csvOpenMode =
|
|
61
|
-
csvOpenNewline =
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
151
|
+
csvOpenMode = "w"
|
|
152
|
+
csvOpenNewline = ""
|
|
153
|
+
|
|
154
|
+
OimFact = dict[str, Any]
|
|
155
|
+
OimReport = dict[str, Any]
|
|
156
|
+
|
|
157
|
+
class NamespacePrefixes:
|
|
158
|
+
def __init__(self, prefixesByNamespace: dict[str, str] | None = None) -> None:
|
|
159
|
+
self._prefixesByNamespace: dict[str, str] = prefixesByNamespace or {}
|
|
160
|
+
self._usedPrefixes: set[str] = set(self._prefixesByNamespace.values())
|
|
161
|
+
|
|
162
|
+
@property
|
|
163
|
+
def namespaces(self) -> dict[str, str]:
|
|
164
|
+
return {
|
|
165
|
+
prefix: namespace
|
|
166
|
+
for namespace, prefix in sorted(
|
|
167
|
+
self._prefixesByNamespace.items(),
|
|
168
|
+
key=operator.itemgetter(1)
|
|
169
|
+
)
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
def __contains__(self, namespace: str) -> bool:
|
|
173
|
+
return namespace in self._prefixesByNamespace
|
|
174
|
+
|
|
175
|
+
def getPrefix(self, namespace: str) -> str | None:
|
|
176
|
+
return self._prefixesByNamespace.get(namespace)
|
|
177
|
+
|
|
178
|
+
def addNamespace(self, namespace: str, preferredPrefix: str) -> str:
|
|
179
|
+
prefix = self._prefixesByNamespace.get(namespace)
|
|
180
|
+
if prefix is not None:
|
|
181
|
+
return prefix
|
|
182
|
+
|
|
183
|
+
prefix = reservedUriAliases.get(namespace)
|
|
184
|
+
if prefix is None:
|
|
185
|
+
prefix = preferredPrefix
|
|
186
|
+
i = 2
|
|
187
|
+
while prefix in self._usedPrefixes:
|
|
188
|
+
prefix = f"{preferredPrefix}{i}"
|
|
189
|
+
i += 1
|
|
190
|
+
self._prefixesByNamespace[namespace] = prefix
|
|
191
|
+
self._usedPrefixes.add(prefix)
|
|
192
|
+
return prefix
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
def saveLoadableOIM(
|
|
196
|
+
modelXbrl: ModelXbrl,
|
|
197
|
+
oimFile: str,
|
|
198
|
+
outputZip: zipfile.ZipFile | None = None,
|
|
199
|
+
# arguments to add extension features to OIM document
|
|
200
|
+
extensionPrefixes: dict[str, str] | None = None,
|
|
201
|
+
extensionReportObjects: dict[str, Any] | None = None,
|
|
202
|
+
extensionFactPropertiesMethod: Callable[[ModelFact, OimFact], None] | None = None,
|
|
203
|
+
extensionReportFinalizeMethod: Callable[[OimReport], None] | None = None,
|
|
204
|
+
*args: Any,
|
|
205
|
+
**kwargs: Any,
|
|
206
|
+
) -> None:
|
|
71
207
|
isJSON = oimFile.endswith(".json")
|
|
72
208
|
isCSV = oimFile.endswith(".csv")
|
|
73
209
|
isXL = oimFile.endswith(".xlsx")
|
|
74
210
|
isCSVorXL = isCSV or isXL
|
|
75
211
|
if not isJSON and not isCSVorXL:
|
|
76
|
-
|
|
212
|
+
oimFile = oimFile + ".json"
|
|
213
|
+
isJSON = True
|
|
77
214
|
|
|
78
|
-
namespacePrefixes = {nsOim: "xbrl"}
|
|
79
|
-
prefixNamespaces = {}
|
|
215
|
+
namespacePrefixes = NamespacePrefixes({nsOim: "xbrl"})
|
|
80
216
|
if extensionPrefixes:
|
|
81
217
|
for extensionPrefix, extensionNamespace in extensionPrefixes.items():
|
|
82
|
-
namespacePrefixes
|
|
83
|
-
prefixNamespaces[extensionPrefix] = extensionNamespace
|
|
218
|
+
namespacePrefixes.addNamespace(extensionNamespace, extensionPrefix)
|
|
84
219
|
linkTypeAliases = {}
|
|
85
220
|
groupAliases = {}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
if object.prefix:
|
|
103
|
-
namespacePrefixes[object.namespaceURI] = object.prefix
|
|
104
|
-
else:
|
|
105
|
-
_prefix = "_{}".format(sum(1 for p in namespacePrefixes if p.startswith("_")))
|
|
106
|
-
namespacePrefixes[object.namespaceURI] = _prefix
|
|
107
|
-
return "{}:{}".format(namespacePrefixes[object.namespaceURI], object.localName)
|
|
108
|
-
if isinstance(object, (float, Decimal)):
|
|
221
|
+
|
|
222
|
+
def compileQname(qname: QName) -> None:
|
|
223
|
+
if qname.namespaceURI is not None and qname.namespaceURI not in namespacePrefixes:
|
|
224
|
+
namespacePrefixes.addNamespace(qname.namespaceURI, qname.prefix or "")
|
|
225
|
+
|
|
226
|
+
aspectsDefined = {qnOimConceptAspect, qnOimEntityAspect, qnOimPeriodAspect}
|
|
227
|
+
|
|
228
|
+
def oimValue(obj: Any) -> Any:
|
|
229
|
+
if isinstance(obj, list):
|
|
230
|
+
# set-valued enumeration fact
|
|
231
|
+
return " ".join([oimValue(o) for o in obj])
|
|
232
|
+
if isinstance(obj, QName) and obj.namespaceURI is not None:
|
|
233
|
+
if obj.namespaceURI not in namespacePrefixes:
|
|
234
|
+
namespacePrefixes.addNamespace(obj.namespaceURI, obj.prefix or "_")
|
|
235
|
+
return f"{namespacePrefixes.getPrefix(obj.namespaceURI)}:{obj.localName}"
|
|
236
|
+
if isinstance(obj, (float, Decimal)):
|
|
109
237
|
try:
|
|
110
|
-
if isinf(
|
|
111
|
-
return "-INF" if
|
|
112
|
-
elif isnan(
|
|
238
|
+
if isinf(obj):
|
|
239
|
+
return "-INF" if obj < 0 else "INF"
|
|
240
|
+
elif isnan(obj):
|
|
113
241
|
return "NaN"
|
|
242
|
+
elif isinstance(obj, Decimal):
|
|
243
|
+
# XML canonical representation of decimal requires a decimal point.
|
|
244
|
+
# https://www.w3.org/TR/xmlschema-2/#decimal-canonical-representation
|
|
245
|
+
if obj % 1 == 0:
|
|
246
|
+
return f"{obj:.1f}"
|
|
247
|
+
intPart, fracPart = f"{obj:f}".split(".")
|
|
248
|
+
canonicalFracPart = fracPart.rstrip("0") or "0"
|
|
249
|
+
return f"{intPart}.{canonicalFracPart}"
|
|
114
250
|
else:
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
if isinstance(
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
251
|
+
return f"{obj}"
|
|
252
|
+
except Exception:
|
|
253
|
+
return str(obj)
|
|
254
|
+
if isinstance(obj, bool):
|
|
255
|
+
return "true" if obj else "false"
|
|
256
|
+
if isinstance(
|
|
257
|
+
obj,
|
|
258
|
+
(
|
|
259
|
+
DateTime,
|
|
260
|
+
YearMonthDuration,
|
|
261
|
+
DayTimeDuration,
|
|
262
|
+
Time,
|
|
263
|
+
gYearMonth,
|
|
264
|
+
gMonthDay,
|
|
265
|
+
gYear,
|
|
266
|
+
gMonth,
|
|
267
|
+
gDay,
|
|
268
|
+
IsoDuration,
|
|
269
|
+
int,
|
|
270
|
+
),
|
|
271
|
+
):
|
|
272
|
+
return str(obj)
|
|
273
|
+
return obj
|
|
274
|
+
|
|
275
|
+
def oimPeriodValue(cntx: ModelContext) -> dict[str, str]:
|
|
129
276
|
if cntx.isStartEndPeriod:
|
|
130
277
|
s = cntx.startDatetime
|
|
131
278
|
e = cntx.endDatetime
|
|
132
|
-
else:
|
|
279
|
+
else: # instant
|
|
133
280
|
s = e = cntx.instantDatetime
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
281
|
+
assert isinstance(s, datetime) and isinstance(e, datetime)
|
|
282
|
+
return {
|
|
283
|
+
str(qnOimPeriodAspect): (
|
|
284
|
+
f"{s.year:04}-{s.month:02}-{s.day:02}T{s.hour:02}:{s.minute:02}:{s.second:02}{tzinfoStr(s)}/"
|
|
285
|
+
if cntx.isStartEndPeriod
|
|
286
|
+
else ""
|
|
287
|
+
)
|
|
288
|
+
+ f"{e.year:04}-{e.month:02}-{e.day:02}T{e.hour:02}:{e.minute:02}:{e.second:02}{tzinfoStr(e)}"
|
|
289
|
+
}
|
|
290
|
+
|
|
143
291
|
hasTuple = False
|
|
144
|
-
hasType = True
|
|
145
292
|
hasLang = False
|
|
146
293
|
hasUnits = False
|
|
147
294
|
hasNumeric = False
|
|
148
295
|
|
|
149
296
|
footnotesRelationshipSet = ModelRelationshipSet(modelXbrl, "XBRL-footnotes")
|
|
150
297
|
|
|
151
|
-
#compile QNames in instance for OIM
|
|
298
|
+
# compile QNames in instance for OIM
|
|
152
299
|
for fact in modelXbrl.factsInInstance:
|
|
153
|
-
if (fact.id or fact.isTuple or
|
|
154
|
-
footnotesRelationshipSet.toModelObject(fact) or
|
|
155
|
-
(isCSVorXL and footnotesRelationshipSet.fromModelObject(fact))):
|
|
156
|
-
hasId = True
|
|
157
300
|
concept = fact.concept
|
|
158
301
|
if concept is not None:
|
|
159
302
|
if concept.isNumeric:
|
|
@@ -169,9 +312,9 @@ def saveLoadableOIM(modelXbrl, oimFile, outputZip=None,
|
|
|
169
312
|
if fact.modelTupleFacts:
|
|
170
313
|
hasTuple = True
|
|
171
314
|
if hasTuple:
|
|
172
|
-
modelXbrl.error(
|
|
173
|
-
|
|
174
|
-
|
|
315
|
+
modelXbrl.error(
|
|
316
|
+
"arelleOIMsaver:tuplesNotAllowed", "Tuples are not allowed in an OIM document", modelObject=modelXbrl
|
|
317
|
+
)
|
|
175
318
|
return
|
|
176
319
|
|
|
177
320
|
entitySchemePrefixes = {}
|
|
@@ -179,7 +322,7 @@ def saveLoadableOIM(modelXbrl, oimFile, outputZip=None,
|
|
|
179
322
|
if cntx.entityIdentifierElement is not None:
|
|
180
323
|
scheme = cntx.entityIdentifier[0]
|
|
181
324
|
if scheme not in entitySchemePrefixes:
|
|
182
|
-
if not entitySchemePrefixes:
|
|
325
|
+
if not entitySchemePrefixes: # first one is just scheme
|
|
183
326
|
if scheme == "http://www.sec.gov/CIK":
|
|
184
327
|
_schemePrefix = "cik"
|
|
185
328
|
elif scheme == "http://standard.iso.org/iso/17442":
|
|
@@ -187,9 +330,9 @@ def saveLoadableOIM(modelXbrl, oimFile, outputZip=None,
|
|
|
187
330
|
else:
|
|
188
331
|
_schemePrefix = "scheme"
|
|
189
332
|
else:
|
|
190
|
-
_schemePrefix = "scheme{
|
|
191
|
-
|
|
192
|
-
|
|
333
|
+
_schemePrefix = f"scheme{len(entitySchemePrefixes) + 1}"
|
|
334
|
+
namespacePrefixes.addNamespace(scheme, _schemePrefix)
|
|
335
|
+
entitySchemePrefixes[scheme] = namespacePrefixes.getPrefix(scheme)
|
|
193
336
|
for dim in cntx.qnameDims.values():
|
|
194
337
|
compileQname(dim.dimensionQname)
|
|
195
338
|
aspectsDefined.add(dim.dimensionQname)
|
|
@@ -202,69 +345,72 @@ def saveLoadableOIM(modelXbrl, oimFile, outputZip=None,
|
|
|
202
345
|
for measure in measures:
|
|
203
346
|
compileQname(measure)
|
|
204
347
|
|
|
205
|
-
if
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
if hasUnits: aspectsDefined.add(qnOimUnitAspect)
|
|
348
|
+
if hasLang:
|
|
349
|
+
aspectsDefined.add(qnOimLangAspect)
|
|
350
|
+
if hasUnits:
|
|
351
|
+
aspectsDefined.add(qnOimUnitAspect)
|
|
210
352
|
|
|
211
353
|
for footnoteRel in footnotesRelationshipSet.modelRelationships:
|
|
212
|
-
typePrefix = "ftTyp_" + os.path.basename(footnoteRel.arcrole)
|
|
213
|
-
if footnoteRel.linkrole == XbrlConst.defaultLinkRole:
|
|
214
|
-
groupPrefix = "ftGrp_default"
|
|
215
|
-
else:
|
|
216
|
-
groupPrefix = "ftGrp_" + os.path.basename(footnoteRel.linkrole)
|
|
217
354
|
if footnoteRel.arcrole not in linkTypeAliases:
|
|
355
|
+
typePrefix = reservedUriAliases.get(footnoteRel.arcrole, f"ftTyp_{os.path.basename(footnoteRel.arcrole)}")
|
|
218
356
|
linkTypeAliases[footnoteRel.arcrole] = typePrefix
|
|
219
|
-
if
|
|
357
|
+
if footnoteRel.linkrole not in groupAliases:
|
|
358
|
+
groupPrefix = reservedUriAliases.get(footnoteRel.linkrole, f"ftGrp_{os.path.basename(footnoteRel.linkrole)}")
|
|
220
359
|
groupAliases[footnoteRel.linkrole] = groupPrefix
|
|
221
360
|
|
|
222
361
|
dtsReferences = set()
|
|
362
|
+
assert modelXbrl.modelDocument is not None
|
|
223
363
|
baseUrl = modelXbrl.modelDocument.uri.partition("#")[0]
|
|
224
|
-
for doc,ref in sorted(modelXbrl.modelDocument.referencesDocument.items(),
|
|
225
|
-
key=lambda _item:_item[0].uri):
|
|
364
|
+
for doc, ref in sorted(modelXbrl.modelDocument.referencesDocument.items(), key=lambda _item: _item[0].uri):
|
|
226
365
|
if ref.referringModelObject.qname in SCHEMA_LB_REFS:
|
|
227
|
-
dtsReferences.add(relativeUri(baseUrl,doc.uri))
|
|
366
|
+
dtsReferences.add(relativeUri(baseUrl, doc.uri))
|
|
228
367
|
for refType in ("role", "arcrole"):
|
|
229
|
-
for refElt in sorted(
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
368
|
+
for refElt in sorted(
|
|
369
|
+
modelXbrl.modelDocument.xmlRootElement.iterchildren(f"{{http://www.xbrl.org/2003/linkbase}}{refType}Ref"),
|
|
370
|
+
key=lambda elt: elt.get(refType + "URI"),
|
|
371
|
+
):
|
|
233
372
|
dtsReferences.add(refElt.get("{http://www.w3.org/1999/xlink}href").partition("#")[0])
|
|
234
|
-
dtsReferences = sorted(dtsReferences)
|
|
373
|
+
dtsReferences = sorted(dtsReferences) # turn into list
|
|
235
374
|
footnoteFacts = set()
|
|
236
375
|
|
|
237
|
-
def factFootnotes(
|
|
376
|
+
def factFootnotes(
|
|
377
|
+
fact: ModelFact,
|
|
378
|
+
oimFact: dict[str, Any] | None = None,
|
|
379
|
+
csvLinks: dict[str, Any] | None = None,
|
|
380
|
+
):
|
|
238
381
|
footnotes = []
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
elif isCSVorXL:
|
|
382
|
+
oimLinks = {}
|
|
383
|
+
if isCSVorXL and csvLinks is not None:
|
|
242
384
|
oimLinks = csvLinks
|
|
243
385
|
for footnoteRel in footnotesRelationshipSet.fromModelObject(fact):
|
|
244
|
-
srcId = fact.id if fact.id else "f{
|
|
386
|
+
srcId = fact.id if fact.id else f"f{fact.objectIndex}"
|
|
245
387
|
toObj = footnoteRel.toModelObject
|
|
246
388
|
# json
|
|
247
389
|
typePrefix = linkTypeAliases[footnoteRel.arcrole]
|
|
248
390
|
groupPrefix = groupAliases[footnoteRel.linkrole]
|
|
249
391
|
if typePrefix not in oimLinks:
|
|
250
|
-
oimLinks[typePrefix] =
|
|
392
|
+
oimLinks[typePrefix] = {}
|
|
251
393
|
_link = oimLinks[typePrefix]
|
|
252
394
|
if groupPrefix not in _link:
|
|
253
395
|
if isJSON:
|
|
254
396
|
_link[groupPrefix] = []
|
|
255
397
|
elif isCSVorXL:
|
|
256
|
-
_link[groupPrefix] =
|
|
398
|
+
_link[groupPrefix] = {}
|
|
399
|
+
tgtId = toObj.id if toObj.id else f"f{toObj.objectIndex}"
|
|
257
400
|
if isJSON:
|
|
258
401
|
tgtIdList = _link[groupPrefix]
|
|
402
|
+
tgtIdList.append(tgtId)
|
|
259
403
|
elif isCSVorXL:
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
footnote =
|
|
264
|
-
|
|
404
|
+
# Footnote links in xBRL-CSV include the CSV table identifier.
|
|
405
|
+
tgtIdList = _link[groupPrefix].setdefault(f"facts.r_{srcId}.value", [])
|
|
406
|
+
tgtIdList.append(f"footnotes.r_{tgtId}.footnote")
|
|
407
|
+
footnote = {
|
|
408
|
+
"group": footnoteRel.linkrole,
|
|
409
|
+
"footnoteType": footnoteRel.arcrole,
|
|
410
|
+
}
|
|
265
411
|
if isinstance(toObj, ModelFact):
|
|
266
412
|
footnote["factRef"] = tgtId
|
|
267
|
-
else:
|
|
413
|
+
else: # text footnotes
|
|
268
414
|
footnote["id"] = tgtId
|
|
269
415
|
footnote["footnote"] = toObj.viewText()
|
|
270
416
|
if toObj.xmlLang:
|
|
@@ -272,46 +418,38 @@ def saveLoadableOIM(modelXbrl, oimFile, outputZip=None,
|
|
|
272
418
|
footnoteFacts.add(toObj)
|
|
273
419
|
footnotes.append(footnote)
|
|
274
420
|
if oimLinks:
|
|
275
|
-
_links =
|
|
276
|
-
|
|
277
|
-
(groupPrefix, idList)
|
|
278
|
-
for groupPrefix, idList in sorted(groups.items())
|
|
279
|
-
)))
|
|
421
|
+
_links = {
|
|
422
|
+
typePrefix: {groupPrefix: idList for groupPrefix, idList in sorted(groups.items())}
|
|
280
423
|
for typePrefix, groups in sorted(oimLinks.items())
|
|
281
|
-
|
|
282
|
-
if isJSON:
|
|
424
|
+
}
|
|
425
|
+
if isJSON and oimFact is not None:
|
|
283
426
|
oimFact["links"] = _links
|
|
284
427
|
|
|
285
428
|
return footnotes
|
|
286
429
|
|
|
287
|
-
def factAspects(fact):
|
|
288
|
-
oimFact =
|
|
289
|
-
aspects =
|
|
430
|
+
def factAspects(fact: ModelFact) -> dict[str, Any]:
|
|
431
|
+
oimFact = {}
|
|
432
|
+
aspects = {}
|
|
290
433
|
if isCSVorXL:
|
|
291
|
-
oimFact["id"] = fact.id or "f{
|
|
292
|
-
parent = fact.getparent()
|
|
434
|
+
oimFact["id"] = fact.id or f"f{fact.objectIndex}"
|
|
293
435
|
concept = fact.concept
|
|
294
|
-
aspects[str(qnOimConceptAspect)] = oimValue(concept.qname)
|
|
295
436
|
if concept is not None:
|
|
296
|
-
|
|
437
|
+
aspects[str(qnOimConceptAspect)] = oimValue(concept.qname)
|
|
438
|
+
if concept.type is not None and concept.type.isOimTextFactType and fact.xmlLang:
|
|
297
439
|
aspects[str(qnOimLangAspect)] = fact.xmlLang
|
|
298
440
|
if fact.isItem:
|
|
299
441
|
if fact.isNil:
|
|
300
442
|
_value = None
|
|
301
443
|
else:
|
|
302
444
|
_inferredDecimals = inferredDecimals(fact)
|
|
303
|
-
_value = oimValue(fact.xValue
|
|
445
|
+
_value = oimValue(fact.xValue)
|
|
304
446
|
oimFact["value"] = _value
|
|
305
447
|
if fact.concept is not None and fact.concept.isNumeric:
|
|
306
448
|
_numValue = fact.xValue
|
|
307
449
|
if isinstance(_numValue, Decimal) and not isinf(_numValue) and not isnan(_numValue):
|
|
308
|
-
if _numValue == _numValue.to_integral()
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
_numValue = float(_numValue)
|
|
312
|
-
if not fact.isNil:
|
|
313
|
-
if not isinf(_inferredDecimals): # accuracy omitted if infinite
|
|
314
|
-
oimFact["decimals"] = _inferredDecimals
|
|
450
|
+
_numValue = int(_numValue) if _numValue == _numValue.to_integral() else float(_numValue)
|
|
451
|
+
if not fact.isNil and not isinf(_inferredDecimals): # accuracy omitted if infinite
|
|
452
|
+
oimFact["decimals"] = _inferredDecimals
|
|
315
453
|
oimFact["dimensions"] = aspects
|
|
316
454
|
cntx = fact.context
|
|
317
455
|
if cntx is not None:
|
|
@@ -322,7 +460,7 @@ def saveLoadableOIM(modelXbrl, oimFile, outputZip=None,
|
|
|
322
460
|
for _qn, dim in sorted(cntx.qnameDims.items(), key=lambda item: item[0]):
|
|
323
461
|
if dim.isExplicit:
|
|
324
462
|
dimVal = oimValue(dim.memberQname)
|
|
325
|
-
else:
|
|
463
|
+
else: # typed
|
|
326
464
|
if dim.typedMember.get("{http://www.w3.org/2001/XMLSchema-instance}nil") in ("true", "1"):
|
|
327
465
|
dimVal = None
|
|
328
466
|
else:
|
|
@@ -331,81 +469,77 @@ def saveLoadableOIM(modelXbrl, oimFile, outputZip=None,
|
|
|
331
469
|
unit = fact.unit
|
|
332
470
|
if unit is not None:
|
|
333
471
|
_mMul, _mDiv = unit.measures
|
|
334
|
-
_sMul =
|
|
472
|
+
_sMul = "*".join(oimValue(m) for m in sorted(_mMul, key=lambda m: oimValue(m)))
|
|
335
473
|
if _mDiv:
|
|
336
|
-
_sDiv =
|
|
474
|
+
_sDiv = "*".join(oimValue(m) for m in sorted(_mDiv, key=lambda m: oimValue(m)))
|
|
337
475
|
if len(_mDiv) > 1:
|
|
338
|
-
if len(_mMul) > 1
|
|
339
|
-
_sUnit = "({})/({})".format(_sMul,_sDiv)
|
|
340
|
-
else:
|
|
341
|
-
_sUnit = "{}/({})".format(_sMul,_sDiv)
|
|
476
|
+
_sUnit = f"({_sMul})/({_sDiv})" if len(_mMul) > 1 else f"{_sMul}/({_sDiv})"
|
|
342
477
|
else:
|
|
343
|
-
if len(_mMul) > 1
|
|
344
|
-
_sUnit = "({})/{}".format(_sMul,_sDiv)
|
|
345
|
-
else:
|
|
346
|
-
_sUnit = "{}/{}".format(_sMul,_sDiv)
|
|
478
|
+
_sUnit = f"({_sMul})/{_sDiv}" if len(_mMul) > 1 else f"{_sMul}/{_sDiv}"
|
|
347
479
|
else:
|
|
348
480
|
_sUnit = _sMul
|
|
349
481
|
if _sUnit != "xbrli:pure":
|
|
350
482
|
aspects[str(qnOimUnitAspect)] = _sUnit
|
|
351
|
-
# Tuples removed from xBRL-JSON
|
|
352
|
-
#if parent.qname != XbrlConst.qnXbrliXbrl:
|
|
353
|
-
# aspects[str(qnOimTupleParentAspect)] = parent.id if parent.id else "f{}".format(parent.objectIndex)
|
|
354
|
-
# aspects[str(qnOimTupleOrderAspect)] = elementIndex(fact)
|
|
355
483
|
|
|
356
484
|
if isJSON:
|
|
357
485
|
factFootnotes(fact, oimFact=oimFact)
|
|
358
486
|
return oimFact
|
|
359
487
|
|
|
360
|
-
namespaces = OrderedDict((p,ns) for ns, p in sorted(namespacePrefixes.items(),
|
|
361
|
-
key=lambda item: item[1]))
|
|
362
|
-
|
|
363
488
|
# common metadata
|
|
364
|
-
oimReport =
|
|
365
|
-
oimReport["documentInfo"] = oimDocInfo =
|
|
489
|
+
oimReport = {} # top level of oim json output
|
|
490
|
+
oimReport["documentInfo"] = oimDocInfo = {}
|
|
366
491
|
oimDocInfo["documentType"] = nsOim + ("/xbrl-json" if isJSON else "/xbrl-csv")
|
|
367
492
|
if isJSON:
|
|
368
|
-
oimDocInfo["features"] = oimFeatures =
|
|
369
|
-
oimDocInfo["namespaces"] = namespaces
|
|
493
|
+
oimDocInfo["features"] = oimFeatures = {}
|
|
494
|
+
oimDocInfo["namespaces"] = namespacePrefixes.namespaces
|
|
370
495
|
if linkTypeAliases:
|
|
371
|
-
oimDocInfo["linkTypes"] =
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
oimDocInfo["linkGroups"] = OrderedDict((a,u) for u,a in sorted(groupAliases.items(),
|
|
375
|
-
key=lambda item: item[1]))
|
|
496
|
+
oimDocInfo["linkTypes"] = {a: u for u, a in sorted(linkTypeAliases.items(), key=operator.itemgetter(1))}
|
|
497
|
+
if groupAliases:
|
|
498
|
+
oimDocInfo["linkGroups"] = {a: u for u, a in sorted(groupAliases.items(), key=operator.itemgetter(1))}
|
|
376
499
|
oimDocInfo["taxonomy"] = dtsReferences
|
|
377
500
|
if isJSON:
|
|
378
501
|
oimFeatures["xbrl:canonicalValues"] = True
|
|
379
502
|
|
|
503
|
+
factsToSave = modelXbrl.facts
|
|
504
|
+
pluginData = modelXbrl.modelManager.cntlr.getPluginData(PLUGIN_NAME)
|
|
505
|
+
if isinstance(pluginData, SaveLoadableOIMPluginData) and pluginData.deduplicateFactsType is not None:
|
|
506
|
+
deduplicatedFacts = frozenset(ValidateDuplicateFacts.getDeduplicatedFacts(modelXbrl, pluginData.deduplicateFactsType))
|
|
507
|
+
duplicateFacts = frozenset(f for f in modelXbrl.facts if f not in deduplicatedFacts)
|
|
508
|
+
if duplicateFacts:
|
|
509
|
+
for fact in duplicateFacts:
|
|
510
|
+
ValidateDuplicateFacts.logDeduplicatedFact(modelXbrl, fact)
|
|
511
|
+
factsToSave = [f for f in factsToSave if f not in duplicateFacts]
|
|
380
512
|
|
|
381
513
|
if isJSON:
|
|
382
514
|
# save JSON
|
|
383
|
-
oimReport["facts"] = oimFacts =
|
|
515
|
+
oimReport["facts"] = oimFacts = {}
|
|
384
516
|
# add in report level extension objects
|
|
385
517
|
if extensionReportObjects:
|
|
386
518
|
for extObjQName, extObj in extensionReportObjects.items():
|
|
387
519
|
oimReport[extObjQName] = extObj
|
|
388
520
|
|
|
389
|
-
def saveJsonFacts(facts, oimFacts,
|
|
521
|
+
def saveJsonFacts(facts: list[ModelFact], oimFacts: dict[str, dict[str, Any]]) -> None:
|
|
390
522
|
for fact in facts:
|
|
391
523
|
oimFact = factAspects(fact)
|
|
392
524
|
# add in fact level extension objects
|
|
393
525
|
if extensionFactPropertiesMethod:
|
|
394
526
|
extensionFactPropertiesMethod(fact, oimFact)
|
|
395
|
-
id = fact.id if fact.id else "f{
|
|
527
|
+
id = fact.id if fact.id else f"f{fact.objectIndex}"
|
|
396
528
|
oimFacts[id] = oimFact
|
|
397
529
|
if fact.modelTupleFacts:
|
|
398
|
-
saveJsonFacts(fact.modelTupleFacts, oimFacts
|
|
530
|
+
saveJsonFacts(fact.modelTupleFacts, oimFacts)
|
|
399
531
|
|
|
400
|
-
saveJsonFacts(
|
|
532
|
+
saveJsonFacts(factsToSave, oimFacts)
|
|
401
533
|
|
|
402
534
|
# add footnotes as pseudo facts
|
|
403
535
|
for ftObj in footnoteFacts:
|
|
404
|
-
ftId = ftObj.id if ftObj.id else "f{
|
|
405
|
-
oimFacts[ftId] = oimFact =
|
|
536
|
+
ftId = ftObj.id if ftObj.id else f"f{ftObj.objectIndex}"
|
|
537
|
+
oimFacts[ftId] = oimFact = {}
|
|
406
538
|
oimFact["value"] = ftObj.viewText()
|
|
407
|
-
oimFact["dimensions"] =
|
|
408
|
-
|
|
539
|
+
oimFact["dimensions"] = {
|
|
540
|
+
"concept": "xbrl:note",
|
|
541
|
+
"noteId": ftId,
|
|
542
|
+
}
|
|
409
543
|
if ftObj.xmlLang:
|
|
410
544
|
oimFact["dimensions"]["language"] = ftObj.xmlLang.lower()
|
|
411
545
|
|
|
@@ -414,55 +548,51 @@ def saveLoadableOIM(modelXbrl, oimFile, outputZip=None,
|
|
|
414
548
|
if extensionReportFinalizeMethod:
|
|
415
549
|
extensionReportFinalizeMethod(oimReport)
|
|
416
550
|
|
|
417
|
-
if outputZip:
|
|
418
|
-
fh =
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
if outputZip:
|
|
423
|
-
|
|
424
|
-
outputZip.writestr(os.path.basename(oimFile),fh.read())
|
|
425
|
-
fh.close()
|
|
551
|
+
with io.StringIO() if outputZip else open(oimFile, "w", encoding="utf-8") as fh:
|
|
552
|
+
fh.write(json.dumps(oimReport, indent=1))
|
|
553
|
+
if outputZip:
|
|
554
|
+
fh.seek(0)
|
|
555
|
+
outputZip.writestr(os.path.basename(oimFile), fh.read())
|
|
556
|
+
if not outputZip:
|
|
557
|
+
modelXbrl.modelManager.cntlr.showStatus(_("Saved JSON OIM file {}").format(oimFile))
|
|
426
558
|
|
|
427
559
|
elif isCSVorXL:
|
|
428
560
|
# save CSV
|
|
429
|
-
oimReport["tables"] = oimTables =
|
|
430
|
-
oimReport["tableTemplates"] = csvTableTemplates =
|
|
431
|
-
oimTables["facts"] = csvTable =
|
|
561
|
+
oimReport["tables"] = oimTables = {}
|
|
562
|
+
oimReport["tableTemplates"] = csvTableTemplates = {}
|
|
563
|
+
oimTables["facts"] = csvTable = {}
|
|
432
564
|
csvTable["template"] = "facts"
|
|
433
565
|
csvTable["url"] = "tbd"
|
|
434
|
-
csvTableTemplates["facts"] = csvTableTemplate =
|
|
566
|
+
csvTableTemplates["facts"] = csvTableTemplate = {}
|
|
435
567
|
csvTableTemplate["rowIdColumn"] = "id"
|
|
436
|
-
csvTableTemplate["dimensions"] = csvTableDimensions =
|
|
437
|
-
csvTableTemplate["columns"] = csvFactColumns =
|
|
568
|
+
csvTableTemplate["dimensions"] = csvTableDimensions = {}
|
|
569
|
+
csvTableTemplate["columns"] = csvFactColumns = {}
|
|
570
|
+
csvLinks = {}
|
|
438
571
|
if footnotesRelationshipSet.modelRelationships:
|
|
439
|
-
csvLinks = OrderedDict()
|
|
440
572
|
oimReport["links"] = csvLinks
|
|
441
573
|
aspectQnCol = {}
|
|
442
574
|
aspectsHeader = []
|
|
443
|
-
factsColumns = []
|
|
444
575
|
|
|
445
|
-
def addAspectQnCol(aspectQn):
|
|
576
|
+
def addAspectQnCol(aspectQn: QName | str) -> None:
|
|
446
577
|
colQName = str(aspectQn).replace("xbrl:", "")
|
|
447
578
|
colNCName = colQName.replace(":", "_")
|
|
448
579
|
if colNCName not in aspectQnCol:
|
|
449
580
|
aspectQnCol[colNCName] = len(aspectsHeader)
|
|
450
581
|
aspectsHeader.append(colNCName)
|
|
451
582
|
if colNCName == "value":
|
|
452
|
-
csvFactColumns[colNCName] = col =
|
|
453
|
-
col["dimensions"] =
|
|
583
|
+
csvFactColumns[colNCName] = col = {}
|
|
584
|
+
col["dimensions"] = {}
|
|
454
585
|
elif colNCName == "id":
|
|
455
|
-
csvFactColumns[colNCName] = {}
|
|
586
|
+
csvFactColumns[colNCName] = {} # empty object
|
|
456
587
|
elif colNCName == "decimals":
|
|
457
|
-
csvFactColumns[colNCName] = {}
|
|
588
|
+
csvFactColumns[colNCName] = {} # empty object
|
|
458
589
|
csvTableTemplate[colQName] = "$" + colNCName
|
|
459
590
|
else:
|
|
460
|
-
csvFactColumns[colNCName] = {}
|
|
591
|
+
csvFactColumns[colNCName] = {} # empty object
|
|
461
592
|
csvTableDimensions[colQName] = "$" + colNCName
|
|
462
593
|
|
|
463
|
-
|
|
464
594
|
# pre-ordered aspect columns
|
|
465
|
-
#if hasId:
|
|
595
|
+
# if hasId:
|
|
466
596
|
addAspectQnCol("id")
|
|
467
597
|
addAspectQnCol(qnOimConceptAspect)
|
|
468
598
|
if hasNumeric:
|
|
@@ -478,9 +608,10 @@ def saveLoadableOIM(modelXbrl, oimFile, outputZip=None,
|
|
|
478
608
|
addAspectQnCol(aspectQn)
|
|
479
609
|
addAspectQnCol("value")
|
|
480
610
|
|
|
481
|
-
def aspectCols(fact):
|
|
482
|
-
cols = [None
|
|
483
|
-
|
|
611
|
+
def aspectCols(fact: ModelFact) -> list[Any]:
|
|
612
|
+
cols: list[Any] = [None] * len(aspectsHeader)
|
|
613
|
+
|
|
614
|
+
def setColValues(aspects: dict[str, Any]) -> None:
|
|
484
615
|
for aspectQn, aspectValue in aspects.items():
|
|
485
616
|
colQName = str(aspectQn).replace("xbrl:", "")
|
|
486
617
|
colNCName = colQName.replace(":", "_")
|
|
@@ -496,209 +627,369 @@ def saveLoadableOIM(modelXbrl, oimFile, outputZip=None,
|
|
|
496
627
|
else:
|
|
497
628
|
_aspectValue = aspectValue
|
|
498
629
|
cols[aspectQnCol[colNCName]] = _aspectValue
|
|
630
|
+
|
|
499
631
|
setColValues(factAspects(fact))
|
|
500
632
|
return cols
|
|
501
633
|
|
|
502
634
|
# metadata
|
|
503
635
|
|
|
504
|
-
_open = _writerow = _close = None
|
|
505
636
|
if isCSV:
|
|
506
|
-
if oimFile.endswith("-facts.csv"):
|
|
637
|
+
if oimFile.endswith("-facts.csv"): # strip -facts.csv if a prior -facts.csv file was chosen
|
|
507
638
|
_baseURL = oimFile[:-10]
|
|
508
639
|
elif oimFile.endswith(".csv"):
|
|
509
640
|
_baseURL = oimFile[:-4]
|
|
510
641
|
else:
|
|
511
642
|
_baseURL = oimFile
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
643
|
+
_csvInfo = {} # open file, writer
|
|
644
|
+
|
|
645
|
+
def _open(filesuffix: str | None, tabname: str, csvTable: dict[str, Any] | None = None) -> None:
|
|
646
|
+
_filename = _baseURL if filesuffix is None else _baseURL + filesuffix
|
|
515
647
|
if csvTable is not None:
|
|
516
|
-
csvTable["url"] = os.path.basename(_filename)
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
648
|
+
csvTable["url"] = os.path.basename(_filename) # located in same directory with metadata
|
|
649
|
+
_csvInfo["file"] = open(_filename, csvOpenMode, newline=csvOpenNewline, encoding="utf-8-sig")
|
|
650
|
+
_csvInfo["writer"] = csv.writer(_csvInfo["file"], dialect="excel")
|
|
651
|
+
|
|
652
|
+
def _writerow(row: Iterable[str], header: bool = False) -> None:
|
|
653
|
+
_csvInfo["writer"].writerow(row)
|
|
654
|
+
|
|
655
|
+
def _close() -> None:
|
|
656
|
+
_csvInfo["file"].close()
|
|
657
|
+
_csvInfo.clear()
|
|
524
658
|
elif isXL:
|
|
525
|
-
headerWidths = {
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
659
|
+
headerWidths = {
|
|
660
|
+
"concept": 40,
|
|
661
|
+
"decimals": 8,
|
|
662
|
+
"language": 9,
|
|
663
|
+
"value": 50,
|
|
664
|
+
"entity": 20,
|
|
665
|
+
"period": 20,
|
|
666
|
+
"unit": 20,
|
|
667
|
+
"metadata": 100,
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
# Excel's light orange fill color = 00FF990
|
|
671
|
+
hdrCellFill = PatternFill(patternType=fills.FILL_SOLID, fgColor=Color("00FFBF5F"))
|
|
532
672
|
workbook = Workbook()
|
|
533
673
|
# remove pre-existing worksheets
|
|
534
|
-
while len(workbook.worksheets)>0:
|
|
674
|
+
while len(workbook.worksheets) > 0:
|
|
535
675
|
workbook.remove(workbook.worksheets[0])
|
|
536
|
-
|
|
537
|
-
|
|
676
|
+
_xlInfo = {} # open file, writer
|
|
677
|
+
|
|
678
|
+
def _open(filesuffix: str | None, tabname: str, csvTable: dict[str, Any] | None = None) -> None:
|
|
538
679
|
if csvTable is not None:
|
|
539
680
|
csvTable["url"] = tabname + "!"
|
|
540
|
-
|
|
541
|
-
|
|
681
|
+
_xlInfo["ws"] = workbook.create_sheet(title=tabname)
|
|
682
|
+
|
|
683
|
+
def _writerow(rowvalues: Iterable[str], header: bool = False) -> None:
|
|
542
684
|
row = []
|
|
543
|
-
_ws =
|
|
685
|
+
_ws = _xlInfo["ws"]
|
|
544
686
|
for i, v in enumerate(rowvalues):
|
|
545
687
|
cell = WriteOnlyCell(_ws, value=v)
|
|
546
688
|
if header:
|
|
547
689
|
cell.fill = hdrCellFill
|
|
548
690
|
cell.alignment = Alignment(horizontal="center", vertical="center", wrap_text=True)
|
|
549
|
-
colLetter = chr(ord(
|
|
691
|
+
colLetter = chr(ord("A") + i)
|
|
550
692
|
_ws.column_dimensions[colLetter] = ColumnDimension(_ws, customWidth=True)
|
|
551
693
|
_ws.column_dimensions[colLetter].width = headerWidths.get(v, 40)
|
|
552
694
|
|
|
553
695
|
else:
|
|
554
|
-
cell.alignment = Alignment(
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
696
|
+
cell.alignment = Alignment(
|
|
697
|
+
horizontal="right"
|
|
698
|
+
if isinstance(v, Number)
|
|
699
|
+
else "center"
|
|
700
|
+
if isinstance(v, bool)
|
|
701
|
+
else "left",
|
|
702
|
+
vertical="top",
|
|
703
|
+
wrap_text=isinstance(v, str),
|
|
704
|
+
)
|
|
559
705
|
row.append(cell)
|
|
560
706
|
_ws.append(row)
|
|
561
|
-
def _close():
|
|
562
|
-
_xlinfo.clear()
|
|
563
707
|
|
|
708
|
+
def _close() -> None:
|
|
709
|
+
_xlInfo.clear()
|
|
564
710
|
|
|
565
711
|
# save facts
|
|
566
712
|
_open("-facts.csv", "facts", csvTable)
|
|
567
713
|
_writerow(aspectsHeader, header=True)
|
|
568
714
|
|
|
569
|
-
def saveCSVfacts(facts):
|
|
715
|
+
def saveCSVfacts(facts: list[ModelFact]) -> None:
|
|
570
716
|
for fact in facts:
|
|
571
717
|
_writerow(aspectCols(fact))
|
|
572
718
|
saveCSVfacts(fact.modelTupleFacts)
|
|
573
|
-
|
|
719
|
+
|
|
720
|
+
saveCSVfacts(factsToSave)
|
|
574
721
|
_close()
|
|
575
722
|
|
|
576
723
|
# save footnotes
|
|
577
724
|
if footnotesRelationshipSet.modelRelationships:
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
725
|
+
footnotesDeduplicatedById = {
|
|
726
|
+
footnote["id"]: footnote
|
|
727
|
+
for fact in modelXbrl.facts
|
|
728
|
+
for footnote in factFootnotes(fact, csvLinks=csvLinks)
|
|
729
|
+
}
|
|
730
|
+
footnotes = sorted(footnotesDeduplicatedById.values(), key=operator.itemgetter("id"))
|
|
731
|
+
if footnotes: # text footnotes
|
|
732
|
+
footnotesTable = {"template": "footnotes"}
|
|
733
|
+
oimTables["footnotes"] = footnotesTable
|
|
734
|
+
csvTableTemplates[footnotesTable["template"]] = {
|
|
735
|
+
"rowIdColumn" : "id",
|
|
736
|
+
"dimensions": {
|
|
737
|
+
"language": "$language"
|
|
738
|
+
},
|
|
739
|
+
"columns": {
|
|
740
|
+
"id": {},
|
|
741
|
+
"footnote": {
|
|
742
|
+
"dimensions": {
|
|
743
|
+
"concept": "xbrl:note",
|
|
744
|
+
},
|
|
745
|
+
},
|
|
746
|
+
"language": {},
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
_open("-footnotes.csv", "footnotes", footnotesTable)
|
|
593
750
|
cols = ("id", "footnote", "language")
|
|
594
751
|
_writerow(cols, header=True)
|
|
595
752
|
for footnote in footnotes:
|
|
596
|
-
_writerow(tuple(
|
|
753
|
+
_writerow(tuple(footnote.get(col, "") for col in cols))
|
|
597
754
|
_close()
|
|
598
755
|
|
|
599
756
|
# save metadata
|
|
600
757
|
if isCSV:
|
|
601
|
-
|
|
758
|
+
assert isinstance(_baseURL, str)
|
|
759
|
+
csvMetadataFile = _baseURL + "-metadata.json"
|
|
760
|
+
with open(csvMetadataFile, "w", encoding="utf-8") as fh:
|
|
602
761
|
fh.write(json.dumps(oimReport, ensure_ascii=False, indent=2, sort_keys=False))
|
|
762
|
+
modelXbrl.modelManager.cntlr.showStatus(_("Saved CSV OIM metadata file {}").format(csvMetadataFile))
|
|
603
763
|
elif isXL:
|
|
604
764
|
_open(None, "metadata")
|
|
605
765
|
_writerow(["metadata"], header=True)
|
|
606
766
|
_writerow([json.dumps(oimReport, ensure_ascii=False, indent=1, sort_keys=False)])
|
|
607
767
|
_close()
|
|
608
|
-
|
|
609
|
-
if isXL:
|
|
610
768
|
workbook.save(oimFile)
|
|
769
|
+
modelXbrl.modelManager.cntlr.showStatus(_("Saved Excel file {}").format(oimFile))
|
|
611
770
|
|
|
612
|
-
def saveLoadableOIMMenuEntender(cntlr, menu, *args, **kwargs):
|
|
613
|
-
# Extend menu with an item for the savedts plugin
|
|
614
|
-
menu.add_command(label="Save Loadable OIM",
|
|
615
|
-
underline=0,
|
|
616
|
-
command=lambda: saveLoadableOIMMenuCommand(cntlr) )
|
|
617
771
|
|
|
618
|
-
def saveLoadableOIMMenuCommand(cntlr):
|
|
772
|
+
def saveLoadableOIMMenuCommand(cntlr: CntlrWinMain) -> None:
|
|
619
773
|
# save DTS menu item has been invoked
|
|
620
|
-
if (
|
|
621
|
-
cntlr.
|
|
774
|
+
if (
|
|
775
|
+
cntlr.config is None
|
|
776
|
+
or cntlr.modelManager is None
|
|
777
|
+
or cntlr.modelManager.modelXbrl is None
|
|
778
|
+
or cntlr.modelManager.modelXbrl.modelDocument is None
|
|
779
|
+
or cntlr.modelManager.modelXbrl.modelDocument.type
|
|
780
|
+
not in (ModelDocument.Type.INSTANCE, ModelDocument.Type.INLINEXBRL, ModelDocument.Type.INLINEXBRLDOCUMENTSET)
|
|
781
|
+
):
|
|
782
|
+
cntlr.addToLog(
|
|
783
|
+
messageCode="arelleOIMsaver",
|
|
784
|
+
message=_("No supported XBRL instance documents loaded that can be saved to OIM format."),
|
|
785
|
+
)
|
|
622
786
|
return
|
|
623
787
|
# get file name into which to save log file while in foreground thread
|
|
624
|
-
oimFile = cntlr.uiFileDialog(
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
788
|
+
oimFile = cntlr.uiFileDialog(
|
|
789
|
+
"save",
|
|
790
|
+
title=_("arelle - Save Loadable OIM file"),
|
|
791
|
+
initialdir=cntlr.config.setdefault("loadableOIMFileDir", "."),
|
|
792
|
+
filetypes=[(_("JSON file .json"), "*.json"), (_("CSV file .csv"), "*.csv"), (_("XLSX file .xlsx"), "*.xlsx")],
|
|
793
|
+
defaultextension=".json",
|
|
794
|
+
) # type: ignore[no-untyped-call]
|
|
795
|
+
if not isinstance(oimFile, str):
|
|
796
|
+
# User cancelled file dialog.
|
|
797
|
+
return
|
|
798
|
+
|
|
632
799
|
cntlr.config["loadableOIMFileDir"] = os.path.dirname(oimFile)
|
|
633
800
|
cntlr.saveConfig()
|
|
634
801
|
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
802
|
+
thread = threading.Thread(
|
|
803
|
+
target=lambda _modelXbrl=cntlr.modelManager.modelXbrl, _oimFile=oimFile: saveLoadableOIM(
|
|
804
|
+
_modelXbrl, _oimFile, None
|
|
805
|
+
)
|
|
806
|
+
)
|
|
640
807
|
thread.daemon = True
|
|
641
808
|
thread.start()
|
|
642
809
|
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
810
|
+
|
|
811
|
+
def saveOimFiles(
|
|
812
|
+
cntlr: Cntlr,
|
|
813
|
+
modelXbrl: ModelXbrl,
|
|
814
|
+
oimFiles: list[str],
|
|
815
|
+
responseZipStream: BinaryIO | None = None,
|
|
816
|
+
) -> None:
|
|
817
|
+
try:
|
|
818
|
+
if responseZipStream is None:
|
|
819
|
+
for oimFile in oimFiles:
|
|
820
|
+
saveLoadableOIM(modelXbrl, oimFile, None)
|
|
821
|
+
else:
|
|
822
|
+
with zipfile.ZipFile(responseZipStream, "a", zipfile.ZIP_DEFLATED, True) as _zip:
|
|
823
|
+
for oimFile in oimFiles:
|
|
824
|
+
saveLoadableOIM(modelXbrl, oimFile, _zip)
|
|
825
|
+
responseZipStream.seek(0)
|
|
826
|
+
except Exception as ex:
|
|
827
|
+
cntlr.addToLog(f"Exception saving OIM {ex}")
|
|
828
|
+
|
|
829
|
+
|
|
830
|
+
@dataclass
|
|
831
|
+
class SaveLoadableOIMPluginData(PluginData):
|
|
832
|
+
deduplicateFactsType: ValidateDuplicateFacts.DeduplicationType | None
|
|
833
|
+
saveTestcaseOimFileSuffix: str | None
|
|
834
|
+
|
|
835
|
+
|
|
836
|
+
class SaveLoadableOIMPlugin(PluginHooks):
|
|
837
|
+
@staticmethod
|
|
838
|
+
def cntlrCmdLineOptions(
|
|
839
|
+
parser: OptionParser,
|
|
840
|
+
*args: Any,
|
|
841
|
+
**kwargs: Any,
|
|
842
|
+
) -> None:
|
|
843
|
+
parser.add_option(
|
|
844
|
+
"--saveLoadableOIM",
|
|
845
|
+
action="store",
|
|
846
|
+
dest="saveLoadableOIM",
|
|
847
|
+
help=_("Save Loadable OIM file (JSON, CSV or XLSX)"),
|
|
848
|
+
)
|
|
849
|
+
parser.add_option(
|
|
850
|
+
"--saveLoadableOIMDirectory",
|
|
851
|
+
action="store",
|
|
852
|
+
dest="saveLoadableOIMDirectory",
|
|
853
|
+
help=_("Directory to export all supported OIM formats (JSON and CSV)"),
|
|
854
|
+
)
|
|
855
|
+
parser.add_option(
|
|
856
|
+
"--saveTestcaseOIM",
|
|
857
|
+
action="store",
|
|
858
|
+
dest="saveTestcaseOimFileSuffix",
|
|
859
|
+
help=_("Save Testcase Variation OIM file (argument file suffix and type, such as -savedOim.csv"),
|
|
860
|
+
)
|
|
861
|
+
parser.add_option(
|
|
862
|
+
"--deduplicateOimFacts",
|
|
863
|
+
action="store",
|
|
864
|
+
choices=[a.value for a in ValidateDuplicateFacts.DeduplicationType],
|
|
865
|
+
dest="deduplicateOimFacts",
|
|
866
|
+
help=_("Remove duplicate facts when saving the OIM instance"))
|
|
867
|
+
|
|
868
|
+
@staticmethod
|
|
869
|
+
def cntlrCmdLineUtilityRun(
|
|
870
|
+
cntlr: Cntlr,
|
|
871
|
+
options: RuntimeOptions,
|
|
872
|
+
*args: Any,
|
|
873
|
+
**kwargs: Any,
|
|
874
|
+
) -> None:
|
|
875
|
+
deduplicateOimFacts = cast(Optional[str], getattr(options, "deduplicateOimFacts", None))
|
|
876
|
+
saveTestcaseOimFileSuffix = cast(Optional[str], getattr(options, "saveTestcaseOimFileSuffix", None))
|
|
877
|
+
deduplicateFactsType = None
|
|
878
|
+
if deduplicateOimFacts is not None:
|
|
879
|
+
deduplicateFactsType = ValidateDuplicateFacts.DeduplicationType(deduplicateOimFacts)
|
|
880
|
+
pluginData = SaveLoadableOIMPluginData(PLUGIN_NAME, deduplicateFactsType, saveTestcaseOimFileSuffix)
|
|
881
|
+
cntlr.setPluginData(pluginData)
|
|
882
|
+
|
|
883
|
+
@staticmethod
|
|
884
|
+
def cntlrWinMainMenuTools(
|
|
885
|
+
cntlr: CntlrWinMain,
|
|
886
|
+
menu: Menu,
|
|
887
|
+
*args: Any,
|
|
888
|
+
**kwargs: Any,
|
|
889
|
+
) -> None:
|
|
890
|
+
menu.add_command(label="Save Loadable OIM", underline=0, command=lambda: saveLoadableOIMMenuCommand(cntlr))
|
|
891
|
+
|
|
892
|
+
@staticmethod
|
|
893
|
+
def cntlrCmdLineXbrlRun(
|
|
894
|
+
cntlr: CntlrCmdLine,
|
|
895
|
+
options: RuntimeOptions,
|
|
896
|
+
modelXbrl: ModelXbrl,
|
|
897
|
+
entrypoint: dict[str, str] | None = None,
|
|
898
|
+
sourceZipStream: BinaryIO | None = None,
|
|
899
|
+
responseZipStream: BinaryIO | None = None,
|
|
900
|
+
*args: Any,
|
|
901
|
+
**kwargs: Any,
|
|
902
|
+
) -> None:
|
|
903
|
+
# extend XBRL-loaded run processing for this option
|
|
904
|
+
oimFile = cast(Optional[str], getattr(options, "saveLoadableOIM", None))
|
|
905
|
+
allOimDirectory = cast(Optional[str], getattr(options, "saveLoadableOIMDirectory", None))
|
|
906
|
+
if (oimFile or allOimDirectory) and (
|
|
907
|
+
modelXbrl is None
|
|
908
|
+
or modelXbrl.modelDocument is None
|
|
909
|
+
or modelXbrl.modelDocument.type
|
|
910
|
+
not in {
|
|
911
|
+
ModelDocument.Type.INSTANCE,
|
|
912
|
+
ModelDocument.Type.INLINEXBRL,
|
|
913
|
+
ModelDocument.Type.INLINEXBRLDOCUMENTSET,
|
|
914
|
+
}
|
|
915
|
+
):
|
|
663
916
|
cntlr.addToLog("No XBRL instance has been loaded.")
|
|
664
917
|
return
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
918
|
+
if oimFile:
|
|
919
|
+
saveOimFiles(cntlr, modelXbrl, [oimFile], responseZipStream)
|
|
920
|
+
if allOimDirectory:
|
|
921
|
+
oimDir = Path(allOimDirectory)
|
|
922
|
+
try:
|
|
923
|
+
oimDir.mkdir(parents=True, exist_ok=True)
|
|
924
|
+
except OSError as err:
|
|
925
|
+
cntlr.addToLog(
|
|
926
|
+
_("Unable to save OIM files into requested directory: {}, {}").format(allOimDirectory, err.strerror)
|
|
927
|
+
)
|
|
928
|
+
return
|
|
929
|
+
assert modelXbrl.modelDocument is not None
|
|
930
|
+
basefileStem = None
|
|
931
|
+
if hasattr(modelXbrl, "ixdsTarget"):
|
|
932
|
+
ixdsTarget = modelXbrl.ixdsTarget
|
|
933
|
+
for doc in modelXbrl.modelDocument.referencesDocument:
|
|
934
|
+
if doc.type in {ModelDocument.Type.INLINEXBRL, ModelDocument.Type.INSTANCE}:
|
|
935
|
+
instanceFilename = Path(doc.uri)
|
|
936
|
+
if ixdsTarget is not None:
|
|
937
|
+
basefileStem = f"{instanceFilename.stem}.{ixdsTarget}"
|
|
938
|
+
else:
|
|
939
|
+
basefileStem = instanceFilename.stem
|
|
940
|
+
break
|
|
941
|
+
if basefileStem is None:
|
|
942
|
+
basefileStem = Path(modelXbrl.modelDocument.basename).stem
|
|
943
|
+
oimFiles = [str(oimDir.joinpath(basefileStem + ext)) for ext in (".csv", ".json")]
|
|
944
|
+
saveOimFiles(cntlr, modelXbrl, oimFiles, responseZipStream)
|
|
945
|
+
|
|
946
|
+
@staticmethod
|
|
947
|
+
def testcaseVariationValidated(
|
|
948
|
+
testcaseDTS: ModelXbrl,
|
|
949
|
+
testInstanceDTS: ModelXbrl,
|
|
950
|
+
extraErrors: list[str],
|
|
951
|
+
*args: Any,
|
|
952
|
+
**kwargs: Any,
|
|
953
|
+
) -> None:
|
|
954
|
+
pluginData = testcaseDTS.modelManager.cntlr.getPluginData(PLUGIN_NAME)
|
|
955
|
+
oimFileSuffix = (
|
|
956
|
+
pluginData.saveTestcaseOimFileSuffix if isinstance(pluginData, SaveLoadableOIMPluginData) else None
|
|
957
|
+
)
|
|
958
|
+
if (
|
|
959
|
+
oimFileSuffix
|
|
960
|
+
and testInstanceDTS is not None
|
|
961
|
+
and testInstanceDTS.modelDocument is not None
|
|
962
|
+
and testInstanceDTS.modelDocument.type
|
|
963
|
+
in (ModelDocument.Type.INSTANCE, ModelDocument.Type.INLINEXBRL, ModelDocument.Type.INLINEXBRLDOCUMENTSET)
|
|
964
|
+
and not any(oimErrorPattern.match(error) for error in testInstanceDTS.errors if error is not None)
|
|
965
|
+
): # no OIM errors
|
|
966
|
+
try:
|
|
967
|
+
saveLoadableOIM(testInstanceDTS, testInstanceDTS.modelDocument.uri + oimFileSuffix)
|
|
968
|
+
except Exception as ex:
|
|
969
|
+
testcaseDTS.modelManager.cntlr.addToLog(f"Exception saving OIM {ex}")
|
|
677
970
|
|
|
678
|
-
|
|
971
|
+
@staticmethod
|
|
972
|
+
def saveLoadableOimSave(
|
|
973
|
+
modelXbrl: ModelXbrl,
|
|
974
|
+
oimFile: str,
|
|
975
|
+
*args: Any,
|
|
976
|
+
**kwargs: Any,
|
|
977
|
+
) -> None:
|
|
978
|
+
return saveLoadableOIM(modelXbrl, oimFile, *args, **kwargs)
|
|
679
979
|
|
|
680
|
-
def saveLoadableOIMAfterTestcaseValidated(testcaseDTS, testInstanceDTS, extraErrors, *args, **kwargs):
|
|
681
|
-
oimFileSuffix = getattr(testcaseDTS.modelManager, "saveTestcaseOimFileSuffix", None)
|
|
682
|
-
if (oimFileSuffix and testInstanceDTS is not None and
|
|
683
|
-
testInstanceDTS.modelDocument.type in (ModelDocument.Type.INSTANCE, ModelDocument.Type.INLINEXBRL, ModelDocument.Type.INLINEXBRLDOCUMENTSET) and
|
|
684
|
-
not any(oimErrorPattern.match(error) for error in testInstanceDTS.errors)): # no OIM errors
|
|
685
|
-
try:
|
|
686
|
-
saveLoadableOIM(testInstanceDTS, testInstanceDTS.modelDocument.uri + oimFileSuffix)
|
|
687
|
-
except Exception as ex:
|
|
688
|
-
cntlr.addToLog("Exception saving OIM {}".format(ex))
|
|
689
980
|
|
|
690
981
|
__pluginInfo__ = {
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
982
|
+
"name": PLUGIN_NAME,
|
|
983
|
+
"version": "1.3",
|
|
984
|
+
"description": "This plug-in saves XBRL in OIM JSON, CSV or XLSX that can be re-loaded per se.",
|
|
985
|
+
"license": "Apache-2",
|
|
986
|
+
"author": authorLabel,
|
|
987
|
+
"copyright": copyrightLabel,
|
|
697
988
|
# classes of mount points (required)
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
989
|
+
"CntlrWinMain.Menu.Tools": SaveLoadableOIMPlugin.cntlrWinMainMenuTools,
|
|
990
|
+
"CntlrCmdLine.Options": SaveLoadableOIMPlugin.cntlrCmdLineOptions,
|
|
991
|
+
"CntlrCmdLine.Utility.Run": SaveLoadableOIMPlugin.cntlrCmdLineUtilityRun,
|
|
992
|
+
"CntlrCmdLine.Xbrl.Run": SaveLoadableOIMPlugin.cntlrCmdLineXbrlRun,
|
|
993
|
+
"TestcaseVariation.Validated": SaveLoadableOIMPlugin.testcaseVariationValidated,
|
|
994
|
+
"SaveLoadableOim.Save": SaveLoadableOIMPlugin.saveLoadableOimSave,
|
|
704
995
|
}
|