From 193f6bfebaa43d0d6749d10a4e7ca78a0d31361d Mon Sep 17 00:00:00 2001
From: Milan Bracke <mbracke@antidot.net>
Date: Mon, 14 Jun 2021 15:00:36 +0200
Subject: [PATCH] Docx reader: fix handling of nested fields

Fields delimited by fldChar elements can contain other fields. Before,
the nested fields would be ignored, except for the end, which would be
considered the end of the parent field.

To fix this issue, fields needed to be considered containing ParParts
instead of Runs, since a Run can't represent complex enough structures.
This also impacted Hyperlinks since they can originate from a field.
---
 src/Text/Pandoc/Readers/Docx.hs       |  18 +-
 src/Text/Pandoc/Readers/Docx/Parse.hs | 241 +++++++++++++++-----------
 test/Tests/Readers/Docx.hs            |   4 +
 test/docx/nested_instrText.docx       | Bin 0 -> 14112 bytes
 test/docx/nested_instrText.native     |   5 +
 5 files changed, 156 insertions(+), 112 deletions(-)
 create mode 100644 test/docx/nested_instrText.docx
 create mode 100644 test/docx/nested_instrText.native

diff --git a/src/Text/Pandoc/Readers/Docx.hs b/src/Text/Pandoc/Readers/Docx.hs
index 66cd84291..462e3c679 100644
--- a/src/Text/Pandoc/Readers/Docx.hs
+++ b/src/Text/Pandoc/Readers/Docx.hs
@@ -246,8 +246,8 @@ runToText _                = ""
 
 parPartToText :: ParPart -> T.Text
 parPartToText (PlainRun run)             = runToText run
-parPartToText (InternalHyperLink _ runs) = T.concat $ map runToText runs
-parPartToText (ExternalHyperLink _ runs) = T.concat $ map runToText runs
+parPartToText (InternalHyperLink _ children) = T.concat $ map parPartToText children
+parPartToText (ExternalHyperLink _ children) = T.concat $ map parPartToText children
 parPartToText _                          = ""
 
 blacklistedCharStyles :: [CharStyleName]
@@ -437,18 +437,18 @@ parPartToInlines' Chart =
   return $ spanWith ("", ["chart"], []) $ text "[CHART]"
 parPartToInlines' Diagram =
   return $ spanWith ("", ["diagram"], []) $ text "[DIAGRAM]"
-parPartToInlines' (InternalHyperLink anchor runs) = do
-  ils <- smushInlines <$> mapM runToInlines runs
+parPartToInlines' (InternalHyperLink anchor children) = do
+  ils <- smushInlines <$> mapM parPartToInlines' children
   return $ link ("#" <> anchor) "" ils
-parPartToInlines' (ExternalHyperLink target runs) = do
-  ils <- smushInlines <$> mapM runToInlines runs
+parPartToInlines' (ExternalHyperLink target children) = do
+  ils <- smushInlines <$> mapM parPartToInlines' children
   return $ link target "" ils
 parPartToInlines' (PlainOMath exps) =
   return $ math $ writeTeX exps
-parPartToInlines' (Field info runs) =
+parPartToInlines' (Field info children) =
   case info of
-    HyperlinkField url -> parPartToInlines' $ ExternalHyperLink url runs
-    UnknownField -> smushInlines <$> mapM runToInlines runs
+    HyperlinkField url -> parPartToInlines' $ ExternalHyperLink url children
+    _ -> smushInlines <$> mapM parPartToInlines' children
 parPartToInlines' NullParPart = return mempty
 
 isAnchorSpan :: Inline -> Bool
diff --git a/src/Text/Pandoc/Readers/Docx/Parse.hs b/src/Text/Pandoc/Readers/Docx/Parse.hs
index e4d3ea6f8..a97d4b3d1 100644
--- a/src/Text/Pandoc/Readers/Docx/Parse.hs
+++ b/src/Text/Pandoc/Readers/Docx/Parse.hs
@@ -93,14 +93,13 @@ data ReaderEnv = ReaderEnv { envNotes         :: Notes
                deriving Show
 
 data ReaderState = ReaderState { stateWarnings :: [T.Text]
-                               , stateFldCharState :: FldCharState
+                               , stateFldCharState :: [FldCharState]
                                }
                  deriving Show
 
 data FldCharState = FldCharOpen
                   | FldCharFieldInfo FieldInfo
-                  | FldCharContent FieldInfo [Run]
-                  | FldCharClosed
+                  | FldCharContent FieldInfo [ParPart]
                   deriving (Show)
 
 data DocxError = DocxError
@@ -314,13 +313,13 @@ data ParPart = PlainRun Run
              | CommentStart CommentId Author (Maybe CommentDate) [BodyPart]
              | CommentEnd CommentId
              | BookMark BookMarkId Anchor
-             | InternalHyperLink Anchor [Run]
-             | ExternalHyperLink URL [Run]
+             | InternalHyperLink Anchor [ParPart]
+             | ExternalHyperLink URL [ParPart]
              | Drawing FilePath T.Text T.Text B.ByteString Extent -- title, alt
              | Chart                                              -- placeholder for now
              | Diagram                                            -- placeholder for now
              | PlainOMath [Exp]
-             | Field FieldInfo [Run]
+             | Field FieldInfo [ParPart]
              | NullParPart      -- when we need to return nothing, but
                                 -- not because of an error.
              deriving Show
@@ -373,7 +372,7 @@ archiveToDocxWithWarnings archive = do
                        , envDocXmlPath = docXmlPath
                        }
       rState = ReaderState { stateWarnings = []
-                           , stateFldCharState = FldCharClosed
+                           , stateFldCharState = []
                            }
       (eitherDoc, st) = runD (archiveToDocument archive) rEnv rState
   case eitherDoc of
@@ -701,28 +700,31 @@ elemToBodyPart ns element
 elemToBodyPart ns element
   | isElem ns "w" "p" element = do
       parstyle <- elemToParagraphStyle ns element <$> asks envParStyles
-      parparts <- mapD (elemToParPart ns) (elChildren element)
+      parparts' <- mapD (elemToParPart ns) (elChildren element)
+      fldCharState <- gets stateFldCharState
+      modify $ \st -> st {stateFldCharState = emptyFldCharContents fldCharState}
       -- Word uses list enumeration for numbered headings, so we only
       -- want to infer a list from the styles if it is NOT a heading.
-      case pHeading parstyle of
-        Nothing | Just (numId, lvl) <- pNumInfo parstyle -> do
-                    levelInfo <- lookupLevel numId lvl <$> asks envNumbering
-                    return $ ListItem parstyle numId lvl levelInfo parparts
-        _ -> let
-          hasCaptionStyle = elem "Caption" (pStyleId <$> pStyle parstyle)
+      let parparts = parparts' ++ (openFldCharsToParParts fldCharState) in
+        case pHeading parstyle of
+          Nothing | Just (numId, lvl) <- pNumInfo parstyle -> do
+                      levelInfo <- lookupLevel numId lvl <$> asks envNumbering
+                      return $ ListItem parstyle numId lvl levelInfo parparts
+          _ -> let
+            hasCaptionStyle = elem "Caption" (pStyleId <$> pStyle parstyle)
 
-          hasSimpleTableField = fromMaybe False $ do
-            fldSimple <- findChildByName ns "w" "fldSimple" element
-            instr <- findAttrByName ns "w" "instr" fldSimple
-            pure ("Table" `elem` T.words instr)
+            hasSimpleTableField = fromMaybe False $ do
+              fldSimple <- findChildByName ns "w" "fldSimple" element
+              instr <- findAttrByName ns "w" "instr" fldSimple
+              pure ("Table" `elem` T.words instr)
 
