Topic: D1031R1 draft 1 LLFIO with proposed C++
Author: Daniel Gutson <danielgutson@gmail.com>
Date: Wed, 1 Aug 2018 15:37:13 -0300
Raw View
--0000000000006966f6057263fce2
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
Though the actual way of recognizing this work would be currently reading
the proposal, and I will do my best during the weekend, I will do something
that I think is not very common these days: to say an anonymous "thank you"
for the (personal) time you took to contribute to the C++.
Same for all the people putting effort, time and/or money in the progress
of the language.
Sorry for the spam to those offended.
Daniel.
On Wed, Aug 1, 2018 at 3:01 PM Niall Douglas <nialldouglas14@gmail.com>
wrote:
> So assuming people were put off by the length of the paper, below is the
> section I'd really like feedback upon.
>
> Niall
>
>
> 3 Impact on the Standard
>
> Listed at the end of this section are the in-flight WG21 papers this
> proposal is dependent upon, and which would need to enter the standard
> before this library can be considered. However a bigger issue involves th=
e
> potential changes to the C++ object model, plus new contracts with which =
to
> indicate the limited side effects of i/o functions in order to enable
> improved optimisation.
>
>
> 3.1 Potential changes to the C++ object model
>
> Firstly I wish to make it clear that there is the viable option of simply
> making no changes at all to the object model, and any placement of object=
s
> into mapped memory is declared to be undefined behaviour, as it is at
> present5 .
>
>
> However I also think that an opportunity missed. Via memory maps, the
> proposed low level file i/o library herein enables object lifetime to
> exceed that of the program. It also enables an object to appear in multip=
le
> instances of concurrent C++ program execution, or indeed at multiple
> addresses within a C++ program. And finally one can mark individual pages
> of memory with different access permissions than read-only or read-write
> (e.g. no access i.e. unreachable), or kick individual pages out to swap, =
or
> throw away their contents. In other words, individual pages of memory can
> become unreachable with the objects within that storage still being alive=
..
>
>
>
> All four things are problematic for the current C++ standard=E2=80=99s ob=
ject
> model, not least that objects cannot currently outlive the program; that
> there is no awareness of it being possible for multiple concurrent C++
> program instances to exist in the current standard; that objects not mark=
ed
> with [[no_unique_address]] and which are not bits in a bitfield must
> currently always have a single, unique address in the process; that all
> alive objects are equally reachable from anywhere in the program; and
> finally that objects are always available at their unique address, and ar=
e
> not also elsewhere.
>
>
> Furthermore, there are reordering constraints peculiar to mapped memory i=
f
> a modification to an object is to persist at all, or indeed in a form whi=
ch
> is usable. This is because in most implementations of C++, atomic
> reordering constraints only affect apparent ordering to CPU cores within
> the same symmetric multiprocessing cluster, and may have no effect on the=
actual
> ordering of when modifications are sent to main memory and/or the storage
> device. Thus, if a C++ program modifies an object, and then modifies it
> again, some of the changes of the latter modification may land in main
> memory before some of the changes of the earlier modification, irrespecti=
ve
> of any atomics or fences or anything else which a C++ program currently c=
an
> legally do. This has obvious implications for the integrity of that objec=
t
> across a program restart.
>
>
> I therefore suggest some changes to the C++ object model, listed below.
>
>
> 3.1.1 The relevant parts of the current standard
>
> There are presently four kinds of storage duration. As [basic.stc]
> describes it:
>
>
> The storage duration is the property of an object that defines the minimu=
m
> potential lifetime of the storage containing the object. The storage
> duration is determined by the construct used to create the object and is
> one of the following:
>
> 1. static storage duration
> 2. thread storage duration
> 3. automatic storage duration
> 4. dynamic storage duration
>
> [basic.life] describes in some detail the lifetime model, and it
> essentially reduces down to one of these possible states for each object
> (and apologies for the over-simplification for purposes of terse
> exposition):
>
>
> 1. Unconstructed (from P0593: and considered unreachable by the
> compiler during analysis), but storage is of the right size and
> alignment, and pointers and glvalues to the storage of the object type=
are
> permitted to be used under limited circumstances.
> 2. Unalive, in the process of being constructed, for types with
> non-trivial constructors only.
> 3. Alive, fully constructed.
> 4. Unalive, in the process of being destructed, for types with
> non-trivial destructors only.
>
> You will note that due to their triviality, memory storing trivial types
> such as std::byte can either be unconstructed, or fully constructed, and
> no lifetime state exists apart from those two. It is important to
> understand that currently speaking, using allocated memory in which nothi=
ng
> has been constructed is undefined behaviour, so the common method of
> reinterpret casting the return from malloc() to a pointer of the type you
> want is presently undefined behaviour.
>
>
> This is being dealt with in [P0593] Implicit creation of objects for
> low-level object manipulation. Amongst its many recommendations, it makes
> unconstructed memory unreachable by default. You can make it reachable by
> (i) constructing objects into it (ii) via the proposed std::bless() which
> tells the compiler that a region of unreachable memory (i.e. unconstructe=
d)
> is now reachable (and contains alive trivial objects of some form). You c=
an
> restore it to being unreachable by calling the destructor of the objects,
> even if those objects are completely trivial. P0593 doesn=E2=80=99t menti=
on it
> explicitly (yet!), but given std::launder=E2=80=99s special casing for st=
d::byte,
> it seems likely that calling the destructor for std::byte on a region
> with unknown trivially destructible types of objects in it will always ma=
rk
> it unreachable. And finally, P0593 names various functions as always
> returning memory which is reachable i.e. containing an array of alive
> objects of some unspecified trivial type.
>
>
> This new concept of reachable vs unreachable memory is an important one,
> and it is leaned upon heavily in the proposed extensions.
>
>
> 3.1.2 A new storage duration: mapped
>
> As always, naming is very hard, but mapped storage duration seems a
> reasonable name for memory which can be shared between concurrently runni=
ng
> processes, or between multiple start-stop cycles of the same program (not=
e
> that a program using an object from mapped storage which it itself did no=
t
> store there is undefined behaviour).
>
>
> The storage for objects with mapped storage duration shall last for the
> duration of the filesystem entity (see TS definitions below for precise
> meaning) referred to by the section_handle instance which represents the
> storage. section_handle instances may refer to filesystem entities whose
> lifetimes automatically end when the program ends (=E2=80=98anonymous ino=
des=E2=80=99), or
> which may persist for an indeterminate period, including across subsequen=
t
> executions of the C++ program.
>
>
> Mapped storage has the most similarity to dynamic storage, but with the
> following differences:
>
> - It has allocation and alignment granularities with architecture
> specific coarse sizes (=E2=80=98memory page=E2=80=99). 4Kb/2Mb/1Gb pag=
e sizes are common.
> - New allocations are guaranteed to be all bits zero on creation.
> - It has map on first read semantics. This means that the first read
> from a memory page can take hundreds of CPU cycles, and a TLB shootdow=
n
> causes an interrupt for other CPUs.
> - It has allocate on first write semantics. This means that the first
> write to a memory page can take thousands or even hundreds of thousand=
s of
> CPU cycles, plus a TLB shootdown.
> - Usually, but not always, mapped storage is a memory cache of
> equivalent storage a high latency storage device. Hence they can be
> individually pushed to storage, their contents thrown away, deallocate=
d,
> given different access permission or caching strategies, and lots of o=
ther
> interesting (i.e. potentially game changing for large STL containers)
> operations. Individual pages can be:
> - Read-only, read-write, or copy-on-write. These are self
> describing, and these are hard characteristics: violating them mean=
s
> program failure.
> - Committed or uncommitted. This indicates whether the page counts
> towards the resources used by the C++ program. Uncommitted memory i=
s
> inaccessible, and acts as a placeholder for later use (i.e. it is r=
eserved
> address space, useful for expanding large arrays without content co=
pying).
> - Dirty or clean. This indicates whether the page contains data not
> yet mirrored onto its backing storage.
> - Allocated or unallocated. This indicates whether storage backing
> the page has been allocated on the storage device. If not, the firs=
t write
> to a clean page may be very expensive as the page may need to be co=
pied by
> the kernel and/or space allocated for it on the backing storage dev=
ice.
>
> The storage represented by a section_handle instance can be mapped into
> (i.e. made available to) a C++ program by creating a map_handle sourcing
> the storage from a section_handle instance. The storage mapped by the low
> level map_handle shall represent unconstructed and unreachable memory,
> and will require the use of std::bless() or map_view to make it reachable
> (alternatively, use the convenience class mapped on a section_handle inst=
ance
> which bundles the aforementioned low level operations on your behalf).
>
>
> Destroying a map_view does not make the storage unreachable. Decommitting
> individual pages does, as does destroying a mapped or map_handle.
>
>
> 3.1.3 A new lifetime stage: unreachable
>
> I propose adding a new separate lifetime status for objects: unreachable.
> Under P0593, unconstructed objects are unreachable, but there is no
> possibility for a partially constructed, alive or partially destructed
> object to be unreachable. I propose that this new status ought to be adde=
d
> such that objects can now have the following lifetime states:
>
>
> 1. Unconstructed, always unreachable.
> 2. Unalive, in the process of being constructed, for types with
> non-trivial constructors only. Always reachable.
> 3. Alive, fully constructed, reachable. Has a single, unique address
> in memory (unless marked with [[no_unique_address]]).
> 4. Alive, fully constructed, unreachable. Does NOT have a single,
> unique address in memory (it may have many, or none). May change whils=
t
> unreachable (i.e. reload it after marking it reachable at some address=
).
> 5. Unalive, in the process of being destructed, for types with
> non-trivial destructors only. Always reachable.
>
> P0593 proposed these functions to mark regions as reachable:
>
>
> // Requires: [start, (char*)start + length) denotes a region of allocated
> // storage that is a subset of the region of storage reachable through
> start.
> // Effects: implicitly creates objects within the denoted region.
> void std::bless(void *start, size_t length);
>
> // Effects: create an object of implicit lifetype type T in the storage
> // pointed to by T, while preserving the object representation.
> template<typename T> T *std::bless(void *p);
>
>
> Thus the obvious corrollary for marking regions as unreachable:
>
>
> // Requires: [start, (char*)start + length) denotes a region of allocated
> // storage that is a subset of the region of storage reachable through
> start.
> // Effects: implicitly uncreates objects within the denoted region.
> void std::unbless(void *start, size_t length);
>
> // Effects: uncreate an object of implicit lifetype type T in the storage
> // pointed to by T, while preserving the object representation.
> template<typename T> void *std::unbless(T *p);
>
>
> A gain of this new unreachable lifetime status is that it neatly solves
> the problem of objects appearing at multiple addresses in a running
> program. We can now say that only one of those addresses can be reachable
> for an alive object at a time. If a program wishes to change an object=E2=
=80=99s
> current reachable address, they unbless the old location, and bless the n=
ew
> location.
>
>
> It should be emphasised that similarly to blessing, unblessing of trivial
> types causes no code emission. It simply tells the compiler what is now
> unreachable.
>
>
> Finally, it may seem that unreachability is a bit of a big sledgehammer t=
o
> throw at this problem. However, there are a number of other problems
> elsewhere in C++ where having unreachable but alive objects would be very
> useful =E2=80=93 thread local storage on a million CPU core compute resou=
rce is an
> excellent example6 . That said, this is a big change to lifetime, and if
> strong arguments are made against it then I am happy to propose something
> more conservative.
>
>
> 3.1.4 Blessing and unblessing polymorphic objects
>
> Currently P0593 makes no mention of polymorphic objects i.e. ones with
> vptrs in many implementations. I can see lots of reasons why it would be
> useful to bless and unbless polymorphic objects i.e. update the vptr to t=
he
> correct one for the currently running program, or clear the vptr to the
> system null pointer.
>
>
> Imagine, for example, a polymorphic object with mapped storage duration
> whose constructing program instance terminates. Upon restart of the
> program, the storage is mapped back into the program, but now the
> polymorphic object has the wrong vptr! So we need to write the correct vp=
tr
> for that object, after which all works as expected7 .
>
>
> This also applies to shared mapped memory. Extending the C++ object model
> to handle memory being modifiable by concurrently running C++ programs
> would be very hard, so I propose that we don=E2=80=99t do that. Rather we=
say that
> objects in mapped storage can only be reachable in exactly one or none
> running C++ programs at a time i.e. at exactly one or no address at any o=
ne
> time, otherwise it is undefined behaviour. Therefore, if process A wants =
to
> make available an object to process B, it unblesses it and tells process
> B that the object is now available for use. Process B blesses the object
> into reachable, and uses it. When done, it unblesses it once more. Now
> process A can bless it and use it again, if so desired.
>
>
> Implied in this is that blessing and unblessing becomes able to rewrite
> the vptr (or whatever the C++ implementation uses to implement
> polymorphism). To be truthful, I am torn on this. On the one hand, if you
> wish to be able to bless and unbless polymorphic objects, rewriting the
> vptr is unavoidable, and the frequency of relocating polymorphic objects =
in
> current C++ is low. On the other hand, future C++=E2=80=99s may do a lot =
more
> remapping of memory during large array expansion in order to skip doing a
> memory copy, and in this circumstance every single polymorphic object in =
a
> few million item array would need their vptr=E2=80=99s needlessly rewritt=
en, which
> is unnecessary work.
>
>
> I=E2=80=99m going to err on the side of caution, and propose that the pol=
ymorphic
> editions of bless and unbless shall be:
>
>
> // Effects: create an object of implicit lifetype type T in the storage
> // pointed to by T, while preserving the object representation
> // apart from any necessary changes to make any polymorphic
> // objects within and including T ready for use.
> template<typename T> T *std::revive(void *p);
>
> // Effects: uncreate an object of implicit lifetype type T in the storage
> // pointed to by T, while preserving the object representation
> // apart from any necessary changes to make any polymorphic
> // functions within the objects within and including T unusable.
> template<typename T> void *std::stun(T *p);
>
>
> Note that stun() and revive() not just change the vptrs of the type you
> pass them, but also any vptrs of any nested types within that type. They
> also perform blessing and unblessing, so you do not have to do that
> separately. Calling these functions on non-polymorphic types is permitted=
..
>
>
> 3.2 New attributes [[no_side_effects]] and [[no_visible_side_effects]],
> and new contract syntax for specifying lack of side effects
>
> It is highly important for the future efficiency of any iostreams v2 that
> the low level i/o functions do not cause the compiler to dump and reload
> all state for every i/o, as they must do at present. The i/o functions
> proposed do not modify their handle on most platforms, and on those
> platforms we can guarantee to the compiler that there are either no side
> effects or no visible side effects except for those objects modified by
> parameters.
>
>
> Reusing bless() and unbless(), I propose the following contracts syntax
> for the io_handle functions so we can tell the compiler what side effects
> the i/o functions have:
>
>
> constexpr! void ensure_blessed(buffers_type buffers)
> {
> for(auto &buffer : buffers)
> {
> bless(buffer.data(), buffer.size());
> }
> }
>
> // This function has no side effects visible to the caller except
> // for the objects it creates in the scatter buffer list.
> virtual buffers_type io_handle::read(io_request<buffers_type> reqs,
> deadline d =3D deadline()) throws(
> file_io_error)
> [[no_side_effects]]
> [[ensures: ensure_blessed(reqs.buffers)]]
> [[ensures: ensure_blessed(return)]];
>
>
> The key thing to note here is if the caller never accesses any of the
> scatter buffers returned by the function, the read can be optimised out
> entirely due to the [[no_side_effects]] attribute. Obviously the compiler
> also does not dump and reload any state around this scatter read apart fr=
om
> buffers supplied and returned, despite it calling a kernel system call,
> because we are giving a hard guarantee to the compiler that it is safe to
> assume no side effects apart from modifying the scatter buffers.
>
>
> Gather write is less exciting, but straightforward:
>
>
> virtual const_buffers_type io_handle::write(io_request<const_buffers_type=
>
> reqs,
> deadline d =3D deadline())
> throws(file_io_error) [[no_visible_side_effect=
s
> ]];
>
>
> Here we are telling the compiler that there are side effects, just not
> ones visible to the caller. Hence the compiler cannot optimise out callin=
g
> this function, but it can skip dumping and reloading state despite the
> kernel system call made by the function.
>
>
> 3.2.1 I/O write reordering barriers
>
> C and C++ allow the programmer to constrain memory read and write
> operations, specifically to constrain the extent of reordering that the
> compiler and CPU are permitted to do. One can use atomics with a memory
> order specified, or one can call a fence function which applies a memory
> reordering constraint for the current thread of execution either at just
> the compiler level, or also at the CPU level whereby the CPU is told what
> ordering its symmetric multiprocessing cores needs to manifest in visible
> side effects.
>
>
> File i/o is no different: concurrent users of the same file or directory
> or file system will experience races unless they take special measures to
> coordinate amongst themselves.
>
>
> Given that I have proposed above that C++ standardises mapped storage
> duration into the language itself, it might seem self evident that one
> would also need to propose a standardised mechanism for indicating
> reordering constraints on i/o, which are separate to those for threads. M=
y
> current advice is that we should not do this =E2=80=93 yet.
>
>
> The first reason why is that persistent memory is just around the corner,
> and I think it would be unwise to standardise without the industry gainin=
g
> plenty of empirical experience first. So kick that decision down a few
> standard releases.
>
> Secondly, the proposed library herein does expose whatever acquire-releas=
e
> semantics is implemented by the host operating system for file i/o, plus
> the advisory locking infrastructure implemented by the host, plus the
> ability to enable write-through caching semantics. It also provides
> barrier(), though one should not write code which relies upon it working,
> as it frequently does not.
>
>
> Note that if the file is opened in non-volatile RAM storage mode, barrier=
()
> calls the appropriate architecture-specific assembler instructions to
> correctly barrier writes to main memory, so in this sense there is librar=
y,
> if not language, support for persistent memory. The obvious sticker is th=
at barrier()
> is a virtual function with significant preamble and epilogue, so for
> flushing a single cache line it is extremely inefficient relative to dire=
ct
> language support for this.
>
> Nevertheless, one can write standards conforming code with the proposed
> library which performs better on persistent memory than on traditional
> storage, and my advice is that this is good enough for the next few years=
..
>
> --
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit
> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/b214ce98-2aa=
a-4f7f-a04a-77687422111a%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/b214ce98-2a=
aa-4f7f-a04a-77687422111a%40isocpp.org?utm_medium=3Demail&utm_source=3Dfoot=
er>
> .
>
--=20
Who=E2=80=99s got the sweetest disposition?
One guess, that=E2=80=99s who?
Who=E2=80=99d never, ever start an argument?
Who never shows a bit of temperament?
Who's never wrong but always right?
Who'd never dream of starting a fight?
Who get stuck with all the bad luck?
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CAFdMc-0j945MOprtHf1w2jx6Qb-DeSKZitKxPMDSJ_v--D3=
Kjw%40mail.gmail.com.
--0000000000006966f6057263fce2
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Though the actual way of recognizing this work would be cu=
rrently reading the proposal, and I will do my best during the weekend, I w=
ill do something that I think is not very common these days: to say an anon=
ymous "thank you" for the (personal) time you took to contribute =
to the C++.<div>Same for all the people putting effort, time and/or money i=
n the progress of the language.</div><div><br></div><div>Sorry for the spam=
to those offended.</div><div><br></div><div>=C2=A0 =C2=A0 Daniel.</div></d=
iv><br><div class=3D"gmail_quote"><div dir=3D"ltr">On Wed, Aug 1, 2018 at 3=
:01 PM Niall Douglas <<a href=3D"mailto:nialldouglas14@gmail.com">nialld=
ouglas14@gmail.com</a>> wrote:<br></div><blockquote class=3D"gmail_quote=
" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><=
div dir=3D"ltr">So assuming people were put off by the length of the paper,=
below is the section I'd really like feedback upon.<div><br></div><div=
>Niall</div><div><br></div><div><br></div><div><h3 class=3D"m_-670148805620=
2737086sectionHead"><span class=3D"m_-6701488056202737086titlemark">3 </s=
pan><a id=3D"m_-6701488056202737086x1-150003"></a>Impact on the Standard</h=
3><p class=3D"m_-6701488056202737086noindent">Listed at the end of this sec=
tion are the in-flight WG21 papers this proposal is dependent upon, and whi=
ch would need to enter the standard before this library can be considered. =
However a bigger issue involves the potential changes to the C++ object mod=
el, plus new contracts with which to indicate the limited side effects of i=
/o functions in order to enable improved optimisation. </p><p class=3D"m_-6=
701488056202737086noindent"><br></p><p class=3D"m_-6701488056202737086noind=
ent"></p><h4 class=3D"m_-6701488056202737086subsectionHead"><span class=3D"=
m_-6701488056202737086titlemark">3.1 </span><a id=3D"m_-67014880562027370=
86x1-160003.1"></a>Potential changes to the C++ object model</h4><p class=
=3D"m_-6701488056202737086noindent">Firstly I wish to make it clear that th=
ere is the viable option of simply making no changes at all to the object m=
odel, and any placement of objects into mapped memory is declared to be und=
efined behaviour, as it is at present<span class=3D"m_-6701488056202737086f=
ootnote-mark"><a><sup class=3D"m_-6701488056202737086textsuperscript">5</su=
p></a></span><a id=3D"m_-6701488056202737086x1-16001f5"></a> . </p><p class=
=3D"m_-6701488056202737086noindent"><br></p><p class=3D"m_-6701488056202737=
086noindent">However I also think that an opportunity missed. Via memory ma=
ps, the proposed low level file i/o library herein enables object lifetime =
to exceed that of the program. It also enables an object to appear in multi=
ple instances of concurrent C++ program execution, or indeed at multiple ad=
dresses within a C++ program. And finally one can mark individual pages of =
memory with different access permissions than read-only or read-write (e.g.=
no access i.e. unreachable), or kick individual pages out to swap, or thro=
w away their contents. In other words, individual pages of memory can becom=
e <span class=3D"m_-6701488056202737086ecti-1095">unreachable </span>with t=
he objects within that storage still being <span class=3D"m_-67014880562027=
37086ecti-1095">alive</span>. </p><p class=3D"m_-6701488056202737086noinden=
t"><br></p><p class=3D"m_-6701488056202737086noindent">All four things are =
problematic for the current C++ standard=E2=80=99s object model, not least =
that objects cannot currently outlive the program; that there is no awarene=
ss of it being possible for multiple concurrent C++ program instances to ex=
ist in the current standard; that objects not marked with <span class=3D"m_=
-6701488056202737086obeylines-h">[[no_unique_address]]</span> and which are=
not bits in a bitfield must currently always have a single, =
=
=
unique address in the process; that all alive objects are equ=
ally reachable from anywhere in the program; and finally that objects are a=
lways available at their unique address, and are not also elsewhere. </p><p=
class=3D"m_-6701488056202737086noindent"><br></p><p class=3D"m_-6701488056=
202737086noindent">Furthermore, there are reordering constraints peculiar t=
o mapped memory if a modification to an object is to persist at all, or ind=
eed in a form which is usable. This is because in most implementations of C=
++, atomic reordering constraints only affect <span class=3D"m_-67014880562=
02737086ecti-1095">apparent </span>ordering to CPU cores within the same sy=
mmetric multiprocessing cluster, and may have no effect on the <span class=
=3D"m_-6701488056202737086ecti-1095">actual </span>ordering of when modific=
ations are sent to main memory and/or the storage device. Thus, if a C++ pr=
ogram modifies an object, and then modifies it again, some of the changes o=
f the latter modification may land in main memory before some of the change=
s of the earlier modification, irrespective of any atomics or fences or any=
thing else which a C++ program currently can legally do. This has obvious i=
mplications for the integrity of that object across a program restart. </p>=
<p class=3D"m_-6701488056202737086noindent"><br></p><p class=3D"m_-67014880=
56202737086noindent">I therefore suggest some changes to the C++ object mod=
el, listed below. </p><p class=3D"m_-6701488056202737086noindent"><br></p><=
h5 class=3D"m_-6701488056202737086subsubsectionHead"><span class=3D"m_-6701=
488056202737086titlemark">3.1.1 </span><a id=3D"m_-6701488056202737086x1-=
170003.1.1"></a>The relevant parts of the current standard</h5><p class=3D"=
m_-6701488056202737086noindent">There are presently four kinds of storage d=
uration. As <span class=3D"m_-6701488056202737086obeylines-h">[basic.stc]</=
span> describes it: </p><p class=3D"m_-6701488056202737086noindent"><b=
r></p><div class=3D"m_-6701488056202737086quote"><p class=3D"m_-67014880562=
02737086noindent"><span class=3D"m_-6701488056202737086ecti-1095">The stora=
ge duration is the property of an object that defines the minimum potential=
lifetime of</span> <span class=3D"m_-6701488056202737086ecti-1095">th=
e storage containing the object. The storage duration is determined by the =
construct used to</span> <span class=3D"m_-6701488056202737086ecti-109=
5">create the object and is one of the following:</span> </p><ol class=
=3D"m_-6701488056202737086enumerate1"><li class=3D"m_-6701488056202737086en=
umerate" id=3D"m_-6701488056202737086x1-17002x1"><span class=3D"m_-67014880=
56202737086ecti-1095">static storage duration</span> </li><li class=3D=
"m_-6701488056202737086enumerate" id=3D"m_-6701488056202737086x1-17004x2"><=
span class=3D"m_-6701488056202737086ecti-1095">thread storage duration</spa=
n> </li><li class=3D"m_-6701488056202737086enumerate" id=3D"m_-6701488=
056202737086x1-17006x3"><span class=3D"m_-6701488056202737086ecti-1095">aut=
omatic storage duration</span> </li><li class=3D"m_-670148805620273708=
6enumerate" id=3D"m_-6701488056202737086x1-17008x4"><span class=3D"m_-67014=
88056202737086ecti-1095">dynamic storage duration</span></li></ol></div><p =
class=3D"m_-6701488056202737086noindent"><span class=3D"m_-6701488056202737=
086obeylines-h">[basic.life]</span> describes in some detail the lifetime m=
odel, and it essentially reduces down to one of these possible states for e=
ach object (and apologies for the over-simplification for purposes of terse=
exposition): </p><p class=3D"m_-6701488056202737086noindent"></p><ol class=
=3D"m_-6701488056202737086enumerate1"><li class=3D"m_-6701488056202737086en=
umerate" id=3D"m_-6701488056202737086x1-17010x1">Unconstructed <span class=
=3D"m_-6701488056202737086ecti-1095">(from P0593: and considered unreachabl=
e by the compiler during analysis)</span>, but =
=
=
storage is of the right size and alignment, and pointers and glvalues t=
o the storage of the object type are permitted to be used under limited=
circumstances. </li><li class=3D"m_-6701488056202737086enumerate" id=
=3D"m_-6701488056202737086x1-17012x2">Unalive, in the process of being cons=
tructed, for types with non-trivial constructors only. </li><li class=
=3D"m_-6701488056202737086enumerate" id=3D"m_-6701488056202737086x1-17014x3=
">Alive, fully constructed. </li><li class=3D"m_-6701488056202737086en=
umerate" id=3D"m_-6701488056202737086x1-17016x4">Unalive, in the process of=
being destructed, for types with non-trivial destructors only.</li></ol><p=
class=3D"m_-6701488056202737086noindent">You will note that due to their t=
riviality, memory storing trivial types such as <span class=3D"m_-670148805=
6202737086fvmr8t-x-x-93">std::byte </span>can either be unconstructed, or f=
ully constructed, and no lifetime state exists apart from those two. It is =
important to understand that currently speaking, using allocated memory in =
which nothing has been constructed is undefined behaviour, so the common me=
thod of reinterpret casting the return from <span class=3D"m_-6701488056202=
737086fvmr8t-x-x-93">malloc() </span>to a pointer of the type you want is p=
resently undefined behaviour. </p><p class=3D"m_-6701488056202737086noinden=
t"><br></p><p class=3D"m_-6701488056202737086noindent">This is being dealt =
with in <span class=3D"m_-6701488056202737086cite">[<a>P0593</a>]</span> <s=
pan class=3D"m_-6701488056202737086ecti-1095">Implicit creation of objects =
for low-level object manipulation</span>. Amongst its many recommendations,=
it makes unconstructed memory <span class=3D"m_-6701488056202737086ecti-10=
95">unreachable </span>by default. You can make it reachable by (i) constru=
cting objects into it (ii) via the proposed <span class=3D"m_-6701488056202=
737086fvmr8t-x-x-93">std::bless() </span>which tells the compiler that a re=
gion of unreachable memory (i.e. unconstructed) is now reachable (and conta=
ins alive trivial objects of some form). You can restore it to being unreac=
hable by calling the destructor of the objects, even if those objects are c=
ompletely trivial. P0593 doesn=E2=80=99t mention it explicitly (yet!), but =
given <span class=3D"m_-6701488056202737086fvmr8t-x-x-93">std::launder</spa=
n>=E2=80=99s special casing for <span class=3D"m_-6701488056202737086fvmr8t=
-x-x-93">std::byte</span>, it seems likely that calling the destructor for =
<span class=3D"m_-6701488056202737086fvmr8t-x-x-93">std::byte </span>on a r=
egion with unknown trivially destructible types of objects in it will alway=
s mark it unreachable. And finally, P0593 names various functions as always=
returning memory which is reachable i.e. containing an array of alive obje=
cts of some unspecified trivial type. </p><p class=3D"m_-670148805620273708=
6noindent"><br></p><p class=3D"m_-6701488056202737086noindent">This new con=
cept of reachable vs unreachable memory is an important one, and it is lean=
ed upon heavily in the proposed extensions. </p><p class=3D"m_-670148805620=
2737086noindent"><br></p><p class=3D"m_-6701488056202737086noindent"></p><h=
5 class=3D"m_-6701488056202737086subsubsectionHead"><span class=3D"m_-67014=
88056202737086titlemark">3.1.2 </span><a id=3D"m_-6701488056202737086x1-1=
80003.1.2"></a>A new storage duration: <span class=3D"m_-670148805620273708=
6ecti-1095">mapped</span></h5><p class=3D"m_-6701488056202737086noindent">A=
s always, naming is very hard, but <span class=3D"m_-6701488056202737086ect=
i-1095">mapped storage duration </span>seems a reasonable name for memory w=
hich can be shared between concurrently running processes, or between multi=
ple start-stop cycles of the same program (note that a program using an obj=
ect from mapped storage which it itself did not store there is undefined be=
haviour). </p><p class=3D"m_-6701488056202737086noindent"><br></p><p class=
=3D"m_-6701488056202737086noindent">The storage for objects with mapped sto=
rage duration shall last for the duration of the filesystem entity (see TS =
definitions below for precise meaning) referred to by the <span class=3D"m_=
-6701488056202737086fvmr8t-x-x-93">section_handle </span>instance which rep=
resents the storage. <span class=3D"m_-6701488056202737086fvmr8t-x-x-93">se=
ction_handle </span>instances may refer to filesystem entities whose lifeti=
mes automatically end when the program ends (=E2=80=98anonymous inodes=E2=
=80=99), or which may persist for an indeterminate period, including across=
subsequent executions of the C++ program. =
=
</p>=
<p class=3D"m_-6701488056202737086noindent"><br></p><p class=3D"m_-67014880=
56202737086noindent">Mapped storage has the most similarity to dynamic stor=
age, but with the following differences: </p><ul class=3D"m_-670148805=
6202737086itemize1"><li class=3D"m_-6701488056202737086itemize">It has allo=
cation and alignment granularities with architecture specific coarse sizes =
(=E2=80=98memory page=E2=80=99). 4Kb/2Mb/1Gb page sizes are common. =
</li><li class=3D"m_-6701488056202737086itemize">New allocations are guar=
anteed to be all bits zero on creation. </li><li class=3D"m_-670148805=
6202737086itemize">It has map on first read semantics. This means that the =
first read from a memory page can take hundreds of CPU cycles, and a TL=
B shootdown causes an interrupt for other CPUs. </li><li class=3D"m_-6=
701488056202737086itemize">It has allocate on first write semantics. This m=
eans that the first write to a memory page can take thousands or even h=
undreds of thousands of CPU cycles, plus a TLB shootdown. </li><li cla=
ss=3D"m_-6701488056202737086itemize">Usually, but not always, mapped storag=
e is a memory cache of equivalent storage a high latency storage device=
.. Hence they can be individually pushed to storage, their contents thrown a=
way, deallocated, given different access permission or caching strategi=
es, and lots of other interesting (i.e. potentially game changing for l=
arge STL containers) operations. Individual pages can be: <ul=
class=3D"m_-6701488056202737086itemize2"><li class=3D"m_-67014880562027370=
86itemize">Read-only, read-write, or copy-on-write. These are self describi=
ng, and these are hard characteristics: violating them means progr=
am failure. </li><li class=3D"m_-6701488056202737086itemize">Comm=
itted or uncommitted. This indicates whether the page counts towar=
ds the resources used by the C++ program. Uncommitted memory is i=
naccessible, and acts as a placeholder for later use (i.e. it is r=
eserved address space, useful for expanding large arrays without c=
ontent copying). </li><li class=3D"m_-6701488056202737086itemize"=
>Dirty or clean. This indicates whether the page contains data not yet mirr=
ored onto its backing storage. </li><li class=3D"m_-6701=
488056202737086itemize">Allocated or unallocated. This indicates whether st=
orage backing the page has been allocated on the storage device. I=
f not, the first write to a clean page may be very expensive as th=
e page may need to be copied by the kernel and/or space allocated for it =
on the backing storage device.</li></ul></li></ul><p class=3D"m_-670=
1488056202737086noindent">The storage represented by a <span class=3D"m_-67=
01488056202737086fvmr8t-x-x-93">section_handle </span>instance can be <span=
class=3D"m_-6701488056202737086ecti-1095">mapped </span>into (i.e. made av=
ailable to) a C++ program by creating a <span class=3D"m_-67014880562027370=
86fvmr8t-x-x-93">map_handle </span>sourcing the storage from a <span class=
=3D"m_-6701488056202737086fvmr8t-x-x-93">section_handle </span>instance. Th=
e storage mapped by the low level <span class=3D"m_-6701488056202737086fvmr=
8t-x-x-93">map_handle </span>shall represent unconstructed and unreachable =
memory, and will =
=
require the use of <span class=
=3D"m_-6701488056202737086fvmr8t-x-x-93">std::bless() </span>or <span class=
=3D"m_-6701488056202737086fvmr8t-x-x-93">map_view<u></u> <u></u></span>to m=
ake it reachable (alternatively, use the convenience class <span class=3D"m=
_-6701488056202737086fvmr8t-x-x-93">mapped<u></u> <u></u></span>on a <span =
class=3D"m_-6701488056202737086fvmr8t-x-x-93">section_handle </span>instanc=
e which bundles the aforementioned low level operations on your behalf). </=
p><p class=3D"m_-6701488056202737086noindent"><br></p><p class=3D"m_-670148=
8056202737086noindent">Destroying a <span class=3D"m_-6701488056202737086fv=
mr8t-x-x-93">map_view<u></u> <u></u></span>does not make the storage unreac=
hable. Decommitting individual pages does, as does destroying a <span class=
=3D"m_-6701488056202737086fvmr8t-x-x-93">mapped<u></u> <u></u></span>or <sp=
an class=3D"m_-6701488056202737086fvmr8t-x-x-93">map_handle</span>. </p><p =
class=3D"m_-6701488056202737086noindent"><br></p><p class=3D"m_-67014880562=
02737086noindent"></p><h5 class=3D"m_-6701488056202737086subsubsectionHead"=
><span class=3D"m_-6701488056202737086titlemark">3.1.3 </span><a id=3D"m_=
-6701488056202737086x1-190003.1.3"></a>A new lifetime stage: <span class=3D=
"m_-6701488056202737086ecti-1095">unreachable</span></h5><p class=3D"m_-670=
1488056202737086noindent">I propose adding a new separate lifetime status f=
or objects: <span class=3D"m_-6701488056202737086ecti-1095">unreachable</sp=
an>. Under P0593, unconstructed objects are unreachable, but there is no po=
ssibility for a partially constructed, alive or partially destructed object=
to be unreachable. I propose that this new status ought to be added such t=
hat objects can now have the following lifetime states: </p><p class=3D"m_-=
6701488056202737086noindent"></p><ol class=3D"m_-6701488056202737086enumera=
te1"><li class=3D"m_-6701488056202737086enumerate" id=3D"m_-670148805620273=
7086x1-19002x1">Unconstructed, always unreachable. </li><li class=3D"m=
_-6701488056202737086enumerate" id=3D"m_-6701488056202737086x1-19004x2">Una=
live, in the process of being constructed, for types with non-trivial const=
ructors only. Always reachable. </li><li class=3D"m_-6701488056202=
737086enumerate" id=3D"m_-6701488056202737086x1-19006x3">Alive, fully const=
ructed, reachable. Has a single, unique address in memory (unless marked =
with <span class=3D"m_-6701488056202737086obeylines-h">[[no_unique_addres=
s]]</span>). </li><li class=3D"m_-6701488056202737086enumerate" id=3D"=
m_-6701488056202737086x1-19008x4">Alive, fully constructed, unreachable. Do=
es NOT have a single, unique address in memory (it may have many, or no=
ne). May change whilst unreachable (i.e. reload it after marking it rea=
chable at some address). </li><li class=3D"m_-6701488056202737086enume=
rate" id=3D"m_-6701488056202737086x1-19010x5">Unalive, in the process of be=
ing destructed, for types with non-trivial destructors only. Always rea=
chable.</li></ol><p class=3D"m_-6701488056202737086noindent">P0593 proposed=
these functions to mark regions as reachable: </p><p class=3D"m_-670148805=
6202737086noindent"><br></p><div class=3D"m_-6701488056202737086lstlisting"=
id=3D"m_-6701488056202737086listing-10"><div class=3D"m_-67014880562027370=
86prettyprint" style=3D"background-color:rgb(250,250,250);border-color:rgb(=
187,187,187);border-style:solid;border-width:1px;word-wrap:break-word"><cod=
e class=3D"m_-6701488056202737086prettyprint"><div class=3D"m_-670148805620=
2737086subprettyprint"><span style=3D"color:#800" class=3D"m_-6701488056202=
737086styled-by-prettify">// Requires: [start, (char*)start + length) denot=
es a region of allocated </span><span style=3D"color:#000" class=3D"m_-6701=
488056202737086styled-by-prettify"><br></span><span style=3D"color:#800" cl=
ass=3D"m_-6701488056202737086styled-by-prettify">// storage that is a subse=
t of the region of storage reachable through start. </span><span style=3D"c=
olor:#000" class=3D"m_-6701488056202737086styled-by-prettify"><br></span><s=
pan style=3D"color:#800" class=3D"m_-6701488056202737086styled-by-prettify"=
>// Effects: implicitly creates objects within the denoted region. </span><=
span style=3D"color:#000" class=3D"m_-6701488056202737086styled-by-prettify=
"><br></span><span style=3D"color:#008" class=3D"m_-6701488056202737086styl=
ed-by-prettify">void</span><span style=3D"color:#000" class=3D"m_-670148805=
6202737086styled-by-prettify"> std</span><span style=3D"color:#660" class=
=3D"m_-6701488056202737086styled-by-prettify">::</span><span style=3D"color=
:#000" class=3D"m_-6701488056202737086styled-by-prettify">bless</span><span=
style=3D"color:#660" class=3D"m_-6701488056202737086styled-by-prettify">(<=
/span><span style=3D"color:#008" class=3D"m_-6701488056202737086styled-by-p=
rettify">void</span><span style=3D"color:#000" class=3D"m_-6701488056202737=
086styled-by-prettify"> </span><span style=3D"color:#660" class=3D"m_-67014=
88056202737086styled-by-prettify">*</span><span style=3D"color:#000" class=
=3D"m_-6701488056202737086styled-by-prettify">start</span><span style=3D"co=
lor:#660" class=3D"m_-6701488056202737086styled-by-prettify">,</span><span =
style=3D"color:#000" class=3D"m_-6701488056202737086styled-by-prettify"> si=
ze_t length</span><span style=3D"color:#660" class=3D"m_-670148805620273708=
6styled-by-prettify">);</span><span style=3D"color:#000" class=3D"m_-670148=
8056202737086styled-by-prettify"> <br>=C2=A0<br></span><span style=3D"color=
:#800" class=3D"m_-6701488056202737086styled-by-prettify">// Effects: creat=
e an object of implicit lifetype type T in the storage </span><span style=
=3D"color:#000" class=3D"m_-6701488056202737086styled-by-prettify"><br></sp=
an><span style=3D"color:#800" class=3D"m_-6701488056202737086styled-by-pret=
tify">// =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0pointed to by T, while preservin=
g the object representation. </span><span style=3D"color:#000" class=3D"m_-=
6701488056202737086styled-by-prettify"><br></span><span style=3D"color:#008=
" class=3D"m_-6701488056202737086styled-by-prettify">template</span><span s=
tyle=3D"color:#660" class=3D"m_-6701488056202737086styled-by-prettify"><=
</span><span style=3D"color:#008" class=3D"m_-6701488056202737086styled-by-=
prettify">typename</span><span style=3D"color:#000" class=3D"m_-67014880562=
02737086styled-by-prettify"> T</span><span style=3D"color:#660" class=3D"m_=
-6701488056202737086styled-by-prettify">></span><span style=3D"color:#00=
0" class=3D"m_-6701488056202737086styled-by-prettify"> T </span><span style=
=3D"color:#660" class=3D"m_-6701488056202737086styled-by-prettify">*</span>=
<span style=3D"color:#000" class=3D"m_-6701488056202737086styled-by-prettif=
y">std</span><span style=3D"color:#660" class=3D"m_-6701488056202737086styl=
ed-by-prettify">::</span><span style=3D"color:#000" class=3D"m_-67014880562=
02737086styled-by-prettify">bless</span><span style=3D"color:#660" class=3D=
"m_-6701488056202737086styled-by-prettify">(</span><span style=3D"color:#00=
8" class=3D"m_-6701488056202737086styled-by-prettify">void</span><span styl=
e=3D"color:#000" class=3D"m_-6701488056202737086styled-by-prettify"> </span=
><span style=3D"color:#660" class=3D"m_-6701488056202737086styled-by-pretti=
fy">*</span><span style=3D"color:#000" class=3D"m_-6701488056202737086style=
d-by-prettify">p</span><span style=3D"color:#660" class=3D"m_-6701488056202=
737086styled-by-prettify">);</span></div></code></div><span class=3D"m_-670=
1488056202737086fvmr8t-x-x-76"><br></span> </div><div class=3D"m_-670148805=
6202737086lstlisting" id=3D"m_-6701488056202737086listing-10"><span class=
=3D"m_-6701488056202737086fvmr8t-x-x-76"><br></span></div><p class=3D"m_-67=
01488056202737086noindent">Thus the obvious corrollary for marking regions =
as unreachable: </p><p class=3D"m_-6701488056202737086noindent"><br></p><di=
v class=3D"m_-6701488056202737086prettyprint" style=3D"background-color:rgb=
(250,250,250);border-color:rgb(187,187,187);border-style:solid;border-width=
:1px;word-wrap:break-word"><code class=3D"m_-6701488056202737086prettyprint=
"><div class=3D"m_-6701488056202737086subprettyprint"><span style=3D"color:=
#800" class=3D"m_-6701488056202737086styled-by-prettify">// Requires: [star=
t, (char*)start + length) denotes a region of allocated </span><span style=
=3D"color:#000" class=3D"m_-6701488056202737086styled-by-prettify"><br></sp=
an><span style=3D"color:#800" class=3D"m_-6701488056202737086styled-by-pret=
tify">// storage that is a subset of the region of storage reachable throug=
h start. </span><span style=3D"color:#000" class=3D"m_-6701488056202737086s=
tyled-by-prettify"><br></span><span style=3D"color:#800" class=3D"m_-670148=
8056202737086styled-by-prettify">// Effects: implicitly uncreates objects w=
ithin the denoted region. </span><span style=3D"color:#000" class=3D"m_-670=
1488056202737086styled-by-prettify"><br></span><span style=3D"color:#008" c=
lass=3D"m_-6701488056202737086styled-by-prettify">void</span><span style=3D=
"color:#000" class=3D"m_-6701488056202737086styled-by-prettify"> std</span>=
<span style=3D"color:#660" class=3D"m_-6701488056202737086styled-by-prettif=
y">::</span><span style=3D"color:#000" class=3D"m_-6701488056202737086style=
d-by-prettify">unbless</span><span style=3D"color:#660" class=3D"m_-6701488=
056202737086styled-by-prettify">(</span><span style=3D"color:#008" class=3D=
"m_-6701488056202737086styled-by-prettify">void</span><span style=3D"color:=
#000" class=3D"m_-6701488056202737086styled-by-prettify"> </span><span styl=
e=3D"color:#660" class=3D"m_-6701488056202737086styled-by-prettify">*</span=
><span style=3D"color:#000" class=3D"m_-6701488056202737086styled-by-pretti=
fy">start</span><span style=3D"color:#660" class=3D"m_-6701488056202737086s=
tyled-by-prettify">,</span><span style=3D"color:#000" class=3D"m_-670148805=
6202737086styled-by-prettify"> size_t length</span><span style=3D"color:#66=
0" class=3D"m_-6701488056202737086styled-by-prettify">);</span><span style=
=3D"color:#000" class=3D"m_-6701488056202737086styled-by-prettify"> <br>=C2=
=A0<br></span><span style=3D"color:#800" class=3D"m_-6701488056202737086sty=
led-by-prettify">// Effects: uncreate an object of implicit lifetype type T=
in the storage </span><span style=3D"color:#000" class=3D"m_-6701488056202=
737086styled-by-prettify"><br></span><span style=3D"color:#800" class=3D"m_=
-6701488056202737086styled-by-prettify">// =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0pointed to by T, while preserving the object representation. </span><spa=
n style=3D"color:#000" class=3D"m_-6701488056202737086styled-by-prettify"><=
br></span><span style=3D"color:#008" class=3D"m_-6701488056202737086styled-=
by-prettify">template</span><span style=3D"color:#660" class=3D"m_-67014880=
56202737086styled-by-prettify"><</span><span style=3D"color:#008" class=
=3D"m_-6701488056202737086styled-by-prettify">typename</span><span style=3D=
"color:#000" class=3D"m_-6701488056202737086styled-by-prettify"> T</span><s=
pan style=3D"color:#660" class=3D"m_-6701488056202737086styled-by-prettify"=
>></span><span style=3D"color:#000" class=3D"m_-6701488056202737086style=
d-by-prettify"> </span><span style=3D"color:#008" class=3D"m_-6701488056202=
737086styled-by-prettify">void</span><span style=3D"color:#000" class=3D"m_=
-6701488056202737086styled-by-prettify"> </span><span style=3D"color:#660" =
class=3D"m_-6701488056202737086styled-by-prettify">*</span><span style=3D"c=
olor:#000" class=3D"m_-6701488056202737086styled-by-prettify">std</span><sp=
an style=3D"color:#660" class=3D"m_-6701488056202737086styled-by-prettify">=
::</span><span style=3D"color:#000" class=3D"m_-6701488056202737086styled-b=
y-prettify">unbless</span><span style=3D"color:#660" class=3D"m_-6701488056=
202737086styled-by-prettify">(</span><span style=3D"color:#000" class=3D"m_=
-6701488056202737086styled-by-prettify">T </span><span style=3D"color:#660"=
class=3D"m_-6701488056202737086styled-by-prettify">*</span><span style=3D"=
color:#000" class=3D"m_-6701488056202737086styled-by-prettify">p</span><spa=
n style=3D"color:#660" class=3D"m_-6701488056202737086styled-by-prettify">)=
;</span><span style=3D"color:#000" class=3D"m_-6701488056202737086styled-by=
-prettify"> <br></span></div></code></div><div class=3D"m_-6701488056202737=
086lstlisting" id=3D"m_-6701488056202737086listing-11"><br><span class=3D"m=
_-6701488056202737086fvmr8t-x-x-76"><br></span></div><p class=3D"m_-6701488=
056202737086noindent">A gain of this new unreachable lifetime status is tha=
t it neatly solves the problem of objects appearing at multiple addresses i=
n a running program. We can now say that only one of those addresses can be=
reachable for an alive object at a time. If a program wishes to change an =
object=E2=80=99s current reachable address, they unbless the old location, =
and bless the new location. </p><p class=3D"m_-6701488056202737086noindent"=
><br></p><p class=3D"m_-6701488056202737086noindent">It should be emphasise=
d that similarly to blessing, unblessing of trivial types causes no code em=
ission. It simply tells the compiler what is now unreachable. </p><p class=
=3D"m_-6701488056202737086noindent"><br></p><p class=3D"m_-6701488056202737=
086noindent">Finally, it may seem that unreachability is a bit of a big sle=
dgehammer to throw at this problem. However, there are a number of other pr=
oblems elsewhere in C++ where having unreachable but alive objects would be=
very useful =E2=80=93 thread local storage on a million CPU core compute r=
esource is an excellent example<span class=3D"m_-6701488056202737086footnot=
e-mark"><a><sup class=3D"m_-6701488056202737086textsuperscript">6</sup></a>=
</span><a id=3D"m_-6701488056202737086x1-19027f6"></a> . That said, this is=
a big change to lifetime, and if strong arguments are made against it then=
I am happy to propose something more conservative. </p><p class=3D"m_-6701=
488056202737086noindent"><br></p><h5 class=3D"m_-6701488056202737086subsubs=
ectionHead"><span class=3D"m_-6701488056202737086titlemark">3.1.4 </span>=
<a id=3D"m_-6701488056202737086x1-200003.1.4"></a>Blessing and unblessing p=
olymorphic objects</h5><p class=3D"m_-6701488056202737086noindent">Currentl=
y P0593 makes no mention of polymorphic objects i.e. ones with vptrs in man=
y implementations. I can see lots of reasons why it would be useful to bles=
s and unbless polymorphic objects i.e. update the vptr to the correct one f=
or the currently running program, or clear the vptr to the system null poin=
ter. </p><p class=3D"m_-6701488056202737086noindent"><br></p><p class=3D"m_=
-6701488056202737086noindent">Imagine, for example, a polymorphic object wi=
th mapped storage duration whose constructing program instance terminates. =
Upon restart of the program, the storage is mapped back into the program, b=
ut now the polymorphic object has the wrong vptr! So we need to write the c=
orrect vptr for that object, after which all works as expected<span class=
=3D"m_-6701488056202737086footnote-mark"><a><sup class=3D"m_-67014880562027=
37086textsuperscript">7</sup></a></span><a id=3D"m_-6701488056202737086x1-2=
0001f7"></a> . </p><p class=3D"m_-6701488056202737086noindent"><br></p><p c=
lass=3D"m_-6701488056202737086noindent">This also applies to shared mapped =
memory. Extending the C++ object model to handle memory being modifiable by=
concurrently running C++ programs would be very hard, so I propose that we=
don=E2=80=99t do that. Rather we say that objects in mapped storage can on=
ly be reachable in exactly one or none running C++ programs at a time i.e. =
at exactly one or no address at any one time, otherwise it is undefined =
=
=
behaviour. Therefore, if process A wants to make a=
vailable an object to process B, it <span class=3D"m_-6701488056202737086ec=
ti-1095">unblesses </span>it and tells process B that the object is now ava=
ilable for use. Process B blesses the object into reachable, and uses it. W=
hen done, it unblesses it once more. Now process A can bless it and use it =
again, if so desired. </p><p class=3D"m_-6701488056202737086noindent"><br><=
/p><p class=3D"m_-6701488056202737086noindent">Implied in this is that bles=
sing and unblessing becomes able to rewrite the vptr (or whatever the C++ i=
mplementation uses to implement polymorphism). To be truthful, I am torn on=
this. On the one hand, if you wish to be able to bless and unbless polymor=
phic objects, rewriting the vptr is unavoidable, and the frequency of reloc=
ating polymorphic objects in current C++ is low. On the other hand, future =
C++=E2=80=99s may do a lot more remapping of memory during large array expa=
nsion in order to skip doing a memory copy, and in this circumstance every =
single polymorphic object in a few million item array would need their vptr=
=E2=80=99s needlessly rewritten, which is unnecessary work. </p><p class=3D=
"m_-6701488056202737086noindent"><br></p><p class=3D"m_-6701488056202737086=
noindent">I=E2=80=99m going to err on the side of caution, and propose that=
the polymorphic editions of bless and unbless shall be: </p><p class=3D"m_=
-6701488056202737086noindent"><br></p><div class=3D"m_-6701488056202737086l=
stlisting" id=3D"m_-6701488056202737086listing-12"><div class=3D"m_-6701488=
056202737086prettyprint" style=3D"background-color:rgb(250,250,250);border-=
color:rgb(187,187,187);border-style:solid;border-width:1px;word-wrap:break-=
word"><code class=3D"m_-6701488056202737086prettyprint"><div class=3D"m_-67=
01488056202737086subprettyprint"><span style=3D"color:#800" class=3D"m_-670=
1488056202737086styled-by-prettify">// Effects: create an object of implici=
t lifetype type T in the storage </span><span style=3D"color:#000" class=3D=
"m_-6701488056202737086styled-by-prettify"><br></span><span style=3D"color:=
#800" class=3D"m_-6701488056202737086styled-by-prettify">// =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0pointed to by T, while preserving the object representa=
tion </span><span style=3D"color:#000" class=3D"m_-6701488056202737086style=
d-by-prettify"><br></span><span style=3D"color:#800" class=3D"m_-6701488056=
202737086styled-by-prettify">// =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0apart fro=
m any necessary changes to make any polymorphic </span><span style=3D"color=
:#000" class=3D"m_-6701488056202737086styled-by-prettify"><br></span><span =
style=3D"color:#800" class=3D"m_-6701488056202737086styled-by-prettify">// =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0objects within and including T ready for =
use. </span><span style=3D"color:#000" class=3D"m_-6701488056202737086style=
d-by-prettify"><br></span><span style=3D"color:#008" class=3D"m_-6701488056=
202737086styled-by-prettify">template</span><span style=3D"color:#660" clas=
s=3D"m_-6701488056202737086styled-by-prettify"><</span><span style=3D"co=
lor:#008" class=3D"m_-6701488056202737086styled-by-prettify">typename</span=
><span style=3D"color:#000" class=3D"m_-6701488056202737086styled-by-pretti=
fy"> T</span><span style=3D"color:#660" class=3D"m_-6701488056202737086styl=
ed-by-prettify">></span><span style=3D"color:#000" class=3D"m_-670148805=
6202737086styled-by-prettify"> T </span><span style=3D"color:#660" class=3D=
"m_-6701488056202737086styled-by-prettify">*</span><span style=3D"color:#00=
0" class=3D"m_-6701488056202737086styled-by-prettify">std</span><span style=
=3D"color:#660" class=3D"m_-6701488056202737086styled-by-prettify">::</span=
><span style=3D"color:#000" class=3D"m_-6701488056202737086styled-by-pretti=
fy">revive</span><span style=3D"color:#660" class=3D"m_-6701488056202737086=
styled-by-prettify">(</span><span style=3D"color:#008" class=3D"m_-67014880=
56202737086styled-by-prettify">void</span><span style=3D"color:#000" class=
=3D"m_-6701488056202737086styled-by-prettify"> </span><span style=3D"color:=
#660" class=3D"m_-6701488056202737086styled-by-prettify">*</span><span styl=
e=3D"color:#000" class=3D"m_-6701488056202737086styled-by-prettify">p</span=
><span style=3D"color:#660" class=3D"m_-6701488056202737086styled-by-pretti=
fy">);</span><span style=3D"color:#000" class=3D"m_-6701488056202737086styl=
ed-by-prettify"> <br>=C2=A0<br></span><span style=3D"color:#800" class=3D"m=
_-6701488056202737086styled-by-prettify">// Effects: uncreate an object of =
implicit lifetype type T in the storage </span><span style=3D"color:#000" c=
lass=3D"m_-6701488056202737086styled-by-prettify"><br></span><span style=3D=
"color:#800" class=3D"m_-6701488056202737086styled-by-prettify">// =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0pointed to by T, while preserving the object rep=
resentation </span><span style=3D"color:#000" class=3D"m_-67014880562027370=
86styled-by-prettify"><br></span><span style=3D"color:#800" class=3D"m_-670=
1488056202737086styled-by-prettify">// =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ap=
art from any necessary changes to make any polymorphic </span><span style=
=3D"color:#000" class=3D"m_-6701488056202737086styled-by-prettify"><br></sp=
an><span style=3D"color:#800" class=3D"m_-6701488056202737086styled-by-pret=
tify">// =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0functions within the objects wit=
hin and including T unusable. </span><span style=3D"color:#000" class=3D"m_=
-6701488056202737086styled-by-prettify"><br></span><span style=3D"color:#00=
8" class=3D"m_-6701488056202737086styled-by-prettify">template</span><span =
style=3D"color:#660" class=3D"m_-6701488056202737086styled-by-prettify"><=
;</span><span style=3D"color:#008" class=3D"m_-6701488056202737086styled-by=
-prettify">typename</span><span style=3D"color:#000" class=3D"m_-6701488056=
202737086styled-by-prettify"> T</span><span style=3D"color:#660" class=3D"m=
_-6701488056202737086styled-by-prettify">></span><span style=3D"color:#0=
00" class=3D"m_-6701488056202737086styled-by-prettify"> </span><span style=
=3D"color:#008" class=3D"m_-6701488056202737086styled-by-prettify">void</sp=
an><span style=3D"color:#000" class=3D"m_-6701488056202737086styled-by-pret=
tify"> </span><span style=3D"color:#660" class=3D"m_-6701488056202737086sty=
led-by-prettify">*</span><span style=3D"color:#000" class=3D"m_-67014880562=
02737086styled-by-prettify">std</span><span style=3D"color:#660" class=3D"m=
_-6701488056202737086styled-by-prettify">::</span><span style=3D"color:#000=
" class=3D"m_-6701488056202737086styled-by-prettify">stun</span><span style=
=3D"color:#660" class=3D"m_-6701488056202737086styled-by-prettify">(</span>=
<span style=3D"color:#000" class=3D"m_-6701488056202737086styled-by-prettif=
y">T </span><span style=3D"color:#660" class=3D"m_-6701488056202737086style=
d-by-prettify">*</span><span style=3D"color:#000" class=3D"m_-6701488056202=
737086styled-by-prettify">p</span><span style=3D"color:#660" class=3D"m_-67=
01488056202737086styled-by-prettify">);</span></div></code></div><span clas=
s=3D"m_-6701488056202737086fvmr8t-x-x-76"><br></span> </div><div class=3D"m=
_-6701488056202737086lstlisting" id=3D"m_-6701488056202737086listing-12"><s=
pan class=3D"m_-6701488056202737086fvmr8t-x-x-76"><br></span></div><p class=
=3D"m_-6701488056202737086noindent">Note that <span class=3D"m_-67014880562=
02737086fvmr8t-x-x-93">stun() </span>and <span class=3D"m_-6701488056202737=
086fvmr8t-x-x-93">revive() </span>not just change the vptrs of the type you=
pass them, but also any vptrs of any nested types within that type. They a=
lso perform blessing and unblessing, so you do not have to do that separate=
ly. Calling these functions on non-polymorphic types is permitted. </p><p c=
lass=3D"m_-6701488056202737086noindent"><br></p><h4 class=3D"m_-67014880562=
02737086subsectionHead"><span class=3D"m_-6701488056202737086titlemark">3.2=
</span><a id=3D"m_-6701488056202737086x1-210003.2"></a>New attributes <s=
pan class=3D"m_-6701488056202737086fvmr8t-x-x-93">[[no_side_effects]] </spa=
n>and <span class=3D"m_-6701488056202737086fvmr8t-x-x-93">[[no_visible_side=
_effects]]</span>, and new contract syntax for specifying lack of side effe=
cts</h4><p class=3D"m_-6701488056202737086noindent">It is highly important =
for the future efficiency of any iostreams v2 that the low level i/o functi=
ons do not cause the compiler to dump and reload all state for every i/o, a=
s they must do at present. The i/o functions proposed do not modify their h=
andle on most platforms, and on those platforms we can guarantee to the com=
piler that there are either no side effects or no visible side effects exce=
pt for those objects modified by parameters. </p><p class=3D"m_-67014880562=
02737086noindent"><br></p><p class=3D"m_-6701488056202737086noindent">Reusi=
ng <span class=3D"m_-6701488056202737086fvmr8t-x-x-93">bless() </span>and <=
span class=3D"m_-6701488056202737086fvmr8t-x-x-93">unbless()</span>, I prop=
ose the following contracts syntax for the <span class=3D"m_-67014880562027=
37086fvmr8t-x-x-93">io_handle </span>functions so we can tell the compiler =
what side effects the i/o functions have: </p><p class=3D"m_-67014880562027=
37086noindent"><br></p><div class=3D"m_-6701488056202737086lstlisting" id=
=3D"m_-6701488056202737086listing-13"><div class=3D"m_-6701488056202737086p=
rettyprint" style=3D"background-color:rgb(250,250,250);border-color:rgb(187=
,187,187);border-style:solid;border-width:1px;word-wrap:break-word"><code c=
lass=3D"m_-6701488056202737086prettyprint"><div class=3D"m_-670148805620273=
7086subprettyprint"><span style=3D"color:#008" class=3D"m_-6701488056202737=
086styled-by-prettify">constexpr</span><span style=3D"color:#660" class=3D"=
m_-6701488056202737086styled-by-prettify">!</span><span style=3D"color:#000=
" class=3D"m_-6701488056202737086styled-by-prettify"> </span><span style=3D=
"color:#008" class=3D"m_-6701488056202737086styled-by-prettify">void</span>=
<span style=3D"color:#000" class=3D"m_-6701488056202737086styled-by-prettif=
y"> ensure_blessed</span><span style=3D"color:#660" class=3D"m_-67014880562=
02737086styled-by-prettify">(</span><span style=3D"color:#000" class=3D"m_-=
6701488056202737086styled-by-prettify">buffers_type buffers</span><span sty=
le=3D"color:#660" class=3D"m_-6701488056202737086styled-by-prettify">)</spa=
n><span style=3D"color:#000" class=3D"m_-6701488056202737086styled-by-prett=
ify"> <br></span><span style=3D"color:#660" class=3D"m_-6701488056202737086=
styled-by-prettify">{</span><span style=3D"color:#000" class=3D"m_-67014880=
56202737086styled-by-prettify"> <br>=C2=A0 </span><span style=3D"color:#008=
" class=3D"m_-6701488056202737086styled-by-prettify">for</span><span style=
=3D"color:#660" class=3D"m_-6701488056202737086styled-by-prettify">(</span>=
<span style=3D"color:#008" class=3D"m_-6701488056202737086styled-by-prettif=
y">auto</span><span style=3D"color:#000" class=3D"m_-6701488056202737086sty=
led-by-prettify"> </span><span style=3D"color:#660" class=3D"m_-67014880562=
02737086styled-by-prettify">&</span><span style=3D"color:#000" class=3D=
"m_-6701488056202737086styled-by-prettify">buffer </span><span style=3D"col=
or:#660" class=3D"m_-6701488056202737086styled-by-prettify">:</span><span s=
tyle=3D"color:#000" class=3D"m_-6701488056202737086styled-by-prettify"> buf=
fers</span><span style=3D"color:#660" class=3D"m_-6701488056202737086styled=
-by-prettify">)</span><span style=3D"color:#000" class=3D"m_-67014880562027=
37086styled-by-prettify"> <br>=C2=A0 </span><span style=3D"color:#660" clas=
s=3D"m_-6701488056202737086styled-by-prettify">{</span><span style=3D"color=
:#000" class=3D"m_-6701488056202737086styled-by-prettify"> <br>=C2=A0 =C2=
=A0 bless</span><span style=3D"color:#660" class=3D"m_-6701488056202737086s=
tyled-by-prettify">(</span><span style=3D"color:#000" class=3D"m_-670148805=
6202737086styled-by-prettify">buffer</span><span style=3D"color:#660" class=
=3D"m_-6701488056202737086styled-by-prettify">.</span><span style=3D"color:=
#000" class=3D"m_-6701488056202737086styled-by-prettify">data</span><span s=
tyle=3D"color:#660" class=3D"m_-6701488056202737086styled-by-prettify">(),<=
/span><span style=3D"color:#000" class=3D"m_-6701488056202737086styled-by-p=
rettify"> buffer</span><span style=3D"color:#660" class=3D"m_-6701488056202=
737086styled-by-prettify">.</span><span style=3D"color:#000" class=3D"m_-67=
01488056202737086styled-by-prettify">size</span><span style=3D"color:#660" =
class=3D"m_-6701488056202737086styled-by-prettify">());</span><span style=
=3D"color:#000" class=3D"m_-6701488056202737086styled-by-prettify"> <br>=C2=
=A0 </span><span style=3D"color:#660" class=3D"m_-6701488056202737086styled=
-by-prettify">}</span><span style=3D"color:#000" class=3D"m_-67014880562027=
37086styled-by-prettify"> <br></span><span style=3D"color:#660" class=3D"m_=
-6701488056202737086styled-by-prettify">}</span><span style=3D"color:#000" =
class=3D"m_-6701488056202737086styled-by-prettify"> <br>=C2=A0<br></span><s=
pan style=3D"color:#800" class=3D"m_-6701488056202737086styled-by-prettify"=
>// This function has no side effects visible to the caller except </span><=
span style=3D"color:#000" class=3D"m_-6701488056202737086styled-by-prettify=
"><br></span><span style=3D"color:#800" class=3D"m_-6701488056202737086styl=
ed-by-prettify">// for the objects it creates in the scatter buffer list. <=
/span><span style=3D"color:#000" class=3D"m_-6701488056202737086styled-by-p=
rettify"><br></span><span style=3D"color:#008" class=3D"m_-6701488056202737=
086styled-by-prettify">virtual</span><span style=3D"color:#000" class=3D"m_=
-6701488056202737086styled-by-prettify"> buffers_type io_handle</span><span=
style=3D"color:#660" class=3D"m_-6701488056202737086styled-by-prettify">::=
</span><span style=3D"color:#000" class=3D"m_-6701488056202737086styled-by-=
prettify">read</span><span style=3D"color:#660" class=3D"m_-670148805620273=
7086styled-by-prettify">(</span><span style=3D"color:#000" class=3D"m_-6701=
488056202737086styled-by-prettify">io_request</span><span style=3D"color:#0=
80" class=3D"m_-6701488056202737086styled-by-prettify"><buffers_type>=
</span><span style=3D"color:#000" class=3D"m_-6701488056202737086styled-by-=
prettify"> reqs</span><span style=3D"color:#660" class=3D"m_-67014880562027=
37086styled-by-prettify">,</span><span style=3D"color:#000" class=3D"m_-670=
1488056202737086styled-by-prettify"> <br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0deadline d </span><span style=3D"color:#660" class=
=3D"m_-6701488056202737086styled-by-prettify">=3D</span><span style=3D"colo=
r:#000" class=3D"m_-6701488056202737086styled-by-prettify"> deadline</span>=
<span style=3D"color:#660" class=3D"m_-6701488056202737086styled-by-prettif=
y">())</span><span style=3D"color:#000" class=3D"m_-6701488056202737086styl=
ed-by-prettify"> </span><span style=3D"color:#008" class=3D"m_-670148805620=
2737086styled-by-prettify">throws</span><span style=3D"color:#660" class=3D=
"m_-6701488056202737086styled-by-prettify">(</span><span style=3D"color:#00=
0" class=3D"m_-6701488056202737086styled-by-prettify">file_io_error</span><=
span style=3D"color:#660" class=3D"m_-6701488056202737086styled-by-prettify=
">)</span><span style=3D"color:#000" class=3D"m_-6701488056202737086styled-=
by-prettify"> <br>=C2=A0 =C2=A0 </span><span style=3D"color:#660" class=3D"=
m_-6701488056202737086styled-by-prettify">[[</span><span style=3D"color:#00=
0" class=3D"m_-6701488056202737086styled-by-prettify">no_side_effects</span=
><span style=3D"color:#660" class=3D"m_-6701488056202737086styled-by-pretti=
fy">]]</span><span style=3D"color:#000" class=3D"m_-6701488056202737086styl=
ed-by-prettify"> <br>=C2=A0 =C2=A0 </span><span style=3D"color:#660" class=
=3D"m_-6701488056202737086styled-by-prettify">[[</span><span style=3D"color=
:#000" class=3D"m_-6701488056202737086styled-by-prettify">ensures</span><sp=
an style=3D"color:#660" class=3D"m_-6701488056202737086styled-by-prettify">=
:</span><span style=3D"color:#000" class=3D"m_-6701488056202737086styled-by=
-prettify"> ensure_blessed</span><span style=3D"color:#660" class=3D"m_-670=
1488056202737086styled-by-prettify">(</span><span style=3D"color:#000" clas=
s=3D"m_-6701488056202737086styled-by-prettify">reqs</span><span style=3D"co=
lor:#660" class=3D"m_-6701488056202737086styled-by-prettify">.</span><span =
style=3D"color:#000" class=3D"m_-6701488056202737086styled-by-prettify">buf=
fers</span><span style=3D"color:#660" class=3D"m_-6701488056202737086styled=
-by-prettify">)]]</span><span style=3D"color:#000" class=3D"m_-670148805620=
2737086styled-by-prettify"> <br>=C2=A0 =C2=A0 </span><span style=3D"color:#=
660" class=3D"m_-6701488056202737086styled-by-prettify">[[</span><span styl=
e=3D"color:#000" class=3D"m_-6701488056202737086styled-by-prettify">ensures=
</span><span style=3D"color:#660" class=3D"m_-6701488056202737086styled-by-=
prettify">:</span><span style=3D"color:#000" class=3D"m_-670148805620273708=
6styled-by-prettify"> ensure_blessed</span><span style=3D"color:#660" class=
=3D"m_-6701488056202737086styled-by-prettify">(</span><span style=3D"color:=
#008" class=3D"m_-6701488056202737086styled-by-prettify">return</span><span=
style=3D"color:#660" class=3D"m_-6701488056202737086styled-by-prettify">)]=
];</span></div></code></div><span class=3D"m_-6701488056202737086fvmr8t-x-x=
-76"><br></span> </div><div class=3D"m_-6701488056202737086lstlisting" id=
=3D"m_-6701488056202737086listing-13"><span class=3D"m_-6701488056202737086=
fvmr8t-x-x-76"><br></span></div><p class=3D"m_-6701488056202737086noindent"=
>The key thing to note here is if the caller never accesses any of the scat=
ter buffers returned by the function, =
=
the read =
can be optimised out entirely due to the <span class=3D"m_-6701488056202737=
086fvmr8t-x-x-93">[[no_side_effects]] </span>attribute. Obviously the compi=
ler also does not dump and reload any state around this scatter read apart =
from buffers supplied and returned, despite it calling a kernel system call=
, because we are giving a hard guarantee to the compiler that it is safe to=
assume no side effects apart from modifying the scatter buffers. </p><p cl=
ass=3D"m_-6701488056202737086noindent"><br></p><p class=3D"m_-6701488056202=
737086noindent">Gather write is less exciting, but straightforward: </p><p =
class=3D"m_-6701488056202737086noindent"><br></p><div class=3D"m_-670148805=
6202737086prettyprint" style=3D"background-color:rgb(250,250,250);border-co=
lor:rgb(187,187,187);border-style:solid;border-width:1px;word-wrap:break-wo=
rd"><code class=3D"m_-6701488056202737086prettyprint"><div class=3D"m_-6701=
488056202737086subprettyprint"><span style=3D"color:#008" class=3D"m_-67014=
88056202737086styled-by-prettify">virtual</span><span style=3D"color:#000" =
class=3D"m_-6701488056202737086styled-by-prettify"> const_buffers_type io_h=
andle</span><span style=3D"color:#660" class=3D"m_-6701488056202737086style=
d-by-prettify">::</span><span style=3D"color:#000" class=3D"m_-670148805620=
2737086styled-by-prettify">write</span><span style=3D"color:#660" class=3D"=
m_-6701488056202737086styled-by-prettify">(</span><span style=3D"color:#000=
" class=3D"m_-6701488056202737086styled-by-prettify">io_request</span><span=
style=3D"color:#080" class=3D"m_-6701488056202737086styled-by-prettify">&l=
t;const_buffers_type></span><span style=3D"color:#000" class=3D"m_-67014=
88056202737086styled-by-prettify"> reqs</span><span style=3D"color:#660" cl=
ass=3D"m_-6701488056202737086styled-by-prettify">,</span><span style=3D"col=
or:#000" class=3D"m_-6701488056202737086styled-by-prettify"> <br>=C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 deadl=
ine d </span><span style=3D"color:#660" class=3D"m_-6701488056202737086styl=
ed-by-prettify">=3D</span><span style=3D"color:#000" class=3D"m_-6701488056=
202737086styled-by-prettify"> deadline</span><span style=3D"color:#660" cla=
ss=3D"m_-6701488056202737086styled-by-prettify">())</span><span style=3D"co=
lor:#000" class=3D"m_-6701488056202737086styled-by-prettify"> <br>=C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0</span><span style=3D"color:#008" class=3D"m_-670148805620=
2737086styled-by-prettify">throws</span><span style=3D"color:#660" class=3D=
"m_-6701488056202737086styled-by-prettify">(</span><span style=3D"color:#00=
0" class=3D"m_-6701488056202737086styled-by-prettify">file_io_error</span><=
span style=3D"color:#660" class=3D"m_-6701488056202737086styled-by-prettify=
">)</span><span style=3D"color:#000" class=3D"m_-6701488056202737086styled-=
by-prettify"> </span><span style=3D"color:#660" class=3D"m_-670148805620273=
7086styled-by-prettify">[[</span><span style=3D"color:#000" class=3D"m_-670=
1488056202737086styled-by-prettify">no_visible_side_effects</span><span sty=
le=3D"color:#660" class=3D"m_-6701488056202737086styled-by-prettify">]];</s=
pan><span style=3D"color:#000" class=3D"m_-6701488056202737086styled-by-pre=
ttify"> <br></span></div></code></div><div class=3D"m_-6701488056202737086l=
stlisting" id=3D"m_-6701488056202737086listing-14"><br><span class=3D"m_-67=
01488056202737086fvmr8t-x-x-76"><br></span></div><p class=3D"m_-67014880562=
02737086noindent">Here we are telling the compiler that there are side effe=
cts, just not ones visible to the caller. Hence the compiler cannot optimis=
e out calling this function, but it can skip dumping and reloading state de=
spite the kernel system call made by the function. </p><p class=3D"m_-67014=
88056202737086noindent"><br></p><p class=3D"m_-6701488056202737086noindent"=
></p><h5 class=3D"m_-6701488056202737086subsubsectionHead"><span class=3D"m=
_-6701488056202737086titlemark">3.2.1 </span><a id=3D"m_-6701488056202737=
086x1-220003.2.1"></a>I/O write reordering barriers</h5><p class=3D"m_-6701=
488056202737086noindent">C and C++ allow the programmer to constrain memory=
read and write operations, specifically to constrain the extent of reorder=
ing that the compiler and CPU are permitted to do. One can use atomics with=
a memory order specified, or one can call a fence function which applies a=
memory reordering constraint for the current thread of execution either at=
just the compiler level, or also at the CPU level whereby the CPU is told =
what ordering its symmetric multiprocessing cores needs to manifest in visi=
ble side effects. </p><p class=3D"m_-6701488056202737086noindent"><br></p><=
p class=3D"m_-6701488056202737086noindent">File i/o is no different: concur=
rent users of the same file or directory or file system will experience rac=
es unless they take special measures to coordinate amongst themselves. </p>=
<p class=3D"m_-6701488056202737086noindent"><br></p><p class=3D"m_-67014880=
56202737086noindent">Given that I have proposed above that C++ standardises=
mapped storage duration into the language itself, it might seem self evide=
nt that one would also need to propose a standardised mechanism for indicat=
ing reordering constraints on i/o, which are separate to those for threads.=
My current advice is that we should <span class=3D"m_-6701488056202737086e=
cbx-1095">not </span>do this =E2=80=93 yet. </p><p class=3D"m_-670148805620=
2737086noindent"><br></p><p class=3D"m_-6701488056202737086noindent">The fi=
rst reason why is that persistent memory is just around the corner, and I t=
hink it would be unwise to standardise without the industry gaining plenty =
of empirical experience first. So kick that decision down a few standard re=
leases. </p><p class=3D"m_-6701488056202737086noindent">Secondly, the propo=
sed library herein does expose whatever acquire-release semantics is implem=
ented by the host operating system for file i/o, plus the advisory locking =
infrastructure implemented by the host, plus the ability to enable write-th=
rough caching semantics. It also provides <span class=3D"m_-670148805620273=
7086fvmr8t-x-x-93">barrier()</span>, though one should not write code which=
relies upon it working, as it frequently does not. </p><p class=3D"m_-6701=
488056202737086noindent"><br></p><p class=3D"m_-6701488056202737086noindent=
">Note that if the file is opened in non-volatile RAM storage mode, <span c=
lass=3D"m_-6701488056202737086fvmr8t-x-x-93">barrier() </span>calls the app=
ropriate architecture-specific assembler instructions to correctly barrier =
writes to main memory, so in this sense =
=
there i=
s library, if not language, support for persistent memory. The obvious stic=
ker is that <span class=3D"m_-6701488056202737086fvmr8t-x-x-93">barrier() <=
/span>is a virtual function with significant preamble and epilogue, so for =
flushing a single cache line it is extremely inefficient relative to direct=
language support for this. </p><p class=3D"m_-6701488056202737086noindent"=
>Nevertheless, one can write standards conforming code with the proposed li=
brary which performs better on persistent memory than on traditional storag=
e, and my advice is that this is good enough for the next few years.=C2=A0<=
/p></div></div>
<p></p>
-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/b214ce98-2aaa-4f7f-a04a-77687422111a%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/b214ce98-2aaa-=
4f7f-a04a-77687422111a%40isocpp.org</a>.<br>
</blockquote></div><br clear=3D"all"><div><br></div>-- <br><div dir=3D"ltr"=
class=3D"gmail_signature" data-smartmail=3D"gmail_signature">Who=E2=80=99s=
got the sweetest disposition?<br>One guess, that=E2=80=99s who?<br>Who=E2=
=80=99d never, ever start an argument?<br>Who never shows a bit of temperam=
ent?<br>Who's never wrong but always right?<br>Who'd never dream of=
starting a fight?<br>Who get stuck with all the bad luck? </div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAFdMc-0j945MOprtHf1w2jx6Qb-DeSKZitKx=
PMDSJ_v--D3Kjw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">htt=
ps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAFdMc-0j945MOprt=
Hf1w2jx6Qb-DeSKZitKxPMDSJ_v--D3Kjw%40mail.gmail.com</a>.<br />
--0000000000006966f6057263fce2--
.
Author: Jake Arkinstall <jake.arkinstall@gmail.com>
Date: Wed, 1 Aug 2018 22:27:51 +0100
Raw View
--000000000000a32c2d0572665e0d
Content-Type: text/plain; charset="UTF-8"
This.
On Wed, 1 Aug 2018, 19:37 Daniel Gutson, <danielgutson@gmail.com> wrote:
> Though the actual way of recognizing this work would be currently reading
> the proposal, and I will do my best during the weekend, I will do something
> that I think is not very common these days: to say an anonymous "thank you"
> for the (personal) time you took to contribute to the C++.
> Same for all the people putting effort, time and/or money in the progress
> of the language.
>
It's a long proposal and, for me at least, there's a lot of background
reading involved. I think it's going to take a few days before you'll get
some useful feedback, but it isn't being ignored - it is far too
interesting for that.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCONbyBeHy_cBv%2B4nA7Ys2HFym7hj6mmxAx79F%3DPMUf2Hg%40mail.gmail.com.
--000000000000a32c2d0572665e0d
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"auto"><div>This.<br><br><div class=3D"gmail_quote"><div dir=3D"=
ltr">On Wed, 1 Aug 2018, 19:37 Daniel Gutson, <<a href=3D"mailto:danielg=
utson@gmail.com" target=3D"_blank" rel=3D"noreferrer">danielgutson@gmail.co=
m</a>> wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"margin=
:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">T=
hough the actual way of recognizing this work would be currently reading th=
e proposal, and I will do my best during the weekend, I will do something t=
hat I think is not very common these days: to say an anonymous "thank =
you" for the (personal) time you took to contribute to the C++.<div>Sa=
me for all the people putting effort, time and/or money in the progress of =
the language.</div></div></blockquote></div></div><div dir=3D"auto"><br></d=
iv><div dir=3D"auto">It's a long proposal and, for me at least, there&#=
39;s a lot of background reading involved. I think it's going to take a=
few days before you'll get some useful feedback, but it isn't bein=
g ignored - it is far too interesting for that.</div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCONbyBeHy_cBv%2B4nA7Ys2HFym7h=
j6mmxAx79F%3DPMUf2Hg%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoote=
r">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCON=
byBeHy_cBv%2B4nA7Ys2HFym7hj6mmxAx79F%3DPMUf2Hg%40mail.gmail.com</a>.<br />
--000000000000a32c2d0572665e0d--
.
Author: Thiago Macieira <thiago@macieira.org>
Date: Wed, 01 Aug 2018 22:06:02 -0700
Raw View
On Wednesday, 1 August 2018 20:20:20 PDT Arthur O'Dwyer wrote:
> Another nail in the coffin of this contrived unique_ptr example:
> unique_ptr<T> points to a thing that you're going to `delete` later, whic=
h
> depends on the state of the global new/delete heap in the current process=
=E2=80=94
> there's *no way* that's going to work if the current process isn't the on=
e
> who new'ed the object, right?
That depends on the deleter. For the default deleter, you're definitely rig=
ht.
For a special deleter that operates on shared memory, unique_ptr might work=
..
--=20
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/2334577.JfUF7F00up%40tjmaciei-mobl1.
.
Author: Richard Hodges <hodges.r@gmail.com>
Date: Fri, 3 Aug 2018 09:19:17 +0200
Raw View
--00000000000090076a057282bfaf
Content-Type: text/plain; charset="UTF-8"
Picking up on the subject of storage durations, we have:
T i = x; // automatic storage duration
T* pi = new int(T); // dynamic storage duration
[thread_local] static T si = x; // static storage duration
do we merely need to be able to create new objects marked as persistent?
auto ppi = new (persistence_policy(...args...)) T ();
where persistence_policy is some policy class, derived from
std::persistence_policy, which could take care of
deserialisation/serialisation, fixing vtables, remapping, etc.
Of course the keyword new would need a small modification, in order to only
actually call the constructor if the policy says it should.
On Thu, 2 Aug 2018 at 22:37, Nicol Bolas <jmckesson@gmail.com> wrote:
> On Thursday, August 2, 2018 at 5:12:53 AM UTC-4, Niall Douglas wrote:
>>
>>
>>> So you have this operation you want to be able to do. You want to take
>>> objects in one address, make them disappear from that address, and then
>>> make them appear in a (potentially) different address. And you want to
>>> change the C++ object model to make this work.
>>>
>>> Here's a question: do you *need* to change the object model in order to
>>> get this effect?
>>>
>>
>> So, here's what we want to be able to do without UB:
>>
>> 1. Modify where allocated memory appears in the process (use cases:
>> expanding arrays without memory copies, patching binaries, mapping page
>> cached files etc)
>> 2. Share a region of memory with another running process (use cases:
>> IPC, multiprocessing, etc)
>> 3. Reduce C++ causing unnecessary page faults/prevent use of memory
>> with changed access permissions by making the compiler aware of what memory
>> is not to be touched.
>> 4. Handle objects written out in a previous incarnation of a program
>> being at a different address in a new incarnation of a program.
>> 5. Enforce a new read/write reordering constraint separate to
>> compiler and thread barriers.
>>
>> In hindsight, I probably ought to have specified this more succinctly in
>> the paper. I will change it.
>>
>> There are also multiple levels of persistability going on here:
>>
>> 1. Trivially copyable types, which are just bits. You can use their
>> in-memory representation directly, just need to constrain write reordering.
>> 2. Trivially relocatable types, which are moved with just bits, if we
>> standardise those. You can use their in-memory representation directly,
>> just need to constrain write reordering.
>> 3. Polymorphic types where if it weren't for the vptr, would be
>> either of the first two categories. You can use their in-memory
>> representation directly, bar the vptr restamp on load.
>> 4. Other types whose in-memory representation can be used directly
>> after some trivial transformation e.g. replace all pointers with offset
>> pointers.
>>
>> So the common factor to all these is that their in-memory representation
>> is sufficient for their persisted representation i.e. no memory copying
>> needed, but there can be a "phase change" between "active" and "sleeping".
>>
>> Serialisation is where you need to create new objects which represent a
>> persisted edition of an in-memory form. That's a whole separate topic, to
>> be addressed as iostreams v2 after we've nailed down the in-memory stuff
>> which is a prerequisite as the serialised form of an object is clearly a
>> persistable object meeting at least the criteria of the above.
>>
>
> There may be a common factor in these cases, but there is no common
> *solution* with them. Cases #1 and #2 are fundamentally different from #3
> and #4. Why? Because it's impossible to do 3&4 on an arbitrary range of
> memory.
>
> In cases 1&2, you can logically move these objects' values around and
> reconstitute them with no per-object code. This means you could just have
> the mapping/unmapping operation perform the "operation" needed to make this
> legal.
>
> With 3&4, you're packing an object's values into a form from which it can
> be unpacked to reconstitute the original object's value. This operation has
> to be done on a per-object basis. That is, you can't just do "unmap range
> of memory, map it latter, do some casting, and go." You have to go to each
> object and perform some operation; code must be executed for each object
> before each unmap and after each map. Also, this operation has to cascade
> up and down the subobject hierarchy, applying that operation to each
> subobject in turn. Preferably in an order similar to how subobjects are
> created and destroyed.
>
> If you're executing code at map/unmap time, you are *doing serialization*.
> It may not be the most complex form of serialization, but it is still
> serialization.
>
> As such, I would say that what you're talking about is best handled in the
> C++ object model via what I said: destruction and construction. If you're
> unmapping memory, then any objects within it are destroyed, ending their
> lifetimes. When you map them, a new object is constructed in the storage
> whose values contain the old objects' values
>
> Since this would be done via beginning and ending object lifetimes, that
> provides opportunities to inject user/compiler-code into the process via
> specialized constructors and destructors. For some objects (which may *or
> may not* equate to implicit lifetime or trivially relocatable types),
> these constructors/destructors would be trivial, and as such, we can give
> them special properties and effects.
>
> If I were to give a name to this process, I would say that you are
> *trivializing* the value of an object. At its core, what you're wanting
> to do is to take an object, turn its values into data that is no longer
> considered to be "that object", but still is within the same storage. These
> bytes can be copied around verbatim, or the underlying storage can be
> persisted as you desire. You can later *detrivialize* the value back into
> an object of that *exact type*.
>
> The trivialized form of an object is not that object anymore. It's just
> bytes of data. For some objects, its trivial form is exactly its regular
> form. For other objects, this is not the case. But the trivial form has the
> same size as the regular form.
>
> A trivializing destructor takes the object and alters its values to make
> it trivial. As implied by this being invoked by a destructor, once you
> trivialize the object's data, the object's lifetime has ended. The storage
> behind a trivialized object is preserved after the object's lifetime has
> ended.
>
> A detrivializing constructor takes the object representation of a
> trivialized object of that type and undoes the trivialization.
>
> The one change to the object model that would be needed to do all of this
> would be a guarantee of the preservation of the values of a
> destroyed/created object. Currently, the C++ object model makes no
> guarantees of the value of the object's storage after its lifetime has
> ended. And when you begin the lifetime of an object, its storage before
> initialization has either zero values (if it's static) or unspecified
> values.
>
> So you would need to say that trivializing destructors preserve the value
> of the memory, and detrivializing initialization/construction operations
> would maintain the storage of the memory at the start of the detrivializing
> constructor. And of course, objects with trivial trivializing operations
> (maybe "trivializing" wasn't such a good term...) can do these implicitly.
>
> You will still need a placement-new replacement to be able to detrivialize
> objects with non-trivial detrivializing construction. The placement part
> obtains storage for the object, and that part is legally allowed to
> overwrite such storage. So you'd need an alternate version which isn't
> allowed to.
>
> Note that a TriviallyCopyable type is not necessarily an object with
> trivial trivialization (wow, that's terrible naming ;). The reason being:
> pointers. An object with pointers is TriviallyCopyable, so you could
> theoretically map or unmap it. But if those pointers point to mapped
> memory, you need to manually trivialize and detrivialize them.
>
> Indeed, I'm starting to wonder about that. It seems that the need for
> trivialization is more a property of the object than of the object's
> *type*. Trivialization ought to be distinct from trivial relocation and
> trivial copying. But it should still be something done via
> constructors/destructors.
>
> I think "Mapped storage duration" is too on-point in terms of where the
>>>> memory comes from, rather than how C++ thinks of it.
>>>>
>>>> The four storage durations are based on how C++ interacts with them.
>>>> Automatic storage duration objects have storage durations determined
>>>> entirely by their objects' scopes. Static storage duration objects have
>>>> their storage duration be the lifetime of the program. Thread-local storage
>>>> duration objects have their storage duration be the lifetime of the thread.
>>>> And dynamic duration objects have their storage duration determined
>>>> dynamically: by direct manipulation of the code.
>>>>
>>>
>>> Sure. And I propose that mapped storage duration has the lifetime of its
>>> backing filesystem entity. Same approach.
>>>
>>>
>>>>
>>>> But I think there is a deeper misunderstanding here. You are confusing
>>>> properties of "storage" with the properties of "storage duration". The
>>>> former is a thing that an object needs to have in order to exist. The
>>>> latter is a property of an object, determined by the means used to
>>>> construct it, and it's purpose is to govern the (default) lifetime of that
>>>> object.
>>>>
>>>> For example, you can create an automatic variable with automatic
>>>> storage duration. You can then reuse that variable's storage to create
>>>> objects with dynamic storage duration. By reusing it, you will have ended
>>>> the lifetime of the automatic variable. You would then have an object with
>>>> dynamic storage duration whose storage happens to be on the stack.
>>>>
>>>> Which is why "stack storage duration" would be a misnomer, much like
>>>> "mapped storage duration".
>>>>
>>>
>>> Would "filesystem storage duration" be better?
>>>
>>
> Let me try to explain again.
>
> Automatic storage duration is named based on its high-level concepts: the
> storage duration of the object is handled "automatically" by the scope of
> the declaration. The memory for that storage may come from something we
> call the "stack", but we don't name it "stack storage duration" even though
> such objects are (nominally) on the "stack".
>
> The same goes for your notion. Both "mapped" and "filesystem" are all
> named based on where the storage comes from. *That* is what is wrong with
> these terms. Terms should be based on the high-level concepts of the kind
> of storage duration you're imposing on the object, not based on where the
> memory is or how it's being interacted with.
>
> I originally discounted that naming because there are mapped storage
>> durations whose backing filesystem entity is the swap file/kernel, so I
>> felt mentioning filesystem would be confusing.
>>
>>
>>>
>>> Of course, C++ has a bunch of rules about what happens when you do this
>>> and then try to use that variable's name later on. As well as what happens
>>> when that variable goes out of scope, and what you need to do to make
>>> leaving scope not invoke UB (namely, create an object of that type
>>> *back* in that storage).
>>>
>>> What you seem to want is simply a wider form of dynamic storage
>>> duration. You're not changing the meaning of the storage duration; you're
>>> simply adding ways to create/destroy such objects.
>>>
>>
>> It's more I'm looking for a storage duration which exceeds the duration
>> of the program, but still has a well defined duration. Dynamic storage
>> can't do that.
>>
>
> You're misunderstanding something critical here. "Storage duration" is a
> misnomer; it has *nothing* to do with the duration of a piece of memory
> (yes, really). Storage duration defines how the lifetime of an object
> works, based on how it is created. Dynamic storage duration means that the
> lifetime of the object being created is governed explicitly by
> runtime-executed code.
>
> For example:
>
> int i; //i has automatic storage duration.
> auto pf = new(&i) float;
>
> The storage for `*pf` comes from an automatic variable, but the storage
> duration of the object is *dynamic*. It has dynamic storage duration
> because it is created by `operator new`, rather than a declaration or
> somesuch.
>
> Therefore, the only way you would need your hypothetical "mapped storage
> duration" would be if you are proposing a new way to create objects. If you
> can create objects in mapped storage with `operator new`, then those
> objects have dynamic storage duration, *period*.
>
> *On Bless:*
>>>
>>> P0593 proposed these functions to mark regions as reachable:
>>>>
>>>
>>> Your notion of "reachability" has nothing to do with what P0593 is
>>> doing. `bless` does not make objects "reachable"; that proposal only uses
>>> the word "reachable" once, and that is merely a description about the
>>> relationship between a pointer and a size (which really ought to be a
>>> `std::span<std::byte>`).
>>>
>>> And your definition of "reachable" here does not map to what P0593 is
>>> doing. `std::bless` and equivalent functions declare that a piece of memory
>>> *creates* implicit objects. When you call `bless` on a range of memory,
>>> objects will be created to make your code work. What your "reachable"
>>> behavior seems to want is for them to already exist.
>>>
>>
>> Eh ... you're right that I find blessing underspecified. This is that
>> fuzziness about lifetime I mentioned earlier. I've spent a good few weeks
>> pondering P0593, indeed I asked a ton of questions about it as the SG12
>> meeting at Rapperswil. And I'm confused about what it precisely does.
>>
>> Personally, I find reachable vs unreachable a much less ambiguous
>> explanation of what it does.
>>
>
> If you're confused by "what it precisely does", then I'm not sure how good
> an idea it is to impose your own terminology on it. You need to understand
> what it currently means before you can say that your terminology describes
> that meaning better or worse. After all, if you don't understand it, your
> terminology could be imposing different behavior than what it's trying to
> do.
>
> Which is what's happening here. What you say reachability means and what
> P0593 says `bless` means are two different things.
>
> `launder` says "there is an object, at this address, of this type. Get me
> a pointer to it."
>
> `bless` says "*create* objects of implicit lifetime types within this
> storage, such that my following code will be legal."
>
> What you want your "make reachable" operation to say is "there already are
> some objects of various types in this storage; I want to access them." Your
> "reachable" concept isn't *creating* objects, but `std::bless` *is*.
>
> You're thinking of this from a low-level "what is going on in memory"
> perspective. When dealing with the C++ object model, you have to think from
> a high-level "what are objects" perspective. This is what leads us to the
> following:
>
> And more helpful for compiler writers and formal verification. But I
>> totally get that it may simply be my incompetence, and I need to be
>> corrected. I am not a compiler writer after all.
>>
>> (Richard Smith, feel free to jump in and correct me now!)
>>
>>
>>> This may seem like a trivial difference, but it isn't. P0593 points it
>>> out
>>> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0593r2.html#type-punning>:
>>> when you create objects, the contents of the storage are rendered
>>> unspecified. And this is just as true for objects implicitly created by
>>> `std::bless`.
>>>
>>
>> Sure. They become reachable. It says nothing about their content.
>>
>
> From the section I linked to (emphasis added):
>
> Specifically, the value held by an object is only stable *throughout its
>> lifetime*. When the lifetime of the int object in line #1 ends (when its
>> storage is reused by the float object in line #2), *its value is gone*.
>> Symmetrically, when the float object is created, the object has an
>> indeterminate value ([dcl.init]p12), and therefore *any attempt to load
>> its value results in undefined behavior*.
>>
>
> The thing about P0593 is that it's actually a bit inconsistent about this.
> Since we don't have actual standards wording, we have to do the best we can
> with the details we've been given. The area of inconsistency is that
> Section 4.1 of the same document says:
>
> In some cases it is desirable to change the dynamic type of existing
>> storage while maintaining the object representation. If the destination
>> type is an implicit lifetime type, this can be accomplished by usage of
>> std::bless to change the type, followed by std::launder to acquire a
>> pointer to the newly-created object.
>>
>
> That section can only be true if the previously quoted section is *false*.
> If there's a newly created object in that storage, the only way to access
> the value from the recently-destroyed object that used to live there is if
> it's value is not "gone".
>
> However, section 4.1 is the odd man out in P0593. Throughout that paper,
> it refers to the operation which `bless` performs as "creating objects". If
> you create an object in storage that already contains an object, then you
> are reusing that object's storage. Reusing an object's storage ends that
> object's lifetime.
>
> And the C++ object model is very clear: the value of an object whose
> lifetime has ended is not preserved. The contents of an object's storage
> after its lifetime has ended is not defined by the standard.
>
> So my reading of P0593 is that if you `bless` a range of memory, any
> objects already residing there have their lifetimes ended. The objects
> which have been created by this process therefore have unspecified values,
> since all previous objects in that storage have been reused.
>
> And once an object's lifetime ends, the value of that object is gone.
>
> Basically, consider this:
>
> int i = 45;
> int *pi = new(&i) int;
> std::cout << i;
>
> The standard says that this is not guaranteed to print 45. My reading of
> P0593 is that the following is the equivalent of the above:
>
> int i = 45;
> std::bless(&i, sizeof(int)); //"Creates objects" in `i`.
> std::cout << i; //Newly created `int` object, due to `bless` and access
>
> So this is not guaranteed to print 45 either. And neither
> `reinterpret_cast` nor `launder` would change that.
>
> Now, I could be misinterpreting P0593. Like I said, it doesn't have formal
> standards wording. But the frequent use of the phrase "create objects",
> coupled with the *explicit* prohibition of type punning, suggests that
> I'm probably right.
>
> --
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit
> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/f7dffe3e-6e9c-47cb-a834-267e170640ed%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/f7dffe3e-6e9c-47cb-a834-267e170640ed%40isocpp.org?utm_medium=email&utm_source=footer>
> .
>
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALvx3ha9nKJTiGqj-S_UR-EBRcwS7VkNyPG86Pf%3DjJgLnqj7ag%40mail.gmail.com.
--00000000000090076a057282bfaf
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Picking up on the subject of storage durations, we have:<d=
iv><br></div><div><font face=3D"monospace, monospace">T i =3D x;=C2=A0 // a=
utomatic storage duration</font></div><div><br></div><div><font face=3D"mon=
ospace, monospace">T* pi =3D new int(T);=C2=A0 // dynamic storage duration<=
/font></div><div><br></div><div><font face=3D"monospace, monospace">[thread=
_local] static T si =3D x;=C2=A0 =C2=A0// static storage duration</font></d=
iv><div><br></div><div>do we merely need to be able to create new objects m=
arked as persistent?</div><div><br></div><div><font face=3D"monospace, mono=
space">auto ppi =3D new (persistence_policy(...args...)) T ();<br></font></=
div><div><br></div><div>where <font face=3D"monospace, monospace">persisten=
ce_policy</font> is some policy class, derived from <font face=3D"monospace=
, monospace">std::persistence_policy</font>,=C2=A0 which could take care of=
deserialisation/serialisation, fixing vtables, remapping, etc.</div><div><=
br></div><div>Of course the keyword new would need a small modification, in=
order to only actually call the constructor if the policy says it should.<=
/div><div><br></div></div><br><div class=3D"gmail_quote"><div dir=3D"ltr">O=
n Thu, 2 Aug 2018 at 22:37, Nicol Bolas <<a href=3D"mailto:jmckesson@gma=
il.com">jmckesson@gmail.com</a>> wrote:<br></div><blockquote class=3D"gm=
ail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-le=
ft:1ex"><div dir=3D"ltr">On Thursday, August 2, 2018 at 5:12:53 AM UTC-4, N=
iall Douglas wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;marg=
in-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"=
><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bord=
er-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><div><br></d=
iv><div>So you have this operation you want to be able to do. You want to t=
ake=20
objects in one address, make them disappear from that address, and then=20
make them appear in a (potentially) different address. And you want to chan=
ge the C++ object model to make this work.</div><div><br></div><div>Here=
9;s a question: do you <i>need</i> to change the object model in order to g=
et this effect?<br></div></div></div></blockquote><div><br></div><div>So, h=
ere's what we want to be able to do without UB:</div><div><ol><li>Modif=
y where allocated memory appears in the process (use cases: expanding array=
s without memory copies, patching binaries, mapping page cached files etc)<=
/li><li>Share a region of memory with another running process (use cases: I=
PC, multiprocessing, etc)</li><li>Reduce C++ causing unnecessary page fault=
s/prevent use of memory with changed access permissions by making the compi=
ler aware of what memory is not to be touched.</li><li>Handle objects writt=
en out in a previous incarnation of a program being at a different address =
in a new incarnation of a program.</li><li>Enforce a new read/write reorder=
ing constraint separate to compiler and thread barriers.</li></ol></div><di=
v>In hindsight, I probably ought to have specified this more succinctly in =
the paper. I will change it.</div><div><br></div><div>There are also multip=
le levels of persistability going on here:</div><div><ol><li>Trivially copy=
able types, which are just bits. You can use their in-memory representation=
directly, just need to constrain write reordering.</li><li>Trivially reloc=
atable types, which are moved with just bits, if we standardise those. You =
can use their in-memory representation directly, just need to constrain wri=
te reordering.</li><li>Polymorphic types where if it weren't for the vp=
tr, would be either of the first two categories. You can use their in-memor=
y representation directly, bar the vptr restamp on load.</li><li>Other type=
s whose in-memory representation can be used directly after some trivial tr=
ansformation e.g. replace all pointers with offset pointers.</li></ol></div=
><div>So the common factor to all these is that their in-memory representat=
ion is sufficient for their persisted representation i.e. no memory copying=
needed, but there can be a "phase change" between "active&q=
uot; and "sleeping".</div><div><br></div><div>Serialisation is wh=
ere you need to create new objects which represent a persisted edition of a=
n in-memory form. That's a whole separate topic, to be addressed as ios=
treams v2 after we've nailed down the in-memory stuff which is a prereq=
uisite as the serialised form of an object is clearly a persistable object =
meeting at least the criteria of the above.</div></div></blockquote><div><b=
r></div><div>There may be a common factor in these cases, but there is no c=
ommon <i>solution</i> with them. Cases #1 and #2 are fundamentally differen=
t from #3 and #4. Why? Because it's impossible to do 3&4 on an arbi=
trary range of memory.</div><div><br></div><div>In cases 1&2, you can l=
ogically move these objects' values around and reconstitute them with n=
o per-object code. This means you could just have the mapping/unmapping ope=
ration perform the "operation" needed to make this legal.<br></di=
v><div><br></div><div>With 3&4, you're packing an object's valu=
es into a form from which it can be unpacked to reconstitute the original o=
bject's value. This operation has to be done on a per-object basis. Tha=
t is, you can't just do "unmap range of memory, map it latter, do =
some casting, and go." You have to go to each object and perform some =
operation; code must be executed for each object before each unmap and afte=
r each map. Also, this operation has to cascade up and down the subobject h=
ierarchy, applying that operation to each subobject in turn. Preferably in =
an order similar to how subobjects are created and destroyed.<br></div><div=
><br></div><div>If you're executing code at map/unmap time, you are <i>=
doing serialization</i>. It may not be the most complex form of serializati=
on, but it is still serialization.</div><div><br></div><div>As such, I woul=
d say that what you're talking about is best handled in the C++ object =
model via what I said: destruction and construction. If you're unmappin=
g memory, then any objects within it are destroyed, ending their lifetimes.=
When you map them, a new object is constructed in the storage whose values=
contain the old objects' values<br></div><div><br></div><div>Since thi=
s would be done via beginning and ending object lifetimes, that provides op=
portunities to inject user/compiler-code into the process via specialized c=
onstructors and destructors. For some objects (which may <i>or may not</i> =
equate to implicit lifetime or trivially relocatable types), these construc=
tors/destructors would be trivial, and as such, we can give them special pr=
operties and effects.<br></div><div><br></div><div>If I were to give a name=
to this process, I would say that you are <i>trivializing</i> the value of=
an object. At its core, what you're wanting to do is to take an object=
, turn its values into data that is no longer considered to be "that o=
bject", but still is within the same storage. These bytes can be copie=
d around verbatim, or the underlying storage can be persisted as you desire=
.. You can later <i>detrivialize</i> the value back into an object of that <=
i>exact type</i>.</div><div><br></div><div>The trivialized form of an objec=
t is not that object anymore. It's just bytes of data. For some objects=
, its trivial form is exactly its regular form. For other objects, this is =
not the case. But the trivial form has the same size as the regular form.</=
div><div><br></div><div></div><div>A trivializing destructor takes the obje=
ct and alters its values to make it trivial. As implied by this being invok=
ed by a destructor, once you trivialize the object's data, the object&#=
39;s lifetime has ended. The storage behind a trivialized object is preserv=
ed after the object's lifetime has ended.<br></div><div><br></div><div>=
A detrivializing constructor takes the object representation of a trivializ=
ed object of that type and undoes the trivialization.</div><div><br></div><=
div>The one change to the object model that would be needed to do all of th=
is would be a guarantee of the preservation of the values of a destroyed/cr=
eated object. Currently, the C++ object model makes no guarantees of the va=
lue of the object's storage after its lifetime has ended. And when you =
begin the lifetime of an object, its storage before initialization has eith=
er zero values (if it's static) or unspecified values.<br></div><div><b=
r></div><div>So you would need to say that trivializing destructors preserv=
e the value of the memory, and detrivializing initialization/construction o=
perations would maintain the storage of the memory at the start of the detr=
ivializing constructor. And of course, objects with trivial trivializing op=
erations (maybe "trivializing" wasn't such a good term...) ca=
n do these implicitly.</div><div><br></div><div>You will still need a place=
ment-new replacement to be able to detrivialize objects with non-trivial de=
trivializing construction. The placement part obtains storage for the objec=
t, and that part is legally allowed to overwrite such storage. So you'd=
need an alternate version which isn't allowed to.</div><div><br></div>=
<div>Note that a TriviallyCopyable type is not necessarily an object with t=
rivial trivialization (wow, that's terrible naming ;). The reason being=
: pointers. An object with pointers is TriviallyCopyable, so you could theo=
retically map or unmap it. But if those pointers point to mapped memory, yo=
u need to manually trivialize and detrivialize them.</div><div><br></div><d=
iv>Indeed, I'm starting to wonder about that. It seems that the need fo=
r trivialization is more a property of the object than of the object's =
<i>type</i>. Trivialization ought to be distinct from trivial relocation an=
d trivial copying. But it should still be something done via constructors/d=
estructors.<br></div><div><br></div><blockquote class=3D"gmail_quote" style=
=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"=
><div dir=3D"ltr"><div></div><blockquote class=3D"gmail_quote" style=3D"mar=
gin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div d=
ir=3D"ltr"><div dir=3D"ltr"><div></div><blockquote class=3D"gmail_quote" st=
yle=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1=
ex"><div dir=3D"ltr"><div></div><div>I think "Mapped storage duration&=
quot; is too on-point in terms of where the memory comes from, rather than =
how C++ thinks of it.<br></div><div><br></div><div>The four storage duratio=
ns are based on how C++ interacts with them. Automatic storage duration obj=
ects have storage durations determined entirely by their objects' scope=
s. Static storage duration objects have their storage duration be the lifet=
ime of the program. Thread-local storage duration objects have their storag=
e duration be the lifetime of the thread. And dynamic duration objects have=
their storage duration determined dynamically: by direct manipulation of t=
he code.<br></div></div></blockquote><div><br></div><div>Sure. And I propos=
e that mapped storage duration has the lifetime of its backing filesystem e=
ntity. Same approach.</div><div>=C2=A0</div><blockquote class=3D"gmail_quot=
e" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-l=
eft:1ex"><div dir=3D"ltr"><br><div>But I think there is a deeper misunderst=
anding here. You are confusing properties of "storage" with the p=
roperties of "storage duration". The former is a thing that an ob=
ject needs to have in order to exist. The latter is a property of an object=
, determined by the means used to construct it, and it's purpose is to =
govern the (default) lifetime of that object.<br></div><div><br></div><div>=
For example, you can create an automatic variable with automatic storage du=
ration. You can then reuse that variable's storage to create objects wi=
th dynamic storage duration. By reusing it, you will have ended the lifetim=
e of the automatic variable. You would then have an object with dynamic sto=
rage duration whose storage happens to be on the stack.</div><div><br></div=
><div>Which is why "stack storage duration" would be a misnomer, =
much like "mapped storage duration".<br></div></div></blockquote>=
<div><br></div><div>Would "filesystem storage duration" be better=
?</div></div></div></blockquote></div></blockquote><div><br></div><div>Let =
me try to explain again.</div><div><br></div><div>Automatic storage duratio=
n is named based on its high-level concepts: the storage duration of the ob=
ject is handled "automatically" by the scope of the declaration. =
The memory for that storage may come from something we call the "stack=
", but we don't name it "stack storage duration" even th=
ough such objects are (nominally) on the "stack".<br></div><div><=
br></div><div>The same goes for your notion. Both "mapped" and &q=
uot;filesystem" are all named based on where the storage comes from. <=
i>That</i> is what is wrong with these terms. Terms should be based on the =
high-level concepts of the kind of storage duration you're imposing on =
the object, not based on where the memory is or how it's being interact=
ed with.</div><div></div><br><blockquote class=3D"gmail_quote" style=3D"mar=
gin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div d=
ir=3D"ltr"><div></div><div>I originally discounted that naming because ther=
e are mapped storage durations whose backing filesystem entity is the swap =
file/kernel, so I felt mentioning filesystem would be confusing.</div><div>=
=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left=
:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><=
/div><div><br></div><div>Of course, C++ has a bunch of rules about what hap=
pens when you do this and then try to use that variable's name later on=
.. As well as what happens when that variable goes out of scope, and what yo=
u need to do to make leaving scope not invoke UB (namely, create an object =
of that type <i>back</i> in that storage).</div><div><br></div><div>What yo=
u seem to want is simply a wider form of dynamic storage duration. You'=
re not changing the meaning of the storage duration; you're simply addi=
ng ways to create/destroy such objects.</div></div></blockquote><div><br></=
div><div>It's more I'm looking for a storage duration which exceeds=
the duration of the program, but still has a well defined duration. Dynami=
c storage can't do that.</div></div></blockquote><div><br></div><div>Yo=
u're misunderstanding something critical here. "Storage duration&q=
uot; is a misnomer; it has <i>nothing</i> to do with the duration of a piec=
e of memory (yes, really). Storage duration defines how the lifetime of an =
object works, based on how it is created. Dynamic storage duration means th=
at the lifetime of the object being created is governed explicitly by runti=
me-executed code.<br></div><div><br></div><div>For example:</div><div><br><=
/div><div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,1=
87,187);border-style:solid;border-width:1px" class=3D"m_-658443390837245461=
3prettyprint"><code class=3D"m_-6584433908372454613prettyprint"><div class=
=3D"m_-6584433908372454613subprettyprint"><span style=3D"color:#008" class=
=3D"m_-6584433908372454613styled-by-prettify">int</span><span style=3D"colo=
r:#000" class=3D"m_-6584433908372454613styled-by-prettify"> i</span><span s=
tyle=3D"color:#660" class=3D"m_-6584433908372454613styled-by-prettify">;</s=
pan><span style=3D"color:#000" class=3D"m_-6584433908372454613styled-by-pre=
ttify"> </span><span style=3D"color:#800" class=3D"m_-6584433908372454613st=
yled-by-prettify">//i has automatic storage duration.</span><span style=3D"=
color:#000" class=3D"m_-6584433908372454613styled-by-prettify"><br></span><=
span style=3D"color:#008" class=3D"m_-6584433908372454613styled-by-prettify=
">auto</span><span style=3D"color:#000" class=3D"m_-6584433908372454613styl=
ed-by-prettify"> pf </span><span style=3D"color:#660" class=3D"m_-658443390=
8372454613styled-by-prettify">=3D</span><span style=3D"color:#000" class=3D=
"m_-6584433908372454613styled-by-prettify"> </span><span style=3D"color:#00=
8" class=3D"m_-6584433908372454613styled-by-prettify">new</span><span style=
=3D"color:#660" class=3D"m_-6584433908372454613styled-by-prettify">(&</=
span><span style=3D"color:#000" class=3D"m_-6584433908372454613styled-by-pr=
ettify">i</span><span style=3D"color:#660" class=3D"m_-6584433908372454613s=
tyled-by-prettify">)</span><span style=3D"color:#000" class=3D"m_-658443390=
8372454613styled-by-prettify"> </span><span style=3D"color:#008" class=3D"m=
_-6584433908372454613styled-by-prettify">float</span><span style=3D"color:#=
660" class=3D"m_-6584433908372454613styled-by-prettify">;</span><span style=
=3D"color:#000" class=3D"m_-6584433908372454613styled-by-prettify"><br></sp=
an></div></code></div><div><br>The storage for `*pf` comes from an automati=
c variable, but the storage duration of the object is <i>dynamic</i>. It ha=
s dynamic storage duration because it is created by `operator new`, rather =
than a declaration or somesuch.<br></div><div></div><div><br></div><div>The=
refore, the only way you would need your hypothetical "mapped storage =
duration" would be if you are proposing a new way to create objects. I=
f you can create objects in mapped storage with `operator new`, then those =
objects have dynamic storage duration, <i>period</i>.<br></div><div><br></d=
iv><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bo=
rder-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div><blo=
ckquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-le=
ft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div><div><u>On =
Bless:</u></div><div><br></div><blockquote class=3D"gmail_quote" style=3D"m=
argin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left=
:1ex"><div>P0593 proposed these functions to mark regions as reachable:</di=
v></blockquote><div><br></div><div></div><div>Your notion of "reachabi=
lity" has nothing to do with what P0593 is doing. `bless` does not mak=
e objects "reachable"; that proposal only uses the word "rea=
chable" once, and that is merely a description about the relationship =
between a pointer and a size (which really ought to be a `std::span<std:=
:byte>`).</div><div><br></div><div>And your definition of "reachabl=
e" here does not map to what P0593 is doing. `std::bless` and equivale=
nt functions declare that a piece of memory <i>creates</i> implicit objects=
.. When you call `bless` on a range of memory, objects will be created to ma=
ke your code work. What your "reachable" behavior seems to want i=
s for them to already exist.</div></div></blockquote><div><br></div><div>Eh=
... you're right that I find blessing underspecified. This is that fuz=
ziness about lifetime I mentioned earlier. I've spent a good few weeks =
pondering P0593, indeed I asked a ton of questions about it as the SG12 mee=
ting at Rapperswil. And I'm confused about what it precisely does.</div=
><div><br></div><div>Personally, I find reachable vs unreachable a much les=
s ambiguous explanation of what it does.</div></div></blockquote><div><br><=
/div><div>If you're confused by "what it precisely does", the=
n I'm not sure how good an idea it is to impose your own terminology on=
it. You need to understand what it currently means before you can say that=
your terminology describes that meaning better or worse. After all, if you=
don't understand it, your terminology could be imposing different beha=
vior than what it's trying to do.<br></div><div><br></div><div>Which is=
what's happening here. What you say reachability means and what P0593 =
says `bless` means are two different things.</div><div><br></div><div>`laun=
der` says "there is an object, at this address, of this type. Get me a=
pointer to it."</div><div><br></div><div>`bless` says "<i>create=
</i> objects of implicit lifetime types within this storage, such that my f=
ollowing code will be legal."</div><div><br></div><div>What you want y=
our "make reachable" operation to say is "there already are =
some objects of various types in this storage; I want to access them."=
Your "reachable" concept isn't <i>creating</i> objects, but =
`std::bless` <i>is</i>.<br></div><div><br></div><div>You're thinking of=
this from a low-level "what is going on in memory" perspective. =
When dealing with the C++ object model, you have to think from a high-level=
"what are objects" perspective. This is what leads us to the fol=
lowing:</div><div><br></div><blockquote class=3D"gmail_quote" style=3D"marg=
in:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div di=
r=3D"ltr"><div> And more helpful for compiler writers and formal verificati=
on. But I totally get that it may simply be my incompetence, and I need to =
be corrected. I am not a compiler writer after all.</div><div><br></div><di=
v>(Richard Smith, feel free to jump in and correct me now!)</div><div>=C2=
=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.=
8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></di=
v><div>This may seem like a trivial difference, but it isn't. <a href=
=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0593r2.html#ty=
pe-punning" rel=3D"nofollow" target=3D"_blank">P0593 points it out</a>: whe=
n you create objects, the contents of the storage are rendered unspecified.=
And this is just as true for objects implicitly created by `std::bless`.</=
div></div></blockquote><div><br></div><div>Sure. They become reachable. It =
says nothing about their content.</div></div></blockquote><div><br></div><d=
iv>From the section I linked to (emphasis added):</div><div><br></div><bloc=
kquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:=
1px solid rgb(204,204,204);padding-left:1ex"><div>Specifically, the value h=
eld by an object is only stable <b>throughout its lifetime</b>. When the li=
fetime of the int object in line #1 ends (when its storage is reused by the=
float object in line #2), <b>its value is gone</b>. Symmetrically, when th=
e float object is created, the object has an indeterminate value ([dcl.init=
]p12), and therefore <b>any attempt to load its value results in undefined =
behavior</b>.<br></div></blockquote><div><br></div><div>The thing about P05=
93 is that it's actually a bit inconsistent about this. Since we don=
9;t have actual standards wording, we have to do the best we can with the d=
etails we've been given. The area of inconsistency is that Section 4.1 =
of the same document says:</div><div><br></div><blockquote class=3D"gmail_q=
uote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,2=
04);padding-left:1ex"><div>In some cases it is desirable to change the dyna=
mic type of existing storage while maintaining the object representation. I=
f the destination type is an implicit lifetime type, this can be accomplish=
ed by usage of std::bless to change the type, followed by std::launder to a=
cquire a pointer to the newly-created object.<br></div></blockquote><div><b=
r></div><div>That section can only be true if the previously quoted section=
is <i>false</i>. If there's a newly created object in that storage, th=
e only way to access the value from the recently-destroyed object that used=
to live there is if it's value is not "gone".</div><div><br>=
</div><div>However, section 4.1 is the odd man out in P0593. Throughout tha=
t paper, it refers to the operation which `bless` performs as "creatin=
g objects". If you create an object in storage that already contains a=
n object, then you are reusing that object's storage. Reusing an object=
's storage ends that object's lifetime.</div><div><br></div><div>An=
d the C++ object model is very clear: the value of an object whose lifetime=
has ended is not preserved. The contents of an object's storage after =
its lifetime has ended is not defined by the standard.<br></div><div><br></=
div><div>So my reading of P0593 is that if you `bless` a range of memory, a=
ny objects already residing there have their lifetimes ended. The objects w=
hich have been created by this process therefore have unspecified values, s=
ince all previous objects in that storage have been reused.<br></div><div><=
br></div><div>And once an object's lifetime ends, the value of that obj=
ect is gone.</div><div><br></div><div>Basically, consider this:</div><div><=
br></div><div style=3D"background-color:rgb(250,250,250);border-color:rgb(1=
87,187,187);border-style:solid;border-width:1px" class=3D"m_-65844339083724=
54613prettyprint"><code class=3D"m_-6584433908372454613prettyprint"><div cl=
ass=3D"m_-6584433908372454613subprettyprint"><span style=3D"color:#008" cla=
ss=3D"m_-6584433908372454613styled-by-prettify">int</span><span style=3D"co=
lor:#000" class=3D"m_-6584433908372454613styled-by-prettify"> i </span><spa=
n style=3D"color:#660" class=3D"m_-6584433908372454613styled-by-prettify">=
=3D</span><span style=3D"color:#000" class=3D"m_-6584433908372454613styled-=
by-prettify"> </span><span style=3D"color:#066" class=3D"m_-658443390837245=
4613styled-by-prettify">45</span><span style=3D"color:#660" class=3D"m_-658=
4433908372454613styled-by-prettify">;</span><span style=3D"color:#000" clas=
s=3D"m_-6584433908372454613styled-by-prettify"><br></span><span style=3D"co=
lor:#008" class=3D"m_-6584433908372454613styled-by-prettify">int</span><spa=
n style=3D"color:#000" class=3D"m_-6584433908372454613styled-by-prettify"> =
</span><span style=3D"color:#660" class=3D"m_-6584433908372454613styled-by-=
prettify">*</span><span style=3D"color:#000" class=3D"m_-658443390837245461=
3styled-by-prettify">pi </span><span style=3D"color:#660" class=3D"m_-65844=
33908372454613styled-by-prettify">=3D</span><span style=3D"color:#000" clas=
s=3D"m_-6584433908372454613styled-by-prettify"> </span><span style=3D"color=
:#008" class=3D"m_-6584433908372454613styled-by-prettify">new</span><span s=
tyle=3D"color:#660" class=3D"m_-6584433908372454613styled-by-prettify">(&am=
p;</span><span style=3D"color:#000" class=3D"m_-6584433908372454613styled-b=
y-prettify">i</span><span style=3D"color:#660" class=3D"m_-6584433908372454=
613styled-by-prettify">)</span><span style=3D"color:#000" class=3D"m_-65844=
33908372454613styled-by-prettify"> </span><span style=3D"color:#008" class=
=3D"m_-6584433908372454613styled-by-prettify">int</span><span style=3D"colo=
r:#660" class=3D"m_-6584433908372454613styled-by-prettify">;</span><span st=
yle=3D"color:#000" class=3D"m_-6584433908372454613styled-by-prettify"><br>s=
td</span><span style=3D"color:#660" class=3D"m_-6584433908372454613styled-b=
y-prettify">::</span><span style=3D"color:#000" class=3D"m_-658443390837245=
4613styled-by-prettify">cout </span><span style=3D"color:#660" class=3D"m_-=
6584433908372454613styled-by-prettify"><<</span><span style=3D"color:=
#000" class=3D"m_-6584433908372454613styled-by-prettify"> i</span><span sty=
le=3D"color:#660" class=3D"m_-6584433908372454613styled-by-prettify">;</spa=
n></div></code></div><div><br></div><div></div><div>The standard says that =
this is not guaranteed to print 45. My reading of P0593 is that the followi=
ng is the equivalent of the above:</div><div><br></div><div style=3D"backgr=
ound-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style:soli=
d;border-width:1px" class=3D"m_-6584433908372454613prettyprint"><code class=
=3D"m_-6584433908372454613prettyprint"><div class=3D"m_-6584433908372454613=
subprettyprint"><span style=3D"color:#008" class=3D"m_-6584433908372454613s=
tyled-by-prettify">int</span><span style=3D"color:#000" class=3D"m_-6584433=
908372454613styled-by-prettify"> i </span><span style=3D"color:#660" class=
=3D"m_-6584433908372454613styled-by-prettify">=3D</span><span style=3D"colo=
r:#000" class=3D"m_-6584433908372454613styled-by-prettify"> </span><span st=
yle=3D"color:#066" class=3D"m_-6584433908372454613styled-by-prettify">45</s=
pan><span style=3D"color:#660" class=3D"m_-6584433908372454613styled-by-pre=
ttify">;</span><span style=3D"color:#000" class=3D"m_-6584433908372454613st=
yled-by-prettify"><br>std</span><span style=3D"color:#660" class=3D"m_-6584=
433908372454613styled-by-prettify">::</span><span style=3D"color:#000" clas=
s=3D"m_-6584433908372454613styled-by-prettify">bless</span><span style=3D"c=
olor:#660" class=3D"m_-6584433908372454613styled-by-prettify">(&</span>=
<span style=3D"color:#000" class=3D"m_-6584433908372454613styled-by-prettif=
y">i</span><span style=3D"color:#660" class=3D"m_-6584433908372454613styled=
-by-prettify">,</span><span style=3D"color:#000" class=3D"m_-65844339083724=
54613styled-by-prettify"> </span><span style=3D"color:#008" class=3D"m_-658=
4433908372454613styled-by-prettify">sizeof</span><span style=3D"color:#660"=
class=3D"m_-6584433908372454613styled-by-prettify">(</span><span style=3D"=
color:#008" class=3D"m_-6584433908372454613styled-by-prettify">int</span><s=
pan style=3D"color:#660" class=3D"m_-6584433908372454613styled-by-prettify"=
>));</span><span style=3D"color:#000" class=3D"m_-6584433908372454613styled=
-by-prettify"> </span><span style=3D"color:#800" class=3D"m_-65844339083724=
54613styled-by-prettify">//"Creates objects" in `i`.</span><span =
style=3D"color:#000" class=3D"m_-6584433908372454613styled-by-prettify"><br=
>std</span><span style=3D"color:#660" class=3D"m_-6584433908372454613styled=
-by-prettify">::</span><span style=3D"color:#000" class=3D"m_-6584433908372=
454613styled-by-prettify">cout </span><span style=3D"color:#660" class=3D"m=
_-6584433908372454613styled-by-prettify"><<</span><span style=3D"colo=
r:#000" class=3D"m_-6584433908372454613styled-by-prettify"> i</span><span s=
tyle=3D"color:#660" class=3D"m_-6584433908372454613styled-by-prettify">;</s=
pan><span style=3D"color:#000" class=3D"m_-6584433908372454613styled-by-pre=
ttify"> </span><span style=3D"color:#800" class=3D"m_-6584433908372454613st=
yled-by-prettify">//Newly created `int` object, due to `bless` and access</=
span><span style=3D"color:#000" class=3D"m_-6584433908372454613styled-by-pr=
ettify"><br></span></div></code></div><div><br></div><div></div><div>So thi=
s is not guaranteed to print 45 either. And neither `reinterpret_cast` nor =
`launder` would change that.</div><div><br></div><div>Now, I could be misin=
terpreting P0593. Like I said, it doesn't have formal standards wording=
.. But the frequent use of the phrase "create objects", coupled wi=
th the <i>explicit</i> prohibition of type punning, suggests that I'm p=
robably right.</div></div>
<p></p>
-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/f7dffe3e-6e9c-47cb-a834-267e170640ed%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/f7dffe3e-6e9c-=
47cb-a834-267e170640ed%40isocpp.org</a>.<br>
</blockquote></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CALvx3ha9nKJTiGqj-S_UR-EBRcwS7VkNyPG8=
6Pf%3DjJgLnqj7ag%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALvx3ha9nKJTiG=
qj-S_UR-EBRcwS7VkNyPG86Pf%3DjJgLnqj7ag%40mail.gmail.com</a>.<br />
--00000000000090076a057282bfaf--
.
Author: "Arthur O'Dwyer" <arthur.j.odwyer@gmail.com>
Date: Fri, 3 Aug 2018 11:00:24 -0700
Raw View
--000000000000c66f1305728bb3bb
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
On Fri, Aug 3, 2018 at 10:33 AM, Nicol Bolas <jmckesson@gmail.com> wrote:
> I understand your point on the whole parallel constructor/destructor
> thing. The reason I suggested to use them is that it fits within the
> existing paradigm, which means you don't have to do something like create=
a
> new series of special member functions. But making new functions may be t=
he
> cleaner alternative.
>
> I'm going to invent some new strawman terminology because "trivialization=
"
> just isn't working out. Let's call it "reduction" and "regeneration". So
> every type has "reducers", which work like destructors in that they end t=
he
> object's lifetime, but they ensure that the object's values remain presen=
t.
> And every type has "regenerators", which work like constructors in that
> they begin the object's lifetime but can access the reduced value of the
> objects in their current space.
>
I like each new iteration of your terminology less and less. :P What was
wrong with "serialization" and "deserialization"?
So let's explore some rules. Trivial reduction requires:
>
> * There is no user-provided default reducer overload.
> * All subobjects must have trivial reduction.
> * The type must be TriviallyRelocatable or Implicit Lifetime (which
> requires a trivial destructor).
>
For Niall's purposes, a reducible/trivializable/serializable (persistable)
object does NOT need to be either TriviallyRelocatable or ImplicitLifetime.
For example, as far as I can tell, boost::interprocess::offset_ptr<T>
should be the canonical building block for "persistable, shareable"
objects, and it is definitely not TriviallyRelocatable.
Thinking about this further, "trivial relocation" could be redefined as
> trivial reduction, memcpy, and trivial regeneration. And thus, a type is
> trivially relocatable if it has no-argument reducer and regenerators that
> are trivial, which can be declared with `=3D default` syntax.
>
That conclusion is incorrect. The problem is that your
"reduction/regeneration" operations are not context-free: they require some
knowledge of the surrounding context. "Reducing" an object in preparation
for serializing it to disk can be trivial in some contexts but not others.
struct Poly {
virtual void foo();
};
Suppose we have an object of type `Poly` in memory, and we want to write it
out and then read it back in later, in a different process.
If that process is exactly the same as the current process, then `Poly` is
trivially reducible/serializable: we just write out the bytes of its vptr.
Later, when we read it back in, we reinterpret those bytes as a pointer,
and it points to the same place in the new process as in our current
process, and we're good to go.
But if that new process is *different* from our current process =E2=80=94 e=
ither
because it's running on a different architecture, or because it's a
different program, or because it's a new compilation of the same program,
or because it's exactly the same program but our loader does ASLR =E2=80=94=
then
when we reinterpret those serialized bytes as a vptr, they'll point to
garbage, and our code won't work.
In one scenario, our code works. In the other scenario, our code
breaks. We *cannot
say for sure whether our code will work* unless we know which scenario
we're in.
So, if you are proposing a way that C++ can guarantee that certain code
works, you *must* (at least implicitly) be proposing a way for the C++
compiler to know which scenario we're in.
And I don't see that mechanism here =E2=80=94 not in Nicol's terminology as
presented in this thread, and also not in Niall's paper.
P1144 "trivially relocatable" is easier, because the situation is nailed
down: everything happens within a single process. This lets us say *for
sure* that `struct Poly` is trivially relocatable. Whereas `struct Poly`
may or may not be safe to serialize to disk, depending on how far you're
going to transport it. Even just transporting it to a different process
might easily break it.
=E2=80=93Arthur
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CADvuK0LAA4tWyiC0Y2O5VD01c8-BGgOpNeaYSVog835KZ4M=
-bA%40mail.gmail.com.
--000000000000c66f1305728bb3bb
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Fri, Aug 3, 2018 at 10:33 AM, Nicol Bolas <span dir=3D"=
ltr"><<a href=3D"mailto:jmckesson@gmail.com" target=3D"_blank">jmckesson=
@gmail.com</a>></span> wrote:<br><div class=3D"gmail_extra"><div class=
=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8=
ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>I und=
erstand your point on the whole parallel constructor/destructor thing. The =
reason I suggested to use them is that it fits within the existing paradigm=
, which means you don't have to do something like create a new series o=
f special member functions. But making new functions may be the cleaner alt=
ernative.<br></div><div><br></div><div>I'm going to invent some new str=
awman terminology because "trivialization" just isn't working=
out. Let's call it "reduction" and "regeneration".=
So every type has "reducers", which work like destructors in tha=
t they end the object's lifetime, but they ensure that the object's=
values remain present. And every type has "regenerators", which =
work like constructors in that they begin the object's lifetime but can=
access the reduced value of the objects in their current space.</div></div=
></blockquote><div><br></div><div>I like each new iteration of your termino=
logy less and less. :P =C2=A0What was wrong with "serialization" =
and "deserialization"?</div><div><br></div><div><br></div><blockq=
uote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc =
solid;padding-left:1ex"><div dir=3D"ltr"><div>So let's explore some rul=
es. Trivial reduction requires:</div><div><br></div><div><div><div>* There =
is no user-provided default reducer overload.<br></div><div></div>* All sub=
objects must have trivial reduction.</div><div>* The type must be Trivially=
Relocatable or Implicit Lifetime (which requires a trivial destructor).</di=
v></div></div></blockquote><div><br></div><div>For Niall's purposes, a =
reducible/trivializable/serializable (persistable) object does NOT need to =
be either TriviallyRelocatable or ImplicitLifetime. For example, as far as =
I can tell, boost::interprocess::offset_ptr<T> should be the canonica=
l building block for "persistable, shareable" objects, and it is =
definitely not TriviallyRelocatable.</div><div><br></div><div><br></div><bl=
ockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #=
ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><div>Thinking about this =
further, "trivial relocation" could be redefined as trivial reduc=
tion, memcpy, and trivial regeneration. And thus, a type is trivially reloc=
atable if it has no-argument reducer and regenerators that are trivial, whi=
ch can be declared with `=3D default` syntax.</div></div></div></blockquote=
><div><br></div><div>That conclusion is incorrect. The problem is that your=
"reduction/regeneration" operations are not context-free: they r=
equire some knowledge of the surrounding context. "Reducing" an o=
bject in preparation for serializing it to disk can be trivial in some cont=
exts but not others.</div><div><br></div><div>=C2=A0 =C2=A0 struct Poly {</=
div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 virtual void foo();</div><div>=C2=A0 =
=C2=A0 };</div><div><br></div><div>Suppose we have an object of type `Poly`=
in memory, and we want to write it out and then read it back in later, in =
a different process.</div><div>If that process is exactly the same as the c=
urrent process, then `Poly` is trivially reducible/serializable: we just wr=
ite out the bytes of its vptr. Later, when we read it back in, we reinterpr=
et those bytes as a pointer, and it points to the same place in the new pro=
cess as in our current process, and we're good to go.</div><div>But if =
that new process is <i>different</i> from our current process =E2=80=94 eit=
her because it's running on a different architecture, or because it'=
;s a different program, or because it's a new compilation of the same p=
rogram, or because it's exactly the same program but our loader does AS=
LR =E2=80=94 then when we reinterpret those serialized bytes as a vptr, the=
y'll point to garbage, and our code won't work.</div><div><br></div=
><div>In one scenario, our code works. In the other scenario, our code brea=
ks. We <i>cannot say for sure whether our code will work</i> unless we know=
which scenario we're in.</div><div><br></div><div>So, if you are propo=
sing a way that C++ can guarantee that certain code works, you <i>must</i> =
(at least implicitly) be proposing a way for the C++ compiler to know which=
scenario we're in.</div><div><br></div><div>And I don't see that m=
echanism here =E2=80=94 not in Nicol's terminology as presented in this=
thread, and also not in Niall's paper.</div><div><br></div><div>P1144 =
"trivially relocatable" is easier, because the situation is naile=
d down: everything happens within a single process. This lets us say <i>for=
sure</i> that `struct Poly` is trivially relocatable. Whereas `struct Poly=
` may or may not be safe to serialize to disk, depending on how far you'=
;re going to transport it. Even just transporting it to a different process=
might easily break it.</div><div><br></div><div>=E2=80=93Arthur</div></div=
></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CADvuK0LAA4tWyiC0Y2O5VD01c8-BGgOpNeaY=
SVog835KZ4M-bA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">htt=
ps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CADvuK0LAA4tWyiC0=
Y2O5VD01c8-BGgOpNeaYSVog835KZ4M-bA%40mail.gmail.com</a>.<br />
--000000000000c66f1305728bb3bb--
.
Author: "Arthur O'Dwyer" <arthur.j.odwyer@gmail.com>
Date: Fri, 3 Aug 2018 11:11:40 -0700
Raw View
--0000000000000e0e8905728bdc26
Content-Type: multipart/alternative; boundary="0000000000000e0e8605728bdc24"
--0000000000000e0e8605728bdc24
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
On Fri, Aug 3, 2018 at 10:59 AM, Niall Douglas <nialldouglas14@gmail.com>
wrote:
> On Friday, August 3, 2018 at 6:33:25 PM UTC+1, Nicol Bolas wrote:
>>
>>
>> Thinking about this further, "trivial relocation" could be redefined as
>> trivial reduction, memcpy, and trivial regeneration. And thus, a type is
>> trivially relocatable if it has no-argument reducer and regenerators tha=
t
>> are trivial, which can be declared with `=3D default` syntax.
>>
>> Now, I'm not saying we should go changing Arthur's proposal, since it is
>> much farther along than this. But it would allow us to have a second way=
to
>> declare that a type is TriviallyRelocatable.
>>
>> Still though, that's *exciting* because this gives Arthur the ability to
> relocate polymorphic objects. I agree that the current revision of his
> proposal shouldn't propose this, but a future addendum paper certainly
> could extend his work via this mechanism.
>
P1144 already (since draft revision 1 when I put the wording in) explains
that having a vptr doesn't stop an object from being trivially relocatable.
I'm attaching the current draft for reference.
Polymorphism is not a problem for the existing C++ abstract machine. It's
only a problem when you start extending the abstract machine to permit *sha=
ring
of data* between processes that do not share the same *code*.
Likewise, pointers are not a problem for the existing C++ abstract
machine. They are only a problem when you start extending the abstract
machine to permit sharing of data between processes that do not share the
same *address space*.
=E2=80=93Arthur
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CADvuK0JPThgCbGpjm3tSLB8DhOF15Yr4eg78khK4sUpS1xW=
TKQ%40mail.gmail.com.
--0000000000000e0e8605728bdc24
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Fri, Aug 3, 2018 at 10:59 AM, Niall Douglas <span dir=
=3D"ltr"><<a href=3D"mailto:nialldouglas14@gmail.com" target=3D"_blank">=
nialldouglas14@gmail.com</a>></span> wrote:<br><div class=3D"gmail_extra=
"><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"mar=
gin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr=
"><span class=3D"">On Friday, August 3, 2018 at 6:33:25 PM UTC+1, Nicol Bol=
as wrote:</span><span class=3D""><blockquote class=3D"gmail_quote" style=3D=
"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><d=
iv dir=3D"ltr"><div><div></div><div><br></div><div>Thinking about this furt=
her, "trivial relocation" could be redefined as trivial reduction=
, memcpy, and trivial regeneration. And thus, a type is trivially relocatab=
le if it has no-argument reducer and regenerators that are trivial, which c=
an be declared with `=3D default` syntax.</div><div><br></div><div>Now, I&#=
39;m not saying we should go changing Arthur's proposal, since it is mu=
ch farther along than this. But it would allow us to have a second way to d=
eclare that a type is TriviallyRelocatable.<br></div><div><br></div></div><=
/div></blockquote></span><div>Still though, that's <i>exciting</i>=C2=
=A0because this gives Arthur the ability to relocate polymorphic objects. I=
agree that the current revision of his proposal shouldn't propose this=
, but a future addendum paper certainly could extend his work via this mech=
anism.</div></div></blockquote><div><br></div><div>P1144 already (since dra=
ft revision 1 when I put the wording in) explains that having a vptr doesn&=
#39;t stop an object from being trivially relocatable.</div><div>I'm at=
taching the current draft for reference.</div><div><br></div><div>Polymorph=
ism is not a problem for the existing C++ abstract machine.=C2=A0 It's =
only a problem when you start extending the abstract machine to permit <i>s=
haring of data</i> between processes that do not share the same=C2=A0<i>cod=
e</i>.</div><div><br></div><div>Likewise, pointers are not a problem for th=
e existing C++ abstract machine.=C2=A0 They are only a problem when you sta=
rt extending the abstract machine to permit sharing of data between process=
es that do not share the same <i>address space</i>.</div><div><br></div><di=
v>=E2=80=93Arthur</div></div></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CADvuK0JPThgCbGpjm3tSLB8DhOF15Yr4eg78=
khK4sUpS1xWTKQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">htt=
ps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CADvuK0JPThgCbGpj=
m3tSLB8DhOF15Yr4eg78khK4sUpS1xWTKQ%40mail.gmail.com</a>.<br />
--0000000000000e0e8605728bdc24--
--0000000000000e0e8905728bdc26
Content-Type: text/html; charset="UTF-8";
name="object-relocation-in-terms-of-move-plus-destroy-draft-10.html"
Content-Disposition: attachment;
filename="object-relocation-in-terms-of-move-plus-destroy-draft-10.html"
Content-Transfer-Encoding: base64
X-Attachment-Id: f_jkeb23lj0
PCFkb2N0eXBlIGh0bWw+PGh0bWwgbGFuZz0iZW4iPgogPGhlYWQ+CiAgPG1ldGEgY29udGVudD0i
dGV4dC9odG1sOyBjaGFyc2V0PXV0Zi04IiBodHRwLWVxdWl2PSJDb250ZW50LVR5cGUiPgogIDxt
ZXRhIGNvbnRlbnQ9IndpZHRoPWRldmljZS13aWR0aCwgaW5pdGlhbC1zY2FsZT0xLCBzaHJpbmst
dG8tZml0PW5vIiBuYW1lPSJ2aWV3cG9ydCI+CiAgPHRpdGxlPkQxMTQ0UjA6IE9iamVjdCByZWxv
Y2F0aW9uIGluIHRlcm1zIG9mIG1vdmUgcGx1cyBkZXN0cm95PC90aXRsZT4KPHN0eWxlIGRhdGEt
ZmlsbC13aXRoPSJzdHlsZXNoZWV0Ij4vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAg
ICAgICAgICAgIFN0eWxlIHNoZWV0IGZvciB0aGUgVzNDIHNwZWNpZmljYXRpb25zICAgICAgICAg
ICAgICAgICAgICoKICoKICogU3BlY2lhbCBjbGFzc2VzIGhhbmRsZWQgYnkgdGhpcyBzdHlsZSBz
aGVldCBpbmNsdWRlOgogKgogKiBJbmRpY2VzCiAqICAgLSAudG9jIGZvciB0aGUgVGFibGUgb2Yg
Q29udGVudHMgKDxvbCBjbGFzcz0idG9jIj4pCiAqICAgICArIDxzcGFuIGNsYXNzPSJzZWNubyI+
IGZvciB0aGUgc2VjdGlvbiBudW1iZXJzCiAqICAgLSAjdG9jIGZvciB0aGUgVGFibGUgb2YgQ29u
dGVudHMgKDxuYXYgaWQ9InRvYyI+KQogKiAgIC0gdWwuaW5kZXggZm9yIEluZGljZXMgKDxhIGhy
ZWY9IiNyZWYiPnRlcm08L2E+PHNwYW4+LCBpbiDCp04uTTwvc3Bhbj4pCiAqICAgLSB0YWJsZS5p
bmRleCBmb3IgSW5kZXggVGFibGVzIChlLmcuIGZvciBwcm9wZXJ0aWVzIG9yIGVsZW1lbnRzKQog
KgogKiBTdHJ1Y3R1cmFsIE1hcmt1cAogKiAgIC0gdGFibGUuZGF0YSBmb3IgZ2VuZXJhbCBkYXRh
IHRhYmxlcwogKiAgICAgLT4gdXNlICdzY29wZScgYXR0cmlidXRlLCA8Y29sZ3JvdXA+LCA8dGhl
YWQ+LCBhbmQgPHRib2R5PiBmb3IgYmVzdCByZXN1bHRzICEKICogICAgIC0+IHVzZSA8dGFibGUg
Y2xhc3M9J2NvbXBsZXggZGF0YSc+IGZvciBleHRyYS1jb21wbGV4IHRhYmxlcwogKiAgICAgLT4g
dXNlIDx0ZCBjbGFzcz0nbG9uZyc+IGZvciBwYXJhZ3JhcGgtbGVuZ3RoIGNlbGwgY29udGVudAog
KiAgICAgLT4gdXNlIDx0ZCBjbGFzcz0ncHJlJz4gd2hlbiBtYW51YWwgbGluZSBicmVha3MvaW5k
ZW50YXRpb24gd291bGQgaGVscCByZWFkYWJpbGl0eQogKiAgIC0gZGwuc3dpdGNoIGZvciBzd2l0
Y2ggc3RhdGVtZW50cwogKiAgIC0gb2wuYWxnb3JpdGhtIGZvciBhbGdvcml0aG1zIChoZWxwcyB0
byB2aXN1YWxpemUgbmVzdGluZykKICogICAtIC5maWd1cmUgYW5kIC5jYXB0aW9uIChIVE1MNCkg
YW5kIGZpZ3VyZSBhbmQgZmlnY2FwdGlvbiAoSFRNTDUpCiAqICAgICAtPiAuc2lkZWZpZ3VyZSBm
b3IgcmlnaHQtZmxvYXRlZCBmaWd1cmVzCiAqICAgLSBpbnMvZGVsCiAqCiAqIENvZGUKICogICAt
IHByZSBhbmQgY29kZQogKgogKiBTcGVjaWFsIFNlY3Rpb25zCiAqICAgLSAubm90ZSAgICAgICBm
b3IgaW5mb3JtYXRpdmUgbm90ZXMgICAgICAgICAgICAgKGRpdiwgcCwgc3BhbiwgYXNpZGUsIGRl
dGFpbHMpCiAqICAgLSAuZXhhbXBsZSAgICBmb3IgaW5mb3JtYXRpdmUgZXhhbXBsZXMgICAgICAg
ICAgKGRpdiwgcCwgcHJlLCBzcGFuKQogKiAgIC0gLmlzc3VlICAgICAgZm9yIGlzc3VlcyAgICAg
ICAgICAgICAgICAgICAgICAgIChkaXYsIHAsIHNwYW4pCiAqICAgLSAuYXNzZXJ0aW9uICBmb3Ig
YXNzZXJ0aW9ucyAgICAgICAgICAgICAgICAgICAgKGRpdiwgcCwgc3BhbikKICogICAtIC5hZHZp
c2VtZW50IGZvciBsb3VkIG5vcm1hdGl2ZSBzdGF0ZW1lbnRzICAgICAoZGl2LCBwLCBzdHJvbmcp
CiAqICAgLSAuYW5ub3lpbmctd2FybmluZyBmb3Igc3BlYyBvYnNvbGV0aW9uIG5vdGljZXMgKGRp
diwgYXNpZGUsIGRldGFpbHMpCiAqCiAqIERlZmluaXRpb24gQm94ZXMKICogICAtIHByZS5kZWYg
ICBmb3IgV2ViSURMIGRlZmluaXRpb25zCiAqICAgLSB0YWJsZS5kZWYgZm9yIHRhYmxlcyB0aGF0
IGRlZmluZSBvdGhlciBlbnRpdGllcyAoZS5nLiBDU1MgcHJvcGVydGllcykKICogICAtIGRsLmRl
ZiAgICBmb3IgZGVmaW5pdGlvbiBsaXN0cyB0aGF0IGRlZmluZSBvdGhlciBlbnRpdGxlcyAoZS5n
LiBIVE1MIGVsZW1lbnRzKQogKgogKiBOdW1iZXJpbmcKICogICAtIC5zZWNubyBmb3Igc2VjdGlv
biBudW1iZXJzIGluIC50b2MgYW5kIGhlYWRpbmdzICg8c3BhbiBjbGFzcz0nc2Vjbm8nPjMuMjwv
c3Bhbj4pCiAqICAgLSAubWFya2VyIGZvciBzb3VyY2UtaW5zZXJ0ZWQgZXhhbXBsZS9maWd1cmUv
aXNzdWUgbnVtYmVycyAoPHNwYW4gY2xhc3M9J21hcmtlcic+SXNzdWUgNDwvc3Bhbj4pCiAqICAg
LSA6OmJlZm9yZSBzdHlsZWQgZm9yIENTUy1nZW5lcmF0ZWQgaXNzdWUvZXhhbXBsZS9maWd1cmUg
bnVtYmVyczoKICogICAgIC0+IERvY3VtZW50cyB3aXNoaW5nIHRvIHVzZSB0aGlzIG9ubHkgbmVl
ZCB0byBhZGQKICogICAgICAgIGZpZ2NhcHRpb246OmJlZm9yZSwKICogICAgICAgIC5jYXB0aW9u
OjpiZWZvcmUgeyBjb250ZW50OiAiRmlndXJlICIgIGNvdW50ZXIoZmlndXJlKSAiICI7ICB9CiAq
ICAgICAgICAuZXhhbXBsZTo6YmVmb3JlIHsgY29udGVudDogIkV4YW1wbGUgIiBjb3VudGVyKGV4
YW1wbGUpICIgIjsgfQogKiAgICAgICAgLmlzc3VlOjpiZWZvcmUgICB7IGNvbnRlbnQ6ICJJc3N1
ZSAiICAgY291bnRlcihpc3N1ZSkgIiAiOyAgIH0KICoKICogSGVhZGVyIFN0dWZmIChpZ25vcmUs
IGp1c3QgZG9uJ3QgY29uZmxpY3Qgd2l0aCB0aGVzZSBjbGFzc2VzKQogKiAgIC0gLmhlYWQgZm9y
IHRoZSBoZWFkZXIKICogICAtIC5jb3B5cmlnaHQgZm9yIHRoZSBjb3B5cmlnaHQKICoKICogTWlz
Y2VsbGFuZW91cwogKiAgIC0gLm92ZXJsYXJnZSBmb3IgdGhpbmdzIHRoYXQgc2hvdWxkIGJlIGFz
IHdpZGUgYXMgcG9zc2libGUsIGV2ZW4gaWYKICogICAgIHRoYXQgb3ZlcmZsb3dzIHRoZSBib2R5
IHRleHQgYXJlYS4gVGhpcyBjYW4gYmUgdXNlZCBvbiBhbiBpdGVtIG9yCiAqICAgICBvbiBpdHMg
Y29udGFpbmVyLCBkZXBlbmRpbmcgb24gdGhlIGVmZmVjdCBkZXNpcmVkLgogKiAgICAgTm90ZSB0
aGF0IHRoaXMgc3R5bGluZyBiYXNpY2FsbHkgZG9lc24ndCBoZWxwIGF0IGFsbCB3aGVuIHByaW50
aW5nLAogKiAgICAgc2luY2UgQTQgcGFwZXIgaXNuJ3QgbXVjaCB3aWRlciB0aGFuIHRoZSBtYXgt
d2lkdGggaGVyZS4KICogICAgIEl0J3MgYmV0dGVyIHRvIGRlc2lnbiB0aGluZ3MgdG8gZml0IGlu
dG8gYSBuYXJyb3dlciBtZWFzdXJlIGlmIHBvc3NpYmxlLgogKiAgIC0ganMtYWRkZWQgVG9DIGp1
bXAgbGlua3MgKHNlZSBmaXh1cC5qcykKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqKiovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBC
b2R5ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqKioqKiovCgoJYm9keSB7CgkJY291bnRlci1yZXNldDogZXhhbXBsZSBmaWd1cmUgaXNzdWU7
CgoJCS8qIExheW91dCAqLwoJCW1heC13aWR0aDogNTBlbTsgICAgICAgICAgICAgICAvKiBsaW1p
dCBsaW5lIGxlbmd0aCB0byA1MGVtIGZvciByZWFkYWJpbGl0eSAgICovCgkJbWFyZ2luOiAwIGF1
dG87ICAgICAgICAgICAgICAgIC8qIGNlbnRlciB0ZXh0IHdpdGhpbiBwYWdlICAgICAgICAgICAg
ICAgICAgICAgKi8KCQlwYWRkaW5nOiAxLjZlbSAxLjVlbSAyZW0gNTBweDsgLyogYXNzdW1lIDE2
cHggZm9udCBzaXplIGZvciBkb3dubGV2ZWwgY2xpZW50cyAqLwoJCXBhZGRpbmc6IDEuNmVtIDEu
NWVtIDJlbSBjYWxjKDI2cHggKyAxLjVlbSk7IC8qIGxlYXZlIHNwYWNlIGZvciBzdGF0dXMgZmxh
ZyAgICAgKi8KCgkJLyogVHlwb2dyYXBoeSAqLwoJCWxpbmUtaGVpZ2h0OiAxLjU7CgkJZm9udC1m
YW1pbHk6IHNhbnMtc2VyaWY7CgkJd2lkb3dzOiAyOwoJCW9ycGhhbnM6IDI7CgkJd29yZC13cmFw
OiBicmVhay13b3JkOwoJCW92ZXJmbG93LXdyYXA6IGJyZWFrLXdvcmQ7CgkJaHlwaGVuczogYXV0
bzsKCgkJLyogQ29sb3JzICovCgkJY29sb3I6IGJsYWNrOwoJCWJhY2tncm91bmQ6IHdoaXRlIHRv
cCBsZWZ0IGZpeGVkIG5vLXJlcGVhdDsKCQliYWNrZ3JvdW5kLXNpemU6IDI1cHggYXV0bzsKCX0K
CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICBGcm9u
dCBNYXR0ZXIgJiBOYXZpZ2F0aW9uICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqLwoKLyoqIEhlYWRlciAqKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCglkaXYuaGVhZCB7IG1h
cmdpbi1ib3R0b206IDFlbSB9CglkaXYuaGVhZCBociB7IGJvcmRlci1zdHlsZTogc29saWQ7IH0K
CglkaXYuaGVhZCBoMSB7CgkJZm9udC13ZWlnaHQ6IGJvbGQ7CgkJbWFyZ2luOiAwIDAgLjFlbTsK
CQlmb250LXNpemU6IDIyMCU7Cgl9CgoJZGl2LmhlYWQgaDIgeyBtYXJnaW4tYm90dG9tOiAxLjVl
bTt9CgovKiogVzNDIExvZ28gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKCS5oZWFkIC5sb2dvIHsKCQlmbG9hdDogcmln
aHQ7CgkJbWFyZ2luOiAwLjRyZW0gMCAwLjJyZW0gLjRyZW07Cgl9CgoJLmhlYWQgaW1nW3NyYyo9
ImxvZ29zL1czQyJdIHsKCQlkaXNwbGF5OiBibG9jazsKCQlib3JkZXI6IHNvbGlkICMxYTVlOWE7
CgkJYm9yZGVyLXdpZHRoOiAuNjVyZW0gLjdyZW0gLjZyZW07CgkJYm9yZGVyLXJhZGl1czogLjRy
ZW07CgkJYmFja2dyb3VuZDogIzFhNWU5YTsKCQljb2xvcjogd2hpdGU7CgkJZm9udC13ZWlnaHQ6
IGJvbGQ7Cgl9CgoJLmhlYWQgYTpob3ZlciA+IGltZ1tzcmMqPSJsb2dvcy9XM0MiXSwKCS5oZWFk
IGE6Zm9jdXMgPiBpbWdbc3JjKj0ibG9nb3MvVzNDIl0gewoJCW9wYWNpdHk6IC44OwoJfQoKCS5o
ZWFkIGE6YWN0aXZlID4gaW1nW3NyYyo9ImxvZ29zL1czQyJdIHsKCQliYWNrZ3JvdW5kOiAjYzAw
OwoJCWJvcmRlci1jb2xvcjogI2MwMDsKCX0KCgkvKiBzZWUgYWxzbyBhZGRpdGlvbmFsIHJ1bGVz
IGluIExpbmsgU3R5bGluZyBzZWN0aW9uICovCgovKiogQ29weXJpZ2h0ICoqKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKCXAu
Y29weXJpZ2h0LAoJcC5jb3B5cmlnaHQgc21hbGwgeyBmb250LXNpemU6IHNtYWxsIH0KCi8qKiBC
YWNrIHRvIFRvcCAvIFRvQyBUb2dnbGUgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqKiovCgoJQG1lZGlhIHByaW50IHsKCQkjdG9jLW5hdiB7CgkJCWRpc3Bs
YXk6IG5vbmU7CgkJfQoJfQoJQG1lZGlhIG5vdCBwcmludCB7CgkJI3RvYy1uYXYgewoJCQlwb3Np
dGlvbjogZml4ZWQ7CgkJCXotaW5kZXg6IDI7CgkJCWJvdHRvbTogMDsgbGVmdDogMDsKCQkJbWFy
Z2luOiAwOwoJCQltaW4td2lkdGg6IDEuMzNlbTsKCQkJYm9yZGVyLXRvcC1yaWdodC1yYWRpdXM6
IDJyZW07CgkJCWJveC1zaGFkb3c6IDAgMCAycHg7CgkJCWZvbnQtc2l6ZTogMS41ZW07CgkJCWNv
bG9yOiBibGFjazsKCQl9CgkJI3RvYy1uYXYgPiBhIHsKCQkJZGlzcGxheTogYmxvY2s7CgkJCXdo
aXRlLXNwYWNlOiBub3dyYXA7CgoJCQloZWlnaHQ6IDEuMzNlbTsKCQkJcGFkZGluZzogLjFlbSAw
LjNlbTsKCQkJbWFyZ2luOiAwOwoKCQkJYmFja2dyb3VuZDogd2hpdGU7CgkJCWJveC1zaGFkb3c6
IDAgMCAycHg7CgkJCWJvcmRlcjogbm9uZTsKCQkJYm9yZGVyLXRvcC1yaWdodC1yYWRpdXM6IDEu
MzNlbTsKCQkJYmFja2dyb3VuZDogd2hpdGU7CgkJfQoJCSN0b2MtbmF2ID4gI3RvYy1qdW1wIHsK
CQkJcGFkZGluZy1ib3R0b206IDJlbTsKCQkJbWFyZ2luLWJvdHRvbTogLTEuOWVtOwoJCX0KCgkJ
I3RvYy1uYXYgPiBhOmhvdmVyLAoJCSN0b2MtbmF2ID4gYTpmb2N1cyB7CgkJCWJhY2tncm91bmQ6
ICNmOGY4Zjg7CgkJfQoJCSN0b2MtbmF2ID4gYTpub3QoOmhvdmVyKTpub3QoOmZvY3VzKSB7CgkJ
CWNvbG9yOiAjNzA3MDcwOwoJCX0KCgkJLyogc3RhdHVzYmFyIGdldHMgaW4gdGhlIHdheSBvbiBr
ZXlib2FyZCBmb2N1czsgcmVtb3ZlIG9uY2UgYnJvd3NlcnMgZml4ICovCgkJI3RvYy1uYXYgPiBh
W2hyZWY9IiN0b2MiXTpub3QoOmhvdmVyKTpmb2N1czpsYXN0LWNoaWxkIHsKCQkJcGFkZGluZy1i
b3R0b206IDEuNXJlbTsKCQl9CgoJCSN0b2MtbmF2Om5vdCg6aG92ZXIpID4gYTpub3QoOmZvY3Vz
KSA+IHNwYW4gKyBzcGFuIHsKCQkJLyogSWRlYWxseSB0aGlzIHVzZXMgOmZvY3VzLXdpdGhpbiBv
biAjdG9jLW5hdiAqLwoJCQlkaXNwbGF5OiBub25lOwoJCX0KCQkjdG9jLW5hdiA+IGEgPiBzcGFu
ICsgc3BhbiB7CgkJCXBhZGRpbmctcmlnaHQ6IDAuMmVtOwoJCX0KCgkJI3RvYy10b2dnbGUtaW5s
aW5lIHsKCQkJdmVydGljYWwtYWxpZ246IDAuMDVlbTsKCQkJZm9udC1zaXplOiA4MCU7CgkJCWNv
bG9yOiBncmF5OwoJCQljb2xvcjogaHNsYSgyMDMsMjAlLDQwJSwuNyk7CgkJCWJvcmRlci1zdHls
ZTogbm9uZTsKCQkJYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7CgkJCXBvc2l0aW9uOiByZWxhdGl2
ZTsKCQl9CgkJI3RvYy10b2dnbGUtaW5saW5lOmhvdmVyOm5vdCg6YWN0aXZlKSwKCQkjdG9jLXRv
Z2dsZS1pbmxpbmU6Zm9jdXM6bm90KDphY3RpdmUpIHsKCQkJdGV4dC1zaGFkb3c6IDFweCAxcHgg
c2lsdmVyOwoJCQl0b3A6IC0xcHg7CgkJCWxlZnQ6IC0xcHg7CgkJfQoKCQkjdG9jLW5hdiA6YWN0
aXZlIHsKCQkJY29sb3I6ICNDMDA7CgkJfQoJfQoKLyoqIFRvQyBTaWRlYmFyICoqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgkv
KiBGbG9hdGluZyBzaWRlYmFyICovCglAbWVkaWEgc2NyZWVuIHsKCQlib2R5LnRvYy1zaWRlYmFy
ICN0b2MgewoJCQlwb3NpdGlvbjogZml4ZWQ7CgkJCXRvcDogMDsgYm90dG9tOiAwOwoJCQlsZWZ0
OiAwOwoJCQl3aWR0aDogMjMuNWVtOwoJCQltYXgtd2lkdGg6IDgwJTsKCQkJbWF4LXdpZHRoOiBj
YWxjKDEwMCUgLSAyZW0gLSAyNnB4KTsKCQkJb3ZlcmZsb3c6IGF1dG87CgkJCXBhZGRpbmc6IDAg
MWVtOwoJCQlwYWRkaW5nLWxlZnQ6IDQycHg7CgkJCXBhZGRpbmctbGVmdDogY2FsYygxZW0gKyAy
NnB4KTsKCQkJYmFja2dyb3VuZDogaW5oZXJpdDsKCQkJYmFja2dyb3VuZC1jb2xvcjogI2Y3Zjhm
OTsKCQkJei1pbmRleDogMTsKCQkJYm94LXNoYWRvdzogLS4xZW0gMCAuMjVlbSByZ2JhKDAsMCww
LC4xKSBpbnNldDsKCQl9CgkJYm9keS50b2Mtc2lkZWJhciAjdG9jIGgyIHsKCQkJbWFyZ2luLXRv
cDogLjhyZW07CgkJCWZvbnQtdmFyaWFudDogc21hbGwtY2FwczsKCQkJZm9udC12YXJpYW50OiBh
bGwtc21hbGwtY2FwczsKCQkJdGV4dC10cmFuc2Zvcm06IGxvd2VyY2FzZTsKCQkJZm9udC13ZWln
aHQ6IGJvbGQ7CgkJCWNvbG9yOiBncmF5OwoJCQljb2xvcjogaHNsYSgyMDMsMjAlLDQwJSwuNyk7
CgkJfQoJCWJvZHkudG9jLXNpZGViYXIgI3RvYy1qdW1wOm5vdCg6Zm9jdXMpIHsKCQkJd2lkdGg6
IDA7CgkJCWhlaWdodDogMDsKCQkJcGFkZGluZzogMDsKCQkJcG9zaXRpb246IGFic29sdXRlOwoJ
CQlvdmVyZmxvdzogaGlkZGVuOwoJCX0KCX0KCS8qIEhpZGUgbWFpbiBzY3JvbGxlciB3aGVuIG9u
bHkgdGhlIFRvQyBpcyB2aXNpYmxlIGFueXdheSAqLwoJQG1lZGlhIHNjcmVlbiBhbmQgKG1heC13
aWR0aDogMjhlbSkgewoJCWJvZHkudG9jLXNpZGViYXIgewoJCQlvdmVyZmxvdzogaGlkZGVuOwoJ
CX0KCX0KCgkvKiBTaWRlYmFyIHdpdGggaXRzIG93biBzcGFjZSAqLwoJQG1lZGlhIHNjcmVlbiBh
bmQgKG1pbi13aWR0aDogNzhlbSkgewoJCWJvZHk6bm90KC50b2MtaW5saW5lKSAjdG9jIHsKCQkJ
cG9zaXRpb246IGZpeGVkOwoJCQl0b3A6IDA7IGJvdHRvbTogMDsKCQkJbGVmdDogMDsKCQkJd2lk
dGg6IDIzLjVlbTsKCQkJb3ZlcmZsb3c6IGF1dG87CgkJCXBhZGRpbmc6IDAgMWVtOwoJCQlwYWRk
aW5nLWxlZnQ6IDQycHg7CgkJCXBhZGRpbmctbGVmdDogY2FsYygxZW0gKyAyNnB4KTsKCQkJYmFj
a2dyb3VuZDogaW5oZXJpdDsKCQkJYmFja2dyb3VuZC1jb2xvcjogI2Y3ZjhmOTsKCQkJei1pbmRl
eDogMTsKCQkJYm94LXNoYWRvdzogLS4xZW0gMCAuMjVlbSByZ2JhKDAsMCwwLC4xKSBpbnNldDsK
CQl9CgkJYm9keTpub3QoLnRvYy1pbmxpbmUpICN0b2MgaDIgewoJCQltYXJnaW4tdG9wOiAuOHJl
bTsKCQkJZm9udC12YXJpYW50OiBzbWFsbC1jYXBzOwoJCQlmb250LXZhcmlhbnQ6IGFsbC1zbWFs
bC1jYXBzOwoJCQl0ZXh0LXRyYW5zZm9ybTogbG93ZXJjYXNlOwoJCQlmb250LXdlaWdodDogYm9s
ZDsKCQkJY29sb3I6IGdyYXk7CgkJCWNvbG9yOiBoc2xhKDIwMywyMCUsNDAlLC43KTsKCQl9CgoJ
CWJvZHk6bm90KC50b2MtaW5saW5lKSB7CgkJCXBhZGRpbmctbGVmdDogMjllbTsKCQl9CgkJLyog
U2VlIGFsc28gT3ZlcmZsb3cgc2VjdGlvbiBhdCB0aGUgYm90dG9tICovCgoJCWJvZHk6bm90KC50
b2MtaW5saW5lKSAjdG9jLWp1bXA6bm90KDpmb2N1cykgewoJCQl3aWR0aDogMDsKCQkJaGVpZ2h0
OiAwOwoJCQlwYWRkaW5nOiAwOwoJCQlwb3NpdGlvbjogYWJzb2x1dGU7CgkJCW92ZXJmbG93OiBo
aWRkZW47CgkJfQoJfQoJQG1lZGlhIHNjcmVlbiBhbmQgKG1pbi13aWR0aDogOTBlbSkgewoJCWJv
ZHk6bm90KC50b2MtaW5saW5lKSB7CgkJCW1hcmdpbjogMCA0ZW07CgkJfQoJfQoKLyoqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKi8KLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNlY3Rpb25p
bmcgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyoqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqKi8KCi8qKiBIZWFkaW5ncyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgoJaDEsIGgyLCBoMywgaDQsIGg1LCBoNiwg
ZHQgewoJCXBhZ2UtYnJlYWstYWZ0ZXI6IGF2b2lkOwoJCXBhZ2UtYnJlYWstaW5zaWRlOiBhdm9p
ZDsKCQlmb250OiAxMDAlIHNhbnMtc2VyaWY7ICAgLyogUmVzZXQgYWxsIGZvbnQgc3R5bGluZyB0
byBjbGVhciBvdXQgVUEgc3R5bGVzICovCgkJZm9udC1mYW1pbHk6IGluaGVyaXQ7ICAgIC8qIElu
aGVyaXQgdGhlIGZvbnQgZmFtaWx5LiAqLwoJCWxpbmUtaGVpZ2h0OiAxLjI7ICAgICAgICAvKiBL
ZWVwIHdyYXBwZWQgaGVhZGluZ3MgY29tcGFjdCAqLwoJCWh5cGhlbnM6IG1hbnVhbDsgICAgICAg
ICAvKiBIeXBoZW5hdGVkIGhlYWRpbmdzIGxvb2sgd2VpcmQgKi8KCX0KCgloMiwgaDMsIGg0LCBo
NSwgaDYgewoJCW1hcmdpbi10b3A6IDNyZW07Cgl9CgoJaDEsIGgyLCBoMyB7CgkJY29sb3I6ICMw
MDVBOUM7CgkJYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7Cgl9CgoJaDEgeyBmb250LXNpemU6IDE3
MCU7IH0KCWgyIHsgZm9udC1zaXplOiAxNDAlOyB9CgloMyB7IGZvbnQtc2l6ZTogMTIwJTsgfQoJ
aDQgeyBmb250LXdlaWdodDogYm9sZDsgfQoJaDUgeyBmb250LXN0eWxlOiBpdGFsaWM7IH0KCWg2
IHsgZm9udC12YXJpYW50OiBzbWFsbC1jYXBzOyB9CglkdCB7IGZvbnQtd2VpZ2h0OiBib2xkOyB9
CgovKiogU3ViaGVhZGluZ3MgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqLwoKCWgxICsgaDIsCgkjc3VidGl0bGUgewoJCS8qICNz
dWJ0aXRsZSBpcyBhIHN1YnRpdGxlIGluIGFuIEgyIHVuZGVyIHRoZSBIMSAqLwoJCW1hcmdpbi10
b3A6IDA7Cgl9CgloMiArIGgzLAoJaDMgKyBoNCwKCWg0ICsgaDUsCgloNSArIGg2IHsKCQltYXJn
aW4tdG9wOiAxLjJlbTsgLyogPSAxIHggbGluZS1oZWlnaHQgKi8KCX0KCi8qKiBTZWN0aW9uIGRp
dmlkZXIgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqKioqKiovCgoJOm5vdCguaGVhZCkgPiBociB7CgkJZm9udC1zaXplOiAxLjVlbTsKCQl0ZXh0
LWFsaWduOiBjZW50ZXI7CgkJbWFyZ2luOiAxZW0gYXV0bzsKCQloZWlnaHQ6IGF1dG87CgkJYm9y
ZGVyOiB0cmFuc3BhcmVudCBzb2xpZCAwOwoJCWJhY2tncm91bmQ6IHRyYW5zcGFyZW50OwoJfQoJ
Om5vdCguaGVhZCkgPiBocjo6YmVmb3JlIHsKCQljb250ZW50OiAiXDI3MjdcMjAwM1wyMDAzXDI3
MjdcMjAwM1wyMDAzXDI3MjciOwoJfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyogICAgICAg
ICAgICAgICAgICAgICAgICAgICAgUGFyYWdyYXBocyBhbmQgTGlzdHMgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCglwIHsKCQltYXJnaW46IDFl
bSAwOwoJfQoKCWRkID4gcDpmaXJzdC1jaGlsZCwKCWxpID4gcDpmaXJzdC1jaGlsZCB7CgkJbWFy
Z2luLXRvcDogMDsKCX0KCgl1bCwgb2wgewoJCW1hcmdpbi1sZWZ0OiAwOwoJCXBhZGRpbmctbGVm
dDogMmVtOwoJfQoKCWxpIHsKCQltYXJnaW46IDAuMjVlbSAwIDAuNWVtOwoJCXBhZGRpbmc6IDA7
Cgl9CgoJZGwgZGQgewoJCW1hcmdpbjogMCAwIC41ZW0gMmVtOwoJfQoKCS5oZWFkIGRkICsgZGQg
eyAvKiBjb21wYWN0IGZvciBoZWFkZXIgKi8KCQltYXJnaW4tdG9wOiAtLjVlbTsKCX0KCgkvKiBT
dHlsZSBmb3IgYWxnb3JpdGhtcyAqLwoJb2wuYWxnb3JpdGhtIG9sOm5vdCguYWxnb3JpdGhtKSwK
CS5hbGdvcml0aG0gPiBvbCBvbDpub3QoLmFsZ29yaXRobSkgewoJIGJvcmRlci1sZWZ0OiAwLjVl
bSBzb2xpZCAjREVGOwoJfQoKCS8qIFB1dCBuaWNlIGJveGVzIGFyb3VuZCBlYWNoIGFsZ29yaXRo
bS4gKi8KCVtkYXRhLWFsZ29yaXRobV06bm90KC5oZWFkaW5nKSB7CgkgIHBhZGRpbmc6IC41ZW07
CgkgIGJvcmRlcjogdGhpbiBzb2xpZCAjZGRkOyBib3JkZXItcmFkaXVzOiAuNWVtOwoJICBtYXJn
aW46IC41ZW0gY2FsYygtMC41ZW0gLSAxcHgpOwoJfQoJW2RhdGEtYWxnb3JpdGhtXTpub3QoLmhl
YWRpbmcpID4gOmZpcnN0LWNoaWxkIHsKCSAgbWFyZ2luLXRvcDogMDsKCX0KCVtkYXRhLWFsZ29y
aXRobV06bm90KC5oZWFkaW5nKSA+IDpsYXN0LWNoaWxkIHsKCSAgbWFyZ2luLWJvdHRvbTogMDsK
CX0KCgkvKiBTdHlsZSBmb3Igc3dpdGNoL2Nhc2UgPGRsPnMgKi8KCWRsLnN3aXRjaCA+IGRkID4g
b2wub25seSwKCWRsLnN3aXRjaCA+IGRkID4gLm9ubHkgPiBvbCB7CgkgbWFyZ2luLWxlZnQ6IDA7
Cgl9CglkbC5zd2l0Y2ggPiBkZCA+IG9sLmFsZ29yaXRobSwKCWRsLnN3aXRjaCA+IGRkID4gLmFs
Z29yaXRobSA+IG9sIHsKCSBtYXJnaW4tbGVmdDogLTJlbTsKCX0KCWRsLnN3aXRjaCB7CgkgcGFk
ZGluZy1sZWZ0OiAyZW07Cgl9CglkbC5zd2l0Y2ggPiBkdCB7CgkgdGV4dC1pbmRlbnQ6IC0xLjVl
bTsKCSBtYXJnaW4tdG9wOiAxZW07Cgl9CglkbC5zd2l0Y2ggPiBkdCArIGR0IHsKCSBtYXJnaW4t
dG9wOiAwOwoJfQoJZGwuc3dpdGNoID4gZHQ6OmJlZm9yZSB7CgkgY29udGVudDogJ1wyMUFBJzsK
CSBwYWRkaW5nOiAwIDAuNWVtIDAgMDsKCSBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7Cgkgd2lkdGg6
IDFlbTsKCSB0ZXh0LWFsaWduOiByaWdodDsKCSBsaW5lLWhlaWdodDogMC41ZW07Cgl9CgovKiog
VGVybWlub2xvZ3kgTWFya3VwICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqLwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgSW5saW5lIE1hcmt1cCAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKiogVGVybWlub2xvZ3kgTWFy
a3VwICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqLwoJZGZuICAgeyAvKiBEZWZpbmluZyBpbnN0YW5jZSAqLwoJCWZvbnQtd2VpZ2h0OiBib2xk
ZXI7Cgl9CglhID4gaSB7IC8qIEluc3RhbmNlIG9mIHRlcm0gKi8KCQlmb250LXN0eWxlOiBub3Jt
YWw7Cgl9CglkdCBkZm4gY29kZSwgY29kZS5pZGwgewoJCWZvbnQtc2l6ZTogbWVkaXVtOwoJfQoJ
ZGZuIHZhciB7CgkJZm9udC1zdHlsZTogbm9ybWFsOwoJfQoKLyoqIENoYW5nZSBNYXJraW5nICoq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
Ki8KCglkZWwgeyBjb2xvcjogcmVkOyAgdGV4dC1kZWNvcmF0aW9uOiBsaW5lLXRocm91Z2g7IH0K
CWlucyB7IGNvbG9yOiAjMDgwOyB0ZXh0LWRlY29yYXRpb246IHVuZGVybGluZTsgICAgfQoKLyoq
IE1pc2NlbGxhbmVvdXMgaW1wcm92ZW1lbnRzIHRvIGlubGluZSBmb3JtYXR0aW5nICoqKioqKioq
KioqKioqKioqKioqKioqKioqKi8KCglzdXAgewoJCXZlcnRpY2FsLWFsaWduOiBzdXBlcjsKCQlm
b250LXNpemU6IDgwJQoJfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyogICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICBDb2RlICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qKiBHZW5lcmFsIG1vbm9zcGFjZS9w
cmUgcnVsZXMgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiov
CgoJcHJlLCBjb2RlLCBzYW1wIHsKCQlmb250LWZhbWlseTogTWVubG8sIENvbnNvbGFzLCAiRGVq
YVZ1IFNhbnMgTW9ubyIsIE1vbmFjbywgbW9ub3NwYWNlOwoJCWZvbnQtc2l6ZTogLjllbTsKCQlw
YWdlLWJyZWFrLWluc2lkZTogYXZvaWQ7CgkJaHlwaGVuczogbm9uZTsKCQl0ZXh0LXRyYW5zZm9y
bTogbm9uZTsKCX0KCXByZSBjb2RlLAoJY29kZSBjb2RlIHsKCQlmb250LXNpemU6IDEwMCU7Cgl9
CgoJcHJlIHsKCQltYXJnaW4tdG9wOiAxZW07CgkJbWFyZ2luLWJvdHRvbTogMWVtOwoJCW92ZXJm
bG93OiBhdXRvOwoJfQoKLyoqIElubGluZSBDb2RlIGZyYWdtZW50cyAqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgLyogRG8gc29tZXRoaW5n
IG5pY2UuICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgIExpbmtzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAq
LwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqIEdlbmVyYWwgSHlwZXJsaW5rcyAqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgkvKiBX
ZSBoeXBlcmxpbmsgYSBsb3QsIHNvIG1ha2UgaXQgbGVzcyBpbnRydXNpdmUgKi8KCWFbaHJlZl0g
ewoJCWNvbG9yOiAjMDM0NTc1OwoJCXRleHQtZGVjb3JhdGlvbjogbm9uZTsKCQlib3JkZXItYm90
dG9tOiAxcHggc29saWQgIzcwNzA3MDsKCQkvKiBOZWVkIGEgYml0IG9mIGV4dGVuZGluZyBmb3Ig
aXQgdG8gbG9vayBva2F5ICovCgkJcGFkZGluZzogMCAxcHggMDsKCQltYXJnaW46IDAgLTFweCAw
OwoJfQoJYTp2aXNpdGVkIHsKCQlib3JkZXItYm90dG9tLWNvbG9yOiAjQkJCOwoJfQoKCS8qIFVz
ZSBkaXN0aW5ndWlzaGluZyBjb2xvcnMgd2hlbiB1c2VyIGlzIGludGVyYWN0aW5nIHdpdGggdGhl
IGxpbmsgKi8KCWFbaHJlZl06Zm9jdXMsCglhW2hyZWZdOmhvdmVyIHsKCQliYWNrZ3JvdW5kOiAj
ZjhmOGY4OwoJCWJhY2tncm91bmQ6IHJnYmEoNzUlLCA3NSUsIDc1JSwgLjI1KTsKCQlib3JkZXIt
Ym90dG9tLXdpZHRoOiAzcHg7CgkJbWFyZ2luLWJvdHRvbTogLTJweDsKCX0KCWFbaHJlZl06YWN0
aXZlIHsKCQljb2xvcjogI0MwMDsKCQlib3JkZXItY29sb3I6ICNDMDA7Cgl9CgoJLyogQmFja291
dCBhYm92ZSBzdHlsaW5nIGZvciBXM0MgbG9nbyAqLwoJLmhlYWQgLmxvZ28sCgkuaGVhZCAubG9n
byBhIHsKCQlib3JkZXI6IG5vbmU7CgkJdGV4dC1kZWNvcmF0aW9uOiBub25lOwoJCWJhY2tncm91
bmQ6IHRyYW5zcGFyZW50OwoJfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyogICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICBJbWFnZXMgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCglpbWcgewoJCWJvcmRlci1zdHls
ZTogbm9uZTsKCX0KCgkvKiBGb3IgYXV0b2dlbiBudW1iZXJzLCBhZGQKCSAgIC5jYXB0aW9uOjpi
ZWZvcmUsIGZpZ2NhcHRpb246OmJlZm9yZSB7IGNvbnRlbnQ6ICJGaWd1cmUgIiBjb3VudGVyKGZp
Z3VyZSkgIi4gIjsgfQoJKi8KCglmaWd1cmUsIC5maWd1cmUsIC5zaWRlZmlndXJlIHsKCQlwYWdl
LWJyZWFrLWluc2lkZTogYXZvaWQ7CgkJdGV4dC1hbGlnbjogY2VudGVyOwoJCW1hcmdpbjogMi41
ZW0gMDsKCX0KCS5maWd1cmUgaW1nLCAgICAuc2lkZWZpZ3VyZSBpbWcsICAgIGZpZ3VyZSBpbWcs
CgkuZmlndXJlIG9iamVjdCwgLnNpZGVmaWd1cmUgb2JqZWN0LCBmaWd1cmUgb2JqZWN0IHsKCQlt
YXgtd2lkdGg6IDEwMCU7CgkJbWFyZ2luOiBhdXRvOwoJfQoJLmZpZ3VyZSBwcmUsIC5zaWRlZmln
dXJlIHByZSwgZmlndXJlIHByZSB7CgkJdGV4dC1hbGlnbjogbGVmdDsKCQlkaXNwbGF5OiB0YWJs
ZTsKCQltYXJnaW46IDFlbSBhdXRvOwoJfQoJLmZpZ3VyZSB0YWJsZSwgZmlndXJlIHRhYmxlIHsK
CQltYXJnaW46IGF1dG87Cgl9CglAbWVkaWEgc2NyZWVuIGFuZCAobWluLXdpZHRoOiAyMGVtKSB7
CgkJLnNpZGVmaWd1cmUgewoJCQlmbG9hdDogcmlnaHQ7CgkJCXdpZHRoOiA1MCU7CgkJCW1hcmdp
bjogMCAwIDAuNWVtIDAuNWVtCgkJfQoJfQoJLmNhcHRpb24sIGZpZ2NhcHRpb24sIGNhcHRpb24g
ewoJCWZvbnQtc3R5bGU6IGl0YWxpYzsKCQlmb250LXNpemU6IDkwJTsKCX0KCS5jYXB0aW9uOjpi
ZWZvcmUsIGZpZ2NhcHRpb246OmJlZm9yZSwgZmlnY2FwdGlvbiA+IC5tYXJrZXIgewoJCWZvbnQt
d2VpZ2h0OiBib2xkOwoJfQoJLmNhcHRpb24sIGZpZ2NhcHRpb24gewoJCWNvdW50ZXItaW5jcmVt
ZW50OiBmaWd1cmU7Cgl9CgoJLyogREwgbGlzdCBpcyBpbmRlbnRlZCAyZW0sIGJ1dCBmaWd1cmUg
aW5zaWRlIGl0IGlzIG5vdCAqLwoJZGQgPiAuZmlndXJlLCBkZCA+IGZpZ3VyZSB7IG1hcmdpbi1s
ZWZ0OiAtMmVtIH0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICBDb2xvcmVkIEJveGVzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKiovCgoJLmlzc3VlLCAubm90ZSwgLmV4YW1wbGUsIC5h
c3NlcnRpb24sIC5hZHZpc2VtZW50LCBibG9ja3F1b3RlIHsKCQlwYWRkaW5nOiAuNWVtOwoJCWJv
cmRlcjogLjVlbTsKCQlib3JkZXItbGVmdC1zdHlsZTogc29saWQ7CgkJcGFnZS1icmVhay1pbnNp
ZGU6IGF2b2lkOwoJfQoJc3Bhbi5pc3N1ZSwgc3Bhbi5ub3RlIHsKCQlwYWRkaW5nOiAuMWVtIC41
ZW0gLjE1ZW07CgkJYm9yZGVyLXJpZ2h0LXN0eWxlOiBzb2xpZDsKCX0KCgkuaXNzdWUsCgkubm90
ZSwKCS5leGFtcGxlLAoJLmFkdmlzZW1lbnQsCgkuYXNzZXJ0aW9uLAoJYmxvY2txdW90ZSB7CgkJ
bWFyZ2luOiAxZW0gYXV0bzsKCX0KCS5ub3RlICA+IHA6Zmlyc3QtY2hpbGQsCgkuaXNzdWUgPiBw
OmZpcnN0LWNoaWxkLAoJYmxvY2txdW90ZSA+IDpmaXJzdC1jaGlsZCB7CgkJbWFyZ2luLXRvcDog
MDsKCX0KCWJsb2NrcXVvdGUgPiA6bGFzdC1jaGlsZCB7CgkJbWFyZ2luLWJvdHRvbTogMDsKCX0K
Ci8qKiBCbG9ja3F1b3RlcyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKiovCgoJYmxvY2txdW90ZSB7CgkJYm9yZGVyLWNvbG9yOiBz
aWx2ZXI7Cgl9CgovKiogT3BlbiBpc3N1ZSAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKCS5pc3N1ZSB7CgkJYm9yZGVyLWNv
bG9yOiAjRTA1MjUyOwoJCWJhY2tncm91bmQ6ICNGQkU5RTk7CgkJY291bnRlci1pbmNyZW1lbnQ6
IGlzc3VlOwoJCW92ZXJmbG93OiBhdXRvOwoJfQoJLmlzc3VlOjpiZWZvcmUsIC5pc3N1ZSA+IC5t
YXJrZXIgewoJCXRleHQtdHJhbnNmb3JtOiB1cHBlcmNhc2U7CgkJY29sb3I6ICNBRTFFMUU7CgkJ
cGFkZGluZy1yaWdodDogMWVtOwoJCXRleHQtdHJhbnNmb3JtOiB1cHBlcmNhc2U7Cgl9CgkvKiBB
ZGQgLmlzc3VlOjpiZWZvcmUgeyBjb250ZW50OiAiSXNzdWUgIiBjb3VudGVyKGlzc3VlKSAiICI7
IH0gZm9yIGF1dG9nZW4gbnVtYmVycywKCSAgIG9yIHVzZSBjbGFzcz0ibWFya2VyIiB0byBtYXJr
IHVwIHRoZSBpc3N1ZSBudW1iZXIgaW4gc291cmNlLiAqLwoKLyoqIEV4YW1wbGUgKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
Ki8KCgkuZXhhbXBsZSB7CgkJYm9yZGVyLWNvbG9yOiAjRTBDQjUyOwoJCWJhY2tncm91bmQ6ICNG
Q0ZBRUU7CgkJY291bnRlci1pbmNyZW1lbnQ6IGV4YW1wbGU7CgkJb3ZlcmZsb3c6IGF1dG87CgkJ
Y2xlYXI6IGJvdGg7Cgl9CgkuZXhhbXBsZTo6YmVmb3JlLCAuZXhhbXBsZSA+IC5tYXJrZXIgewoJ
CXRleHQtdHJhbnNmb3JtOiB1cHBlcmNhc2U7CgkJY29sb3I6ICM4MjcwMTc7CgkJbWluLXdpZHRo
OiA3LjVlbTsKCQlkaXNwbGF5OiBibG9jazsKCX0KCS8qIEFkZCAuZXhhbXBsZTo6YmVmb3JlIHsg
Y29udGVudDogIkV4YW1wbGUgIiBjb3VudGVyKGV4YW1wbGUpICIgIjsgfSBmb3IgYXV0b2dlbiBu
dW1iZXJzLAoJICAgb3IgdXNlIGNsYXNzPSJtYXJrZXIiIHRvIG1hcmsgdXAgdGhlIGV4YW1wbGUg
bnVtYmVyIGluIHNvdXJjZS4gKi8KCi8qKiBOb24tbm9ybWF0aXZlIE5vdGUgKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgoJLm5vdGUgewoJ
CWJvcmRlci1jb2xvcjogIzUyRTA1MjsKCQliYWNrZ3JvdW5kOiAjRTlGQkU5OwoJCW92ZXJmbG93
OiBhdXRvOwoJfQoKCS5ub3RlOjpiZWZvcmUsIC5ub3RlID4gLm1hcmtlciwKCWRldGFpbHMubm90
ZSA+IHN1bW1hcnk6OmJlZm9yZSwKCWRldGFpbHMubm90ZSA+IHN1bW1hcnkgPiAubWFya2VyIHsK
CQl0ZXh0LXRyYW5zZm9ybTogdXBwZXJjYXNlOwoJCWRpc3BsYXk6IGJsb2NrOwoJCWNvbG9yOiBo
c2woMTIwLCA3MCUsIDMwJSk7Cgl9CgkvKiBBZGQgLm5vdGU6OmJlZm9yZSB7IGNvbnRlbnQ6ICJO
b3RlIjsgfSBmb3IgYXV0b2dlbiBsYWJlbCwKCSAgIG9yIHVzZSBjbGFzcz0ibWFya2VyIiB0byBt
YXJrIHVwIHRoZSBsYWJlbCBpbiBzb3VyY2UuICovCgoJZGV0YWlscy5ub3RlID4gc3VtbWFyeSB7
CgkJZGlzcGxheTogYmxvY2s7CgkJY29sb3I6IGhzbCgxMjAsIDcwJSwgMzAlKTsKCX0KCWRldGFp
bHMubm90ZVtvcGVuXSA+IHN1bW1hcnkgewoJCWJvcmRlci1ib3R0b206IDFweCBzaWx2ZXIgc29s
aWQ7Cgl9CgovKiogQXNzZXJ0aW9uIEJveCAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoJLyogIGZvciBhc3NlcnRpb25zIGluIGFs
Z29yaXRobXMgKi8KCgkuYXNzZXJ0aW9uIHsKCQlib3JkZXItY29sb3I6ICNBQUE7CgkJYmFja2dy
b3VuZDogI0VFRTsKCX0KCi8qKiBBZHZpc2VtZW50IEJveCAqKioqKioqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgkvKiAgZm9yIGF0dGVudGlv
bi1ncmFiYmluZyBub3JtYXRpdmUgc3RhdGVtZW50cyAqLwoKCS5hZHZpc2VtZW50IHsKCQlib3Jk
ZXItY29sb3I6IG9yYW5nZTsKCQlib3JkZXItc3R5bGU6IG5vbmUgc29saWQ7CgkJYmFja2dyb3Vu
ZDogI0ZGRUVDQzsKCX0KCXN0cm9uZy5hZHZpc2VtZW50IHsKCQlkaXNwbGF5OiBibG9jazsKCQl0
ZXh0LWFsaWduOiBjZW50ZXI7Cgl9CgkuYWR2aXNlbWVudCA+IC5tYXJrZXIgewoJCWNvbG9yOiAj
QjM1RjAwOwoJfQoKLyoqIFNwZWMgT2Jzb2xldGlvbiBOb3RpY2UgKioqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCS8qIG9ibm94aW91cyBvYnNvbGV0
aW9uIG5vdGljZSBmb3Igb2xkZXIvYWJhbmRvbmVkIHNwZWNzLiAqLwoKCWRldGFpbHMgewoJCWRp
c3BsYXk6IGJsb2NrOwoJfQoJc3VtbWFyeSB7CgkJZm9udC13ZWlnaHQ6IGJvbGRlcjsKCX0KCgku
YW5ub3lpbmctd2FybmluZzpub3QoZGV0YWlscyksCglkZXRhaWxzLmFubm95aW5nLXdhcm5pbmc6
bm90KFtvcGVuXSkgPiBzdW1tYXJ5LAoJZGV0YWlscy5hbm5veWluZy13YXJuaW5nW29wZW5dIHsK
CQliYWNrZ3JvdW5kOiAjZmRkOwoJCWNvbG9yOiByZWQ7CgkJZm9udC13ZWlnaHQ6IGJvbGQ7CgkJ
cGFkZGluZzogLjc1ZW0gMWVtOwoJCWJvcmRlcjogdGhpY2sgcmVkOwoJCWJvcmRlci1zdHlsZTog
c29saWQ7CgkJYm9yZGVyLXJhZGl1czogMWVtOwoJfQoJLmFubm95aW5nLXdhcm5pbmcgOmxhc3Qt
Y2hpbGQgewoJCW1hcmdpbi1ib3R0b206IDA7Cgl9CgpAbWVkaWEgbm90IHByaW50IHsKCWRldGFp
bHMuYW5ub3lpbmctd2FybmluZ1tvcGVuXSB7CgkJcG9zaXRpb246IGZpeGVkOwoJCWxlZnQ6IDFl
bTsKCQlyaWdodDogMWVtOwoJCWJvdHRvbTogMWVtOwoJCXotaW5kZXg6IDEwMDA7Cgl9Cn0KCglk
ZXRhaWxzLmFubm95aW5nLXdhcm5pbmc6bm90KFtvcGVuXSkgPiBzdW1tYXJ5IHsKCQl0ZXh0LWFs
aWduOiBjZW50ZXI7Cgl9CgovKiogRW50aXR5IERlZmluaXRpb24gQm94ZXMgKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKCS5kZWYgewoJCXBhZGRp
bmc6IC41ZW0gMWVtOwoJCWJhY2tncm91bmQ6ICNERUY7CgkJbWFyZ2luOiAxLjJlbSAwOwoJCWJv
cmRlci1sZWZ0OiAwLjVlbSBzb2xpZCAjOENDQkYyOwoJfQoKLyoqKioqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
Ki8KLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUYWJsZXMgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgl0aCwg
dGQgewoJCXRleHQtYWxpZ246IGxlZnQ7CgkJdGV4dC1hbGlnbjogc3RhcnQ7Cgl9CgovKiogUHJv
cGVydHkvRGVzY3JpcHRvciBEZWZpbml0aW9uIFRhYmxlcyAqKioqKioqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqLwoKCXRhYmxlLmRlZiB7CgkJLyogaW5oZXJpdHMgLmRlZiBib3ggc3R5
bGluZywgc2VlIGFib3ZlICovCgkJd2lkdGg6IDEwMCU7CgkJYm9yZGVyLXNwYWNpbmc6IDA7Cgl9
CgoJdGFibGUuZGVmIHRkLAoJdGFibGUuZGVmIHRoIHsKCQlwYWRkaW5nOiAwLjVlbTsKCQl2ZXJ0
aWNhbC1hbGlnbjogYmFzZWxpbmU7CgkJYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkICNiYmQ3ZTk7
Cgl9CgoJdGFibGUuZGVmID4gdGJvZHkgPiB0cjpsYXN0LWNoaWxkIHRoLAoJdGFibGUuZGVmID4g
dGJvZHkgPiB0cjpsYXN0LWNoaWxkIHRkIHsKCQlib3JkZXItYm90dG9tOiAwOwoJfQoKCXRhYmxl
LmRlZiB0aCB7CgkJZm9udC1zdHlsZTogaXRhbGljOwoJCWZvbnQtd2VpZ2h0OiBub3JtYWw7CgkJ
cGFkZGluZy1sZWZ0OiAxZW07CgkJd2lkdGg6IDNlbTsKCX0KCgkvKiBGb3Igd2hlbiB2YWx1ZXMg
YXJlIGV4dHJhLWNvbXBsZXggYW5kIG5lZWQgZm9ybWF0dGluZyBmb3IgcmVhZGFiaWxpdHkgKi8K
CXRhYmxlIHRkLnByZSB7CgkJd2hpdGUtc3BhY2U6IHByZS13cmFwOwoJfQoKCS8qIEEgZm9vdG5v
dGUgYXQgdGhlIGJvdHRvbSBvZiBhIGRlZiB0YWJsZSAqLwoJdGFibGUuZGVmICAgICAgICAgICB0
ZC5mb290bm90ZSB7CgkJcGFkZGluZy10b3A6IDAuNmVtOwoJfQoJdGFibGUuZGVmICAgICAgICAg
ICB0ZC5mb290bm90ZTo6YmVmb3JlIHsKCQljb250ZW50OiAiICI7CgkJZGlzcGxheTogYmxvY2s7
CgkJaGVpZ2h0OiAwLjZlbTsKCQl3aWR0aDogNGVtOwoJCWJvcmRlci10b3A6IHRoaW4gc29saWQ7
Cgl9CgovKiogRGF0YSB0YWJsZXMgKGFuZCBwcm9wZXJseSBtYXJrZWQtdXAgaW5kZXggdGFibGVz
KSAqKioqKioqKioqKioqKioqKioqKioqKioqLwoJLyoKCQkgPHRhYmxlIGNsYXNzPSJkYXRhIj4g
aGlnaGxpZ2h0cyBzdHJ1Y3R1cmFsIHJlbGF0aW9uc2hpcHMgaW4gYSB0YWJsZQoJCSB3aGVuIGNv
cnJlY3QgbWFya3VwIGlzIHVzZWQgKGUuZy4gdGhlYWQvdGJvZHksIHRoIHZzLiB0ZCwgc2NvcGUg
YXR0cmlidXRlKQoKCQkgVXNlIGNsYXNzPSJjb21wbGV4IGRhdGEiIGZvciBwYXJ0aWN1bGFybHkg
Y29tcGxpY2F0ZWQgdGFibGVzIC0tCgkJIChUaGlzIHdpbGwgZHJhdyBtb3JlIGxpbmVzOiBidXNp
ZXIsIGJ1dCBjbGVhcmVyLikKCgkJIFVzZSBjbGFzcz0ibG9uZyIgb24gdGFibGUgY2VsbHMgd2l0
aCBwYXJhZ3JhcGgtbGlrZSBjb250ZW50cwoJCSAoVGhpcyB3aWxsIGFkanVzdCB0ZXh0IGFsaWdu
bWVudCBhY2NvcmRpbmdseS4pCgkJIEFsdGVybmF0ZWx5IHVzZSBjbGFzcz0ibG9uZ2xhc3Rjb2wi
IG9uIHRhYmxlcywgdG8gaGF2ZSB0aGUgbGFzdCBjb2x1bW4gYXNzdW1lICJsb25nIi4KCSovCgoJ
dGFibGUgewoJCXdvcmQtd3JhcDogbm9ybWFsOwoJCW92ZXJmbG93LXdyYXA6IG5vcm1hbDsKCQlo
eXBoZW5zOiBtYW51YWw7Cgl9CgoJdGFibGUuZGF0YSwKCXRhYmxlLmluZGV4IHsKCQltYXJnaW46
IDFlbSBhdXRvOwoJCWJvcmRlci1jb2xsYXBzZTogY29sbGFwc2U7CgkJYm9yZGVyOiBoaWRkZW47
CgkJd2lkdGg6IDEwMCU7Cgl9Cgl0YWJsZS5kYXRhIGNhcHRpb24sCgl0YWJsZS5pbmRleCBjYXB0
aW9uIHsKCQltYXgtd2lkdGg6IDUwZW07CgkJbWFyZ2luOiAwIGF1dG8gMWVtOwoJfQoKCXRhYmxl
LmRhdGEgdGQsICB0YWJsZS5kYXRhIHRoLAoJdGFibGUuaW5kZXggdGQsIHRhYmxlLmluZGV4IHRo
IHsKCQlwYWRkaW5nOiAwLjVlbSAxZW07CgkJYm9yZGVyLXdpZHRoOiAxcHg7CgkJYm9yZGVyLWNv
bG9yOiBzaWx2ZXI7CgkJYm9yZGVyLXRvcC1zdHlsZTogc29saWQ7Cgl9CgoJdGFibGUuZGF0YSB0
aGVhZCB0ZDplbXB0eSB7CgkJcGFkZGluZzogMDsKCQlib3JkZXI6IDA7Cgl9CgoJdGFibGUuZGF0
YSAgdGhlYWQsCgl0YWJsZS5pbmRleCB0aGVhZCwKCXRhYmxlLmRhdGEgIHRib2R5LAoJdGFibGUu
aW5kZXggdGJvZHkgewoJCWJvcmRlci1ib3R0b206IDJweCBzb2xpZDsKCX0KCgl0YWJsZS5kYXRh
IGNvbGdyb3VwLAoJdGFibGUuaW5kZXggY29sZ3JvdXAgewoJCWJvcmRlci1sZWZ0OiAycHggc29s
aWQ7Cgl9CgoJdGFibGUuZGF0YSAgdGJvZHkgdGg6Zmlyc3QtY2hpbGQsCgl0YWJsZS5pbmRleCB0
Ym9keSB0aDpmaXJzdC1jaGlsZCAgewoJCWJvcmRlci1yaWdodDogMnB4IHNvbGlkOwoJCWJvcmRl
ci10b3A6IDFweCBzb2xpZCBzaWx2ZXI7CgkJcGFkZGluZy1yaWdodDogMWVtOwoJfQoKCXRhYmxl
LmRhdGEgdGhbY29sc3Bhbl0sCgl0YWJsZS5kYXRhIHRkW2NvbHNwYW5dIHsKCQl0ZXh0LWFsaWdu
OiBjZW50ZXI7Cgl9CgoJdGFibGUuY29tcGxleC5kYXRhIHRoLAoJdGFibGUuY29tcGxleC5kYXRh
IHRkIHsKCQlib3JkZXI6IDFweCBzb2xpZCBzaWx2ZXI7CgkJdGV4dC1hbGlnbjogY2VudGVyOwoJ
fQoKCXRhYmxlLmRhdGEubG9uZ2xhc3Rjb2wgdGQ6bGFzdC1jaGlsZCwKCXRhYmxlLmRhdGEgdGQu
bG9uZyB7CgkgdmVydGljYWwtYWxpZ246IGJhc2VsaW5lOwoJIHRleHQtYWxpZ246IGxlZnQ7Cgl9
CgoJdGFibGUuZGF0YSBpbWcgewoJCXZlcnRpY2FsLWFsaWduOiBtaWRkbGU7Cgl9CgoKLyoKQWx0
ZXJuYXRlIHRhYmxlIGFsaWdubWVudCBydWxlcwoKCXRhYmxlLmRhdGEsCgl0YWJsZS5pbmRleCB7
CgkJdGV4dC1hbGlnbjogY2VudGVyOwoJfQoKCXRhYmxlLmRhdGEgIHRoZWFkIHRoW3Njb3BlPSJy
b3ciXSwKCXRhYmxlLmluZGV4IHRoZWFkIHRoW3Njb3BlPSJyb3ciXSB7CgkJdGV4dC1hbGlnbjog
cmlnaHQ7Cgl9CgoJdGFibGUuZGF0YSAgdGJvZHkgdGg6Zmlyc3QtY2hpbGQsCgl0YWJsZS5pbmRl
eCB0Ym9keSB0aDpmaXJzdC1jaGlsZCAgewoJCXRleHQtYWxpZ246IHJpZ2h0OwoJfQoKUG9zc2li
bGUgZXh0cmEgcm93c3BhbiBoYW5kbGluZwoKCXRhYmxlLmRhdGEgIHRib2R5IHRoW3Jvd3NwYW5d
Om5vdChbcm93c3Bhbj0nMSddKSwKCXRhYmxlLmluZGV4IHRib2R5IHRoW3Jvd3NwYW5dOm5vdChb
cm93c3Bhbj0nMSddKSwKCXRhYmxlLmRhdGEgIHRib2R5IHRkW3Jvd3NwYW5dOm5vdChbcm93c3Bh
bj0nMSddKSwKCXRhYmxlLmluZGV4IHRib2R5IHRkW3Jvd3NwYW5dOm5vdChbcm93c3Bhbj0nMSdd
KSB7CgkJYm9yZGVyLWxlZnQ6IDFweCBzb2xpZCBzaWx2ZXI7Cgl9CgoJdGFibGUuZGF0YSAgdGJv
ZHkgdGhbcm93c3Bhbl06Zmlyc3QtY2hpbGQsCgl0YWJsZS5pbmRleCB0Ym9keSB0aFtyb3dzcGFu
XTpmaXJzdC1jaGlsZCwKCXRhYmxlLmRhdGEgIHRib2R5IHRkW3Jvd3NwYW5dOmZpcnN0LWNoaWxk
LAoJdGFibGUuaW5kZXggdGJvZHkgdGRbcm93c3Bhbl06Zmlyc3QtY2hpbGR7CgkJYm9yZGVyLWxl
ZnQ6IDA7CgkJYm9yZGVyLXJpZ2h0OiAxcHggc29saWQgc2lsdmVyOwoJfQoqLwoKLyoqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKi8KLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5kaWNl
cyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyoqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqKi8KCgovKiogVGFibGUgb2YgQ29udGVudHMgKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKCS50b2MgYSB7CgkJLyogTW9yZSBzcGFj
aW5nOyB1c2UgcGFkZGluZyB0byBtYWtlIGl0IHBhcnQgb2YgdGhlIGNsaWNrIHRhcmdldC4gKi8K
CQlwYWRkaW5nLXRvcDogMC4xcmVtOwoJCS8qIExhcmdlciwgbW9yZSBjb25zaXN0ZW50bHktc2l6
ZWQgY2xpY2sgdGFyZ2V0ICovCgkJZGlzcGxheTogYmxvY2s7CgkJLyogUmV2ZXJzZSBjb2xvciBz
Y2hlbWUgKi8KCQljb2xvcjogYmxhY2s7CgkJYm9yZGVyLWNvbG9yOiAjMzk4MEI1OwoJCWJvcmRl
ci1ib3R0b20td2lkdGg6IDNweCAhaW1wb3J0YW50OwoJCW1hcmdpbi1ib3R0b206IDBweCAhaW1w
b3J0YW50OwoJfQoJLnRvYyBhOnZpc2l0ZWQgewoJCWJvcmRlci1jb2xvcjogIzA1NDU3MjsKCX0K
CS50b2MgYTpub3QoOmZvY3VzKTpub3QoOmhvdmVyKSB7CgkJLyogQWxsb3cgY29sb3JzIHRvIGNh
c2NhZGUgdGhyb3VnaCBmcm9tIGxpbmsgc3R5bGluZyAqLwoJCWJvcmRlci1ib3R0b20tY29sb3I6
IHRyYW5zcGFyZW50OwoJfQoKCS50b2MsIC50b2Mgb2wsIC50b2MgdWwsIC50b2MgbGkgewoJCWxp
c3Qtc3R5bGU6IG5vbmU7IC8qIE51bWJlcnMgbXVzdCBiZSBpbmxpbmVkIGludG8gc291cmNlICov
CgkJLyogYmVjYXVzZSBnZW5lcmF0ZWQgY29udGVudCBpc24ndCBzZWFyY2gvc2VsZWN0YWJsZSBh
bmQgbWFya2VycyBjYW4ndCBkbyBtdWx0aWxldmVsIHlldCAqLwoJCW1hcmdpbjogIDA7CgkJcGFk
ZGluZzogMDsKCQlsaW5lLWhlaWdodDogMS4xcmVtOyAvKiBjb25zaXN0ZW50IHNwYWNpbmcgKi8K
CX0KCgkvKiBUb0Mgbm90IGluZGVudGVkIHVudGlsIHRoaXJkIGxldmVsLCBidXQgZm9udCBzdHls
ZSAmIG1hcmdpbnMgc2hvdyBoaWVyYXJjaHkgKi8KCS50b2MgPiBsaSAgICAgICAgICAgICB7IGZv
bnQtd2VpZ2h0OiBib2xkOyAgIH0KCS50b2MgPiBsaSBsaSAgICAgICAgICB7IGZvbnQtd2VpZ2h0
OiBub3JtYWw7IH0KCS50b2MgPiBsaSBsaSBsaSAgICAgICB7IGZvbnQtc2l6ZTogICA5NSU7ICAg
IH0KCS50b2MgPiBsaSBsaSBsaSBsaSAgICB7IGZvbnQtc2l6ZTogICA5MCU7ICAgIH0KCS50b2Mg
PiBsaSBsaSBsaSBsaSAuc2Vjbm8geyBmb250LXNpemU6IDg1JTsgfQoJLnRvYyA+IGxpIGxpIGxp
IGxpIGxpIHsgZm9udC1zaXplOiAgIDg1JTsgICAgfQoJLnRvYyA+IGxpIGxpIGxpIGxpIGxpIC5z
ZWNubyB7IGZvbnQtc2l6ZTogMTAwJTsgfQoKCS8qIEBzdXBwb3J0cyBub3QgKGRpc3BsYXk6Z3Jp
ZCkgeyAqLwoJCS50b2MgPiBsaSAgICAgICAgICAgICB7IG1hcmdpbjogMS41cmVtIDA7ICAgIH0K
CQkudG9jID4gbGkgbGkgICAgICAgICAgeyBtYXJnaW46IDAuM3JlbSAwOyAgICB9CgkJLnRvYyA+
IGxpIGxpIGxpICAgICAgIHsgbWFyZ2luLWxlZnQ6IDJyZW07ICAgfQoKCQkvKiBTZWN0aW9uIG51
bWJlcnMgaW4gYSBjb2x1bW4gb2YgdGhlaXIgb3duICovCgkJLnRvYyAuc2Vjbm8gewoJCQlmbG9h
dDogbGVmdDsKCQkJd2lkdGg6IDRyZW07CgkJCXdoaXRlLXNwYWNlOiBub3dyYXA7CgkJfQoKCQku
dG9jIGxpIHsKCQkJY2xlYXI6IGJvdGg7CgkJfQoKCQk6bm90KGxpKSA+IC50b2MgICAgICAgICAg
ICAgIHsgbWFyZ2luLWxlZnQ6ICA1cmVtOyB9CgkJLnRvYyAuc2Vjbm8gICAgICAgICAgICAgICAg
ICB7IG1hcmdpbi1sZWZ0OiAtNXJlbTsgfQoJCS50b2MgPiBsaSBsaSBsaSAuc2Vjbm8gICAgICAg
eyBtYXJnaW4tbGVmdDogLTdyZW07IH0KCQkudG9jID4gbGkgbGkgbGkgbGkgLnNlY25vICAgIHsg
bWFyZ2luLWxlZnQ6IC05cmVtOyB9CgkJLnRvYyA+IGxpIGxpIGxpIGxpIGxpIC5zZWNubyB7IG1h
cmdpbi1sZWZ0OiAtMTFyZW07IH0KCgkJLyogVGlnaHRlbiB1cCBpbmRlbnRhdGlvbiBpbiBuYXJy
b3cgVG9DcyAqLwoJCUBtZWRpYSAobWF4LXdpZHRoOiAzMGVtKSB7CgkJCTpub3QobGkpID4gLnRv
YyAgICAgICAgICAgICAgeyBtYXJnaW4tbGVmdDogIDRyZW07IH0KCQkJLnRvYyAuc2Vjbm8gICAg
ICAgICAgICAgICAgICB7IG1hcmdpbi1sZWZ0OiAtNHJlbTsgfQoJCQkudG9jID4gbGkgbGkgbGkg
ICAgICAgICAgICAgIHsgbWFyZ2luLWxlZnQ6ICAxcmVtOyB9CgkJCS50b2MgPiBsaSBsaSBsaSAu
c2Vjbm8gICAgICAgeyBtYXJnaW4tbGVmdDogLTVyZW07IH0KCQkJLnRvYyA+IGxpIGxpIGxpIGxp
IC5zZWNubyAgICB7IG1hcmdpbi1sZWZ0OiAtNnJlbTsgfQoJCQkudG9jID4gbGkgbGkgbGkgbGkg
bGkgLnNlY25vIHsgbWFyZ2luLWxlZnQ6IC03cmVtOyB9CgkJfQoJLyogfSAqLwoKCUBzdXBwb3J0
cyAoZGlzcGxheTpncmlkKSB7CgkJLyogVXNlICN0b2Mgb3ZlciAudG9jIHRvIG92ZXJyaWRlIG5v
bi1Ac3VwcG9ydHMgcnVsZXMuICovCgkJI3RvYyB7CgkJCWRpc3BsYXk6IGdyaWQ7CgkJCWFsaWdu
LWNvbnRlbnQ6IHN0YXJ0OwoJCQlncmlkLXRlbXBsYXRlLWNvbHVtbnM6IGF1dG8gMWZyOwoJCQln
cmlkLWNvbHVtbi1nYXA6IDFyZW07CgkJCWNvbHVtbi1nYXA6IDFyZW07CgkJCWdyaWQtcm93LWdh
cDogLjZyZW07CgkJCXJvdy1nYXA6IC42cmVtOwoJCX0KCQkjdG9jIGgyIHsKCQkJZ3JpZC1jb2x1
bW46IDEgLyAtMTsKCQkJbWFyZ2luLWJvdHRvbTogMDsKCQl9CgkJI3RvYyBvbCwKCQkjdG9jIGxp
LAoJCSN0b2MgYSB7CgkJCWRpc3BsYXk6IGNvbnRlbnRzOwoJCQkvKiBTd2l0Y2ggPGE+IHRvIHN1
YmdyaWQgd2hlbiBzdXBwb3J0ZWQgKi8KCQl9CgkJI3RvYyBzcGFuIHsKCQkJbWFyZ2luOiAwOwoJ
CX0KCQkjdG9jID4gLnRvYyA+IGxpID4gYSA+IHNwYW4gewoJCQkvKiBUaGUgc3BhbnMgb2YgdGhl
IHRvcC1sZXZlbCBsaXN0LAoJCQkgICBjb21wcmlzaW5nIHRoZSBmaXJzdCBpdGVtcyBvZiBlYWNo
IHRvcC1sZXZlbCBzZWN0aW9uLiAqLwoJCQltYXJnaW4tdG9wOiAxLjFyZW07CgkJfQoJCSN0b2Mj
dG9jIC5zZWNubyB7IC8qIFVnaCwgbmVlZCBtb3JlIHNwZWNpZmljaXR5IHRvIG92ZXJyaWRlIGJh
c2UuY3NzICovCgkJCWdyaWQtY29sdW1uOiAxOwoJCQl3aWR0aDogYXV0bzsKCQkJbWFyZ2luLWxl
ZnQ6IDA7CgkJfQoJCSN0b2MgLmNvbnRlbnQgewoJCQlncmlkLWNvbHVtbjogMjsKCQkJd2lkdGg6
IGF1dG87CgkJCW1hcmdpbi1yaWdodDogMXJlbTsKCQl9CgkJI3RvYyAuY29udGVudDpob3ZlciB7
CgkJCWJhY2tncm91bmQ6IHJnYmEoNzUlLCA3NSUsIDc1JSwgLjI1KTsKCQkJYm9yZGVyLWJvdHRv
bTogM3B4IHNvbGlkICMwNTQ1NzI7CgkJCW1hcmdpbi1ib3R0b206IC0zcHg7CgkJfQoJCSN0b2Mg
bGkgbGkgbGkgLmNvbnRlbnQgewoJCQltYXJnaW4tbGVmdDogMXJlbTsKCQl9CgkJI3RvYyBsaSBs
aSBsaSBsaSAuY29udGVudCB7CgkJCW1hcmdpbi1sZWZ0OiAycmVtOwoJCX0KCX0KCgovKiogSW5k
ZXggKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqLwoKCS8qIEluZGV4IExpc3RzOiBMYXlvdXQgKi8KCXVsLmluZGV4ICAg
ICAgIHsgbWFyZ2luLWxlZnQ6IDA7IGNvbHVtbnM6IDE1ZW07IHRleHQtaW5kZW50OiAxZW0gaGFu
Z2luZzsgfQoJdWwuaW5kZXggbGkgICAgeyBtYXJnaW4tbGVmdDogMDsgbGlzdC1zdHlsZTogbm9u
ZTsgYnJlYWstaW5zaWRlOiBhdm9pZDsgfQoJdWwuaW5kZXggbGkgbGkgeyBtYXJnaW4tbGVmdDog
MWVtIH0KCXVsLmluZGV4IGRsICAgIHsgbWFyZ2luLXRvcDogMDsgfQoJdWwuaW5kZXggZHQgICAg
eyBtYXJnaW46IC4yZW0gMCAuMmVtIDIwcHg7fQoJdWwuaW5kZXggZGQgICAgeyBtYXJnaW46IC4y
ZW0gMCAuMmVtIDQwcHg7fQoJLyogSW5kZXggTGlzdHM6IFR5cG9ncmFwaHkgKi8KCXVsLmluZGV4
IHVsLAoJdWwuaW5kZXggZGwgeyBmb250LXNpemU6IHNtYWxsZXI7IH0KCUBtZWRpYSBub3QgcHJp
bnQgewoJCXVsLmluZGV4IGxpIHNwYW4gewoJCQl3aGl0ZS1zcGFjZTogbm93cmFwOwoJCQljb2xv
cjogdHJhbnNwYXJlbnQ7IH0KCQl1bC5pbmRleCBsaSBhOmhvdmVyICsgc3BhbiwKCQl1bC5pbmRl
eCBsaSBhOmZvY3VzICsgc3BhbiB7CgkJCWNvbG9yOiAjNzA3MDcwOwoJCX0KCX0KCi8qKiBJbmRl
eCBUYWJsZXMgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqKiovCgkvKiBTZWUgYWxzbyB0aGUgZGF0YSB0YWJsZSBzdHlsaW5nIHNlY3Rpb24sIHdoaWNo
IHRoaXMgZWZmZWN0aXZlbHkgc3ViY2xhc3NlcyAqLwoKCXRhYmxlLmluZGV4IHsKCQlmb250LXNp
emU6IHNtYWxsOwoJCWJvcmRlci1jb2xsYXBzZTogY29sbGFwc2U7CgkJYm9yZGVyLXNwYWNpbmc6
IDA7CgkJdGV4dC1hbGlnbjogbGVmdDsKCQltYXJnaW46IDFlbSAwOwoJfQoKCXRhYmxlLmluZGV4
IHRkLAoJdGFibGUuaW5kZXggdGggewoJCXBhZGRpbmc6IDAuNGVtOwoJfQoKCXRhYmxlLmluZGV4
IHRyOmhvdmVyIHRkOm5vdChbcm93c3Bhbl0pLAoJdGFibGUuaW5kZXggdHI6aG92ZXIgdGg6bm90
KFtyb3dzcGFuXSkgewoJCWJhY2tncm91bmQ6ICNmN2Y4Zjk7Cgl9CgoJLyogVGhlIGxpbmsgaW4g
dGhlIGZpcnN0IGNvbHVtbiBpbiB0aGUgcHJvcGVydHkgdGFibGUgKGZvcm1lcmx5IGEgVEQpICov
Cgl0YWJsZS5pbmRleCB0aDpmaXJzdC1jaGlsZCBhIHsKCQlmb250LXdlaWdodDogYm9sZDsKCX0K
Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKiovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgUHJpbnQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKiovCgoJQG1lZGlhIHByaW50IHsKCQkvKiBQYWdlcyBoYXZlIHRoZWlyIG93
biBtYXJnaW5zLiAqLwoJCWh0bWwgewoJCQltYXJnaW46IDA7CgkJfQoJCS8qIFNlcmlmIGZvciBw
cmludC4gKi8KCQlib2R5IHsKCQkJZm9udC1mYW1pbHk6IHNlcmlmOwoJCX0KCX0KCUBwYWdlIHsK
CQltYXJnaW46IDEuNWNtIDEuMWNtOwoJfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyogICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMZWdhY3kgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgkvKiBUaGlzIHJ1bGUg
aXMgaW5oZXJpdGVkIGZyb20gcGFzdCBzdHlsZSBzaGVldHMuIE5vIGlkZWEgd2hhdCBpdCdzIGZv
ci4gKi8KCS5oaWRlIHsgZGlzcGxheTogbm9uZSB9CgoKCi8qKioqKioqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiov
Ci8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPdmVyZmxvdyBDb250cm9sICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgoJLmZpZ3Vy
ZSAuY2FwdGlvbiwgLnNpZGVmaWd1cmUgLmNhcHRpb24sIGZpZ2NhcHRpb24gewoJCS8qIGluIGNh
c2UgZmlndXJlIGlzIG92ZXJsYXJnZSwgbGltaXQgY2FwdGlvbiB0byA1MGVtICovCgkJbWF4LXdp
ZHRoOiA1MHJlbTsKCQltYXJnaW4tbGVmdDogYXV0bzsKCQltYXJnaW4tcmlnaHQ6IGF1dG87Cgl9
Cgkub3ZlcmxhcmdlID4gdGFibGUgewoJCS8qIGxpbWl0IHByZWZlcnJlZCB3aWR0aCBvZiB0YWJs
ZSAqLwoJCW1heC13aWR0aDogNTBlbTsKCQltYXJnaW4tbGVmdDogYXV0bzsKCQltYXJnaW4tcmln
aHQ6IGF1dG87Cgl9CgoJQG1lZGlhIChtaW4td2lkdGg6IDU1ZW0pIHsKCQkub3ZlcmxhcmdlIHsK
CQkJbWFyZ2luLWxlZnQ6IGNhbGMoMTNweCArIDI2LjVyZW0gLSA1MHZ3KTsKCQkJbWFyZ2luLXJp
Z2h0OiBjYWxjKDEzcHggKyAyNi41cmVtIC0gNTB2dyk7CgkJCW1heC13aWR0aDogbm9uZTsKCQl9
Cgl9CglAbWVkaWEgc2NyZWVuIGFuZCAobWluLXdpZHRoOiA3OGVtKSB7CgkJYm9keTpub3QoLnRv
Yy1pbmxpbmUpIC5vdmVybGFyZ2UgewoJCQkvKiAzMC41ZW0gYm9keSBwYWRkaW5nIDUwZW0gY29u
dGVudCBhcmVhICovCgkJCW1hcmdpbi1sZWZ0OiBjYWxjKDQwZW0gLSA1MHZ3KSAhaW1wb3J0YW50
OwoJCQltYXJnaW4tcmlnaHQ6IGNhbGMoNDBlbSAtIDUwdncpICFpbXBvcnRhbnQ7CgkJfQoJfQoJ
QG1lZGlhIHNjcmVlbiBhbmQgKG1pbi13aWR0aDogOTBlbSkgewoJCWJvZHk6bm90KC50b2MtaW5s
aW5lKSAub3ZlcmxhcmdlIHsKCQkJLyogNGVtIGh0bWwgbWFyZ2luIDMwLjVlbSBib2R5IHBhZGRp
bmcgNTBlbSBjb250ZW50IGFyZWEgKi8KCQkJbWFyZ2luLWxlZnQ6IDAgIWltcG9ydGFudDsKCQkJ
bWFyZ2luLXJpZ2h0OiBjYWxjKDg0LjVlbSAtIDEwMHZ3KSAhaW1wb3J0YW50OwoJCX0KCX0KCglA
bWVkaWEgbm90IHByaW50IHsKCQkub3ZlcmxhcmdlIHsKCQkJb3ZlcmZsb3cteDogYXV0bzsKCQkJ
LyogU2VlIExlYSBWZXJvdSdzIGV4cGxhbmF0aW9uIGJhY2tncm91bmQtYXR0YWNobWVudDoKCQkJ
ICogaHR0cDovL2xlYS52ZXJvdS5tZS8yMDEyLzA0L2JhY2tncm91bmQtYXR0YWNobWVudC1sb2Nh
bC8KCQkJICoKCQkJYmFja2dyb3VuZDogdG9wIGxlZnQgIC8gNGVtIDEwMCUgbGluZWFyLWdyYWRp
ZW50KHRvIHJpZ2h0LCAgI2ZmZmZmZiwgcmdiYSgyNTUsIDI1NSwgMjU1LCAwKSkgbG9jYWwsCgkJ
CSAgICAgICAgICAgIHRvcCByaWdodCAvIDRlbSAxMDAlIGxpbmVhci1ncmFkaWVudCh0byBsZWZ0
LCAjZmZmZmZmLCByZ2JhKDI1NSwgMjU1LCAyNTUsIDApKSBsb2NhbCwKCQkJICAgICAgICAgICAg
dG9wIGxlZnQgIC8gMWVtIDEwMCUgbGluZWFyLWdyYWRpZW50KHRvIHJpZ2h0LCAgI2MzYzNjNSwg
cmdiYSgxOTUsIDE5NSwgMTk3LCAwKSkgc2Nyb2xsLAoJCQkgICAgICAgICAgICB0b3AgcmlnaHQg
LyAxZW0gMTAwJSBsaW5lYXItZ3JhZGllbnQodG8gbGVmdCwgI2MzYzNjNSwgcmdiYSgxOTUsIDE5
NSwgMTk3LCAwKSkgc2Nyb2xsLAoJCQkgICAgICAgICAgICB3aGl0ZTsKCQkJYmFja2dyb3VuZC1y
ZXBlYXQ6IG5vLXJlcGVhdDsKCQkJKi8KCQl9Cgl9Cjwvc3R5bGU+CjxzdHlsZSB0eXBlPSJ0ZXh0
L2NzcyI+CiAgICB0YWJsZSwgdGgsIHRkIHsKICAgICAgYm9yZGVyOiAxcHggc29saWQgYmxhY2s7
CiAgICAgIGJvcmRlci1jb2xsYXBzZTogY29sbGFwc2U7CiAgICAgIHZlcnRpY2FsLWFsaWduOiB0
b3A7CiAgICB9CiAgICB0aCwgdGQgewogICAgICBib3JkZXItbGVmdDogbm9uZTsKICAgICAgYm9y
ZGVyLXJpZ2h0OiBub25lOwogICAgICBwYWRkaW5nOiAwcHggMTBweDsKICAgIH0KICAgIHRoIHsK
ICAgICAgdGV4dC1hbGlnbjogY2VudGVyOwogICAgfQogIDwvc3R5bGU+CiAgPG1ldGEgY29udGVu
dD0iQmlrZXNoZWQgdmVyc2lvbiA5YzdiM2MxYmY0YWZjZjhlY2E0ZmQzYTE1MjlhMjk4ZWUzNWJl
MDA2IiBuYW1lPSJnZW5lcmF0b3IiPgogIDxsaW5rIGhyZWY9Imh0dHBzOi8vaXNvY3BwLm9yZy9m
YXZpY29uLmljbyIgcmVsPSJpY29uIj4KPHN0eWxlPgppbnMgIHtiYWNrZ3JvdW5kLWNvbG9yOiAj
Q0NGRkNDOyB0ZXh0LWRlY29yYXRpb246IHVuZGVybGluZTt9CmRlbCAge2JhY2tncm91bmQtY29s
b3I6ICNGRkNBQ0E7IHRleHQtZGVjb3JhdGlvbjogbGluZS10aHJvdWdoO30KPC9zdHlsZT4KPHN0
eWxlPi8qIHN0eWxlLW1kLWxpc3RzICovCgovKiBUaGlzIGlzIGEgd2VpcmQgaGFjayBmb3IgbWUg
bm90IHlldCBmb2xsb3dpbmcgdGhlIGNvbW1vbm1hcmsgc3BlYwogICByZWdhcmRpbmcgcGFyYWdy
YXBoIGFuZCBsaXN0cy4gKi8KW2RhdGEtbWRdID4gOmZpcnN0LWNoaWxkIHsKICAgIG1hcmdpbi10
b3A6IDA7Cn0KW2RhdGEtbWRdID4gOmxhc3QtY2hpbGQgewogICAgbWFyZ2luLWJvdHRvbTogMDsK
fTwvc3R5bGU+CjxzdHlsZT4vKiBzdHlsZS1zZWxmbGlua3MgKi8KCi5oZWFkaW5nLCAuaXNzdWUs
IC5ub3RlLCAuZXhhbXBsZSwgbGksIGR0IHsKICAgIHBvc2l0aW9uOiByZWxhdGl2ZTsKfQphLnNl
bGYtbGluayB7CiAgICBwb3NpdGlvbjogYWJzb2x1dGU7CiAgICB0b3A6IDA7CiAgICBsZWZ0OiBj
YWxjKC0xICogKDMuNXJlbSAtIDI2cHgpKTsKICAgIHdpZHRoOiBjYWxjKDMuNXJlbSAtIDI2cHgp
OwogICAgaGVpZ2h0OiAyZW07CiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7CiAgICBib3JkZXI6IG5v
bmU7CiAgICB0cmFuc2l0aW9uOiBvcGFjaXR5IC4yczsKICAgIG9wYWNpdHk6IC41Owp9CmEuc2Vs
Zi1saW5rOmhvdmVyIHsKICAgIG9wYWNpdHk6IDE7Cn0KLmhlYWRpbmcgPiBhLnNlbGYtbGluayB7
CiAgICBmb250LXNpemU6IDgzJTsKfQpsaSA+IGEuc2VsZi1saW5rIHsKICAgIGxlZnQ6IGNhbGMo
LTEgKiAoMy41cmVtIC0gMjZweCkgLSAyZW0pOwp9CmRmbiA+IGEuc2VsZi1saW5rIHsKICAgIHRv
cDogYXV0bzsKICAgIGxlZnQ6IGF1dG87CiAgICBvcGFjaXR5OiAwOwogICAgd2lkdGg6IDEuNWVt
OwogICAgaGVpZ2h0OiAxLjVlbTsKICAgIGJhY2tncm91bmQ6IGdyYXk7CiAgICBjb2xvcjogd2hp
dGU7CiAgICBmb250LXN0eWxlOiBub3JtYWw7CiAgICB0cmFuc2l0aW9uOiBvcGFjaXR5IC4ycywg
YmFja2dyb3VuZC1jb2xvciAuMnMsIGNvbG9yIC4yczsKfQpkZm46aG92ZXIgPiBhLnNlbGYtbGlu
ayB7CiAgICBvcGFjaXR5OiAxOwp9CmRmbiA+IGEuc2VsZi1saW5rOmhvdmVyIHsKICAgIGNvbG9y
OiBibGFjazsKfQoKYS5zZWxmLWxpbms6OmJlZm9yZSAgICAgICAgICAgIHsgY29udGVudDogIsK2
IjsgfQouaGVhZGluZyA+IGEuc2VsZi1saW5rOjpiZWZvcmUgeyBjb250ZW50OiAiwqciOyB9CmRm
biA+IGEuc2VsZi1saW5rOjpiZWZvcmUgICAgICB7IGNvbnRlbnQ6ICIjIjsgfTwvc3R5bGU+Cjxz
dHlsZT4vKiBzdHlsZS1jb3VudGVycyAqLwoKYm9keSB7CiAgICBjb3VudGVyLXJlc2V0OiBleGFt
cGxlIGZpZ3VyZSBpc3N1ZTsKfQouaXNzdWUgewogICAgY291bnRlci1pbmNyZW1lbnQ6IGlzc3Vl
Owp9Ci5pc3N1ZTpub3QoLm5vLW1hcmtlcik6OmJlZm9yZSB7CiAgICBjb250ZW50OiAiSXNzdWUg
IiBjb3VudGVyKGlzc3VlKTsKfQoKLmV4YW1wbGUgewogICAgY291bnRlci1pbmNyZW1lbnQ6IGV4
YW1wbGU7Cn0KLmV4YW1wbGU6bm90KC5uby1tYXJrZXIpOjpiZWZvcmUgewogICAgY29udGVudDog
IkV4YW1wbGUgIiBjb3VudGVyKGV4YW1wbGUpOwp9Ci5pbnZhbGlkLmV4YW1wbGU6bm90KC5uby1t
YXJrZXIpOjpiZWZvcmUsCi5pbGxlZ2FsLmV4YW1wbGU6bm90KC5uby1tYXJrZXIpOjpiZWZvcmUg
ewogICAgY29udGVudDogIkludmFsaWQgRXhhbXBsZSIgY291bnRlcihleGFtcGxlKTsKfQoKZmln
Y2FwdGlvbiB7CiAgICBjb3VudGVyLWluY3JlbWVudDogZmlndXJlOwp9CmZpZ2NhcHRpb246bm90
KC5uby1tYXJrZXIpOjpiZWZvcmUgewogICAgY29udGVudDogIkZpZ3VyZSAiIGNvdW50ZXIoZmln
dXJlKSAiICI7Cn08L3N0eWxlPgo8c3R5bGU+Lyogc3R5bGUtYXV0b2xpbmtzICovCgouY3NzLmNz
cywgLnByb3BlcnR5LnByb3BlcnR5LCAuZGVzY3JpcHRvci5kZXNjcmlwdG9yIHsKICAgIGNvbG9y
OiAjMDA1YTljOwogICAgZm9udC1zaXplOiBpbmhlcml0OwogICAgZm9udC1mYW1pbHk6IGluaGVy
aXQ7Cn0KLmNzczo6YmVmb3JlLCAucHJvcGVydHk6OmJlZm9yZSwgLmRlc2NyaXB0b3I6OmJlZm9y
ZSB7CiAgICBjb250ZW50OiAi4oCYIjsKfQouY3NzOjphZnRlciwgLnByb3BlcnR5OjphZnRlciwg
LmRlc2NyaXB0b3I6OmFmdGVyIHsKICAgIGNvbnRlbnQ6ICLigJkiOwp9Ci5wcm9wZXJ0eSwgLmRl
c2NyaXB0b3IgewogICAgLyogRG9uJ3Qgd3JhcCBwcm9wZXJ0eSBhbmQgZGVzY3JpcHRvciBuYW1l
cyAqLwogICAgd2hpdGUtc3BhY2U6IG5vd3JhcDsKfQoudHlwZSB7IC8qIENTUyB2YWx1ZSA8dHlw
ZT4gKi8KICAgIGZvbnQtc3R5bGU6IGl0YWxpYzsKfQpwcmUgLnByb3BlcnR5OjpiZWZvcmUsIHBy
ZSAucHJvcGVydHk6OmFmdGVyIHsKICAgIGNvbnRlbnQ6ICIiOwp9CltkYXRhLWxpbmstdHlwZT0i
cHJvcGVydHkiXTo6YmVmb3JlLApbZGF0YS1saW5rLXR5cGU9InByb3BkZXNjIl06OmJlZm9yZSwK
W2RhdGEtbGluay10eXBlPSJkZXNjcmlwdG9yIl06OmJlZm9yZSwKW2RhdGEtbGluay10eXBlPSJ2
YWx1ZSJdOjpiZWZvcmUsCltkYXRhLWxpbmstdHlwZT0iZnVuY3Rpb24iXTo6YmVmb3JlLApbZGF0
YS1saW5rLXR5cGU9ImF0LXJ1bGUiXTo6YmVmb3JlLApbZGF0YS1saW5rLXR5cGU9InNlbGVjdG9y
Il06OmJlZm9yZSwKW2RhdGEtbGluay10eXBlPSJtYXliZSJdOjpiZWZvcmUgewogICAgY29udGVu
dDogIuKAmCI7Cn0KW2RhdGEtbGluay10eXBlPSJwcm9wZXJ0eSJdOjphZnRlciwKW2RhdGEtbGlu
ay10eXBlPSJwcm9wZGVzYyJdOjphZnRlciwKW2RhdGEtbGluay10eXBlPSJkZXNjcmlwdG9yIl06
OmFmdGVyLApbZGF0YS1saW5rLXR5cGU9InZhbHVlIl06OmFmdGVyLApbZGF0YS1saW5rLXR5cGU9
ImZ1bmN0aW9uIl06OmFmdGVyLApbZGF0YS1saW5rLXR5cGU9ImF0LXJ1bGUiXTo6YWZ0ZXIsCltk
YXRhLWxpbmstdHlwZT0ic2VsZWN0b3IiXTo6YWZ0ZXIsCltkYXRhLWxpbmstdHlwZT0ibWF5YmUi
XTo6YWZ0ZXIgewogICAgY29udGVudDogIuKAmSI7Cn0KCltkYXRhLWxpbmstdHlwZV0ucHJvZHVj
dGlvbjo6YmVmb3JlLApbZGF0YS1saW5rLXR5cGVdLnByb2R1Y3Rpb246OmFmdGVyLAoucHJvZCBb
ZGF0YS1saW5rLXR5cGVdOjpiZWZvcmUsCi5wcm9kIFtkYXRhLWxpbmstdHlwZV06OmFmdGVyIHsK
ICAgIGNvbnRlbnQ6ICIiOwp9CgpbZGF0YS1saW5rLXR5cGU9ZWxlbWVudF0sCltkYXRhLWxpbmst
dHlwZT1lbGVtZW50LWF0dHJdIHsKICAgIGZvbnQtZmFtaWx5OiBNZW5sbywgQ29uc29sYXMsICJE
ZWphVnUgU2FucyBNb25vIiwgbW9ub3NwYWNlOwogICAgZm9udC1zaXplOiAuOWVtOwp9CltkYXRh
LWxpbmstdHlwZT1lbGVtZW50XTo6YmVmb3JlIHsgY29udGVudDogIjwiIH0KW2RhdGEtbGluay10
eXBlPWVsZW1lbnRdOjphZnRlciAgeyBjb250ZW50OiAiPiIgfQoKW2RhdGEtbGluay10eXBlPWJp
Ymxpb10gewogICAgd2hpdGUtc3BhY2U6IHByZTsKfTwvc3R5bGU+CjxzdHlsZT4vKiBzdHlsZS1k
Zm4tcGFuZWwgKi8KCi5kZm4tcGFuZWwgewogICAgcG9zaXRpb246IGFic29sdXRlOwogICAgei1p
bmRleDogMzU7CiAgICBoZWlnaHQ6IGF1dG87CiAgICB3aWR0aDogLXdlYmtpdC1maXQtY29udGVu
dDsKICAgIHdpZHRoOiBmaXQtY29udGVudDsKICAgIG1heC13aWR0aDogMzAwcHg7CiAgICBtYXgt
aGVpZ2h0OiA1MDBweDsKICAgIG92ZXJmbG93OiBhdXRvOwogICAgcGFkZGluZzogMC41ZW0gMC43
NWVtOwogICAgZm9udDogc21hbGwgSGVsdmV0aWNhIE5ldWUsIHNhbnMtc2VyaWYsIERyb2lkIFNh
bnMgRmFsbGJhY2s7CiAgICBiYWNrZ3JvdW5kOiAjREREREREOwogICAgY29sb3I6IGJsYWNrOwog
ICAgYm9yZGVyOiBvdXRzZXQgMC4yZW07Cn0KLmRmbi1wYW5lbDpub3QoLm9uKSB7IGRpc3BsYXk6
IG5vbmU7IH0KLmRmbi1wYW5lbCAqIHsgbWFyZ2luOiAwOyBwYWRkaW5nOiAwOyB0ZXh0LWluZGVu
dDogMDsgfQouZGZuLXBhbmVsID4gYiB7IGRpc3BsYXk6IGJsb2NrOyB9Ci5kZm4tcGFuZWwgYSB7
IGNvbG9yOiBibGFjazsgfQouZGZuLXBhbmVsIGE6bm90KDpob3ZlcikgeyB0ZXh0LWRlY29yYXRp
b246IG5vbmUgIWltcG9ydGFudDsgYm9yZGVyLWJvdHRvbTogbm9uZSAhaW1wb3J0YW50OyB9Ci5k
Zm4tcGFuZWwgPiBiICsgYiB7IG1hcmdpbi10b3A6IDAuMjVlbTsgfQouZGZuLXBhbmVsIHVsIHsg
cGFkZGluZzogMDsgfQouZGZuLXBhbmVsIGxpIHsgbGlzdC1zdHlsZTogaW5zaWRlOyB9Ci5kZm4t
cGFuZWwuYWN0aXZhdGVkIHsKICAgIGRpc3BsYXk6IGlubGluZS1ibG9jazsKICAgIHBvc2l0aW9u
OiBmaXhlZDsKICAgIGxlZnQ6IC41ZW07CiAgICBib3R0b206IDJlbTsKICAgIG1hcmdpbjogMCBh
dXRvOwogICAgbWF4LXdpZHRoOiBjYWxjKDEwMHZ3IC0gMS41ZW0gLSAuNGVtIC0gLjVlbSk7CiAg
ICBtYXgtaGVpZ2h0OiAzMHZoOwp9CgouZGZuLXBhbmVsZWQgeyBjdXJzb3I6IHBvaW50ZXI7IH0K
PC9zdHlsZT4KPHN0eWxlPi8qIHN0eWxlLXN5bnRheC1oaWdobGlnaHRpbmcgKi8KCi5oaWdobGln
aHQ6bm90KC5pZGwpIHsgYmFja2dyb3VuZDogaHNsKDI0LCAyMCUsIDk1JSk7IH0KY29kZS5oaWdo
bGlnaHQgeyBwYWRkaW5nOiAuMWVtOyBib3JkZXItcmFkaXVzOiAuM2VtOyB9CnByZS5oaWdobGln
aHQsIHByZSA+IGNvZGUuaGlnaGxpZ2h0IHsgZGlzcGxheTogYmxvY2s7IHBhZGRpbmc6IDFlbTsg
bWFyZ2luOiAuNWVtIDA7IG92ZXJmbG93OiBhdXRvOyBib3JkZXItcmFkaXVzOiAwOyB9CmMtW2Fd
IHsgY29sb3I6ICM5OTAwNTUgfSAvKiBLZXl3b3JkLkRlY2xhcmF0aW9uICovCmMtW2JdIHsgY29s
b3I6ICM5OTAwNTUgfSAvKiBLZXl3b3JkLlR5cGUgKi8KYy1bY10geyBjb2xvcjogIzcwODA5MCB9
IC8qIENvbW1lbnQgKi8KYy1bZF0geyBjb2xvcjogIzcwODA5MCB9IC8qIENvbW1lbnQuTXVsdGls
aW5lICovCmMtW2VdIHsgY29sb3I6ICMwMDc3YWEgfSAvKiBOYW1lLkF0dHJpYnV0ZSAqLwpjLVtm
XSB7IGNvbG9yOiAjNjY5OTAwIH0gLyogTmFtZS5UYWcgKi8KYy1bZ10geyBjb2xvcjogIzIyMjIy
MiB9IC8qIE5hbWUuVmFyaWFibGUgKi8KYy1ba10geyBjb2xvcjogIzk5MDA1NSB9IC8qIEtleXdv
cmQgKi8KYy1bbF0geyBjb2xvcjogIzAwMDAwMCB9IC8qIExpdGVyYWwgKi8KYy1bbV0geyBjb2xv
cjogIzAwMDAwMCB9IC8qIExpdGVyYWwuTnVtYmVyICovCmMtW25dIHsgY29sb3I6ICMwMDc3YWEg
fSAvKiBOYW1lICovCmMtW29dIHsgY29sb3I6ICM5OTk5OTkgfSAvKiBPcGVyYXRvciAqLwpjLVtw
XSB7IGNvbG9yOiAjOTk5OTk5IH0gLyogUHVuY3R1YXRpb24gKi8KYy1bc10geyBjb2xvcjogI2E2
N2Y1OSB9IC8qIExpdGVyYWwuU3RyaW5nICovCmMtW3RdIHsgY29sb3I6ICNhNjdmNTkgfSAvKiBM
aXRlcmFsLlN0cmluZy5TaW5nbGUgKi8KYy1bdV0geyBjb2xvcjogI2E2N2Y1OSB9IC8qIExpdGVy
YWwuU3RyaW5nLkRvdWJsZSAqLwpjLVtjcF0geyBjb2xvcjogIzcwODA5MCB9IC8qIENvbW1lbnQu
UHJlcHJvYyAqLwpjLVtjMV0geyBjb2xvcjogIzcwODA5MCB9IC8qIENvbW1lbnQuU2luZ2xlICov
CmMtW2NzXSB7IGNvbG9yOiAjNzA4MDkwIH0gLyogQ29tbWVudC5TcGVjaWFsICovCmMtW2tjXSB7
IGNvbG9yOiAjOTkwMDU1IH0gLyogS2V5d29yZC5Db25zdGFudCAqLwpjLVtrbl0geyBjb2xvcjog
Izk5MDA1NSB9IC8qIEtleXdvcmQuTmFtZXNwYWNlICovCmMtW2twXSB7IGNvbG9yOiAjOTkwMDU1
IH0gLyogS2V5d29yZC5Qc2V1ZG8gKi8KYy1ba3JdIHsgY29sb3I6ICM5OTAwNTUgfSAvKiBLZXl3
b3JkLlJlc2VydmVkICovCmMtW2xkXSB7IGNvbG9yOiAjMDAwMDAwIH0gLyogTGl0ZXJhbC5EYXRl
ICovCmMtW25jXSB7IGNvbG9yOiAjMDA3N2FhIH0gLyogTmFtZS5DbGFzcyAqLwpjLVtub10geyBj
b2xvcjogIzAwNzdhYSB9IC8qIE5hbWUuQ29uc3RhbnQgKi8KYy1bbmRdIHsgY29sb3I6ICMwMDc3
YWEgfSAvKiBOYW1lLkRlY29yYXRvciAqLwpjLVtuaV0geyBjb2xvcjogIzAwNzdhYSB9IC8qIE5h
bWUuRW50aXR5ICovCmMtW25lXSB7IGNvbG9yOiAjMDA3N2FhIH0gLyogTmFtZS5FeGNlcHRpb24g
Ki8KYy1bbmZdIHsgY29sb3I6ICMwMDc3YWEgfSAvKiBOYW1lLkZ1bmN0aW9uICovCmMtW25sXSB7
IGNvbG9yOiAjMDA3N2FhIH0gLyogTmFtZS5MYWJlbCAqLwpjLVtubl0geyBjb2xvcjogIzAwNzdh
YSB9IC8qIE5hbWUuTmFtZXNwYWNlICovCmMtW3B5XSB7IGNvbG9yOiAjMDA3N2FhIH0gLyogTmFt
ZS5Qcm9wZXJ0eSAqLwpjLVtvd10geyBjb2xvcjogIzk5OTk5OSB9IC8qIE9wZXJhdG9yLldvcmQg
Ki8KYy1bbWJdIHsgY29sb3I6ICMwMDAwMDAgfSAvKiBMaXRlcmFsLk51bWJlci5CaW4gKi8KYy1b
bWZdIHsgY29sb3I6ICMwMDAwMDAgfSAvKiBMaXRlcmFsLk51bWJlci5GbG9hdCAqLwpjLVttaF0g
eyBjb2xvcjogIzAwMDAwMCB9IC8qIExpdGVyYWwuTnVtYmVyLkhleCAqLwpjLVttaV0geyBjb2xv
cjogIzAwMDAwMCB9IC8qIExpdGVyYWwuTnVtYmVyLkludGVnZXIgKi8KYy1bbW9dIHsgY29sb3I6
ICMwMDAwMDAgfSAvKiBMaXRlcmFsLk51bWJlci5PY3QgKi8KYy1bc2JdIHsgY29sb3I6ICNhNjdm
NTkgfSAvKiBMaXRlcmFsLlN0cmluZy5CYWNrdGljayAqLwpjLVtzY10geyBjb2xvcjogI2E2N2Y1
OSB9IC8qIExpdGVyYWwuU3RyaW5nLkNoYXIgKi8KYy1bc2RdIHsgY29sb3I6ICNhNjdmNTkgfSAv
KiBMaXRlcmFsLlN0cmluZy5Eb2MgKi8KYy1bc2VdIHsgY29sb3I6ICNhNjdmNTkgfSAvKiBMaXRl
cmFsLlN0cmluZy5Fc2NhcGUgKi8KYy1bc2hdIHsgY29sb3I6ICNhNjdmNTkgfSAvKiBMaXRlcmFs
LlN0cmluZy5IZXJlZG9jICovCmMtW3NpXSB7IGNvbG9yOiAjYTY3ZjU5IH0gLyogTGl0ZXJhbC5T
dHJpbmcuSW50ZXJwb2wgKi8KYy1bc3hdIHsgY29sb3I6ICNhNjdmNTkgfSAvKiBMaXRlcmFsLlN0
cmluZy5PdGhlciAqLwpjLVtzcl0geyBjb2xvcjogI2E2N2Y1OSB9IC8qIExpdGVyYWwuU3RyaW5n
LlJlZ2V4ICovCmMtW3NzXSB7IGNvbG9yOiAjYTY3ZjU5IH0gLyogTGl0ZXJhbC5TdHJpbmcuU3lt
Ym9sICovCmMtW3ZjXSB7IGNvbG9yOiAjMDA3N2FhIH0gLyogTmFtZS5WYXJpYWJsZS5DbGFzcyAq
LwpjLVt2Z10geyBjb2xvcjogIzAwNzdhYSB9IC8qIE5hbWUuVmFyaWFibGUuR2xvYmFsICovCmMt
W3ZpXSB7IGNvbG9yOiAjMDA3N2FhIH0gLyogTmFtZS5WYXJpYWJsZS5JbnN0YW5jZSAqLwpjLVtp
bF0geyBjb2xvcjogIzAwMDAwMCB9IC8qIExpdGVyYWwuTnVtYmVyLkludGVnZXIuTG9uZyAqLwo8
L3N0eWxlPgogPGJvZHkgY2xhc3M9ImgtZW50cnkiPgogIDxkaXYgY2xhc3M9ImhlYWQiPgogICA8
cCBkYXRhLWZpbGwtd2l0aD0ibG9nbyI+PC9wPgogICA8aDEgY2xhc3M9InAtbmFtZSBuby1yZWYi
IGlkPSJ0aXRsZSI+RDExNDRSMDxicj5PYmplY3QgcmVsb2NhdGlvbiBpbiB0ZXJtcyBvZiBtb3Zl
IHBsdXMgZGVzdHJveTwvaDE+CiAgIDxoMiBjbGFzcz0ibm8tbnVtIG5vLXRvYyBuby1yZWYgaGVh
ZGluZyBzZXR0bGVkIiBpZD0ic3VidGl0bGUiPjxzcGFuIGNsYXNzPSJjb250ZW50Ij5EcmFmdCBQ
cm9wb3NhbCwgPHRpbWUgY2xhc3M9ImR0LXVwZGF0ZWQiIGRhdGV0aW1lPSIyMDE4LTA3LTA2Ij4y
MDE4LTA3LTA2PC90aW1lPjwvc3Bhbj48L2gyPgogICA8ZGl2IGRhdGEtZmlsbC13aXRoPSJzcGVj
LW1ldGFkYXRhIj4KICAgIDxkbD4KICAgICA8ZHQ+SXNzdWUgVHJhY2tpbmc6CiAgICAgPGRkPjxh
IGhyZWY9IiNpc3N1ZXMtaW5kZXgiPklubGluZSBJbiBTcGVjPC9hPgogICAgIDxkdD5BdXRob3Jz
OgogICAgIDxkZD4KICAgICAgPGRkIGNsYXNzPSJlZGl0b3IgcC1hdXRob3IgaC1jYXJkIHZjYXJk
Ij48YSBjbGFzcz0icC1uYW1lIGZuIHUtZW1haWwgZW1haWwiIGhyZWY9Im1haWx0bzphcnRodXIu
ai5vZHd5ZXJAZ21haWwuY29tIj5BcnRodXIgTydEd3llcjwvYT4KICAgICA8ZGQ+CiAgICAgIDxk
ZCBjbGFzcz0iZWRpdG9yIHAtYXV0aG9yIGgtY2FyZCB2Y2FyZCI+PGEgY2xhc3M9InAtbmFtZSBm
biB1LWVtYWlsIGVtYWlsIiBocmVmPSJtYWlsdG86d214MTY4MzV2dkAxNjMuY29tIj5NaW5neGlu
IFdhbmc8L2E+CiAgICAgPGR0PkF1ZGllbmNlOgogICAgIDxkZD5MRVdHLCBFV0cKICAgICA8ZHQ+
UHJvamVjdDoKICAgICA8ZGQ+SVNPL0lFQyBKVEMxL1NDMjIvV0cyMSAxNDg4MjogUHJvZ3JhbW1p
bmcgTGFuZ3VhZ2Ug4oCUIEMrKwogICAgIDxkdD5EcmFmdCBSZXZpc2lvbjoKICAgICA8ZGQ+MTAK
ICAgICA8ZHQ+Q3VycmVudCBTb3VyY2U6CiAgICAgPGRkPjxhIGhyZWY9Imh0dHBzOi8vZ2l0aHVi
LmNvbS9RdXV4cGx1c29uZS9kcmFmdC9ibG9iL2doLXBhZ2VzL2QxMTQ0LmJzIj5naXRodWIuY29t
L1F1dXhwbHVzb25lL2RyYWZ0L2Jsb2IvZ2gtcGFnZXMvZDExNDQtb2JqZWN0LXJlbG9jYXRpb24u
YnM8L2E+CiAgICAgPGR0PkN1cnJlbnQ6CiAgICAgPGRkPjxhIGhyZWY9Imh0dHBzOi8vcmF3Z2l0
LmNvbS9RdXV4cGx1c29uZS9kcmFmdC9naC1wYWdlcy9kMTE0NC5odG1sIj5yYXdnaXQuY29tL1F1
dXhwbHVzb25lL2RyYWZ0L2doLXBhZ2VzL2QxMTQ0LW9iamVjdC1yZWxvY2F0aW9uLmh0bWw8L2E+
CiAgICA8L2RsPgogICA8L2Rpdj4KICAgPGRpdiBkYXRhLWZpbGwtd2l0aD0id2FybmluZyI+PC9k
aXY+CiAgIDxociB0aXRsZT0iU2VwYXJhdG9yIGZvciBoZWFkZXIiPgogIDwvZGl2PgogIDxkaXYg
Y2xhc3M9InAtc3VtbWFyeSIgZGF0YS1maWxsLXdpdGg9ImFic3RyYWN0Ij4KICAgPGgyIGNsYXNz
PSJuby1udW0gbm8tdG9jIG5vLXJlZiBoZWFkaW5nIHNldHRsZWQiIGlkPSJhYnN0cmFjdCI+PHNw
YW4gY2xhc3M9ImNvbnRlbnQiPkFic3RyYWN0PC9zcGFuPjwvaDI+CiAgIDxwPldlIGRlZmluZSBh
IG5ldyBhbGdvcml0aG0gInJlbG9jYXRlIiB3aGljaCBpcyB0YW50YW1vdW50IHRvIGEgbW92ZSBh
bmQgYSBkZXN0cm95LAoKYW5hbG9nb3VzIHRvIHRoZSBleGlzdGluZyBhbGdvcml0aG0gInN3YXAi
IHdoaWNoIGlzIHRhbnRhbW91bnQgdG8gYSBtb3ZlLCB0d28gbW92ZS1hc3NpZ25tZW50cywgYW5k
IGEgZGVzdHJveS4KRm9yIG1vc3QgKGJ1dCBub3QgYWxsKSBDKysgdHlwZXMsIHRoZSAicmVsb2Nh
dGUiIG9wZXJhdGlvbiBpcyBlcXVpdmFsZW50IHRvIGEgc2luZ2xlIDxjb2RlIGNsYXNzPSJoaWdo
bGlnaHQiPjxjLSBuPm1lbWNweTwvYy0+PC9jb2RlPi4KRm9yIHRoZSBiZW5lZml0IG9mIGxpYnJh
cnkgd3JpdGVycywgd2UgcHJvdmlkZSBhIHN0YW5kYXJkIHR5cGUgdHJhaXQgdG8gZGV0ZWN0IHR5
cGVzIHdob3NlICJyZWxvY2F0ZSIgaXMga25vd24gdG8gYmUgZXF1aXZhbGVudCB0byA8Y29kZSBj
bGFzcz0iaGlnaGxpZ2h0Ij48Yy0gbj5tZW1jcHk8L2MtPjwvY29kZT4uCkZpbmFsbHksIHdlIHBy
b3ZpZGUgYSBwb3J0YWJsZSB3YXkgZm9yIGFueSB1c2VyLWRlZmluZWQgdHlwZSAoc3VjaCBhcyA8
Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gbj5ib29zdDwvYy0+PGMtIG8+Ojo8L2MtPjxjLSBu
PnNoYXJlZF9wdHI8L2MtPjwvY29kZT4pIHRvIHdhcnJhbnQgdG8gdGhlIGltcGxlbWVudGF0aW9u
IHRoYXQgaXRzICJyZWxvY2F0ZSIgaXMgZXF1aXZhbGVudCB0byA8Y29kZSBjbGFzcz0iaGlnaGxp
Z2h0Ij48Yy0gbj5tZW1jcHk8L2MtPjwvY29kZT4sIHRodXMgZ2FpbmluZyB0aGUgc2FtZSBwZXJm
b3JtYW5jZSBiZW5lZml0cyBhcyB0aGUgc3RhbmRhcmQgbGlicmFyeSB0eXBlcy48L3A+CiAgPC9k
aXY+CiAgPG5hdiBkYXRhLWZpbGwtd2l0aD0idGFibGUtb2YtY29udGVudHMiIGlkPSJ0b2MiPgog
ICA8aDIgY2xhc3M9Im5vLW51bSBuby10b2Mgbm8tcmVmIiBpZD0iY29udGVudHMiPlRhYmxlIG9m
IENvbnRlbnRzPC9oMj4KICAgPG9sIGNsYXNzPSJ0b2MiIHJvbGU9ImRpcmVjdG9yeSI+CiAgICA8
bGk+CiAgICAgPGEgaHJlZj0iI2ludHJvIj48c3BhbiBjbGFzcz0ic2Vjbm8iPjE8L3NwYW4+IDxz
cGFuIGNsYXNzPSJjb250ZW50Ij5JbnRyb2R1Y3Rpb24gYW5kIG1vdGl2YXRpb248L3NwYW4+PC9h
PgogICAgIDxvbCBjbGFzcz0idG9jIj4KICAgICAgPGxpPjxhIGhyZWY9IiNkb2luZy1pdC13cm9u
ZyI+PHNwYW4gY2xhc3M9InNlY25vIj4xLjE8L3NwYW4+IDxzcGFuIGNsYXNzPSJjb250ZW50Ij5S
ZWFsLXdvcmxkIGNvZGUgYWxyZWFkeSBkb2VzIGl0IHdyb25nPC9zcGFuPjwvYT4KICAgICA8L29s
PgogICAgPGxpPgogICAgIDxhIGhyZWY9IiNkZXNpZ24tZ29hbHMiPjxzcGFuIGNsYXNzPSJzZWNu
byI+Mjwvc3Bhbj4gPHNwYW4gY2xhc3M9ImNvbnRlbnQiPkRlc2lnbiBnb2Fsczwvc3Bhbj48L2E+
CiAgICAgPG9sIGNsYXNzPSJ0b2MiPgogICAgICA8bGk+PGEgaHJlZj0iI3VzZTEiPjxzcGFuIGNs
YXNzPSJzZWNubyI+Mi4xPC9zcGFuPiA8c3BhbiBjbGFzcz0iY29udGVudCI+U3RhbmRhcmQgbGli
cmFyeSB0eXBlcyBzdWNoIGFzIDxjb2RlIGNsYXNzPSJoaWdobGlnaHQiPjxjLSBuPnN0ZDwvYy0+
PGMtIG8+Ojo8L2MtPjxjLSBuPnN0cmluZzwvYy0+PC9jb2RlPjwvc3Bhbj48L2E+CiAgICAgIDxs
aT48YSBocmVmPSIjdXNlMiI+PHNwYW4gY2xhc3M9InNlY25vIj4yLjI8L3NwYW4+IDxzcGFuIGNs
YXNzPSJjb250ZW50Ij5Qcm9ncmFtLWRlZmluZWQgdHlwZXMgdGhhdCBmb2xsb3cgdGhlIFJ1bGUg
b2YgWmVybzwvc3Bhbj48L2E+CiAgICAgIDxsaT48YSBocmVmPSIjdXNlMyI+PHNwYW4gY2xhc3M9
InNlY25vIj4yLjM8L3NwYW4+IDxzcGFuIGNsYXNzPSJjb250ZW50Ij5Qcm9ncmFtLWRlZmluZWQg
dHlwZXMgd2l0aCBub24tZGVmYXVsdGVkIHNwZWNpYWwgbWVtYmVyczwvc3Bhbj48L2E+CiAgICAg
PC9vbD4KICAgIDxsaT48YSBocmVmPSIjcHJvcG9zYWwiPjxzcGFuIGNsYXNzPSJzZWNubyI+Mzwv
c3Bhbj4gPHNwYW4gY2xhc3M9ImNvbnRlbnQiPlByb3Bvc2VkIGxhbmd1YWdlIGFuZCBsaWJyYXJ5
IGZlYXR1cmVzPC9zcGFuPjwvYT4KICAgIDxsaT4KICAgICA8YSBocmVmPSIjd29yZGluZyI+PHNw
YW4gY2xhc3M9InNlY25vIj40PC9zcGFuPiA8c3BhbiBjbGFzcz0iY29udGVudCI+UHJvcG9zZWQg
d29yZGluZyBmb3IgQysrMjA8L3NwYW4+PC9hPgogICAgIDxvbCBjbGFzcz0idG9jIj4KICAgICAg
PGxpPjxhIGhyZWY9IiN3b3JkaW5nLW9wZXJhdGlvbiI+PHNwYW4gY2xhc3M9InNlY25vIj40LjE8
L3NwYW4+IDxzcGFuIGNsYXNzPSJjb250ZW50Ij5SZWxvY2F0aW9uIG9wZXJhdGlvbjwvc3Bhbj48
L2E+CiAgICAgIDxsaT48YSBocmVmPSIjd29yZGluZy11bmluaXQtcmVsb2NhdGUiPjxzcGFuIGNs
YXNzPSJzZWNubyI+NC4yPC9zcGFuPiA8c3BhbiBjbGFzcz0iY29udGVudCI+QWxnb3JpdGhtIDxj
b2RlIGNsYXNzPSJoaWdobGlnaHQiPjxjLSBuPnVuaW5pdGlhbGl6ZWRfcmVsb2NhdGU8L2MtPjwv
Y29kZT48L3NwYW4+PC9hPgogICAgICA8bGk+PGEgaHJlZj0iI3dvcmRpbmctdW5pbml0LXJlbG9j
YXRlLW4iPjxzcGFuIGNsYXNzPSJzZWNubyI+NC4zPC9zcGFuPiA8c3BhbiBjbGFzcz0iY29udGVu
dCI+QWxnb3JpdGhtIDxjb2RlIGNsYXNzPSJoaWdobGlnaHQiPjxjLSBuPnVuaW5pdGlhbGl6ZWRf
cmVsb2NhdGVfbjwvYy0+PC9jb2RlPjwvc3Bhbj48L2E+CiAgICAgIDxsaT48YSBocmVmPSIjd29y
ZGluZy1pbmhlcml0YW5jZSI+PHNwYW4gY2xhc3M9InNlY25vIj40LjQ8L3NwYW4+IDxzcGFuIGNs
YXNzPSJjb250ZW50Ij5Ucml2aWFsbHkgcmVsb2NhdGFibGUgdHlwZTwvc3Bhbj48L2E+CiAgICAg
IDxsaT48YSBocmVmPSIjd29yZGluZy1hdHRyaWJ1dGUiPjxzcGFuIGNsYXNzPSJzZWNubyI+NC41
PC9zcGFuPiA8c3BhbiBjbGFzcz0iY29udGVudCI+PGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMt
IHA+W1s8L2MtPjxjLSBuPnRyaXZpYWxseV9yZWxvY2F0YWJsZTwvYy0+PGMtIHA+XV08L2MtPjwv
Y29kZT4gYXR0cmlidXRlPC9zcGFuPjwvYT4KICAgICAgPGxpPjxhIGhyZWY9IiN3b3JkaW5nLXRy
YWl0cyI+PHNwYW4gY2xhc3M9InNlY25vIj40LjY8L3NwYW4+IDxzcGFuIGNsYXNzPSJjb250ZW50
Ij5UeXBlIHRyYWl0cyA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gbj5pc19yZWxvY2F0YWJs
ZTwvYy0+PC9jb2RlPiBldGMuPC9zcGFuPjwvYT4KICAgICAgPGxpPjxhIGhyZWY9IiN3b3JkaW5n
LWNvbmNlcHQiPjxzcGFuIGNsYXNzPSJzZWNubyI+NC43PC9zcGFuPiA8c3BhbiBjbGFzcz0iY29u
dGVudCI+PGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMtIG4+UmVsb2NhdGFibGU8L2MtPjwvY29k
ZT4gY29uY2VwdDwvc3Bhbj48L2E+CiAgICAgPC9vbD4KICAgIDxsaT4KICAgICA8YSBocmVmPSIj
ZnVydGhlciI+PHNwYW4gY2xhc3M9InNlY25vIj41PC9zcGFuPiA8c3BhbiBjbGFzcz0iY29udGVu
dCI+RnVydGhlciBjb25zaWRlcmF0aW9ucyBhbmQgZGlyZWN0aW9uczwvc3Bhbj48L2E+CiAgICAg
PG9sIGNsYXNzPSJ0b2MiPgogICAgICA8bGk+PGEgaHJlZj0iI3RyaXZpYWxseS1zd2FwcGFibGUi
PjxzcGFuIGNsYXNzPSJzZWNubyI+NS4xPC9zcGFuPiA8c3BhbiBjbGFzcz0iY29udGVudCI+VHJp
dmlhbGx5IHN3YXBwYWJsZSB0eXBlczwvc3Bhbj48L2E+CiAgICAgIDxsaT48YSBocmVmPSIjaGV0
ZXJvIj48c3BhbiBjbGFzcz0ic2Vjbm8iPjUuMjwvc3Bhbj4gPHNwYW4gY2xhc3M9ImNvbnRlbnQi
PkhldGVyb2dlbmVvdXMgcmVsb2NhdGlvbjwvc3Bhbj48L2E+CiAgICAgPC9vbD4KICAgIDxsaT48
YSBocmVmPSIjYWNrbm93bGVkZ2VtZW50cyI+PHNwYW4gY2xhc3M9InNlY25vIj42PC9zcGFuPiA8
c3BhbiBjbGFzcz0iY29udGVudCI+QWNrbm93bGVkZ2VtZW50czwvc3Bhbj48L2E+CiAgICA8bGk+
CiAgICAgPGEgaHJlZj0iI3BvbGxzIj48c3BhbiBjbGFzcz0ic2Vjbm8iPjwvc3Bhbj4gPHNwYW4g
Y2xhc3M9ImNvbnRlbnQiPkFwcGVuZGl4IEE6IFN0cmF3IHBvbGxzIHJlcXVlc3RlZDwvc3Bhbj48
L2E+CiAgICAgPG9sIGNsYXNzPSJ0b2MiPgogICAgICA8bGk+PGEgaHJlZj0iI2xld2ctcG9sbHMi
PjxzcGFuIGNsYXNzPSJzZWNubyI+PC9zcGFuPiA8c3BhbiBjbGFzcz0iY29udGVudCI+UG9sbHMg
Zm9yIExFV0c8L3NwYW4+PC9hPgogICAgICA8bGk+PGEgaHJlZj0iI2V3Zy1wb2xscyI+PHNwYW4g
Y2xhc3M9InNlY25vIj48L3NwYW4+IDxzcGFuIGNsYXNzPSJjb250ZW50Ij5Qb2xscyBmb3IgRVdH
PC9zcGFuPjwvYT4KICAgICA8L29sPgogICAgPGxpPgogICAgIDxhIGhyZWY9IiNzYW1wbGVzIj48
c3BhbiBjbGFzcz0ic2Vjbm8iPjwvc3Bhbj4gPHNwYW4gY2xhc3M9ImNvbnRlbnQiPkFwcGVuZGl4
IEI6IFNhbXBsZSBjb2RlPC9zcGFuPjwvYT4KICAgICA8b2wgY2xhc3M9InRvYyI+CiAgICAgIDxs
aT48YSBocmVmPSIjc2FtcGxlLWRlZHVjaW5nIj48c3BhbiBjbGFzcz0ic2Vjbm8iPjwvc3Bhbj4g
PHNwYW4gY2xhc3M9ImNvbnRlbnQiPkRlZmluaW5nIGEgdHJpdmlhbGx5IHJlbG9jYXRhYmxlIGZ1
bmN0aW9uIG9iamVjdDwvc3Bhbj48L2E+CiAgICAgIDxsaT48YSBocmVmPSIjc2FtcGxlLW9wdGlu
Zy1pbiI+PHNwYW4gY2xhc3M9InNlY25vIj48L3NwYW4+IDxzcGFuIGNsYXNzPSJjb250ZW50Ij5X
YXJyYW50aW5nIHRoYXQgYSB1c2VyLWRlZmluZWQgcmVsb2NhdGlvbiBvcGVyYXRpb24gaXMgZXF1
aXZhbGVudCB0byA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gbj5tZW1jcHk8L2MtPjwvY29k
ZT48L3NwYW4+PC9hPgogICAgICA8bGk+PGEgaHJlZj0iI3NhbXBsZS11bmluaXQtcmVsb2NhdGUi
PjxzcGFuIGNsYXNzPSJzZWNubyI+PC9zcGFuPiA8c3BhbiBjbGFzcz0iY29udGVudCI+UmVmZXJl
bmNlIGltcGxlbWVudGF0aW9uIG9mIDxjb2RlIGNsYXNzPSJoaWdobGlnaHQiPjxjLSBuPnN0ZDwv
Yy0+PGMtIG8+Ojo8L2MtPjxjLSBuPnVuaW5pdGlhbGl6ZWRfcmVsb2NhdGU8L2MtPjwvY29kZT48
L3NwYW4+PC9hPgogICAgICA8bGk+PGEgaHJlZj0iI3NhbXBsZS1jb25kaXRpb25hbCI+PHNwYW4g
Y2xhc3M9InNlY25vIj48L3NwYW4+IDxzcGFuIGNsYXNzPSJjb250ZW50Ij5Db25kaXRpb25hbGx5
IHRyaXZpYWwgcmVsb2NhdGlvbjwvc3Bhbj48L2E+CiAgICAgPC9vbD4KICAgIDxsaT4KICAgICA8
YSBocmVmPSIjbm9uLXRyaXZpYWwtc2FtcGxlcyI+PHNwYW4gY2xhc3M9InNlY25vIj48L3NwYW4+
IDxzcGFuIGNsYXNzPSJjb250ZW50Ij5BcHBlbmRpeCBDOiBFeGFtcGxlcyBvZiBub24tdHJpdmlh
bGx5IHJlbG9jYXRhYmxlIGNsYXNzIHR5cGVzPC9zcGFuPjwvYT4KICAgICA8b2wgY2xhc3M9InRv
YyI+CiAgICAgIDxsaT48YSBocmVmPSIjbm9uLXRyaXZpYWwtc2FtcGxlLXN0cmluZyI+PHNwYW4g
Y2xhc3M9InNlY25vIj48L3NwYW4+IDxzcGFuIGNsYXNzPSJjb250ZW50Ij5DbGFzcyBjb250YWlu
cyBwb2ludGVyIHRvIHNlbGY8L3NwYW4+PC9hPgogICAgICA8bGk+PGEgaHJlZj0iI25vbi10cml2
aWFsLXNhbXBsZS1saXN0Ij48c3BhbiBjbGFzcz0ic2Vjbm8iPjwvc3Bhbj4gPHNwYW4gY2xhc3M9
ImNvbnRlbnQiPkFsbG9jYXRlZCBtZW1vcnkgY29udGFpbnMgcG9pbnRlciB0byBzZWxmPC9zcGFu
PjwvYT4KICAgICAgPGxpPjxhIGhyZWY9IiNub24tdHJpdmlhbC1zYW1wbGUtb2Zmc2V0LXB0ciI+
PHNwYW4gY2xhc3M9InNlY25vIj48L3NwYW4+IDxzcGFuIGNsYXNzPSJjb250ZW50Ij5DbGFzcyBp
bnZhcmlhbnQgZGVwZW5kcyBvbiA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gaz50aGlzPC9j
LT48L2NvZGU+PC9zcGFuPjwvYT4KICAgICAgPGxpPjxhIGhyZWY9IiNub24tdHJpdmlhbC1zYW1w
bGUtcmVnaXN0cnkiPjxzcGFuIGNsYXNzPSJzZWNubyI+PC9zcGFuPiA8c3BhbiBjbGFzcz0iY29u
dGVudCI+UHJvZ3JhbSBpbnZhcmlhbnQgZGVwZW5kcyBvbiA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0
Ij48Yy0gaz50aGlzPC9jLT48L2NvZGU+PC9zcGFuPjwvYT4KICAgICA8L29sPgogICAgPGxpPjxh
IGhyZWY9IiNpbXBsZW1lbnRhdGlvbiI+PHNwYW4gY2xhc3M9InNlY25vIj48L3NwYW4+IDxzcGFu
IGNsYXNzPSJjb250ZW50Ij5BcHBlbmRpeCBEOiBJbXBsZW1lbnRhdGlvbiBhbmQgYmVuY2htYXJr
czwvc3Bhbj48L2E+CiAgICA8bGk+CiAgICAgPGEgaHJlZj0iI2luZGV4Ij48c3BhbiBjbGFzcz0i
c2Vjbm8iPjwvc3Bhbj4gPHNwYW4gY2xhc3M9ImNvbnRlbnQiPkluZGV4PC9zcGFuPjwvYT4KICAg
ICA8b2wgY2xhc3M9InRvYyI+CiAgICAgIDxsaT48YSBocmVmPSIjaW5kZXgtZGVmaW5lZC1oZXJl
Ij48c3BhbiBjbGFzcz0ic2Vjbm8iPjwvc3Bhbj4gPHNwYW4gY2xhc3M9ImNvbnRlbnQiPlRlcm1z
IGRlZmluZWQgYnkgdGhpcyBzcGVjaWZpY2F0aW9uPC9zcGFuPjwvYT4KICAgICA8L29sPgogICAg
PGxpPgogICAgIDxhIGhyZWY9IiNyZWZlcmVuY2VzIj48c3BhbiBjbGFzcz0ic2Vjbm8iPjwvc3Bh
bj4gPHNwYW4gY2xhc3M9ImNvbnRlbnQiPlJlZmVyZW5jZXM8L3NwYW4+PC9hPgogICAgIDxvbCBj
bGFzcz0idG9jIj4KICAgICAgPGxpPjxhIGhyZWY9IiNub3JtYXRpdmUiPjxzcGFuIGNsYXNzPSJz
ZWNubyI+PC9zcGFuPiA8c3BhbiBjbGFzcz0iY29udGVudCI+Tm9ybWF0aXZlIFJlZmVyZW5jZXM8
L3NwYW4+PC9hPgogICAgICA8bGk+PGEgaHJlZj0iI2luZm9ybWF0aXZlIj48c3BhbiBjbGFzcz0i
c2Vjbm8iPjwvc3Bhbj4gPHNwYW4gY2xhc3M9ImNvbnRlbnQiPkluZm9ybWF0aXZlIFJlZmVyZW5j
ZXM8L3NwYW4+PC9hPgogICAgIDwvb2w+CiAgICA8bGk+PGEgaHJlZj0iI2lzc3Vlcy1pbmRleCI+
PHNwYW4gY2xhc3M9InNlY25vIj48L3NwYW4+IDxzcGFuIGNsYXNzPSJjb250ZW50Ij5Jc3N1ZXMg
SW5kZXg8L3NwYW4+PC9hPgogICA8L29sPgogIDwvbmF2PgogIDxtYWluPgogICA8aDIgY2xhc3M9
ImhlYWRpbmcgc2V0dGxlZCIgZGF0YS1sZXZlbD0iMSIgaWQ9ImludHJvIj48c3BhbiBjbGFzcz0i
c2Vjbm8iPjEuIDwvc3Bhbj48c3BhbiBjbGFzcz0iY29udGVudCI+SW50cm9kdWN0aW9uIGFuZCBt
b3RpdmF0aW9uPC9zcGFuPjxhIGNsYXNzPSJzZWxmLWxpbmsiIGhyZWY9IiNpbnRybyI+PC9hPjwv
aDI+CiAgIDxwPklmIHlvdSBhcmUgcmVhZGluZyB0aGlzIHBhcGVyLCBhbmQgeW91IGhhdmUgbm90
IHlldCB3YXRjaGVkIEFydGh1cuKAmXMgc2Vzc2lvbiBmcm9tIEMrK05vdyAyMDE4Cm9uIDxhIGRh
dGEtbGluay10eXBlPSJiaWJsaW8iIGhyZWY9IiNiaWJsaW8tYmVzdCI+IlRoZSBCZXN0IFR5cGUg
VHJhaXRzIEMrKyBEb2VzbuKAmXQgSGF2ZSwiPC9hPiBpdCB3aWxsIGhlbHAgaWYgeW91IGltbWVk
aWF0ZWx5IHN0b3AgcmVhZGluZyBhbmQgPGEgaHJlZj0iaHR0cHM6Ly93d3cueW91dHViZS5jb20v
d2F0Y2g/dj1NV0JmbW1nOC1ZbyI+Z28gd2F0Y2g8L2E+IHRoZSBmaXJzdCAzMCBtaW51dGVzIG9m
IHRoYXQgdmlkZW8gYXQgMnggc3BlZWQgd2l0aCB0aGUgY2FwdGlvbnMgdHVybmVkIG9uLgpJdOKA
mXMgZ29pbmcgdG8gYmUgd29ydGggeW91ciAxNSBtaW51dGVzLiBJ4oCZbGwgd2FpdC48L3A+CiAg
IDxwPkluIHRoZSB2aWRlbywgYmVzaWRlcyBzaG93aW5nIGltcGxlbWVudGF0aW9uIHRlY2huaXF1
ZXMgYW5kIGJlbmNobWFyayByZXN1bHRzLCB3ZSBkZWZpbmVkIG91cgp0ZXJtcy4gVGhlc2UgdGVy
bXMgYXJlIHN1bW1hcml6ZWQgYnJpZWZseSBiZWxvdy48L3A+CiAgIDxwPkMrKzE3IGtub3dzIHRo
ZSB2ZXJicyAibW92ZSwiICJjb3B5LCIgImRlc3Ryb3ksIiBhbmQgInN3YXAsIiB3aGVyZSAic3dh
cCIgaXMgYSBoaWdoZXItbGV2ZWwgb3BlcmF0aW9uCmNvbXBvc2VkIG9mIHNldmVyYWwgbG93ZXIt
bGV2ZWwgb3BlcmF0aW9ucy4gVG8gdGhpcyBsaXN0IHdlIHByb3Bvc2UgdG8gYWRkIHRoZSB2ZXJi
ICJyZWxvY2F0ZSwiCndoaWNoIGlzIGEgaGlnaGVyLWxldmVsIG9wZXJhdGlvbiBjb21wb3NlZCBv
ZiBleGFjdGx5IHR3byBsb3dlci1sZXZlbCBvcGVyYXRpb25zLgpHaXZlbiBhbiBvYmplY3QgdHlw
ZSA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gbj5UPC9jLT48L2NvZGU+IGFuZCBtZW1vcnkg
YWRkcmVzc2VzIDxjb2RlIGNsYXNzPSJoaWdobGlnaHQiPjxjLSBuPnNyYzwvYy0+PC9jb2RlPiBh
bmQgPGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMtIG4+ZHN0PC9jLT48L2NvZGU+LAp0aGUgcGhy
YXNlICI8Yj48aT5yZWxvY2F0ZTwvaT48L2I+IGEgPGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMt
IG4+VDwvYy0+PC9jb2RlPiBmcm9tIDxjb2RlIGNsYXNzPSJoaWdobGlnaHQiPjxjLSBuPnNyYzwv
Yy0+PC9jb2RlPiB0byA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gbj5kc3Q8L2MtPjwvY29k
ZT4iIG1lYW5zIG5vIG1vcmUgYW5kIG5vCmxlc3MgdGhhbiAiPGVtPm1vdmUtY29uc3RydWN0PC9l
bT4gPGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMtIG4+ZHN0PC9jLT48L2NvZGU+IGZyb20gPGNv
ZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMtIG4+c3JjPC9jLT48L2NvZGU+LCBhbmQgdGhlbiBpbW1l
ZGlhdGVseSA8ZW0+ZGVzdHJveTwvZW0+IHRoZSBvYmplY3QgYXQgPGNvZGUgY2xhc3M9ImhpZ2hs
aWdodCI+PGMtIG4+c3JjPC9jLT48L2NvZGU+LiI8L3A+CiAgIDxwPkp1c3QgYXMgdGhlIHZlcmIg
InN3YXAiIHByb2R1Y2VzIHRoZSBhZGplY3RpdmUgInN3YXBwYWJsZSwiIHRoZSB2ZXJiICJyZWxv
Y2F0ZSIgcHJvZHVjZXMgdGhlIGFkamVjdGl2ZQoicmVsb2NhdGFibGUuIiBBbnkgdHlwZSB3aGlj
aCBpcyBib3RoIG1vdmUtY29uc3RydWN0aWJsZSBhbmQKZGVzdHJ1Y3RpYmxlIGlzIDxiPjxpPnJl
bG9jYXRhYmxlPC9pPjwvYj4uIFRoZSBub3Rpb24gY2FuIGJlIG1vZGlmaWVkIGJ5IGFkdmVyYnM6
IHdlIHNheSB0aGF0IGEgdHlwZQppcyA8Yj48aT5ub3Rocm93IHJlbG9jYXRhYmxlPC9pPjwvYj4g
aWYgaXRzIHJlbG9jYXRpb24gb3BlcmF0aW9uIGlzIG5vZXhjZXB0LCBhbmQgd2Ugc2F5IHRoYXQg
YSB0eXBlCmlzIDxiPjxpPjxhIGRhdGEtbGluay10eXBlPSJhYnN0cmFjdC1vcCIgaHJlZj0iI2Fi
c3RyYWN0LW9wZGVmLXRyaXZpYWxseS1yZWxvY2F0YWJsZSIgaWQ9InJlZi1mb3ItYWJzdHJhY3Qt
b3BkZWYtdHJpdmlhbGx5LXJlbG9jYXRhYmxlIj50cml2aWFsbHkgcmVsb2NhdGFibGU8L2E+PC9p
PjwvYj4gaWYgaXRzIHJlbG9jYXRpb24gb3BlcmF0aW9uIGlzIHRyaXZpYWwgKHdoaWNoLCBqdXN0
IGxpa2UgdHJpdmlhbCBtb3ZlLWNvbnN0cnVjdGlvbgphbmQgdHJpdmlhbCBjb3B5LWNvbnN0cnVj
dGlvbiwgbWVhbnMgInRoZSBvcGVyYXRpb24gaXMgdGFudGFtb3VudCB0byBhIDxjb2RlIGNsYXNz
PSJoaWdobGlnaHQiPjxjLSBuPm1lbWNweTwvYy0+PC9jb2RlPiIpLjwvcD4KICAgPHA+QWxtb3N0
IGFsbCByZWxvY2F0YWJsZSB0eXBlcyBhcmUgdHJpdmlhbGx5IHJlbG9jYXRhYmxlOiA8Y29kZSBj
bGFzcz0iaGlnaGxpZ2h0Ij48Yy0gbj5zdGQ8L2MtPjxjLSBvPjo6PC9jLT48Yy0gbj51bmlxdWVf
cHRyPC9jLT48Yy0gbz4mbHQ7PC9jLT48Yy0gYj5pbnQ8L2MtPjxjLSBvPj48L2MtPjwvY29kZT4s
IDxjb2RlIGNsYXNzPSJoaWdobGlnaHQiPjxjLSBuPnN0ZDwvYy0+PGMtIG8+Ojo8L2MtPjxjLSBu
PnZlY3RvcjwvYy0+PGMtIG8+Jmx0OzwvYy0+PGMtIGI+aW50PC9jLT48Yy0gbz4+PC9jLT48L2Nv
ZGU+LCA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gbj5zdGQ8L2MtPjxjLSBvPjo6PC9jLT48
Yy0gbj5zdHJpbmc8L2MtPjwvY29kZT4uIE5vbi10cml2aWFsbHkgcmVsb2NhdGFibGUgdHlwZXMK
ZXhpc3QgYnV0IGFyZSByYXJlOyBzZWUgPGEgaHJlZj0iI25vbi10cml2aWFsLXNhbXBsZXMiPkFw
cGVuZGl4IEM6IEV4YW1wbGVzIG9mIG5vbi10cml2aWFsbHkgcmVsb2NhdGFibGUgY2xhc3MgdHlw
ZXM8L2E+LjwvcD4KICAgPHA+QXJ0aHVyIGhhcyBlc3RhYmxpc2hlZCAoc2VlIDxhIGRhdGEtbGlu
ay10eXBlPSJiaWJsaW8iIGhyZWY9IiNiaWJsaW8tYmVuY2giPltCZW5jaF08L2E+KQp0aGF0IGlm
IHN0YW5kYXJkIGxpYnJhcnkgY29kZSBoYWQgYSByZWxpYWJsZSB3YXkgb2YgZGV0ZWN0aW5nICJ0
cml2aWFsIHJlbG9jYXRhYmlsaXR5LCIgd2UgY291bGQgb3B0aW1pemUKdGhhdCBjYXNlIGFuZCBn
ZXQgYSBzcGVlZCBib29zdCBvZiB1cCB0byAzeCBvbiByb3V0aW5lcyB0aGF0IHBlcmZvcm0gcmVh
bGxvY2F0aW9uLCBzdWNoIGFzPC9wPgo8cHJlIGNsYXNzPSJoaWdobGlnaHQiPiAgICA8Yy0gbj5z
dGQ8L2MtPjxjLSBvPjo6PC9jLT48Yy0gbj52ZWN0b3I8L2MtPjxjLSBvPiZsdDs8L2MtPjxjLSBu
PlI8L2MtPjxjLSBvPj46OjwvYy0+PGMtIG4+cmVzaXplPC9jLT4KICAgIDxjLSBuPnN0ZDwvYy0+
PGMtIG8+Ojo8L2MtPjxjLSBuPnZlY3RvcjwvYy0+PGMtIG8+Jmx0OzwvYy0+PGMtIG4+UjwvYy0+
PGMtIG8+Pjo6PC9jLT48Yy0gbj5yZXNlcnZlPC9jLT4KICAgIDxjLSBuPnN0ZDwvYy0+PGMtIG8+
Ojo8L2MtPjxjLSBuPnZlY3RvcjwvYy0+PGMtIG8+Jmx0OzwvYy0+PGMtIG4+UjwvYy0+PGMtIG8+
Pjo6PC9jLT48Yy0gbj5lbXBsYWNlX2JhY2s8L2MtPgogICAgPGMtIG4+c3RkPC9jLT48Yy0gbz46
OjwvYy0+PGMtIG4+dmVjdG9yPC9jLT48Yy0gbz4mbHQ7PC9jLT48Yy0gbj5SPC9jLT48Yy0gbz4+
Ojo8L2MtPjxjLSBuPnB1c2hfYmFjazwvYy0+CjwvcHJlPgogICA8cD5GdXJ0aGVybW9yZSwgd2Ug
Y2FuIHVzZSB0aGUgc2FtZSAidHJpdmlhbCByZWxvY2F0YWJpbGl0eSIgcHJvcGVydHkgdG8gc2hy
aW5rIHRoZSBjb2RlCmdlbmVyYXRlZCBieSBzbWFsbC1idWZmZXItb3B0aW1pemVkIChTQk8pIHR5
cGUtZXJhc2luZyB3cmFwcGVycyBzdWNoIGFzIDxjb2RlIGNsYXNzPSJoaWdobGlnaHQiPjxjLSBu
PnN0ZDwvYy0+PGMtIG8+Ojo8L2MtPjxjLSBuPmZ1bmN0aW9uPC9jLT48L2NvZGU+IGFuZCA8Y29k
ZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gbj5zdGQ8L2MtPjxjLSBvPjo6PC9jLT48Yy0gbj5hbnk8
L2MtPjwvY29kZT4uCkZvciB0aGVzZSB0eXBlcywgYSA8ZW0+bW92ZTwvZW0+IG9mIHRoZSB3cmFw
cGVyIG9iamVjdCBpcyBpbXBsZW1lbnRlZCBpbiB0ZXJtcyBvZiBhIDxlbT5yZWxvY2F0aW9uPC9l
bT4gb2YgdGhlIGNvbnRhaW5lZCBvYmplY3QuIChTZWUgZm9yIGV4YW1wbGUgPGEgZGF0YS1saW5r
LXR5cGU9ImJpYmxpbyIgaHJlZj0iI2JpYmxpby1saWJjeHhhbnkiPmxpYmMrKydzIHN0ZDo6YW55
PC9hPiwKd2hlcmUgdGhlIGZ1bmN0aW9uIHRoYXQgcGVyZm9ybXMgdGhlIHJlbG9jYXRpb24gb3Bl
cmF0aW9uIGlzIGNvbmZ1c2luZ2x5IG5hbWVkIDxjb2RlIGNsYXNzPSJoaWdobGlnaHQiPjxjLSBu
Pl9fbW92ZTwvYy0+PC9jb2RlPi4pCkluIGdlbmVyYWwsIHRoZSA8ZW0+cmVsb2NhdGU8L2VtPiBv
cGVyYXRpb24gZm9yIGEgY29udGFpbmVkIHR5cGUgPGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMt
IG4+QzwvYy0+PC9jb2RlPiBtdXN0IGJlIHVuaXF1ZWx5IGNvZGVnZW5uZWQgZm9yIGVhY2gKZGlm
ZmVyZW50IDxjb2RlIGNsYXNzPSJoaWdobGlnaHQiPjxjLSBuPkM8L2MtPjwvY29kZT4sIGxlYWRp
bmcgdG8gY29kZSBibG9hdC4gQnV0IGEgc2luZ2xlIGluc3RhbnRpYXRpb24gc3VmZmljZXMgdG8g
cmVsb2NhdGUgZXZlcnkgPGVtPnRyaXZpYWxseTwvZW0+IHJlbG9jYXRhYmxlIDxjb2RlIGNsYXNz
PSJoaWdobGlnaHQiPjxjLSBuPkM8L2MtPjwvY29kZT4gaW4gdGhlIHByb2dyYW0uIEEgc21hbGxl
ciBudW1iZXIgb2YgaW5zdGFudGlhdGlvbnMgbWVhbnMgZmFzdGVyIGNvbXBpbGUgdGltZXMsCmEg
c21hbGxlciB0ZXh0IHNlY3Rpb24sIGFuZCBwZXJoYXBzICJob3R0ZXIiIGNvZGUgKGJlY2F1c2Ug
YSByZWxhdGl2ZWx5IGhpZ2hlciBwcm9wb3J0aW9uIG9mIHlvdXIKY29kZSBub3cgZml0cyBpbiBp
Y2FjaGUpLjwvcD4KICAgPHA+SW4gYmV0d2VlbiB0aGVzZSB0d28gc2NlbmFyaW9zIGlzIHRoZSBt
b3ZlLWNvbnN0cnVjdG9yIG9mIDxjb2RlIGNsYXNzPSJoaWdobGlnaHQiPjxjLSBuPmZpeGVkX2Nh
cGFjaXR5X3ZlY3RvcjwvYy0+PGMtIG8+Jmx0OzwvYy0+PGMtIG4+UjwvYy0+PGMtIHA+LDwvYy0+
PGMtIG4+TjwvYy0+PGMtIG8+PjwvYy0+PC9jb2RlPiwKd2hpY2ggY2FuIGJlIGltcGxlbWVudGVk
IGFzIGFuIGVsZW1lbnQtYnktZWxlbWVudCA8ZW0+bW92ZTwvZW0+IChsZWF2aW5nIHRoZSBzb3Vy
Y2UgdmVjdG9y4oCZcyBlbGVtZW50cyBpbiB0aGVpcgptb3ZlZC1mcm9tIHN0YXRlKSwgb3IgY2Fu
IGJlIGltcGxlbWVudGVkIG1vcmUgZWZmaWNpZW50bHkgYXMgYW4gZWxlbWVudC1ieS1lbGVtZW50
IDxlbT5yZWxvY2F0ZTwvZW0+IChsZWF2aW5nCnRoZSBzb3VyY2UgdmVjdG9yIGVtcHR5KS48L3A+
CiAgIDxwIGNsYXNzPSJub3RlIiByb2xlPSJub3RlIj48c3Bhbj5Ob3RlOjwvc3Bhbj4gVGhlIG5h
bWUgPGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMtIG4+Zml4ZWRfY2FwYWNpdHlfdmVjdG9yPC9j
LT48L2NvZGU+IGlzIG15IHByZWZlcnJlZCBuYW1lIGZvciB0aGUgdHlwZQp0aGF0IEJvb3N0LkNv
bnRhaW5lciBjYWxscyA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gbj5zdGF0aWNfdmVjdG9y
PC9jLT48L2NvZGU+LiA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gbj5ib29zdDwvYy0+PGMt
IG8+Ojo8L2MtPjxjLSBuPmNvbnRhaW5lcjwvYy0+PGMtIG8+Ojo8L2MtPjxjLSBuPnN0YXRpY192
ZWN0b3I8L2MtPjxjLSBvPiZsdDs8L2MtPjxjLSBuPlI8L2MtPjxjLSBwPiw8L2MtPjxjLSBuPk48
L2MtPjxjLSBvPj48L2MtPjwvY29kZT4gaW1wbGVtZW50cyB0aGUKbGVzcyBlZmZpY2llbnQgZWxl
bWVudC1ieS1lbGVtZW50LW1vdmUgc3RyYXRlZ3kuIE1vdmluZy1vdXQtb2YgYSA8Y29kZSBjbGFz
cz0iaGlnaGxpZ2h0Ij48Yy0gbj5ib29zdDwvYy0+PGMtIG8+Ojo8L2MtPjxjLSBuPmNvbnRhaW5l
cjwvYy0+PGMtIG8+Ojo8L2MtPjxjLSBuPnN0YXRpY192ZWN0b3I8L2MtPjwvY29kZT4gd2lsbCBu
b3QgbWFrZSB0aGUgc291cmNlIHZlY3RvciA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gbj5l
bXB0eTwvYy0+PGMtIHA+KCk8L2MtPjwvY29kZT4uPC9wPgogICA8cD5Tb21lIGNvbmN1cnJlbnQg
ZGF0YSBzdHJ1Y3R1cmVzIG1pZ2h0IHJlYXNvbmFibHkgYXNzZXJ0IHRoZSB0cml2aWFsIHJlbG9j
YXRhYmlsaXR5IG9mCnRoZWlyIGVsZW1lbnRzLCBqdXN0IGFzIHRoZXkgc29tZXRpbWVzIGFzc2Vy
dCB0aGUgc3Ryb25nZXIgcHJvcGVydHkgb2YgdHJpdmlhbCA8ZW0+Y29weWFiaWxpdHk8L2VtPiB0
b2RheS48L3A+CiAgIDxoMyBjbGFzcz0iaGVhZGluZyBzZXR0bGVkIiBkYXRhLWxldmVsPSIxLjEi
IGlkPSJkb2luZy1pdC13cm9uZyI+PHNwYW4gY2xhc3M9InNlY25vIj4xLjEuIDwvc3Bhbj48c3Bh
biBjbGFzcz0iY29udGVudCI+UmVhbC13b3JsZCBjb2RlIGFscmVhZHkgZG9lcyBpdCB3cm9uZzwv
c3Bhbj48YSBjbGFzcz0ic2VsZi1saW5rIiBocmVmPSIjZG9pbmctaXQtd3JvbmciPjwvYT48L2gz
PgogICA8cD5GaW5hbGx5LCBhbmQgaW1wb3J0YW50bHksIG1hbnkgcmVhbC13b3JsZCBjb2RlYmFz
ZXMgY29udGFpbiB0ZW1wbGF0ZXMgd2hpY2ggcmVxdWlyZQp0cml2aWFsIHJlbG9jYXRhYmlsaXR5
IG9mIHRoZWlyIHRlbXBsYXRlIHBhcmFtZXRlcnMsIGJ1dCBjdXJyZW50bHkgaGF2ZSBubyB3YXkg
dG8gPGVtPmNoZWNrPC9lbT4gdHJpdmlhbCByZWxvY2F0YWJpbGl0eS4gRm9yIGV4YW1wbGUsIDxh
IGRhdGEtbGluay10eXBlPSJiaWJsaW8iIGhyZWY9IiNiaWJsaW8tZm9sbHkiPltGb2xseV08L2E+
IHJlcXVpcmVzIHRoZSBwcm9ncmFtbWVyIHRvIHdhcnJhbnQgdGhlIHRyaXZpYWwKcmVsb2NhdGFi
aWxpdHkgb2YgYW55IHR5cGUgc3RvcmVkIGluIGEgPGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMt
IG4+Zm9sbHk8L2MtPjxjLSBvPjo6PC9jLT48Yy0gbj5mYnZlY3RvcjwvYy0+PC9jb2RlPi48L3A+
CjxwcmUgY2xhc3M9Imxhbmd1YWdlLWMrKyBoaWdobGlnaHQiPiAgICA8Yy0gbj5jbGFzczwvYy0+
IDxjLSBuPldpZGdldDwvYy0+IDxjLSBwPns8L2MtPgogICAgICAgIDxjLSBuPnN0ZDwvYy0+PGMt
IG8+Ojo8L2MtPjxjLSBuPnZlY3RvcjwvYy0+PGMtIG8+Jmx0OzwvYy0+PGMtIGI+aW50PC9jLT48
Yy0gbz4+PC9jLT4gPGMtIG4+bHN0XzwvYy0+PGMtIHA+OzwvYy0+CiAgICA8Yy0gcD59OzwvYy0+
CgogICAgPGMtIG4+Zm9sbHk8L2MtPjxjLSBvPjo6PC9jLT48Yy0gbj5mYnZlY3RvcjwvYy0+PGMt
IG8+Jmx0OzwvYy0+PGMtIG4+V2lkZ2V0PC9jLT48Yy0gbz4+PC9jLT4gPGMtIG4+dmVjPC9jLT48
Yy0gcD47PC9jLT4gIDxjLSBjMT4vLyBGQUlMUyBBVCBDT01QSUxFIFRJTUUgZm9yIGxhY2sgb2Yg
d2FycmFudDwvYy0+CjwvcHJlPgogICA8cD5CdXQgdGhpcyBtZXJlbHkgZW5jb3VyYWdlcyB0aGUg
cHJvZ3JhbW1lciB0byBhZGQgdGhlIHdhcnJhbnQgYW5kIGNvbnRpbnVlLiBBbiBpbmNvcnJlY3QK
d2FycmFudCB3aWxsIGJlIGRpc2NvdmVyZWQgb25seSBhdCBydW50aW1lLCB2aWEgdW5kZWZpbmVk
IGJlaGF2aW9yLiAoU2VlIDxhIGhyZWY9IiNub24tdHJpdmlhbC1zYW1wbGUtbGlzdCI+QWxsb2Nh
dGVkIG1lbW9yeSBjb250YWlucyBwb2ludGVyIHRvIHNlbGY8L2E+IGFuZCA8YSBkYXRhLWxpbmst
dHlwZT0iYmlibGlvIiBocmVmPSIjYmlibGlvLWZvbGx5aXNzdWU4ODkiPltGb2xseUlzc3VlODg5
XTwvYT4uKTwvcD4KPHByZSBjbGFzcz0ibGFuZ3VhZ2UtYysrIGhpZ2hsaWdodCI+ICAgIDxjLSBu
PmNsYXNzPC9jLT4gPGMtIG4+R2FkZ2V0PC9jLT4gPGMtIHA+ezwvYy0+CiAgICAgICAgPGMtIG4+
c3RkPC9jLT48Yy0gbz46OjwvYy0+PGMtIG4+bGlzdDwvYy0+PGMtIG8+Jmx0OzwvYy0+PGMtIGI+
aW50PC9jLT48Yy0gbz4+PC9jLT4gPGMtIG4+bHN0XzwvYy0+PGMtIHA+OzwvYy0+CiAgICA8Yy0g
cD59OzwvYy0+CiAgICA8Yy0gYzE+Ly8gc2lnaCwgYWRkIHRoZSB3YXJyYW50IG9uIGF1dG9waWxv
dDwvYy0+CiAgICA8Yy0gbj50ZW1wbGF0ZTwvYy0+PGMtIG8+Jmx0Oz48L2MtPiA8Yy0gaz5zdHJ1
Y3Q8L2MtPiA8Yy0gbj5mb2xseTwvYy0+PGMtIG8+Ojo8L2MtPjxjLSBuPklzUmVsb2NhdGFibGU8
L2MtPjxjLSBvPiZsdDs8L2MtPjxjLSBuPkdhZGdldDwvYy0+PGMtIG8+PjwvYy0+IDxjLSBvPjo8
L2MtPiA8Yy0gbj5zdGQ8L2MtPjxjLSBvPjo6PC9jLT48Yy0gbj50cnVlX3R5cGU8L2MtPiA8Yy0g
cD57fTs8L2MtPgoKICAgIDxjLSBuPmZvbGx5PC9jLT48Yy0gbz46OjwvYy0+PGMtIG4+ZmJ2ZWN0
b3I8L2MtPjxjLSBvPiZsdDs8L2MtPjxjLSBuPkdhZGdldDwvYy0+PGMtIG8+PjwvYy0+IDxjLSBu
PnZlYzwvYy0+PGMtIHA+OzwvYy0+ICA8Yy0gYzE+Ly8gQ1JBU0hFUyBBVCBSVU5USU1FIGR1ZSB0
byBmcmF1ZHVsZW50IHdhcnJhbnQ8L2MtPgo8L3ByZT4KICAgPHA+SWYgdGhpcyBwcm9wb3NhbCBp
cyBhZG9wdGVkLCB0aGVuIEZvbGx5IGNhbiBzdGFydCB1c2luZyA8Y29kZSBjbGFzcz0iaGlnaGxp
Z2h0Ij48Yy0gaz5zdGF0aWNfYXNzZXJ0PC9jLT48Yy0gcD4oPC9jLT48Yy0gbj5zdGQ8L2MtPjxj
LSBvPjo6PC9jLT48Yy0gbj5pc190cml2aWFsbHlfcmVsb2NhdGFibGVfdjwvYy0+PGMtIG8+Jmx0
OzwvYy0+PGMtIG4+VDwvYy0+PGMtIG8+PjwvYy0+PGMtIHA+KTwvYy0+PC9jb2RlPiBpbiB0aGUg
aW1wbGVtZW50YXRpb24gb2YgPGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMtIG4+ZmJ2ZWN0b3I8
L2MtPjwvY29kZT4sIGFuZCB0aGUgcHJvZ3JhbW1lciBjYW4gc3RvcCB3cml0aW5nIGV4cGxpY2l0
IHdhcnJhbnRzIGluIHRoZSB2YXN0IG1ham9yaXR5Cm9mIGNhc2VzLCA8ZW0+YW5kPC9lbT4gdGhl
IHByb2dyYW1tZXIgY2FuIHN0YXJ0IHdyaXRpbmcgYXNzZXJ0aW9ucyBvZiBjb3JyZWN0bmVzcywg
d2hpY2ggYWlkcyBtYWludGFpbmFiaWxpdHkgYW5kCmNhbiBldmVuIGZpbmQgcmVhbCBidWdzLiBF
eGFtcGxlOjwvcD4KPHByZSBjbGFzcz0ibGFuZ3VhZ2UtYysrIGhpZ2hsaWdodCI+ICAgIDxjLSBu
PmNsYXNzPC9jLT4gPGMtIG4+V2lkZ2V0PC9jLT4gPGMtIHA+ezwvYy0+CiAgICAgICAgPGMtIG4+
c3RkPC9jLT48Yy0gbz46OjwvYy0+PGMtIG4+dmVjdG9yPC9jLT48Yy0gbz4mbHQ7PC9jLT48Yy0g
Yj5pbnQ8L2MtPjxjLSBvPj48L2MtPiA8Yy0gbj5sc3RfPC9jLT48Yy0gcD47PC9jLT4KICAgIDxj
LSBwPn07PC9jLT4KICAgIDxjLSBuPnN0YXRpY19hc3NlcnQ8L2MtPjxjLSBwPig8L2MtPjxjLSBu
PnN0ZDwvYy0+PGMtIG8+Ojo8L2MtPjxjLSBuPmlzX3RyaXZpYWxseV9yZWxvY2F0YWJsZV92PC9j
LT48Yy0gbz4mbHQ7PC9jLT48Yy0gbj5XaWRnZXQ8L2MtPjxjLSBvPj48L2MtPjxjLSBwPik7PC9j
LT4gIDxjLSBjMT4vLyBjb3JyZWN0bHkgU1VDQ0VFRFM8L2MtPgoKICAgIDxjLSBuPmNsYXNzPC9j
LT4gPGMtIG4+R2FkZ2V0PC9jLT4gPGMtIHA+ezwvYy0+CiAgICAgICAgPGMtIG4+c3RkPC9jLT48
Yy0gbz46OjwvYy0+PGMtIG4+bGlzdDwvYy0+PGMtIG8+Jmx0OzwvYy0+PGMtIGI+aW50PC9jLT48
Yy0gbz4+PC9jLT4gPGMtIG4+bHN0XzwvYy0+PGMtIHA+OzwvYy0+CiAgICA8Yy0gcD59OzwvYy0+
CiAgICA8Yy0gbj5zdGF0aWNfYXNzZXJ0PC9jLT48Yy0gcD4oPC9jLT48Yy0gbj5zdGQ8L2MtPjxj
LSBvPjo6PC9jLT48Yy0gbj5pc190cml2aWFsbHlfcmVsb2NhdGFibGVfdjwvYy0+PGMtIG8+Jmx0
OzwvYy0+PGMtIG4+R2FkZ2V0PC9jLT48Yy0gbz4+PC9jLT48Yy0gcD4pOzwvYy0+ICA8Yy0gYzE+
Ly8gY29ycmVjdGx5IEZBSUxTPC9jLT4KPC9wcmU+CiAgIDxwPlRoZSBpbXByb3ZlbWVudCBpbiB1
c2VyIGV4cGVyaWVuY2UgZm9yIHJlYWwtd29ybGQgY29kZWJhc2VzIChzdWNoIGFzIDxhIGRhdGEt
bGluay10eXBlPSJiaWJsaW8iIGhyZWY9IiNiaWJsaW8tZm9sbHkiPltGb2xseV08L2E+LCA8YSBk
YXRhLWxpbmstdHlwZT0iYmlibGlvIiBocmVmPSIjYmlibGlvLWVhc3RsIj5bRUFTVExdPC9hPiwg
QkRFLCBRdCwgZXRjLikKaXMgdGhlIG1vc3QgaW1wb3J0YW50IGJlbmVmaXQgdG8gYmUgZ2FpbmVk
IGJ5IHRoaXMgcHJvcG9zYWwuPC9wPgogICA8aDIgY2xhc3M9ImhlYWRpbmcgc2V0dGxlZCIgZGF0
YS1sZXZlbD0iMiIgaWQ9ImRlc2lnbi1nb2FscyI+PHNwYW4gY2xhc3M9InNlY25vIj4yLiA8L3Nw
YW4+PHNwYW4gY2xhc3M9ImNvbnRlbnQiPkRlc2lnbiBnb2Fsczwvc3Bhbj48YSBjbGFzcz0ic2Vs
Zi1saW5rIiBocmVmPSIjZGVzaWduLWdvYWxzIj48L2E+PC9oMj4KICAgPHA+RXZlcnkgQysrIHR5
cGUgYWxyZWFkeSA8ZW0+aXM8L2VtPiBvciA8ZW0+aXMgbm90PC9lbT4gdHJpdmlhbGx5IHJlbG9j
YXRhYmxlLiBUaGlzIHByb3Bvc2FsIGlzIG5vdCBhYm91dAoibWFraW5nIG1vcmUgdHlwZXMgdHJp
dmlhbGx5IHJlbG9jYXRhYmxlLiI8L3A+CiAgIDxwPlRoZSBvcHRpbWl6YXRpb25zIGRpc2N1c3Nl
ZCBhYm92ZSBhcmUgcHVyZWx5IGluIHRoZSBkb21haW4gb2YgbGlicmFyeSB2ZW5kb3JzLiBJZiB5
b3XigJlyZSB3cml0aW5nCmEgdmVjdG9yLCBhbmQgeW91IGRldGVjdCB0aGF0IHlvdXIgZWxlbWVu
dCB0eXBlIDxjb2RlIGNsYXNzPSJoaWdobGlnaHQiPjxjLSBuPlQ8L2MtPjwvY29kZT4gaXMgdHJp
dmlhbGx5IHJlbG9jYXRhYmxlLCB0aGVuCndoZXRoZXIgeW91IGRvIGFueSBzcGVjaWFsIG9wdGlt
aXphdGlvbiBpbiB0aGF0IGNhc2UgaXMgbWVyZWx5IGEgUXVhbGl0eSBvZiBJbXBsZW1lbnRhdGlv
biAoUW9JKSBpc3N1ZS4KVGhpcyBwcm9wb3NhbCBpcyBub3QgYWJvdXQgInN0YW5kYXJkaXppbmcg
Y2VydGFpbiBsaWJyYXJ5IG9wdGltaXphdGlvbnMuIjwvcD4KICAgPHA+V2hhdCBDKysgbGFja3Mg
aXMgYSBzdGFuZGFyZCB3YXkgZm9yIGxpYnJhcnkgdmVuZG9ycyB0byA8ZW0+ZGV0ZWN0PC9lbT4g
dGhlIChleGlzdGluZykgdHJpdmlhbCByZWxvY2F0YWJpbGl0eQpvZiBhIHR5cGUgPGNvZGUgY2xh
c3M9ImhpZ2hsaWdodCI+PGMtIG4+VDwvYy0+PC9jb2RlPiwgc28gdGhhdCB0aGV5IGNhbiByZWxp
YWJseSBhcHBseSB0aGVpciAoZXhpc3RpbmcpIG9wdGltaXphdGlvbnMuCkFsbCB3ZSByZWFsbHkg
bmVlZCBpcyB0byBhZGQgPGVtPmRldGVjdGlvbjwvZW0+LCBhbmQgdGhlbiBhbGwgdGhlIG9wdGlt
aXphdGlvbnMgZGVzY3JpYmVkIGFib3ZlIHdpbGwgbmF0dXJhbGx5CmVtZXJnZSB3aXRob3V0IGFu
eSBmdXJ0aGVyIHNwZWNpYWwgZWZmb3J0IGJ5IFdHMjEuPC9wPgogICA8cD5MaWJyYXJ5IHZlbmRv
cnMgdG9kYXkgb2Z0ZW4gKGNvcnJlY3RseSkgaW5mZXIgdGhhdCBhbnkgPGVtPnRyaXZpYWxseSBj
b3B5YWJsZTwvZW0+IHR5cGUgaXMgdHJpdmlhbGx5IHJlbG9jYXRhYmxlLgpIb3dldmVyLCB3ZSB3
b3VsZCBsaWtlIHRvIGRvIGV2ZW4gYmV0dGVyLiBUaGUgZm9sbG93aW5nIHRocmVlIHVzZS1jYXNl
cyBhcmUgaW1wb3J0YW50IGZvciBpbXByb3ZpbmcgdGhlCnBlcmZvcm1hbmNlIG9mIHJlYWwgcHJv
Z3JhbXM6PC9wPgogICA8aDMgY2xhc3M9ImhlYWRpbmcgc2V0dGxlZCIgZGF0YS1sZXZlbD0iMi4x
IiBpZD0idXNlMSI+PHNwYW4gY2xhc3M9InNlY25vIj4yLjEuIDwvc3Bhbj48c3BhbiBjbGFzcz0i
Y29udGVudCI+U3RhbmRhcmQgbGlicmFyeSB0eXBlcyBzdWNoIGFzIDxjb2RlIGNsYXNzPSJoaWdo
bGlnaHQiPjxjLSBuPnN0ZDwvYy0+PGMtIG8+Ojo8L2MtPjxjLSBuPnN0cmluZzwvYy0+PC9jb2Rl
Pjwvc3Bhbj48YSBjbGFzcz0ic2VsZi1saW5rIiBocmVmPSIjdXNlMSI+PC9hPjwvaDM+CiAgIDxw
PkluIG9yZGVyIHRvIG9wdGltaXplIDxjb2RlIGNsYXNzPSJoaWdobGlnaHQiPjxjLSBuPnN0ZDwv
Yy0+PGMtIG8+Ojo8L2MtPjxjLSBuPnZlY3RvcjwvYy0+PGMtIG8+Jmx0OzwvYy0+PGMtIG4+c3Rk
PC9jLT48Yy0gbz46OjwvYy0+PGMtIG4+c3RyaW5nPC9jLT48Yy0gbz4+Ojo8L2MtPjxjLSBuPnJl
c2l6ZTwvYy0+PC9jb2RlPiwgd2UgbXVzdCBjb21lIHVwIHdpdGggYSB3YXkgdG8gYWNoaWV2ZTwv
cD4KPHByZSBjbGFzcz0ibGFuZ3VhZ2UtYysrIGhpZ2hsaWdodCI+ICAgIDxjLSBjcD4jaW5jbHVk
ZTwvYy0+ICZsdDtzdHJpbmc+CiAgICA8Yy0gbj5zdGF0aWNfYXNzZXJ0PC9jLT48Yy0gcD4oPC9j
LT48Yy0gbj5pc190cml2aWFsbHlfcmVsb2NhdGFibGU8L2MtPjxjLSBvPiZsdDs8L2MtPiA8Yy0g
bj5zdGQ8L2MtPjxjLSBvPjo6PC9jLT48Yy0gbj5zdHJpbmc8L2MtPiA8Yy0gbz4+Ojo8L2MtPjxj
LSBuPnZhbHVlPC9jLT48Yy0gcD4pOzwvYy0+CjwvcHJlPgogICBUaGlzIGNvdWxkIGJlIGRvbmUg
dW5pbGF0ZXJhbGx5IGJ5IHRoZSBsaWJyYXJ5IHZlbmRvciwgdmlhIGEgbm9uLXN0YW5kYXJkIGF0
dHJpYnV0ZQooPGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMtIHA+W1s8L2MtPjxjLSBuPmNsYW5n
PC9jLT48Yy0gbz46OjwvYy0+PGMtIG4+dHJpdmlhbGx5X3JlbG9jYXRhYmxlPC9jLT48Yy0gcD5d
XTwvYy0+PC9jb2RlPiksIG9yIGEgbWVtYmVyIHR5cGVkZWYgd2l0aCBhIHJlc2VydmVkIG5hbWUK
KDxjb2RlIGNsYXNzPSJoaWdobGlnaHQiPjxjLSBrPnVzaW5nPC9jLT4gPGMtIG4+X19pc190cml2
X3JlbG9jYXRhYmxlPC9jLT4gPGMtIG8+PTwvYy0+IDxjLSBiPnZvaWQ8L2MtPjwvY29kZT4pLCBv
ciBzaW1wbHkgYSB2ZW5kb3ItcHJvdmlkZWQgc3BlY2lhbGl6YXRpb24Kb2YgPGNvZGUgY2xhc3M9
ImhpZ2hsaWdodCI+PGMtIG4+c3RkPC9jLT48Yy0gbz46OjwvYy0+PGMtIG4+aXNfdHJpdmlhbGx5
X3JlbG9jYXRhYmxlPC9jLT48Yy0gbz4mbHQ7PC9jLT48Yy0gbj5zdGQ8L2MtPjxjLSBvPjo6PC9j
LT48Yy0gbj5zdHJpbmc8L2MtPjxjLSBvPj48L2MtPjwvY29kZT4uIAogICA8cD5UaGF0IGlzLCB3
ZSBjYW4gaW4gcHJpbmNpcGxlIHNvbHZlIMKnMi4xIHdoaWxlIGNvbmZpbmluZyBvdXIgIm1hZ2lj
IiB0byB0aGUgaGVhZGVycwpvZiB0aGUgaW1wbGVtZW50YXRpb24gaXRzZWxmLiBUaGUgcHJvZ3Jh
bW1lciBkb2VzbuKAmXQgaGF2ZSB0byBsZWFybiBhbnl0aGluZyBuZXcsIHNvIGZhci48L3A+CiAg
IDxoMyBjbGFzcz0iaGVhZGluZyBzZXR0bGVkIiBkYXRhLWxldmVsPSIyLjIiIGlkPSJ1c2UyIj48
c3BhbiBjbGFzcz0ic2Vjbm8iPjIuMi4gPC9zcGFuPjxzcGFuIGNsYXNzPSJjb250ZW50Ij5Qcm9n
cmFtLWRlZmluZWQgdHlwZXMgdGhhdCBmb2xsb3cgdGhlIFJ1bGUgb2YgWmVybzwvc3Bhbj48YSBj
bGFzcz0ic2VsZi1saW5rIiBocmVmPSIjdXNlMiI+PC9hPjwvaDM+CiAgIDxwIGNsYXNzPSJub3Rl
IiByb2xlPSJub3RlIj48c3Bhbj5Ob3RlOjwvc3Bhbj4gVGhlIHRlcm0gInByb2dyYW0tZGVmaW5l
ZCB0eXBlcyIgaXMgZGVmaW5lZCBpbiA8YSBkYXRhLWxpbmstdHlwZT0iYmlibGlvIiBocmVmPSIj
YmlibGlvLWx3ZzIxMzkiPltMV0cyMTM5XTwvYT4gYW5kIDxhIGRhdGEtbGluay10eXBlPSJiaWJs
aW8iIGhyZWY9IiNiaWJsaW8tbHdnMzExOSI+W0xXRzMxMTldPC9hPi48L3A+CiAgIDxwPkluIG9y
ZGVyIHRvIG9wdGltaXplIHRoZSBTQk8gPGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMtIG4+c3Rk
PC9jLT48Yy0gbz46OjwvYy0+PGMtIG4+ZnVuY3Rpb248L2MtPjwvY29kZT4gaW4gYW55IG1lYW5p
bmdmdWwgc2Vuc2UsCndlIG11c3QgY29tZSB1cCB3aXRoIGEgd2F5IHRvIGFjaGlldmU8L3A+Cjxw
cmUgY2xhc3M9Imxhbmd1YWdlLWMrKyBoaWdobGlnaHQiPiAgICA8Yy0gY3A+I2luY2x1ZGU8L2Mt
PiAmbHQ7c3RyaW5nPgogICAgPGMtIGs+YXV0bzwvYy0+IDxjLSBuPmxhbTI8L2MtPiA8Yy0gbz49
PC9jLT4gPGMtIHA+WzwvYy0+PGMtIG4+eDwvYy0+PGMtIG8+PTwvYy0+PGMtIG4+c3RkPC9jLT48
Yy0gbz46OjwvYy0+PGMtIG4+c3RyaW5nPC9jLT48Yy0gcD4oPC9jLT48Yy0gcz4iaGVsbG8iPC9j
LT48Yy0gcD4pXXt9OzwvYy0+CiAgICA8Yy0gbj5zdGF0aWNfYXNzZXJ0PC9jLT48Yy0gcD4oPC9j
LT48Yy0gbj5pc190cml2aWFsbHlfcmVsb2NhdGFibGU8L2MtPjxjLSBvPiZsdDs8L2MtPiA8Yy0g
bj5kZWNsdHlwZTwvYy0+PGMtIHA+KDwvYy0+PGMtIG4+bGFtMjwvYy0+PGMtIHA+KTwvYy0+IDxj
LSBvPj46OjwvYy0+PGMtIG4+dmFsdWU8L2MtPjxjLSBwPik7PC9jLT4KPC9wcmU+CiAgIExhbWJk
YXMgYXJlIG5vdCBhIHNwZWNpYWwgY2FzZSBpbiBDKys7IHRoZXkgYXJlIHNpbXBseSBjbGFzcyB0
eXBlcyB3aXRoIGFsbCB0aGVpciBzcGVjaWFsIG1lbWJlcnMgZGVmYXVsdGVkLgpUaGVyZWZvcmUs
IHByZXN1bWFibHkgd2Ugc2hvdWxkIGJlIGFibGUgdG8gdXNlIHRoZSBzYW1lIHNvbHV0aW9uIGZv
ciBsYW1iZGFzIGFzIGZvciAKPHByZSBjbGFzcz0ibGFuZ3VhZ2UtYysrIGhpZ2hsaWdodCI+ICAg
IDxjLSBjcD4jaW5jbHVkZTwvYy0+ICZsdDtzdHJpbmc+CiAgICA8Yy0gaz5zdHJ1Y3Q8L2MtPiA8
Yy0gbj5BPC9jLT4gPGMtIHA+ezwvYy0+CiAgICAgICAgPGMtIG4+c3RkPC9jLT48Yy0gbz46Ojwv
Yy0+PGMtIG4+c3RyaW5nPC9jLT4gPGMtIG4+czwvYy0+PGMtIHA+OzwvYy0+CiAgICA8Yy0gcD59
OzwvYy0+CiAgICA8Yy0gbj5zdGF0aWNfYXNzZXJ0PC9jLT48Yy0gcD4oPC9jLT48Yy0gbj5pc190
cml2aWFsbHlfcmVsb2NhdGFibGU8L2MtPjxjLSBvPiZsdDs8L2MtPiA8Yy0gbj5BPC9jLT4gPGMt
IG8+Pjo6PC9jLT48Yy0gbj52YWx1ZTwvYy0+PGMtIHA+KTs8L2MtPgo8L3ByZT4KICAgSGVyZSA8
Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gaz5zdHJ1Y3Q8L2MtPiA8Yy0gbj5BPC9jLT48L2Nv
ZGU+IGZvbGxvd3MgdGhlIFJ1bGUgb2YgWmVybzogaXRzIG1vdmUtY29uc3RydWN0b3IgYW5kIGRl
c3RydWN0b3IgYXJlIGJvdGggZGVmYXVsdGVkLgpJZiB0aGV5IHdlcmUgYWxzbyA8ZW0+dHJpdmlh
bDwvZW0+LCB0aGVuIHdl4oCZZCBiZSBkb25lLiBJbiBmYWN0IHRoZXkgYXJlIG5vbi10cml2aWFs
OyBhbmQgeWV0LCBiZWNhdXNlIHRoZSB0eXBl4oCZcwpiYXNlcyBhbmQgbWVtYmVycyBhcmUgYWxs
IG9mIHRyaXZpYWxseSByZWxvY2F0YWJsZSB0eXBlcywgdGhlIHR5cGUgYXMgYSB3aG9sZSA8ZW0+
aXM8L2VtPiB0cml2aWFsbHkgcmVsb2NhdGFibGUuIAogICA8cD7CpzIuMiBhc2tzIHNwZWNpZmlj
YWxseSB0aGF0IHdlIG1ha2UgdGhlIDxjb2RlIGNsYXNzPSJoaWdobGlnaHQiPjxjLSBrPnN0YXRp
Y19hc3NlcnQ8L2MtPjwvY29kZT4gc3VjY2VlZCB3aXRob3V0IGJyZWFraW5nIHRoZSAiUnVsZSBv
ZiBaZXJvLiIKV2UgZG8gbm90IHdhbnQgdG8gcmVxdWlyZSB0aGUgcHJvZ3JhbW1lciB0byBhbm5v
dGF0ZSA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gaz5zdHJ1Y3Q8L2MtPiA8Yy0gbj5BPC9j
LT48L2NvZGU+IHdpdGggYSBzcGVjaWFsIGF0dHJpYnV0ZSwgb3IKYSBzcGVjaWFsIG1lbWJlciB0
eXBlZGVmLCBvciBhbnl0aGluZyBsaWtlIHRoYXQuIFdlIHdhbnQgaXQgdG8gSnVzdCBXb3JrLiBF
dmVuIGZvciBsYW1iZGEgdHlwZXMuClRoaXMgaXMgYSBtdWNoIGhhcmRlciBwcm9ibGVtIHRoYW4g
wqcyLjE7IGl0IHJlcXVpcmVzIHN0YW5kYXJkIHN1cHBvcnQgaW4gdGhlIGNvcmUgbGFuZ3VhZ2Uu
CkJ1dCBpdCBzdGlsbCBkb2VzIG5vdCByZXF1aXJlIGFueSBuZXcgPGVtPnN5bnRheDwvZW0+Ljwv
cD4KICAgPGgzIGNsYXNzPSJoZWFkaW5nIHNldHRsZWQiIGRhdGEtbGV2ZWw9IjIuMyIgaWQ9InVz
ZTMiPjxzcGFuIGNsYXNzPSJzZWNubyI+Mi4zLiA8L3NwYW4+PHNwYW4gY2xhc3M9ImNvbnRlbnQi
PlByb2dyYW0tZGVmaW5lZCB0eXBlcyB3aXRoIG5vbi1kZWZhdWx0ZWQgc3BlY2lhbCBtZW1iZXJz
PC9zcGFuPjxhIGNsYXNzPSJzZWxmLWxpbmsiIGhyZWY9IiN1c2UzIj48L2E+PC9oMz4KICAgPHA+
SW4gb3JkZXIgdG8gb3B0aW1pemUgPGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMtIG4+c3RkPC9j
LT48Yy0gbz46OjwvYy0+PGMtIG4+dmVjdG9yPC9jLT48Yy0gbz4mbHQ7PC9jLT48Yy0gbj5ib29z
dDwvYy0+PGMtIG8+Ojo8L2MtPjxjLSBuPnNoYXJlZF9wdHI8L2MtPjxjLSBvPiZsdDs8L2MtPjxj
LSBuPlQ8L2MtPjxjLSBvPj4+Ojo8L2MtPjxjLSBuPnJlc2l6ZTwvYy0+PC9jb2RlPiwKd2UgbXVz
dCBjb21lIHVwIHdpdGggYSB3YXkgdG8gYWNoaWV2ZTwvcD4KPHByZSBjbGFzcz0ibGFuZ3VhZ2Ut
YysrIGhpZ2hsaWdodCI+ICAgIDxjLSBrPnN0cnVjdDwvYy0+IDxjLSBuPkI8L2MtPiA8Yy0gcD57
PC9jLT4KICAgICAgICA8Yy0gbj5CPC9jLT48Yy0gcD4oPC9jLT48Yy0gbj5CPC9jLT48Yy0gbz4m
YW1wOyZhbXA7PC9jLT48Yy0gcD4pOzwvYy0+ICA8Yy0gYzE+Ly8gbm9uLXRyaXZpYWw8L2MtPgog
ICAgICAgIDxjLSBvPn48L2MtPjxjLSBuPkI8L2MtPjxjLSBwPigpOzwvYy0+ICA8Yy0gYzE+Ly8g
bm9uLXRyaXZpYWw8L2MtPgogICAgPGMtIHA+fTs8L2MtPgogICAgPGMtIG4+c3RhdGljX2Fzc2Vy
dDwvYy0+PGMtIHA+KDwvYy0+PGMtIG4+aXNfdHJpdmlhbGx5X3JlbG9jYXRhYmxlPC9jLT48Yy0g
bz4mbHQ7PC9jLT4gPGMtIG4+QjwvYy0+IDxjLSBvPj46OjwvYy0+PGMtIG4+dmFsdWU8L2MtPjxj
LSBwPik7PC9jLT4KPC9wcmU+CiAgIHZpYSBzb21lIGtpbmQgb2YgcHJvZ3JhbW1lci1wcm92aWRl
ZCBhbm5vdGF0aW9uLiAKICAgPHAgY2xhc3M9Im5vdGUiIHJvbGU9Im5vdGUiPjxzcGFuPk5vdGU6
PC9zcGFuPiBXZSBjYW5ub3QgcG9zc2libHkgZG8gaXQgd2l0aG91dCBhbm5vdGF0aW9uLCBiZWNh
dXNlIHRoZXJlIGV4aXN0CmV4YW1wbGVzIG9mIHR5cGVzIHRoYXQgbG9vayBqdXN0IGxpa2UgPGNv
ZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMtIG4+QjwvYy0+PC9jb2RlPiBhbmQgPGVtPmFyZTwvZW0+
IHRyaXZpYWxseSByZWxvY2F0YWJsZSAoZm9yIGV4YW1wbGUsIDxhIGRhdGEtbGluay10eXBlPSJi
aWJsaW8iIGhyZWY9IiNiaWJsaW8tbGlic3RkY3h4ZnVuY3Rpb24iPmxpYnN0ZGMrKydzIHN0ZDo6
ZnVuY3Rpb248L2E+KSBhbmQgdGhlcmUgZXhpc3QgdHlwZXMgdGhhdCBsb29rIGp1c3QgbGlrZSA8
Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gbj5CPC9jLT48L2NvZGU+IGFuZCBhcmUgPGVtPm5v
dDwvZW0+IHRyaXZpYWxseSByZWxvY2F0YWJsZSAoZm9yIGV4YW1wbGUsIDxhIGRhdGEtbGluay10
eXBlPSJiaWJsaW8iIGhyZWY9IiNiaWJsaW8tbGliY3h4ZnVuY3Rpb24iPmxpYmMrKydzIHN0ZDo6
ZnVuY3Rpb248L2E+KS4KVGhlIGNvbXBpbGVyIGNhbm5vdCAiY3JhY2sgb3BlbiIgdGhlIGRlZmlu
aXRpb25zIG9mIDxjb2RlIGNsYXNzPSJoaWdobGlnaHQiPjxjLSBuPkI8L2MtPjxjLSBwPig8L2Mt
PjxjLSBuPkI8L2MtPjxjLSBvPiZhbXA7JmFtcDs8L2MtPjxjLSBwPik8L2MtPjwvY29kZT4gYW5k
IDxjb2RlIGNsYXNzPSJoaWdobGlnaHQiPjxjLSBvPn48L2MtPjxjLSBuPkI8L2MtPjxjLSBwPigp
PC9jLT48L2NvZGU+IHRvIHNlZSBpZgp0aGV5IGNvbWJpbmUgdG8gZm9ybSBhIHRyaXZpYWwgb3Bl
cmF0aW9uLiBPbmUsIHRoYXTigJlzIHRoZSBIYWx0aW5nIFByb2JsZW0uIFR3bywKdGhlIGRlZmlu
aXRpb25zIG9mIDxjb2RlIGNsYXNzPSJoaWdobGlnaHQiPjxjLSBuPkI8L2MtPjxjLSBwPig8L2Mt
PjxjLSBuPkI8L2MtPjxjLSBvPiZhbXA7JmFtcDs8L2MtPjxjLSBwPik8L2MtPjwvY29kZT4gYW5k
IDxjb2RlIGNsYXNzPSJoaWdobGlnaHQiPjxjLSBvPn48L2MtPjxjLSBuPkI8L2MtPjxjLSBwPigp
PC9jLT48L2NvZGU+IG1pZ2h0IG5vdCBiZSBhdmFpbGFibGUgaW4gdGhpcyB0cmFuc2xhdGlvbgp1
bml0LiBUaHJlZSwgdGhlIGRlZmluaXRpb25zIG1pZ2h0IGFjdHVhbGx5IGJlCmF2YWlsYWJsZSBh
bmQgImNyYWNrYWJsZSIgaW4gPGVtPnRoaXM8L2VtPiB0cmFuc2xhdGlvbiB1bml0LCBidXQgdW5h
dmFpbGFibGUgaW4gc29tZSBvdGhlciB0cmFuc2xhdGlvbiB1bml0IQpUaGlzIHdvdWxkIGxlYWQg
dG8gT0RSIHZpb2xhdGlvbnMgYW5kIGdlbmVyYWxseSByZWFsbHkgYmFkIHN0dWZmLiBTbyB3ZSBj
YW5ub3QgYWNoaWV2ZQpvdXIgZ29hbCBieSBhdm9pZGluZyBhbm5vdGF0aW9uLjwvcD4KICAgPHA+
VGhpcyB1c2UtY2FzZSBpcyB0aGUgb25seSBvbmUgdGhhdCByZXF1aXJlcyB1cyB0byBkZXNpZ24g
dGhlICJvcHQtaW4iIHN5bnRheC4KSW4gPGEgaHJlZj0iI3VzZTEiPsKnMi4xIFN0YW5kYXJkIGxp
YnJhcnkgdHlwZXMgc3VjaCBhcyBzdGQ6OnN0cmluZzwvYT4sIGFueSBzcGVjaWFsIHN5bnRheCBp
cyBoaWRkZW4gaW5zaWRlIHRoZQppbXBsZW1lbnRhdGlvbuKAmXMgb3duIGhlYWRlcnMuIEluIDxh
IGhyZWY9IiN1c2UyIj7CpzIuMiBQcm9ncmFtLWRlZmluZWQgdHlwZXMgdGhhdCBmb2xsb3cgdGhl
IFJ1bGUgb2YgWmVybzwvYT4sIG91ciBkZXNpZ24gZ29hbCBpcyB0byA8ZW0+YXZvaWQ8L2VtPiBz
cGVjaWFsIHN5bnRheC4KSW4gPGEgaHJlZj0iI3VzZTMiPsKnMi4zIFByb2dyYW0tZGVmaW5lZCB0
eXBlcyB3aXRoIG5vbi1kZWZhdWx0ZWQgc3BlY2lhbCBtZW1iZXJzPC9hPiwgV0cyMSBtdXN0IGFj
dHVhbGx5IGRlc2lnbiB1c2VyLWZhY2luZyBzeW50YXguPC9wPgogICA8cD5UaGVyZWZvcmUsIEkg
YmVsaWV2ZSBpdCB3b3VsZCBiZSBhY2NlcHRhYmxlIHRvIHB1bnQgb24gwqcyLjMgYW5kIGNvbWUg
YmFjayB0byBpdCBsYXRlci4KV2Ugc2F5LCAiU3VyZSwgdGhhdCB3b3VsZCBiZSBuaWNlLCBidXQg
dGhlcmXigJlzIG5vIHN5bnRheCBmb3IgaXQuIEJlIGdsYWQgdGhhdCBpdCB3b3JrcyBmb3IKY29y
ZS1sYW5ndWFnZSBhbmQgbGlicmFyeSB0eXBlcy4gQXNrIGFnYWluIGluIHRocmVlIHllYXJzLiIg
IEFuZCBhcyBsb25nIGFzIHdlIGxlYXZlIHRoZSBkZXNpZ24Kc3BhY2Ugb3BlbiwgSSBiZWxpZXZl
IHdlIHdvdWxkbuKAmXQgbG9zZSBhbnl0aGluZyBieSBkZWxheWluZyBhIHNvbHV0aW9uIHRvIMKn
Mi4zLjwvcD4KICAgPHA+VGhpcyBwYXBlciBkb2VzIHByb3Bvc2UgYSBzdGFuZGFyZCBzeW50YXgg
Zm9yIMKnMi4zIOKAlCBhbiBhdHRyaWJ1dGUg4oCUIHdoaWNoIGluIHR1cm4KcHJvdmlkZXMgYSA8
ZW0+c2ltcGxlIGFuZCBwb3J0YWJsZTwvZW0+IHNvbHV0aW9uIHRvIMKnMi4xIGZvciBsaWJyYXJ5
IHZlbmRvcnMuIEhvd2V2ZXIsIG91cgphdHRyaWJ1dGUtYmFzZWQgc3ludGF4IGlzIHNldmVyYWJs
ZSBmcm9tIHRoZSByZXN0IG9mIHRoaXMgcGFwZXIuIFdpdGggZXh0cmVtZWx5IG1pbm9yIHN1cmdl
cnksCldHMjEgY291bGQgcmVqZWN0IG91ciBuZXcgYXR0cmlidXRlIGFuZCBzdGlsbCBzb2x2ZSDC
pzIuMSBhbmQgwqcyLjIgZm9yIEMrKzIwLjwvcD4KICAgPGgyIGNsYXNzPSJoZWFkaW5nIHNldHRs
ZWQiIGRhdGEtbGV2ZWw9IjMiIGlkPSJwcm9wb3NhbCI+PHNwYW4gY2xhc3M9InNlY25vIj4zLiA8
L3NwYW4+PHNwYW4gY2xhc3M9ImNvbnRlbnQiPlByb3Bvc2VkIGxhbmd1YWdlIGFuZCBsaWJyYXJ5
IGZlYXR1cmVzPC9zcGFuPjxhIGNsYXNzPSJzZWxmLWxpbmsiIGhyZWY9IiNwcm9wb3NhbCI+PC9h
PjwvaDI+CiAgIDxwPlRoaXMgcGFwZXIgcHJvcG9zZXMgZml2ZSBzZXBhcmF0ZSBhZGRpdGlvbnMg
dG8gdGhlIEMrKyBTdGFuZGFyZC4gVGhlc2UgYWRkaXRpb25zIGludHJvZHVjZQoicmVsb2NhdGUi
IGFzIGEgd2VsbC1zdXBwb3J0ZWQgQysrIG5vdGlvbiBvbiBwYXIgd2l0aCAic3dhcCwiIGFuZCBm
dXJ0aGVybW9yZSwgc3VjY2Vzc2Z1bGx5CmNvbW11bmljYXRlIHRyaXZpYWwgcmVsb2NhdGFiaWxp
dHkgaW4gZWFjaCBvZiB0aGUgdGhyZWUgdXNlLWNhc2VzIGFib3ZlLjwvcD4KICAgPHVsPgogICAg
PGxpIGRhdGEtbWQ+CiAgICAgPHA+QSBuZXcgc3RhbmRhcmQgYWxnb3JpdGhtLCA8Y29kZSBjbGFz
cz0iaGlnaGxpZ2h0Ij48Yy0gbj51bmluaXRpYWxpemVkX3JlbG9jYXRlPC9jLT48Yy0gcD4oPC9j
LT48Yy0gbj5maXJzdDwvYy0+PGMtIHA+LDwvYy0+IDxjLSBuPmxhc3Q8L2MtPjxjLSBwPiw8L2Mt
PiA8Yy0gbj5kX2ZpcnN0PC9jLT48Yy0gcD4pPC9jLT48L2NvZGU+LAppbiB0aGUgPGNvZGUgY2xh
c3M9ImhpZ2hsaWdodCI+PGMtIG8+Jmx0OzwvYy0+PGMtIG4+bWVtb3J5PC9jLT48Yy0gbz4+PC9j
LT48L2NvZGU+IGhlYWRlci48L3A+CiAgICA8bGkgZGF0YS1tZD4KICAgICA8cD5BZGRpdGlvbmFs
IHR5cGUgdHJhaXRzLCA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gbj5pc19yZWxvY2F0YWJs
ZTwvYy0+PGMtIG8+Jmx0OzwvYy0+PGMtIG4+VDwvYy0+PGMtIG8+PjwvYy0+PC9jb2RlPiBhbmQg
PGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMtIG4+aXNfbm90aHJvd19yZWxvY2F0YWJsZTwvYy0+
PGMtIG8+Jmx0OzwvYy0+PGMtIG4+VDwvYy0+PGMtIG8+PjwvYy0+PC9jb2RlPiwKaW4gdGhlIDxj
b2RlIGNsYXNzPSJoaWdobGlnaHQiPjxjLSBvPiZsdDs8L2MtPjxjLSBuPnR5cGVfdHJhaXRzPC9j
LT48Yy0gbz4+PC9jLT48L2NvZGU+IGhlYWRlci48L3A+CiAgICA8bGkgZGF0YS1tZD4KICAgICA8
cD5BIG5ldyB0eXBlIHRyYWl0LCA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gbj5pc190cml2
aWFsbHlfcmVsb2NhdGFibGU8L2MtPjxjLSBvPiZsdDs8L2MtPjxjLSBuPlQ8L2MtPjxjLSBvPj48
L2MtPjwvY29kZT4sIGluIHRoZSA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gbz4mbHQ7PC9j
LT48Yy0gbj50eXBlX3RyYWl0czwvYy0+PGMtIG8+PjwvYy0+PC9jb2RlPiBoZWFkZXIuIFRoaXMg
aXMgdGhlIDxlbT5kZXRlY3Rpb248L2VtPiBtZWNoYW5pc20uPC9wPgogICAgPGxpIGRhdGEtbWQ+
CiAgICAgPHA+QSBuZXcgY29yZS1sYW5ndWFnZSBydWxlIGJ5IHdoaWNoIGEgY2xhc3MgdHlwZeKA
mXMgInRyaXZpYWwgcmVsb2NhdGFiaWxpdHkiCmlzIGluaGVyaXRlZCBhY2NvcmRpbmcgdG8gdGhl
IFJ1bGUgb2YgWmVyby48L3A+CiAgICA8bGkgZGF0YS1tZD4KICAgICA8cD5BIG5ldyBhdHRyaWJ1
dGUsIDxjb2RlIGNsYXNzPSJoaWdobGlnaHQiPjxjLSBwPltbPC9jLT48Yy0gbj50cml2aWFsbHlf
cmVsb2NhdGFibGU8L2MtPjxjLSBwPl1dPC9jLT48L2NvZGU+LCBpbiB0aGUgY29yZSBsYW5ndWFn
ZS4KVGhpcyBpcyB0aGUgPGVtPm9wdC1pbjwvZW0+IG1lY2hhbmlzbSBmb3IgcHJvZ3JhbS1kZWZp
bmVkIHR5cGVzLjwvcD4KICAgPC91bD4KICAgPHA+VGhlc2UgZml2ZSBidWxsZXQgcG9pbnRzIGFy
ZSBzZXZlcmFibGUgdG8gYSBjZXJ0YWluIGRlZ3JlZS4gRm9yIGV4YW1wbGUsIGlmIHRoZSA8Y29k
ZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gcD5bWzwvYy0+PGMtIG4+dHJpdmlhbGx5X3JlbG9jYXRh
YmxlPC9jLT48Yy0gcD5dXTwvYy0+PC9jb2RlPiBhdHRyaWJ1dGUgKHBvaW50cyA0IGFuZCA1KSBp
cyBhZG9wdGVkLCBsaWJyYXJ5IHZlbmRvcnMgd2lsbCBjZXJ0YWlubHkgdXNlIGl0IGluIHRoZWly
IGltcGxlbWVudGF0aW9uczsKYnV0IGlmIHRoZSBhdHRyaWJ1dGUgaXMgcmVqZWN0ZWQsIGxpYnJh
cnkgdmVuZG9ycyBjb3VsZCBzdGlsbCBpbmRpY2F0ZSB0aGUgdHJpdmlhbCByZWxvY2F0YWJpbGl0
eQpmb3IgY2VydGFpbiBzdGFuZGFyZCBsaWJyYXJ5IHR5cGVzIGJ5IHByb3ZpZGluZyBsaWJyYXJ5
IHNwZWNpYWxpemF0aW9ucyBvZiA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gbj5pc190cml2
aWFsbHlfcmVsb2NhdGFibGU8L2MtPjwvY29kZT4gKHBvaW50IDMpLjwvcD4KICAgPHA+UG9pbnRz
IDEgYW5kIDIgYXJlIGNvbXBsZXRlbHkgc2V2ZXJhYmxlIGZyb20gcG9pbnRzIDMsIDQsIGFuZCA1
OwpidXQgd2UgYmVsaWV2ZSB0aGVzZSBhbGdvcml0aG1zIHNob3VsZCBiZSBwcm92aWRlZCBmb3Ig
c3ltbWV0cnkgd2l0aCB0aGUKb3RoZXIgdW5pbml0aWFsaXplZC1tZW1vcnkgYWxnb3JpdGhtcyBp
biB0aGUgPGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMtIG8+Jmx0OzwvYy0+PGMtIG4+bWVtb3J5
PC9jLT48Yy0gbz4+PC9jLT48L2NvZGU+IGhlYWRlcgooPGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+
PGMtIG4+dW5pbml0aWFsaXplZF9jb3B5PC9jLT48L2NvZGU+LCA8Y29kZSBjbGFzcz0iaGlnaGxp
Z2h0Ij48Yy0gbj51bmluaXRpYWxpemVkX21vdmU8L2MtPjwvY29kZT4sIGFuZCA8Y29kZSBjbGFz
cz0iaGlnaGxpZ2h0Ij48Yy0gbj5kZXN0cm95PC9jLT48L2NvZGU+KQphbmQgdGhlIG90aGVyIHRy
aW9zIG9mIHR5cGUtdHJhaXRzIGluIHRoZSA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gbz4m
bHQ7PC9jLT48Yy0gbj50eXBlX3RyYWl0czwvYy0+PGMtIG8+PjwvYy0+PC9jb2RlPiBoZWFkZXIK
KG9uZSBzdWNoIHRyaW8gYmVpbmcgPGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMtIG4+aXNfZGVz
dHJ1Y3RpYmxlPC9jLT48L2NvZGU+LCA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gbj5pc19u
b3Rocm93X2Rlc3RydWN0aWJsZTwvYy0+PC9jb2RlPiwgPGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+
PGMtIG4+aXNfdHJpdmlhbGx5X2Rlc3RydWN0aWJsZTwvYy0+PC9jb2RlPikuIEkgZG8gbm90IGV4
cGVjdCB0aGVzZSB0ZW1wbGF0ZXMgdG8gYmUgZnJlcXVlbnRseSB1c2VmdWwsCmJ1dCBJIGJlbGll
dmUgdGhleSBtdXN0IGJlIHByb3ZpZGVkLCBzbyBhcyBub3QgdG8gdW5wbGVhc2FudGx5IHN1cnBy
aXNlIHRoZSBwcm9ncmFtbWVyCmJ5IHRoZWlyIGFic2VuY2UuPC9wPgogICA8cD5Qb2ludHMgMyBh
bmQgNCB0b2dldGhlciBtb3RpdmF0ZSBwb2ludCA1LiBJbiBvcmRlciB0byBhY2hpZXZlIHRoZSBn
b2FsIG9mIDxhIGhyZWY9IiN1c2UyIj7CpzIuMiBQcm9ncmFtLWRlZmluZWQgdHlwZXMgdGhhdCBm
b2xsb3cgdGhlIFJ1bGUgb2YgWmVybzwvYT4sCndlIDxlbT5tdXN0PC9lbT4gZGVmaW5lIGEgY29y
ZS1sYW5ndWFnZSBtZWNoYW5pc20gYnkgd2hpY2ggd2UgY2FuICJpbmhlcml0IiB0cml2aWFsIHJl
bG9jYXRhYmlsaXR5LgpUaGlzIGlzIGVzcGVjaWFsbHkgaW1wb3J0YW50IGZvciB0aGUgdGVtcGxh
dGUgY2FzZS48L3A+CjxwcmUgY2xhc3M9Imxhbmd1YWdlLWMrKyBoaWdobGlnaHQiPiAgICA8Yy0g
bj50ZW1wbGF0ZTwvYy0+PGMtIG8+Jmx0OzwvYy0+PGMtIG4+Y2xhc3M8L2MtPiA8Yy0gbj5UPC9j
LT48Yy0gbz4+PC9jLT4KICAgIDxjLSBrPnN0cnVjdDwvYy0+IDxjLSBuPkQ8L2MtPiA8Yy0gcD57
PC9jLT4KICAgICAgICA8Yy0gbj5UPC9jLT4gPGMtIG4+dDwvYy0+PGMtIHA+OzwvYy0+CiAgICA8
Yy0gcD59OzwvYy0+CgogICAgPGMtIGMxPi8vIGNsYXNzIEMgY29tZXMgaW4gZnJvbSBvdXRzaWRl
LCBhbHJlYWR5IG1hcmtlZCwgdmlhIHdoYXRldmVyIG1lY2hhbmlzbTwvYy0+CiAgICA8Yy0gbj5j
b25zdGV4cHI8L2MtPiA8Yy0gYj5ib29sPC9jLT4gPGMtIG4+YzwvYy0+IDxjLSBvPj08L2MtPiA8
Yy0gbj5pc190cml2aWFsbHlfcmVsb2NhdGFibGU8L2MtPjxjLSBvPiZsdDs8L2MtPiA8Yy0gbj5D
PC9jLT4gPGMtIG8+Pjo6PC9jLT48Yy0gbj52YWx1ZTwvYy0+PGMtIHA+OzwvYy0+CiAgICA8Yy0g
bj5jb25zdGV4cHI8L2MtPiA8Yy0gYj5ib29sPC9jLT4gPGMtIG4+ZGM8L2MtPiA8Yy0gbz49PC9j
LT4gPGMtIG4+aXNfdHJpdmlhbGx5X3JlbG9jYXRhYmxlPC9jLT48Yy0gbz4mbHQ7PC9jLT4gPGMt
IG4+RDwvYy0+PGMtIG8+Jmx0OzwvYy0+PGMtIG4+QzwvYy0+PGMtIG8+PjwvYy0+IDxjLSBvPj46
OjwvYy0+PGMtIG4+dmFsdWU8L2MtPjxjLSBwPjs8L2MtPgogICAgPGMtIG4+c3RhdGljX2Fzc2Vy
dDwvYy0+PGMtIHA+KDwvYy0+PGMtIG4+ZGM8L2MtPiA8Yy0gbz49PTwvYy0+IDxjLSBuPmM8L2Mt
PjxjLSBwPik7PC9jLT4KPC9wcmU+CiAgIFdlIHByb3Bvc2UgdGhhdCA8Y29kZSBjbGFzcz0iaGln
aGxpZ2h0Ij48Yy0gbj5zdGQ8L2MtPjxjLSBvPjo6PC9jLT48Yy0gbj5pc190cml2aWFsbHlfcmVs
b2NhdGFibGU8L2MtPjxjLSBvPiZsdDs8L2MtPjxjLSBuPlQ8L2MtPjxjLSBvPj48L2MtPjwvY29k
ZT4gc2hvdWxkIGJlIGp1c3QgYSBwbGFpbiBvbGQKY2xhc3MgdGVtcGxhdGUsIGV4YWN0bHkgbGlr
ZSA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gbj5zdGQ8L2MtPjxjLSBvPjo6PC9jLT48Yy0g
bj5pc190cml2aWFsbHlfZGVzdHJ1Y3RpYmxlPC9jLT48Yy0gbz4mbHQ7PC9jLT48Yy0gbj5UPC9j
LT48Yy0gbz4+PC9jLT48L2NvZGU+IGFuZCBzbyBvbi4KVGhlIGNvcmUgbGFuZ3VhZ2UgKjxhIGRh
dGEtbGluay10eXBlPSJiaWJsaW8iIGhyZWY9IiNiaWJsaW8tY29udHJhIj5zaG91bGQgbm90IGtu
b3cgb3IgY2FyZTwvYT4qIHRoYXQgdGhlIGNsYXNzIHRlbXBsYXRlIDxjb2RlIGNsYXNzPSJoaWdo
bGlnaHQiPjxjLSBuPmlzX3RyaXZpYWxseV9yZWxvY2F0YWJsZTwvYy0+PC9jb2RlPiBleGlzdHMs
IGFueSBtb3JlIHRoYW4gaXQga25vd3MgdGhhdCB0aGUgY2xhc3MgdGVtcGxhdGUgPGNvZGUgY2xh
c3M9ImhpZ2hsaWdodCI+PGMtIG4+aXNfdHJpdmlhbGx5X2Rlc3RydWN0aWJsZTwvYy0+PC9jb2Rl
PiBleGlzdHMuIAogICA8cD5XZSBleHBlY3QgdGhhdCB0aGUgbGlicmFyeSB2ZW5kb3Igd2lsbCBp
bXBsZW1lbnQgPGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMtIG4+c3RkPC9jLT48Yy0gbz46Ojwv
Yy0+PGMtIG4+aXNfdHJpdmlhbGx5X3JlbG9jYXRhYmxlPC9jLT48L2NvZGU+LApqdXN0IGxpa2Ug
PGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMtIG4+c3RkPC9jLT48Yy0gbz46OjwvYy0+PGMtIG4+
aXNfdHJpdmlhbGx5X2Rlc3RydWN0aWJsZTwvYy0+PC9jb2RlPiwgaW4gdGVybXMgb2YgYSBub24t
c3RhbmRhcmQgY29tcGlsZXIKYnVpbHRpbiB3aG9zZSBuYXR1cmFsIHNwZWxsaW5nIGlzIDxjb2Rl
IGNsYXNzPSJoaWdobGlnaHQiPjxjLSBuPl9faXNfdHJpdmlhbGx5X3JlbG9jYXRhYmxlPC9jLT48
Yy0gcD4oPC9jLT48Yy0gbj5UPC9jLT48Yy0gcD4pPC9jLT48L2NvZGU+LiBUaGUgY29tcGlsZXIK
Y29tcHV0ZXMgdGhlIHZhbHVlIG9mIDxjb2RlIGNsYXNzPSJoaWdobGlnaHQiPjxjLSBuPl9faXNf
dHJpdmlhbGx5X3JlbG9jYXRhYmxlPC9jLT48Yy0gcD4oPC9jLT48Yy0gbj5UPC9jLT48Yy0gcD4p
PC9jLT48L2NvZGU+IGJ5IGluc3BlY3RpbmcgdGhlCmRlZmluaXRpb24gb2YgPGNvZGUgY2xhc3M9
ImhpZ2hsaWdodCI+PGMtIG4+VDwvYy0+PC9jb2RlPiAoYW5kIHRoZSBkZWZpbml0aW9ucyBvZiBp
dHMgYmFzZSBjbGFzc2VzIGFuZCBtZW1iZXJzLApyZWN1cnNpdmVseSwgaW4gdGhlIGNhc2UgdGhh
dCBib3RoIG9mIGl0cyBzcGVjaWFsIG1lbWJlcnMgYXJlIGRlZmF1bHRlZCkuIFRoaXMKcmVjdXJz
aXZlIHByb2Nlc3MgImJvdHRvbXMgb3V0IiBhdCBwcmltaXRpdmUgdHlwZXMsIG9yIGF0IGFueSB0
eXBlIHdpdGggYSB1c2VyLXByb3ZpZGVkCm1vdmUgb3IgZGVzdHJveSBvcGVyYXRpb24uIENsYXNz
ZXMgd2l0aCB1c2VyLXByb3ZpZGVkIG1vdmUgb3IgZGVzdHJveSBvcGVyYXRpb25zIG11c3QKY29u
c2VydmF0aXZlbHkgYmUgYXNzdW1lZCA8ZW0+bm90PC9lbT4gdG8gYmUgdHJpdmlhbGx5IHJlbG9j
YXRhYmxlLiBUbyBhY2hpZXZlIHRoZSBnb2FsCm9mIDxhIGhyZWY9IiN1c2UzIj7CpzIuMyBQcm9n
cmFtLWRlZmluZWQgdHlwZXMgd2l0aCBub24tZGVmYXVsdGVkIHNwZWNpYWwgbWVtYmVyczwvYT4s
IHdlIG11c3QgcHJvdmlkZSBhIHdheSBmb3Igc3VjaCBhIGNsYXNzIHRvICJvcHQgaW4iIGFuZCB3
YXJyYW50IHRvIHRoZQppbXBsZW1lbnRhdGlvbiB0aGF0IGl0IGlzIGluIGZhY3QgdHJpdmlhbGx5
IHJlbG9jYXRhYmxlIChkZXNwaXRlIGJlaW5nIG5vbi10cml2aWFsbHkKbW92ZS1jb25zdHJ1Y3Rp
YmxlIGFuZC9vciBub24tdHJpdmlhbGx5IGRlc3RydWN0aWJsZSkuPC9wPgogICA8cD5JbiBwb2lu
dCA1IHdlIHByb3Bvc2UgdGhhdCB0aGUgb3B0LWluIG1lY2hhbmlzbSBzaG91bGQgYmUgYW4gYXR0
cmlidXRlLiBUaGUgcHJvZ3JhbW1lcgpvZiBhIHRyaXZpYWxseSByZWxvY2F0YWJsZSBidXQgbm9u
LXRyaXZpYWxseSBkZXN0cnVjdGlibGUgY2xhc3MgPGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMt
IG4+QzwvYy0+PC9jb2RlPiB3aWxsIG1hcmsgaXQgZm9yCnRoZSBjb21waWxlciB1c2luZyB0aGUg
YXR0cmlidXRlOjwvcD4KPHByZSBjbGFzcz0ibGFuZ3VhZ2UtYysrIGhpZ2hsaWdodCI+ICAgIDxj
LSBrPnN0cnVjdDwvYy0+IDxjLSBwPltbPC9jLT48Yy0gbj50cml2aWFsbHlfcmVsb2NhdGFibGU8
L2MtPjxjLSBwPl1dPC9jLT4gPGMtIG4+QzwvYy0+IDxjLSBwPns8L2MtPgogICAgICAgIDxjLSBu
PkM8L2MtPjxjLSBwPig8L2MtPjxjLSBuPkM8L2MtPjxjLSBvPiZhbXA7JmFtcDs8L2MtPjxjLSBw
Pik7PC9jLT4gIDxjLSBjMT4vLyBkZWZpbmVkIGVsc2V3aGVyZTwvYy0+CiAgICAgICAgPGMtIG8+
fjwvYy0+PGMtIG4+QzwvYy0+PGMtIHA+KCk7PC9jLT4gPGMtIGMxPi8vIGRlZmluZWQgZWxzZXdo
ZXJlPC9jLT4KICAgIDxjLSBwPn07PC9jLT4KICAgIDxjLSBuPnN0YXRpY19hc3NlcnQ8L2MtPjxj
LSBwPig8L2MtPjxjLSBuPmlzX3RyaXZpYWxseV9yZWxvY2F0YWJsZTwvYy0+PGMtIG8+Jmx0Ozwv
Yy0+IDxjLSBuPkM8L2MtPiA8Yy0gbz4+Ojo8L2MtPjxjLSBuPnZhbHVlPC9jLT48Yy0gcD4pOzwv
Yy0+CjwvcHJlPgogICBUaGUgYXR0cmlidXRlIG92ZXJyaWRlcyB0aGUgY29tcGlsZXLigJlzIHVz
dWFsIGNvbXB1dGF0aW9uLiBBbiBleGFtcGxlIG9mIGEgImNvbmRpdGlvbmFsbHkiCnRyaXZpYWxs
eSByZWxvY2F0YWJsZSBjbGFzcyBpcyBzaG93biBpbiA8YSBocmVmPSIjc2FtcGxlLWNvbmRpdGlv
bmFsIj5Db25kaXRpb25hbGx5IHRyaXZpYWwgcmVsb2NhdGlvbjwvYT4uIAogICA8aDIgY2xhc3M9
ImhlYWRpbmcgc2V0dGxlZCIgZGF0YS1sZXZlbD0iNCIgaWQ9IndvcmRpbmciPjxzcGFuIGNsYXNz
PSJzZWNubyI+NC4gPC9zcGFuPjxzcGFuIGNsYXNzPSJjb250ZW50Ij5Qcm9wb3NlZCB3b3JkaW5n
IGZvciBDKysyMDwvc3Bhbj48YSBjbGFzcz0ic2VsZi1saW5rIiBocmVmPSIjd29yZGluZyI+PC9h
PjwvaDI+CiAgIDxwPlRoZSB3b3JkaW5nIGluIHRoaXMgc2VjdGlvbiBpcyByZWxhdGl2ZSB0byA8
YSBkYXRhLWxpbmstdHlwZT0iYmlibGlvIiBocmVmPSIjYmlibGlvLW40NzUwIj5XRzIxIGRyYWZ0
IE40NzUwPC9hPiwKdGhhdCBpcywgdGhlIGN1cnJlbnQgZHJhZnQgb2YgdGhlIEMrKzE3IHN0YW5k
YXJkLjwvcD4KICAgPGgzIGNsYXNzPSJoZWFkaW5nIHNldHRsZWQiIGRhdGEtbGV2ZWw9IjQuMSIg
aWQ9IndvcmRpbmctb3BlcmF0aW9uIj48c3BhbiBjbGFzcz0ic2Vjbm8iPjQuMS4gPC9zcGFuPjxz
cGFuIGNsYXNzPSJjb250ZW50Ij5SZWxvY2F0aW9uIG9wZXJhdGlvbjwvc3Bhbj48YSBjbGFzcz0i
c2VsZi1saW5rIiBocmVmPSIjd29yZGluZy1vcGVyYXRpb24iPjwvYT48L2gzPgogICA8cD5BZGQg
YSBuZXcgc2VjdGlvbiBpbiA8YSBocmVmPSJodHRwOi8vZWVsLmlzL2MrK2RyYWZ0L2RlZmluaXRp
b25zIj5bZGVmaW5pdGlvbnNdPC9hPjo8L3A+CiAgIDxwIGNsYXNzPSJpc3N1ZSIgaWQ9Imlzc3Vl
LTc1ZmZlMjAxIj48YSBjbGFzcz0ic2VsZi1saW5rIiBocmVmPSIjaXNzdWUtNzVmZmUyMDEiPjwv
YT4gW2RlZmluaXRpb25zXSBpcyBwcm9iYWJseSB0aGUgd3JvbmcgcGxhY2UgZm9yIHRoZSBjb3Jl
LWxhbmd1YWdlIGRlZmluaXRpb24gb2YgInJlbG9jYXRpb24gb3BlcmF0aW9uIjwvcD4KICAgPHA+
PHNtYWxsPjwvc21hbGw+PC9wPgogICA8YmxvY2txdW90ZT4KICAgIDxwPjwvcD4KICAgIDxzbWFs
bD4gPGRsPjxkdCBkYXRhLW1kPjxkZm4gY2xhc3M9ImRmbi1wYW5lbGVkIiBkYXRhLWRmbi10eXBl
PSJhYnN0cmFjdC1vcCIgZGF0YS1leHBvcnQgaWQ9ImFic3RyYWN0LW9wZGVmLXJlbG9jYXRpb24t
b3BlcmF0aW9uIj5yZWxvY2F0aW9uIG9wZXJhdGlvbjwvZGZuPjwvZHQ+PGRkIGRhdGEtbWQ+PHA+
dGhlIGhvbW9nZW5lb3VzIGJpbmFyeSBvcGVyYXRpb24gcGVyZm9ybWVkIG9uIGEgcmFuZ2UgYnkg
PGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMtIG4+c3RkPC9jLT48Yy0gbz46OjwvYy0+PGMtIG4+
dW5pbml0aWFsaXplZF9yZWxvY2F0ZTwvYy0+PC9jb2RlPiwgY29uc2lzdGluZyBvZiBhIG1vdmUt
Y29uc3RydWN0aW9uIGltbWVkaWF0ZWx5IGZvbGxvd2VkIGJ5IGEgZGVzdHJ1Y3Rpb24gb2YgdGhl
IHNvdXJjZSBvYmplY3Q8L3A+IDwvZGQ+PC9kbD4gPC9zbWFsbD4KICAgPC9ibG9ja3F1b3RlPgog
ICA8cCBjbGFzcz0iaXNzdWUiIGlkPSJpc3N1ZS03Yzg2ZjVmNyI+PGEgY2xhc3M9InNlbGYtbGlu
ayIgaHJlZj0iI2lzc3VlLTdjODZmNWY3Ij48L2E+IHRoaXMgZGVmaW5pdGlvbiBvZiAicmVsb2Nh
dGlvbiBvcGVyYXRpb24iIGlzIG5vdCBnb29kPC9wPgogICA8aDMgY2xhc3M9ImhlYWRpbmcgc2V0
dGxlZCIgZGF0YS1sZXZlbD0iNC4yIiBpZD0id29yZGluZy11bmluaXQtcmVsb2NhdGUiPjxzcGFu
IGNsYXNzPSJzZWNubyI+NC4yLiA8L3NwYW4+PHNwYW4gY2xhc3M9ImNvbnRlbnQiPkFsZ29yaXRo
bSA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gbj51bmluaXRpYWxpemVkX3JlbG9jYXRlPC9j
LT48L2NvZGU+PC9zcGFuPjxhIGNsYXNzPSJzZWxmLWxpbmsiIGhyZWY9IiN3b3JkaW5nLXVuaW5p
dC1yZWxvY2F0ZSI+PC9hPjwvaDM+CiAgIDxwPkFkZCBhIG5ldyBzZWN0aW9uIGFmdGVyIDxhIGhy
ZWY9Imh0dHA6Ly9lZWwuaXMvYysrZHJhZnQvdW5pbml0aWFsaXplZC5tb3ZlIj5bdW5pbml0aWFs
aXplZC5tb3ZlXTwvYT46PC9wPgogICA8cD48c21hbGw+PC9zbWFsbD48L3A+CiAgIDxibG9ja3F1
b3RlPgogICAgPHA+PC9wPgogICAgPHNtYWxsPiA8cHJlIGNsYXNzPSJoaWdobGlnaHQiPjxjLSBr
PnRlbXBsYXRlPC9jLT48Yy0gbz4mbHQ7PC9jLT48Yy0gaz5jbGFzczwvYy0+IDxjLSBuYz5JbnB1
dEl0ZXJhdG9yPC9jLT48Yy0gcD4sPC9jLT4gPGMtIGs+Y2xhc3M8L2MtPiA8Yy0gbmM+Rm9yd2Fy
ZEl0ZXJhdG9yPC9jLT48Yy0gbz4+PC9jLT4KPGMtIG4+Rm9yd2FyZEl0ZXJhdG9yPC9jLT4gPGMt
IG4+dW5pbml0aWFsaXplZF9yZWxvY2F0ZTwvYy0+PGMtIHA+KDwvYy0+PGMtIG4+SW5wdXRJdGVy
YXRvcjwvYy0+IDxjLSBuPmZpcnN0PC9jLT48Yy0gcD4sPC9jLT4gPGMtIG4+SW5wdXRJdGVyYXRv
cjwvYy0+IDxjLSBuPmxhc3Q8L2MtPjxjLSBwPiw8L2MtPgogICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICA8Yy0gbj5Gb3J3YXJkSXRlcmF0b3I8L2MtPiA8Yy0gbj5yZXN1bHQ8
L2MtPjxjLSBwPik7PC9jLT4KPC9wcmU+IDxwPjxlbT5FZmZlY3RzOjwvZW0+IEVxdWl2YWxlbnQg
dG86PC9wPiA8cHJlIGNsYXNzPSJoaWdobGlnaHQiPjxjLSBrPmZvcjwvYy0+IDxjLSBwPig7PC9j
LT4gPGMtIG4+Zmlyc3Q8L2MtPiA8Yy0gbz4hPTwvYy0+IDxjLSBuPmxhc3Q8L2MtPjxjLSBwPjs8
L2MtPiA8Yy0gcD4oPC9jLT48Yy0gYj52b2lkPC9jLT48Yy0gcD4pPC9jLT48Yy0gbz4rKzwvYy0+
PGMtIG4+cmVzdWx0PC9jLT48Yy0gcD4sPC9jLT4gPGMtIG8+Kys8L2MtPjxjLSBuPmZpcnN0PC9j
LT48Yy0gcD4pPC9jLT4gPGMtIHA+ezwvYy0+CiAgPGMtIG8+Ojo8L2MtPjxjLSBrPm5ldzwvYy0+
IDxjLSBwPig8L2MtPjxjLSBrPnN0YXRpY19jYXN0PC9jLT48Yy0gbz4mbHQ7PC9jLT48Yy0gYj52
b2lkPC9jLT48Yy0gbz4qPjwvYy0+PGMtIHA+KDwvYy0+PGMtIG4+YWRkcmVzc29mPC9jLT48Yy0g
cD4oPC9jLT48Yy0gbz4qPC9jLT48Yy0gbj5yZXN1bHQ8L2MtPjxjLSBwPikpKTwvYy0+CiAgICA8
Yy0gaz50eXBlbmFtZTwvYy0+IDxjLSBuPml0ZXJhdG9yX3RyYWl0czwvYy0+PGMtIG8+Jmx0Ozwv
Yy0+PGMtIG4+Rm9yd2FyZEl0ZXJhdG9yPC9jLT48Yy0gbz4+Ojo8L2MtPjxjLSBuPnZhbHVlX3R5
cGU8L2MtPjxjLSBwPig8L2MtPjxjLSBuPnN0ZDwvYy0+PGMtIG8+Ojo8L2MtPjxjLSBuPm1vdmU8
L2MtPjxjLSBwPig8L2MtPjxjLSBvPio8L2MtPjxjLSBuPmZpcnN0PC9jLT48Yy0gcD4pKTs8L2Mt
PgogIDxjLSBuPmRlc3Ryb3lfYXQ8L2MtPjxjLSBwPig8L2MtPjxjLSBuPmFkZHJlc3NvZjwvYy0+
PGMtIHA+KDwvYy0+PGMtIG8+KjwvYy0+PGMtIG4+Zmlyc3Q8L2MtPjxjLSBwPikpOzwvYy0+Cjxj
LSBwPn08L2MtPgo8Yy0gaz5yZXR1cm48L2MtPiA8Yy0gbj5yZXN1bHQ8L2MtPjxjLSBwPjs8L2Mt
Pgo8L3ByZT48L3NtYWxsPgogICA8L2Jsb2NrcXVvdGU+CiAgIDxoMyBjbGFzcz0iaGVhZGluZyBz
ZXR0bGVkIiBkYXRhLWxldmVsPSI0LjMiIGlkPSJ3b3JkaW5nLXVuaW5pdC1yZWxvY2F0ZS1uIj48
c3BhbiBjbGFzcz0ic2Vjbm8iPjQuMy4gPC9zcGFuPjxzcGFuIGNsYXNzPSJjb250ZW50Ij5BbGdv
cml0aG0gPGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMtIG4+dW5pbml0aWFsaXplZF9yZWxvY2F0
ZV9uPC9jLT48L2NvZGU+PC9zcGFuPjxhIGNsYXNzPSJzZWxmLWxpbmsiIGhyZWY9IiN3b3JkaW5n
LXVuaW5pdC1yZWxvY2F0ZS1uIj48L2E+PC9oMz4KICAgPHA+PHNtYWxsPjwvc21hbGw+PC9wPgog
ICA8YmxvY2txdW90ZT4KICAgIDxwPjwvcD4KICAgIDxzbWFsbD4gPHByZSBjbGFzcz0iaGlnaGxp
Z2h0Ij48Yy0gaz50ZW1wbGF0ZTwvYy0+PGMtIG8+Jmx0OzwvYy0+PGMtIGs+Y2xhc3M8L2MtPiA8
Yy0gbmM+SW5wdXRJdGVyYXRvcjwvYy0+PGMtIHA+LDwvYy0+IDxjLSBrPmNsYXNzPC9jLT4gPGMt
IG5jPlNpemU8L2MtPjxjLSBwPiw8L2MtPiA8Yy0gaz5jbGFzczwvYy0+IDxjLSBuYz5Gb3J3YXJk
SXRlcmF0b3I8L2MtPjxjLSBvPj48L2MtPgogIDxjLSBuPnBhaXI8L2MtPjxjLSBvPiZsdDs8L2Mt
PjxjLSBuPklucHV0SXRlcmF0b3I8L2MtPjxjLSBwPiw8L2MtPiA8Yy0gbj5Gb3J3YXJkSXRlcmF0
b3I8L2MtPjxjLSBvPj48L2MtPgogICAgPGMtIG4+dW5pbml0aWFsaXplZF9yZWxvY2F0ZV9uPC9j
LT48Yy0gcD4oPC9jLT48Yy0gbj5JbnB1dEl0ZXJhdG9yPC9jLT4gPGMtIG4+Zmlyc3Q8L2MtPjxj
LSBwPiw8L2MtPiA8Yy0gbj5TaXplPC9jLT4gPGMtIG4+bjwvYy0+PGMtIHA+LDwvYy0+IDxjLSBu
PkZvcndhcmRJdGVyYXRvcjwvYy0+IDxjLSBuPnJlc3VsdDwvYy0+PGMtIHA+KTs8L2MtPgo8L3By
ZT4gPHA+PGVtPkVmZmVjdHM6PC9lbT4gRXF1aXZhbGVudCB0bzo8L3A+IDxwcmUgY2xhc3M9Imhp
Z2hsaWdodCI+PGMtIGs+Zm9yPC9jLT4gPGMtIHA+KDs8L2MtPiA8Yy0gbj5uPC9jLT4gPGMtIG8+
PjwvYy0+IDxjLSBtaT4wPC9jLT48Yy0gcD47PC9jLT4gPGMtIG8+Kys8L2MtPjxjLSBuPnJlc3Vs
dDwvYy0+PGMtIHA+LDwvYy0+IDxjLSBwPig8L2MtPjxjLSBiPnZvaWQ8L2MtPjxjLSBwPik8L2Mt
PiA8Yy0gbz4rKzwvYy0+PGMtIG4+Zmlyc3Q8L2MtPjxjLSBwPiw8L2MtPiA8Yy0gbz4tLTwvYy0+
PGMtIG4+bjwvYy0+PGMtIHA+KTwvYy0+IDxjLSBwPns8L2MtPgogIDxjLSBvPjo6PC9jLT48Yy0g
az5uZXc8L2MtPiA8Yy0gcD4oPC9jLT48Yy0gaz5zdGF0aWNfY2FzdDwvYy0+PGMtIG8+Jmx0Ozwv
Yy0+PGMtIGI+dm9pZDwvYy0+PGMtIG8+Kj48L2MtPjxjLSBwPig8L2MtPjxjLSBuPmFkZHJlc3Nv
ZjwvYy0+PGMtIHA+KDwvYy0+PGMtIG8+KjwvYy0+PGMtIG4+cmVzdWx0PC9jLT48Yy0gcD4pKSk8
L2MtPgogICAgPGMtIGs+dHlwZW5hbWU8L2MtPiA8Yy0gbj5pdGVyYXRvcl90cmFpdHM8L2MtPjxj
LSBvPiZsdDs8L2MtPjxjLSBuPkZvcndhcmRJdGVyYXRvcjwvYy0+PGMtIG8+Pjo6PC9jLT48Yy0g
bj52YWx1ZV90eXBlPC9jLT48Yy0gcD4oPC9jLT48Yy0gbj5zdGQ8L2MtPjxjLSBvPjo6PC9jLT48
Yy0gbj5tb3ZlPC9jLT48Yy0gcD4oPC9jLT48Yy0gbz4qPC9jLT48Yy0gbj5maXJzdDwvYy0+PGMt
IHA+KSk7PC9jLT4KICA8Yy0gbj5kZXN0cm95X2F0PC9jLT48Yy0gcD4oPC9jLT48Yy0gbj5hZGRy
ZXNzb2Y8L2MtPjxjLSBwPig8L2MtPjxjLSBvPio8L2MtPjxjLSBuPmZpcnN0PC9jLT48Yy0gcD4p
KTs8L2MtPgo8Yy0gcD59PC9jLT4KPGMtIGs+cmV0dXJuPC9jLT4gPGMtIHA+ezwvYy0+PGMtIG4+
Zmlyc3Q8L2MtPjxjLSBwPiw8L2MtPjxjLSBuPnJlc3VsdDwvYy0+PGMtIHA+fTs8L2MtPgo8L3By
ZT48L3NtYWxsPgogICA8L2Jsb2NrcXVvdGU+CiAgIDxoMyBjbGFzcz0iaGVhZGluZyBzZXR0bGVk
IiBkYXRhLWxldmVsPSI0LjQiIGlkPSJ3b3JkaW5nLWluaGVyaXRhbmNlIj48c3BhbiBjbGFzcz0i
c2Vjbm8iPjQuNC4gPC9zcGFuPjxzcGFuIGNsYXNzPSJjb250ZW50Ij5Ucml2aWFsbHkgcmVsb2Nh
dGFibGUgdHlwZTwvc3Bhbj48YSBjbGFzcz0ic2VsZi1saW5rIiBocmVmPSIjd29yZGluZy1pbmhl
cml0YW5jZSI+PC9hPjwvaDM+CiAgIDxwIGNsYXNzPSJpc3N1ZSIgaWQ9Imlzc3VlLWZmYmJkMzNj
Ij48YSBjbGFzcz0ic2VsZi1saW5rIiBocmVmPSIjaXNzdWUtZmZiYmQzM2MiPjwvYT4gV2hlcmUg
aW4gdGhlIFN0YW5kYXJkIHNob3VsZCB3ZSBwbGFjZSB0aGUgZGVmaW5pdGlvbiBvZiAidHJpdmlh
bGx5IHJlbG9jYXRhYmxlIj88L3A+CiAgIDxwPkFkZCBhIG5ldyBzZWN0aW9uIHNvbWV3aGVyZTo8
L3A+CiAgIDxwPjxzbWFsbD48L3NtYWxsPjwvcD4KICAgPGJsb2NrcXVvdGU+PHNtYWxsPiBBIG1v
dmUtY29uc3RydWN0aWJsZSwgZGVzdHJ1Y3RpYmxlIG9iamVjdCB0eXBlIDxjb2RlIGNsYXNzPSJo
aWdobGlnaHQiPjxjLSBuPlQ8L2MtPjwvY29kZT4gaXMgYSA8ZGZuIGNsYXNzPSJkZm4tcGFuZWxl
ZCIgZGF0YS1kZm4tdHlwZT0iYWJzdHJhY3Qtb3AiIGRhdGEtZXhwb3J0IGlkPSJhYnN0cmFjdC1v
cGRlZi10cml2aWFsbHktcmVsb2NhdGFibGUiPnRyaXZpYWxseSByZWxvY2F0YWJsZTwvZGZuPiB0
eXBlIGlmIGl0IGlzOjxwPjwvcD4gPHVsPjxsaSBkYXRhLW1kPjxwPmEgdHJpdmlhbGx5IGNvcHlh
YmxlIHR5cGUsIG9yPC9wPiA8L2xpPjxsaSBkYXRhLW1kPjxwPmEgKHBvc3NpYmx5IGN2LXF1YWxp
ZmllZCkgY2xhc3MgdHlwZSBkZWNsYXJlZCB3aXRoIHRoZSA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0
Ij48Yy0gcD5bWzwvYy0+PGMtIG4+dHJpdmlhbGx5X3JlbG9jYXRhYmxlPC9jLT48Yy0gcD5dXTwv
Yy0+PC9jb2RlPiBhdHRyaWJ1dGUsIG9yPC9wPiA8L2xpPjxsaSBkYXRhLW1kPjxwPmEgKHBvc3Np
Ymx5IGN2LXF1YWxpZmllZCkgY2xhc3MgdHlwZSB3aGljaDo8L3A+IDx1bD48bGkgZGF0YS1tZD48
cD5oYXMgZWl0aGVyIGEgZGVmYXVsdGVkLCBub24tZGVsZXRlZCBtb3ZlIGNvbnN0cnVjdG9yIG9y
IG5vIG1vdmUgY29uc3RydWN0b3IgYW5kIGEgZGVmYXVsdGVkLCBub24tZGVsZXRlZCBjb3B5IGNv
bnN0cnVjdG9yLDwvcD4gPC9saT48bGkgZGF0YS1tZD48cD5oYXMgYSBkZWZhdWx0ZWQsIG5vbi1k
ZWxldGVkIGRlc3RydWN0b3IsPC9wPiA8L2xpPjxsaSBkYXRhLW1kPjxwPmVpdGhlciBpcyBmaW5h
bCwgb3IgaGFzIGEgZmluYWwgZGVzdHJ1Y3Rvciwgb3IgaGFzIGEgbm9uLXZpcnR1YWwgZGVzdHJ1
Y3Rvciw8L3A+IDwvbGk+PGxpIGRhdGEtbWQ+PHA+aGFzIG5vIHZpcnR1YWwgYmFzZSBjbGFzc2Vz
LDwvcD4gPC9saT48bGkgZGF0YS1tZD48cD5oYXMgbm8gPGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+
PGMtIGs+bXV0YWJsZTwvYy0+PC9jb2RlPiBtZW1iZXJzLDwvcD4gPC9saT48bGkgZGF0YS1tZD48
cD5hbGwgb2Ygd2hvc2UgbWVtYmVycyBhcmUgZWl0aGVyIG9mIHJlZmVyZW5jZSB0eXBlIG9yIG9m
IHRyaXZpYWxseSByZWxvY2F0YWJsZSB0eXBlLCBhbmQ8L3A+IDwvbGk+PGxpIGRhdGEtbWQ+PHA+
YWxsIG9mIHdob3NlIGJhc2UgY2xhc3NlcyBhcmUgdHJpdmlhbGx5IHJlbG9jYXRhYmxlLjwvcD4g
PC9saT48L3VsPjwvbGk+PC91bD4gPHA+WzxlbT5Ob3RlOjwvZW0+IEZvciBhIHRyaXZpYWxseSBy
ZWxvY2F0YWJsZSB0eXBlLCB0aGUgPGEgZGF0YS1saW5rLXR5cGU9ImFic3RyYWN0LW9wIiBocmVm
PSIjYWJzdHJhY3Qtb3BkZWYtcmVsb2NhdGlvbi1vcGVyYXRpb24iIGlkPSJyZWYtZm9yLWFic3Ry
YWN0LW9wZGVmLXJlbG9jYXRpb24tb3BlcmF0aW9uIj5yZWxvY2F0aW9uIG9wZXJhdGlvbjwvYT4g
KHN1Y2ggYXMgdGhlIHJlbG9jYXRpb24gb3BlcmF0aW9ucwpwZXJmb3JtZWQgYnkgdGhlIGxpYnJh
cnkgZnVuY3Rpb25zIDxjb2RlIGNsYXNzPSJoaWdobGlnaHQiPjxjLSBuPnN0ZDwvYy0+PGMtIG8+
Ojo8L2MtPjxjLSBuPnN3YXA8L2MtPjwvY29kZT4gYW5kIDxjb2RlIGNsYXNzPSJoaWdobGlnaHQi
PjxjLSBuPnN0ZDwvYy0+PGMtIG8+Ojo8L2MtPjxjLSBuPnZlY3RvcjwvYy0+PGMtIG8+Ojo8L2Mt
PjxjLSBuPnJlc2l6ZTwvYy0+PC9jb2RlPikgaXMgdGFudGFtb3VudAp0byBhIHNpbXBsZSBjb3B5
IG9mIHRoZSB1bmRlcmx5aW5nIGJ5dGVzLiA8ZW0+4oCUZW5kIG5vdGU8L2VtPl08L3A+IDxwPls8
ZW0+Tm90ZTo8L2VtPiBJdCBpcyBpbnRlbmRlZCB0aGF0IG1vc3Qgc3RhbmRhcmQgbGlicmFyeSB0
eXBlcyBiZSB0cml2aWFsbHkgcmVsb2NhdGFibGUgdHlwZXMuIDxlbT7igJRlbmQgbm90ZTwvZW0+
XTwvcD4gPC9zbWFsbD48L2Jsb2NrcXVvdGU+CiAgIDxwIGNsYXNzPSJub3RlIiByb2xlPSJub3Rl
Ij48c3Bhbj5Ob3RlOjwvc3Bhbj4gV2UgY291bGQgc2ltcGxpZnkgdGhlIHdvcmRpbmcgYnkgcmVt
b3ZpbmcgdGhlIHdvcmRzICJlaXRoZXIgaXMgZmluYWwsIG9yIGhhcyBhIGZpbmFsIGRlc3RydWN0
b3IsIG9yIi4KSG93ZXZlciwgdGhpcyB3b3VsZCBsZWFkIHRvIHRoZSBjb21waWxlcuKAmXMgZmFp
bGluZwp0byBpZGVudGlmeSBjZXJ0YWluICh1bnJlYWxpc3RpYykgY2xhc3MgdHlwZXMgYXMgdHJp
dmlhbGx5IHJlbG9jYXRhYmxlLCB3aGVuIGluIGZhY3QgaXQgaGFzIGVub3VnaAppbmZvcm1hdGlv
biB0byBpbmZlciB0aGF0IHRoZXkgPGVtPmFyZTwvZW0+IHRyaXZpYWxseSByZWxvY2F0YWJsZSBp
biBwcmFjdGljZS4gVGhpcyB3b3VsZCBsZWF2ZSByb29tIGZvciBhCiJiZXR0ZXIiIGltcGxlbWVu
dGF0aW9uIGJlbmVhdGggb3Vycy4gSSB0ZW50YXRpdmVseSBwcmVmZXIgdG8gb3B0aW1pemUgZm9y
IG1heGltdW0gcGVyZm9ybWFuY2Ugb3ZlciBzcGVjIHNpbXBsaWNpdHkuPC9wPgogICA8cCBjbGFz
cz0ibm90ZSIgcm9sZT0ibm90ZSI+PHNwYW4+Tm90ZTo8L3NwYW4+IFRoZXJlIGlzIG5vIHNwZWNp
YWwgdHJlYXRtZW50IGZvciB2b2xhdGlsZSBzdWJvYmplY3RzLiBVc2luZyA8Y29kZSBjbGFzcz0i
aGlnaGxpZ2h0Ij48Yy0gbj5tZW1tb3ZlPC9jLT48L2NvZGU+IG9uIHZvbGF0aWxlIHN1Ym9iamVj
dHMKY2FuIGNhdXNlIHRlYXJpbmcgb2YgcmVhZHMgYW5kIHdyaXRlcy4gVGhpcyBwYXBlciBpbnRy
b2R1Y2VzIG5vIDxlbT5uZXc8L2VtPiBpc3N1ZXMgaW4gdGhpcyBhcmVhOwpzZWUgPGEgZGF0YS1s
aW5rLXR5cGU9ImJpYmxpbyIgaHJlZj0iI2JpYmxpby1zdWJvYmplY3RzIj5bU3Vib2JqZWN0c108
L2E+LiBUaGUgZXhpc3RpbmcgaXNzdWVzIHdpdGggPGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMt
IGs+dm9sYXRpbGU8L2MtPjwvY29kZT4gYXJlIGFkZHJlc3NlZCBuYXJyb3dseSBieSA8YSBkYXRh
LWxpbmstdHlwZT0iYmlibGlvIiBocmVmPSIjYmlibGlvLXAxMTUzcjAiPltQMTE1M1IwXTwvYT4g
YW5kIGJyb2FkbHkgYnkgPGEgZGF0YS1saW5rLXR5cGU9ImJpYmxpbyIgaHJlZj0iI2JpYmxpby1w
MTE1MnIwIj5bUDExNTJSMF08L2E+LjwvcD4KICAgPHAgY2xhc3M9Im5vdGUiIHJvbGU9Im5vdGUi
PjxzcGFuPk5vdGU6PC9zcGFuPiBUaGVyZSBpcyBubyBzcGVjaWFsIHRyZWF0bWVudCBmb3IgcG9z
c2libHkgb3ZlcmxhcHBpbmcgc3Vib2JqZWN0cy4gVXNpbmcgPGNvZGUgY2xhc3M9ImhpZ2hsaWdo
dCI+PGMtIG4+bWVtbW92ZTwvYy0+PC9jb2RlPiBvbiBwb3NzaWJseSBvdmVybGFwcGluZwpzdWJv
YmplY3RzIGNhbiBvdmVyd3JpdGUgdW5yZWxhdGVkIG9iamVjdHMgaW4gdGhlIHZpY2luaXR5IG9m
IHRoZSBkZXN0aW5hdGlvbi4gVGhpcyBwYXBlciBpbnRyb2R1Y2VzCm5vIDxlbT5uZXc8L2VtPiBp
c3N1ZXMgaW4gdGhpcyBhcmVhOyBzZWUgPGEgZGF0YS1saW5rLXR5cGU9ImJpYmxpbyIgaHJlZj0i
I2JpYmxpby1zdWJvYmplY3RzIj5bU3Vib2JqZWN0c108L2E+LjwvcD4KICAgPHAgY2xhc3M9Imlz
c3VlIiBpZD0iaXNzdWUtYTBkNDVjZWQiPjxhIGNsYXNzPSJzZWxmLWxpbmsiIGhyZWY9IiNpc3N1
ZS1hMGQ0NWNlZCI+PC9hPiBNdXN0IHdlIGFsc28gc2F5IHRoYXQgdGhlIHJlbGV2YW50IG1vdmUg
Y29uc3RydWN0b3IgKHJlc3AuIGNvcHkgY29uc3RydWN0b3IpIG11c3QgYmUgcHVibGljIGFuZCB1
bmFtYmlndW91cz88L3A+CiAgIDxkaXYgY2xhc3M9Imlzc3VlIiBpZD0iaXNzdWUtOTdkOTJkZDAi
PgogICAgPGEgY2xhc3M9InNlbGYtbGluayIgaHJlZj0iI2lzc3VlLTk3ZDkyZGQwIj48L2E+IENv
bnNpZGVyIHRoZSBmb2xsb3dpbmcgdGVzdCBjYXNl4oCUPHdicj4KPHByZSBjbGFzcz0iaGlnaGxp
Z2h0Ij4gICAgPGMtIGs+c3RydWN0PC9jLT4gPGMtIG4+TTwvYy0+IDxjLSBwPns8L2MtPgogICAg
ICAgIDxjLSBuPk08L2MtPjxjLSBwPigpPC9jLT4gPGMtIG8+PTwvYy0+IDxjLSBrPmRlZmF1bHQ8
L2MtPjxjLSBwPjs8L2MtPgogICAgICAgIDxjLSBuPk08L2MtPjxjLSBwPig8L2MtPjxjLSBuPk08
L2MtPjxjLSBvPiZhbXA7PC9jLT48Yy0gcD4pPC9jLT4gPGMtIHA+ezwvYy0+IDxjLSBuPnB1dHM8
L2MtPjxjLSBwPig8L2MtPjxjLSBzPiJldmlsIjwvYy0+PGMtIHA+KTs8L2MtPiA8Yy0gcD59PC9j
LT4KICAgICAgICA8Yy0gbj5NPC9jLT48Yy0gcD4oPC9jLT48Yy0gaz5jb25zdDwvYy0+IDxjLSBu
Pk08L2MtPjxjLSBvPiZhbXA7PC9jLT48Yy0gcD4pPC9jLT4gPGMtIG8+PTwvYy0+IDxjLSBrPmRl
ZmF1bHQ8L2MtPjxjLSBwPjs8L2MtPgogICAgPGMtIHA+fTs8L2MtPgogICAgPGMtIGs+c3RydWN0
PC9jLT4gPGMtIG4+VDwvYy0+IDxjLSBwPns8L2MtPgogICAgICAgIDxjLSBrPm11dGFibGU8L2Mt
PiA8Yy0gbj5NPC9jLT4gPGMtIG4+bTwvYy0+PGMtIHA+OzwvYy0+CiAgICAgICAgPGMtIG8+fjwv
Yy0+PGMtIG4+VDwvYy0+PGMtIHA+KCk8L2MtPiA8Yy0gbz49PC9jLT4gPGMtIGs+ZGVmYXVsdDwv
Yy0+PGMtIHA+OzwvYy0+CiAgICA8Yy0gcD59OzwvYy0+CiAgICA8Yy0gaz5zdGF0aWNfYXNzZXJ0
PC9jLT48Yy0gcD4oPC9jLT4gPGMtIG4+c3RkPC9jLT48Yy0gbz46OjwvYy0+PGMtIG4+aXNfdHJp
dmlhbGx5X3JlbG9jYXRhYmxlX3Y8L2MtPjxjLSBvPiZsdDs8L2MtPjxjLSBuPk08L2MtPjxjLSBv
Pj48L2MtPiA8Yy0gcD4pOzwvYy0+CiAgICA8Yy0gaz5zdGF0aWNfYXNzZXJ0PC9jLT48Yy0gcD4o
PC9jLT4gPGMtIG8+ITwvYy0+PGMtIG4+c3RkPC9jLT48Yy0gbz46OjwvYy0+PGMtIG4+aXNfdHJp
dmlhbGx5X3JlbG9jYXRhYmxlX3Y8L2MtPjxjLSBvPiZsdDs8L2MtPjxjLSBuPlQ8L2MtPjxjLSBv
Pj48L2MtPiA8Yy0gcD4pOzwvYy0+CjwvcHJlPgogICAgVGhlIGRlY2xhcmF0aW9uIDxjb2RlIGNs
YXNzPSJoaWdobGlnaHQiPjxjLSBuPk08L2MtPiA8Yy0gbmY+bTI8L2MtPjxjLSBwPig8L2MtPjxj
LSBuPnN0ZDwvYy0+PGMtIG8+Ojo8L2MtPjxjLSBuPm1vdmU8L2MtPjxjLSBwPig8L2MtPjxjLSBu
Pm08L2MtPjxjLSBwPikpOzwvYy0+PC9jb2RlPiBjYXVzZXMgYSBjYWxsIHRvIHRoZSB0cml2aWFs
LCBkZWZhdWx0ZWQgY29weSBjb25zdHJ1Y3RvciA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0g
bj5NPC9jLT48Yy0gcD4oPC9jLT48Yy0gaz5jb25zdDwvYy0+IDxjLSBuPk08L2MtPjxjLSBvPiZh
bXA7PC9jLT48Yy0gcD4pPC9jLT48L2NvZGU+LCBhbmQgPGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+
PGMtIG4+TTwvYy0+PC9jb2RlPiBpcyB0cml2aWFsbHkgZGVzdHJ1Y3RpYmxlIGFzIHdlbGwsIHNv
IHdlIHdvdWxkIGxpa2UgPGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMtIG4+TTwvYy0+PC9jb2Rl
PiB0byBiZSB0cml2aWFsbHkgcmVsb2NhdGFibGUuIEJ1dCB0aGUgZGVjbGFyYXRpb24gPGNvZGUg
Y2xhc3M9ImhpZ2hsaWdodCI+PGMtIG4+VDwvYy0+IDxjLSBuZj50MjwvYy0+PGMtIHA+KDwvYy0+
PGMtIG4+c3RkPC9jLT48Yy0gbz46OjwvYy0+PGMtIG4+bW92ZTwvYy0+PGMtIHA+KDwvYy0+PGMt
IG4+dDwvYy0+PGMtIHA+KSk7PC9jLT48L2NvZGU+IHN1cnByaXNpbmdseSBjYXVzZXMgYSBjYWxs
IHRvIHRoZSB1c2VyLXByb3ZpZGVkIDxjb2RlIGNsYXNzPSJoaWdobGlnaHQiPjxjLSBuPk08L2Mt
PjxjLSBwPig8L2MtPjxjLSBuPk08L2MtPjxjLSBvPiZhbXA7PC9jLT48Yy0gcD4pPC9jLT48L2Nv
ZGU+LCBzbyA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gbj5UPC9jLT48L2NvZGU+IGNhbm5v
dCBwb3NzaWJseSBiZSB0cml2aWFsbHkKcmVsb2NhdGFibGUuIEl0IG1heSBiZSBvdmVybHkgY29u
c2VydmF0aXZlIG9mIHVzIHRvIGJhbiA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gaz5tdXRh
YmxlPC9jLT48L2NvZGU+IG1lbWJlcnMsIGJ1dCBhdCBsZWFzdCB3ZSBrbm93IGl0IGlzIDxlbT5z
dWZmaWNpZW50bHk8L2VtPiBjb25zZXJ2YXRpdmUuIEFzIGFsd2F5cywgdGhlIHByb2dyYW1tZXIg
bWF5IGV4cGxpY2l0bHkgb3ZlcnJpZGUgdGhlIGNvbXBpbGVy4oCZcyBqdWRnbWVudCBieSBkZWNs
YXJpbmcgPGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMtIG4+VDwvYy0+PC9jb2RlPiBhcyA8Y29k
ZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gcD5bWzwvYy0+PGMtIG4+dHJpdmlhbGx5X3JlbG9jYXRh
YmxlPC9jLT48Yy0gcD5dXTwvYy0+PC9jb2RlPi4gCiAgIDwvZGl2PgogICA8aDMgY2xhc3M9Imhl
YWRpbmcgc2V0dGxlZCIgZGF0YS1sZXZlbD0iNC41IiBpZD0id29yZGluZy1hdHRyaWJ1dGUiPjxz
cGFuIGNsYXNzPSJzZWNubyI+NC41LiA8L3NwYW4+PHNwYW4gY2xhc3M9ImNvbnRlbnQiPjxjb2Rl
IGNsYXNzPSJoaWdobGlnaHQiPjxjLSBwPltbPC9jLT48Yy0gbj50cml2aWFsbHlfcmVsb2NhdGFi
bGU8L2MtPjxjLSBwPl1dPC9jLT48L2NvZGU+IGF0dHJpYnV0ZTwvc3Bhbj48YSBjbGFzcz0ic2Vs
Zi1saW5rIiBocmVmPSIjd29yZGluZy1hdHRyaWJ1dGUiPjwvYT48L2gzPgogICA8cD5BZGQgYSBu
ZXcgc2VjdGlvbiBhZnRlciA8YSBocmVmPSJodHRwOi8vZWVsLmlzL2MrK2RyYWZ0L2RjbC5hdHRy
Lm5vdW5pcXVlYWRkciI+W2RjbC5hdHRyLm5vdW5pcXVlYXR0cl08L2E+OjwvcD4KICAgPHA+PHNt
YWxsPjwvc21hbGw+PC9wPgogICA8YmxvY2txdW90ZT48c21hbGw+IFRoZSA8ZW0+YXR0cmlidXRl
LXRva2VuPC9lbT4gPGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMtIG4+dHJpdmlhbGx5X3JlbG9j
YXRhYmxlPC9jLT48L2NvZGU+IHNwZWNpZmllcyB0aGF0IGEgY2xhc3MgdHlwZeKAmXMgcmVsb2Nh
dGlvbiBvcGVyYXRpb24gaGFzIG5vCnZpc2libGUgc2lkZS1lZmZlY3RzIG90aGVyIHRoYW4gYSBj
b3B5IG9mIHRoZSB1bmRlcmx5aW5nIGJ5dGVzLCBhcyBpZiBieSB0aGUgbGlicmFyeSBmdW5jdGlv
biA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gbj5zdGQ8L2MtPjxjLSBvPjo6PC9jLT48Yy0g
bj5tZW1jcHk8L2MtPjwvY29kZT4uCkl0IHNoYWxsIGFwcGVhciBhdCBtb3N0IG9uY2UgaW4gZWFj
aCA8ZW0+YXR0cmlidXRlLWxpc3Q8L2VtPiBhbmQgbm8gPGVtPmF0dHJpYnV0ZS1hcmd1bWVudC1j
bGF1c2U8L2VtPiBzaGFsbCBiZSBwcmVzZW50LgpJdCBtYXkgYmUgYXBwbGllZCB0byB0aGUgZGVj
bGFyYXRpb24gb2YgYSBjbGFzcy4KVGhlIGZpcnN0IGRlY2xhcmF0aW9uIG9mIGEgdHlwZSBzaGFs
bCBzcGVjaWZ5IHRoZSA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gbj50cml2aWFsbHlfcmVs
b2NhdGFibGU8L2MtPjwvY29kZT4gYXR0cmlidXRlIGlmIGFueSBkZWNsYXJhdGlvbiBvZiB0aGF0
IHR5cGUKc3BlY2lmaWVzIHRoZSA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gbj50cml2aWFs
bHlfcmVsb2NhdGFibGU8L2MtPjwvY29kZT4gYXR0cmlidXRlLgpJZiBhIHR5cGUgaXMgZGVjbGFy
ZWQgd2l0aCB0aGUgPGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMtIG4+dHJpdmlhbGx5X3JlbG9j
YXRhYmxlPC9jLT48L2NvZGU+IGF0dHJpYnV0ZSBpbiBvbmUgdHJhbnNsYXRpb24gdW5pdCBhbmQg
dGhlCnNhbWUgdHlwZSBpcyBkZWNsYXJlZCB3aXRob3V0IHRoZSA8Y29kZSBjbGFzcz0iaGlnaGxp
Z2h0Ij48Yy0gbj50cml2aWFsbHlfcmVsb2NhdGFibGU8L2MtPjwvY29kZT4gYXR0cmlidXRlIGlu
IGFub3RoZXIgdHJhbnNsYXRpb24gdW5pdCwKdGhlIHByb2dyYW0gaXMgaWxsLWZvcm1lZCwgbm8g
ZGlhZ25vc3RpYyByZXF1aXJlZC48cD48L3A+IDxwPklmIGEgdHlwZSA8Y29kZSBjbGFzcz0iaGln
aGxpZ2h0Ij48Yy0gbj5UPC9jLT48L2NvZGU+IGlzIGRlY2xhcmVkIHdpdGggdGhlIDxjb2RlIGNs
YXNzPSJoaWdobGlnaHQiPjxjLSBuPnRyaXZpYWxseV9yZWxvY2F0YWJsZTwvYy0+PC9jb2RlPiBh
dHRyaWJ1dGUsIGFuZCA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gbj5UPC9jLT48L2NvZGU+
IGlzIGVpdGhlciBub3QgbW92ZS1jb25zdHJ1Y3RpYmxlCm9yIG5vdCBkZXN0cnVjdGlibGUsIHRo
ZSBwcm9ncmFtIGlzIGlsbC1mb3JtZWQuPC9wPiA8cD5JZiBhIGNsYXNzIHR5cGUgaXMgZGVjbGFy
ZWQgd2l0aCB0aGUgPGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMtIG4+dHJpdmlhbGx5X3JlbG9j
YXRhYmxlPC9jLT48L2NvZGU+IGF0dHJpYnV0ZSwgdGhlIGltcGxlbWVudGF0aW9uIG1heSByZXBs
YWNlCnJlbG9jYXRpb24gb3BlcmF0aW9ucyBpbnZvbHZpbmcgdGhhdCB0eXBlIChzdWNoIGFzIHRo
b3NlIHBlcmZvcm1lZCBieSB0aGUgbGlicmFyeSBmdW5jdGlvbnMgPGNvZGUgY2xhc3M9ImhpZ2hs
aWdodCI+PGMtIG4+c3RkPC9jLT48Yy0gbz46OjwvYy0+PGMtIG4+c3dhcDwvYy0+PC9jb2RlPiBh
bmQgPGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMtIG4+c3RkPC9jLT48Yy0gbz46OjwvYy0+PGMt
IG4+dmVjdG9yPC9jLT48Yy0gbz46OjwvYy0+PGMtIG4+cmVzaXplPC9jLT48L2NvZGU+KSB3aXRo
IHNpbXBsZSBjb3BpZXMgb2YgdGhlIHVuZGVybHlpbmcgYnl0ZXMuPC9wPiA8cD5JZiBhIGNsYXNz
IHR5cGUgaXMgZGVjbGFyZWQgd2l0aCB0aGUgPGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMtIG4+
dHJpdmlhbGx5X3JlbG9jYXRhYmxlPC9jLT48L2NvZGU+IGF0dHJpYnV0ZSwgYW5kIHRoZSBwcm9n
cmFtIHJlbGllcyBvbgpvYnNlcnZhYmxlIHNpZGUtZWZmZWN0cyBvZiByZWxvY2F0aW9uIG90aGVy
IHRoYW4gYSBjb3B5IG9mIHRoZSB1bmRlcmx5aW5nIGJ5dGVzLCB0aGUgYmVoYXZpb3IgaXMgdW5k
ZWZpbmVkLjwvcD4gPC9zbWFsbD48L2Jsb2NrcXVvdGU+CiAgIDxoMyBjbGFzcz0iaGVhZGluZyBz
ZXR0bGVkIiBkYXRhLWxldmVsPSI0LjYiIGlkPSJ3b3JkaW5nLXRyYWl0cyI+PHNwYW4gY2xhc3M9
InNlY25vIj40LjYuIDwvc3Bhbj48c3BhbiBjbGFzcz0iY29udGVudCI+VHlwZSB0cmFpdHMgPGNv
ZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMtIG4+aXNfcmVsb2NhdGFibGU8L2MtPjwvY29kZT4gZXRj
Ljwvc3Bhbj48YSBjbGFzcz0ic2VsZi1saW5rIiBocmVmPSIjd29yZGluZy10cmFpdHMiPjwvYT48
L2gzPgogICA8cD5BZGQgbmV3IGVudHJpZXMgdG8gVGFibGUgNDYgaW4gPGEgaHJlZj0iaHR0cDov
L2VlbC5pcy9jKytkcmFmdC9tZXRhLnVuYXJ5LnByb3AiPlttZXRhLnVuYXJ5LnByb3BdPC9hPjo8
L3A+CiAgIDxwPjxzbWFsbD48L3NtYWxsPjwvcD4KICAgPGJsb2NrcXVvdGU+CiAgICA8cD48L3A+
CiAgICA8c21hbGw+IDx0YWJsZT4gPHRib2R5Pjx0cj48dGg+VGVtcGxhdGU8L3RoPjx0aD5Db25k
aXRpb248L3RoPjx0aD5QcmVjb25kaXRpb25zPC90aD48L3RyPiA8dHI+IDx0ZD48Y29kZSBjbGFz
cz0iaGlnaGxpZ2h0Ij48Yy0gaz50ZW1wbGF0ZTwvYy0+PGMtIG8+Jmx0OzwvYy0+PGMtIGs+Y2xh
c3M8L2MtPiA8Yy0gbmM+VDwvYy0+PGMtIG8+PjwvYy0+IDxjLSBrPnN0cnVjdDwvYy0+IDxjLSBu
PmlzX3JlbG9jYXRhYmxlPC9jLT48Yy0gcD47PC9jLT48L2NvZGU+PC90ZD4gPHRkPjxjb2RlIGNs
YXNzPSJoaWdobGlnaHQiPjxjLSBuPmlzX21vdmVfY29uc3RydWN0aWJsZV92PC9jLT48Yy0gbz4m
bHQ7PC9jLT48Yy0gbj5UPC9jLT48Yy0gbz4+PC9jLT48L2NvZGU+IGlzIDxjb2RlIGNsYXNzPSJo
aWdobGlnaHQiPnRydWU8L2NvZGU+IGFuZCA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gbj5p
c19kZXN0cnVjdGlibGVfdjwvYy0+PGMtIG8+Jmx0OzwvYy0+PGMtIG4+VDwvYy0+PGMtIG8+Pjwv
Yy0+PC9jb2RlPiBpcyA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij50cnVlPC9jb2RlPjwvdGQ+IDx0
ZD5UIHNoYWxsIGJlIGEgY29tcGxldGUgdHlwZSwgPGk+Y3Y8L2k+IDxjb2RlIGNsYXNzPSJoaWdo
bGlnaHQiPjxjLSBiPnZvaWQ8L2MtPjwvY29kZT4sIG9yIGFuIGFycmF5IG9mIHVua25vd24gYm91
bmQuPC90ZD4gPC90cj4gPHRyPiA8dGQ+PGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMtIGs+dGVt
cGxhdGU8L2MtPjxjLSBvPiZsdDs8L2MtPjxjLSBrPmNsYXNzPC9jLT4gPGMtIG5jPlQ8L2MtPjxj
LSBvPj48L2MtPiA8Yy0gaz5zdHJ1Y3Q8L2MtPiA8Yy0gbj5pc19ub3Rocm93X3JlbG9jYXRhYmxl
PC9jLT48Yy0gcD47PC9jLT48L2NvZGU+PC90ZD4gPHRkPjxjb2RlIGNsYXNzPSJoaWdobGlnaHQi
PjxjLSBuPmlzX3JlbG9jYXRhYmxlX3Y8L2MtPjxjLSBvPiZsdDs8L2MtPjxjLSBuPlQ8L2MtPjxj
LSBvPj48L2MtPjwvY29kZT4gaXMgPGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+dHJ1ZTwvY29kZT4g
YW5kIGJvdGggdGhlIGluZGljYXRlZCBtb3ZlLWNvbnN0cnVjdG9yIGFuZCB0aGUgZGVzdHJ1Y3Rv
ciBhcmUga25vd24gbm90IHRvIHRocm93IGFueSBleGNlcHRpb25zLjwvdGQ+IDx0ZD5UIHNoYWxs
IGJlIGEgY29tcGxldGUgdHlwZSwgPGk+Y3Y8L2k+IDxjb2RlIGNsYXNzPSJoaWdobGlnaHQiPjxj
LSBiPnZvaWQ8L2MtPjwvY29kZT4sIG9yIGFuIGFycmF5IG9mIHVua25vd24gYm91bmQuPC90ZD4g
PC90cj4gPHRyPiA8dGQ+PGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMtIGs+dGVtcGxhdGU8L2Mt
PjxjLSBvPiZsdDs8L2MtPjxjLSBrPmNsYXNzPC9jLT4gPGMtIG5jPlQ8L2MtPjxjLSBvPj48L2Mt
PiA8Yy0gaz5zdHJ1Y3Q8L2MtPiA8Yy0gbj5pc190cml2aWFsbHlfcmVsb2NhdGFibGU8L2MtPjxj
LSBwPjs8L2MtPjwvY29kZT48L3RkPiA8dGQ+PGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMtIG4+
VDwvYy0+PC9jb2RlPiBpcyBhIDxhIGRhdGEtbGluay10eXBlPSJhYnN0cmFjdC1vcCIgaHJlZj0i
I2Fic3RyYWN0LW9wZGVmLXRyaXZpYWxseS1yZWxvY2F0YWJsZSIgaWQ9InJlZi1mb3ItYWJzdHJh
Y3Qtb3BkZWYtdHJpdmlhbGx5LXJlbG9jYXRhYmxl4pGgIj50cml2aWFsbHkgcmVsb2NhdGFibGU8
L2E+IHR5cGUuPC90ZD4gPHRkPlQgc2hhbGwgYmUgYSBjb21wbGV0ZSB0eXBlLCA8aT5jdjwvaT4g
PGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMtIGI+dm9pZDwvYy0+PC9jb2RlPiwgb3IgYW4gYXJy
YXkgb2YgdW5rbm93biBib3VuZC48L3RkPiA8L3RyPiA8L3Rib2R5PjwvdGFibGU+IDwvc21hbGw+
CiAgIDwvYmxvY2txdW90ZT4KICAgPGgzIGNsYXNzPSJoZWFkaW5nIHNldHRsZWQiIGRhdGEtbGV2
ZWw9IjQuNyIgaWQ9IndvcmRpbmctY29uY2VwdCI+PHNwYW4gY2xhc3M9InNlY25vIj40LjcuIDwv
c3Bhbj48c3BhbiBjbGFzcz0iY29udGVudCI+PGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMtIG4+
UmVsb2NhdGFibGU8L2MtPjwvY29kZT4gY29uY2VwdDwvc3Bhbj48YSBjbGFzcz0ic2VsZi1saW5r
IiBocmVmPSIjd29yZGluZy1jb25jZXB0Ij48L2E+PC9oMz4KICAgPHA+QWRkIGEgbmV3IHNlY3Rp
b24gYWZ0ZXIgPGEgaHJlZj0iaHR0cDovL2VlbC5pcy9jKytkcmFmdC9jb25jZXB0Lm1vdmVjb25z
dHJ1Y3RpYmxlIj5bY29uY2VwdC5tb3ZlY29uc3RydWN0aWJsZV08L2E+OjwvcD4KICAgPHA+PHNt
YWxsPjwvc21hbGw+PC9wPgogICA8YmxvY2txdW90ZT4KICAgIDxwPjwvcD4KICAgIDxzbWFsbD4g
PHByZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gaz50ZW1wbGF0ZTwvYy0+PGMtIG8+Jmx0OzwvYy0+
PGMtIGs+Y2xhc3M8L2MtPiA8Yy0gbmM+VDwvYy0+PGMtIG8+PjwvYy0+CiAgPGMtIG4+Y29uY2Vw
dDwvYy0+IDxjLSBuPlJlbG9jYXRhYmxlPC9jLT4gPGMtIG8+PTwvYy0+IDxjLSBuPk1vdmVDb25z
dHJ1Y3RpYmxlPC9jLT48Yy0gbz4mbHQ7PC9jLT48Yy0gbj5UPC9jLT48Yy0gbz4+PC9jLT4gPGMt
IG8+JmFtcDsmYW1wOzwvYy0+IDxjLSBuPkRlc3RydWN0aWJsZTwvYy0+PGMtIG8+Jmx0OzwvYy0+
PGMtIG4+VDwvYy0+PGMtIG8+PjwvYy0+PGMtIHA+OzwvYy0+CjwvcHJlPiA8cD48ZW0+Tm90ZTo8
L2VtPiBUaGlzIGNvbmNlcHQgaXMgZXhhY3RseSBlcXVpdmFsZW50IHRvIDxjb2RlIGNsYXNzPSJo
aWdobGlnaHQiPjxjLSBuPk1vdmVDb25zdHJ1Y3RpYmxlPC9jLT48Yy0gbz4mbHQ7PC9jLT48Yy0g
bj5UPC9jLT48Yy0gbz4+PC9jLT48L2NvZGU+LjwvcD4gPC9zbWFsbD4KICAgPC9ibG9ja3F1b3Rl
PgogICA8aDIgY2xhc3M9ImhlYWRpbmcgc2V0dGxlZCIgZGF0YS1sZXZlbD0iNSIgaWQ9ImZ1cnRo
ZXIiPjxzcGFuIGNsYXNzPSJzZWNubyI+NS4gPC9zcGFuPjxzcGFuIGNsYXNzPSJjb250ZW50Ij5G
dXJ0aGVyIGNvbnNpZGVyYXRpb25zIGFuZCBkaXJlY3Rpb25zPC9zcGFuPjxhIGNsYXNzPSJzZWxm
LWxpbmsiIGhyZWY9IiNmdXJ0aGVyIj48L2E+PC9oMj4KICAgPGgzIGNsYXNzPSJoZWFkaW5nIHNl
dHRsZWQiIGRhdGEtbGV2ZWw9IjUuMSIgaWQ9InRyaXZpYWxseS1zd2FwcGFibGUiPjxzcGFuIGNs
YXNzPSJzZWNubyI+NS4xLiA8L3NwYW4+PHNwYW4gY2xhc3M9ImNvbnRlbnQiPlRyaXZpYWxseSBz
d2FwcGFibGUgdHlwZXM8L3NwYW4+PGEgY2xhc3M9InNlbGYtbGluayIgaHJlZj0iI3RyaXZpYWxs
eS1zd2FwcGFibGUiPjwvYT48L2gzPgogICA8cD48YSBkYXRhLWxpbmstdHlwZT0iYmlibGlvIiBo
cmVmPSIjYmlibGlvLXdhbmciPk1pbmd4aW4gV2FuZyBoYXMgcHJvcG9zZWQ8L2E+IHRoYXQgInN3
YXAiCmNvdWxkIGJlIGV4cHJlc3NlZCBpbiB0ZXJtcyBvZiAicmVsb2NhdGUiLiA8Y29kZSBjbGFz
cz0iaGlnaGxpZ2h0Ij48Yy0gbj5zdGQ8L2MtPjxjLSBvPjo6PC9jLT48Yy0gbj5zd2FwPC9jLT48
L2NvZGU+IHRvZGF5IGlzCnR5cGljYWxseSBpbXBsZW1lbnRlZCBpbiB0ZXJtcyBvZiBvbmUgbW92
ZS1jb25zdHJ1Y3Rpb24sIHR3byBtb3ZlLWFzc2lnbm1lbnRzLAphbmQgb25lIGRlc3RydWN0aW9u
OyBidXQgdGhlcmUgaXMgbm90aGluZyBpbiB0aGUgU3RhbmRhcmQgdGhhdCBwcmV2ZW50cyBhIGxp
YnJhcnkKdmVuZG9yIGZyb20gaW1wbGVtZW50aW5nIGl0IGFzIHRocmVlIHJlbG9jYXRpb25zLCB3
aGljaCBpbiB0aGUgdHJpdmlhbGx5LXJlbG9jYXRhYmxlCmNhc2UgKHRoZSB1c3VhbCBjYXNlIGZv
ciBtb3N0IHR5cGVzKSBjb3VsZCBiZSBvcHRpbWl6ZWQgaW50byB0aHJlZSBjYWxscyB0byA8Y29k
ZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gbj5tZW1jcHk8L2MtPjwvY29kZT4uPC9wPgogICA8cD5G
b3IgcmVhc29ucyA8YSBkYXRhLWxpbmstdHlwZT0iYmlibGlvIiBocmVmPSIjYmlibGlvLXNhbmUi
PmRlc2NyaWJlZCBlbHNld2hlcmU8L2E+LCBpdCBzZWVtcyByZWFzb25hYmxlCnRvIGNsYWltIHRo
YXQgbW92ZS1hc3NpZ25tZW50IG11c3QgYWx3YXlzICJkbyB0aGUgc2FuZSB0aGluZywiIGFuZCB0
aGVyZWZvcmUgd2UKbWlnaHQgcHJvcG9zZSB0byBkZWZpbmUgPHNtYWxsPjwvc21hbGw+PC9wPgog
ICA8c21hbGw+IDxwcmUgY2xhc3M9Imxhbmd1YWdlLWMrKyBoaWdobGlnaHQiPjxjLSBuPnRlbXBs
YXRlPC9jLT48Yy0gbz4mbHQ7PC9jLT48Yy0gbj5jbGFzczwvYy0+IDxjLSBuPlQ8L2MtPjxjLSBv
Pj48L2MtPgo8Yy0gaz5zdHJ1Y3Q8L2MtPiA8Yy0gbmw+aXNfdHJpdmlhbGx5X3N3YXBwYWJsZTwv
Yy0+IDxjLSBwPjo8L2MtPiA8Yy0gbj5ib29sX2NvbnN0YW50PC9jLT48Yy0gbz4mbHQ7PC9jLT4K
ICAgIDxjLSBuPmlzX3RyaXZpYWxseV9yZWxvY2F0YWJsZV92PC9jLT48Yy0gbz4mbHQ7PC9jLT48
Yy0gbj5UPC9jLT48Yy0gbz4+PC9jLT4gPGMtIG8+JmFtcDsmYW1wOzwvYy0+CiAgICA8Yy0gbj5p
c19tb3ZlX2Fzc2lnbmFibGVfdjwvYy0+PGMtIG8+Jmx0OzwvYy0+PGMtIG4+VDwvYy0+PGMtIG8+
PjwvYy0+CjxjLSBvPj48L2MtPiA8Yy0gcD57fTs8L2MtPgo8L3ByZT48L3NtYWxsPiB0aHVzIGNv
bXBsZXRpbmcgdGhlIGN1cnJlbnRseS1pbmNvbXBsZXRlIHRyaW8gd2l0aCA8Y29kZSBjbGFzcz0i
aGlnaGxpZ2h0Ij48Yy0gbj5pc19zd2FwcGFibGU8L2MtPjwvY29kZT4gYW5kIDxjb2RlIGNsYXNz
PSJoaWdobGlnaHQiPjxjLSBuPmlzX25vdGhyb3dfc3dhcHBhYmxlPC9jLT48L2NvZGU+LiAKICAg
PHA+SG93ZXZlciwgd2UgZG8gbm90IHByb3Bvc2UgInRyaXZpYWxseSBzd2FwcGFibGUiIGF0IHRo
ZSBwcmVzZW50IHRpbWUuCkl0IGNhbiBlYXNpbHkgYmUgYWRkZWQgaW4gYSBsYXRlciBwYXBlci48
L3A+CiAgIDxoMyBjbGFzcz0iaGVhZGluZyBzZXR0bGVkIiBkYXRhLWxldmVsPSI1LjIiIGlkPSJo
ZXRlcm8iPjxzcGFuIGNsYXNzPSJzZWNubyI+NS4yLiA8L3NwYW4+PHNwYW4gY2xhc3M9ImNvbnRl
bnQiPkhldGVyb2dlbmVvdXMgcmVsb2NhdGlvbjwvc3Bhbj48YSBjbGFzcz0ic2VsZi1saW5rIiBo
cmVmPSIjaGV0ZXJvIj48L2E+PC9oMz4KICAgPHA+Q29uc2lkZXIgdGhhdCA8Y29kZSBjbGFzcz0i
aGlnaGxpZ2h0Ij48Yy0gbj5pc19yZWxvY2F0YWJsZV92PC9jLT48Yy0gbz4mbHQ7PC9jLT48Yy0g
bj5UPC9jLT48Yy0gbz4+PC9jLT48L2NvZGU+IG1lYW5zIDxjb2RlIGNsYXNzPSJoaWdobGlnaHQi
PjxjLSBuPmlzX2NvbnN0cnVjdGlibGVfdjwvYy0+PGMtIG8+Jmx0OzwvYy0+PGMtIG4+VDwvYy0+
PGMtIHA+LDwvYy0+PGMtIG4+VDwvYy0+PGMtIG8+JmFtcDsmYW1wOz48L2MtPiA8Yy0gbj5hbmQ8
L2MtPiA8Yy0gbj5pc19kZXN0cnVjdGlibGVfdjwvYy0+PGMtIG8+Jmx0OzwvYy0+PGMtIG4+VDwv
Yy0+PGMtIG8+PjwvYy0+PC9jb2RlPi4KV2UgaGF2ZSBhY2Nlc3MgdG8gYSBoZXRlcm9nZW5lb3Vz
IDxjb2RlIGNsYXNzPSJoaWdobGlnaHQiPjxjLSBuPmlzX2NvbnN0cnVjdGlibGU8L2MtPjxjLSBv
PiZsdDs8L2MtPjxjLSBuPlQ8L2MtPjxjLSBwPiw8L2MtPiA8Yy0gbj5VczwvYy0+PGMtIHA+Li4u
PC9jLT48Yy0gbz4+PC9jLT48L2NvZGU+LgpTaG91bGQgd2UgYWRkIGEgaGV0ZXJvZ2VuZW91cyA8
Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gbj5pc19yZWxvY2F0YWJsZV9mcm9tPC9jLT48Yy0g
bz4mbHQ7PC9jLT48Yy0gbj5UPC9jLT48Yy0gcD4sPC9jLT4gPGMtIG4+VTwvYy0+PGMtIG8+Pjwv
Yy0+PC9jb2RlPj88L3A+CiAgIDxwPk5vdGljZSB0aGF0IDxjb2RlIGNsYXNzPSJoaWdobGlnaHQi
PjxjLSBuPnVuaW5pdGlhbGl6ZWRfY29weTwvYy0+PC9jb2RlPiBhbmQgPGNvZGUgY2xhc3M9Imhp
Z2hsaWdodCI+PGMtIG4+dW5pbml0aWFsaXplZF9tb3ZlPC9jLT48L2NvZGU+IGFyZSBhbHJlYWR5
IGhldGVyb2dlbmVvdXMuCkhlcmUgaXMgd2hhdCBhIGhldGVyb2dlbmVvdXMgPGNvZGUgY2xhc3M9
ImhpZ2hsaWdodCI+PGMtIG4+dW5pbml0aWFsaXplZF9yZWxvY2F0ZTwvYy0+PC9jb2RlPiB3b3Vs
ZCBsb29rIGxpa2UuPC9wPgogICA8cD48c21hbGw+PC9zbWFsbD48L3A+CiAgIDxzbWFsbD4gPHBy
ZSBjbGFzcz0ibGFuZ3VhZ2UtYysrIGhpZ2hsaWdodCI+PGMtIG4+dGVtcGxhdGU8L2MtPjxjLSBv
PiZsdDs8L2MtPjxjLSBuPmNsYXNzPC9jLT4gPGMtIG4+RndkSXQ8L2MtPjxjLSBwPiw8L2MtPiA8
Yy0gbj5jbGFzczwvYy0+IDxjLSBuPk91dEl0PC9jLT48Yy0gbz4+PC9jLT4KPGMtIGI+dm9pZDwv
Yy0+IDxjLSBuPnVuaW5pdGlhbGl6ZWRfcmVsb2NhdGU8L2MtPjxjLSBwPig8L2MtPjxjLSBuPkZ3
ZEl0PC9jLT4gPGMtIG4+Zmlyc3Q8L2MtPjxjLSBwPiw8L2MtPiA8Yy0gbj5Gd2RJdDwvYy0+IDxj
LSBuPmxhc3Q8L2MtPjxjLSBwPiw8L2MtPiA8Yy0gbj5PdXRJdDwvYy0+IDxjLSBuPmRfZmlyc3Q8
L2MtPjxjLSBwPik8L2MtPiA8Yy0gcD57PC9jLT4KICAgIDxjLSBuPnVzaW5nPC9jLT4gPGMtIG4+
U3JjVDwvYy0+IDxjLSBvPj08L2MtPiA8Yy0gbj5yZW1vdmVfY3ZyZWZfdDwvYy0+PGMtIG8+Jmx0
OzwvYy0+PGMtIG4+ZGVjbHR5cGU8L2MtPjxjLSBwPig8L2MtPjxjLSBvPio8L2MtPjxjLSBuPmZp
cnN0PC9jLT48Yy0gcD4pPC9jLT48Yy0gbz4+PC9jLT48Yy0gcD47PC9jLT4KICAgIDxjLSBuPnVz
aW5nPC9jLT4gPGMtIG4+RHN0VDwvYy0+IDxjLSBvPj08L2MtPiA8Yy0gbj5yZW1vdmVfY3ZyZWZf
dDwvYy0+PGMtIG8+Jmx0OzwvYy0+PGMtIG4+ZGVjbHR5cGU8L2MtPjxjLSBwPig8L2MtPjxjLSBv
Pio8L2MtPjxjLSBuPmRfZmlyc3Q8L2MtPjxjLSBwPik8L2MtPjxjLSBvPj48L2MtPjxjLSBwPjs8
L2MtPgogICAgPGMtIG4+c3RhdGljX2Fzc2VydDwvYy0+PGMtIHA+KDwvYy0+PGMtIG4+aXNfcmVs
b2NhdGFibGVfZnJvbV92PC9jLT48Yy0gbz4mbHQ7PC9jLT48Yy0gbj5Ec3RUPC9jLT48Yy0gcD4s
PC9jLT4gPGMtIG4+U3JjVDwvYy0+PGMtIG8+PjwvYy0+PGMtIHA+KTs8L2MtPgogICAgPGMtIGs+
aWY8L2MtPiA8Yy0gbmY+Y29uc3RleHByPC9jLT4gPGMtIHA+KDwvYy0+PGMtIG4+aXNfdHJpdmlh
bGx5X3JlbG9jYXRhYmxlX2Zyb21fdjwvYy0+PGMtIG8+Jmx0OzwvYy0+PGMtIG4+RHN0VDwvYy0+
PGMtIHA+LDwvYy0+IDxjLSBuPlNyY1Q8L2MtPjxjLSBvPj48L2MtPjxjLSBwPik8L2MtPiA8Yy0g
cD57PC9jLT4KICAgICAgICA8Yy0gbj5zdGF0aWNfYXNzZXJ0PC9jLT48Yy0gcD4oPC9jLT48Yy0g
az5zaXplb2Y8L2MtPiA8Yy0gcD4oPC9jLT48Yy0gbj5TcmNUPC9jLT48Yy0gcD4pPC9jLT4gPGMt
IG8+PT08L2MtPiA8Yy0gaz5zaXplb2Y8L2MtPjxjLSBwPig8L2MtPjxjLSBuPkRzdFQ8L2MtPjxj
LSBwPikpOzwvYy0+CiAgICAgICAgPGMtIGs+aWY8L2MtPiA8Yy0gbj5jb25zdGV4cHI8L2MtPiA8
Yy0gcD4oPC9jLT48Yy0gbj5pc19wb2ludGVyX3Y8L2MtPjxjLSBvPiZsdDs8L2MtPjxjLSBuPkZ3
ZEl0PC9jLT48Yy0gbz4+PC9jLT4gPGMtIG8+JmFtcDsmYW1wOzwvYy0+IDxjLSBuPmlzX3BvaW50
ZXJfdjwvYy0+PGMtIG8+Jmx0OzwvYy0+PGMtIG4+T3V0SXQ8L2MtPjxjLSBvPj48L2MtPjxjLSBw
Pik8L2MtPiA8Yy0gcD57PC9jLT4KICAgICAgICAgICAgPGMtIGMxPi8vIFRyaXZpYWwgcmVsb2Nh
dGlvbiArIGNvbnRpZ3VvdXMgaXRlcmF0b3JzID0gbWVtY3B5PC9jLT4KICAgICAgICAgICAgPGMt
IGI+c2l6ZV90PC9jLT4gPGMtIG4+bjwvYy0+IDxjLSBvPj08L2MtPiA8Yy0gbj5sYXN0PC9jLT4g
PGMtIG8+LTwvYy0+IDxjLSBuPmZpcnN0PC9jLT48Yy0gcD47PC9jLT4KICAgICAgICAgICAgPGMt
IGs+aWY8L2MtPiA8Yy0gcD4oPC9jLT48Yy0gbj5uPC9jLT48Yy0gcD4pPC9jLT4gPGMtIG4+bWVt
Y3B5PC9jLT48Yy0gcD4oPC9jLT48Yy0gbj5kX2ZpcnN0PC9jLT48Yy0gcD4sPC9jLT4gPGMtIG4+
Zmlyc3Q8L2MtPjxjLSBwPiw8L2MtPiA8Yy0gbj5uPC9jLT4gPGMtIG8+KjwvYy0+IDxjLSBrPnNp
emVvZjwvYy0+IDxjLSBwPig8L2MtPjxjLSBuPlNyY1Q8L2MtPjxjLSBwPikpOzwvYy0+CiAgICAg
ICAgICAgIDxjLSBuPmRfZmlyc3Q8L2MtPiA8Yy0gbz4rPTwvYy0+IDxjLSBuPm48L2MtPjxjLSBw
Pjs8L2MtPgogICAgICAgIDxjLSBwPn08L2MtPiA8Yy0gaz5lbHNlPC9jLT4gPGMtIHA+ezwvYy0+
CiAgICAgICAgICAgIDxjLSBrPndoaWxlPC9jLT4gPGMtIHA+KDwvYy0+PGMtIG4+Zmlyc3Q8L2Mt
PiA8Yy0gbz4hPTwvYy0+IDxjLSBuPmxhc3Q8L2MtPjxjLSBwPik8L2MtPiA8Yy0gcD57PC9jLT4K
ICAgICAgICAgICAgICAgIDxjLSBuPm1lbWNweTwvYy0+PGMtIHA+KDwvYy0+PGMtIG4+YWRkcmVz
c29mPC9jLT48Yy0gcD4oPC9jLT48Yy0gbz4qPC9jLT48Yy0gbj5kX2ZpcnN0PC9jLT48Yy0gcD4p
LDwvYy0+IDxjLSBuPmFkZHJlc3NvZjwvYy0+PGMtIHA+KDwvYy0+PGMtIG8+KjwvYy0+PGMtIG4+
Zmlyc3Q8L2MtPjxjLSBwPiksPC9jLT4gPGMtIGs+c2l6ZW9mPC9jLT4gPGMtIHA+KDwvYy0+PGMt
IG4+U3JjVDwvYy0+PGMtIHA+KSk7PC9jLT4KICAgICAgICAgICAgICAgIDxjLSBvPisrPC9jLT48
Yy0gbj5kX2ZpcnN0PC9jLT48Yy0gcD47PC9jLT4gPGMtIG8+Kys8L2MtPjxjLSBuPmZpcnN0PC9j
LT48Yy0gcD47PC9jLT4KICAgICAgICAgICAgPGMtIHA+fTwvYy0+CiAgICAgICAgPGMtIHA+fTwv
Yy0+CiAgICA8Yy0gcD59PC9jLT4gPGMtIGs+ZWxzZTwvYy0+IDxjLSBwPns8L2MtPgogICAgICAg
IDxjLSBrPndoaWxlPC9jLT4gPGMtIHA+KDwvYy0+PGMtIG4+Zmlyc3Q8L2MtPiA8Yy0gbz4hPTwv
Yy0+IDxjLSBuPmxhc3Q8L2MtPjxjLSBwPik8L2MtPiA8Yy0gcD57PC9jLT4KICAgICAgICAgICAg
PGMtIG8+Ojo8L2MtPjxjLSBuPm5ldzwvYy0+IDxjLSBwPigoPC9jLT48Yy0gYj52b2lkPC9jLT48
Yy0gbz4qPC9jLT48Yy0gcD4pPC9jLT48Yy0gbj5hZGRyZXNzb2Y8L2MtPjxjLSBwPig8L2MtPjxj
LSBvPio8L2MtPjxjLSBuPmRfZmlyc3Q8L2MtPjxjLSBwPikpPC9jLT4gPGMtIG4+RHN0VDwvYy0+
PGMtIHA+KDwvYy0+PGMtIG4+bW92ZTwvYy0+PGMtIHA+KDwvYy0+PGMtIG8+KjwvYy0+PGMtIG4+
Zmlyc3Q8L2MtPjxjLSBwPikpOzwvYy0+CiAgICAgICAgICAgIDxjLSBwPig8L2MtPjxjLSBvPio8
L2MtPjxjLSBuPmZpcnN0PC9jLT48Yy0gcD4pLjwvYy0+PGMtIG8+fjwvYy0+PGMtIG4+U3JjVDwv
Yy0+PGMtIHA+KCk7PC9jLT4KICAgICAgICAgICAgPGMtIG8+Kys8L2MtPjxjLSBuPmRfZmlyc3Q8
L2MtPjxjLSBwPjs8L2MtPiA8Yy0gbz4rKzwvYy0+PGMtIG4+Zmlyc3Q8L2MtPjxjLSBwPjs8L2Mt
PgogICAgICAgIDxjLSBwPn08L2MtPgogICAgPGMtIHA+fTwvYy0+CiAgICA8Yy0gaz5yZXR1cm48
L2MtPiA8Yy0gbj5kX2ZpcnN0PC9jLT48Yy0gcD47PC9jLT4KPGMtIHA+fTwvYy0+CjwvcHJlPjwv
c21hbGw+IAogICA8cD5UaGlzIGltcGxlbWVudGF0aW9uIGNvdWxkIGJlIHVzZWQgdG8gcXVpY2ts
eSByZWxvY2F0ZSBhbiBhcnJheSBvZiA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gYj5pbnQ8
L2MtPjxjLSBvPio8L2MtPjwvY29kZT4gaW50byBhbiBhcnJheSBvZiA8Y29kZSBjbGFzcz0iaGln
aGxpZ2h0Ij48Yy0gbj51bmlxdWVfcHRyPC9jLT48Yy0gbz4mbHQ7PC9jLT48Yy0gYj5pbnQ8L2Mt
PjxjLSBvPj48L2MtPjwvY29kZT4gKGJ1dCBub3QgdmljZSB2ZXJzYSkuCkFsbCB3ZeKAmWQgbmVl
ZCBpcyBmb3Igc29tZWJvZHkgdG8gc2V0IHRoZSB2YWx1ZSBvZiA8Y29kZSBjbGFzcz0iaGlnaGxp
Z2h0Ij48Yy0gbj5pc190cml2aWFsbHlfcmVsb2NhdGFibGVfZnJvbTwvYy0+PC9jb2RlPiBhcHBy
b3ByaWF0ZWx5IGZvciBlYWNoIHBhaXIgb2YgdHlwZXMgaW4gdGhlIHByb2dyYW0uPC9wPgogICA8
cD5JIHRoaW5rIHRoaXMgaXMgYSB2ZXJ5IGludHJpZ3VpbmcgaWRlYS4gVGhlIGRldGVjdGlvbiBz
eW50YXggKDxjb2RlIGNsYXNzPSJoaWdobGlnaHQiPjxjLSBuPmlzX3RyaXZpYWxseV9yZWxvY2F0
YWJsZV9mcm9tPC9jLT48L2NvZGU+KQppcyBmYWlybHkgb2J2aW91cy4gQnV0IEkgZG9u4oCZdCBz
ZWUgd2hhdCB0aGUgb3B0LWluIHN5bnRheAp3b3VsZCBsb29rIGxpa2Ugb24gYSBwcm9ncmFtLWRl
ZmluZWQgY2xhc3Mgc3VjaCBhcyA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gbj50b21ic3Rv
bmU8L2MtPjxjLSBvPjo6PC9jLT48Yy0gbj5vcHRpb25hbDwvYy0+PC9jb2RlPi4KTGV04oCZcyBs
ZWF2ZSB0aGF0IHByb2JsZW0gYWxvbmUgZm9yIGEgZmV3IHllYXJzIGFuZCBzZWUgd2hhdCBkZXZl
bG9wcy48L3A+CiAgIDxwPldlIGNvdWxkIGNvbmNlaXZhYmx5IHByb3ZpZGUgdGhlIGRldGVjdGlv
biB0cmFpdCB0b2RheSwKd2l0aCBkZWxpYmVyYXRlbHkgY3VydGFpbGVkIHNlbWFudGljcywgZS5n
Ljo8L3A+CiAgIDxwPjxzbWFsbD48L3NtYWxsPjwvcD4KICAgPHNtYWxsPiA8cHJlIGNsYXNzPSJs
YW5ndWFnZS1jKysgaGlnaGxpZ2h0Ij4gICAgPGMtIG4+dGVtcGxhdGU8L2MtPjxjLSBvPiZsdDs8
L2MtPjxjLSBuPmNsYXNzPC9jLT4gPGMtIG4+VDwvYy0+PGMtIHA+LDwvYy0+IDxjLSBuPmNsYXNz
PC9jLT4gPGMtIG4+VTwvYy0+PGMtIG8+PjwvYy0+CiAgICA8Yy0gaz5zdHJ1Y3Q8L2MtPiA8Yy0g
bmw+aXNfdHJpdmlhbGx5X3JlbG9jYXRhYmxlX2Zyb208L2MtPiA8Yy0gcD46PC9jLT4gPGMtIG4+
Ym9vbF9jb25zdGFudDwvYy0+PGMtIG8+Jmx0OzwvYy0+CiAgICAgICAgPGMtIG4+aXNfdHJpdmlh
bGx5X3JlbG9jYXRhYmxlX3Y8L2MtPjxjLSBvPiZsdDs8L2MtPjxjLSBuPlQ8L2MtPjxjLSBvPj48
L2MtPiA8Yy0gbj5hbmQ8L2MtPgogICAgICAgIDxjLSBuPmlzX3NhbWVfdjwvYy0+PGMtIG8+Jmx0
OzwvYy0+PGMtIG4+VTwvYy0+PGMtIHA+LDwvYy0+IDxjLSBuPnJlbW92ZV9jdnJlZl90PC9jLT48
Yy0gbz4mbHQ7PC9jLT48Yy0gbj5UPC9jLT48Yy0gbz4+PjwvYy0+CiAgICA8Yy0gbz4+PC9jLT4g
PGMtIHA+e307PC9jLT4KICAgIDxjLSBuPnRlbXBsYXRlPC9jLT48Yy0gbz4mbHQ7PC9jLT48Yy0g
bj5jbGFzczwvYy0+IDxjLSBuPlQ8L2MtPjxjLSBwPiw8L2MtPiA8Yy0gbj5jbGFzczwvYy0+IDxj
LSBuPlU8L2MtPjxjLSBvPj48L2MtPgogICAgPGMtIGs+c3RydWN0PC9jLT4gPGMtIG4+aXNfdHJp
dmlhbGx5X3JlbG9jYXRhYmxlX2Zyb208L2MtPjxjLSBvPiZsdDs8L2MtPjxjLSBuPlQ8L2MtPjxj
LSBwPiw8L2MtPiA8Yy0gbj5VPC9jLT48Yy0gbz4mYW1wOz48L2MtPiA8Yy0gbz46PC9jLT4gPGMt
IG4+aXNfdHJpdmlhbGx5X3JlbG9jYXRhYmxlX2Zyb208L2MtPjxjLSBvPiZsdDs8L2MtPjxjLSBu
PlQ8L2MtPjxjLSBwPiw8L2MtPiA8Yy0gbj5VPC9jLT48Yy0gbz4+PC9jLT4gPGMtIHA+e307PC9j
LT4KICAgIDxjLSBuPnRlbXBsYXRlPC9jLT48Yy0gbz4mbHQ7PC9jLT48Yy0gbj5jbGFzczwvYy0+
IDxjLSBuPlQ8L2MtPjxjLSBwPiw8L2MtPiA8Yy0gbj5jbGFzczwvYy0+IDxjLSBuPlU8L2MtPjxj
LSBvPj48L2MtPgogICAgPGMtIGs+c3RydWN0PC9jLT4gPGMtIG4+aXNfdHJpdmlhbGx5X3JlbG9j
YXRhYmxlX2Zyb208L2MtPjxjLSBvPiZsdDs8L2MtPjxjLSBuPlQ8L2MtPjxjLSBwPiw8L2MtPiA8
Yy0gbj5VPC9jLT48Yy0gbz4mYW1wOyZhbXA7PjwvYy0+IDxjLSBvPjo8L2MtPiA8Yy0gbj5pc190
cml2aWFsbHlfcmVsb2NhdGFibGVfZnJvbTwvYy0+PGMtIG8+Jmx0OzwvYy0+PGMtIG4+VDwvYy0+
PGMtIHA+LDwvYy0+IDxjLSBuPlU8L2MtPjxjLSBvPj48L2MtPiA8Yy0gcD57fTs8L2MtPgo8L3By
ZT48L3NtYWxsPiAKICAgPHA+cGx1cyBwZXJtaXNzaW9uIGZvciB2ZW5kb3JzIHRvIGV4dGVuZCB0
aGUgdHJhaXQgdmlhIHBhcnRpYWwgc3BlY2lhbGl6YXRpb25zIG9uCmEgUW9JIGJhc2lzOjwvcD4K
ICAgPHA+PHNtYWxsPjwvc21hbGw+PC9wPgogICA8c21hbGw+IDxwcmUgY2xhc3M9Imxhbmd1YWdl
LWMrKyBoaWdobGlnaHQiPiAgICA8Yy0gbj50ZW1wbGF0ZTwvYy0+PGMtIG8+Jmx0OzwvYy0+PGMt
IG4+Y2xhc3M8L2MtPiA8Yy0gbj5UPC9jLT48Yy0gbz4+PC9jLT4KICAgIDxjLSBrPnN0cnVjdDwv
Yy0+IDxjLSBuPmlzX3RyaXZpYWxseV9yZWxvY2F0YWJsZV9mcm9tPC9jLT48Yy0gbz4mbHQ7PC9j
LT48Yy0gbj51bmlxdWVfcHRyPC9jLT48Yy0gbz4mbHQ7PC9jLT48Yy0gbj5UPC9jLT48Yy0gbz4+
PC9jLT48Yy0gcD4sPC9jLT4gPGMtIG4+VDwvYy0+PGMtIG8+Kj48L2MtPiA8Yy0gbz46PC9jLT4g
PGMtIG4+dHJ1ZV90eXBlPC9jLT4gPGMtIHA+e307PC9jLT4KICAgIDxjLSBuPnRlbXBsYXRlPC9j
LT48Yy0gbz4mbHQ7PC9jLT48Yy0gbj5jbGFzczwvYy0+IDxjLSBuPlQ8L2MtPjxjLSBvPj48L2Mt
PgogICAgPGMtIGs+c3RydWN0PC9jLT4gPGMtIG4+aXNfdHJpdmlhbGx5X3JlbG9jYXRhYmxlX2Zy
b208L2MtPjxjLSBvPiZsdDs8L2MtPjxjLSBrPmNvbnN0PC9jLT4gPGMtIG4+VDwvYy0+PGMtIG8+
KjwvYy0+PGMtIHA+LDwvYy0+IDxjLSBuPlQ8L2MtPjxjLSBvPio+PC9jLT4gPGMtIG8+OjwvYy0+
IDxjLSBuPnRydWVfdHlwZTwvYy0+IDxjLSBwPnt9OzwvYy0+CiAgICA8Yy0gaz5zdHJ1Y3Q8L2Mt
PiA8Yy0gbj5pc190cml2aWFsbHlfcmVsb2NhdGFibGVfZnJvbTwvYy0+PGMtIG8+Jmx0OzwvYy0+
PGMtIGI+aW50PC9jLT48Yy0gcD4sPC9jLT4gPGMtIGI+dW5zaWduZWQ8L2MtPjxjLSBvPj48L2Mt
PiA8Yy0gbz46PC9jLT4gPGMtIG4+dHJ1ZV90eXBlPC9jLT4gPGMtIHA+e307PC9jLT4KICAgIDxj
LSBjMT4vLyBhbmQgc28gb248L2MtPgo8L3ByZT48L3NtYWxsPiAKICAgPHA+SG93ZXZlciwgaWYg
d2UgZG8gdGhpcywgd2UgbWF5IHNvb24gZmluZCB0aGF0IHByb2dyYW1tZXJzIGFyZSBhZGRpbmcg
c3BlY2lhbGl6YXRpb25zCm9mIDxjb2RlIGNsYXNzPSJoaWdobGlnaHQiPjxjLSBuPmlzX3RyaXZp
YWxseV9yZWxvY2F0YWJsZV9mcm9tPC9jLT48L2NvZGU+IHRvIHRoZWlyIG93biBwcm9ncmFtcywg
YmVjYXVzZSB0aGV5IGZpbmQgaXQKbWFrZXMgdGhlaXIgY29kZSBydW4gZmFzdGVyLiBJdCB3aWxs
IGJlY29tZSBhIGRlLWZhY3RvIGN1c3RvbWl6YXRpb24gcG9pbnQsIGFuZCB3ZSB3aWxsCm5ldmVy
IGJlIGFibGUgdG8gImZpeCBpdCByaWdodCIgZm9yIGZlYXIgb2YgYnJlYWtpbmcgcHJvZ3JhbW1l
cnMnIGV4aXN0aW5nIGNvZGUuPC9wPgogICA8cD5UaGVyZWZvcmUsIEkgYmVsaWV2ZSB0aGF0IHdl
IHNob3VsZCA8ZW0+bm90PC9lbT4gcHVyc3VlICJoZXRlcm9nZW5lb3VzIiByZWxvY2F0aW9uCm9w
ZXJhdGlvbnMgaW4gQysrMjAuPC9wPgogICA8cD5Ob3RlIHRoYXQgdmVuZG9ycyBhcmUgYWxyZWFk
eSBmcmVlIHRvIG9wdGltaXplIGhldGVyb2dlbmVvdXMgb3BlcmF0aW9ucyBpbnNpZGUKbGlicmFy
eSBhbGdvcml0aG1zLCB1bmRlciB0aGUgYXMtaWYgcnVsZS4gV2UgbGFjayBhIHBvcnRhYmxlIGFu
ZCBnZW5lcmljIGRldGVjdGlvbgp0cmFpdCwgYnV0IHZlbmRvcnMgYXJlIHByZXN1bWFibHkgd2Vs
bCBhd2FyZSBvZiBzcGVjaWZpYyBzcGVjaWFsIGNhc2VzIHRoYXQgdGhleSA8ZW0+Y291bGQ8L2Vt
PiBkZXRlY3QgYW5kIG9wdGltaXplIHRvZGF5IOKAlDx3YnI+Zm9yIGV4YW1wbGUsIGEgPGNvZGUg
Y2xhc3M9ImhpZ2hsaWdodCI+PGMtIG4+c3RkPC9jLT48Yy0gbz46OjwvYy0+PGMtIG4+Y29weTwv
Yy0+PC9jb2RlPiBmcm9tIGFuIGFycmF5IG9mIDxjb2RlIGNsYXNzPSJoaWdobGlnaHQiPjxjLSBi
PmludDwvYy0+PGMtIG8+KjwvYy0+PC9jb2RlPiBpbnRvCmFuIGFycmF5IG9mIDxjb2RlIGNsYXNz
PSJoaWdobGlnaHQiPjxjLSBrPmNvbnN0PC9jLT4gPGMtIGI+aW50PC9jLT48Yy0gbz4qPC9jLT48
L2NvZGU+LCBvciBmcm9tIGFuIGFycmF5IG9mIDY0LWJpdCA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0
Ij48Yy0gYj5sb25nPC9jLT48L2NvZGU+IGludG8KYW4gYXJyYXkgb2YgNjQtYml0IDxjb2RlIGNs
YXNzPSJoaWdobGlnaHQiPjxjLSBiPmxvbmc8L2MtPiA8Yy0gYj5sb25nPC9jLT48L2NvZGU+IChz
ZWUgPGEgZGF0YS1saW5rLXR5cGU9ImJpYmxpbyIgaHJlZj0iI2JpYmxpby10Y2YiPltUQ0ZdPC9h
PikuClRvZGF5IHZlbmRvcnMgZ2VuZXJhbGx5IGNob29zZSBub3QgdG8gcGVyZm9ybSB0aGVzZSBv
cHRpbWl6YXRpb25zLjwvcD4KICAgPGgyIGNsYXNzPSJoZWFkaW5nIHNldHRsZWQiIGRhdGEtbGV2
ZWw9IjYiIGlkPSJhY2tub3dsZWRnZW1lbnRzIj48c3BhbiBjbGFzcz0ic2Vjbm8iPjYuIDwvc3Bh
bj48c3BhbiBjbGFzcz0iY29udGVudCI+QWNrbm93bGVkZ2VtZW50czwvc3Bhbj48YSBjbGFzcz0i
c2VsZi1saW5rIiBocmVmPSIjYWNrbm93bGVkZ2VtZW50cyI+PC9hPjwvaDI+CiAgIDxwPlRoYW5r
cyB0byBFbGlhcyBLb3N1bmVuLCBOaWFsbCBEb3VnbGFzLCBhbmQgSm9obiBCYW5kZWxhIGZvciB0
aGVpciBmZWVkYmFjayBvbiBlYXJseSBkcmFmdHMgb2YgdGhpcyBwYXBlci48L3A+CiAgIDxwPk1h
bnkgdGhhbmtzIHRvIE1hdHQgR29kYm9sdCBmb3IgYWxsb3dpbmcgbWUgdG8gaW5zdGFsbCB0aGUg
cHJvdG90eXBlIGltcGxlbWVudGF0aW9uIG9uIENvbXBpbGVyIEV4cGxvcmVyCig8YSBocmVmPSJo
dHRwczovL2dvZGJvbHQub3JnL2cvVEEyWG15Ij5nb2Rib2x0Lm9yZzwvYT4pLiBTZWUgYWxzbyA8
YSBkYXRhLWxpbmstdHlwZT0iYmlibGlvIiBocmVmPSIjYmlibGlvLWFubm91bmNpbmciPltBbm5v
dW5jaW5nXTwvYT4uPC9wPgogICA8cD5UaGFua3MgdG8gUGFibG8gSGFscGVybiBmb3IgPGEgZGF0
YS1saW5rLXR5cGU9ImJpYmxpbyIgaHJlZj0iI2JpYmxpby1uNDE1OCI+W040MTU4XTwvYT4sIHRv
IHdoaWNoIHRoaXMgcGFwZXIgYmVhcnMgYSBzdHJpa2luZyBhbmQgY29pbmNpZGVudGFsIHJlc2Vt
YmxhbmNlIOKAlDx3YnI+aW5jbHVkaW5nIHRoZSBtZWFuaW5nIGFzc2lnbmVkIHRvIHRoZSB3b3Jk
ICJ0cml2aWFsLCIgYW5kIHRoZSBsaWJyYXJ5LWFsZ29yaXRobSBhcHByb2FjaCB0byBhdm9pZGlu
ZyB0aGUKcHJvYmxlbXMgd2l0aCAibGFtZSBkdWNrIG9iamVjdHMiIGRpc2N1c3NlZCBpbiA8YSBo
cmVmPSJodHRwOi8vd3d3Lm9wZW4tc3RkLm9yZy9qdGMxL3NjMjIvd2cyMS9kb2NzL3BhcGVycy8y
MDAyL24xMzc3Lmh0bSNBbHRlcm5hdGl2ZSUyMG1vdmUlMjBkZXNpZ25zIj50aGUgZmluYWwgc2Vj
dGlvbjwvYT4gb2YgPGEgZGF0YS1saW5rLXR5cGU9ImJpYmxpbyIgaHJlZj0iI2JpYmxpby1uMTM3
NyI+W04xMzc3XTwvYT4uIFNlZSA8YSBocmVmPSJodHRwOi8vd2lraS5lZGcuY29tL2Jpbi92aWV3
L1dnMjFyYXBwZXJzd2lsMjAxNC9ONDAzNCI+ZGlzY3Vzc2lvbiBvZiBONDAzNCBhdCBSYXBwZXJz
d2lsPC9hPiAoSnVuZSAyMDE0KQphbmQgPGEgaHJlZj0iaHR0cDovL3dpa2kuZWRnLmNvbS9iaW4v
dmlldy9XZzIxdXJiYW5hLWNoYW1wYWlnbi9Fdm9sdXRpb25Xb3JraW5nR3JvdXAjTjQxNThfRGVz
dHJ1Y3RpdmVfTW92ZV9SZXZfMSI+ZGlzY3Vzc2lvbgpvZiBONDE1OCBhdCBVcmJhbmE8L2E+IChO
b3ZlbWJlciAyMDE0KS48L3A+CiAgIDxwPlRoZSB0ZXJtICJyZWxvY2F0aW9uIiBpcyBkdWUgdG8g
PGEgZGF0YS1saW5rLXR5cGU9ImJpYmxpbyIgaHJlZj0iI2JpYmxpby1lYXN0bCI+W0VBU1RMXTwv
YT4gKDxjb2RlIGNsYXNzPSJoaWdobGlnaHQiPjxjLSBuPmhhc190cml2aWFsX3JlbG9jYXRlPC9j
LT48L2NvZGU+KSBhbmQgPGEgZGF0YS1saW5rLXR5cGU9ImJpYmxpbyIgaHJlZj0iI2JpYmxpby1m
b2xseSI+W0ZvbGx5XTwvYT4gKDxjb2RlIGNsYXNzPSJoaWdobGlnaHQiPjxjLSBuPklzUmVsb2Nh
dGFibGU8L2MtPjwvY29kZT4pLiBUaGUgc2FtZSBjb25jZXB0CmFwcGVhcnMgaW4gcHJlLUMrKzEx
IGxpYnJhcmllcyB1bmRlciB0aGUgbmFtZSAibW92YWJsZSI6IFF0ICg8Y29kZSBjbGFzcz0iaGln
aGxpZ2h0Ij48Yy0gbj5RX01PVkFCTEVfVFlQRTwvYy0+PC9jb2RlPikgYW5kIEJTTCAoPGNvZGUg
Y2xhc3M9ImhpZ2hsaWdodCI+PGMtIG4+SXNCaXR3aXNlTW92ZWFibGU8L2MtPjwvY29kZT4pLgpU
aGUgc2FtZSBjb25jZXB0IGFsc28gYXBwZWFycyBpbiA8YSBkYXRhLWxpbmstdHlwZT0iYmlibGlv
IiBocmVmPSIjYmlibGlvLXN3aWZ0Ij5bU3dpZnRdPC9hPiBhcyAiPGk+Yml0d2lzZSBtb3ZhYmxl
PC9pPi4iPC9wPgogICA8cD5TaWduaWZpY2FudGx5IGRpZmZlcmVudCBhcHByb2FjaGVzIHRvIHRo
aXMgcHJvYmxlbSBoYXZlIHByZXZpb3VzbHkgYXBwZWFyZWQgaW4gRGVuaXMgQmlkZXLigJlzIDxh
IGRhdGEtbGluay10eXBlPSJiaWJsaW8iIGhyZWY9IiNiaWJsaW8tcDAwMjNyMCI+W1AwMDIzUjBd
PC9hPiAoaW50cm9kdWNpbmcgYSBjb3JlLWxhbmd1YWdlICJyZWxvY2F0aW9uIiBvcGVyYXRvcikg
YW5kIE5pYWxsIERvdWdsYXPigJlzIDxhIGRhdGEtbGluay10eXBlPSJiaWJsaW8iIGhyZWY9IiNi
aWJsaW8tcDEwMjlyMCI+W1AxMDI5UjBdPC9hPiAodHJlYXRpbmcgcmVsb2NhdGFiaWxpdHkgYXMg
YW4gYXNwZWN0Cm9mIG1vdmUtY29uc3RydWN0aW9uIGluIGlzb2xhdGlvbiwgcmF0aGVyIHRoYW4g
YW4gYXNwZWN0IG9mIHRoZSBjbGFzcyB0eXBlIGFzIGEgd2hvbGUpLjwvcD4KICAgPGgyIGNsYXNz
PSJoZWFkaW5nIHNldHRsZWQiIGlkPSJwb2xscyI+PHNwYW4gY2xhc3M9ImNvbnRlbnQiPkFwcGVu
ZGl4IEE6IFN0cmF3IHBvbGxzIHJlcXVlc3RlZDwvc3Bhbj48YSBjbGFzcz0ic2VsZi1saW5rIiBo
cmVmPSIjcG9sbHMiPjwvYT48L2gyPgogICA8aDMgY2xhc3M9ImhlYWRpbmcgc2V0dGxlZCIgaWQ9
Imxld2ctcG9sbHMiPjxzcGFuIGNsYXNzPSJjb250ZW50Ij5Qb2xscyBmb3IgTEVXRzwvc3Bhbj48
YSBjbGFzcz0ic2VsZi1saW5rIiBocmVmPSIjbGV3Zy1wb2xscyI+PC9hPjwvaDM+CiAgIDx0YWJs
ZSBjbGFzcz0iZGVmIj4KICAgIDx0Ym9keT4KICAgICA8dHI+CiAgICAgIDx0aCBzdHlsZT0id2lk
dGg6IDcwJTsiPgogICAgICA8dGg+PHN0cm9uZz5TRjwvc3Ryb25nPgogICAgICA8dGg+PHN0cm9u
Zz5GPC9zdHJvbmc+CiAgICAgIDx0aD48c3Ryb25nPk48L3N0cm9uZz4KICAgICAgPHRoPjxzdHJv
bmc+QTwvc3Ryb25nPgogICAgICA8dGg+PHN0cm9uZz5TQTwvc3Ryb25nPgogICAgIDx0cj4KICAg
ICAgPHRoPjxzbWFsbD5UaGUgYWxnb3JpdGhtIDxjb2RlIGNsYXNzPSJoaWdobGlnaHQiPjxjLSBu
PnVuaW5pdGlhbGl6ZWRfcmVsb2NhdGU8L2MtPjxjLSBwPig8L2MtPjxjLSBuPmZpcnN0PC9jLT48
Yy0gcD4sPC9jLT4gPGMtIG4+bGFzdDwvYy0+PGMtIHA+LDwvYy0+IDxjLSBuPmRfZmlyc3Q8L2Mt
PjxjLSBwPik8L2MtPjwvY29kZT4gc2hvdWxkIGJlIGFkZGVkIHRvIHRoZSA8Y29kZSBjbGFzcz0i
aGlnaGxpZ2h0Ij48Yy0gbz4mbHQ7PC9jLT48Yy0gbj5tZW1vcnk8L2MtPjxjLSBvPj48L2MtPjwv
Y29kZT4gaGVhZGVyLAphcyBwcm9wb3NlZCBpbiB0aGlzIHBhcGVyLjwvc21hbGw+CiAgICAgIDx0
aD5fCiAgICAgIDx0aD5fCiAgICAgIDx0aD5fCiAgICAgIDx0aD5fCiAgICAgIDx0aD5fCiAgICAg
PHRyPgogICAgICA8dGg+PHNtYWxsPlRoZSB0eXBlIHRyYWl0IDxjb2RlIGNsYXNzPSJoaWdobGln
aHQiPjxjLSBuPmlzX3JlbG9jYXRhYmxlPC9jLT48Yy0gbz4mbHQ7PC9jLT48Yy0gbj5UPC9jLT48
Yy0gbz4+PC9jLT48L2NvZGU+IChhbmQgaXRzIDxjb2RlIGNsYXNzPSJoaWdobGlnaHQiPjxjLSBu
Pl92PC9jLT48L2NvZGU+IHZlcnNpb24pIHNob3VsZCBiZSBhZGRlZCB0byB0aGUgPGNvZGUgY2xh
c3M9ImhpZ2hsaWdodCI+PGMtIG8+Jmx0OzwvYy0+PGMtIG4+dHlwZV90cmFpdHM8L2MtPjxjLSBv
Pj48L2MtPjwvY29kZT4gaGVhZGVyLCBhcyBwcm9wb3NlZCBpbiB0aGlzIHBhcGVyLjwvc21hbGw+
CiAgICAgIDx0aD5fCiAgICAgIDx0aD5fCiAgICAgIDx0aD5fCiAgICAgIDx0aD5fCiAgICAgIDx0
aD5fCiAgICAgPHRyPgogICAgICA8dGg+PHNtYWxsPklmIDxjb2RlIGNsYXNzPSJoaWdobGlnaHQi
PjxjLSBuPmlzX3JlbG9jYXRhYmxlPC9jLT48Yy0gbz4mbHQ7PC9jLT48Yy0gbj5UPC9jLT48Yy0g
bz4+PC9jLT48L2NvZGU+IDxlbT5pczwvZW0+IGFkZGVkLCB0aGVuIHdlIHNob3VsZCBhbHNvIGFk
ZCA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gbj5pc19ub3Rocm93X3JlbG9jYXRhYmxlPC9j
LT48Yy0gbz4mbHQ7PC9jLT48Yy0gbj5UPC9jLT48Yy0gbz4+PC9jLT48L2NvZGU+IChhbmQgaXRz
IDxjb2RlIGNsYXNzPSJoaWdobGlnaHQiPjxjLSBuPl92PC9jLT48L2NvZGU+IHZlcnNpb24pLCBh
cyBwcm9wb3NlZCBpbiB0aGlzIHBhcGVyLjwvc21hbGw+CiAgICAgIDx0aD5fCiAgICAgIDx0aD5f
CiAgICAgIDx0aD5fCiAgICAgIDx0aD5fCiAgICAgIDx0aD5fCiAgICAgPHRyPgogICAgICA8dGg+
PHNtYWxsPlRoZSB0eXBlIHRyYWl0IDxjb2RlIGNsYXNzPSJoaWdobGlnaHQiPjxjLSBuPmlzX3Ry
aXZpYWxseV9yZWxvY2F0YWJsZTwvYy0+PGMtIG8+Jmx0OzwvYy0+PGMtIG4+VDwvYy0+PGMtIG8+
PjwvYy0+PC9jb2RlPiAoYW5kIGl0cyA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gbj5fdjwv
Yy0+PC9jb2RlPiB2ZXJzaW9uKSBzaG91bGQgYmUgYWRkZWQgdG8gdGhlIDxjb2RlIGNsYXNzPSJo
aWdobGlnaHQiPjxjLSBvPiZsdDs8L2MtPjxjLSBuPnR5cGVfdHJhaXRzPC9jLT48Yy0gbz4+PC9j
LT48L2NvZGU+IGhlYWRlciwgdW5kZXIgdGhhdCBleGFjdCBuYW1lLCBhcyBwcm9wb3NlZCBpbiB0
aGlzIHBhcGVyLjwvc21hbGw+CiAgICAgIDx0aD5fCiAgICAgIDx0aD5fCiAgICAgIDx0aD5fCiAg
ICAgIDx0aD5fCiAgICAgIDx0aD5fCiAgICAgPHRyPgogICAgICA8dGg+PHNtYWxsPldlIGFwcHJv
dmUgb2YgYSB0cmFpdCB3aXRoIHRoZSBzZW1hbnRpY3Mgb2YgPGNvZGUgY2xhc3M9ImhpZ2hsaWdo
dCI+PGMtIG4+aXNfdHJpdmlhbGx5X3JlbG9jYXRhYmxlPC9jLT48Yy0gbz4mbHQ7PC9jLT48Yy0g
bj5UPC9jLT48Yy0gbz4+PC9jLT48L2NvZGU+LCBidXQgbm90IG5lY2Vzc2FyaWx5IHVuZGVyIHRo
YXQgZXhhY3QgbmFtZS4gKEZvciBleGFtcGxlLCA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0g
bj5pc19iaXR3aXNlX3JlbG9jYXRhYmxlPC9jLT48L2NvZGU+Lik8L3NtYWxsPgogICAgICA8dGg+
XwogICAgICA8dGg+XwogICAgICA8dGg+XwogICAgICA8dGg+XwogICAgICA8dGg+XwogICAgIDx0
cj4KICAgICAgPHRoPjxzbWFsbD5JZiA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gbj5pc190
cml2aWFsbHlfcmVsb2NhdGFibGU8L2MtPjxjLSBvPiZsdDs8L2MtPjxjLSBuPlQ8L2MtPjxjLSBv
Pj48L2MtPjwvY29kZT4gPGVtPmlzPC9lbT4gYWRkZWQsIHVuZGVyIHRoYXQgZXhhY3QgbmFtZSwg
dGhlbiB0aGUgdHlwZSB0cmFpdCA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gbj5pc190cml2
aWFsbHlfc3dhcHBhYmxlPC9jLT48Yy0gbz4mbHQ7PC9jLT48Yy0gbj5UPC9jLT48Yy0gbz4+PC9j
LT48L2NvZGU+IChhbmQgaXRzIDxjb2RlIGNsYXNzPSJoaWdobGlnaHQiPjxjLSBuPl92PC9jLT48
L2NvZGU+IHZlcnNpb24pIHNob3VsZCBhbHNvIGJlIGFkZGVkIHRvIHRoZSA8Y29kZSBjbGFzcz0i
aGlnaGxpZ2h0Ij48Yy0gbz4mbHQ7PC9jLT48Yy0gbj50eXBlX3RyYWl0czwvYy0+PGMtIG8+Pjwv
Yy0+PC9jb2RlPiBoZWFkZXIuPC9zbWFsbD4KICAgICAgPHRoPl8KICAgICAgPHRoPl8KICAgICAg
PHRoPl8KICAgICAgPHRoPl8KICAgICAgPHRoPl8KICAgPC90YWJsZT4KICAgPGgzIGNsYXNzPSJo
ZWFkaW5nIHNldHRsZWQiIGlkPSJld2ctcG9sbHMiPjxzcGFuIGNsYXNzPSJjb250ZW50Ij5Qb2xs
cyBmb3IgRVdHPC9zcGFuPjxhIGNsYXNzPSJzZWxmLWxpbmsiIGhyZWY9IiNld2ctcG9sbHMiPjwv
YT48L2gzPgogICA8dGFibGUgY2xhc3M9ImRlZiI+CiAgICA8dGJvZHk+CiAgICAgPHRyPgogICAg
ICA8dGggc3R5bGU9IndpZHRoOiA3MCU7Ij4KICAgICAgPHRoPjxzdHJvbmc+U0Y8L3N0cm9uZz4K
ICAgICAgPHRoPjxzdHJvbmc+Rjwvc3Ryb25nPgogICAgICA8dGg+PHN0cm9uZz5OPC9zdHJvbmc+
CiAgICAgIDx0aD48c3Ryb25nPkE8L3N0cm9uZz4KICAgICAgPHRoPjxzdHJvbmc+U0E8L3N0cm9u
Zz4KICAgICA8dHI+CiAgICAgIDx0aD48c21hbGw+V2UgYXBwcm92ZSBvZiB0aGUgZ2VuZXJhbCBp
ZGVhIHRoYXQgdXNlci1kZWZpbmVkIGNsYXNzZXMgc2hvdWxkIGJlIGFibGUgdG8gd2FycmFudCB0
aGVpciBvd24gdHJpdmlhbCByZWxvY2F0YWJpbGl0eS48L3NtYWxsPgogICAgICA8dGg+XwogICAg
ICA8dGg+XwogICAgICA8dGg+XwogICAgICA8dGg+XwogICAgICA8dGg+XwogICAgIDx0cj4KICAg
ICAgPHRoPjxzbWFsbD5XZSBhcHByb3ZlIG9mIHRoZSBnZW5lcmFsIGlkZWEgdGhhdCB1c2VyLWRl
ZmluZWQgY2xhc3NlcyB3aGljaCBmb2xsb3cgdGhlIFJ1bGUgb2YgWmVybyBzaG91bGQgaW5oZXJp
dCB0aGUgdHJpdmlhbCByZWxvY2F0YWJpbGl0eSBvZiB0aGVpciBiYXNlcyBhbmQgbWVtYmVycy48
L3NtYWxsPgogICAgICA8dGg+XwogICAgICA8dGg+XwogICAgICA8dGg+XwogICAgICA8dGg+Xwog
ICAgICA8dGg+XwogICAgIDx0cj4KICAgICAgPHRoPjxzbWFsbD5Ob2JvZHkgc2hvdWxkIGJlIGFi
bGUgdG8gd2FycmFudCB0aGUgdHJpdmlhbCByZWxvY2F0YWJpbGl0eSBvZiA8Y29kZSBjbGFzcz0i
aGlnaGxpZ2h0Ij48Yy0gaz5jbGFzczwvYy0+IDxjLSBuYz5DPC9jLT48L2NvZGU+IGV4Y2VwdCBm
b3IgPGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMtIGs+Y2xhc3M8L2MtPiA8Yy0gbmM+QzwvYy0+
PC9jb2RlPiBpdHNlbGYgKGkuZS4sIHdlIGRvIG5vdCB3YW50IHRvIHNlZSBhIGN1c3RvbWl6YXRp
b24gcG9pbnQgYW5hbG9nb3VzIHRvIDxjb2RlIGNsYXNzPSJoaWdobGlnaHQiPjxjLSBuPnN0ZDwv
Yy0+PGMtIG8+Ojo8L2MtPjxjLSBuPmhhc2g8L2MtPjwvY29kZT4pLjwvc21hbGw+CiAgICAgIDx0
aD5fCiAgICAgIDx0aD5fCiAgICAgIDx0aD5fCiAgICAgIDx0aD5fCiAgICAgIDx0aD5fCiAgICAg
PHRyPgogICAgICA8dGg+PHNtYWxsPklmIGEgdHJhaXQgd2l0aCB0aGUgc2VtYW50aWNzIG9mIDxj
b2RlIGNsYXNzPSJoaWdobGlnaHQiPjxjLSBuPmlzX3RyaXZpYWxseV9yZWxvY2F0YWJsZTwvYy0+
PGMtIG8+Jmx0OzwvYy0+PGMtIG4+VDwvYy0+PGMtIG8+PjwvYy0+PC9jb2RlPiBpcyBhZGRlZCB0
byB0aGUgPGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMtIG8+Jmx0OzwvYy0+PGMtIG4+dHlwZV90
cmFpdHM8L2MtPjxjLSBvPj48L2MtPjwvY29kZT4gaGVhZGVyLCB0aGUgcHJvZ3JhbW1lciBzaG91
bGQgYmUgcGVybWl0dGVkIHRvIHNwZWNpYWxpemUgaXQgZm9yIHByb2dyYW0tZGVmaW5lZCB0eXBl
cyAoaS5lLiwgd2Ugd2FudCB0byBzZWUgdGhhdCB0cmFpdCBpdHNlbGYgYmVjb21lIGEgY3VzdG9t
aXphdGlvbiBwb2ludCBhbmFsb2dvdXMgdG8gPGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMtIG4+
c3RkPC9jLT48Yy0gbz46OjwvYy0+PGMtIG4+aGFzaDwvYy0+PC9jb2RlPikuPC9zbWFsbD4KICAg
ICAgPHRoPl8KICAgICAgPHRoPl8KICAgICAgPHRoPl8KICAgICAgPHRoPl8KICAgICAgPHRoPl8K
ICAgICA8dHI+CiAgICAgIDx0aD48c21hbGw+QSBjbGFzcyBzaG91bGQgYmUgYWJsZSB0byB3YXJy
YW50IGl0cyBvd24gdHJpdmlhbCByZWxvY2F0YWJpbGl0eSB2aWEgdGhlIGF0dHJpYnV0ZSA8Y29k
ZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gcD5bWzwvYy0+PGMtIG4+dHJpdmlhbGx5X3JlbG9jYXRh
YmxlPC9jLT48Yy0gcD5dXTwvYy0+PC9jb2RlPiwgYXMgcHJvcG9zZWQgaW4gdGhpcyBwYXBlci48
L3NtYWxsPgogICAgICA8dGg+XwogICAgICA8dGg+XwogICAgICA8dGg+XwogICAgICA8dGg+Xwog
ICAgICA8dGg+XwogICAgIDx0cj4KICAgICAgPHRoPjxzbWFsbD5BIGNsYXNzIHNob3VsZCBiZSBh
YmxlIHRvIHdhcnJhbnQgaXRzIG93biB0cml2aWFsIHJlbG9jYXRhYmlsaXR5IHZpYSBzb21lIGF0
dHJpYnV0ZSwgYnV0IG5vdCBuZWNlc3NhcmlseSB1bmRlciB0aGF0IGV4YWN0IG5hbWUuPC9zbWFs
bD4KICAgICAgPHRoPl8KICAgICAgPHRoPl8KICAgICAgPHRoPl8KICAgICAgPHRoPl8KICAgICAg
PHRoPl8KICAgICA8dHI+CiAgICAgIDx0aD48c21hbGw+QSBjbGFzcyBzaG91bGQgYmUgYWJsZSB0
byB3YXJyYW50IGl0cyBvd24gdHJpdmlhbCByZWxvY2F0YWJpbGl0eSBhcyBwcm9wb3NlZCBpbiB0
aGlzIHBhcGVyLCBidXQgdmlhIGEgY29udGV4dHVhbCBrZXl3b3JkIHJhdGhlciB0aGFuIGFuIGF0
dHJpYnV0ZS48L3NtYWxsPgogICAgICA8dGg+XwogICAgICA8dGg+XwogICAgICA8dGg+XwogICAg
ICA8dGg+XwogICAgICA8dGg+XwogICAgIDx0cj4KICAgICAgPHRoPjxzbWFsbD5Ucml2aWFsIHJl
bG9jYXRhYmlsaXR5IHNob3VsZCBiZSBhc3N1bWVkIGJ5IGRlZmF1bHQuIENsYXNzZXMgc3VjaCBh
cyB0aG9zZSBpbiA8YSBocmVmPSIjbm9uLXRyaXZpYWwtc2FtcGxlcyI+QXBwZW5kaXggQzwvYT4g
c2hvdWxkIGluZGljYXRlIHRoZWlyIG5vbi10cml2aWFsIHJlbG9jYXRhYmlsaXR5IHZpYSBhbiBv
cHQtaW4gbWVjaGFuaXNtLjwvc21hbGw+CiAgICAgIDx0aD5fCiAgICAgIDx0aD5fCiAgICAgIDx0
aD5fCiAgICAgIDx0aD5fCiAgICAgIDx0aD5fCiAgICAgPHRyPgogICAgICA8dGg+PHNtYWxsPlRv
IHNpbXBsaWZ5IDxhIGhyZWY9IiNzYW1wbGUtY29uZGl0aW9uYWwiPkNvbmRpdGlvbmFsbHkgdHJp
dmlhbCByZWxvY2F0aW9uPC9hPiwgaWYgYW4gYXR0cmlidXRlIHdpdGggdGhlIHNlbWFudGljcyBv
ZiA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gcD5bWzwvYy0+PGMtIG4+dHJpdmlhbGx5X3Jl
bG9jYXRhYmxlPC9jLT48Yy0gcD5dXTwvYy0+PC9jb2RlPiBpcyBhZGRlZCwgaXQgc2hvdWxkIHRh
a2UgYSBib29sZWFuIGFyZ3VtZW50Ljwvc21hbGw+CiAgICAgIDx0aD5fCiAgICAgIDx0aD5fCiAg
ICAgIDx0aD5fCiAgICAgIDx0aD5fCiAgICAgIDx0aD5fCiAgIDwvdGFibGU+CiAgIDxoMiBjbGFz
cz0iaGVhZGluZyBzZXR0bGVkIiBpZD0ic2FtcGxlcyI+PHNwYW4gY2xhc3M9ImNvbnRlbnQiPkFw
cGVuZGl4IEI6IFNhbXBsZSBjb2RlPC9zcGFuPjxhIGNsYXNzPSJzZWxmLWxpbmsiIGhyZWY9IiNz
YW1wbGVzIj48L2E+PC9oMj4KICAgPGgzIGNsYXNzPSJoZWFkaW5nIHNldHRsZWQiIGlkPSJzYW1w
bGUtZGVkdWNpbmciPjxzcGFuIGNsYXNzPSJjb250ZW50Ij5EZWZpbmluZyBhIHRyaXZpYWxseSBy
ZWxvY2F0YWJsZSBmdW5jdGlvbiBvYmplY3Q8L3NwYW4+PGEgY2xhc3M9InNlbGYtbGluayIgaHJl
Zj0iI3NhbXBsZS1kZWR1Y2luZyI+PC9hPjwvaDM+CiAgIDxwPlRoZSBmb2xsb3dpbmcgc2FtcGxl
IGlsbHVzdHJhdGVzIDxhIGhyZWY9IiN1c2UyIj7CpzIuMiBQcm9ncmFtLWRlZmluZWQgdHlwZXMg
dGhhdCBmb2xsb3cgdGhlIFJ1bGUgb2YgWmVybzwvYT4uIEhlcmUgPGNvZGUgY2xhc3M9ImhpZ2hs
aWdodCI+PGMtIG4+QTwvYy0+PC9jb2RlPiBpcyBhIHByb2dyYW0tZGVmaW5lZCB0eXBlCmZvbGxv
d2luZyB0aGUgUnVsZSBvZiBaZXJvLiBCZWNhdXNlIGFsbCBvZiBpdHMgYmFzZXMgYW5kIG1lbWJl
cnMgYXJlIHdhcnJhbnRlZCBhcwp0cml2aWFsbHkgcmVsb2NhdGFibGUsIGFuZCBpdHMgbW92ZS1j
b25zdHJ1Y3RvciBhbmQgZGVzdHJ1Y3RvciBhcmUgYm90aCBkZWZhdWx0ZWQsCnRoZSBjb21waWxl
ciBjb25jbHVkZXMgdGhhdCA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gbj5BPC9jLT48L2Nv
ZGU+IGl0c2VsZiBpcyB0cml2aWFsbHkgcmVsb2NhdGFibGUuPC9wPgo8cHJlIGNsYXNzPSJoaWdo
bGlnaHQiPiAgICA8Yy0gY3A+I2luY2x1ZGU8L2MtPiAmbHQ7c3RyaW5nPgogICAgPGMtIGNwPiNp
bmNsdWRlPC9jLT4gJmx0O3R5cGVfdHJhaXRzPgoKICAgIDxjLSBjMT4vLyBBc3N1bWUgdGhhdCB0
aGUgbGlicmFyeSB2ZW5kb3IgaGFzIHRha2VuIGNhcmUgb2YgdGhpcyBwYXJ0LjwvYy0+CiAgICA8
Yy0gaz5zdGF0aWNfYXNzZXJ0PC9jLT48Yy0gcD4oPC9jLT48Yy0gbj5zdGQ8L2MtPjxjLSBvPjo6
PC9jLT48Yy0gbj5pc190cml2aWFsbHlfcmVsb2NhdGFibGVfdjwvYy0+PGMtIG8+Jmx0OzwvYy0+
IDxjLSBuPnN0ZDwvYy0+PGMtIG8+Ojo8L2MtPjxjLSBuPnN0cmluZzwvYy0+IDxjLSBvPj48L2Mt
PjxjLSBwPik7PC9jLT4KCiAgICA8Yy0gaz5zdHJ1Y3Q8L2MtPiA8Yy0gbj5BPC9jLT4gPGMtIHA+
ezwvYy0+CiAgICAgICAgPGMtIG4+c3RkPC9jLT48Yy0gbz46OjwvYy0+PGMtIG4+c3RyaW5nPC9j
LT4gPGMtIG4+czwvYy0+PGMtIHA+OzwvYy0+CiAgICAgICAgPGMtIG4+c3RkPC9jLT48Yy0gbz46
OjwvYy0+PGMtIG4+c3RyaW5nPC9jLT4gPGMtIGs+b3BlcmF0b3I8L2MtPjxjLSBwPigpKDwvYy0+
PGMtIG4+c3RkPC9jLT48Yy0gbz46OjwvYy0+PGMtIG4+c3RyaW5nPC9jLT4gPGMtIG4+dDwvYy0+
PGMtIHA+KTwvYy0+IDxjLSBrPmNvbnN0PC9jLT4gPGMtIHA+ezwvYy0+IDxjLSBrPnJldHVybjwv
Yy0+IDxjLSBuPnM8L2MtPiA8Yy0gbz4rPC9jLT4gPGMtIG4+dDwvYy0+PGMtIHA+OzwvYy0+IDxj
LSBwPn08L2MtPgogICAgPGMtIHA+fTs8L2MtPgoKICAgIDxjLSBrPnN0YXRpY19hc3NlcnQ8L2Mt
PjxjLSBwPig8L2MtPjxjLSBuPnN0ZDwvYy0+PGMtIG8+Ojo8L2MtPjxjLSBuPmlzX3RyaXZpYWxs
eV9yZWxvY2F0YWJsZV92PC9jLT48Yy0gbz4mbHQ7PC9jLT4gPGMtIG4+QTwvYy0+IDxjLSBvPj48
L2MtPjxjLSBwPik7PC9jLT4KPC9wcmU+CiAgIDxwPlRoZSBmb2xsb3dpbmcgc2FtcGxlLCBpbnZv
bHZpbmcgYW4gaW1wbGVtZW50YXRpb24tZGVmaW5lZCBjbG9zdXJlIHR5cGUsCmFsc28gaWxsdXN0
cmF0ZXMgPGEgaHJlZj0iI3VzZTIiPsKnMi4yIFByb2dyYW0tZGVmaW5lZCB0eXBlcyB0aGF0IGZv
bGxvdyB0aGUgUnVsZSBvZiBaZXJvPC9hPi48L3A+CjxwcmUgY2xhc3M9ImhpZ2hsaWdodCI+ICAg
IDxjLSBjcD4jaW5jbHVkZTwvYy0+ICZsdDtzdHJpbmc+CiAgICA8Yy0gY3A+I2luY2x1ZGU8L2Mt
PiAmbHQ7dHlwZV90cmFpdHM+CgogICAgPGMtIGMxPi8vIEFzc3VtZSB0aGF0IHRoZSBsaWJyYXJ5
IHZlbmRvciBoYXMgdGFrZW4gY2FyZSBvZiB0aGlzIHBhcnQuPC9jLT4KICAgIDxjLSBrPnN0YXRp
Y19hc3NlcnQ8L2MtPjxjLSBwPig8L2MtPjxjLSBuPnN0ZDwvYy0+PGMtIG8+Ojo8L2MtPjxjLSBu
PmlzX3RyaXZpYWxseV9yZWxvY2F0YWJsZV92PC9jLT48Yy0gbz4mbHQ7PC9jLT4gPGMtIG4+c3Rk
PC9jLT48Yy0gbz46OjwvYy0+PGMtIG4+c3RyaW5nPC9jLT4gPGMtIG8+PjwvYy0+PGMtIHA+KTs8
L2MtPgoKICAgIDxjLSBrPmF1dG88L2MtPiA8Yy0gbj5hPC9jLT4gPGMtIG8+PTwvYy0+IDxjLSBw
Pls8L2MtPjxjLSBuPnM8L2MtPiA8Yy0gbz49PC9jLT4gPGMtIG4+c3RkPC9jLT48Yy0gbz46Ojwv
Yy0+PGMtIG4+c3RyaW5nPC9jLT48Yy0gcD4oPC9jLT48Yy0gcz4iaGVsbG8iPC9jLT48Yy0gcD4p
XSg8L2MtPjxjLSBuPnN0ZDwvYy0+PGMtIG8+Ojo8L2MtPjxjLSBuPnN0cmluZzwvYy0+IDxjLSBu
PnQ8L2MtPjxjLSBwPik8L2MtPiA8Yy0gcD57PC9jLT4KICAgICAgICA8Yy0gaz5yZXR1cm48L2Mt
PiA8Yy0gbj5zPC9jLT4gPGMtIG8+KzwvYy0+IDxjLSBuPnQ8L2MtPjxjLSBwPjs8L2MtPgogICAg
PGMtIHA+fTs8L2MtPgoKICAgIDxjLSBrPnN0YXRpY19hc3NlcnQ8L2MtPjxjLSBwPig8L2MtPjxj
LSBuPnN0ZDwvYy0+PGMtIG8+Ojo8L2MtPjxjLSBuPmlzX3RyaXZpYWxseV9yZWxvY2F0YWJsZV92
PC9jLT48Yy0gbz4mbHQ7PC9jLT4gPGMtIGs+ZGVjbHR5cGU8L2MtPjxjLSBwPig8L2MtPjxjLSBu
PmE8L2MtPjxjLSBwPik8L2MtPiA8Yy0gbz4+PC9jLT48Yy0gcD4pOzwvYy0+CjwvcHJlPgogICA8
aDMgY2xhc3M9ImhlYWRpbmcgc2V0dGxlZCIgaWQ9InNhbXBsZS1vcHRpbmctaW4iPjxzcGFuIGNs
YXNzPSJjb250ZW50Ij5XYXJyYW50aW5nIHRoYXQgYSB1c2VyLWRlZmluZWQgcmVsb2NhdGlvbiBv
cGVyYXRpb24gaXMgZXF1aXZhbGVudCB0byA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gbj5t
ZW1jcHk8L2MtPjwvY29kZT48L3NwYW4+PGEgY2xhc3M9InNlbGYtbGluayIgaHJlZj0iI3NhbXBs
ZS1vcHRpbmctaW4iPjwvYT48L2gzPgogICA8cD5UaGUgZm9sbG93aW5nIHNhbXBsZSBpbGx1c3Ry
YXRlcyA8YSBocmVmPSIjdXNlMyI+wqcyLjMgUHJvZ3JhbS1kZWZpbmVkIHR5cGVzIHdpdGggbm9u
LWRlZmF1bHRlZCBzcGVjaWFsIG1lbWJlcnM8L2E+LiBUaGUgcnVsZXMgcHJvcG9zZWQgaW4gdGhp
cyBwYXBlciBlbnN1cmUKdGhhdCBhbnkgdHlwZSB3aXRoIG5vbi10cml2aWFsIHVzZXItZGVmaW5l
ZCBtb3ZlIGFuZCBkZXN0cnVjdG9yIG9wZXJhdGlvbnMgd2lsbCBiZQpjb25zaWRlcmVkIG5vbi10
cml2aWFsbHkgcmVsb2NhdGFibGUgYnkgZGVmYXVsdC48L3A+CjxwcmUgY2xhc3M9ImhpZ2hsaWdo
dCI+ICAgIDxjLSBjcD4jaW5jbHVkZTwvYy0+ICZsdDt0eXBlX3RyYWl0cz4KCiAgICA8Yy0gaz5z
dHJ1Y3Q8L2MtPiA8Yy0gbj5DPC9jLT4gPGMtIHA+ezwvYy0+CiAgICAgICAgPGMtIGs+Y29uc3Q8
L2MtPiA8Yy0gYj5jaGFyPC9jLT4gPGMtIG8+KjwvYy0+PGMtIG4+czwvYy0+IDxjLSBvPj08L2Mt
PiA8Yy0gaz5udWxscHRyPC9jLT48Yy0gcD47PC9jLT4KICAgICAgICA8Yy0gbj5DPC9jLT48Yy0g
cD4oPC9jLT48Yy0gaz5jb25zdDwvYy0+IDxjLSBiPmNoYXI8L2MtPiA8Yy0gbz4qPC9jLT48Yy0g
bj5zPC9jLT48Yy0gcD4pPC9jLT4gPGMtIG8+OjwvYy0+IDxjLSBuPnM8L2MtPjxjLSBwPig8L2Mt
PjxjLSBuPnM8L2MtPjxjLSBwPik8L2MtPiA8Yy0gcD57fTwvYy0+CiAgICAgICAgPGMtIG4+Qzwv
Yy0+PGMtIHA+KDwvYy0+PGMtIG4+QzwvYy0+PGMtIG8+JmFtcDsmYW1wOzwvYy0+IDxjLSBuPnJo
czwvYy0+PGMtIHA+KTwvYy0+IDxjLSBvPjo8L2MtPiA8Yy0gbj5zPC9jLT48Yy0gcD4oPC9jLT48
Yy0gbj5yaHM8L2MtPjxjLSBwPi48L2MtPjxjLSBuPnM8L2MtPjxjLSBwPik8L2MtPiA8Yy0gcD57
PC9jLT4gPGMtIG4+cmhzPC9jLT48Yy0gcD4uPC9jLT48Yy0gbj5zPC9jLT4gPGMtIG8+PTwvYy0+
IDxjLSBrPm51bGxwdHI8L2MtPjxjLSBwPjs8L2MtPiA8Yy0gcD59PC9jLT4KICAgICAgICA8Yy0g
bz5+PC9jLT48Yy0gbj5DPC9jLT48Yy0gcD4oKTwvYy0+IDxjLSBwPns8L2MtPiA8Yy0gaz5kZWxl
dGU8L2MtPiA8Yy0gbj5zPC9jLT48Yy0gcD47PC9jLT4gPGMtIHA+fTwvYy0+CiAgICA8Yy0gcD59
OzwvYy0+CgogICAgPGMtIGs+c3RhdGljX2Fzc2VydDwvYy0+PGMtIHA+KDwvYy0+PGMtIG4+bm90
PC9jLT4gPGMtIG4+c3RkPC9jLT48Yy0gbz46OjwvYy0+PGMtIG4+aXNfdHJpdmlhbGx5X3JlbG9j
YXRhYmxlX3Y8L2MtPjxjLSBvPiZsdDs8L2MtPiA8Yy0gbj5DPC9jLT4gPGMtIG8+PjwvYy0+PGMt
IHA+KTs8L2MtPgoKICAgIDxjLSBrPnN0cnVjdDwvYy0+IDxjLSBubD5EPC9jLT4gPGMtIHA+Ojwv
Yy0+IDxjLSBuPkM8L2MtPiA8Yy0gcD57fTs8L2MtPgoKICAgIDxjLSBrPnN0YXRpY19hc3NlcnQ8
L2MtPjxjLSBwPig8L2MtPjxjLSBuPm5vdDwvYy0+IDxjLSBuPnN0ZDwvYy0+PGMtIG8+Ojo8L2Mt
PjxjLSBuPmlzX3RyaXZpYWxseV9yZWxvY2F0YWJsZV92PC9jLT48Yy0gbz4mbHQ7PC9jLT4gPGMt
IG4+RDwvYy0+IDxjLSBvPj48L2MtPjxjLSBwPik7PC9jLT4KPC9wcmU+CiAgIDxwPlRoZSBwcm9n
cmFtbWVyIG1heSBhcHBseSB0aGUgPGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMtIHA+W1s8L2Mt
PjxjLSBuPnRyaXZpYWxseV9yZWxvY2F0YWJsZTwvYy0+PGMtIHA+XV08L2MtPjwvY29kZT4gYXR0
cmlidXRlIHRvIG92ZXJyaWRlIHRoZSBjb21waWxlcuKAmXMgZGVmYXVsdApiZWhhdmlvciBhbmQg
d2FycmFudCAodW5kZXIgcGVuYWx0eSBvZiB1bmRlZmluZWQgYmVoYXZpb3IpIHRoYXQgdGhpcyB0
eXBlIGlzIGluIGZhY3QgdHJpdmlhbGx5IHJlbG9jYXRhYmxlLjwvcD4KPHByZSBjbGFzcz0iaGln
aGxpZ2h0Ij4gICAgPGMtIGNwPiNpbmNsdWRlPC9jLT4gJmx0O3R5cGVfdHJhaXRzPgoKICAgIDxj
LSBrPnN0cnVjdDwvYy0+IDxjLSBwPltbPC9jLT48Yy0gbj50cml2aWFsbHlfcmVsb2NhdGFibGU8
L2MtPjxjLSBwPl1dPC9jLT4gPGMtIG4+RTwvYy0+IDxjLSBwPns8L2MtPgogICAgICAgIDxjLSBr
PmNvbnN0PC9jLT4gPGMtIGI+Y2hhcjwvYy0+IDxjLSBvPio8L2MtPjxjLSBuPnM8L2MtPiA8Yy0g
bz49PC9jLT4gPGMtIGs+bnVsbHB0cjwvYy0+PGMtIHA+OzwvYy0+CiAgICAgICAgPGMtIG4+RTwv
Yy0+PGMtIHA+KDwvYy0+PGMtIGs+Y29uc3Q8L2MtPiA8Yy0gYj5jaGFyPC9jLT4gPGMtIG8+Kjwv
Yy0+PGMtIG4+czwvYy0+PGMtIHA+KTwvYy0+IDxjLSBvPjo8L2MtPiA8Yy0gbj5zPC9jLT48Yy0g
cD4oPC9jLT48Yy0gbj5zPC9jLT48Yy0gcD4pPC9jLT4gPGMtIHA+e308L2MtPgogICAgICAgIDxj
LSBuPkU8L2MtPjxjLSBwPig8L2MtPjxjLSBuPkM8L2MtPjxjLSBvPiZhbXA7JmFtcDs8L2MtPiA8
Yy0gbj5yaHM8L2MtPjxjLSBwPik8L2MtPiA8Yy0gbz46PC9jLT4gPGMtIG4+czwvYy0+PGMtIHA+
KDwvYy0+PGMtIG4+cmhzPC9jLT48Yy0gcD4uPC9jLT48Yy0gbj5zPC9jLT48Yy0gcD4pPC9jLT4g
PGMtIHA+ezwvYy0+IDxjLSBuPnJoczwvYy0+PGMtIHA+LjwvYy0+PGMtIG4+czwvYy0+IDxjLSBv
Pj08L2MtPiA8Yy0gaz5udWxscHRyPC9jLT48Yy0gcD47PC9jLT4gPGMtIHA+fTwvYy0+CiAgICAg
ICAgPGMtIG8+fjwvYy0+PGMtIG4+RTwvYy0+PGMtIHA+KCk8L2MtPiA8Yy0gcD57PC9jLT4gPGMt
IGs+ZGVsZXRlPC9jLT4gPGMtIG4+czwvYy0+PGMtIHA+OzwvYy0+IDxjLSBwPn08L2MtPgogICAg
PGMtIHA+fTs8L2MtPgoKICAgIDxjLSBrPnN0YXRpY19hc3NlcnQ8L2MtPjxjLSBwPig8L2MtPjxj
LSBuPnN0ZDwvYy0+PGMtIG8+Ojo8L2MtPjxjLSBuPmlzX3RyaXZpYWxseV9yZWxvY2F0YWJsZV92
PC9jLT48Yy0gbz4mbHQ7PC9jLT4gPGMtIG4+RTwvYy0+IDxjLSBvPj48L2MtPjxjLSBwPik7PC9j
LT4KCiAgICA8Yy0gaz5zdHJ1Y3Q8L2MtPiA8Yy0gbmw+RjwvYy0+IDxjLSBwPjo8L2MtPiA8Yy0g
bj5FPC9jLT4gPGMtIHA+e307PC9jLT4KCiAgICA8Yy0gaz5zdGF0aWNfYXNzZXJ0PC9jLT48Yy0g
cD4oPC9jLT48Yy0gbj5zdGQ8L2MtPjxjLSBvPjo6PC9jLT48Yy0gbj5pc190cml2aWFsbHlfcmVs
b2NhdGFibGVfdjwvYy0+PGMtIG8+Jmx0OzwvYy0+IDxjLSBuPkY8L2MtPiA8Yy0gbz4+PC9jLT48
Yy0gcD4pOzwvYy0+CjwvcHJlPgogICA8aDMgY2xhc3M9ImhlYWRpbmcgc2V0dGxlZCIgaWQ9InNh
bXBsZS11bmluaXQtcmVsb2NhdGUiPjxzcGFuIGNsYXNzPSJjb250ZW50Ij5SZWZlcmVuY2UgaW1w
bGVtZW50YXRpb24gb2YgPGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMtIG4+c3RkPC9jLT48Yy0g
bz46OjwvYy0+PGMtIG4+dW5pbml0aWFsaXplZF9yZWxvY2F0ZTwvYy0+PC9jb2RlPjwvc3Bhbj48
YSBjbGFzcz0ic2VsZi1saW5rIiBocmVmPSIjc2FtcGxlLXVuaW5pdC1yZWxvY2F0ZSI+PC9hPjwv
aDM+CiAgIDxwPjxzbWFsbD48L3NtYWxsPjwvcD4KICAgPHNtYWxsPiA8cHJlIGNsYXNzPSJoaWdo
bGlnaHQiPjxjLSBrPnRlbXBsYXRlPC9jLT48Yy0gbz4mbHQ7PC9jLT48Yy0gaz5jbGFzczwvYy0+
IDxjLSBuYz5JbnB1dEl0ZXJhdG9yPC9jLT48Yy0gcD4sPC9jLT4gPGMtIGs+Y2xhc3M8L2MtPiA8
Yy0gbmM+Rm9yd2FyZEl0ZXJhdG9yPC9jLT48Yy0gbz4+PC9jLT4KPGMtIG4+Rm9yd2FyZEl0ZXJh
dG9yPC9jLT4gPGMtIG4+dW5pbml0aWFsaXplZF9yZWxvY2F0ZTwvYy0+PGMtIHA+KDwvYy0+PGMt
IG4+SW5wdXRJdGVyYXRvcjwvYy0+IDxjLSBuPmZpcnN0PC9jLT48Yy0gcD4sPC9jLT4gPGMtIG4+
SW5wdXRJdGVyYXRvcjwvYy0+IDxjLSBuPmxhc3Q8L2MtPjxjLSBwPiw8L2MtPgogICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8Yy0gbj5Gb3J3YXJkSXRlcmF0b3I8L2MtPiA8
Yy0gbj5yZXN1bHQ8L2MtPjxjLSBwPik8L2MtPgo8Yy0gcD57PC9jLT4KICAgIDxjLSBrPnVzaW5n
PC9jLT4gPGMtIG4+VDwvYy0+IDxjLSBvPj08L2MtPiA8Yy0gaz50eXBlbmFtZTwvYy0+IDxjLSBu
Pml0ZXJhdG9yX3RyYWl0czwvYy0+PGMtIG8+Jmx0OzwvYy0+PGMtIG4+Rm9yd2FyZEl0ZXJhdG9y
PC9jLT48Yy0gbz4+Ojo8L2MtPjxjLSBuPnZhbHVlX3R5cGU8L2MtPjxjLSBwPjs8L2MtPgogICAg
PGMtIGs+dXNpbmc8L2MtPiA8Yy0gbj5VPC9jLT4gPGMtIG8+PTwvYy0+IDxjLSBuPnN0ZDwvYy0+
PGMtIG8+Ojo8L2MtPjxjLSBuPnJlbW92ZV9yZWZfdDwvYy0+PGMtIG8+Jmx0OzwvYy0+PGMtIGs+
ZGVjbHR5cGU8L2MtPjxjLSBwPig8L2MtPjxjLSBuPnN0ZDwvYy0+PGMtIG8+Ojo8L2MtPjxjLSBu
Pm1vdmU8L2MtPjxjLSBwPig8L2MtPjxjLSBvPio8L2MtPjxjLSBuPmZpcnN0PC9jLT48Yy0gcD4p
KTwvYy0+PGMtIG8+PjwvYy0+PGMtIHA+OzwvYy0+CiAgICA8Yy0gaz5jb25zdGV4cHI8L2MtPiA8
Yy0gYj5ib29sPC9jLT4gPGMtIG4+bWVtY3B5YWJsZTwvYy0+IDxjLSBvPj08L2MtPiA8Yy0gcD4o
PC9jLT48Yy0gbj5zdGQ8L2MtPjxjLSBvPjo6PC9jLT48Yy0gbj5pc19zYW1lX3Y8L2MtPjxjLSBv
PiZsdDs8L2MtPjxjLSBuPlQ8L2MtPjxjLSBwPiw8L2MtPiA8Yy0gbj5VPC9jLT48Yy0gbz4+PC9j
LT4gPGMtIG8+JmFtcDsmYW1wOzwvYy0+IDxjLSBuPnN0ZDwvYy0+PGMtIG8+Ojo8L2MtPjxjLSBu
PmlzX3RyaXZpYWxseV9yZWxvY2F0YWJsZV92PC9jLT48Yy0gbz4mbHQ7PC9jLT48Yy0gbj5UPC9j
LT48Yy0gbz4+PC9jLT48Yy0gcD4pOzwvYy0+CiAgICA8Yy0gaz5jb25zdGV4cHI8L2MtPiA8Yy0g
Yj5ib29sPC9jLT4gPGMtIG4+Ym90aF9jb250aWd1b3VzPC9jLT4gPGMtIG8+PTwvYy0+IDxjLSBw
Pig8L2MtPjxjLSBuPnN0ZDwvYy0+PGMtIG8+Ojo8L2MtPjxjLSBuPmlzX3BvaW50ZXJfdjwvYy0+
PGMtIG8+Jmx0OzwvYy0+PGMtIG4+SW5wdXRJdGVyYXRvcjwvYy0+PGMtIG8+PjwvYy0+IDxjLSBv
PiZhbXA7JmFtcDs8L2MtPiA8Yy0gbj5zdGQ8L2MtPjxjLSBvPjo6PC9jLT48Yy0gbj5pc19wb2lu
dGVyX3Y8L2MtPjxjLSBvPiZsdDs8L2MtPjxjLSBuPkZvcndhcmRJdGVyYXRvcjwvYy0+PGMtIG8+
PjwvYy0+PGMtIHA+KTs8L2MtPgoKICAgIDxjLSBrPmlmPC9jLT4gPGMtIG5mPmNvbnN0ZXhwcjwv
Yy0+IDxjLSBwPig8L2MtPjxjLSBuPm1lbWNweWFibGU8L2MtPiA8Yy0gbz4mYW1wOyZhbXA7PC9j
LT4gPGMtIG4+Ym90aF9jb250aWd1b3VzPC9jLT48Yy0gcD4pPC9jLT4gPGMtIHA+ezwvYy0+CiAg
ICAgICAgPGMtIG4+c3RkPC9jLT48Yy0gbz46OjwvYy0+PGMtIGI+c2l6ZV90PC9jLT4gPGMtIG4+
bmJ5dGVzPC9jLT4gPGMtIG8+PTwvYy0+IDxjLSBwPig8L2MtPjxjLSBiPmNoYXI8L2MtPiA8Yy0g
bz4qPC9jLT48Yy0gcD4pPC9jLT48Yy0gbj5sYXN0PC9jLT4gPGMtIG8+LTwvYy0+IDxjLSBwPig8
L2MtPjxjLSBiPmNoYXI8L2MtPiA8Yy0gbz4qPC9jLT48Yy0gcD4pPC9jLT48Yy0gbj5maXJzdDwv
Yy0+PGMtIHA+OzwvYy0+CiAgICAgICAgPGMtIGs+aWY8L2MtPiA8Yy0gcD4oPC9jLT48Yy0gbj5u
Ynl0ZXM8L2MtPiA8Yy0gbz4hPTwvYy0+IDxjLSBtaT4wPC9jLT48Yy0gcD4pPC9jLT4gPGMtIHA+
ezwvYy0+CiAgICAgICAgICAgIDxjLSBuPnN0ZDwvYy0+PGMtIG8+Ojo8L2MtPjxjLSBuPm1lbW1v
dmU8L2MtPjxjLSBwPig8L2MtPjxjLSBuPnN0ZDwvYy0+PGMtIG8+Ojo8L2MtPjxjLSBuPmFkZHJl
c3NvZjwvYy0+PGMtIHA+KDwvYy0+PGMtIG8+KjwvYy0+PGMtIG4+cmVzdWx0PC9jLT48Yy0gcD4p
LDwvYy0+IDxjLSBuPnN0ZDwvYy0+PGMtIG8+Ojo8L2MtPjxjLSBuPmFkZHJlc3NvZjwvYy0+PGMt
IHA+KDwvYy0+PGMtIG8+KjwvYy0+PGMtIG4+Zmlyc3Q8L2MtPjxjLSBwPiksPC9jLT4gPGMtIG4+
bmJ5dGVzPC9jLT48Yy0gcD4pOzwvYy0+CiAgICAgICAgICAgIDxjLSBuPnJlc3VsdDwvYy0+IDxj
LSBvPis9PC9jLT4gPGMtIHA+KDwvYy0+PGMtIG4+bGFzdDwvYy0+IDxjLSBvPi08L2MtPiA8Yy0g
bj5maXJzdDwvYy0+PGMtIHA+KTs8L2MtPgogICAgICAgIDxjLSBwPn08L2MtPgogICAgPGMtIHA+
fTwvYy0+IDxjLSBrPmVsc2U8L2MtPiA8Yy0gaz5pZjwvYy0+IDxjLSBuZj5jb25zdGV4cHI8L2Mt
PiA8Yy0gcD4oPC9jLT48Yy0gbj5tZW1jcHlhYmxlPC9jLT48Yy0gcD4pPC9jLT4gPGMtIHA+ezwv
Yy0+CiAgICAgICAgPGMtIGs+Zm9yPC9jLT4gPGMtIHA+KDs8L2MtPiA8Yy0gbj5maXJzdDwvYy0+
IDxjLSBvPiE9PC9jLT4gPGMtIG4+bGFzdDwvYy0+PGMtIHA+OzwvYy0+IDxjLSBwPig8L2MtPjxj
LSBiPnZvaWQ8L2MtPjxjLSBwPik8L2MtPjxjLSBvPisrPC9jLT48Yy0gbj5yZXN1bHQ8L2MtPjxj
LSBwPiw8L2MtPiA8Yy0gbz4rKzwvYy0+PGMtIG4+Zmlyc3Q8L2MtPjxjLSBwPik8L2MtPiA8Yy0g
cD57PC9jLT4KICAgICAgICAgICAgPGMtIG4+c3RkPC9jLT48Yy0gbz46OjwvYy0+PGMtIG4+bWVt
bW92ZTwvYy0+PGMtIHA+KDwvYy0+PGMtIG4+c3RkPC9jLT48Yy0gbz46OjwvYy0+PGMtIG4+YWRk
cmVzc29mPC9jLT48Yy0gcD4oPC9jLT48Yy0gbz4qPC9jLT48Yy0gbj5yZXN1bHQ8L2MtPjxjLSBw
PiksPC9jLT4gPGMtIG4+c3RkPC9jLT48Yy0gbz46OjwvYy0+PGMtIG4+YWRkcmVzc29mPC9jLT48
Yy0gcD4oPC9jLT48Yy0gbz4qPC9jLT48Yy0gbj5maXJzdDwvYy0+PGMtIHA+KSw8L2MtPiA8Yy0g
az5zaXplb2Y8L2MtPiA8Yy0gcD4oPC9jLT48Yy0gbj5UPC9jLT48Yy0gcD4pKTs8L2MtPgogICAg
ICAgIDxjLSBwPn08L2MtPgogICAgPGMtIHA+fTwvYy0+IDxjLSBrPmVsc2U8L2MtPiA8Yy0gcD57
PC9jLT4KICAgICAgICA8Yy0gaz5mb3I8L2MtPiA8Yy0gcD4oOzwvYy0+IDxjLSBuPmZpcnN0PC9j
LT4gPGMtIG8+IT08L2MtPiA8Yy0gbj5sYXN0PC9jLT48Yy0gcD47PC9jLT4gPGMtIHA+KDwvYy0+
PGMtIGI+dm9pZDwvYy0+PGMtIHA+KTwvYy0+PGMtIG8+Kys8L2MtPjxjLSBuPnJlc3VsdDwvYy0+
PGMtIHA+LDwvYy0+IDxjLSBvPisrPC9jLT48Yy0gbj5maXJzdDwvYy0+PGMtIHA+KTwvYy0+IDxj
LSBwPns8L2MtPgogICAgICAgICAgICA8Yy0gbz46OjwvYy0+PGMtIGs+bmV3PC9jLT4gPGMtIHA+
KDwvYy0+PGMtIGs+c3RhdGljX2Nhc3Q8L2MtPjxjLSBvPiZsdDs8L2MtPjxjLSBiPnZvaWQ8L2Mt
PjxjLSBvPio+PC9jLT48Yy0gcD4oPC9jLT48Yy0gbj5zdGQ8L2MtPjxjLSBvPjo6PC9jLT48Yy0g
bj5hZGRyZXNzb2Y8L2MtPjxjLSBwPig8L2MtPjxjLSBvPio8L2MtPjxjLSBuPnJlc3VsdDwvYy0+
PGMtIHA+KSkpPC9jLT4gPGMtIG4+VDwvYy0+PGMtIHA+KDwvYy0+PGMtIG4+c3RkPC9jLT48Yy0g
bz46OjwvYy0+PGMtIG4+bW92ZTwvYy0+PGMtIHA+KDwvYy0+PGMtIG8+KjwvYy0+PGMtIG4+Zmly
c3Q8L2MtPjxjLSBwPikpOzwvYy0+CiAgICAgICAgICAgIDxjLSBuPnN0ZDwvYy0+PGMtIG8+Ojo8
L2MtPjxjLSBuPmRlc3Ryb3lfYXQ8L2MtPjxjLSBwPig8L2MtPjxjLSBuPnN0ZDwvYy0+PGMtIG8+
Ojo8L2MtPjxjLSBuPmFkZHJlc3NvZjwvYy0+PGMtIHA+KDwvYy0+PGMtIG8+KjwvYy0+PGMtIG4+
Zmlyc3Q8L2MtPjxjLSBwPikpOzwvYy0+CiAgICAgICAgPGMtIHA+fTwvYy0+CiAgICA8Yy0gcD59
PC9jLT4KICAgIDxjLSBrPnJldHVybjwvYy0+IDxjLSBuPnJlc3VsdDwvYy0+PGMtIHA+OzwvYy0+
CjxjLSBwPn08L2MtPgo8L3ByZT48L3NtYWxsPiAKICAgPHA+VGhlIGNvZGUgaW4gdGhlIGZpcnN0
IGJyYW5jaCBtdXN0IHVzZSA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gbj5tZW1tb3ZlPC9j
LT48L2NvZGU+LCByYXRoZXIgdGhhbiA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gbj5tZW1j
cHk8L2MtPjwvY29kZT4sIHRvIHByZXNlcnZlIHRoZQpmb3JtYWxseSBzcGVjaWZpZWQgYmVoYXZp
b3IgaW4gdGhlIGNhc2UgdGhhdCB0aGUgc291cmNlIHJhbmdlIG92ZXJsYXBzIHRoZSBkZXN0aW5h
dGlvbiByYW5nZS48L3A+CiAgIDxwPlRoZSBjb2RlIGluIHRoZSBzZWNvbmQgYnJhbmNoLCB3aGlj
aCBwZXJmb3JtcyBvbmUgPGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMtIG4+bWVtbW92ZTwvYy0+
PC9jb2RlPiBwZXIgZWxlbWVudCwgcHJvYmFibHkKZG9lc27igJl0IGhhdmUgbXVjaCBvZiBhIHBl
cmZvcm1hbmNlIGJlbmVmaXQsIGFuZCBtaWdodCBiZSBlbGltaW5hdGVkIGJ5IGxpYnJhcnkgdmVu
ZG9ycy48L3A+CiAgIDxoMyBjbGFzcz0iaGVhZGluZyBzZXR0bGVkIiBpZD0ic2FtcGxlLWNvbmRp
dGlvbmFsIj48c3BhbiBjbGFzcz0iY29udGVudCI+Q29uZGl0aW9uYWxseSB0cml2aWFsIHJlbG9j
YXRpb248L3NwYW4+PGEgY2xhc3M9InNlbGYtbGluayIgaHJlZj0iI3NhbXBsZS1jb25kaXRpb25h
bCI+PC9hPjwvaDM+CiAgIDxwPldlIGV4cGVjdCwgYnV0IGRvIG5vdCByZXF1aXJlLCB0aGF0IDxj
b2RlIGNsYXNzPSJoaWdobGlnaHQiPjxjLSBuPnN0ZDwvYy0+PGMtIG8+Ojo8L2MtPjxjLSBuPm9w
dGlvbmFsPC9jLT48Yy0gbz4mbHQ7PC9jLT48Yy0gbj5UPC9jLT48Yy0gbz4+PC9jLT48L2NvZGU+
IHNob3VsZCBiZSB0cml2aWFsbHkgcmVsb2NhdGFibGUKaWYgYW5kIG9ubHkgaWYgPGNvZGUgY2xh
c3M9ImhpZ2hsaWdodCI+PGMtIG4+VDwvYy0+PC9jb2RlPiBpdHNlbGYgaXMgdHJpdmlhbGx5IHJl
bG9jYXRhYmxlLiBXZSBwcm9wb3NlIG5vIGRlZGljYXRlZCBzeW50YXggZm9yIGNvbmRpdGlvbmFs
IDxjb2RlIGNsYXNzPSJoaWdobGlnaHQiPjxjLSBwPltbPC9jLT48Yy0gbj50cml2aWFsbHlfcmVs
b2NhdGFibGU8L2MtPjxjLSBwPl1dPC9jLT48L2NvZGU+LjwvcD4KICAgPHA+VGhlIGZvbGxvd2lu
ZyBhYmJyZXZpYXRlZCBpbXBsZW1lbnRhdGlvbiBzaG93cyBob3cgdG8gYWNoaWV2ZSBhbiA8Y29k
ZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gbj5vcHRpb25hbDwvYy0+PGMtIG8+Jmx0OzwvYy0+PGMt
IG4+VDwvYy0+PGMtIG8+PjwvYy0+PC9jb2RlPiB3aGljaApoYXMgdGhlIHNhbWUgdHJpdmlhbC1t
b3ZlLWNvbnN0cnVjdGliaWxpdHkgYXMgPGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMtIG4+VDwv
Yy0+PC9jb2RlPiwgdGhlIHNhbWUgdHJpdmlhbC1kZXN0cnVjdGliaWxpdHkKYXMgPGNvZGUgY2xh
c3M9ImhpZ2hsaWdodCI+PGMtIG4+VDwvYy0+PC9jb2RlPiwgYW5kIHRoZSBzYW1lIHRyaXZpYWwt
cmVsb2NhdGFiaWxpdHkgYXMgPGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMtIG4+VDwvYy0+PC9j
b2RlPi48L3A+CiAgIDxwPjxzbWFsbD48L3NtYWxsPjwvcD4KICAgPHNtYWxsPiA8cHJlIGNsYXNz
PSJoaWdobGlnaHQiPjxjLSBrPnRlbXBsYXRlPC9jLT48Yy0gbz4mbHQ7PC9jLT48Yy0gaz5jbGFz
czwvYy0+IDxjLSBuYz5UPC9jLT48Yy0gbz4+PC9jLT4KPGMtIGs+Y2xhc3M8L2MtPiA8Yy0gbmM+
b3B0aW9uYWw8L2MtPiA8Yy0gbz46PC9jLT4KICAgIDxjLSBuPm9wdGlvbmFsX2E8L2MtPjxjLSBv
PiZsdDs8L2MtPjxjLSBuPlQ8L2MtPjxjLSBwPiw8L2MtPiA8Yy0gbj5pc190cml2aWFsbHlfcmVs
b2NhdGFibGU8L2MtPjxjLSBvPiZsdDs8L2MtPjxjLSBuPlQ8L2MtPjxjLSBvPj4+PC9jLT4KPGMt
IHA+ezwvYy0+CiAgICA8Yy0gaz51c2luZzwvYy0+IDxjLSBuPm9wdGlvbmFsX2E8L2MtPjxjLSBv
PiZsdDs8L2MtPjxjLSBuPlQ8L2MtPjxjLSBwPiw8L2MtPiA8Yy0gbj5pc190cml2aWFsbHlfcmVs
b2NhdGFibGU8L2MtPjxjLSBvPiZsdDs8L2MtPjxjLSBuPlQ8L2MtPjxjLSBvPj4+Ojo8L2MtPjxj
LSBuPm9wdGlvbmFsX2E8L2MtPjxjLSBwPjs8L2MtPgo8Yy0gcD59OzwvYy0+Cgo8Yy0gaz50ZW1w
bGF0ZTwvYy0+PGMtIG8+Jmx0OzwvYy0+PGMtIGs+Y2xhc3M8L2MtPiA8Yy0gbmM+VDwvYy0+PGMt
IHA+LDwvYy0+IDxjLSBiPmJvb2w8L2MtPiA8Yy0gbj5SPC9jLT48Yy0gbz4+PC9jLT4KPGMtIGs+
Y2xhc3M8L2MtPiA8Yy0gbmM+b3B0aW9uYWxfYTwvYy0+IDxjLSBvPjo8L2MtPgogICAgPGMtIG4+
b3B0aW9uYWxfYjwvYy0+PGMtIG8+Jmx0OzwvYy0+PGMtIG4+VDwvYy0+PGMtIHA+LDwvYy0+IDxj
LSBuPmlzX3RyaXZpYWxseV9kZXN0cnVjdGlibGU8L2MtPjxjLSBvPiZsdDs8L2MtPjxjLSBuPlQ8
L2MtPjxjLSBvPj48L2MtPjxjLSBwPiw8L2MtPiA8Yy0gbj5pc190cml2aWFsbHlfbW92ZV9jb25z
dHJ1Y3RpYmxlPC9jLT48Yy0gbz4mbHQ7PC9jLT48Yy0gbj5UPC9jLT48Yy0gbz4+PjwvYy0+Cjxj
LSBwPns8L2MtPgogICAgPGMtIGs+dXNpbmc8L2MtPiA8Yy0gbj5vcHRpb25hbF9iPC9jLT48Yy0g
bz4mbHQ7PC9jLT48Yy0gbj5UPC9jLT48Yy0gcD4sPC9jLT4gPGMtIG4+aXNfdHJpdmlhbGx5X2Rl
c3RydWN0aWJsZTwvYy0+PGMtIG8+Jmx0OzwvYy0+PGMtIG4+VDwvYy0+PGMtIG8+PjwvYy0+PGMt
IHA+LDwvYy0+CiAgICAgICAgPGMtIG4+aXNfdHJpdmlhbGx5X21vdmVfY29uc3RydWN0aWJsZTwv
Yy0+PGMtIG8+Jmx0OzwvYy0+PGMtIG4+VDwvYy0+PGMtIG8+Pj46OjwvYy0+PGMtIG4+b3B0aW9u
YWxfYjwvYy0+PGMtIHA+OzwvYy0+CjxjLSBwPn07PC9jLT4KCjxjLSBrPnRlbXBsYXRlPC9jLT48
Yy0gbz4mbHQ7PC9jLT48Yy0gaz5jbGFzczwvYy0+IDxjLSBuYz5UPC9jLT48Yy0gbz4+PC9jLT4K
PGMtIGs+Y2xhc3M8L2MtPiBbWzxjLSBuYz50cml2aWFsbHlfcmVsb2NhdGFibGU8L2MtPjxjLSBw
Pl1dPC9jLT4gPGMtIG4+b3B0aW9uYWxfYTwvYy0+PGMtIG8+Jmx0OzwvYy0+PGMtIG4+VDwvYy0+
PGMtIHA+LDwvYy0+IHRydWU8Yy0gbz4+PC9jLT4gPGMtIG8+OjwvYy0+CiAgICA8Yy0gbj5vcHRp
b25hbF9iPC9jLT48Yy0gbz4mbHQ7PC9jLT48Yy0gbj5UPC9jLT48Yy0gcD4sPC9jLT4gPGMtIG4+
aXNfdHJpdmlhbGx5X2Rlc3RydWN0aWJsZTwvYy0+PGMtIG8+Jmx0OzwvYy0+PGMtIG4+VDwvYy0+
PGMtIG8+PjwvYy0+PGMtIHA+LDwvYy0+IDxjLSBuPmlzX3RyaXZpYWxseV9tb3ZlX2NvbnN0cnVj
dGlibGU8L2MtPjxjLSBvPiZsdDs8L2MtPjxjLSBuPlQ8L2MtPjxjLSBvPj4+PC9jLT4KPGMtIHA+
ezwvYy0+CiAgICA8Yy0gaz51c2luZzwvYy0+IDxjLSBuPm9wdGlvbmFsX2I8L2MtPjxjLSBvPiZs
dDs8L2MtPjxjLSBuPlQ8L2MtPjxjLSBwPiw8L2MtPiA8Yy0gbj5pc190cml2aWFsbHlfZGVzdHJ1
Y3RpYmxlPC9jLT48Yy0gbz4mbHQ7PC9jLT48Yy0gbj5UPC9jLT48Yy0gbz4+PC9jLT48Yy0gcD4s
PC9jLT4KICAgICAgICA8Yy0gbj5pc190cml2aWFsbHlfbW92ZV9jb25zdHJ1Y3RpYmxlPC9jLT48
Yy0gbz4mbHQ7PC9jLT48Yy0gbj5UPC9jLT48Yy0gbz4+Pjo6PC9jLT48Yy0gbj5vcHRpb25hbF9i
PC9jLT48Yy0gcD47PC9jLT4KPGMtIHA+fTs8L2MtPgoKPGMtIGs+dGVtcGxhdGU8L2MtPjxjLSBv
PiZsdDs8L2MtPjxjLSBrPmNsYXNzPC9jLT4gPGMtIG5jPlQ8L2MtPjxjLSBwPiw8L2MtPiA8Yy0g
Yj5ib29sPC9jLT4gPGMtIG4+RDwvYy0+PGMtIHA+LDwvYy0+IDxjLSBiPmJvb2w8L2MtPiA8Yy0g
bj5NPC9jLT48Yy0gbz4+PC9jLT4KPGMtIGs+Y2xhc3M8L2MtPiA8Yy0gbmM+b3B0aW9uYWxfYjwv
Yy0+IDxjLSBwPns8L2MtPgogICAgPGMtIGs+dW5pb248L2MtPiA8Yy0gcD57PC9jLT4KICAgICAg
ICA8Yy0gYj5jaGFyPC9jLT4gPGMtIG4+ZHVtbXlfPC9jLT48Yy0gcD47PC9jLT4KICAgICAgICA8
Yy0gbj5UPC9jLT4gPGMtIG4+dmFsdWVfPC9jLT48Yy0gcD47PC9jLT4KICAgIDxjLSBwPn07PC9j
LT4KICAgIDxjLSBiPmJvb2w8L2MtPiA8Yy0gbj5lbmdhZ2VkXzwvYy0+IDxjLSBvPj08L2MtPiBm
YWxzZTxjLSBwPjs8L2MtPgoKICAgIDxjLSBuPm9wdGlvbmFsX2I8L2MtPjxjLSBwPigpPC9jLT4g
PGMtIG8+PTwvYy0+IDxjLSBrPmRlZmF1bHQ8L2MtPjxjLSBwPjs8L2MtPgogICAgPGMtIG4+b3B0
aW9uYWxfYjwvYy0+PGMtIHA+KDwvYy0+PGMtIG4+aW5wbGFjZV90PC9jLT48Yy0gcD4sPC9jLT4g
PGMtIG4+QXJnczwvYy0+PGMtIG8+JmFtcDsmYW1wOzwvYy0+IDxjLSBuPmFyZ3M8L2MtPjxjLSBw
Pi4uLik8L2MtPiA8Yy0gbz46PC9jLT4KICAgICAgICA8Yy0gbj5lbmdhZ2VkXzwvYy0+PGMtIHA+
KDwvYy0+dHJ1ZTxjLSBwPiksPC9jLT4gPGMtIG4+dmFsdWVfPC9jLT48Yy0gcD4oPC9jLT48Yy0g
bj5zdGQ8L2MtPjxjLSBvPjo6PC9jLT48Yy0gbj5mb3J3YXJkPC9jLT48Yy0gbz4mbHQ7PC9jLT48
Yy0gbj5BcmdzPC9jLT48Yy0gbz4+PC9jLT48Yy0gcD4oPC9jLT48Yy0gbj5hcmdzPC9jLT48Yy0g
cD4pLi4uKTwvYy0+IDxjLSBwPnt9PC9jLT4KICAgIDxjLSBuPm9wdGlvbmFsX2I8L2MtPjxjLSBw
Pig8L2MtPjxjLSBuPm9wdGlvbmFsX2I8L2MtPjxjLSBvPiZhbXA7JmFtcDs8L2MtPiA8Yy0gbj5y
aHM8L2MtPjxjLSBwPik8L2MtPiA8Yy0gcD57PC9jLT4KICAgICAgICA8Yy0gaz5pZjwvYy0+IDxj
LSBwPig8L2MtPjxjLSBuPnJoczwvYy0+PGMtIHA+LjwvYy0+PGMtIG4+ZW5nYWdlZF88L2MtPjxj
LSBwPik8L2MtPiA8Yy0gcD57PC9jLT4KICAgICAgICAgICAgPGMtIG4+ZW5nYWdlZF88L2MtPiA8
Yy0gbz49PC9jLT4gdHJ1ZTxjLSBwPjs8L2MtPgogICAgICAgICAgICA8Yy0gbz46OjwvYy0+PGMt
IGs+bmV3PC9jLT4gPGMtIHA+KDwvYy0+PGMtIG4+c3RkPC9jLT48Yy0gbz46OjwvYy0+PGMtIG4+
YWRkcmVzc29mPC9jLT48Yy0gcD4oPC9jLT48Yy0gbj52YWx1ZV88L2MtPjxjLSBwPikpPC9jLT4g
PGMtIG4+VDwvYy0+PGMtIHA+KDwvYy0+PGMtIG4+c3RkPC9jLT48Yy0gbz46OjwvYy0+PGMtIG4+
bW92ZTwvYy0+PGMtIHA+KDwvYy0+PGMtIG4+cmhzPC9jLT48Yy0gcD4uPC9jLT48Yy0gbj52YWx1
ZV88L2MtPjxjLSBwPikpOzwvYy0+CiAgICAgICAgPGMtIHA+fTwvYy0+CiAgICA8Yy0gcD59PC9j
LT4KICAgIDxjLSBvPn48L2MtPjxjLSBuPm9wdGlvbmFsX2I8L2MtPjxjLSBwPigpPC9jLT4gPGMt
IHA+ezwvYy0+CiAgICAgICAgPGMtIGs+aWY8L2MtPiA8Yy0gcD4oPC9jLT48Yy0gbj5lbmdhZ2Vk
XzwvYy0+PGMtIHA+KTwvYy0+IDxjLSBuPnZhbHVlXzwvYy0+PGMtIHA+LjwvYy0+PGMtIG8+fjwv
Yy0+PGMtIG4+VDwvYy0+PGMtIHA+KCk7PC9jLT4KICAgIDxjLSBwPn08L2MtPgo8Yy0gcD59Ozwv
Yy0+Cgo8Yy0gaz50ZW1wbGF0ZTwvYy0+PGMtIG8+Jmx0OzwvYy0+PGMtIGs+Y2xhc3M8L2MtPiA8
Yy0gbmM+VDwvYy0+PGMtIG8+PjwvYy0+CjxjLSBrPmNsYXNzPC9jLT4gPGMtIG5jPm9wdGlvbmFs
X2I8L2MtPjxjLSBvPiZsdDs8L2MtPjxjLSBuPlQ8L2MtPjxjLSBwPiw8L2MtPiBmYWxzZTxjLSBw
Piw8L2MtPiB0cnVlPGMtIG8+PjwvYy0+IDxjLSBwPns8L2MtPgogICAgPGMtIGs+dW5pb248L2Mt
PiA8Yy0gcD57PC9jLT4KICAgICAgICA8Yy0gYj5jaGFyPC9jLT4gPGMtIG4+ZHVtbXlfPC9jLT48
Yy0gcD47PC9jLT4KICAgICAgICA8Yy0gbj5UPC9jLT4gPGMtIG4+dmFsdWVfPC9jLT48Yy0gcD47
PC9jLT4KICAgIDxjLSBwPn07PC9jLT4KICAgIDxjLSBiPmJvb2w8L2MtPiA8Yy0gbj5lbmdhZ2Vk
XzwvYy0+IDxjLSBvPj08L2MtPiBmYWxzZTxjLSBwPjs8L2MtPgoKICAgIDxjLSBuPm9wdGlvbmFs
X2I8L2MtPjxjLSBwPigpPC9jLT4gPGMtIG8+PTwvYy0+IDxjLSBrPmRlZmF1bHQ8L2MtPjxjLSBw
Pjs8L2MtPgogICAgPGMtIG4+b3B0aW9uYWxfYjwvYy0+PGMtIHA+KDwvYy0+PGMtIG4+aW5wbGFj
ZV90PC9jLT48Yy0gcD4sPC9jLT4gPGMtIG4+QXJnczwvYy0+PGMtIG8+JmFtcDsmYW1wOzwvYy0+
IDxjLSBuPmFyZ3M8L2MtPjxjLSBwPi4uLik8L2MtPiA8Yy0gbz46PC9jLT4KICAgICAgICA8Yy0g
bj5lbmdhZ2VkXzwvYy0+PGMtIHA+KDwvYy0+dHJ1ZTxjLSBwPiksPC9jLT4gPGMtIG4+dmFsdWVf
PC9jLT48Yy0gcD4oPC9jLT48Yy0gbj5zdGQ8L2MtPjxjLSBvPjo6PC9jLT48Yy0gbj5mb3J3YXJk
PC9jLT48Yy0gbz4mbHQ7PC9jLT48Yy0gbj5BcmdzPC9jLT48Yy0gbz4+PC9jLT48Yy0gcD4oPC9j
LT48Yy0gbj5hcmdzPC9jLT48Yy0gcD4pLi4uKTwvYy0+IDxjLSBwPnt9PC9jLT4KICAgIDxjLSBu
Pm9wdGlvbmFsX2I8L2MtPjxjLSBwPig8L2MtPjxjLSBuPm9wdGlvbmFsX2I8L2MtPjxjLSBvPiZh
bXA7JmFtcDs8L2MtPjxjLSBwPik8L2MtPiA8Yy0gbz49PC9jLT4gPGMtIGs+ZGVmYXVsdDwvYy0+
PGMtIHA+OzwvYy0+CiAgICA8Yy0gbz5+PC9jLT48Yy0gbj5vcHRpb25hbF9iPC9jLT48Yy0gcD4o
KTwvYy0+IDxjLSBwPns8L2MtPgogICAgICAgIDxjLSBrPmlmPC9jLT4gPGMtIHA+KDwvYy0+PGMt
IG4+ZW5nYWdlZF88L2MtPjxjLSBwPik8L2MtPiA8Yy0gbj52YWx1ZV88L2MtPjxjLSBwPi48L2Mt
PjxjLSBvPn48L2MtPjxjLSBuPlQ8L2MtPjxjLSBwPigpOzwvYy0+CiAgICA8Yy0gcD59PC9jLT4K
PGMtIHA+fTs8L2MtPgoKPGMtIGs+dGVtcGxhdGU8L2MtPjxjLSBvPiZsdDs8L2MtPjxjLSBrPmNs
YXNzPC9jLT4gPGMtIG5jPlQ8L2MtPjxjLSBvPj48L2MtPgo8Yy0gaz5jbGFzczwvYy0+IDxjLSBu
Yz5vcHRpb25hbF9iPC9jLT48Yy0gbz4mbHQ7PC9jLT48Yy0gbj5UPC9jLT48Yy0gcD4sPC9jLT4g
dHJ1ZTxjLSBwPiw8L2MtPiBmYWxzZTxjLSBvPj48L2MtPiA8Yy0gcD57PC9jLT4KICAgIDxjLSBr
PnVuaW9uPC9jLT4gPGMtIHA+ezwvYy0+CiAgICAgICAgPGMtIGI+Y2hhcjwvYy0+IDxjLSBuPmR1
bW15XzwvYy0+PGMtIHA+OzwvYy0+CiAgICAgICAgPGMtIG4+VDwvYy0+IDxjLSBuPnZhbHVlXzwv
Yy0+PGMtIHA+OzwvYy0+CiAgICA8Yy0gcD59OzwvYy0+CiAgICA8Yy0gYj5ib29sPC9jLT4gPGMt
IG4+ZW5nYWdlZF88L2MtPiA8Yy0gbz49PC9jLT4gZmFsc2U8Yy0gcD47PC9jLT4KCiAgICA8Yy0g
bj5vcHRpb25hbF9iPC9jLT48Yy0gcD4oKTwvYy0+IDxjLSBvPj08L2MtPiA8Yy0gaz5kZWZhdWx0
PC9jLT48Yy0gcD47PC9jLT4KICAgIDxjLSBuPm9wdGlvbmFsX2I8L2MtPjxjLSBwPig8L2MtPjxj
LSBuPmlucGxhY2VfdDwvYy0+PGMtIHA+LDwvYy0+IDxjLSBuPkFyZ3M8L2MtPjxjLSBvPiZhbXA7
JmFtcDs8L2MtPiA8Yy0gbj5hcmdzPC9jLT48Yy0gcD4uLi4pPC9jLT4gPGMtIG8+OjwvYy0+CiAg
ICAgICAgPGMtIG4+ZW5nYWdlZF88L2MtPjxjLSBwPig8L2MtPnRydWU8Yy0gcD4pLDwvYy0+IDxj
LSBuPnZhbHVlXzwvYy0+PGMtIHA+KDwvYy0+PGMtIG4+c3RkPC9jLT48Yy0gbz46OjwvYy0+PGMt
IG4+Zm9yd2FyZDwvYy0+PGMtIG8+Jmx0OzwvYy0+PGMtIG4+QXJnczwvYy0+PGMtIG8+PjwvYy0+
PGMtIHA+KDwvYy0+PGMtIG4+YXJnczwvYy0+PGMtIHA+KS4uLik8L2MtPiA8Yy0gcD57fTwvYy0+
CiAgICA8Yy0gbj5vcHRpb25hbF9iPC9jLT48Yy0gcD4oPC9jLT48Yy0gbj5vcHRpb25hbF9iPC9j
LT48Yy0gbz4mYW1wOyZhbXA7PC9jLT4gPGMtIG4+cmhzPC9jLT48Yy0gcD4pPC9jLT4gPGMtIHA+
ezwvYy0+CiAgICAgICAgPGMtIGs+aWY8L2MtPiA8Yy0gcD4oPC9jLT48Yy0gbj5yaHM8L2MtPjxj
LSBwPi48L2MtPjxjLSBuPmVuZ2FnZWRfPC9jLT48Yy0gcD4pPC9jLT4gPGMtIHA+ezwvYy0+CiAg
ICAgICAgICAgIDxjLSBuPmVuZ2FnZWRfPC9jLT4gPGMtIG8+PTwvYy0+IHRydWU8Yy0gcD47PC9j
LT4KICAgICAgICAgICAgPGMtIG8+Ojo8L2MtPjxjLSBrPm5ldzwvYy0+IDxjLSBwPig8L2MtPjxj
LSBuPnN0ZDwvYy0+PGMtIG8+Ojo8L2MtPjxjLSBuPmFkZHJlc3NvZjwvYy0+PGMtIHA+KDwvYy0+
PGMtIG4+dmFsdWVfPC9jLT48Yy0gcD4pKTwvYy0+IDxjLSBuPlQ8L2MtPjxjLSBwPig8L2MtPjxj
LSBuPnN0ZDwvYy0+PGMtIG8+Ojo8L2MtPjxjLSBuPm1vdmU8L2MtPjxjLSBwPig8L2MtPjxjLSBu
PnJoczwvYy0+PGMtIHA+LjwvYy0+PGMtIG4+dmFsdWVfPC9jLT48Yy0gcD4pKTs8L2MtPgogICAg
ICAgIDxjLSBwPn08L2MtPgogICAgPGMtIHA+fTwvYy0+CiAgICA8Yy0gbz5+PC9jLT48Yy0gbj5v
cHRpb25hbF9iPC9jLT48Yy0gcD4oKTwvYy0+IDxjLSBvPj08L2MtPiA8Yy0gaz5kZWZhdWx0PC9j
LT48Yy0gcD47PC9jLT4KPGMtIHA+fTs8L2MtPgoKPGMtIGs+dGVtcGxhdGU8L2MtPjxjLSBvPiZs
dDs8L2MtPjxjLSBrPmNsYXNzPC9jLT4gPGMtIG5jPlQ8L2MtPjxjLSBvPj48L2MtPgo8Yy0gaz5j
bGFzczwvYy0+IDxjLSBuYz5vcHRpb25hbF9iPC9jLT48Yy0gbz4mbHQ7PC9jLT48Yy0gbj5UPC9j
LT48Yy0gcD4sPC9jLT4gdHJ1ZTxjLSBwPiw8L2MtPiB0cnVlPGMtIG8+PjwvYy0+IDxjLSBwPns8
L2MtPgogICAgPGMtIGs+dW5pb248L2MtPiA8Yy0gcD57PC9jLT4KICAgICAgICA8Yy0gYj5jaGFy
PC9jLT4gPGMtIG4+ZHVtbXlfPC9jLT48Yy0gcD47PC9jLT4KICAgICAgICA8Yy0gbj5UPC9jLT4g
PGMtIG4+dmFsdWVfPC9jLT48Yy0gcD47PC9jLT4KICAgIDxjLSBwPn07PC9jLT4KICAgIDxjLSBi
PmJvb2w8L2MtPiA8Yy0gbj5lbmdhZ2VkXzwvYy0+IDxjLSBvPj08L2MtPiBmYWxzZTxjLSBwPjs8
L2MtPgoKICAgIDxjLSBuPm9wdGlvbmFsX2I8L2MtPjxjLSBwPigpPC9jLT4gPGMtIG8+PTwvYy0+
IDxjLSBrPmRlZmF1bHQ8L2MtPjxjLSBwPjs8L2MtPgogICAgPGMtIG4+b3B0aW9uYWxfYjwvYy0+
PGMtIHA+KDwvYy0+PGMtIG4+aW5wbGFjZV90PC9jLT48Yy0gcD4sPC9jLT4gPGMtIG4+QXJnczwv
Yy0+PGMtIG8+JmFtcDsmYW1wOzwvYy0+IDxjLSBuPmFyZ3M8L2MtPjxjLSBwPi4uLik8L2MtPiA8
Yy0gbz46PC9jLT4KICAgICAgICA8Yy0gbj5lbmdhZ2VkXzwvYy0+PGMtIHA+KDwvYy0+dHJ1ZTxj
LSBwPiksPC9jLT4gPGMtIG4+dmFsdWVfPC9jLT48Yy0gcD4oPC9jLT48Yy0gbj5zdGQ8L2MtPjxj
LSBvPjo6PC9jLT48Yy0gbj5mb3J3YXJkPC9jLT48Yy0gbz4mbHQ7PC9jLT48Yy0gbj5BcmdzPC9j
LT48Yy0gbz4+PC9jLT48Yy0gcD4oPC9jLT48Yy0gbj5hcmdzPC9jLT48Yy0gcD4pLi4uKTwvYy0+
IDxjLSBwPnt9PC9jLT4KCiAgICA8Yy0gbj5vcHRpb25hbF9iPC9jLT48Yy0gcD4oPC9jLT48Yy0g
bj5vcHRpb25hbF9iPC9jLT48Yy0gbz4mYW1wOyZhbXA7PC9jLT48Yy0gcD4pPC9jLT4gPGMtIG8+
PTwvYy0+IDxjLSBrPmRlZmF1bHQ8L2MtPjxjLSBwPjs8L2MtPgogICAgPGMtIG8+fjwvYy0+PGMt
IG4+b3B0aW9uYWxfYjwvYy0+PGMtIHA+KCk8L2MtPiA8Yy0gbz49PC9jLT4gPGMtIGs+ZGVmYXVs
dDwvYy0+PGMtIHA+OzwvYy0+CjxjLSBwPn07PC9jLT4KPC9wcmU+PC9zbWFsbD4gCiAgIDxoMiBj
bGFzcz0iaGVhZGluZyBzZXR0bGVkIiBpZD0ibm9uLXRyaXZpYWwtc2FtcGxlcyI+PHNwYW4gY2xh
c3M9ImNvbnRlbnQiPkFwcGVuZGl4IEM6IEV4YW1wbGVzIG9mIG5vbi10cml2aWFsbHkgcmVsb2Nh
dGFibGUgY2xhc3MgdHlwZXM8L3NwYW4+PGEgY2xhc3M9InNlbGYtbGluayIgaHJlZj0iI25vbi10
cml2aWFsLXNhbXBsZXMiPjwvYT48L2gyPgogICA8aDMgY2xhc3M9ImhlYWRpbmcgc2V0dGxlZCIg
aWQ9Im5vbi10cml2aWFsLXNhbXBsZS1zdHJpbmciPjxzcGFuIGNsYXNzPSJjb250ZW50Ij5DbGFz
cyBjb250YWlucyBwb2ludGVyIHRvIHNlbGY8L3NwYW4+PGEgY2xhc3M9InNlbGYtbGluayIgaHJl
Zj0iI25vbi10cml2aWFsLXNhbXBsZS1zdHJpbmciPjwvYT48L2gzPgogICA8cD5UaGlzIGZpY3Rp
b25hbCA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gbj5zaG9ydF9zdHJpbmc8L2MtPjwvY29k
ZT4gaWxsdXN0cmF0ZXMgYSBtZWNoYW5pc20gdGhhdCBjYW4gYXBwbHkKdG8gYW55IHNtYWxsLWJ1
ZmZlci1vcHRpbWl6ZWQgY2xhc3MuIDxhIGRhdGEtbGluay10eXBlPSJiaWJsaW8iIGhyZWY9IiNi
aWJsaW8tbGliY3h4ZnVuY3Rpb24iPmxpYmMrKydzIHN0ZDo6ZnVuY3Rpb248L2E+IHVzZXMgdGhp
cyBtZWNoYW5pc20gKG9uIGEgMjQtYnl0ZSBidWZmZXIpIGFuZCBpcyB0aHVzIG5vdCB0cml2aWFs
bHkgcmVsb2NhdGFibGUuPC9wPgogICA8cD5Ib3dldmVyLCBkaWZmZXJlbnQgbWVjaGFuaXNtcyBm
b3Igc21hbGwtYnVmZmVyIG9wdGltaXphdGlvbiBleGlzdC4gPGEgZGF0YS1saW5rLXR5cGU9ImJp
YmxpbyIgaHJlZj0iI2JpYmxpby1saWJjeHhhbnkiPmxpYmMrKydzIHN0ZDo6YW55PC9hPiBhbHNv
IGFjaGlldmVzIHNtYWxsLWJ1ZmZlciBvcHRpbWl6YXRpb24Kb24gYSAyNC1ieXRlIGJ1ZmZlciwg
d2l0aG91dCAobmVjZXNzYXJpbHkpIHNhY3JpZmljaW5nIHRyaXZpYWwgcmVsb2NhdGFiaWxpdHku
PC9wPgogICA8cD48c21hbGw+PC9zbWFsbD48L3A+CiAgIDxzbWFsbD4gPHByZSBjbGFzcz0iaGln
aGxpZ2h0Ij48Yy0gaz5zdHJ1Y3Q8L2MtPiA8Yy0gbj5zaG9ydF9zdHJpbmc8L2MtPiA8Yy0gcD57
PC9jLT4KICAgIDxjLSBiPmNoYXI8L2MtPiA8Yy0gbz4qPC9jLT48Yy0gbj5kYXRhXzwvYy0+IDxj
LSBvPj08L2MtPiA8Yy0gbj5idWZmZXJfPC9jLT48Yy0gcD47PC9jLT4KICAgIDxjLSBiPnNpemVf
dDwvYy0+IDxjLSBuPnNpemVfPC9jLT4gPGMtIG8+PTwvYy0+IDxjLSBtaT4wPC9jLT48Yy0gcD47
PC9jLT4KICAgIDxjLSBiPmNoYXI8L2MtPiA8Yy0gbj5idWZmZXJfPC9jLT48Yy0gcD5bPC9jLT48
Yy0gbWk+ODwvYy0+PGMtIHA+XTwvYy0+IDxjLSBvPj08L2MtPiA8Yy0gcD57fTs8L2MtPgoKICAg
IDxjLSBrPmNvbnN0PC9jLT4gPGMtIGI+Y2hhcjwvYy0+IDxjLSBvPio8L2MtPjxjLSBuZj5kYXRh
PC9jLT48Yy0gcD4oKTwvYy0+IDxjLSBrPmNvbnN0PC9jLT4gPGMtIHA+ezwvYy0+IDxjLSBrPnJl
dHVybjwvYy0+IDxjLSBuPmRhdGFfPC9jLT48Yy0gcD47PC9jLT4gPGMtIHA+fTwvYy0+CgogICAg
PGMtIG4+c2hvcnRfc3RyaW5nPC9jLT48Yy0gcD4oKTwvYy0+IDxjLSBvPj08L2MtPiA8Yy0gaz5k
ZWZhdWx0PC9jLT48Yy0gcD47PC9jLT4KICAgIDxjLSBuPnNob3J0X3N0cmluZzwvYy0+PGMtIHA+
KDwvYy0+PGMtIGs+Y29uc3Q8L2MtPiA8Yy0gYj5jaGFyPC9jLT4gPGMtIG8+KjwvYy0+PGMtIG4+
czwvYy0+PGMtIHA+KTwvYy0+IDxjLSBvPjo8L2MtPiA8Yy0gbj5zaXplXzwvYy0+PGMtIHA+KDwv
Yy0+PGMtIG4+c3RybGVuPC9jLT48Yy0gcD4oPC9jLT48Yy0gbj5zPC9jLT48Yy0gcD4pKTwvYy0+
IDxjLSBwPns8L2MtPgogICAgICAgIDxjLSBrPmlmPC9jLT4gPGMtIHA+KDwvYy0+PGMtIG4+c2l6
ZV88L2MtPiA8Yy0gbz4mbHQ7PC9jLT4gPGMtIGs+c2l6ZW9mPC9jLT4gPGMtIG4+YnVmZmVyXzwv
Yy0+PGMtIHA+KTwvYy0+CiAgICAgICAgICAgIDxjLSBuPnN0cmNweTwvYy0+PGMtIHA+KDwvYy0+
PGMtIG4+YnVmZmVyXzwvYy0+PGMtIHA+LDwvYy0+IDxjLSBuPnM8L2MtPjxjLSBwPik7PC9jLT4K
ICAgICAgICA8Yy0gaz5lbHNlPC9jLT4KICAgICAgICAgICAgPGMtIG4+ZGF0YV88L2MtPiA8Yy0g
bz49PC9jLT4gPGMtIG4+c3RyZHVwPC9jLT48Yy0gcD4oPC9jLT48Yy0gbj5zPC9jLT48Yy0gcD4p
OzwvYy0+CiAgICA8Yy0gcD59PC9jLT4KICAgIDxjLSBuPnNob3J0X3N0cmluZzwvYy0+PGMtIHA+
KDwvYy0+PGMtIG4+c2hvcnRfc3RyaW5nPC9jLT48Yy0gbz4mYW1wOyZhbXA7PC9jLT4gPGMtIG4+
czwvYy0+PGMtIHA+KTwvYy0+IDxjLSBwPns8L2MtPgogICAgICAgIDxjLSBuPm1lbWNweTwvYy0+
PGMtIHA+KDwvYy0+PGMtIGs+dGhpczwvYy0+PGMtIHA+LDwvYy0+IDxjLSBvPiZhbXA7PC9jLT48
Yy0gbj5zPC9jLT48Yy0gcD4sPC9jLT4gPGMtIGs+c2l6ZW9mPC9jLT48Yy0gcD4oPC9jLT48Yy0g
bz4qPC9jLT48Yy0gaz50aGlzPC9jLT48Yy0gcD4pKTs8L2MtPgogICAgICAgIDxjLSBrPmlmPC9j
LT4gPGMtIHA+KDwvYy0+PGMtIG4+czwvYy0+PGMtIHA+LjwvYy0+PGMtIG4+ZGF0YV88L2MtPiA8
Yy0gbz49PTwvYy0+IDxjLSBuPnM8L2MtPjxjLSBwPi48L2MtPjxjLSBuPmJ1ZmZlcl88L2MtPjxj
LSBwPik8L2MtPgogICAgICAgICAgICA8Yy0gbj5kYXRhXzwvYy0+IDxjLSBvPj08L2MtPiA8Yy0g
bj5idWZmZXJfPC9jLT48Yy0gcD47PC9jLT4KICAgICAgICA8Yy0gaz5lbHNlPC9jLT4KICAgICAg
ICAgICAgPGMtIG4+czwvYy0+PGMtIHA+LjwvYy0+PGMtIG4+ZGF0YV88L2MtPiA8Yy0gbz49PC9j
LT4gPGMtIGs+bnVsbHB0cjwvYy0+PGMtIHA+OzwvYy0+CiAgICA8Yy0gcD59PC9jLT4KICAgIDxj
LSBvPn48L2MtPjxjLSBuPnNob3J0X3N0cmluZzwvYy0+PGMtIHA+KCk8L2MtPiA8Yy0gcD57PC9j
LT4KICAgICAgICA8Yy0gaz5pZjwvYy0+IDxjLSBwPig8L2MtPjxjLSBuPmRhdGFfPC9jLT4gPGMt
IG8+IT08L2MtPiA8Yy0gbj5idWZmZXJfPC9jLT48Yy0gcD4pPC9jLT4KICAgICAgICAgICAgPGMt
IG4+ZnJlZTwvYy0+PGMtIHA+KDwvYy0+PGMtIG4+ZGF0YV88L2MtPjxjLSBwPik7PC9jLT4KICAg
IDxjLSBwPn08L2MtPgo8Yy0gcD59OzwvYy0+CjwvcHJlPjwvc21hbGw+IAogICA8aDMgY2xhc3M9
ImhlYWRpbmcgc2V0dGxlZCIgaWQ9Im5vbi10cml2aWFsLXNhbXBsZS1saXN0Ij48c3BhbiBjbGFz
cz0iY29udGVudCI+QWxsb2NhdGVkIG1lbW9yeSBjb250YWlucyBwb2ludGVyIHRvIHNlbGY8L3Nw
YW4+PGEgY2xhc3M9InNlbGYtbGluayIgaHJlZj0iI25vbi10cml2aWFsLXNhbXBsZS1saXN0Ij48
L2E+PC9oMz4KICAgPHA+PGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMtIG4+c3RkPC9jLT48Yy0g
bz46OjwvYy0+PGMtIG4+bGlzdDwvYy0+PC9jb2RlPiBuZWVkcyBzb21ld2hlcmUgdG8gc3RvcmUg
aXRzICJwYXN0LXRoZS1lbmQiIG5vZGUsIGNvbW1vbmx5IHJlZmVycmVkIHRvCmFzIHRoZSAic2Vu
dGluZWwgbm9kZSwiIHdob3NlIDxjb2RlIGNsYXNzPSJoaWdobGlnaHQiPjxjLSBuPnByZXY8L2Mt
PjwvY29kZT4gcG9pbnRlciBwb2ludHMgdG8gdGhlIGxpc3TigJlzIGxhc3Qgbm9kZS4KSWYgdGhl
IHNlbnRpbmVsIG5vZGUgaXMgYWxsb2NhdGVkIG9uIHRoZSBoZWFwLCB0aGVuIDxjb2RlIGNsYXNz
PSJoaWdobGlnaHQiPjxjLSBuPnN0ZDwvYy0+PGMtIG8+Ojo8L2MtPjxjLSBuPmxpc3Q8L2MtPjwv
Y29kZT4gY2FuIGJlIHRyaXZpYWxseQpyZWxvY2F0YWJsZTsgYnV0IGlmIHRoZSBzZW50aW5lbCBu
b2RlIGlzIHBsYWNlZCB3aXRoaW4gdGhlIDxjb2RlIGNsYXNzPSJoaWdobGlnaHQiPjxjLSBuPmxp
c3Q8L2MtPjwvY29kZT4gb2JqZWN0IGl0c2VsZgooYXMgaGFwcGVucyBvbiBsaWJjKysgYW5kIGxp
YnN0ZGMrKyksIHRoZW4gcmVsb2NhdGluZyB0aGUgPGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMt
IG4+bGlzdDwvYy0+PC9jb2RlPiBvYmplY3QgcmVxdWlyZXMKZml4aW5nIHVwIHRoZSBsaXN04oCZ
cyBsYXN0IG5vZGXigJlzIDxjb2RlIGNsYXNzPSJoaWdobGlnaHQiPjxjLSBuPm5leHQ8L2MtPjwv
Y29kZT4gcG9pbnRlciBzbyB0aGF0IGl0IHBvaW50cyB0byB0aGUKbmV3IHNlbnRpbmVsIG5vZGUg
aW5zaWRlIHRoZSBkZXN0aW5hdGlvbiA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gbj5saXN0
PC9jLT48L2NvZGU+IG9iamVjdC4gVGhpcyBmaXh1cCBvZiBhbiBhcmJpdHJhcnkKaGVhcCBvYmpl
Y3QgY2Fubm90IGJlIHNpbXVsYXRlZCBieSA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gbj5t
ZW1jcHk8L2MtPjwvY29kZT4uPC9wPgogICA8cD5UcmFkaXRpb25hbCBpbXBsZW1lbnRhdGlvbnMg
b2YgPGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMtIG4+c3RkPC9jLT48Yy0gbz46OjwvYy0+PGMt
IG4+c2V0PC9jLT48L2NvZGU+IGFuZCA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gbj5zdGQ8
L2MtPjxjLSBvPjo6PC9jLT48Yy0gbj5tYXA8L2MtPjwvY29kZT4gYWxzbyBzdG9yZSBhICJwYXN0
LXRoZS1lbmQiCm5vZGUgaW5zaWRlIHRoZW1zZWx2ZXMgYW5kIHRodXMgYWxzbyBmYWxsIGludG8g
dGhpcyBjYXRlZ29yeS48L3A+CiAgIDxwPjxzbWFsbD48L3NtYWxsPjwvcD4KICAgPHNtYWxsPiA8
cHJlIGNsYXNzPSJoaWdobGlnaHQiPjxjLSBrPnN0cnVjdDwvYy0+IDxjLSBuPm5vZGU8L2MtPiA8
Yy0gcD57PC9jLT4KICAgIDxjLSBuPm5vZGU8L2MtPiA8Yy0gbz4qPC9jLT48Yy0gbj5wcmV2Xzwv
Yy0+IDxjLSBvPj08L2MtPiA8Yy0gaz5udWxscHRyPC9jLT48Yy0gcD47PC9jLT4KICAgIDxjLSBu
Pm5vZGU8L2MtPiA8Yy0gbz4qPC9jLT48Yy0gbj5uZXh0XzwvYy0+IDxjLSBvPj08L2MtPiA8Yy0g
az5udWxscHRyPC9jLT48Yy0gcD47PC9jLT4KPGMtIHA+fTs8L2MtPgo8Yy0gaz5zdHJ1Y3Q8L2Mt
PiA8Yy0gbj5saXN0PC9jLT4gPGMtIHA+ezwvYy0+CiAgICA8Yy0gbj5ub2RlPC9jLT4gPGMtIG4+
bl88L2MtPjxjLSBwPjs8L2MtPgogICAgPGMtIG4+aXRlcmF0b3I8L2MtPiA8Yy0gbmY+YmVnaW48
L2MtPjxjLSBwPigpPC9jLT4gPGMtIHA+ezwvYy0+IDxjLSBrPnJldHVybjwvYy0+IDxjLSBuPml0
ZXJhdG9yPC9jLT48Yy0gcD4oPC9jLT48Yy0gbj5uXzwvYy0+PGMtIHA+LjwvYy0+PGMtIG4+bmV4
dF88L2MtPjxjLSBwPik7PC9jLT4gPGMtIHA+fTwvYy0+CiAgICA8Yy0gbj5pdGVyYXRvcjwvYy0+
IDxjLSBuZj5lbmQ8L2MtPjxjLSBwPigpPC9jLT4gPGMtIHA+ezwvYy0+IDxjLSBrPnJldHVybjwv
Yy0+IDxjLSBuPml0ZXJhdG9yPC9jLT48Yy0gcD4oPC9jLT48Yy0gbz4mYW1wOzwvYy0+PGMtIG4+
bl88L2MtPjxjLSBwPik7PC9jLT4gPGMtIHA+fTwvYy0+CiAgICA8Yy0gbj5saXN0PC9jLT48Yy0g
cD4oPC9jLT48Yy0gbj5saXN0PC9jLT48Yy0gbz4mYW1wOyZhbXA7PC9jLT4gPGMtIG4+bDwvYy0+
PGMtIHA+KTwvYy0+IDxjLSBwPns8L2MtPgogICAgICAgIDxjLSBrPmlmPC9jLT4gPGMtIHA+KDwv
Yy0+PGMtIG4+bDwvYy0+PGMtIHA+LjwvYy0+PGMtIG4+bl88L2MtPjxjLSBwPi48L2MtPjxjLSBu
Pm5leHRfPC9jLT48Yy0gcD4pPC9jLT4gPGMtIG4+bDwvYy0+PGMtIHA+LjwvYy0+PGMtIG4+bl88
L2MtPjxjLSBwPi48L2MtPjxjLSBuPm5leHRfPC9jLT48Yy0gbz4tPjwvYy0+PGMtIG4+cHJldl88
L2MtPiA8Yy0gbz49PC9jLT4gPGMtIG8+JmFtcDs8L2MtPjxjLSBuPm5fPC9jLT48Yy0gcD47PC9j
LT4gIDxjLSBjMT4vLyBmaXh1cDwvYy0+CiAgICAgICAgPGMtIGs+aWY8L2MtPiA8Yy0gcD4oPC9j
LT48Yy0gbj5sPC9jLT48Yy0gcD4uPC9jLT48Yy0gbj5uXzwvYy0+PGMtIHA+LjwvYy0+PGMtIG4+
cHJldl88L2MtPjxjLSBwPik8L2MtPiA8Yy0gbj5sPC9jLT48Yy0gcD4uPC9jLT48Yy0gbj5uXzwv
Yy0+PGMtIHA+LjwvYy0+PGMtIG4+cHJldl88L2MtPjxjLSBvPi0+PC9jLT48Yy0gbj5uZXh0Xzwv
Yy0+IDxjLSBvPj08L2MtPiA8Yy0gbz4mYW1wOzwvYy0+PGMtIG4+bl88L2MtPjxjLSBwPjs8L2Mt
PiAgPGMtIGMxPi8vIGZpeHVwPC9jLT4KICAgICAgICA8Yy0gbj5uXzwvYy0+IDxjLSBvPj08L2Mt
PiA8Yy0gbj5sPC9jLT48Yy0gcD4uPC9jLT48Yy0gbj5uXzwvYy0+PGMtIHA+OzwvYy0+CiAgICAg
ICAgPGMtIG4+bDwvYy0+PGMtIHA+LjwvYy0+PGMtIG4+bl88L2MtPiA8Yy0gbz49PC9jLT4gPGMt
IG4+bm9kZTwvYy0+PGMtIHA+e307PC9jLT4KICAgIDxjLSBwPn08L2MtPgogICAgPGMtIGMxPi8v
IC4uLjwvYy0+CjxjLSBwPn07PC9jLT4KPC9wcmU+PC9zbWFsbD4gCiAgIDxoMyBjbGFzcz0iaGVh
ZGluZyBzZXR0bGVkIiBpZD0ibm9uLXRyaXZpYWwtc2FtcGxlLW9mZnNldC1wdHIiPjxzcGFuIGNs
YXNzPSJjb250ZW50Ij5DbGFzcyBpbnZhcmlhbnQgZGVwZW5kcyBvbiA8Y29kZSBjbGFzcz0iaGln
aGxpZ2h0Ij48Yy0gaz50aGlzPC9jLT48L2NvZGU+PC9zcGFuPjxhIGNsYXNzPSJzZWxmLWxpbmsi
IGhyZWY9IiNub24tdHJpdmlhbC1zYW1wbGUtb2Zmc2V0LXB0ciI+PC9hPjwvaDM+CiAgIDxwPlRo
ZSA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gbj5vZmZzZXRfcHRyPC9jLT48L2NvZGU+IHBy
b3ZpZGVkIGJ5IDxhIGRhdGEtbGluay10eXBlPSJiaWJsaW8iIGhyZWY9IiNiaWJsaW8tYm9vc3Rp
bnRlcnByb2Nlc3MiPltCb29zdC5JbnRlcnByb2Nlc3NdPC9hPiBpcyBhbiBleGFtcGxlIG9mIHRo
aXMgY2F0ZWdvcnkuPC9wPgogICA8cD48c21hbGw+PC9zbWFsbD48L3A+CiAgIDxzbWFsbD4gPHBy
ZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gaz5zdHJ1Y3Q8L2MtPiA8Yy0gbj5vZmZzZXRfcHRyPC9j
LT4gPGMtIHA+ezwvYy0+CiAgICA8Yy0gYj51aW50cHRyX3Q8L2MtPiA8Yy0gbj52YWx1ZV88L2Mt
PjxjLSBwPjs8L2MtPgoKICAgIDxjLSBiPnVpbnRwdHJfdDwvYy0+IDxjLSBuZj5oZXJlPC9jLT48
Yy0gcD4oKTwvYy0+IDxjLSBrPmNvbnN0PC9jLT4gPGMtIHA+ezwvYy0+IDxjLSBrPnJldHVybjwv
Yy0+IDxjLSBiPnVpbnRwdHJfdDwvYy0+PGMtIHA+KDwvYy0+PGMtIGs+dGhpczwvYy0+PGMtIHA+
KTs8L2MtPiA8Yy0gcD59PC9jLT4KICAgIDxjLSBiPnVpbnRwdHJfdDwvYy0+IDxjLSBuZj5kaXN0
YW5jZV90bzwvYy0+PGMtIHA+KDwvYy0+PGMtIGI+dm9pZDwvYy0+IDxjLSBvPio8L2MtPjxjLSBu
PnA8L2MtPjxjLSBwPik8L2MtPiA8Yy0gaz5jb25zdDwvYy0+IDxjLSBwPns8L2MtPiA8Yy0gaz5y
ZXR1cm48L2MtPiA8Yy0gYj51aW50cHRyX3Q8L2MtPjxjLSBwPig8L2MtPjxjLSBuPnA8L2MtPjxj
LSBwPik8L2MtPiA8Yy0gbz4tPC9jLT4gPGMtIG4+aGVyZTwvYy0+PGMtIHA+KCk7PC9jLT4gPGMt
IHA+fTwvYy0+CiAgICA8Yy0gYj52b2lkPC9jLT4gPGMtIG8+KjwvYy0+PGMtIG5mPmdldDwvYy0+
PGMtIHA+KCk8L2MtPiA8Yy0gaz5jb25zdDwvYy0+IDxjLSBwPns8L2MtPiA8Yy0gaz5yZXR1cm48
L2MtPiA8Yy0gcD4oPC9jLT48Yy0gYj52b2lkPC9jLT48Yy0gbz4qPC9jLT48Yy0gcD4pKDwvYy0+
PGMtIG4+aGVyZTwvYy0+PGMtIHA+KCk8L2MtPiA8Yy0gbz4rPC9jLT4gPGMtIG4+dmFsdWVfPC9j
LT48Yy0gcD4pOzwvYy0+IDxjLSBwPn08L2MtPgoKICAgIDxjLSBuPm9mZnNldF9wdHI8L2MtPjxj
LSBwPigpPC9jLT4gPGMtIG8+OjwvYy0+IDxjLSBuPnZhbHVlXzwvYy0+PGMtIHA+KDwvYy0+PGMt
IG4+ZGlzdGFuY2VfdG88L2MtPjxjLSBwPig8L2MtPjxjLSBrPm51bGxwdHI8L2MtPjxjLSBwPikp
PC9jLT4gPGMtIHA+e308L2MtPgogICAgPGMtIG4+b2Zmc2V0X3B0cjwvYy0+PGMtIHA+KDwvYy0+
PGMtIGI+dm9pZDwvYy0+IDxjLSBvPio8L2MtPjxjLSBuPnA8L2MtPjxjLSBwPik8L2MtPiA8Yy0g
bz46PC9jLT4gPGMtIG4+dmFsdWVfPC9jLT48Yy0gcD4oPC9jLT48Yy0gbj5kaXN0YW5jZV90bzwv
Yy0+PGMtIHA+KDwvYy0+PGMtIG4+cDwvYy0+PGMtIHA+KSk8L2MtPiA8Yy0gcD57fTwvYy0+CiAg
ICA8Yy0gbj5vZmZzZXRfcHRyPC9jLT48Yy0gcD4oPC9jLT48Yy0gaz5jb25zdDwvYy0+IDxjLSBu
Pm9mZnNldF9wdHI8L2MtPjxjLSBvPiZhbXA7PC9jLT4gPGMtIG4+cmhzPC9jLT48Yy0gcD4pPC9j
LT4gPGMtIG8+OjwvYy0+IDxjLSBuPnZhbHVlXzwvYy0+PGMtIHA+KDwvYy0+PGMtIG4+ZGlzdGFu
Y2VfdG88L2MtPjxjLSBwPig8L2MtPjxjLSBuPnJoczwvYy0+PGMtIHA+LjwvYy0+PGMtIG4+Z2V0
PC9jLT48Yy0gcD4oKSkpPC9jLT4gPGMtIHA+e308L2MtPgogICAgPGMtIG4+b2Zmc2V0X3B0cjwv
Yy0+PGMtIG8+JmFtcDs8L2MtPiA8Yy0gaz5vcGVyYXRvcjwvYy0+PGMtIG8+PTwvYy0+PGMtIHA+
KDwvYy0+PGMtIGs+Y29uc3Q8L2MtPiA8Yy0gbj5vZmZzZXRfcHRyPC9jLT48Yy0gbz4mYW1wOzwv
Yy0+IDxjLSBuPnJoczwvYy0+PGMtIHA+KTwvYy0+IDxjLSBwPns8L2MtPgogICAgICAgIDxjLSBu
PnZhbHVlXzwvYy0+IDxjLSBvPj08L2MtPiA8Yy0gbj5kaXN0YW5jZV90bzwvYy0+PGMtIHA+KDwv
Yy0+PGMtIG4+cmhzPC9jLT48Yy0gcD4uPC9jLT48Yy0gbj5nZXQ8L2MtPjxjLSBwPigpKTs8L2Mt
PgogICAgICAgIDxjLSBrPnJldHVybjwvYy0+IDxjLSBvPio8L2MtPjxjLSBrPnRoaXM8L2MtPjxj
LSBwPjs8L2MtPgogICAgPGMtIHA+fTwvYy0+CiAgICA8Yy0gbz5+PC9jLT48Yy0gbj5vZmZzZXRf
cHRyPC9jLT48Yy0gcD4oKTwvYy0+IDxjLSBvPj08L2MtPiA8Yy0gaz5kZWZhdWx0PC9jLT48Yy0g
cD47PC9jLT4KPGMtIHA+fTs8L2MtPgo8L3ByZT48L3NtYWxsPiAKICAgPGgzIGNsYXNzPSJoZWFk
aW5nIHNldHRsZWQiIGlkPSJub24tdHJpdmlhbC1zYW1wbGUtcmVnaXN0cnkiPjxzcGFuIGNsYXNz
PSJjb250ZW50Ij5Qcm9ncmFtIGludmFyaWFudCBkZXBlbmRzIG9uIDxjb2RlIGNsYXNzPSJoaWdo
bGlnaHQiPjxjLSBrPnRoaXM8L2MtPjwvY29kZT48L3NwYW4+PGEgY2xhc3M9InNlbGYtbGluayIg
aHJlZj0iI25vbi10cml2aWFsLXNhbXBsZS1yZWdpc3RyeSI+PC9hPjwvaDM+CiAgIDxwPkluIHRo
ZSBmb2xsb3dpbmcgc25pcHBldCwgPGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMtIGs+c3RydWN0
PC9jLT4gPGMtIG4+V2lkZ2V0PC9jLT48L2NvZGU+IGlzIHJlbG9jYXRhYmxlLCBidXQgbm90CnRy
aXZpYWxseSByZWxvY2F0YWJsZSwgYmVjYXVzZSB0aGUgcmVsb2NhdGlvbiBvcGVyYXRpb24gb2Yg
ZGVzdHJveWluZyBhIDxjb2RlIGNsYXNzPSJoaWdobGlnaHQiPjxjLSBuPldpZGdldDwvYy0+PC9j
b2RlPiBhdCBwb2ludCBBCmFuZCBjb25zdHJ1Y3RpbmcgYSBuZXcgPGNvZGUgY2xhc3M9ImhpZ2hs
aWdodCI+PGMtIG4+V2lkZ2V0PC9jLT48L2NvZGU+IGF0IHBvaW50IEIgaGFzIGJlaGF2aW9yIHRo
YXQgaXMgb2JzZXJ2YWJseSBkaWZmZXJlbnQKZnJvbSBhIHNpbXBsZSA8Y29kZSBjbGFzcz0iaGln
aGxpZ2h0Ij48Yy0gbj5tZW1jcHk8L2MtPjwvY29kZT4uPC9wPgogICA8cD48c21hbGw+PC9zbWFs
bD48L3A+CiAgIDxzbWFsbD4gPHByZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gbj5zdGQ8L2MtPjxj
LSBvPjo6PC9jLT48Yy0gbj5zZXQ8L2MtPjxjLSBvPiZsdDs8L2MtPjxjLSBiPnZvaWQ8L2MtPiA8
Yy0gbz4qPjwvYy0+IDxjLSBuPnJlZ2lzdHJ5PC9jLT48Yy0gcD47PC9jLT4KCjxjLSBrPnN0cnVj
dDwvYy0+IDxjLSBuPnJlZ2lzdGVyZWRfb2JqZWN0PC9jLT4gPGMtIHA+ezwvYy0+CiAgICA8Yy0g
bj5yZWdpc3RlcmVkX29iamVjdDwvYy0+PGMtIHA+KCk8L2MtPiA8Yy0gcD57PC9jLT4gPGMtIG4+
cmVnaXN0cnk8L2MtPjxjLSBwPi48L2MtPjxjLSBuPmluc2VydDwvYy0+PGMtIHA+KDwvYy0+PGMt
IGs+dGhpczwvYy0+PGMtIHA+KTs8L2MtPiA8Yy0gcD59PC9jLT4KICAgIDxjLSBuPnJlZ2lzdGVy
ZWRfb2JqZWN0PC9jLT48Yy0gcD4oPC9jLT48Yy0gbj5yZWdpc3RlcmVkX29iamVjdDwvYy0+PGMt
IG8+JmFtcDsmYW1wOzwvYy0+PGMtIHA+KTwvYy0+IDxjLSBvPj08L2MtPiA8Yy0gaz5kZWZhdWx0
PC9jLT48Yy0gcD47PC9jLT4KICAgIDxjLSBuPnJlZ2lzdGVyZWRfb2JqZWN0PC9jLT48Yy0gcD4o
PC9jLT48Yy0gaz5jb25zdDwvYy0+IDxjLSBuPnJlZ2lzdGVyZWRfb2JqZWN0PC9jLT48Yy0gbz4m
YW1wOzwvYy0+PGMtIHA+KTwvYy0+IDxjLSBvPj08L2MtPiA8Yy0gaz5kZWZhdWx0PC9jLT48Yy0g
cD47PC9jLT4KICAgIDxjLSBuPnJlZ2lzdGVyZWRfb2JqZWN0PC9jLT48Yy0gbz4mYW1wOzwvYy0+
IDxjLSBrPm9wZXJhdG9yPC9jLT48Yy0gbz49PC9jLT48Yy0gcD4oPC9jLT48Yy0gbj5yZWdpc3Rl
cmVkX29iamVjdDwvYy0+PGMtIG8+JmFtcDsmYW1wOzwvYy0+PGMtIHA+KTwvYy0+IDxjLSBvPj08
L2MtPiA8Yy0gaz5kZWZhdWx0PC9jLT48Yy0gcD47PC9jLT4KICAgIDxjLSBuPnJlZ2lzdGVyZWRf
b2JqZWN0PC9jLT48Yy0gbz4mYW1wOzwvYy0+IDxjLSBrPm9wZXJhdG9yPC9jLT48Yy0gbz49PC9j
LT48Yy0gcD4oPC9jLT48Yy0gaz5jb25zdDwvYy0+IDxjLSBuPnJlZ2lzdGVyZWRfb2JqZWN0PC9j
LT48Yy0gbz4mYW1wOzwvYy0+PGMtIHA+KTwvYy0+IDxjLSBvPj08L2MtPiA8Yy0gaz5kZWZhdWx0
PC9jLT48Yy0gcD47PC9jLT4KICAgIDxjLSBvPn48L2MtPjxjLSBuPnJlZ2lzdGVyZWRfb2JqZWN0
PC9jLT48Yy0gcD4oKTwvYy0+IDxjLSBwPns8L2MtPiA8Yy0gbj5yZWdpc3RyeTwvYy0+PGMtIHA+
LjwvYy0+PGMtIG4+ZXJhc2U8L2MtPjxjLSBwPig8L2MtPjxjLSBrPnRoaXM8L2MtPjxjLSBwPik7
PC9jLT4gPGMtIHA+fTwvYy0+CjxjLSBwPn07PC9jLT4KCjxjLSBrPnN0cnVjdDwvYy0+IDxjLSBu
bD5XaWRnZXQ8L2MtPiA8Yy0gcD46PC9jLT4gPGMtIG4+cmVnaXN0ZXJlZF9vYmplY3Q8L2MtPiA8
Yy0gcD57fTs8L2MtPgo8L3ByZT48L3NtYWxsPiAKICAgPGgyIGNsYXNzPSJoZWFkaW5nIHNldHRs
ZWQiIGlkPSJpbXBsZW1lbnRhdGlvbiI+PHNwYW4gY2xhc3M9ImNvbnRlbnQiPkFwcGVuZGl4IEQ6
IEltcGxlbWVudGF0aW9uIGFuZCBiZW5jaG1hcmtzPC9zcGFuPjxhIGNsYXNzPSJzZWxmLWxpbmsi
IGhyZWY9IiNpbXBsZW1lbnRhdGlvbiI+PC9hPjwvaDI+CiAgIDxwPkEgcHJvdG90eXBlIENsYW5n
L2xpYmMrKyBpbXBsZW1lbnRhdGlvbiBpcyBhdDwvcD4KICAgPHVsPgogICAgPGxpIGRhdGEtbWQ+
CiAgICAgPHA+PGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL1F1dXhwbHVzb25lL2NsYW5nL3Ry
ZWUvdHJpdmlhbGx5LXJlbG9jYXRhYmxlIj5naXRodWIuY29tL1F1dXhwbHVzb25lL2NsYW5nL3Ry
ZWUvdHJpdmlhbGx5LXJlbG9jYXRhYmxlPC9hPjwvcD4KICAgIDxsaSBkYXRhLW1kPgogICAgIDxw
PjxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9RdXV4cGx1c29uZS9saWJjeHgvdHJlZS90cml2
aWFsbHktcmVsb2NhdGFibGUiPmdpdGh1Yi5jb20vUXV1eHBsdXNvbmUvbGliY3h4L3RyZWUvdHJp
dmlhbGx5LXJlbG9jYXRhYmxlPC9hPjwvcD4KICAgIDxsaSBkYXRhLW1kPgogICAgIDxwPjxhIGhy
ZWY9Imh0dHBzOi8vZ29kYm9sdC5vcmcvZy9UQTJYbXkiPmdvZGJvbHQub3JnPC9hPiwgdW5kZXIg
dGhlIG5hbWUgIng4Ni02NCBjbGFuZyAoZXhwZXJpbWVudGFsIFAxMTQ0KSI8L3A+CiAgIDwvdWw+
CiAgIDxwIGNsYXNzPSJpc3N1ZSIgaWQ9Imlzc3VlLWY5NTdhNGQ4Ij48YSBjbGFzcz0ic2VsZi1s
aW5rIiBocmVmPSIjaXNzdWUtZjk1N2E0ZDgiPjwvYT4gbm8gYmVuY2htYXJrcyB5ZXQ8L3A+CiAg
PC9tYWluPgo8c2NyaXB0PgooZnVuY3Rpb24oKSB7CiAgInVzZSBzdHJpY3QiOwogIHZhciBjb2xs
YXBzZVNpZGViYXJUZXh0ID0gJzxzcGFuIGFyaWEtaGlkZGVuPSJ0cnVlIj7ihpA8L3NwYW4+ICcK
ICAgICAgICAgICAgICAgICAgICAgICAgICArICc8c3Bhbj5Db2xsYXBzZSBTaWRlYmFyPC9zcGFu
Pic7CiAgdmFyIGV4cGFuZFNpZGViYXJUZXh0ICAgPSAnPHNwYW4gYXJpYS1oaWRkZW49InRydWUi
PuKGkjwvc3Bhbj4gJwogICAgICAgICAgICAgICAgICAgICAgICAgICsgJzxzcGFuPlBvcCBPdXQg
U2lkZWJhcjwvc3Bhbj4nOwogIHZhciB0b2NKdW1wVGV4dCAgICAgICAgID0gJzxzcGFuIGFyaWEt
aGlkZGVuPSJ0cnVlIj7ihpE8L3NwYW4+ICcKICAgICAgICAgICAgICAgICAgICAgICAgICArICc8
c3Bhbj5KdW1wIHRvIFRhYmxlIG9mIENvbnRlbnRzPC9zcGFuPic7CgogIHZhciBzaWRlYmFyTWVk
aWEgPSB3aW5kb3cubWF0Y2hNZWRpYSgnc2NyZWVuIGFuZCAobWluLXdpZHRoOiA3OGVtKScpOwog
IHZhciBhdXRvVG9nZ2xlICAgPSBmdW5jdGlvbihlKXsgdG9nZ2xlU2lkZWJhcihlLm1hdGNoZXMp
IH07CiAgaWYoc2lkZWJhck1lZGlhLmFkZExpc3RlbmVyKSB7CiAgICBzaWRlYmFyTWVkaWEuYWRk
TGlzdGVuZXIoYXV0b1RvZ2dsZSk7CiAgfQoKICBmdW5jdGlvbiB0b2dnbGVTaWRlYmFyKG9uKSB7
CiAgICBpZiAob24gPT0gdW5kZWZpbmVkKSB7CiAgICAgIG9uID0gIWRvY3VtZW50LmJvZHkuY2xh
c3NMaXN0LmNvbnRhaW5zKCd0b2Mtc2lkZWJhcicpOwogICAgfQoKICAgIC8qIERvbuKAmXQgc2Ny
b2xsIHRvIGNvbXBlbnNhdGUgZm9yIHRoZSBUb0MgaWYgd2XigJlyZSBhYm92ZSBpdCBhbHJlYWR5
LiAqLwogICAgdmFyIGhlYWRZID0gMDsKICAgIHZhciBoZWFkID0gZG9jdW1lbnQucXVlcnlTZWxl
Y3RvcignLmhlYWQnKTsKICAgIGlmIChoZWFkKSB7CiAgICAgIC8vIHRlcnJpYmxlIGFwcHJveCBv
ZiAidG9wIG9mIFRvQyIKICAgICAgaGVhZFkgKz0gaGVhZC5vZmZzZXRUb3AgKyBoZWFkLm9mZnNl
dEhlaWdodDsKICAgIH0KICAgIHZhciBza2lwU2Nyb2xsID0gd2luZG93LnNjcm9sbFkgPCBoZWFk
WTsKCiAgICB2YXIgdG9nZ2xlID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3RvYy10b2dnbGUn
KTsKICAgIHZhciB0b2NOYXYgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndG9jJyk7CiAgICBp
ZiAob24pIHsKICAgICAgdmFyIHRvY0hlaWdodCA9IHRvY05hdi5vZmZzZXRIZWlnaHQ7CiAgICAg
IGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LmFkZCgndG9jLXNpZGViYXInKTsKICAgICAgZG9jdW1l
bnQuYm9keS5jbGFzc0xpc3QucmVtb3ZlKCd0b2MtaW5saW5lJyk7CiAgICAgIHRvZ2dsZS5pbm5l
ckhUTUwgPSBjb2xsYXBzZVNpZGViYXJUZXh0OwogICAgICBpZiAoIXNraXBTY3JvbGwpIHsKICAg
ICAgICB3aW5kb3cuc2Nyb2xsQnkoMCwgMCAtIHRvY0hlaWdodCk7CiAgICAgIH0KICAgICAgdG9j
TmF2LmZvY3VzKCk7CiAgICAgIHNpZGViYXJNZWRpYS5hZGRMaXN0ZW5lcihhdXRvVG9nZ2xlKTsg
Ly8gYXV0by1jb2xsYXBzZSB3aGVuIG91dCBvZiByb29tCiAgICB9CiAgICBlbHNlIHsKICAgICAg
ZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QuYWRkKCd0b2MtaW5saW5lJyk7CiAgICAgIGRvY3VtZW50
LmJvZHkuY2xhc3NMaXN0LnJlbW92ZSgndG9jLXNpZGViYXInKTsKICAgICAgdG9nZ2xlLmlubmVy
SFRNTCA9IGV4cGFuZFNpZGViYXJUZXh0OwogICAgICBpZiAoIXNraXBTY3JvbGwpIHsKICAgICAg
ICB3aW5kb3cuc2Nyb2xsQnkoMCwgdG9jTmF2Lm9mZnNldEhlaWdodCk7CiAgICAgIH0KICAgICAg
aWYgKHRvZ2dsZS5tYXRjaGVzKCc6aG92ZXInKSkgewogICAgICAgIC8qIFVuZm9jdXMgYnV0dG9u
IHdoZW4gbm90IHVzaW5nIGtleWJvYXJkIG5hdmlnYXRpb24sCiAgICAgICAgICAgYmVjYXVzZSBJ
IGRvbuKAmXQga25vdyB3aGVyZSBlbHNlIHRvIHNlbmQgdGhlIGZvY3VzLiAqLwogICAgICAgIHRv
Z2dsZS5ibHVyKCk7CiAgICAgIH0KICAgIH0KICB9CgogIGZ1bmN0aW9uIGNyZWF0ZVNpZGViYXJU
b2dnbGUoKSB7CiAgICAvKiBDcmVhdGUgdGhlIHNpZGViYXIgdG9nZ2xlIGluIEpTOyBpdCBzaG91
bGRu4oCZdCBleGlzdCB3aGVuIEpTIGlzIG9mZi4gKi8KICAgIHZhciB0b2dnbGUgPSBkb2N1bWVu
dC5jcmVhdGVFbGVtZW50KCdhJyk7CiAgICAgIC8qIFRoaXMgc2hvdWxkIHByb2JhYmx5IGJlIGEg
YnV0dG9uLCBidXQgYXBwZWFyYW5jZSBpc27igJl0IHN0YW5kYXJkcy10cmFjay4qLwogICAgdG9n
Z2xlLmlkID0gJ3RvYy10b2dnbGUnOwogICAgdG9nZ2xlLmNsYXNzID0gJ3RvYy10b2dnbGUnOwog
ICAgdG9nZ2xlLmhyZWYgPSAnI3RvYyc7CiAgICB0b2dnbGUuaW5uZXJIVE1MID0gY29sbGFwc2VT
aWRlYmFyVGV4dDsKCiAgICBzaWRlYmFyTWVkaWEuYWRkTGlzdGVuZXIoYXV0b1RvZ2dsZSk7CiAg
ICB2YXIgdG9nZ2xlciA9IGZ1bmN0aW9uKGUpIHsKICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpOwog
ICAgICBzaWRlYmFyTWVkaWEucmVtb3ZlTGlzdGVuZXIoYXV0b1RvZ2dsZSk7IC8vIHBlcnNpc3Qg
ZXhwbGljaXQgb2ZmIHN0YXRlcwogICAgICB0b2dnbGVTaWRlYmFyKCk7CiAgICAgIHJldHVybiBm
YWxzZTsKICAgIH0KICAgIHRvZ2dsZS5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIHRvZ2dsZXIs
IGZhbHNlKTsKCgogICAgLyogR2V0IDxuYXYgaWQ9dG9jLW5hdj4sIG9yIG1ha2UgaXQgaWYgd2Ug
ZG9u4oCZdCBoYXZlIG9uZS4gKi8KICAgIHZhciB0b2NOYXYgPSBkb2N1bWVudC5nZXRFbGVtZW50
QnlJZCgndG9jLW5hdicpOwogICAgaWYgKCF0b2NOYXYpIHsKICAgICAgdG9jTmF2ID0gZG9jdW1l
bnQuY3JlYXRlRWxlbWVudCgncCcpOwogICAgICB0b2NOYXYuaWQgPSAndG9jLW5hdic7CiAgICAg
IC8qIFByZXBlbmQgZm9yIGJldHRlciBrZXlib2FyZCBuYXZpZ2F0aW9uICovCiAgICAgIGRvY3Vt
ZW50LmJvZHkuaW5zZXJ0QmVmb3JlKHRvY05hdiwgZG9jdW1lbnQuYm9keS5maXJzdENoaWxkKTsK
ICAgIH0KICAgIC8qIFdoaWxlIHdl4oCZcmUgYXQgaXQsIG1ha2Ugc3VyZSB3ZSBoYXZlIGEgSnVt
cCB0byBUb2MgbGluay4gKi8KICAgIHZhciB0b2NKdW1wID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5
SWQoJ3RvYy1qdW1wJyk7CiAgICBpZiAoIXRvY0p1bXApIHsKICAgICAgdG9jSnVtcCA9IGRvY3Vt
ZW50LmNyZWF0ZUVsZW1lbnQoJ2EnKTsKICAgICAgdG9jSnVtcC5pZCA9ICd0b2MtanVtcCc7CiAg
ICAgIHRvY0p1bXAuaHJlZiA9ICcjdG9jJzsKICAgICAgdG9jSnVtcC5pbm5lckhUTUwgPSB0b2NK
dW1wVGV4dDsKICAgICAgdG9jTmF2LmFwcGVuZENoaWxkKHRvY0p1bXApOwogICAgfQoKICAgIHRv
Y05hdi5hcHBlbmRDaGlsZCh0b2dnbGUpOwogIH0KCiAgdmFyIHRvYyA9IGRvY3VtZW50LmdldEVs
ZW1lbnRCeUlkKCd0b2MnKTsKICBpZiAodG9jKSB7CiAgICBjcmVhdGVTaWRlYmFyVG9nZ2xlKCk7
CiAgICB0b2dnbGVTaWRlYmFyKHNpZGViYXJNZWRpYS5tYXRjaGVzKTsKCiAgICAvKiBJZiB0aGUg
c2lkZWJhciBoYXMgYmVlbiBtYW51YWxseSBvcGVuZWQgYW5kIGlzIGN1cnJlbnRseSBvdmVybGF5
aW5nIHRoZSB0ZXh0CiAgICAgICAod2luZG93IHRvbyBzbWFsbCBmb3IgdGhlIE1RIHRvIGFkZCB0
aGUgbWFyZ2luIHRvIGJvZHkpLAogICAgICAgdGhlbiBhdXRvLWNsb3NlIHRoZSBzaWRlYmFyIG9u
Y2UgeW91IGNsaWNrIG9uIHNvbWV0aGluZyBpbiB0aGVyZS4gKi8KICAgIHRvYy5hZGRFdmVudExp
c3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uKGUpIHsKICAgICAgaWYoZS50YXJnZXQudGFnTmFtZS50
b0xvd2VyQ2FzZSgpID09ICJhIiAmJiBkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5jb250YWlucygn
dG9jLXNpZGViYXInKSAmJiAhc2lkZWJhck1lZGlhLm1hdGNoZXMpIHsKICAgICAgICB0b2dnbGVT
aWRlYmFyKGZhbHNlKTsKICAgICAgfQogICAgfSwgZmFsc2UpOwogIH0KICBlbHNlIHsKICAgIGNv
bnNvbGUud2FybigiQ2Fu4oCZdCBmaW5kIFRhYmxlIG9mIENvbnRlbnRzLiBQbGVhc2UgdXNlIDxu
YXYgaWQ9J3RvYyc+IGFyb3VuZCB0aGUgVG9DLiIpOwogIH0KCiAgLyogV3JhcCB0YWJsZXMgaW4g
Y2FzZSB0aGV5IG92ZXJmbG93ICovCiAgdmFyIHRhYmxlcyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0
b3JBbGwoJzpub3QoLm92ZXJsYXJnZSkgPiB0YWJsZS5kYXRhLCA6bm90KC5vdmVybGFyZ2UpID4g
dGFibGUuaW5kZXgnKTsKICB2YXIgbnVtVGFibGVzID0gdGFibGVzLmxlbmd0aDsKICBmb3IgKHZh
ciBpID0gMDsgaSA8IG51bVRhYmxlczsgaSsrKSB7CiAgICB2YXIgdGFibGUgPSB0YWJsZXNbaV07
CiAgICB2YXIgd3JhcHBlciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpOwogICAgd3Jh
cHBlci5jbGFzc05hbWUgPSAnb3ZlcmxhcmdlJzsKICAgIHRhYmxlLnBhcmVudE5vZGUuaW5zZXJ0
QmVmb3JlKHdyYXBwZXIsIHRhYmxlKTsKICAgIHdyYXBwZXIuYXBwZW5kQ2hpbGQodGFibGUpOwog
IH0KCn0pKCk7Cjwvc2NyaXB0PgogIDxoMiBjbGFzcz0ibm8tbnVtIG5vLXJlZiBoZWFkaW5nIHNl
dHRsZWQiIGlkPSJpbmRleCI+PHNwYW4gY2xhc3M9ImNvbnRlbnQiPkluZGV4PC9zcGFuPjxhIGNs
YXNzPSJzZWxmLWxpbmsiIGhyZWY9IiNpbmRleCI+PC9hPjwvaDI+CiAgPGgzIGNsYXNzPSJuby1u
dW0gbm8tcmVmIGhlYWRpbmcgc2V0dGxlZCIgaWQ9ImluZGV4LWRlZmluZWQtaGVyZSI+PHNwYW4g
Y2xhc3M9ImNvbnRlbnQiPlRlcm1zIGRlZmluZWQgYnkgdGhpcyBzcGVjaWZpY2F0aW9uPC9zcGFu
PjxhIGNsYXNzPSJzZWxmLWxpbmsiIGhyZWY9IiNpbmRleC1kZWZpbmVkLWhlcmUiPjwvYT48L2gz
PgogIDx1bCBjbGFzcz0iaW5kZXgiPgogICA8bGk+PGEgaHJlZj0iI2Fic3RyYWN0LW9wZGVmLXJl
bG9jYXRpb24tb3BlcmF0aW9uIj5yZWxvY2F0aW9uIG9wZXJhdGlvbjwvYT48c3Bhbj4sIGluIMKn
NC4xPC9zcGFuPgogICA8bGk+PGEgaHJlZj0iI2Fic3RyYWN0LW9wZGVmLXRyaXZpYWxseS1yZWxv
Y2F0YWJsZSI+dHJpdmlhbGx5IHJlbG9jYXRhYmxlPC9hPjxzcGFuPiwgaW4gwqc0LjQ8L3NwYW4+
CiAgPC91bD4KICA8aDIgY2xhc3M9Im5vLW51bSBuby1yZWYgaGVhZGluZyBzZXR0bGVkIiBpZD0i
cmVmZXJlbmNlcyI+PHNwYW4gY2xhc3M9ImNvbnRlbnQiPlJlZmVyZW5jZXM8L3NwYW4+PGEgY2xh
c3M9InNlbGYtbGluayIgaHJlZj0iI3JlZmVyZW5jZXMiPjwvYT48L2gyPgogIDxoMyBjbGFzcz0i
bm8tbnVtIG5vLXJlZiBoZWFkaW5nIHNldHRsZWQiIGlkPSJub3JtYXRpdmUiPjxzcGFuIGNsYXNz
PSJjb250ZW50Ij5Ob3JtYXRpdmUgUmVmZXJlbmNlczwvc3Bhbj48YSBjbGFzcz0ic2VsZi1saW5r
IiBocmVmPSIjbm9ybWF0aXZlIj48L2E+PC9oMz4KICA8ZGw+CiAgIDxkdCBpZD0iYmlibGlvLWx3
ZzIxMzkiPltMV0cyMTM5XQogICA8ZGQ+TG/Dr2MgSm9seS4gPGEgaHJlZj0iaHR0cHM6Ly9jcGx1
c3BsdXMuZ2l0aHViLmlvL0xXRy9pc3N1ZTIxMzkiPldoYXQgaXMgYSB1c2VyLWRlZmluZWQgdHlw
ZT88L2E+LiBNYXJjaCAyMDEy4oCTSnVuZSAyMDE4LiBVUkw6IDxhIGhyZWY9Imh0dHBzOi8vY3Bs
dXNwbHVzLmdpdGh1Yi5pby9MV0cvaXNzdWUyMTM5Ij5odHRwczovL2NwbHVzcGx1cy5naXRodWIu
aW8vTFdHL2lzc3VlMjEzOTwvYT4KICAgPGR0IGlkPSJiaWJsaW8tbHdnMzExOSI+W0xXRzMxMTld
CiAgIDxkZD5IdWJlcnQgVG9uZy4gPGEgaHJlZj0iaHR0cHM6Ly9jcGx1c3BsdXMuZ2l0aHViLmlv
L0xXRy9pc3N1ZTMxMTkiPlByb2dyYW0tZGVmaW5lZG5lc3Mgb2YgY2xvc3VyZSB0eXBlczwvYT4u
IEp1bmUgMjAxOOKAlC4gVVJMOiA8YSBocmVmPSJodHRwczovL2NwbHVzcGx1cy5naXRodWIuaW8v
TFdHL2lzc3VlMzExOSI+aHR0cHM6Ly9jcGx1c3BsdXMuZ2l0aHViLmlvL0xXRy9pc3N1ZTMxMTk8
L2E+CiAgIDxkdCBpZD0iYmlibGlvLW40NzUwIj5bTjQ3NTBdCiAgIDxkZD5JU08vSUVDIEpUQzEv
U0MyMi9XRzIxIC0gVGhlIEMrKyBTdGFuZGFyZHMgQ29tbWl0dGVlOyBSaWNoYXJkIFNtaXRoLiA8
YSBocmVmPSJodHRwOi8vd3d3Lm9wZW4tc3RkLm9yZy9qdGMxL3NjMjIvd2cyMS9kb2NzL3BhcGVy
cy8yMDE4L240NzUwLnBkZiI+TjQ3NTA6IFdvcmtpbmcgRHJhZnQsIFN0YW5kYXJkIGZvciBQcm9n
cmFtbWluZyBMYW5ndWFnZSBDKys8L2E+LiBNYXkgMjAxOC4gVVJMOiA8YSBocmVmPSJodHRwOi8v
d3d3Lm9wZW4tc3RkLm9yZy9qdGMxL3NjMjIvd2cyMS9kb2NzL3BhcGVycy8yMDE4L240NzUwLnBk
ZiI+aHR0cDovL3d3dy5vcGVuLXN0ZC5vcmcvanRjMS9zYzIyL3dnMjEvZG9jcy9wYXBlcnMvMjAx
OC9uNDc1MC5wZGY8L2E+CiAgPC9kbD4KICA8aDMgY2xhc3M9Im5vLW51bSBuby1yZWYgaGVhZGlu
ZyBzZXR0bGVkIiBpZD0iaW5mb3JtYXRpdmUiPjxzcGFuIGNsYXNzPSJjb250ZW50Ij5JbmZvcm1h
dGl2ZSBSZWZlcmVuY2VzPC9zcGFuPjxhIGNsYXNzPSJzZWxmLWxpbmsiIGhyZWY9IiNpbmZvcm1h
dGl2ZSI+PC9hPjwvaDM+CiAgPGRsPgogICA8ZHQgaWQ9ImJpYmxpby1hbm5vdW5jaW5nIj5bQW5u
b3VuY2luZ10KICAgPGRkPkFydGh1ciBPJ0R3eWVyLiA8YSBocmVmPSJodHRwczovL3F1dXhwbHVz
b25lLmdpdGh1Yi5pby9ibG9nLzIwMTgvMDcvMTgvYW5ub3VuY2luZy10cml2aWFsbHktcmVsb2Nh
dGFibGUvIj5Bbm5vdW5jaW5nICJ0cml2aWFsbHkgcmVsb2NhdGFibGUiPC9hPi4gSnVseSAyMDE4
LiBVUkw6IDxhIGhyZWY9Imh0dHBzOi8vcXV1eHBsdXNvbmUuZ2l0aHViLmlvL2Jsb2cvMjAxOC8w
Ny8xOC9hbm5vdW5jaW5nLXRyaXZpYWxseS1yZWxvY2F0YWJsZS8iPmh0dHBzOi8vcXV1eHBsdXNv
bmUuZ2l0aHViLmlvL2Jsb2cvMjAxOC8wNy8xOC9hbm5vdW5jaW5nLXRyaXZpYWxseS1yZWxvY2F0
YWJsZS88L2E+CiAgIDxkdCBpZD0iYmlibGlvLWJlbmNoIj5bQmVuY2hdCiAgIDxkZD5BcnRodXIg
TydEd3llci4gPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL1F1dXhwbHVzb25lL2Zyb20tc2Ny
YXRjaC9ibG9iLzA5NWIyNDZkL2NwcG5vdzIwMTgvYmVuY2htYXJrLXJlbG9jYXRhYmxlLmNjIj5C
ZW5jaG1hcmsgY29kZSBmcm9tICJUaGUgQmVzdCBUeXBlIFRyYWl0cyBDKysgRG9lc24ndCBIYXZl
IjwvYT4uIEFwcmlsIDIwMTguIFVSTDogPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL1F1dXhw
bHVzb25lL2Zyb20tc2NyYXRjaC9ibG9iLzA5NWIyNDZkL2NwcG5vdzIwMTgvYmVuY2htYXJrLXJl
bG9jYXRhYmxlLmNjIj5odHRwczovL2dpdGh1Yi5jb20vUXV1eHBsdXNvbmUvZnJvbS1zY3JhdGNo
L2Jsb2IvMDk1YjI0NmQvY3Bwbm93MjAxOC9iZW5jaG1hcmstcmVsb2NhdGFibGUuY2M8L2E+CiAg
IDxkdCBpZD0iYmlibGlvLWJlc3QiPltCZXN0XQogICA8ZGQ+QXJ0aHVyIE8nRHd5ZXIuIDxhIGhy
ZWY9Imh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9TVdCZm1tZzgtWW8iPlRoZSBCZXN0
IFR5cGUgVHJhaXRzIEMrKyBEb2Vzbid0IEhhdmUgKHZpZGVvKTwvYT4uIEFwcmlsIDIwMTguIFVS
TDogPGEgaHJlZj0iaHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj1NV0JmbW1nOC1ZbyI+
aHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj1NV0JmbW1nOC1ZbzwvYT4KICAgPGR0IGlk
PSJiaWJsaW8tYm9vc3RpbnRlcnByb2Nlc3MiPltCb29zdC5JbnRlcnByb2Nlc3NdCiAgIDxkZD5J
b24gR2F6dGHDsWFnYS4gPGEgaHJlZj0iaHR0cHM6Ly93d3cuYm9vc3Qub3JnL2RvYy9saWJzLzFf
NjdfMC9kb2MvaHRtbC9pbnRlcnByb2Nlc3Mvb2Zmc2V0X3B0ci5odG1sIj5NYXBwaW5nIEFkZHJl
c3MgSW5kZXBlbmRlbnQgUG9pbnRlcjogb2Zmc2V0X3B0cjwvYT4uIDIwMDUuIFVSTDogPGEgaHJl
Zj0iaHR0cHM6Ly93d3cuYm9vc3Qub3JnL2RvYy9saWJzLzFfNjdfMC9kb2MvaHRtbC9pbnRlcnBy
b2Nlc3Mvb2Zmc2V0X3B0ci5odG1sIj5odHRwczovL3d3dy5ib29zdC5vcmcvZG9jL2xpYnMvMV82
N18wL2RvYy9odG1sL2ludGVycHJvY2Vzcy9vZmZzZXRfcHRyLmh0bWw8L2E+CiAgIDxkdCBpZD0i
YmlibGlvLWNvbnRyYSI+W0NvbnRyYV0KICAgPGRkPkFydGh1ciBPJ0R3eWVyLiA8YSBocmVmPSJo
dHRwczovL3F1dXhwbHVzb25lLmdpdGh1Yi5pby9ibG9nLzIwMTgvMDQvMTUvYnVpbHQtaW4tbGli
cmFyeS10eXBlcy8iPkNvbnRyYSBidWlsdC1pbiBsaWJyYXJ5IHR5cGVzPC9hPi4gQXByaWwgMjAx
OC4gVVJMOiA8YSBocmVmPSJodHRwczovL3F1dXhwbHVzb25lLmdpdGh1Yi5pby9ibG9nLzIwMTgv
MDQvMTUvYnVpbHQtaW4tbGlicmFyeS10eXBlcy8iPmh0dHBzOi8vcXV1eHBsdXNvbmUuZ2l0aHVi
LmlvL2Jsb2cvMjAxOC8wNC8xNS9idWlsdC1pbi1saWJyYXJ5LXR5cGVzLzwvYT4KICAgPGR0IGlk
PSJiaWJsaW8tZWFzdGwiPltFQVNUTF0KICAgPGRkPlBhdWwgUGVkcmlhbmEuIDxhIGhyZWY9Imh0
dHA6Ly93d3cub3Blbi1zdGQub3JnL2p0YzEvc2MyMi93ZzIxL2RvY3MvcGFwZXJzLzIwMDcvbjIy
NzEuaHRtbCN0eXBlX3RyYWl0c19leHRlbnNpb25zIj5OMjI3MTogRUFTVEwg4oCUIEVsZWN0cm9u
aWMgQXJ0cyBTdGFuZGFyZCBUZW1wbGF0ZSBMaWJyYXJ5PC9hPi4gVVJMOiA8YSBocmVmPSJodHRw
Oi8vd3d3Lm9wZW4tc3RkLm9yZy9qdGMxL3NjMjIvd2cyMS9kb2NzL3BhcGVycy8yMDA3L24yMjcx
Lmh0bWwjdHlwZV90cmFpdHNfZXh0ZW5zaW9ucyI+aHR0cDovL3d3dy5vcGVuLXN0ZC5vcmcvanRj
MS9zYzIyL3dnMjEvZG9jcy9wYXBlcnMvMjAwNy9uMjI3MS5odG1sI3R5cGVfdHJhaXRzX2V4dGVu
c2lvbnM8L2E+CiAgIDxkdCBpZD0iYmlibGlvLWZvbGx5Ij5bRm9sbHldCiAgIDxkZD5GYWNlYm9v
ay4gPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL2ZvbGx5L2Jsb2IvbWFzdGVy
L2ZvbGx5L2RvY3MvRkJWZWN0b3IubWQjb2JqZWN0LXJlbG9jYXRpb24iPkZvbGx5IGRvY3VtZW50
YXRpb24gb24gIk9iamVjdCBSZWxvY2F0aW9uIjwvYT4uIFVSTDogPGEgaHJlZj0iaHR0cHM6Ly9n
aXRodWIuY29tL2ZhY2Vib29rL2ZvbGx5L2Jsb2IvbWFzdGVyL2ZvbGx5L2RvY3MvRkJWZWN0b3Iu
bWQjb2JqZWN0LXJlbG9jYXRpb24iPmh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9mb2xseS9i
bG9iL21hc3Rlci9mb2xseS9kb2NzL0ZCVmVjdG9yLm1kI29iamVjdC1yZWxvY2F0aW9uPC9hPgog
ICA8ZHQgaWQ9ImJpYmxpby1mb2xseWlzc3VlODg5Ij5bRm9sbHlJc3N1ZTg4OV0KICAgPGRkPkFy
dGh1ciBPJ0R3eWVyLiA8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svZm9sbHkv
aXNzdWVzLzg4OSI+VHJhaXRzLmggbWFya3Mgc3RkOjpsaXN0IGFzIHRyaXZpYWxseSByZWxvY2F0
YWJsZSwgYnV0IGluIGZhY3QgaXQgaXMgbm90PC9hPi4gVVJMOiA8YSBocmVmPSJodHRwczovL2dp
dGh1Yi5jb20vZmFjZWJvb2svZm9sbHkvaXNzdWVzLzg4OSI+aHR0cHM6Ly9naXRodWIuY29tL2Zh
Y2Vib29rL2ZvbGx5L2lzc3Vlcy84ODk8L2E+CiAgIDxkdCBpZD0iYmlibGlvLWxpYmN4eGFueSI+
W0xpYmN4eEFueV0KICAgPGRkPkVyaWMgRmlzZWxpZXIuIDxhIGhyZWY9Imh0dHBzOi8vZ2l0aHVi
LmNvbS9sbHZtLW1pcnJvci9saWJjeHgvYmxvYi84ZmRjNDkxOC9pbmNsdWRlL2FueSNMMzg5LUwz
OTQiPmxpYmMrKyBpbXBsZW1lbnRhdGlvbiBvZiBzdGQ6OmFueSAodHJpdmlhbGx5IHJlbG9jYXRh
YmxlKTwvYT4uIEp1bHkgMjAxNi4gVVJMOiA8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vbGx2
bS1taXJyb3IvbGliY3h4L2Jsb2IvOGZkYzQ5MTgvaW5jbHVkZS9hbnkjTDM4OS1MMzk0Ij5odHRw
czovL2dpdGh1Yi5jb20vbGx2bS1taXJyb3IvbGliY3h4L2Jsb2IvOGZkYzQ5MTgvaW5jbHVkZS9h
bnkjTDM4OS1MMzk0PC9hPgogICA8ZHQgaWQ9ImJpYmxpby1saWJjeHhmdW5jdGlvbiI+W0xpYmN4
eEZ1bmN0aW9uXQogICA8ZGQ+SG93YXJkIEhpbm5hbnQgZXQgYWwuIDxhIGhyZWY9Imh0dHBzOi8v
Z2l0aHViLmNvbS9sbHZtLW1pcnJvci9saWJjeHgvYmxvYi80ZTdmZmNhYS9pbmNsdWRlL2Z1bmN0
aW9uYWwjTDE3MTktTDE3MzQiPmxpYmMrKyBpbXBsZW1lbnRhdGlvbiBvZiBzdGQ6OmZ1bmN0aW9u
IChub24tdHJpdmlhbGx5IHJlbG9jYXRhYmxlKTwvYT4uIFVSTDogPGEgaHJlZj0iaHR0cHM6Ly9n
aXRodWIuY29tL2xsdm0tbWlycm9yL2xpYmN4eC9ibG9iLzRlN2ZmY2FhL2luY2x1ZGUvZnVuY3Rp
b25hbCNMMTcxOS1MMTczNCI+aHR0cHM6Ly9naXRodWIuY29tL2xsdm0tbWlycm9yL2xpYmN4eC9i
bG9iLzRlN2ZmY2FhL2luY2x1ZGUvZnVuY3Rpb25hbCNMMTcxOS1MMTczNDwvYT4KICAgPGR0IGlk
PSJiaWJsaW8tbGlic3RkY3h4ZnVuY3Rpb24iPltMaWJzdGRjeHhGdW5jdGlvbl0KICAgPGRkPkRv
dWcgR3JlZ29yIGV0IGFsLiA8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vZ2NjLW1pcnJvci9n
Y2MvYmxvYi9tYXN0ZXIvbGlic3RkYyUyQiUyQi12My9pbmNsdWRlL2JpdHMvc3RkX2Z1bmN0aW9u
LmgiPmxpYnN0ZGMrKyBpbXBsZW1lbnRhdGlvbiBvZiBzdGQ6OmZ1bmN0aW9uICh0cml2aWFsbHkg
cmVsb2NhdGFibGUpPC9hPi4gVVJMOiA8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vZ2NjLW1p
cnJvci9nY2MvYmxvYi9tYXN0ZXIvbGlic3RkYyUyQiUyQi12My9pbmNsdWRlL2JpdHMvc3RkX2Z1
bmN0aW9uLmgiPmh0dHBzOi8vZ2l0aHViLmNvbS9nY2MtbWlycm9yL2djYy9ibG9iL21hc3Rlci9s
aWJzdGRjJTJCJTJCLXYzL2luY2x1ZGUvYml0cy9zdGRfZnVuY3Rpb24uaDwvYT4KICAgPGR0IGlk
PSJiaWJsaW8tbjEzNzciPltOMTM3N10KICAgPGRkPkhvd2FyZCBIaW5uYW50OyBQZXRlciBEaW1v
djsgRGF2ZSBBYnJhaGFtcy4gPGEgaHJlZj0iaHR0cDovL3d3dy5vcGVuLXN0ZC5vcmcvanRjMS9z
YzIyL3dnMjEvZG9jcy9wYXBlcnMvMjAwMi9uMTM3Ny5odG0iPk4xMzc3OiBBIFByb3Bvc2FsIHRv
IEFkZCBNb3ZlIFNlbWFudGljcyBTdXBwb3J0IHRvIHRoZSBDKysgTGFuZ3VhZ2U8L2E+LiBTZXB0
ZW1iZXIgMjAwMi4gVVJMOiA8YSBocmVmPSJodHRwOi8vd3d3Lm9wZW4tc3RkLm9yZy9qdGMxL3Nj
MjIvd2cyMS9kb2NzL3BhcGVycy8yMDAyL24xMzc3Lmh0bSI+aHR0cDovL3d3dy5vcGVuLXN0ZC5v
cmcvanRjMS9zYzIyL3dnMjEvZG9jcy9wYXBlcnMvMjAwMi9uMTM3Ny5odG08L2E+CiAgIDxkdCBp
ZD0iYmlibGlvLW40MTU4Ij5bTjQxNThdCiAgIDxkZD5QYWJsbyBIYWxwZXJuLiA8YSBocmVmPSJo
dHRwOi8vd3d3Lm9wZW4tc3RkLm9yZy9qdGMxL3NjMjIvd2cyMS9kb2NzL3BhcGVycy8yMDE0L240
MTU4LnBkZiI+TjQxNTg6IERlc3RydWN0aXZlIE1vdmUgKFJldiAxKTwvYT4uIE9jdG9iZXIgMjAx
NC4gVVJMOiA8YSBocmVmPSJodHRwOi8vd3d3Lm9wZW4tc3RkLm9yZy9qdGMxL3NjMjIvd2cyMS9k
b2NzL3BhcGVycy8yMDE0L240MTU4LnBkZiI+aHR0cDovL3d3dy5vcGVuLXN0ZC5vcmcvanRjMS9z
YzIyL3dnMjEvZG9jcy9wYXBlcnMvMjAxNC9uNDE1OC5wZGY8L2E+CiAgIDxkdCBpZD0iYmlibGlv
LXAwMDIzcjAiPltQMDAyM1IwXQogICA8ZGQ+RGVuaXMgQmlkZXIuIDxhIGhyZWY9Imh0dHA6Ly9v
cGVuLXN0ZC5vcmcvSlRDMS9TQzIyL1dHMjEvZG9jcy9wYXBlcnMvMjAxNi9wMDAyM3IwLnBkZiI+
UDAwMjNSMDogUmVsb2NhdG9yOiBFZmZpY2llbnRseSBNb3ZpbmcgT2JqZWN0czwvYT4uIEFwcmls
IDIwMTYuIFVSTDogPGEgaHJlZj0iaHR0cDovL29wZW4tc3RkLm9yZy9KVEMxL1NDMjIvV0cyMS9k
b2NzL3BhcGVycy8yMDE2L3AwMDIzcjAucGRmIj5odHRwOi8vb3Blbi1zdGQub3JnL0pUQzEvU0My
Mi9XRzIxL2RvY3MvcGFwZXJzLzIwMTYvcDAwMjNyMC5wZGY8L2E+CiAgIDxkdCBpZD0iYmlibGlv
LXAxMDI5cjAiPltQMTAyOVIwXQogICA8ZGQ+TmlhbGwgRG91Z2xhcy4gPGEgaHJlZj0iaHR0cDov
L3d3dy5vcGVuLXN0ZC5vcmcvanRjMS9zYzIyL3dnMjEvZG9jcy9wYXBlcnMvMjAxOC9wMTAyOXIw
LnBkZiI+UDEwMjlSMDogU0cxNCBbW21vdmVfcmVsb2NhdGVzXV08L2E+LiBNYXkgMjAxOC4gVVJM
OiA8YSBocmVmPSJodHRwOi8vd3d3Lm9wZW4tc3RkLm9yZy9qdGMxL3NjMjIvd2cyMS9kb2NzL3Bh
cGVycy8yMDE4L3AxMDI5cjAucGRmIj5odHRwOi8vd3d3Lm9wZW4tc3RkLm9yZy9qdGMxL3NjMjIv
d2cyMS9kb2NzL3BhcGVycy8yMDE4L3AxMDI5cjAucGRmPC9hPgogICA8ZHQgaWQ9ImJpYmxpby1w
MTE1MnIwIj5bUDExNTJSMF0KICAgPGRkPkpGIEJhc3RpZW4uIFAxMTUyUjA6IERlcHJlY2F0aW5n
IHZvbGF0aWxlLiBKdWx5IDIwMTguIAogICA8ZHQgaWQ9ImJpYmxpby1wMTE1M3IwIj5bUDExNTNS
MF0KICAgPGRkPkFydGh1ciBPJ0R3eWVyOyBKRiBCYXN0aWVuLiBQMTE1M1IwOiBDb3B5aW5nIHZv
bGF0aWxlIHN1Ym9iamVjdHMgaXMgbm90IHRyaXZpYWwuIEp1bHkgMjAxOC4gCiAgIDxkdCBpZD0i
YmlibGlvLXNhbmUiPltTYW5lXQogICA8ZGQ+QXJ0aHVyIE8nRHd5ZXIuIDxhIGhyZWY9Imh0dHBz
Oi8vcXV1eHBsdXNvbmUuZ2l0aHViLmlvL2Jsb2cvMjAxOC8wNy8wNi90aG91Z2h0cy1vbi1zYW5l
bHktbW92ZS1hc3NpZ25hYmxlLyI+VGhvdWdodHMgb24gInNhbmVseSBtb3ZlLWFzc2lnbmFibGUi
PC9hPi4gSnVseSAyMDE4LiBVUkw6IDxhIGhyZWY9Imh0dHBzOi8vcXV1eHBsdXNvbmUuZ2l0aHVi
LmlvL2Jsb2cvMjAxOC8wNy8wNi90aG91Z2h0cy1vbi1zYW5lbHktbW92ZS1hc3NpZ25hYmxlLyI+
aHR0cHM6Ly9xdXV4cGx1c29uZS5naXRodWIuaW8vYmxvZy8yMDE4LzA3LzA2L3Rob3VnaHRzLW9u
LXNhbmVseS1tb3ZlLWFzc2lnbmFibGUvPC9hPgogICA8ZHQgaWQ9ImJpYmxpby1zdWJvYmplY3Rz
Ij5bU3Vib2JqZWN0c10KICAgPGRkPkFydGh1ciBPJ0R3eWVyLiA8YSBocmVmPSJodHRwczovL3F1
dXhwbHVzb25lLmdpdGh1Yi5pby9ibG9nLzIwMTgvMDcvMTMvdHJpdmlhbGx5LWNvcHlhYmxlLWNv
cm5lci1jYXNlcy8iPldoZW4gaXMgYSB0cml2aWFsbHkgY29weWFibGUgb2JqZWN0IG5vdCB0cml2
aWFsbHkgY29weWFibGU/PC9hPi4gSnVseSAyMDE4LiBVUkw6IDxhIGhyZWY9Imh0dHBzOi8vcXV1
eHBsdXNvbmUuZ2l0aHViLmlvL2Jsb2cvMjAxOC8wNy8xMy90cml2aWFsbHktY29weWFibGUtY29y
bmVyLWNhc2VzLyI+aHR0cHM6Ly9xdXV4cGx1c29uZS5naXRodWIuaW8vYmxvZy8yMDE4LzA3LzEz
L3RyaXZpYWxseS1jb3B5YWJsZS1jb3JuZXItY2FzZXMvPC9hPgogICA8ZHQgaWQ9ImJpYmxpby1z
d2lmdCI+W1N3aWZ0XQogICA8ZGQ+TWljaGFlbCBJbHNlbWFuLiA8YSBocmVmPSJodHRwczovL2dp
dGh1Yi5jb20vYXBwbGUvc3dpZnQvYmxvYi9tYXN0ZXIvZG9jcy9BQklTdGFiaWxpdHlNYW5pZmVz
dG8ubWQiPlN3aWZ0IEFCSSBTdGFiaWxpdHkgTWFuaWZlc3RvPC9hPi4gSmFudWFyeSAyMDE3LiBV
Ukw6IDxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9hcHBsZS9zd2lmdC9ibG9iL21hc3Rlci9k
b2NzL0FCSVN0YWJpbGl0eU1hbmlmZXN0by5tZCI+aHR0cHM6Ly9naXRodWIuY29tL2FwcGxlL3N3
aWZ0L2Jsb2IvbWFzdGVyL2RvY3MvQUJJU3RhYmlsaXR5TWFuaWZlc3RvLm1kPC9hPgogICA8ZHQg
aWQ9ImJpYmxpby10Y2YiPltUQ0ZdCiAgIDxkZD5BcnRodXIgTydEd3llci4gPGEgaHJlZj0iaHR0
cHM6Ly9xdXV4cGx1c29uZS5naXRodWIuaW8vYmxvZy8yMDE4LzA3LzAzL3RyaXZpYWxseS1jb25z
dHJ1Y3RpYmxlLWZyb20vIj5Ucml2aWFsbHktY29uc3RydWN0aWJsZS1mcm9tPC9hPi4gSnVseSAy
MDE4LiBVUkw6IDxhIGhyZWY9Imh0dHBzOi8vcXV1eHBsdXNvbmUuZ2l0aHViLmlvL2Jsb2cvMjAx
OC8wNy8wMy90cml2aWFsbHktY29uc3RydWN0aWJsZS1mcm9tLyI+aHR0cHM6Ly9xdXV4cGx1c29u
ZS5naXRodWIuaW8vYmxvZy8yMDE4LzA3LzAzL3RyaXZpYWxseS1jb25zdHJ1Y3RpYmxlLWZyb20v
PC9hPgogICA8ZHQgaWQ9ImJpYmxpby13YW5nIj5bV2FuZ10KICAgPGRkPk1pbmd4aW4gV2FuZy4g
PGEgaHJlZj0iaHR0cHM6Ly9ncm91cHMuZ29vZ2xlLmNvbS9hL2lzb2NwcC5vcmcvZC9tc2cvc3Rk
LXByb3Bvc2Fscy9IR0NIVlNSd1NNay9rN0lyLXJteEJnQUoiPkJldHRlciBQZXJmb3JtYW5jZSBp
biBQb2x5bW9ycGhpYyBQcm9ncmFtbWluZzogVHJpdmlhbGx5IFN3YXBwYWJsZTwvYT4uIEp1bmUg
MjAxOC4gVVJMOiA8YSBocmVmPSJodHRwczovL2dyb3Vwcy5nb29nbGUuY29tL2EvaXNvY3BwLm9y
Zy9kL21zZy9zdGQtcHJvcG9zYWxzL0hHQ0hWU1J3U01rL2s3SXItcm14QmdBSiI+aHR0cHM6Ly9n
cm91cHMuZ29vZ2xlLmNvbS9hL2lzb2NwcC5vcmcvZC9tc2cvc3RkLXByb3Bvc2Fscy9IR0NIVlNS
d1NNay9rN0lyLXJteEJnQUo8L2E+CiAgPC9kbD4KICA8aDIgY2xhc3M9Im5vLW51bSBuby1yZWYg
aGVhZGluZyBzZXR0bGVkIiBpZD0iaXNzdWVzLWluZGV4Ij48c3BhbiBjbGFzcz0iY29udGVudCI+
SXNzdWVzIEluZGV4PC9zcGFuPjxhIGNsYXNzPSJzZWxmLWxpbmsiIGhyZWY9IiNpc3N1ZXMtaW5k
ZXgiPjwvYT48L2gyPgogIDxkaXYgc3R5bGU9ImNvdW50ZXItcmVzZXQ6aXNzdWUiPgogICA8ZGl2
IGNsYXNzPSJpc3N1ZSI+IFtkZWZpbml0aW9uc10gaXMgcHJvYmFibHkgdGhlIHdyb25nIHBsYWNl
IGZvciB0aGUgY29yZS1sYW5ndWFnZSBkZWZpbml0aW9uIG9mICJyZWxvY2F0aW9uIG9wZXJhdGlv
biI8YSBocmVmPSIjaXNzdWUtNzVmZmUyMDEiPiDihrUgPC9hPjwvZGl2PgogICA8ZGl2IGNsYXNz
PSJpc3N1ZSI+IHRoaXMgZGVmaW5pdGlvbiBvZiAicmVsb2NhdGlvbiBvcGVyYXRpb24iIGlzIG5v
dCBnb29kPGEgaHJlZj0iI2lzc3VlLTdjODZmNWY3Ij4g4oa1IDwvYT48L2Rpdj4KICAgPGRpdiBj
bGFzcz0iaXNzdWUiPiBXaGVyZSBpbiB0aGUgU3RhbmRhcmQgc2hvdWxkIHdlIHBsYWNlIHRoZSBk
ZWZpbml0aW9uIG9mICJ0cml2aWFsbHkgcmVsb2NhdGFibGUiPzxhIGhyZWY9IiNpc3N1ZS1mZmJi
ZDMzYyI+IOKGtSA8L2E+PC9kaXY+CiAgIDxkaXYgY2xhc3M9Imlzc3VlIj4gTXVzdCB3ZSBhbHNv
IHNheSB0aGF0IHRoZSByZWxldmFudCBtb3ZlIGNvbnN0cnVjdG9yIChyZXNwLiBjb3B5IGNvbnN0
cnVjdG9yKSBtdXN0IGJlIHB1YmxpYyBhbmQgdW5hbWJpZ3VvdXM/PGEgaHJlZj0iI2lzc3VlLWEw
ZDQ1Y2VkIj4g4oa1IDwvYT48L2Rpdj4KICAgPGRpdiBjbGFzcz0iaXNzdWUiPgogICAgIENvbnNp
ZGVyIHRoZSBmb2xsb3dpbmcgdGVzdCBjYXNl4oCUPHdicj4KPHByZSBjbGFzcz0iaGlnaGxpZ2h0
Ij4gICAgPGMtIGs+c3RydWN0PC9jLT4gPGMtIG4+TTwvYy0+IDxjLSBwPns8L2MtPgogICAgICAg
IDxjLSBuPk08L2MtPjxjLSBwPigpPC9jLT4gPGMtIG8+PTwvYy0+IDxjLSBrPmRlZmF1bHQ8L2Mt
PjxjLSBwPjs8L2MtPgogICAgICAgIDxjLSBuPk08L2MtPjxjLSBwPig8L2MtPjxjLSBuPk08L2Mt
PjxjLSBvPiZhbXA7PC9jLT48Yy0gcD4pPC9jLT4gPGMtIHA+ezwvYy0+IDxjLSBuPnB1dHM8L2Mt
PjxjLSBwPig8L2MtPjxjLSBzPiJldmlsIjwvYy0+PGMtIHA+KTs8L2MtPiA8Yy0gcD59PC9jLT4K
ICAgICAgICA8Yy0gbj5NPC9jLT48Yy0gcD4oPC9jLT48Yy0gaz5jb25zdDwvYy0+IDxjLSBuPk08
L2MtPjxjLSBvPiZhbXA7PC9jLT48Yy0gcD4pPC9jLT4gPGMtIG8+PTwvYy0+IDxjLSBrPmRlZmF1
bHQ8L2MtPjxjLSBwPjs8L2MtPgogICAgPGMtIHA+fTs8L2MtPgogICAgPGMtIGs+c3RydWN0PC9j
LT4gPGMtIG4+VDwvYy0+IDxjLSBwPns8L2MtPgogICAgICAgIDxjLSBrPm11dGFibGU8L2MtPiA8
Yy0gbj5NPC9jLT4gPGMtIG4+bTwvYy0+PGMtIHA+OzwvYy0+CiAgICAgICAgPGMtIG8+fjwvYy0+
PGMtIG4+VDwvYy0+PGMtIHA+KCk8L2MtPiA8Yy0gbz49PC9jLT4gPGMtIGs+ZGVmYXVsdDwvYy0+
PGMtIHA+OzwvYy0+CiAgICA8Yy0gcD59OzwvYy0+CiAgICA8Yy0gaz5zdGF0aWNfYXNzZXJ0PC9j
LT48Yy0gcD4oPC9jLT4gPGMtIG4+c3RkPC9jLT48Yy0gbz46OjwvYy0+PGMtIG4+aXNfdHJpdmlh
bGx5X3JlbG9jYXRhYmxlX3Y8L2MtPjxjLSBvPiZsdDs8L2MtPjxjLSBuPk08L2MtPjxjLSBvPj48
L2MtPiA8Yy0gcD4pOzwvYy0+CiAgICA8Yy0gaz5zdGF0aWNfYXNzZXJ0PC9jLT48Yy0gcD4oPC9j
LT4gPGMtIG8+ITwvYy0+PGMtIG4+c3RkPC9jLT48Yy0gbz46OjwvYy0+PGMtIG4+aXNfdHJpdmlh
bGx5X3JlbG9jYXRhYmxlX3Y8L2MtPjxjLSBvPiZsdDs8L2MtPjxjLSBuPlQ8L2MtPjxjLSBvPj48
L2MtPiA8Yy0gcD4pOzwvYy0+CjwvcHJlPgogICAgVGhlIGRlY2xhcmF0aW9uIDxjb2RlIGNsYXNz
PSJoaWdobGlnaHQiPjxjLSBuPk08L2MtPiA8Yy0gbmY+bTI8L2MtPjxjLSBwPig8L2MtPjxjLSBu
PnN0ZDwvYy0+PGMtIG8+Ojo8L2MtPjxjLSBuPm1vdmU8L2MtPjxjLSBwPig8L2MtPjxjLSBuPm08
L2MtPjxjLSBwPikpOzwvYy0+PC9jb2RlPiBjYXVzZXMgYSBjYWxsIHRvIHRoZSB0cml2aWFsLCBk
ZWZhdWx0ZWQgY29weSBjb25zdHJ1Y3RvciA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gbj5N
PC9jLT48Yy0gcD4oPC9jLT48Yy0gaz5jb25zdDwvYy0+IDxjLSBuPk08L2MtPjxjLSBvPiZhbXA7
PC9jLT48Yy0gcD4pPC9jLT48L2NvZGU+LCBhbmQgPGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMt
IG4+TTwvYy0+PC9jb2RlPiBpcyB0cml2aWFsbHkgZGVzdHJ1Y3RpYmxlIGFzIHdlbGwsIHNvIHdl
IHdvdWxkIGxpa2UgPGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMtIG4+TTwvYy0+PC9jb2RlPiB0
byBiZSB0cml2aWFsbHkgcmVsb2NhdGFibGUuIEJ1dCB0aGUgZGVjbGFyYXRpb24gPGNvZGUgY2xh
c3M9ImhpZ2hsaWdodCI+PGMtIG4+VDwvYy0+IDxjLSBuZj50MjwvYy0+PGMtIHA+KDwvYy0+PGMt
IG4+c3RkPC9jLT48Yy0gbz46OjwvYy0+PGMtIG4+bW92ZTwvYy0+PGMtIHA+KDwvYy0+PGMtIG4+
dDwvYy0+PGMtIHA+KSk7PC9jLT48L2NvZGU+IHN1cnByaXNpbmdseSBjYXVzZXMgYSBjYWxsIHRv
IHRoZSB1c2VyLXByb3ZpZGVkIDxjb2RlIGNsYXNzPSJoaWdobGlnaHQiPjxjLSBuPk08L2MtPjxj
LSBwPig8L2MtPjxjLSBuPk08L2MtPjxjLSBvPiZhbXA7PC9jLT48Yy0gcD4pPC9jLT48L2NvZGU+
LCBzbyA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gbj5UPC9jLT48L2NvZGU+IGNhbm5vdCBw
b3NzaWJseSBiZSB0cml2aWFsbHkKcmVsb2NhdGFibGUuIEl0IG1heSBiZSBvdmVybHkgY29uc2Vy
dmF0aXZlIG9mIHVzIHRvIGJhbiA8Y29kZSBjbGFzcz0iaGlnaGxpZ2h0Ij48Yy0gaz5tdXRhYmxl
PC9jLT48L2NvZGU+IG1lbWJlcnMsIGJ1dCBhdCBsZWFzdCB3ZSBrbm93IGl0IGlzIDxlbT5zdWZm
aWNpZW50bHk8L2VtPiBjb25zZXJ2YXRpdmUuIEFzIGFsd2F5cywgdGhlIHByb2dyYW1tZXIgbWF5
IGV4cGxpY2l0bHkgb3ZlcnJpZGUgdGhlIGNvbXBpbGVy4oCZcyBqdWRnbWVudCBieSBkZWNsYXJp
bmcgPGNvZGUgY2xhc3M9ImhpZ2hsaWdodCI+PGMtIG4+VDwvYy0+PC9jb2RlPiBhcyA8Y29kZSBj
bGFzcz0iaGlnaGxpZ2h0Ij48Yy0gcD5bWzwvYy0+PGMtIG4+dHJpdmlhbGx5X3JlbG9jYXRhYmxl
PC9jLT48Yy0gcD5dXTwvYy0+PC9jb2RlPi4gPGEgaHJlZj0iI2lzc3VlLTk3ZDkyZGQwIj4g4oa1
IDwvYT4KICAgPC9kaXY+CiAgIDxkaXYgY2xhc3M9Imlzc3VlIj4gbm8gYmVuY2htYXJrcyB5ZXQ8
YSBocmVmPSIjaXNzdWUtZjk1N2E0ZDgiPiDihrUgPC9hPjwvZGl2PgogIDwvZGl2PgogIDxhc2lk
ZSBjbGFzcz0iZGZuLXBhbmVsIiBkYXRhLWZvcj0iYWJzdHJhY3Qtb3BkZWYtcmVsb2NhdGlvbi1v
cGVyYXRpb24iPgogICA8Yj48YSBocmVmPSIjYWJzdHJhY3Qtb3BkZWYtcmVsb2NhdGlvbi1vcGVy
YXRpb24iPiNhYnN0cmFjdC1vcGRlZi1yZWxvY2F0aW9uLW9wZXJhdGlvbjwvYT48L2I+PGI+UmVm
ZXJlbmNlZCBpbjo8L2I+CiAgIDx1bD4KICAgIDxsaT48YSBocmVmPSIjcmVmLWZvci1hYnN0cmFj
dC1vcGRlZi1yZWxvY2F0aW9uLW9wZXJhdGlvbiI+NC40LiBUcml2aWFsbHkgcmVsb2NhdGFibGUg
dHlwZTwvYT4KICAgPC91bD4KICA8L2FzaWRlPgogIDxhc2lkZSBjbGFzcz0iZGZuLXBhbmVsIiBk
YXRhLWZvcj0iYWJzdHJhY3Qtb3BkZWYtdHJpdmlhbGx5LXJlbG9jYXRhYmxlIj4KICAgPGI+PGEg
aHJlZj0iI2Fic3RyYWN0LW9wZGVmLXRyaXZpYWxseS1yZWxvY2F0YWJsZSI+I2Fic3RyYWN0LW9w
ZGVmLXRyaXZpYWxseS1yZWxvY2F0YWJsZTwvYT48L2I+PGI+UmVmZXJlbmNlZCBpbjo8L2I+CiAg
IDx1bD4KICAgIDxsaT48YSBocmVmPSIjcmVmLWZvci1hYnN0cmFjdC1vcGRlZi10cml2aWFsbHkt
cmVsb2NhdGFibGUiPjEuIEludHJvZHVjdGlvbiBhbmQgbW90aXZhdGlvbjwvYT4KICAgIDxsaT48
YSBocmVmPSIjcmVmLWZvci1hYnN0cmFjdC1vcGRlZi10cml2aWFsbHktcmVsb2NhdGFibGXikaAi
PjQuNi4gVHlwZSB0cmFpdHMgaXNfcmVsb2NhdGFibGUgZXRjLjwvYT4KICAgPC91bD4KICA8L2Fz
aWRlPgo8c2NyaXB0Pi8qIHNjcmlwdC1kZm4tcGFuZWwgKi8KCmRvY3VtZW50LmJvZHkuYWRkRXZl
bnRMaXN0ZW5lcigiY2xpY2siLCBmdW5jdGlvbihlKSB7CiAgICB2YXIgcXVlcnlBbGwgPSBmdW5j
dGlvbihzZWwpIHsgcmV0dXJuIFtdLnNsaWNlLmNhbGwoZG9jdW1lbnQucXVlcnlTZWxlY3RvckFs
bChzZWwpKTsgfQogICAgLy8gRmluZCB0aGUgZGZuIGVsZW1lbnQgb3IgcGFuZWwsIGlmIGFueSwg
dGhhdCB3YXMgY2xpY2tlZCBvbi4KICAgIHZhciBlbCA9IGUudGFyZ2V0OwogICAgdmFyIHRhcmdl
dDsKICAgIHZhciBoaXRBTGluayA9IGZhbHNlOwogICAgd2hpbGUoZWwucGFyZW50RWxlbWVudCkg
ewogICAgICAgIGlmKGVsLnRhZ05hbWUgPT0gIkEiKSB7CiAgICAgICAgICAgIC8vIENsaWNraW5n
IG9uIGEgbGluayBpbiBhIDxkZm4+IHNob3VsZG4ndCBzdW1tb24gdGhlIHBhbmVsCiAgICAgICAg
ICAgIGhpdEFMaW5rID0gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgaWYoZWwuY2xhc3NMaXN0LmNv
bnRhaW5zKCJkZm4tcGFuZWxlZCIpKSB7CiAgICAgICAgICAgIHRhcmdldCA9ICJkZm4iOwogICAg
ICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgaWYoZWwuY2xhc3NMaXN0LmNvbnRhaW5z
KCJkZm4tcGFuZWwiKSkgewogICAgICAgICAgICB0YXJnZXQgPSAiZGZuLXBhbmVsIjsKICAgICAg
ICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGVsID0gZWwucGFyZW50RWxlbWVudDsKICAg
IH0KICAgIGlmKHRhcmdldCAhPSAiZGZuLXBhbmVsIikgewogICAgICAgIC8vIFR1cm4gb2ZmIGFu
eSBjdXJyZW50bHkgIm9uIiBvciAiYWN0aXZhdGVkIiBwYW5lbHMuCiAgICAgICAgcXVlcnlBbGwo
Ii5kZm4tcGFuZWwub24sIC5kZm4tcGFuZWwuYWN0aXZhdGVkIikuZm9yRWFjaChmdW5jdGlvbihl
bCl7CiAgICAgICAgICAgIGVsLmNsYXNzTGlzdC5yZW1vdmUoIm9uIik7CiAgICAgICAgICAgIGVs
LmNsYXNzTGlzdC5yZW1vdmUoImFjdGl2YXRlZCIpOwogICAgICAgIH0pOwogICAgfQogICAgaWYo
dGFyZ2V0ID09ICJkZm4iICYmICFoaXRBTGluaykgewogICAgICAgIC8vIG9wZW4gdGhlIHBhbmVs
CiAgICAgICAgdmFyIGRmblBhbmVsID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiLmRmbi1wYW5l
bFtkYXRhLWZvcj0nIiArIGVsLmlkICsgIiddIik7CiAgICAgICAgaWYoZGZuUGFuZWwpIHsKICAg
ICAgICAgICAgZGZuUGFuZWwuY2xhc3NMaXN0LmFkZCgib24iKTsKICAgICAgICAgICAgdmFyIHJl
Y3QgPSBlbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTsKICAgICAgICAgICAgZGZuUGFuZWwuc3R5
bGUubGVmdCA9IHdpbmRvdy5zY3JvbGxYICsgcmVjdC5yaWdodCArIDUgKyAicHgiOwogICAgICAg
ICAgICBkZm5QYW5lbC5zdHlsZS50b3AgPSB3aW5kb3cuc2Nyb2xsWSArIHJlY3QudG9wICsgInB4
IjsKICAgICAgICAgICAgdmFyIHBhbmVsUmVjdCA9IGRmblBhbmVsLmdldEJvdW5kaW5nQ2xpZW50
UmVjdCgpOwogICAgICAgICAgICB2YXIgcGFuZWxXaWR0aCA9IHBhbmVsUmVjdC5yaWdodCAtIHBh
bmVsUmVjdC5sZWZ0OwogICAgICAgICAgICBpZihwYW5lbFJlY3QucmlnaHQgPiBkb2N1bWVudC5i
b2R5LnNjcm9sbFdpZHRoICYmIChyZWN0LmxlZnQgLSAocGFuZWxXaWR0aCArIDUpKSA+IDApIHsK
ICAgICAgICAgICAgICAgIC8vIFJlcG9zaXRpb24sIGJlY2F1c2UgdGhlIHBhbmVsIGlzIG92ZXJm
bG93aW5nCiAgICAgICAgICAgICAgICBkZm5QYW5lbC5zdHlsZS5sZWZ0ID0gd2luZG93LnNjcm9s
bFggKyByZWN0LmxlZnQgLSAocGFuZWxXaWR0aCArIDUpICsgInB4IjsKICAgICAgICAgICAgfQog
ICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGNvbnNvbGUubG9nKCJDb3VsZG4ndCBmaW5kIC5k
Zm4tcGFuZWxbZGF0YS1mb3I9JyIgKyBlbC5pZCArICInXSIpOwogICAgICAgIH0KICAgIH0gZWxz
ZSBpZih0YXJnZXQgPT0gImRmbi1wYW5lbCIpIHsKICAgICAgICAvLyBTd2l0Y2ggaXQgdG8gImFj
dGl2YXRlZCIgc3RhdGUsIHdoaWNoIHBpbnMgaXQuCiAgICAgICAgZWwuY2xhc3NMaXN0LmFkZCgi
YWN0aXZhdGVkIik7CiAgICAgICAgZWwuc3R5bGUubGVmdCA9IG51bGw7CiAgICAgICAgZWwuc3R5
bGUudG9wID0gbnVsbDsKICAgIH0KCn0pOwo8L3NjcmlwdD4=
--0000000000000e0e8905728bdc26--
.
Author: Tom Honermann <tom@honermann.net>
Date: Fri, 3 Aug 2018 15:19:18 -0400
Raw View
This is a multi-part message in MIME format.
--------------A192898EB18394AACDBC47C6
Content-Type: text/plain; charset="UTF-8"; format=flowed
Content-Transfer-Encoding: quoted-printable
On 08/03/2018 01:59 PM, Niall Douglas wrote:
> On Friday, August 3, 2018 at 6:33:25 PM UTC+1, Nicol Bolas wrote:
>
> I understand your point on the whole parallel
> constructor/destructor thing. The reason I suggested to use them
> is that it fits within the existing paradigm, which means you
> don't have to do something like create a new series of special
> member functions. But making new functions may be the cleaner
> alternative.
>
> I'm going to invent some new strawman terminology because
> "trivialization" just isn't working out. Let's call it "reduction"
> and "regeneration". So every type has "reducers", which work like
> destructors in that they end the object's lifetime, but they
> ensure that the object's values remain present. And every type has
> "regenerators", which work like constructors in that they begin
> the object's lifetime but can access the reduced value of the
> objects in their current space.
>
> Both reduction and regeneration functions need to be able to take
> arbitrary parameters. And you need special syntax to invoke
> regeneration, for a specific type, on a piece of memory.
>
> Reduction and regeneration can be trivial operations. For implicit
> lifetime and TriviallyRelocatable types, reduction can be done
> trivially. But you can also perform non-trivial
> reduction/regeneration of specific objects of those types.
>
> This is actually a lot like the relationship between such types
> and their constructors. implicit lifetime types can have
> non-trivial constructors, but there are still trivial ways of
> interacting with them.
>
> Some operations invoke "trivial reduction" on all complete objects
> in a piece of storage. These would be things like functions that
> unmap objects, but much like your original `unbless`, we can have
> a function to directly invoke this process. If that storage
> contains objects which do not have trivial reduction, undefined
> behavior results. So if you want to do non-trivial reduction, you
> have to do it before performing such reduction.
>
> Similarly, some operations invoke "trivial regeneration", like the
> memory mapping process. And this is where we have to start getting
> into `bless`-like wording, where objects of trivially
> regeneratable types can "magically" appear based on usage. But you
> can also explicitly invoke non-trivial regeneration for specific
> objects, which causes those objects to pop into being.
>
> So let's explore some rules. Trivial reduction requires:
>
> * There is no user-provided default reducer overload.
> * All subobjects must have trivial reduction.
> * The type must be TriviallyRelocatable or Implicit Lifetime
> (which requires a trivial destructor).
>
> And similarly, trivial regeneration requires:
>
> * There is no user-provided default regeration overload.
> * All subobjects must have trivial regeneration.
> * The type must be TriviallyRelocatable or Implicit Lifetime.
>
> So, here's what we need:
>
> 1. Syntax for declaring reducers/regenerator member functions. It
> needs to not conflict with existing names.
> =C2=A0=C2=A0=C2=A0 * Regenerators probably need similar abilities tha=
t
> constructors have. Things like member initializer lists,
> inheriting regenerators, forwarding regenerators, etc.
>
> 2. Changes to the object model to allow for reducers/regenerators
> to destroy/create objects, but preserving the stored bitpattern of
> the results of the reduction and providing it to the regenerator
> on regeneration.
>
> =C2=A0=C2=A0=C2=A0 * There needs to be some idea of how exceptions wo=
rk with
> regeneration. That is, when exactly each subobject is considered
> live, so that exceptions thrown from later subobject regeneration
> can destroy them. These rules could work much like the rules of
> constructors, but we need to spell them out all the same.
>
> 3. Syntax for invoking regeneration on a piece of memory (which is
> required to contain the data from a previous reduction operation
> for an object of that type).
>
> 4. Syntax for invoking reduction on an object. It would probably
> look like an explicit destructor call.
>
>
> This is one of those very few occasions in standards work where I can=20
> get onboard with everything you just stated above. Well, apart from=20
> the naming of reduction/regeneration.
>
> Tony van Eerd, I summon thee! Any thoughts on naming? You have a knack=20
> for thinking of naming acceptable to a majority.
Bike shedding is probably a bit premature here, but...
- hibernate & awaken
- dismiss & summon
- disavow & reclaim
- drop & retrieve/recover
Tom.
>
> Thinking about this further, "trivial relocation" could be
> redefined as trivial reduction, memcpy, and trivial regeneration.
> And thus, a type is trivially relocatable if it has no-argument
> reducer and regenerators that are trivial, which can be declared
> with `=3D default` syntax.
>
> Now, I'm not saying we should go changing Arthur's proposal, since
> it is much farther along than this. But it would allow us to have
> a second way to declare that a type is TriviallyRelocatable.
>
> Still though, that's /exciting/=C2=A0because this gives Arthur the abilit=
y=20
> to relocate polymorphic objects. I agree that the current revision of=20
> his proposal shouldn't propose this, but a future addendum paper=20
> certainly could extend his work via this mechanism.
>
> Thanks Nicol. That was a very productive discussion.
>
> Now, I'll be frank here, I don't think I have the spare time between=20
> now and SD mailing deadline to write this up. Getting a lot of=20
> pressure to issue new editions of my other papers, especially on the=20
> deterministic exceptions front where WG14 are super keen for detail,=20
> as is Herb. But I'll certainly aim for Kona.
>
> (BTW this is to not shut down any further feedback on my draft paper.=20
> I certainly would be very interested in what people think of Nicol's=20
> proposal. Oh, and should these operations be functions, or operators?)
>
> Niall
>
> --=20
> You received this message because you are subscribed to the Google=20
> Groups "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send=20
> an email to std-proposals+unsubscribe@isocpp.org=20
> <mailto:std-proposals+unsubscribe@isocpp.org>.
> To post to this group, send email to std-proposals@isocpp.org=20
> <mailto:std-proposals@isocpp.org>.
> To view this discussion on the web visit=20
> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/76f49e93-09c=
4-4eec-98d3-c7f0bdeea573%40isocpp.org=20
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/76f49e93-09=
c4-4eec-98d3-c7f0bdeea573%40isocpp.org?utm_medium=3Demail&utm_source=3Dfoot=
er>.
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/0ebf42f7-fe4e-058c-6aa6-9c11adf660b8%40honermann=
..net.
--------------A192898EB18394AACDBC47C6
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<html>
<head>
<meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Dutf-8=
">
</head>
<body text=3D"#000000" bgcolor=3D"#FFFFFF">
<div class=3D"moz-cite-prefix">On 08/03/2018 01:59 PM, Niall Douglas
wrote:<br>
</div>
<blockquote type=3D"cite"
cite=3D"mid:76f49e93-09c4-4eec-98d3-c7f0bdeea573@isocpp.org">
<meta http-equiv=3D"content-type" content=3D"text/html; charset=3Dutf=
-8">
<div dir=3D"ltr">On Friday, August 3, 2018 at 6:33:25 PM UTC+1,
Nicol Bolas wrote:
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<div dir=3D"ltr">
<div>I understand your point on the whole parallel
constructor/destructor thing. The reason I suggested to
use them is that it fits within the existing paradigm,
which means you don't have to do something like create a
new series of special member functions. But making new
functions may be the cleaner alternative.<br>
</div>
<div><br>
</div>
<div>I'm going to invent some new strawman terminology
because "trivialization" just isn't working out. Let's
call it "reduction" and "regeneration". So every type has
"reducers", which work like destructors in that they end
the object's lifetime, but they ensure that the object's
values remain present. And every type has "regenerators",
which work like constructors in that they begin the
object's lifetime but can access the reduced value of the
objects in their current space.</div>
<div><br>
</div>
<div>Both reduction and regeneration functions need to be
able to take arbitrary parameters. And you need special
syntax to invoke regeneration, for a specific type, on a
piece of memory.</div>
<div><br>
</div>
<div>Reduction and regeneration can be trivial operations.
For implicit lifetime and TriviallyRelocatable types,
reduction can be done trivially. But you can also perform
non-trivial reduction/regeneration of specific objects of
those types.</div>
<div><br>
</div>
<div>This is actually a lot like the relationship between
such types and their constructors. implicit lifetime types
can have non-trivial constructors, but there are still
trivial ways of interacting with them.<br>
</div>
<div><br>
</div>
<div>Some operations invoke "trivial reduction" on all
complete objects in a piece of storage. These would be
things like functions that unmap objects, but much like
your original `unbless`, we can have a function to
directly invoke this process. If that storage contains
objects which do not have trivial reduction, undefined
behavior results. So if you want to do non-trivial
reduction, you have to do it before performing such
reduction.</div>
<div><br>
</div>
<div>Similarly, some operations invoke "trivial
regeneration", like the memory mapping process. And this
is where we have to start getting into `bless`-like
wording, where objects of trivially regeneratable types
can "magically" appear based on usage. But you can also
explicitly invoke non-trivial regeneration for specific
objects, which causes those objects to pop into being.</div>
<div><br>
</div>
<div>So let's explore some rules. Trivial reduction
requires:</div>
<div><br>
</div>
<div>
<div>
<div>* There is no user-provided default reducer
overload.<br>
</div>
* All subobjects must have trivial reduction.</div>
<div>* The type must be TriviallyRelocatable or Implicit
Lifetime (which requires a trivial destructor).</div>
<br>
<div>And similarly, trivial regeneration requires:</div>
<div><br>
</div>
<div>* There is no user-provided default regeration
overload.<br>
</div>
<div>* All subobjects must have trivial regeneration.</div>
<div>* The type must be TriviallyRelocatable or Implicit
Lifetime.<br>
</div>
<br>
<div>So, here's what we need:</div>
<div><br>
</div>
<div>1. Syntax for declaring reducers/regenerator member
functions. It needs to not conflict with existing names.</d=
iv>
<div>=C2=A0=C2=A0=C2=A0 * Regenerators probably need similar =
abilities
that constructors have. Things like member initializer
lists, inheriting regenerators, forwarding regenerators,
etc.<br>
</div>
<div><br>
</div>
<div>2. Changes to the object model to allow for
reducers/regenerators to destroy/create objects, but
preserving the stored bitpattern of the results of the
reduction and providing it to the regenerator on
regeneration.</div>
<div><br>
</div>
<div>=C2=A0=C2=A0=C2=A0 * There needs to be some idea of how =
exceptions
work with regeneration. That is, when exactly each
subobject is considered live, so that exceptions thrown
from later subobject regeneration can destroy them.
These rules could work much like the rules of
constructors, but we need to spell them out all the
same.<br>
</div>
<div><br>
</div>
<div>3. Syntax for invoking regeneration on a piece of
memory (which is required to contain the data from a
previous reduction operation for an object of that
type).</div>
<div><br>
</div>
<div>4. Syntax for invoking reduction on an object. It
would probably look like an explicit destructor call.<br>
</div>
</div>
</div>
</blockquote>
<div><br>
</div>
<div>This is one of those very few occasions in standards work
where I can get onboard with everything you just stated above.
Well, apart from the naming of reduction/regeneration.</div>
<div><br>
</div>
<div>Tony van Eerd, I summon thee! Any thoughts on naming? You
have a knack for thinking of naming acceptable to a majority.</di=
v>
</div>
</blockquote>
<br>
Bike shedding is probably a bit premature here, but...<br>
- hibernate & awaken<br>
- dismiss & summon<br>
- disavow & reclaim<br>
- drop & retrieve/recover<br>
<br>
Tom.<br>
<br>
<blockquote type=3D"cite"
cite=3D"mid:76f49e93-09c4-4eec-98d3-c7f0bdeea573@isocpp.org">
<div dir=3D"ltr">
<div>=C2=A0</div>
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<div dir=3D"ltr">
<div>
<div><br>
</div>
<div>Thinking about this further, "trivial relocation"
could be redefined as trivial reduction, memcpy, and
trivial regeneration. And thus, a type is trivially
relocatable if it has no-argument reducer and
regenerators that are trivial, which can be declared
with `=3D default` syntax.</div>
<div><br>
</div>
<div>Now, I'm not saying we should go changing Arthur's
proposal, since it is much farther along than this. But
it would allow us to have a second way to declare that a
type is TriviallyRelocatable.<br>
</div>
<div><br>
</div>
</div>
</div>
</blockquote>
<div>Still though, that's <i>exciting</i>=C2=A0because this gives
Arthur the ability to relocate polymorphic objects. I agree
that the current revision of his proposal shouldn't propose
this, but a future addendum paper certainly could extend his
work via this mechanism.</div>
<div><br>
</div>
<div>Thanks Nicol. That was a very productive discussion.</div>
<div><br>
</div>
<div>Now, I'll be frank here, I don't think I have the spare
time between now and SD mailing deadline to write this up.
Getting a lot of pressure to issue new editions of my other
papers, especially on the deterministic exceptions front where
WG14 are super keen for detail, as is Herb. But I'll certainly
aim for Kona.</div>
<div><br>
</div>
<div>(BTW this is to not shut down any further feedback on my
draft paper. I certainly would be very interested in what
people think of Nicol's proposal. Oh, and should these
operations be functions, or operators?)</div>
<div><br>
</div>
<div>Niall</div>
<div><br>
</div>
</div>
-- <br>
You received this message because you are subscribed to the Google
Groups "ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it,
send an email to <a
href=3D"mailto:std-proposals+unsubscribe@isocpp.org"
moz-do-not-send=3D"true">std-proposals+unsubscribe@isocpp.org</a>.<=
br>
To post to this group, send email to <a
href=3D"mailto:std-proposals@isocpp.org" moz-do-not-send=3D"true">s=
td-proposals@isocpp.org</a>.<br>
To view this discussion on the web visit <a
href=3D"https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/76f49e=
93-09c4-4eec-98d3-c7f0bdeea573%40isocpp.org?utm_medium=3Demail&utm_sour=
ce=3Dfooter"
moz-do-not-send=3D"true">https://groups.google.com/a/isocpp.org/d/m=
sgid/std-proposals/76f49e93-09c4-4eec-98d3-c7f0bdeea573%40isocpp.org</a>.<b=
r>
</blockquote>
<p><br>
</p>
</body>
</html>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/0ebf42f7-fe4e-058c-6aa6-9c11adf660b8%=
40honermann.net?utm_medium=3Demail&utm_source=3Dfooter">https://groups.goog=
le.com/a/isocpp.org/d/msgid/std-proposals/0ebf42f7-fe4e-058c-6aa6-9c11adf66=
0b8%40honermann.net</a>.<br />
--------------A192898EB18394AACDBC47C6--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 3 Aug 2018 12:57:51 -0700 (PDT)
Raw View
------=_Part_801_443058036.1533326271411
Content-Type: multipart/alternative;
boundary="----=_Part_802_2035748923.1533326271412"
------=_Part_802_2035748923.1533326271412
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
On Friday, August 3, 2018 at 2:00:28 PM UTC-4, Arthur O'Dwyer wrote:
>
> On Fri, Aug 3, 2018 at 10:33 AM, Nicol Bolas <jmck...@gmail.com=20
> <javascript:>> wrote:
>
>> I understand your point on the whole parallel constructor/destructor=20
>> thing. The reason I suggested to use them is that it fits within the=20
>> existing paradigm, which means you don't have to do something like creat=
e a=20
>> new series of special member functions. But making new functions may be =
the=20
>> cleaner alternative.
>>
>> I'm going to invent some new strawman terminology because=20
>> "trivialization" just isn't working out. Let's call it "reduction" and=
=20
>> "regeneration". So every type has "reducers", which work like destructor=
s=20
>> in that they end the object's lifetime, but they ensure that the object'=
s=20
>> values remain present. And every type has "regenerators", which work lik=
e=20
>> constructors in that they begin the object's lifetime but can access the=
=20
>> reduced value of the objects in their current space.
>>
>
> I like each new iteration of your terminology less and less. :P What was=
=20
> wrong with "serialization" and "deserialization"?
>
>
> So let's explore some rules. Trivial reduction requires:
>>
>> * There is no user-provided default reducer overload.
>> * All subobjects must have trivial reduction.
>> * The type must be TriviallyRelocatable or Implicit Lifetime (which=20
>> requires a trivial destructor).
>>
>
> For Niall's purposes, a reducible/trivializable/serializable (persistable=
)=20
> object does NOT need to be either TriviallyRelocatable or ImplicitLifetim=
e.=20
> For example, as far as I can tell, boost::interprocess::offset_ptr<T>=20
> should be the canonical building block for "persistable, shareable"=20
> objects, and it is definitely not TriviallyRelocatable.
>
>
> Thinking about this further, "trivial relocation" could be redefined as=
=20
>> trivial reduction, memcpy, and trivial regeneration. And thus, a type is=
=20
>> trivially relocatable if it has no-argument reducer and regenerators tha=
t=20
>> are trivial, which can be declared with `=3D default` syntax.
>>
>
> That conclusion is incorrect. The problem is that your=20
> "reduction/regeneration" operations are not context-free: they require so=
me=20
> knowledge of the surrounding context. "Reducing" an object in preparation=
=20
> for serializing it to disk can be trivial in some contexts but not others=
..
>
> struct Poly {
> virtual void foo();
> };
>
> Suppose we have an object of type `Poly` in memory, and we want to write=
=20
> it out and then read it back in later, in a different process.
> If that process is exactly the same as the current process, then `Poly` i=
s=20
> trivially reducible/serializable: we just write out the bytes of its vptr=
..=20
> Later, when we read it back in, we reinterpret those bytes as a pointer,=
=20
> and it points to the same place in the new process as in our current=20
> process, and we're good to go.
> But if that new process is *different* from our current process =E2=80=94=
either=20
> because it's running on a different architecture, or because it's a=20
> different program, or because it's a new compilation of the same program,=
=20
> or because it's exactly the same program but our loader does ASLR =E2=80=
=94 then=20
> when we reinterpret those serialized bytes as a vptr, they'll point to=20
> garbage, and our code won't work.
>
> In one scenario, our code works. In the other scenario, our code breaks.=
=20
> We *cannot say for sure whether our code will work* unless we know which=
=20
> scenario we're in.
>
> So, if you are proposing a way that C++ can guarantee that certain code=
=20
> works, you *must* (at least implicitly) be proposing a way for the C++=20
> compiler to know which scenario we're in.
>
> And I don't see that mechanism here =E2=80=94 not in Nicol's terminology =
as=20
> presented in this thread, and also not in Niall's paper.
>
> P1144 "trivially relocatable" is easier, because the situation is nailed=
=20
> down: everything happens within a single process. This lets us say *for=
=20
> sure* that `struct Poly` is trivially relocatable. Whereas `struct Poly`=
=20
> may or may not be safe to serialize to disk, depending on how far you're=
=20
> going to transport it. Even just transporting it to a different process=
=20
> might easily break it.
>
I get your point on contexts. Originally, I imagined that "context" was=20
solely for user purposes. That relocator and regenerator functions could be=
=20
given parameters that represent their context. I hadn't realized that=20
compiler-generated code would need context info too.
From the compiler's perspective, there are really only two contexts:=20
reduction for the purposes of regenerating the object "here" (in the=20
currently executing process) and reduction for the purposes of regenerating=
=20
the object "elsewhere" (in a compatible process). Only in the latter case=
=20
do you need vtable fixup.
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/58b96c37-e548-43be-beea-7e3e709b114f%40isocpp.or=
g.
------=_Part_802_2035748923.1533326271412
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Friday, August 3, 2018 at 2:00:28 PM UTC-4, Arthur O=
9;Dwyer wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-l=
eft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"=
>On Fri, Aug 3, 2018 at 10:33 AM, Nicol Bolas <span dir=3D"ltr"><<a href=
=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"PhP3mVV4DQAJ" r=
el=3D"nofollow" onmousedown=3D"this.href=3D'javascript:';return tru=
e;" onclick=3D"this.href=3D'javascript:';return true;">jmck...@gmai=
l.com</a>></span> wrote:<br><div><div class=3D"gmail_quote"><blockquote =
class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid=
;padding-left:1ex"><div dir=3D"ltr"><div>I understand your point on the who=
le parallel constructor/destructor thing. The reason I suggested to use the=
m is that it fits within the existing paradigm, which means you don't h=
ave to do something like create a new series of special member functions. B=
ut making new functions may be the cleaner alternative.<br></div><div><br><=
/div><div>I'm going to invent some new strawman terminology because &qu=
ot;trivialization" just isn't working out. Let's call it "=
;reduction" and "regeneration". So every type has "redu=
cers", which work like destructors in that they end the object's l=
ifetime, but they ensure that the object's values remain present. And e=
very type has "regenerators", which work like constructors in tha=
t they begin the object's lifetime but can access the reduced value of =
the objects in their current space.</div></div></blockquote><div><br></div>=
<div>I like each new iteration of your terminology less and less. :P =C2=A0=
What was wrong with "serialization" and "deserialization&quo=
t;?</div><div><br></div><div><br></div><blockquote class=3D"gmail_quote" st=
yle=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div =
dir=3D"ltr"><div>So let's explore some rules. Trivial reduction require=
s:</div><div><br></div><div><div><div>* There is no user-provided default r=
educer overload.<br></div><div></div>* All subobjects must have trivial red=
uction.</div><div>* The type must be TriviallyRelocatable or Implicit Lifet=
ime (which requires a trivial destructor).</div></div></div></blockquote><d=
iv><br></div><div>For Niall's purposes, a reducible/trivializable/<wbr>=
serializable (persistable) object does NOT need to be either TriviallyReloc=
atable or ImplicitLifetime. For example, as far as I can tell, boost::inter=
process::offset_<wbr>ptr<T> should be the canonical building block fo=
r "persistable, shareable" objects, and it is definitely not Triv=
iallyRelocatable.</div><div><br></div><div><br></div><blockquote class=3D"g=
mail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-l=
eft:1ex"><div dir=3D"ltr"><div><div>Thinking about this further, "triv=
ial relocation" could be redefined as trivial reduction, memcpy, and t=
rivial regeneration. And thus, a type is trivially relocatable if it has no=
-argument reducer and regenerators that are trivial, which can be declared =
with `=3D default` syntax.</div></div></div></blockquote><div><br></div><di=
v>That conclusion is incorrect. The problem is that your "reduction/re=
generation" operations are not context-free: they require some knowled=
ge of the surrounding context. "Reducing" an object in preparatio=
n for serializing it to disk can be trivial in some contexts but not others=
..</div><div><br></div><div>=C2=A0 =C2=A0 struct Poly {</div><div>=C2=A0 =C2=
=A0 =C2=A0 =C2=A0 virtual void foo();</div><div>=C2=A0 =C2=A0 };</div><div>=
<br></div><div>Suppose we have an object of type `Poly` in memory, and we w=
ant to write it out and then read it back in later, in a different process.=
</div><div>If that process is exactly the same as the current process, then=
`Poly` is trivially reducible/serializable: we just write out the bytes of=
its vptr. Later, when we read it back in, we reinterpret those bytes as a =
pointer, and it points to the same place in the new process as in our curre=
nt process, and we're good to go.</div><div>But if that new process is =
<i>different</i> from our current process =E2=80=94 either because it's=
running on a different architecture, or because it's a different progr=
am, or because it's a new compilation of the same program, or because i=
t's exactly the same program but our loader does ASLR =E2=80=94 then wh=
en we reinterpret those serialized bytes as a vptr, they'll point to ga=
rbage, and our code won't work.</div><div><br></div><div>In one scenari=
o, our code works. In the other scenario, our code breaks. We <i>cannot say=
for sure whether our code will work</i> unless we know which scenario we&#=
39;re in.</div><div><br></div><div>So, if you are proposing a way that C++ =
can guarantee that certain code works, you <i>must</i> (at least implicitly=
) be proposing a way for the C++ compiler to know which scenario we're =
in.</div><div><br></div><div>And I don't see that mechanism here =E2=80=
=94 not in Nicol's terminology as presented in this thread, and also no=
t in Niall's paper.</div><div><br></div><div>P1144 "trivially relo=
catable" is easier, because the situation is nailed down: everything h=
appens within a single process. This lets us say <i>for sure</i> that `stru=
ct Poly` is trivially relocatable. Whereas `struct Poly` may or may not be =
safe to serialize to disk, depending on how far you're going to transpo=
rt it. Even just transporting it to a different process might easily break =
it.</div></div></div></div></blockquote><div><br></div><div>I get your poin=
t on contexts. Originally, I imagined that "context" was solely f=
or user purposes. That relocator and regenerator functions could be given p=
arameters that represent their context. I hadn't realized that compiler=
-generated code would need context info too.<br></div><div></div><div><br><=
/div><div>From the compiler's perspective, there are really only two co=
ntexts: reduction for the purposes of regenerating the object "here&qu=
ot; (in the currently executing process) and reduction for the purposes of =
regenerating the object "elsewhere" (in a compatible process). On=
ly in the latter case do you need vtable fixup.</div><br></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/58b96c37-e548-43be-beea-7e3e709b114f%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/58b96c37-e548-43be-beea-7e3e709b114f=
%40isocpp.org</a>.<br />
------=_Part_802_2035748923.1533326271412--
------=_Part_801_443058036.1533326271411--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 3 Aug 2018 13:11:55 -0700 (PDT)
Raw View
------=_Part_854_2112028937.1533327115166
Content-Type: multipart/alternative;
boundary="----=_Part_855_1338354048.1533327115166"
------=_Part_855_1338354048.1533327115166
Content-Type: text/plain; charset="UTF-8"
On Friday, August 3, 2018 at 3:19:20 PM UTC-4, Tom Honermann wrote:
>
> On 08/03/2018 01:59 PM, Niall Douglas wrote:
>
> On Friday, August 3, 2018 at 6:33:25 PM UTC+1, Nicol Bolas wrote:
>>
>> I understand your point on the whole parallel constructor/destructor
>> thing. The reason I suggested to use them is that it fits within the
>> existing paradigm, which means you don't have to do something like create a
>> new series of special member functions. But making new functions may be the
>> cleaner alternative.
>>
>> I'm going to invent some new strawman terminology because
>> "trivialization" just isn't working out. Let's call it "reduction" and
>> "regeneration". So every type has "reducers", which work like destructors
>> in that they end the object's lifetime, but they ensure that the object's
>> values remain present. And every type has "regenerators", which work like
>> constructors in that they begin the object's lifetime but can access the
>> reduced value of the objects in their current space.
>>
>> Both reduction and regeneration functions need to be able to take
>> arbitrary parameters. And you need special syntax to invoke regeneration,
>> for a specific type, on a piece of memory.
>>
>> Reduction and regeneration can be trivial operations. For implicit
>> lifetime and TriviallyRelocatable types, reduction can be done trivially.
>> But you can also perform non-trivial reduction/regeneration of specific
>> objects of those types.
>>
>> This is actually a lot like the relationship between such types and their
>> constructors. implicit lifetime types can have non-trivial constructors,
>> but there are still trivial ways of interacting with them.
>>
>> Some operations invoke "trivial reduction" on all complete objects in a
>> piece of storage. These would be things like functions that unmap objects,
>> but much like your original `unbless`, we can have a function to directly
>> invoke this process. If that storage contains objects which do not have
>> trivial reduction, undefined behavior results. So if you want to do
>> non-trivial reduction, you have to do it before performing such reduction.
>>
>> Similarly, some operations invoke "trivial regeneration", like the memory
>> mapping process. And this is where we have to start getting into
>> `bless`-like wording, where objects of trivially regeneratable types can
>> "magically" appear based on usage. But you can also explicitly invoke
>> non-trivial regeneration for specific objects, which causes those objects
>> to pop into being.
>>
>> So let's explore some rules. Trivial reduction requires:
>>
>> * There is no user-provided default reducer overload.
>> * All subobjects must have trivial reduction.
>> * The type must be TriviallyRelocatable or Implicit Lifetime (which
>> requires a trivial destructor).
>>
>> And similarly, trivial regeneration requires:
>>
>> * There is no user-provided default regeration overload.
>> * All subobjects must have trivial regeneration.
>> * The type must be TriviallyRelocatable or Implicit Lifetime.
>>
>> So, here's what we need:
>>
>> 1. Syntax for declaring reducers/regenerator member functions. It needs
>> to not conflict with existing names.
>> * Regenerators probably need similar abilities that constructors
>> have. Things like member initializer lists, inheriting regenerators,
>> forwarding regenerators, etc.
>>
>> 2. Changes to the object model to allow for reducers/regenerators to
>> destroy/create objects, but preserving the stored bitpattern of the results
>> of the reduction and providing it to the regenerator on regeneration.
>>
>> * There needs to be some idea of how exceptions work with
>> regeneration. That is, when exactly each subobject is considered live, so
>> that exceptions thrown from later subobject regeneration can destroy them.
>> These rules could work much like the rules of constructors, but we need to
>> spell them out all the same.
>>
>> 3. Syntax for invoking regeneration on a piece of memory (which is
>> required to contain the data from a previous reduction operation for an
>> object of that type).
>>
>> 4. Syntax for invoking reduction on an object. It would probably look
>> like an explicit destructor call.
>>
>
> This is one of those very few occasions in standards work where I can get
> onboard with everything you just stated above. Well, apart from the naming
> of reduction/regeneration.
>
> Tony van Eerd, I summon thee! Any thoughts on naming? You have a knack for
> thinking of naming acceptable to a majority.
>
>
> Bike shedding is probably a bit premature here, but...
> - hibernate & awaken
> - dismiss & summon
> - disavow & reclaim
> - drop & retrieve/recover
>
> Tom.
>
Suspension! That's the term. It gives the right impression, that the object
goes away yet is in a form that can return.
When you suspend an object, you end its lifetime but you leave the values
of its storage alone. You can later unsuspend the values of that memory,
beginning the lifetime of a new object.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/26912de5-7af9-4f66-94bf-9fb0aba8ac94%40isocpp.org.
------=_Part_855_1338354048.1533327115166
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Friday, August 3, 2018 at 3:19:20 PM UTC-4, Tom Honerma=
nn wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: =
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
=20
=20
=20
<div text=3D"#000000" bgcolor=3D"#FFFFFF">
<div>On 08/03/2018 01:59 PM, Niall Douglas
wrote:<br>
</div>
<blockquote type=3D"cite">
=20
<div dir=3D"ltr">On Friday, August 3, 2018 at 6:33:25 PM UTC+1,
Nicol Bolas wrote:
<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex">
<div dir=3D"ltr">
<div>I understand your point on the whole parallel
constructor/destructor thing. The reason I suggested to
use them is that it fits within the existing paradigm,
which means you don't have to do something like create a
new series of special member functions. But making new
functions may be the cleaner alternative.<br>
</div>
<div><br>
</div>
<div>I'm going to invent some new strawman terminology
because "trivialization" just isn't working out=
.. Let's
call it "reduction" and "regeneration". S=
o every type has
"reducers", which work like destructors in that the=
y end
the object's lifetime, but they ensure that the object=
9;s
values remain present. And every type has "regenerators&=
quot;,
which work like constructors in that they begin the
object's lifetime but can access the reduced value of the
objects in their current space.</div>
<div><br>
</div>
<div>Both reduction and regeneration functions need to be
able to take arbitrary parameters. And you need special
syntax to invoke regeneration, for a specific type, on a
piece of memory.</div>
<div><br>
</div>
<div>Reduction and regeneration can be trivial operations.
For implicit lifetime and TriviallyRelocatable types,
reduction can be done trivially. But you can also perform
non-trivial reduction/regeneration of specific objects of
those types.</div>
<div><br>
</div>
<div>This is actually a lot like the relationship between
such types and their constructors. implicit lifetime types
can have non-trivial constructors, but there are still
trivial ways of interacting with them.<br>
</div>
<div><br>
</div>
<div>Some operations invoke "trivial reduction" on al=
l
complete objects in a piece of storage. These would be
things like functions that unmap objects, but much like
your original `unbless`, we can have a function to
directly invoke this process. If that storage contains
objects which do not have trivial reduction, undefined
behavior results. So if you want to do non-trivial
reduction, you have to do it before performing such
reduction.</div>
<div><br>
</div>
<div>Similarly, some operations invoke "trivial
regeneration", like the memory mapping process. And this
is where we have to start getting into `bless`-like
wording, where objects of trivially regeneratable types
can "magically" appear based on usage. But you can =
also
explicitly invoke non-trivial regeneration for specific
objects, which causes those objects to pop into being.</div>
<div><br>
</div>
<div>So let's explore some rules. Trivial reduction
requires:</div>
<div><br>
</div>
<div>
<div>
<div>* There is no user-provided default reducer
overload.<br>
</div>
* All subobjects must have trivial reduction.</div>
<div>* The type must be TriviallyRelocatable or Implicit
Lifetime (which requires a trivial destructor).</div>
<br>
<div>And similarly, trivial regeneration requires:</div>
<div><br>
</div>
<div>* There is no user-provided default regeration
overload.<br>
</div>
<div>* All subobjects must have trivial regeneration.</div>
<div>* The type must be TriviallyRelocatable or Implicit
Lifetime.<br>
</div>
<br>
<div>So, here's what we need:</div>
<div><br>
</div>
<div>1. Syntax for declaring reducers/regenerator member
functions. It needs to not conflict with existing names.</d=
iv>
<div>=C2=A0=C2=A0=C2=A0 * Regenerators probably need similar =
abilities
that constructors have. Things like member initializer
lists, inheriting regenerators, forwarding regenerators,
etc.<br>
</div>
<div><br>
</div>
<div>2. Changes to the object model to allow for
reducers/regenerators to destroy/create objects, but
preserving the stored bitpattern of the results of the
reduction and providing it to the regenerator on
regeneration.</div>
<div><br>
</div>
<div>=C2=A0=C2=A0=C2=A0 * There needs to be some idea of how =
exceptions
work with regeneration. That is, when exactly each
subobject is considered live, so that exceptions thrown
from later subobject regeneration can destroy them.
These rules could work much like the rules of
constructors, but we need to spell them out all the
same.<br>
</div>
<div><br>
</div>
<div>3. Syntax for invoking regeneration on a piece of
memory (which is required to contain the data from a
previous reduction operation for an object of that
type).</div>
<div><br>
</div>
<div>4. Syntax for invoking reduction on an object. It
would probably look like an explicit destructor call.<br>
</div>
</div>
</div>
</blockquote>
<div><br>
</div>
<div>This is one of those very few occasions in standards work
where I can get onboard with everything you just stated above.
Well, apart from the naming of reduction/regeneration.</div>
<div><br>
</div>
<div>Tony van Eerd, I summon thee! Any thoughts on naming? You
have a knack for thinking of naming acceptable to a majority.</di=
v>
</div>
</blockquote>
<br>
Bike shedding is probably a bit premature here, but...<br>
- hibernate & awaken<br>
- dismiss & summon<br>
- disavow & reclaim<br>
- drop & retrieve/recover<br>
<br>
Tom.<br></div></blockquote><div><br></div><div>Suspension! That's t=
he term. It gives the right impression, that the object goes away yet is in=
a form that can return.</div><div><br></div><div>When you suspend an objec=
t, you end its lifetime but you leave the values of its storage alone. You =
can later unsuspend the values of that memory, beginning the lifetime of a =
new object.<br></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/26912de5-7af9-4f66-94bf-9fb0aba8ac94%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/26912de5-7af9-4f66-94bf-9fb0aba8ac94=
%40isocpp.org</a>.<br />
------=_Part_855_1338354048.1533327115166--
------=_Part_854_2112028937.1533327115166--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Fri, 3 Aug 2018 23:17:17 +0300
Raw View
On 3 August 2018 at 23:11, Nicol Bolas <jmckesson@gmail.com> wrote:
>> Bike shedding is probably a bit premature here, but...
>> - hibernate & awaken
>> - dismiss & summon
>> - disavow & reclaim
>> - drop & retrieve/recover
>>
>> Tom.
>
>
> Suspension! That's the term. It gives the right impression, that the object
> goes away yet is in a form that can return.
>
> When you suspend an object, you end its lifetime but you leave the values of
> its storage alone. You can later unsuspend the values of that memory,
> beginning the lifetime of a new object.
I don't think so, suspension is an overloaded term. When a suspended
coroutine resumes,
the objects that were alive during suspension time are still alive.
The same objects, not different
ones.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAFk2RUZsBN%3DGLSB67zL2nvxEg%2BVCLe2K8b_bsqfY1Um3rXO51w%40mail.gmail.com.
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 3 Aug 2018 13:41:43 -0700 (PDT)
Raw View
------=_Part_863_1844652873.1533328904064
Content-Type: multipart/alternative;
boundary="----=_Part_864_814194527.1533328904064"
------=_Part_864_814194527.1533328904064
Content-Type: text/plain; charset="UTF-8"
On Friday, August 3, 2018 at 4:17:19 PM UTC-4, Ville Voutilainen wrote:
>
> On 3 August 2018 at 23:11, Nicol Bolas <jmck...@gmail.com <javascript:>>
> wrote:
> >> Bike shedding is probably a bit premature here, but...
> >> - hibernate & awaken
> >> - dismiss & summon
> >> - disavow & reclaim
> >> - drop & retrieve/recover
> >>
> >> Tom.
> >
> >
> > Suspension! That's the term. It gives the right impression, that the
> object
> > goes away yet is in a form that can return.
> >
> > When you suspend an object, you end its lifetime but you leave the
> values of
> > its storage alone. You can later unsuspend the values of that memory,
> > beginning the lifetime of a new object.
>
> I don't think so, suspension is an overloaded term. When a suspended
> coroutine resumes,
> the objects that were alive during suspension time are still alive.
> The same objects, not different
> ones.
>
Well, we could just... not have coroutines ;)
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/3e910352-2b3f-45e1-9fa5-b57045d11859%40isocpp.org.
------=_Part_864_814194527.1533328904064
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Friday, August 3, 2018 at 4:17:19 PM UTC-4, Vil=
le Voutilainen wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 3 Augu=
st 2018 at 23:11, Nicol Bolas <<a href=3D"javascript:" target=3D"_blank"=
gdf-obfuscated-mailto=3D"gbWoec1_DQAJ" rel=3D"nofollow" onmousedown=3D"thi=
s.href=3D'javascript:';return true;" onclick=3D"this.href=3D'ja=
vascript:';return true;">jmck...@gmail.com</a>> wrote:
<br>>> Bike shedding is probably a bit premature here, but...
<br>>> - hibernate & awaken
<br>>> - dismiss & summon
<br>>> - disavow & reclaim
<br>>> - drop & retrieve/recover
<br>>>
<br>>> Tom.
<br>>
<br>>
<br>> Suspension! That's the term. It gives the right impression, th=
at the object
<br>> goes away yet is in a form that can return.
<br>>
<br>> When you suspend an object, you end its lifetime but you leave the=
values of
<br>> its storage alone. You can later unsuspend the values of that memo=
ry,
<br>> beginning the lifetime of a new object.
<br>
<br>I don't think so, suspension is an overloaded term. When a suspende=
d
<br>coroutine resumes,
<br>the objects that were alive during suspension time are still alive.
<br>The same objects, not different
<br>ones.
<br></blockquote><div><br></div><div>Well, we could just... not have corout=
ines ;) <br></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/3e910352-2b3f-45e1-9fa5-b57045d11859%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/3e910352-2b3f-45e1-9fa5-b57045d11859=
%40isocpp.org</a>.<br />
------=_Part_864_814194527.1533328904064--
------=_Part_863_1844652873.1533328904064--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Sat, 4 Aug 2018 00:03:19 +0300
Raw View
On 3 August 2018 at 23:41, Matthew Woehlke <mwoehlke.floss@gmail.com> wrote:
> On 2018-08-03 16:17, Ville Voutilainen wrote:
>> On 3 August 2018 at 23:11, Nicol Bolas <jmckesson@gmail.com> wrote:
>>>> Bike shedding is probably a bit premature here, but...
>>>> - hibernate & awaken
>>>> - dismiss & summon
>>>> - disavow & reclaim
>>>> - drop & retrieve/recover
>>>
>>> Suspension! That's the term. It gives the right impression, that the object
>>> goes away yet is in a form that can return.
>>>
>>> When you suspend an object, you end its lifetime but you leave the values of
>>> its storage alone. You can later unsuspend the values of that memory,
>>> beginning the lifetime of a new object.
>>
>> I don't think so, suspension is an overloaded term. When a suspended
>> coroutine resumes, the objects that were alive during suspension time
>> are still alive. The same objects, not different ones.
> Yeah...
>
> If not for its other baggage (in particular, that we might want it for
> real serialization), I personally would lean toward [un]pickle...
>
> (I guess freeze/thaw already got rejected?)
>
> Hmm, what else?
>
> - reduce / revive
> - chill / warm
> - dissolve / reform
> - disjoin / rejoin (good symmetry but otherwise lame)
> - adjourn / assemble (or adjourn/convene)
> - [de]mobilize
> - mothball / ??
> - retain / restore
> - dehydrate / rehydrate
>
> ...and now a few "just for fun" ;-)
>
> - parch / soak
> - desiccate / moisten
> - mummify / unwrap
dematerialize / reify
dematerialize / manifest
dematerialize / materialize
My vocabulary is not good enough to find anything better than
dematerialize on the left hand side, so materialize
would be a decent counterpart for it. I do like reify and manifest
slightly better, because the facility reifies/manifests an
object from raw bits.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAFk2RUZDgZ%2BsNQn0G4%3Dw8HxX41JfBnB5hT4v%3Dmaau2pimbFAyg%40mail.gmail.com.
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 3 Aug 2018 14:49:44 -0700 (PDT)
Raw View
------=_Part_903_1508470656.1533332984691
Content-Type: multipart/alternative;
boundary="----=_Part_904_920163065.1533332984692"
------=_Part_904_920163065.1533332984692
Content-Type: text/plain; charset="UTF-8"
On Friday, August 3, 2018 at 5:03:21 PM UTC-4, Ville Voutilainen wrote:
>
> On 3 August 2018 at 23:41, Matthew Woehlke <mwoehlk...@gmail.com
> <javascript:>> wrote:
> > On 2018-08-03 16:17, Ville Voutilainen wrote:
> >> On 3 August 2018 at 23:11, Nicol Bolas <jmck...@gmail.com <javascript:>>
> wrote:
> >>>> Bike shedding is probably a bit premature here, but...
> >>>> - hibernate & awaken
> >>>> - dismiss & summon
> >>>> - disavow & reclaim
> >>>> - drop & retrieve/recover
> >>>
> >>> Suspension! That's the term. It gives the right impression, that the
> object
> >>> goes away yet is in a form that can return.
> >>>
> >>> When you suspend an object, you end its lifetime but you leave the
> values of
> >>> its storage alone. You can later unsuspend the values of that memory,
> >>> beginning the lifetime of a new object.
> >>
> >> I don't think so, suspension is an overloaded term. When a suspended
> >> coroutine resumes, the objects that were alive during suspension time
> >> are still alive. The same objects, not different ones.
> > Yeah...
> >
> > If not for its other baggage (in particular, that we might want it for
> > real serialization), I personally would lean toward [un]pickle...
> >
> > (I guess freeze/thaw already got rejected?)
> >
> > Hmm, what else?
> >
> > - reduce / revive
> > - chill / warm
> > - dissolve / reform
> > - disjoin / rejoin (good symmetry but otherwise lame)
> > - adjourn / assemble (or adjourn/convene)
> > - [de]mobilize
> > - mothball / ??
> > - retain / restore
> > - dehydrate / rehydrate
> >
> > ...and now a few "just for fun" ;-)
> >
> > - parch / soak
> > - desiccate / moisten
> > - mummify / unwrap
>
> dematerialize / reify
> dematerialize / manifest
> dematerialize / materialize
>
> My vocabulary is not good enough to find anything better than
> dematerialize on the left hand side, so materialize
> would be a decent counterpart for it. I do like reify and manifest
> slightly better, because the facility reifies/manifests an
> object from raw bits.
>
Materialize is already taken by prvalues and temporaries. So
"dematerialize" would be confusing.
For the time being, I've settled on "activate/deactivate".
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/1bab67b7-671b-4320-99b1-60816c1e0686%40isocpp.org.
------=_Part_904_920163065.1533332984692
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Friday, August 3, 2018 at 5:03:21 PM UTC-4, Vil=
le Voutilainen wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 3 Augu=
st 2018 at 23:41, Matthew Woehlke <<a href=3D"javascript:" target=3D"_bl=
ank" gdf-obfuscated-mailto=3D"ku34nFCCDQAJ" rel=3D"nofollow" onmousedown=3D=
"this.href=3D'javascript:';return true;" onclick=3D"this.href=3D=
9;javascript:';return true;">mwoehlk...@gmail.com</a>> wrote:
<br>> On 2018-08-03 16:17, Ville Voutilainen wrote:
<br>>> On 3 August 2018 at 23:11, Nicol Bolas <<a href=3D"javascri=
pt:" target=3D"_blank" gdf-obfuscated-mailto=3D"ku34nFCCDQAJ" rel=3D"nofoll=
ow" onmousedown=3D"this.href=3D'javascript:';return true;" onclick=
=3D"this.href=3D'javascript:';return true;">jmck...@gmail.com</a>&g=
t; wrote:
<br>>>>> Bike shedding is probably a bit premature here, but...
<br>>>>> - hibernate & awaken
<br>>>>> - dismiss & summon
<br>>>>> - disavow & reclaim
<br>>>>> - drop & retrieve/recover
<br>>>>
<br>>>> Suspension! That's the term. It gives the right impres=
sion, that the object
<br>>>> goes away yet is in a form that can return.
<br>>>>
<br>>>> When you suspend an object, you end its lifetime but you l=
eave the values of
<br>>>> its storage alone. You can later unsuspend the values of t=
hat memory,
<br>>>> beginning the lifetime of a new object.
<br>>>
<br>>> I don't think so, suspension is an overloaded term. When a=
suspended
<br>>> coroutine resumes, the objects that were alive during suspensi=
on time
<br>>> are still alive. The same objects, not different ones.
<br>> Yeah...
<br>>
<br>> If not for its other baggage (in particular, that we might want it=
for
<br>> real serialization), I personally would lean toward [un]pickle...
<br>>
<br>> (I guess freeze/thaw already got rejected?)
<br>>
<br>> Hmm, what else?
<br>>
<br>> - reduce / revive
<br>> - chill / warm
<br>> - dissolve / reform
<br>> - disjoin / rejoin (good symmetry but otherwise lame)
<br>> - adjourn / assemble (or adjourn/convene)
<br>> - [de]mobilize
<br>> - mothball / ??
<br>> - retain / restore
<br>> - dehydrate / rehydrate
<br>>
<br>> ...and now a few "just for fun" ;-)
<br>>
<br>> - parch / soak
<br>> - desiccate / moisten
<br>> - mummify / unwrap
<br>
<br>dematerialize / reify
<br>dematerialize / manifest
<br>dematerialize / materialize
<br>
<br>My vocabulary is not good enough to find anything better than
<br>dematerialize on the left hand side, so materialize
<br>would be a decent counterpart for it. I do like reify and manifest
<br>slightly better, because the facility reifies/manifests an
<br>object from raw bits.
<br></blockquote><div><br></div><div>Materialize is already taken by prvalu=
es and temporaries. So "dematerialize" would be confusing.</div><=
div><br></div><div>For the time being, I've settled on "activate/d=
eactivate".<br></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/1bab67b7-671b-4320-99b1-60816c1e0686%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/1bab67b7-671b-4320-99b1-60816c1e0686=
%40isocpp.org</a>.<br />
------=_Part_904_920163065.1533332984692--
------=_Part_903_1508470656.1533332984691--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Sat, 4 Aug 2018 01:02:09 +0300
Raw View
On 4 August 2018 at 00:49, Nicol Bolas <jmckesson@gmail.com> wrote:
>> dematerialize / reify
>> dematerialize / manifest
>> dematerialize / materialize
>>
>> My vocabulary is not good enough to find anything better than
>> dematerialize on the left hand side, so materialize
>> would be a decent counterpart for it. I do like reify and manifest
>> slightly better, because the facility reifies/manifests an
>> object from raw bits.
>
>
> Materialize is already taken by prvalues and temporaries. So "dematerialize"
> would be confusing.
>
> For the time being, I've settled on "activate/deactivate".
Fine. dissolve / reify, then.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAFk2RUbEy4M%3DVxP%3DeO5YTxyEBvi0ZUmnW%2BA6iN95mfTH60mWQw%40mail.gmail.com.
.
Author: "Arthur O'Dwyer" <arthur.j.odwyer@gmail.com>
Date: Fri, 3 Aug 2018 15:09:54 -0700
Raw View
--00000000000008d36405728f3091
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
On Fri, Aug 3, 2018 at 3:02 PM, Ville Voutilainen <
ville.voutilainen@gmail.com> wrote:
> On 4 August 2018 at 00:49, Nicol Bolas <jmckesson@gmail.com> wrote:
> >> dematerialize / reify
> >> dematerialize / manifest
> >> dematerialize / materialize
> >[...]
> > Materialize is already taken by prvalues and temporaries. So
> "dematerialize"
> > would be confusing.
> >
> > For the time being, I've settled on "activate/deactivate".
>
> Fine. dissolve / reify, then.
>
Before anyone can decide on a name for the thing, step 1 is to decide on
what the thing actually *is*.
Niall's original conception was that the thing is not related to beginning
or ending object lifetime at all =E2=80=94 object lifetime just kind of per=
sists
"through" this operation.
(If the operation *is* related to beginning and ending object lifetime,
then I propose "construct" and "destruct". ;))
My own conception is that I want to see how this functionality would
actually be used in a real-world high-level library; I imagine that we
don't need any special names or semantics at all. For example, we could
just state that if you use "libPersistence", then
auto p =3D libpersistence::open("somefile.bin");
std::vector<int> foo =3D p.readobject("foo");
p.writeobject("foo") =3D foo;
will *just work*, and we don't necessarily need to describe the mechanism *=
by
which* it works =E2=80=94 not right away, anyway. Step one is to focus on t=
hat
implementation: can it be implemented? is it efficient enough for
real-world uses? is it robust enough for real-world uses?
But certainly, if there is any reason to subtly prefer "reify" over
"manifest" or vice versa, it will strongly depend on the subtle semantics
of the operation. And we do not have any semantics at all, yet. Heck, I
haven't seen a *use-case* yet.
=E2=80=93Arthur
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CADvuK0KDe0LJ8qQ7mbKw5%3DS2355WcVU6teDV8cufQe5nP=
551TA%40mail.gmail.com.
--00000000000008d36405728f3091
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Fri, Aug 3, 2018 at 3:02 PM, Ville Voutilainen <span di=
r=3D"ltr"><<a href=3D"mailto:ville.voutilainen@gmail.com" target=3D"_bla=
nk">ville.voutilainen@gmail.com</a>></span> wrote:<br><div class=3D"gmai=
l_extra"><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=
=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span cl=
ass=3D"">On 4 August 2018 at 00:49, Nicol Bolas <<a href=3D"mailto:jmcke=
sson@gmail.com">jmckesson@gmail.com</a>> wrote:<br>
>> dematerialize / reify<br>
>> dematerialize / manifest<br>
>> dematerialize / materialize<br>>[...]<br>
> Materialize is already taken by prvalues and temporaries. So "dem=
aterialize"<br>
> would be confusing.<br>
><br>
> For the time being, I've settled on "activate/deactivate"=
;.<br>
<br>
</span>Fine. dissolve / reify, then.<br></blockquote><div><br></div><div>Be=
fore anyone can decide on a name for the thing, step 1 is to decide on what=
the thing actually <i><b>is</b></i>.</div><div><br></div><div>Niall's =
original conception was that the thing is not related to beginning or endin=
g object lifetime at all =E2=80=94 object lifetime just kind of persists &q=
uot;through" this operation.</div><div>(If the operation <i>is</i> rel=
ated to beginning and ending object lifetime, then I propose "construc=
t" and "destruct". ;))</div><div><br></div><div>My own conce=
ption is that I want to see how this functionality would actually be used i=
n a real-world high-level library; I imagine that we don't need any spe=
cial names or semantics at all. For example, we could just state that if yo=
u use "libPersistence", then</div><div><br></div><div>=C2=A0 =C2=
=A0 auto p =3D libpersistence::open("somefile.bin");</div><div>=
=C2=A0 =C2=A0 std::vector<int> foo =3D p.readobject("foo");=
</div><div>=C2=A0 =C2=A0 p.writeobject("foo") =3D foo;</div><div>=
<br></div><div>will <i>just work</i>, and we don't necessarily need to =
describe the mechanism <i>by which</i> it works =E2=80=94 not right away, a=
nyway. Step one is to focus on that implementation: can it be implemented? =
is it efficient enough for real-world uses? is it robust enough for real-wo=
rld uses?</div><div><br></div><div>But certainly, if there is any reason to=
subtly prefer "reify" over "manifest" or vice versa, i=
t will strongly depend on the subtle semantics of the operation. And we do =
not have any semantics at all, yet. Heck, I haven't seen a <i>use-case<=
/i> yet.</div><div><br></div><div>=E2=80=93Arthur</div></div></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CADvuK0KDe0LJ8qQ7mbKw5%3DS2355WcVU6te=
DV8cufQe5nP551TA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CADvuK0KDe0LJ8q=
Q7mbKw5%3DS2355WcVU6teDV8cufQe5nP551TA%40mail.gmail.com</a>.<br />
--00000000000008d36405728f3091--
.
Author: Tom Honermann <tom@honermann.net>
Date: Fri, 3 Aug 2018 18:41:59 -0400
Raw View
On 08/03/2018 06:02 PM, Ville Voutilainen wrote:
> On 4 August 2018 at 00:49, Nicol Bolas <jmckesson@gmail.com> wrote:
>>> dematerialize / reify
>>> dematerialize / manifest
>>> dematerialize / materialize
>>>
>>> My vocabulary is not good enough to find anything better than
>>> dematerialize on the left hand side, so materialize
>>> would be a decent counterpart for it. I do like reify and manifest
>>> slightly better, because the facility reifies/manifests an
>>> object from raw bits.
>>
>> Materialize is already taken by prvalues and temporaries. So "dematerial=
ize"
>> would be confusing.
>>
>> For the time being, I've settled on "activate/deactivate".
> Fine. dissolve / reify, then.
>
More fine.=C2=A0 detach / attach.=C2=A0 These correlate with existing memor=
y=20
mapping terminology as exhibited by shmdt() and shmat(). Detach is also=20
used by std::thread though.
Tom.
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/499882c0-db85-7126-8c5b-bd57e2600fe9%40honermann=
..net.
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 3 Aug 2018 19:08:26 -0700 (PDT)
Raw View
------=_Part_923_1688764810.1533348507042
Content-Type: multipart/alternative;
boundary="----=_Part_924_479936405.1533348507042"
------=_Part_924_479936405.1533348507042
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
On Friday, August 3, 2018 at 6:09:57 PM UTC-4, Arthur O'Dwyer wrote:
>
> On Fri, Aug 3, 2018 at 3:02 PM, Ville Voutilainen <ville.vo...@gmail.com=
=20
> <javascript:>> wrote:
>
>> On 4 August 2018 at 00:49, Nicol Bolas <jmck...@gmail.com <javascript:>>=
=20
>> wrote:
>> >> dematerialize / reify
>> >> dematerialize / manifest
>> >> dematerialize / materialize
>> >[...]
>> > Materialize is already taken by prvalues and temporaries. So=20
>> "dematerialize"
>> > would be confusing.
>> >
>> > For the time being, I've settled on "activate/deactivate".
>>
>> Fine. dissolve / reify, then.
>>
>
> Before anyone can decide on a name for the thing, step 1 is to decide on=
=20
> what the thing actually *is*.
>
> Niall's original conception was that the thing is not related to beginnin=
g=20
> or ending object lifetime at all =E2=80=94 object lifetime just kind of p=
ersists=20
> "through" this operation.
> (If the operation *is* related to beginning and ending object lifetime,=
=20
> then I propose "construct" and "destruct". ;))
>
> My own conception is that I want to see how this functionality would=20
> actually be used in a real-world high-level library; I imagine that we=20
> don't need any special names or semantics at all. For example, we could=
=20
> just state that if you use "libPersistence", then
>
> auto p =3D libpersistence::open("somefile.bin");
> std::vector<int> foo =3D p.readobject("foo");
> p.writeobject("foo") =3D foo;
>
> will *just work*, and we don't necessarily need to describe the mechanism=
*by=20
> which* it works =E2=80=94 not right away, anyway. Step one is to focus on=
that=20
> implementation: can it be implemented? is it efficient enough for=20
> real-world uses? is it robust enough for real-world uses?
>
The kind of persistence that Niall is talking about is persistence at its=
=20
lowest level: what happens to a C++ object if it is in mapped memory that=
=20
gets unmapped? Can it survive? Can another process receive and manipulate=
=20
that object? How can we make transmission of objects work at that level?
Defining this is the point of this exercise. The high level details you're=
=20
talking about for some hypothetical library are beyond this exercise. We're=
=20
talking about a low-level tool for low-level needs. How high-level code=20
deals with it is something that can be looked at once we allow the object=
=20
model to be able to consider these possibilities.
Think about all of the issues that went into defining the C++11 memory=20
model that included the possibility of data races. Those weren't based on=
=20
high-level constructs and the like; it was solely about pinning down how=20
memory works between threads. That's the kind of thing this is dealing=20
with: how objects work in a world where storage for them can exist beyond=
=20
the lifespan of the program.
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/21d282b1-b939-47f8-9745-ff153387ea2c%40isocpp.or=
g.
------=_Part_924_479936405.1533348507042
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Friday, August 3, 2018 at 6:09:57 PM UTC-4, Arthur O=
9;Dwyer wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-l=
eft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"=
>On Fri, Aug 3, 2018 at 3:02 PM, Ville Voutilainen <span dir=3D"ltr"><<a=
href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"x328-vKFDQ=
AJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'javascript:';retur=
n true;" onclick=3D"this.href=3D'javascript:';return true;">ville.v=
o...@gmail.com</a>></span> wrote:<br><div><div class=3D"gmail_quote"><bl=
ockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #=
ccc solid;padding-left:1ex"><span>On 4 August 2018 at 00:49, Nicol Bolas &l=
t;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"x328-v=
KFDQAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'javascript:';r=
eturn true;" onclick=3D"this.href=3D'javascript:';return true;">jmc=
k...@gmail.com</a>> wrote:<br>
>> dematerialize / reify<br>
>> dematerialize / manifest<br>
>> dematerialize / materialize<br>>[...]<br>
> Materialize is already taken by prvalues and temporaries. So "dem=
aterialize"<br>
> would be confusing.<br>
><br>
> For the time being, I've settled on "activate/deactivate"=
;.<br>
<br>
</span>Fine. dissolve / reify, then.<br></blockquote><div><br></div><div>Be=
fore anyone can decide on a name for the thing, step 1 is to decide on what=
the thing actually <i><b>is</b></i>.</div><div><br></div><div>Niall's =
original conception was that the thing is not related to beginning or endin=
g object lifetime at all =E2=80=94 object lifetime just kind of persists &q=
uot;through" this operation.</div><div>(If the operation <i>is</i> rel=
ated to beginning and ending object lifetime, then I propose "construc=
t" and "destruct". ;))</div><div><br></div><div>My own conce=
ption is that I want to see how this functionality would actually be used i=
n a real-world high-level library; I imagine that we don't need any spe=
cial names or semantics at all. For example, we could just state that if yo=
u use "libPersistence", then</div><div><br></div><div>=C2=A0 =C2=
=A0 auto p =3D libpersistence::open("<wbr>somefile.bin");</div><d=
iv>=C2=A0 =C2=A0 std::vector<int> foo =3D p.readobject("foo"=
;);</div><div>=C2=A0 =C2=A0 p.writeobject("foo") =3D foo;</div><d=
iv><br></div><div>will <i>just work</i>, and we don't necessarily need =
to describe the mechanism <i>by which</i> it works =E2=80=94 not right away=
, anyway. Step one is to focus on that implementation: can it be implemente=
d? is it efficient enough for real-world uses? is it robust enough for real=
-world uses?</div></div></div></div></blockquote><div><br></div><div>The ki=
nd of persistence that Niall is talking about is persistence at its lowest =
level: what happens to a C++ object if it is in mapped memory that gets unm=
apped? Can it survive? Can another process receive and manipulate that obje=
ct? How can we make transmission of objects work at that level?</div><div><=
br></div><div>Defining this is the point of this exercise. The high level d=
etails you're talking about for some hypothetical library are beyond th=
is exercise. We're talking about a low-level tool for low-level needs. =
How high-level code deals with it is something that can be looked at once w=
e allow the object model to be able to consider these possibilities.</div><=
div><br></div><div>Think about all of the issues that went into defining th=
e C++11 memory model that included the possibility of data races. Those wer=
en't based on high-level constructs and the like; it was solely about p=
inning down how memory works between threads. That's the kind of thing =
this is dealing with: how objects work in a world where storage for them ca=
n exist beyond the lifespan of the program.<br></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/21d282b1-b939-47f8-9745-ff153387ea2c%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/21d282b1-b939-47f8-9745-ff153387ea2c=
%40isocpp.org</a>.<br />
------=_Part_924_479936405.1533348507042--
------=_Part_923_1688764810.1533348507042--
.
Author: Niall Douglas <nialldouglas14@gmail.com>
Date: Mon, 6 Aug 2018 10:35:16 -0700 (PDT)
Raw View
------=_Part_1623_2134852687.1533576916968
Content-Type: multipart/alternative;
boundary="----=_Part_1624_557873716.1533576916968"
------=_Part_1624_557873716.1533576916968
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
>
>
> Niall's original conception was that the thing is not related to beginnin=
g=20
> or ending object lifetime at all =E2=80=94 object lifetime just kind of p=
ersists=20
> "through" this operation.
> (If the operation *is* related to beginning and ending object lifetime,=
=20
> then I propose "construct" and "destruct". ;))
>
> My own conception is that I want to see how this functionality would=20
> actually be used in a real-world high-level library; I imagine that we=20
> don't need any special names or semantics at all. For example, we could=
=20
> just state that if you use "libPersistence", then
>
> auto p =3D libpersistence::open("somefile.bin");
> std::vector<int> foo =3D p.readobject("foo");
> p.writeobject("foo") =3D foo;
>
> will *just work*, and we don't necessarily need to describe the mechanism=
*by=20
> which* it works =E2=80=94 not right away, anyway. Step one is to focus on=
that=20
> implementation: can it be implemented? is it efficient enough for=20
> real-world uses? is it robust enough for real-world uses?
>
Nobody is in any doubt that a serialisation library can be written which=20
works well on the major compilers. There are dozens to choose from. P1026 *=
A=20
call for a Data Persistence (iostream v2) study group* lists and benchmarks=
=20
some of them.
Intel's PMDK https://github.com/pmem/pmdk goes a step further, and stores=
=20
STL objects directly in persistent memory. It can use mapped kernel cache=
=20
memory in lieu of proper persistent memory. So again, nobody is in any=20
doubt that these can be written and they work well on the major compilers.
What we are doing here is figuring out how to *standardise* support for=20
these sorts of library into the C++ standard. Because right now, this stuff=
=20
is far into UB land. It relies on the major compilers interpreting UB a=20
certain way, because if you don't rely heavily on UB you get terrible=20
performance.
If we are to build an iostreams v2, we need to improve the C++ object and=
=20
lifetime model such that resorting to UB tricks is no longer necessary. My=
=20
proposition is that these improvements would also benefit codegen and=20
static analysis in any case, because they help the compiler reason more=20
strongly and more accurately about code. So they're worth doing in any case=
..
They are also hard to do. There is a reason nobody has standardised mapped=
=20
memory support into C++ yet. It's a deep well and a long road.
=20
>
> But certainly, if there is any reason to subtly prefer "reify" over=20
> "manifest" or vice versa, it will strongly depend on the subtle semantics=
=20
> of the operation. And we do not have any semantics at all, yet. Heck, I=
=20
> haven't seen a *use-case* yet.
>
>
Any of the examples in P1031's long list of example use cases which use=20
mapped memory become UB as soon you unmap and remap any memory you placed=
=20
an object into. They're use cases.
More deeply, we cannot currently implement malloc() in C++ without relying=
=20
on UB. I'd like to fix that. There's another use case.
Niall
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/1760d8e5-eda9-4fec-86b1-953bf932de16%40isocpp.or=
g.
------=_Part_1624_557873716.1533576916968
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bor=
der-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div class=3D=
"gmail_quote"><br></div></div></blockquote><blockquote class=3D"gmail_quote=
" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding=
-left: 1ex;"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><div>Niall=
9;s original conception was that the thing is not related to beginning or e=
nding object lifetime at all =E2=80=94 object lifetime just kind of persist=
s "through" this operation.</div><div>(If the operation <i>is</i>=
related to beginning and ending object lifetime, then I propose "cons=
truct" and "destruct". ;))</div><div><br></div><div>My own c=
onception is that I want to see how this functionality would actually be us=
ed in a real-world high-level library; I imagine that we don't need any=
special names or semantics at all. For example, we could just state that i=
f you use "libPersistence", then</div><div><br></div><div>=C2=A0 =
=C2=A0 auto p =3D libpersistence::open("<wbr>somefile.bin");</div=
><div>=C2=A0 =C2=A0 std::vector<int> foo =3D p.readobject("foo&q=
uot;);</div><div>=C2=A0 =C2=A0 p.writeobject("foo") =3D foo;</div=
><div><br></div><div>will <i>just work</i>, and we don't necessarily ne=
ed to describe the mechanism <i>by which</i> it works =E2=80=94 not right a=
way, anyway. Step one is to focus on that implementation: can it be impleme=
nted? is it efficient enough for real-world uses? is it robust enough for r=
eal-world uses?</div></div></div></div></blockquote><div><br></div><div>Nob=
ody is in any doubt that a serialisation library can be written which works=
well on the major compilers. There are dozens to choose from. P1026=C2=A0<=
span style=3D"color: rgb(0, 0, 0); font-family: "Times New Roman"=
; font-size: medium;"><i>A call for a Data Persistence (iostream v2) study =
group</i></span>=C2=A0lists and benchmarks some of them.</div><div><br></di=
v><div>Intel's PMDK=C2=A0https://github.com/pmem/pmdk goes a step furth=
er, and stores STL objects directly in persistent memory. It can use mapped=
kernel cache memory in lieu of proper persistent memory. So again, nobody =
is in any doubt that these can be written and they work well on the major c=
ompilers.</div><div><br></div><div>What we are doing here is figuring out h=
ow to <i>standardise</i>=C2=A0support for these sorts of library into the C=
++ standard. Because right now, this stuff is far into UB land. It relies o=
n the major compilers interpreting UB a certain way, because if you don'=
;t rely heavily on UB you get terrible performance.</div><div><br></div><di=
v>If we are to build an iostreams v2, we need to improve the C++ object and=
lifetime model such that resorting to UB tricks is no longer necessary. My=
proposition is that these improvements would also benefit codegen and stat=
ic analysis in any case, because they help the compiler reason more strongl=
y and more accurately about code. So they're worth doing in any case.</=
div><div><br></div><div>They are also hard to do. There is a reason nobody =
has standardised mapped memory support into C++ yet. It's a deep well a=
nd a long road.</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" sty=
le=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left=
: 1ex;"><div dir=3D"ltr"><div class=3D"gmail_quote"><div><br></div><div>But=
certainly, if there is any reason to subtly prefer "reify" over =
"manifest" or vice versa, it will strongly depend on the subtle s=
emantics of the operation. And we do not have any semantics at all, yet. He=
ck, I haven't seen a <i>use-case</i> yet.</div><div><br></div></div></d=
iv></blockquote><div><br></div><div>Any of the examples in P1031's long=
list of example use cases which use mapped memory become UB as soon you un=
map and remap any memory you placed an object into. They're use cases.<=
br></div><div><br></div><div>More deeply, we cannot currently implement mal=
loc() in C++ without relying on UB. I'd like to fix that. There's a=
nother use case.</div><div><br></div><div>Niall</div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/1760d8e5-eda9-4fec-86b1-953bf932de16%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/1760d8e5-eda9-4fec-86b1-953bf932de16=
%40isocpp.org</a>.<br />
------=_Part_1624_557873716.1533576916968--
------=_Part_1623_2134852687.1533576916968--
.
Author: Niall Douglas <nialldouglas14@gmail.com>
Date: Mon, 6 Aug 2018 10:59:04 -0700 (PDT)
Raw View
------=_Part_298_1608135950.1533578344088
Content-Type: multipart/alternative;
boundary="----=_Part_299_525592280.1533578344088"
------=_Part_299_525592280.1533578344088
Content-Type: text/plain; charset="UTF-8"
>
> The kind of persistence that Niall is talking about is persistence at its
> lowest level: what happens to a C++ object if it is in mapped memory that
> gets unmapped? Can it survive? Can another process receive and manipulate
> that object? How can we make transmission of objects work at that level?
>
> Defining this is the point of this exercise. The high level details you're
> talking about for some hypothetical library are beyond this exercise. We're
> talking about a low-level tool for low-level needs. How high-level code
> deals with it is something that can be looked at once we allow the object
> model to be able to consider these possibilities.
>
> Think about all of the issues that went into defining the C++11 memory
> model that included the possibility of data races. Those weren't based on
> high-level constructs and the like; it was solely about pinning down how
> memory works between threads. That's the kind of thing this is dealing
> with: how objects work in a world where storage for them can exist beyond
> the lifespan of the program.
>
The analogy to the changes to the memory model to support threads is apt.
Even if we limited ourselves to solely trivially copyable types, there is a
whole new world of read and write reordering barriers to those of atomics
and threads, which are like those for threads, but are wholly independent.
We have this problem with persistence because we don't control when the
kernel/CPU flushes modifications to an object to storage - either or both
may completely reorder modifications at will, which is a race. Therefore we
need to build an awareness into the C++ object model that persisting an
object is a reordering barrier at the compiler, current CPU and storage
level. Note this does not include thread level. In this way, persistent
storage is different to shared memory, even if we use the same library
primitive functions for both.
I'm personally minded that the next layer on top of mapped memory ought to
be records a la VMS. In other words, you can define a given file to be an
array of objects with a known type and size, and the manipulation of each
which is guaranteed to be atomic. Support for these is partial amongst the
major operating systems, POSIX treats it as an extension. But their
availability certainly simplifies a lot of code, and if they don't suit
your use case, fall back to the byte layer underneath (the one we are
defining now).
Anyway, that's later, and I suspect I can't return to this until the Kona
mailing date anyway.
Niall
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/8c1e1577-c78f-41ef-9749-365b57680979%40isocpp.org.
------=_Part_299_525592280.1533578344088
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bor=
der-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>The kind=
of persistence that Niall is talking about is persistence at its lowest le=
vel: what happens to a C++ object if it is in mapped memory that gets unmap=
ped? Can it survive? Can another process receive and manipulate that object=
? How can we make transmission of objects work at that level?</div></div></=
blockquote><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left=
: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><d=
iv><br></div><div>Defining this is the point of this exercise. The high lev=
el details you're talking about for some hypothetical library are beyon=
d this exercise. We're talking about a low-level tool for low-level nee=
ds. How high-level code deals with it is something that can be looked at on=
ce we allow the object model to be able to consider these possibilities.</d=
iv><div><br></div><div>Think about all of the issues that went into definin=
g the C++11 memory model that included the possibility of data races. Those=
weren't based on high-level constructs and the like; it was solely abo=
ut pinning down how memory works between threads. That's the kind of th=
ing this is dealing with: how objects work in a world where storage for the=
m can exist beyond the lifespan of the program.<br></div></div></blockquote=
><div><br></div><div>The analogy to the changes to the memory model to supp=
ort threads is apt.</div><div><br></div><div>Even if we limited ourselves t=
o solely trivially copyable types, there is a whole new world of read and w=
rite reordering barriers to those of atomics and threads, which are like th=
ose for threads, but are wholly independent.</div><div><br></div><div>We ha=
ve this problem with persistence because we don't control when the kern=
el/CPU flushes modifications to an object to storage - either or both may c=
ompletely reorder modifications at will, which is a race. Therefore we need=
to build an awareness into the C++ object model that persisting an object =
is a reordering barrier at the compiler, current CPU and storage level. Not=
e this does not include thread level. In this way, persistent storage is di=
fferent to shared memory, even if we use the same library primitive functio=
ns for both.</div><div><br></div><div>I'm personally minded that the ne=
xt layer on top of mapped memory ought to be records a la VMS. In other wor=
ds, you can define a given file to be an array of objects with a known type=
and size, and the manipulation of each which is guaranteed to be atomic. S=
upport for these is partial amongst the major operating systems, POSIX trea=
ts it as an extension. But their availability certainly simplifies a lot of=
code, and if they don't suit your use case, fall back to the byte laye=
r underneath (the one we are defining now).</div><div><br></div><div>Anyway=
, that's later, and I suspect I can't return to this until the Kona=
mailing date anyway.</div><div><br></div><div>Niall</div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/8c1e1577-c78f-41ef-9749-365b57680979%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/8c1e1577-c78f-41ef-9749-365b57680979=
%40isocpp.org</a>.<br />
------=_Part_299_525592280.1533578344088--
------=_Part_298_1608135950.1533578344088--
.
Author: "Arthur O'Dwyer" <arthur.j.odwyer@gmail.com>
Date: Mon, 6 Aug 2018 12:10:30 -0700
Raw View
--00000000000003b3140572c90847
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
On Mon, Aug 6, 2018 at 10:13 AM, Niall Douglas <nialldouglas14@gmail.com>
wrote:
>
>>>> Thinking about this further, "trivial relocation" could be redefined a=
s
>>>> trivial reduction, memcpy, and trivial regeneration. And thus, a type =
is
>>>> trivially relocatable if it has no-argument reducer and regenerators t=
hat
>>>> are trivial, which can be declared with `=3D default` syntax.
>>>>
>>>>
>>>> By my above definition, they would not have *trivial* relocation
>> abilities, since reduction/regeneration would have to execute code. And =
as
>> Arthur pointed out, there are differences between relocation and
>> reduction/regeneration. Indeed, based on his post, TriviallyRelocatable =
is
>> not something we can use to allow trivial reduction/regeneration. Or
>> rather, it would have to be TriviallyRelocatable & non-polymorphic.
>>
>> I need to think on this some more.
>>
>> Trivial operation X simply means that the compiler can perform operation
> X entirely on its own, as frequently and infrequently as it so chooses,
> including ignoring the programmer if it would be as-if the same. That's t=
he
> meaning of triviality.
>
I should point out that that is not *my* definition of triviality. My
definition of triviality is "as-if by memfoo." That is, for any given
operation on an object-in-memory (e.g. copying, e.g. relocation, e.g.
comparison, e.g. destruction, e.g. swapping) there is exactly one "trivial"
implementation of that operation, which relies on absolutely nothing about
the object's type except maybe its size.
This is subtly different from the current Standard's notion of
"triviality," which is closer to Niall's (but still not identical). The
Standard's notion is that any operation is "trivial" iff it runs no
user-provided functions.
E.g. copying a `volatile int` is "trivial" by the Standard's definition but
not by mine (since it cannot be done by memcpy) nor Niall's (since it
cannot be memoized).
E.g. constructing a `float` from an `int` is "trivial" by the Standard's
definition (is_trivially_constructible_v<float,int>
<https://godbolt.org/g/mdCALZ>) and by Niall's, but not by mine (since it
cannot be done by memcpy).
E.g. comparing two `float`s is "trivial" by the Standard's definition and
by Niall's, but not by mine (since it cannot be done by memcmp).
Further reading:
https://quuxplusone.github.io/blog/2018/07/03/trivially-constructible-from/
If the compiler can trivially reduce, copy and regenerate on its own,
> that's still trivial by definition. It's also optimisable, so if the
> compiler knows that nothing will modify the bytes between the reduction a=
nd
> regeneration, it can optimise out say vptr modification and just use
> straight memcpy.
>
I still don't see what you hope to achieve with "vptr modification." If a
persisted object contains native pointers, they *will not* point to the
correct place when reloaded, unless <a global property of the program is
carefully maintained by the programmer>. This applies to all kinds of
structs, not just vptrs.
struct Vec { int *p; }; // cannot be written out and "regenerated"
later
struct MemFn { T *p; void (*f)(T); }; // cannot be written out and
"regenerated" later
struct Poly { virtual void foo(); }; // cannot be written out and
"regenerated" later
I definitely wouldn't worry about the third example until you've got
something working-in-practice for the first two, simpler, examples.
> nobody is in any doubt that these can be written and they work well on
the major compilers.
> What we are doing here is figuring out how to *standardise* support for
these sorts of library into the C++ standard. [...]
> we need to improve the C++ object and lifetime model such that resorting
to UB tricks is no longer necessary.
I think that's simply "std::bless should work for non-implicit-lifetime
types," as suggested in the "Further Work" section of P0593,
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0593r2.html#direct=
-object-creation
:
> a combined operation to create an object of implicit lifetime type
in-place while preserving the object representation may be useful ... we
could imagine extending its semantics to also permit conversions where each
subobject of non-implicit-lifetime type in the destination corresponds to
an object of the same type (ignoring cv-qualifications) in the source ...
All you need is a way to say "here are some bytes, please treat them as an
object." Right now, everyone (including STL vendors) does that via
reinterpret_cast, and it works great, and it isn't going to break anytime
soon (because all STL implementations depend on it).
Post-P0593-further-work, some people may switch to using reinterpret_cast
plus std::bless, which will work equally great (modulo an initial crop of
compiler bugs, I'm sure). I don't think the UB-ness of reinterpret_cast is
really the biggest blocker to getting persistent data structures into C++.
=E2=80=93Arthur
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CADvuK0%2Bn%3DpDRRBwcUjpSLM0R_LMXYA3GBWq2QkPas6U=
YY4CD3Q%40mail.gmail.com.
--00000000000003b3140572c90847
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Mon, Aug 6, 2018 at 10:13 AM, Niall Douglas <span dir=
=3D"ltr"><<a href=3D"mailto:nialldouglas14@gmail.com" target=3D"_blank">=
nialldouglas14@gmail.com</a>></span> wrote:<br><div class=3D"gmail_extra=
"><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"mar=
gin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-=
left-color:rgb(204,204,204);padding-left:1ex"><blockquote class=3D"gmail_qu=
ote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-st=
yle:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir=3D"=
ltr"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;bo=
rder-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,2=
04);padding-left:1ex"><div dir=3D"ltr"><blockquote class=3D"gmail_quote" st=
yle=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:sol=
id;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><d=
iv><div><br></div><div>Thinking about this further, "trivial relocatio=
n" could be redefined as trivial reduction, memcpy, and trivial regene=
ration. And thus, a type is trivially relocatable if it has no-argument red=
ucer and regenerators that are trivial, which can be declared with `=3D def=
ault` syntax.</div><div><br></div><div><br></div></div></div></blockquote><=
/div></blockquote><div>By my above definition, they would not have <i>trivi=
al</i> relocation abilities, since reduction/regeneration would have to exe=
cute code. And as Arthur pointed out, there are differences between relocat=
ion and reduction/regeneration. Indeed, based on his post, TriviallyRelocat=
able is not something we can use to allow trivial reduction/regeneration. O=
r rather, it would have to be TriviallyRelocatable & non-polymorphic.</=
div><div><br></div><div>I need to think on this some more.</div><br></div><=
/blockquote><div>Trivial operation X simply means that the compiler can per=
form operation X entirely on its own, as frequently and infrequently as it =
so chooses, including ignoring the programmer if it would be as-if the same=
.. That's the meaning of triviality.=C2=A0</div></blockquote><div><br></=
div><div>I should point out that that is not <i>my</i> definition of trivia=
lity.=C2=A0 My definition of triviality is "as-if by memfoo." Tha=
t is, for any given operation on an object-in-memory (e.g. copying, e.g. re=
location, e.g. comparison, e.g. destruction, e.g. swapping) there is exactl=
y one "trivial" implementation of that operation, which relies on=
absolutely nothing about the object's type except maybe its size.</div=
><div><br></div><div>This is subtly different from the current Standard'=
;s notion of "triviality," which is closer to Niall's (but st=
ill not identical). The Standard's notion is that any operation is &quo=
t;trivial" iff it runs no user-provided functions.</div><div><br></div=
><div>E.g. copying a `volatile int` is "trivial" by the Standard&=
#39;s definition but not by mine (since it cannot be done by memcpy) nor Ni=
all's (since it cannot be memoized).</div><div>E.g. constructing a `flo=
at` from an `int` is "trivial" by the Standard's definition (=
<a href=3D"https://godbolt.org/g/mdCALZ">is_trivially_constructible_v<fl=
oat,int></a>) and by Niall's, but not by mine (since it cannot be do=
ne by memcpy).<br></div><div><div>E.g. comparing two `float`s is "triv=
ial" by the Standard's definition and by Niall's, but not by m=
ine (since it cannot be done by memcmp).</div></div><div><br></div><div>Fur=
ther reading: <a href=3D"https://quuxplusone.github.io/blog/2018/07/03/triv=
ially-constructible-from/">https://quuxplusone.github.io/blog/2018/07/03/tr=
ivially-constructible-from/</a></div><div><br></div><div><br></div><blockqu=
ote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-wid=
th:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-l=
eft:1ex"><div></div><div>If the compiler can trivially reduce, copy and reg=
enerate on its own, that's still trivial by definition. It's also o=
ptimisable, so if the compiler knows that nothing will modify the bytes bet=
ween the reduction and regeneration, it can optimise out say vptr modificat=
ion and just use straight memcpy.</div></blockquote><div><br></div><div>I s=
till don't see what you hope to achieve with "vptr modification.&q=
uot; If a persisted object contains native pointers, they <i>will not</i> p=
oint to the correct place when reloaded, unless <a global property of th=
e program is carefully maintained by the programmer>. This applies to al=
l kinds of structs, not just vptrs.</div><div><br></div><div>=C2=A0 =C2=A0 =
struct Vec { int *p; }; =C2=A0// cannot be written out and "regenerate=
d" later</div><div>=C2=A0 =C2=A0 struct MemFn { T *p; void (*f)(T); };=
=C2=A0// cannot be written out and "regenerated" later</div><div=
>=C2=A0 =C2=A0 struct Poly { virtual void foo(); }; =C2=A0// cannot be writ=
ten out and "regenerated" later</div><div><br></div><div>I defini=
tely wouldn't worry about the third example until you've got someth=
ing working-in-practice for the first two, simpler, examples.</div><div><br=
></div><div><br></div><div><div style=3D"font-size:12.800000190734863px">&g=
t; nobody is in any doubt that these can be written and they work well on t=
he major compilers.</div><div style=3D"font-size:12.800000190734863px">>=
What we are doing here is figuring out how to=C2=A0<i>standardise</i>=C2=
=A0support for these sorts of library into the C++ standard. [...]</div><di=
v style=3D"font-size:12.800000190734863px">> we need to improve the C++ =
object and lifetime model such that resorting to UB tricks is no longer nec=
essary.</div></div><div><br></div><div>I think that's simply "std:=
:bless should work for non-implicit-lifetime types," as suggested in t=
he "Further Work" section of P0593,</div><div><a href=3D"http://w=
ww.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0593r2.html#direct-object-=
creation">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0593r2.h=
tml#direct-object-creation</a> :<br></div><div>>=C2=A0<span style=3D"col=
or:rgb(0,0,0);font-family:sans-serif;font-size:medium">a combined operation=
to create an object of implicit lifetime type in-place while preserving th=
e object representation may be useful ...=C2=A0</span><span style=3D"color:=
rgb(0,0,0);font-family:sans-serif;font-size:medium">we could imagine extend=
ing its semantics to also permit conversions where each subobject of non-im=
plicit-lifetime type in the destination corresponds to an object of the sam=
e type (ignoring cv-qualifications) in the source ...</span></div><div><br>=
</div><div>All you need is a way to say "here are some bytes, please t=
reat them as an object." =C2=A0Right now, everyone (including STL vend=
ors) does that via reinterpret_cast, and it works great, and it isn't g=
oing to break anytime soon (because all STL implementations depend on it).=
=C2=A0 Post-P0593-further-work, some people may switch to using reinterpret=
_cast plus std::bless, which will work equally great (modulo an initial cro=
p of compiler bugs, I'm sure).=C2=A0 I don't think the UB-ness of r=
einterpret_cast is really the biggest blocker to getting persistent data st=
ructures into C++.</div><div><br></div><div>=E2=80=93Arthur</div></div></di=
v></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CADvuK0%2Bn%3DpDRRBwcUjpSLM0R_LMXYA3G=
BWq2QkPas6UYY4CD3Q%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CADvuK0%2Bn%3=
DpDRRBwcUjpSLM0R_LMXYA3GBWq2QkPas6UYY4CD3Q%40mail.gmail.com</a>.<br />
--00000000000003b3140572c90847--
.
Author: "Arthur O'Dwyer" <arthur.j.odwyer@gmail.com>
Date: Mon, 6 Aug 2018 12:42:36 -0700
Raw View
--000000000000c5aeac0572c97a5e
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
On Mon, Aug 6, 2018 at 10:35 AM, Niall Douglas <nialldouglas14@gmail.com>
wrote:
>
>> Niall's original conception was that the thing is not related to
>> beginning or ending object lifetime at all =E2=80=94 object lifetime jus=
t kind of
>> persists "through" this operation.
>> (If the operation *is* related to beginning and ending object lifetime,
>> then I propose "construct" and "destruct". ;))
>>
>> My own conception is that I want to see how this functionality would
>> actually be used in a real-world high-level library; I imagine that we
>> don't need any special names or semantics at all. For example, we could
>> just state that if you use "libPersistence", then
>>
>> auto p =3D libpersistence::open("somefile.bin");
>> std::vector<int> foo =3D p.readobject("foo");
>> p.writeobject("foo") =3D foo;
>>
>> will *just work*, and we don't necessarily need to describe the
>> mechanism *by which* it works =E2=80=94 not right away, anyway. Step one=
is to
>> focus on that implementation: can it be implemented? is it efficient eno=
ugh
>> for real-world uses? is it robust enough for real-world uses?
>>
>
> Nobody is in any doubt that a serialisation library can be written which
> works well on the major compilers. There are dozens to choose from. P1026=
*A
> call for a Data Persistence (iostream v2) study group* lists and
> benchmarks some of them.
>
Do you mean
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1026r0.pdf page 3?
It lists:
- memcpy
- bitsery <https://github.com/fraillt/bitsery#usage-example>
- yas <https://github.com/niXman/yas#samples>
- zpp <https://github.com/eyalz800/serializer#contents>
- Cereal <https://uscilab.github.io/cereal/index.html>
- Flatbuffers
<https://google.github.io/flatbuffers/flatbuffers_guide_tutorial.html>
- Boost.Serialization
- std::stringstream
These are all what I would call *serialization* libraries, yes. They're
ways of taking an object of type T as input, and producing some kind of
formatted string as output (maybe JSON, maybe XML, maybe some proprietary
binary format), in a neatly reversible way. Notably they do *not* involve
the filesystem at all, and they do *not* involve the object model at all.
Serialization is a completely value-space operation.
T someobj;
std::string s =3D serialize(someobj, FMT_JSON); // or FMT_BINARY, same
difference
T otherobj =3D deserialize(s, FMT_JSON);
assert(otherobj =3D=3D someobj); // more or less
I say "more or less" because of course if `T` is `std::shared_ptr<U>`, then
these libraries aren't going to make `otherobj =3D=3D someobj` in the C++
sense; they're going to allocate a new object for `otherobj` to point to.
That's because that's their use-case. Their use-case is things like
save-games =E2=80=94 things where the original objects don't need to *persi=
st* in
any sense. These libraries are all about *serialization* (marshalling,
pickling, stringification...). They don't have anything to do with
*persistence*. They also do not rely on UB.
> Intel's PMDK https://github.com/pmem/pmdk goes a step further, and stores
> STL objects directly in persistent memory. It can use mapped kernel cache
> memory in lieu of proper persistent memory. So again, nobody is in any
> doubt that these can be written and they work well on the major compilers=
..
>
PMDK is what I'm talking about when I say "*persistence*." I contend that
PMDK is still fairly experimental, though; much more experimental than any
of the *serialization* libraries you listed above. Its API
<http://pmem.io/2016/01/12/cpp-04.html> doesn't look anything like a
JSON-serialization library, nor does it look anything like what's in your
P1031R0
<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1031r0.pdf>.
I observe that
- *Serialization* is fundamentally value-semantic.
- *Persistence* is fundamentally object-semantic.
=E2=80=93Arthur
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CADvuK0Lv_PaXRBO%3DKcz%2B6vPsNOM08FXdSxctjngQnTw=
6z3crkw%40mail.gmail.com.
--000000000000c5aeac0572c97a5e
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Mon, Aug 6, 2018 at 10:35 AM, Niall Douglas <span dir=
=3D"ltr"><<a href=3D"mailto:nialldouglas14@gmail.com" target=3D"_blank">=
nialldouglas14@gmail.com</a>></span> wrote:<br><div class=3D"gmail_extra=
"><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"mar=
gin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-=
left-color:rgb(204,204,204);padding-left:1ex"><span class=3D"gmail-"><block=
quote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-w=
idth:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding=
-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_quote"><br></div></div></bl=
ockquote><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8e=
x;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,2=
04,204);padding-left:1ex"><div dir=3D"ltr"><div><div class=3D"gmail_quote">=
<div>Niall's original conception was that the thing is not related to b=
eginning or ending object lifetime at all =E2=80=94 object lifetime just ki=
nd of persists "through" this operation.</div><div>(If the operat=
ion <i>is</i> related to beginning and ending object lifetime, then I propo=
se "construct" and "destruct". ;))</div><div><br></div>=
<div>My own conception is that I want to see how this functionality would a=
ctually be used in a real-world high-level library; I imagine that we don&#=
39;t need any special names or semantics at all. For example, we could just=
state that if you use "libPersistence", then</div><div><br></div=
><div>=C2=A0 =C2=A0 auto p =3D libpersistence::open("somefile<wbr>.bin=
");</div><div>=C2=A0 =C2=A0 std::vector<int> foo =3D p.readobjec=
t("foo");</div><div>=C2=A0 =C2=A0 p.writeobject("foo") =
=3D foo;</div><div><br></div><div>will <i>just work</i>, and we don't n=
ecessarily need to describe the mechanism <i>by which</i> it works =E2=80=
=94 not right away, anyway. Step one is to focus on that implementation: ca=
n it be implemented? is it efficient enough for real-world uses? is it robu=
st enough for real-world uses?</div></div></div></div></blockquote><div><br=
></div></span><div>Nobody is in any doubt that a serialisation library can =
be written which works well on the major compilers. There are dozens to cho=
ose from. P1026=C2=A0<span style=3D"color:rgb(0,0,0);font-family:"Time=
s New Roman";font-size:medium"><i>A call for a Data Persistence (iostr=
eam v2) study group</i></span>=C2=A0lists and benchmarks some of them.</div=
></blockquote><div><br></div><div>Do you mean=C2=A0<a href=3D"http://www.op=
en-std.org/jtc1/sc22/wg21/docs/papers/2018/p1026r0.pdf">http://www.open-std=
..org/jtc1/sc22/wg21/docs/papers/2018/p1026r0.pdf</a> page 3? It lists:</div=
><div>- memcpy</div><div>- <a href=3D"https://github.com/fraillt/bitsery#us=
age-example">bitsery</a></div><div>- <a href=3D"https://github.com/niXman/y=
as#samples">yas</a></div><div>- <a href=3D"https://github.com/eyalz800/seri=
alizer#contents">zpp</a></div><div>- <a href=3D"https://uscilab.github.io/c=
ereal/index.html">Cereal</a></div><div>- <a href=3D"https://google.github.i=
o/flatbuffers/flatbuffers_guide_tutorial.html">Flatbuffers</a></div><div>- =
Boost.Serialization</div><div>- std::stringstream</div><div><br></div><div>=
These are all what I would call <i>serialization</i> libraries, yes. They&#=
39;re ways of taking an object of type T as input, and producing some kind =
of formatted string as output (maybe JSON, maybe XML, maybe some proprietar=
y binary format), in a neatly reversible way. Notably they do <i>not</i> in=
volve the filesystem at all, and they do <i>not</i> involve the object mode=
l at all. Serialization is a completely value-space operation.</div><div><b=
r></div><div>=C2=A0 =C2=A0 T someobj;</div><div>=C2=A0 =C2=A0 std::string s=
=3D serialize(someobj, FMT_JSON); =C2=A0// or FMT_BINARY, same difference<=
/div><div>=C2=A0 =C2=A0 T otherobj =3D deserialize(s, FMT_JSON);</div><div>=
=C2=A0 =C2=A0 assert(otherobj =3D=3D someobj); =C2=A0// more or less</div><=
div><br></div><div>I say "more or less" because of course if `T` =
is `std::shared_ptr<U>`, then these libraries aren't going to mak=
e `otherobj =3D=3D someobj` in the C++ sense; they're going to allocate=
a new object for `otherobj` to point to. That's because that's the=
ir use-case. Their use-case is things like save-games =E2=80=94 things wher=
e the original objects don't need to <i>persist</i> in any sense.=C2=A0=
These libraries are all about <i>serialization</i>=C2=A0(marshalling, pick=
ling, stringification...).=C2=A0 They don't have anything to do with <i=
>persistence</i>.=C2=A0 They also do not rely on UB.</div><div><br></div><d=
iv>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0p=
x 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb=
(204,204,204);padding-left:1ex"><div></div><div>Intel's PMDK=C2=A0<a hr=
ef=3D"https://github.com/pmem/pmdk" target=3D"_blank">https://github.com/pm=
em/<wbr>pmdk</a> goes a step further, and stores STL objects directly in pe=
rsistent memory. It can use mapped kernel cache memory in lieu of proper pe=
rsistent memory. So again, nobody is in any doubt that these can be written=
and they work well on the major compilers.</div></blockquote><div><br></di=
v><div>PMDK is what I'm talking about when I say "<i>persistence</=
i>." =C2=A0I contend that PMDK is still fairly experimental, though; m=
uch more experimental than any of the <i>serialization</i> libraries you li=
sted above. =C2=A0<a href=3D"http://pmem.io/2016/01/12/cpp-04.html">Its API=
</a> doesn't look anything like a JSON-serialization library, nor does =
it look anything like what's in your <a href=3D"http://www.open-std.org=
/jtc1/sc22/wg21/docs/papers/2018/p1031r0.pdf">P1031R0</a>.</div><div><br></=
div><div>I observe that</div><div>- <i>Serialization</i> is fundamentally v=
alue-semantic.</div><div>- <i>Persistence</i> is fundamentally object-seman=
tic.</div><div><br></div><div>=E2=80=93Arthur</div></div></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CADvuK0Lv_PaXRBO%3DKcz%2B6vPsNOM08FXd=
SxctjngQnTw6z3crkw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CADvuK0Lv_PaX=
RBO%3DKcz%2B6vPsNOM08FXdSxctjngQnTw6z3crkw%40mail.gmail.com</a>.<br />
--000000000000c5aeac0572c97a5e--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Mon, 6 Aug 2018 13:43:09 -0700 (PDT)
Raw View
------=_Part_1544_477866830.1533588189512
Content-Type: multipart/alternative;
boundary="----=_Part_1545_1131684563.1533588189512"
------=_Part_1545_1131684563.1533588189512
Content-Type: text/plain; charset="UTF-8"
On Monday, August 6, 2018 at 3:10:34 PM UTC-4, Arthur O'Dwyer wrote:
>
> On Mon, Aug 6, 2018 at 10:13 AM, Niall Douglas <nialldo...@gmail.com
> <javascript:>> wrote:
>
>>
>>>>> Thinking about this further, "trivial relocation" could be redefined
>>>>> as trivial reduction, memcpy, and trivial regeneration. And thus, a type is
>>>>> trivially relocatable if it has no-argument reducer and regenerators that
>>>>> are trivial, which can be declared with `= default` syntax.
>>>>>
>>>>>
>>>>> By my above definition, they would not have *trivial* relocation
>>> abilities, since reduction/regeneration would have to execute code. And as
>>> Arthur pointed out, there are differences between relocation and
>>> reduction/regeneration. Indeed, based on his post, TriviallyRelocatable is
>>> not something we can use to allow trivial reduction/regeneration. Or
>>> rather, it would have to be TriviallyRelocatable & non-polymorphic.
>>>
>>> I need to think on this some more.
>>>
>>> Trivial operation X simply means that the compiler can perform operation
>> X entirely on its own, as frequently and infrequently as it so chooses,
>> including ignoring the programmer if it would be as-if the same. That's the
>> meaning of triviality.
>>
>
> I should point out that that is not *my* definition of triviality. My
> definition of triviality is "as-if by memfoo." That is, for any given
> operation on an object-in-memory (e.g. copying, e.g. relocation, e.g.
> comparison, e.g. destruction, e.g. swapping) there is exactly one "trivial"
> implementation of that operation, which relies on absolutely nothing about
> the object's type except maybe its size.
>
This, exactly. This is what I think of when dealing with triviality.
And note: types with virtuals are not trivially default constructible, nor
are they Trivially Copyable. So the standard is at least partially in
agreement with this notion.
This is subtly different from the current Standard's notion of
> "triviality," which is closer to Niall's (but still not identical). The
> Standard's notion is that any operation is "trivial" iff it runs no
> user-provided functions.
>
> E.g. copying a `volatile int` is "trivial" by the Standard's definition
> but not by mine (since it cannot be done by memcpy) nor Niall's (since it
> cannot be memoized).
> E.g. constructing a `float` from an `int` is "trivial" by the Standard's
> definition (is_trivially_constructible_v<float,int>
> <https://godbolt.org/g/mdCALZ>) and by Niall's, but not by mine (since it
> cannot be done by memcpy).
> E.g. comparing two `float`s is "trivial" by the Standard's definition and
> by Niall's, but not by mine (since it cannot be done by memcmp).
>
> Further reading:
> https://quuxplusone.github.io/blog/2018/07/03/trivially-constructible-from/
>
>
> If the compiler can trivially reduce, copy and regenerate on its own,
>> that's still trivial by definition. It's also optimisable, so if the
>> compiler knows that nothing will modify the bytes between the reduction and
>> regeneration, it can optimise out say vptr modification and just use
>> straight memcpy.
>>
>
> I still don't see what you hope to achieve with "vptr modification." If a
> persisted object contains native pointers, they *will not* point to the
> correct place when reloaded, unless <a global property of the program is
> carefully maintained by the programmer>. This applies to all kinds of
> structs, not just vptrs.
>
That's true. But unlike pointer members of the object, you *can't* modify
the vtable pointer. By "you", I mean "the user". Such things are the domain
of the compiler.
So if you want to be able to persist polymorphic types, you *have to* have
compiler involvement.
That's why I like thinking of persistence as a form of
construction/destruction. When you construct a polymorphic type, it puts
the vtable pointer in place. So when you unpack/whatever the value
representation of a polymorphic type, that operation can likewise put the
vtable pointer in place. And part of that operation should, just like
object construction, allow you to execute whatever code you need for manual
fixup of any pointers.
And thus, there are types for which persistence can be trivial (or
"implicit" using my current wording) and types which cannot. Pointer types
can be persisted, and defaultly persistent, but they are not *implicitly*
so.
struct Vec { int *p; }; // cannot be written out and "regenerated"
> later
>
Whether it can be done without code execution or not depends *entirely* on
what `p` points to and how long the object will be persistent. If `p`
points to a static object and the particular persistent instance of `Vec`
will not be persistent across program executions, then it's fine as is.
> struct MemFn { T *p; void (*f)(T); }; // cannot be written out and
> "regenerated" later
> struct Poly { virtual void foo(); }; // cannot be written out and
> "regenerated" later
>
> I definitely wouldn't worry about the third example until you've got
> something working-in-practice for the first two, simpler, examples.
>
But the third example is the easiest and the only one the compiler can
actually do for you. And most important of all, the only one you *cannot*
do for yourself.
> nobody is in any doubt that these can be written and they work well on
> the major compilers.
> > What we are doing here is figuring out how to *standardise* support for
> these sorts of library into the C++ standard. [...]
> > we need to improve the C++ object and lifetime model such that resorting
> to UB tricks is no longer necessary.
>
> I think that's simply "std::bless should work for non-implicit-lifetime
> types," as suggested in the "Further Work" section of P0593,
>
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0593r2.html#direct-object-creation
> :
> > a combined operation to create an object of implicit lifetime type
> in-place while preserving the object representation may be useful ... we
> could imagine extending its semantics to also permit conversions where each
> subobject of non-implicit-lifetime type in the destination corresponds to
> an object of the same type (ignoring cv-qualifications) in the source ...
>
> All you need is a way to say "here are some bytes, please treat them as an
> object." Right now, everyone (including STL vendors) does that via
> reinterpret_cast, and it works great, and it isn't going to break anytime
> soon (because all STL implementations depend on it).
> Post-P0593-further-work, some people may switch to using reinterpret_cast
> plus std::bless, which will work equally great (modulo an initial crop of
> compiler bugs, I'm sure). I don't think the UB-ness of reinterpret_cast is
> really the biggest blocker to getting persistent data structures into C++.
>
You cannot standardize something if the object model says that its
undefined behavior. You can't just say, "this has behavior X and it's
undefined behavior." That's a contradiction.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/a298811a-132e-42c5-979e-c02f9563a457%40isocpp.org.
------=_Part_1545_1131684563.1533588189512
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Monday, August 6, 2018 at 3:10:34 PM UTC-4, Arthur O=
9;Dwyer wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-l=
eft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"=
>On Mon, Aug 6, 2018 at 10:13 AM, Niall Douglas <span dir=3D"ltr"><<a hr=
ef=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"c3_Ds-ZnDgAJ"=
rel=3D"nofollow" onmousedown=3D"this.href=3D'javascript:';return t=
rue;" onclick=3D"this.href=3D'javascript:';return true;">nialldo...=
@gmail.com</a>></span> wrote:<br><div><div class=3D"gmail_quote"><blockq=
uote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-wi=
dth:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-=
left:1ex"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8=
ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,=
204,204);padding-left:1ex"><div dir=3D"ltr"><blockquote class=3D"gmail_quot=
e" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-styl=
e:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir=3D"lt=
r"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;bord=
er-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204=
);padding-left:1ex"><div dir=3D"ltr"><div><div><br></div><div>Thinking abou=
t this further, "trivial relocation" could be redefined as trivia=
l reduction, memcpy, and trivial regeneration. And thus, a type is triviall=
y relocatable if it has no-argument reducer and regenerators that are trivi=
al, which can be declared with `=3D default` syntax.</div><div><br></div><d=
iv><br></div></div></div></blockquote></div></blockquote><div>By my above d=
efinition, they would not have <i>trivial</i> relocation abilities, since r=
eduction/regeneration would have to execute code. And as Arthur pointed out=
, there are differences between relocation and reduction/regeneration. Inde=
ed, based on his post, TriviallyRelocatable is not something we can use to =
allow trivial reduction/regeneration. Or rather, it would have to be Trivia=
llyRelocatable & non-polymorphic.</div><div><br></div><div>I need to th=
ink on this some more.</div><br></div></blockquote><div>Trivial operation X=
simply means that the compiler can perform operation X entirely on its own=
, as frequently and infrequently as it so chooses, including ignoring the p=
rogrammer if it would be as-if the same. That's the meaning of triviali=
ty.=C2=A0</div></blockquote><div><br></div><div>I should point out that tha=
t is not <i>my</i> definition of triviality.=C2=A0 My definition of trivial=
ity is "as-if by memfoo." That is, for any given operation on an =
object-in-memory (e.g. copying, e.g. relocation, e.g. comparison, e.g. dest=
ruction, e.g. swapping) there is exactly one "trivial" implementa=
tion of that operation, which relies on absolutely nothing about the object=
's type except maybe its size.</div></div></div></div></blockquote><div=
><br></div><div>This, exactly. This is what I think of when dealing with tr=
iviality.</div><div><br></div><div>And note: types with virtuals are not tr=
ivially default constructible, nor are they Trivially Copyable. So the stan=
dard is at least partially in agreement with this notion.<br></div><div><br=
></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.=
8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><=
div class=3D"gmail_quote"><div></div><div>This is subtly different from the=
current Standard's notion of "triviality," which is closer t=
o Niall's (but still not identical). The Standard's notion is that =
any operation is "trivial" iff it runs no user-provided functions=
..</div><div><br></div><div>E.g. copying a `volatile int` is "trivial&q=
uot; by the Standard's definition but not by mine (since it cannot be d=
one by memcpy) nor Niall's (since it cannot be memoized).</div><div>E.g=
.. constructing a `float` from an `int` is "trivial" by the Standa=
rd's definition (<a href=3D"https://godbolt.org/g/mdCALZ" target=3D"_bl=
ank" rel=3D"nofollow" onmousedown=3D"this.href=3D'https://www.google.co=
m/url?q\x3dhttps%3A%2F%2Fgodbolt.org%2Fg%2FmdCALZ\x26sa\x3dD\x26sntz\x3d1\x=
26usg\x3dAFQjCNEcyTPhBHfg8T0QP0NUvBxGYZCOsw';return true;" onclick=3D"t=
his.href=3D'https://www.google.com/url?q\x3dhttps%3A%2F%2Fgodbolt.org%2=
Fg%2FmdCALZ\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEcyTPhBHfg8T0QP0NUvBxGY=
ZCOsw';return true;">is_trivially_constructible_v<<wbr>float,int>=
</a>) and by Niall's, but not by mine (since it cannot be done by memcp=
y).<br></div><div><div>E.g. comparing two `float`s is "trivial" b=
y the Standard's definition and by Niall's, but not by mine (since =
it cannot be done by memcmp).</div></div><div><br></div><div>Further readin=
g: <a href=3D"https://quuxplusone.github.io/blog/2018/07/03/trivially-const=
ructible-from/" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=
=3D'https://www.google.com/url?q\x3dhttps%3A%2F%2Fquuxplusone.github.io=
%2Fblog%2F2018%2F07%2F03%2Ftrivially-constructible-from%2F\x26sa\x3dD\x26sn=
tz\x3d1\x26usg\x3dAFQjCNHOF-gI6gwSN9VBFJ0xJ94P6uTeuQ';return true;" onc=
lick=3D"this.href=3D'https://www.google.com/url?q\x3dhttps%3A%2F%2Fquux=
plusone.github.io%2Fblog%2F2018%2F07%2F03%2Ftrivially-constructible-from%2F=
\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHOF-gI6gwSN9VBFJ0xJ94P6uTeuQ';=
return true;">https://quuxplusone.github.io/<wbr>blog/2018/07/03/trivially-=
<wbr>constructible-from/</a></div><div><br></div><div><br></div><blockquote=
class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:=
1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left=
:1ex"><div></div><div>If the compiler can trivially reduce, copy and regene=
rate on its own, that's still trivial by definition. It's also opti=
misable, so if the compiler knows that nothing will modify the bytes betwee=
n the reduction and regeneration, it can optimise out say vptr modification=
and just use straight memcpy.</div></blockquote><div><br></div><div>I stil=
l don't see what you hope to achieve with "vptr modification."=
; If a persisted object contains native pointers, they <i>will not</i> poin=
t to the correct place when reloaded, unless <a global property of the p=
rogram is carefully maintained by the programmer>. This applies to all k=
inds of structs, not just vptrs.</div></div></div></div></blockquote><div><=
br></div><div>That's true. But unlike pointer members of the object, yo=
u <i>can't</i> modify the vtable pointer. By "you", I mean &q=
uot;the user". Such things are the domain of the compiler.</div><div><=
br></div><div>So if you want to be able to persist polymorphic types, you <=
i>have to</i> have compiler involvement.</div><div><br></div><div>That'=
s why I like thinking of persistence as a form of construction/destruction.=
When you construct a polymorphic type, it puts the vtable pointer in place=
.. So when you unpack/whatever the value representation of a polymorphic typ=
e, that operation can likewise put the vtable pointer in place. And part of=
that operation should, just like object construction, allow you to execute=
whatever code you need for manual fixup of any pointers.</div><div><br></d=
iv><div>And thus, there are types for which persistence can be trivial (or =
"implicit" using my current wording) and types which cannot. Poin=
ter types can be persisted, and defaultly persistent, but they are not <i>i=
mplicitly</i> so.<br></div><div><br></div><blockquote class=3D"gmail_quote"=
style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-=
left: 1ex;"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><div></div><di=
v>=C2=A0 =C2=A0 struct Vec { int *p; }; =C2=A0// cannot be written out and =
"regenerated" later</div></div></div></div></blockquote><div><br>=
</div><div>Whether it can be done without code execution or not depends <i>=
entirely</i> on what `p` points to and how long the object will be persiste=
nt. If `p` points to a static object and the particular persistent instance=
of `Vec` will not be persistent across program executions, then it's f=
ine as is.<br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" styl=
e=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left:=
1ex;"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><div>=C2=A0 =C2=A0 =
struct MemFn { T *p; void (*f)(T); }; =C2=A0// cannot be written out and &q=
uot;regenerated" later</div><div>=C2=A0 =C2=A0 struct Poly { virtual v=
oid foo(); }; =C2=A0// cannot be written out and "regenerated" la=
ter</div><div><br></div><div>I definitely wouldn't worry about the thir=
d example until you've got something working-in-practice for the first =
two, simpler, examples.</div></div></div></div></blockquote><div><br></div>=
<div>But the third example is the easiest and the only one the compiler can=
actually do for you. And most important of all, the only one you <i>cannot=
</i> do for yourself.<br></div><div><br></div><blockquote class=3D"gmail_qu=
ote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padd=
ing-left: 1ex;"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><div></div=
><div><div style=3D"font-size:12.800000190734863px">> nobody is in any d=
oubt that these can be written and they work well on the major compilers.</=
div><div style=3D"font-size:12.800000190734863px">> What we are doing he=
re is figuring out how to=C2=A0<i>standardise</i>=C2=A0support for these so=
rts of library into the C++ standard. [...]</div><div style=3D"font-size:12=
..800000190734863px">> we need to improve the C++ object and lifetime mod=
el such that resorting to UB tricks is no longer necessary.</div></div><div=
><br></div><div>I think that's simply "std::bless should work for =
non-implicit-lifetime types," as suggested in the "Further Work&q=
uot; section of P0593,</div><div><a href=3D"http://www.open-std.org/jtc1/sc=
22/wg21/docs/papers/2018/p0593r2.html#direct-object-creation" target=3D"_bl=
ank" rel=3D"nofollow" onmousedown=3D"this.href=3D'http://www.google.com=
/url?q\x3dhttp%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22%2Fwg21%2Fdocs%2Fpaper=
s%2F2018%2Fp0593r2.html%23direct-object-creation\x26sa\x3dD\x26sntz\x3d1\x2=
6usg\x3dAFQjCNGDGvuHlKkmOQfJc2s0ONTA7x351A';return true;" onclick=3D"th=
is.href=3D'http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.open-std.org=
%2Fjtc1%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F2018%2Fp0593r2.html%23direct-object=
-creation\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGDGvuHlKkmOQfJc2s0ONTA7x3=
51A';return true;">http://www.open-std.org/jtc1/<wbr>sc22/wg21/docs/pap=
ers/2018/<wbr>p0593r2.html#direct-object-<wbr>creation</a> :<br></div><div>=
>=C2=A0<span style=3D"color:rgb(0,0,0);font-family:sans-serif;font-size:=
medium">a combined operation to create an object of implicit lifetime type =
in-place while preserving the object representation may be useful ...=C2=A0=
</span><span style=3D"color:rgb(0,0,0);font-family:sans-serif;font-size:med=
ium">we could imagine extending its semantics to also permit conversions wh=
ere each subobject of non-implicit-lifetime type in the destination corresp=
onds to an object of the same type (ignoring cv-qualifications) in the sour=
ce ...</span></div><div><br></div><div>All you need is a way to say "h=
ere are some bytes, please treat them as an object." =C2=A0Right now, =
everyone (including STL vendors) does that via reinterpret_cast, and it wor=
ks great, and it isn't going to break anytime soon (because all STL imp=
lementations depend on it).=C2=A0 Post-P0593-further-work, some people may =
switch to using reinterpret_cast plus std::bless, which will work equally g=
reat (modulo an initial crop of compiler bugs, I'm sure).=C2=A0 I don&#=
39;t think the UB-ness of reinterpret_cast is really the biggest blocker to=
getting persistent data structures into C++.</div></div></div></div></bloc=
kquote><div><br></div><div>You cannot standardize something if the object m=
odel says that its undefined behavior. You can't just say, "this h=
as behavior X and it's undefined behavior." That's a contradic=
tion.<br></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/a298811a-132e-42c5-979e-c02f9563a457%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/a298811a-132e-42c5-979e-c02f9563a457=
%40isocpp.org</a>.<br />
------=_Part_1545_1131684563.1533588189512--
------=_Part_1544_477866830.1533588189512--
.
Author: "Arthur O'Dwyer" <arthur.j.odwyer@gmail.com>
Date: Mon, 6 Aug 2018 15:15:38 -0700
Raw View
--000000000000119e410572cb9ea7
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
On Mon, Aug 6, 2018 at 1:43 PM, Nicol Bolas <jmckesson@gmail.com> wrote:
> On Monday, August 6, 2018 at 3:10:34 PM UTC-4, Arthur O'Dwyer wrote:
>>
>> On Mon, Aug 6, 2018 at 10:13 AM, Niall Douglas <nialldo...@gmail.com>
>> wrote:
>>
>>>
>>>>>> Trivial operation X simply means that the compiler can perform
>>> operation X entirely on its own, as frequently and infrequently as it s=
o
>>> chooses, including ignoring the programmer if it would be as-if the sam=
e.
>>> That's the meaning of triviality.
>>>
>>
>> I should point out that that is not *my* definition of triviality. My
>> definition of triviality is "as-if by memfoo." That is, for any given
>> operation on an object-in-memory (e.g. copying, e.g. relocation, e.g.
>> comparison, e.g. destruction, e.g. swapping) there is exactly one "trivi=
al"
>> implementation of that operation, which relies on absolutely nothing abo=
ut
>> the object's type except maybe its size.
>>
>
> This, exactly. This is what I think of when dealing with triviality.
>
> And note: types with virtuals are not trivially default constructible, no=
r
> are they Trivially Copyable. So the standard is at least partially in
> agreement with this notion.
>
Once you're talking about types with vptrs, you're definitely shading into
the area where "the Standard's notion of triviality" starts bifurcating
into many subtly different definitions that all happen to share the same
word. :/ I'm not a fan of the Standard's terminology in this area.
Default-constructing an object-with-a-vptr can be done without running any
user code, but is non-trivial by my definition and also non-trivial by the
Standard's (and I'm not sure about Niall's).
Copy-constructing an object-with-a-vptr is can be done without running any
user code, and is "trivial" by my definition, and by Niall's, but not by
the Standard's.
Destructing an object-with-a-vptr is "trivial" by all three definitions.
Destructing an object-with-a-virtual-destructor is "non-trivial" by all
three definitions.
I still don't see what you hope to achieve with "vptr modification." If a
>> persisted object contains native pointers, they *will not* point to the
>> correct place when reloaded, unless <a global property of the program is
>> carefully maintained by the programmer>. This applies to all kinds of
>> structs, not just vptrs.
>>
>
> That's true. But unlike pointer members of the object, you *can't* modify
> the vtable pointer. By "you", I mean "the user". Such things are the doma=
in
> of the compiler.
> So if you want to be able to persist polymorphic types, you *have to*
> have compiler involvement.
>
I still don't get it =E2=80=94 and now I'm even more confused as to what we=
're
talking about, after seeing all those serialization libraries that Niall
thought were related to persistence.
If you want to *serialize* a polymorphic object: awesome, just do it.
If you want to *deserialize* a polymorphic object: you'll be constructing a
new object on the fly, so you don't have to overwrite any vptrs or
anything. No UB here.
If you want to store a polymorphic object in *persistent memory*: awesome,
just do it. The library (e.g. PMDK) will take care of the persistence for
you.
If you want to access a polymorphic object in existing memory, without the
aid of any library to bless the pointer for you: adopt the "Further Work"
of P0593r2
<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0593r2.html#direc=
t-object-creation>
and call std::bless<T> on that memory.
If you want to construct a polymorphic object in existing memory, some of
whose bytes have the correct values and some of which have garbage values,
and you *do not know* the correct values for those bytes: well, that's
currently impossible, but if you think that's what you want to do, I'd
really like to see your use-case.
That's why I like thinking of persistence as a form of
> construction/destruction. When you construct a polymorphic type, it puts
> the vtable pointer in place. So when you unpack/whatever the value
> representation of a polymorphic type, that operation can likewise put the
> vtable pointer in place. And part of that operation should, just like
> object construction, allow you to execute whatever code you need for manu=
al
> fixup of any pointers.
>
This sounds like you're talking about serialization, not persistence. And
deserialization will construct new objects anyway (via placement new, or
regular new, or whatever). It never needs to rewrite vptrs. (Or, if I'm
wrong, please point to an existing line of code in a serialization library
that rewrites vptrs.)
struct Vec { int *p; }; // cannot be written out and "regenerated"
>> later
>>
>
> Whether it can be done without code execution or not depends *entirely*
> on what `p` points to and how long the object will be persistent. If `p`
> points to a static object and the particular persistent instance of `Vec`
> will not be persistent across program executions, then it's fine as is.
>
Right. And there are "less strongly typed" types, such as `std::pair<int,
int*>`, where you can't even hope to tell from the *type* of the object
what its runtime *behavior* will be like. But for a serialization library
(like, one that reads and writes save-game files), this is fine. The
programmer just never tries to serialize a `std::pair<int, int*>` *per se*.
All you need is a way to say "here are some bytes, please treat them as an
>> object." Right now, everyone (including STL vendors) does that via
>> reinterpret_cast, and it works great, and it isn't going to break anytim=
e
>> soon (because all STL implementations depend on it).
>> Post-P0593-further-work, some people may switch to using reinterpret_cas=
t
>> plus std::bless, which will work equally great (modulo an initial crop o=
f
>> compiler bugs, I'm sure). I don't think the UB-ness of reinterpret_cast=
is
>> really the biggest blocker to getting persistent data structures into C+=
+.
>>
>
> You cannot standardize something if the object model says that its
> undefined behavior. You can't just say, "this has behavior X and it's
> undefined behavior." That's a contradiction.
>
> Sure, philosophically speaking it might seem that way. But this model has
worked great for C++ for more than 20 years. People never tire of pointing
out that std::vector is unimplementable... that malloc() is
unimplementable... that std::async is unimplementable... that std::optional
is unimplementable... And yet, they're part of the standard library so that
working programmers can use them every single day *without worrying* about
how unimplementable they are!
All I'm saying is that step 1 should be to pick some "unimplementable, but
useful" semantics that would improve programmers' lives, and implement it.
And then step 2 should be to standardize that API into the library. And if
standardizing that API turns out to require some additional groundwork,
okay, cool... But this proposal seems to be trying to standardize *only
groundwork* in service of no actual library API.
=E2=80=93Arthur
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CADvuK0%2BCUrO9pcLTkn_KSk5qMAcJ%3D%2Bo0RxHM2DeDK=
Gy9F3cpVw%40mail.gmail.com.
--000000000000119e410572cb9ea7
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Mon, Aug 6, 2018 at 1:43 PM, Nicol Bolas <span dir=3D"l=
tr"><<a href=3D"mailto:jmckesson@gmail.com" target=3D"_blank">jmckesson@=
gmail.com</a>></span> wrote:<br><div class=3D"gmail_extra"><div class=3D=
"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px=
0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(=
204,204,204);padding-left:1ex"><div dir=3D"ltr">On Monday, August 6, 2018 a=
t 3:10:34 PM UTC-4, Arthur O'Dwyer wrote:<span class=3D"gmail-"><blockq=
uote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-wi=
dth:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-=
left:1ex"><div dir=3D"ltr">On Mon, Aug 6, 2018 at 10:13 AM, Niall Douglas <=
span dir=3D"ltr"><<a rel=3D"nofollow">nialldo...@gmail.com</a>></span=
> wrote:<br><div><div class=3D"gmail_quote"><blockquote class=3D"gmail_quot=
e" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-styl=
e:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><blockquote cl=
ass=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px=
;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1e=
x"><div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0=
px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-colo=
r:rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><blockquote class=3D"=
gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border=
-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div=
dir=3D"ltr"><div><div><br></div></div></div></blockquote></div></blockquot=
e></div></blockquote><div>Trivial operation X simply means that the compile=
r can perform operation X entirely on its own, as frequently and infrequent=
ly as it so chooses, including ignoring the programmer if it would be as-if=
the same. That's the meaning of triviality.=C2=A0</div></blockquote><d=
iv><br></div><div>I should point out that that is not <i>my</i> definition =
of triviality.=C2=A0 My definition of triviality is "as-if by memfoo.&=
quot; That is, for any given operation on an object-in-memory (e.g. copying=
, e.g. relocation, e.g. comparison, e.g. destruction, e.g. swapping) there =
is exactly one "trivial" implementation of that operation, which =
relies on absolutely nothing about the object's type except maybe its s=
ize.</div></div></div></div></blockquote><div><br></div></span><div>This, e=
xactly. This is what I think of when dealing with triviality.</div><div><br=
></div><div>And note: types with virtuals are not trivially default constru=
ctible, nor are they Trivially Copyable. So the standard is at least partia=
lly in agreement with this notion.</div></div></blockquote><div><br></div><=
div>Once you're talking about types with vptrs, you're definitely s=
hading into the area where "the Standard's notion of triviality&qu=
ot; starts bifurcating into many subtly different definitions that all happ=
en to share the same word. :/ =C2=A0I'm not a fan of the Standard's=
terminology in this area.</div><div><br></div><div>Default-constructing an=
object-with-a-vptr can be done without running any user code, but is non-t=
rivial by my definition and also non-trivial by the Standard's (and I&#=
39;m not sure about Niall's).</div><div>Copy-constructing an object-wit=
h-a-vptr is can be done without running any user code, and is "trivial=
" by my definition, and by Niall's, but not by the Standard's.=
</div><div>Destructing an object-with-a-vptr is "trivial" by all =
three definitions.</div><div><div>Destructing an object-with-a-virtual-dest=
ructor is "non-trivial" by all three definitions.</div></div><div=
><br></div><div><br></div><div><br></div><blockquote class=3D"gmail_quote" =
style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:s=
olid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr">=
<span class=3D"gmail-"><blockquote class=3D"gmail_quote" style=3D"margin:0p=
x 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-c=
olor:rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div><div class=3D=
"gmail_quote"><div>I still don't see what you hope to achieve with &quo=
t;vptr modification." If a persisted object contains native pointers, =
they <i>will not</i> point to the correct place when reloaded, unless <a=
global property of the program is carefully maintained by the programmer&g=
t;. This applies to all kinds of structs, not just vptrs.</div></div></div>=
</div></blockquote><div><br></div></span><div>That's true. But unlike p=
ointer members of the object, you <i>can't</i> modify the vtable pointe=
r. By "you", I mean "the user". Such things are the dom=
ain of the compiler.</div><div>So if you want to be able to persist polymor=
phic types, you <i>have to</i> have compiler involvement.</div></div></bloc=
kquote><div><br></div><div>I still don't get it =E2=80=94 and now I'=
;m even more confused as to what we're talking about, after seeing all =
those serialization libraries that Niall thought were related to persistenc=
e.</div><div><br></div><div>If you want to <i>serialize</i> a polymorphic o=
bject: awesome, just do it.</div><div><div>If you want to <i>deserialize</i=
> a polymorphic object: you'll be constructing a new object on the fly,=
so you don't have to overwrite any vptrs or anything. No UB here.</div=
></div><div><br></div><div><div>If you want to store a polymorphic object i=
n <i>persistent memory</i>: awesome, just do it. The library (e.g. PMDK) wi=
ll take care of the persistence for you.</div><div><div>If you want to acce=
ss a polymorphic object in existing=C2=A0memory, without the aid of any lib=
rary to bless the pointer for you: adopt <a href=3D"http://www.open-std.org=
/jtc1/sc22/wg21/docs/papers/2018/p0593r2.html#direct-object-creation">the &=
quot;Further Work" of P0593r2</a> and call std::bless<T> on that=
memory.</div><div><br></div><div>If you want to construct a polymorphic ob=
ject in existing memory, some of whose bytes have the correct values and so=
me of which have garbage values, and you <i>do not know</i> the correct val=
ues for those bytes: well, that's currently impossible, but if you thin=
k that's what you want to do, I'd really like to see your use-case.=
</div><div><br></div><div><br></div></div></div><blockquote class=3D"gmail_=
quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-=
style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir=
=3D"ltr"><div>That's why I like thinking of persistence as a form of co=
nstruction/destruction. When you construct a polymorphic type, it puts the =
vtable pointer in place. So when you unpack/whatever the value representati=
on of a polymorphic type, that operation can likewise put the vtable pointe=
r in place. And part of that operation should, just like object constructio=
n, allow you to execute whatever code you need for manual fixup of any poin=
ters.<br></div></div></blockquote><div><br></div><div>This sounds like you&=
#39;re talking about serialization, not persistence. And deserialization wi=
ll construct new objects anyway (via placement new, or regular new, or what=
ever). It never needs to rewrite vptrs. (Or, if I'm wrong, please point=
to an existing line of code in a serialization library that rewrites vptrs=
..)</div><div><br></div><div><br></div><div><br></div><blockquote class=3D"g=
mail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-=
left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div =
dir=3D"ltr"><div></div><span class=3D"gmail-"><blockquote class=3D"gmail_qu=
ote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-st=
yle:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir=3D"=
ltr"><div><div class=3D"gmail_quote"><div>=C2=A0 =C2=A0 struct Vec { int *p=
; }; =C2=A0// cannot be written out and "regenerated" later</div>=
</div></div></div></blockquote><div><br></div></span><div>Whether it can be=
done without code execution or not depends <i>entirely</i> on what `p` poi=
nts to and how long the object will be persistent. If `p` points to a stati=
c object and the particular persistent instance of `Vec` will not be persis=
tent across program executions, then it's fine as is.<br></div></div></=
blockquote><div><br></div><div>Right.=C2=A0 And there are "less strong=
ly typed" types, such as `std::pair<int, int*>`, where you can&#=
39;t even hope to tell from the <i>type</i> of the object what its runtime =
<i>behavior</i> will be like.=C2=A0 But for a serialization library (like, =
one that reads and writes save-game files), this is fine.=C2=A0 The program=
mer just never tries to serialize a `std::pair<int, int*>` <i>per se<=
/i>.</div><div><br></div><blockquote class=3D"gmail_quote" style=3D"margin:=
0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left=
-color:rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><span class=3D"g=
mail-"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;=
border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204=
,204);padding-left:1ex"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><d=
iv>All you need is a way to say "here are some bytes, please treat the=
m as an object." =C2=A0Right now, everyone (including STL vendors) doe=
s that via reinterpret_cast, and it works great, and it isn't going to =
break anytime soon (because all STL implementations depend on it).=C2=A0 Po=
st-P0593-further-work, some people may switch to using reinterpret_cast plu=
s std::bless, which will work equally great (modulo an initial crop of comp=
iler bugs, I'm sure).=C2=A0 I don't think the UB-ness of reinterpre=
t_cast is really the biggest blocker to getting persistent data structures =
into C++.</div></div></div></div></blockquote><div><br></div></span><div>Yo=
u cannot standardize something if the object model says that its undefined =
behavior. You can't just say, "this has behavior X and it's un=
defined behavior." That's a contradiction.<br></div></div><span cl=
ass=3D"gmail-">
<p></p>
</span></blockquote><div>Sure, philosophically speaking it might seem that =
way. But this model has worked great for C++ for more than 20 years. People=
never tire of pointing out that std::vector is unimplementable... that mal=
loc() is unimplementable... that std::async is unimplementable... that std:=
:optional is unimplementable... And yet, they're part of the standard l=
ibrary so that working programmers can use them every single day <i>without=
worrying</i> about how unimplementable they are!</div><div><br></div><div>=
All I'm saying is that step 1 should be to pick some "unimplementa=
ble, but useful" semantics that would improve programmers' lives, =
and implement it. And then step 2 should be to standardize that API into th=
e library. And if standardizing that API turns out to require some addition=
al groundwork, okay, cool... But this proposal seems to be trying to standa=
rdize <i>only groundwork</i> in service of no actual library API.</div><div=
><br></div><div>=E2=80=93Arthur</div></div></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CADvuK0%2BCUrO9pcLTkn_KSk5qMAcJ%3D%2B=
o0RxHM2DeDKGy9F3cpVw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoote=
r">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CADvuK0%2BC=
UrO9pcLTkn_KSk5qMAcJ%3D%2Bo0RxHM2DeDKGy9F3cpVw%40mail.gmail.com</a>.<br />
--000000000000119e410572cb9ea7--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Mon, 6 Aug 2018 18:33:42 -0700 (PDT)
Raw View
------=_Part_1670_1587939153.1533605622214
Content-Type: multipart/alternative;
boundary="----=_Part_1671_81080270.1533605622215"
------=_Part_1671_81080270.1533605622215
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
On Monday, August 6, 2018 at 6:15:42 PM UTC-4, Arthur O'Dwyer wrote:
>
> On Mon, Aug 6, 2018 at 1:43 PM, Nicol Bolas <jmck...@gmail.com=20
> <javascript:>> wrote:
>
>> On Monday, August 6, 2018 at 3:10:34 PM UTC-4, Arthur O'Dwyer wrote:
>>>
>>> On Mon, Aug 6, 2018 at 10:13 AM, Niall Douglas <nialldo...@gmail.com>=
=20
>>> wrote:
>>>
>>>>
>>>>>>> Trivial operation X simply means that the compiler can perform=20
>>>> operation X entirely on its own, as frequently and infrequently as it =
so=20
>>>> chooses, including ignoring the programmer if it would be as-if the sa=
me.=20
>>>> That's the meaning of triviality.=20
>>>>
>>>
>>> I should point out that that is not *my* definition of triviality. My=
=20
>>> definition of triviality is "as-if by memfoo." That is, for any given=
=20
>>> operation on an object-in-memory (e.g. copying, e.g. relocation, e.g.=
=20
>>> comparison, e.g. destruction, e.g. swapping) there is exactly one "triv=
ial"=20
>>> implementation of that operation, which relies on absolutely nothing ab=
out=20
>>> the object's type except maybe its size.
>>>
>>
>> This, exactly. This is what I think of when dealing with triviality.
>>
>> And note: types with virtuals are not trivially default constructible,=
=20
>> nor are they Trivially Copyable. So the standard is at least partially i=
n=20
>> agreement with this notion.
>>
>
> Once you're talking about types with vptrs, you're definitely shading int=
o=20
> the area where "the Standard's notion of triviality" starts bifurcating=
=20
> into many subtly different definitions that all happen to share the same=
=20
> word. :/ I'm not a fan of the Standard's terminology in this area.
>
> Default-constructing an object-with-a-vptr can be done without running an=
y=20
> user code, but is non-trivial by my definition and also non-trivial by th=
e=20
> Standard's (and I'm not sure about Niall's).
> Copy-constructing an object-with-a-vptr is can be done without running an=
y=20
> user code, and is "trivial" by my definition, and by Niall's, but not by=
=20
> the Standard's.
> Destructing an object-with-a-vptr is "trivial" by all three definitions.
>
Destructing an object-with-a-virtual-destructor is "non-trivial" by all=20
> three definitions.
>
>
>
> I still don't see what you hope to achieve with "vptr modification." If a=
=20
>>> persisted object contains native pointers, they *will not* point to the=
=20
>>> correct place when reloaded, unless <a global property of the program i=
s=20
>>> carefully maintained by the programmer>. This applies to all kinds of=
=20
>>> structs, not just vptrs.
>>>
>>
>> That's true. But unlike pointer members of the object, you *can't*=20
>> modify the vtable pointer. By "you", I mean "the user". Such things are =
the=20
>> domain of the compiler.
>> So if you want to be able to persist polymorphic types, you *have to*=20
>> have compiler involvement.
>>
>
> I still don't get it =E2=80=94 and now I'm even more confused as to what =
we're=20
> talking about, after seeing all those serialization libraries that Niall=
=20
> thought were related to persistence.
>
> If you want to *serialize* a polymorphic object: awesome, just do it.
> If you want to *deserialize* a polymorphic object: you'll be constructing=
=20
> a new object on the fly, so you don't have to overwrite any vptrs or=20
> anything. No UB here.
>
> If you want to store a polymorphic object in *persistent memory*:=20
> awesome, just do it. The library (e.g. PMDK) will take care of the=20
> persistence for you.
> If you want to access a polymorphic object in existing memory, without th=
e=20
> aid of any library to bless the pointer for you: adopt the "Further Work"=
=20
> of P0593r2=20
> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0593r2.html#dir=
ect-object-creation>=20
> and call std::bless<T> on that memory.
>
But that doesn't work. Even if `bless<T>` could take non-implicit lifetime=
=20
objects, it will *not* do vtable pointer fixup. And you need vtable fixup=
=20
because you might be doing that persistent access on a different process=20
with different addresses for its vtables and virtual functions.
Furthermore, even if `bless<T>` for polymorphic types worked, you would=20
have created a very limited idea. You're starting an object's lifetime in=
=20
some storage, and you're invoking code to do it. But that code cannot=20
include any user-defined code.
It'd be like having only default/copy/move constructors in C++, with any=20
user-defined code having to happen via two-phase construction. How is that=
=20
a good thing?
Things like that are why a top-down approach to memory model stuff is not=
=20
as good as a bottom-up one. With bottom-up, you have the ability to design=
=20
a real foundation for building higher-level functionality, rather than=20
building just enough low-level stuff for your arbitrary high-level=20
functionality.
We want low-level tools for users to build what works for them, not a=20
monolithic high-level tool with only enough low-level functionality to make=
=20
the specific high-level stuff we picked out. The latter kind of design=20
tends to lead to Stroustrup's "Remember the Vasa!" issues.
Holistic design starts at the bottom.
If you want to construct a polymorphic object in existing memory, some of=
=20
> whose bytes have the correct values and some of which have garbage values=
,=20
> and you *do not know* the correct values for those bytes: well, that's=20
> currently impossible, but if you think that's what you want to do, I'd=20
> really like to see your use-case.
>
>
> That's why I like thinking of persistence as a form of=20
>> construction/destruction. When you construct a polymorphic type, it puts=
=20
>> the vtable pointer in place. So when you unpack/whatever the value=20
>> representation of a polymorphic type, that operation can likewise put th=
e=20
>> vtable pointer in place. And part of that operation should, just like=20
>> object construction, allow you to execute whatever code you need for man=
ual=20
>> fixup of any pointers.
>>
>
> This sounds like you're talking about serialization, not persistence.
>
That is a matter of semantics and is essentially irrelevant. Persistence is=
=20
a form of serialization, so all persistence is serialization.
If you're going to define persistence as working only on objects whose=20
values are completely unmodified from the last time they were valid C++=20
objects to the next time they are (that is, no code execution of any kind),=
=20
then you can only deal with aggregates of non-pointer scalar types, period.=
=20
That's not the definition Niall wants to work with here, and I see no=20
reason why we should be so limited.
Aspects of that limitation will happen naturally (because such types do=20
have the logical advantage of not having to run code in order to persist=20
them), but by having a foundation to deal with persistence of objects of=20
types that require some in-situ work at persistence boundaries, you also=20
gain advantages when dealing which such "natural" types.
Here's what I mean. A struct holding an `int` could be implicitly=20
persisted. But what if that `int` happens to be a POSIX file descriptor?=20
Then persisting such an object implicitly needs to invoke UB, which means=
=20
you need to have persistence be part of the object model. You need to know=
=20
when you're persisting something, so that you can know that you've invoked=
=20
UB when you do it to objects that can't handle it. You also need a way to=
=20
determine when an object can't handle implicit persistence.
That all needs to be part of the object model to make even implicit=20
persistence work. Extending that slightly to allow customized persistence=
=20
on a per-object basis not only allows persistence of virtual types, but=20
also allows persistence of types with pointers in them. It allows users to=
=20
pass arbitrary context information so that they can choose how to package=
=20
their pointers. And so forth.
And deserialization will construct new objects anyway (via placement new,=
=20
> or regular new, or whatever). It never needs to rewrite vptrs. (Or, if I'=
m=20
> wrong, please point to an existing line of code in a serialization librar=
y=20
> that rewrites vptrs.)
>
I've been party to proprietary serialization systems that have done exactly=
=20
that. I described it earlier in the thread.
struct Vec { int *p; }; // cannot be written out and "regenerated"=20
>>> later
>>>
>>
>> Whether it can be done without code execution or not depends *entirely*=
=20
>> on what `p` points to and how long the object will be persistent. If `p`=
=20
>> points to a static object and the particular persistent instance of `Vec=
`=20
>> will not be persistent across program executions, then it's fine as is.
>>
>
> Right. And there are "less strongly typed" types, such as `std::pair<int=
,=20
> int*>`, where you can't even hope to tell from the *type* of the object=
=20
> what its runtime *behavior* will be like. But for a serialization=20
> library (like, one that reads and writes save-game files), this is fine. =
=20
> The programmer just never tries to serialize a `std::pair<int, int*>` *pe=
r=20
> se*.
>
> All you need is a way to say "here are some bytes, please treat them as a=
n=20
>>> object." Right now, everyone (including STL vendors) does that via=20
>>> reinterpret_cast, and it works great, and it isn't going to break anyti=
me=20
>>> soon (because all STL implementations depend on it). =20
>>> Post-P0593-further-work, some people may switch to using reinterpret_ca=
st=20
>>> plus std::bless, which will work equally great (modulo an initial crop =
of=20
>>> compiler bugs, I'm sure). I don't think the UB-ness of reinterpret_cas=
t is=20
>>> really the biggest blocker to getting persistent data structures into C=
++.
>>>
>>
>> You cannot standardize something if the object model says that its=20
>> undefined behavior. You can't just say, "this has behavior X and it's=20
>> undefined behavior." That's a contradiction.
>>
>> Sure, philosophically speaking it might seem that way. But this model ha=
s=20
> worked great for C++ for more than 20 years. People never tire of pointin=
g=20
> out that std::vector is unimplementable... that malloc() is=20
> unimplementable... that std::async is unimplementable... that std::option=
al=20
> is unimplementable... And yet, they're part of the standard library so th=
at=20
> working programmers can use them every single day *without worrying*=20
> about how unimplementable they are!
>
That basically makes the C++ standard a misnomer: the actual standard is=20
merely what compilers agree on. That's antithetical to the entire *purpose*=
=20
in having a standard.
I fail to see how that can be considered "working great".
Also, the point in raiding the issue of `std::vector` being unimplementable=
=20
is not really about `std::vector`. Implementations of the standard library,=
=20
since they're part of the C++ implementation, can do whatever they want so=
=20
long as they provide the required behavior. The problem is that *users*=20
cannot implement a type equivalent to `std::vector` without explicitly=20
relying on UB.
All I'm saying is that step 1 should be to pick some "unimplementable, but=
=20
> useful" semantics that would improve programmers' lives, and implement it=
..
>
That's not possible without doing it at the compiler level, because those=
=20
semantics cannot exist without the compiler's help.
And then step 2 should be to standardize that API into the library. And if=
=20
> standardizing that API turns out to require some additional groundwork,=
=20
> okay, cool... But this proposal seems to be trying to standardize *only=
=20
> groundwork* in service of no actual library API.
>
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/8966e1de-589f-4970-a8db-f0ab5b4fa8c1%40isocpp.or=
g.
------=_Part_1671_81080270.1533605622215
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Monday, August 6, 2018 at 6:15:42 PM UTC-4, Arthur O=
9;Dwyer wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-l=
eft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"=
>On Mon, Aug 6, 2018 at 1:43 PM, Nicol Bolas <span dir=3D"ltr"><<a href=
=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"Thss_AByDgAJ" r=
el=3D"nofollow" onmousedown=3D"this.href=3D'javascript:';return tru=
e;" onclick=3D"this.href=3D'javascript:';return true;">jmck...@gmai=
l.com</a>></span> wrote:<br><div><div class=3D"gmail_quote"><blockquote =
class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1=
px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:=
1ex"><div dir=3D"ltr">On Monday, August 6, 2018 at 3:10:34 PM UTC-4, Arthur=
O'Dwyer wrote:<span><blockquote class=3D"gmail_quote" style=3D"margin:=
0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left=
-color:rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr">On Mon, Aug 6, 2=
018 at 10:13 AM, Niall Douglas <span dir=3D"ltr"><<a rel=3D"nofollow">ni=
alldo...@gmail.com</a>></span> wrote:<br><div><div class=3D"gmail_quote"=
><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border=
-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);=
padding-left:1ex"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px=
0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:=
rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><blockquote class=3D"gm=
ail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-l=
eft-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div d=
ir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.=
8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204=
,204,204);padding-left:1ex"><div dir=3D"ltr"><div><div><br></div></div></di=
v></blockquote></div></blockquote></div></blockquote><div>Trivial operation=
X simply means that the compiler can perform operation X entirely on its o=
wn, as frequently and infrequently as it so chooses, including ignoring the=
programmer if it would be as-if the same. That's the meaning of trivia=
lity.=C2=A0</div></blockquote><div><br></div><div>I should point out that t=
hat is not <i>my</i> definition of triviality.=C2=A0 My definition of trivi=
ality is "as-if by memfoo." That is, for any given operation on a=
n object-in-memory (e.g. copying, e.g. relocation, e.g. comparison, e.g. de=
struction, e.g. swapping) there is exactly one "trivial" implemen=
tation of that operation, which relies on absolutely nothing about the obje=
ct's type except maybe its size.</div></div></div></div></blockquote><d=
iv><br></div></span><div>This, exactly. This is what I think of when dealin=
g with triviality.</div><div><br></div><div>And note: types with virtuals a=
re not trivially default constructible, nor are they Trivially Copyable. So=
the standard is at least partially in agreement with this notion.</div></d=
iv></blockquote><div><br></div><div>Once you're talking about types wit=
h vptrs, you're definitely shading into the area where "the Standa=
rd's notion of triviality" starts bifurcating into many subtly dif=
ferent definitions that all happen to share the same word. :/ =C2=A0I'm=
not a fan of the Standard's terminology in this area.</div><div><br></=
div><div>Default-constructing an object-with-a-vptr can be done without run=
ning any user code, but is non-trivial by my definition and also non-trivia=
l by the Standard's (and I'm not sure about Niall's).</div><div=
>Copy-constructing an object-with-a-vptr is can be done without running any=
user code, and is "trivial" by my definition, and by Niall's=
, but not by the Standard's.</div><div>Destructing an object-with-a-vpt=
r is "trivial" by all three definitions.</div></div></div></div><=
/blockquote><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><=
div><div class=3D"gmail_quote"><div><div>Destructing an object-with-a-virtu=
al-<wbr>destructor is "non-trivial" by all three definitions.</di=
v></div><div><br></div><div><br></div><div><br></div><blockquote class=3D"g=
mail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-=
left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div =
dir=3D"ltr"><span><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px=
0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:=
rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div><div class=3D"gmai=
l_quote"><div>I still don't see what you hope to achieve with "vpt=
r modification." If a persisted object contains native pointers, they =
<i>will not</i> point to the correct place when reloaded, unless <a glob=
al property of the program is carefully maintained by the programmer>. T=
his applies to all kinds of structs, not just vptrs.</div></div></div></div=
></blockquote><div><br></div></span><div>That's true. But unlike pointe=
r members of the object, you <i>can't</i> modify the vtable pointer. By=
"you", I mean "the user". Such things are the domain o=
f the compiler.</div><div>So if you want to be able to persist polymorphic =
types, you <i>have to</i> have compiler involvement.</div></div></blockquot=
e><div><br></div><div>I still don't get it =E2=80=94 and now I'm ev=
en more confused as to what we're talking about, after seeing all those=
serialization libraries that Niall thought were related to persistence.</d=
iv><div><br></div><div>If you want to <i>serialize</i> a polymorphic object=
: awesome, just do it.</div><div><div>If you want to <i>deserialize</i> a p=
olymorphic object: you'll be constructing a new object on the fly, so y=
ou don't have to overwrite any vptrs or anything. No UB here.</div></di=
v><div><br></div><div><div>If you want to store a polymorphic object in <i>=
persistent memory</i>: awesome, just do it. The library (e.g. PMDK) will ta=
ke care of the persistence for you.</div><div><div>If you want to access a =
polymorphic object in existing=C2=A0memory, without the aid of any library =
to bless the pointer for you: adopt <a href=3D"http://www.open-std.org/jtc1=
/sc22/wg21/docs/papers/2018/p0593r2.html#direct-object-creation" target=3D"=
_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D'http://www.google.=
com/url?q\x3dhttp%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22%2Fwg21%2Fdocs%2Fpa=
pers%2F2018%2Fp0593r2.html%23direct-object-creation\x26sa\x3dD\x26sntz\x3d1=
\x26usg\x3dAFQjCNGDGvuHlKkmOQfJc2s0ONTA7x351A';return true;" onclick=3D=
"this.href=3D'http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.open-std.=
org%2Fjtc1%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F2018%2Fp0593r2.html%23direct-obj=
ect-creation\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGDGvuHlKkmOQfJc2s0ONTA=
7x351A';return true;">the "Further Work" of P0593r2</a> and c=
all std::bless<T> on that memory.</div></div></div></div></div></div>=
</blockquote><div><br></div><div>But that doesn't work. Even if `bless&=
lt;T>` could take non-implicit lifetime objects, it will <i>not</i> do v=
table pointer fixup. And you need vtable fixup because you might be doing t=
hat persistent access on a different process with different addresses for i=
ts vtables and virtual functions.</div><div><br></div><div>Furthermore, eve=
n if `bless<T>` for polymorphic types worked, you would have created =
a very limited idea. You're starting an object's lifetime in some s=
torage, and you're invoking code to do it. But that code cannot include=
any user-defined code.</div><div><br></div><div>It'd be like having on=
ly default/copy/move constructors in C++, with any user-defined code having=
to happen via two-phase construction. How is that a good thing?<br></div><=
div><br></div><div>Things like that are why a top-down approach to memory m=
odel stuff is not as good as a bottom-up one. With bottom-up, you have the =
ability to design a real foundation for building higher-level functionality=
, rather than building just enough low-level stuff for your arbitrary high-=
level functionality.</div><div><br></div><div>We want low-level tools for u=
sers to build what works for them, not a monolithic high-level tool with on=
ly enough low-level functionality to make the specific high-level stuff we =
picked out. The latter kind of design tends to lead to Stroustrup's &qu=
ot;Remember the Vasa!" issues.</div><div><br></div><div>Holistic desig=
n starts at the bottom.<br></div><div><br></div><blockquote class=3D"gmail_=
quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;pa=
dding-left: 1ex;"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><div><di=
v><div></div><div>If you want to construct a polymorphic object in existing=
memory, some of whose bytes have the correct values and some of which have=
garbage values, and you <i>do not know</i> the correct values for those by=
tes: well, that's currently impossible, but if you think that's wha=
t you want to do, I'd really like to see your use-case.</div><div><br><=
/div><div><br></div></div></div><blockquote class=3D"gmail_quote" style=3D"=
margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;bord=
er-left-color:rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div>That=
's why I like thinking of persistence as a form of construction/destruc=
tion. When you construct a polymorphic type, it puts the vtable pointer in =
place. So when you unpack/whatever the value representation of a polymorphi=
c type, that operation can likewise put the vtable pointer in place. And pa=
rt of that operation should, just like object construction, allow you to ex=
ecute whatever code you need for manual fixup of any pointers.<br></div></d=
iv></blockquote><div><br></div><div>This sounds like you're talking abo=
ut serialization, not persistence.</div></div></div></div></blockquote><div=
><br></div><div>That is a matter of semantics and is essentially irrelevant=
.. Persistence is a form of serialization, so all persistence is serializati=
on.</div><div><br></div><div>If you're going to define persistence as w=
orking only on objects whose values are completely unmodified from the last=
time they were valid C++ objects to the next time they are (that is, no co=
de execution of any kind), then you can only deal with aggregates of non-po=
inter scalar types, period. That's not the definition Niall wants to wo=
rk with here, and I see no reason why we should be so limited.</div><div><b=
r></div><div>Aspects of that limitation will happen naturally (because such=
types do have the logical advantage of not having to run code in order to =
persist them), but by having a foundation to deal with persistence of objec=
ts of types that require some in-situ work at persistence boundaries, you a=
lso gain advantages when dealing which such "natural" types.</div=
><div><br></div><div>Here's what I mean. A struct holding an `int` coul=
d be implicitly persisted. But what if that `int` happens to be a POSIX fil=
e descriptor? Then persisting such an object implicitly needs to invoke UB,=
which means you need to have persistence be part of the object model. You =
need to know when you're persisting something, so that you can know tha=
t you've invoked UB when you do it to objects that can't handle it.=
You also need a way to determine when an object can't handle implicit =
persistence.</div><div><br></div><div></div><div>That all needs to be part =
of the object model to make even implicit persistence work. Extending that =
slightly to allow customized persistence on a per-object basis not only all=
ows persistence of virtual types, but also allows persistence of types with=
pointers in them. It allows users to pass arbitrary context information so=
that they can choose how to package their pointers. And so forth.<br></div=
><div><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin=
-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"lt=
r"><div><div class=3D"gmail_quote"><div>And deserialization will construct =
new objects anyway (via placement new, or regular new, or whatever). It nev=
er needs to rewrite vptrs. (Or, if I'm wrong, please point to an existi=
ng line of code in a serialization library that rewrites vptrs.)</div></div=
></div></div></blockquote><div><br></div><div>I've been party to propri=
etary serialization systems that have done exactly that. I described it ear=
lier in the thread.<br></div><div><br></div><blockquote class=3D"gmail_quot=
e" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;paddin=
g-left: 1ex;"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><div></div><=
div></div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8=
ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,=
204,204);padding-left:1ex"><div dir=3D"ltr"><div></div><span><blockquote cl=
ass=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px=
;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1e=
x"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><div>=C2=A0 =C2=A0 stru=
ct Vec { int *p; }; =C2=A0// cannot be written out and "regenerated&qu=
ot; later</div></div></div></div></blockquote><div><br></div></span><div>Wh=
ether it can be done without code execution or not depends <i>entirely</i> =
on what `p` points to and how long the object will be persistent. If `p` po=
ints to a static object and the particular persistent instance of `Vec` wil=
l not be persistent across program executions, then it's fine as is.<br=
></div></div></blockquote><div><br></div><div>Right.=C2=A0 And there are &q=
uot;less strongly typed" types, such as `std::pair<int, int*>`, =
where you can't even hope to tell from the <i>type</i> of the object wh=
at its runtime <i>behavior</i> will be like.=C2=A0 But for a serialization =
library (like, one that reads and writes save-game files), this is fine.=C2=
=A0 The programmer just never tries to serialize a `std::pair<int, int*&=
gt;` <i>per se</i>.</div><div><br></div><blockquote class=3D"gmail_quote" s=
tyle=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:so=
lid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><=
span><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;bo=
rder-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,2=
04);padding-left:1ex"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><div=
>All you need is a way to say "here are some bytes, please treat them =
as an object." =C2=A0Right now, everyone (including STL vendors) does =
that via reinterpret_cast, and it works great, and it isn't going to br=
eak anytime soon (because all STL implementations depend on it).=C2=A0 Post=
-P0593-further-work, some people may switch to using reinterpret_cast plus =
std::bless, which will work equally great (modulo an initial crop of compil=
er bugs, I'm sure).=C2=A0 I don't think the UB-ness of reinterpret_=
cast is really the biggest blocker to getting persistent data structures in=
to C++.</div></div></div></div></blockquote><div><br></div></span><div>You =
cannot standardize something if the object model says that its undefined be=
havior. You can't just say, "this has behavior X and it's unde=
fined behavior." That's a contradiction.<br></div></div><span>
<p></p>
</span></blockquote><div>Sure, philosophically speaking it might seem that =
way. But this model has worked great for C++ for more than 20 years. People=
never tire of pointing out that std::vector is unimplementable... that mal=
loc() is unimplementable... that std::async is unimplementable... that std:=
:optional is unimplementable... And yet, they're part of the standard l=
ibrary so that working programmers can use them every single day <i>without=
worrying</i> about how unimplementable they are!</div></div></div></div></=
blockquote><div><br></div><div>That basically makes the C++ standard a misn=
omer: the actual standard is merely what compilers agree on. That's ant=
ithetical to the entire <i>purpose</i> in having a standard.</div><div><br>=
</div><div>I fail to see how that can be considered "working great&quo=
t;.</div><div><br></div><div>Also, the point in raiding the issue of `std::=
vector` being unimplementable is not really about `std::vector`. Implementa=
tions of the standard library, since they're part of the C++ implementa=
tion, can do whatever they want so long as they provide the required behavi=
or. The problem is that <i>users</i> cannot implement a type equivalent to =
`std::vector` without explicitly relying on UB.<br></div><div><br></div><bl=
ockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border=
-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div class=
=3D"gmail_quote"><div></div><div>All I'm saying is that step 1 should b=
e to pick some "unimplementable, but useful" semantics that would=
improve programmers' lives, and implement it.</div></div></div></div><=
/blockquote><div><br></div><div>That's not possible without doing it at=
the compiler level, because those semantics cannot exist without the compi=
ler's help.<br></div><div><br></div><blockquote class=3D"gmail_quote" s=
tyle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-le=
ft: 1ex;"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><div>And then st=
ep 2 should be to standardize that API into the library. And if standardizi=
ng that API turns out to require some additional groundwork, okay, cool... =
But this proposal seems to be trying to standardize <i>only groundwork</i> =
in service of no actual library API.</div></div></div></div>
</blockquote></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/8966e1de-589f-4970-a8db-f0ab5b4fa8c1%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/8966e1de-589f-4970-a8db-f0ab5b4fa8c1=
%40isocpp.org</a>.<br />
------=_Part_1671_81080270.1533605622215--
------=_Part_1670_1587939153.1533605622214--
.
Author: Niall Douglas <nialldouglas14@gmail.com>
Date: Tue, 7 Aug 2018 01:41:17 -0700 (PDT)
Raw View
------=_Part_1745_1348028512.1533631277413
Content-Type: multipart/alternative;
boundary="----=_Part_1746_147494931.1533631277414"
------=_Part_1746_147494931.1533631277414
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
>
> Nobody is in any doubt that a serialisation library can be written which=
=20
>> works well on the major compilers. There are dozens to choose from. P102=
6 *A=20
>> call for a Data Persistence (iostream v2) study group* lists and=20
>> benchmarks some of them.
>>
>
> Do you mean=20
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1026r0.pdf page=
=20
> 3? It lists:
> - memcpy
> - bitsery <https://github.com/fraillt/bitsery#usage-example>
> - yas <https://github.com/niXman/yas#samples>
> - zpp <https://github.com/eyalz800/serializer#contents>
> - Cereal <https://uscilab.github.io/cereal/index.html>
> - Flatbuffers=20
> <https://google.github.io/flatbuffers/flatbuffers_guide_tutorial.html>
> - Boost.Serialization
> - std::stringstream
>
> These are all what I would call *serialization* libraries, yes. They're=
=20
> ways of taking an object of type T as input, and producing some kind of=
=20
> formatted string as output (maybe JSON, maybe XML, maybe some proprietary=
=20
> binary format), in a neatly reversible way.
>
For some of those e.g. Boost.Serialisation, you are correct.
For some others e.g. Flatbuffers, you are incorrect.
Those in the first category always make a copy. So, for some given C++=20
object X, a serialised edition of that object Y is created and that is what=
=20
is sent over the wire. As Nicol put it before, object Y is trivially=20
serialisable.
Those in the second category do not make a copy. So, for some given C++=20
object X, its serialised edition is the same object X, and that is what is=
=20
sent over the wire. One could call these "intrusively serialisable". This=
=20
approach almost always involves a reinterpret cast, plus relies on the=20
compiler dumping and reloading state around syscalls, which is both UB and=
=20
inefficient.
What I want to do at standards level sets aside everything in category one=
=20
for now. I also want to set aside most of what is in category two, for now.=
=20
I just want to get to being able to take a reasonably large subset of=20
possible C++ objects, and apply a transformation to them which:
1. Involves no memory copying.
2. Puts them into a state from which a live C++ object can be=20
reconstituted later.
3. Is sufficiently unambitious that it might actually be possible to get=
=20
this through the committee for C++ 23 without the compiler vendors vetoi=
ng=20
it.
=20
> Notably they do *not* involve the filesystem at all, and they do *not*=20
> involve the object model at all. Serialization is a completely value-spac=
e=20
> operation.
>
As a nitpick, all memory on a virtual memory kernel architecture involves=
=20
the filesystem. Memory *is* the filesystem. If you are not mapping a file,=
=20
you are mapping the swap file.
But assuming you meant something else, when we speak of filesystem, we=20
really mean "remote memory" which implies a DMA to remote storage. That can=
=20
be a network card, a NUMA node, or a storage device. All of which are=20
conceptually the same thing.
Let me put this another way: you don't bother serialising something unless=
=20
you need to serialise it. That non sequiter means that if your C++ object=
=20
can't be used as-is, you need to make a copy of it, or otherwise transform=
=20
it, into a form which can be used. The filesystem, like a network card, has=
=20
semantics incompatible with using some C++ objects without such a=20
transformation.
=20
>
> T someobj;
> std::string s =3D serialize(someobj, FMT_JSON); // or FMT_BINARY, sa=
me=20
> difference
> T otherobj =3D deserialize(s, FMT_JSON);
> assert(otherobj =3D=3D someobj); // more or less
>
> I say "more or less" because of course if `T` is `std::shared_ptr<U>`,=20
> then these libraries aren't going to make `otherobj =3D=3D someobj` in th=
e C++=20
> sense; they're going to allocate a new object for `otherobj` to point to.=
=20
> That's because that's their use-case. Their use-case is things like=20
> save-games =E2=80=94 things where the original objects don't need to *per=
sist* in=20
> any sense. These libraries are all about *serialization* (marshalling,=
=20
> pickling, stringification...). They don't have anything to do with=20
> *persistence*. They also do not rely on UB.
>
I am not including any of what you describe in what I am talking about=20
here. I am solely focusing on the zero-copy, zero-allocation,=20
zero-synchronisation subset. We need to get those sorted out before we can=
=20
usefully discuss an iostreams v2.=20
>
> =20
>
>> Intel's PMDK https://github.com/pmem/pmdk goes a step further, and=20
>> stores STL objects directly in persistent memory. It can use mapped kern=
el=20
>> cache memory in lieu of proper persistent memory. So again, nobody is in=
=20
>> any doubt that these can be written and they work well on the major=20
>> compilers.
>>
>
> PMDK is what I'm talking about when I say "*persistence*." I contend=20
> that PMDK is still fairly experimental, though; much more experimental th=
an=20
> any of the *serialization* libraries you listed above. Its API=20
> <http://pmem.io/2016/01/12/cpp-04.html> doesn't look anything like a=20
> JSON-serialization library, nor does it look anything like what's in your=
=20
> P1031R0=20
> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1031r0.pdf>.
>
Intel's PMDK is a reasonable first generation attempt at solving this=20
problem space. If C++ had non-UB support along the lines I described=20
earlier, and if it followed an intrusive design, I think it could be=20
greatly improved upon.
=20
>
> I observe that
> - *Serialization* is fundamentally value-semantic.
> - *Persistence* is fundamentally object-semantic.
>
=20
I still prefer my original phrasing that serialisation involves copies and=
=20
metadata above and beyond the actual objects themselves. And all that is to=
=20
be excluded from scope, for now.
Niall
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/74c34cc6-f384-44be-b47d-62560622a03e%40isocpp.or=
g.
------=_Part_1746_147494931.1533631277414
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bor=
der-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div cla=
ss=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0p=
x 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color=
:rgb(204,204,204);padding-left:1ex"><div>Nobody is in any doubt that a seri=
alisation library can be written which works well on the major compilers. T=
here are dozens to choose from. P1026=C2=A0<span style=3D"color:rgb(0,0,0);=
font-family:"Times New Roman";font-size:medium"><i>A call for a D=
ata Persistence (iostream v2) study group</i></span>=C2=A0lists and benchma=
rks some of them.</div></blockquote><div><br></div><div>Do you mean=C2=A0<a=
href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1026r0.pd=
f" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D'http:=
//www.google.com/url?q\x3dhttp%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22%2Fwg2=
1%2Fdocs%2Fpapers%2F2018%2Fp1026r0.pdf\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAF=
QjCNFN9vD2FYo-tcI7SxxBC6ovNRR7hg';return true;" onclick=3D"this.href=3D=
'http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.open-std.org%2Fjtc1%2F=
sc22%2Fwg21%2Fdocs%2Fpapers%2F2018%2Fp1026r0.pdf\x26sa\x3dD\x26sntz\x3d1\x2=
6usg\x3dAFQjCNFN9vD2FYo-tcI7SxxBC6ovNRR7hg';return true;">http://www.op=
en-std.org/<wbr>jtc1/sc22/wg21/docs/papers/<wbr>2018/p1026r0.pdf</a> page 3=
? It lists:</div><div>- memcpy</div><div>- <a href=3D"https://github.com/fr=
aillt/bitsery#usage-example" target=3D"_blank" rel=3D"nofollow" onmousedown=
=3D"this.href=3D'https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.c=
om%2Ffraillt%2Fbitsery%23usage-example\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAF=
QjCNHFCictr7cAgpiby0slJxAuw6GTkQ';return true;" onclick=3D"this.href=3D=
'https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Ffraillt%2Fb=
itsery%23usage-example\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHFCictr7cAgp=
iby0slJxAuw6GTkQ';return true;">bitsery</a></div><div>- <a href=3D"http=
s://github.com/niXman/yas#samples" target=3D"_blank" rel=3D"nofollow" onmou=
sedown=3D"this.href=3D'https://www.google.com/url?q\x3dhttps%3A%2F%2Fgi=
thub.com%2FniXman%2Fyas%23samples\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNF=
p9OwHE0QkH9CQVE4tRJDKKx5zmA';return true;" onclick=3D"this.href=3D'=
https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2FniXman%2Fyas%23s=
amples\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFp9OwHE0QkH9CQVE4tRJDKKx5zmA=
';return true;">yas</a></div><div>- <a href=3D"https://github.com/eyalz=
800/serializer#contents" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"=
this.href=3D'https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2=
Feyalz800%2Fserializer%23contents\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNE=
aw8qYEKuOvlacIVfbKypgO0WssQ';return true;" onclick=3D"this.href=3D'=
https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Feyalz800%2Fseria=
lizer%23contents\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEaw8qYEKuOvlacIVfb=
KypgO0WssQ';return true;">zpp</a></div><div>- <a href=3D"https://uscila=
b.github.io/cereal/index.html" target=3D"_blank" rel=3D"nofollow" onmousedo=
wn=3D"this.href=3D'https://www.google.com/url?q\x3dhttps%3A%2F%2Fuscila=
b.github.io%2Fcereal%2Findex.html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNE=
Wh30Hx6F240LRI9Iu-Me3pATJug';return true;" onclick=3D"this.href=3D'=
https://www.google.com/url?q\x3dhttps%3A%2F%2Fuscilab.github.io%2Fcereal%2F=
index.html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEWh30Hx6F240LRI9Iu-Me3pA=
TJug';return true;">Cereal</a></div><div>- <a href=3D"https://google.gi=
thub.io/flatbuffers/flatbuffers_guide_tutorial.html" target=3D"_blank" rel=
=3D"nofollow" onmousedown=3D"this.href=3D'https://www.google.com/url?q\=
x3dhttps%3A%2F%2Fgoogle.github.io%2Fflatbuffers%2Fflatbuffers_guide_tutoria=
l.html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEM4TzprQ-ZWJ2MlI1reKnNSQm-jA=
';return true;" onclick=3D"this.href=3D'https://www.google.com/url?=
q\x3dhttps%3A%2F%2Fgoogle.github.io%2Fflatbuffers%2Fflatbuffers_guide_tutor=
ial.html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEM4TzprQ-ZWJ2MlI1reKnNSQm-=
jA';return true;">Flatbuffers</a></div><div>- Boost.Serialization</div>=
<div>- std::stringstream</div><div><br></div><div>These are all what I woul=
d call <i>serialization</i> libraries, yes. They're ways of taking an o=
bject of type T as input, and producing some kind of formatted string as ou=
tput (maybe JSON, maybe XML, maybe some proprietary binary format), in a ne=
atly reversible way.</div></div></div></div></blockquote><div><br></div><di=
v>For some of those e.g. Boost.Serialisation, you are correct.</div><div><b=
r></div><div>For some others e.g. Flatbuffers, you are incorrect.</div><div=
><br></div><div>Those in the first category always make a copy. So, for som=
e given C++ object X, a serialised edition of that object Y is created and =
that is what is sent over the wire. As Nicol put it before, object Y is tri=
vially serialisable.</div><div><br></div><div>Those in the second category =
do not make a copy. So, for some given C++ object X, its serialised edition=
is the same object X, and that is what is sent over the wire. One could ca=
ll these "intrusively serialisable". This approach almost always =
involves a reinterpret cast, plus relies on the compiler dumping and reload=
ing state around syscalls, which is both UB and inefficient.</div><div><br>=
</div><div>What I want to do at standards level sets aside everything in ca=
tegory one for now. I also want to set aside most of what is in category tw=
o, for now. I just want to get to being able to take a reasonably large sub=
set of possible C++ objects, and apply a transformation to them which:</div=
><div><ol><li>Involves no memory copying.</li><li>Puts them into a state fr=
om which a live C++ object can be reconstituted later.</li><li>Is sufficien=
tly unambitious that it might actually be possible to get this through the =
committee for C++ 23 without the compiler vendors vetoing it.</li></ol></di=
v><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D=
"ltr"><div><div class=3D"gmail_quote"><div> Notably they do <i>not</i> invo=
lve the filesystem at all, and they do <i>not</i> involve the object model =
at all. Serialization is a completely value-space operation.</div></div></d=
iv></div></blockquote><div><br></div><div>As a nitpick, all memory on a vir=
tual memory kernel architecture involves the filesystem. Memory=C2=A0<i>is<=
/i>=C2=A0the filesystem. If you are not mapping a file, you are mapping the=
swap file.</div><div><br></div><div>But assuming you meant something else,=
when we speak of filesystem, we really mean "remote memory" whic=
h implies a DMA to remote storage. That can be a network card, a NUMA node,=
or a storage device. All of which are conceptually the same thing.</div><d=
iv><br></div><div>Let me put this another way: you don't bother seriali=
sing something unless you need to serialise it. That non sequiter means tha=
t if your C++ object can't be used as-is, you need to make a copy of it=
, or otherwise transform it, into a form which can be used. The filesystem,=
like a network card, has semantics incompatible with using some C++ object=
s without such a transformation.</div><div>=C2=A0</div><blockquote class=3D=
"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc s=
olid;padding-left: 1ex;"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><=
div><br></div><div>=C2=A0 =C2=A0 T someobj;</div><div>=C2=A0 =C2=A0 std::st=
ring s =3D serialize(someobj, FMT_JSON); =C2=A0// or FMT_BINARY, same diffe=
rence</div><div>=C2=A0 =C2=A0 T otherobj =3D deserialize(s, FMT_JSON);</div=
><div>=C2=A0 =C2=A0 assert(otherobj =3D=3D someobj); =C2=A0// more or less<=
/div><div><br></div><div>I say "more or less" because of course i=
f `T` is `std::shared_ptr<U>`, then these libraries aren't going =
to make `otherobj =3D=3D someobj` in the C++ sense; they're going to al=
locate a new object for `otherobj` to point to. That's because that'=
;s their use-case. Their use-case is things like save-games =E2=80=94 thing=
s where the original objects don't need to <i>persist</i> in any sense.=
=C2=A0 These libraries are all about <i>serialization</i>=C2=A0(marshalling=
, pickling, stringification...).=C2=A0 They don't have anything to do w=
ith <i>persistence</i>.=C2=A0 They also do not rely on UB.</div></div></div=
></div></blockquote><div><br></div><div>I am not including any of what you =
describe in what I am talking about here. I am solely focusing on the zero-=
copy, zero-allocation, zero-synchronisation subset. We need to get those so=
rted out before we can usefully discuss an iostreams v2.=C2=A0</div><blockq=
uote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-lef=
t: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div class=3D"g=
mail_quote"><div><br></div><div>=C2=A0</div><blockquote class=3D"gmail_quot=
e" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-styl=
e:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div></div><di=
v>Intel's PMDK=C2=A0<a href=3D"https://github.com/pmem/pmdk" target=3D"=
_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D'https://www.google=
..com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fpmem%2Fpmdk\x26sa\x3dD\x26sntz\x3d=
1\x26usg\x3dAFQjCNHyZ6-HN-lzKhfTMuj6Nm7vyKk-kQ';return true;" onclick=
=3D"this.href=3D'https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.c=
om%2Fpmem%2Fpmdk\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHyZ6-HN-lzKhfTMuj6=
Nm7vyKk-kQ';return true;">https://github.com/pmem/<wbr>pmdk</a> goes a =
step further, and stores STL objects directly in persistent memory. It can =
use mapped kernel cache memory in lieu of proper persistent memory. So agai=
n, nobody is in any doubt that these can be written and they work well on t=
he major compilers.</div></blockquote><div><br></div><div>PMDK is what I=
9;m talking about when I say "<i>persistence</i>." =C2=A0I conten=
d that PMDK is still fairly experimental, though; much more experimental th=
an any of the <i>serialization</i> libraries you listed above. =C2=A0<a hre=
f=3D"http://pmem.io/2016/01/12/cpp-04.html" target=3D"_blank" rel=3D"nofoll=
ow" onmousedown=3D"this.href=3D'http://www.google.com/url?q\x3dhttp%3A%=
2F%2Fpmem.io%2F2016%2F01%2F12%2Fcpp-04.html\x26sa\x3dD\x26sntz\x3d1\x26usg\=
x3dAFQjCNEAguOI1Jx006vlBLwlqNQOxtTKzg';return true;" onclick=3D"this.hr=
ef=3D'http://www.google.com/url?q\x3dhttp%3A%2F%2Fpmem.io%2F2016%2F01%2=
F12%2Fcpp-04.html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEAguOI1Jx006vlBLw=
lqNQOxtTKzg';return true;">Its API</a> doesn't look anything like a=
JSON-serialization library, nor does it look anything like what's in y=
our <a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p103=
1r0.pdf" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D'=
;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22=
%2Fwg21%2Fdocs%2Fpapers%2F2018%2Fp1031r0.pdf\x26sa\x3dD\x26sntz\x3d1\x26usg=
\x3dAFQjCNH9wYoik4DN8tUhSSCjOkD6CvP9XA';return true;" onclick=3D"this.h=
ref=3D'http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.open-std.org%2Fj=
tc1%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F2018%2Fp1031r0.pdf\x26sa\x3dD\x26sntz\x=
3d1\x26usg\x3dAFQjCNH9wYoik4DN8tUhSSCjOkD6CvP9XA';return true;">P1031R0=
</a>.</div></div></div></div></blockquote><div><br></div><div>Intel's P=
MDK is a reasonable first generation attempt at solving this problem space.=
If C++ had non-UB support along the lines I described earlier, and if it f=
ollowed an intrusive design, I think it could be greatly improved upon.</di=
v><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D=
"ltr"><div><div class=3D"gmail_quote"><div><br></div><div>I observe that</d=
iv><div>- <i>Serialization</i> is fundamentally value-semantic.</div><div>-=
<i>Persistence</i> is fundamentally object-semantic.</div></div></div></di=
v></blockquote><div>=C2=A0</div><div>I still prefer my original phrasing th=
at serialisation involves copies and metadata above and beyond the actual o=
bjects themselves. And all that is to be excluded from scope, for now.</div=
><div><br></div><div>Niall</div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/74c34cc6-f384-44be-b47d-62560622a03e%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/74c34cc6-f384-44be-b47d-62560622a03e=
%40isocpp.org</a>.<br />
------=_Part_1746_147494931.1533631277414--
------=_Part_1745_1348028512.1533631277413--
.
Author: Niall Douglas <nialldouglas14@gmail.com>
Date: Tue, 7 Aug 2018 01:58:41 -0700 (PDT)
Raw View
------=_Part_533_1209461885.1533632321969
Content-Type: multipart/alternative;
boundary="----=_Part_534_1703320353.1533632321969"
------=_Part_534_1703320353.1533632321969
Content-Type: text/plain; charset="UTF-8"
>
>
> And note: types with virtuals are not trivially default constructible, nor
> are they Trivially Copyable. So the standard is at least partially in
> agreement with this notion.
>
Fair enough. What we really need is a new standards term for operations
which are not expensive and the compiler can do on its own. I'll see what I
can do on that.
>
>> If the compiler can trivially reduce, copy and regenerate on its own,
>>> that's still trivial by definition. It's also optimisable, so if the
>>> compiler knows that nothing will modify the bytes between the reduction and
>>> regeneration, it can optimise out say vptr modification and just use
>>> straight memcpy.
>>>
>>
>> I still don't see what you hope to achieve with "vptr modification." If a
>> persisted object contains native pointers, they *will not* point to the
>> correct place when reloaded, unless <a global property of the program is
>> carefully maintained by the programmer>. This applies to all kinds of
>> structs, not just vptrs.
>>
>
> That's true. But unlike pointer members of the object, you *can't* modify
> the vtable pointer. By "you", I mean "the user". Such things are the domain
> of the compiler.
>
> So if you want to be able to persist polymorphic types, you *have to*
> have compiler involvement.
>
It's not like this is hard for the compiler if the type is known to it.
Every time you construct an object, the compiler statically writes its
vptr. I've certainly written vptr restamping code in the past which simply
pokes the vptr with its new "correct" value (since C++ 11, you need to use
a seq_cst atomic, otherwise the compiler unhelpfully reorders the restamp
with respect to other operations on the object).
>
> That's why I like thinking of persistence as a form of
> construction/destruction. When you construct a polymorphic type, it puts
> the vtable pointer in place. So when you unpack/whatever the value
> representation of a polymorphic type, that operation can likewise put the
> vtable pointer in place. And part of that operation should, just like
> object construction, allow you to execute whatever code you need for manual
> fixup of any pointers.
>
I'm almost tempted, actually, to split object construction/destruction into
two parts: the compiler defined part, and the user defined part. We'd be
effectively opening up the compiler defined part to user customisation
which isn't possible right now. This could also give a universal solution
to bless().
If you like the idea, what syntax would be best?
Niall
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/49ba21e5-6e65-405c-877e-7a4ae005c3a5%40isocpp.org.
------=_Part_534_1703320353.1533632321969
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"l=
tr"><div><br></div><div>And note: types with virtuals are not trivially def=
ault constructible, nor are they Trivially Copyable. So the standard is at =
least partially in agreement with this notion.<br></div></div></blockquote>=
<div><br></div><div>Fair enough. What we really need is a new standards ter=
m for operations which are not expensive and the compiler can do on its own=
.. I'll see what I can do on that.</div><div>=C2=A0</div><blockquote cla=
ss=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #=
ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div></div><blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><di=
v><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0=
..8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(20=
4,204,204);padding-left:1ex"><div></div><div>If the compiler can trivially =
reduce, copy and regenerate on its own, that's still trivial by definit=
ion. It's also optimisable, so if the compiler knows that nothing will =
modify the bytes between the reduction and regeneration, it can optimise ou=
t say vptr modification and just use straight memcpy.</div></blockquote><di=
v><br></div><div>I still don't see what you hope to achieve with "=
vptr modification." If a persisted object contains native pointers, th=
ey <i>will not</i> point to the correct place when reloaded, unless <a g=
lobal property of the program is carefully maintained by the programmer>=
.. This applies to all kinds of structs, not just vptrs.</div></div></div></=
div></blockquote><div><br></div><div>That's true. But unlike pointer me=
mbers of the object, you <i>can't</i> modify the vtable pointer. By &qu=
ot;you", I mean "the user". Such things are the domain of th=
e compiler.</div><div><br></div><div>So if you want to be able to persist p=
olymorphic types, you <i>have to</i> have compiler involvement.</div></div>=
</blockquote><div><br></div><div>It's not like this is hard for the com=
piler if the type is known to it. Every time you construct an object, the c=
ompiler statically writes its vptr. I've certainly written vptr restamp=
ing code in the past which simply pokes the vptr with its new "correct=
" value (since C++ 11, you need to use a seq_cst atomic, otherwise the=
compiler unhelpfully reorders the restamp with respect to other operations=
on the object).</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" st=
yle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-lef=
t: 1ex;"><div dir=3D"ltr"><div><br></div><div>That's why I like thinkin=
g of persistence as a form of construction/destruction. When you construct =
a polymorphic type, it puts the vtable pointer in place. So when you unpack=
/whatever the value representation of a polymorphic type, that operation ca=
n likewise put the vtable pointer in place. And part of that operation shou=
ld, just like object construction, allow you to execute whatever code you n=
eed for manual fixup of any pointers.</div></div></blockquote><div><br></di=
v><div>I'm almost tempted, actually, to split object construction/destr=
uction into two parts: the compiler defined part, and the user defined part=
.. We'd be effectively opening up the compiler defined part to user cust=
omisation which isn't possible right now. This could also give a univer=
sal solution to bless().</div><div><br></div><div>If you like the idea, wha=
t syntax would be best?</div><div><br></div><div>Niall</div><div><br></div>=
</div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/49ba21e5-6e65-405c-877e-7a4ae005c3a5%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/49ba21e5-6e65-405c-877e-7a4ae005c3a5=
%40isocpp.org</a>.<br />
------=_Part_534_1703320353.1533632321969--
------=_Part_533_1209461885.1533632321969--
.
Author: florian.csdt@gmail.com
Date: Tue, 7 Aug 2018 02:09:10 -0700 (PDT)
Raw View
------=_Part_1862_569714722.1533632950890
Content-Type: multipart/alternative;
boundary="----=_Part_1863_1624703918.1533632950890"
------=_Part_1863_1624703918.1533632950890
Content-Type: text/plain; charset="UTF-8"
I'm not sure to fully understand, but I have the impression that persisting
polymorphic objects in the unbounded case without adding any extra
information is impossible.
What do you mean when say persisting a polymorphic object?
struct Base { virtual void foo(); };
struct Derived { void foo() override; };
Base* derived = /* allocate on persistent storage as Derived */;
/* persist derived object (as Base?) */
Do you want to be able to "unpersist" the derived object as a Base, or
directly as a Derived because you know somehow it was actually Derived (and
not a class derived from Derived)?
If you mean the latter, then there is no problem, but it might not be that
useful.
If you mean the former, then I don't see how it can be done without any
extra information.
If you mean something else, please correct me.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/e7a0139f-911a-4e40-aba4-71f4fbfa6c53%40isocpp.org.
------=_Part_1863_1624703918.1533632950890
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">I'm not sure to fully understand, but I have the impre=
ssion that=20
persisting polymorphic objects in the unbounded case without adding any=20
extra information is impossible.<br><br>What do you mean when say persistin=
g a polymorphic object?<br><br><div style=3D"background-color: rgb(250, 250=
, 250); border-color: rgb(187, 187, 187); border-style: solid; border-width=
: 1px; overflow-wrap: break-word;" class=3D"prettyprint"><code class=3D"pre=
ttyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;" class=
=3D"styled-by-prettify">struct</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> </span><span style=3D"color: #606;" class=3D"styled-by=
-prettify">Base</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
style=3D"color: #008;" class=3D"styled-by-prettify">virtual</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">void</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> foo</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">();</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">};</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>struct</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #606;" class=3D"styled-by-prettify">Derived</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">void</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> foo</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">()</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">override</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">};</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span><span sty=
le=3D"color: #606;" class=3D"styled-by-prettify">Base</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">*</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> derived </span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #800;" class=3D"sty=
led-by-prettify">/* allocate on persistent storage as Derived */</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span><span style=
=3D"color: #800;" class=3D"styled-by-prettify">/* persist derived object (a=
s Base?) */</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
><br></span></div></code></div><br>Do you want to be able to "unpersis=
t" the derived object as a Base, or directly as a Derived because you =
know somehow it was actually Derived (and not a class derived from Derived)=
?<br><br>If you mean the latter, then there is no problem, but it might not=
be that useful.<br>If you mean the former, then I don't see how it can=
be done without any extra information.<br><br>If you mean something else, =
please correct me.<br></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/e7a0139f-911a-4e40-aba4-71f4fbfa6c53%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/e7a0139f-911a-4e40-aba4-71f4fbfa6c53=
%40isocpp.org</a>.<br />
------=_Part_1863_1624703918.1533632950890--
------=_Part_1862_569714722.1533632950890--
.
Author: Niall Douglas <nialldouglas14@gmail.com>
Date: Tue, 7 Aug 2018 10:35:24 -0700 (PDT)
Raw View
------=_Part_1988_1274411854.1533663324576
Content-Type: multipart/alternative;
boundary="----=_Part_1989_944490659.1533663324576"
------=_Part_1989_944490659.1533663324576
Content-Type: text/plain; charset="UTF-8"
On Tuesday, August 7, 2018 at 10:09:11 AM UTC+1, floria...@gmail.com wrote:
>
> I'm not sure to fully understand, but I have the impression that
> persisting polymorphic objects in the unbounded case without adding any
> extra information is impossible.
>
> What do you mean when say persisting a polymorphic object?
>
Final types only.
Niall
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/54f98214-d02e-4bb2-bfa9-0b7cf1cf9772%40isocpp.org.
------=_Part_1989_944490659.1533663324576
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Tuesday, August 7, 2018 at 10:09:11 AM UTC+1, floria...=
@gmail.com wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"l=
tr">I'm not sure to fully understand, but I have the impression that=20
persisting polymorphic objects in the unbounded case without adding any=20
extra information is impossible.<br><br>What do you mean when say persistin=
g a polymorphic object?<br></div></blockquote><div><br></div><div>Final typ=
es only.</div><div><br></div><div>Niall=C2=A0</div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/54f98214-d02e-4bb2-bfa9-0b7cf1cf9772%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/54f98214-d02e-4bb2-bfa9-0b7cf1cf9772=
%40isocpp.org</a>.<br />
------=_Part_1989_944490659.1533663324576--
------=_Part_1988_1274411854.1533663324576--
.
Author: Vinnie Falco <vinnie.falco@gmail.com>
Date: Tue, 7 Aug 2018 16:09:32 -0700 (PDT)
Raw View
------=_Part_2028_1748701363.1533683372513
Content-Type: multipart/alternative;
boundary="----=_Part_2029_1857532943.1533683372513"
------=_Part_2029_1857532943.1533683372513
Content-Type: text/plain; charset="UTF-8"
On Friday, August 3, 2018 at 1:41:44 PM UTC-7, Nicol Bolas wrote:
>
> Well, we could just... not have coroutines ;)
>
Somewhat related, I need someone who is an expert at working on Clang and
LLVM to help me implement a new form of suspend-down coroutines (doesn't
have to be in time for San Diego). Please reach out to me if you are able
to help or know someone who can.
Thanks
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/2763eee5-3885-4dc5-83d9-4339eff100bf%40isocpp.org.
------=_Part_2029_1857532943.1533683372513
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Friday, August 3, 2018 at 1:41:44 PM UTC-7, Nicol Bolas=
wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.=
8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>W=
ell, we could just... not have coroutines ;) <br></div></div></blockquote><=
div><br></div><div>Somewhat related, I need someone who is an expert at wor=
king on Clang and LLVM to help me implement a new form of suspend-down coro=
utines (doesn't have to be in time for San Diego). Please reach out to =
me if you are able to help or know someone who can.</div><div><br>Thanks<br=
><br></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/2763eee5-3885-4dc5-83d9-4339eff100bf%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/2763eee5-3885-4dc5-83d9-4339eff100bf=
%40isocpp.org</a>.<br />
------=_Part_2029_1857532943.1533683372513--
------=_Part_2028_1748701363.1533683372513--
.
Author: Magnus Fromreide <magfr@lysator.liu.se>
Date: Mon, 24 Sep 2018 22:18:47 +0200
Raw View
On Fri, Aug 03, 2018 at 06:41:59PM -0400, Tom Honermann wrote:
>
> More fine.=C2=A0 detach / attach.=C2=A0 These correlate with existing mem=
ory mapping
> terminology as exhibited by shmdt() and shmat().
If this proposal will allow only one user of an object at any time with ext=
ra
baggage beeing required in order to shift the use to another concurrently
running process then I think the similarity to shm* is bad.
One use case for shared meory is as a read-only preloaded cache of things
and that might very well be readonly so it could be used by multiple procee=
ses
simultaneously.
/MF
> Detach is also used by
> std::thread though.
>=20
> Tom.
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/20180924201846.GA22618%40noemi.bahnhof.se.
.