<?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>34827</bug_id>
          
          <creation_ts>2010-02-10 18:34:49 -0800</creation_ts>
          <short_desc>audio engine: add FFTFrame files</short_desc>
          <delta_ts>2010-09-07 19:44:57 -0700</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>1</classification_id>
          <classification>Unclassified</classification>
          <product>WebKit</product>
          <component>New Bugs</component>
          <version>528+ (Nightly build)</version>
          <rep_platform>Other</rep_platform>
          <op_sys>OS X 10.5</op_sys>
          <bug_status>RESOLVED</bug_status>
          <resolution>FIXED</resolution>
          
          
          <bug_file_loc></bug_file_loc>
          <status_whiteboard></status_whiteboard>
          <keywords></keywords>
          <priority>P2</priority>
          <bug_severity>Normal</bug_severity>
          <target_milestone>---</target_milestone>
          
          
          <everconfirmed>0</everconfirmed>
          <reporter name="Chris Rogers">crogers</reporter>
          <assigned_to name="Nobody">webkit-unassigned</assigned_to>
          <cc>abarth</cc>
    
    <cc>cmarrin</cc>
    
    <cc>dino</cc>
    
    <cc>eric.carlson</cc>
    
    <cc>eric</cc>
    
    <cc>kbr</cc>
    
    <cc>simon.fraser</cc>
    
    <cc>webkit.review.bot</cc>
          

      

      

      

          <comment_sort_order>oldest_to_newest</comment_sort_order>  
          <long_desc isprivate="0" >
    <commentid>189567</commentid>
    <comment_count>0</comment_count>
    <who name="Chris Rogers">crogers</who>
    <bug_when>2010-02-10 18:34:49 -0800</bug_when>
    <thetext>audio engine: add FFTFrame files</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>189568</commentid>
    <comment_count>1</comment_count>
      <attachid>48540</attachid>
    <who name="Chris Rogers">crogers</who>
    <bug_when>2010-02-10 18:39:42 -0800</bug_when>
    <thetext>Created attachment 48540
Patch</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>189569</commentid>
    <comment_count>2</comment_count>
      <attachid>48540</attachid>
    <who name="Chris Rogers">crogers</who>
    <bug_when>2010-02-10 18:42:25 -0800</bug_when>
    <thetext>Comment on attachment 48540
Patch

FFTFrame is one of the lowest level building blocks for the convolution engine and spatialized panning</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>190159</commentid>
    <comment_count>3</comment_count>
      <attachid>48666</attachid>
    <who name="Chris Rogers">crogers</who>
    <bug_when>2010-02-12 14:44:26 -0800</bug_when>
    <thetext>Created attachment 48666
Patch</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>198982</commentid>
    <comment_count>4</comment_count>
      <attachid>48666</attachid>
    <who name="Jeremy Orlow">jorlow</who>
    <bug_when>2010-03-12 04:08:21 -0800</bug_when>
    <thetext>Comment on attachment 48666
Patch

&gt; diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
&gt; index 866f6d8..a11dd7a 100644
&gt; --- a/WebCore/ChangeLog
&gt; +++ b/WebCore/ChangeLog
&gt; @@ -1,3 +1,35 @@
&gt; +2010-02-12  Chris Rogers  &lt;crogers@google.com&gt;
&gt; +
&gt; +        Reviewed by NOBODY (OOPS!).
&gt; +
&gt; +        audio engine: add FFTFrame files
&gt; +        https://bugs.webkit.org/show_bug.cgi?id=34827
&gt; +
&gt; +        No tests - no javascript API

Add a &quot;yet&quot;


&gt; diff --git a/WebCore/platform/audio/FFTFrame.cpp b/WebCore/platform/audio/FFTFrame.cpp
&gt; new file mode 100644
&gt; index 0000000..17f6c8e
&gt; --- /dev/null
&gt; +++ b/WebCore/platform/audio/FFTFrame.cpp
&gt; @@ -0,0 +1,268 @@
&gt; +/*
&gt; + * Copyright (C) 2010 Google Inc. All rights reserved.
&gt; + *
&gt; + * Redistribution and use in source and binary forms, with or without
&gt; + * modification, are permitted provided that the following conditions
&gt; + * are met:
&gt; + *
&gt; + * 1.  Redistributions of source code must retain the above copyright
&gt; + *     notice, this list of conditions and the following disclaimer.
&gt; + * 2.  Redistributions in binary form must reproduce the above copyright
&gt; + *     notice, this list of conditions and the following disclaimer in the
&gt; + *     documentation and/or other materials provided with the distribution.
&gt; + * 3.  Neither the name of Apple Computer, Inc. (&quot;Apple&quot;) nor the names of
&gt; + *     its contributors may be used to endorse or promote products derived
&gt; + *     from this software without specific prior written permission.
&gt; + *
&gt; + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS &quot;AS IS&quot; AND ANY
&gt; + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
&gt; + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
&gt; + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
&gt; + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
&gt; + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
&gt; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
&gt; + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
&gt; + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
&gt; + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
&gt; + */
&gt; +
&gt; +// Cross-platform FFTFrame implementation

This comment seems out of place and not particularly useful.

&gt; +
&gt; +#include &quot;config.h&quot;
&gt; +#include &quot;FFTFrame.h&quot;
&gt; +
&gt; +#include &lt;wtf/Complex.h&gt;
&gt; +#include &lt;wtf/MathExtras.h&gt;
&gt; +
&gt; +namespace WebCore {
&gt; +
&gt; +void FFTFrame::doPaddedFFT(float* data, size_t dataSize)
&gt; +{
&gt; +    // Zero-pad the impulse response
&gt; +    AudioFloatArray paddedResponse(fftSize());
&gt; +    
&gt; +    assert(dataSize &lt;= fftSize());
&gt; +    memcpy(paddedResponse, data, sizeof(float) * dataSize);
&gt; +
&gt; +    // Get the frequency-domain version of padded response
&gt; +    doFFT(paddedResponse);
&gt; +}
&gt; +
&gt; +FFTFrame* FFTFrame::createInterpolatedFrame(FFTFrame&amp; frame1, FFTFrame&amp; frame2, double x)

Use PassOwnPtr&lt;&gt;

&gt; +{
&gt; +    FFTFrame* newFrame = new FFTFrame(frame1.fftSize());

Use OwnPtr&lt;&gt;

&gt; +
&gt; +    newFrame-&gt;interpolateFrequencyComponents(frame1, frame2, x);
&gt; +
&gt; +    // In the time-domain, the 2nd half of the response must be zero, to avoid circular convolution aliasing...
&gt; +    int fftSize = newFrame-&gt;fftSize();
&gt; +    AudioFloatArray buffer(fftSize);
&gt; +    newFrame-&gt;doInverseFFT(buffer);
&gt; +
&gt; +    memset(buffer.data() + fftSize / 2, 0, sizeof(float) * fftSize / 2);
&gt; +
&gt; +    newFrame-&gt;doFFT(buffer);
&gt; +
&gt; +    return newFrame;
&gt; +}
&gt; +
&gt; +void FFTFrame::interpolateFrequencyComponents(FFTFrame&amp; frame1,
&gt; +                                              FFTFrame&amp; frame2,
&gt; +                                              double interp)
&gt; +{
&gt; +    // FIXME : with some work, this method could be optimized
&gt; +
&gt; +    float* realP = realData();
&gt; +    float* imagP = imagData();
&gt; +
&gt; +    float* realP1 = frame1.realData();
&gt; +    float* imagP1 = frame1.imagData();
&gt; +    float* realP2 = frame2.realData();
&gt; +    float* imagP2 = frame2.imagData();
&gt; +
&gt; +    m_FFTSize = frame1.fftSize();
&gt; +    m_log2FFTSize = frame1.log2FFTSize();
&gt; +
&gt; +    double s1base = (1.0 - interp);
&gt; +    double s2base = interp;
&gt; +
&gt; +    double phaseAccum = 0.0;
&gt; +    double lastPhase1 = 0.0;
&gt; +    double lastPhase2 = 0.0;
&gt; +
&gt; +    realP[0] = s1base * realP1[0] + s2base * realP2[0];
&gt; +    imagP[0] = s1base * imagP1[0] + s2base * imagP2[0];
&gt; +
&gt; +    int n = m_FFTSize / 2;
&gt; +
&gt; +    for (int i = 1; i &lt; n; ++i) {
&gt; +        Complex c1(realP1[i], imagP1[i]);
&gt; +        Complex c2(realP2[i], imagP2[i]);
&gt; +
&gt; +        double mag1 = abs(c1);
&gt; +        double mag2 = abs(c2);
&gt; +
&gt; +        // Interpolate magnitudes in decibels
&gt; +        double mag1db = 20.0 * log10(mag1);
&gt; +        double mag2db = 20.0 * log10(mag2);
&gt; +
&gt; +        double s1 = s1base;
&gt; +        double s2 = s2base;
&gt; +
&gt; +        double magdbdiff = mag1db - mag2db;
&gt; +
&gt; +        // Empirical tweak to retain higher-frequency zeroes
&gt; +        double threshold =  (i &gt; 16) ? 5.0 : 2.0;
&gt; +
&gt; +        if (magdbdiff &lt; -threshold &amp;&amp; mag1db &lt; 0.0) {
&gt; +            s1 = pow(s1, 0.75);
&gt; +            s2 = 1.0 - s1;
&gt; +        } else if (magdbdiff &gt; threshold &amp;&amp; mag2db &lt; 0.0) {
&gt; +            s2 = pow(s2, 0.75);
&gt; +            s1 = 1.0 - s2;
&gt; +        }
&gt; +
&gt; +        // Average magnitude by decibels instead of linearly
&gt; +        double magdb = s1 * mag1db + s2 * mag2db;
&gt; +        double mag = pow(10.0, 0.05 * magdb);
&gt; +
&gt; +        // Now, deal with phase
&gt; +        double phase1 = arg(c1);
&gt; +        double phase2 = arg(c2);
&gt; +
&gt; +        double deltaPhase1 = phase1 - lastPhase1;
&gt; +        double deltaPhase2 = phase2 - lastPhase2;
&gt; +        lastPhase1 = phase1;
&gt; +        lastPhase2 = phase2;
&gt; +
&gt; +        // Unwrap phase deltas
&gt; +        if (deltaPhase1 &gt; M_PI)
&gt; +            deltaPhase1 -= 2.0 * M_PI;
&gt; +        if (deltaPhase1 &lt; -M_PI)
&gt; +            deltaPhase1 += 2.0 * M_PI;
&gt; +        if (deltaPhase2 &gt; M_PI)
&gt; +            deltaPhase2 -= 2.0 * M_PI;
&gt; +        if (deltaPhase2 &lt; -M_PI)
&gt; +            deltaPhase2 += 2.0 * M_PI;
&gt; +
&gt; +        // Blend group-delays
&gt; +        double deltaPhaseBlend;
&gt; +
&gt; +        if (deltaPhase1 - deltaPhase2 &gt; M_PI)
&gt; +            deltaPhaseBlend = s1 * deltaPhase1 + s2 * (2.0 * M_PI + deltaPhase2);
&gt; +        else if (deltaPhase2 - deltaPhase1 &gt; M_PI)
&gt; +            deltaPhaseBlend = s1 * (2.0 * M_PI + deltaPhase1) + s2 * deltaPhase2;
&gt; +        else
&gt; +            deltaPhaseBlend = s1 * deltaPhase1 + s2 * deltaPhase2;
&gt; +
&gt; +        phaseAccum += deltaPhaseBlend;
&gt; +
&gt; +        // Unwrap
&gt; +        if (phaseAccum &gt; M_PI)
&gt; +            phaseAccum -= 2.0 * M_PI;
&gt; +        if (phaseAccum &lt; -M_PI)
&gt; +            phaseAccum += 2.0 * M_PI;
&gt; +
&gt; +        Complex c = complexFromMagnitudePhase(mag, phaseAccum);
&gt; +
&gt; +        realP[i] = c.real();
&gt; +        imagP[i] = c.imag();
&gt; +    }
&gt; +}
&gt; +
&gt; +double  FFTFrame::extractAverageGroupDelay()
&gt; +{
&gt; +    float* realP = realData();
&gt; +    float* imagP = imagData();
&gt; +
&gt; +    double aveSum = 0.0;
&gt; +    double weightSum = 0.0;
&gt; +    double lastPhase = 0.0;
&gt; +
&gt; +    int halfSize = fftSize() / 2;
&gt; +
&gt; +    const double kSamplePhaseDelay = (2.0 * M_PI) / double(fftSize());
&gt; +
&gt; +    // Calculate weighted average group delay
&gt; +    for (int i = 0; i &lt; halfSize; i++) {
&gt; +        Complex c(realP[i], imagP[i]);
&gt; +        double mag = abs(c);
&gt; +        double phase = arg(c);
&gt; +
&gt; +        double deltaPhase = phase - lastPhase;
&gt; +        lastPhase = phase;
&gt; +
&gt; +        // Unwrap
&gt; +        if (deltaPhase &lt; -M_PI)
&gt; +            deltaPhase += 2.0 * M_PI;
&gt; +        if (deltaPhase &gt; M_PI)
&gt; +            deltaPhase -= 2.0 * M_PI;
&gt; +
&gt; +        aveSum += mag * deltaPhase;
&gt; +        weightSum += mag;
&gt; +    }
&gt; +
&gt; +    // Note how we invert the phase delta wrt frequency since this is how group delay is defined
&gt; +    double ave = aveSum / weightSum;
&gt; +    double aveSampleDelay = -ave / kSamplePhaseDelay;
&gt; +
&gt; +    // Leave 20 sample headroom (for leading edge of impulse)
&gt; +    if (aveSampleDelay &gt; 20.0)
&gt; +        aveSampleDelay -= 20.0;
&gt; +
&gt; +    // Remove average group delay (minus 20 samples for headroom)
&gt; +    addConstantGroupDelay(-aveSampleDelay);
&gt; +
&gt; +    // Remove DC offset
&gt; +    realP[0] = 0.0;
&gt; +
&gt; +    return aveSampleDelay;
&gt; +}
&gt; +
&gt; +void  FFTFrame::addConstantGroupDelay(double sampleFrameDelay)
&gt; +{
&gt; +    int halfSize = fftSize() / 2;
&gt; +
&gt; +    float* realP = realData();
&gt; +    float* imagP = imagData();
&gt; +
&gt; +    const double kSamplePhaseDelay = (2.0 * M_PI) / double(fftSize());
&gt; +
&gt; +    double phaseAdj = -sampleFrameDelay * kSamplePhaseDelay;
&gt; +
&gt; +    // Add constant group delay
&gt; +    for (int i = 1; i &lt; halfSize; i++) {
&gt; +        Complex c(realP[i], imagP[i]);
&gt; +        double mag = abs(c);
&gt; +        double phase = arg(c);
&gt; +
&gt; +        phase += i * phaseAdj;
&gt; +
&gt; +        Complex c2 = complexFromMagnitudePhase(mag, phase);
&gt; +
&gt; +        realP[i] = c2.real();
&gt; +        imagP[i] = c2.imag();
&gt; +    }
&gt; +}
&gt; +
&gt; +// For debugging

#ifndef NDEBUG then?

&gt; +void FFTFrame::print()
&gt; +{
&gt; +    FFTFrame&amp; frame = *this;
&gt; +    float* realP = frame.realData();
&gt; +    float* imagP = frame.imagData();
&gt; +    printf(&quot;**** \n&quot;);
&gt; +    printf(&quot;DC = %f : nyquist = %f\n&quot;, realP[0], imagP[0]);
&gt; +
&gt; +    int n = m_FFTSize / 2;
&gt; +
&gt; +    for (int i = 1; i &lt; n; i++) {
&gt; +        double mag = sqrt(realP[i] * realP[i] + imagP[i] * imagP[i]);
&gt; +        double phase = atan2(realP[i], imagP[i]);
&gt; +
&gt; +        printf(&quot;[%d] (%f %f)\n&quot;, i, mag, phase);
&gt; +    }
&gt; +    printf(&quot;****\n&quot;);
&gt; +}
&gt; +
&gt; +} // namespace WebCore
&gt; diff --git a/WebCore/platform/audio/FFTFrame.h b/WebCore/platform/audio/FFTFrame.h
&gt; new file mode 100644
&gt; index 0000000..2130eb0
&gt; --- /dev/null
&gt; +++ b/WebCore/platform/audio/FFTFrame.h
&gt; @@ -0,0 +1,52 @@
&gt; +/*
&gt; + * Copyright (C) 2010 Google Inc. All rights reserved.
&gt; + *
&gt; + * Redistribution and use in source and binary forms, with or without
&gt; + * modification, are permitted provided that the following conditions
&gt; + * are met:
&gt; + *
&gt; + * 1.  Redistributions of source code must retain the above copyright
&gt; + *     notice, this list of conditions and the following disclaimer.
&gt; + * 2.  Redistributions in binary form must reproduce the above copyright
&gt; + *     notice, this list of conditions and the following disclaimer in the
&gt; + *     documentation and/or other materials provided with the distribution.
&gt; + * 3.  Neither the name of Apple Computer, Inc. (&quot;Apple&quot;) nor the names of
&gt; + *     its contributors may be used to endorse or promote products derived
&gt; + *     from this software without specific prior written permission.
&gt; + *
&gt; + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS &quot;AS IS&quot; AND ANY
&gt; + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
&gt; + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
&gt; + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
&gt; + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
&gt; + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
&gt; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
&gt; + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
&gt; + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
&gt; + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
&gt; + */
&gt; +
&gt; +#ifndef FFTFrame_h
&gt; +#define FFTFrame_h
&gt; +
&gt; +#include &lt;wtf/Platform.h&gt;
&gt; +
&gt; +// Defines the interface for an &quot;FFT frame&quot;, an object which is able to perform a forward
&gt; +// and reverse FFT, internally storing the resultant frequency-domain data
&gt; +//
&gt; +// The reason we don&apos;t create an abstract base class and subclass for Mac, MKL, etc.
&gt; +// is because then it would not be possible to use the object in a cross-platform way
&gt; +// as an ivarof a class or as a stack-based object, since we would have to resort to

s/ivar/instance variable/

&gt; +// factory methods, etc.  Since it turns out to be quite useful to use these as ivars
&gt; +// and stack based objects, and since the exact type *is* known at compile-time, we use
&gt; +// this approach.

I don&apos;t understand.  You can just name all of the cross platform libraries FFTFrameBase or FFTFramePlatform or something and then have FFTFrame inherit from that.  The only reason not to do this is if there&apos;s a lot of 2 way dependencies between the halves (and thus you&apos;d need to use virtual calls..which is not desirable).  You could also do this by having the platform specific parts be in their own class and have that class be owned by the cross platform bits or visa versa.  Or you can even split this into multiple layers.  I haven&apos;t looked closely 

The thing I dislike the most is that the .h file is 100% per platform but then pulls in some common CPP files.

&gt; +
&gt; +#if OS(DARWIN)
&gt; +    #include &quot;FFTFrameMac.h&quot;
&gt; +#elif OS(LINUX) || OS(WINDOWS)
&gt; +    #include &quot;FFTFrameMKL.h&quot;
&gt; +#else
&gt; +    #error &quot;OS not supported&quot;
&gt; +#endif

Don&apos;t indent.