-          hasComplexTableField = fromMaybe False $ do
-            instrText <- findElementByName ns "w" "instrText" element
-            pure ("Table" `elem` T.words (strContent instrText))
+            hasComplexTableField = fromMaybe False $ do
+              instrText <- findElementByName ns "w" "instrText" element
+              pure ("Table" `elem` T.words (strContent instrText))
 
-          in if hasCaptionStyle && (hasSimpleTableField || hasComplexTableField)
-             then return $ TblCaption parstyle parparts
-             else return $ Paragraph parstyle parparts
+            in if hasCaptionStyle && (hasSimpleTableField || hasComplexTableField)
+              then return $ TblCaption parstyle parparts
+              else return $ Paragraph parstyle parparts
 
 elemToBodyPart ns element
   | isElem ns "w" "tbl" element = do
@@ -754,6 +756,19 @@ lookupRelationship docLocation relid rels =
   where
     pairs = map (\(Relationship loc relid' target) -> ((loc, relid'), target)) rels
 
+openFldCharsToParParts :: [FldCharState] -> [ParPart]
+openFldCharsToParParts [] = []
+openFldCharsToParParts (FldCharContent info children : ancestors) = case openFldCharsToParParts ancestors of
+  Field parentInfo siblings : _ -> [Field parentInfo $ siblings ++ [Field info $ reverse children]]
+  _ -> [Field info $ reverse children]
+openFldCharsToParParts (_ : ancestors) = openFldCharsToParParts ancestors
+
+emptyFldCharContents :: [FldCharState] -> [FldCharState]
+emptyFldCharContents = map
+  (\x -> case x of
+    FldCharContent info _ -> FldCharContent info []
+    _ -> x)
+
 expandDrawingId :: T.Text -> D (FilePath, B.ByteString)
 expandDrawingId s = do
   location <- asks envLocation
@@ -778,51 +793,6 @@ getTitleAndAlt ns element =
   in (title, alt)
 
 elemToParPart :: NameSpaces -> Element -> D ParPart
-elemToParPart ns element
-  | isElem ns "w" "r" element
-  , Just drawingElem <- findChildByName ns "w" "drawing" element
-  , pic_ns <- "http://schemas.openxmlformats.org/drawingml/2006/picture"
-  , Just picElem <- findElement (QName "pic" (Just pic_ns) (Just "pic")) drawingElem
-  = let (title, alt) = getTitleAndAlt ns drawingElem
-        a_ns = "http://schemas.openxmlformats.org/drawingml/2006/main"
-        drawing = findElement (QName "blip" (Just a_ns) (Just "a")) picElem
-                  >>= findAttrByName ns "r" "embed"
-    in
-     case drawing of
-       Just s -> expandDrawingId s >>= (\(fp, bs) -> return $ Drawing fp title alt bs $ elemToExtent drawingElem)
-       Nothing -> throwError WrongElem
--- The two cases below are an attempt to deal with images in deprecated vml format.
--- Todo: check out title and attr for deprecated format.
-elemToParPart ns element
-  | isElem ns "w" "r" element
-  , Just _ <- findChildByName ns "w" "pict" element =
-    let drawing = findElement (elemName ns "v" "imagedata") element
-                  >>= findAttrByName ns "r" "id"
-    in
-     case drawing of
-       Just s -> expandDrawingId s >>= (\(fp, bs) -> return $ Drawing fp "" "" bs Nothing)
-       Nothing -> throwError WrongElem
-elemToParPart ns element
-  | isElem ns "w" "r" element
-  , Just objectElem <- findChildByName ns "w" "object" element
-  , Just shapeElem <- findChildByName ns "v" "shape" objectElem
-  , Just imagedataElem <- findChildByName ns "v" "imagedata" shapeElem
-  , Just drawingId <- findAttrByName ns "r" "id" imagedataElem
-  = expandDrawingId drawingId >>= (\(fp, bs) -> return $ Drawing fp "" "" bs Nothing)
--- Diagram
-elemToParPart ns element
-  | isElem ns "w" "r" element
-  , Just drawingElem <- findChildByName ns "w" "drawing" element
-  , d_ns <- "http://schemas.openxmlformats.org/drawingml/2006/diagram"
-  , Just _ <- findElement (QName "relIds" (Just d_ns) (Just "dgm")) drawingElem
-  = return Diagram
--- Chart
-elemToParPart ns element
-  | isElem ns "w" "r" element
-  , Just drawingElem <- findChildByName ns "w" "drawing" element
-  , c_ns <- "http://schemas.openxmlformats.org/drawingml/2006/chart"
-  , Just _ <- findElement (QName "chart" (Just c_ns) (Just "c")) drawingElem
-  = return Chart
 {-
 The next one is a bit complicated. fldChar fields work by first
 having a <w:fldChar fldCharType="begin"> in a run, then a run with
@@ -854,8 +824,13 @@ example (omissions and my comments in brackets):
 So we do this in a number of steps. If we encounter the fldchar begin
 tag, we start open a fldchar state variable (see state above). We add
 the instrtext to it as FieldInfo. Then we close that and start adding
-the runs when we get to separate. Then when we get to end, we produce
-the Field type with appropriate FieldInfo and Runs.
+the children when we get to separate. Then when we get to end, we produce
+the Field type with appropriate FieldInfo and ParParts.
+
+Since there can be nested fields, the fldchar state needs to be a stack,
+so we can have multiple fldchars open at the same time. When a fldchar is
+closed, we either add the resulting field to its parent or we return it if
+there is no parent.
 -}
 elemToParPart ns element
   | isElem ns "w" "r" element
@@ -863,78 +838,138 @@ elemToParPart ns element
   , Just fldCharType <- findAttrByName ns "w" "fldCharType" fldChar = do
       fldCharState <- gets stateFldCharState
       case fldCharState of
-        FldCharClosed | fldCharType == "begin" -> do
-          modify $ \st -> st {stateFldCharState = FldCharOpen}
+        _ | fldCharType == "begin" -> do
+          modify $ \st -> st {stateFldCharState = FldCharOpen : fldCharState}
           return NullParPart
-        FldCharFieldInfo info | fldCharType == "separate" -> do
-          modify $ \st -> st {stateFldCharState = FldCharContent info []}
+        FldCharFieldInfo info : ancestors | fldCharType == "separate" -> do
+          modify $ \st -> st {stateFldCharState = FldCharContent info [] : ancestors}
           return NullParPart
-        FldCharContent info runs | fldCharType == "end" -> do
-          modify $ \st -> st {stateFldCharState = FldCharClosed}
-          return $ Field info $ reverse runs
+        [FldCharContent info children] | fldCharType == "end" -> do
+          modify $ \st -> st {stateFldCharState = []}
+          return $ Field info $ reverse children
+        FldCharContent info children : FldCharContent parentInfo siblings : ancestors | fldCharType == "end" ->
+          let parent = FldCharContent parentInfo $ (Field info (reverse children)) : siblings in do
+            modify $ \st -> st {stateFldCharState = parent : ancestors}
+            return NullParPart
         _ -> throwError WrongElem
 elemToParPart ns element
   | isElem ns "w" "r" element
   , Just instrText <- findChildByName ns "w" "instrText" element = do
       fldCharState <- gets stateFldCharState
       case fldCharState of
-        FldCharOpen -> do
+        FldCharOpen : ancestors -> do
           info <- eitherToD $ parseFieldInfo $ strContent instrText
-          modify $ \st -> st{stateFldCharState = FldCharFieldInfo info}
+          modify $ \st -> st {stateFldCharState = FldCharFieldInfo info : ancestors}
           return NullParPart
         _ -> return NullParPart
