<s> '''<STR_LIT>''' <EOL> from arelle import ViewFile , ModelDtsObject , XbrlConst , XmlUtil <EOL> from arelle . XbrlConst import conceptNameLabelRole <EOL> from arelle . ViewFile import CSV , HTML , XML , JSON <EOL> import datetime , re <EOL> from collections import defaultdict <EOL> stripXmlPattern = re . compile ( r"<STR_LIT>" ) <EOL> def viewFacts ( modelXbrl , outfile , arcrole = None , linkrole = None , linkqname = None , arcqname = None , ignoreDims = False , showDimDefaults = False , labelrole = None , lang = None ) : <EOL> if not arcrole : arcrole = XbrlConst . parentChild <EOL> modelXbrl . modelManager . showStatus ( _ ( "<STR_LIT>" ) ) <EOL> view = ViewFacts ( modelXbrl , outfile , arcrole , linkrole , linkqname , arcqname , ignoreDims , showDimDefaults , labelrole , lang ) <EOL> view . view ( modelXbrl . modelDocument ) <EOL> view . close ( ) <EOL> class ViewFacts ( ViewFile . View ) : <EOL> def __init__ ( self , modelXbrl , outfile , arcrole , linkrole , linkqname , arcqname , ignoreDims , showDimDefaults , labelrole , lang ) : <EOL> super ( ViewFacts , self ) . __init__ ( modelXbrl , outfile , "<STR_LIT>" , lang ) <EOL> self . arcrole = arcrole <EOL> self . linkrole = linkrole <EOL> self . linkqname = linkqname <EOL> self . arcqname = arcqname <EOL> self . ignoreDims = ignoreDims <EOL> self . showDimDefaults = showDimDefaults <EOL> self . labelrole = labelrole <EOL> def view ( self , modelDocument ) : <EOL> relationshipSet = self . modelXbrl . relationshipSet ( self . arcrole , self . linkrole , self . linkqname , self . arcqname ) <EOL> if relationshipSet : <EOL> linkroleUris = [ ] <EOL> for linkroleUri in relationshipSet . linkRoleUris : <EOL> modelRoleTypes = self . modelXbrl . roleTypes . get ( linkroleUri ) <EOL> if modelRoleTypes : <EOL> roledefinition = ( modelRoleTypes [ <NUM_LIT:0> ] . genLabel ( lang = self . lang , strip = True ) or modelRoleTypes [ <NUM_LIT:0> ] . definition or linkroleUri ) <EOL> else : <EOL> roledefinition = linkroleUri <EOL> linkroleUris . append ( ( roledefinition , linkroleUri ) ) <EOL> linkroleUris . sort ( ) <EOL> for roledefinition , linkroleUri in linkroleUris : <EOL> linkRelationshipSet = self . modelXbrl . relationshipSet ( self . arcrole , linkroleUri , self . linkqname , self . arcqname ) <EOL> for rootConcept in linkRelationshipSet . rootConcepts : <EOL> self . treeDepth ( rootConcept , rootConcept , <NUM_LIT:2> , self . arcrole , linkRelationshipSet , set ( ) ) <EOL> self . conceptFacts = defaultdict ( list ) <EOL> for fact in self . modelXbrl . facts : <EOL> self . conceptFacts [ fact . qname ] . append ( fact ) <EOL> self . periodContexts = defaultdict ( set ) <EOL> contextStartDatetimes = { } <EOL> for context in self . modelXbrl . contexts . values ( ) : <EOL> if self . type in ( CSV , HTML ) : <EOL> if self . ignoreDims : <EOL> if context . isForeverPeriod : <EOL> contextkey = datetime . datetime ( datetime . MINYEAR , <NUM_LIT:1> , <NUM_LIT:1> ) <EOL> else : <EOL> contextkey = context . endDatetime <EOL> else : <EOL> if context . isForeverPeriod : <EOL> contextkey = "<STR_LIT>" <EOL> else : <EOL> contextkey = ( context . endDatetime - datetime . timedelta ( days = <NUM_LIT:1> ) ) . strftime ( "<STR_LIT>" ) <EOL> values = [ ] <EOL> dims = context . qnameDims <EOL> if len ( dims ) > <NUM_LIT:0> : <EOL> for dimQname in sorted ( dims . keys ( ) , key = lambda d : str ( d ) ) : <EOL> dimvalue = dims [ dimQname ] <EOL> if dimvalue . isExplicit : <EOL> values . append ( dimvalue . member . label ( self . labelrole , lang = self . lang ) <EOL> if dimvalue . member is not None <EOL> else str ( dimvalue . memberQname ) ) <EOL> else : <EOL> values . append ( XmlUtil . innerText ( dimvalue . typedMember ) ) <EOL> nonDimensions = context . nonDimValues ( "<STR_LIT>" ) + context . nonDimValues ( "<STR_LIT>" ) <EOL> if len ( nonDimensions ) > <NUM_LIT:0> : <EOL> for element in sorted ( nonDimensions , key = lambda e : e . localName ) : <EOL> values . append ( XmlUtil . innerText ( element ) ) <EOL> if len ( values ) > <NUM_LIT:0> : <EOL> contextkey += "<STR_LIT>" + '<STR_LIT:U+002CU+0020>' . join ( values ) <EOL> else : <EOL> contextkey = context . id <EOL> objectId = context . objectId ( ) <EOL> self . periodContexts [ contextkey ] . add ( objectId ) <EOL> if context . isStartEndPeriod : <EOL> contextStartDatetimes [ objectId ] = context . startDatetime <EOL> self . periodKeys = list ( self . periodContexts . keys ( ) ) <EOL> self . periodKeys . sort ( ) <EOL> heading = [ "<STR_LIT>" ] <EOL> columnHeadings = [ ] <EOL> self . contextColId = { } <EOL> self . startdatetimeColId = { } <EOL> self . numCols = <NUM_LIT:1> <EOL> for periodKey in self . periodKeys : <EOL> columnHeadings . append ( periodKey ) <EOL> for contextId in self . periodContexts [ periodKey ] : <EOL> self . contextColId [ contextId ] = self . numCols <EOL> if contextId in contextStartDatetimes : <EOL> self . startdatetimeColId [ contextStartDatetimes [ contextId ] ] = self . numCols <EOL> self . numCols += <NUM_LIT:1> <EOL> for colHeading in columnHeadings : <EOL> if self . ignoreDims : <EOL> if colHeading . year == datetime . MINYEAR : <EOL> date = "<STR_LIT>" <EOL> else : <EOL> date = ( colHeading - datetime . timedelta ( days = <NUM_LIT:1> ) ) . strftime ( "<STR_LIT>" ) <EOL> heading . append ( date ) <EOL> else : <EOL> heading . append ( colHeading ) <EOL> self . addRow ( heading , asHeader = True ) <EOL> if relationshipSet : <EOL> for roledefinition , linkroleUri in linkroleUris : <EOL> attr = { "<STR_LIT>" : linkroleUri } <EOL> self . addRow ( [ roledefinition ] , treeIndent = <NUM_LIT:0> , colSpan = len ( heading ) , <EOL> xmlRowElementName = "<STR_LIT>" , xmlRowEltAttr = attr , xmlCol0skipElt = True ) <EOL> linkRelationshipSet = self . modelXbrl . relationshipSet ( self . arcrole , linkroleUri , self . linkqname , self . arcqname ) <EOL> for rootConcept in linkRelationshipSet . rootConcepts : <EOL> self . viewConcept ( rootConcept , rootConcept , "<STR_LIT>" , self . labelrole , <NUM_LIT:1> , linkRelationshipSet , set ( ) ) <EOL> return True <EOL> def treeDepth ( self , concept , modelObject , indent , arcrole , relationshipSet , visited ) : <EOL> if concept is None : <EOL> return <EOL> if indent > self . treeCols : self . treeCols = indent <EOL> if concept not in visited : <EOL> visited . add ( concept ) <EOL> for modelRel in relationshipSet . fromModelObject ( concept ) : <EOL> nestedRelationshipSet = relationshipSet <EOL> targetRole = modelRel . targetRole <EOL> if targetRole is None or len ( targetRole ) == <NUM_LIT:0> : <EOL> targetRole = relationshipSet . linkrole <EOL> else : <EOL> nestedRelationshipSet = self . modelXbrl . relationshipSet ( arcrole , targetRole ) <EOL> self . treeDepth ( modelRel . toModelObject , modelRel , indent + <NUM_LIT:1> , arcrole , nestedRelationshipSet , visited ) <EOL> visited . remove ( concept ) <EOL> def viewConcept ( self , concept , modelObject , labelPrefix , preferredLabel , n , relationshipSet , visited ) : <EOL> if ( not isinstance ( concept , ModelDtsObject . ModelConcept ) or <EOL> concept . substitutionGroupQname == XbrlConst . qnXbrldtDimensionItem ) : <EOL> return <EOL> cols = [ '<STR_LIT>' for i in range ( self . numCols ) ] <EOL> cols [ <NUM_LIT:0> ] = labelPrefix + concept . label ( preferredLabel , lang = self . lang , linkroleHint = relationshipSet . linkrole ) <EOL> self . setRowFacts ( cols , concept , preferredLabel ) <EOL> attr = { "<STR_LIT>" : str ( concept . qname ) } <EOL> self . addRow ( cols , treeIndent = n , <EOL> xmlRowElementName = "<STR_LIT>" , xmlRowEltAttr = attr , xmlCol0skipElt = True ) <EOL> if concept not in visited : <EOL> visited . add ( concept ) <EOL> for i , modelRel in enumerate ( relationshipSet . fromModelObject ( concept ) ) : <EOL> nestedRelationshipSet = relationshipSet <EOL> targetRole = modelRel . targetRole <EOL> if self . arcrole == XbrlConst . summationItem : <EOL> childPrefix = "<STR_LIT>" . format ( modelRel . weight ) <EOL> elif targetRole is None or len ( targetRole ) == <NUM_LIT:0> : <EOL> targetRole = relationshipSet . linkrole <EOL> childPrefix = "<STR_LIT>" <EOL> else : <EOL> nestedRelationshipSet = self . modelXbrl . relationshipSet ( self . arcrole , targetRole , self . linkqname , self . arcqname ) <EOL> childPrefix = "<STR_LIT>" <EOL> toConcept = modelRel . toModelObject <EOL> if toConcept in visited : <EOL> childPrefix += "<STR_LIT>" <EOL> labelrole = modelRel . preferredLabel <EOL> if not labelrole or self . labelrole == conceptNameLabelRole : <EOL> labelrole = self . labelrole <EOL> self . viewConcept ( toConcept , modelRel , childPrefix , labelrole , n + <NUM_LIT:1> , nestedRelationshipSet , visited ) <EOL> visited . remove ( concept ) <EOL> def setRowFacts ( self , cols , concept , preferredLabel ) : <EOL> for fact in self . conceptFacts [ concept . qname ] : <EOL> try : <EOL> colId = self . contextColId [ fact . context . objectId ( ) ] <EOL> if preferredLabel == XbrlConst . periodStartLabel : <EOL> date = fact . context . instantDatetime <EOL> if date : <EOL> if date in self . startdatetimeColId : <EOL> colId = self . startdatetimeColId [ date ] <EOL> else : <EOL> continue <EOL> cols [ colId ] = fact . effectiveValue <EOL> except AttributeError : <EOL> pass </s>