&gt; +
&gt; +#endif // FFTFrame_h
&gt; diff --git a/WebCore/platform/audio/mac/FFTFrameMac.cpp b/WebCore/platform/audio/mac/FFTFrameMac.cpp
&gt; new file mode 100644
&gt; index 0000000..e99b573
&gt; --- /dev/null
&gt; +++ b/WebCore/platform/audio/mac/FFTFrameMac.cpp
&gt; @@ -0,0 +1,215 @@
&gt; +/*
&gt; + * Copyright (C) 2010 Google Inc. All rights reserved.
&gt; + *
&gt; + * Redistribution and use in source and binary forms, with or without
&gt; + * modification, are permitted provided that the following conditions
&gt; + * are met:
&gt; + *
&gt; + * 1.  Redistributions of source code must retain the above copyright
&gt; + *     notice, this list of conditions and the following disclaimer.
&gt; + * 2.  Redistributions in binary form must reproduce the above copyright
&gt; + *     notice, this list of conditions and the following disclaimer in the
&gt; + *     documentation and/or other materials provided with the distribution.
&gt; + * 3.  Neither the name of Apple Computer, Inc. (&quot;Apple&quot;) nor the names of
&gt; + *     its contributors may be used to endorse or promote products derived
&gt; + *     from this software without specific prior written permission.
&gt; + *
&gt; + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS &quot;AS IS&quot; AND ANY
&gt; + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
&gt; + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
&gt; + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
&gt; + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
&gt; + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
&gt; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
&gt; + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
&gt; + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
&gt; + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
&gt; + */
&gt; +
&gt; +// Mac OS X - specific FFTFrame implementation
&gt; +
&gt; +#include &quot;config.h&quot;
&gt; +#include &quot;FFTFrameMac.h&quot;
&gt; +
&gt; +namespace WebCore {
&gt; +
&gt; +const int kMaxFFTPow2Size = 24;
&gt; +
&gt; +FFTSetup* FFTFrame::fftSetups = 0;
&gt; +
&gt; +// Normal constructor: allocates for a given fftSize
&gt; +FFTFrame::FFTFrame(size_t fftSize)
&gt; +    : m_realData(fftSize)
&gt; +    , m_imagData(fftSize)
&gt; +{
&gt; +    m_FFTSize = fftSize;
&gt; +    m_log2FFTSize = log2(fftSize);
&gt; +
&gt; +    // We only allow power of two
&gt; +    assert(pow(2.0, m_log2FFTSize) == m_FFTSize);

ASSERT not assert.

And I don&apos;t like that you&apos;re using a float function here.  Why not just use &lt;&lt;?

&gt; +
&gt; +    // Lazily create and share fftSetup with other frames
&gt; +    m_FFTSetup = fftSetupForSize(fftSize);
&gt; +
&gt; +    // Setup frame data
&gt; +    m_frame.realp = m_realData;
&gt; +    m_frame.imagp = m_imagData;
&gt; +}
&gt; +
&gt; +// Creates a blank/empty frame (interpolate() must later be called)
&gt; +FFTFrame::FFTFrame()
&gt; +    : m_realData(0)
&gt; +    , m_imagData(0)
&gt; +{
&gt; +    // Later will be set to correct values when interpolate() is called
&gt; +    m_frame.realp = 0;
&gt; +    m_frame.imagp = 0;
&gt; +
&gt; +    m_FFTSize = 0;
&gt; +    m_log2FFTSize = 0;
&gt; +}
&gt; +
&gt; +// Copy constructor
&gt; +FFTFrame::FFTFrame(const FFTFrame&amp; frame)
&gt; +    : m_FFTSize(frame.m_FFTSize)
&gt; +    , m_log2FFTSize(frame.m_log2FFTSize)
&gt; +    , m_FFTSetup(frame.m_FFTSetup)
&gt; +    , m_realData(frame.m_FFTSize)
&gt; +    , m_imagData(frame.m_FFTSize)
&gt; +{
&gt; +    // Copy/setup frame data
&gt; +    size_t nbytes = sizeof(float) * m_FFTSize;
&gt; +    FFTFrame&amp; safeFrame = const_cast&lt;FFTFrame&amp;&gt;(frame);
&gt; +    memcpy(realData(), safeFrame.realData(), nbytes);
&gt; +    memcpy(imagData(), safeFrame.imagData(), nbytes);

You don&apos;t need to do this.  You can just do frame-&gt;realp and such.  In general, we should do everything we can to avoid const_cast.

&gt; +
&gt; +    m_frame.realp = realData();
&gt; +    m_frame.imagp = imagData();
&gt; +}
&gt; +
&gt; +FFTFrame::~FFTFrame()
&gt; +{
&gt; +}
&gt; +
&gt; +// Uses Accelerate.framework highly-optimized zvmul() function

Not sure if this comment adds any value.

&gt; +void FFTFrame::multiply(const FFTFrame&amp; frame)
&gt; +{
&gt; +    FFTFrame&amp; frame1 = *this;
&gt; +    FFTFrame&amp; frame2 = const_cast&lt;FFTFrame&amp;&gt;(frame);
&gt; +
&gt; +    float* realP1 = frame1.realData();
&gt; +    float* imagP1 = frame1.imagData();
&gt; +    float* realP2 = frame2.realData();
&gt; +    float* imagP2 = frame2.imagData();
&gt; +
&gt; +    // Scale accounts for vecLib&apos;s peculiar scaling
&gt; +    // This ensures the right scaling all the way back to inverse FFT
&gt; +    float scale = 0.5;
&gt; +
&gt; +    // Multiply packed DC/nyquist component
&gt; +    realP1[0] *= scale * realP2[0];
&gt; +    imagP1[0] *= scale * imagP2[0];
&gt; +
&gt; +    // Multiply the rest, skipping packed DC/Nyquist components
&gt; +    DSPSplitComplex sc1 = frame1.dspSplitComplex();
&gt; +    sc1.realp++;
&gt; +    sc1.imagp++;
&gt; +
&gt; +    DSPSplitComplex sc2 = frame2.dspSplitComplex();
&gt; +    sc2.realp++;
&gt; +    sc2.imagp++;
&gt; +
&gt; +    size_t halfSize = m_FFTSize / 2;
&gt; +
&gt; +    // Complex multiply
&gt; +    zvmul(&amp;sc1,
&gt; +          1,
&gt; +          &amp;sc2,
&gt; +          1,
&gt; +          &amp;sc1,
&gt; +          1,
&gt; +          halfSize - 1,
&gt; +          1 /* normal multiplication */);
&gt; +
&gt; +    // We&apos;ve previously scaled the packed part, now scale the rest.....
&gt; +    vsmul(sc1.realp, 1, &amp;scale, sc1.realp, 1, halfSize - 1);
&gt; +    vsmul(sc1.imagp, 1, &amp;scale, sc1.imagp, 1, halfSize - 1);
&gt; +
&gt; +    // Scalar code for reference

I&apos;m leaning towards saying this should removed so it won&apos;t go stale.  Would you mind terribly?

&gt; +#if 0
&gt; +    float scale = 0.5;
&gt; +
&gt; +    // multiply packed DC/nyquist component
&gt; +    realP2[0] *= scale *realP1[0];
&gt; +    imagP2[0] *= scale *imagP1[0];
&gt; +
&gt; +    // scalar code
&gt; +    for (int i = 1; i &lt; halfSize; i++) {
&gt; +        // scale by 1/2 since we&apos;re not handling the scaling in the FFT -&gt; IFFT
&gt; +        // (we&apos;re handling it all in the IFFT stage)
&gt; +
&gt; +
&gt; +        float r1 = realP1[i];
&gt; +        float c1 = imagP1[i];
&gt; +
&gt; +        float r2 = realP2[i];
&gt; +        float c2 = imagP2[i];
&gt; +
&gt; +        // multiply in the frequency domain
&gt; +        float r3 = r1*r2 - c1*c2;
&gt; +        float c3 = r1*c2 + r2*c1;
&gt; +
&gt; +        realP2[i] = scale * r3;
&gt; +        imagP2[i] = scale * c3;
&gt; +    }
&gt; +#endif
&gt; +}
&gt; +
&gt; +void FFTFrame::doFFT(float* data)
&gt; +{
&gt; +    ctoz((DSPComplex*)data, 2, &amp;m_frame, 1, m_FFTSize / 2);
&gt; +    fft_zrip(m_FFTSetup, &amp;m_frame, 1, m_log2FFTSize, FFT_FORWARD);
&gt; +}
&gt; +
&gt; +void FFTFrame::doInverseFFT(float* data)
&gt; +{
&gt; +    fft_zrip(m_FFTSetup, &amp;m_frame, 1, m_log2FFTSize, FFT_INVERSE);
&gt; +    ztoc(&amp;m_frame, 1, (DSPComplex*)data, 2, m_FFTSize / 2);
&gt; +
&gt; +    // Do final scaling so that x == IFFT(FFT(x))
&gt; +    float scale = 0.5 / m_FFTSize;
&gt; +    vsmul(data, 1, &amp;scale, data, 1, m_FFTSize);
&gt; +}
&gt; +
&gt; +FFTSetup FFTFrame::fftSetupForSize(size_t fftSize)
&gt; +{
&gt; +    if (!fftSetups) {
&gt; +        fftSetups = (FFTSetup*)malloc(sizeof(FFTSetup) * kMaxFFTPow2Size);
&gt; +        memset(fftSetups, 0, sizeof(FFTSetup) * kMaxFFTPow2Size);
&gt; +    }
&gt; +
&gt; +    int pow2size = log2(fftSize);
&gt; +
&gt; +    assert(pow2size &lt; kMaxFFTPow2Size);
&gt; +
&gt; +    if (!fftSetups[pow2size])
&gt; +        fftSetups[pow2size] = create_fftsetup(pow2size, FFT_RADIX2);
&gt; +
&gt; +    return fftSetups[pow2size];
&gt; +}

Nit, but it seems like vertical whitespace could be condensed a bit here without making it much harder to read.

&gt; +
&gt; +void FFTFrame::cleanupFFTSetups()
&gt; +{
&gt; +    if (!fftSetups)
&gt; +        return;
&gt; +
&gt; +    for (int i = 0; i &lt; kMaxFFTPow2Size; ++i) {
&gt; +        if (fftSetups[i])
&gt; +            destroy_fftsetup(fftSetups[i]);
&gt; +    }
&gt; +
&gt; +    free(fftSetups);
&gt; +    fftSetups = 0;
&gt; +}
&gt; +
&gt; +} // namespace WebCore
&gt; diff --git a/WebCore/platform/audio/mac/FFTFrameMac.h b/WebCore/platform/audio/mac/FFTFrameMac.h
&gt; new file mode 100644
&gt; index 0000000..40f976b
&gt; --- /dev/null
&gt; +++ b/WebCore/platform/audio/mac/FFTFrameMac.h
&gt; @@ -0,0 +1,91 @@
&gt; +/*
&gt; + * Copyright (C) 2010 Google Inc. All rights reserved.
&gt; + *
&gt; + * Redistribution and use in source and binary forms, with or without
&gt; + * modification, are permitted provided that the following conditions
&gt; + * are met:
&gt; + *
&gt; + * 1.  Redistributions of source code must retain the above copyright
&gt; + *     notice, this list of conditions and the following disclaimer.
&gt; + * 2.  Redistributions in binary form must reproduce the above copyright
&gt; + *     notice, this list of conditions and the following disclaimer in the
&gt; + *     documentation and/or other materials provided with the distribution.
&gt; + * 3.  Neither the name of Apple Computer, Inc. (&quot;Apple&quot;) nor the names of
&gt; + *     its contributors may be used to endorse or promote products derived
&gt; + *     from this software without specific prior written permission.
&gt; + *
&gt; + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS &quot;AS IS&quot; AND ANY
&gt; + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
&gt; + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
&gt; + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
&gt; + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
&gt; + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
&gt; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
&gt; + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
&gt; + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
&gt; + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
&gt; + */
&gt; +
&gt; +// FFT abstraction implemented using Mac OS X Accelerate.framework (vecLib)
&gt; +//
&gt; +
&gt; +#ifndef FFTFrameMac_h
&gt; +#define FFTFrameMac_h
&gt; +
&gt; +#include &quot;AudioFloatArray.h&quot;
&gt; +#include &lt;Accelerate/Accelerate.h&gt;
&gt; +
&gt; +namespace WebCore {
&gt; +
&gt; +class FFTFrame {
&gt; +public:
&gt; +    FFTFrame(size_t fftSize);
&gt; +    FFTFrame(); // creates a blank/empty frame for later use with interpolate()

You mean createInterpolatedFrame or something in some other class?  If the former, correct.  If the latter, make it ClassName::interpolate()

Btw, all of these should be private and you should expose constructors for only what needs to be created outside of this class.

&gt; +    FFTFrame(const FFTFrame&amp; frame);
&gt; +    virtual ~FFTFrame();

Why does this need to be virtual?

&gt; +
&gt; +    void doFFT(float* data);
&gt; +    void doPaddedFFT(float* data, size_t dataSize); // zero-padding with dataSize &lt;= fftSize
&gt; +    void doInverseFFT(float* data);
&gt; +
&gt; +    // Multiplies ourself with |frame| : effectively operator*=()
&gt; +    void multiply(const FFTFrame&amp; frame);
&gt; +
&gt; +    // Interpolates from frame1 -&gt; frame2 as |x| goes from 0.0 -&gt; 1.0
&gt; +    static FFTFrame* createInterpolatedFrame(FFTFrame&amp; frame1, FFTFrame&amp; frame2, double x);

Can the inputs be const?

This should return a PassOwnPtr&lt;FFTFrame&gt;.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>273048</commentid>
    <comment_count>5</comment_count>
      <attachid>66283</attachid>
    <who name="Chris Rogers">crogers</who>
    <bug_when>2010-09-01 15:07:35 -0700</bug_when>
    <thetext>Created attachment 66283
Patch</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>273050</commentid>
    <comment_count>6</comment_count>
    <who name="Chris Rogers">crogers</who>
    <bug_when>2010-09-01 15:08:29 -0700</bug_when>
    <thetext>Addressed all of Jeremy Orlow&apos;s comments.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>273718</commentid>
    <comment_count>7</comment_count>
      <attachid>66283</attachid>
    <who name="Kenneth Russell">kbr</who>
    <bug_when>2010-09-02 18:29:19 -0700</bug_when>
    <thetext>Comment on attachment 66283
Patch

I reorganized the files below to put the header first.

General comment: as in the other files, you really should settle on either floats or doubles throughout. Since it looks like your audio streams are all floats, it seems natural that everything should stick to floats except if there is some precision or range problem with doing so.

&gt; Index: WebCore/platform/audio/FFTFrame.h
&gt; ===================================================================
&gt; --- WebCore/platform/audio/FFTFrame.h	(revision 0)
&gt; +++ WebCore/platform/audio/FFTFrame.h	(revision 0)
&gt; @@ -0,0 +1,101 @@
&gt; +/*
&gt; + * Copyright (C) 2010 Google Inc. All rights reserved.
&gt; + *
&gt; + * Redistribution and use in source and binary forms, with or without
&gt; + * modification, are permitted provided that the following conditions
&gt; + * are met:
&gt; + *
&gt; + * 1.  Redistributions of source code must retain the above copyright
&gt; + *     notice, this list of conditions and the following disclaimer.
&gt; + * 2.  Redistributions in binary form must reproduce the above copyright
&gt; + *     notice, this list of conditions and the following disclaimer in the
&gt; + *     documentation and/or other materials provided with the distribution.
&gt; + * 3.  Neither the name of Apple Computer, Inc. (&quot;Apple&quot;) nor the names of
&gt; + *     its contributors may be used to endorse or promote products derived
&gt; + *     from this software without specific prior written permission.
&gt; + *
&gt; + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS &quot;AS IS&quot; AND ANY
&gt; + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
&gt; + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
&gt; + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
&gt; + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
&gt; + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
&gt; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
&gt; + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
&gt; + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
&gt; + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
&gt; + */
&gt; +
&gt; +#ifndef FFTFrame_h
&gt; +#define FFTFrame_h
&gt; +
&gt; +#include &quot;AudioFloatArray.h&quot;
&gt; +
&gt; +#if OS(DARWIN)
&gt; +#include &lt;Accelerate/Accelerate.h&gt;
&gt; +#endif
&gt; +
&gt; +#include &lt;wtf/PassOwnPtr.h&gt;
&gt; +#include &lt;wtf/Platform.h&gt;
&gt; +
&gt; +namespace WebCore {
&gt; +
&gt; +// Defines the interface for an &quot;FFT frame&quot;, an object which is able to perform a forward
&gt; +// and reverse FFT, internally storing the resultant frequency-domain data.
&gt; +
&gt; +class FFTFrame {
&gt; +public:

It&apos;s hard to figure out which functions are implemented by cross-platform code in platform/audio/FFTFrame.cpp and which require platform-dependent implementations. Please add a comment to the class indicating that all methods must be implemented with platform-dependent code except where indicated. Then doPaddedFFT, createInterpolatedFrame, interpolateFrequencyComponents, extractAverageGroupDelay, addConstantGroupDelay, and print can be marked as being platform-independent in the header.

&gt; +    FFTFrame(unsigned fftSize);
&gt; +    FFTFrame(); // creates a blank/empty frame for later use with createInterpolatedFrame()
&gt; +    FFTFrame(const FFTFrame&amp; frame);
&gt; +    ~FFTFrame();
&gt; +
&gt; +    static void cleanup();

There&apos;s a better way to handle the global cleanup problem. See below.

&gt; +
&gt; +    void doFFT(float* data);
&gt; +    void doPaddedFFT(float* data, size_t dataSize); // zero-padding with dataSize &lt;= fftSize
&gt; +    void doInverseFFT(float* data);
&gt; +
&gt; +    // Multiplies ourself with frame : effectively operator*=()
&gt; +    void multiply(const FFTFrame&amp; frame);
&gt; +
&gt; +    // Interpolates from frame1 -&gt; frame2 as x goes from 0.0 -&gt; 1.0
&gt; +    static PassOwnPtr&lt;FFTFrame&gt; createInterpolatedFrame(const FFTFrame&amp; frame1, const FFTFrame&amp; frame2, double x);
&gt; +
&gt; +    double extractAverageGroupDelay();
&gt; +    void addConstantGroupDelay(double sampleFrameDelay);
&gt; +
&gt; +    unsigned fftSize() const { return m_FFTSize; }
&gt; +    unsigned log2FFTSize() const { return m_log2FFTSize; }
&gt; +
&gt; +    float* realData() const;
&gt; +    float* imagData() const;
&gt; +
&gt; +    // For debugging
&gt; +    void print();
&gt; +
&gt; +private:
&gt; +    unsigned m_FFTSize;
&gt; +    unsigned m_log2FFTSize;
&gt; +
&gt; +    void interpolateFrequencyComponents(const FFTFrame&amp; frame1, const FFTFrame&amp; frame2, double x);
&gt; +
&gt; +#if OS(DARWIN)
&gt; +    DSPSplitComplex&amp; dspSplitComplex() { return m_frame; }
&gt; +    DSPSplitComplex dspSplitComplex() const { return m_frame; }
&gt; +
&gt; +    static FFTSetup fftSetupForSize(unsigned fftSize);
&gt; +
&gt; +    static FFTSetup* fftSetups;

See below for a suggestion that will allow you to get rid of fftSetupForSize and fftSetups here.

&gt; +
&gt; +    FFTSetup m_FFTSetup;
&gt; +
&gt; +    DSPSplitComplex m_frame;
&gt; +    AudioFloatArray m_realData;
&gt; +    AudioFloatArray m_imagData;
&gt; +#endif // OS(DARWIN)
&gt; +};
&gt; +
&gt; +} // namespace WebCore
&gt; +
&gt; +#endif // FFTFrame_h
&gt; Index: WebCore/platform/audio/FFTFrame.cpp
&gt; ===================================================================
&gt; --- WebCore/platform/audio/FFTFrame.cpp	(revision 0)
&gt; +++ WebCore/platform/audio/FFTFrame.cpp	(revision 0)
&gt; @@ -0,0 +1,271 @@
&gt; +/*
&gt; + * Copyright (C) 2010 Google Inc. All rights reserved.
&gt; + *
&gt; + * Redistribution and use in source and binary forms, with or without
&gt; + * modification, are permitted provided that the following conditions
&gt; + * are met:
&gt; + *
&gt; + * 1.  Redistributions of source code must retain the above copyright
&gt; + *     notice, this list of conditions and the following disclaimer.
&gt; + * 2.  Redistributions in binary form must reproduce the above copyright
&gt; + *     notice, this list of conditions and the following disclaimer in the
&gt; + *     documentation and/or other materials provided with the distribution.
&gt; + * 3.  Neither the name of Apple Computer, Inc. (&quot;Apple&quot;) nor the names of
&gt; + *     its contributors may be used to endorse or promote products derived
&gt; + *     from this software without specific prior written permission.
&gt; + *
&gt; + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS &quot;AS IS&quot; AND ANY
&gt; + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
&gt; + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
&gt; + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
&gt; + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
&gt; + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
&gt; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
&gt; + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
&gt; + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
&gt; + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
&gt; + */
&gt; +
&gt; +#include &quot;config.h&quot;
&gt; +
&gt; +#if ENABLE(WEB_AUDIO)
&gt; +
&gt; +#include &quot;FFTFrame.h&quot;
&gt; +
&gt; +#include &lt;wtf/Complex.h&gt;
&gt; +#include &lt;wtf/MathExtras.h&gt;
&gt; +#include &lt;wtf/OwnPtr.h&gt;
&gt; +
&gt; +namespace WebCore {
&gt; +
&gt; +void FFTFrame::doPaddedFFT(float* data, size_t dataSize)
&gt; +{
&gt; +    // Zero-pad the impulse response
&gt; +    AudioFloatArray paddedResponse(fftSize());
&gt; +    
&gt; +    ASSERT(dataSize &lt;= fftSize());
&gt; +    memcpy(paddedResponse.data(), data, sizeof(float) * dataSize);

AudioFloatArray should handle this; you shouldn&apos;t need to call memcpy manually here.

&gt; +
&gt; +    // Get the frequency-domain version of padded response
&gt; +    doFFT(paddedResponse.data());
&gt; +}
&gt; +
&gt; +PassOwnPtr&lt;FFTFrame&gt; FFTFrame::createInterpolatedFrame(const FFTFrame&amp; frame1, const FFTFrame&amp; frame2, double x)
&gt; +{
&gt; +    OwnPtr&lt;FFTFrame&gt; newFrame = adoptPtr(new FFTFrame(frame1.fftSize()));
&gt; +
&gt; +    newFrame-&gt;interpolateFrequencyComponents(frame1, frame2, x);
&gt; +
&gt; +    // In the time-domain, the 2nd half of the response must be zero, to avoid circular convolution aliasing...
&gt; +    int fftSize = newFrame-&gt;fftSize();
&gt; +    AudioFloatArray buffer(fftSize);
&gt; +    newFrame-&gt;doInverseFFT(buffer.data());
&gt; +
&gt; +    memset(buffer.data() + fftSize / 2, 0, sizeof(float) * fftSize / 2);

How about an AudioFloatArray::clearRange() or similar to avoid manual memset?

&gt; +
&gt; +    newFrame-&gt;doFFT(buffer.data());
&gt; +
&gt; +    return newFrame.release();
&gt; +}
&gt; +

The other routines in this file look fine to me.

&gt; +#ifndef NDEBUG
&gt; +void FFTFrame::print()
&gt; +{
&gt; +    FFTFrame&amp; frame = *this;
&gt; +    float* realP = frame.realData();
&gt; +    float* imagP = frame.imagData();
&gt; +    printf(&quot;**** \n&quot;);
&gt; +    printf(&quot;DC = %f : nyquist = %f\n&quot;, realP[0], imagP[0]);
&gt; +
&gt; +    int n = m_FFTSize / 2;
&gt; +
&gt; +    for (int i = 1; i &lt; n; i++) {
&gt; +        double mag = sqrt(realP[i] * realP[i] + imagP[i] * imagP[i]);
&gt; +        double phase = atan2(realP[i], imagP[i]);
&gt; +
&gt; +        printf(&quot;[%d] (%f %f)\n&quot;, i, mag, phase);
&gt; +    }
&gt; +    printf(&quot;****\n&quot;);
&gt; +}
&gt; +#endif // NDEBUG

I don&apos;t think this matters too much, but consider using the LOG macros in wtf/Assertions.h for your printing. Otherwise, #ifndef NDEBUG #include &lt;stdio.h&gt;.

&gt; +
&gt; +} // namespace WebCore
&gt; +
&gt; +#endif // ENABLE(WEB_AUDIO)

&gt; Index: WebCore/platform/audio/mac/FFTFrameMac.cpp
&gt; ===================================================================
&gt; --- WebCore/platform/audio/mac/FFTFrameMac.cpp	(revision 0)
&gt; +++ WebCore/platform/audio/mac/FFTFrameMac.cpp	(revision 0)
&gt; @@ -0,0 +1,191 @@
&gt; +/*
&gt; + * Copyright (C) 2010 Google Inc. All rights reserved.
&gt; + *
&gt; + * Redistribution and use in source and binary forms, with or without
&gt; + * modification, are permitted provided that the following conditions
&gt; + * are met:
&gt; + *
&gt; + * 1.  Redistributions of source code must retain the above copyright
&gt; + *     notice, this list of conditions and the following disclaimer.
&gt; + * 2.  Redistributions in binary form must reproduce the above copyright
&gt; + *     notice, this list of conditions and the following disclaimer in the
&gt; + *     documentation and/or other materials provided with the distribution.
&gt; + * 3.  Neither the name of Apple Computer, Inc. (&quot;Apple&quot;) nor the names of
&gt; + *     its contributors may be used to endorse or promote products derived
&gt; + *     from this software without specific prior written permission.
&gt; + *
&gt; + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS &quot;AS IS&quot; AND ANY
&gt; + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
&gt; + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
&gt; + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
&gt; + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
&gt; + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
&gt; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
&gt; + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
&gt; + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
&gt; + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
&gt; + */
&gt; +
&gt; +// Mac OS X - specific FFTFrame implementation
&gt; +
&gt; +#include &quot;config.h&quot;
&gt; +
&gt; +#if ENABLE(WEB_AUDIO)
&gt; +
&gt; +#include &quot;FFTFrame.h&quot;
&gt; +
&gt; +namespace WebCore {
&gt; +
&gt; +const int kMaxFFTPow2Size = 24;
&gt; +
&gt; +FFTSetup* FFTFrame::fftSetups = 0;
&gt; +
&gt; +// Normal constructor: allocates for a given fftSize
&gt; +FFTFrame::FFTFrame(unsigned fftSize)
&gt; +    : m_realData(fftSize)
&gt; +    , m_imagData(fftSize)
&gt; +{
&gt; +    m_FFTSize = fftSize;
&gt; +    m_log2FFTSize = static_cast&lt;unsigned&gt;(log2(fftSize));
&gt; +
&gt; +    // We only allow power of two
&gt; +    ASSERT(1UL &lt;&lt; m_log2FFTSize == m_FFTSize);
&gt; +
&gt; +    // Lazily create and share fftSetup with other frames
&gt; +    m_FFTSetup = fftSetupForSize(fftSize);

See below for suggestion on this.

&gt; +
&gt; +    // Setup frame data
&gt; +    m_frame.realp = m_realData.data();
&gt; +    m_frame.imagp = m_imagData.data();
&gt; +}
&gt; +
&gt; +// Creates a blank/empty frame (interpolate() must later be called)
&gt; +FFTFrame::FFTFrame()
&gt; +    : m_realData(0)
&gt; +    , m_imagData(0)
&gt; +{
&gt; +    // Later will be set to correct values when interpolate() is called
&gt; +    m_frame.realp = 0;
&gt; +    m_frame.imagp = 0;
&gt; +
&gt; +    m_FFTSize = 0;
&gt; +    m_log2FFTSize = 0;
&gt; +}
&gt; +
&gt; +// Copy constructor
&gt; +FFTFrame::FFTFrame(const FFTFrame&amp; frame)
&gt; +    : m_FFTSize(frame.m_FFTSize)
&gt; +    , m_log2FFTSize(frame.m_log2FFTSize)
&gt; +    , m_FFTSetup(frame.m_FFTSetup)
&gt; +    , m_realData(frame.m_FFTSize)
&gt; +    , m_imagData(frame.m_FFTSize)
&gt; +{
&gt; +    // Setup frame data
&gt; +    m_frame.realp = m_realData.data();
&gt; +    m_frame.imagp = m_imagData.data();
&gt; +
&gt; +    // Copy/setup frame data
&gt; +    unsigned nbytes = sizeof(float) * m_FFTSize;
&gt; +    memcpy(realData(), frame.m_frame.realp, nbytes);
&gt; +    memcpy(imagData(), frame.m_frame.imagp, nbytes);

Helper setters on AudioFloatArray would be 

&gt; +}
&gt; +
&gt; +FFTFrame::~FFTFrame()
&gt; +{
&gt; +}
&gt; +
&gt; +void FFTFrame::multiply(const FFTFrame&amp; frame)
&gt; +{
&gt; +    FFTFrame&amp; frame1 = *this;
&gt; +    const FFTFrame&amp; frame2 = frame;
&gt; +
&gt; +    float* realP1 = frame1.realData();
&gt; +    float* imagP1 = frame1.imagData();
&gt; +    const float* realP2 = frame2.realData();
&gt; +    const float* imagP2 = frame2.imagData();
&gt; +
&gt; +    // Scale accounts for vecLib&apos;s peculiar scaling
&gt; +    // This ensures the right scaling all the way back to inverse FFT
&gt; +    float scale = 0.5f;
&gt; +
&gt; +    // Multiply packed DC/nyquist component
&gt; +    realP1[0] *= scale * realP2[0];
&gt; +    imagP1[0] *= scale * imagP2[0];
&gt; +
&gt; +    // Multiply the rest, skipping packed DC/Nyquist components
&gt; +    DSPSplitComplex sc1 = frame1.dspSplitComplex();
&gt; +    sc1.realp++;
&gt; +    sc1.imagp++;
&gt; +
&gt; +    DSPSplitComplex sc2 = frame2.dspSplitComplex();
&gt; +    sc2.realp++;
&gt; +    sc2.imagp++;
&gt; +
&gt; +    unsigned halfSize = m_FFTSize / 2;
&gt; +
&gt; +    // Complex multiply
&gt; +    vDSP_zvmul(&amp;sc1, 1, &amp;sc2, 1, &amp;sc1, 1, halfSize - 1, 1 /* normal multiplication */);
&gt; +
&gt; +    // We&apos;ve previously scaled the packed part, now scale the rest.....
&gt; +    vDSP_vsmul(sc1.realp, 1, &amp;scale, sc1.realp, 1, halfSize - 1);
&gt; +    vDSP_vsmul(sc1.imagp, 1, &amp;scale, sc1.imagp, 1, halfSize - 1);
&gt; +}
&gt; +
&gt; +void FFTFrame::doFFT(float* data)
&gt; +{
&gt; +    vDSP_ctoz((DSPComplex*)data, 2, &amp;m_frame, 1, m_FFTSize / 2);
&gt; +    vDSP_fft_zrip(m_FFTSetup, &amp;m_frame, 1, m_log2FFTSize, FFT_FORWARD);
&gt; +}
&gt; +
&gt; +void FFTFrame::doInverseFFT(float* data)
&gt; +{
&gt; +    vDSP_fft_zrip(m_FFTSetup, &amp;m_frame, 1, m_log2FFTSize, FFT_INVERSE);
&gt; +    vDSP_ztoc(&amp;m_frame, 1, (DSPComplex*)data, 2, m_FFTSize / 2);
&gt; +
&gt; +    // Do final scaling so that x == IFFT(FFT(x))
&gt; +    float scale = 0.5f / m_FFTSize;
&gt; +    vDSP_vsmul(data, 1, &amp;scale, data, 1, m_FFTSize);
&gt; +}
&gt; +
&gt; +FFTSetup FFTFrame::fftSetupForSize(unsigned fftSize)
&gt; +{
&gt; +    if (!fftSetups) {
&gt; +        fftSetups = (FFTSetup*)malloc(sizeof(FFTSetup) * kMaxFFTPow2Size);
&gt; +        memset(fftSetups, 0, sizeof(FFTSetup) * kMaxFFTPow2Size);
&gt; +    }
&gt; +
&gt; +    int pow2size = static_cast&lt;int&gt;(log2(fftSize));
&gt; +    ASSERT(pow2size &lt; kMaxFFTPow2Size);
&gt; +    if (!fftSetups[pow2size])
&gt; +        fftSetups[pow2size] = vDSP_create_fftsetup(pow2size, FFT_RADIX2);
&gt; +
&gt; +    return fftSetups[pow2size];
&gt; +}
&gt; +
&gt; +void FFTFrame::cleanup()
&gt; +{
&gt; +    if (!fftSetups)
&gt; +        return;
&gt; +
&gt; +    for (int i = 0; i &lt; kMaxFFTPow2Size; ++i) {
&gt; +        if (fftSetups[i])
&gt; +            vDSP_destroy_fftsetup(fftSetups[i]);
&gt; +    }
&gt; +
&gt; +    free(fftSetups);
&gt; +    fftSetups = 0;
&gt; +}
&gt; +

Here&apos;s how you can get rid of FFTFrame::cleanup. Make a class private to this implementation file which holds and lazily initializes the fftSetups. Create a static instance of that class in this file. All its constructor should do is zero its internal fftSetups pointer. You can do the same work in fftSetupForSize (you can just make it a method on that new class). Its destructor should do the work currently in FFTFrame::cleanup. Potentially you could also just make the static variable in this file an OwnPtr of that new class. I&apos;m not sure which would be preferred in WebKit style.

&gt; +float* FFTFrame::realData() const
&gt; +{
&gt; +    return m_frame.realp;
&gt; +}
&gt; +    
&gt; +float* FFTFrame::imagData() const
&gt; +{
&gt; +    return m_frame.imagp;
&gt; +}
&gt; +
&gt; +} // namespace WebCore
&gt; +
&gt; +#endif // ENABLE(WEB_AUDIO)</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>274066</commentid>
    <comment_count>8</comment_count>
    <who name="Chris Rogers">crogers</who>
    <bug_when>2010-09-03 11:36:45 -0700</bug_when>
    <thetext>Hi Ken, thanks for your comments.  I&apos;ll fix everything, but I had a question about your suggestion to create a static instance variable to handle the fft setups.  I&apos;m pretty sure that we&apos;re not allowed to have code run at static initialization time since one of the build steps checks for this.  So I don&apos;t think we can have a static instance of the class, but instead will need a pointer to the class.  Then we&apos;ll still need a cleanup method to delete it later on...</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>274177</commentid>
    <comment_count>9</comment_count>
    <who name="Kenneth Russell">kbr</who>
    <bug_when>2010-09-03 14:26:30 -0700</bug_when>
    <thetext>(In reply to comment #8)
&gt; Hi Ken, thanks for your comments.  I&apos;ll fix everything, but I had a question about your suggestion to create a static instance variable to handle the fft setups.  I&apos;m pretty sure that we&apos;re not allowed to have code run at static initialization time since one of the build steps checks for this.  So I don&apos;t think we can have a static instance of the class, but instead will need a pointer to the class.  Then we&apos;ll still need a cleanup method to delete it later on...

I see. I didn&apos;t realize that. In that case don&apos;t worry about that part of my review.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>274185</commentid>
    <comment_count>10</comment_count>
      <attachid>66544</attachid>
    <who name="Chris Rogers">crogers</who>
    <bug_when>2010-09-03 14:40:59 -0700</bug_when>
    <thetext>Created attachment 66544
Patch</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>274186</commentid>
    <comment_count>11</comment_count>
    <who name="Chris Rogers">crogers</who>
    <bug_when>2010-09-03 14:42:10 -0700</bug_when>
    <thetext>Hi Ken, I think I&apos;ve addressed all of your comments.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>275409</commentid>
    <comment_count>12</comment_count>
      <attachid>66544</attachid>
    <who name="Kenneth Russell">kbr</who>
    <bug_when>2010-09-07 17:03:55 -0700</bug_when>
    <thetext>Comment on attachment 66544
Patch

Revised code looks good to me.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>275478</commentid>
    <comment_count>13</comment_count>
      <attachid>66544</attachid>
    <who name="Chris Rogers">crogers</who>
    <bug_when>2010-09-07 18:03:04 -0700</bug_when>
    <thetext>Comment on attachment 66544
Patch

Clearing flags on attachment: 66544

Committed r66941: &lt;http://trac.webkit.org/changeset/66941&gt;</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>275480</commentid>
    <comment_count>14</comment_count>
    <who name="Chris Rogers">crogers</who>
    <bug_when>2010-09-07 18:03:10 -0700</bug_when>
    <thetext>All reviewed patches have been landed.  Closing bug.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>275557</commentid>
    <comment_count>15</comment_count>
    <who name="WebKit Review Bot">webkit.review.bot</who>
    <bug_when>2010-09-07 19:44:57 -0700</bug_when>
    <thetext>http://trac.webkit.org/changeset/66941 might have broken SnowLeopard Intel Release (Tests)</thetext>
  </long_desc>
      
          <attachment
              isobsolete="1"
              ispatch="1"
              isprivate="0"
          >
            <attachid>48540</attachid>
            <date>2010-02-10 18:39:42 -0800</date>
            <delta_ts>2010-02-12 14:44:22 -0800</delta_ts>
            <desc>Patch</desc>
            <filename>bug-34827-20100210183940.patch</filename>
            <type>text/plain</type>
            <size>21714</size>
            <attacher name="Chris Rogers">crogers</attacher>
            
              <data encoding="base64">ZGlmZiAtLWdpdCBhL1dlYkNvcmUvQ2hhbmdlTG9nIGIvV2ViQ29yZS9DaGFuZ2VMb2cKaW5kZXgg
ODY2ZjZkOC4uMTkxOTRmZSAxMDA2NDQKLS0tIGEvV2ViQ29yZS9DaGFuZ2VMb2cKKysrIGIvV2Vi
Q29yZS9DaGFuZ2VMb2cKQEAgLTEsMyArMSwzMyBAQAorMjAxMC0wMi0xMCAgQ2hyaXMgUm9nZXJz
ICA8Y3JvZ2Vyc0Bnb29nbGUuY29tPgorCisgICAgICAgIFJldmlld2VkIGJ5IE5PQk9EWSAoT09Q
UyEpLgorCisgICAgICAgIGF1ZGlvIGVuZ2luZTogYWRkIEZGVEZyYW1lIGZpbGVzCisgICAgICAg
IGh0dHBzOi8vYnVncy53ZWJraXQub3JnL3Nob3dfYnVnLmNnaT9pZD0zNDgyNworCisgICAgICAg
IG5vIHRlc3RzIHNpbmNlIG5vIGphdmFzY3JpcHQgQVBJCisKKyAgICAgICAgKiBwbGF0Zm9ybS9h
dWRpby9GRlRGcmFtZS5jcHA6IEFkZGVkLgorICAgICAgICAoV2ViQ29yZTo6RkZURnJhbWU6Omlu
dGVycG9sYXRlKToKKyAgICAgICAgKFdlYkNvcmU6OkZGVEZyYW1lOjpwcmludCk6CisgICAgICAg
IChXZWJDb3JlOjpGRlRGcmFtZTo6ZXh0cmFjdEF2ZXJhZ2VHcm91cERlbGF5KToKKyAgICAgICAg
KFdlYkNvcmU6OkZGVEZyYW1lOjphZGRDb25zdGFudEdyb3VwRGVsYXkpOgorICAgICAgICAqIHBs
YXRmb3JtL2F1ZGlvL0ZGVEZyYW1lLmg6IEFkZGVkLgorICAgICAgICAqIHBsYXRmb3JtL2F1ZGlv
L21hYy9GRlRGcmFtZU1hYy5jcHA6IEFkZGVkLgorICAgICAgICAoV2ViQ29yZTo6RkZURnJhbWU6
OkZGVEZyYW1lKToKKyAgICAgICAgKFdlYkNvcmU6OkZGVEZyYW1lOjp+RkZURnJhbWUpOgorICAg
ICAgICAoV2ViQ29yZTo6RkZURnJhbWU6Om11bHRpcGx5KToKKyAgICAgICAgKFdlYkNvcmU6OkZG
VEZyYW1lOjpkb0ZGVCk6CisgICAgICAgIChXZWJDb3JlOjpGRlRGcmFtZTo6ZG9JbnZlcnNlRkZU
KToKKyAgICAgICAgKFdlYkNvcmU6OkZGVEZyYW1lOjpmZnRTZXR1cEZvclNpemUpOgorICAgICAg
ICAoV2ViQ29yZTo6RkZURnJhbWU6OmNsZWFudXBGRlRTZXR1cHMpOgorICAgICAgICAqIHBsYXRm
b3JtL2F1ZGlvL21hYy9GRlRGcmFtZU1hYy5oOiBBZGRlZC4KKyAgICAgICAgKFdlYkNvcmU6OkZG
VEZyYW1lOjpmZnRTaXplKToKKyAgICAgICAgKFdlYkNvcmU6OkZGVEZyYW1lOjpsb2cyRkZUU2l6
ZSk6CisgICAgICAgIChXZWJDb3JlOjpGRlRGcmFtZTo6cmVhbERhdGEpOgorICAgICAgICAoV2Vi
Q29yZTo6RkZURnJhbWU6OmltYWdEYXRhKToKKyAgICAgICAgKFdlYkNvcmU6OkZGVEZyYW1lOjpk
c3BTcGxpdENvbXBsZXgpOgorCiAyMDEwLTAyLTA5ICBDaHJpcyBSb2dlcnMgIDxjcm9nZXJzQGdv
b2dsZS5jb20+CiAKICAgICAgICAgUmV2aWV3ZWQgYnkgTk9CT0RZIChPT1BTISkuCmRpZmYgLS1n
aXQgYS9XZWJDb3JlL3BsYXRmb3JtL2F1ZGlvL0ZGVEZyYW1lLmNwcCBiL1dlYkNvcmUvcGxhdGZv
cm0vYXVkaW8vRkZURnJhbWUuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAu
LmUwZjFiMTIKLS0tIC9kZXYvbnVsbAorKysgYi9XZWJDb3JlL3BsYXRmb3JtL2F1ZGlvL0ZGVEZy
YW1lLmNwcApAQCAtMCwwICsxLDIzOCBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBHb29n
bGUgSW5jLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1
c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorICogbW9kaWZp
Y2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRp
b25zCisgKiBhcmUgbWV0OgorICoKKyAqIDEuICBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNv
ZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorICogICAgIG5vdGljZSwgdGhpcyBs
aXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKyAqIDIuICBS
ZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNv
cHlyaWdodAorICogICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBm
b2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUKKyAqICAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBv
dGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgorICogMy4gIE5l
aXRoZXIgdGhlIG5hbWUgb2YgQXBwbGUgQ29tcHV0ZXIsIEluYy4gKCJBcHBsZSIpIG5vciB0aGUg
bmFtZXMgb2YKKyAqICAgICBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ug
b3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkCisgKiAgICAgZnJvbSB0aGlzIHNvZnR3YXJlIHdp
dGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorICoKKyAqIFRISVMgU09G
VFdBUkUgSVMgUFJPVklERUQgQlkgQVBQTEUgQU5EIElUUyBDT05UUklCVVRPUlMgIkFTIElTIiBB
TkQgQU5ZCisgKiBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQg
Tk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVECisgKiBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJ
TElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCisgKiBESVNDTEFJ
TUVELiBJTiBOTyBFVkVOVCBTSEFMTCBBUFBMRSBPUiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJM
RSBGT1IgQU5ZCisgKiBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVN
UExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUworICogKElOQ0xVRElORywgQlVUIE5PVCBM
SU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOwor
ICogTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElP
TikgSE9XRVZFUiBDQVVTRUQgQU5ECisgKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hF
VEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorICogKElOQ0xVRElO
RyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUg
VVNFIE9GCisgKiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklM
SVRZIE9GIFNVQ0ggREFNQUdFLgorICovCisKKy8vIENyb3NzLXBsYXRmb3JtIEZGVEZyYW1lIGlt
cGxlbWVudGF0aW9uCisKKyNpbmNsdWRlICJjb25maWcuaCIKKyNpbmNsdWRlICJGRlRGcmFtZS5o
IgorCisjaW5jbHVkZSA8d3RmL0NvbXBsZXguaD4KKyNpbmNsdWRlIDx3dGYvTWF0aEV4dHJhcy5o
PgorCituYW1lc3BhY2UgV2ViQ29yZSB7CisKK3ZvaWQgRkZURnJhbWU6OmludGVycG9sYXRlKEZG
VEZyYW1lJiBmcmFtZTEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBGRlRGcmFtZSYgZnJh
bWUyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgZG91YmxlIGludGVycCkKK3sKKyAgICAv
LyBGSVhNRSA6IHdpdGggc29tZSB3b3JrLCB0aGlzIG1ldGhvZCBjb3VsZCBiZSBvcHRpbWl6ZWQK
KworICAgIGZsb2F0KiByZWFsUCA9IHJlYWxEYXRhKCk7CisgICAgZmxvYXQqIGltYWdQID0gaW1h
Z0RhdGEoKTsKKworICAgIGZsb2F0KiByZWFsUDEgPSBmcmFtZTEucmVhbERhdGEoKTsKKyAgICBm
bG9hdCogaW1hZ1AxID0gZnJhbWUxLmltYWdEYXRhKCk7CisgICAgZmxvYXQqIHJlYWxQMiA9IGZy
YW1lMi5yZWFsRGF0YSgpOworICAgIGZsb2F0KiBpbWFnUDIgPSBmcmFtZTIuaW1hZ0RhdGEoKTsK
KworICAgIG1fRkZUU2l6ZSA9IGZyYW1lMS5mZnRTaXplKCk7CisgICAgbV9sb2cyRkZUU2l6ZSA9
IGZyYW1lMS5sb2cyRkZUU2l6ZSgpOworCisgICAgZG91YmxlIHMxYmFzZSA9ICgxLjAgLSBpbnRl
cnApOworICAgIGRvdWJsZSBzMmJhc2UgPSBpbnRlcnA7CisKKyAgICBkb3VibGUgcGhhc2VBY2N1
bSA9IDAuMDsKKyAgICBkb3VibGUgbGFzdFBoYXNlMSA9IDAuMDsKKyAgICBkb3VibGUgbGFzdFBo
YXNlMiA9IDAuMDsKKworICAgIHJlYWxQWzBdID0gczFiYXNlICogcmVhbFAxWzBdICsgczJiYXNl
ICogcmVhbFAyWzBdOworICAgIGltYWdQWzBdID0gczFiYXNlICogaW1hZ1AxWzBdICsgczJiYXNl
ICogaW1hZ1AyWzBdOworCisgICAgaW50IG4gPSBtX0ZGVFNpemUgLyAyOworCisgICAgZm9yIChp
bnQgaSA9IDE7IGkgPCBuOyArK2kpIHsKKyAgICAgICAgQ29tcGxleCBjMShyZWFsUDFbaV0sIGlt
YWdQMVtpXSk7CisgICAgICAgIENvbXBsZXggYzIocmVhbFAyW2ldLCBpbWFnUDJbaV0pOworCisg
ICAgICAgIGRvdWJsZSBtYWcxID0gYWJzKGMxKTsKKyAgICAgICAgZG91YmxlIG1hZzIgPSBhYnMo
YzIpOworCisgICAgICAgIC8vIEludGVycG9sYXRlIG1hZ25pdHVkZXMgaW4gZGVjaWJlbHMKKyAg
ICAgICAgZG91YmxlIG1hZzFkYiA9IDIwLjAgKiBsb2cxMChtYWcxKTsKKyAgICAgICAgZG91Ymxl
IG1hZzJkYiA9IDIwLjAgKiBsb2cxMChtYWcyKTsKKworICAgICAgICBkb3VibGUgczEgPSBzMWJh
c2U7CisgICAgICAgIGRvdWJsZSBzMiA9IHMyYmFzZTsKKworICAgICAgICBkb3VibGUgbWFnZGJk
aWZmID0gbWFnMWRiIC0gbWFnMmRiOworCisgICAgICAgIC8vIEVtcGlyaWNhbCB0d2VhayB0byBy
ZXRhaW4gaGlnaGVyLWZyZXF1ZW5jeSB6ZXJvZXMKKyAgICAgICAgZG91YmxlIHRocmVzaG9sZCA9
ICAoaSA+IDE2KSA/IDUuMCA6IDIuMDsKKworICAgICAgICBpZiAobWFnZGJkaWZmIDwgLXRocmVz
aG9sZCAmJiBtYWcxZGIgPCAwLjApIHsKKyAgICAgICAgICAgIHMxID0gcG93KHMxLCAwLjc1KTsK
KyAgICAgICAgICAgIHMyID0gMS4wIC0gczE7CisgICAgICAgIH0gZWxzZSBpZiAobWFnZGJkaWZm
ID4gdGhyZXNob2xkICYmIG1hZzJkYiA8IDAuMCkgeworICAgICAgICAgICAgczIgPSBwb3coczIs
IDAuNzUpOworICAgICAgICAgICAgczEgPSAxLjAgLSBzMjsKKyAgICAgICAgfQorCisgICAgICAg
IC8vIEF2ZXJhZ2UgbWFnbml0dWRlIGJ5IGRlY2liZWxzIGluc3RlYWQgb2YgbGluZWFybHkKKyAg
ICAgICAgZG91YmxlIG1hZ2RiID0gczEgKiBtYWcxZGIgKyBzMiAqIG1hZzJkYjsKKyAgICAgICAg
ZG91YmxlIG1hZyA9IHBvdygxMC4wLCAwLjA1ICogbWFnZGIpOworCisgICAgICAgIC8vIE5vdywg
ZGVhbCB3aXRoIHBoYXNlCisgICAgICAgIGRvdWJsZSBwaGFzZTEgPSBhcmcoYzEpOworICAgICAg
ICBkb3VibGUgcGhhc2UyID0gYXJnKGMyKTsKKworICAgICAgICBkb3VibGUgZGVsdGFQaGFzZTEg
PSBwaGFzZTEgLSBsYXN0UGhhc2UxOworICAgICAgICBkb3VibGUgZGVsdGFQaGFzZTIgPSBwaGFz
ZTIgLSBsYXN0UGhhc2UyOworICAgICAgICBsYXN0UGhhc2UxID0gcGhhc2UxOworICAgICAgICBs
YXN0UGhhc2UyID0gcGhhc2UyOworCisgICAgICAgIC8vIFVud3JhcCBwaGFzZSBkZWx0YXMKKyAg
ICAgICAgaWYgKGRlbHRhUGhhc2UxID4gTV9QSSkKKyAgICAgICAgICAgIGRlbHRhUGhhc2UxIC09
IDIuMCAqIE1fUEk7CisgICAgICAgIGlmIChkZWx0YVBoYXNlMSA8IC1NX1BJKQorICAgICAgICAg
ICAgZGVsdGFQaGFzZTEgKz0gMi4wICogTV9QSTsKKyAgICAgICAgaWYgKGRlbHRhUGhhc2UyID4g
TV9QSSkKKyAgICAgICAgICAgIGRlbHRhUGhhc2UyIC09IDIuMCAqIE1fUEk7CisgICAgICAgIGlm
IChkZWx0YVBoYXNlMiA8IC1NX1BJKQorICAgICAgICAgICAgZGVsdGFQaGFzZTIgKz0gMi4wICog
TV9QSTsKKworICAgICAgICAvLyBCbGVuZCBncm91cC1kZWxheXMKKyAgICAgICAgZG91YmxlIGRl
bHRhUGhhc2VCbGVuZDsKKworICAgICAgICBpZiAoZGVsdGFQaGFzZTEgLSBkZWx0YVBoYXNlMiA+
IE1fUEkpCisgICAgICAgICAgICBkZWx0YVBoYXNlQmxlbmQgPSBzMSAqIGRlbHRhUGhhc2UxICsg
czIgKiAoMi4wICogTV9QSSArIGRlbHRhUGhhc2UyKTsKKyAgICAgICAgZWxzZSBpZiAoZGVsdGFQ
aGFzZTIgLSBkZWx0YVBoYXNlMSA+IE1fUEkpCisgICAgICAgICAgICBkZWx0YVBoYXNlQmxlbmQg
PSBzMSAqICgyLjAgKiBNX1BJICsgZGVsdGFQaGFzZTEpICsgczIgKiBkZWx0YVBoYXNlMjsKKyAg
ICAgICAgZWxzZQorICAgICAgICAgICAgZGVsdGFQaGFzZUJsZW5kID0gczEgKiBkZWx0YVBoYXNl
MSArIHMyICogZGVsdGFQaGFzZTI7CisKKyAgICAgICAgcGhhc2VBY2N1bSArPSBkZWx0YVBoYXNl
QmxlbmQ7CisKKyAgICAgICAgLy8gVW53cmFwCisgICAgICAgIGlmIChwaGFzZUFjY3VtID4gTV9Q
SSkKKyAgICAgICAgICAgIHBoYXNlQWNjdW0gLT0gMi4wICogTV9QSTsKKyAgICAgICAgaWYgKHBo
YXNlQWNjdW0gPCAtTV9QSSkKKyAgICAgICAgICAgIHBoYXNlQWNjdW0gKz0gMi4wICogTV9QSTsK
KworICAgICAgICBDb21wbGV4IGMgPSBjb21wbGV4RnJvbU1hZ25pdHVkZVBoYXNlKG1hZywgcGhh
c2VBY2N1bSk7CisKKyAgICAgICAgcmVhbFBbaV0gPSBjLnJlYWwoKTsKKyAgICAgICAgaW1hZ1Bb
aV0gPSBjLmltYWcoKTsKKyAgICB9Cit9CisKKy8vIEZvciBkZWJ1Z2dpbmcKK3ZvaWQgRkZURnJh
bWU6OnByaW50KCkKK3sKKyAgICBGRlRGcmFtZSYgZnJhbWUgPSAqdGhpczsKKyAgICBmbG9hdCog
cmVhbFAgPSBmcmFtZS5yZWFsRGF0YSgpOworICAgIGZsb2F0KiBpbWFnUCA9IGZyYW1lLmltYWdE
YXRhKCk7CisgICAgcHJpbnRmKCIqKioqIFxuIik7CisgICAgcHJpbnRmKCJEQyA9ICVmIDogbnlx
dWlzdCA9ICVmXG4iLCByZWFsUFswXSwgaW1hZ1BbMF0pOworCisgICAgaW50IG4gPSBtX0ZGVFNp
emUgLyAyOworCisgICAgZm9yIChpbnQgaSA9IDE7IGkgPCBuOyBpKyspIHsKKyAgICAgICAgZG91
YmxlIG1hZyA9IHNxcnQocmVhbFBbaV0gKiByZWFsUFtpXSArIGltYWdQW2ldICogaW1hZ1BbaV0p
OworICAgICAgICBkb3VibGUgcGhhc2UgPSBhdGFuMihyZWFsUFtpXSwgaW1hZ1BbaV0pOworCisg
ICAgICAgIHByaW50ZigiWyVkXSAoJWYgJWYpXG4iLCBpLCBtYWcsIHBoYXNlKTsKKyAgICB9Cisg
ICAgcHJpbnRmKCIqKioqXG4iKTsKK30KKworZG91YmxlICBGRlRGcmFtZTo6ZXh0cmFjdEF2ZXJh
Z2VHcm91cERlbGF5KCkKK3sKKyAgICBmbG9hdCogcmVhbFAgPSByZWFsRGF0YSgpOworICAgIGZs
b2F0KiBpbWFnUCA9IGltYWdEYXRhKCk7CisKKyAgICBkb3VibGUgYXZlU3VtID0gMC4wOworICAg
IGRvdWJsZSB3ZWlnaHRTdW0gPSAwLjA7CisgICAgZG91YmxlIGxhc3RQaGFzZSA9IDAuMDsKKwor
ICAgIGludCBoYWxmU2l6ZSA9IGZmdFNpemUoKSAvIDI7CisKKyAgICBjb25zdCBkb3VibGUga1Nh
bXBsZVBoYXNlRGVsYXkgPSAoMi4wICogTV9QSSkgLyBkb3VibGUoZmZ0U2l6ZSgpKTsKKworICAg
IC8vIENhbGN1bGF0ZSB3ZWlnaHRlZCBhdmVyYWdlIGdyb3VwIGRlbGF5CisgICAgZm9yIChpbnQg
aSA9IDA7IGkgPCBoYWxmU2l6ZTsgaSsrKSB7CisgICAgICAgIENvbXBsZXggYyhyZWFsUFtpXSwg
aW1hZ1BbaV0pOworICAgICAgICBkb3VibGUgbWFnID0gYWJzKGMpOworICAgICAgICBkb3VibGUg
cGhhc2UgPSBhcmcoYyk7CisKKyAgICAgICAgZG91YmxlIGRlbHRhUGhhc2UgPSBwaGFzZSAtIGxh
c3RQaGFzZTsKKyAgICAgICAgbGFzdFBoYXNlID0gcGhhc2U7CisKKyAgICAgICAgLy8gVW53cmFw
CisgICAgICAgIGlmIChkZWx0YVBoYXNlIDwgLU1fUEkpCisgICAgICAgICAgICBkZWx0YVBoYXNl
ICs9IDIuMCAqIE1fUEk7CisgICAgICAgIGlmIChkZWx0YVBoYXNlID4gTV9QSSkKKyAgICAgICAg
ICAgIGRlbHRhUGhhc2UgLT0gMi4wICogTV9QSTsKKworICAgICAgICBhdmVTdW0gKz0gbWFnICog
ZGVsdGFQaGFzZTsKKyAgICAgICAgd2VpZ2h0U3VtICs9IG1hZzsKKyAgICB9CisKKyAgICAvLyBO
b3RlIGhvdyB3ZSBpbnZlcnQgdGhlIHBoYXNlIGRlbHRhIHdydCBmcmVxdWVuY3kgc2luY2UgdGhp
cyBpcyBob3cgZ3JvdXAgZGVsYXkgaXMgZGVmaW5lZAorICAgIGRvdWJsZSBhdmUgPSBhdmVTdW0g
LyB3ZWlnaHRTdW07CisgICAgZG91YmxlIGF2ZVNhbXBsZURlbGF5ID0gLWF2ZSAvIGtTYW1wbGVQ
aGFzZURlbGF5OworCisgICAgLy8gTGVhdmUgMjAgc2FtcGxlIGhlYWRyb29tIChmb3IgbGVhZGlu
ZyBlZGdlIG9mIGltcHVsc2UpCisgICAgaWYgKGF2ZVNhbXBsZURlbGF5ID4gMjAuMCkKKyAgICAg
ICAgYXZlU2FtcGxlRGVsYXkgLT0gMjAuMDsKKworICAgIC8vIFJlbW92ZSBhdmVyYWdlIGdyb3Vw
IGRlbGF5IChtaW51cyAyMCBzYW1wbGVzIGZvciBoZWFkcm9vbSkKKyAgICBhZGRDb25zdGFudEdy
b3VwRGVsYXkoLWF2ZVNhbXBsZURlbGF5KTsKKworICAgIC8vIFJlbW92ZSBEQyBvZmZzZXQKKyAg
ICByZWFsUFswXSA9IDAuMDsKKworICAgIHJldHVybiBhdmVTYW1wbGVEZWxheTsKK30KKwordm9p
ZCAgRkZURnJhbWU6OmFkZENvbnN0YW50R3JvdXBEZWxheShkb3VibGUgc2FtcGxlRnJhbWVEZWxh
eSkKK3sKKyAgICBpbnQgaGFsZlNpemUgPSBmZnRTaXplKCkgLyAyOworCisgICAgZmxvYXQqIHJl
YWxQID0gcmVhbERhdGEoKTsKKyAgICBmbG9hdCogaW1hZ1AgPSBpbWFnRGF0YSgpOworCisgICAg
Y29uc3QgZG91YmxlIGtTYW1wbGVQaGFzZURlbGF5ID0gKDIuMCAqIE1fUEkpIC8gZG91YmxlKGZm
dFNpemUoKSk7CisKKyAgICBkb3VibGUgcGhhc2VBZGogPSAtc2FtcGxlRnJhbWVEZWxheSAqIGtT
YW1wbGVQaGFzZURlbGF5OworCisgICAgLy8gQWRkIGNvbnN0YW50IGdyb3VwIGRlbGF5CisgICAg
Zm9yIChpbnQgaSA9IDE7IGkgPCBoYWxmU2l6ZTsgaSsrKSB7CisgICAgICAgIENvbXBsZXggYyhy
ZWFsUFtpXSwgaW1hZ1BbaV0pOworICAgICAgICBkb3VibGUgbWFnID0gYWJzKGMpOworICAgICAg
ICBkb3VibGUgcGhhc2UgPSBhcmcoYyk7CisKKyAgICAgICAgcGhhc2UgKz0gaSAqIHBoYXNlQWRq
OworCisgICAgICAgIENvbXBsZXggYzIgPSBjb21wbGV4RnJvbU1hZ25pdHVkZVBoYXNlKG1hZywg
cGhhc2UpOworCisgICAgICAgIHJlYWxQW2ldID0gYzIucmVhbCgpOworICAgICAgICBpbWFnUFtp
XSA9IGMyLmltYWcoKTsKKyAgICB9Cit9CisKK30gLy8gbmFtZXNwYWNlIFdlYkNvcmUKZGlmZiAt
LWdpdCBhL1dlYkNvcmUvcGxhdGZvcm0vYXVkaW8vRkZURnJhbWUuaCBiL1dlYkNvcmUvcGxhdGZv
cm0vYXVkaW8vRkZURnJhbWUuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4y
MTMwZWIwCi0tLSAvZGV2L251bGwKKysrIGIvV2ViQ29yZS9wbGF0Zm9ybS9hdWRpby9GRlRGcmFt
ZS5oCkBAIC0wLDAgKzEsNTIgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgR29vZ2xlIElu
Yy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGlu
IHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKyAqIG1vZGlmaWNhdGlv
biwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwor
ICogYXJlIG1ldDoKKyAqCisgKiAxLiAgUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11
c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKyAqICAgICBub3RpY2UsIHRoaXMgbGlzdCBv
ZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisgKiAyLiAgUmVkaXN0
cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmln
aHQKKyAqICAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93
aW5nIGRpc2NsYWltZXIgaW4gdGhlCisgKiAgICAgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIg
bWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi4KKyAqIDMuICBOZWl0aGVy
IHRoZSBuYW1lIG9mIEFwcGxlIENvbXB1dGVyLCBJbmMuICgiQXBwbGUiKSBub3IgdGhlIG5hbWVz
IG9mCisgKiAgICAgaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHBy
b21vdGUgcHJvZHVjdHMgZGVyaXZlZAorICogICAgIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0
IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKyAqCisgKiBUSElTIFNPRlRXQVJF
IElTIFBST1ZJREVEIEJZIEFQUExFIEFORCBJVFMgQ09OVFJJQlVUT1JTICJBUyBJUyIgQU5EIEFO
WQorICogRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBM
SU1JVEVEIFRPLCBUSEUgSU1QTElFRAorICogV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkg
QU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQorICogRElTQ0xBSU1FRC4g
SU4gTk8gRVZFTlQgU0hBTEwgQVBQTEUgT1IgSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9S
IEFOWQorICogRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZ
LCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMKKyAqIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRF
RCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsKKyAqIExP
U1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhP
V0VWRVIgQ0FVU0VEIEFORAorICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIg
SU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKyAqIChJTkNMVURJTkcgTkVH
TElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBP
RgorICogVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBP
RiBTVUNIIERBTUFHRS4KKyAqLworCisjaWZuZGVmIEZGVEZyYW1lX2gKKyNkZWZpbmUgRkZURnJh
bWVfaAorCisjaW5jbHVkZSA8d3RmL1BsYXRmb3JtLmg+CisKKy8vIERlZmluZXMgdGhlIGludGVy
ZmFjZSBmb3IgYW4gIkZGVCBmcmFtZSIsIGFuIG9iamVjdCB3aGljaCBpcyBhYmxlIHRvIHBlcmZv
cm0gYSBmb3J3YXJkCisvLyBhbmQgcmV2ZXJzZSBGRlQsIGludGVybmFsbHkgc3RvcmluZyB0aGUg
cmVzdWx0YW50IGZyZXF1ZW5jeS1kb21haW4gZGF0YQorLy8KKy8vIFRoZSByZWFzb24gd2UgZG9u
J3QgY3JlYXRlIGFuIGFic3RyYWN0IGJhc2UgY2xhc3MgYW5kIHN1YmNsYXNzIGZvciBNYWMsIE1L
TCwgZXRjLgorLy8gaXMgYmVjYXVzZSB0aGVuIGl0IHdvdWxkIG5vdCBiZSBwb3NzaWJsZSB0byB1
c2UgdGhlIG9iamVjdCBpbiBhIGNyb3NzLXBsYXRmb3JtIHdheQorLy8gYXMgYW4gaXZhciBvZiBh
IGNsYXNzIG9yIGFzIGEgc3RhY2stYmFzZWQgb2JqZWN0LCBzaW5jZSB3ZSB3b3VsZCBoYXZlIHRv
IHJlc29ydCB0bworLy8gZmFjdG9yeSBtZXRob2RzLCBldGMuICBTaW5jZSBpdCB0dXJucyBvdXQg
dG8gYmUgcXVpdGUgdXNlZnVsIHRvIHVzZSB0aGVzZSBhcyBpdmFycworLy8gYW5kIHN0YWNrIGJh
c2VkIG9iamVjdHMsIGFuZCBzaW5jZSB0aGUgZXhhY3QgdHlwZSAqaXMqIGtub3duIGF0IGNvbXBp
bGUtdGltZSwgd2UgdXNlCisvLyB0aGlzIGFwcHJvYWNoLgorCisjaWYgT1MoREFSV0lOKQorICAg
ICNpbmNsdWRlICJGRlRGcmFtZU1hYy5oIgorI2VsaWYgT1MoTElOVVgpIHx8IE9TKFdJTkRPV1Mp
CisgICAgI2luY2x1ZGUgIkZGVEZyYW1lTUtMLmgiCisjZWxzZQorICAgICNlcnJvciAiT1Mgbm90
IHN1cHBvcnRlZCIKKyNlbmRpZgorCisjZW5kaWYgLy8gRkZURnJhbWVfaApkaWZmIC0tZ2l0IGEv
V2ViQ29yZS9wbGF0Zm9ybS9hdWRpby9tYWMvRkZURnJhbWVNYWMuY3BwIGIvV2ViQ29yZS9wbGF0
Zm9ybS9hdWRpby9tYWMvRkZURnJhbWVNYWMuY3BwCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4
IDAwMDAwMDAuLmU5OWI1NzMKLS0tIC9kZXYvbnVsbAorKysgYi9XZWJDb3JlL3BsYXRmb3JtL2F1
ZGlvL21hYy9GRlRGcmFtZU1hYy5jcHAKQEAgLTAsMCArMSwyMTUgQEAKKy8qCisgKiBDb3B5cmln
aHQgKEMpIDIwMTAgR29vZ2xlIEluYy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBSZWRp
c3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdp
dGhvdXQKKyAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBm
b2xsb3dpbmcgY29uZGl0aW9ucworICogYXJlIG1ldDoKKyAqCisgKiAxLiAgUmVkaXN0cmlidXRp
b25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKyAqICAg
ICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2Ns
YWltZXIuCisgKiAyLiAgUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9k
dWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKKyAqICAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25k
aXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlCisgKiAgICAgZG9jdW1l
bnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1
dGlvbi4KKyAqIDMuICBOZWl0aGVyIHRoZSBuYW1lIG9mIEFwcGxlIENvbXB1dGVyLCBJbmMuICgi
QXBwbGUiKSBub3IgdGhlIG5hbWVzIG9mCisgKiAgICAgaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUg
dXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZAorICogICAgIGZyb20g
dGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4K
KyAqCisgKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIEFQUExFIEFORCBJVFMgQ09OVFJJ
QlVUT1JTICJBUyBJUyIgQU5EIEFOWQorICogRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMs
IElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRAorICogV0FSUkFOVElF
UyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NF
IEFSRQorICogRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgQVBQTEUgT1IgSVRTIENPTlRS
SUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWQorICogRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRB
TCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMKKyAqIChJTkNM
VURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09E
UyBPUiBTRVJWSUNFUzsKKyAqIExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJ
TkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAorICogT04gQU5ZIFRIRU9SWSBP
RiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRP
UlQKKyAqIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5Z
IFdBWSBPVVQgT0YgVEhFIFVTRSBPRgorICogVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VE
IE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKyAqLworCisvLyBNYWMgT1MgWCAt
IHNwZWNpZmljIEZGVEZyYW1lIGltcGxlbWVudGF0aW9uCisKKyNpbmNsdWRlICJjb25maWcuaCIK
KyNpbmNsdWRlICJGRlRGcmFtZU1hYy5oIgorCituYW1lc3BhY2UgV2ViQ29yZSB7CisKK2NvbnN0
IGludCBrTWF4RkZUUG93MlNpemUgPSAyNDsKKworRkZUU2V0dXAqIEZGVEZyYW1lOjpmZnRTZXR1
cHMgPSAwOworCisvLyBOb3JtYWwgY29uc3RydWN0b3I6IGFsbG9jYXRlcyBmb3IgYSBnaXZlbiBm
ZnRTaXplCitGRlRGcmFtZTo6RkZURnJhbWUoc2l6ZV90IGZmdFNpemUpCisgICAgOiBtX3JlYWxE
YXRhKGZmdFNpemUpCisgICAgLCBtX2ltYWdEYXRhKGZmdFNpemUpCit7CisgICAgbV9GRlRTaXpl
ID0gZmZ0U2l6ZTsKKyAgICBtX2xvZzJGRlRTaXplID0gbG9nMihmZnRTaXplKTsKKworICAgIC8v
IFdlIG9ubHkgYWxsb3cgcG93ZXIgb2YgdHdvCisgICAgYXNzZXJ0KHBvdygyLjAsIG1fbG9nMkZG
VFNpemUpID09IG1fRkZUU2l6ZSk7CisKKyAgICAvLyBMYXppbHkgY3JlYXRlIGFuZCBzaGFyZSBm
ZnRTZXR1cCB3aXRoIG90aGVyIGZyYW1lcworICAgIG1fRkZUU2V0dXAgPSBmZnRTZXR1cEZvclNp
emUoZmZ0U2l6ZSk7CisKKyAgICAvLyBTZXR1cCBmcmFtZSBkYXRhCisgICAgbV9mcmFtZS5yZWFs
cCA9IG1fcmVhbERhdGE7CisgICAgbV9mcmFtZS5pbWFncCA9IG1faW1hZ0RhdGE7Cit9CisKKy8v
IENyZWF0ZXMgYSBibGFuay9lbXB0eSBmcmFtZSAoaW50ZXJwb2xhdGUoKSBtdXN0IGxhdGVyIGJl
IGNhbGxlZCkKK0ZGVEZyYW1lOjpGRlRGcmFtZSgpCisgICAgOiBtX3JlYWxEYXRhKDApCisgICAg
LCBtX2ltYWdEYXRhKDApCit7CisgICAgLy8gTGF0ZXIgd2lsbCBiZSBzZXQgdG8gY29ycmVjdCB2
YWx1ZXMgd2hlbiBpbnRlcnBvbGF0ZSgpIGlzIGNhbGxlZAorICAgIG1fZnJhbWUucmVhbHAgPSAw
OworICAgIG1fZnJhbWUuaW1hZ3AgPSAwOworCisgICAgbV9GRlRTaXplID0gMDsKKyAgICBtX2xv
ZzJGRlRTaXplID0gMDsKK30KKworLy8gQ29weSBjb25zdHJ1Y3RvcgorRkZURnJhbWU6OkZGVEZy
YW1lKGNvbnN0IEZGVEZyYW1lJiBmcmFtZSkKKyAgICA6IG1fRkZUU2l6ZShmcmFtZS5tX0ZGVFNp
emUpCisgICAgLCBtX2xvZzJGRlRTaXplKGZyYW1lLm1fbG9nMkZGVFNpemUpCisgICAgLCBtX0ZG
VFNldHVwKGZyYW1lLm1fRkZUU2V0dXApCisgICAgLCBtX3JlYWxEYXRhKGZyYW1lLm1fRkZUU2l6
ZSkKKyAgICAsIG1faW1hZ0RhdGEoZnJhbWUubV9GRlRTaXplKQoreworICAgIC8vIENvcHkvc2V0
dXAgZnJhbWUgZGF0YQorICAgIHNpemVfdCBuYnl0ZXMgPSBzaXplb2YoZmxvYXQpICogbV9GRlRT
aXplOworICAgIEZGVEZyYW1lJiBzYWZlRnJhbWUgPSBjb25zdF9jYXN0PEZGVEZyYW1lJj4oZnJh
bWUpOworICAgIG1lbWNweShyZWFsRGF0YSgpLCBzYWZlRnJhbWUucmVhbERhdGEoKSwgbmJ5dGVz
KTsKKyAgICBtZW1jcHkoaW1hZ0RhdGEoKSwgc2FmZUZyYW1lLmltYWdEYXRhKCksIG5ieXRlcyk7
CisKKyAgICBtX2ZyYW1lLnJlYWxwID0gcmVhbERhdGEoKTsKKyAgICBtX2ZyYW1lLmltYWdwID0g
aW1hZ0RhdGEoKTsKK30KKworRkZURnJhbWU6On5GRlRGcmFtZSgpCit7Cit9CisKKy8vIFVzZXMg
QWNjZWxlcmF0ZS5mcmFtZXdvcmsgaGlnaGx5LW9wdGltaXplZCB6dm11bCgpIGZ1bmN0aW9uCit2
b2lkIEZGVEZyYW1lOjptdWx0aXBseShjb25zdCBGRlRGcmFtZSYgZnJhbWUpCit7CisgICAgRkZU
RnJhbWUmIGZyYW1lMSA9ICp0aGlzOworICAgIEZGVEZyYW1lJiBmcmFtZTIgPSBjb25zdF9jYXN0
PEZGVEZyYW1lJj4oZnJhbWUpOworCisgICAgZmxvYXQqIHJlYWxQMSA9IGZyYW1lMS5yZWFsRGF0
YSgpOworICAgIGZsb2F0KiBpbWFnUDEgPSBmcmFtZTEuaW1hZ0RhdGEoKTsKKyAgICBmbG9hdCog
cmVhbFAyID0gZnJhbWUyLnJlYWxEYXRhKCk7CisgICAgZmxvYXQqIGltYWdQMiA9IGZyYW1lMi5p
bWFnRGF0YSgpOworCisgICAgLy8gU2NhbGUgYWNjb3VudHMgZm9yIHZlY0xpYidzIHBlY3VsaWFy
IHNjYWxpbmcKKyAgICAvLyBUaGlzIGVuc3VyZXMgdGhlIHJpZ2h0IHNjYWxpbmcgYWxsIHRoZSB3
YXkgYmFjayB0byBpbnZlcnNlIEZGVAorICAgIGZsb2F0IHNjYWxlID0gMC41OworCisgICAgLy8g
TXVsdGlwbHkgcGFja2VkIERDL255cXVpc3QgY29tcG9uZW50CisgICAgcmVhbFAxWzBdICo9IHNj
YWxlICogcmVhbFAyWzBdOworICAgIGltYWdQMVswXSAqPSBzY2FsZSAqIGltYWdQMlswXTsKKwor
ICAgIC8vIE11bHRpcGx5IHRoZSByZXN0LCBza2lwcGluZyBwYWNrZWQgREMvTnlxdWlzdCBjb21w
b25lbnRzCisgICAgRFNQU3BsaXRDb21wbGV4IHNjMSA9IGZyYW1lMS5kc3BTcGxpdENvbXBsZXgo
KTsKKyAgICBzYzEucmVhbHArKzsKKyAgICBzYzEuaW1hZ3ArKzsKKworICAgIERTUFNwbGl0Q29t
cGxleCBzYzIgPSBmcmFtZTIuZHNwU3BsaXRDb21wbGV4KCk7CisgICAgc2MyLnJlYWxwKys7Cisg
ICAgc2MyLmltYWdwKys7CisKKyAgICBzaXplX3QgaGFsZlNpemUgPSBtX0ZGVFNpemUgLyAyOwor
CisgICAgLy8gQ29tcGxleCBtdWx0aXBseQorICAgIHp2bXVsKCZzYzEsCisgICAgICAgICAgMSwK
KyAgICAgICAgICAmc2MyLAorICAgICAgICAgIDEsCisgICAgICAgICAgJnNjMSwKKyAgICAgICAg
ICAxLAorICAgICAgICAgIGhhbGZTaXplIC0gMSwKKyAgICAgICAgICAxIC8qIG5vcm1hbCBtdWx0
aXBsaWNhdGlvbiAqLyk7CisKKyAgICAvLyBXZSd2ZSBwcmV2aW91c2x5IHNjYWxlZCB0aGUgcGFj
a2VkIHBhcnQsIG5vdyBzY2FsZSB0aGUgcmVzdC4uLi4uCisgICAgdnNtdWwoc2MxLnJlYWxwLCAx
LCAmc2NhbGUsIHNjMS5yZWFscCwgMSwgaGFsZlNpemUgLSAxKTsKKyAgICB2c211bChzYzEuaW1h
Z3AsIDEsICZzY2FsZSwgc2MxLmltYWdwLCAxLCBoYWxmU2l6ZSAtIDEpOworCisgICAgLy8gU2Nh
bGFyIGNvZGUgZm9yIHJlZmVyZW5jZQorI2lmIDAKKyAgICBmbG9hdCBzY2FsZSA9IDAuNTsKKwor
ICAgIC8vIG11bHRpcGx5IHBhY2tlZCBEQy9ueXF1aXN0IGNvbXBvbmVudAorICAgIHJlYWxQMlsw
XSAqPSBzY2FsZSAqcmVhbFAxWzBdOworICAgIGltYWdQMlswXSAqPSBzY2FsZSAqaW1hZ1AxWzBd
OworCisgICAgLy8gc2NhbGFyIGNvZGUKKyAgICBmb3IgKGludCBpID0gMTsgaSA8IGhhbGZTaXpl
OyBpKyspIHsKKyAgICAgICAgLy8gc2NhbGUgYnkgMS8yIHNpbmNlIHdlJ3JlIG5vdCBoYW5kbGlu
ZyB0aGUgc2NhbGluZyBpbiB0aGUgRkZUIC0+IElGRlQKKyAgICAgICAgLy8gKHdlJ3JlIGhhbmRs
aW5nIGl0IGFsbCBpbiB0aGUgSUZGVCBzdGFnZSkKKworCisgICAgICAgIGZsb2F0IHIxID0gcmVh
bFAxW2ldOworICAgICAgICBmbG9hdCBjMSA9IGltYWdQMVtpXTsKKworICAgICAgICBmbG9hdCBy
MiA9IHJlYWxQMltpXTsKKyAgICAgICAgZmxvYXQgYzIgPSBpbWFnUDJbaV07CisKKyAgICAgICAg
Ly8gbXVsdGlwbHkgaW4gdGhlIGZyZXF1ZW5jeSBkb21haW4KKyAgICAgICAgZmxvYXQgcjMgPSBy
MSpyMiAtIGMxKmMyOworICAgICAgICBmbG9hdCBjMyA9IHIxKmMyICsgcjIqYzE7CisKKyAgICAg
ICAgcmVhbFAyW2ldID0gc2NhbGUgKiByMzsKKyAgICAgICAgaW1hZ1AyW2ldID0gc2NhbGUgKiBj
MzsKKyAgICB9CisjZW5kaWYKK30KKwordm9pZCBGRlRGcmFtZTo6ZG9GRlQoZmxvYXQqIGRhdGEp
Cit7CisgICAgY3RveigoRFNQQ29tcGxleCopZGF0YSwgMiwgJm1fZnJhbWUsIDEsIG1fRkZUU2l6
ZSAvIDIpOworICAgIGZmdF96cmlwKG1fRkZUU2V0dXAsICZtX2ZyYW1lLCAxLCBtX2xvZzJGRlRT
aXplLCBGRlRfRk9SV0FSRCk7Cit9CisKK3ZvaWQgRkZURnJhbWU6OmRvSW52ZXJzZUZGVChmbG9h
dCogZGF0YSkKK3sKKyAgICBmZnRfenJpcChtX0ZGVFNldHVwLCAmbV9mcmFtZSwgMSwgbV9sb2cy
RkZUU2l6ZSwgRkZUX0lOVkVSU0UpOworICAgIHp0b2MoJm1fZnJhbWUsIDEsIChEU1BDb21wbGV4
KilkYXRhLCAyLCBtX0ZGVFNpemUgLyAyKTsKKworICAgIC8vIERvIGZpbmFsIHNjYWxpbmcgc28g
dGhhdCB4ID09IElGRlQoRkZUKHgpKQorICAgIGZsb2F0IHNjYWxlID0gMC41IC8gbV9GRlRTaXpl
OworICAgIHZzbXVsKGRhdGEsIDEsICZzY2FsZSwgZGF0YSwgMSwgbV9GRlRTaXplKTsKK30KKwor
RkZUU2V0dXAgRkZURnJhbWU6OmZmdFNldHVwRm9yU2l6ZShzaXplX3QgZmZ0U2l6ZSkKK3sKKyAg
ICBpZiAoIWZmdFNldHVwcykgeworICAgICAgICBmZnRTZXR1cHMgPSAoRkZUU2V0dXAqKW1hbGxv
YyhzaXplb2YoRkZUU2V0dXApICoga01heEZGVFBvdzJTaXplKTsKKyAgICAgICAgbWVtc2V0KGZm
dFNldHVwcywgMCwgc2l6ZW9mKEZGVFNldHVwKSAqIGtNYXhGRlRQb3cyU2l6ZSk7CisgICAgfQor
CisgICAgaW50IHBvdzJzaXplID0gbG9nMihmZnRTaXplKTsKKworICAgIGFzc2VydChwb3cyc2l6
ZSA8IGtNYXhGRlRQb3cyU2l6ZSk7CisKKyAgICBpZiAoIWZmdFNldHVwc1twb3cyc2l6ZV0pCisg
ICAgICAgIGZmdFNldHVwc1twb3cyc2l6ZV0gPSBjcmVhdGVfZmZ0c2V0dXAocG93MnNpemUsIEZG
VF9SQURJWDIpOworCisgICAgcmV0dXJuIGZmdFNldHVwc1twb3cyc2l6ZV07Cit9CisKK3ZvaWQg
RkZURnJhbWU6OmNsZWFudXBGRlRTZXR1cHMoKQoreworICAgIGlmICghZmZ0U2V0dXBzKQorICAg
ICAgICByZXR1cm47CisKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGtNYXhGRlRQb3cyU2l6ZTsg
KytpKSB7CisgICAgICAgIGlmIChmZnRTZXR1cHNbaV0pCisgICAgICAgICAgICBkZXN0cm95X2Zm
dHNldHVwKGZmdFNldHVwc1tpXSk7CisgICAgfQorCisgICAgZnJlZShmZnRTZXR1cHMpOworICAg
IGZmdFNldHVwcyA9IDA7Cit9CisKK30gLy8gbmFtZXNwYWNlIFdlYkNvcmUKZGlmZiAtLWdpdCBh
L1dlYkNvcmUvcGxhdGZvcm0vYXVkaW8vbWFjL0ZGVEZyYW1lTWFjLmggYi9XZWJDb3JlL3BsYXRm
b3JtL2F1ZGlvL21hYy9GRlRGcmFtZU1hYy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAw
MDAwMDAuLmM5OThmMzkKLS0tIC9kZXYvbnVsbAorKysgYi9XZWJDb3JlL3BsYXRmb3JtL2F1ZGlv
L21hYy9GRlRGcmFtZU1hYy5oCkBAIC0wLDAgKzEsODggQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMp
IDIwMTAgR29vZ2xlIEluYy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBSZWRpc3RyaWJ1
dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQK
KyAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dp
bmcgY29uZGl0aW9ucworICogYXJlIG1ldDoKKyAqCisgKiAxLiAgUmVkaXN0cmlidXRpb25zIG9m
IHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKyAqICAgICBub3Rp
Y2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIu
CisgKiAyLiAgUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRo
ZSBhYm92ZSBjb3B5cmlnaHQKKyAqICAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25z
IGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlCisgKiAgICAgZG9jdW1lbnRhdGlv
biBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi4K
KyAqIDMuICBOZWl0aGVyIHRoZSBuYW1lIG9mIEFwcGxlIENvbXB1dGVyLCBJbmMuICgiQXBwbGUi
KSBub3IgdGhlIG5hbWVzIG9mCisgKiAgICAgaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0
byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZAorICogICAgIGZyb20gdGhpcyBz
b2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKyAqCisg
KiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIEFQUExFIEFORCBJVFMgQ09OVFJJQlVUT1JT
ICJBUyBJUyIgQU5EIEFOWQorICogRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xV
RElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRAorICogV0FSUkFOVElFUyBPRiBN
RVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQor
ICogRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgQVBQTEUgT1IgSVRTIENPTlRSSUJVVE9S
UyBCRSBMSUFCTEUgRk9SIEFOWQorICogRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BF
Q0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMKKyAqIChJTkNMVURJTkcs
IEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBT
RVJWSUNFUzsKKyAqIExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJ
TlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAorICogT04gQU5ZIFRIRU9SWSBPRiBMSUFC
SUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKyAq
IChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBP
VVQgT0YgVEhFIFVTRSBPRgorICogVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRI
RSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKyAqLworCisvLyBGRlQgYWJzdHJhY3Rpb24g
aW1wbGVtZW50ZWQgdXNpbmcgTWFjIE9TIFggQWNjZWxlcmF0ZS5mcmFtZXdvcmsgKHZlY0xpYikK
Ky8vCisKKyNpZm5kZWYgRkZURnJhbWVNYWNfaAorI2RlZmluZSBGRlRGcmFtZU1hY19oCisKKyNp
bmNsdWRlICJBdWRpb0Zsb2F0QXJyYXkuaCIKKyNpbmNsdWRlIDxBY2NlbGVyYXRlL0FjY2VsZXJh
dGUuaD4KKworbmFtZXNwYWNlIFdlYkNvcmUgeworCitjbGFzcyBGRlRGcmFtZSB7CitwdWJsaWM6
CisgICAgRkZURnJhbWUoc2l6ZV90IGZmdFNpemUpOworICAgIEZGVEZyYW1lKCk7IC8vIGNyZWF0
ZXMgYSBibGFuay9lbXB0eSBmcmFtZSBmb3IgbGF0ZXIgdXNlIHdpdGggaW50ZXJwb2xhdGUoKQor
ICAgIEZGVEZyYW1lKGNvbnN0IEZGVEZyYW1lJiBmcmFtZSk7CisgICAgdmlydHVhbCB+RkZURnJh
bWUoKTsKKworICAgIHZvaWQgZG9GRlQoZmxvYXQqIGRhdGEpOworICAgIHZvaWQgZG9JbnZlcnNl
RkZUKGZsb2F0KiBkYXRhKTsKKworICAgIC8vIE11bHRpcGxpZXMgdGhpcyBmcmFtZSB3aXRoIHxv
dGhlcl9mcmFtZXwgYW5kIHB1dHMgcmVzdWx0cyBpbnRvIHRoaXMgZnJhbWUKKyAgICB2b2lkIG11
bHRpcGx5KGNvbnN0IEZGVEZyYW1lJiBmcmFtZTIpOworCisgICAgLy8gSW50ZXJwb2xhdGVzIGZy
b20gZnJhbWUxIC0+IGZyYW1lMiBhcyB8aW50ZXJwfCBnb2VzIGZyb20gMC4wIC0+IDEuMAorICAg
IHZvaWQgaW50ZXJwb2xhdGUoRkZURnJhbWUmIGZyYW1lMSwgRkZURnJhbWUmIGZyYW1lMiwgZG91
YmxlIGludGVycCk7CisKKyAgICBkb3VibGUgZXh0cmFjdEF2ZXJhZ2VHcm91cERlbGF5KCk7Cisg
ICAgdm9pZCBhZGRDb25zdGFudEdyb3VwRGVsYXkoZG91YmxlIHNhbXBsZUZyYW1lRGVsYXkpOwor
CisgICAgc2l6ZV90IGZmdFNpemUoKSBjb25zdCB7IHJldHVybiBtX0ZGVFNpemU7IH0KKyAgICBz
aXplX3QgbG9nMkZGVFNpemUoKSBjb25zdCB7IHJldHVybiBtX2xvZzJGRlRTaXplOyB9CisKKyAg
ICBmbG9hdCogcmVhbERhdGEoKSB7IHJldHVybiBtX3JlYWxEYXRhOyB9CisgICAgZmxvYXQqIGlt
YWdEYXRhKCkgeyByZXR1cm4gbV9pbWFnRGF0YTsgfQorCisgICAgLy8gRm9yIGRlYnVnZ2luZwor
ICAgIHZvaWQgcHJpbnQoKTsKKworICAgIHN0YXRpYyB2b2lkIGNsZWFudXBGRlRTZXR1cHMoKTsK
KworcHJpdmF0ZToKKyAgICBEU1BTcGxpdENvbXBsZXgmIGRzcFNwbGl0Q29tcGxleCgpIHsgcmV0
dXJuIG1fZnJhbWU7IH0KKworICAgIHN0YXRpYyBGRlRTZXR1cCBmZnRTZXR1cEZvclNpemUoc2l6
ZV90IGZmdFNpemUpOworCisgICAgc3RhdGljIEZGVFNldHVwKiBmZnRTZXR1cHM7CisKKyAgICBz
aXplX3QgbV9GRlRTaXplOworICAgIHNpemVfdCBtX2xvZzJGRlRTaXplOworICAgIEZGVFNldHVw
IG1fRkZUU2V0dXA7CisKKyAgICBEU1BTcGxpdENvbXBsZXggbV9mcmFtZTsKKyAgICBBdWRpb0Zs
b2F0QXJyYXkgbV9yZWFsRGF0YTsKKyAgICBBdWRpb0Zsb2F0QXJyYXkgbV9pbWFnRGF0YTsKK307
CisKK30gLy8gbmFtZXNwYWNlIFdlYkNvcmUKKworI2VuZGlmIC8vIEZGVEZyYW1lTWFjX2gK
</data>

          </attachment>
          <attachment
              isobsolete="1"
              ispatch="1"
              isprivate="0"
          >
            <attachid>48666</attachid>
            <date>2010-02-12 14:44:26 -0800</date>
            <delta_ts>2010-09-01 15:07:32 -0700</delta_ts>
            <desc>Patch</desc>
            <filename>bug-34827-20100212144425.patch</filename>
            <type>text/plain</type>
            <size>22998</size>
            <attacher name="Chris Rogers">crogers</attacher>
            
              <data encoding="base64">ZGlmZiAtLWdpdCBhL1dlYkNvcmUvQ2hhbmdlTG9nIGIvV2ViQ29yZS9DaGFuZ2VMb2cKaW5kZXgg
ODY2ZjZkOC4uYTExZGQ3YSAxMDA2NDQKLS0tIGEvV2ViQ29yZS9DaGFuZ2VMb2cKKysrIGIvV2Vi
Q29yZS9DaGFuZ2VMb2cKQEAgLTEsMyArMSwzNSBAQAorMjAxMC0wMi0xMiAgQ2hyaXMgUm9nZXJz
ICA8Y3JvZ2Vyc0Bnb29nbGUuY29tPgorCisgICAgICAgIFJldmlld2VkIGJ5IE5PQk9EWSAoT09Q
UyEpLgorCisgICAgICAgIGF1ZGlvIGVuZ2luZTogYWRkIEZGVEZyYW1lIGZpbGVzCisgICAgICAg
IGh0dHBzOi8vYnVncy53ZWJraXQub3JnL3Nob3dfYnVnLmNnaT9pZD0zNDgyNworCisgICAgICAg
IE5vIHRlc3RzIC0gbm8gamF2YXNjcmlwdCBBUEkKKworICAgICAgICAqIHBsYXRmb3JtL2F1ZGlv
L0ZGVEZyYW1lLmNwcDogQWRkZWQuCisgICAgICAgIChXZWJDb3JlOjpGRlRGcmFtZTo6ZG9QYWRk
ZWRGRlQpOgorICAgICAgICAoV2ViQ29yZTo6RkZURnJhbWU6OmNyZWF0ZUludGVycG9sYXRlZEZy
YW1lKToKKyAgICAgICAgKFdlYkNvcmU6OkZGVEZyYW1lOjppbnRlcnBvbGF0ZUZyZXF1ZW5jeUNv
bXBvbmVudHMpOgorICAgICAgICAoV2ViQ29yZTo6RkZURnJhbWU6OmV4dHJhY3RBdmVyYWdlR3Jv
dXBEZWxheSk6CisgICAgICAgIChXZWJDb3JlOjpGRlRGcmFtZTo6YWRkQ29uc3RhbnRHcm91cERl
bGF5KToKKyAgICAgICAgKFdlYkNvcmU6OkZGVEZyYW1lOjpwcmludCk6CisgICAgICAgICogcGxh
dGZvcm0vYXVkaW8vRkZURnJhbWUuaDogQWRkZWQuCisgICAgICAgICogcGxhdGZvcm0vYXVkaW8v
bWFjL0ZGVEZyYW1lTWFjLmNwcDogQWRkZWQuCisgICAgICAgIChXZWJDb3JlOjpGRlRGcmFtZTo6
RkZURnJhbWUpOgorICAgICAgICAoV2ViQ29yZTo6RkZURnJhbWU6On5GRlRGcmFtZSk6CisgICAg
ICAgIChXZWJDb3JlOjpGRlRGcmFtZTo6bXVsdGlwbHkpOgorICAgICAgICAoV2ViQ29yZTo6RkZU
RnJhbWU6OmRvRkZUKToKKyAgICAgICAgKFdlYkNvcmU6OkZGVEZyYW1lOjpkb0ludmVyc2VGRlQp
OgorICAgICAgICAoV2ViQ29yZTo6RkZURnJhbWU6OmZmdFNldHVwRm9yU2l6ZSk6CisgICAgICAg
IChXZWJDb3JlOjpGRlRGcmFtZTo6Y2xlYW51cEZGVFNldHVwcyk6CisgICAgICAgICogcGxhdGZv
cm0vYXVkaW8vbWFjL0ZGVEZyYW1lTWFjLmg6IEFkZGVkLgorICAgICAgICAoV2ViQ29yZTo6RkZU
RnJhbWU6OmZmdFNpemUpOgorICAgICAgICAoV2ViQ29yZTo6RkZURnJhbWU6OmxvZzJGRlRTaXpl
KToKKyAgICAgICAgKFdlYkNvcmU6OkZGVEZyYW1lOjpyZWFsRGF0YSk6CisgICAgICAgIChXZWJD
b3JlOjpGRlRGcmFtZTo6aW1hZ0RhdGEpOgorICAgICAgICAoV2ViQ29yZTo6RkZURnJhbWU6OmRz
cFNwbGl0Q29tcGxleCk6CisKIDIwMTAtMDItMDkgIENocmlzIFJvZ2VycyAgPGNyb2dlcnNAZ29v
Z2xlLmNvbT4KIAogICAgICAgICBSZXZpZXdlZCBieSBOT0JPRFkgKE9PUFMhKS4KZGlmZiAtLWdp
dCBhL1dlYkNvcmUvcGxhdGZvcm0vYXVkaW8vRkZURnJhbWUuY3BwIGIvV2ViQ29yZS9wbGF0Zm9y
bS9hdWRpby9GRlRGcmFtZS5jcHAKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4u
MTdmNmM4ZQotLS0gL2Rldi9udWxsCisrKyBiL1dlYkNvcmUvcGxhdGZvcm0vYXVkaW8vRkZURnJh
bWUuY3BwCkBAIC0wLDAgKzEsMjY4IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIEdvb2ds
ZSBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogUmVkaXN0cmlidXRpb24gYW5kIHVz
ZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisgKiBtb2RpZmlj
YXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlv
bnMKKyAqIGFyZSBtZXQ6CisgKgorICogMS4gIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29k
ZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisgKiAgICAgbm90aWNlLCB0aGlzIGxp
c3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorICogMi4gIFJl
ZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29w
eXJpZ2h0CisgKiAgICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZv
bGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZQorICogICAgIGRvY3VtZW50YXRpb24gYW5kL29yIG90
aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uCisgKiAzLiAgTmVp
dGhlciB0aGUgbmFtZSBvZiBBcHBsZSBDb21wdXRlciwgSW5jLiAoIkFwcGxlIikgbm9yIHRoZSBu
YW1lcyBvZgorICogICAgIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBv
ciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQKKyAqICAgICBmcm9tIHRoaXMgc29mdHdhcmUgd2l0
aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisgKgorICogVEhJUyBTT0ZU
V0FSRSBJUyBQUk9WSURFRCBCWSBBUFBMRSBBTkQgSVRTIENPTlRSSUJVVE9SUyAiQVMgSVMiIEFO
RCBBTlkKKyAqIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBO
T1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQKKyAqIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklM
SVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKKyAqIERJU0NMQUlN
RUQuIElOIE5PIEVWRU5UIFNIQUxMIEFQUExFIE9SIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxF
IEZPUiBBTlkKKyAqIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1Q
TEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTCisgKiAoSU5DTFVESU5HLCBCVVQgTk9UIExJ
TUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7Cisg
KiBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9O
KSBIT1dFVkVSIENBVVNFRCBBTkQKKyAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVU
SEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisgKiAoSU5DTFVESU5H
IE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBV
U0UgT0YKKyAqIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJ
VFkgT0YgU1VDSCBEQU1BR0UuCisgKi8KKworLy8gQ3Jvc3MtcGxhdGZvcm0gRkZURnJhbWUgaW1w
bGVtZW50YXRpb24KKworI2luY2x1ZGUgImNvbmZpZy5oIgorI2luY2x1ZGUgIkZGVEZyYW1lLmgi
CisKKyNpbmNsdWRlIDx3dGYvQ29tcGxleC5oPgorI2luY2x1ZGUgPHd0Zi9NYXRoRXh0cmFzLmg+
CisKK25hbWVzcGFjZSBXZWJDb3JlIHsKKwordm9pZCBGRlRGcmFtZTo6ZG9QYWRkZWRGRlQoZmxv
YXQqIGRhdGEsIHNpemVfdCBkYXRhU2l6ZSkKK3sKKyAgICAvLyBaZXJvLXBhZCB0aGUgaW1wdWxz
ZSByZXNwb25zZQorICAgIEF1ZGlvRmxvYXRBcnJheSBwYWRkZWRSZXNwb25zZShmZnRTaXplKCkp
OworICAgIAorICAgIGFzc2VydChkYXRhU2l6ZSA8PSBmZnRTaXplKCkpOworICAgIG1lbWNweShw
YWRkZWRSZXNwb25zZSwgZGF0YSwgc2l6ZW9mKGZsb2F0KSAqIGRhdGFTaXplKTsKKworICAgIC8v
IEdldCB0aGUgZnJlcXVlbmN5LWRvbWFpbiB2ZXJzaW9uIG9mIHBhZGRlZCByZXNwb25zZQorICAg
IGRvRkZUKHBhZGRlZFJlc3BvbnNlKTsKK30KKworRkZURnJhbWUqIEZGVEZyYW1lOjpjcmVhdGVJ
bnRlcnBvbGF0ZWRGcmFtZShGRlRGcmFtZSYgZnJhbWUxLCBGRlRGcmFtZSYgZnJhbWUyLCBkb3Vi
bGUgeCkKK3sKKyAgICBGRlRGcmFtZSogbmV3RnJhbWUgPSBuZXcgRkZURnJhbWUoZnJhbWUxLmZm
dFNpemUoKSk7CisKKyAgICBuZXdGcmFtZS0+aW50ZXJwb2xhdGVGcmVxdWVuY3lDb21wb25lbnRz
KGZyYW1lMSwgZnJhbWUyLCB4KTsKKworICAgIC8vIEluIHRoZSB0aW1lLWRvbWFpbiwgdGhlIDJu
ZCBoYWxmIG9mIHRoZSByZXNwb25zZSBtdXN0IGJlIHplcm8sIHRvIGF2b2lkIGNpcmN1bGFyIGNv
bnZvbHV0aW9uIGFsaWFzaW5nLi4uCisgICAgaW50IGZmdFNpemUgPSBuZXdGcmFtZS0+ZmZ0U2l6
ZSgpOworICAgIEF1ZGlvRmxvYXRBcnJheSBidWZmZXIoZmZ0U2l6ZSk7CisgICAgbmV3RnJhbWUt
PmRvSW52ZXJzZUZGVChidWZmZXIpOworCisgICAgbWVtc2V0KGJ1ZmZlci5kYXRhKCkgKyBmZnRT
aXplIC8gMiwgMCwgc2l6ZW9mKGZsb2F0KSAqIGZmdFNpemUgLyAyKTsKKworICAgIG5ld0ZyYW1l
LT5kb0ZGVChidWZmZXIpOworCisgICAgcmV0dXJuIG5ld0ZyYW1lOworfQorCit2b2lkIEZGVEZy
YW1lOjppbnRlcnBvbGF0ZUZyZXF1ZW5jeUNvbXBvbmVudHMoRkZURnJhbWUmIGZyYW1lMSwKKyAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGRlRGcmFtZSYgZnJh
bWUyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvdWJs
ZSBpbnRlcnApCit7CisgICAgLy8gRklYTUUgOiB3aXRoIHNvbWUgd29yaywgdGhpcyBtZXRob2Qg
Y291bGQgYmUgb3B0aW1pemVkCisKKyAgICBmbG9hdCogcmVhbFAgPSByZWFsRGF0YSgpOworICAg
IGZsb2F0KiBpbWFnUCA9IGltYWdEYXRhKCk7CisKKyAgICBmbG9hdCogcmVhbFAxID0gZnJhbWUx
LnJlYWxEYXRhKCk7CisgICAgZmxvYXQqIGltYWdQMSA9IGZyYW1lMS5pbWFnRGF0YSgpOworICAg
IGZsb2F0KiByZWFsUDIgPSBmcmFtZTIucmVhbERhdGEoKTsKKyAgICBmbG9hdCogaW1hZ1AyID0g
ZnJhbWUyLmltYWdEYXRhKCk7CisKKyAgICBtX0ZGVFNpemUgPSBmcmFtZTEuZmZ0U2l6ZSgpOwor
ICAgIG1fbG9nMkZGVFNpemUgPSBmcmFtZTEubG9nMkZGVFNpemUoKTsKKworICAgIGRvdWJsZSBz
MWJhc2UgPSAoMS4wIC0gaW50ZXJwKTsKKyAgICBkb3VibGUgczJiYXNlID0gaW50ZXJwOworCisg
ICAgZG91YmxlIHBoYXNlQWNjdW0gPSAwLjA7CisgICAgZG91YmxlIGxhc3RQaGFzZTEgPSAwLjA7
CisgICAgZG91YmxlIGxhc3RQaGFzZTIgPSAwLjA7CisKKyAgICByZWFsUFswXSA9IHMxYmFzZSAq
IHJlYWxQMVswXSArIHMyYmFzZSAqIHJlYWxQMlswXTsKKyAgICBpbWFnUFswXSA9IHMxYmFzZSAq
IGltYWdQMVswXSArIHMyYmFzZSAqIGltYWdQMlswXTsKKworICAgIGludCBuID0gbV9GRlRTaXpl
IC8gMjsKKworICAgIGZvciAoaW50IGkgPSAxOyBpIDwgbjsgKytpKSB7CisgICAgICAgIENvbXBs
ZXggYzEocmVhbFAxW2ldLCBpbWFnUDFbaV0pOworICAgICAgICBDb21wbGV4IGMyKHJlYWxQMltp
XSwgaW1hZ1AyW2ldKTsKKworICAgICAgICBkb3VibGUgbWFnMSA9IGFicyhjMSk7CisgICAgICAg
IGRvdWJsZSBtYWcyID0gYWJzKGMyKTsKKworICAgICAgICAvLyBJbnRlcnBvbGF0ZSBtYWduaXR1
ZGVzIGluIGRlY2liZWxzCisgICAgICAgIGRvdWJsZSBtYWcxZGIgPSAyMC4wICogbG9nMTAobWFn
MSk7CisgICAgICAgIGRvdWJsZSBtYWcyZGIgPSAyMC4wICogbG9nMTAobWFnMik7CisKKyAgICAg
ICAgZG91YmxlIHMxID0gczFiYXNlOworICAgICAgICBkb3VibGUgczIgPSBzMmJhc2U7CisKKyAg
ICAgICAgZG91YmxlIG1hZ2RiZGlmZiA9IG1hZzFkYiAtIG1hZzJkYjsKKworICAgICAgICAvLyBF
bXBpcmljYWwgdHdlYWsgdG8gcmV0YWluIGhpZ2hlci1mcmVxdWVuY3kgemVyb2VzCisgICAgICAg
IGRvdWJsZSB0aHJlc2hvbGQgPSAgKGkgPiAxNikgPyA1LjAgOiAyLjA7CisKKyAgICAgICAgaWYg
KG1hZ2RiZGlmZiA8IC10aHJlc2hvbGQgJiYgbWFnMWRiIDwgMC4wKSB7CisgICAgICAgICAgICBz
MSA9IHBvdyhzMSwgMC43NSk7CisgICAgICAgICAgICBzMiA9IDEuMCAtIHMxOworICAgICAgICB9
IGVsc2UgaWYgKG1hZ2RiZGlmZiA+IHRocmVzaG9sZCAmJiBtYWcyZGIgPCAwLjApIHsKKyAgICAg
ICAgICAgIHMyID0gcG93KHMyLCAwLjc1KTsKKyAgICAgICAgICAgIHMxID0gMS4wIC0gczI7Cisg
ICAgICAgIH0KKworICAgICAgICAvLyBBdmVyYWdlIG1hZ25pdHVkZSBieSBkZWNpYmVscyBpbnN0
ZWFkIG9mIGxpbmVhcmx5CisgICAgICAgIGRvdWJsZSBtYWdkYiA9IHMxICogbWFnMWRiICsgczIg
KiBtYWcyZGI7CisgICAgICAgIGRvdWJsZSBtYWcgPSBwb3coMTAuMCwgMC4wNSAqIG1hZ2RiKTsK
KworICAgICAgICAvLyBOb3csIGRlYWwgd2l0aCBwaGFzZQorICAgICAgICBkb3VibGUgcGhhc2Ux
ID0gYXJnKGMxKTsKKyAgICAgICAgZG91YmxlIHBoYXNlMiA9IGFyZyhjMik7CisKKyAgICAgICAg
ZG91YmxlIGRlbHRhUGhhc2UxID0gcGhhc2UxIC0gbGFzdFBoYXNlMTsKKyAgICAgICAgZG91Ymxl
IGRlbHRhUGhhc2UyID0gcGhhc2UyIC0gbGFzdFBoYXNlMjsKKyAgICAgICAgbGFzdFBoYXNlMSA9
IHBoYXNlMTsKKyAgICAgICAgbGFzdFBoYXNlMiA9IHBoYXNlMjsKKworICAgICAgICAvLyBVbndy
YXAgcGhhc2UgZGVsdGFzCisgICAgICAgIGlmIChkZWx0YVBoYXNlMSA+IE1fUEkpCisgICAgICAg
ICAgICBkZWx0YVBoYXNlMSAtPSAyLjAgKiBNX1BJOworICAgICAgICBpZiAoZGVsdGFQaGFzZTEg
PCAtTV9QSSkKKyAgICAgICAgICAgIGRlbHRhUGhhc2UxICs9IDIuMCAqIE1fUEk7CisgICAgICAg
IGlmIChkZWx0YVBoYXNlMiA+IE1fUEkpCisgICAgICAgICAgICBkZWx0YVBoYXNlMiAtPSAyLjAg
KiBNX1BJOworICAgICAgICBpZiAoZGVsdGFQaGFzZTIgPCAtTV9QSSkKKyAgICAgICAgICAgIGRl
bHRhUGhhc2UyICs9IDIuMCAqIE1fUEk7CisKKyAgICAgICAgLy8gQmxlbmQgZ3JvdXAtZGVsYXlz
CisgICAgICAgIGRvdWJsZSBkZWx0YVBoYXNlQmxlbmQ7CisKKyAgICAgICAgaWYgKGRlbHRhUGhh
c2UxIC0gZGVsdGFQaGFzZTIgPiBNX1BJKQorICAgICAgICAgICAgZGVsdGFQaGFzZUJsZW5kID0g
czEgKiBkZWx0YVBoYXNlMSArIHMyICogKDIuMCAqIE1fUEkgKyBkZWx0YVBoYXNlMik7CisgICAg
ICAgIGVsc2UgaWYgKGRlbHRhUGhhc2UyIC0gZGVsdGFQaGFzZTEgPiBNX1BJKQorICAgICAgICAg
ICAgZGVsdGFQaGFzZUJsZW5kID0gczEgKiAoMi4wICogTV9QSSArIGRlbHRhUGhhc2UxKSArIHMy
ICogZGVsdGFQaGFzZTI7CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIGRlbHRhUGhhc2VCbGVu
ZCA9IHMxICogZGVsdGFQaGFzZTEgKyBzMiAqIGRlbHRhUGhhc2UyOworCisgICAgICAgIHBoYXNl
QWNjdW0gKz0gZGVsdGFQaGFzZUJsZW5kOworCisgICAgICAgIC8vIFVud3JhcAorICAgICAgICBp
ZiAocGhhc2VBY2N1bSA+IE1fUEkpCisgICAgICAgICAgICBwaGFzZUFjY3VtIC09IDIuMCAqIE1f
UEk7CisgICAgICAgIGlmIChwaGFzZUFjY3VtIDwgLU1fUEkpCisgICAgICAgICAgICBwaGFzZUFj
Y3VtICs9IDIuMCAqIE1fUEk7CisKKyAgICAgICAgQ29tcGxleCBjID0gY29tcGxleEZyb21NYWdu
aXR1ZGVQaGFzZShtYWcsIHBoYXNlQWNjdW0pOworCisgICAgICAgIHJlYWxQW2ldID0gYy5yZWFs
KCk7CisgICAgICAgIGltYWdQW2ldID0gYy5pbWFnKCk7CisgICAgfQorfQorCitkb3VibGUgIEZG
VEZyYW1lOjpleHRyYWN0QXZlcmFnZUdyb3VwRGVsYXkoKQoreworICAgIGZsb2F0KiByZWFsUCA9
IHJlYWxEYXRhKCk7CisgICAgZmxvYXQqIGltYWdQID0gaW1hZ0RhdGEoKTsKKworICAgIGRvdWJs
ZSBhdmVTdW0gPSAwLjA7CisgICAgZG91YmxlIHdlaWdodFN1bSA9IDAuMDsKKyAgICBkb3VibGUg
bGFzdFBoYXNlID0gMC4wOworCisgICAgaW50IGhhbGZTaXplID0gZmZ0U2l6ZSgpIC8gMjsKKwor
ICAgIGNvbnN0IGRvdWJsZSBrU2FtcGxlUGhhc2VEZWxheSA9ICgyLjAgKiBNX1BJKSAvIGRvdWJs
ZShmZnRTaXplKCkpOworCisgICAgLy8gQ2FsY3VsYXRlIHdlaWdodGVkIGF2ZXJhZ2UgZ3JvdXAg
ZGVsYXkKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IGhhbGZTaXplOyBpKyspIHsKKyAgICAgICAg
Q29tcGxleCBjKHJlYWxQW2ldLCBpbWFnUFtpXSk7CisgICAgICAgIGRvdWJsZSBtYWcgPSBhYnMo
Yyk7CisgICAgICAgIGRvdWJsZSBwaGFzZSA9IGFyZyhjKTsKKworICAgICAgICBkb3VibGUgZGVs
dGFQaGFzZSA9IHBoYXNlIC0gbGFzdFBoYXNlOworICAgICAgICBsYXN0UGhhc2UgPSBwaGFzZTsK
KworICAgICAgICAvLyBVbndyYXAKKyAgICAgICAgaWYgKGRlbHRhUGhhc2UgPCAtTV9QSSkKKyAg
ICAgICAgICAgIGRlbHRhUGhhc2UgKz0gMi4wICogTV9QSTsKKyAgICAgICAgaWYgKGRlbHRhUGhh
c2UgPiBNX1BJKQorICAgICAgICAgICAgZGVsdGFQaGFzZSAtPSAyLjAgKiBNX1BJOworCisgICAg
ICAgIGF2ZVN1bSArPSBtYWcgKiBkZWx0YVBoYXNlOworICAgICAgICB3ZWlnaHRTdW0gKz0gbWFn
OworICAgIH0KKworICAgIC8vIE5vdGUgaG93IHdlIGludmVydCB0aGUgcGhhc2UgZGVsdGEgd3J0
IGZyZXF1ZW5jeSBzaW5jZSB0aGlzIGlzIGhvdyBncm91cCBkZWxheSBpcyBkZWZpbmVkCisgICAg
ZG91YmxlIGF2ZSA9IGF2ZVN1bSAvIHdlaWdodFN1bTsKKyAgICBkb3VibGUgYXZlU2FtcGxlRGVs
YXkgPSAtYXZlIC8ga1NhbXBsZVBoYXNlRGVsYXk7CisKKyAgICAvLyBMZWF2ZSAyMCBzYW1wbGUg
aGVhZHJvb20gKGZvciBsZWFkaW5nIGVkZ2Ugb2YgaW1wdWxzZSkKKyAgICBpZiAoYXZlU2FtcGxl
RGVsYXkgPiAyMC4wKQorICAgICAgICBhdmVTYW1wbGVEZWxheSAtPSAyMC4wOworCisgICAgLy8g
UmVtb3ZlIGF2ZXJhZ2UgZ3JvdXAgZGVsYXkgKG1pbnVzIDIwIHNhbXBsZXMgZm9yIGhlYWRyb29t
KQorICAgIGFkZENvbnN0YW50R3JvdXBEZWxheSgtYXZlU2FtcGxlRGVsYXkpOworCisgICAgLy8g
UmVtb3ZlIERDIG9mZnNldAorICAgIHJlYWxQWzBdID0gMC4wOworCisgICAgcmV0dXJuIGF2ZVNh
bXBsZURlbGF5OworfQorCit2b2lkICBGRlRGcmFtZTo6YWRkQ29uc3RhbnRHcm91cERlbGF5KGRv
dWJsZSBzYW1wbGVGcmFtZURlbGF5KQoreworICAgIGludCBoYWxmU2l6ZSA9IGZmdFNpemUoKSAv
IDI7CisKKyAgICBmbG9hdCogcmVhbFAgPSByZWFsRGF0YSgpOworICAgIGZsb2F0KiBpbWFnUCA9
IGltYWdEYXRhKCk7CisKKyAgICBjb25zdCBkb3VibGUga1NhbXBsZVBoYXNlRGVsYXkgPSAoMi4w
ICogTV9QSSkgLyBkb3VibGUoZmZ0U2l6ZSgpKTsKKworICAgIGRvdWJsZSBwaGFzZUFkaiA9IC1z
YW1wbGVGcmFtZURlbGF5ICoga1NhbXBsZVBoYXNlRGVsYXk7CisKKyAgICAvLyBBZGQgY29uc3Rh
bnQgZ3JvdXAgZGVsYXkKKyAgICBmb3IgKGludCBpID0gMTsgaSA8IGhhbGZTaXplOyBpKyspIHsK
KyAgICAgICAgQ29tcGxleCBjKHJlYWxQW2ldLCBpbWFnUFtpXSk7CisgICAgICAgIGRvdWJsZSBt
YWcgPSBhYnMoYyk7CisgICAgICAgIGRvdWJsZSBwaGFzZSA9IGFyZyhjKTsKKworICAgICAgICBw
aGFzZSArPSBpICogcGhhc2VBZGo7CisKKyAgICAgICAgQ29tcGxleCBjMiA9IGNvbXBsZXhGcm9t
TWFnbml0dWRlUGhhc2UobWFnLCBwaGFzZSk7CisKKyAgICAgICAgcmVhbFBbaV0gPSBjMi5yZWFs
KCk7CisgICAgICAgIGltYWdQW2ldID0gYzIuaW1hZygpOworICAgIH0KK30KKworLy8gRm9yIGRl
YnVnZ2luZwordm9pZCBGRlRGcmFtZTo6cHJpbnQoKQoreworICAgIEZGVEZyYW1lJiBmcmFtZSA9
ICp0aGlzOworICAgIGZsb2F0KiByZWFsUCA9IGZyYW1lLnJlYWxEYXRhKCk7CisgICAgZmxvYXQq
IGltYWdQID0gZnJhbWUuaW1hZ0RhdGEoKTsKKyAgICBwcmludGYoIioqKiogXG4iKTsKKyAgICBw
cmludGYoIkRDID0gJWYgOiBueXF1aXN0ID0gJWZcbiIsIHJlYWxQWzBdLCBpbWFnUFswXSk7CisK
KyAgICBpbnQgbiA9IG1fRkZUU2l6ZSAvIDI7CisKKyAgICBmb3IgKGludCBpID0gMTsgaSA8IG47
IGkrKykgeworICAgICAgICBkb3VibGUgbWFnID0gc3FydChyZWFsUFtpXSAqIHJlYWxQW2ldICsg
aW1hZ1BbaV0gKiBpbWFnUFtpXSk7CisgICAgICAgIGRvdWJsZSBwaGFzZSA9IGF0YW4yKHJlYWxQ
W2ldLCBpbWFnUFtpXSk7CisKKyAgICAgICAgcHJpbnRmKCJbJWRdICglZiAlZilcbiIsIGksIG1h
ZywgcGhhc2UpOworICAgIH0KKyAgICBwcmludGYoIioqKipcbiIpOworfQorCit9IC8vIG5hbWVz
cGFjZSBXZWJDb3JlCmRpZmYgLS1naXQgYS9XZWJDb3JlL3BsYXRmb3JtL2F1ZGlvL0ZGVEZyYW1l
LmggYi9XZWJDb3JlL3BsYXRmb3JtL2F1ZGlvL0ZGVEZyYW1lLmgKbmV3IGZpbGUgbW9kZSAxMDA2
NDQKaW5kZXggMDAwMDAwMC4uMjEzMGViMAotLS0gL2Rldi9udWxsCisrKyBiL1dlYkNvcmUvcGxh
dGZvcm0vYXVkaW8vRkZURnJhbWUuaApAQCAtMCwwICsxLDUyIEBACisvKgorICogQ29weXJpZ2h0
IChDKSAyMDEwIEdvb2dsZSBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogUmVkaXN0
cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRo
b3V0CisgKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9s
bG93aW5nIGNvbmRpdGlvbnMKKyAqIGFyZSBtZXQ6CisgKgorICogMS4gIFJlZGlzdHJpYnV0aW9u
cyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisgKiAgICAg
bm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFp
bWVyLgorICogMi4gIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVj
ZSB0aGUgYWJvdmUgY29weXJpZ2h0CisgKiAgICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0
aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZQorICogICAgIGRvY3VtZW50
YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRp
b24uCisgKiAzLiAgTmVpdGhlciB0aGUgbmFtZSBvZiBBcHBsZSBDb21wdXRlciwgSW5jLiAoIkFw
cGxlIikgbm9yIHRoZSBuYW1lcyBvZgorICogICAgIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVz
ZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQKKyAqICAgICBmcm9tIHRo
aXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisg
KgorICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBBUFBMRSBBTkQgSVRTIENPTlRSSUJV
VE9SUyAiQVMgSVMiIEFORCBBTlkKKyAqIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJ
TkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQKKyAqIFdBUlJBTlRJRVMg
T0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBB
UkUKKyAqIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIEFQUExFIE9SIElUUyBDT05UUklC
VVRPUlMgQkUgTElBQkxFIEZPUiBBTlkKKyAqIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUws
IFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTCisgKiAoSU5DTFVE
SU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMg
T1IgU0VSVklDRVM7CisgKiBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5F
U1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKKyAqIE9OIEFOWSBUSEVPUlkgT0Yg
TElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JU
CisgKiAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBX
QVkgT1VUIE9GIFRIRSBVU0UgT0YKKyAqIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBP
RiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisgKi8KKworI2lmbmRlZiBGRlRGcmFt
ZV9oCisjZGVmaW5lIEZGVEZyYW1lX2gKKworI2luY2x1ZGUgPHd0Zi9QbGF0Zm9ybS5oPgorCisv
LyBEZWZpbmVzIHRoZSBpbnRlcmZhY2UgZm9yIGFuICJGRlQgZnJhbWUiLCBhbiBvYmplY3Qgd2hp
Y2ggaXMgYWJsZSB0byBwZXJmb3JtIGEgZm9yd2FyZAorLy8gYW5kIHJldmVyc2UgRkZULCBpbnRl
cm5hbGx5IHN0b3JpbmcgdGhlIHJlc3VsdGFudCBmcmVxdWVuY3ktZG9tYWluIGRhdGEKKy8vCisv
LyBUaGUgcmVhc29uIHdlIGRvbid0IGNyZWF0ZSBhbiBhYnN0cmFjdCBiYXNlIGNsYXNzIGFuZCBz
dWJjbGFzcyBmb3IgTWFjLCBNS0wsIGV0Yy4KKy8vIGlzIGJlY2F1c2UgdGhlbiBpdCB3b3VsZCBu
b3QgYmUgcG9zc2libGUgdG8gdXNlIHRoZSBvYmplY3QgaW4gYSBjcm9zcy1wbGF0Zm9ybSB3YXkK
Ky8vIGFzIGFuIGl2YXIgb2YgYSBjbGFzcyBvciBhcyBhIHN0YWNrLWJhc2VkIG9iamVjdCwgc2lu
Y2Ugd2Ugd291bGQgaGF2ZSB0byByZXNvcnQgdG8KKy8vIGZhY3RvcnkgbWV0aG9kcywgZXRjLiAg
U2luY2UgaXQgdHVybnMgb3V0IHRvIGJlIHF1aXRlIHVzZWZ1bCB0byB1c2UgdGhlc2UgYXMgaXZh
cnMKKy8vIGFuZCBzdGFjayBiYXNlZCBvYmplY3RzLCBhbmQgc2luY2UgdGhlIGV4YWN0IHR5cGUg
KmlzKiBrbm93biBhdCBjb21waWxlLXRpbWUsIHdlIHVzZQorLy8gdGhpcyBhcHByb2FjaC4KKwor
I2lmIE9TKERBUldJTikKKyAgICAjaW5jbHVkZSAiRkZURnJhbWVNYWMuaCIKKyNlbGlmIE9TKExJ
TlVYKSB8fCBPUyhXSU5ET1dTKQorICAgICNpbmNsdWRlICJGRlRGcmFtZU1LTC5oIgorI2Vsc2UK
KyAgICAjZXJyb3IgIk9TIG5vdCBzdXBwb3J0ZWQiCisjZW5kaWYKKworI2VuZGlmIC8vIEZGVEZy
YW1lX2gKZGlmZiAtLWdpdCBhL1dlYkNvcmUvcGxhdGZvcm0vYXVkaW8vbWFjL0ZGVEZyYW1lTWFj
LmNwcCBiL1dlYkNvcmUvcGxhdGZvcm0vYXVkaW8vbWFjL0ZGVEZyYW1lTWFjLmNwcApuZXcgZmls
ZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lOTliNTczCi0tLSAvZGV2L251bGwKKysrIGIv
V2ViQ29yZS9wbGF0Zm9ybS9hdWRpby9tYWMvRkZURnJhbWVNYWMuY3BwCkBAIC0wLDAgKzEsMjE1
IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEwIEdvb2dsZSBJbmMuIEFsbCByaWdodHMgcmVz
ZXJ2ZWQuCisgKgorICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFy
eSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisgKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQg
cHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKKyAqIGFyZSBtZXQ6CisgKgor
ICogMS4gIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJv
dmUgY29weXJpZ2h0CisgKiAgICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQg
dGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorICogMi4gIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5h
cnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0CisgKiAgICAgbm90aWNl
LCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGlu
IHRoZQorICogICAgIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRl
ZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uCisgKiAzLiAgTmVpdGhlciB0aGUgbmFtZSBvZiBBcHBs
ZSBDb21wdXRlciwgSW5jLiAoIkFwcGxlIikgbm9yIHRoZSBuYW1lcyBvZgorICogICAgIGl0cyBj
b250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRl
cml2ZWQKKyAqICAgICBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3
cml0dGVuIHBlcm1pc3Npb24uCisgKgorICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBB
UFBMRSBBTkQgSVRTIENPTlRSSUJVVE9SUyAiQVMgSVMiIEFORCBBTlkKKyAqIEVYUFJFU1MgT1Ig
SU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElN
UExJRUQKKyAqIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBB
IFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKKyAqIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxM
IEFQUExFIE9SIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkKKyAqIERJUkVDVCwg
SU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElB
TCBEQU1BR0VTCisgKiAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5U
IE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7CisgKiBMT1NTIE9GIFVTRSwgREFUQSwg
T1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQK
KyAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJ
Q1QgTElBQklMSVRZLCBPUiBUT1JUCisgKiAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJX
SVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YKKyAqIFRISVMgU09GVFdB
UkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisg
Ki8KKworLy8gTWFjIE9TIFggLSBzcGVjaWZpYyBGRlRGcmFtZSBpbXBsZW1lbnRhdGlvbgorCisj
aW5jbHVkZSAiY29uZmlnLmgiCisjaW5jbHVkZSAiRkZURnJhbWVNYWMuaCIKKworbmFtZXNwYWNl
IFdlYkNvcmUgeworCitjb25zdCBpbnQga01heEZGVFBvdzJTaXplID0gMjQ7CisKK0ZGVFNldHVw
KiBGRlRGcmFtZTo6ZmZ0U2V0dXBzID0gMDsKKworLy8gTm9ybWFsIGNvbnN0cnVjdG9yOiBhbGxv
Y2F0ZXMgZm9yIGEgZ2l2ZW4gZmZ0U2l6ZQorRkZURnJhbWU6OkZGVEZyYW1lKHNpemVfdCBmZnRT
aXplKQorICAgIDogbV9yZWFsRGF0YShmZnRTaXplKQorICAgICwgbV9pbWFnRGF0YShmZnRTaXpl
KQoreworICAgIG1fRkZUU2l6ZSA9IGZmdFNpemU7CisgICAgbV9sb2cyRkZUU2l6ZSA9IGxvZzIo
ZmZ0U2l6ZSk7CisKKyAgICAvLyBXZSBvbmx5IGFsbG93IHBvd2VyIG9mIHR3bworICAgIGFzc2Vy
dChwb3coMi4wLCBtX2xvZzJGRlRTaXplKSA9PSBtX0ZGVFNpemUpOworCisgICAgLy8gTGF6aWx5
IGNyZWF0ZSBhbmQgc2hhcmUgZmZ0U2V0dXAgd2l0aCBvdGhlciBmcmFtZXMKKyAgICBtX0ZGVFNl
dHVwID0gZmZ0U2V0dXBGb3JTaXplKGZmdFNpemUpOworCisgICAgLy8gU2V0dXAgZnJhbWUgZGF0
YQorICAgIG1fZnJhbWUucmVhbHAgPSBtX3JlYWxEYXRhOworICAgIG1fZnJhbWUuaW1hZ3AgPSBt
X2ltYWdEYXRhOworfQorCisvLyBDcmVhdGVzIGEgYmxhbmsvZW1wdHkgZnJhbWUgKGludGVycG9s
YXRlKCkgbXVzdCBsYXRlciBiZSBjYWxsZWQpCitGRlRGcmFtZTo6RkZURnJhbWUoKQorICAgIDog
bV9yZWFsRGF0YSgwKQorICAgICwgbV9pbWFnRGF0YSgwKQoreworICAgIC8vIExhdGVyIHdpbGwg
YmUgc2V0IHRvIGNvcnJlY3QgdmFsdWVzIHdoZW4gaW50ZXJwb2xhdGUoKSBpcyBjYWxsZWQKKyAg
ICBtX2ZyYW1lLnJlYWxwID0gMDsKKyAgICBtX2ZyYW1lLmltYWdwID0gMDsKKworICAgIG1fRkZU
U2l6ZSA9IDA7CisgICAgbV9sb2cyRkZUU2l6ZSA9IDA7Cit9CisKKy8vIENvcHkgY29uc3RydWN0
b3IKK0ZGVEZyYW1lOjpGRlRGcmFtZShjb25zdCBGRlRGcmFtZSYgZnJhbWUpCisgICAgOiBtX0ZG
VFNpemUoZnJhbWUubV9GRlRTaXplKQorICAgICwgbV9sb2cyRkZUU2l6ZShmcmFtZS5tX2xvZzJG
RlRTaXplKQorICAgICwgbV9GRlRTZXR1cChmcmFtZS5tX0ZGVFNldHVwKQorICAgICwgbV9yZWFs
RGF0YShmcmFtZS5tX0ZGVFNpemUpCisgICAgLCBtX2ltYWdEYXRhKGZyYW1lLm1fRkZUU2l6ZSkK
K3sKKyAgICAvLyBDb3B5L3NldHVwIGZyYW1lIGRhdGEKKyAgICBzaXplX3QgbmJ5dGVzID0gc2l6
ZW9mKGZsb2F0KSAqIG1fRkZUU2l6ZTsKKyAgICBGRlRGcmFtZSYgc2FmZUZyYW1lID0gY29uc3Rf
Y2FzdDxGRlRGcmFtZSY+KGZyYW1lKTsKKyAgICBtZW1jcHkocmVhbERhdGEoKSwgc2FmZUZyYW1l
LnJlYWxEYXRhKCksIG5ieXRlcyk7CisgICAgbWVtY3B5KGltYWdEYXRhKCksIHNhZmVGcmFtZS5p
bWFnRGF0YSgpLCBuYnl0ZXMpOworCisgICAgbV9mcmFtZS5yZWFscCA9IHJlYWxEYXRhKCk7Cisg
ICAgbV9mcmFtZS5pbWFncCA9IGltYWdEYXRhKCk7Cit9CisKK0ZGVEZyYW1lOjp+RkZURnJhbWUo
KQoreworfQorCisvLyBVc2VzIEFjY2VsZXJhdGUuZnJhbWV3b3JrIGhpZ2hseS1vcHRpbWl6ZWQg
enZtdWwoKSBmdW5jdGlvbgordm9pZCBGRlRGcmFtZTo6bXVsdGlwbHkoY29uc3QgRkZURnJhbWUm
IGZyYW1lKQoreworICAgIEZGVEZyYW1lJiBmcmFtZTEgPSAqdGhpczsKKyAgICBGRlRGcmFtZSYg
ZnJhbWUyID0gY29uc3RfY2FzdDxGRlRGcmFtZSY+KGZyYW1lKTsKKworICAgIGZsb2F0KiByZWFs
UDEgPSBmcmFtZTEucmVhbERhdGEoKTsKKyAgICBmbG9hdCogaW1hZ1AxID0gZnJhbWUxLmltYWdE
YXRhKCk7CisgICAgZmxvYXQqIHJlYWxQMiA9IGZyYW1lMi5yZWFsRGF0YSgpOworICAgIGZsb2F0
KiBpbWFnUDIgPSBmcmFtZTIuaW1hZ0RhdGEoKTsKKworICAgIC8vIFNjYWxlIGFjY291bnRzIGZv
ciB2ZWNMaWIncyBwZWN1bGlhciBzY2FsaW5nCisgICAgLy8gVGhpcyBlbnN1cmVzIHRoZSByaWdo
dCBzY2FsaW5nIGFsbCB0aGUgd2F5IGJhY2sgdG8gaW52ZXJzZSBGRlQKKyAgICBmbG9hdCBzY2Fs
ZSA9IDAuNTsKKworICAgIC8vIE11bHRpcGx5IHBhY2tlZCBEQy9ueXF1aXN0IGNvbXBvbmVudAor
ICAgIHJlYWxQMVswXSAqPSBzY2FsZSAqIHJlYWxQMlswXTsKKyAgICBpbWFnUDFbMF0gKj0gc2Nh
bGUgKiBpbWFnUDJbMF07CisKKyAgICAvLyBNdWx0aXBseSB0aGUgcmVzdCwgc2tpcHBpbmcgcGFj
a2VkIERDL055cXVpc3QgY29tcG9uZW50cworICAgIERTUFNwbGl0Q29tcGxleCBzYzEgPSBmcmFt
ZTEuZHNwU3BsaXRDb21wbGV4KCk7CisgICAgc2MxLnJlYWxwKys7CisgICAgc2MxLmltYWdwKys7
CisKKyAgICBEU1BTcGxpdENvbXBsZXggc2MyID0gZnJhbWUyLmRzcFNwbGl0Q29tcGxleCgpOwor
ICAgIHNjMi5yZWFscCsrOworICAgIHNjMi5pbWFncCsrOworCisgICAgc2l6ZV90IGhhbGZTaXpl
ID0gbV9GRlRTaXplIC8gMjsKKworICAgIC8vIENvbXBsZXggbXVsdGlwbHkKKyAgICB6dm11bCgm
c2MxLAorICAgICAgICAgIDEsCisgICAgICAgICAgJnNjMiwKKyAgICAgICAgICAxLAorICAgICAg
ICAgICZzYzEsCisgICAgICAgICAgMSwKKyAgICAgICAgICBoYWxmU2l6ZSAtIDEsCisgICAgICAg
ICAgMSAvKiBub3JtYWwgbXVsdGlwbGljYXRpb24gKi8pOworCisgICAgLy8gV2UndmUgcHJldmlv
dXNseSBzY2FsZWQgdGhlIHBhY2tlZCBwYXJ0LCBub3cgc2NhbGUgdGhlIHJlc3QuLi4uLgorICAg
IHZzbXVsKHNjMS5yZWFscCwgMSwgJnNjYWxlLCBzYzEucmVhbHAsIDEsIGhhbGZTaXplIC0gMSk7
CisgICAgdnNtdWwoc2MxLmltYWdwLCAxLCAmc2NhbGUsIHNjMS5pbWFncCwgMSwgaGFsZlNpemUg
LSAxKTsKKworICAgIC8vIFNjYWxhciBjb2RlIGZvciByZWZlcmVuY2UKKyNpZiAwCisgICAgZmxv
YXQgc2NhbGUgPSAwLjU7CisKKyAgICAvLyBtdWx0aXBseSBwYWNrZWQgREMvbnlxdWlzdCBjb21w
b25lbnQKKyAgICByZWFsUDJbMF0gKj0gc2NhbGUgKnJlYWxQMVswXTsKKyAgICBpbWFnUDJbMF0g
Kj0gc2NhbGUgKmltYWdQMVswXTsKKworICAgIC8vIHNjYWxhciBjb2RlCisgICAgZm9yIChpbnQg
aSA9IDE7IGkgPCBoYWxmU2l6ZTsgaSsrKSB7CisgICAgICAgIC8vIHNjYWxlIGJ5IDEvMiBzaW5j
ZSB3ZSdyZSBub3QgaGFuZGxpbmcgdGhlIHNjYWxpbmcgaW4gdGhlIEZGVCAtPiBJRkZUCisgICAg
ICAgIC8vICh3ZSdyZSBoYW5kbGluZyBpdCBhbGwgaW4gdGhlIElGRlQgc3RhZ2UpCisKKworICAg
ICAgICBmbG9hdCByMSA9IHJlYWxQMVtpXTsKKyAgICAgICAgZmxvYXQgYzEgPSBpbWFnUDFbaV07
CisKKyAgICAgICAgZmxvYXQgcjIgPSByZWFsUDJbaV07CisgICAgICAgIGZsb2F0IGMyID0gaW1h
Z1AyW2ldOworCisgICAgICAgIC8vIG11bHRpcGx5IGluIHRoZSBmcmVxdWVuY3kgZG9tYWluCisg
ICAgICAgIGZsb2F0IHIzID0gcjEqcjIgLSBjMSpjMjsKKyAgICAgICAgZmxvYXQgYzMgPSByMSpj
MiArIHIyKmMxOworCisgICAgICAgIHJlYWxQMltpXSA9IHNjYWxlICogcjM7CisgICAgICAgIGlt
YWdQMltpXSA9IHNjYWxlICogYzM7CisgICAgfQorI2VuZGlmCit9CisKK3ZvaWQgRkZURnJhbWU6
OmRvRkZUKGZsb2F0KiBkYXRhKQoreworICAgIGN0b3ooKERTUENvbXBsZXgqKWRhdGEsIDIsICZt
X2ZyYW1lLCAxLCBtX0ZGVFNpemUgLyAyKTsKKyAgICBmZnRfenJpcChtX0ZGVFNldHVwLCAmbV9m
cmFtZSwgMSwgbV9sb2cyRkZUU2l6ZSwgRkZUX0ZPUldBUkQpOworfQorCit2b2lkIEZGVEZyYW1l
Ojpkb0ludmVyc2VGRlQoZmxvYXQqIGRhdGEpCit7CisgICAgZmZ0X3pyaXAobV9GRlRTZXR1cCwg
Jm1fZnJhbWUsIDEsIG1fbG9nMkZGVFNpemUsIEZGVF9JTlZFUlNFKTsKKyAgICB6dG9jKCZtX2Zy
YW1lLCAxLCAoRFNQQ29tcGxleCopZGF0YSwgMiwgbV9GRlRTaXplIC8gMik7CisKKyAgICAvLyBE
byBmaW5hbCBzY2FsaW5nIHNvIHRoYXQgeCA9PSBJRkZUKEZGVCh4KSkKKyAgICBmbG9hdCBzY2Fs
ZSA9IDAuNSAvIG1fRkZUU2l6ZTsKKyAgICB2c211bChkYXRhLCAxLCAmc2NhbGUsIGRhdGEsIDEs
IG1fRkZUU2l6ZSk7Cit9CisKK0ZGVFNldHVwIEZGVEZyYW1lOjpmZnRTZXR1cEZvclNpemUoc2l6
ZV90IGZmdFNpemUpCit7CisgICAgaWYgKCFmZnRTZXR1cHMpIHsKKyAgICAgICAgZmZ0U2V0dXBz
ID0gKEZGVFNldHVwKiltYWxsb2Moc2l6ZW9mKEZGVFNldHVwKSAqIGtNYXhGRlRQb3cyU2l6ZSk7
CisgICAgICAgIG1lbXNldChmZnRTZXR1cHMsIDAsIHNpemVvZihGRlRTZXR1cCkgKiBrTWF4RkZU
UG93MlNpemUpOworICAgIH0KKworICAgIGludCBwb3cyc2l6ZSA9IGxvZzIoZmZ0U2l6ZSk7CisK
KyAgICBhc3NlcnQocG93MnNpemUgPCBrTWF4RkZUUG93MlNpemUpOworCisgICAgaWYgKCFmZnRT
ZXR1cHNbcG93MnNpemVdKQorICAgICAgICBmZnRTZXR1cHNbcG93MnNpemVdID0gY3JlYXRlX2Zm
dHNldHVwKHBvdzJzaXplLCBGRlRfUkFESVgyKTsKKworICAgIHJldHVybiBmZnRTZXR1cHNbcG93
MnNpemVdOworfQorCit2b2lkIEZGVEZyYW1lOjpjbGVhbnVwRkZUU2V0dXBzKCkKK3sKKyAgICBp
ZiAoIWZmdFNldHVwcykKKyAgICAgICAgcmV0dXJuOworCisgICAgZm9yIChpbnQgaSA9IDA7IGkg
PCBrTWF4RkZUUG93MlNpemU7ICsraSkgeworICAgICAgICBpZiAoZmZ0U2V0dXBzW2ldKQorICAg
ICAgICAgICAgZGVzdHJveV9mZnRzZXR1cChmZnRTZXR1cHNbaV0pOworICAgIH0KKworICAgIGZy
ZWUoZmZ0U2V0dXBzKTsKKyAgICBmZnRTZXR1cHMgPSAwOworfQorCit9IC8vIG5hbWVzcGFjZSBX
ZWJDb3JlCmRpZmYgLS1naXQgYS9XZWJDb3JlL3BsYXRmb3JtL2F1ZGlvL21hYy9GRlRGcmFtZU1h
Yy5oIGIvV2ViQ29yZS9wbGF0Zm9ybS9hdWRpby9tYWMvRkZURnJhbWVNYWMuaApuZXcgZmlsZSBt
b2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40MGY5NzZiCi0tLSAvZGV2L251bGwKKysrIGIvV2Vi
Q29yZS9wbGF0Zm9ybS9hdWRpby9tYWMvRkZURnJhbWVNYWMuaApAQCAtMCwwICsxLDkxIEBACisv
KgorICogQ29weXJpZ2h0IChDKSAyMDEwIEdvb2dsZSBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQu
CisgKgorICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jt
cywgd2l0aCBvciB3aXRob3V0CisgKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlk
ZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKKyAqIGFyZSBtZXQ6CisgKgorICogMS4g
IFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29w
eXJpZ2h0CisgKiAgICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZv
bGxvd2luZyBkaXNjbGFpbWVyLgorICogMi4gIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9y
bSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0CisgKiAgICAgbm90aWNlLCB0aGlz
IGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZQor
ICogICAgIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRo
IHRoZSBkaXN0cmlidXRpb24uCisgKiAzLiAgTmVpdGhlciB0aGUgbmFtZSBvZiBBcHBsZSBDb21w
dXRlciwgSW5jLiAoIkFwcGxlIikgbm9yIHRoZSBuYW1lcyBvZgorICogICAgIGl0cyBjb250cmli
dXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQK
KyAqICAgICBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVu
IHBlcm1pc3Npb24uCisgKgorICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBBUFBMRSBB
TkQgSVRTIENPTlRSSUJVVE9SUyAiQVMgSVMiIEFORCBBTlkKKyAqIEVYUFJFU1MgT1IgSU1QTElF
RCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQK
KyAqIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJ
Q1VMQVIgUFVSUE9TRSBBUkUKKyAqIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIEFQUExF
IE9SIElUUyBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkKKyAqIERJUkVDVCwgSU5ESVJF
Q1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1B
R0VTCisgKiAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNV
QlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7CisgKiBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJP
RklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKKyAqIE9O
IEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElB
QklMSVRZLCBPUiBUT1JUCisgKiAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBB
UklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YKKyAqIFRISVMgU09GVFdBUkUsIEVW
RU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisgKi8KKwor
Ly8gRkZUIGFic3RyYWN0aW9uIGltcGxlbWVudGVkIHVzaW5nIE1hYyBPUyBYIEFjY2VsZXJhdGUu
ZnJhbWV3b3JrICh2ZWNMaWIpCisvLworCisjaWZuZGVmIEZGVEZyYW1lTWFjX2gKKyNkZWZpbmUg
RkZURnJhbWVNYWNfaAorCisjaW5jbHVkZSAiQXVkaW9GbG9hdEFycmF5LmgiCisjaW5jbHVkZSA8
QWNjZWxlcmF0ZS9BY2NlbGVyYXRlLmg+CisKK25hbWVzcGFjZSBXZWJDb3JlIHsKKworY2xhc3Mg
RkZURnJhbWUgeworcHVibGljOgorICAgIEZGVEZyYW1lKHNpemVfdCBmZnRTaXplKTsKKyAgICBG
RlRGcmFtZSgpOyAvLyBjcmVhdGVzIGEgYmxhbmsvZW1wdHkgZnJhbWUgZm9yIGxhdGVyIHVzZSB3
aXRoIGludGVycG9sYXRlKCkKKyAgICBGRlRGcmFtZShjb25zdCBGRlRGcmFtZSYgZnJhbWUpOwor
ICAgIHZpcnR1YWwgfkZGVEZyYW1lKCk7CisKKyAgICB2b2lkIGRvRkZUKGZsb2F0KiBkYXRhKTsK
KyAgICB2b2lkIGRvUGFkZGVkRkZUKGZsb2F0KiBkYXRhLCBzaXplX3QgZGF0YVNpemUpOyAvLyB6
ZXJvLXBhZGRpbmcgd2l0aCBkYXRhU2l6ZSA8PSBmZnRTaXplCisgICAgdm9pZCBkb0ludmVyc2VG
RlQoZmxvYXQqIGRhdGEpOworCisgICAgLy8gTXVsdGlwbGllcyBvdXJzZWxmIHdpdGggfGZyYW1l
fCA6IGVmZmVjdGl2ZWx5IG9wZXJhdG9yKj0oKQorICAgIHZvaWQgbXVsdGlwbHkoY29uc3QgRkZU
RnJhbWUmIGZyYW1lKTsKKworICAgIC8vIEludGVycG9sYXRlcyBmcm9tIGZyYW1lMSAtPiBmcmFt
ZTIgYXMgfHh8IGdvZXMgZnJvbSAwLjAgLT4gMS4wCisgICAgc3RhdGljIEZGVEZyYW1lKiBjcmVh
dGVJbnRlcnBvbGF0ZWRGcmFtZShGRlRGcmFtZSYgZnJhbWUxLCBGRlRGcmFtZSYgZnJhbWUyLCBk
b3VibGUgeCk7CisKKyAgICBkb3VibGUgZXh0cmFjdEF2ZXJhZ2VHcm91cERlbGF5KCk7CisgICAg
dm9pZCBhZGRDb25zdGFudEdyb3VwRGVsYXkoZG91YmxlIHNhbXBsZUZyYW1lRGVsYXkpOworCisg
ICAgc2l6ZV90IGZmdFNpemUoKSBjb25zdCB7IHJldHVybiBtX0ZGVFNpemU7IH0KKyAgICBzaXpl
X3QgbG9nMkZGVFNpemUoKSBjb25zdCB7IHJldHVybiBtX2xvZzJGRlRTaXplOyB9CisKKyAgICBm
bG9hdCogcmVhbERhdGEoKSB7IHJldHVybiBtX3JlYWxEYXRhOyB9CisgICAgZmxvYXQqIGltYWdE
YXRhKCkgeyByZXR1cm4gbV9pbWFnRGF0YTsgfQorCisgICAgLy8gRm9yIGRlYnVnZ2luZworICAg
IHZvaWQgcHJpbnQoKTsKKworICAgIHN0YXRpYyB2b2lkIGNsZWFudXBGRlRTZXR1cHMoKTsKKwor
cHJpdmF0ZToKKyAgICB2b2lkIGludGVycG9sYXRlRnJlcXVlbmN5Q29tcG9uZW50cyhGRlRGcmFt
ZSYgZnJhbWUxLCBGRlRGcmFtZSYgZnJhbWUyLCBkb3VibGUgeCk7CisKKyAgICBEU1BTcGxpdENv
bXBsZXgmIGRzcFNwbGl0Q29tcGxleCgpIHsgcmV0dXJuIG1fZnJhbWU7IH0KKworICAgIHN0YXRp
YyBGRlRTZXR1cCBmZnRTZXR1cEZvclNpemUoc2l6ZV90IGZmdFNpemUpOworCisgICAgc3RhdGlj
IEZGVFNldHVwKiBmZnRTZXR1cHM7CisKKyAgICBzaXplX3QgbV9GRlRTaXplOworICAgIHNpemVf
dCBtX2xvZzJGRlRTaXplOworICAgIEZGVFNldHVwIG1fRkZUU2V0dXA7CisKKyAgICBEU1BTcGxp
dENvbXBsZXggbV9mcmFtZTsKKyAgICBBdWRpb0Zsb2F0QXJyYXkgbV9yZWFsRGF0YTsKKyAgICBB
dWRpb0Zsb2F0QXJyYXkgbV9pbWFnRGF0YTsKK307CisKK30gLy8gbmFtZXNwYWNlIFdlYkNvcmUK
KworI2VuZGlmIC8vIEZGVEZyYW1lTWFjX2gK
</data>

          </attachment>
          <attachment
              isobsolete="1"
              ispatch="1"
              isprivate="0"
          >
            <attachid>66283</attachid>
            <date>2010-09-01 15:07:35 -0700</date>
            <delta_ts>2010-09-03 14:40:56 -0700</delta_ts>
            <desc>Patch</desc>
            <filename>bug-34827-20100901150734.patch</filename>
            <type>text/plain</type>
            <size>20312</size>
            <attacher name="Chris Rogers">crogers</attacher>
            
              <data encoding="base64">SW5kZXg6IFdlYkNvcmUvQ2hhbmdlTG9nCj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tIFdlYkNvcmUvQ2hhbmdlTG9n
CShyZXZpc2lvbiA2NjYyMCkKKysrIFdlYkNvcmUvQ2hhbmdlTG9nCSh3b3JraW5nIGNvcHkpCkBA
IC0xLDMgKzEsMzUgQEAKKzIwMTAtMDktMDEgIENocmlzIFJvZ2VycyAgPGNyb2dlcnNAZ29vZ2xl
LmNvbT4KKworICAgICAgICBSZXZpZXdlZCBieSBOT0JPRFkgKE9PUFMhKS4KKworICAgICAgICBh
dWRpbyBlbmdpbmU6IGFkZCBGRlRGcmFtZSBmaWxlcworICAgICAgICBodHRwczovL2J1Z3Mud2Vi
a2l0Lm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MzQ4MjcKKworICAgICAgICBObyBuZXcgdGVzdHMgc2lu
Y2UgYXVkaW8gQVBJIGlzIG5vdCB5ZXQgaW1wbGVtZW50ZWQuCisKKyAgICAgICAgKiBwbGF0Zm9y
bS9hdWRpby9GRlRGcmFtZS5jcHA6IEFkZGVkLgorICAgICAgICAoV2ViQ29yZTo6RkZURnJhbWU6
OmRvUGFkZGVkRkZUKToKKyAgICAgICAgKFdlYkNvcmU6OkZGVEZyYW1lOjpjcmVhdGVJbnRlcnBv
bGF0ZWRGcmFtZSk6CisgICAgICAgIChXZWJDb3JlOjpGRlRGcmFtZTo6aW50ZXJwb2xhdGVGcmVx
dWVuY3lDb21wb25lbnRzKToKKyAgICAgICAgKFdlYkNvcmU6OkZGVEZyYW1lOjpleHRyYWN0QXZl
cmFnZUdyb3VwRGVsYXkpOgorICAgICAgICAoV2ViQ29yZTo6RkZURnJhbWU6OmFkZENvbnN0YW50
R3JvdXBEZWxheSk6CisgICAgICAgIChXZWJDb3JlOjpGRlRGcmFtZTo6cHJpbnQpOgorICAgICAg
ICAqIHBsYXRmb3JtL2F1ZGlvL0ZGVEZyYW1lLmg6IEFkZGVkLgorICAgICAgICAoV2ViQ29yZTo6
RkZURnJhbWU6OmZmdFNpemUpOgorICAgICAgICAoV2ViQ29yZTo6RkZURnJhbWU6OmxvZzJGRlRT
aXplKToKKyAgICAgICAgKFdlYkNvcmU6OkZGVEZyYW1lOjpkc3BTcGxpdENvbXBsZXgpOgorICAg
ICAgICAqIHBsYXRmb3JtL2F1ZGlvL21hYzogQWRkZWQuCisgICAgICAgICogcGxhdGZvcm0vYXVk
aW8vbWFjL0ZGVEZyYW1lTWFjLmNwcDogQWRkZWQuCisgICAgICAgIChXZWJDb3JlOjpGRlRGcmFt
ZTo6RkZURnJhbWUpOgorICAgICAgICAoV2ViQ29yZTo6RkZURnJhbWU6On5GRlRGcmFtZSk6Cisg
ICAgICAgIChXZWJDb3JlOjpGRlRGcmFtZTo6bXVsdGlwbHkpOgorICAgICAgICAoV2ViQ29yZTo6
RkZURnJhbWU6OmRvRkZUKToKKyAgICAgICAgKFdlYkNvcmU6OkZGVEZyYW1lOjpkb0ludmVyc2VG
RlQpOgorICAgICAgICAoV2ViQ29yZTo6RkZURnJhbWU6OmZmdFNldHVwRm9yU2l6ZSk6CisgICAg
ICAgIChXZWJDb3JlOjpGRlRGcmFtZTo6Y2xlYW51cCk6CisgICAgICAgIChXZWJDb3JlOjpGRlRG
cmFtZTo6cmVhbERhdGEpOgorICAgICAgICAoV2ViQ29yZTo6RkZURnJhbWU6OmltYWdEYXRhKToK
KwogMjAxMC0wOS0wMSAgUm9iIEJ1aXMgIDxyd2xidWlzQGdtYWlsLmNvbT4KIAogICAgICAgICBS
ZXZpZXdlZCBieSBEYXJpbiBBZGxlci4KSW5kZXg6IFdlYkNvcmUvcGxhdGZvcm0vYXVkaW8vRkZU
RnJhbWUuY3BwCj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT0KLS0tIFdlYkNvcmUvcGxhdGZvcm0vYXVkaW8vRkZURnJhbWUu
Y3BwCShyZXZpc2lvbiAwKQorKysgV2ViQ29yZS9wbGF0Zm9ybS9hdWRpby9GRlRGcmFtZS5jcHAJ
KHJldmlzaW9uIDApCkBAIC0wLDAgKzEsMjcxIEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDEw
IEdvb2dsZSBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKgorICogUmVkaXN0cmlidXRpb24g
YW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisgKiBt
b2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNv
bmRpdGlvbnMKKyAqIGFyZSBtZXQ6CisgKgorICogMS4gIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3Vy
Y2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CisgKiAgICAgbm90aWNlLCB0
aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgorICog
Mi4gIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJv
dmUgY29weXJpZ2h0CisgKiAgICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQg
dGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZQorICogICAgIGRvY3VtZW50YXRpb24gYW5k
L29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uCisgKiAz
LiAgTmVpdGhlciB0aGUgbmFtZSBvZiBBcHBsZSBDb21wdXRlciwgSW5jLiAoIkFwcGxlIikgbm9y
IHRoZSBuYW1lcyBvZgorICogICAgIGl0cyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5k
b3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQKKyAqICAgICBmcm9tIHRoaXMgc29mdHdh
cmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisgKgorICogVEhJ
UyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBBUFBMRSBBTkQgSVRTIENPTlRSSUJVVE9SUyAiQVMg
SVMiIEFORCBBTlkKKyAqIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcs
IEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQKKyAqIFdBUlJBTlRJRVMgT0YgTUVSQ0hB
TlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKKyAqIERJ
U0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIEFQUExFIE9SIElUUyBDT05UUklCVVRPUlMgQkUg
TElBQkxFIEZPUiBBTlkKKyAqIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUws
IEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTCisgKiAoSU5DTFVESU5HLCBCVVQg
Tk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklD
RVM7CisgKiBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJS
VVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQKKyAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZ
LCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCisgKiAoSU5D
TFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9G
IFRIRSBVU0UgT0YKKyAqIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9T
U0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCisgKi8KKworI2luY2x1ZGUgImNvbmZpZy5oIgorCisj
aWYgRU5BQkxFKFdFQl9BVURJTykKKworI2luY2x1ZGUgIkZGVEZyYW1lLmgiCisKKyNpbmNsdWRl
IDx3dGYvQ29tcGxleC5oPgorI2luY2x1ZGUgPHd0Zi9NYXRoRXh0cmFzLmg+CisjaW5jbHVkZSA8
d3RmL093blB0ci5oPgorCituYW1lc3BhY2UgV2ViQ29yZSB7CisKK3ZvaWQgRkZURnJhbWU6OmRv
UGFkZGVkRkZUKGZsb2F0KiBkYXRhLCBzaXplX3QgZGF0YVNpemUpCit7CisgICAgLy8gWmVyby1w
YWQgdGhlIGltcHVsc2UgcmVzcG9uc2UKKyAgICBBdWRpb0Zsb2F0QXJyYXkgcGFkZGVkUmVzcG9u
c2UoZmZ0U2l6ZSgpKTsKKyAgICAKKyAgICBBU1NFUlQoZGF0YVNpemUgPD0gZmZ0U2l6ZSgpKTsK
KyAgICBtZW1jcHkocGFkZGVkUmVzcG9uc2UuZGF0YSgpLCBkYXRhLCBzaXplb2YoZmxvYXQpICog
ZGF0YVNpemUpOworCisgICAgLy8gR2V0IHRoZSBmcmVxdWVuY3ktZG9tYWluIHZlcnNpb24gb2Yg
cGFkZGVkIHJlc3BvbnNlCisgICAgZG9GRlQocGFkZGVkUmVzcG9uc2UuZGF0YSgpKTsKK30KKwor
UGFzc093blB0cjxGRlRGcmFtZT4gRkZURnJhbWU6OmNyZWF0ZUludGVycG9sYXRlZEZyYW1lKGNv
bnN0IEZGVEZyYW1lJiBmcmFtZTEsIGNvbnN0IEZGVEZyYW1lJiBmcmFtZTIsIGRvdWJsZSB4KQor
eworICAgIE93blB0cjxGRlRGcmFtZT4gbmV3RnJhbWUgPSBhZG9wdFB0cihuZXcgRkZURnJhbWUo
ZnJhbWUxLmZmdFNpemUoKSkpOworCisgICAgbmV3RnJhbWUtPmludGVycG9sYXRlRnJlcXVlbmN5
Q29tcG9uZW50cyhmcmFtZTEsIGZyYW1lMiwgeCk7CisKKyAgICAvLyBJbiB0aGUgdGltZS1kb21h
aW4sIHRoZSAybmQgaGFsZiBvZiB0aGUgcmVzcG9uc2UgbXVzdCBiZSB6ZXJvLCB0byBhdm9pZCBj
aXJjdWxhciBjb252b2x1dGlvbiBhbGlhc2luZy4uLgorICAgIGludCBmZnRTaXplID0gbmV3RnJh
bWUtPmZmdFNpemUoKTsKKyAgICBBdWRpb0Zsb2F0QXJyYXkgYnVmZmVyKGZmdFNpemUpOworICAg
IG5ld0ZyYW1lLT5kb0ludmVyc2VGRlQoYnVmZmVyLmRhdGEoKSk7CisKKyAgICBtZW1zZXQoYnVm
ZmVyLmRhdGEoKSArIGZmdFNpemUgLyAyLCAwLCBzaXplb2YoZmxvYXQpICogZmZ0U2l6ZSAvIDIp
OworCisgICAgbmV3RnJhbWUtPmRvRkZUKGJ1ZmZlci5kYXRhKCkpOworCisgICAgcmV0dXJuIG5l
d0ZyYW1lLnJlbGVhc2UoKTsKK30KKwordm9pZCBGRlRGcmFtZTo6aW50ZXJwb2xhdGVGcmVxdWVu
Y3lDb21wb25lbnRzKGNvbnN0IEZGVEZyYW1lJiBmcmFtZTEsIGNvbnN0IEZGVEZyYW1lJiBmcmFt
ZTIsIGRvdWJsZSBpbnRlcnApCit7CisgICAgLy8gRklYTUUgOiB3aXRoIHNvbWUgd29yaywgdGhp
cyBtZXRob2QgY291bGQgYmUgb3B0aW1pemVkCisKKyAgICBmbG9hdCogcmVhbFAgPSByZWFsRGF0
YSgpOworICAgIGZsb2F0KiBpbWFnUCA9IGltYWdEYXRhKCk7CisKKyAgICBjb25zdCBmbG9hdCog
cmVhbFAxID0gZnJhbWUxLnJlYWxEYXRhKCk7CisgICAgY29uc3QgZmxvYXQqIGltYWdQMSA9IGZy
YW1lMS5pbWFnRGF0YSgpOworICAgIGNvbnN0IGZsb2F0KiByZWFsUDIgPSBmcmFtZTIucmVhbERh
dGEoKTsKKyAgICBjb25zdCBmbG9hdCogaW1hZ1AyID0gZnJhbWUyLmltYWdEYXRhKCk7CisKKyAg
ICBtX0ZGVFNpemUgPSBmcmFtZTEuZmZ0U2l6ZSgpOworICAgIG1fbG9nMkZGVFNpemUgPSBmcmFt
ZTEubG9nMkZGVFNpemUoKTsKKworICAgIGRvdWJsZSBzMWJhc2UgPSAoMS4wIC0gaW50ZXJwKTsK
KyAgICBkb3VibGUgczJiYXNlID0gaW50ZXJwOworCisgICAgZG91YmxlIHBoYXNlQWNjdW0gPSAw
LjA7CisgICAgZG91YmxlIGxhc3RQaGFzZTEgPSAwLjA7CisgICAgZG91YmxlIGxhc3RQaGFzZTIg
PSAwLjA7CisKKyAgICByZWFsUFswXSA9IHN0YXRpY19jYXN0PGZsb2F0PihzMWJhc2UgKiByZWFs
UDFbMF0gKyBzMmJhc2UgKiByZWFsUDJbMF0pOworICAgIGltYWdQWzBdID0gc3RhdGljX2Nhc3Q8
ZmxvYXQ+KHMxYmFzZSAqIGltYWdQMVswXSArIHMyYmFzZSAqIGltYWdQMlswXSk7CisKKyAgICBp
bnQgbiA9IG1fRkZUU2l6ZSAvIDI7CisKKyAgICBmb3IgKGludCBpID0gMTsgaSA8IG47ICsraSkg
eworICAgICAgICBDb21wbGV4IGMxKHJlYWxQMVtpXSwgaW1hZ1AxW2ldKTsKKyAgICAgICAgQ29t
cGxleCBjMihyZWFsUDJbaV0sIGltYWdQMltpXSk7CisKKyAgICAgICAgZG91YmxlIG1hZzEgPSBh
YnMoYzEpOworICAgICAgICBkb3VibGUgbWFnMiA9IGFicyhjMik7CisKKyAgICAgICAgLy8gSW50
ZXJwb2xhdGUgbWFnbml0dWRlcyBpbiBkZWNpYmVscworICAgICAgICBkb3VibGUgbWFnMWRiID0g
MjAuMCAqIGxvZzEwKG1hZzEpOworICAgICAgICBkb3VibGUgbWFnMmRiID0gMjAuMCAqIGxvZzEw
KG1hZzIpOworCisgICAgICAgIGRvdWJsZSBzMSA9IHMxYmFzZTsKKyAgICAgICAgZG91YmxlIHMy
ID0gczJiYXNlOworCisgICAgICAgIGRvdWJsZSBtYWdkYmRpZmYgPSBtYWcxZGIgLSBtYWcyZGI7
CisKKyAgICAgICAgLy8gRW1waXJpY2FsIHR3ZWFrIHRvIHJldGFpbiBoaWdoZXItZnJlcXVlbmN5
IHplcm9lcworICAgICAgICBkb3VibGUgdGhyZXNob2xkID0gIChpID4gMTYpID8gNS4wIDogMi4w
OworCisgICAgICAgIGlmIChtYWdkYmRpZmYgPCAtdGhyZXNob2xkICYmIG1hZzFkYiA8IDAuMCkg
eworICAgICAgICAgICAgczEgPSBwb3coczEsIDAuNzUpOworICAgICAgICAgICAgczIgPSAxLjAg
LSBzMTsKKyAgICAgICAgfSBlbHNlIGlmIChtYWdkYmRpZmYgPiB0aHJlc2hvbGQgJiYgbWFnMmRi
IDwgMC4wKSB7CisgICAgICAgICAgICBzMiA9IHBvdyhzMiwgMC43NSk7CisgICAgICAgICAgICBz
MSA9IDEuMCAtIHMyOworICAgICAgICB9CisKKyAgICAgICAgLy8gQXZlcmFnZSBtYWduaXR1ZGUg
YnkgZGVjaWJlbHMgaW5zdGVhZCBvZiBsaW5lYXJseQorICAgICAgICBkb3VibGUgbWFnZGIgPSBz
MSAqIG1hZzFkYiArIHMyICogbWFnMmRiOworICAgICAgICBkb3VibGUgbWFnID0gcG93KDEwLjAs
IDAuMDUgKiBtYWdkYik7CisKKyAgICAgICAgLy8gTm93LCBkZWFsIHdpdGggcGhhc2UKKyAgICAg
ICAgZG91YmxlIHBoYXNlMSA9IGFyZyhjMSk7CisgICAgICAgIGRvdWJsZSBwaGFzZTIgPSBhcmco
YzIpOworCisgICAgICAgIGRvdWJsZSBkZWx0YVBoYXNlMSA9IHBoYXNlMSAtIGxhc3RQaGFzZTE7
CisgICAgICAgIGRvdWJsZSBkZWx0YVBoYXNlMiA9IHBoYXNlMiAtIGxhc3RQaGFzZTI7CisgICAg
ICAgIGxhc3RQaGFzZTEgPSBwaGFzZTE7CisgICAgICAgIGxhc3RQaGFzZTIgPSBwaGFzZTI7CisK
KyAgICAgICAgLy8gVW53cmFwIHBoYXNlIGRlbHRhcworICAgICAgICBpZiAoZGVsdGFQaGFzZTEg
PiBNX1BJKQorICAgICAgICAgICAgZGVsdGFQaGFzZTEgLT0gMi4wICogTV9QSTsKKyAgICAgICAg
aWYgKGRlbHRhUGhhc2UxIDwgLU1fUEkpCisgICAgICAgICAgICBkZWx0YVBoYXNlMSArPSAyLjAg
KiBNX1BJOworICAgICAgICBpZiAoZGVsdGFQaGFzZTIgPiBNX1BJKQorICAgICAgICAgICAgZGVs
dGFQaGFzZTIgLT0gMi4wICogTV9QSTsKKyAgICAgICAgaWYgKGRlbHRhUGhhc2UyIDwgLU1fUEkp
CisgICAgICAgICAgICBkZWx0YVBoYXNlMiArPSAyLjAgKiBNX1BJOworCisgICAgICAgIC8vIEJs
ZW5kIGdyb3VwLWRlbGF5cworICAgICAgICBkb3VibGUgZGVsdGFQaGFzZUJsZW5kOworCisgICAg
ICAgIGlmIChkZWx0YVBoYXNlMSAtIGRlbHRhUGhhc2UyID4gTV9QSSkKKyAgICAgICAgICAgIGRl
bHRhUGhhc2VCbGVuZCA9IHMxICogZGVsdGFQaGFzZTEgKyBzMiAqICgyLjAgKiBNX1BJICsgZGVs
dGFQaGFzZTIpOworICAgICAgICBlbHNlIGlmIChkZWx0YVBoYXNlMiAtIGRlbHRhUGhhc2UxID4g
TV9QSSkKKyAgICAgICAgICAgIGRlbHRhUGhhc2VCbGVuZCA9IHMxICogKDIuMCAqIE1fUEkgKyBk
ZWx0YVBoYXNlMSkgKyBzMiAqIGRlbHRhUGhhc2UyOworICAgICAgICBlbHNlCisgICAgICAgICAg
ICBkZWx0YVBoYXNlQmxlbmQgPSBzMSAqIGRlbHRhUGhhc2UxICsgczIgKiBkZWx0YVBoYXNlMjsK
KworICAgICAgICBwaGFzZUFjY3VtICs9IGRlbHRhUGhhc2VCbGVuZDsKKworICAgICAgICAvLyBV
bndyYXAKKyAgICAgICAgaWYgKHBoYXNlQWNjdW0gPiBNX1BJKQorICAgICAgICAgICAgcGhhc2VB
Y2N1bSAtPSAyLjAgKiBNX1BJOworICAgICAgICBpZiAocGhhc2VBY2N1bSA8IC1NX1BJKQorICAg
ICAgICAgICAgcGhhc2VBY2N1bSArPSAyLjAgKiBNX1BJOworCisgICAgICAgIENvbXBsZXggYyA9
IGNvbXBsZXhGcm9tTWFnbml0dWRlUGhhc2UobWFnLCBwaGFzZUFjY3VtKTsKKworICAgICAgICBy
ZWFsUFtpXSA9IHN0YXRpY19jYXN0PGZsb2F0PihjLnJlYWwoKSk7CisgICAgICAgIGltYWdQW2ld
ID0gc3RhdGljX2Nhc3Q8ZmxvYXQ+KGMuaW1hZygpKTsKKyAgICB9Cit9CisKK2RvdWJsZSBGRlRG
cmFtZTo6ZXh0cmFjdEF2ZXJhZ2VHcm91cERlbGF5KCkKK3sKKyAgICBmbG9hdCogcmVhbFAgPSBy
ZWFsRGF0YSgpOworICAgIGZsb2F0KiBpbWFnUCA9IGltYWdEYXRhKCk7CisKKyAgICBkb3VibGUg
YXZlU3VtID0gMC4wOworICAgIGRvdWJsZSB3ZWlnaHRTdW0gPSAwLjA7CisgICAgZG91YmxlIGxh
c3RQaGFzZSA9IDAuMDsKKworICAgIGludCBoYWxmU2l6ZSA9IGZmdFNpemUoKSAvIDI7CisKKyAg
ICBjb25zdCBkb3VibGUga1NhbXBsZVBoYXNlRGVsYXkgPSAoMi4wICogTV9QSSkgLyBkb3VibGUo
ZmZ0U2l6ZSgpKTsKKworICAgIC8vIENhbGN1bGF0ZSB3ZWlnaHRlZCBhdmVyYWdlIGdyb3VwIGRl
bGF5CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBoYWxmU2l6ZTsgaSsrKSB7CisgICAgICAgIENv
bXBsZXggYyhyZWFsUFtpXSwgaW1hZ1BbaV0pOworICAgICAgICBkb3VibGUgbWFnID0gYWJzKGMp
OworICAgICAgICBkb3VibGUgcGhhc2UgPSBhcmcoYyk7CisKKyAgICAgICAgZG91YmxlIGRlbHRh
UGhhc2UgPSBwaGFzZSAtIGxhc3RQaGFzZTsKKyAgICAgICAgbGFzdFBoYXNlID0gcGhhc2U7CisK
KyAgICAgICAgLy8gVW53cmFwCisgICAgICAgIGlmIChkZWx0YVBoYXNlIDwgLU1fUEkpCisgICAg
ICAgICAgICBkZWx0YVBoYXNlICs9IDIuMCAqIE1fUEk7CisgICAgICAgIGlmIChkZWx0YVBoYXNl
ID4gTV9QSSkKKyAgICAgICAgICAgIGRlbHRhUGhhc2UgLT0gMi4wICogTV9QSTsKKworICAgICAg
ICBhdmVTdW0gKz0gbWFnICogZGVsdGFQaGFzZTsKKyAgICAgICAgd2VpZ2h0U3VtICs9IG1hZzsK
KyAgICB9CisKKyAgICAvLyBOb3RlIGhvdyB3ZSBpbnZlcnQgdGhlIHBoYXNlIGRlbHRhIHdydCBm
cmVxdWVuY3kgc2luY2UgdGhpcyBpcyBob3cgZ3JvdXAgZGVsYXkgaXMgZGVmaW5lZAorICAgIGRv
dWJsZSBhdmUgPSBhdmVTdW0gLyB3ZWlnaHRTdW07CisgICAgZG91YmxlIGF2ZVNhbXBsZURlbGF5
ID0gLWF2ZSAvIGtTYW1wbGVQaGFzZURlbGF5OworCisgICAgLy8gTGVhdmUgMjAgc2FtcGxlIGhl
YWRyb29tIChmb3IgbGVhZGluZyBlZGdlIG9mIGltcHVsc2UpCisgICAgaWYgKGF2ZVNhbXBsZURl
bGF5ID4gMjAuMCkKKyAgICAgICAgYXZlU2FtcGxlRGVsYXkgLT0gMjAuMDsKKworICAgIC8vIFJl
bW92ZSBhdmVyYWdlIGdyb3VwIGRlbGF5IChtaW51cyAyMCBzYW1wbGVzIGZvciBoZWFkcm9vbSkK
KyAgICBhZGRDb25zdGFudEdyb3VwRGVsYXkoLWF2ZVNhbXBsZURlbGF5KTsKKworICAgIC8vIFJl
bW92ZSBEQyBvZmZzZXQKKyAgICByZWFsUFswXSA9IDAuMGY7CisKKyAgICByZXR1cm4gYXZlU2Ft
cGxlRGVsYXk7Cit9CisKK3ZvaWQgRkZURnJhbWU6OmFkZENvbnN0YW50R3JvdXBEZWxheShkb3Vi
bGUgc2FtcGxlRnJhbWVEZWxheSkKK3sKKyAgICBpbnQgaGFsZlNpemUgPSBmZnRTaXplKCkgLyAy
OworCisgICAgZmxvYXQqIHJlYWxQID0gcmVhbERhdGEoKTsKKyAgICBmbG9hdCogaW1hZ1AgPSBp
bWFnRGF0YSgpOworCisgICAgY29uc3QgZG91YmxlIGtTYW1wbGVQaGFzZURlbGF5ID0gKDIuMCAq
IE1fUEkpIC8gZG91YmxlKGZmdFNpemUoKSk7CisKKyAgICBkb3VibGUgcGhhc2VBZGogPSAtc2Ft
cGxlRnJhbWVEZWxheSAqIGtTYW1wbGVQaGFzZURlbGF5OworCisgICAgLy8gQWRkIGNvbnN0YW50
IGdyb3VwIGRlbGF5CisgICAgZm9yIChpbnQgaSA9IDE7IGkgPCBoYWxmU2l6ZTsgaSsrKSB7Cisg
ICAgICAgIENvbXBsZXggYyhyZWFsUFtpXSwgaW1hZ1BbaV0pOworICAgICAgICBkb3VibGUgbWFn
ID0gYWJzKGMpOworICAgICAgICBkb3VibGUgcGhhc2UgPSBhcmcoYyk7CisKKyAgICAgICAgcGhh
c2UgKz0gaSAqIHBoYXNlQWRqOworCisgICAgICAgIENvbXBsZXggYzIgPSBjb21wbGV4RnJvbU1h
Z25pdHVkZVBoYXNlKG1hZywgcGhhc2UpOworCisgICAgICAgIHJlYWxQW2ldID0gc3RhdGljX2Nh
c3Q8ZmxvYXQ+KGMyLnJlYWwoKSk7CisgICAgICAgIGltYWdQW2ldID0gc3RhdGljX2Nhc3Q8Zmxv
YXQ+KGMyLmltYWcoKSk7CisgICAgfQorfQorCisjaWZuZGVmIE5ERUJVRwordm9pZCBGRlRGcmFt
ZTo6cHJpbnQoKQoreworICAgIEZGVEZyYW1lJiBmcmFtZSA9ICp0aGlzOworICAgIGZsb2F0KiBy
ZWFsUCA9IGZyYW1lLnJlYWxEYXRhKCk7CisgICAgZmxvYXQqIGltYWdQID0gZnJhbWUuaW1hZ0Rh
dGEoKTsKKyAgICBwcmludGYoIioqKiogXG4iKTsKKyAgICBwcmludGYoIkRDID0gJWYgOiBueXF1
aXN0ID0gJWZcbiIsIHJlYWxQWzBdLCBpbWFnUFswXSk7CisKKyAgICBpbnQgbiA9IG1fRkZUU2l6
ZSAvIDI7CisKKyAgICBmb3IgKGludCBpID0gMTsgaSA8IG47IGkrKykgeworICAgICAgICBkb3Vi
bGUgbWFnID0gc3FydChyZWFsUFtpXSAqIHJlYWxQW2ldICsgaW1hZ1BbaV0gKiBpbWFnUFtpXSk7
CisgICAgICAgIGRvdWJsZSBwaGFzZSA9IGF0YW4yKHJlYWxQW2ldLCBpbWFnUFtpXSk7CisKKyAg
ICAgICAgcHJpbnRmKCJbJWRdICglZiAlZilcbiIsIGksIG1hZywgcGhhc2UpOworICAgIH0KKyAg
ICBwcmludGYoIioqKipcbiIpOworfQorI2VuZGlmIC8vIE5ERUJVRworCit9IC8vIG5hbWVzcGFj
ZSBXZWJDb3JlCisKKyNlbmRpZiAvLyBFTkFCTEUoV0VCX0FVRElPKQpJbmRleDogV2ViQ29yZS9w
bGF0Zm9ybS9hdWRpby9GRlRGcmFtZS5oCj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tIFdlYkNvcmUvcGxhdGZvcm0v
YXVkaW8vRkZURnJhbWUuaAkocmV2aXNpb24gMCkKKysrIFdlYkNvcmUvcGxhdGZvcm0vYXVkaW8v
RkZURnJhbWUuaAkocmV2aXNpb24gMCkKQEAgLTAsMCArMSwxMDEgQEAKKy8qCisgKiBDb3B5cmln
aHQgKEMpIDIwMTAgR29vZ2xlIEluYy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBSZWRp
c3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdp
dGhvdXQKKyAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBm
b2xsb3dpbmcgY29uZGl0aW9ucworICogYXJlIG1ldDoKKyAqCisgKiAxLiAgUmVkaXN0cmlidXRp
b25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKyAqICAg
ICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2Ns
YWltZXIuCisgKiAyLiAgUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9k
dWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKKyAqICAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25k
aXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlCisgKiAgICAgZG9jdW1l
bnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1
dGlvbi4KKyAqIDMuICBOZWl0aGVyIHRoZSBuYW1lIG9mIEFwcGxlIENvbXB1dGVyLCBJbmMuICgi
QXBwbGUiKSBub3IgdGhlIG5hbWVzIG9mCisgKiAgICAgaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUg
dXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZAorICogICAgIGZyb20g
dGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4K
KyAqCisgKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIEFQUExFIEFORCBJVFMgQ09OVFJJ
QlVUT1JTICJBUyBJUyIgQU5EIEFOWQorICogRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMs
IElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRAorICogV0FSUkFOVElF
UyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NF
IEFSRQorICogRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgQVBQTEUgT1IgSVRTIENPTlRS
SUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWQorICogRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRB
TCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMKKyAqIChJTkNM
VURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09E
UyBPUiBTRVJWSUNFUzsKKyAqIExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJ
TkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAorICogT04gQU5ZIFRIRU9SWSBP
RiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRP
UlQKKyAqIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5Z
IFdBWSBPVVQgT0YgVEhFIFVTRSBPRgorICogVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VE
IE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKyAqLworCisjaWZuZGVmIEZGVEZy
YW1lX2gKKyNkZWZpbmUgRkZURnJhbWVfaAorCisjaW5jbHVkZSAiQXVkaW9GbG9hdEFycmF5Lmgi
CisKKyNpZiBPUyhEQVJXSU4pCisjaW5jbHVkZSA8QWNjZWxlcmF0ZS9BY2NlbGVyYXRlLmg+Cisj
ZW5kaWYKKworI2luY2x1ZGUgPHd0Zi9QYXNzT3duUHRyLmg+CisjaW5jbHVkZSA8d3RmL1BsYXRm
b3JtLmg+CisKK25hbWVzcGFjZSBXZWJDb3JlIHsKKworLy8gRGVmaW5lcyB0aGUgaW50ZXJmYWNl
IGZvciBhbiAiRkZUIGZyYW1lIiwgYW4gb2JqZWN0IHdoaWNoIGlzIGFibGUgdG8gcGVyZm9ybSBh
IGZvcndhcmQKKy8vIGFuZCByZXZlcnNlIEZGVCwgaW50ZXJuYWxseSBzdG9yaW5nIHRoZSByZXN1
bHRhbnQgZnJlcXVlbmN5LWRvbWFpbiBkYXRhLgorCitjbGFzcyBGRlRGcmFtZSB7CitwdWJsaWM6
CisgICAgRkZURnJhbWUodW5zaWduZWQgZmZ0U2l6ZSk7CisgICAgRkZURnJhbWUoKTsgLy8gY3Jl
YXRlcyBhIGJsYW5rL2VtcHR5IGZyYW1lIGZvciBsYXRlciB1c2Ugd2l0aCBjcmVhdGVJbnRlcnBv
bGF0ZWRGcmFtZSgpCisgICAgRkZURnJhbWUoY29uc3QgRkZURnJhbWUmIGZyYW1lKTsKKyAgICB+
RkZURnJhbWUoKTsKKworICAgIHN0YXRpYyB2b2lkIGNsZWFudXAoKTsKKworICAgIHZvaWQgZG9G
RlQoZmxvYXQqIGRhdGEpOworICAgIHZvaWQgZG9QYWRkZWRGRlQoZmxvYXQqIGRhdGEsIHNpemVf
dCBkYXRhU2l6ZSk7IC8vIHplcm8tcGFkZGluZyB3aXRoIGRhdGFTaXplIDw9IGZmdFNpemUKKyAg
ICB2b2lkIGRvSW52ZXJzZUZGVChmbG9hdCogZGF0YSk7CisKKyAgICAvLyBNdWx0aXBsaWVzIG91
cnNlbGYgd2l0aCBmcmFtZSA6IGVmZmVjdGl2ZWx5IG9wZXJhdG9yKj0oKQorICAgIHZvaWQgbXVs
dGlwbHkoY29uc3QgRkZURnJhbWUmIGZyYW1lKTsKKworICAgIC8vIEludGVycG9sYXRlcyBmcm9t
IGZyYW1lMSAtPiBmcmFtZTIgYXMgeCBnb2VzIGZyb20gMC4wIC0+IDEuMAorICAgIHN0YXRpYyBQ
YXNzT3duUHRyPEZGVEZyYW1lPiBjcmVhdGVJbnRlcnBvbGF0ZWRGcmFtZShjb25zdCBGRlRGcmFt
ZSYgZnJhbWUxLCBjb25zdCBGRlRGcmFtZSYgZnJhbWUyLCBkb3VibGUgeCk7CisKKyAgICBkb3Vi
bGUgZXh0cmFjdEF2ZXJhZ2VHcm91cERlbGF5KCk7CisgICAgdm9pZCBhZGRDb25zdGFudEdyb3Vw
RGVsYXkoZG91YmxlIHNhbXBsZUZyYW1lRGVsYXkpOworCisgICAgdW5zaWduZWQgZmZ0U2l6ZSgp
IGNvbnN0IHsgcmV0dXJuIG1fRkZUU2l6ZTsgfQorICAgIHVuc2lnbmVkIGxvZzJGRlRTaXplKCkg
Y29uc3QgeyByZXR1cm4gbV9sb2cyRkZUU2l6ZTsgfQorCisgICAgZmxvYXQqIHJlYWxEYXRhKCkg
Y29uc3Q7CisgICAgZmxvYXQqIGltYWdEYXRhKCkgY29uc3Q7CisKKyAgICAvLyBGb3IgZGVidWdn
aW5nCisgICAgdm9pZCBwcmludCgpOworCitwcml2YXRlOgorICAgIHVuc2lnbmVkIG1fRkZUU2l6
ZTsKKyAgICB1bnNpZ25lZCBtX2xvZzJGRlRTaXplOworCisgICAgdm9pZCBpbnRlcnBvbGF0ZUZy
ZXF1ZW5jeUNvbXBvbmVudHMoY29uc3QgRkZURnJhbWUmIGZyYW1lMSwgY29uc3QgRkZURnJhbWUm
IGZyYW1lMiwgZG91YmxlIHgpOworCisjaWYgT1MoREFSV0lOKQorICAgIERTUFNwbGl0Q29tcGxl
eCYgZHNwU3BsaXRDb21wbGV4KCkgeyByZXR1cm4gbV9mcmFtZTsgfQorICAgIERTUFNwbGl0Q29t
cGxleCBkc3BTcGxpdENvbXBsZXgoKSBjb25zdCB7IHJldHVybiBtX2ZyYW1lOyB9CisKKyAgICBz
dGF0aWMgRkZUU2V0dXAgZmZ0U2V0dXBGb3JTaXplKHVuc2lnbmVkIGZmdFNpemUpOworCisgICAg
c3RhdGljIEZGVFNldHVwKiBmZnRTZXR1cHM7CisKKyAgICBGRlRTZXR1cCBtX0ZGVFNldHVwOwor
CisgICAgRFNQU3BsaXRDb21wbGV4IG1fZnJhbWU7CisgICAgQXVkaW9GbG9hdEFycmF5IG1fcmVh
bERhdGE7CisgICAgQXVkaW9GbG9hdEFycmF5IG1faW1hZ0RhdGE7CisjZW5kaWYgLy8gT1MoREFS
V0lOKQorfTsKKworfSAvLyBuYW1lc3BhY2UgV2ViQ29yZQorCisjZW5kaWYgLy8gRkZURnJhbWVf
aApJbmRleDogV2ViQ29yZS9wbGF0Zm9ybS9hdWRpby9tYWMvRkZURnJhbWVNYWMuY3BwCj09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT0KLS0tIFdlYkNvcmUvcGxhdGZvcm0vYXVkaW8vbWFjL0ZGVEZyYW1lTWFjLmNwcAkocmV2
aXNpb24gMCkKKysrIFdlYkNvcmUvcGxhdGZvcm0vYXVkaW8vbWFjL0ZGVEZyYW1lTWFjLmNwcAko
cmV2aXNpb24gMCkKQEAgLTAsMCArMSwxOTEgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAg
R29vZ2xlIEluYy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBSZWRpc3RyaWJ1dGlvbiBh
bmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKyAqIG1v
ZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29u
ZGl0aW9ucworICogYXJlIG1ldDoKKyAqCisgKiAxLiAgUmVkaXN0cmlidXRpb25zIG9mIHNvdXJj
ZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKyAqICAgICBub3RpY2UsIHRo
aXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisgKiAy
LiAgUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92
ZSBjb3B5cmlnaHQKKyAqICAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0
aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlCisgKiAgICAgZG9jdW1lbnRhdGlvbiBhbmQv
b3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi4KKyAqIDMu
ICBOZWl0aGVyIHRoZSBuYW1lIG9mIEFwcGxlIENvbXB1dGVyLCBJbmMuICgiQXBwbGUiKSBub3Ig
dGhlIG5hbWVzIG9mCisgKiAgICAgaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRv
cnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZAorICogICAgIGZyb20gdGhpcyBzb2Z0d2Fy
ZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKyAqCisgKiBUSElT
IFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIEFQUExFIEFORCBJVFMgQ09OVFJJQlVUT1JTICJBUyBJ
UyIgQU5EIEFOWQorICogRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywg
QlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRAorICogV0FSUkFOVElFUyBPRiBNRVJDSEFO
VEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRQorICogRElT
Q0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgQVBQTEUgT1IgSVRTIENPTlRSSUJVVE9SUyBCRSBM
SUFCTEUgRk9SIEFOWQorICogRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwg
RVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMKKyAqIChJTkNMVURJTkcsIEJVVCBO
T1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNF
UzsKKyAqIExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJV
UFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAorICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFks
IFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKyAqIChJTkNM
VURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0Yg
VEhFIFVTRSBPRgorICogVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NT
SUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKyAqLworCisvLyBNYWMgT1MgWCAtIHNwZWNpZmljIEZG
VEZyYW1lIGltcGxlbWVudGF0aW9uCisKKyNpbmNsdWRlICJjb25maWcuaCIKKworI2lmIEVOQUJM
RShXRUJfQVVESU8pCisKKyNpbmNsdWRlICJGRlRGcmFtZS5oIgorCituYW1lc3BhY2UgV2ViQ29y
ZSB7CisKK2NvbnN0IGludCBrTWF4RkZUUG93MlNpemUgPSAyNDsKKworRkZUU2V0dXAqIEZGVEZy
YW1lOjpmZnRTZXR1cHMgPSAwOworCisvLyBOb3JtYWwgY29uc3RydWN0b3I6IGFsbG9jYXRlcyBm
b3IgYSBnaXZlbiBmZnRTaXplCitGRlRGcmFtZTo6RkZURnJhbWUodW5zaWduZWQgZmZ0U2l6ZSkK
KyAgICA6IG1fcmVhbERhdGEoZmZ0U2l6ZSkKKyAgICAsIG1faW1hZ0RhdGEoZmZ0U2l6ZSkKK3sK
KyAgICBtX0ZGVFNpemUgPSBmZnRTaXplOworICAgIG1fbG9nMkZGVFNpemUgPSBzdGF0aWNfY2Fz
dDx1bnNpZ25lZD4obG9nMihmZnRTaXplKSk7CisKKyAgICAvLyBXZSBvbmx5IGFsbG93IHBvd2Vy
IG9mIHR3bworICAgIEFTU0VSVCgxVUwgPDwgbV9sb2cyRkZUU2l6ZSA9PSBtX0ZGVFNpemUpOwor
CisgICAgLy8gTGF6aWx5IGNyZWF0ZSBhbmQgc2hhcmUgZmZ0U2V0dXAgd2l0aCBvdGhlciBmcmFt
ZXMKKyAgICBtX0ZGVFNldHVwID0gZmZ0U2V0dXBGb3JTaXplKGZmdFNpemUpOworCisgICAgLy8g
U2V0dXAgZnJhbWUgZGF0YQorICAgIG1fZnJhbWUucmVhbHAgPSBtX3JlYWxEYXRhLmRhdGEoKTsK
KyAgICBtX2ZyYW1lLmltYWdwID0gbV9pbWFnRGF0YS5kYXRhKCk7Cit9CisKKy8vIENyZWF0ZXMg
YSBibGFuay9lbXB0eSBmcmFtZSAoaW50ZXJwb2xhdGUoKSBtdXN0IGxhdGVyIGJlIGNhbGxlZCkK
K0ZGVEZyYW1lOjpGRlRGcmFtZSgpCisgICAgOiBtX3JlYWxEYXRhKDApCisgICAgLCBtX2ltYWdE
YXRhKDApCit7CisgICAgLy8gTGF0ZXIgd2lsbCBiZSBzZXQgdG8gY29ycmVjdCB2YWx1ZXMgd2hl
biBpbnRlcnBvbGF0ZSgpIGlzIGNhbGxlZAorICAgIG1fZnJhbWUucmVhbHAgPSAwOworICAgIG1f
ZnJhbWUuaW1hZ3AgPSAwOworCisgICAgbV9GRlRTaXplID0gMDsKKyAgICBtX2xvZzJGRlRTaXpl
ID0gMDsKK30KKworLy8gQ29weSBjb25zdHJ1Y3RvcgorRkZURnJhbWU6OkZGVEZyYW1lKGNvbnN0
IEZGVEZyYW1lJiBmcmFtZSkKKyAgICA6IG1fRkZUU2l6ZShmcmFtZS5tX0ZGVFNpemUpCisgICAg
LCBtX2xvZzJGRlRTaXplKGZyYW1lLm1fbG9nMkZGVFNpemUpCisgICAgLCBtX0ZGVFNldHVwKGZy
YW1lLm1fRkZUU2V0dXApCisgICAgLCBtX3JlYWxEYXRhKGZyYW1lLm1fRkZUU2l6ZSkKKyAgICAs
IG1faW1hZ0RhdGEoZnJhbWUubV9GRlRTaXplKQoreworICAgIC8vIFNldHVwIGZyYW1lIGRhdGEK
KyAgICBtX2ZyYW1lLnJlYWxwID0gbV9yZWFsRGF0YS5kYXRhKCk7CisgICAgbV9mcmFtZS5pbWFn
cCA9IG1faW1hZ0RhdGEuZGF0YSgpOworCisgICAgLy8gQ29weS9zZXR1cCBmcmFtZSBkYXRhCisg
ICAgdW5zaWduZWQgbmJ5dGVzID0gc2l6ZW9mKGZsb2F0KSAqIG1fRkZUU2l6ZTsKKyAgICBtZW1j
cHkocmVhbERhdGEoKSwgZnJhbWUubV9mcmFtZS5yZWFscCwgbmJ5dGVzKTsKKyAgICBtZW1jcHko
aW1hZ0RhdGEoKSwgZnJhbWUubV9mcmFtZS5pbWFncCwgbmJ5dGVzKTsKK30KKworRkZURnJhbWU6
On5GRlRGcmFtZSgpCit7Cit9CisKK3ZvaWQgRkZURnJhbWU6Om11bHRpcGx5KGNvbnN0IEZGVEZy
YW1lJiBmcmFtZSkKK3sKKyAgICBGRlRGcmFtZSYgZnJhbWUxID0gKnRoaXM7CisgICAgY29uc3Qg
RkZURnJhbWUmIGZyYW1lMiA9IGZyYW1lOworCisgICAgZmxvYXQqIHJlYWxQMSA9IGZyYW1lMS5y
ZWFsRGF0YSgpOworICAgIGZsb2F0KiBpbWFnUDEgPSBmcmFtZTEuaW1hZ0RhdGEoKTsKKyAgICBj
b25zdCBmbG9hdCogcmVhbFAyID0gZnJhbWUyLnJlYWxEYXRhKCk7CisgICAgY29uc3QgZmxvYXQq
IGltYWdQMiA9IGZyYW1lMi5pbWFnRGF0YSgpOworCisgICAgLy8gU2NhbGUgYWNjb3VudHMgZm9y
IHZlY0xpYidzIHBlY3VsaWFyIHNjYWxpbmcKKyAgICAvLyBUaGlzIGVuc3VyZXMgdGhlIHJpZ2h0
IHNjYWxpbmcgYWxsIHRoZSB3YXkgYmFjayB0byBpbnZlcnNlIEZGVAorICAgIGZsb2F0IHNjYWxl
ID0gMC41ZjsKKworICAgIC8vIE11bHRpcGx5IHBhY2tlZCBEQy9ueXF1aXN0IGNvbXBvbmVudAor
ICAgIHJlYWxQMVswXSAqPSBzY2FsZSAqIHJlYWxQMlswXTsKKyAgICBpbWFnUDFbMF0gKj0gc2Nh
bGUgKiBpbWFnUDJbMF07CisKKyAgICAvLyBNdWx0aXBseSB0aGUgcmVzdCwgc2tpcHBpbmcgcGFj
a2VkIERDL055cXVpc3QgY29tcG9uZW50cworICAgIERTUFNwbGl0Q29tcGxleCBzYzEgPSBmcmFt
ZTEuZHNwU3BsaXRDb21wbGV4KCk7CisgICAgc2MxLnJlYWxwKys7CisgICAgc2MxLmltYWdwKys7
CisKKyAgICBEU1BTcGxpdENvbXBsZXggc2MyID0gZnJhbWUyLmRzcFNwbGl0Q29tcGxleCgpOwor
ICAgIHNjMi5yZWFscCsrOworICAgIHNjMi5pbWFncCsrOworCisgICAgdW5zaWduZWQgaGFsZlNp
emUgPSBtX0ZGVFNpemUgLyAyOworCisgICAgLy8gQ29tcGxleCBtdWx0aXBseQorICAgIHZEU1Bf
enZtdWwoJnNjMSwgMSwgJnNjMiwgMSwgJnNjMSwgMSwgaGFsZlNpemUgLSAxLCAxIC8qIG5vcm1h
bCBtdWx0aXBsaWNhdGlvbiAqLyk7CisKKyAgICAvLyBXZSd2ZSBwcmV2aW91c2x5IHNjYWxlZCB0
aGUgcGFja2VkIHBhcnQsIG5vdyBzY2FsZSB0aGUgcmVzdC4uLi4uCisgICAgdkRTUF92c211bChz
YzEucmVhbHAsIDEsICZzY2FsZSwgc2MxLnJlYWxwLCAxLCBoYWxmU2l6ZSAtIDEpOworICAgIHZE
U1BfdnNtdWwoc2MxLmltYWdwLCAxLCAmc2NhbGUsIHNjMS5pbWFncCwgMSwgaGFsZlNpemUgLSAx
KTsKK30KKwordm9pZCBGRlRGcmFtZTo6ZG9GRlQoZmxvYXQqIGRhdGEpCit7CisgICAgdkRTUF9j
dG96KChEU1BDb21wbGV4KilkYXRhLCAyLCAmbV9mcmFtZSwgMSwgbV9GRlRTaXplIC8gMik7Cisg
ICAgdkRTUF9mZnRfenJpcChtX0ZGVFNldHVwLCAmbV9mcmFtZSwgMSwgbV9sb2cyRkZUU2l6ZSwg
RkZUX0ZPUldBUkQpOworfQorCit2b2lkIEZGVEZyYW1lOjpkb0ludmVyc2VGRlQoZmxvYXQqIGRh
dGEpCit7CisgICAgdkRTUF9mZnRfenJpcChtX0ZGVFNldHVwLCAmbV9mcmFtZSwgMSwgbV9sb2cy
RkZUU2l6ZSwgRkZUX0lOVkVSU0UpOworICAgIHZEU1BfenRvYygmbV9mcmFtZSwgMSwgKERTUENv
bXBsZXgqKWRhdGEsIDIsIG1fRkZUU2l6ZSAvIDIpOworCisgICAgLy8gRG8gZmluYWwgc2NhbGlu
ZyBzbyB0aGF0IHggPT0gSUZGVChGRlQoeCkpCisgICAgZmxvYXQgc2NhbGUgPSAwLjVmIC8gbV9G
RlRTaXplOworICAgIHZEU1BfdnNtdWwoZGF0YSwgMSwgJnNjYWxlLCBkYXRhLCAxLCBtX0ZGVFNp
emUpOworfQorCitGRlRTZXR1cCBGRlRGcmFtZTo6ZmZ0U2V0dXBGb3JTaXplKHVuc2lnbmVkIGZm
dFNpemUpCit7CisgICAgaWYgKCFmZnRTZXR1cHMpIHsKKyAgICAgICAgZmZ0U2V0dXBzID0gKEZG
VFNldHVwKiltYWxsb2Moc2l6ZW9mKEZGVFNldHVwKSAqIGtNYXhGRlRQb3cyU2l6ZSk7CisgICAg
ICAgIG1lbXNldChmZnRTZXR1cHMsIDAsIHNpemVvZihGRlRTZXR1cCkgKiBrTWF4RkZUUG93MlNp
emUpOworICAgIH0KKworICAgIGludCBwb3cyc2l6ZSA9IHN0YXRpY19jYXN0PGludD4obG9nMihm
ZnRTaXplKSk7CisgICAgQVNTRVJUKHBvdzJzaXplIDwga01heEZGVFBvdzJTaXplKTsKKyAgICBp
ZiAoIWZmdFNldHVwc1twb3cyc2l6ZV0pCisgICAgICAgIGZmdFNldHVwc1twb3cyc2l6ZV0gPSB2
RFNQX2NyZWF0ZV9mZnRzZXR1cChwb3cyc2l6ZSwgRkZUX1JBRElYMik7CisKKyAgICByZXR1cm4g
ZmZ0U2V0dXBzW3BvdzJzaXplXTsKK30KKwordm9pZCBGRlRGcmFtZTo6Y2xlYW51cCgpCit7Cisg
ICAgaWYgKCFmZnRTZXR1cHMpCisgICAgICAgIHJldHVybjsKKworICAgIGZvciAoaW50IGkgPSAw
OyBpIDwga01heEZGVFBvdzJTaXplOyArK2kpIHsKKyAgICAgICAgaWYgKGZmdFNldHVwc1tpXSkK
KyAgICAgICAgICAgIHZEU1BfZGVzdHJveV9mZnRzZXR1cChmZnRTZXR1cHNbaV0pOworICAgIH0K
KworICAgIGZyZWUoZmZ0U2V0dXBzKTsKKyAgICBmZnRTZXR1cHMgPSAwOworfQorCitmbG9hdCog
RkZURnJhbWU6OnJlYWxEYXRhKCkgY29uc3QKK3sKKyAgICByZXR1cm4gbV9mcmFtZS5yZWFscDsK
K30KKyAgICAKK2Zsb2F0KiBGRlRGcmFtZTo6aW1hZ0RhdGEoKSBjb25zdAoreworICAgIHJldHVy
biBtX2ZyYW1lLmltYWdwOworfQorCit9IC8vIG5hbWVzcGFjZSBXZWJDb3JlCisKKyNlbmRpZiAv
LyBFTkFCTEUoV0VCX0FVRElPKQo=
</data>

          </attachment>
          <attachment
              isobsolete="0"
              ispatch="1"
              isprivate="0"
          >
            <attachid>66544</attachid>
            <date>2010-09-03 14:40:59 -0700</date>
            <delta_ts>2010-09-07 18:03:04 -0700</delta_ts>
            <desc>Patch</desc>
            <filename>bug-34827-20100903144058.patch</filename>
            <type>text/plain</type>
            <size>20458</size>
            <attacher name="Chris Rogers">crogers</attacher>
            
              <data encoding="base64">SW5kZXg6IFdlYkNvcmUvQ2hhbmdlTG9nCj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tIFdlYkNvcmUvQ2hhbmdlTG9n
CShyZXZpc2lvbiA2Njc3MSkKKysrIFdlYkNvcmUvQ2hhbmdlTG9nCSh3b3JraW5nIGNvcHkpCkBA
IC0xLDMgKzEsMzQgQEAKKzIwMTAtMDktMDMgIENocmlzIFJvZ2VycyAgPGNyb2dlcnNAZ29vZ2xl
LmNvbT4KKworICAgICAgICBSZXZpZXdlZCBieSBOT0JPRFkgKE9PUFMhKS4KKworICAgICAgICBh
dWRpbyBlbmdpbmU6IGFkZCBGRlRGcmFtZSBmaWxlcworICAgICAgICBodHRwczovL2J1Z3Mud2Vi
a2l0Lm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MzQ4MjcKKworICAgICAgICBObyBuZXcgdGVzdHMgc2lu
Y2UgYXVkaW8gQVBJIGlzIG5vdCB5ZXQgaW1wbGVtZW50ZWQuCisKKyAgICAgICAgKiBwbGF0Zm9y
bS9hdWRpby9GRlRGcmFtZS5jcHA6IEFkZGVkLgorICAgICAgICAoV2ViQ29yZTo6RkZURnJhbWU6
OmRvUGFkZGVkRkZUKToKKyAgICAgICAgKFdlYkNvcmU6OkZGVEZyYW1lOjpjcmVhdGVJbnRlcnBv
bGF0ZWRGcmFtZSk6CisgICAgICAgIChXZWJDb3JlOjpGRlRGcmFtZTo6aW50ZXJwb2xhdGVGcmVx
dWVuY3lDb21wb25lbnRzKToKKyAgICAgICAgKFdlYkNvcmU6OkZGVEZyYW1lOjpleHRyYWN0QXZl
cmFnZUdyb3VwRGVsYXkpOgorICAgICAgICAoV2ViQ29yZTo6RkZURnJhbWU6OmFkZENvbnN0YW50
R3JvdXBEZWxheSk6CisgICAgICAgIChXZWJDb3JlOjpGRlRGcmFtZTo6cHJpbnQpOgorICAgICAg
ICAqIHBsYXRmb3JtL2F1ZGlvL0ZGVEZyYW1lLmg6IEFkZGVkLgorICAgICAgICAoV2ViQ29yZTo6
RkZURnJhbWU6OmZmdFNpemUpOgorICAgICAgICAoV2ViQ29yZTo6RkZURnJhbWU6OmxvZzJGRlRT
aXplKToKKyAgICAgICAgKFdlYkNvcmU6OkZGVEZyYW1lOjpkc3BTcGxpdENvbXBsZXgpOgorICAg
ICAgICAqIHBsYXRmb3JtL2F1ZGlvL21hYy9GRlRGcmFtZU1hYy5jcHA6IEFkZGVkLgorICAgICAg
ICAoV2ViQ29yZTo6RkZURnJhbWU6OkZGVEZyYW1lKToKKyAgICAgICAgKFdlYkNvcmU6OkZGVEZy
YW1lOjp+RkZURnJhbWUpOgorICAgICAgICAoV2ViQ29yZTo6RkZURnJhbWU6Om11bHRpcGx5KToK
KyAgICAgICAgKFdlYkNvcmU6OkZGVEZyYW1lOjpkb0ZGVCk6CisgICAgICAgIChXZWJDb3JlOjpG
RlRGcmFtZTo6ZG9JbnZlcnNlRkZUKToKKyAgICAgICAgKFdlYkNvcmU6OkZGVEZyYW1lOjpmZnRT
ZXR1cEZvclNpemUpOgorICAgICAgICAoV2ViQ29yZTo6RkZURnJhbWU6OmNsZWFudXApOgorICAg
ICAgICAoV2ViQ29yZTo6RkZURnJhbWU6OnJlYWxEYXRhKToKKyAgICAgICAgKFdlYkNvcmU6OkZG
VEZyYW1lOjppbWFnRGF0YSk6CisKIDIwMTAtMDktMDMgIERvbWluaWMgQ29vbmV5ICA8ZG9taW5p
Y2NAZ29vZ2xlLmNvbT4KIAogICAgICAgICBSZXZpZXdlZCBieSBBZGFtIEJhcnRoLgpJbmRleDog
V2ViQ29yZS9wbGF0Zm9ybS9hdWRpby9GRlRGcmFtZS5jcHAKPT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0gV2ViQ29y
ZS9wbGF0Zm9ybS9hdWRpby9GRlRGcmFtZS5jcHAJKHJldmlzaW9uIDApCisrKyBXZWJDb3JlL3Bs
YXRmb3JtL2F1ZGlvL0ZGVEZyYW1lLmNwcAkocmV2aXNpb24gMCkKQEAgLTAsMCArMSwyNjkgQEAK
Ky8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTAgR29vZ2xlIEluYy4gQWxsIHJpZ2h0cyByZXNlcnZl
ZC4KKyAqCisgKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZv
cm1zLCB3aXRoIG9yIHdpdGhvdXQKKyAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92
aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucworICogYXJlIG1ldDoKKyAqCisgKiAx
LiAgUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBj
b3B5cmlnaHQKKyAqICAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUg
Zm9sbG93aW5nIGRpc2NsYWltZXIuCisgKiAyLiAgUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBm
b3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKKyAqICAgICBub3RpY2UsIHRo
aXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhl
CisgKiAgICAgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdp
dGggdGhlIGRpc3RyaWJ1dGlvbi4KKyAqIDMuICBOZWl0aGVyIHRoZSBuYW1lIG9mIEFwcGxlIENv
bXB1dGVyLCBJbmMuICgiQXBwbGUiKSBub3IgdGhlIG5hbWVzIG9mCisgKiAgICAgaXRzIGNvbnRy
aWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZl
ZAorICogICAgIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0
ZW4gcGVybWlzc2lvbi4KKyAqCisgKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIEFQUExF
IEFORCBJVFMgQ09OVFJJQlVUT1JTICJBUyBJUyIgQU5EIEFOWQorICogRVhQUkVTUyBPUiBJTVBM
SUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElF
RAorICogV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFS
VElDVUxBUiBQVVJQT1NFIEFSRQorICogRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgQVBQ
TEUgT1IgSVRTIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWQorICogRElSRUNULCBJTkRJ
UkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERB
TUFHRVMKKyAqIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0Yg
U1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsKKyAqIExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQ
Uk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAorICog
T04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBM
SUFCSUxJVFksIE9SIFRPUlQKKyAqIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0Up
IEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRgorICogVEhJUyBTT0ZUV0FSRSwg
RVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKyAqLwor
CisjaW5jbHVkZSAiY29uZmlnLmgiCisKKyNpZiBFTkFCTEUoV0VCX0FVRElPKQorCisjaW5jbHVk
ZSAiRkZURnJhbWUuaCIKKworI2luY2x1ZGUgPHd0Zi9Db21wbGV4Lmg+CisjaW5jbHVkZSA8d3Rm
L01hdGhFeHRyYXMuaD4KKyNpbmNsdWRlIDx3dGYvT3duUHRyLmg+CisKK25hbWVzcGFjZSBXZWJD
b3JlIHsKKwordm9pZCBGRlRGcmFtZTo6ZG9QYWRkZWRGRlQoZmxvYXQqIGRhdGEsIHNpemVfdCBk
YXRhU2l6ZSkKK3sKKyAgICAvLyBaZXJvLXBhZCB0aGUgaW1wdWxzZSByZXNwb25zZQorICAgIEF1
ZGlvRmxvYXRBcnJheSBwYWRkZWRSZXNwb25zZShmZnRTaXplKCkpOyAvLyB6ZXJvLWluaXRpYWxp
emVkCisgICAgcGFkZGVkUmVzcG9uc2UuY29weVRvUmFuZ2UoZGF0YSwgMCwgZGF0YVNpemUpOwor
CisgICAgLy8gR2V0IHRoZSBmcmVxdWVuY3ktZG9tYWluIHZlcnNpb24gb2YgcGFkZGVkIHJlc3Bv
bnNlCisgICAgZG9GRlQocGFkZGVkUmVzcG9uc2UuZGF0YSgpKTsKK30KKworUGFzc093blB0cjxG
RlRGcmFtZT4gRkZURnJhbWU6OmNyZWF0ZUludGVycG9sYXRlZEZyYW1lKGNvbnN0IEZGVEZyYW1l
JiBmcmFtZTEsIGNvbnN0IEZGVEZyYW1lJiBmcmFtZTIsIGRvdWJsZSB4KQoreworICAgIE93blB0
cjxGRlRGcmFtZT4gbmV3RnJhbWUgPSBhZG9wdFB0cihuZXcgRkZURnJhbWUoZnJhbWUxLmZmdFNp
emUoKSkpOworCisgICAgbmV3RnJhbWUtPmludGVycG9sYXRlRnJlcXVlbmN5Q29tcG9uZW50cyhm
cmFtZTEsIGZyYW1lMiwgeCk7CisKKyAgICAvLyBJbiB0aGUgdGltZS1kb21haW4sIHRoZSAybmQg
aGFsZiBvZiB0aGUgcmVzcG9uc2UgbXVzdCBiZSB6ZXJvLCB0byBhdm9pZCBjaXJjdWxhciBjb252
b2x1dGlvbiBhbGlhc2luZy4uLgorICAgIGludCBmZnRTaXplID0gbmV3RnJhbWUtPmZmdFNpemUo
KTsKKyAgICBBdWRpb0Zsb2F0QXJyYXkgYnVmZmVyKGZmdFNpemUpOworICAgIG5ld0ZyYW1lLT5k
b0ludmVyc2VGRlQoYnVmZmVyLmRhdGEoKSk7CisgICAgYnVmZmVyLnplcm9SYW5nZShmZnRTaXpl
IC8gMiwgZmZ0U2l6ZSk7CisKKyAgICAvLyBQdXQgYmFjayBpbnRvIGZyZXF1ZW5jeSBkb21haW4u
CisgICAgbmV3RnJhbWUtPmRvRkZUKGJ1ZmZlci5kYXRhKCkpOworCisgICAgcmV0dXJuIG5ld0Zy
YW1lLnJlbGVhc2UoKTsKK30KKwordm9pZCBGRlRGcmFtZTo6aW50ZXJwb2xhdGVGcmVxdWVuY3lD
b21wb25lbnRzKGNvbnN0IEZGVEZyYW1lJiBmcmFtZTEsIGNvbnN0IEZGVEZyYW1lJiBmcmFtZTIs
IGRvdWJsZSBpbnRlcnApCit7CisgICAgLy8gRklYTUUgOiB3aXRoIHNvbWUgd29yaywgdGhpcyBt
ZXRob2QgY291bGQgYmUgb3B0aW1pemVkCisKKyAgICBmbG9hdCogcmVhbFAgPSByZWFsRGF0YSgp
OworICAgIGZsb2F0KiBpbWFnUCA9IGltYWdEYXRhKCk7CisKKyAgICBjb25zdCBmbG9hdCogcmVh
bFAxID0gZnJhbWUxLnJlYWxEYXRhKCk7CisgICAgY29uc3QgZmxvYXQqIGltYWdQMSA9IGZyYW1l
MS5pbWFnRGF0YSgpOworICAgIGNvbnN0IGZsb2F0KiByZWFsUDIgPSBmcmFtZTIucmVhbERhdGEo
KTsKKyAgICBjb25zdCBmbG9hdCogaW1hZ1AyID0gZnJhbWUyLmltYWdEYXRhKCk7CisKKyAgICBt
X0ZGVFNpemUgPSBmcmFtZTEuZmZ0U2l6ZSgpOworICAgIG1fbG9nMkZGVFNpemUgPSBmcmFtZTEu
bG9nMkZGVFNpemUoKTsKKworICAgIGRvdWJsZSBzMWJhc2UgPSAoMS4wIC0gaW50ZXJwKTsKKyAg
ICBkb3VibGUgczJiYXNlID0gaW50ZXJwOworCisgICAgZG91YmxlIHBoYXNlQWNjdW0gPSAwLjA7
CisgICAgZG91YmxlIGxhc3RQaGFzZTEgPSAwLjA7CisgICAgZG91YmxlIGxhc3RQaGFzZTIgPSAw
LjA7CisKKyAgICByZWFsUFswXSA9IHN0YXRpY19jYXN0PGZsb2F0PihzMWJhc2UgKiByZWFsUDFb
MF0gKyBzMmJhc2UgKiByZWFsUDJbMF0pOworICAgIGltYWdQWzBdID0gc3RhdGljX2Nhc3Q8Zmxv
YXQ+KHMxYmFzZSAqIGltYWdQMVswXSArIHMyYmFzZSAqIGltYWdQMlswXSk7CisKKyAgICBpbnQg
biA9IG1fRkZUU2l6ZSAvIDI7CisKKyAgICBmb3IgKGludCBpID0gMTsgaSA8IG47ICsraSkgewor
ICAgICAgICBDb21wbGV4IGMxKHJlYWxQMVtpXSwgaW1hZ1AxW2ldKTsKKyAgICAgICAgQ29tcGxl
eCBjMihyZWFsUDJbaV0sIGltYWdQMltpXSk7CisKKyAgICAgICAgZG91YmxlIG1hZzEgPSBhYnMo
YzEpOworICAgICAgICBkb3VibGUgbWFnMiA9IGFicyhjMik7CisKKyAgICAgICAgLy8gSW50ZXJw
b2xhdGUgbWFnbml0dWRlcyBpbiBkZWNpYmVscworICAgICAgICBkb3VibGUgbWFnMWRiID0gMjAu
MCAqIGxvZzEwKG1hZzEpOworICAgICAgICBkb3VibGUgbWFnMmRiID0gMjAuMCAqIGxvZzEwKG1h
ZzIpOworCisgICAgICAgIGRvdWJsZSBzMSA9IHMxYmFzZTsKKyAgICAgICAgZG91YmxlIHMyID0g
czJiYXNlOworCisgICAgICAgIGRvdWJsZSBtYWdkYmRpZmYgPSBtYWcxZGIgLSBtYWcyZGI7CisK
KyAgICAgICAgLy8gRW1waXJpY2FsIHR3ZWFrIHRvIHJldGFpbiBoaWdoZXItZnJlcXVlbmN5IHpl
cm9lcworICAgICAgICBkb3VibGUgdGhyZXNob2xkID0gIChpID4gMTYpID8gNS4wIDogMi4wOwor
CisgICAgICAgIGlmIChtYWdkYmRpZmYgPCAtdGhyZXNob2xkICYmIG1hZzFkYiA8IDAuMCkgewor
ICAgICAgICAgICAgczEgPSBwb3coczEsIDAuNzUpOworICAgICAgICAgICAgczIgPSAxLjAgLSBz
MTsKKyAgICAgICAgfSBlbHNlIGlmIChtYWdkYmRpZmYgPiB0aHJlc2hvbGQgJiYgbWFnMmRiIDwg
MC4wKSB7CisgICAgICAgICAgICBzMiA9IHBvdyhzMiwgMC43NSk7CisgICAgICAgICAgICBzMSA9
IDEuMCAtIHMyOworICAgICAgICB9CisKKyAgICAgICAgLy8gQXZlcmFnZSBtYWduaXR1ZGUgYnkg
ZGVjaWJlbHMgaW5zdGVhZCBvZiBsaW5lYXJseQorICAgICAgICBkb3VibGUgbWFnZGIgPSBzMSAq
IG1hZzFkYiArIHMyICogbWFnMmRiOworICAgICAgICBkb3VibGUgbWFnID0gcG93KDEwLjAsIDAu
MDUgKiBtYWdkYik7CisKKyAgICAgICAgLy8gTm93LCBkZWFsIHdpdGggcGhhc2UKKyAgICAgICAg
ZG91YmxlIHBoYXNlMSA9IGFyZyhjMSk7CisgICAgICAgIGRvdWJsZSBwaGFzZTIgPSBhcmcoYzIp
OworCisgICAgICAgIGRvdWJsZSBkZWx0YVBoYXNlMSA9IHBoYXNlMSAtIGxhc3RQaGFzZTE7Cisg
ICAgICAgIGRvdWJsZSBkZWx0YVBoYXNlMiA9IHBoYXNlMiAtIGxhc3RQaGFzZTI7CisgICAgICAg
IGxhc3RQaGFzZTEgPSBwaGFzZTE7CisgICAgICAgIGxhc3RQaGFzZTIgPSBwaGFzZTI7CisKKyAg
ICAgICAgLy8gVW53cmFwIHBoYXNlIGRlbHRhcworICAgICAgICBpZiAoZGVsdGFQaGFzZTEgPiBN
X1BJKQorICAgICAgICAgICAgZGVsdGFQaGFzZTEgLT0gMi4wICogTV9QSTsKKyAgICAgICAgaWYg
KGRlbHRhUGhhc2UxIDwgLU1fUEkpCisgICAgICAgICAgICBkZWx0YVBoYXNlMSArPSAyLjAgKiBN
X1BJOworICAgICAgICBpZiAoZGVsdGFQaGFzZTIgPiBNX1BJKQorICAgICAgICAgICAgZGVsdGFQ
aGFzZTIgLT0gMi4wICogTV9QSTsKKyAgICAgICAgaWYgKGRlbHRhUGhhc2UyIDwgLU1fUEkpCisg
ICAgICAgICAgICBkZWx0YVBoYXNlMiArPSAyLjAgKiBNX1BJOworCisgICAgICAgIC8vIEJsZW5k
IGdyb3VwLWRlbGF5cworICAgICAgICBkb3VibGUgZGVsdGFQaGFzZUJsZW5kOworCisgICAgICAg
IGlmIChkZWx0YVBoYXNlMSAtIGRlbHRhUGhhc2UyID4gTV9QSSkKKyAgICAgICAgICAgIGRlbHRh
UGhhc2VCbGVuZCA9IHMxICogZGVsdGFQaGFzZTEgKyBzMiAqICgyLjAgKiBNX1BJICsgZGVsdGFQ
aGFzZTIpOworICAgICAgICBlbHNlIGlmIChkZWx0YVBoYXNlMiAtIGRlbHRhUGhhc2UxID4gTV9Q
SSkKKyAgICAgICAgICAgIGRlbHRhUGhhc2VCbGVuZCA9IHMxICogKDIuMCAqIE1fUEkgKyBkZWx0
YVBoYXNlMSkgKyBzMiAqIGRlbHRhUGhhc2UyOworICAgICAgICBlbHNlCisgICAgICAgICAgICBk
ZWx0YVBoYXNlQmxlbmQgPSBzMSAqIGRlbHRhUGhhc2UxICsgczIgKiBkZWx0YVBoYXNlMjsKKwor
ICAgICAgICBwaGFzZUFjY3VtICs9IGRlbHRhUGhhc2VCbGVuZDsKKworICAgICAgICAvLyBVbndy
YXAKKyAgICAgICAgaWYgKHBoYXNlQWNjdW0gPiBNX1BJKQorICAgICAgICAgICAgcGhhc2VBY2N1
bSAtPSAyLjAgKiBNX1BJOworICAgICAgICBpZiAocGhhc2VBY2N1bSA8IC1NX1BJKQorICAgICAg
ICAgICAgcGhhc2VBY2N1bSArPSAyLjAgKiBNX1BJOworCisgICAgICAgIENvbXBsZXggYyA9IGNv
bXBsZXhGcm9tTWFnbml0dWRlUGhhc2UobWFnLCBwaGFzZUFjY3VtKTsKKworICAgICAgICByZWFs
UFtpXSA9IHN0YXRpY19jYXN0PGZsb2F0PihjLnJlYWwoKSk7CisgICAgICAgIGltYWdQW2ldID0g
c3RhdGljX2Nhc3Q8ZmxvYXQ+KGMuaW1hZygpKTsKKyAgICB9Cit9CisKK2RvdWJsZSBGRlRGcmFt
ZTo6ZXh0cmFjdEF2ZXJhZ2VHcm91cERlbGF5KCkKK3sKKyAgICBmbG9hdCogcmVhbFAgPSByZWFs
RGF0YSgpOworICAgIGZsb2F0KiBpbWFnUCA9IGltYWdEYXRhKCk7CisKKyAgICBkb3VibGUgYXZl
U3VtID0gMC4wOworICAgIGRvdWJsZSB3ZWlnaHRTdW0gPSAwLjA7CisgICAgZG91YmxlIGxhc3RQ
aGFzZSA9IDAuMDsKKworICAgIGludCBoYWxmU2l6ZSA9IGZmdFNpemUoKSAvIDI7CisKKyAgICBj
b25zdCBkb3VibGUga1NhbXBsZVBoYXNlRGVsYXkgPSAoMi4wICogTV9QSSkgLyBkb3VibGUoZmZ0
U2l6ZSgpKTsKKworICAgIC8vIENhbGN1bGF0ZSB3ZWlnaHRlZCBhdmVyYWdlIGdyb3VwIGRlbGF5
CisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBoYWxmU2l6ZTsgaSsrKSB7CisgICAgICAgIENvbXBs
ZXggYyhyZWFsUFtpXSwgaW1hZ1BbaV0pOworICAgICAgICBkb3VibGUgbWFnID0gYWJzKGMpOwor
ICAgICAgICBkb3VibGUgcGhhc2UgPSBhcmcoYyk7CisKKyAgICAgICAgZG91YmxlIGRlbHRhUGhh
c2UgPSBwaGFzZSAtIGxhc3RQaGFzZTsKKyAgICAgICAgbGFzdFBoYXNlID0gcGhhc2U7CisKKyAg
ICAgICAgLy8gVW53cmFwCisgICAgICAgIGlmIChkZWx0YVBoYXNlIDwgLU1fUEkpCisgICAgICAg
ICAgICBkZWx0YVBoYXNlICs9IDIuMCAqIE1fUEk7CisgICAgICAgIGlmIChkZWx0YVBoYXNlID4g
TV9QSSkKKyAgICAgICAgICAgIGRlbHRhUGhhc2UgLT0gMi4wICogTV9QSTsKKworICAgICAgICBh
dmVTdW0gKz0gbWFnICogZGVsdGFQaGFzZTsKKyAgICAgICAgd2VpZ2h0U3VtICs9IG1hZzsKKyAg
ICB9CisKKyAgICAvLyBOb3RlIGhvdyB3ZSBpbnZlcnQgdGhlIHBoYXNlIGRlbHRhIHdydCBmcmVx
dWVuY3kgc2luY2UgdGhpcyBpcyBob3cgZ3JvdXAgZGVsYXkgaXMgZGVmaW5lZAorICAgIGRvdWJs
ZSBhdmUgPSBhdmVTdW0gLyB3ZWlnaHRTdW07CisgICAgZG91YmxlIGF2ZVNhbXBsZURlbGF5ID0g
LWF2ZSAvIGtTYW1wbGVQaGFzZURlbGF5OworCisgICAgLy8gTGVhdmUgMjAgc2FtcGxlIGhlYWRy
b29tIChmb3IgbGVhZGluZyBlZGdlIG9mIGltcHVsc2UpCisgICAgaWYgKGF2ZVNhbXBsZURlbGF5
ID4gMjAuMCkKKyAgICAgICAgYXZlU2FtcGxlRGVsYXkgLT0gMjAuMDsKKworICAgIC8vIFJlbW92
ZSBhdmVyYWdlIGdyb3VwIGRlbGF5IChtaW51cyAyMCBzYW1wbGVzIGZvciBoZWFkcm9vbSkKKyAg
ICBhZGRDb25zdGFudEdyb3VwRGVsYXkoLWF2ZVNhbXBsZURlbGF5KTsKKworICAgIC8vIFJlbW92
ZSBEQyBvZmZzZXQKKyAgICByZWFsUFswXSA9IDAuMGY7CisKKyAgICByZXR1cm4gYXZlU2FtcGxl
RGVsYXk7Cit9CisKK3ZvaWQgRkZURnJhbWU6OmFkZENvbnN0YW50R3JvdXBEZWxheShkb3VibGUg
c2FtcGxlRnJhbWVEZWxheSkKK3sKKyAgICBpbnQgaGFsZlNpemUgPSBmZnRTaXplKCkgLyAyOwor
CisgICAgZmxvYXQqIHJlYWxQID0gcmVhbERhdGEoKTsKKyAgICBmbG9hdCogaW1hZ1AgPSBpbWFn
RGF0YSgpOworCisgICAgY29uc3QgZG91YmxlIGtTYW1wbGVQaGFzZURlbGF5ID0gKDIuMCAqIE1f
UEkpIC8gZG91YmxlKGZmdFNpemUoKSk7CisKKyAgICBkb3VibGUgcGhhc2VBZGogPSAtc2FtcGxl
RnJhbWVEZWxheSAqIGtTYW1wbGVQaGFzZURlbGF5OworCisgICAgLy8gQWRkIGNvbnN0YW50IGdy
b3VwIGRlbGF5CisgICAgZm9yIChpbnQgaSA9IDE7IGkgPCBoYWxmU2l6ZTsgaSsrKSB7CisgICAg
ICAgIENvbXBsZXggYyhyZWFsUFtpXSwgaW1hZ1BbaV0pOworICAgICAgICBkb3VibGUgbWFnID0g
YWJzKGMpOworICAgICAgICBkb3VibGUgcGhhc2UgPSBhcmcoYyk7CisKKyAgICAgICAgcGhhc2Ug
Kz0gaSAqIHBoYXNlQWRqOworCisgICAgICAgIENvbXBsZXggYzIgPSBjb21wbGV4RnJvbU1hZ25p
dHVkZVBoYXNlKG1hZywgcGhhc2UpOworCisgICAgICAgIHJlYWxQW2ldID0gc3RhdGljX2Nhc3Q8
ZmxvYXQ+KGMyLnJlYWwoKSk7CisgICAgICAgIGltYWdQW2ldID0gc3RhdGljX2Nhc3Q8ZmxvYXQ+
KGMyLmltYWcoKSk7CisgICAgfQorfQorCisjaWZuZGVmIE5ERUJVRwordm9pZCBGRlRGcmFtZTo6
cHJpbnQoKQoreworICAgIEZGVEZyYW1lJiBmcmFtZSA9ICp0aGlzOworICAgIGZsb2F0KiByZWFs
UCA9IGZyYW1lLnJlYWxEYXRhKCk7CisgICAgZmxvYXQqIGltYWdQID0gZnJhbWUuaW1hZ0RhdGEo
KTsKKyAgICBwcmludGYoIioqKiogXG4iKTsKKyAgICBwcmludGYoIkRDID0gJWYgOiBueXF1aXN0
ID0gJWZcbiIsIHJlYWxQWzBdLCBpbWFnUFswXSk7CisKKyAgICBpbnQgbiA9IG1fRkZUU2l6ZSAv
IDI7CisKKyAgICBmb3IgKGludCBpID0gMTsgaSA8IG47IGkrKykgeworICAgICAgICBkb3VibGUg
bWFnID0gc3FydChyZWFsUFtpXSAqIHJlYWxQW2ldICsgaW1hZ1BbaV0gKiBpbWFnUFtpXSk7Cisg
ICAgICAgIGRvdWJsZSBwaGFzZSA9IGF0YW4yKHJlYWxQW2ldLCBpbWFnUFtpXSk7CisKKyAgICAg
ICAgcHJpbnRmKCJbJWRdICglZiAlZilcbiIsIGksIG1hZywgcGhhc2UpOworICAgIH0KKyAgICBw
cmludGYoIioqKipcbiIpOworfQorI2VuZGlmIC8vIE5ERUJVRworCit9IC8vIG5hbWVzcGFjZSBX
ZWJDb3JlCisKKyNlbmRpZiAvLyBFTkFCTEUoV0VCX0FVRElPKQpJbmRleDogV2ViQ29yZS9wbGF0
Zm9ybS9hdWRpby9GRlRGcmFtZS5oCj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tIFdlYkNvcmUvcGxhdGZvcm0vYXVk
aW8vRkZURnJhbWUuaAkocmV2aXNpb24gMCkKKysrIFdlYkNvcmUvcGxhdGZvcm0vYXVkaW8vRkZU
RnJhbWUuaAkocmV2aXNpb24gMCkKQEAgLTAsMCArMSwxMDIgQEAKKy8qCisgKiBDb3B5cmlnaHQg
KEMpIDIwMTAgR29vZ2xlIEluYy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBSZWRpc3Ry
aWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhv
dXQKKyAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xs
b3dpbmcgY29uZGl0aW9ucworICogYXJlIG1ldDoKKyAqCisgKiAxLiAgUmVkaXN0cmlidXRpb25z
IG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKyAqICAgICBu
b3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWlt
ZXIuCisgKiAyLiAgUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNl
IHRoZSBhYm92ZSBjb3B5cmlnaHQKKyAqICAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRp
b25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlCisgKiAgICAgZG9jdW1lbnRh
dGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlv
bi4KKyAqIDMuICBOZWl0aGVyIHRoZSBuYW1lIG9mIEFwcGxlIENvbXB1dGVyLCBJbmMuICgiQXBw
bGUiKSBub3IgdGhlIG5hbWVzIG9mCisgKiAgICAgaXRzIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNl
ZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZAorICogICAgIGZyb20gdGhp
cyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KKyAq
CisgKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIEFQUExFIEFORCBJVFMgQ09OVFJJQlVU
T1JTICJBUyBJUyIgQU5EIEFOWQorICogRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElO
Q0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRAorICogV0FSUkFOVElFUyBP
RiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFS
RQorICogRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgQVBQTEUgT1IgSVRTIENPTlRSSUJV
VE9SUyBCRSBMSUFCTEUgRk9SIEFOWQorICogRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwg
U1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMKKyAqIChJTkNMVURJ
TkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBP
UiBTRVJWSUNFUzsKKyAqIExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVT
UyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORAorICogT04gQU5ZIFRIRU9SWSBPRiBM
SUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQK
KyAqIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdB
WSBPVVQgT0YgVEhFIFVTRSBPRgorICogVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9G
IFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KKyAqLworCisjaWZuZGVmIEZGVEZyYW1l
X2gKKyNkZWZpbmUgRkZURnJhbWVfaAorCisjaW5jbHVkZSAiQXVkaW9BcnJheS5oIgorCisjaWYg
T1MoREFSV0lOKQorI2luY2x1ZGUgPEFjY2VsZXJhdGUvQWNjZWxlcmF0ZS5oPgorI2VuZGlmCisK
KyNpbmNsdWRlIDx3dGYvUGFzc093blB0ci5oPgorI2luY2x1ZGUgPHd0Zi9QbGF0Zm9ybS5oPgor
CituYW1lc3BhY2UgV2ViQ29yZSB7CisKKy8vIERlZmluZXMgdGhlIGludGVyZmFjZSBmb3IgYW4g
IkZGVCBmcmFtZSIsIGFuIG9iamVjdCB3aGljaCBpcyBhYmxlIHRvIHBlcmZvcm0gYSBmb3J3YXJk
CisvLyBhbmQgcmV2ZXJzZSBGRlQsIGludGVybmFsbHkgc3RvcmluZyB0aGUgcmVzdWx0YW50IGZy
ZXF1ZW5jeS1kb21haW4gZGF0YS4KKworY2xhc3MgRkZURnJhbWUgeworcHVibGljOgorICAgIC8v
IFRoZSBjb25zdHJ1Y3RvcnMsIGRlc3RydWN0b3IsIGFuZCBtZXRob2RzIHVwIHRvIHRoZSBDUk9T
Uy1QTEFURk9STSBzZWN0aW9uIGhhdmUgcGxhdGZvcm0tZGVwZW5kZW50IGltcGxlbWVudGF0aW9u
cy4KKworICAgIEZGVEZyYW1lKHVuc2lnbmVkIGZmdFNpemUpOworICAgIEZGVEZyYW1lKCk7IC8v
IGNyZWF0ZXMgYSBibGFuay9lbXB0eSBmcmFtZSBmb3IgbGF0ZXIgdXNlIHdpdGggY3JlYXRlSW50
ZXJwb2xhdGVkRnJhbWUoKQorICAgIEZGVEZyYW1lKGNvbnN0IEZGVEZyYW1lJiBmcmFtZSk7Cisg
ICAgfkZGVEZyYW1lKCk7CisKKyAgICBzdGF0aWMgdm9pZCBjbGVhbnVwKCk7CisgICAgdm9pZCBk
b0ZGVChmbG9hdCogZGF0YSk7CisgICAgdm9pZCBkb0ludmVyc2VGRlQoZmxvYXQqIGRhdGEpOwor
ICAgIHZvaWQgbXVsdGlwbHkoY29uc3QgRkZURnJhbWUmIGZyYW1lKTsgLy8gbXVsdGlwbGllcyBv
dXJzZWxmIHdpdGggZnJhbWUgOiBlZmZlY3RpdmVseSBvcGVyYXRvcio9KCkKKworICAgIGZsb2F0
KiByZWFsRGF0YSgpIGNvbnN0OworICAgIGZsb2F0KiBpbWFnRGF0YSgpIGNvbnN0OworCisgICAg
dm9pZCBwcmludCgpOyAvLyBmb3IgZGVidWdnaW5nCisKKyAgICAvLyBDUk9TUy1QTEFURk9STQor
ICAgIC8vIFRoZSByZW1haW5pbmcgcHVibGljIG1ldGhvZHMgaGF2ZSBjcm9zcy1wbGF0Zm9ybSBp
bXBsZW1lbnRhdGlvbnM6CisKKyAgICAvLyBJbnRlcnBvbGF0ZXMgZnJvbSBmcmFtZTEgLT4gZnJh
bWUyIGFzIHggZ29lcyBmcm9tIDAuMCAtPiAxLjAKKyAgICBzdGF0aWMgUGFzc093blB0cjxGRlRG
cmFtZT4gY3JlYXRlSW50ZXJwb2xhdGVkRnJhbWUoY29uc3QgRkZURnJhbWUmIGZyYW1lMSwgY29u
c3QgRkZURnJhbWUmIGZyYW1lMiwgZG91YmxlIHgpOworCisgICAgdm9pZCBkb1BhZGRlZEZGVChm
bG9hdCogZGF0YSwgc2l6ZV90IGRhdGFTaXplKTsgLy8gemVyby1wYWRkaW5nIHdpdGggZGF0YVNp
emUgPD0gZmZ0U2l6ZQorICAgIGRvdWJsZSBleHRyYWN0QXZlcmFnZUdyb3VwRGVsYXkoKTsKKyAg
ICB2b2lkIGFkZENvbnN0YW50R3JvdXBEZWxheShkb3VibGUgc2FtcGxlRnJhbWVEZWxheSk7CisK
KyAgICB1bnNpZ25lZCBmZnRTaXplKCkgY29uc3QgeyByZXR1cm4gbV9GRlRTaXplOyB9CisgICAg
dW5zaWduZWQgbG9nMkZGVFNpemUoKSBjb25zdCB7IHJldHVybiBtX2xvZzJGRlRTaXplOyB9CisK
K3ByaXZhdGU6CisgICAgdW5zaWduZWQgbV9GRlRTaXplOworICAgIHVuc2lnbmVkIG1fbG9nMkZG
VFNpemU7CisKKyAgICB2b2lkIGludGVycG9sYXRlRnJlcXVlbmN5Q29tcG9uZW50cyhjb25zdCBG
RlRGcmFtZSYgZnJhbWUxLCBjb25zdCBGRlRGcmFtZSYgZnJhbWUyLCBkb3VibGUgeCk7CisKKyNp
ZiBPUyhEQVJXSU4pCisgICAgRFNQU3BsaXRDb21wbGV4JiBkc3BTcGxpdENvbXBsZXgoKSB7IHJl
dHVybiBtX2ZyYW1lOyB9CisgICAgRFNQU3BsaXRDb21wbGV4IGRzcFNwbGl0Q29tcGxleCgpIGNv
bnN0IHsgcmV0dXJuIG1fZnJhbWU7IH0KKworICAgIHN0YXRpYyBGRlRTZXR1cCBmZnRTZXR1cEZv
clNpemUodW5zaWduZWQgZmZ0U2l6ZSk7CisKKyAgICBzdGF0aWMgRkZUU2V0dXAqIGZmdFNldHVw
czsKKworICAgIEZGVFNldHVwIG1fRkZUU2V0dXA7CisKKyAgICBEU1BTcGxpdENvbXBsZXggbV9m
cmFtZTsKKyAgICBBdWRpb0Zsb2F0QXJyYXkgbV9yZWFsRGF0YTsKKyAgICBBdWRpb0Zsb2F0QXJy
YXkgbV9pbWFnRGF0YTsKKyNlbmRpZiAvLyBPUyhEQVJXSU4pCit9OworCit9IC8vIG5hbWVzcGFj
ZSBXZWJDb3JlCisKKyNlbmRpZiAvLyBGRlRGcmFtZV9oCkluZGV4OiBXZWJDb3JlL3BsYXRmb3Jt
L2F1ZGlvL21hYy9GRlRGcmFtZU1hYy5jcHAKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0gV2ViQ29yZS9wbGF0Zm9y
bS9hdWRpby9tYWMvRkZURnJhbWVNYWMuY3BwCShyZXZpc2lvbiAwKQorKysgV2ViQ29yZS9wbGF0
Zm9ybS9hdWRpby9tYWMvRkZURnJhbWVNYWMuY3BwCShyZXZpc2lvbiAwKQpAQCAtMCwwICsxLDE5
MSBAQAorLyoKKyAqIENvcHlyaWdodCAoQykgMjAxMCBHb29nbGUgSW5jLiBBbGwgcmlnaHRzIHJl
c2VydmVkLgorICoKKyAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5h
cnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVk
IHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCisgKiBhcmUgbWV0OgorICoK
KyAqIDEuICBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFi
b3ZlIGNvcHlyaWdodAorICogICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5k
IHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KKyAqIDIuICBSZWRpc3RyaWJ1dGlvbnMgaW4gYmlu
YXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAorICogICAgIG5vdGlj
ZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBp
biB0aGUKKyAqICAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlk
ZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgorICogMy4gIE5laXRoZXIgdGhlIG5hbWUgb2YgQXBw
bGUgQ29tcHV0ZXIsIEluYy4gKCJBcHBsZSIpIG5vciB0aGUgbmFtZXMgb2YKKyAqICAgICBpdHMg
Y29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBk
ZXJpdmVkCisgKiAgICAgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Ig
d3JpdHRlbiBwZXJtaXNzaW9uLgorICoKKyAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkg
QVBQTEUgQU5EIElUUyBDT05UUklCVVRPUlMgIkFTIElTIiBBTkQgQU5ZCisgKiBFWFBSRVNTIE9S
IElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJ
TVBMSUVECisgKiBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1Ig
QSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCisgKiBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFM
TCBBUFBMRSBPUiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZCisgKiBESVJFQ1Qs
IElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJ
QUwgREFNQUdFUworICogKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVO
VCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOworICogTE9TUyBPRiBVU0UsIERBVEEs
IE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5E
CisgKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RS
SUNUIExJQUJJTElUWSwgT1IgVE9SVAorICogKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVS
V0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GCisgKiBUSElTIFNPRlRX
QVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgor
ICovCisKKy8vIE1hYyBPUyBYIC0gc3BlY2lmaWMgRkZURnJhbWUgaW1wbGVtZW50YXRpb24KKwor
I2luY2x1ZGUgImNvbmZpZy5oIgorCisjaWYgRU5BQkxFKFdFQl9BVURJTykKKworI2luY2x1ZGUg
IkZGVEZyYW1lLmgiCisKK25hbWVzcGFjZSBXZWJDb3JlIHsKKworY29uc3QgaW50IGtNYXhGRlRQ
b3cyU2l6ZSA9IDI0OworCitGRlRTZXR1cCogRkZURnJhbWU6OmZmdFNldHVwcyA9IDA7CisKKy8v
IE5vcm1hbCBjb25zdHJ1Y3RvcjogYWxsb2NhdGVzIGZvciBhIGdpdmVuIGZmdFNpemUKK0ZGVEZy
YW1lOjpGRlRGcmFtZSh1bnNpZ25lZCBmZnRTaXplKQorICAgIDogbV9yZWFsRGF0YShmZnRTaXpl
KQorICAgICwgbV9pbWFnRGF0YShmZnRTaXplKQoreworICAgIG1fRkZUU2l6ZSA9IGZmdFNpemU7
CisgICAgbV9sb2cyRkZUU2l6ZSA9IHN0YXRpY19jYXN0PHVuc2lnbmVkPihsb2cyKGZmdFNpemUp
KTsKKworICAgIC8vIFdlIG9ubHkgYWxsb3cgcG93ZXIgb2YgdHdvCisgICAgQVNTRVJUKDFVTCA8
PCBtX2xvZzJGRlRTaXplID09IG1fRkZUU2l6ZSk7CisKKyAgICAvLyBMYXppbHkgY3JlYXRlIGFu
ZCBzaGFyZSBmZnRTZXR1cCB3aXRoIG90aGVyIGZyYW1lcworICAgIG1fRkZUU2V0dXAgPSBmZnRT
ZXR1cEZvclNpemUoZmZ0U2l6ZSk7CisKKyAgICAvLyBTZXR1cCBmcmFtZSBkYXRhCisgICAgbV9m
cmFtZS5yZWFscCA9IG1fcmVhbERhdGEuZGF0YSgpOworICAgIG1fZnJhbWUuaW1hZ3AgPSBtX2lt
YWdEYXRhLmRhdGEoKTsKK30KKworLy8gQ3JlYXRlcyBhIGJsYW5rL2VtcHR5IGZyYW1lIChpbnRl
cnBvbGF0ZSgpIG11c3QgbGF0ZXIgYmUgY2FsbGVkKQorRkZURnJhbWU6OkZGVEZyYW1lKCkKKyAg
ICA6IG1fcmVhbERhdGEoMCkKKyAgICAsIG1faW1hZ0RhdGEoMCkKK3sKKyAgICAvLyBMYXRlciB3
aWxsIGJlIHNldCB0byBjb3JyZWN0IHZhbHVlcyB3aGVuIGludGVycG9sYXRlKCkgaXMgY2FsbGVk
CisgICAgbV9mcmFtZS5yZWFscCA9IDA7CisgICAgbV9mcmFtZS5pbWFncCA9IDA7CisKKyAgICBt
X0ZGVFNpemUgPSAwOworICAgIG1fbG9nMkZGVFNpemUgPSAwOworfQorCisvLyBDb3B5IGNvbnN0
cnVjdG9yCitGRlRGcmFtZTo6RkZURnJhbWUoY29uc3QgRkZURnJhbWUmIGZyYW1lKQorICAgIDog
bV9GRlRTaXplKGZyYW1lLm1fRkZUU2l6ZSkKKyAgICAsIG1fbG9nMkZGVFNpemUoZnJhbWUubV9s
b2cyRkZUU2l6ZSkKKyAgICAsIG1fRkZUU2V0dXAoZnJhbWUubV9GRlRTZXR1cCkKKyAgICAsIG1f
cmVhbERhdGEoZnJhbWUubV9GRlRTaXplKQorICAgICwgbV9pbWFnRGF0YShmcmFtZS5tX0ZGVFNp
emUpCit7CisgICAgLy8gU2V0dXAgZnJhbWUgZGF0YQorICAgIG1fZnJhbWUucmVhbHAgPSBtX3Jl
YWxEYXRhLmRhdGEoKTsKKyAgICBtX2ZyYW1lLmltYWdwID0gbV9pbWFnRGF0YS5kYXRhKCk7CisK
KyAgICAvLyBDb3B5L3NldHVwIGZyYW1lIGRhdGEKKyAgICB1bnNpZ25lZCBuYnl0ZXMgPSBzaXpl
b2YoZmxvYXQpICogbV9GRlRTaXplOworICAgIG1lbWNweShyZWFsRGF0YSgpLCBmcmFtZS5tX2Zy
YW1lLnJlYWxwLCBuYnl0ZXMpOworICAgIG1lbWNweShpbWFnRGF0YSgpLCBmcmFtZS5tX2ZyYW1l
LmltYWdwLCBuYnl0ZXMpOworfQorCitGRlRGcmFtZTo6fkZGVEZyYW1lKCkKK3sKK30KKwordm9p
ZCBGRlRGcmFtZTo6bXVsdGlwbHkoY29uc3QgRkZURnJhbWUmIGZyYW1lKQoreworICAgIEZGVEZy
YW1lJiBmcmFtZTEgPSAqdGhpczsKKyAgICBjb25zdCBGRlRGcmFtZSYgZnJhbWUyID0gZnJhbWU7
CisKKyAgICBmbG9hdCogcmVhbFAxID0gZnJhbWUxLnJlYWxEYXRhKCk7CisgICAgZmxvYXQqIGlt
YWdQMSA9IGZyYW1lMS5pbWFnRGF0YSgpOworICAgIGNvbnN0IGZsb2F0KiByZWFsUDIgPSBmcmFt
ZTIucmVhbERhdGEoKTsKKyAgICBjb25zdCBmbG9hdCogaW1hZ1AyID0gZnJhbWUyLmltYWdEYXRh
KCk7CisKKyAgICAvLyBTY2FsZSBhY2NvdW50cyBmb3IgdmVjTGliJ3MgcGVjdWxpYXIgc2NhbGlu
ZworICAgIC8vIFRoaXMgZW5zdXJlcyB0aGUgcmlnaHQgc2NhbGluZyBhbGwgdGhlIHdheSBiYWNr
IHRvIGludmVyc2UgRkZUCisgICAgZmxvYXQgc2NhbGUgPSAwLjVmOworCisgICAgLy8gTXVsdGlw
bHkgcGFja2VkIERDL255cXVpc3QgY29tcG9uZW50CisgICAgcmVhbFAxWzBdICo9IHNjYWxlICog
cmVhbFAyWzBdOworICAgIGltYWdQMVswXSAqPSBzY2FsZSAqIGltYWdQMlswXTsKKworICAgIC8v
IE11bHRpcGx5IHRoZSByZXN0LCBza2lwcGluZyBwYWNrZWQgREMvTnlxdWlzdCBjb21wb25lbnRz
CisgICAgRFNQU3BsaXRDb21wbGV4IHNjMSA9IGZyYW1lMS5kc3BTcGxpdENvbXBsZXgoKTsKKyAg
ICBzYzEucmVhbHArKzsKKyAgICBzYzEuaW1hZ3ArKzsKKworICAgIERTUFNwbGl0Q29tcGxleCBz
YzIgPSBmcmFtZTIuZHNwU3BsaXRDb21wbGV4KCk7CisgICAgc2MyLnJlYWxwKys7CisgICAgc2My
LmltYWdwKys7CisKKyAgICB1bnNpZ25lZCBoYWxmU2l6ZSA9IG1fRkZUU2l6ZSAvIDI7CisKKyAg
ICAvLyBDb21wbGV4IG11bHRpcGx5CisgICAgdkRTUF96dm11bCgmc2MxLCAxLCAmc2MyLCAxLCAm
c2MxLCAxLCBoYWxmU2l6ZSAtIDEsIDEgLyogbm9ybWFsIG11bHRpcGxpY2F0aW9uICovKTsKKwor
ICAgIC8vIFdlJ3ZlIHByZXZpb3VzbHkgc2NhbGVkIHRoZSBwYWNrZWQgcGFydCwgbm93IHNjYWxl
IHRoZSByZXN0Li4uLi4KKyAgICB2RFNQX3ZzbXVsKHNjMS5yZWFscCwgMSwgJnNjYWxlLCBzYzEu
cmVhbHAsIDEsIGhhbGZTaXplIC0gMSk7CisgICAgdkRTUF92c211bChzYzEuaW1hZ3AsIDEsICZz
Y2FsZSwgc2MxLmltYWdwLCAxLCBoYWxmU2l6ZSAtIDEpOworfQorCit2b2lkIEZGVEZyYW1lOjpk
b0ZGVChmbG9hdCogZGF0YSkKK3sKKyAgICB2RFNQX2N0b3ooKERTUENvbXBsZXgqKWRhdGEsIDIs
ICZtX2ZyYW1lLCAxLCBtX0ZGVFNpemUgLyAyKTsKKyAgICB2RFNQX2ZmdF96cmlwKG1fRkZUU2V0
dXAsICZtX2ZyYW1lLCAxLCBtX2xvZzJGRlRTaXplLCBGRlRfRk9SV0FSRCk7Cit9CisKK3ZvaWQg
RkZURnJhbWU6OmRvSW52ZXJzZUZGVChmbG9hdCogZGF0YSkKK3sKKyAgICB2RFNQX2ZmdF96cmlw
KG1fRkZUU2V0dXAsICZtX2ZyYW1lLCAxLCBtX2xvZzJGRlRTaXplLCBGRlRfSU5WRVJTRSk7Cisg
ICAgdkRTUF96dG9jKCZtX2ZyYW1lLCAxLCAoRFNQQ29tcGxleCopZGF0YSwgMiwgbV9GRlRTaXpl
IC8gMik7CisKKyAgICAvLyBEbyBmaW5hbCBzY2FsaW5nIHNvIHRoYXQgeCA9PSBJRkZUKEZGVCh4
KSkKKyAgICBmbG9hdCBzY2FsZSA9IDAuNWYgLyBtX0ZGVFNpemU7CisgICAgdkRTUF92c211bChk
YXRhLCAxLCAmc2NhbGUsIGRhdGEsIDEsIG1fRkZUU2l6ZSk7Cit9CisKK0ZGVFNldHVwIEZGVEZy
YW1lOjpmZnRTZXR1cEZvclNpemUodW5zaWduZWQgZmZ0U2l6ZSkKK3sKKyAgICBpZiAoIWZmdFNl
dHVwcykgeworICAgICAgICBmZnRTZXR1cHMgPSAoRkZUU2V0dXAqKW1hbGxvYyhzaXplb2YoRkZU
U2V0dXApICoga01heEZGVFBvdzJTaXplKTsKKyAgICAgICAgbWVtc2V0KGZmdFNldHVwcywgMCwg
c2l6ZW9mKEZGVFNldHVwKSAqIGtNYXhGRlRQb3cyU2l6ZSk7CisgICAgfQorCisgICAgaW50IHBv
dzJzaXplID0gc3RhdGljX2Nhc3Q8aW50Pihsb2cyKGZmdFNpemUpKTsKKyAgICBBU1NFUlQocG93
MnNpemUgPCBrTWF4RkZUUG93MlNpemUpOworICAgIGlmICghZmZ0U2V0dXBzW3BvdzJzaXplXSkK
KyAgICAgICAgZmZ0U2V0dXBzW3BvdzJzaXplXSA9IHZEU1BfY3JlYXRlX2ZmdHNldHVwKHBvdzJz
aXplLCBGRlRfUkFESVgyKTsKKworICAgIHJldHVybiBmZnRTZXR1cHNbcG93MnNpemVdOworfQor
Cit2b2lkIEZGVEZyYW1lOjpjbGVhbnVwKCkKK3sKKyAgICBpZiAoIWZmdFNldHVwcykKKyAgICAg
ICAgcmV0dXJuOworCisgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBrTWF4RkZUUG93MlNpemU7ICsr
aSkgeworICAgICAgICBpZiAoZmZ0U2V0dXBzW2ldKQorICAgICAgICAgICAgdkRTUF9kZXN0cm95
X2ZmdHNldHVwKGZmdFNldHVwc1tpXSk7CisgICAgfQorCisgICAgZnJlZShmZnRTZXR1cHMpOwor
ICAgIGZmdFNldHVwcyA9IDA7Cit9CisKK2Zsb2F0KiBGRlRGcmFtZTo6cmVhbERhdGEoKSBjb25z
dAoreworICAgIHJldHVybiBtX2ZyYW1lLnJlYWxwOworfQorICAgIAorZmxvYXQqIEZGVEZyYW1l
OjppbWFnRGF0YSgpIGNvbnN0Cit7CisgICAgcmV0dXJuIG1fZnJhbWUuaW1hZ3A7Cit9CisKK30g
Ly8gbmFtZXNwYWNlIFdlYkNvcmUKKworI2VuZGlmIC8vIEVOQUJMRShXRUJfQVVESU8pCg==
</data>

          </attachment>
      

    </bug>

</bugzilla>