-elemToParPart ns element
+{-
+There is an open fldchar, so we calculate the element and add it to the
+children. For this we need to first change the fldchar state to an empty
+stack to avoid descendants of children simply being added to the state instead
+of to their direct parent element. This would happen in the case of a
+w:hyperlink element for example.
+-}
+elemToParPart ns element = do
+  fldCharState <- gets stateFldCharState
+  case fldCharState of
+    FldCharContent info children : ancestors -> do
+      modify $ \st -> st {stateFldCharState = []}
+      parPart <- elemToParPart' ns element `catchError` \_ -> return NullParPart
+      modify $ \st -> st{stateFldCharState = FldCharContent info (parPart : children) : ancestors}
+      return NullParPart
+    _ -> elemToParPart' ns element
+
+elemToParPart' :: NameSpaces -> Element -> D ParPart
+elemToParPart' ns element
+  | isElem ns "w" "r" element
+  , Just drawingElem <- findChildByName ns "w" "drawing" element
+  , pic_ns <- "http://schemas.openxmlformats.org/drawingml/2006/picture"
+  , Just picElem <- findElement (QName "pic" (Just pic_ns) (Just "pic")) drawingElem
+  = let (title, alt) = getTitleAndAlt ns drawingElem
+        a_ns = "http://schemas.openxmlformats.org/drawingml/2006/main"
+        drawing = findElement (QName "blip" (Just a_ns) (Just "a")) picElem
+                  >>= findAttrByName ns "r" "embed"
+    in
+     case drawing of
+       Just s -> expandDrawingId s >>= (\(fp, bs) -> return $ Drawing fp title alt bs $ elemToExtent drawingElem)
+       Nothing -> throwError WrongElem
+-- The two cases below are an attempt to deal with images in deprecated vml format.
+-- Todo: check out title and attr for deprecated format.
+elemToParPart' ns element
+  | isElem ns "w" "r" element
+  , Just _ <- findChildByName ns "w" "pict" element =
+    let drawing = findElement (elemName ns "v" "imagedata") element
+                  >>= findAttrByName ns "r" "id"
+    in
+     case drawing of
+       Just s -> expandDrawingId s >>= (\(fp, bs) -> return $ Drawing fp "" "" bs Nothing)
+       Nothing -> throwError WrongElem
+elemToParPart' ns element
+  | isElem ns "w" "r" element
+  , Just objectElem <- findChildByName ns "w" "object" element
+  , Just shapeElem <- findChildByName ns "v" "shape" objectElem
+  , Just imagedataElem <- findChildByName ns "v" "imagedata" shapeElem
+  , Just drawingId <- findAttrByName ns "r" "id" imagedataElem
+  = expandDrawingId drawingId >>= (\(fp, bs) -> return $ Drawing fp "" "" bs Nothing)
+-- Diagram
+elemToParPart' ns element
+  | isElem ns "w" "r" element
+  , Just drawingElem <- findChildByName ns "w" "drawing" element
+  , d_ns <- "http://schemas.openxmlformats.org/drawingml/2006/diagram"
+  , Just _ <- findElement (QName "relIds" (Just d_ns) (Just "dgm")) drawingElem
+  = return Diagram
+-- Chart
+elemToParPart' ns element
+  | isElem ns "w" "r" element
+  , Just drawingElem <- findChildByName ns "w" "drawing" element
+  , c_ns <- "http://schemas.openxmlformats.org/drawingml/2006/chart"
+  , Just _ <- findElement (QName "chart" (Just c_ns) (Just "c")) drawingElem
+  = return Chart
+elemToParPart' ns element
   | isElem ns "w" "r" element = do
     run <- elemToRun ns element
-    -- we check to see if we have an open FldChar in state that we're
-    -- recording.
-    fldCharState <- gets stateFldCharState
-    case fldCharState of
-      FldCharContent info runs -> do
-        modify $ \st -> st{stateFldCharState = FldCharContent info (run : runs)}
-        return NullParPart
-      _ -> return $ PlainRun run
-elemToParPart ns element
+    return $ PlainRun run
+elemToParPart' ns element
   | Just change <- getTrackedChange ns element = do
       runs <- mapD (elemToRun ns) (elChildren element)
       return $ ChangedRuns change runs
-elemToParPart ns element
+elemToParPart' ns element
   | isElem ns "w" "bookmarkStart" element
   , Just bmId <- findAttrByName ns "w" "id" element
   , Just bmName <- findAttrByName ns "w" "name" element =
     return $ BookMark bmId bmName
-elemToParPart ns element
+elemToParPart' ns element
   | isElem ns "w" "hyperlink" element
   , Just relId <- findAttrByName ns "r" "id" element = do
     location <- asks envLocation
-    runs <- mapD (elemToRun ns) (elChildren element)
+    children <- mapD (elemToParPart ns) (elChildren element)
     rels <- asks envRelationships
     case lookupRelationship location relId rels of
       Just target ->
          case findAttrByName ns "w" "anchor" element of
-             Just anchor -> return $ ExternalHyperLink (target <> "#" <> anchor) runs
-             Nothing -> return $ ExternalHyperLink target runs
-      Nothing     -> return $ ExternalHyperLink "" runs
-elemToParPart ns element
+             Just anchor -> return $ ExternalHyperLink (target <> "#" <> anchor) children
+             Nothing -> return $ ExternalHyperLink target children
+      Nothing     -> return $ ExternalHyperLink "" children
+elemToParPart' ns element
   | isElem ns "w" "hyperlink" element
   , Just anchor <- findAttrByName ns "w" "anchor" element = do
-    runs <- mapD (elemToRun ns) (elChildren element)
-    return $ InternalHyperLink anchor runs
-elemToParPart ns element
+    children <- mapD (elemToParPart ns) (elChildren element)
+    return $ InternalHyperLink anchor children
+elemToParPart' ns element
   | isElem ns "w" "commentRangeStart" element
   , Just cmtId <- findAttrByName ns "w" "id" element = do
       (Comments _ commentMap) <- asks envComments
       case M.lookup cmtId commentMap of
         Just cmtElem -> elemToCommentStart ns cmtElem
         Nothing      -> throwError WrongElem
-elemToParPart ns element
+elemToParPart' ns element
   | isElem ns "w" "commentRangeEnd" element
   , Just cmtId <- findAttrByName ns "w" "id" element =
     return $ CommentEnd cmtId
-elemToParPart ns element
+elemToParPart' ns element
   | isElem ns "m" "oMath" element =
     fmap PlainOMath (eitherToD $ readOMML $ showElement element)
-elemToParPart _ _ = throwError WrongElem
+elemToParPart' _ _ = throwError WrongElem
 
 elemToCommentStart :: NameSpaces -> Element -> D ParPart
 elemToCommentStart ns element
