<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE bugzilla SYSTEM "https://bugs.webkit.org/page.cgi?id=bugzilla.dtd">

<bugzilla version="5.0.4.1"
          urlbase="https://bugs.webkit.org/"
          
          maintainer="admin@webkit.org"
>

    <bug>
          <bug_id>205203</bug_id>
          
          <creation_ts>2019-12-13 01:08:46 -0800</creation_ts>
          <short_desc>TextManipulationController should observe newly inserted or displayed contents</short_desc>
          <delta_ts>2019-12-16 14:37:17 -0800</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>1</classification_id>
          <classification>Unclassified</classification>
          <product>WebKit</product>
          <component>HTML Editing</component>
          <version>WebKit Nightly Build</version>
          <rep_platform>Unspecified</rep_platform>
          <op_sys>Unspecified</op_sys>
          <bug_status>RESOLVED</bug_status>
          <resolution>FIXED</resolution>
          
          
          <bug_file_loc></bug_file_loc>
          <status_whiteboard></status_whiteboard>
          <keywords>InRadar</keywords>
          <priority>P2</priority>
          <bug_severity>Normal</bug_severity>
          <target_milestone>---</target_milestone>
          
          
          <everconfirmed>1</everconfirmed>
          <reporter name="Ryosuke Niwa">rniwa</reporter>
          <assigned_to name="Ryosuke Niwa">rniwa</assigned_to>
          <cc>cdumez</cc>
    
    <cc>dbates</cc>
    
    <cc>esprehn+autocc</cc>
    
    <cc>ews-watchlist</cc>
    
    <cc>glenn</cc>
    
    <cc>kangil.han</cc>
    
    <cc>kondapallykalyan</cc>
    
    <cc>llivonbemel</cc>
    
    <cc>mifenton</cc>
    
    <cc>pdr</cc>
    
    <cc>simon.fraser</cc>
    
    <cc>webkit-bug-importer</cc>
    
    <cc>wenson_hsieh</cc>
          

      

      

      

          <comment_sort_order>oldest_to_newest</comment_sort_order>  
          <long_desc isprivate="0" >
    <commentid>1598281</commentid>
    <comment_count>0</comment_count>
    <who name="Ryosuke Niwa">rniwa</who>
    <bug_when>2019-12-13 01:08:46 -0800</bug_when>
    <thetext>When new content is inserted by DOM API or the exiting content gets newly rendered,
TextManipulationController should inform of its clients.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1598283</commentid>
    <comment_count>1</comment_count>
      <attachid>385585</attachid>
    <who name="Ryosuke Niwa">rniwa</who>
    <bug_when>2019-12-13 01:10:25 -0800</bug_when>
    <thetext>Created attachment 385585
WIP</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1598284</commentid>
    <comment_count>2</comment_count>
    <who name="Ryosuke Niwa">rniwa</who>
    <bug_when>2019-12-13 01:11:19 -0800</bug_when>
    <thetext>&lt;rdar://problem/56567020&gt;</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1598587</commentid>
    <comment_count>3</comment_count>
    <who name="Ryosuke Niwa">rniwa</who>
    <bug_when>2019-12-13 18:41:31 -0800</bug_when>
    <thetext>I need to do this in more than one piece.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1598593</commentid>
    <comment_count>4</comment_count>
      <attachid>385669</attachid>
    <who name="Ryosuke Niwa">rniwa</who>
    <bug_when>2019-12-13 19:09:39 -0800</bug_when>
    <thetext>Created attachment 385669
Adds the feature</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1598878</commentid>
    <comment_count>5</comment_count>
      <attachid>385669</attachid>
    <who name="Wenson Hsieh">wenson_hsieh</who>
    <bug_when>2019-12-16 07:33:57 -0800</bug_when>
    <thetext>Comment on attachment 385669
Adds the feature

View in context: https://bugs.webkit.org/attachment.cgi?id=385669&amp;action=review

&gt; Source/WebCore/ChangeLog:14
&gt; +        a newly inserted content, we scheudle a new event loop task to do this work.

Nit - scheudle

&gt; Source/WebCore/editing/TextManipulationController.cpp:131
&gt; +    if (document != start.deepEquivalent().document() || document != end.deepEquivalent().document())

Is it worth keeping the null check for the case where start and end positions are null?

&gt; Tools/ChangeLog:9
&gt; +        Added tests for detectign newly inserted or displayed contents in WKTextManipulation SPI.

Nit - detectign</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1598931</commentid>
    <comment_count>6</comment_count>
      <attachid>385669</attachid>
    <who name="Louie Livon-Bemel">llivonbemel</who>
    <bug_when>2019-12-16 09:38:06 -0800</bug_when>
    <thetext>Comment on attachment 385669
Adds the feature

