<div dir="ltr"><div class="markdown-here-wrapper" style=""><p style="margin:0px 0px 1.2em!important">Hello corelibs-dev and build-dev,</p>
<p style="margin:0px 0px 1.2em!important">Back in May, Brian Croom implemented performance testing in swift-corelibs-xctest: <a href="https://github.com/apple/swift-corelibs-xctest/pull/109">https://github.com/apple/swift-corelibs-xctest/pull/109</a></p>
<p style="margin:0px 0px 1.2em!important">I’d love to see Swift developers use this feature to measure the performance of their code. I think we’ll need to add functionality to swift-corelibs-xctest and SwiftPM in order to do so.</p>
<h1 id="the-problem-recording-performance-test-baselines" style="margin:1.3em 0px 1em;padding:0px;font-weight:bold;font-size:1.6em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(221,221,221)">The problem: recording performance test baselines</h1>
<p style="margin:0px 0px 1.2em!important">In order for performance tests to be useful, Apple’s Xcode provides a way to record “baseline” metrics. Baseline metrics allow a developer to indicate “this performance test should never be slower than 1.2 seconds on average, with 10% standard deviation as ‘wiggle room’”. When Apple XCTest tests are run, they are informed of the baseline metrics that have been set in Xcode. Apple XCTest performance tests that have a baseline registered will fail if performance becomes slower than the acceptable amount.</p>
<p style="margin:0px 0px 1.2em!important">If we could provide swift-corelibs-xctest with a mapping from each performance test to its baseline metric, it would be easy to write the code to fail a test if it didn’t perform well enough. That mapping, however, is the tricky part. Here’s why:</p>
<ul style="margin:1.2em 0px;padding-left:2em">
<li style="margin:0.5em 0px">The mapping needs to group metrics based on the host machine running the test. Performance will of course vary based on the hardware, so it’s important to make sure performance baselines set on a Raspberry Pi aren’t used when testing on a Mac Pro.</li>
<li style="margin:0.5em 0px">The mapping also needs to group metrics based on the target machine. Using Apple XCTest, a developer can start a test suite run from their MacBook Pro (macOS 64-bit), and see the results of the performance tests when run on their iPhone 6s (iOS armv7s). I don’t think this is relevant to swift-corelibs-xctest just yet — as far as I know, SwiftPM is not capable of cross-compilation, so the host machine will always be identical to the target machine. Still, we should design something flexible enough for this scenario.</li>
</ul>
<h1 id="xcode-s-solution-plist-files" style="margin:1.3em 0px 1em;padding:0px;font-weight:bold;font-size:1.6em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(221,221,221)">Xcode’s solution: plist files</h1>
<p style="margin:0px 0px 1.2em!important">Xcode’s solves this problem using two kinds of .plist files. I tried creating a sample project, named <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);border-radius:3px;display:inline;background-color:rgb(248,248,248)">Perforate.xcodeproj</code>, which contained a single performance test. Here’s what Xcode created:</p>
<pre style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;font-size:1em;line-height:1.2em;margin:1.2em 0px"><code class="hljs language-xml" style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);border-radius:3px;display:inline;background-color:rgb(248,248,248);white-space:pre;overflow:auto;border-radius:3px;border:1px solid rgb(204,204,204);padding:0.5em 0.7em;display:block!important;display:block;overflow-x:auto;padding:0.5em;color:rgb(51,51,51);background:rgb(248,248,248)"><span class="hljs-comment" style="color:rgb(153,153,136);font-style:italic"><!-- Perforate.xcodeproj/xcshareddata/xcbaselines/DA77262F1D447DB300735C93.xcbaseline/Info.plist --></span>
<span class="hljs-pi" style="color:rgb(153,153,153);font-weight:bold"><?xml version="1.0" encoding="UTF-8"?></span>
<span class="hljs-doctype" style="color:rgb(153,153,153);font-weight:bold"><!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "<a href="http://www.apple.com/DTDs/PropertyList-1.0.dtd">http://www.apple.com/DTDs/PropertyList-1.0.dtd</a>"></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"><<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">plist</span> <span class="hljs-attribute" style="color:rgb(0,128,128)">version</span>=<span class="hljs-value" style="color:rgb(221,17,68)">"1.0"</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"><<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">dict</span>></span>
<span class="hljs-comment" style="color:rgb(153,153,136);font-style:italic"><!-- runDestinationsByUUID: These are the host/target machine groups. --></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"><<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">key</span>></span>runDestinationsByUUID<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"></<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">key</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"><<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">dict</span>></span>
<span class="hljs-comment" style="color:rgb(153,153,136);font-style:italic"><!--
It appears each group is given a UUID, but to be honest, I'm not sure why.
It seems like these should be "keyed" on aspects of the host/target machines.
As-is, I imagine Xcode and Apple XCTest need to traverse each group's
`localComputer`, `targetArchitecture`, and `targetDevice`'s values in order to find a match.
--></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"><<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">key</span>></span>8CE9E051-9AB6-44AF-8B80-F2DEFD409CB5<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"></<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">key</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"><<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">dict</span>></span>
<span class="hljs-comment" style="color:rgb(153,153,136);font-style:italic"><!-- Information about the host machine: number of CPUs, cores, etc. --></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"><<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">key</span>></span>localComputer<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"></<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">key</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"><<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">dict</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"><<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">key</span>></span>busSpeedInMHz<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"></<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">key</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"><<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">integer</span>></span>100<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"></<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">integer</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"><<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">key</span>></span>cpuCount<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"></<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">key</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"><<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">integer</span>></span>1<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"></<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">integer</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"><<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">key</span>></span>cpuKind<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"></<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">key</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"><<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">string</span>></span>Intel Core i7<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"></<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">string</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"><<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">key</span>></span>cpuSpeedInMHz<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"></<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">key</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"><<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">integer</span>></span>2800<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"></<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">integer</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"><<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">key</span>></span>logicalCPUCoresPerPackage<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"></<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">key</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"><<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">integer</span>></span>8<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"></<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">integer</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"><<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">key</span>></span>modelCode<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"></<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">key</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"><<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">string</span>></span>MacBookPro11,3<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"></<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">string</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"><<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">key</span>></span>physicalCPUCoresPerPackage<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"></<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">key</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"><<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">integer</span>></span>4<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"></<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">integer</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"><<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">key</span>></span>platformIdentifier<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"></<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">key</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"><<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">string</span>></span>com.apple.platform.macosx<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"></<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">string</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"></<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">dict</span>></span>
<span class="hljs-comment" style="color:rgb(153,153,136);font-style:italic"><!-- The target architecture and device are stored as separate keys. --></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"><<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">key</span>></span>targetArchitecture<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"></<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">key</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"><<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">string</span>></span>x86_64<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"></<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">string</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"><<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">key</span>></span>targetDevice<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"></<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">key</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"><<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">dict</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"><<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">key</span>></span>modelCode<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"></<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">key</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"><<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">string</span>></span>iPhone8,2<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"></<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">string</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"><<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">key</span>></span>platformIdentifier<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"></<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">key</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"><<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">string</span>></span>com.apple.platform.iphonesimulator<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"></<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">string</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"></<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">dict</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"></<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">dict</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"></<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">dict</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"></<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">dict</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"></<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">plist</span>></span>
</code></pre>
<pre style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;font-size:1em;line-height:1.2em;margin:1.2em 0px"><code class="hljs language-xml" style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);border-radius:3px;display:inline;background-color:rgb(248,248,248);white-space:pre;overflow:auto;border-radius:3px;border:1px solid rgb(204,204,204);padding:0.5em 0.7em;display:block!important;display:block;overflow-x:auto;padding:0.5em;color:rgb(51,51,51);background:rgb(248,248,248)"><span class="hljs-comment" style="color:rgb(153,153,136);font-style:italic"><!-- Perforate.xcodeproj/xcshareddata/xcbaselines/DA77262F1D447DB300735C93.xcbaseline/8CE9E051-9AB6-44AF-8B80-F2DEFD409CB5.plist --></span>
<span class="hljs-comment" style="color:rgb(153,153,136);font-style:italic"><!-- Notice that this file is named after the `runDestinationsByUUID` key from the first file: 8CE9E051-9AB6-44AF-8B80-F2DEFD409CB5. --></span>
<span class="hljs-pi" style="color:rgb(153,153,153);font-weight:bold"><?xml version="1.0" encoding="UTF-8"?></span>
<span class="hljs-doctype" style="color:rgb(153,153,153);font-weight:bold"><!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "<a href="http://www.apple.com/DTDs/PropertyList-1.0.dtd">http://www.apple.com/DTDs/PropertyList-1.0.dtd</a>"></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"><<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">plist</span> <span class="hljs-attribute" style="color:rgb(0,128,128)">version</span>=<span class="hljs-value" style="color:rgb(221,17,68)">"1.0"</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"><<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">dict</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"><<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">key</span>></span>classNames<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"></<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">key</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"><<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">dict</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"><<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">key</span>></span>PerforateTests<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"></<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">key</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"><<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">dict</span>></span>
<span class="hljs-comment" style="color:rgb(153,153,136);font-style:italic"><!-- The metrics are mapped by class name and test method name to performance metrics. --></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"><<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">key</span>></span>test_uniqueOrdered_performance<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"></<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">key</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"><<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">dict</span>></span>
<span class="hljs-comment" style="color:rgb(153,153,136);font-style:italic"><!-- There are several categories of performance metrics. The only one publicly available in Apple XCTest so far is wall clock time. --></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"><<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">key</span>></span>com.apple.XCTPerformanceMetric_WallClockTime<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"></<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">key</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"><<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">dict</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"><<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">key</span>></span>baselineAverage<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"></<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">key</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"><<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">real</span>></span>0.5<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"></<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">real</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"><<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">key</span>></span>baselineIntegrationDisplayName<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"></<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">key</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"><<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">string</span>></span>Local Baseline<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"></<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">string</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"></<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">dict</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"></<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">dict</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"></<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">dict</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"></<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">dict</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"></<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">dict</span>></span>
<span class="hljs-tag" style="color:rgb(0,0,128);font-weight:normal"></<span class="hljs-title" style="color:rgb(153,0,0);font-weight:bold;color:rgb(0,0,128);font-weight:normal">plist</span>></span>
</code></pre>
<h1 id="proposed-solution-for-swiftpm-swift-corelibs-xctest-json-files" style="margin:1.3em 0px 1em;padding:0px;font-weight:bold;font-size:1.6em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(221,221,221)">Proposed solution for SwiftPM/swift-corelibs-xctest: JSON files</h1>
<p style="margin:0px 0px 1.2em!important">I think we can mimic Xcode’s approach here. Here’s what I’m proposing:</p>
<ul style="margin:1.2em 0px;padding-left:2em">
<li style="margin:0.5em 0px">swift-corelibs-xctest’s test runner should take a <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);border-radius:3px;display:inline;background-color:rgb(248,248,248)">--performance-metrics <PATH></code> argument, where <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);border-radius:3px;display:inline;background-color:rgb(248,248,248)"><PATH></code> is the location of a file containing JSON that looks pretty much exactly like the <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);border-radius:3px;display:inline;background-color:rgb(248,248,248)">8CE9E051-9AB6-44AF-8B80-F2DEFD409CB5.plist</code> from above:</li>
</ul>
<pre style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;font-size:1em;line-height:1.2em;margin:1.2em 0px"><code class="hljs language-json" style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);border-radius:3px;display:inline;background-color:rgb(248,248,248);white-space:pre;overflow:auto;border-radius:3px;border:1px solid rgb(204,204,204);padding:0.5em 0.7em;display:block!important;display:block;overflow-x:auto;padding:0.5em;color:rgb(51,51,51);background:rgb(248,248,248)">{
"<span class="hljs-attribute" style="color:rgb(0,128,128)">classNames</span>": <span class="hljs-value">{
"<span class="hljs-attribute" style="color:rgb(0,128,128)">PerforateTests</span>": <span class="hljs-value">{
"<span class="hljs-attribute" style="color:rgb(0,128,128)">test_uniqueOrdered_performance</span>": <span class="hljs-value">{
"<span class="hljs-attribute" style="color:rgb(0,128,128)">baselineAverage</span>": <span class="hljs-value"><span class="hljs-string" style="color:rgb(221,17,68)">"0.5"</span></span>,
"<span class="hljs-attribute" style="color:rgb(0,128,128)">baselineIntegrationDisplayName</span>": <span class="hljs-value"><span class="hljs-string" style="color:rgb(221,17,68)">"Local Baseline"</span>
</span>}
</span>}
</span>}
</span>}
</code></pre>
<ul style="margin:1.2em 0px;padding-left:2em">
<li style="margin:0.5em 0px">SwiftPM’s <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);border-radius:3px;display:inline;background-color:rgb(248,248,248)">swift test</code> command should also take a <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);border-radius:3px;display:inline;background-color:rgb(248,248,248)">--performance-metrics <PATH></code> argument, where <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);border-radius:3px;display:inline;background-color:rgb(248,248,248)"><PATH></code> is the location of a file containing JSON that looks pretty much exactly like the <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);border-radius:3px;display:inline;background-color:rgb(248,248,248)">xcbaselines/DA77262F1D447DB300735C93.xcbaseline/Info.plist</code> from above (by default, <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);border-radius:3px;display:inline;background-color:rgb(248,248,248)">--performance-metrics</code> could be set to the same path as the <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);border-radius:3px;display:inline;background-color:rgb(248,248,248)">swift test --build-path</code> directory): </li>
</ul>
<pre style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;font-size:1em;line-height:1.2em;margin:1.2em 0px"><code class="hljs language-json" style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);border-radius:3px;display:inline;background-color:rgb(248,248,248);white-space:pre;overflow:auto;border-radius:3px;border:1px solid rgb(204,204,204);padding:0.5em 0.7em;display:block!important;display:block;overflow-x:auto;padding:0.5em;color:rgb(51,51,51);background:rgb(248,248,248)">{
"runDestinationsByUUID": {
"8CE9E051-9AB6-44AF-8B80-F2DEFD409CB5": {
"localComputer": {
"busSpeedInMHz": "100",
# ...
},
"targetArchitecture": "x86_64",
"targetDevice": {
# We might need to change these keys, since "modelCode" seems very Apple-specific.
"modelCode": "linux",
"platformIdentifier": "Ubuntu 15.04",
}
}
}
}
</code></pre>
<p style="margin:0px 0px 1.2em!important">Personally, I think the format of the plist files Xcode and Apple XCTest generate could be improved. Still, I think it’d be nice to stick to the same format (as much as possible) for swift-corelibs-xctest, just to keep things simple.</p>
<h1 id="thoughts-" style="margin:1.3em 0px 1em;padding:0px;font-weight:bold;font-size:1.6em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(221,221,221)">Thoughts?</h1>
<p style="margin:0px 0px 1.2em!important">I admit that I don’t have much experience using Apple XCTest’s performance testing functionality, so I might be missing something here. Does anyone have any feedback on this idea? I’d like to incorporate your feedback, and perhaps submit a Swift Evolution proposal for this feature.</p><p style="margin:0px 0px 1.2em!important">- Brian Gesiak</p>
<div title="MDH:SGVsbG8gY29yZWxpYnMtZGV2IGFuZCBidWlsZC1kZXYsPGRpdj48YnI+PC9kaXY+PGRpdj5CYWNr
IGluIE1heSwgQnJpYW4gQ3Jvb20gaW1wbGVtZW50ZWQgcGVyZm9ybWFuY2UgdGVzdGluZyBpbiBz
d2lmdC1jb3JlbGlicy14Y3Rlc3Q6Jm5ic3A7PGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL2Fw
cGxlL3N3aWZ0LWNvcmVsaWJzLXhjdGVzdC9wdWxsLzEwOSIgdGFyZ2V0PSJfYmxhbmsiPmh0dHBz
Oi8vZ2l0aHViLmNvbS88d2JyPmFwcGxlL3N3aWZ0LWNvcmVsaWJzLXhjdGVzdC88d2JyPnB1bGwv
MTA5PC9hPjxicj48YnI+SSdkIGxvdmUgdG8gc2VlIFN3aWZ0IGRldmVsb3BlcnMgdXNlIHRoaXMg
ZmVhdHVyZSB0byBtZWFzdXJlIHRoZSBwZXJmb3JtYW5jZSBvZiB0aGVpciBjb2RlLiBJIHRoaW5r
IHdlJ2xsIG5lZWQgdG8gYWRkIGZ1bmN0aW9uYWxpdHkgdG8gc3dpZnQtY29yZWxpYnMteGN0ZXN0
IGFuZCBTd2lmdFBNIGluIG9yZGVyIHRvIGRvIHNvLjwvZGl2PjxkaXY+PGJyPjwvZGl2PjxkaXY+
IyBUaGUgcHJvYmxlbTogcmVjb3JkaW5nIHBlcmZvcm1hbmNlIHRlc3QgYmFzZWxpbmVzPC9kaXY+
PGRpdj48YnI+PC9kaXY+PGRpdj5JbiBvcmRlciBmb3IgcGVyZm9ybWFuY2UgdGVzdHMgdG8gYmUg
dXNlZnVsLCBBcHBsZSdzIFhjb2RlIHByb3ZpZGVzIGEgd2F5IHRvIHJlY29yZCAiYmFzZWxpbmUi
IG1ldHJpY3MuIEJhc2VsaW5lIG1ldHJpY3MgYWxsb3cgYSBkZXZlbG9wZXIgdG8gaW5kaWNhdGUg
InRoaXMgcGVyZm9ybWFuY2UgdGVzdCBzaG91bGQgbmV2ZXIgYmUgc2xvd2VyIHRoYW4gMS4yIHNl
Y29uZHMgb24gYXZlcmFnZSwgd2l0aCAxMCUgc3RhbmRhcmQgZGV2aWF0aW9uIGFzICd3aWdnbGUg
cm9vbSciLiBXaGVuIEFwcGxlIFhDVGVzdCB0ZXN0cyBhcmUgcnVuLCB0aGV5IGFyZSBpbmZvcm1l
ZCBvZiB0aGUgYmFzZWxpbmUgbWV0cmljcyB0aGF0IGhhdmUgYmVlbiBzZXQgaW4gWGNvZGUuIEFw
cGxlIFhDVGVzdCBwZXJmb3JtYW5jZSB0ZXN0cyB0aGF0IGhhdmUgYSBiYXNlbGluZSByZWdpc3Rl
cmVkIHdpbGwgZmFpbCBpZiBwZXJmb3JtYW5jZSBiZWNvbWVzIHNsb3dlciB0aGFuIHRoZSBhY2Nl
cHRhYmxlIGFtb3VudC48L2Rpdj48ZGl2Pjxicj48L2Rpdj48ZGl2PklmIHdlIGNvdWxkIHByb3Zp
ZGUgc3dpZnQtY29yZWxpYnMteGN0ZXN0IHdpdGggYSBtYXBwaW5nIGZyb20gZWFjaCBwZXJmb3Jt
YW5jZSB0ZXN0IHRvIGl0cyBiYXNlbGluZSBtZXRyaWMsIGl0IHdvdWxkIGJlIGVhc3kgdG8gd3Jp
dGUgdGhlIGNvZGUgdG8gZmFpbCBhIHRlc3QgaWYgaXQgZGlkbid0IHBlcmZvcm0gd2VsbCBlbm91
Z2guIFRoYXQgbWFwcGluZywgaG93ZXZlciwgaXMgdGhlIHRyaWNreSBwYXJ0LiBIZXJlJ3Mgd2h5
Ojxicj48YnI+LSBUaGUgbWFwcGluZyBuZWVkcyB0byBncm91cCBtZXRyaWNzIGJhc2VkIG9uIHRo
ZSBob3N0IG1hY2hpbmUgcnVubmluZyB0aGUgdGVzdC4gUGVyZm9ybWFuY2Ugd2lsbCBvZiBjb3Vy
c2UgdmFyeSBiYXNlZCBvbiB0aGUgaGFyZHdhcmUsIHNvIGl0J3MgaW1wb3J0YW50IHRvIG1ha2Ug
c3VyZSBwZXJmb3JtYW5jZSBiYXNlbGluZXMgc2V0IG9uIGEgUmFzcGJlcnJ5IFBpIGFyZW4ndCB1
c2VkIHdoZW4gdGVzdGluZyBvbiBhIE1hYyBQcm8uPGJyPi0gVGhlIG1hcHBpbmcgYWxzbyBuZWVk
cyB0byBncm91cCBtZXRyaWNzIGJhc2VkIG9uIHRoZSB0YXJnZXQgbWFjaGluZS4gVXNpbmcgQXBw
bGUgWENUZXN0LCBhIGRldmVsb3BlciBjYW4gc3RhcnQgYSB0ZXN0IHN1aXRlIHJ1biBmcm9tIHRo
ZWlyIE1hY0Jvb2sgUHJvIChtYWNPUyA2NC1iaXQpLCBhbmQgc2VlIHRoZSByZXN1bHRzIG9mIHRo
ZSBwZXJmb3JtYW5jZSB0ZXN0cyB3aGVuIHJ1biBvbiB0aGVpciBpUGhvbmUgNnMgKGlPUyBhcm12
N3MpLiBJIGRvbid0IHRoaW5rIHRoaXMgaXMgcmVsZXZhbnQgdG8gc3dpZnQtY29yZWxpYnMteGN0
ZXN0IGp1c3QgeWV0IC0tIGFzIGZhciBhcyBJIGtub3csIFN3aWZ0UE0gaXMgbm90IGNhcGFibGUg
b2YgY3Jvc3MtY29tcGlsYXRpb24sIHNvIHRoZSBob3N0IG1hY2hpbmUgd2lsbCBhbHdheXMgYmUg
aWRlbnRpY2FsIHRvIHRoZSB0YXJnZXQgbWFjaGluZS4gU3RpbGwsIHdlIHNob3VsZCBkZXNpZ24g
c29tZXRoaW5nIGZsZXhpYmxlIGVub3VnaCBmb3IgdGhpcyBzY2VuYXJpby48YnI+PGJyPiMgWGNv
ZGUncyBzb2x1dGlvbjogcGxpc3QgZmlsZXM8YnI+PGJyPlhjb2RlJ3Mgc29sdmVzIHRoaXMgcHJv
YmxlbSB1c2luZyB0d28ga2luZHMgb2YgLnBsaXN0IGZpbGVzLiBJIHRyaWVkIGNyZWF0aW5nIGEg
c2FtcGxlIHByb2plY3QsIG5hbWVkIGBQZXJmb3JhdGUueGNvZGVwcm9qYCwgd2hpY2ggY29udGFp
bmVkIGEgc2luZ2xlIHBlcmZvcm1hbmNlIHRlc3QuIEhlcmUncyB3aGF0IFhjb2RlIGNyZWF0ZWQ6
PC9kaXY+PGRpdj48YnI+YGBgeG1sPGJyPiZsdDshLS0mbmJzcDtQZXJmb3JhdGUueGNvZGVwcm9q
L3hjc2hhcmVkZGF0YS94Y2Jhc2VsaW5lcy9EQTc3MjYyRjFENDQ3REIzMDA3MzVDOTMueGNiYXNl
bGluZS9JbmZvLnBsaXN0IC0tJmd0Ozxicj48YnI+PGRpdj4mbHQ7P3htbCB2ZXJzaW9uPSIxLjAi
IGVuY29kaW5nPSJVVEYtOCI/Jmd0OzwvZGl2PjxkaXY+Jmx0OyFET0NUWVBFIHBsaXN0IFBVQkxJ
QyAiLS8vQXBwbGUvL0RURCBQTElTVCAxLjAvL0VOIiAiaHR0cDovL3d3dy5hcHBsZS5jb20vRFRE
cy9Qcm9wZXJ0eUxpc3QtMS4wLmR0ZCImZ3Q7PC9kaXY+PGRpdj4mbHQ7cGxpc3QgdmVyc2lvbj0i
MS4wIiZndDs8L2Rpdj48ZGl2PiZsdDtkaWN0Jmd0OzwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyAm
bmJzcDsgJm5ic3A7ICZsdDshLS0gcnVuRGVzdGluYXRpb25zQnlVVUlEOiBUaGVzZSBhcmUgdGhl
IGhvc3QvdGFyZ2V0IG1hY2hpbmUgZ3JvdXBzLiZuYnNwOy0tJmd0OzwvZGl2PjxkaXY+Jm5ic3A7
ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZsdDtrZXkmZ3Q7cnVuRGVzdGluYXRpb25zQnlVVUlEJmx0
Oy9rZXkmZ3Q7PC9kaXY+PGRpdj4mbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJmx0O2RpY3Qm
Z3Q7PGJyPiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAm
bmJzcDsgJmx0OyEtLTxicj4mbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNw
OyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyBJdCBhcHBlYXJzIGVh
Y2ggZ3JvdXAgaXMgZ2l2ZW4gYSBVVUlELCBidXQgdG8gYmUgaG9uZXN0LCBJJ20gbm90IHN1cmUg
d2h5LjwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsg
Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgSXQgc2VlbXMgbGlrZSB0
aGVzZSBzaG91bGQgYmUgImtleWVkIiBvbiBhc3BlY3RzIG9mIHRoZSBob3N0L3RhcmdldCBtYWNo
aW5lcy48L2Rpdj48ZGl2PiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7
ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7IEFzLWlzLCBJIGltYWdp
bmUgWGNvZGUgYW5kIEFwcGxlIFhDVGVzdCBuZWVkIHRvIHRyYXZlcnNlIGVhY2ggZ3JvdXAnczwv
ZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7
ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgYGxvY2FsQ29tcHV0ZXJgLCBgdGFy
Z2V0QXJjaGl0ZWN0dXJlYCwgYW5kIGB0YXJnZXREZXZpY2VgJ3MgdmFsdWVzIGluIG9yZGVyIHRv
IGZpbmQgYSBtYXRjaC48YnI+Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJz
cDsgJm5ic3A7ICZuYnNwOyAtLSZndDs8L2Rpdj48ZGl2PiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZu
YnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJmx0O2tleSZndDs4Q0U5RTA1MS05QUI2
LTQ0QUYtOEI4MC1GMkRFRkQ0MDlDQjUmbHQ7L2tleSZndDs8L2Rpdj48ZGl2PiZuYnNwOyAmbmJz
cDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJmx0O2RpY3QmZ3Q7
PGJyPiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJz
cDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZsdDshLS0gSW5mb3JtYXRpb24gYWJvdXQg
dGhlIGhvc3QgbWFjaGluZTogbnVtYmVyIG9mIENQVXMsIGNvcmVzLCBldGMuIC0tJmd0OzwvZGl2
PjxkaXY+Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZu
YnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJmx0O2tleSZndDtsb2NhbENvbXB1dGVy
Jmx0Oy9rZXkmZ3Q7PC9kaXY+PGRpdj4mbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7
ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbHQ7ZGlj
dCZndDs8L2Rpdj48ZGl2PiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7
ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsg
Jm5ic3A7ICZuYnNwOyAmbHQ7a2V5Jmd0O2J1c1NwZWVkSW5NSHombHQ7L2tleSZndDs8L2Rpdj48
ZGl2PiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJz
cDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNw
OyAmbHQ7aW50ZWdlciZndDsxMDAmbHQ7L2ludGVnZXImZ3Q7PC9kaXY+PGRpdj4mbmJzcDsgJm5i
c3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJz
cDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJmx0O2tleSZndDtj
cHVDb3VudCZsdDsva2V5Jmd0OzwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7
ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsg
Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZsdDtpbnRlZ2VyJmd0OzEmbHQ7L2ludGVnZXIm
Z3Q7PC9kaXY+PGRpdj4mbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAm
bmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZu
YnNwOyAmbmJzcDsgJmx0O2tleSZndDtjcHVLaW5kJmx0Oy9rZXkmZ3Q7PC9kaXY+PGRpdj4mbmJz
cDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNw
OyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJmx0O3N0
cmluZyZndDtJbnRlbCBDb3JlIGk3Jmx0Oy9zdHJpbmcmZ3Q7PC9kaXY+PGRpdj4mbmJzcDsgJm5i
c3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJz
cDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJmx0O2tleSZndDtj
cHVTcGVlZEluTUh6Jmx0Oy9rZXkmZ3Q7PC9kaXY+PGRpdj4mbmJzcDsgJm5ic3A7ICZuYnNwOyAm
bmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZu
YnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJmx0O2ludGVnZXImZ3Q7MjgwMCZsdDsv
aW50ZWdlciZndDs8L2Rpdj48ZGl2PiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsg
Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAm
bmJzcDsgJm5ic3A7ICZuYnNwOyAmbHQ7a2V5Jmd0O2xvZ2ljYWxDUFVDb3Jlc1BlclBhY2thZ2Um
bHQ7L2tleSZndDs8L2Rpdj48ZGl2PiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsg
Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAm
bmJzcDsgJm5ic3A7ICZuYnNwOyAmbHQ7aW50ZWdlciZndDs4Jmx0Oy9pbnRlZ2VyJmd0OzwvZGl2
PjxkaXY+Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZu
YnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5i
c3A7ICZsdDtrZXkmZ3Q7bW9kZWxDb2RlJmx0Oy9rZXkmZ3Q7PC9kaXY+PGRpdj4mbmJzcDsgJm5i
c3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJz
cDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJmx0O3N0cmluZyZn
dDtNYWNCb29rUHJvMTEsMyZsdDsvc3RyaW5nJmd0OzwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyAm
bmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZu
YnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZsdDtrZXkmZ3Q7cGh5c2lj
YWxDUFVDb3Jlc1BlclBhY2thZ2UmbHQ7L2tleSZndDs8L2Rpdj48ZGl2PiZuYnNwOyAmbmJzcDsg
Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAm
bmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbHQ7aW50ZWdlciZndDs0
Jmx0Oy9pbnRlZ2VyJmd0OzwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZu
YnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5i
c3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZsdDtrZXkmZ3Q7cGxhdGZvcm1JZGVudGlmaWVyJmx0
Oy9rZXkmZ3Q7PC9kaXY+PGRpdj4mbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZu
YnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5i
c3A7ICZuYnNwOyAmbmJzcDsgJmx0O3N0cmluZyZndDtjb20uYXBwbGUucGxhdGZvcm0ubWFjb3N4
Jmx0Oy9zdHJpbmcmZ3Q7PC9kaXY+PGRpdj4mbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5i
c3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbHQ7
L2RpY3QmZ3Q7PGJyPiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZu
YnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZsdDshLS0gVGhlIHRhcmdl
dCBhcmNoaXRlY3R1cmUgYW5kIGRldmljZSBhcmUgc3RvcmVkIGFzIHNlcGFyYXRlIGtleXMuIC0t
Jmd0Ozxicj48L2Rpdj48ZGl2PiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5i
c3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZsdDtrZXkmZ3Q7
dGFyZ2V0QXJjaGl0ZWN0dXJlJmx0Oy9rZXkmZ3Q7PC9kaXY+PGRpdj4mbmJzcDsgJm5ic3A7ICZu
YnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5i
c3A7ICZuYnNwOyAmbHQ7c3RyaW5nJmd0O3g4Nl82NCZsdDsvc3RyaW5nJmd0OzwvZGl2PjxkaXY+
Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAm
bmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJmx0O2tleSZndDt0YXJnZXREZXZpY2UmbHQ7L2tl
eSZndDs8L2Rpdj48ZGl2PiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7
ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZsdDtkaWN0Jmd0Ozwv
ZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7
ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsg
Jm5ic3A7ICZsdDtrZXkmZ3Q7bW9kZWxDb2RlJmx0Oy9rZXkmZ3Q7PC9kaXY+PGRpdj4mbmJzcDsg
Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAm
bmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJmx0O3N0cmlu
ZyZndDtpUGhvbmU4LDImbHQ7L3N0cmluZyZndDs8L2Rpdj48ZGl2PiZuYnNwOyAmbmJzcDsgJm5i
c3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJz
cDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbHQ7a2V5Jmd0O3BsYXRmb3Jt
SWRlbnRpZmllciZsdDsva2V5Jmd0OzwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5i
c3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJz
cDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZsdDtzdHJpbmcmZ3Q7Y29tLmFwcGxlLnBs
YXRmb3JtLmlwaG9uZXNpbXVsYXRvciZsdDsvc3RyaW5nJmd0OzwvZGl2PjxkaXY+Jm5ic3A7ICZu
YnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5i
c3A7ICZuYnNwOyAmbmJzcDsgJmx0Oy9kaWN0Jmd0OzwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyAm
bmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbHQ7L2RpY3QmZ3Q7PC9k
aXY+PGRpdj4mbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJmx0Oy9kaWN0Jmd0OzwvZGl2Pjxk
aXY+Jmx0Oy9kaWN0Jmd0OzwvZGl2PjxkaXY+Jmx0Oy9wbGlzdCZndDs8YnI+YGBgPC9kaXY+PC9k
aXY+PGRpdj48YnI+PC9kaXY+PGRpdj5gYGB4bWw8YnI+Jmx0OyEtLSZuYnNwO1BlcmZvcmF0ZS54
Y29kZXByb2oveGNzaGFyZWRkYXRhL3hjYmFzZWxpbmVzL0RBNzcyNjJGMUQ0NDdEQjMwMDczNUM5
My54Y2Jhc2VsaW5lLzhDRTlFMDUxLTlBQjYtNDRBRi04QjgwLUYyREVGRDQwOUNCNS5wbGlzdCAt
LSZndDs8YnI+PGJyPiZsdDshLS0gTm90aWNlIHRoYXQgdGhpcyBmaWxlIGlzIG5hbWVkIGFmdGVy
IHRoZSBgcnVuRGVzdGluYXRpb25zQnlVVUlEYCBrZXkgZnJvbSB0aGUgZmlyc3QgZmlsZTombmJz
cDs4Q0U5RTA1MS05QUI2LTQ0QUYtOEI4MC1GMkRFRkQ0MDlDQjUuIC0tJmd0Ozxicj48YnI+PGRp
dj4mbHQ7P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJVVEYtOCI/Jmd0OzwvZGl2PjxkaXY+
Jmx0OyFET0NUWVBFIHBsaXN0IFBVQkxJQyAiLS8vQXBwbGUvL0RURCBQTElTVCAxLjAvL0VOIiAi
aHR0cDovL3d3dy5hcHBsZS5jb20vRFREcy9Qcm9wZXJ0eUxpc3QtMS4wLmR0ZCImZ3Q7PC9kaXY+
PGRpdj4mbHQ7cGxpc3QgdmVyc2lvbj0iMS4wIiZndDs8L2Rpdj48ZGl2PiZsdDtkaWN0Jmd0Ozxi
cj48L2Rpdj48ZGl2PiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbHQ7a2V5Jmd0O2NsYXNz
TmFtZXMmbHQ7L2tleSZndDs8L2Rpdj48ZGl2PiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAm
bHQ7ZGljdCZndDs8L2Rpdj48ZGl2PiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsg
Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJmx0O2tleSZndDtQZXJmb3JhdGVUZXN0cyZsdDsva2V5Jmd0
OzwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5i
c3A7ICZuYnNwOyAmbHQ7ZGljdCZndDs8YnI+Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZu
YnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJmx0
OyEtLSBUaGUgbWV0cmljcyBhcmUgbWFwcGVkIGJ5IGNsYXNzIG5hbWUgYW5kIHRlc3QgbWV0aG9k
IG5hbWUgdG8gcGVyZm9ybWFuY2UgbWV0cmljcy4gLS0mZ3Q7PC9kaXY+PGRpdj4mbmJzcDsgJm5i
c3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJz
cDsgJm5ic3A7ICZuYnNwOyAmbHQ7a2V5Jmd0O3Rlc3RfdW5pcXVlT3JkZXJlZF9wZXJmb3JtYW5j
ZSZsdDsva2V5Jmd0OzwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNw
OyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJmx0O2Rp
Y3QmZ3Q7PGJyPiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNw
OyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7
ICZuYnNwOyAmbHQ7IS0tIFRoZXJlIGFyZSBzZXZlcmFsIGNhdGVnb3JpZXMgb2YgcGVyZm9ybWFu
Y2UgbWV0cmljcy4gVGhlIG9ubHkgb25lIHB1YmxpY2x5IGF2YWlsYWJsZSBpbiBBcHBsZSBYQ1Rl
c3Qgc28gZmFyIGlzIHdhbGwgY2xvY2sgdGltZS4gLS0mZ3Q7PC9kaXY+PGRpdj4mbmJzcDsgJm5i
c3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJz
cDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJmx0O2tleSZndDtj
b20uYXBwbGUuWENUUGVyZm9ybWFuY2VNZXRyaWNfV2FsbENsb2NrVGltZSZsdDsva2V5Jmd0Ozwv
ZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7
ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsg
Jm5ic3A7ICZsdDtkaWN0Jmd0OzwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7
ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsg
Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAm
bHQ7a2V5Jmd0O2Jhc2VsaW5lQXZlcmFnZSZsdDsva2V5Jmd0OzwvZGl2PjxkaXY+Jm5ic3A7ICZu
YnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5i
c3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJz
cDsgJm5ic3A7ICZuYnNwOyAmbHQ7cmVhbCZndDswLjUmbHQ7L3JlYWwmZ3Q7PC9kaXY+PGRpdj4m
bmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZu
YnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5i
c3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZsdDtrZXkmZ3Q7YmFzZWxpbmVJbnRlZ3JhdGlvbkRp
c3BsYXlOYW1lJmx0Oy9rZXkmZ3Q7PC9kaXY+PGRpdj4mbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJz
cDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNw
OyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7
ICZsdDtzdHJpbmcmZ3Q7TG9jYWwgQmFzZWxpbmUmbHQ7L3N0cmluZyZndDs8L2Rpdj48ZGl2PiZu
YnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5i
c3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbHQ7
L2RpY3QmZ3Q7PC9kaXY+PGRpdj4mbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZu
YnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbHQ7L2RpY3Qm
Z3Q7PC9kaXY+PGRpdj4mbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAm
bmJzcDsgJm5ic3A7ICZsdDsvZGljdCZndDs8L2Rpdj48ZGl2PiZuYnNwOyAmbmJzcDsgJm5ic3A7
ICZuYnNwOyAmbHQ7L2RpY3QmZ3Q7PC9kaXY+PGRpdj4mbHQ7L2RpY3QmZ3Q7PC9kaXY+PGRpdj4m
bHQ7L3BsaXN0Jmd0OzwvZGl2PmBgYDxicj48YnI+IyBQcm9wb3NlZCBzb2x1dGlvbiBmb3IgU3dp
ZnRQTS9zd2lmdC1jb3JlbGlicy14Y3Rlc3Q6IEpTT04gZmlsZXM8YnI+PGJyPkkgdGhpbmsgd2Ug
Y2FuIG1pbWljIFhjb2RlJ3MgYXBwcm9hY2ggaGVyZS4gSGVyZSdzIHdoYXQgSSdtIHByb3Bvc2lu
Zzo8YnI+PGJyPi0gc3dpZnQtY29yZWxpYnMteGN0ZXN0J3MgdGVzdCBydW5uZXIgc2hvdWxkIHRh
a2UgYSBgLS1wZXJmb3JtYW5jZS1tZXRyaWNzICZsdDtQQVRIJmd0O2AgYXJndW1lbnQsIHdoZXJl
IGAmbHQ7UEFUSCZndDtgIGlzIHRoZSBsb2NhdGlvbiBvZiBhIGZpbGUgY29udGFpbmluZyBKU09O
IHRoYXQgbG9va3MgcHJldHR5IG11Y2ggZXhhY3RseSBsaWtlIHRoZSBgOENFOUUwNTEtOUFCNi00
NEFGLThCODAtRjJERUZENDA5Q0I1LnBsaXN0YCBmcm9tIGFib3ZlOjwvZGl2PjxkaXY+PGJyPmBg
YGpzb248YnI+PGRpdj57PC9kaXY+PGRpdj4mbmJzcDsgImNsYXNzTmFtZXMiOiB7PC9kaXY+PGRp
dj4mbmJzcDsgJm5ic3A7ICJQZXJmb3JhdGVUZXN0cyI6IHs8L2Rpdj48ZGl2PiZuYnNwOyAmbmJz
cDsgJm5ic3A7ICJ0ZXN0X3VuaXF1ZU9yZGVyZWRfcGVyZm9ybWFuY2UiOiB7PC9kaXY+PGRpdj4m
bmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgImJhc2VsaW5lQXZlcmFnZSI6ICIwLjUiLDwvZGl2
PjxkaXY+Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICJiYXNlbGluZUludGVncmF0aW9uRGlz
cGxheU5hbWUiOiAiTG9jYWwgQmFzZWxpbmUiPC9kaXY+PGRpdj4mbmJzcDsgJm5ic3A7ICZuYnNw
OyB9PC9kaXY+PGRpdj4mbmJzcDsgJm5ic3A7IH08L2Rpdj48ZGl2PiZuYnNwOyB9PC9kaXY+PGRp
dj59PC9kaXY+YGBgPGJyPjxicj4tIFN3aWZ0UE0ncyBgc3dpZnQgdGVzdGAgY29tbWFuZCBzaG91
bGQgYWxzbyB0YWtlIGEgYC0tcGVyZm9ybWFuY2UtbWV0cmljcyAmbHQ7UEFUSCZndDtgIGFyZ3Vt
ZW50LCB3aGVyZSBgJmx0O1BBVEgmZ3Q7YCBpcyB0aGUgbG9jYXRpb24gb2YgYSBmaWxlIGNvbnRh
aW5pbmcgSlNPTiB0aGF0IGxvb2tzIHByZXR0eSBtdWNoIGV4YWN0bHkgbGlrZSB0aGUgYHhjYmFz
ZWxpbmVzL0RBNzcyNjJGMUQ0NDdEQjMwMDczNUM5My54Y2Jhc2VsaW5lL0luZm8ucGxpc3RgIGZy
b20gYWJvdmUgKGJ5Jm5ic3A7ZGVmYXVsdCwgYC0tcGVyZm9ybWFuY2UtbWV0cmljc2AgY291bGQg
YmUgc2V0IHRvIHRoZSBzYW1lIHBhdGggYXMgdGhlIGBzd2lmdCB0ZXN0IC0tYnVpbGQtcGF0aGAg
ZGlyZWN0b3J5KTombmJzcDs8L2Rpdj48ZGl2Pjxicj5gYGBqc29uPGJyPjxkaXY+ezwvZGl2Pjxk
aXY+Jm5ic3A7ICJydW5EZXN0aW5hdGlvbnNCeVVVSUQiOiB7PC9kaXY+PGRpdj4mbmJzcDsgJm5i
c3A7ICI4Q0U5RTA1MS05QUI2LTQ0QUYtOEI4MC1GMkRFRkQ0MDlDQjUiOiB7PC9kaXY+PGRpdj4m
bmJzcDsgJm5ic3A7ICZuYnNwOyAibG9jYWxDb21wdXRlciI6IHs8L2Rpdj48ZGl2PiZuYnNwOyAm
bmJzcDsgJm5ic3A7ICZuYnNwOyAiYnVzU3BlZWRJbk1IeiI6ICIxMDAiLDwvZGl2PjxkaXY+Jm5i
c3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICMgLi4uPC9kaXY+PGRpdj4mbmJzcDsgJm5ic3A7ICZu
YnNwOyB9LDwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyAmbmJzcDsgInRhcmdldEFyY2hpdGVjdHVy
ZSI6ICJ4ODZfNjQiLDwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyAmbmJzcDsgInRhcmdldERldmlj
ZSI6IHs8YnI+Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICMgV2UgbWlnaHQgbmVlZCB0byBj
aGFuZ2UgdGhlc2Uga2V5cywgc2luY2UgIm1vZGVsQ29kZSIgc2VlbXMgdmVyeSBBcHBsZS1zcGVj
aWZpYy48L2Rpdj48ZGl2PiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAibW9kZWxDb2RlIjog
ImxpbnV4Iiw8L2Rpdj48ZGl2PiZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAicGxhdGZvcm1J
ZGVudGlmaWVyIjogIlVidW50dSAxNS4wNCIsPC9kaXY+PGRpdj4mbmJzcDsgJm5ic3A7ICZuYnNw
OyB9PC9kaXY+PGRpdj4mbmJzcDsgJm5ic3A7IH08L2Rpdj48ZGl2PiZuYnNwOyB9PC9kaXY+PGRp
dj59PC9kaXY+YGBgPGJyPjxicj5QZXJzb25hbGx5LCBJIHRoaW5rIHRoZSBmb3JtYXQgb2YgdGhl
IHBsaXN0IGZpbGVzIFhjb2RlIGFuZCBBcHBsZSBYQ1Rlc3QgZ2VuZXJhdGUgY291bGQgYmUgaW1w
cm92ZWQuIFN0aWxsLCBJIHRoaW5rIGl0J2QgYmUgbmljZSB0byBzdGljayB0byB0aGUgc2FtZSBm
b3JtYXQgKGFzIG11Y2ggYXMgcG9zc2libGUpIGZvciBzd2lmdC1jb3JlbGlicy14Y3Rlc3QsIGp1
c3QgdG8ga2VlcCB0aGluZ3Mgc2ltcGxlLjwvZGl2PjxkaXY+PGJyPjwvZGl2PjxkaXY+IyBUaG91
Z2h0cz88YnI+PGJyPkkgYWRtaXQgdGhhdCBJIGRvbid0IGhhdmUgbXVjaCBleHBlcmllbmNlIHVz
aW5nIEFwcGxlIFhDVGVzdCdzIHBlcmZvcm1hbmNlIHRlc3RpbmcgZnVuY3Rpb25hbGl0eSwgc28g
SSBtaWdodCBiZSBtaXNzaW5nIHNvbWV0aGluZyBoZXJlLiBEb2VzIGFueW9uZSBoYXZlIGFueSBm
ZWVkYmFjayBvbiB0aGlzIGlkZWE/IEknZCBsaWtlIHRvIGluY29ycG9yYXRlIHlvdXIgZmVlZGJh
Y2ssIGFuZCBwZXJoYXBzIHN1Ym1pdCBhIFN3aWZ0IEV2b2x1dGlvbiBwcm9wb3NhbCBmb3IgdGhp
cyBmZWF0dXJlLjwvZGl2PjxkaXY+PGJyPjwvZGl2PjxkaXY+LSBCcmlhbiBHZXNpYWs8L2Rpdj48
ZGl2Pjxicj48L2Rpdj4=" style="height:0;width:0;max-height:0;max-width:0;overflow:hidden;font-size:0em;padding:0;margin:0"></div></div></div>