diff --git a/test/Tests/Readers/Docx.hs b/test/Tests/Readers/Docx.hs
index 2f28af317..af6023836 100644
--- a/test/Tests/Readers/Docx.hs
+++ b/test/Tests/Readers/Docx.hs
@@ -147,6 +147,10 @@ tests = [ testGroup "document"
             "hyperlinks in <w:instrText> tag"
             "docx/instrText_hyperlink.docx"
             "docx/instrText_hyperlink.native"
+          , testCompare
+            "nested fields with <w:instrText> tag"
+            "docx/nested_instrText.docx"
+            "docx/nested_instrText.native"
           , testCompare
             "inline image"
             "docx/image.docx"
diff --git a/test/docx/nested_instrText.docx b/test/docx/nested_instrText.docx
new file mode 100644
index 0000000000000000000000000000000000000000..532584193cc582e1609a7be2b0ddb64d65048250
GIT binary patch
literal 14112
zcmeHu1y>!(*7m{O9fC`6cXtTx4#C~s-QC>@kl=c7CrEG)?j9_-f6UyOduMWIeShG+
zy;kpDr@EirRdx2R-SyNi1!*vFbO0m(8UO$g1J*xHTWf&;07MV~02%-qR9nQ(*4f0?
z`J;-5y@``9y}OMyQ6V@eWj+A(?fL&5|A%{^A$i2Mml0X)Hst{+p-I*7ps<V@G>Si!
zPU#Q|+Y40fIdQQ4r4tQQQ57Ts)|!Nz<#vrlZ6IiBDbpGTrO}Q27>h48AW6@HgJyAI
zhtAI!hhj6CaZPBL-QSwEy#q&v9fXmzu`h8<8CE{KC_4y4;|>r@of4-;<{8665d4J6
zvT@t729~x)ZcioO2!)5JmyZgURJXw9V=GC5ZM^6-qhXdJ6Rh8W9&zM-IGdO3ou&})
zxE$n!e;$jAEs(CD9t-uunb4V4k!EOsq{PkOOH{SDijGH1%_my9<#!ubs>S3D4@-2S
z3?K>PE189r8U?Gluar<FF(B={V%y93NK^?MxB#AgxnK+#fok!Kk#@9Cg)0&1xXrxc
zR;w@x=3oULHxql`m$D;2jXPX{SQKpw46IdKSB_h30GJME{B*M<=glUdu5I!K@rU-7
zA8qcy0D#w5Fo43}T#_IGx9RN7&g9-a4(`n*KRTLNJ2BAzCjaM(|A+nWFHNsV?6K@)
zgcm#udJdZEP+aQ4E|Oy~nq0<Sgo4)oAcMC2-E!gOnfLp5P~AfViIM4<q)AVwY;l*3
zWZiSzR8@q?4w(6Sy*};7c6UHZNP97p`@H=YeAeEL>GL<z4^-cRqBJogCvYJX?!wc@
zy3uy2MQ?UX;Vej~CT5Mu>Wgw6R2Od3eOdA|nC9j!CAGbv%J{@OL-AY3aeQG-1!~h+
z=;Gsg*XnfpRgRLHnPV)eu4!?t85zj46AUY0anIYQjy#LHO20;g(83hJL@+#ho9duy
zz3fNs;Rvvw5o<Pl+_b~X))l&Z3rzp*A5@wN8WL}JP{9F!cK~P*H#<jThJQJUv7M2N
z&0F;PEo}YiFd%QS>+R|P+ebyxh+N-qW4Gj!$PPr?fQ5gg#A=yBd?ff53V(OZdpYz$
zptXp0CjkcvD~4)6$p}vomy>wv;EW4-pgbc`Au-<oy8vKZra{albT<6F0SYm%IQ&@w
z6?(~EY-adk>J9_k#dl~g1Q<{%DXnmt-P!xSgiB>MR4V8yM<yeZn-F0zvxI!tf1485
zV8%3mn1DrtF>o|6r;upT{0>RmL^GjRr<f2!(oG*iujeO1_T`{vTyba+>1S1VK9tQq
z5{EpJo4Bv?#nJ}f%LA98&EaNSte!tlT#rxm+Irz<ZPkoyw#$dfd`O!tHurc+Z6zCj
zNFL%F4i`@4iJ+VJJXQKK9jZfh>O;xup~cuMiaVxWzc@1XV>4LoLCah&H|eepv4!a4
z{l?7~L|LOpXSOFrrZb-=SADWdq<${}kDmztWQcVbi6MiK0Dut_0D$slU%wmTUrlgF
zTib4#9o?6(=9TEc0I3gE^Cvk_z1034&)8Cfcp{%Or2-|Y4P1g~%%_}Y`PE6&4r3c8
zecdL=zQ}@Ae~gj&f(7gEaTzC{<R9U9l6RyH-@9ZRHm-oyQYt;UcRINvBEj5zzfc`P
zrw&&DTc%PZK#BmZW2?Y(Wg_=&PsfXj0yQbCET;e}N>z|h6Xbc{<`~g@z_&7iTa*Dn
zXHlrXqa#nnc1lbXZA7h8;kL!W?Lo)--W*B?g9RHJ`UykE`2)-_anlZR1+kPtd$gsx
z3iX5ilBJ(Hx1xGJ3skhE)(3L<N+8pYNRVi8F!~v!5+ndLG;#$2gP&DJW=qKhL<|xX
z^h;}eVG!{(5f&c&hePp9Y<Q}b7<5ATFIL=|t7z|dhC&BGDN?^}q@a^alaH8~!TaN<
z;7EsB)KKe(8p>kN)uchiLwhzNSJe2L2g3~aax?dNqCu4QGuI~hzSgSw(R)rGp9y60
zNeVo5(9ihV+h<6FXXL|K&m?X(@UGyZBj8HQ#(xtcqfT9Xvi+Ly=$!W4JJV45ja^@0
z>+zvUM*e3I%B}(-<|c9_!E<<x*JueD=4kItH`tdFkru~1kWVoA&LI7)vu53PhW$S9
zAFRA62bmt6V<=+HFk+1wFlcUZ25(?zKm?~Yi3(-8%;%2uchKY5ZOowQd2Cp>&CTmi
zh#Gol0z~xhXS!y{52u1PDZe20Q%FmXW7^2flB1CY4%2pfqwBz(e`KWbYZhyuJ{KgC
z6Mm=*zNYr$o<#k?O|58VuoqmEaFvW2pg(3se8-|!zEg;1p$Q{mgQ`UC!%q&HCrMT?
zR9VKmnQ|e@i96m%U8*QVmsRn2=`E2$BbM772cgC$^ut(;P1z6<E$k><IzTj{3GIv}
zv5&pzJVS~NOon?wCCgroF94n&T8T<pS>$9<Lu$D}g2N5kvw*7|)neZGP6OX1ks)Fh
z)f;Bpr1K{oqXzS)(P;=Ve{!XkehN!z-M;)-E<cW{HvwNGdoa9uqIKPibw{m3)5X>8
z!|r1vmKBe{bMy0Ran4v}PE^`42ZxpR?J)-s$We94KYG0QC846S>1ry<i?T%KYqG&E
zf2CTtpCdRs1i1lhhPP2o*g@7-pEf+6cln}+;IVHbKUpv&>ML0pHt>9^nbC|9y0C;x
zYaT>?S=yWuL6Pwq{s(5TnnmrA;EJ}e*iiiwLzuc}Ur97=FLPho9+`^@g0UNPVYo^>
zCsj6Q*2MVb9bGdVdk98W7zejrf3rD>TdgZitVnjz_`Q5XF}P`j!XDq8BR?x~*zknJ
zisP`1E@g~~TpL3>KizxL&1|ah6m(!h5oW^j)t5(YNhYOG^4zGUM5cV@0FqoIcQ}vN
z@fI3FP7|UwaD8v(rEk!ol$g8ri}M{Zx&Cm%OKM}(YzMw55z6DTV!aj&5U?b>YcD?o
zcnl<x9M=PEohiGhxlQ-#55N9keS+z2xeaOg@g&3UX6j4d(QLPYdw*}Q-+(7R&pwV8
z4F~p>PczX-DPHGA(s&)S(1AENIykW)K0ep$c#Es<I=6}kH{u&qAZXjq3fprXlWH3t
z&6w<r&|&CDE>*z^lsm;q1g?vpYum)c?8q@EF~>Y{c?6>yemqrPvL*Mo6IG<S-9u~5
zjy&BnU)%<G`EqgA+r%92xO2#}-(50GLS>YAW&fxq6#7|+V|@gU<Kr;u$@DbF<Son6
zIH;(*VRp2pc|^fhV!!~`&o}+P-ZL1ka7haWY&Zz9wmFrm?^7n~v-L&F5sZpb3X`f7
zf~<z1j0P<+Q6{=$Iy8%kh(s%+)$ve(cgQ-nmcB_xt8}AMn5{%Nmj2fOW1>lq?!GV)
zk{2uH4<}zAZWsi>m&o{(>xu6BdzO&2wC;b7@4i_d@g^&B&;W<L_y`#f62H~ch12%*
zn4q@Fw!!udR->8jv4s8T`E64pmRpc@(9$JTOgWa-L}$giR#-pK!OW@QUGdA)hwZ73
zfq}V!Mk^tp^7FzO-p5x+8l#hH1V&WkrOrl3HiomRfW;&A`6G40nAF{umb-g;;q&A3
z)YaSX!ZU~F^r^cXQ{1PuvUjh|w3U~~xwqeMR9x4MF3H4jN1CqgsTtM3ZGrB$fqD^f
z^_+<YDdoS53fm_5q@3*($A#mX&yVWBkbqL85!kcqKIEg@8*Na&YF#KSVFmMrJJ4ZU
zQ9TxPAi9eJ71oa~HRJK<<G^&yu*-?v6N%Jp`Ft(A$lX^VzaqqCRMFLf{P=wi8zn;x
zSBClzvTV&_XKDqrFY72tumAY@<-U4f$@&)cl5qh5j6b8Ev$=_l3B&J_>9>!sADXgJ
z%i`FbSPz83r?Dp5bw9}0^rc;=O*vo|Wu;<`ENEqUr?JP}-DIJIcT`|QgtZ*a^RK2w
zs1R5uCkY-twvrRe`iYu}r&iVu(jIanOSz_9d-I<0OthbkvXCBc6(@n?NiY_Lf5NYK
z?O{epha?lVm}RoVN2I2k$%p?$+)WmO?*#e9!{T;3jy@0{vkx41g}<05-)JCO*0oF(
z_uN#FAs$A?V?Ep$M!!8%Y>p9ZaK$dL+-1a44b5L^MpCGERgW-60T9!r_w@4c_}-8I
zF7P#@?JKs==xcFwWGKK4$`JfBwv;tzRRj`u5y5ygsXq?|AwAh(*m-aUBxLeMY^=pF
zVSTGtZ7XB1b&$>QxYJ|j{@BSL<YqJdNu7B!V}s40tt-|GIiTJ}XZ?iZaV$gt1|ZaJ
zmgz)gl%v<S&*NkblZ?gI>9b%ri|#$_XN0is(qA2zmfvn(y$J<ohtr2j$-teN-t01=
zc8;2im1X6=aP$By-yo+Ppv12(petQGk6ffDA`PrI-?SMdXujt1jwnl2Q@72lleMA)
zar?l&0m#tlR<NvD1dkQ$cBuA!c$%~G!}g+#yl>6&PgYp7oU06&+j#w2O()Gvqz@IC
z=&*)9*+?NYm@gDcQDNl!ts|3sXatKvj*wr#=kEBhNTL+UFE_5k)(zs5;^OHT(#Pk^
ztALAJhV>4Qr$z$#5qA?yEly=~pUWR}mu3uk-uDlKgShS-V13L_$mH?33mdf#No3xE
znIIdCUOZ8K*!gv095IxV0X0+kkF;u&3#I@tges^x&b9GotpoqGQa6lVC<k^ENw9X@
z_ptVP$Sb57u5#*MHFhawW+VmN+3B`zLG3@`Eo%=u`f+cL5FF}wGO3uab@T2L1yUJ@
z9*`PAvzfXfD{ZyL1x70{8xG(bUje2=caRZM<{DUA15tC+GGd7)nozTzm&N1sbG!%%
zzDRa*0OnhQHQu5iqY2RzGb9W>=`A42g$&75Gao#gIrk9S(C|t`^2_+1C%f{29)u3C
z!D4-|UR2B!KE`E;Pf!x)FsT+R$hdGfdb&CKIXLzn6=DFPw}C9YRYWvrALJ9>j1Qg=
z`KsC3iMCGY6`bgm49jY&zvyZl3oobwcXic}XW(=_tFPE<j$7%ej>t#fM-_$^Z3Sn(
zb6%~rv3OUOO6og`l`>l|GPtQnhGqWr5)PtuD%=C8xtIK<SFgFXhP<ZgIcbm7g}bdf
z`c*PKyHnEO3y>^>W{Kh&W&RHPZafn)Tsi`D3MPi}FlBp1NaMvJ=tub4J0eIlei_+V
z<f)e9a9lLu`$eLx#!fM)T#84sQEjWnt;J+K0ML5hOnPb@i6pg&eRWsldv8aD*iVBN
zA|mVcP*DrU6j2e8UOL<fB4RTj2Br-{RH}VfLda9PS;(0HShyX>J07$C1-x!XbdPT*
zQ9o??X0igm$hB2v=xN)p%9UWC7VnlMQquKd2irG#jI`J?D3?v56=;-h0@uW<Lc%M|
z!Q|#L9Y$|;`ZjGr84uG*eW`Z78uvac7Gwb=EC%7f^G?2sX;R>r@aH=qCh6Wkq4n#V
z>L;H!>dAr0rL9=HsE=OokuLz(x`u}191}Oq!NGt9CYrlGEoe4pTs?)tCD~U(?+EZj
zc*kr(2`C3EBLJb{bz-a{$tjq(%#k#XZ0nKV+)PL4V9&`QFVTu=_qcRYv7DtY<7L#%
zis$!}aKuSI?DM-!u%qIWPp#Pdhbt>r6P}&MGt_Dwb@o!HovKz^VQDoTCUd?9C=>$U
z$rMmvTYaX}R<+b_M@|marX7<t>j%mQ&8gBLhHvRnSy?f>A3CT1c+cNeCC5~hNX@%B
z0j+n@=vW0_*Qk(&W-7xn%XFqGw{UY5t6r-m*Ja3IT|VvD8Y8vffZN!qT>qr^%#Q>c
zm6Vwj$G0)T;?C{|LAt!4*GKl1?NL}Tkvidaql`7R+Q8Cf)hb<N$__VNVo$H0-<)Hq
z!?bwy0FfHFZl$`USFe7Nm3xfjJz>!Zbt}6q8F*sbSD*E)R;+p19=X~8{;bxvwRG*d
z;M!K%x!NHR$Cl@Dp&6|HbLkoDpC(s}iE>2~Pyj&NTbTLx<jTp!+1bL@%;~of)1ayC
zw9Jm_yPolkgv(b=0tzmuR5?QoQz$oR%cD3w{sT``7;~W=L2^-z`*HpD+>~qFVQ^SZ
z&+x!|Khy~<{ON8+M3eS3+UBygRU?sO+|i({Vf^ROp5gsPkk<W(*zzIujF@gl)b4P@
zNZ#7ZC85BYoz{#?_dLCz*qrURD?^WiR?~XDro*1(Rv%@K5>We(%SvwNGiw#nHg<7i
z)RiORZuj&IKTjJ<Vo6hzG9L^*8s<!uYN;=0=WRO9JQHL)*7v_;yo{pWu(?X0XqFC6
ztE}of*vNwL&#HP2Wx39)`IfT-km?iLx|aKOHAlT~`#rw8o>^t_Nwp7j=;hbCST13r
zs$kX!dAP8Tb}C$%KO%h31#*4{b=ZP0FU`HIRu=41AX2(Kcj12eFo;W*cQjmIJwr-x
zy|dqqdSNrpt2miit=wZKu%zs<rl{RcF-Yp1a#jH}f|7-ypBZb*Dg%0|`}4#fK<rpD
zxi7rJX`jBrOV`|E;@&IkrbRu<8d<~6!7KaojJP2E=;pyjsC#KV1xi>Q8>Q&tA~awb
zs4lF6i$Kgj+LZFtv{~ROqxUI%fGg@5dmM|IBaaTsU>-6yt&S7B6*>dzt^#IqLd_Yu
zxtuxKpp+40AMLOu%(CUT)YgL%@@#US4Xo2jTfeh&LrjlKHK%J_0;#SJ>wx#Atw+wp
z6Lm1~{WG*o8M$|6jSLPm2|Rq}<;vmx#{7_IKzh?E-zUw3@%1>>CH$~w8OJ`IAL?|_
zxT?!>>P8hV1?98WLh1&E%20j#&3Nj5dzx<8K0jC-Os;YwoIRH@Tls>YzY}yDUGyAz
zhYw0(Hz$QbhCbfJpS9hV1Szr#az9Sgo>cw(rjz-!H`!6nf3?ecWDz4(b@hecRbFQ;
zHVnkNX1W;1?T&M!`grsTM_}pc8etkvhRO>!Yd_R7oS&=*9?`Z<8APbO)#hb5SoH?(
z2MJV+QE=C4P?r<n2!-|)68~Xy7TbhX6a{hk%*c8ugZk$lcbISeSs6U{O&iY0t(Q@c
zAR?bPf=$NqgKzjHCwOO??&lhT0366qaO7EQ;w}qwySpv7ukvljr9O}xc@;TWX9k{p
zHyzuG3uYGw7IC>KValnD?;O4)Q<9`BDN_kZv@5t%Ze9AzlJ4T5`a3ntbc0PuB&4?>
z(v#xj$a8tbB2$yR+sy6tk#^^eTQmzNnU**~mXO>kgf@vRbcNpL6}%MTjCnT;)~iW|
z5ecm>xe_FKhq_P_yz!a+=sZ2YQ&B=8)--^*#PHo_RWe8<Gy^mm`bD$7y=Vd%j6?7j
zKuo|$dc3)6OE!-oH(4HWCo;d~Ac8JNQD+MZ3~Gb$%8-i=>%1+=y8x2W(te?~1PD12
zMIPFG;!Z-$7Fyx@ZZc(lEn?aWZ{9+g7JvbC*f6OAjvP3eIfK2_Ds~J=X|A(_je;HV
zDF{|Vm=zl9)#UJ?NSuO>xFY7ZEBYml7F6$rO7J+o(1(q}6iRG!5g#zJd~+a#TZ^!l
z9CRY5ITYOHy*s>Ux2pfCifBA^Ls{?+VlH6<Ckp?4Fv*I<L}J<mEjCm@H_E0I()HM7
zdYC*cL&+MPD_Jxw>%86;8A0S70Rleja_2tRUG%NUmIEudZ+|azrKo`Gfp?B~EV6)L
zIkkN=R^dI&XLo}EDE??aXMun-DyVBBXfA7LiQqVOJ0h3{{LtWd@K`lNN^{YvTsWVt
zjrX3|C`bbGed#~JD{~aMMYmkZE-qRT$-R#XYGcEXKd4Y_i9#Gi$AP{l`fR6o@W4QX
zG7Gx2toQ@w$vHN^3SUKACWB@QHbQs&yiEf>1I-*Cu+?TRXN0)_j=s+$a9v>|a*t)j
zYLn~E=lu=Ldvm$%a7fr&*+eW7Txm=%bGc$LET~xyn8vJpSL1%4C+p-|JWfs$i><=@
zgoy3UB$5Kr4Y%EXa-{+u+2;4?xJ{z&O#Jt#AMfb7y^@em5zW8Sgn8W23HGqzb}3WB
z?t@xN^vDj0S*e7~B27MhMjqE%k=sEHG?fz@MVJaN8w#R9itL{xH(x<#1@rAvOMHJ3
zKXVP;<My%TaNWkQ>9Wj^S0lMdv|=P@?0T!!Z&CO59gi2@?p*ZQXeV%ws*dl})V>in
z05~gFu)*RA8CsLl=atC%XrQZO<>fTb<Dik8neogJ*ZOeFZR7{MuEm-1D$lx5)Hfxz
zw*Kjuq`s=EH-2@~ygaUy0xW$$S^LemtzIO1e6wZU`8<J-w@T;m(kt_e8e!A(e&du4
z7O<sL!<V~a>*L^EX~^o$`re)v$Jkv&R~s?bNTHt!Nrwhh7qg9B7-1V8w}Er_K{$ed
z^O7BAbLrO%akC{fez%eqGu$kTA2Qo4F?kk-B@wx<oNNP_9xh(B-a0o|KDy}F9mDh!
zcUYg8pihK2#AA`N6dbN4)AhKQzpf7OIwKF!o~1?shwGID1eZ2Os<85!qc%HESk?%R
zGqNVwj9X_ec?QjTMdk!9i~a0nojy;Vd|AoKd;iMDt+!*-#1;c=EkB8VX4DV1spIy6
z8iObgIK7DPW;3z&=?%l0v~}+cXz${9lx(8Ns?ki2EA+dEmGfE0pebqAVM-lR1;^UM
zxNfJ64JnK`dvZHkzW2*ndqMiA=+98PSZDh-{oHw514DV^_}^Gn1xGu3Ck7)sN0UDm
zrT<6lzs<h06aPZ&`)rZz7E^vG4s0z%MHM4*9moZiT!;Xd8~oyuSgC|`YqKsooLD<u
z`T4@BzX#Ro41<y@MuWzyFwrkScxsRLL7{6%kddY&D&&)Du+mjmJC?DO!M9@<_i!Sz
zpOaazl)*JP$eCelw}J>+@8C~I(U^ccbh24hz^o>+ZLr3k)c_>09l$xd6_7-og_*gD
zuE$mA{1xFbpyS84$fV8}kGrA09P(9txggvm5U?scIGd4Dkp^0;iae*ao?l>IG<ds!
z>If~?b%p-lvZqEJ)P*v(oepW*9v>i&TDJ=>*w_TKnaS-^I;|YndTZ4}H3e9X+G7HW
zL#_5dR+GjewzrYY(>*y=an>x>>YPUo>6>~#O-{cYjD-jA*>#F!0AmZr<QHArK;XP7
zG}H8}+vN%JQk_&v95RD1bkkR8w;yR+#<uS2HSJjaAR}i$Uny?<=?gBpX#L)L`o9;V
zf=j@k_}>gv=It{T^-m_m^eulv#lX<|cPnjAnzGGeL>F9te?l0)jt3u{EJm)H#J=>Y
z5=r^JO<b%|H!d*YBzO<)hUqb&^M}&|UK_S#k?EW;Auc-O?b6@^)Z^Aqz2vo2i@p>Y
zMaJGCqr@_{G>^#6Rk{h(9USSM%w(xL^pkX<wEEjK`Xh^yPizFyX{OZXk+4?fU(WEf
z7==b9Rb_;km9>!Js=03=rUW?Va8wIPQmfsEPsWj$a`O?3<O@F2ZYS%~w4%spajY#=
zfEOl~Y@{4oTvIh@9l8`_m<)7hiY@*G-*k+F8IU0A`JyIn;tC#hNbN|8O`yMkx{F3c
z00|ujK>KzY#*`Sl**7GD_z`Ja=H^`||3-UNI+(vfAF{*8u*C>du|PS2T_uY;>HzTd
zA+WJrFb=oRK#yh$=RB9kx$@FPXl(m2<Ch$?L*`EnO~@fTsmWBHPtV5}n@B&iRKz|p
z(;g@{-?yVhJAhA|TJlT>n)hYG=nNW9hq92kw;UH48>tTNregZIOS9U|PnEz=5Z5x%
zWEaw;!-idwTapSz78=*`ex$8#m4s$%`N()kqDa`&9HB56kjC_cAI3f2i8OlH<QPk~
z>d+JIHez{Jj+#?$L`)1FVGobiKN)*|mnXcGkqb8!%hNw3OS)s~p>GV5a7mUcz!50$
zGzcwe#Z`)TKW(RY26aDl2PeL#PvU4gaN^UA$;8HC8lUiqid$wpFFF`TPdtj#dyD`E
z688`(@it>W#7Af-D>tJrrK2a~5ZCnPA16eDJ+BvBZ$l#KThajfpVsDPVyOI=IZ^iX
zNBOrD4Zyh@T36q++W}Ese29=C`~a3wp|Ah+YJTkrUB_0p{Fx1?p}Rrn)$6n4f-CSl
zSC+RhQBWsxkpVU8Ij;2fLWsMcHev}$!DsI;w4Rjx1d_CSO&s+UcKX+_Og}$JX<Q`p
z=!VNiyU>##B5;a{RP<b$hV*<HnyE>Z3yHJgn>?_@82hGycI%j3lEKNii3?Hw&D>qE
z!)3z=ivdgnb82Q_)_FG5ssU0&6KYnl|C;l0o6F=W0%uiMaQwhOSoNJFQ&=>2WS@iu
zhvN-a`W4s!mSBm&!bCa&{BXj4EY%~|;xN;0#$}iBI3Uose<vO4L{~du=6+_$NP%Vq
zwM(&gA=}x0*%4^7fN+18?MF91#d!%K4Sx%Q7f7^hVnWBxFcHU_;MaNcg!fO5jqV;n
ztql(Vq`3e9Z{g`*3wut^9@Zwm&pg|6q@9*IQ3ubo8`lGhXHI)Aq=DPBoXSA7YF(@M
zxd|*>B4ow}@TgkxS4RBLphQ$cmVt&r*dI}&j9<^qpYY7XKl$EYv+Yi?q;R1vE}Fmg
ztx*<g(xRsF<;M8(>YRAL6Y~(N3${;~s-MCelj!n&*%$EjxKGBi%ic=>HNG!p<;NR~
zGQ6;G<A~d5CBKKN&ClTGLSrTmd7vb8Qzps#_EnB{8iMM3vV&Ut3BivO{5Z?#A0jCA
zI8ldKC}~t<utr@pRO+G$yH3C%yd`PErKtE};mGv87E9-EG<s4R!2Ta`Ae1Jx=q>3O
zgepcyxH!qo>+39j#oiE{y&#By4bGBk&Vj+q+HzVOL}~l%ZSpX3%)x4AOrlcGensWD
zC%QR0scm_VxQuw?Zx|o$DV0{=;ncjS&#Aqdy{M%5se!ShTwrmNk~26yE3S<^7(EX^
zxslhA#Od)T@S6S*nv?EPF8S8NKjFx(WJWn0b(xLwxU=w(&M&Zl1=JewFu?EBhrv5J
z63+WPI(ul=J0T7=SMXH58}Ph0R9vO*QqdWi^rMzbygr8zt<Bf0sB4cWZT+g?3-yt;
z=+5|#4&LefSmjF-w?XZbif-eSk(8m7eUjAe5pB+D<Xr?sl5h?u-pOI%Y!4yFZ6eH<
z1|N2AzDguH^KVs}iIbzPj9K-;FWECcB;=CjF4n7}`H#VBDOs*>H-~F4NG6i1tC@7o
z8_Vl)rtlwR@$7wEhSfswE??PdS_!pJ_LC3du}<trWUdv%!E6$=D{ahD@oYHM3t+ju
zs{;qlR41prFr1(CAadH(g$UQniGuEV;0!f|KhhBQ8UkGK1`EVl2Z`BP2MfsGt{87u
zaMnSl$*FgPoZ?RJ`p|o*M1SCh%<Bs{N8i|<-f;ECwfRV$Z`<a9JT)(abrQOHdEai^
zBJKOGoJ=jpwee|ex6CQgv??->MD|c;!6+IR<|_()44aWG(V#$r@0&>?ND;!t0Vs<B
zJxK^;q9X3weS)zQ9wzof<R(d&qD+6(CbJUiIAroESE1gAlSOPnfJ<p5PfwBZ8);4B
zq_9R=3<cmLe$x~$s*ouK8Q2Ttg*2L?g<0`IV3JhOKr~mvbfQDW)K@4aOEq+#1BbyR
zwAJKquVy7{rQ|9N&{*$<XX?Yv#ls#wpY7HUHG_m?;bp4v#w?4n)XL8-vk2g>D1kU?
zvh)r;YRbg?y#7||TW-<!coKlI6723ZSG(?acA5y+;Uv&ZfOeCP(g?ujU!C<Tnc_>>
zQB3^GJKgr}M5Ar&yCc2mPfR|}{f4m|g;%zfx_pHZUzR|6)zX@ZcWdib4GK%zKS96P
z4a0rvBDZS>J)5Q0s$Q?^`^1yvsMTQE`s$yBtfzLox@k!E^&AC=+KrLq!HCmf1Qxwv
z=h;}kibKL!Wy#fUNHcG*X(L{oKUbarVmU1KG>cM<^7*(4B8A$@%ku4m;MVpkWkaWZ
z(pVZLol-$k5rMzW5Nbf8!?1h7ndv<jOUoQ?;p=pMiv&?CX;cqF>wd6_!Ml5x_vFzM
zn`-YCkldQ4f;0{qRNQ2+H$o_36CjP|dBR>FK9s&9D)%_0u$tKgXn7Hs^9*;>Yx--J
zl0=Xpf1s1r90-&t3%&jLz>XnGVPJlnsMfTL&Wh|HJT2A;3zJWWf%Q@438sdZxm_UK
z*ptwLacl`^bmTCPm4G0pGlFtxZ{oI&Q9IhS#j>JrGgSWCs(EwfDQFQRn~`q^l+_i1
zqrKLuSs|ulhioF_Qd`MR@ADpe`{W6JZucB-Pe^tOuMQM@w?5x@K#)tphDqiwv9`54
z2%fcj!7`rx5VoGbE=S*Eobd-nGi(h?`L~nf?Igt3P=JE(f*A}%=tBEV;FktMXn|_f
zC~VUnToE2by@SKF%*N69>|m;2Fpv=tf@>D`k%T+zi<o^g)qrp)t`jEnif9rBt1k41
z9c`i=bveQh{<7ndt_)vg1PqDmj`&Xik{uJHeU-6((-!_hPC}emB$ND8)TnqP*N;G8
zMur43r21xVQu;WA{AcHeVViQ);o-pkYXa80vhoGYH9D_stSRHpm2W_%K`(8(EE(4^
zYp(zsAKw*Tmnl<M2{g45S+UI^@WHU>n6Yp@76LmCJ=t2TR0%#hgN(stI`xr3wvnXV
z)SA&aK04X&I`u!M`>;sz-iV103wN3n0<k@A(`=Ec1C?K05k3{0EF<$C;)+=*MT~E2
zoOz3!UCl%<cjmdT++bt0P+@bmP<6QMiaW#naC;cNN)Cg`ENS1(0V6uinlq^$y4R*E
z<2z_%kbe-EbS_du*OV(#8#j1mFqkilZX@&x!{aD)TX7)ugd*Z7R3~%HED}!4n&x3|
zLFoue#tVp5vls6cqcM+*Qkz_RuO$>I-+)^KYftLQ0JQ?$pg;^tHw!`o!2wFHqJK)R
zA}IuiK{6>E@^)tv6#l)6c^n#b!z~K+r#om2rGJ&bAymQze}C*+XPIZLBN&#-yg(RS
z>oalyW|<}fA~JQuAPmOR;~T>JulJ}$^Fv@!etT5vbN7n$=lDR(Ka14j7VqIOmbQao
zPki1W{K6sVzgO+g7yVWr;{UGVSd%%}8^l34<mNXBVSzC0@3r_-?Y}C8O3iqSO8x1N
zmy0gkRdm5RuQGSWtzSE@`K-N`m$xc)Eypn}f9`wvT%u;H_WF3l5bPeQMcB&2dM_>j
zo#jX|irKjRXqshpiXrH8asOQRc!80{e;y)o?eo0HqYNOtZ3OqC-mW6H(+(uFTVb2F
zk*+y<=O*@X8C51|yDHzxd2yw(poCO^1;dnf+b7IJy#Y9CfaUhpd<6N%Ufmc7Zvf@?
z)oA3La=OQ3=HauM06v3VJ9u!_ra6k-N^q3{jL%%K5oL6zoD<rE=Y;IRu{a0FuKat*
zGYt;d69bNK6LSit8tRX5bF$s7xTx(q2#haPp_F#&BFTB>2KxPPWi?edNaMDFY2_dT
z>vPDvCzjzqo!GL!)l`LoSCkWj93KUs)uC;ly%oE%iQc#1(x3kOmZjvmBU|@f8*X8{
zE`p+O6{IHf(p<d13mcifE&_~R6(qLb+l!jYiOWXjOtDPH<|vW0_nO7hO~SL{=|ptw
zf$)5F<ReQg+I7&mi>Ozs+fF(_W1g|MR`78YRO79JCky0Yw;QceHiWHG3aD?_6|?`@
zlr%an-I$S7?thDwssR&en}3Nv8sxC3R9gOrNL-$4w*E5q7XkL(`2Aap-%4lR#PErw
z4sdqwZ(_%pjb8ic-@>sCH;t~b<!|DbN}MLcz@2j!eULIn3GupJWE<Xxz<Js0Ak6sG
zvN6FL(aU~~IrnWftufDc+WK<a?&v}II>Yy|>AG1-spGi;G84`&aaW$z!bmsi^UGq{
zL(LcaXP3%*FU4nq1vu&cDBosH*tPW8?W>7qE=G*6?Ny~r%au_f7%}^0B@WM+?<K^}
zAk4}Z!ewR;K~=tAII1fb&vn~WRq56q?H{!^>Qz~ues(AbnO4*$B~x;}v3=`K4Ef{p
z+RE56ab-OZv1f-Qa@cdFF3XxStDjQT$=rS)xVlK^<_tGGlV>y)b5_?`>_EPA3RJEM
z?Kh-Rbn}3;9jCnU<#7o|bT`*IP_cRf4BN~_I%3RA)BAgR=>@ANRU4U0sj98$jtTEo
zy0!@BEv`#8%9JChx7!e51%tR>*amHO$P-+mHkxZ(Xq-x*#K~tnwlD6k^5+FB586FR
zbaX{brNYb1kfQSwwqizfV&Kr?*>mbOPsYX>_lrI~Z~<`Xw1HDJcn<mXZb!8T=3WyN
zba?h7=Ijeeift_Fmn!R)Z8=J>KMX2LH}@ioqGqBPOvg-ot0rZp%t#F>4odjO&Y%#@
z)%EJkO7h}Dm@qqI8tkOQf}5`OT3fLRbKS0{52x;q`mO1{cd%Mjdn{@ka-^siV7nS#
zs=wU7{v*Ml)3){9^=-=c?TutW{woV+U~m6F66~$Z{y4IgekZ}&NiUETPb-xLAqpyK
zW?>yR$k`_AP3%zN-f~-;3jHQR8;Ha4xK2hr2U+m?e%7-s5{S%>)Bjv-7-DIdrm{H}
zdr@1HxBW>=VUWT&zC|LSKbrRR1g{r#iJdr*o)8=p)&604of*?4s4`sHQu|1SzJUY<
zp3UiP-#}H)N~1Yi8)YO{-$bxlLFSzh;~9qC?O|8px8d=R-V8{&SDeY;JxNi2?%Phw
zq)5}%1cXeJ8%V8^<e~5Z+%eb&Vvpgzx8{>{b%M{U*I0@oGf#out1>~c_uB7wOev9R
z(fLg?Hy@NGcX&UJwR-4plM3RnQ@RP2f-(5V5c66}-_CUS2n_^&4muy3TJ_f_4e7xs
z-cMmf33x`Xaje8j-TAJNuqNSsS*-0A#TolVAwk^4&4$N7rrF%ui8F}rqAx;A{Zl{#
z8`?cz09B?`z8)y<!hP8^MR(rem+8%(hk4~=_oH9&baU*S;jP#IMTUWZ(!Eg;|Gbsx
z&;RDn>pyHPQjq?;g1>Kk_!IcsHR+A>_{%nkUx9zm2>&av{w-1I|Cb;BtEOL5djF$~
z7v>)le1C=inj7^WI5YAe@Lw~fepT`7y7zxnWMKZuMEr&E`4#?m;`~40H!_0&0QfH&
z{a5&}l;(dF@Dl&=_P-IFzv6!-ss4j6BmD#a3uX1IhF`gt|7gG<|Fix7W@3H?|9!yx
l4-^2%dCSrMckBNcJ{6=P-pu2-O*U|Vp0^?P1M6?U{vYKtL@fXS

literal 0
HcmV?d00001

diff --git a/test/docx/nested_instrText.native b/test/docx/nested_instrText.native
new file mode 100644
index 000000000..730b041f5
--- /dev/null
+++ b/test/docx/nested_instrText.native
@@ -0,0 +1,5 @@
+[Para [Str "\24076\26395\28145\20837\20102\35299\30340\35835\32773\21487\20197\21435\30475David",Space,Str "French",Space,Str "Belding\21644Kevin",Space,Str "J.",Space,Str "Mitchell\30340"
+    ,Link ("",[],[]) [Str "Foundations",Space,Str "of",Space,Str "Analysis,",Space,Str "1/16/18",Space,Str "8:40:00",Space,Str "AM,",Space,Str "2nd",Space,Str "Edition"] ("https://books.google.com/books?id=sp_Zcb9ot90C&lpg=PR4&hl=zh-CN&pg=PA19#v=onepage&q&f=true","")
+    ,Str ",\21487\20174\&19\39029\30475\36215\65292\25110D.C.",Space,Str "Goldrei\30340",Space
+    ,Link ("",[],[]) [Str "Classic",Space,Str "Set",Space,Str "Theory:",Space,Str "For",Space,Str "Guided",Space,Str "Independent",Space,Str "Study"] ("https://books.google.ae/books?id=dlc0DwAAQBAJ&lpg=PT29&hl=zh-CN&pg=PT26#v=onepage&q&f=true","")
+    ,Str "\65292\20174\31532\20108\31456\30475\36215\65292\38405\35835\26102\35201\27880\24847\26412\25991\19982\36825\20123\20070\25152\19981\21516\30340\26159\24182\27809\26377\25226\23454\25968\30475\20316\26159\26377\29702\25968\38598\30340\20998\21106\12290"]]