&gt;Subversion Revision: 253360
&gt;diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
&gt;index 7c2d81ccf1bf23a204a5c07ace81710a33b39ef3..947c75e2eb18ef84b46972d7a1927bd9de0ccadf 100644
&gt;--- a/Source/WebCore/ChangeLog
&gt;+++ b/Source/WebCore/ChangeLog
&gt;@@ -1,3 +1,41 @@
&gt;+2019-12-13  Ryosuke Niwa  &lt;rniwa@webkit.org&gt;
&gt;+
&gt;+        TextManipulationController should observe newly inserted or displayed contents
&gt;+        https://bugs.webkit.org/show_bug.cgi?id=205203
&gt;+        &lt;rdar://problem/56567020&gt;
&gt;+
&gt;+        Reviewed by NOBODY (OOPS!).
&gt;+
&gt;+        This patch makes TextManipulationController detect newly inserted or displayed contents and invoke
&gt;+        the callbacks with the newly found items.
&gt;+
&gt;+        To do this, we add a new WeakHashSet to TextManipulationController to which an element is added
&gt;+        whenever its renderer is created. Because it&apos;s expensive (and not safe) to find paragraphs around
&gt;+        a newly inserted content, we scheudle a new event loop task to do this work.
Typo: scheudle -&gt; schedule
&gt;+
&gt;+        To find newly inserted paragraphs, we first expand the element&apos;s boundary to its start and end of
&gt;+        paragraphs. Because each element in this paragraph could have been added in the weak hash set, we
&gt;+        use hash map to de-duplicate start and end positions. We also filter out any element whose parent
&gt;+        is also in the weak hash set since they would simply find inner paragraphs.
&gt;+
&gt;+        Tests: TextManipulation.StartTextManipulationFindNewlyInsertedParagraph
&gt;+               TextManipulation.StartTextManipulationFindNewlyDisplayedParagraph
&gt;+               TextManipulation.StartTextManipulationFindSameParagraphWithNewContent
&gt;+
&gt;+        * dom/TaskSource.h:
&gt;+        (WebCore::TaskSource::InternalAsyncTask): Added.
&gt;+        * editing/TextManipulationController.cpp:
&gt;+        (WebCore::TextManipulationController::startObservingParagraphs):
&gt;+        (WebCore::TextManipulationController::observeParagraphs): Extracted out of startObservingParagraphs.
&gt;+        (WebCore::TextManipulationController::didCreateRendererForElement): Added. Gets called whenever
&gt;+        a new RenderElement is created.
&gt;+        (WebCore::makePositionTuple): Added.
&gt;+        (WebCore::makeHashablePositionRange): Added.
&gt;+        (WebCore::TextManipulationController::scheduleObservartionUpdate): Added.
&gt;+        * editing/TextManipulationController.h:
&gt;+        * rendering/updating/RenderTreeUpdater.cpp:
&gt;+        (WebCore::RenderTreeUpdater::createRenderer):
&gt;+
&gt; 2019-12-10  Fujii Hironori  &lt;Hironori.Fujii@sony.com&gt;
&gt; 
&gt;         [Win] Fix MSVC warning C4701: potentially uninitialized local variable &apos;x&apos; used
&gt;diff --git a/Source/WebCore/dom/TaskSource.h b/Source/WebCore/dom/TaskSource.h
&gt;index 143885c5b8844e2e8060ed7779508a4e61c1b752..c974d94db870e8c2f0c77d1142dd1e9973ae8619 100644
&gt;--- a/Source/WebCore/dom/TaskSource.h
&gt;+++ b/Source/WebCore/dom/TaskSource.h
&gt;@@ -36,7 +36,10 @@ enum class TaskSource : uint8_t {
&gt;     Microtask,
&gt;     Networking,
&gt;     PostedMessageQueue,
&gt;-    UserInteraction
&gt;+    UserInteraction,
&gt;+
&gt;+    // Internal to WebCore
&gt;+    InternalAsyncTask, // Safe to re-order or delay.
&gt; };
&gt; 
&gt; } // namespace WebCore
&gt;diff --git a/Source/WebCore/editing/TextManipulationController.cpp b/Source/WebCore/editing/TextManipulationController.cpp
&gt;index d2e39f7bdf3e5a6bf8b0090cec49a0c0f018143e..e17bdec145b0875bc57666b25b6e4fc2771bfd09 100644
&gt;--- a/Source/WebCore/editing/TextManipulationController.cpp
&gt;+++ b/Source/WebCore/editing/TextManipulationController.cpp
&gt;@@ -29,6 +29,7 @@
&gt; #include &quot;CharacterData.h&quot;
&gt; #include &quot;Editing.h&quot;
&gt; #include &quot;ElementAncestorIterator.h&quot;
&gt;+#include &quot;EventLoop.h&quot;
&gt; #include &quot;ScriptDisallowedScope.h&quot;
&gt; #include &quot;TextIterator.h&quot;
&gt; #include &quot;VisibleUnits.h&quot;
&gt;@@ -118,9 +119,17 @@ void TextManipulationController::startObservingParagraphs(ManipulationItemCallba
&gt; 
&gt;     VisiblePosition start = firstPositionInNode(m_document.get());
&gt;     VisiblePosition end = lastPositionInNode(m_document.get());
&gt;+
&gt;+    observeParagraphs(start, end);
&gt;+}
&gt;+
&gt;+void TextManipulationController::observeParagraphs(VisiblePosition&amp; start, VisiblePosition&amp; end)
&gt;+{
&gt;+    auto document = makeRefPtr(start.deepEquivalent().document());
&gt;+    ASSERT(document);
&gt;     TextIterator iterator { start.deepEquivalent(), end.deepEquivalent() };
&gt;-    if (!document)
&gt;-        return; // VisiblePosition or TextIterator&apos;s constructor may have updated the layout and executed arbitrary scripts.
&gt;+    if (document != start.deepEquivalent().document() || document != end.deepEquivalent().document())
&gt;+        return; // TextIterator&apos;s constructor may have updated the layout and executed arbitrary scripts.
&gt; 
&gt;     ExclusionRuleMatcher exclusionRuleMatcher(m_exclusionRules);
&gt;     Vector&lt;ManipulationToken&gt; tokensInCurrentParagraph;
&gt;@@ -163,6 +172,65 @@ void TextManipulationController::startObservingParagraphs(ManipulationItemCallba
&gt;         addItem(startOfCurrentParagraph, end.deepEquivalent(), WTFMove(tokensInCurrentParagraph));
&gt; }
&gt; 
&gt;+void TextManipulationController::didCreateRendererForElement(Element&amp; element)
&gt;+{
&gt;+    if (m_mutatedElements.computesEmpty())
&gt;+        scheduleObservartionUpdate();
&gt;+    m_mutatedElements.add(element);
&gt;+}
&gt;+
&gt;+using PositionTuple = std::tuple&lt;RefPtr&lt;Node&gt;, unsigned, unsigned&gt;;
&gt;+static const PositionTuple makePositionTuple(const Position&amp; position)
&gt;+{
&gt;+    return { position.anchorNode(), static_cast&lt;unsigned&gt;(position.anchorType()), position.anchorType() == Position::PositionIsOffsetInAnchor ? position.offsetInContainerNode() : 0 }; 
&gt;+}
&gt;+
&gt;+static const std::pair&lt;PositionTuple, PositionTuple&gt; makeHashablePositionRange(const VisiblePosition&amp; start, const VisiblePosition&amp; end)
&gt;+{
&gt;+    return { makePositionTuple(start.deepEquivalent()), makePositionTuple(end.deepEquivalent()) };
&gt;+}
&gt;+
&gt;+void TextManipulationController::scheduleObservartionUpdate()
&gt;+{
&gt;+    if (!m_document)
&gt;+        return;
&gt;+
&gt;+    m_document-&gt;eventLoop().queueTask(TaskSource::InternalAsyncTask, [weakThis = makeWeakPtr(*this)] {
&gt;+        auto* controller = weakThis.get();
&gt;+        if (!controller)
&gt;+            return;
&gt;+
&gt;+        HashSet&lt;Ref&lt;Element&gt;&gt; mutatedElements;
&gt;+        for (auto&amp; weakElement : controller-&gt;m_mutatedElements)
&gt;+            mutatedElements.add(weakElement);
&gt;+        controller-&gt;m_mutatedElements.clear();
&gt;+
&gt;+        HashSet&lt;Ref&lt;Element&gt;&gt; filteredElements;
&gt;+        for (auto&amp; element : mutatedElements) {
&gt;+            auto* parentElement = element-&gt;parentElement();
&gt;+            if (!parentElement || !mutatedElements.contains(parentElement))
&gt;+                filteredElements.add(element.copyRef());
&gt;+        }
&gt;+        mutatedElements.clear();
&gt;+
&gt;+        HashSet&lt;std::pair&lt;PositionTuple, PositionTuple&gt;&gt; paragraphSets;
&gt;+        for (auto&amp; element : filteredElements) {
&gt;+            auto start = startOfParagraph(firstPositionInOrBeforeNode(element.ptr()));
&gt;+            auto end = endOfParagraph(lastPositionInOrAfterNode(element.ptr()));
&gt;+
&gt;+            auto key = makeHashablePositionRange(start, end);
&gt;+            if (!paragraphSets.add(key).isNewEntry)
&gt;+                continue;
&gt;+
&gt;+            auto* controller = weakThis.get();
&gt;+            if (!controller)
&gt;+                return; // Finding the start/end of paragraph may have updated layout &amp; executed arbitrary scripts.
&gt;+
&gt;+            controller-&gt;observeParagraphs(start, end);
&gt;+        }
&gt;+    });
&gt;+}
&gt;+
&gt; void TextManipulationController::addItem(const Position&amp; startOfParagraph, const Position&amp; endOfParagraph, Vector&lt;ManipulationToken&gt;&amp;&amp; tokens)
&gt; {
&gt;     ASSERT(m_document);
&gt;diff --git a/Source/WebCore/editing/TextManipulationController.h b/Source/WebCore/editing/TextManipulationController.h
&gt;index 372cd64ea4fdc6aea60ac78007a392c4e6dbdf85..78a187e7c3d3b0693df2616bd7617beb2bd38550 100644
&gt;--- a/Source/WebCore/editing/TextManipulationController.h
&gt;+++ b/Source/WebCore/editing/TextManipulationController.h
&gt;@@ -30,11 +30,14 @@
&gt; #include &lt;wtf/EnumTraits.h&gt;
&gt; #include &lt;wtf/ObjectIdentifier.h&gt;
&gt; #include &lt;wtf/Optional.h&gt;
&gt;+#include &lt;wtf/WeakHashSet.h&gt;
&gt; #include &lt;wtf/WeakPtr.h&gt;
&gt; 
&gt; namespace WebCore {
&gt; 
&gt; class Document;
&gt;+class Element;
&gt;+class VisiblePosition;
&gt; 
&gt; class TextManipulationController : public CanMakeWeakPtr&lt;TextManipulationController&gt; {
&gt;     WTF_MAKE_FAST_ALLOCATED;
&gt;@@ -93,6 +96,8 @@ public:
&gt;     using ManipulationItemCallback = WTF::Function&lt;void(Document&amp;, ItemIdentifier, const Vector&lt;ManipulationToken&gt;&amp;)&gt;;
&gt;     WEBCORE_EXPORT void startObservingParagraphs(ManipulationItemCallback&amp;&amp;, Vector&lt;ExclusionRule&gt;&amp;&amp; = { });
&gt; 
&gt;+    void didCreateRendererForElement(Element&amp;);
&gt;+
&gt;     enum class ManipulationResult : uint8_t {
&gt;         Success,
&gt;         ContentChanged,
&gt;@@ -103,6 +108,9 @@ public:
&gt;     WEBCORE_EXPORT ManipulationResult completeManipulation(ItemIdentifier, const Vector&lt;ManipulationToken&gt;&amp;);
&gt; 
&gt; private:
&gt;+    void observeParagraphs(VisiblePosition&amp; start, VisiblePosition&amp; end);
&gt;+    void scheduleObservartionUpdate();
&gt;+
&gt;     struct ManipulationItem {
&gt;         Position start;
&gt;         Position end;
&gt;@@ -113,6 +121,7 @@ private:
&gt;     ManipulationResult replace(const ManipulationItem&amp;, const Vector&lt;ManipulationToken&gt;&amp;);
&gt; 
&gt;     WeakPtr&lt;Document&gt; m_document;
&gt;+    WeakHashSet&lt;Element&gt; m_mutatedElements;
&gt;     ManipulationItemCallback m_callback;
&gt;     Vector&lt;ExclusionRule&gt; m_exclusionRules;
&gt;     HashMap&lt;ItemIdentifier, ManipulationItem&gt; m_items;
&gt;diff --git a/Source/WebCore/rendering/updating/RenderTreeUpdater.cpp b/Source/WebCore/rendering/updating/RenderTreeUpdater.cpp
&gt;index 3656f3bfaaff3549b6830040a8e2b86c2cafc009..231bb08736441b7f208f7373d9200d200a3a4a33 100644
&gt;--- a/Source/WebCore/rendering/updating/RenderTreeUpdater.cpp
&gt;+++ b/Source/WebCore/rendering/updating/RenderTreeUpdater.cpp
&gt;@@ -49,6 +49,7 @@
&gt; #include &quot;RuntimeEnabledFeatures.h&quot;
&gt; #include &quot;StyleResolver.h&quot;
&gt; #include &quot;StyleTreeResolver.h&quot;
&gt;+#include &quot;TextManipulationController.h&quot;
&gt; #include &lt;wtf/SystemTracing.h&gt;
&gt; 
&gt; #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
&gt;@@ -397,6 +398,10 @@ void RenderTreeUpdater::createRenderer(Element&amp; element, RenderStyle&amp;&amp; style)
&gt; 
&gt;     m_builder.attach(insertionPosition, WTFMove(newRenderer));
&gt; 
&gt;+    auto* textManipulationController = m_document.textManipulationControllerIfExists();
&gt;+    if (UNLIKELY(textManipulationController))
&gt;+        textManipulationController-&gt;didCreateRendererForElement(element);
&gt;+
&gt;     if (AXObjectCache* cache = m_document.axObjectCache())
&gt;         cache-&gt;updateCacheAfterNodeIsAttached(&amp;element);
&gt; }
&gt;diff --git a/Tools/ChangeLog b/Tools/ChangeLog
&gt;index 00dabe73f48c3cee3417d3a8675f40f9838481d2..786e8d14261c05f0fffa043230ee293dd10fdba6 100644
&gt;--- a/Tools/ChangeLog
&gt;+++ b/Tools/ChangeLog
&gt;@@ -1,3 +1,18 @@
&gt;+2019-12-13  Ryosuke Niwa  &lt;rniwa@webkit.org&gt;
&gt;+
&gt;+        TextManipulationController should observe newly inserted or displayed contents
&gt;+        https://bugs.webkit.org/show_bug.cgi?id=205203
&gt;+        &lt;rdar://problem/56567020&gt;
&gt;+
&gt;+        Reviewed by NOBODY (OOPS!).
&gt;+
&gt;+        Added tests for detectign newly inserted or displayed contents in WKTextManipulation SPI.
Typo: detectign -&gt; detecting
&gt;+
&gt;+        * TestWebKitAPI/Tests/WebKitCocoa/TextManipulation.mm:
&gt;+        (-[TextManipulationDelegate initWithItemCallback]):
&gt;+        (-[TextManipulationDelegate _webView:didFindTextManipulationItem:]):
&gt;+        (TestWebKitAPI::TEST):
&gt;+
&gt; 2019-12-10  Per Arne Vollan  &lt;pvollan@apple.com&gt;
&gt; 
&gt;         Fix API test failure after r253351
&gt;diff --git a/Tools/TestWebKitAPI/Tests/WebKitCocoa/TextManipulation.mm b/Tools/TestWebKitAPI/Tests/WebKitCocoa/TextManipulation.mm
&gt;index d707598fdc7e8822bcf314f98a1d39f995504c75..94f9cdddc776da1f4edfe2cef41a238ed228e59b 100644
&gt;--- a/Tools/TestWebKitAPI/Tests/WebKitCocoa/TextManipulation.mm
&gt;+++ b/Tools/TestWebKitAPI/Tests/WebKitCocoa/TextManipulation.mm
&gt;@@ -39,11 +39,14 @@
&gt; 
&gt; static bool done = false;
&gt; 
&gt;+typedef void(^ItemCallback)(_WKTextManipulationItem *);
&gt;+
&gt; @interface TextManipulationDelegate : NSObject &lt;_WKTextManipulationDelegate&gt;
&gt; 
&gt; - (void)_webView:(WKWebView *)webView didFindTextManipulationItem:(_WKTextManipulationItem *)item;
&gt; 
&gt; @property (nonatomic, readonly, copy) NSArray&lt;_WKTextManipulationItem *&gt; *items;
&gt;+@property (strong) ItemCallback itemCallback;
&gt; 
&gt; @end
&gt; 
&gt;@@ -59,9 +62,19 @@ static bool done = false;
&gt;     return self;
&gt; }
&gt; 
&gt;+- (instancetype)initWithItemCallback
&gt;+{
&gt;+    if (!(self = [super init]))
&gt;+        return nil;
&gt;+    _items = adoptNS([[NSMutableArray alloc] init]);
&gt;+    return self;
&gt;+}
&gt;+
&gt; - (void)_webView:(WKWebView *)webView didFindTextManipulationItem:(_WKTextManipulationItem *)item
&gt; {
&gt;     [_items addObject:item];
&gt;+    if (self.itemCallback)
&gt;+        self.itemCallback(item);
&gt; }
&gt; 
&gt; - (NSArray&lt;_WKTextManipulationItem *&gt; *)items
&gt;@@ -170,6 +183,125 @@ TEST(TextManipulation, StartTextManipulationFindParagraphsWithMultileTokens)
&gt;     EXPECT_STREQ(&quot;Kit&quot;, items[1].tokens[1].content.UTF8String);
&gt; }
&gt; 
&gt;+TEST(TextManipulation, StartTextManipulationFindNewlyInsertedParagraph)
&gt;+{
&gt;+    auto delegate = adoptNS([[TextManipulationDelegate alloc] init]);
&gt;+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 400, 400)]);
&gt;+    [webView _setTextManipulationDelegate:delegate.get()];
&gt;+
&gt;+    [webView synchronouslyLoadHTMLString:@&quot;&lt;!DOCTYPE html&gt;&lt;html&gt;&lt;body&gt;&lt;p&gt;hello&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;&quot;];
&gt;+
&gt;+    done = false;
&gt;+    [webView _startTextManipulationsWithConfiguration:nil completion:^{
&gt;+        done = true;
&gt;+    }];
&gt;+    TestWebKitAPI::Util::run(&amp;done);
&gt;+
&gt;+    __block auto *items = [delegate items];
&gt;+    EXPECT_EQ(items.count, 1UL);
&gt;+    EXPECT_EQ(items[0].tokens.count, 1UL);
&gt;+    EXPECT_STREQ(&quot;hello&quot;, items[0].tokens[0].content.UTF8String);
&gt;+
&gt;+    done = false;
&gt;+    delegate.get().itemCallback = ^(_WKTextManipulationItem *item) {
&gt;+        if (items.count == 3)
&gt;+            done = true;
&gt;+    };
&gt;+    [webView stringByEvaluatingJavaScript:@&quot;document.body.appendChild(document.createElement(&apos;div&apos;)).innerHTML = &apos;world&lt;br&gt;&lt;b&gt;Web&lt;/b&gt;Kit&apos;;&quot;];
&gt;+    TestWebKitAPI::Util::run(&amp;done);
&gt;+
&gt;+    EXPECT_EQ(items.count, 3UL);
&gt;+    EXPECT_EQ(items[1].tokens.count, 1UL);
&gt;+    EXPECT_STREQ(&quot;world&quot;, items[1].tokens[0].content.UTF8String);
&gt;+    EXPECT_EQ(items[2].tokens.count, 2UL);
&gt;+    EXPECT_STREQ(&quot;Web&quot;, items[2].tokens[0].content.UTF8String);
&gt;+    EXPECT_STREQ(&quot;Kit&quot;, items[2].tokens[1].content.UTF8String);
&gt;+}
&gt;+
&gt;+TEST(TextManipulation, StartTextManipulationFindNewlyDisplayedParagraph)
&gt;+{
&gt;+    auto delegate = adoptNS([[TextManipulationDelegate alloc] init]);
&gt;+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 400, 400)]);
&gt;+    [webView _setTextManipulationDelegate:delegate.get()];
&gt;+
&gt;+    [webView synchronouslyLoadHTMLString:@&quot;&lt;!DOCTYPE html&gt;&lt;html&gt;&lt;body&gt;&quot;
&gt;+        &quot;&lt;style&gt; .hidden { display: none; } &lt;/style&gt;&quot;
&gt;+        &quot;&lt;p&gt;hello&lt;/p&gt;&lt;div&gt;&lt;span class=&apos;hidden&apos;&gt;Web&lt;/span&gt;&lt;span class=&apos;hidden&apos;&gt;Kit&lt;/span&gt;&lt;/div&gt;&lt;div class=&apos;hidden&apos;&gt;hey&lt;/div&gt;&lt;/body&gt;&lt;/html&gt;&quot;];
&gt;+
&gt;+    done = false;
&gt;+    [webView _startTextManipulationsWithConfiguration:nil completion:^{
&gt;+        done = true;
&gt;+    }];
&gt;+    TestWebKitAPI::Util::run(&amp;done);
&gt;+
&gt;+    __block auto *items = [delegate items];
&gt;+    EXPECT_EQ(items.count, 1UL);
&gt;+    EXPECT_EQ(items[0].tokens.count, 1UL);
&gt;+    EXPECT_STREQ(&quot;hello&quot;, items[0].tokens[0].content.UTF8String);
&gt;+
&gt;+    done = false;
&gt;+    delegate.get().itemCallback = ^(_WKTextManipulationItem *item) {
&gt;+        if (items.count == 2)
&gt;+            done = true;
&gt;+    };
&gt;+    [webView stringByEvaluatingJavaScript:@&quot;document.querySelectorAll(&apos;span.hidden&apos;).forEach((span) =&gt; span.classList.remove(&apos;hidden&apos;));&quot;];
&gt;+    TestWebKitAPI::Util::run(&amp;done);
&gt;+
&gt;+    EXPECT_EQ(items.count, 2UL);
&gt;+    EXPECT_EQ(items[1].tokens.count, 2UL);
&gt;+    EXPECT_STREQ(&quot;Web&quot;, items[1].tokens[0].content.UTF8String);
&gt;+    EXPECT_STREQ(&quot;Kit&quot;, items[1].tokens[1].content.UTF8String);
&gt;+
&gt;+    // This has to happen separately in order to have a deterministic ordering.
&gt;+    done = false;
&gt;+    delegate.get().itemCallback = ^(_WKTextManipulationItem *item) {
&gt;+        if (items.count == 3)
&gt;+            done = true;
&gt;+    };
&gt;+    [webView stringByEvaluatingJavaScript:@&quot;document.querySelectorAll(&apos;div.hidden&apos;).forEach((div) =&gt; div.classList.remove(&apos;hidden&apos;));&quot;];
&gt;+    TestWebKitAPI::Util::run(&amp;done);
&gt;+
&gt;+    EXPECT_EQ(items.count, 3UL);
&gt;+    EXPECT_EQ(items[2].tokens.count, 1UL);
&gt;+    EXPECT_STREQ(&quot;hey&quot;, items[2].tokens[0].content.UTF8String);
&gt;+}
&gt;+
&gt;+TEST(TextManipulation, StartTextManipulationFindSameParagraphWithNewContent)
&gt;+{
&gt;+    auto delegate = adoptNS([[TextManipulationDelegate alloc] init]);
&gt;+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 400, 400)]);
&gt;+    [webView _setTextManipulationDelegate:delegate.get()];
&gt;+
&gt;+    [webView synchronouslyLoadHTMLString:@&quot;&lt;!DOCTYPE html&gt;&lt;html&gt;&lt;body&gt;&lt;p&gt;hello&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;&quot;];
&gt;+
&gt;+    done = false;
&gt;+    [webView _startTextManipulationsWithConfiguration:nil completion:^{
&gt;+        done = true;
&gt;+    }];
&gt;+    TestWebKitAPI::Util::run(&amp;done);
&gt;+
&gt;+    auto *items = [delegate items];
&gt;+    EXPECT_EQ(items.count, 1UL);
&gt;+    EXPECT_EQ(items[0].tokens.count, 1UL);
&gt;+    EXPECT_STREQ(&quot;hello&quot;, items[0].tokens[0].content.UTF8String);
&gt;+
&gt;+    done = false;
&gt;+    delegate.get().itemCallback = ^(_WKTextManipulationItem *item) {
&gt;+        done = true;
&gt;+    };
&gt;+
&gt;+    [webView stringByEvaluatingJavaScript:@&quot;b = document.createElement(&apos;b&apos;);&quot;
&gt;+        &quot;b.textContent = &apos; world&apos;;&quot;
&gt;+        &quot;document.querySelector(&apos;p&apos;).appendChild(b); &apos;&apos;&quot;];
&gt;+
&gt;+    TestWebKitAPI::Util::run(&amp;done);
&gt;+
&gt;+    EXPECT_EQ(items.count, 2UL);
&gt;+    EXPECT_EQ(items[1].tokens.count, 2UL);
&gt;+    EXPECT_STREQ(&quot;hello&quot;, items[1].tokens[0].content.UTF8String);
&gt;+    EXPECT_STREQ(&quot; world&quot;, items[1].tokens[1].content.UTF8String);
&gt;+}
&gt;+
&gt; TEST(TextManipulation, StartTextManipulationApplySingleExcluionRuleForElement)
&gt; {
&gt;     auto delegate = adoptNS([[TextManipulationDelegate alloc] init]);
&gt;@@ -488,8 +620,6 @@ TEST(TextManipulation, CompleteTextManipulationFailWhenExclusionIsViolated)
&gt;     EXPECT_WK_STREQ(&quot;&lt;p&gt;hi, &lt;em&gt;WebKitten&lt;/em&gt;&lt;/p&gt;&quot;, [webView stringByEvaluatingJavaScript:@&quot;document.body.innerHTML&quot;]);
&gt; }
&gt; 
&gt;-// MARK: - _WKTextManipulationToken Tests
&gt;-
&gt; TEST(TextManipulation, TextManipulationTokenDebugDescription)
&gt; {
&gt;     auto token = adoptNS([[_WKTextManipulationToken alloc] init]);
&gt;@@ -772,8 +902,6 @@ TEST(TextManipulation, TextManipulationTokenNSObjectEqualityWithNonToken)
&gt;     EXPECT_FALSE([token isEqual:nil]);
&gt; }
&gt; 
&gt;-// MARK: - _WKTextManipulationItem Tests
&gt;-
&gt; static RetainPtr&lt;_WKTextManipulationToken&gt; createTextManipulationToken(NSString *identifier, BOOL excluded, NSString *content)
&gt; {
&gt;     auto token = adoptNS([[_WKTextManipulationToken alloc] init]);</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1599116</commentid>
    <comment_count>7</comment_count>
    <who name="Ryosuke Niwa">rniwa</who>
    <bug_when>2019-12-16 14:34:31 -0800</bug_when>
    <thetext>Fixed typos. Thanks for the review!</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1599122</commentid>
    <comment_count>8</comment_count>
    <who name="Ryosuke Niwa">rniwa</who>
    <bug_when>2019-12-16 14:36:57 -0800</bug_when>
    <thetext>Committed r253583: &lt;https://trac.webkit.org/changeset/253583&gt;</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1599123</commentid>
    <comment_count>9</comment_count>
    <who name="Radar WebKit Bug Importer">webkit-bug-importer</who>
    <bug_when>2019-12-16 14:37:17 -0800</bug_when>
    <thetext>&lt;rdar://problem/57985619&gt;</thetext>
  </long_desc>
      
          <attachment
              isobsolete="1"
              ispatch="1"
              isprivate="0"
          >
            <attachid>385585</attachid>
            <date>2019-12-13 01:10:25 -0800</date>
            <delta_ts>2019-12-13 19:09:38 -0800</delta_ts>
            <desc>WIP</desc>
            <filename>wip205203.patch</filename>
            <type>text/plain</type>
            <size>15917</size>
            <attacher name="Ryosuke Niwa">rniwa</attacher>
            
              <data encoding="base64">ZGlmZiAtLWdpdCBhL1NvdXJjZS9XZWJDb3JlL2RvbS9UYXNrU291cmNlLmggYi9Tb3VyY2UvV2Vi
Q29yZS9kb20vVGFza1NvdXJjZS5oCmluZGV4IDE0Mzg4NWM1Yjg4Li5jOTc0ZDk0ZGI4NyAxMDA2
NDQKLS0tIGEvU291cmNlL1dlYkNvcmUvZG9tL1Rhc2tTb3VyY2UuaAorKysgYi9Tb3VyY2UvV2Vi
Q29yZS9kb20vVGFza1NvdXJjZS5oCkBAIC0zNiw3ICszNiwxMCBAQCBlbnVtIGNsYXNzIFRhc2tT
b3VyY2UgOiB1aW50OF90IHsKICAgICBNaWNyb3Rhc2ssCiAgICAgTmV0d29ya2luZywKICAgICBQ
b3N0ZWRNZXNzYWdlUXVldWUsCi0gICAgVXNlckludGVyYWN0aW9uCisgICAgVXNlckludGVyYWN0
aW9uLAorCisgICAgLy8gSW50ZXJuYWwgdG8gV2ViQ29yZQorICAgIEludGVybmFsQXN5bmNUYXNr
LCAvLyBTYWZlIHRvIHJlLW9yZGVyIG9yIGRlbGF5LgogfTsKIAogfSAvLyBuYW1lc3BhY2UgV2Vi
Q29yZQpkaWZmIC0tZ2l0IGEvU291cmNlL1dlYkNvcmUvZWRpdGluZy9UZXh0TWFuaXB1bGF0aW9u
Q29udHJvbGxlci5jcHAgYi9Tb3VyY2UvV2ViQ29yZS9lZGl0aW5nL1RleHRNYW5pcHVsYXRpb25D
b250cm9sbGVyLmNwcAppbmRleCBkMmUzOWY3YmRmMy4uOGFjNDRmZjM4ZDUgMTAwNjQ0Ci0tLSBh
L1NvdXJjZS9XZWJDb3JlL2VkaXRpbmcvVGV4dE1hbmlwdWxhdGlvbkNvbnRyb2xsZXIuY3BwCisr
KyBiL1NvdXJjZS9XZWJDb3JlL2VkaXRpbmcvVGV4dE1hbmlwdWxhdGlvbkNvbnRyb2xsZXIuY3Bw
CkBAIC0yOSw2ICsyOSw3IEBACiAjaW5jbHVkZSAiQ2hhcmFjdGVyRGF0YS5oIgogI2luY2x1ZGUg
IkVkaXRpbmcuaCIKICNpbmNsdWRlICJFbGVtZW50QW5jZXN0b3JJdGVyYXRvci5oIgorI2luY2x1
ZGUgIkV2ZW50TG9vcC5oIgogI2luY2x1ZGUgIlNjcmlwdERpc2FsbG93ZWRTY29wZS5oIgogI2lu
Y2x1ZGUgIlRleHRJdGVyYXRvci5oIgogI2luY2x1ZGUgIlZpc2libGVVbml0cy5oIgpAQCAtMTE4
LDkgKzExOSwxNyBAQCB2b2lkIFRleHRNYW5pcHVsYXRpb25Db250cm9sbGVyOjpzdGFydE9ic2Vy
dmluZ1BhcmFncmFwaHMoTWFuaXB1bGF0aW9uSXRlbUNhbGxiYQogCiAgICAgVmlzaWJsZVBvc2l0
aW9uIHN0YXJ0ID0gZmlyc3RQb3NpdGlvbkluTm9kZShtX2RvY3VtZW50LmdldCgpKTsKICAgICBW
aXNpYmxlUG9zaXRpb24gZW5kID0gbGFzdFBvc2l0aW9uSW5Ob2RlKG1fZG9jdW1lbnQuZ2V0KCkp
OworCisgICAgb2JzZXJ2ZVBhcmFncmFwaHMoc3RhcnQsIGVuZCk7Cit9CisKK3ZvaWQgVGV4dE1h
bmlwdWxhdGlvbkNvbnRyb2xsZXI6Om9ic2VydmVQYXJhZ3JhcGhzKFZpc2libGVQb3NpdGlvbiYg
c3RhcnQsIFZpc2libGVQb3NpdGlvbiYgZW5kKQoreworICAgIGF1dG8gZG9jdW1lbnQgPSBtYWtl
UmVmUHRyKHN0YXJ0LmRlZXBFcXVpdmFsZW50KCkuZG9jdW1lbnQoKSk7CisgICAgQVNTRVJUKGRv
Y3VtZW50KTsKICAgICBUZXh0SXRlcmF0b3IgaXRlcmF0b3IgeyBzdGFydC5kZWVwRXF1aXZhbGVu
dCgpLCBlbmQuZGVlcEVxdWl2YWxlbnQoKSB9OwotICAgIGlmICghZG9jdW1lbnQpCi0gICAgICAg
IHJldHVybjsgLy8gVmlzaWJsZVBvc2l0aW9uIG9yIFRleHRJdGVyYXRvcidzIGNvbnN0cnVjdG9y
IG1heSBoYXZlIHVwZGF0ZWQgdGhlIGxheW91dCBhbmQgZXhlY3V0ZWQgYXJiaXRyYXJ5IHNjcmlw
dHMuCisgICAgaWYgKGRvY3VtZW50ICE9IHN0YXJ0LmRlZXBFcXVpdmFsZW50KCkuZG9jdW1lbnQo
KSB8fCBkb2N1bWVudCAhPSBlbmQuZGVlcEVxdWl2YWxlbnQoKS5kb2N1bWVudCgpKQorICAgICAg
ICByZXR1cm47IC8vIFRleHRJdGVyYXRvcidzIGNvbnN0cnVjdG9yIG1heSBoYXZlIHVwZGF0ZWQg
dGhlIGxheW91dCBhbmQgZXhlY3V0ZWQgYXJiaXRyYXJ5IHNjcmlwdHMuCiAKICAgICBFeGNsdXNp
b25SdWxlTWF0Y2hlciBleGNsdXNpb25SdWxlTWF0Y2hlcihtX2V4Y2x1c2lvblJ1bGVzKTsKICAg
ICBWZWN0b3I8TWFuaXB1bGF0aW9uVG9rZW4+IHRva2Vuc0luQ3VycmVudFBhcmFncmFwaDsKQEAg
LTE2Myw2ICsxNzIsNzIgQEAgdm9pZCBUZXh0TWFuaXB1bGF0aW9uQ29udHJvbGxlcjo6c3RhcnRP
YnNlcnZpbmdQYXJhZ3JhcGhzKE1hbmlwdWxhdGlvbkl0ZW1DYWxsYmEKICAgICAgICAgYWRkSXRl
bShzdGFydE9mQ3VycmVudFBhcmFncmFwaCwgZW5kLmRlZXBFcXVpdmFsZW50KCksIFdURk1vdmUo
dG9rZW5zSW5DdXJyZW50UGFyYWdyYXBoKSk7CiB9CiAKK3ZvaWQgVGV4dE1hbmlwdWxhdGlvbkNv
bnRyb2xsZXI6OmRpZENyZWF0ZVJlbmRlcmVyRm9yRWxlbWVudChFbGVtZW50JiBlbGVtZW50KQor
eworICAgIGlmIChtX211dGF0ZWRFbGVtZW50cy5jb21wdXRlc0VtcHR5KCkpCisgICAgICAgIHNj
aGVkdWxlT2JzZXJ2YXJ0aW9uVXBkYXRlKCk7CisgICAgbV9tdXRhdGVkRWxlbWVudHMuYWRkKGVs
ZW1lbnQpOworfQorCit2b2lkIFRleHRNYW5pcHVsYXRpb25Db250cm9sbGVyOjp3aWxsRGVzdHJv
eVJlbmRlcmVyRm9yRWxlbWVudChFbGVtZW50JiBlbGVtZW50KQoreworICAgIGlmIChtX211dGF0
ZWRFbGVtZW50cy5jb21wdXRlc0VtcHR5KCkpCisgICAgICAgIHNjaGVkdWxlT2JzZXJ2YXJ0aW9u
VXBkYXRlKCk7CisgICAgbV9tdXRhdGVkRWxlbWVudHMuYWRkKGVsZW1lbnQpOworfQorCit1c2lu
ZyBQb3NpdGlvblR1cGxlID0gc3RkOjp0dXBsZTxSZWZQdHI8Tm9kZT4sIHVuc2lnbmVkLCB1bnNp
Z25lZD47CitzdGF0aWMgY29uc3QgUG9zaXRpb25UdXBsZSBtYWtlUG9zaXRpb25UdXBsZShjb25z
dCBQb3NpdGlvbiYgcG9zaXRpb24pCit7CisgICAgcmV0dXJuIHsgcG9zaXRpb24uYW5jaG9yTm9k
ZSgpLCBzdGF0aWNfY2FzdDx1bnNpZ25lZD4ocG9zaXRpb24uYW5jaG9yVHlwZSgpKSwgcG9zaXRp
b24uYW5jaG9yVHlwZSgpID09IFBvc2l0aW9uOjpQb3NpdGlvbklzT2Zmc2V0SW5BbmNob3IgPyBw
b3NpdGlvbi5vZmZzZXRJbkNvbnRhaW5lck5vZGUoKSA6IDAgfTsgCit9CisKK3N0YXRpYyBjb25z
dCBzdGQ6OnBhaXI8UG9zaXRpb25UdXBsZSwgUG9zaXRpb25UdXBsZT4gbWFrZUhhc2hhYmxlUG9z
aXRpb25SYW5nZShjb25zdCBWaXNpYmxlUG9zaXRpb24mIHN0YXJ0LCBjb25zdCBWaXNpYmxlUG9z
aXRpb24mIGVuZCkKK3sKKyAgICByZXR1cm4geyBtYWtlUG9zaXRpb25UdXBsZShzdGFydC5kZWVw
RXF1aXZhbGVudCgpKSwgbWFrZVBvc2l0aW9uVHVwbGUoZW5kLmRlZXBFcXVpdmFsZW50KCkpIH07
Cit9CisKK3ZvaWQgVGV4dE1hbmlwdWxhdGlvbkNvbnRyb2xsZXI6OnNjaGVkdWxlT2JzZXJ2YXJ0
aW9uVXBkYXRlKCkKK3sKKyAgICBpZiAoIW1fZG9jdW1lbnQpCisgICAgICAgIHJldHVybjsKKwor
ICAgIG1fZG9jdW1lbnQtPmV2ZW50TG9vcCgpLnF1ZXVlVGFzayhUYXNrU291cmNlOjpJbnRlcm5h
bEFzeW5jVGFzaywgW3dlYWtUaGlzID0gbWFrZVdlYWtQdHIoKnRoaXMpXSB7CisgICAgICAgIGF1
dG8qIGNvbnRyb2xsZXIgPSB3ZWFrVGhpcy5nZXQoKTsKKyAgICAgICAgaWYgKCFjb250cm9sbGVy
KQorICAgICAgICAgICAgcmV0dXJuOworCisgICAgICAgIEhhc2hTZXQ8UmVmPEVsZW1lbnQ+PiBt
dXRhdGVkRWxlbWVudHM7CisgICAgICAgIGZvciAoYXV0byYgd2Vha0VsZW1lbnQgOiBjb250cm9s
bGVyLT5tX211dGF0ZWRFbGVtZW50cykKKyAgICAgICAgICAgIG11dGF0ZWRFbGVtZW50cy5hZGQo
d2Vha0VsZW1lbnQpOworICAgICAgICBjb250cm9sbGVyLT5tX211dGF0ZWRFbGVtZW50cy5jbGVh
cigpOworCisgICAgICAgIEhhc2hTZXQ8UmVmPEVsZW1lbnQ+PiBmaWx0ZXJlZEVsZW1lbnRzOwor
ICAgICAgICBmb3IgKGF1dG8mIGVsZW1lbnQgOiBtdXRhdGVkRWxlbWVudHMpIHsKKyAgICAgICAg
ICAgIGF1dG8qIHBhcmVudEVsZW1lbnQgPSBlbGVtZW50LT5wYXJlbnRFbGVtZW50KCk7CisgICAg
ICAgICAgICBpZiAoIXBhcmVudEVsZW1lbnQgfHwgIW11dGF0ZWRFbGVtZW50cy5jb250YWlucyhw
YXJlbnRFbGVtZW50KSkKKyAgICAgICAgICAgICAgICBmaWx0ZXJlZEVsZW1lbnRzLmFkZChlbGVt
ZW50LmNvcHlSZWYoKSk7CisgICAgICAgIH0KKyAgICAgICAgbXV0YXRlZEVsZW1lbnRzLmNsZWFy
KCk7CisKKyAgICAgICAgSGFzaFNldDxzdGQ6OnBhaXI8UG9zaXRpb25UdXBsZSwgUG9zaXRpb25U
dXBsZT4+IHBhcmFncmFwaFNldHM7CisgICAgICAgIGZvciAoYXV0byYgZWxlbWVudCA6IGZpbHRl
cmVkRWxlbWVudHMpIHsKKyAgICAgICAgICAgIGF1dG8gc3RhcnQgPSBzdGFydE9mUGFyYWdyYXBo
KGZpcnN0UG9zaXRpb25Jbk9yQmVmb3JlTm9kZShlbGVtZW50LnB0cigpKSk7CisgICAgICAgICAg
ICBhdXRvIGVuZCA9IGVuZE9mUGFyYWdyYXBoKGxhc3RQb3NpdGlvbkluT3JBZnRlck5vZGUoZWxl
bWVudC5wdHIoKSkpOworCisgICAgICAgICAgICBhdXRvIGtleSA9IG1ha2VIYXNoYWJsZVBvc2l0
aW9uUmFuZ2Uoc3RhcnQsIGVuZCk7CisgICAgICAgICAgICBpZiAoIXBhcmFncmFwaFNldHMuYWRk
KGtleSkuaXNOZXdFbnRyeSkKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKworICAgICAgICAg
ICAgYXV0byogY29udHJvbGxlciA9IHdlYWtUaGlzLmdldCgpOworICAgICAgICAgICAgaWYgKCFj
b250cm9sbGVyKQorICAgICAgICAgICAgICAgIHJldHVybjsgLy8gRmluZGluZyB0aGUgc3RhcnQv
ZW5kIG9mIHBhcmFncmFwaCBtYXkgaGF2ZSB1cGRhdGVkIGxheW91dCAmIGV4ZWN1dGVkIGFyYml0
cmFyeSBzY3JpcHRzLgorCisgICAgICAgICAgICBjb250cm9sbGVyLT5vYnNlcnZlUGFyYWdyYXBo
cyhzdGFydCwgZW5kKTsKKyAgICAgICAgfQorICAgIH0pOworfQorCiB2b2lkIFRleHRNYW5pcHVs
YXRpb25Db250cm9sbGVyOjphZGRJdGVtKGNvbnN0IFBvc2l0aW9uJiBzdGFydE9mUGFyYWdyYXBo
LCBjb25zdCBQb3NpdGlvbiYgZW5kT2ZQYXJhZ3JhcGgsIFZlY3RvcjxNYW5pcHVsYXRpb25Ub2tl
bj4mJiB0b2tlbnMpCiB7CiAgICAgQVNTRVJUKG1fZG9jdW1lbnQpOwpkaWZmIC0tZ2l0IGEvU291
cmNlL1dlYkNvcmUvZWRpdGluZy9UZXh0TWFuaXB1bGF0aW9uQ29udHJvbGxlci5oIGIvU291cmNl
L1dlYkNvcmUvZWRpdGluZy9UZXh0TWFuaXB1bGF0aW9uQ29udHJvbGxlci5oCmluZGV4IDM3MmNk
NjRlYTRmLi40Y2Q3YWNkYzQ3YSAxMDA2NDQKLS0tIGEvU291cmNlL1dlYkNvcmUvZWRpdGluZy9U
ZXh0TWFuaXB1bGF0aW9uQ29udHJvbGxlci5oCisrKyBiL1NvdXJjZS9XZWJDb3JlL2VkaXRpbmcv
VGV4dE1hbmlwdWxhdGlvbkNvbnRyb2xsZXIuaApAQCAtMzAsMTEgKzMwLDE0IEBACiAjaW5jbHVk
ZSA8d3RmL0VudW1UcmFpdHMuaD4KICNpbmNsdWRlIDx3dGYvT2JqZWN0SWRlbnRpZmllci5oPgog
I2luY2x1ZGUgPHd0Zi9PcHRpb25hbC5oPgorI2luY2x1ZGUgPHd0Zi9XZWFrSGFzaFNldC5oPgog
I2luY2x1ZGUgPHd0Zi9XZWFrUHRyLmg+CiAKIG5hbWVzcGFjZSBXZWJDb3JlIHsKIAogY2xhc3Mg
RG9jdW1lbnQ7CitjbGFzcyBFbGVtZW50OworY2xhc3MgVmlzaWJsZVBvc2l0aW9uOwogCiBjbGFz
cyBUZXh0TWFuaXB1bGF0aW9uQ29udHJvbGxlciA6IHB1YmxpYyBDYW5NYWtlV2Vha1B0cjxUZXh0
TWFuaXB1bGF0aW9uQ29udHJvbGxlcj4gewogICAgIFdURl9NQUtFX0ZBU1RfQUxMT0NBVEVEOwpA
QCAtOTMsNiArOTYsOSBAQCBwdWJsaWM6CiAgICAgdXNpbmcgTWFuaXB1bGF0aW9uSXRlbUNhbGxi
YWNrID0gV1RGOjpGdW5jdGlvbjx2b2lkKERvY3VtZW50JiwgSXRlbUlkZW50aWZpZXIsIGNvbnN0
IFZlY3RvcjxNYW5pcHVsYXRpb25Ub2tlbj4mKT47CiAgICAgV0VCQ09SRV9FWFBPUlQgdm9pZCBz
dGFydE9ic2VydmluZ1BhcmFncmFwaHMoTWFuaXB1bGF0aW9uSXRlbUNhbGxiYWNrJiYsIFZlY3Rv
cjxFeGNsdXNpb25SdWxlPiYmID0geyB9KTsKIAorICAgIHZvaWQgZGlkQ3JlYXRlUmVuZGVyZXJG
b3JFbGVtZW50KEVsZW1lbnQmKTsKKyAgICB2b2lkIHdpbGxEZXN0cm95UmVuZGVyZXJGb3JFbGVt
ZW50KEVsZW1lbnQmKTsKKwogICAgIGVudW0gY2xhc3MgTWFuaXB1bGF0aW9uUmVzdWx0IDogdWlu
dDhfdCB7CiAgICAgICAgIFN1Y2Nlc3MsCiAgICAgICAgIENvbnRlbnRDaGFuZ2VkLApAQCAtMTAz
LDYgKzEwOSw5IEBAIHB1YmxpYzoKICAgICBXRUJDT1JFX0VYUE9SVCBNYW5pcHVsYXRpb25SZXN1
bHQgY29tcGxldGVNYW5pcHVsYXRpb24oSXRlbUlkZW50aWZpZXIsIGNvbnN0IFZlY3RvcjxNYW5p
cHVsYXRpb25Ub2tlbj4mKTsKIAogcHJpdmF0ZToKKyAgICB2b2lkIG9ic2VydmVQYXJhZ3JhcGhz
KFZpc2libGVQb3NpdGlvbiYgc3RhcnQsIFZpc2libGVQb3NpdGlvbiYgZW5kKTsKKyAgICB2b2lk
IHNjaGVkdWxlT2JzZXJ2YXJ0aW9uVXBkYXRlKCk7CisKICAgICBzdHJ1Y3QgTWFuaXB1bGF0aW9u
SXRlbSB7CiAgICAgICAgIFBvc2l0aW9uIHN0YXJ0OwogICAgICAgICBQb3NpdGlvbiBlbmQ7CkBA
IC0xMTMsNiArMTIyLDcgQEAgcHJpdmF0ZToKICAgICBNYW5pcHVsYXRpb25SZXN1bHQgcmVwbGFj
ZShjb25zdCBNYW5pcHVsYXRpb25JdGVtJiwgY29uc3QgVmVjdG9yPE1hbmlwdWxhdGlvblRva2Vu
PiYpOwogCiAgICAgV2Vha1B0cjxEb2N1bWVudD4gbV9kb2N1bWVudDsKKyAgICBXZWFrSGFzaFNl
dDxFbGVtZW50PiBtX211dGF0ZWRFbGVtZW50czsKICAgICBNYW5pcHVsYXRpb25JdGVtQ2FsbGJh
Y2sgbV9jYWxsYmFjazsKICAgICBWZWN0b3I8RXhjbHVzaW9uUnVsZT4gbV9leGNsdXNpb25SdWxl
czsKICAgICBIYXNoTWFwPEl0ZW1JZGVudGlmaWVyLCBNYW5pcHVsYXRpb25JdGVtPiBtX2l0ZW1z
OwpkaWZmIC0tZ2l0IGEvU291cmNlL1dlYkNvcmUvcmVuZGVyaW5nL1JlbmRlck9iamVjdC5jcHAg
Yi9Tb3VyY2UvV2ViQ29yZS9yZW5kZXJpbmcvUmVuZGVyT2JqZWN0LmNwcAppbmRleCA4ZmU3MDNh
NDU3Mi4uNmU4NmNiNWM4YWIgMTAwNjQ0Ci0tLSBhL1NvdXJjZS9XZWJDb3JlL3JlbmRlcmluZy9S
ZW5kZXJPYmplY3QuY3BwCisrKyBiL1NvdXJjZS9XZWJDb3JlL3JlbmRlcmluZy9SZW5kZXJPYmpl
Y3QuY3BwCkBAIC02OCw2ICs2OCw3IEBACiAjaW5jbHVkZSAiUmVuZGVyV2lkZ2V0LmgiCiAjaW5j
bHVkZSAiU1ZHUmVuZGVyU3VwcG9ydC5oIgogI2luY2x1ZGUgIlN0eWxlUmVzb2x2ZXIuaCIKKyNp
bmNsdWRlICJUZXh0TWFuaXB1bGF0aW9uQ29udHJvbGxlci5oIgogI2luY2x1ZGUgIlRyYW5zZm9y
bVN0YXRlLmgiCiAjaW5jbHVkZSA8YWxnb3JpdGhtPgogI2luY2x1ZGUgPHN0ZGlvLmg+CkBAIC0x
NDcxLDYgKzE0NzIsMTMgQEAgdm9pZCBSZW5kZXJPYmplY3Q6OndpbGxCZURlc3Ryb3llZCgpCiAg
ICAgICAgIEFTU0VSVCghbm9kZS0+cmVuZGVyZXIoKSB8fCBub2RlLT5yZW5kZXJlcigpID09IHRo
aXMgfHwgKGlzPFJlbmRlckVsZW1lbnQ+KCp0aGlzKSAmJiBkb3duY2FzdDxSZW5kZXJFbGVtZW50
PigqdGhpcykuaXNDb250aW51YXRpb24oKSkpOwogICAgICAgICBpZiAobm9kZS0+cmVuZGVyZXIo
KSA9PSB0aGlzKQogICAgICAgICAgICAgbm9kZS0+c2V0UmVuZGVyZXIobnVsbHB0cik7CisKKyAg
ICAgICAgYXV0byogdGV4dE1hbmlwdWxhdGlvbkNvbnRyb2xsZXIgPSBub2RlLT5kb2N1bWVudCgp
LnRleHRNYW5pcHVsYXRpb25Db250cm9sbGVySWZFeGlzdHMoKTsKKyAgICAgICAgaWYgKFVOTElL
RUxZKHRleHRNYW5pcHVsYXRpb25Db250cm9sbGVyKSkgeworICAgICAgICAgICAgaWYgKGlzPEVs
ZW1lbnQ+KCpub2RlKSkKKyAgICAgICAgICAgICAgICB0ZXh0TWFuaXB1bGF0aW9uQ29udHJvbGxl
ci0+d2lsbERlc3Ryb3lSZW5kZXJlckZvckVsZW1lbnQoZG93bmNhc3Q8RWxlbWVudD4oKm5vZGUp
KTsKKyAgICAgICAgfQorCiAgICAgfQogCiAgICAgcmVtb3ZlUmFyZURhdGEoKTsKZGlmZiAtLWdp
dCBhL1NvdXJjZS9XZWJDb3JlL3JlbmRlcmluZy91cGRhdGluZy9SZW5kZXJUcmVlVXBkYXRlci5j
cHAgYi9Tb3VyY2UvV2ViQ29yZS9yZW5kZXJpbmcvdXBkYXRpbmcvUmVuZGVyVHJlZVVwZGF0ZXIu
Y3BwCmluZGV4IDM2NTZmM2JmYWFmLi4yMzFiYjA4NzM2NCAxMDA2NDQKLS0tIGEvU291cmNlL1dl
YkNvcmUvcmVuZGVyaW5nL3VwZGF0aW5nL1JlbmRlclRyZWVVcGRhdGVyLmNwcAorKysgYi9Tb3Vy
Y2UvV2ViQ29yZS9yZW5kZXJpbmcvdXBkYXRpbmcvUmVuZGVyVHJlZVVwZGF0ZXIuY3BwCkBAIC00
OSw2ICs0OSw3IEBACiAjaW5jbHVkZSAiUnVudGltZUVuYWJsZWRGZWF0dXJlcy5oIgogI2luY2x1
ZGUgIlN0eWxlUmVzb2x2ZXIuaCIKICNpbmNsdWRlICJTdHlsZVRyZWVSZXNvbHZlci5oIgorI2lu
Y2x1ZGUgIlRleHRNYW5pcHVsYXRpb25Db250cm9sbGVyLmgiCiAjaW5jbHVkZSA8d3RmL1N5c3Rl
bVRyYWNpbmcuaD4KIAogI2lmIEVOQUJMRShMQVlPVVRfRk9STUFUVElOR19DT05URVhUKQpAQCAt
Mzk3LDYgKzM5OCwxMCBAQCB2b2lkIFJlbmRlclRyZWVVcGRhdGVyOjpjcmVhdGVSZW5kZXJlcihF
bGVtZW50JiBlbGVtZW50LCBSZW5kZXJTdHlsZSYmIHN0eWxlKQogCiAgICAgbV9idWlsZGVyLmF0
dGFjaChpbnNlcnRpb25Qb3NpdGlvbiwgV1RGTW92ZShuZXdSZW5kZXJlcikpOwogCisgICAgYXV0
byogdGV4dE1hbmlwdWxhdGlvbkNvbnRyb2xsZXIgPSBtX2RvY3VtZW50LnRleHRNYW5pcHVsYXRp
b25Db250cm9sbGVySWZFeGlzdHMoKTsKKyAgICBpZiAoVU5MSUtFTFkodGV4dE1hbmlwdWxhdGlv
bkNvbnRyb2xsZXIpKQorICAgICAgICB0ZXh0TWFuaXB1bGF0aW9uQ29udHJvbGxlci0+ZGlkQ3Jl
YXRlUmVuZGVyZXJGb3JFbGVtZW50KGVsZW1lbnQpOworCiAgICAgaWYgKEFYT2JqZWN0Q2FjaGUq
IGNhY2hlID0gbV9kb2N1bWVudC5heE9iamVjdENhY2hlKCkpCiAgICAgICAgIGNhY2hlLT51cGRh
dGVDYWNoZUFmdGVyTm9kZUlzQXR0YWNoZWQoJmVsZW1lbnQpOwogfQpkaWZmIC0tZ2l0IGEvVG9v
bHMvVGVzdFdlYktpdEFQSS9UZXN0cy9XZWJLaXRDb2NvYS9UZXh0TWFuaXB1bGF0aW9uLm1tIGIv
VG9vbHMvVGVzdFdlYktpdEFQSS9UZXN0cy9XZWJLaXRDb2NvYS9UZXh0TWFuaXB1bGF0aW9uLm1t
CmluZGV4IGQ3MDc1OThmZGM3Li45NGY5Y2RkZGM3NyAxMDA2NDQKLS0tIGEvVG9vbHMvVGVzdFdl
YktpdEFQSS9UZXN0cy9XZWJLaXRDb2NvYS9UZXh0TWFuaXB1bGF0aW9uLm1tCisrKyBiL1Rvb2xz
L1Rlc3RXZWJLaXRBUEkvVGVzdHMvV2ViS2l0Q29jb2EvVGV4dE1hbmlwdWxhdGlvbi5tbQpAQCAt
MzksMTEgKzM5LDE0IEBACiAKIHN0YXRpYyBib29sIGRvbmUgPSBmYWxzZTsKIAordHlwZWRlZiB2
b2lkKF5JdGVtQ2FsbGJhY2spKF9XS1RleHRNYW5pcHVsYXRpb25JdGVtICopOworCiBAaW50ZXJm
YWNlIFRleHRNYW5pcHVsYXRpb25EZWxlZ2F0ZSA6IE5TT2JqZWN0IDxfV0tUZXh0TWFuaXB1bGF0
aW9uRGVsZWdhdGU+CiAKIC0gKHZvaWQpX3dlYlZpZXc6KFdLV2ViVmlldyAqKXdlYlZpZXcgZGlk
RmluZFRleHRNYW5pcHVsYXRpb25JdGVtOihfV0tUZXh0TWFuaXB1bGF0aW9uSXRlbSAqKWl0ZW07
CiAKIEBwcm9wZXJ0eSAobm9uYXRvbWljLCByZWFkb25seSwgY29weSkgTlNBcnJheTxfV0tUZXh0
TWFuaXB1bGF0aW9uSXRlbSAqPiAqaXRlbXM7CitAcHJvcGVydHkgKHN0cm9uZykgSXRlbUNhbGxi
YWNrIGl0ZW1DYWxsYmFjazsKIAogQGVuZAogCkBAIC01OSw5ICs2MiwxOSBAQCBzdGF0aWMgYm9v
bCBkb25lID0gZmFsc2U7CiAgICAgcmV0dXJuIHNlbGY7CiB9CiAKKy0gKGluc3RhbmNldHlwZSlp
bml0V2l0aEl0ZW1DYWxsYmFjaworeworICAgIGlmICghKHNlbGYgPSBbc3VwZXIgaW5pdF0pKQor
ICAgICAgICByZXR1cm4gbmlsOworICAgIF9pdGVtcyA9IGFkb3B0TlMoW1tOU011dGFibGVBcnJh
eSBhbGxvY10gaW5pdF0pOworICAgIHJldHVybiBzZWxmOworfQorCiAtICh2b2lkKV93ZWJWaWV3
OihXS1dlYlZpZXcgKil3ZWJWaWV3IGRpZEZpbmRUZXh0TWFuaXB1bGF0aW9uSXRlbTooX1dLVGV4
dE1hbmlwdWxhdGlvbkl0ZW0gKilpdGVtCiB7CiAgICAgW19pdGVtcyBhZGRPYmplY3Q6aXRlbV07
CisgICAgaWYgKHNlbGYuaXRlbUNhbGxiYWNrKQorICAgICAgICBzZWxmLml0ZW1DYWxsYmFjayhp
dGVtKTsKIH0KIAogLSAoTlNBcnJheTxfV0tUZXh0TWFuaXB1bGF0aW9uSXRlbSAqPiAqKWl0ZW1z
CkBAIC0xNzAsNiArMTgzLDEyNSBAQCBURVNUKFRleHRNYW5pcHVsYXRpb24sIFN0YXJ0VGV4dE1h
bmlwdWxhdGlvbkZpbmRQYXJhZ3JhcGhzV2l0aE11bHRpbGVUb2tlbnMpCiAgICAgRVhQRUNUX1NU
UkVRKCJLaXQiLCBpdGVtc1sxXS50b2tlbnNbMV0uY29udGVudC5VVEY4U3RyaW5nKTsKIH0KIAor
VEVTVChUZXh0TWFuaXB1bGF0aW9uLCBTdGFydFRleHRNYW5pcHVsYXRpb25GaW5kTmV3bHlJbnNl
cnRlZFBhcmFncmFwaCkKK3sKKyAgICBhdXRvIGRlbGVnYXRlID0gYWRvcHROUyhbW1RleHRNYW5p
cHVsYXRpb25EZWxlZ2F0ZSBhbGxvY10gaW5pdF0pOworICAgIGF1dG8gd2ViVmlldyA9IGFkb3B0
TlMoW1tUZXN0V0tXZWJWaWV3IGFsbG9jXSBpbml0V2l0aEZyYW1lOk5TTWFrZVJlY3QoMCwgMCwg
NDAwLCA0MDApXSk7CisgICAgW3dlYlZpZXcgX3NldFRleHRNYW5pcHVsYXRpb25EZWxlZ2F0ZTpk
ZWxlZ2F0ZS5nZXQoKV07CisKKyAgICBbd2ViVmlldyBzeW5jaHJvbm91c2x5TG9hZEhUTUxTdHJp
bmc6QCI8IURPQ1RZUEUgaHRtbD48aHRtbD48Ym9keT48cD5oZWxsbzwvcD48L2JvZHk+PC9odG1s
PiJdOworCisgICAgZG9uZSA9IGZhbHNlOworICAgIFt3ZWJWaWV3IF9zdGFydFRleHRNYW5pcHVs
YXRpb25zV2l0aENvbmZpZ3VyYXRpb246bmlsIGNvbXBsZXRpb246XnsKKyAgICAgICAgZG9uZSA9
IHRydWU7CisgICAgfV07CisgICAgVGVzdFdlYktpdEFQSTo6VXRpbDo6cnVuKCZkb25lKTsKKwor
ICAgIF9fYmxvY2sgYXV0byAqaXRlbXMgPSBbZGVsZWdhdGUgaXRlbXNdOworICAgIEVYUEVDVF9F
UShpdGVtcy5jb3VudCwgMVVMKTsKKyAgICBFWFBFQ1RfRVEoaXRlbXNbMF0udG9rZW5zLmNvdW50
LCAxVUwpOworICAgIEVYUEVDVF9TVFJFUSgiaGVsbG8iLCBpdGVtc1swXS50b2tlbnNbMF0uY29u
dGVudC5VVEY4U3RyaW5nKTsKKworICAgIGRvbmUgPSBmYWxzZTsKKyAgICBkZWxlZ2F0ZS5nZXQo
KS5pdGVtQ2FsbGJhY2sgPSBeKF9XS1RleHRNYW5pcHVsYXRpb25JdGVtICppdGVtKSB7CisgICAg
ICAgIGlmIChpdGVtcy5jb3VudCA9PSAzKQorICAgICAgICAgICAgZG9uZSA9IHRydWU7CisgICAg
fTsKKyAgICBbd2ViVmlldyBzdHJpbmdCeUV2YWx1YXRpbmdKYXZhU2NyaXB0OkAiZG9jdW1lbnQu
Ym9keS5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKSkuaW5uZXJIVE1M
ID0gJ3dvcmxkPGJyPjxiPldlYjwvYj5LaXQnOyJdOworICAgIFRlc3RXZWJLaXRBUEk6OlV0aWw6
OnJ1bigmZG9uZSk7CisKKyAgICBFWFBFQ1RfRVEoaXRlbXMuY291bnQsIDNVTCk7CisgICAgRVhQ
RUNUX0VRKGl0ZW1zWzFdLnRva2Vucy5jb3VudCwgMVVMKTsKKyAgICBFWFBFQ1RfU1RSRVEoIndv
cmxkIiwgaXRlbXNbMV0udG9rZW5zWzBdLmNvbnRlbnQuVVRGOFN0cmluZyk7CisgICAgRVhQRUNU
X0VRKGl0ZW1zWzJdLnRva2Vucy5jb3VudCwgMlVMKTsKKyAgICBFWFBFQ1RfU1RSRVEoIldlYiIs
IGl0ZW1zWzJdLnRva2Vuc1swXS5jb250ZW50LlVURjhTdHJpbmcpOworICAgIEVYUEVDVF9TVFJF
USgiS2l0IiwgaXRlbXNbMl0udG9rZW5zWzFdLmNvbnRlbnQuVVRGOFN0cmluZyk7Cit9CisKK1RF
U1QoVGV4dE1hbmlwdWxhdGlvbiwgU3RhcnRUZXh0TWFuaXB1bGF0aW9uRmluZE5ld2x5RGlzcGxh
eWVkUGFyYWdyYXBoKQoreworICAgIGF1dG8gZGVsZWdhdGUgPSBhZG9wdE5TKFtbVGV4dE1hbmlw
dWxhdGlvbkRlbGVnYXRlIGFsbG9jXSBpbml0XSk7CisgICAgYXV0byB3ZWJWaWV3ID0gYWRvcHRO
UyhbW1Rlc3RXS1dlYlZpZXcgYWxsb2NdIGluaXRXaXRoRnJhbWU6TlNNYWtlUmVjdCgwLCAwLCA0
MDAsIDQwMCldKTsKKyAgICBbd2ViVmlldyBfc2V0VGV4dE1hbmlwdWxhdGlvbkRlbGVnYXRlOmRl
bGVnYXRlLmdldCgpXTsKKworICAgIFt3ZWJWaWV3IHN5bmNocm9ub3VzbHlMb2FkSFRNTFN0cmlu
ZzpAIjwhRE9DVFlQRSBodG1sPjxodG1sPjxib2R5PiIKKyAgICAgICAgIjxzdHlsZT4gLmhpZGRl
biB7IGRpc3BsYXk6IG5vbmU7IH0gPC9zdHlsZT4iCisgICAgICAgICI8cD5oZWxsbzwvcD48ZGl2
PjxzcGFuIGNsYXNzPSdoaWRkZW4nPldlYjwvc3Bhbj48c3BhbiBjbGFzcz0naGlkZGVuJz5LaXQ8
L3NwYW4+PC9kaXY+PGRpdiBjbGFzcz0naGlkZGVuJz5oZXk8L2Rpdj48L2JvZHk+PC9odG1sPiJd
OworCisgICAgZG9uZSA9IGZhbHNlOworICAgIFt3ZWJWaWV3IF9zdGFydFRleHRNYW5pcHVsYXRp
b25zV2l0aENvbmZpZ3VyYXRpb246bmlsIGNvbXBsZXRpb246XnsKKyAgICAgICAgZG9uZSA9IHRy
dWU7CisgICAgfV07CisgICAgVGVzdFdlYktpdEFQSTo6VXRpbDo6cnVuKCZkb25lKTsKKworICAg
IF9fYmxvY2sgYXV0byAqaXRlbXMgPSBbZGVsZWdhdGUgaXRlbXNdOworICAgIEVYUEVDVF9FUShp
dGVtcy5jb3VudCwgMVVMKTsKKyAgICBFWFBFQ1RfRVEoaXRlbXNbMF0udG9rZW5zLmNvdW50LCAx
VUwpOworICAgIEVYUEVDVF9TVFJFUSgiaGVsbG8iLCBpdGVtc1swXS50b2tlbnNbMF0uY29udGVu
dC5VVEY4U3RyaW5nKTsKKworICAgIGRvbmUgPSBmYWxzZTsKKyAgICBkZWxlZ2F0ZS5nZXQoKS5p
dGVtQ2FsbGJhY2sgPSBeKF9XS1RleHRNYW5pcHVsYXRpb25JdGVtICppdGVtKSB7CisgICAgICAg
IGlmIChpdGVtcy5jb3VudCA9PSAyKQorICAgICAgICAgICAgZG9uZSA9IHRydWU7CisgICAgfTsK
KyAgICBbd2ViVmlldyBzdHJpbmdCeUV2YWx1YXRpbmdKYXZhU2NyaXB0OkAiZG9jdW1lbnQucXVl
cnlTZWxlY3RvckFsbCgnc3Bhbi5oaWRkZW4nKS5mb3JFYWNoKChzcGFuKSA9PiBzcGFuLmNsYXNz
TGlzdC5yZW1vdmUoJ2hpZGRlbicpKTsiXTsKKyAgICBUZXN0V2ViS2l0QVBJOjpVdGlsOjpydW4o
JmRvbmUpOworCisgICAgRVhQRUNUX0VRKGl0ZW1zLmNvdW50LCAyVUwpOworICAgIEVYUEVDVF9F
UShpdGVtc1sxXS50b2tlbnMuY291bnQsIDJVTCk7CisgICAgRVhQRUNUX1NUUkVRKCJXZWIiLCBp
dGVtc1sxXS50b2tlbnNbMF0uY29udGVudC5VVEY4U3RyaW5nKTsKKyAgICBFWFBFQ1RfU1RSRVEo
IktpdCIsIGl0ZW1zWzFdLnRva2Vuc1sxXS5jb250ZW50LlVURjhTdHJpbmcpOworCisgICAgLy8g
VGhpcyBoYXMgdG8gaGFwcGVuIHNlcGFyYXRlbHkgaW4gb3JkZXIgdG8gaGF2ZSBhIGRldGVybWlu
aXN0aWMgb3JkZXJpbmcuCisgICAgZG9uZSA9IGZhbHNlOworICAgIGRlbGVnYXRlLmdldCgpLml0
ZW1DYWxsYmFjayA9IF4oX1dLVGV4dE1hbmlwdWxhdGlvbkl0ZW0gKml0ZW0pIHsKKyAgICAgICAg
aWYgKGl0ZW1zLmNvdW50ID09IDMpCisgICAgICAgICAgICBkb25lID0gdHJ1ZTsKKyAgICB9Owor
ICAgIFt3ZWJWaWV3IHN0cmluZ0J5RXZhbHVhdGluZ0phdmFTY3JpcHQ6QCJkb2N1bWVudC5xdWVy
eVNlbGVjdG9yQWxsKCdkaXYuaGlkZGVuJykuZm9yRWFjaCgoZGl2KSA9PiBkaXYuY2xhc3NMaXN0
LnJlbW92ZSgnaGlkZGVuJykpOyJdOworICAgIFRlc3RXZWJLaXRBUEk6OlV0aWw6OnJ1bigmZG9u
ZSk7CisKKyAgICBFWFBFQ1RfRVEoaXRlbXMuY291bnQsIDNVTCk7CisgICAgRVhQRUNUX0VRKGl0
ZW1zWzJdLnRva2Vucy5jb3VudCwgMVVMKTsKKyAgICBFWFBFQ1RfU1RSRVEoImhleSIsIGl0ZW1z
WzJdLnRva2Vuc1swXS5jb250ZW50LlVURjhTdHJpbmcpOworfQorCitURVNUKFRleHRNYW5pcHVs
YXRpb24sIFN0YXJ0VGV4dE1hbmlwdWxhdGlvbkZpbmRTYW1lUGFyYWdyYXBoV2l0aE5ld0NvbnRl
bnQpCit7CisgICAgYXV0byBkZWxlZ2F0ZSA9IGFkb3B0TlMoW1tUZXh0TWFuaXB1bGF0aW9uRGVs
ZWdhdGUgYWxsb2NdIGluaXRdKTsKKyAgICBhdXRvIHdlYlZpZXcgPSBhZG9wdE5TKFtbVGVzdFdL
V2ViVmlldyBhbGxvY10gaW5pdFdpdGhGcmFtZTpOU01ha2VSZWN0KDAsIDAsIDQwMCwgNDAwKV0p
OworICAgIFt3ZWJWaWV3IF9zZXRUZXh0TWFuaXB1bGF0aW9uRGVsZWdhdGU6ZGVsZWdhdGUuZ2V0
KCldOworCisgICAgW3dlYlZpZXcgc3luY2hyb25vdXNseUxvYWRIVE1MU3RyaW5nOkAiPCFET0NU
WVBFIGh0bWw+PGh0bWw+PGJvZHk+PHA+aGVsbG88L3A+PC9ib2R5PjwvaHRtbD4iXTsKKworICAg
IGRvbmUgPSBmYWxzZTsKKyAgICBbd2ViVmlldyBfc3RhcnRUZXh0TWFuaXB1bGF0aW9uc1dpdGhD
b25maWd1cmF0aW9uOm5pbCBjb21wbGV0aW9uOl57CisgICAgICAgIGRvbmUgPSB0cnVlOworICAg
IH1dOworICAgIFRlc3RXZWJLaXRBUEk6OlV0aWw6OnJ1bigmZG9uZSk7CisKKyAgICBhdXRvICpp
dGVtcyA9IFtkZWxlZ2F0ZSBpdGVtc107CisgICAgRVhQRUNUX0VRKGl0ZW1zLmNvdW50LCAxVUwp
OworICAgIEVYUEVDVF9FUShpdGVtc1swXS50b2tlbnMuY291bnQsIDFVTCk7CisgICAgRVhQRUNU
X1NUUkVRKCJoZWxsbyIsIGl0ZW1zWzBdLnRva2Vuc1swXS5jb250ZW50LlVURjhTdHJpbmcpOwor
CisgICAgZG9uZSA9IGZhbHNlOworICAgIGRlbGVnYXRlLmdldCgpLml0ZW1DYWxsYmFjayA9IF4o
X1dLVGV4dE1hbmlwdWxhdGlvbkl0ZW0gKml0ZW0pIHsKKyAgICAgICAgZG9uZSA9IHRydWU7Cisg
ICAgfTsKKworICAgIFt3ZWJWaWV3IHN0cmluZ0J5RXZhbHVhdGluZ0phdmFTY3JpcHQ6QCJiID0g
ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYicpOyIKKyAgICAgICAgImIudGV4dENvbnRlbnQgPSAn
IHdvcmxkJzsiCisgICAgICAgICJkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdwJykuYXBwZW5kQ2hp
bGQoYik7ICcnIl07CisKKyAgICBUZXN0V2ViS2l0QVBJOjpVdGlsOjpydW4oJmRvbmUpOworCisg
ICAgRVhQRUNUX0VRKGl0ZW1zLmNvdW50LCAyVUwpOworICAgIEVYUEVDVF9FUShpdGVtc1sxXS50
b2tlbnMuY291bnQsIDJVTCk7CisgICAgRVhQRUNUX1NUUkVRKCJoZWxsbyIsIGl0ZW1zWzFdLnRv
a2Vuc1swXS5jb250ZW50LlVURjhTdHJpbmcpOworICAgIEVYUEVDVF9TVFJFUSgiIHdvcmxkIiwg
aXRlbXNbMV0udG9rZW5zWzFdLmNvbnRlbnQuVVRGOFN0cmluZyk7Cit9CisKIFRFU1QoVGV4dE1h
bmlwdWxhdGlvbiwgU3RhcnRUZXh0TWFuaXB1bGF0aW9uQXBwbHlTaW5nbGVFeGNsdWlvblJ1bGVG
b3JFbGVtZW50KQogewogICAgIGF1dG8gZGVsZWdhdGUgPSBhZG9wdE5TKFtbVGV4dE1hbmlwdWxh
dGlvbkRlbGVnYXRlIGFsbG9jXSBpbml0XSk7CkBAIC00ODgsOCArNjIwLDYgQEAgVEVTVChUZXh0
TWFuaXB1bGF0aW9uLCBDb21wbGV0ZVRleHRNYW5pcHVsYXRpb25GYWlsV2hlbkV4Y2x1c2lvbklz
VmlvbGF0ZWQpCiAgICAgRVhQRUNUX1dLX1NUUkVRKCI8cD5oaSwgPGVtPldlYktpdHRlbjwvZW0+
PC9wPiIsIFt3ZWJWaWV3IHN0cmluZ0J5RXZhbHVhdGluZ0phdmFTY3JpcHQ6QCJkb2N1bWVudC5i
b2R5LmlubmVySFRNTCJdKTsKIH0KIAotLy8gTUFSSzogLSBfV0tUZXh0TWFuaXB1bGF0aW9uVG9r
ZW4gVGVzdHMKLQogVEVTVChUZXh0TWFuaXB1bGF0aW9uLCBUZXh0TWFuaXB1bGF0aW9uVG9rZW5E
ZWJ1Z0Rlc2NyaXB0aW9uKQogewogICAgIGF1dG8gdG9rZW4gPSBhZG9wdE5TKFtbX1dLVGV4dE1h
bmlwdWxhdGlvblRva2VuIGFsbG9jXSBpbml0XSk7CkBAIC03NzIsOCArOTAyLDYgQEAgVEVTVChU
ZXh0TWFuaXB1bGF0aW9uLCBUZXh0TWFuaXB1bGF0aW9uVG9rZW5OU09iamVjdEVxdWFsaXR5V2l0
aE5vblRva2VuKQogICAgIEVYUEVDVF9GQUxTRShbdG9rZW4gaXNFcXVhbDpuaWxdKTsKIH0KIAot
Ly8gTUFSSzogLSBfV0tUZXh0TWFuaXB1bGF0aW9uSXRlbSBUZXN0cwotCiBzdGF0aWMgUmV0YWlu
UHRyPF9XS1RleHRNYW5pcHVsYXRpb25Ub2tlbj4gY3JlYXRlVGV4dE1hbmlwdWxhdGlvblRva2Vu
KE5TU3RyaW5nICppZGVudGlmaWVyLCBCT09MIGV4Y2x1ZGVkLCBOU1N0cmluZyAqY29udGVudCkK
IHsKICAgICBhdXRvIHRva2VuID0gYWRvcHROUyhbW19XS1RleHRNYW5pcHVsYXRpb25Ub2tlbiBh
bGxvY10gaW5pdF0pOwo=
</data>

          </attachment>
          <attachment
              isobsolete="0"
              ispatch="1"
              isprivate="0"
          >
            <attachid>385669</attachid>
            <date>2019-12-13 19:09:39 -0800</date>
            <delta_ts>2019-12-16 07:33:57 -0800</delta_ts>
            <desc>Adds the feature</desc>
            <filename>bug-205203-20191213190938.patch</filename>
            <type>text/plain</type>
            <size>18392</size>
            <attacher name="Ryosuke Niwa">rniwa</attacher>
            
              <data encoding="base64">U3VidmVyc2lvbiBSZXZpc2lvbjogMjUzMzYwCmRpZmYgLS1naXQgYS9Tb3VyY2UvV2ViQ29yZS9D
aGFuZ2VMb2cgYi9Tb3VyY2UvV2ViQ29yZS9DaGFuZ2VMb2cKaW5kZXggN2MyZDgxY2NmMWJmMjNh
MjA0YTVjMDdhY2U4MTcxMGEzM2IzOWVmMy4uOTQ3Yzc1ZTJlYjE4ZWY4NGI0Njk3MmQ3YTE5Mjdi
ZDlkZTBjY2FkZiAxMDA2NDQKLS0tIGEvU291cmNlL1dlYkNvcmUvQ2hhbmdlTG9nCisrKyBiL1Nv
dXJjZS9XZWJDb3JlL0NoYW5nZUxvZwpAQCAtMSwzICsxLDQxIEBACisyMDE5LTEyLTEzICBSeW9z
dWtlIE5pd2EgIDxybml3YUB3ZWJraXQub3JnPgorCisgICAgICAgIFRleHRNYW5pcHVsYXRpb25D
b250cm9sbGVyIHNob3VsZCBvYnNlcnZlIG5ld2x5IGluc2VydGVkIG9yIGRpc3BsYXllZCBjb250
ZW50cworICAgICAgICBodHRwczovL2J1Z3Mud2Via2l0Lm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MjA1
MjAzCisgICAgICAgIDxyZGFyOi8vcHJvYmxlbS81NjU2NzAyMD4KKworICAgICAgICBSZXZpZXdl
ZCBieSBOT0JPRFkgKE9PUFMhKS4KKworICAgICAgICBUaGlzIHBhdGNoIG1ha2VzIFRleHRNYW5p
cHVsYXRpb25Db250cm9sbGVyIGRldGVjdCBuZXdseSBpbnNlcnRlZCBvciBkaXNwbGF5ZWQgY29u
dGVudHMgYW5kIGludm9rZQorICAgICAgICB0aGUgY2FsbGJhY2tzIHdpdGggdGhlIG5ld2x5IGZv
dW5kIGl0ZW1zLgorCisgICAgICAgIFRvIGRvIHRoaXMsIHdlIGFkZCBhIG5ldyBXZWFrSGFzaFNl
dCB0byBUZXh0TWFuaXB1bGF0aW9uQ29udHJvbGxlciB0byB3aGljaCBhbiBlbGVtZW50IGlzIGFk
ZGVkCisgICAgICAgIHdoZW5ldmVyIGl0cyByZW5kZXJlciBpcyBjcmVhdGVkLiBCZWNhdXNlIGl0
J3MgZXhwZW5zaXZlIChhbmQgbm90IHNhZmUpIHRvIGZpbmQgcGFyYWdyYXBocyBhcm91bmQKKyAg
ICAgICAgYSBuZXdseSBpbnNlcnRlZCBjb250ZW50LCB3ZSBzY2hldWRsZSBhIG5ldyBldmVudCBs
b29wIHRhc2sgdG8gZG8gdGhpcyB3b3JrLgorCisgICAgICAgIFRvIGZpbmQgbmV3bHkgaW5zZXJ0
ZWQgcGFyYWdyYXBocywgd2UgZmlyc3QgZXhwYW5kIHRoZSBlbGVtZW50J3MgYm91bmRhcnkgdG8g
aXRzIHN0YXJ0IGFuZCBlbmQgb2YKKyAgICAgICAgcGFyYWdyYXBocy4gQmVjYXVzZSBlYWNoIGVs
ZW1lbnQgaW4gdGhpcyBwYXJhZ3JhcGggY291bGQgaGF2ZSBiZWVuIGFkZGVkIGluIHRoZSB3ZWFr
IGhhc2ggc2V0LCB3ZQorICAgICAgICB1c2UgaGFzaCBtYXAgdG8gZGUtZHVwbGljYXRlIHN0YXJ0
IGFuZCBlbmQgcG9zaXRpb25zLiBXZSBhbHNvIGZpbHRlciBvdXQgYW55IGVsZW1lbnQgd2hvc2Ug
cGFyZW50CisgICAgICAgIGlzIGFsc28gaW4gdGhlIHdlYWsgaGFzaCBzZXQgc2luY2UgdGhleSB3
b3VsZCBzaW1wbHkgZmluZCBpbm5lciBwYXJhZ3JhcGhzLgorCisgICAgICAgIFRlc3RzOiBUZXh0
TWFuaXB1bGF0aW9uLlN0YXJ0VGV4dE1hbmlwdWxhdGlvbkZpbmROZXdseUluc2VydGVkUGFyYWdy
YXBoCisgICAgICAgICAgICAgICBUZXh0TWFuaXB1bGF0aW9uLlN0YXJ0VGV4dE1hbmlwdWxhdGlv
bkZpbmROZXdseURpc3BsYXllZFBhcmFncmFwaAorICAgICAgICAgICAgICAgVGV4dE1hbmlwdWxh
dGlvbi5TdGFydFRleHRNYW5pcHVsYXRpb25GaW5kU2FtZVBhcmFncmFwaFdpdGhOZXdDb250ZW50
CisKKyAgICAgICAgKiBkb20vVGFza1NvdXJjZS5oOgorICAgICAgICAoV2ViQ29yZTo6VGFza1Nv
dXJjZTo6SW50ZXJuYWxBc3luY1Rhc2spOiBBZGRlZC4KKyAgICAgICAgKiBlZGl0aW5nL1RleHRN
YW5pcHVsYXRpb25Db250cm9sbGVyLmNwcDoKKyAgICAgICAgKFdlYkNvcmU6OlRleHRNYW5pcHVs
YXRpb25Db250cm9sbGVyOjpzdGFydE9ic2VydmluZ1BhcmFncmFwaHMpOgorICAgICAgICAoV2Vi
Q29yZTo6VGV4dE1hbmlwdWxhdGlvbkNvbnRyb2xsZXI6Om9ic2VydmVQYXJhZ3JhcGhzKTogRXh0
cmFjdGVkIG91dCBvZiBzdGFydE9ic2VydmluZ1BhcmFncmFwaHMuCisgICAgICAgIChXZWJDb3Jl
OjpUZXh0TWFuaXB1bGF0aW9uQ29udHJvbGxlcjo6ZGlkQ3JlYXRlUmVuZGVyZXJGb3JFbGVtZW50
KTogQWRkZWQuIEdldHMgY2FsbGVkIHdoZW5ldmVyCisgICAgICAgIGEgbmV3IFJlbmRlckVsZW1l
bnQgaXMgY3JlYXRlZC4KKyAgICAgICAgKFdlYkNvcmU6Om1ha2VQb3NpdGlvblR1cGxlKTogQWRk
ZWQuCisgICAgICAgIChXZWJDb3JlOjptYWtlSGFzaGFibGVQb3NpdGlvblJhbmdlKTogQWRkZWQu
CisgICAgICAgIChXZWJDb3JlOjpUZXh0TWFuaXB1bGF0aW9uQ29udHJvbGxlcjo6c2NoZWR1bGVP
YnNlcnZhcnRpb25VcGRhdGUpOiBBZGRlZC4KKyAgICAgICAgKiBlZGl0aW5nL1RleHRNYW5pcHVs
YXRpb25Db250cm9sbGVyLmg6CisgICAgICAgICogcmVuZGVyaW5nL3VwZGF0aW5nL1JlbmRlclRy
ZWVVcGRhdGVyLmNwcDoKKyAgICAgICAgKFdlYkNvcmU6OlJlbmRlclRyZWVVcGRhdGVyOjpjcmVh
dGVSZW5kZXJlcik6CisKIDIwMTktMTItMTAgIEZ1amlpIEhpcm9ub3JpICA8SGlyb25vcmkuRnVq
aWlAc29ueS5jb20+CiAKICAgICAgICAgW1dpbl0gRml4IE1TVkMgd2FybmluZyBDNDcwMTogcG90
ZW50aWFsbHkgdW5pbml0aWFsaXplZCBsb2NhbCB2YXJpYWJsZSAneCcgdXNlZApkaWZmIC0tZ2l0
IGEvU291cmNlL1dlYkNvcmUvZG9tL1Rhc2tTb3VyY2UuaCBiL1NvdXJjZS9XZWJDb3JlL2RvbS9U
YXNrU291cmNlLmgKaW5kZXggMTQzODg1YzViODg0NGUyZTgwNjBlZDc3Nzk1MDhhNGU2MWMxYjc1
Mi4uYzk3NGQ5NGRiODcwZThjMmYwYzc3ZDExNDJkZDFlOTk3M2FlODYxOSAxMDA2NDQKLS0tIGEv
U291cmNlL1dlYkNvcmUvZG9tL1Rhc2tTb3VyY2UuaAorKysgYi9Tb3VyY2UvV2ViQ29yZS9kb20v
VGFza1NvdXJjZS5oCkBAIC0zNiw3ICszNiwxMCBAQCBlbnVtIGNsYXNzIFRhc2tTb3VyY2UgOiB1
aW50OF90IHsKICAgICBNaWNyb3Rhc2ssCiAgICAgTmV0d29ya2luZywKICAgICBQb3N0ZWRNZXNz
YWdlUXVldWUsCi0gICAgVXNlckludGVyYWN0aW9uCisgICAgVXNlckludGVyYWN0aW9uLAorCisg
ICAgLy8gSW50ZXJuYWwgdG8gV2ViQ29yZQorICAgIEludGVybmFsQXN5bmNUYXNrLCAvLyBTYWZl
IHRvIHJlLW9yZGVyIG9yIGRlbGF5LgogfTsKIAogfSAvLyBuYW1lc3BhY2UgV2ViQ29yZQpkaWZm
IC0tZ2l0IGEvU291cmNlL1dlYkNvcmUvZWRpdGluZy9UZXh0TWFuaXB1bGF0aW9uQ29udHJvbGxl
ci5jcHAgYi9Tb3VyY2UvV2ViQ29yZS9lZGl0aW5nL1RleHRNYW5pcHVsYXRpb25Db250cm9sbGVy
LmNwcAppbmRleCBkMmUzOWY3YmRmM2U1YTZiZjhiMDA5MGNlYzQ5YTBjMGYwMTgxNDNlLi5lMTdi
ZGVjMTQ1YjA4NzViYzU3NjY2YjI1YjZlNGZjMjc3MWJmZDA5IDEwMDY0NAotLS0gYS9Tb3VyY2Uv
V2ViQ29yZS9lZGl0aW5nL1RleHRNYW5pcHVsYXRpb25Db250cm9sbGVyLmNwcAorKysgYi9Tb3Vy
Y2UvV2ViQ29yZS9lZGl0aW5nL1RleHRNYW5pcHVsYXRpb25Db250cm9sbGVyLmNwcApAQCAtMjks
NiArMjksNyBAQAogI2luY2x1ZGUgIkNoYXJhY3RlckRhdGEuaCIKICNpbmNsdWRlICJFZGl0aW5n
LmgiCiAjaW5jbHVkZSAiRWxlbWVudEFuY2VzdG9ySXRlcmF0b3IuaCIKKyNpbmNsdWRlICJFdmVu
dExvb3AuaCIKICNpbmNsdWRlICJTY3JpcHREaXNhbGxvd2VkU2NvcGUuaCIKICNpbmNsdWRlICJU
ZXh0SXRlcmF0b3IuaCIKICNpbmNsdWRlICJWaXNpYmxlVW5pdHMuaCIKQEAgLTExOCw5ICsxMTks
MTcgQEAgdm9pZCBUZXh0TWFuaXB1bGF0aW9uQ29udHJvbGxlcjo6c3RhcnRPYnNlcnZpbmdQYXJh
Z3JhcGhzKE1hbmlwdWxhdGlvbkl0ZW1DYWxsYmEKIAogICAgIFZpc2libGVQb3NpdGlvbiBzdGFy
dCA9IGZpcnN0UG9zaXRpb25Jbk5vZGUobV9kb2N1bWVudC5nZXQoKSk7CiAgICAgVmlzaWJsZVBv
c2l0aW9uIGVuZCA9IGxhc3RQb3NpdGlvbkluTm9kZShtX2RvY3VtZW50LmdldCgpKTsKKworICAg
IG9ic2VydmVQYXJhZ3JhcGhzKHN0YXJ0LCBlbmQpOworfQorCit2b2lkIFRleHRNYW5pcHVsYXRp
b25Db250cm9sbGVyOjpvYnNlcnZlUGFyYWdyYXBocyhWaXNpYmxlUG9zaXRpb24mIHN0YXJ0LCBW
aXNpYmxlUG9zaXRpb24mIGVuZCkKK3sKKyAgICBhdXRvIGRvY3VtZW50ID0gbWFrZVJlZlB0cihz
dGFydC5kZWVwRXF1aXZhbGVudCgpLmRvY3VtZW50KCkpOworICAgIEFTU0VSVChkb2N1bWVudCk7
CiAgICAgVGV4dEl0ZXJhdG9yIGl0ZXJhdG9yIHsgc3RhcnQuZGVlcEVxdWl2YWxlbnQoKSwgZW5k
LmRlZXBFcXVpdmFsZW50KCkgfTsKLSAgICBpZiAoIWRvY3VtZW50KQotICAgICAgICByZXR1cm47
IC8vIFZpc2libGVQb3NpdGlvbiBvciBUZXh0SXRlcmF0b3IncyBjb25zdHJ1Y3RvciBtYXkgaGF2
ZSB1cGRhdGVkIHRoZSBsYXlvdXQgYW5kIGV4ZWN1dGVkIGFyYml0cmFyeSBzY3JpcHRzLgorICAg
IGlmIChkb2N1bWVudCAhPSBzdGFydC5kZWVwRXF1aXZhbGVudCgpLmRvY3VtZW50KCkgfHwgZG9j
dW1lbnQgIT0gZW5kLmRlZXBFcXVpdmFsZW50KCkuZG9jdW1lbnQoKSkKKyAgICAgICAgcmV0dXJu
OyAvLyBUZXh0SXRlcmF0b3IncyBjb25zdHJ1Y3RvciBtYXkgaGF2ZSB1cGRhdGVkIHRoZSBsYXlv
dXQgYW5kIGV4ZWN1dGVkIGFyYml0cmFyeSBzY3JpcHRzLgogCiAgICAgRXhjbHVzaW9uUnVsZU1h
dGNoZXIgZXhjbHVzaW9uUnVsZU1hdGNoZXIobV9leGNsdXNpb25SdWxlcyk7CiAgICAgVmVjdG9y
PE1hbmlwdWxhdGlvblRva2VuPiB0b2tlbnNJbkN1cnJlbnRQYXJhZ3JhcGg7CkBAIC0xNjMsNiAr
MTcyLDY1IEBAIHZvaWQgVGV4dE1hbmlwdWxhdGlvbkNvbnRyb2xsZXI6OnN0YXJ0T2JzZXJ2aW5n
UGFyYWdyYXBocyhNYW5pcHVsYXRpb25JdGVtQ2FsbGJhCiAgICAgICAgIGFkZEl0ZW0oc3RhcnRP
ZkN1cnJlbnRQYXJhZ3JhcGgsIGVuZC5kZWVwRXF1aXZhbGVudCgpLCBXVEZNb3ZlKHRva2Vuc0lu
Q3VycmVudFBhcmFncmFwaCkpOwogfQogCit2b2lkIFRleHRNYW5pcHVsYXRpb25Db250cm9sbGVy
OjpkaWRDcmVhdGVSZW5kZXJlckZvckVsZW1lbnQoRWxlbWVudCYgZWxlbWVudCkKK3sKKyAgICBp
ZiAobV9tdXRhdGVkRWxlbWVudHMuY29tcHV0ZXNFbXB0eSgpKQorICAgICAgICBzY2hlZHVsZU9i
c2VydmFydGlvblVwZGF0ZSgpOworICAgIG1fbXV0YXRlZEVsZW1lbnRzLmFkZChlbGVtZW50KTsK
K30KKwordXNpbmcgUG9zaXRpb25UdXBsZSA9IHN0ZDo6dHVwbGU8UmVmUHRyPE5vZGU+LCB1bnNp
Z25lZCwgdW5zaWduZWQ+Oworc3RhdGljIGNvbnN0IFBvc2l0aW9uVHVwbGUgbWFrZVBvc2l0aW9u
VHVwbGUoY29uc3QgUG9zaXRpb24mIHBvc2l0aW9uKQoreworICAgIHJldHVybiB7IHBvc2l0aW9u
LmFuY2hvck5vZGUoKSwgc3RhdGljX2Nhc3Q8dW5zaWduZWQ+KHBvc2l0aW9uLmFuY2hvclR5cGUo
KSksIHBvc2l0aW9uLmFuY2hvclR5cGUoKSA9PSBQb3NpdGlvbjo6UG9zaXRpb25Jc09mZnNldElu
QW5jaG9yID8gcG9zaXRpb24ub2Zmc2V0SW5Db250YWluZXJOb2RlKCkgOiAwIH07IAorfQorCitz
dGF0aWMgY29uc3Qgc3RkOjpwYWlyPFBvc2l0aW9uVHVwbGUsIFBvc2l0aW9uVHVwbGU+IG1ha2VI
YXNoYWJsZVBvc2l0aW9uUmFuZ2UoY29uc3QgVmlzaWJsZVBvc2l0aW9uJiBzdGFydCwgY29uc3Qg
VmlzaWJsZVBvc2l0aW9uJiBlbmQpCit7CisgICAgcmV0dXJuIHsgbWFrZVBvc2l0aW9uVHVwbGUo
c3RhcnQuZGVlcEVxdWl2YWxlbnQoKSksIG1ha2VQb3NpdGlvblR1cGxlKGVuZC5kZWVwRXF1aXZh
bGVudCgpKSB9OworfQorCit2b2lkIFRleHRNYW5pcHVsYXRpb25Db250cm9sbGVyOjpzY2hlZHVs
ZU9ic2VydmFydGlvblVwZGF0ZSgpCit7CisgICAgaWYgKCFtX2RvY3VtZW50KQorICAgICAgICBy
ZXR1cm47CisKKyAgICBtX2RvY3VtZW50LT5ldmVudExvb3AoKS5xdWV1ZVRhc2soVGFza1NvdXJj
ZTo6SW50ZXJuYWxBc3luY1Rhc2ssIFt3ZWFrVGhpcyA9IG1ha2VXZWFrUHRyKCp0aGlzKV0gewor
ICAgICAgICBhdXRvKiBjb250cm9sbGVyID0gd2Vha1RoaXMuZ2V0KCk7CisgICAgICAgIGlmICgh
Y29udHJvbGxlcikKKyAgICAgICAgICAgIHJldHVybjsKKworICAgICAgICBIYXNoU2V0PFJlZjxF
bGVtZW50Pj4gbXV0YXRlZEVsZW1lbnRzOworICAgICAgICBmb3IgKGF1dG8mIHdlYWtFbGVtZW50
IDogY29udHJvbGxlci0+bV9tdXRhdGVkRWxlbWVudHMpCisgICAgICAgICAgICBtdXRhdGVkRWxl
bWVudHMuYWRkKHdlYWtFbGVtZW50KTsKKyAgICAgICAgY29udHJvbGxlci0+bV9tdXRhdGVkRWxl
bWVudHMuY2xlYXIoKTsKKworICAgICAgICBIYXNoU2V0PFJlZjxFbGVtZW50Pj4gZmlsdGVyZWRF
bGVtZW50czsKKyAgICAgICAgZm9yIChhdXRvJiBlbGVtZW50IDogbXV0YXRlZEVsZW1lbnRzKSB7
CisgICAgICAgICAgICBhdXRvKiBwYXJlbnRFbGVtZW50ID0gZWxlbWVudC0+cGFyZW50RWxlbWVu
dCgpOworICAgICAgICAgICAgaWYgKCFwYXJlbnRFbGVtZW50IHx8ICFtdXRhdGVkRWxlbWVudHMu
Y29udGFpbnMocGFyZW50RWxlbWVudCkpCisgICAgICAgICAgICAgICAgZmlsdGVyZWRFbGVtZW50
cy5hZGQoZWxlbWVudC5jb3B5UmVmKCkpOworICAgICAgICB9CisgICAgICAgIG11dGF0ZWRFbGVt
ZW50cy5jbGVhcigpOworCisgICAgICAgIEhhc2hTZXQ8c3RkOjpwYWlyPFBvc2l0aW9uVHVwbGUs
IFBvc2l0aW9uVHVwbGU+PiBwYXJhZ3JhcGhTZXRzOworICAgICAgICBmb3IgKGF1dG8mIGVsZW1l
bnQgOiBmaWx0ZXJlZEVsZW1lbnRzKSB7CisgICAgICAgICAgICBhdXRvIHN0YXJ0ID0gc3RhcnRP
ZlBhcmFncmFwaChmaXJzdFBvc2l0aW9uSW5PckJlZm9yZU5vZGUoZWxlbWVudC5wdHIoKSkpOwor
ICAgICAgICAgICAgYXV0byBlbmQgPSBlbmRPZlBhcmFncmFwaChsYXN0UG9zaXRpb25Jbk9yQWZ0
ZXJOb2RlKGVsZW1lbnQucHRyKCkpKTsKKworICAgICAgICAgICAgYXV0byBrZXkgPSBtYWtlSGFz
aGFibGVQb3NpdGlvblJhbmdlKHN0YXJ0LCBlbmQpOworICAgICAgICAgICAgaWYgKCFwYXJhZ3Jh
cGhTZXRzLmFkZChrZXkpLmlzTmV3RW50cnkpCisgICAgICAgICAgICAgICAgY29udGludWU7CisK
KyAgICAgICAgICAgIGF1dG8qIGNvbnRyb2xsZXIgPSB3ZWFrVGhpcy5nZXQoKTsKKyAgICAgICAg
ICAgIGlmICghY29udHJvbGxlcikKKyAgICAgICAgICAgICAgICByZXR1cm47IC8vIEZpbmRpbmcg
dGhlIHN0YXJ0L2VuZCBvZiBwYXJhZ3JhcGggbWF5IGhhdmUgdXBkYXRlZCBsYXlvdXQgJiBleGVj
dXRlZCBhcmJpdHJhcnkgc2NyaXB0cy4KKworICAgICAgICAgICAgY29udHJvbGxlci0+b2JzZXJ2
ZVBhcmFncmFwaHMoc3RhcnQsIGVuZCk7CisgICAgICAgIH0KKyAgICB9KTsKK30KKwogdm9pZCBU
ZXh0TWFuaXB1bGF0aW9uQ29udHJvbGxlcjo6YWRkSXRlbShjb25zdCBQb3NpdGlvbiYgc3RhcnRP
ZlBhcmFncmFwaCwgY29uc3QgUG9zaXRpb24mIGVuZE9mUGFyYWdyYXBoLCBWZWN0b3I8TWFuaXB1
bGF0aW9uVG9rZW4+JiYgdG9rZW5zKQogewogICAgIEFTU0VSVChtX2RvY3VtZW50KTsKZGlmZiAt
LWdpdCBhL1NvdXJjZS9XZWJDb3JlL2VkaXRpbmcvVGV4dE1hbmlwdWxhdGlvbkNvbnRyb2xsZXIu
aCBiL1NvdXJjZS9XZWJDb3JlL2VkaXRpbmcvVGV4dE1hbmlwdWxhdGlvbkNvbnRyb2xsZXIuaApp
bmRleCAzNzJjZDY0ZWE0ZmRjNmFlYTYwYWM3ODAwN2EzOTJjNGU2ZGJkZjg1Li43OGExODdlN2Mz
ZDNiMDY5M2RmMjYxNmJkNzYxN2JlYjJiZDM4NTUwIDEwMDY0NAotLS0gYS9Tb3VyY2UvV2ViQ29y
ZS9lZGl0aW5nL1RleHRNYW5pcHVsYXRpb25Db250cm9sbGVyLmgKKysrIGIvU291cmNlL1dlYkNv
cmUvZWRpdGluZy9UZXh0TWFuaXB1bGF0aW9uQ29udHJvbGxlci5oCkBAIC0zMCwxMSArMzAsMTQg
QEAKICNpbmNsdWRlIDx3dGYvRW51bVRyYWl0cy5oPgogI2luY2x1ZGUgPHd0Zi9PYmplY3RJZGVu
dGlmaWVyLmg+CiAjaW5jbHVkZSA8d3RmL09wdGlvbmFsLmg+CisjaW5jbHVkZSA8d3RmL1dlYWtI
YXNoU2V0Lmg+CiAjaW5jbHVkZSA8d3RmL1dlYWtQdHIuaD4KIAogbmFtZXNwYWNlIFdlYkNvcmUg
ewogCiBjbGFzcyBEb2N1bWVudDsKK2NsYXNzIEVsZW1lbnQ7CitjbGFzcyBWaXNpYmxlUG9zaXRp
b247CiAKIGNsYXNzIFRleHRNYW5pcHVsYXRpb25Db250cm9sbGVyIDogcHVibGljIENhbk1ha2VX
ZWFrUHRyPFRleHRNYW5pcHVsYXRpb25Db250cm9sbGVyPiB7CiAgICAgV1RGX01BS0VfRkFTVF9B
TExPQ0FURUQ7CkBAIC05Myw2ICs5Niw4IEBAIHB1YmxpYzoKICAgICB1c2luZyBNYW5pcHVsYXRp
b25JdGVtQ2FsbGJhY2sgPSBXVEY6OkZ1bmN0aW9uPHZvaWQoRG9jdW1lbnQmLCBJdGVtSWRlbnRp
ZmllciwgY29uc3QgVmVjdG9yPE1hbmlwdWxhdGlvblRva2VuPiYpPjsKICAgICBXRUJDT1JFX0VY
UE9SVCB2b2lkIHN0YXJ0T2JzZXJ2aW5nUGFyYWdyYXBocyhNYW5pcHVsYXRpb25JdGVtQ2FsbGJh
Y2smJiwgVmVjdG9yPEV4Y2x1c2lvblJ1bGU+JiYgPSB7IH0pOwogCisgICAgdm9pZCBkaWRDcmVh
dGVSZW5kZXJlckZvckVsZW1lbnQoRWxlbWVudCYpOworCiAgICAgZW51bSBjbGFzcyBNYW5pcHVs
YXRpb25SZXN1bHQgOiB1aW50OF90IHsKICAgICAgICAgU3VjY2VzcywKICAgICAgICAgQ29udGVu
dENoYW5nZWQsCkBAIC0xMDMsNiArMTA4LDkgQEAgcHVibGljOgogICAgIFdFQkNPUkVfRVhQT1JU
IE1hbmlwdWxhdGlvblJlc3VsdCBjb21wbGV0ZU1hbmlwdWxhdGlvbihJdGVtSWRlbnRpZmllciwg
Y29uc3QgVmVjdG9yPE1hbmlwdWxhdGlvblRva2VuPiYpOwogCiBwcml2YXRlOgorICAgIHZvaWQg
b2JzZXJ2ZVBhcmFncmFwaHMoVmlzaWJsZVBvc2l0aW9uJiBzdGFydCwgVmlzaWJsZVBvc2l0aW9u
JiBlbmQpOworICAgIHZvaWQgc2NoZWR1bGVPYnNlcnZhcnRpb25VcGRhdGUoKTsKKwogICAgIHN0
cnVjdCBNYW5pcHVsYXRpb25JdGVtIHsKICAgICAgICAgUG9zaXRpb24gc3RhcnQ7CiAgICAgICAg
IFBvc2l0aW9uIGVuZDsKQEAgLTExMyw2ICsxMjEsNyBAQCBwcml2YXRlOgogICAgIE1hbmlwdWxh
dGlvblJlc3VsdCByZXBsYWNlKGNvbnN0IE1hbmlwdWxhdGlvbkl0ZW0mLCBjb25zdCBWZWN0b3I8
TWFuaXB1bGF0aW9uVG9rZW4+Jik7CiAKICAgICBXZWFrUHRyPERvY3VtZW50PiBtX2RvY3VtZW50
OworICAgIFdlYWtIYXNoU2V0PEVsZW1lbnQ+IG1fbXV0YXRlZEVsZW1lbnRzOwogICAgIE1hbmlw
dWxhdGlvbkl0ZW1DYWxsYmFjayBtX2NhbGxiYWNrOwogICAgIFZlY3RvcjxFeGNsdXNpb25SdWxl
PiBtX2V4Y2x1c2lvblJ1bGVzOwogICAgIEhhc2hNYXA8SXRlbUlkZW50aWZpZXIsIE1hbmlwdWxh
dGlvbkl0ZW0+IG1faXRlbXM7CmRpZmYgLS1naXQgYS9Tb3VyY2UvV2ViQ29yZS9yZW5kZXJpbmcv
dXBkYXRpbmcvUmVuZGVyVHJlZVVwZGF0ZXIuY3BwIGIvU291cmNlL1dlYkNvcmUvcmVuZGVyaW5n
L3VwZGF0aW5nL1JlbmRlclRyZWVVcGRhdGVyLmNwcAppbmRleCAzNjU2ZjNiZmFhZmYzNTQ5YjY4
MzAwNDBhOGUyYjg2YzJjYWZjMDA5Li4yMzFiYjA4NzM2NDQxYjdmMjA4ZjczNzNkOTIwMGQyMDBh
M2E0YTMzIDEwMDY0NAotLS0gYS9Tb3VyY2UvV2ViQ29yZS9yZW5kZXJpbmcvdXBkYXRpbmcvUmVu
ZGVyVHJlZVVwZGF0ZXIuY3BwCisrKyBiL1NvdXJjZS9XZWJDb3JlL3JlbmRlcmluZy91cGRhdGlu
Zy9SZW5kZXJUcmVlVXBkYXRlci5jcHAKQEAgLTQ5LDYgKzQ5LDcgQEAKICNpbmNsdWRlICJSdW50
aW1lRW5hYmxlZEZlYXR1cmVzLmgiCiAjaW5jbHVkZSAiU3R5bGVSZXNvbHZlci5oIgogI2luY2x1
ZGUgIlN0eWxlVHJlZVJlc29sdmVyLmgiCisjaW5jbHVkZSAiVGV4dE1hbmlwdWxhdGlvbkNvbnRy
b2xsZXIuaCIKICNpbmNsdWRlIDx3dGYvU3lzdGVtVHJhY2luZy5oPgogCiAjaWYgRU5BQkxFKExB
WU9VVF9GT1JNQVRUSU5HX0NPTlRFWFQpCkBAIC0zOTcsNiArMzk4LDEwIEBAIHZvaWQgUmVuZGVy
VHJlZVVwZGF0ZXI6OmNyZWF0ZVJlbmRlcmVyKEVsZW1lbnQmIGVsZW1lbnQsIFJlbmRlclN0eWxl
JiYgc3R5bGUpCiAKICAgICBtX2J1aWxkZXIuYXR0YWNoKGluc2VydGlvblBvc2l0aW9uLCBXVEZN
b3ZlKG5ld1JlbmRlcmVyKSk7CiAKKyAgICBhdXRvKiB0ZXh0TWFuaXB1bGF0aW9uQ29udHJvbGxl
ciA9IG1fZG9jdW1lbnQudGV4dE1hbmlwdWxhdGlvbkNvbnRyb2xsZXJJZkV4aXN0cygpOworICAg
IGlmIChVTkxJS0VMWSh0ZXh0TWFuaXB1bGF0aW9uQ29udHJvbGxlcikpCisgICAgICAgIHRleHRN
YW5pcHVsYXRpb25Db250cm9sbGVyLT5kaWRDcmVhdGVSZW5kZXJlckZvckVsZW1lbnQoZWxlbWVu
dCk7CisKICAgICBpZiAoQVhPYmplY3RDYWNoZSogY2FjaGUgPSBtX2RvY3VtZW50LmF4T2JqZWN0
Q2FjaGUoKSkKICAgICAgICAgY2FjaGUtPnVwZGF0ZUNhY2hlQWZ0ZXJOb2RlSXNBdHRhY2hlZCgm
ZWxlbWVudCk7CiB9CmRpZmYgLS1naXQgYS9Ub29scy9DaGFuZ2VMb2cgYi9Ub29scy9DaGFuZ2VM
b2cKaW5kZXggMDBkYWJlNzNmNDhjM2NlZTM0MTdkM2E4Njc1ZjQwZjk4Mzg0ODFkMi4uNzg2ZThk
MTQyNjFjMDVmMGZmZmEwNDMyMzBlZTI5M2RkMTBmZGJhNiAxMDA2NDQKLS0tIGEvVG9vbHMvQ2hh
bmdlTG9nCisrKyBiL1Rvb2xzL0NoYW5nZUxvZwpAQCAtMSwzICsxLDE4IEBACisyMDE5LTEyLTEz
ICBSeW9zdWtlIE5pd2EgIDxybml3YUB3ZWJraXQub3JnPgorCisgICAgICAgIFRleHRNYW5pcHVs
YXRpb25Db250cm9sbGVyIHNob3VsZCBvYnNlcnZlIG5ld2x5IGluc2VydGVkIG9yIGRpc3BsYXll
ZCBjb250ZW50cworICAgICAgICBodHRwczovL2J1Z3Mud2Via2l0Lm9yZy9zaG93X2J1Zy5jZ2k/
aWQ9MjA1MjAzCisgICAgICAgIDxyZGFyOi8vcHJvYmxlbS81NjU2NzAyMD4KKworICAgICAgICBS
ZXZpZXdlZCBieSBOT0JPRFkgKE9PUFMhKS4KKworICAgICAgICBBZGRlZCB0ZXN0cyBmb3IgZGV0
ZWN0aWduIG5ld2x5IGluc2VydGVkIG9yIGRpc3BsYXllZCBjb250ZW50cyBpbiBXS1RleHRNYW5p
cHVsYXRpb24gU1BJLgorCisgICAgICAgICogVGVzdFdlYktpdEFQSS9UZXN0cy9XZWJLaXRDb2Nv
YS9UZXh0TWFuaXB1bGF0aW9uLm1tOgorICAgICAgICAoLVtUZXh0TWFuaXB1bGF0aW9uRGVsZWdh
dGUgaW5pdFdpdGhJdGVtQ2FsbGJhY2tdKToKKyAgICAgICAgKC1bVGV4dE1hbmlwdWxhdGlvbkRl
bGVnYXRlIF93ZWJWaWV3OmRpZEZpbmRUZXh0TWFuaXB1bGF0aW9uSXRlbTpdKToKKyAgICAgICAg
KFRlc3RXZWJLaXRBUEk6OlRFU1QpOgorCiAyMDE5LTEyLTEwICBQZXIgQXJuZSBWb2xsYW4gIDxw
dm9sbGFuQGFwcGxlLmNvbT4KIAogICAgICAgICBGaXggQVBJIHRlc3QgZmFpbHVyZSBhZnRlciBy
MjUzMzUxCmRpZmYgLS1naXQgYS9Ub29scy9UZXN0V2ViS2l0QVBJL1Rlc3RzL1dlYktpdENvY29h
L1RleHRNYW5pcHVsYXRpb24ubW0gYi9Ub29scy9UZXN0V2ViS2l0QVBJL1Rlc3RzL1dlYktpdENv
Y29hL1RleHRNYW5pcHVsYXRpb24ubW0KaW5kZXggZDcwNzU5OGZkYzdlODgyMmJjZjMxNGY5OGEx
ZDM5Zjk5NTUwNGM3NS4uOTRmOWNkZGRjNzc2ZGExZjRlZGZlMmNlZjQxYTIzOGVkMjI4ZTU5YiAx
MDA2NDQKLS0tIGEvVG9vbHMvVGVzdFdlYktpdEFQSS9UZXN0cy9XZWJLaXRDb2NvYS9UZXh0TWFu
aXB1bGF0aW9uLm1tCisrKyBiL1Rvb2xzL1Rlc3RXZWJLaXRBUEkvVGVzdHMvV2ViS2l0Q29jb2Ev
VGV4dE1hbmlwdWxhdGlvbi5tbQpAQCAtMzksMTEgKzM5LDE0IEBACiAKIHN0YXRpYyBib29sIGRv
bmUgPSBmYWxzZTsKIAordHlwZWRlZiB2b2lkKF5JdGVtQ2FsbGJhY2spKF9XS1RleHRNYW5pcHVs
YXRpb25JdGVtICopOworCiBAaW50ZXJmYWNlIFRleHRNYW5pcHVsYXRpb25EZWxlZ2F0ZSA6IE5T
T2JqZWN0IDxfV0tUZXh0TWFuaXB1bGF0aW9uRGVsZWdhdGU+CiAKIC0gKHZvaWQpX3dlYlZpZXc6
KFdLV2ViVmlldyAqKXdlYlZpZXcgZGlkRmluZFRleHRNYW5pcHVsYXRpb25JdGVtOihfV0tUZXh0
TWFuaXB1bGF0aW9uSXRlbSAqKWl0ZW07CiAKIEBwcm9wZXJ0eSAobm9uYXRvbWljLCByZWFkb25s
eSwgY29weSkgTlNBcnJheTxfV0tUZXh0TWFuaXB1bGF0aW9uSXRlbSAqPiAqaXRlbXM7CitAcHJv
cGVydHkgKHN0cm9uZykgSXRlbUNhbGxiYWNrIGl0ZW1DYWxsYmFjazsKIAogQGVuZAogCkBAIC01
OSw5ICs2MiwxOSBAQCBzdGF0aWMgYm9vbCBkb25lID0gZmFsc2U7CiAgICAgcmV0dXJuIHNlbGY7
CiB9CiAKKy0gKGluc3RhbmNldHlwZSlpbml0V2l0aEl0ZW1DYWxsYmFjaworeworICAgIGlmICgh
KHNlbGYgPSBbc3VwZXIgaW5pdF0pKQorICAgICAgICByZXR1cm4gbmlsOworICAgIF9pdGVtcyA9
IGFkb3B0TlMoW1tOU011dGFibGVBcnJheSBhbGxvY10gaW5pdF0pOworICAgIHJldHVybiBzZWxm
OworfQorCiAtICh2b2lkKV93ZWJWaWV3OihXS1dlYlZpZXcgKil3ZWJWaWV3IGRpZEZpbmRUZXh0
TWFuaXB1bGF0aW9uSXRlbTooX1dLVGV4dE1hbmlwdWxhdGlvbkl0ZW0gKilpdGVtCiB7CiAgICAg
W19pdGVtcyBhZGRPYmplY3Q6aXRlbV07CisgICAgaWYgKHNlbGYuaXRlbUNhbGxiYWNrKQorICAg
ICAgICBzZWxmLml0ZW1DYWxsYmFjayhpdGVtKTsKIH0KIAogLSAoTlNBcnJheTxfV0tUZXh0TWFu
aXB1bGF0aW9uSXRlbSAqPiAqKWl0ZW1zCkBAIC0xNzAsNiArMTgzLDEyNSBAQCBURVNUKFRleHRN
YW5pcHVsYXRpb24sIFN0YXJ0VGV4dE1hbmlwdWxhdGlvbkZpbmRQYXJhZ3JhcGhzV2l0aE11bHRp
bGVUb2tlbnMpCiAgICAgRVhQRUNUX1NUUkVRKCJLaXQiLCBpdGVtc1sxXS50b2tlbnNbMV0uY29u
dGVudC5VVEY4U3RyaW5nKTsKIH0KIAorVEVTVChUZXh0TWFuaXB1bGF0aW9uLCBTdGFydFRleHRN
YW5pcHVsYXRpb25GaW5kTmV3bHlJbnNlcnRlZFBhcmFncmFwaCkKK3sKKyAgICBhdXRvIGRlbGVn
YXRlID0gYWRvcHROUyhbW1RleHRNYW5pcHVsYXRpb25EZWxlZ2F0ZSBhbGxvY10gaW5pdF0pOwor
ICAgIGF1dG8gd2ViVmlldyA9IGFkb3B0TlMoW1tUZXN0V0tXZWJWaWV3IGFsbG9jXSBpbml0V2l0
aEZyYW1lOk5TTWFrZVJlY3QoMCwgMCwgNDAwLCA0MDApXSk7CisgICAgW3dlYlZpZXcgX3NldFRl
eHRNYW5pcHVsYXRpb25EZWxlZ2F0ZTpkZWxlZ2F0ZS5nZXQoKV07CisKKyAgICBbd2ViVmlldyBz
eW5jaHJvbm91c2x5TG9hZEhUTUxTdHJpbmc6QCI8IURPQ1RZUEUgaHRtbD48aHRtbD48Ym9keT48
cD5oZWxsbzwvcD48L2JvZHk+PC9odG1sPiJdOworCisgICAgZG9uZSA9IGZhbHNlOworICAgIFt3
ZWJWaWV3IF9zdGFydFRleHRNYW5pcHVsYXRpb25zV2l0aENvbmZpZ3VyYXRpb246bmlsIGNvbXBs
ZXRpb246XnsKKyAgICAgICAgZG9uZSA9IHRydWU7CisgICAgfV07CisgICAgVGVzdFdlYktpdEFQ
STo6VXRpbDo6cnVuKCZkb25lKTsKKworICAgIF9fYmxvY2sgYXV0byAqaXRlbXMgPSBbZGVsZWdh
dGUgaXRlbXNdOworICAgIEVYUEVDVF9FUShpdGVtcy5jb3VudCwgMVVMKTsKKyAgICBFWFBFQ1Rf
RVEoaXRlbXNbMF0udG9rZW5zLmNvdW50LCAxVUwpOworICAgIEVYUEVDVF9TVFJFUSgiaGVsbG8i
LCBpdGVtc1swXS50b2tlbnNbMF0uY29udGVudC5VVEY4U3RyaW5nKTsKKworICAgIGRvbmUgPSBm
YWxzZTsKKyAgICBkZWxlZ2F0ZS5nZXQoKS5pdGVtQ2FsbGJhY2sgPSBeKF9XS1RleHRNYW5pcHVs
YXRpb25JdGVtICppdGVtKSB7CisgICAgICAgIGlmIChpdGVtcy5jb3VudCA9PSAzKQorICAgICAg
ICAgICAgZG9uZSA9IHRydWU7CisgICAgfTsKKyAgICBbd2ViVmlldyBzdHJpbmdCeUV2YWx1YXRp
bmdKYXZhU2NyaXB0OkAiZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVF
bGVtZW50KCdkaXYnKSkuaW5uZXJIVE1MID0gJ3dvcmxkPGJyPjxiPldlYjwvYj5LaXQnOyJdOwor
ICAgIFRlc3RXZWJLaXRBUEk6OlV0aWw6OnJ1bigmZG9uZSk7CisKKyAgICBFWFBFQ1RfRVEoaXRl
bXMuY291bnQsIDNVTCk7CisgICAgRVhQRUNUX0VRKGl0ZW1zWzFdLnRva2Vucy5jb3VudCwgMVVM
KTsKKyAgICBFWFBFQ1RfU1RSRVEoIndvcmxkIiwgaXRlbXNbMV0udG9rZW5zWzBdLmNvbnRlbnQu
VVRGOFN0cmluZyk7CisgICAgRVhQRUNUX0VRKGl0ZW1zWzJdLnRva2Vucy5jb3VudCwgMlVMKTsK
KyAgICBFWFBFQ1RfU1RSRVEoIldlYiIsIGl0ZW1zWzJdLnRva2Vuc1swXS5jb250ZW50LlVURjhT
dHJpbmcpOworICAgIEVYUEVDVF9TVFJFUSgiS2l0IiwgaXRlbXNbMl0udG9rZW5zWzFdLmNvbnRl
bnQuVVRGOFN0cmluZyk7Cit9CisKK1RFU1QoVGV4dE1hbmlwdWxhdGlvbiwgU3RhcnRUZXh0TWFu
aXB1bGF0aW9uRmluZE5ld2x5RGlzcGxheWVkUGFyYWdyYXBoKQoreworICAgIGF1dG8gZGVsZWdh
dGUgPSBhZG9wdE5TKFtbVGV4dE1hbmlwdWxhdGlvbkRlbGVnYXRlIGFsbG9jXSBpbml0XSk7Cisg
ICAgYXV0byB3ZWJWaWV3ID0gYWRvcHROUyhbW1Rlc3RXS1dlYlZpZXcgYWxsb2NdIGluaXRXaXRo
RnJhbWU6TlNNYWtlUmVjdCgwLCAwLCA0MDAsIDQwMCldKTsKKyAgICBbd2ViVmlldyBfc2V0VGV4
dE1hbmlwdWxhdGlvbkRlbGVnYXRlOmRlbGVnYXRlLmdldCgpXTsKKworICAgIFt3ZWJWaWV3IHN5
bmNocm9ub3VzbHlMb2FkSFRNTFN0cmluZzpAIjwhRE9DVFlQRSBodG1sPjxodG1sPjxib2R5PiIK
KyAgICAgICAgIjxzdHlsZT4gLmhpZGRlbiB7IGRpc3BsYXk6IG5vbmU7IH0gPC9zdHlsZT4iCisg
ICAgICAgICI8cD5oZWxsbzwvcD48ZGl2PjxzcGFuIGNsYXNzPSdoaWRkZW4nPldlYjwvc3Bhbj48
c3BhbiBjbGFzcz0naGlkZGVuJz5LaXQ8L3NwYW4+PC9kaXY+PGRpdiBjbGFzcz0naGlkZGVuJz5o
ZXk8L2Rpdj48L2JvZHk+PC9odG1sPiJdOworCisgICAgZG9uZSA9IGZhbHNlOworICAgIFt3ZWJW
aWV3IF9zdGFydFRleHRNYW5pcHVsYXRpb25zV2l0aENvbmZpZ3VyYXRpb246bmlsIGNvbXBsZXRp
b246XnsKKyAgICAgICAgZG9uZSA9IHRydWU7CisgICAgfV07CisgICAgVGVzdFdlYktpdEFQSTo6
VXRpbDo6cnVuKCZkb25lKTsKKworICAgIF9fYmxvY2sgYXV0byAqaXRlbXMgPSBbZGVsZWdhdGUg
aXRlbXNdOworICAgIEVYUEVDVF9FUShpdGVtcy5jb3VudCwgMVVMKTsKKyAgICBFWFBFQ1RfRVEo
aXRlbXNbMF0udG9rZW5zLmNvdW50LCAxVUwpOworICAgIEVYUEVDVF9TVFJFUSgiaGVsbG8iLCBp
dGVtc1swXS50b2tlbnNbMF0uY29udGVudC5VVEY4U3RyaW5nKTsKKworICAgIGRvbmUgPSBmYWxz
ZTsKKyAgICBkZWxlZ2F0ZS5nZXQoKS5pdGVtQ2FsbGJhY2sgPSBeKF9XS1RleHRNYW5pcHVsYXRp
b25JdGVtICppdGVtKSB7CisgICAgICAgIGlmIChpdGVtcy5jb3VudCA9PSAyKQorICAgICAgICAg
ICAgZG9uZSA9IHRydWU7CisgICAgfTsKKyAgICBbd2ViVmlldyBzdHJpbmdCeUV2YWx1YXRpbmdK
YXZhU2NyaXB0OkAiZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnc3Bhbi5oaWRkZW4nKS5mb3JF
YWNoKChzcGFuKSA9PiBzcGFuLmNsYXNzTGlzdC5yZW1vdmUoJ2hpZGRlbicpKTsiXTsKKyAgICBU
ZXN0V2ViS2l0QVBJOjpVdGlsOjpydW4oJmRvbmUpOworCisgICAgRVhQRUNUX0VRKGl0ZW1zLmNv
dW50LCAyVUwpOworICAgIEVYUEVDVF9FUShpdGVtc1sxXS50b2tlbnMuY291bnQsIDJVTCk7Cisg
ICAgRVhQRUNUX1NUUkVRKCJXZWIiLCBpdGVtc1sxXS50b2tlbnNbMF0uY29udGVudC5VVEY4U3Ry
aW5nKTsKKyAgICBFWFBFQ1RfU1RSRVEoIktpdCIsIGl0ZW1zWzFdLnRva2Vuc1sxXS5jb250ZW50
LlVURjhTdHJpbmcpOworCisgICAgLy8gVGhpcyBoYXMgdG8gaGFwcGVuIHNlcGFyYXRlbHkgaW4g
b3JkZXIgdG8gaGF2ZSBhIGRldGVybWluaXN0aWMgb3JkZXJpbmcuCisgICAgZG9uZSA9IGZhbHNl
OworICAgIGRlbGVnYXRlLmdldCgpLml0ZW1DYWxsYmFjayA9IF4oX1dLVGV4dE1hbmlwdWxhdGlv
bkl0ZW0gKml0ZW0pIHsKKyAgICAgICAgaWYgKGl0ZW1zLmNvdW50ID09IDMpCisgICAgICAgICAg
ICBkb25lID0gdHJ1ZTsKKyAgICB9OworICAgIFt3ZWJWaWV3IHN0cmluZ0J5RXZhbHVhdGluZ0ph
dmFTY3JpcHQ6QCJkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCdkaXYuaGlkZGVuJykuZm9yRWFj
aCgoZGl2KSA9PiBkaXYuY2xhc3NMaXN0LnJlbW92ZSgnaGlkZGVuJykpOyJdOworICAgIFRlc3RX
ZWJLaXRBUEk6OlV0aWw6OnJ1bigmZG9uZSk7CisKKyAgICBFWFBFQ1RfRVEoaXRlbXMuY291bnQs
IDNVTCk7CisgICAgRVhQRUNUX0VRKGl0ZW1zWzJdLnRva2Vucy5jb3VudCwgMVVMKTsKKyAgICBF
WFBFQ1RfU1RSRVEoImhleSIsIGl0ZW1zWzJdLnRva2Vuc1swXS5jb250ZW50LlVURjhTdHJpbmcp
OworfQorCitURVNUKFRleHRNYW5pcHVsYXRpb24sIFN0YXJ0VGV4dE1hbmlwdWxhdGlvbkZpbmRT
YW1lUGFyYWdyYXBoV2l0aE5ld0NvbnRlbnQpCit7CisgICAgYXV0byBkZWxlZ2F0ZSA9IGFkb3B0
TlMoW1tUZXh0TWFuaXB1bGF0aW9uRGVsZWdhdGUgYWxsb2NdIGluaXRdKTsKKyAgICBhdXRvIHdl
YlZpZXcgPSBhZG9wdE5TKFtbVGVzdFdLV2ViVmlldyBhbGxvY10gaW5pdFdpdGhGcmFtZTpOU01h
a2VSZWN0KDAsIDAsIDQwMCwgNDAwKV0pOworICAgIFt3ZWJWaWV3IF9zZXRUZXh0TWFuaXB1bGF0
aW9uRGVsZWdhdGU6ZGVsZWdhdGUuZ2V0KCldOworCisgICAgW3dlYlZpZXcgc3luY2hyb25vdXNs
eUxvYWRIVE1MU3RyaW5nOkAiPCFET0NUWVBFIGh0bWw+PGh0bWw+PGJvZHk+PHA+aGVsbG88L3A+
PC9ib2R5PjwvaHRtbD4iXTsKKworICAgIGRvbmUgPSBmYWxzZTsKKyAgICBbd2ViVmlldyBfc3Rh
cnRUZXh0TWFuaXB1bGF0aW9uc1dpdGhDb25maWd1cmF0aW9uOm5pbCBjb21wbGV0aW9uOl57Cisg
ICAgICAgIGRvbmUgPSB0cnVlOworICAgIH1dOworICAgIFRlc3RXZWJLaXRBUEk6OlV0aWw6OnJ1
bigmZG9uZSk7CisKKyAgICBhdXRvICppdGVtcyA9IFtkZWxlZ2F0ZSBpdGVtc107CisgICAgRVhQ
RUNUX0VRKGl0ZW1zLmNvdW50LCAxVUwpOworICAgIEVYUEVDVF9FUShpdGVtc1swXS50b2tlbnMu
Y291bnQsIDFVTCk7CisgICAgRVhQRUNUX1NUUkVRKCJoZWxsbyIsIGl0ZW1zWzBdLnRva2Vuc1sw
XS5jb250ZW50LlVURjhTdHJpbmcpOworCisgICAgZG9uZSA9IGZhbHNlOworICAgIGRlbGVnYXRl
LmdldCgpLml0ZW1DYWxsYmFjayA9IF4oX1dLVGV4dE1hbmlwdWxhdGlvbkl0ZW0gKml0ZW0pIHsK
KyAgICAgICAgZG9uZSA9IHRydWU7CisgICAgfTsKKworICAgIFt3ZWJWaWV3IHN0cmluZ0J5RXZh
bHVhdGluZ0phdmFTY3JpcHQ6QCJiID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYicpOyIKKyAg
ICAgICAgImIudGV4dENvbnRlbnQgPSAnIHdvcmxkJzsiCisgICAgICAgICJkb2N1bWVudC5xdWVy
eVNlbGVjdG9yKCdwJykuYXBwZW5kQ2hpbGQoYik7ICcnIl07CisKKyAgICBUZXN0V2ViS2l0QVBJ
OjpVdGlsOjpydW4oJmRvbmUpOworCisgICAgRVhQRUNUX0VRKGl0ZW1zLmNvdW50LCAyVUwpOwor
ICAgIEVYUEVDVF9FUShpdGVtc1sxXS50b2tlbnMuY291bnQsIDJVTCk7CisgICAgRVhQRUNUX1NU
UkVRKCJoZWxsbyIsIGl0ZW1zWzFdLnRva2Vuc1swXS5jb250ZW50LlVURjhTdHJpbmcpOworICAg
IEVYUEVDVF9TVFJFUSgiIHdvcmxkIiwgaXRlbXNbMV0udG9rZW5zWzFdLmNvbnRlbnQuVVRGOFN0
cmluZyk7Cit9CisKIFRFU1QoVGV4dE1hbmlwdWxhdGlvbiwgU3RhcnRUZXh0TWFuaXB1bGF0aW9u
QXBwbHlTaW5nbGVFeGNsdWlvblJ1bGVGb3JFbGVtZW50KQogewogICAgIGF1dG8gZGVsZWdhdGUg
PSBhZG9wdE5TKFtbVGV4dE1hbmlwdWxhdGlvbkRlbGVnYXRlIGFsbG9jXSBpbml0XSk7CkBAIC00
ODgsOCArNjIwLDYgQEAgVEVTVChUZXh0TWFuaXB1bGF0aW9uLCBDb21wbGV0ZVRleHRNYW5pcHVs
YXRpb25GYWlsV2hlbkV4Y2x1c2lvbklzVmlvbGF0ZWQpCiAgICAgRVhQRUNUX1dLX1NUUkVRKCI8
cD5oaSwgPGVtPldlYktpdHRlbjwvZW0+PC9wPiIsIFt3ZWJWaWV3IHN0cmluZ0J5RXZhbHVhdGlu
Z0phdmFTY3JpcHQ6QCJkb2N1bWVudC5ib2R5LmlubmVySFRNTCJdKTsKIH0KIAotLy8gTUFSSzog
LSBfV0tUZXh0TWFuaXB1bGF0aW9uVG9rZW4gVGVzdHMKLQogVEVTVChUZXh0TWFuaXB1bGF0aW9u
LCBUZXh0TWFuaXB1bGF0aW9uVG9rZW5EZWJ1Z0Rlc2NyaXB0aW9uKQogewogICAgIGF1dG8gdG9r
ZW4gPSBhZG9wdE5TKFtbX1dLVGV4dE1hbmlwdWxhdGlvblRva2VuIGFsbG9jXSBpbml0XSk7CkBA
IC03NzIsOCArOTAyLDYgQEAgVEVTVChUZXh0TWFuaXB1bGF0aW9uLCBUZXh0TWFuaXB1bGF0aW9u
VG9rZW5OU09iamVjdEVxdWFsaXR5V2l0aE5vblRva2VuKQogICAgIEVYUEVDVF9GQUxTRShbdG9r
ZW4gaXNFcXVhbDpuaWxdKTsKIH0KIAotLy8gTUFSSzogLSBfV0tUZXh0TWFuaXB1bGF0aW9uSXRl
bSBUZXN0cwotCiBzdGF0aWMgUmV0YWluUHRyPF9XS1RleHRNYW5pcHVsYXRpb25Ub2tlbj4gY3Jl
YXRlVGV4dE1hbmlwdWxhdGlvblRva2VuKE5TU3RyaW5nICppZGVudGlmaWVyLCBCT09MIGV4Y2x1
ZGVkLCBOU1N0cmluZyAqY29udGVudCkKIHsKICAgICBhdXRvIHRva2VuID0gYWRvcHROUyhbW19X
S1RleHRNYW5pcHVsYXRpb25Ub2tlbiBhbGxvY10gaW5pdF0pOwo=
</data>
<flag name="review"
          id="401469"
          type_id="1"
          status="+"
          setter="wenson_hsieh"
    />
          </attachment>
      

    </bug>

</bugzilla>