1 Introduction

eXtensible Business Reporting Language (“XBRL”) is the latest and greatest method of representing financial information in structured format. The use of XBRL is steadily expanding allover the world, and it is becoming the standard method of exchanging financial reports.

This material is a collection of notes on XBRL put together to provide a basic understanding of what is XBRL, what it does, and how it is implemented.

Parts of this material depends heavily, and refers to the XBRL Taxonomy Development Handbook (“TDH”) published by XBRL US and publicly available on the their website. The TDH was created as a guide for creating XBRL taxonomies based on XBRL US experience, which makes it a very valuable resource for anyone or organization interested in the implementation of XBRL.

2 Objectives of this material

This material should provide:

  • Basic understanding of XBRL and its components.
  • Familiarity with core XBRL terminology.
  • Basic understanding of XBRL Taxonomy and instance document.
  • Basic understanding of the process of development of an XBRL taxonomy.
  • Understanding the ecosystem of structured financial reporting and the supporting technologies.

Presentation that goes with this material can be accessed here

3 Why XBRL and what is it exactly?

XBRL stands for eXtensible Business Reporting Language, XBRL international defines XBRL as:

XBRL provides a language in which reporting terms can be authoritatively defined. Those terms can then be used to uniquely represent the contents of financial statements or other kinds of compliance, performance and business reports. XBRL lets reporting information move between organizations rapidly, accurately and digitally.

3.1 Data and Regulatory Reporting

The increase complexity of transactions, regulatory requirements, and volumes of data derives the need for more efficient and structured methods to handle data and convert it into a resource rather than a burden.

Regulatory Data over time

Data over time

How do we collect financial data

Regulatory Reporting

Regulatory Reporting

The methods and processes of financial data collection evolved over time, we started with paper based submissions, then spreadsheets and flat files were used, then electronic submissions through web based portals. XBRL is the next newest thing in this evolution, benefits of XBRL can be summarized as follows:

What XBRL Provides

What XBRL Provides

  • XBRL provides for a stable structure of the data content.
  • XBRL separates data content from the form of the submission.
  • XBRL Provides for automation, which increases accuracy, cost and time savings.

And many more benefits relating to the quality and richness of data.

3.1.1 Current issues that XBRL addresses

General Issues:

  • Machine Readable: reports with XBRL tagging can be consumed and analyzed by computers through XBRL enabled software (XBRL Processors) as opposed to paper based or unstructured reports.
  • Interoperability: XBRL is self-describing and uses XML syntax which makes the information in XBRL format system independent, in other words, the same XBRL information package can be consumed by any system that has XBRL enabled software, which addresses compatibility issues.
  • It provides for a common set of rules that can be used in exchanging any financial information, hence it provides a common language for exchanging data, addressing comparability issues.
  • XBRL provides for automated means of compiling, transmitting, validating and analyzing financial data, which increase efficiency, time and cost saving and at the same time increasing quality of data.
  • XBRL provides high quality, contextually rich financial data rather than fragmented data.
  • XBRL is free and opensource standard, with no licensing fees, addresses issues of propitiatory standards and software, it should be noted that XBRL enabled software is not free.

Regulator Issues:

  • High volumes of data and reports: as mentioned, XBRL provides for automation in collecting and processing data, which facilitates handling large volumes of data in an accurate and efficient manner.
  • Review and validation: XBRL gives financial reports a structure that enables creation of validation rules based on regulations, business rules and any other criteria, and that in turn enables quick corrective action to be taken when needed.
  • Data can be stored for cross checking and further analysis and comparison.
  • Single source of the truth, XBRL structure allows data to be used for many purposes, for example, same report can contain data structures required for a regulator, census, taxes …

Issuer Issues:

  • Simplifies the compilation of reports required by multiple regulators from the same dataset.
  • XBRL taxonomies and the related guides issued by regulators provide for clear and unambiguous reporting requirements, and simplifies compliance.
  • Reduces the chance of costly errors.

3.2 Who uses XBRL?

The XBRL Taxonomy Development Handbook in page 6 lists successful implementation of XBRL around the worlds, that includes:

  • United States: Stock exchange commission (SEC), and Financial Depository Insurance Corporation (FDIC) with total reporting entities of over 17,500

  • United Kingdom: Her Majesty’s Revenues & Customs (HMRC), and Companies House with reporting entities of over 2 million

  • Spain: Business Registrar, Banking Regulator, Securities Regulation, Accounting Oversight and State Federal Comptroller with reporting entities of over 800,000

  • Others: Europe (European Single Electronic Format ESEF), India, Singapore, South Korea, Italy, Peru, World bank and many others

  • Governments and government agencies allover the world are using XBRL, countries like Netherlands and Australia implemented Standard Business Reporting (SBR) programs which are programs designed to reduce regulatory burden for businesses and relies heavily on XBRL.

Currently XBRL international website lists more than 20 XBRL jurisdictions (a jurisdiction is a local representative for XBRL acting as the primary liaison to national government, technology firms and business communities), following are some of the regulators implemented or in the process of implementing XBRL:

Some of the Regulators using XBRL

Some of the Regulators using XBRL

3.2.1 XBRL Implementations Map

XBRL website presents a map and listing for XBRL implementation projects world wide that can be accessed here

Why XBRL? In short, it addresses most current issues relating to exchange of financial data, it is widely used allover the world, and it is simply the next step in the evolution of financial data exchange systems.

3.3 What is Extensible Business Reporting Language (XBRL)?

The Specifications
Technically XBRL is based on XML (eXtensible Markup Language), it can be said that XBRL is an XML extension optimized to deal with business information. In other words, XBRL does what it does by being based on XML.

XBRL is a set of specifications developed and maintained by XBRL International. The base XBRL specification (now version 2.1) is stable since 2003, with additional specifications being added to augment it such as XBRL Dimensions.

XBRL specification are freely available without licensing, note that this doesn’t apply for XBRL enabled software which might have licensing fees.

Data Model
XBRL specifications are tools that enables the definition of dictionaries, data models and rules called XBRL Taxonomies, also XBRL specifications provide the rules to create structured financial reports based on XBRL Taxonomies, these financial reports are called XBRL Instances.

So we can say that XBRL is the set of rules used to create data models and structures that are the basis for structured financial reporting.

Communication Language
The purpose of XBRL is to enable exchange of structured financial data between systems, sometimes the term “transport model” is used to refer to XBRL.

“A Transport Model serves as an organizational structure when moving data from a source to a consumer”

Understanding XBRL starts with XML, the next section briefly explores XML concepts that are relevant to understanding XBRL.

3.4 XML and markup languages

Extensible Markup Language is a markup language that defines a set of rules for encoding documents in a format that is both human-readable and machine-readable.

3.4.1 Back in time

Best way to understand the most basic concept of markup languages is to take a look at ancient Egyptian writings.

Cartouche
[Image by Osama Shukir Muhammed Amin FRCP(Glasg), CC BY-SA 4.0 https://creativecommons.org/licenses/by-sa/4.0, via Wikimedia Commons]

In the image, some of the writing is encapsulated in an oval shape called “Cartouche”, according to the common understanding, this means that the encapsulated writing represents a royal name. The ancient Egyptians choose this method to identify the information by marking or “tagging” it by the oval shape.

XML and markup languages do the same thing, it is just tagging of information in a machine-readable format, in the case of XBRL, this tagging has consequences when it is processed by a computer.

Markup languages in general tags the content of a file or a document in a way that makes it machine readable, i.e. when processed by a computer, the tags tell the computer what to do with the content.

Markup languages has different purposes, for example Hyper Text Markup Language (“HTML”) tags tell the computer how to display the contents of a web page, Mathematical markup language (“MathML”) tags tells the computer how to represent mathematical formulae, XML works the same way purpose of storinh, organizing and transporting content between systems.

Markup languages are usually system independent, an XML file created in a Windows system can be read and parsed by a Linux based system; all systems and programing languages have tools to read and parse XML.

3.5 XML Basics

XML is a set of specifications, rules and tools for describing, storing, and transporting data between systems.

Assume that we want to encode a table of invoices into XML, a fragment of that XML might look as follows:

<table> 
  <invoice CustomerName="abc" InvoiceNum="101">589.91</invoice>
  <invoice CustomerName="xyz" InvoiceNum="101">257.42</invoice>
</table>

3.5.1 XML Form

XML document is composed of elements, each element starts with an opening tag and ends with a closing tag, there can be values or other elements within the opening and closing tags. The XML structure is in the form of a tree, having a root element containing all other elements.

<table> and </table> in the above XML fragment are the opening and closing tags of the root element called table. In the above fragment, the root element has two nested elements called invoice. Each invoice opening tag contains other information in the form of key, value pairs customerName="abc", invoiceNum=101, these are called attributes, which attaches more information about the element and are usually referred to using the @ symbol, as in @customerName. finally we have a value 589.91 between the invoice opening and closing tag, in this case representing the invoice amount.

To be usable, XML must be well formed XML, a well formed XML must have the following:

  • All XML elements must be contained in one root element
  • Each element must have an opening and closing tag
  • Elements must be properly nested
  • Attributes must be quoted

For more about XML well formedness see W3Schools XML Tutorial

3.5.2 Storing Data in XML

Let’s assume we have a branch and head office, everyday the branch needs information about sales to it’s head office in the form of a table of invoices. This table can be expressed in XML format and sent over to the head office. First let’s construct the table using Rscript language:

# Generate a table, same as previous test but 50 rows
set.seed(42)
# Number of rows in the table
table_rows <- 10 
# Customer names
customer_names <- c("abc", "mno","xyz")
# Data frame
tbl_1 <- data.frame(
  CustomerName = sample(customer_names, table_rows, replace = T),
  InvoiceNum = sort(sample(100:999, table_rows)),
  InvoiceDate = sort(sample(seq(as.Date('2000-01-01'), 
                                as.Date('2000-12-31'), 
                                by="day"), table_rows)
                     ),
  InvoiceCurrency = rep("CU",table_rows),
  InvoiceAmt = round(runif(table_rows, min = 100, max = 1000),2), stringsAsFactors = F)

# Display first few rows of the data.frame
head(tbl_1)

Now let’s convert that table to XML format:

# This code converts the invoices table to an XML document 
# and saves it to file

# Create XML root element
xml_root <- xml2::xml_new_root('table')

# Attach each row of the table as an <invoice> element
for(r in asplit(tbl_1,1)) {
  nd <- xml2::xml_add_child(xml_root, 'invoice')
  for(r_n in names(r)){
    xml2::xml_add_child(.x=nd, .value = r_n, r[[r_n]] )
  }
}

# Write the XML document to file
xml_out_tbl_1 <- here::here('docs','xml_files/xml_out.xml')
invisible(xml2::write_xml(xml_root, xml_out_tbl_1))

The resulting XML file looks like this:(see file)

<?xml version="1.0" encoding="UTF-8"?>
<table>
  <invoice>
    <CustomerName>abc</CustomerName>
    <InvoiceNum>264</InvoiceNum>
    <InvoiceDate>2000-01-05</InvoiceDate>
    <InvoiceCurrency>CU</InvoiceCurrency>
    <InvoiceAmt>650.60</InvoiceAmt>
  </invoice>
  <invoice>
    <CustomerName>abc</CustomerName>
    <InvoiceNum>396</InvoiceNum>
    <InvoiceDate>2000-01-24</InvoiceDate>
    <InvoiceCurrency>CU</InvoiceCurrency>
    <InvoiceAmt>441.60</InvoiceAmt>
  </invoice>
  <invoice>
    <CustomerName>abc</CustomerName>
    <InvoiceNum>455</InvoiceNum>
    <InvoiceDate>2000-04-18</InvoiceDate>
    <InvoiceCurrency>CU</InvoiceCurrency>
    <InvoiceAmt>492.19</InvoiceAmt>
  </invoice>
  <invoice>
    <CustomerName>abc</CustomerName>
    <InvoiceNum>509</InvoiceNum>
    <InvoiceDate>2000-07-30</InvoiceDate>
    <InvoiceCurrency>CU</InvoiceCurrency>
    <InvoiceAmt>133.69</InvoiceAmt>
  </invoice>
  <invoice>
    <CustomerName>mno</CustomerName>
    <InvoiceNum>631</InvoiceNum>
    <InvoiceDate>2000-09-15</InvoiceDate>
    <InvoiceCurrency>CU</InvoiceCurrency>
    <InvoiceAmt>976.19</InvoiceAmt>
  </invoice>
  <invoice>
    <CustomerName>mno</CustomerName>
    <InvoiceNum>700</InvoiceNum>
    <InvoiceDate>2000-10-09</InvoiceDate>
    <InvoiceCurrency>CU</InvoiceCurrency>
    <InvoiceAmt>488.58</InvoiceAmt>
  </invoice>
  <invoice>
    <CustomerName>mno</CustomerName>
    <InvoiceNum>721</InvoiceNum>
    <InvoiceDate>2000-10-24</InvoiceDate>
    <InvoiceCurrency>CU</InvoiceCurrency>
    <InvoiceAmt>961.82</InvoiceAmt>
  </invoice>
  <invoice>
    <CustomerName>abc</CustomerName>
    <InvoiceNum>978</InvoiceNum>
    <InvoiceDate>2000-11-09</InvoiceDate>
    <InvoiceCurrency>CU</InvoiceCurrency>
    <InvoiceAmt>898.98</InvoiceAmt>
  </invoice>
  <invoice>
    <CustomerName>xyz</CustomerName>
    <InvoiceNum>981</InvoiceNum>
    <InvoiceDate>2000-12-13</InvoiceDate>
    <InvoiceCurrency>CU</InvoiceCurrency>
    <InvoiceAmt>675.98</InvoiceAmt>
  </invoice>
  <invoice>
    <CustomerName>xyz</CustomerName>
    <InvoiceNum>998</InvoiceNum>
    <InvoiceDate>2000-12-25</InvoiceDate>
    <InvoiceCurrency>CU</InvoiceCurrency>
    <InvoiceAmt>973.87</InvoiceAmt>
  </invoice>
</table>

Examining the resulting XML file, each <invoice> element has 5 child elements each representing a piece of data describing the invoice, with each of those child elements storing the data as its value. If the focus of this table/report is on the invoice amount <invoiceAmt>, then it might be better to have the invoice amount information as the only value, and everything else might be better represented as an attribute. Attributes usually provide additional contextual information about the element and its value, we may call those attributes aspects or even dimensions. So let’s try to rewrite the XML in a different way to reflect this:

# Re-write the XML file with attributes

# create root element for the new XML
xml_root_2 <- xml2::xml_new_root('table')

# define children with attributes
for(r in asplit(tbl_1,1)) {
  nd <- xml2::xml_add_child(xml_root_2, 'invoice', r[[length(r)]])
  for(r_n in names(r)){
    xml2::xml_attrs(nd) <- r[-length(r)]
  }
}

# Write the XML document to file
xml_out_tbl_2 <- here::here('docs','xml_files/xml_out_2.xml')
invisible(xml2::write_xml(xml_root_2, xml_out_tbl_2))

The resulting New XML file looks like this: (see file)

<?xml version="1.0" encoding="UTF-8"?>
<table>
  <invoice CustomerName="abc" InvoiceNum="264" InvoiceDate="2000-01-05" InvoiceCurrency="CU">650.60</invoice>
  <invoice CustomerName="abc" InvoiceNum="396" InvoiceDate="2000-01-24" InvoiceCurrency="CU">441.60</invoice>
  <invoice CustomerName="abc" InvoiceNum="455" InvoiceDate="2000-04-18" InvoiceCurrency="CU">492.19</invoice>
  <invoice CustomerName="abc" InvoiceNum="509" InvoiceDate="2000-07-30" InvoiceCurrency="CU">133.69</invoice>
  <invoice CustomerName="mno" InvoiceNum="631" InvoiceDate="2000-09-15" InvoiceCurrency="CU">976.19</invoice>
  <invoice CustomerName="mno" InvoiceNum="700" InvoiceDate="2000-10-09" InvoiceCurrency="CU">488.58</invoice>
  <invoice CustomerName="mno" InvoiceNum="721" InvoiceDate="2000-10-24" InvoiceCurrency="CU">961.82</invoice>
  <invoice CustomerName="abc" InvoiceNum="978" InvoiceDate="2000-11-09" InvoiceCurrency="CU">898.98</invoice>
  <invoice CustomerName="xyz" InvoiceNum="981" InvoiceDate="2000-12-13" InvoiceCurrency="CU">675.98</invoice>
  <invoice CustomerName="xyz" InvoiceNum="998" InvoiceDate="2000-12-25" InvoiceCurrency="CU">973.87</invoice>
</table>

Now that we have modeled our information in an acceptable form, we can try to re-construct the table from the XML, here R script xml2 library is used to do that, but it can be done on any system using any language or software capable of parsing XML files:

# Read XML file
xml_tbl <- xml2::read_xml(xml_out_tbl_2)

# find all invoice elements
invoices <- xml2::xml_find_all(xml_tbl, './/invoice')
values <- xml2::xml_find_all(xml_tbl, './/invoice/text()') %>% xml2::as_list() %>% unlist()

# extract invoice attributes and values from all elements and convert to a dataframe
xml_to_tbl <- xml2::xml_attrs(invoices) %>% bind_rows() %>% 
  mutate(InvoiceAmt= as.double(values)) %>% as.data.frame()
# Correct data types
xml_to_tbl$InvoiceNum <- as.integer(xml_to_tbl$InvoiceNum)
xml_to_tbl$InvoiceDate <- as.Date(xml_to_tbl$InvoiceDate)
head(xml_to_tbl)
# Compare result of conversion to original table
paste("Matches Original: ", all_equal(xml_to_tbl, tbl_1)) # Should return TRUE
[1] "Matches Original:  TRUE"

3.5.3 XML Schema, Namespaces and Validation

Now that we have an XML document created, the next step is to send it to the destination system.
An important question arises, how do we make sure that the destination/receiving system is able to handle and verify the information in our document correctly? For example, the root element in the example document is called table, what should be expected to be included in a table element? Is it a table of invoices, or is it a table a piece of furniture?

To address the above questions, XML has mechanisms whereby elements in an XML document can be described and verified, these is mechanisms mainly depend on schema, namespaces and types.

Schema Is a component of XML (W3C recommendation) used to describe and validate elements in an XML document. Schema can be described as the blueprint of vocabulary used, what and how data is stored in an XML file, and its data types.
There are different schema languages such as Document Type Definitions (DTDs), Relax-NG, Schematron and W3C XSD (XML Schema Definitions). The focus will be on XSD as this is the Schema language used in XBRL. XSD -being written in XML- has one root element that contains all the declarations, the root element is <schema> and it is defined as follows:

Namespaces Is a component of XML (W3C recommendation) used for providing uniquely named elements and attributes in an XML document. XML document may contain elements from multiple vocabularies (schemas), namespaces help in uniquely identifying elements from different vocabularies having identical names. A namespace takes the form of a URI, for example http://mynamespace.com/1/1. A namespace prefix can be declared in an XML document to refer to specific namespace URI using @xmlns attribute, for example xmlns:myns=http://mynamespace.com/1/1.

Types and Derivation in xsd
Elements declared in an xsd schema are based on XML built-in data types, or types that are derived from these built-in types. Types in xsd determines the value, content and composition of elements, for example, an element that holds a date value may use of the built-in type date and may be typed by setting the type attribute type=date. W3C specifications for data types is available here and here. A depiction of built-in datatypes hierarchy from W3C specifications:

Note substitutionGroup: A substitution group is a feature of XML schema that allows specifying elements that can replace another element in documents generated from that schema. The replaceable element is called the head element and must be defined in the schema’s global scope. The elements of the substitution group must be of the same type as the head element or a type that is derived from the head element’s type.

Given that XML instance can have one and only one root element, this element will inevitably include other elements that have more complicated content than just holding a value of a certain type, and built-in types will not be enough to type these elements. The answer to that is in the X of XML which stands for eXtensible, xsd provides capabilities for creating new types derived from built-in types or other types that are already derived from built-in types. A Summary of type derivation in XSD is as follows:

A useful resource on the topic of XSD data types and derivation is available here.

Following with the invoices table example, a schema was created for this report (using any schema creation software), the schema insures the following:

  • Namespace http://myproject.com/test2/1 was given to refer to the vocabulary of the schema
  • The root element is called table and contains one or more invoice element
  • Each invoice element is required to have a specific set of attributes as follows:
    • @InvoiceNum of data type positive integer
    • @InvoiceDate of data type date
    • @InvoiceCurrency a string that can be either “CU” or “CX”
    • @CustomerName of data type string
    • Finally invoice value must be a positive number or 0

Schema file is as follows: (see file)

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:inv="http://myproject.com/test2/1"
    targetNamespace="http://myproject.com/test2/1"
    elementFormDefault="qualified"
    >
    
    <xs:simpleType name="currType">
        <xs:annotation>
            <xs:documentation>Currency type selection either "CU" or "CX"
            </xs:documentation>
        </xs:annotation>
        <xs:restriction base="xs:string">
            <xs:enumeration value="CU" /> 
            <xs:enumeration value="CX" />
        </xs:restriction>
    </xs:simpleType>
    <xs:attributeGroup name="invoiceGrp">
        <xs:annotation>
            <xs:documentation>Type defining the invoice required information
            </xs:documentation>
        </xs:annotation>
        <xs:attribute name="InvoiceNum" type="xs:unsignedShort"
            use="required" />
        <xs:attribute name="InvoiceDate" type="xs:date"
            use="required" />
        <xs:attribute name="InvoiceCurrency" type="inv:currType"
            use="required" />
        <xs:attribute name="CustomerName" type="xs:string"
            use="required" />
    </xs:attributeGroup>
    <xs:simpleType name="positive_decimalType">
        <xs:annotation>
            <xs:documentation>Restriction on invoice amount to be always a
                positive number.</xs:documentation>
        </xs:annotation>
        <xs:restriction base="xs:decimal">
            <xs:minInclusive value="0" />
        </xs:restriction>
    </xs:simpleType>
    <xs:complexType name="invoiceType">
        <xs:annotation>
            <xs:documentation>Invoice type based using declared positive decimal
                type and invoice attributes group.</xs:documentation>
        </xs:annotation>
        <xs:simpleContent>
            <xs:extension base="inv:positive_decimalType">
                <xs:attributeGroup ref="inv:invoiceGrp" />
            </xs:extension>
        </xs:simpleContent>
    </xs:complexType>
    <xs:element name="table">
        <xs:annotation>
            <xs:documentation>Defines root node using declared invoiceType.
            </xs:documentation>
        </xs:annotation>
        <xs:complexType>
            <xs:sequence>
                <xs:element maxOccurs="unbounded" name="invoice"
                    type="inv:invoiceType" minOccurs="1" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

The XML file must reference the schema to be able to validate the file, this is done using the @xmlns attribute with namespace prefix ‘inv’, and providing the location of the schema file using @xs:schemaLocation attribute, note that the later attribute is from xs=http://www.w3.org/2001/XMLSchema-instance namespace. The new file with the schema reference is named xml_out_2_schema.xml, the part of the file that references the schema looks as follows:

<inv:table xmlns:inv="http://myproject.com/test2/1" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" 
    xs:schemaLocation="http://myproject.com/test2/1 example_2_schema2.xsd">

Validation with no errors
Before processing the XML file, the receiving computer can validate the XML file against the referenced schema, in this example; validation is done using R script xml2::xml_validate() function as follows:

# Read XML instance and schema
inst <- xml2::read_xml(here::here("docs","xml_files/xml_out_2_schema.xml"))
schema <- xml2::read_xml(here::here("docs","xml_files/example_2_schema2.xsd"))

# Validate XML instance against the schema
xml2::xml_validate(inst,schema)
[1] TRUE
attr(,"errors")
character(0)

Validating the first file returns TRUE with 0 errors, meaning that the file is valid according to the schema.

Validation with Errors
Another file is created and named xml_out_2_schema_errors.xml (see file), with some changes as follows:

  1. For the first invoice remove @CustomerName attribute -> test missing attributes are detected.
  2. For the second invoice change @InvoiceNum value to string ix-> test inconsistent attribute datatype is detected.
  3. For the third invoice change @InvoiceCurrency value to XZ -> test only valid currency choices are allowed.
  4. in the fourth invoice change the value from 133.69 to -133.69 -> test if only positive invoice amount values are allowed.

Then we run the validation again on the modified file, we should get an error this time:

# Read XML instance and schema"
inst_err <- xml2::read_xml(here::here("docs","xml_files/xml_out_2_schema_errors.xml"))
schema <- xml2::read_xml(here::here("docs","xml_files/example_2_schema2.xsd"))

# Validate XML instance against the schema
xml2::xml_validate(inst_err,schema)
[1] FALSE
attr(,"errors")
[1] "Element '{http://myproject.com/test2/1}invoice': The attribute 'CustomerName' is required but missing."                                                              
[2] "Element '{http://myproject.com/test2/1}invoice', attribute 'InvoiceNum': 'ix' is not a valid value of the atomic type 'xs:unsignedShort'."                           
[3] "Element '{http://myproject.com/test2/1}invoice', attribute 'InvoiceCurrency': [facet 'enumeration'] The value 'XZ' is not an element of the set {'CU', 'CX'}."       
[4] "Element '{http://myproject.com/test2/1}invoice', attribute 'InvoiceCurrency': 'XZ' is not a valid value of the atomic type '{http://myproject.com/test2/1}currType'."
[5] "Element '{http://myproject.com/test2/1}invoice': [facet 'minInclusive'] The value '-133.69' is less than the minimum value allowed ('0')."                           
[6] "Element '{http://myproject.com/test2/1}invoice': '-133.69' is not a valid value of the atomic type '{http://myproject.com/test2/1}positive_decimalType'."            

As shown above, a simple XML validator (xml2) detected all the errors and reported them.

3.5.5 Conclusion

XML language and standards that provides for:

  • Flexibility in data modeling.
  • Mechanisms for creating types and vocabularies (dictionaries).
  • Mechanisms to validate XML content.
  • Mechanisms to link internal and external components.

In addition to the above, XML is a stable and widely used language, and all that made XML suitable foundation to build XBRL.

3.6 How Does XBRL Represent Data

This section is an overview of the components and specifications of XBRL, some basic concepts of how XBRL represents data, and XBRL example.

It is important to understand that XBRL taxonomies and instance documents are usually created using specialized software that provides a user friendly interface while the software takes care of the form and syntax behind the scene, but it is important to have knowledge of the elements and components defined in XBRL specifications in the raw XML format.

3.6.1 XBRL Components

The figure below visualizes the components of XBRL:

XBRL Components

XBRL Components

  1. At the base, we have XML, the foundation for everything else.

  2. XBRL specifications are based on XML, these specifications provide the building blocks for a reporting system based on XBRL.

  3. XBRL Taxonomy is the most critical ingredient, it uses XBRL specifications to build the structure and the data model for XBRL reporting, we can think of a Taxonomy as the Schema for a particular reporting domain. XBRL Taxonomy consists of:

    • Dictionary/Vocabulary of elements to be used in reporting, in XBRL terminology, these are called “Concepts”.

    • Type Definitions are components or extension of existing components that are the building blocks of Concepts.

    • Linkbases are groups of Xlinks that links concepts together to form a logical structure, an example of linkbases is Presentation Linkbase, which defines one or more hierarchical structures of concepts. This allows the taxonomy to be properly organized, and it permits XBRL rendering software to create visual representations of the taxonomy that are human-readable and easily navigable..

    • Other Imported Taxonomies XBRL taxonomies can import other taxonomies to be part of the base taxonomy, this mechanism allows for reusing existing taxonomies rather than recreating something that already exits. All taxonomies imported by the base taxonomy and any other taxonomies that imported taxonomies import all together are called Discoverable Taxonomy Set (DTS). An example for that is the US-GAAP taxonomy which imports Stock Exchange Commission (SEC) taxonomies. Some of terminology relevant to Taxonomy (_based on XBRL Glossary):

      • Base Taxonomy: A taxonomy that is used as the starting point for an extension taxonomy.
      • Extension Taxonomy: A taxonomy that is constructed using one or more other taxonomies (a base taxonomy) as a starting point. Extension taxonomies are typically created by a different entity from the author of the base taxonomy. Extension taxonomies may be created by preparers (see entity-specific extension taxonomy).
      • Entity-specific extension taxonomy: An extension taxonomy that is created by the preparer of an XBRL report in order to disclose information that is specific to the reporting entity.
      • Taxonomy Entry Point: A taxonomy entry point identifies a subset (or “view”) of a taxonomy. For example, a taxonomy may cater for different industries reporting under the same accounting standard, it may provide an entry point for each industry. A taxonomy entry point is identified by a unique URL (or set of URLs), and is referenced by an XBRL report or an extension taxonomy.
    • Extensions any extensions made to existing taxonomies.

    • Other Resources such as documentation and references may be included in an XBRL Taxonomy.

  4. XBRL Report consists of:

    • Schema containing any extensions to the base taxonomy if extension is allowed.
    • Linkbases relevant to the report.
    • Instance Document containing the information for the current report.
  5. Consumer Data Model is where the data transported by XBRL is stored, taxonomies must consider consumer data needs in its design.

3.6.2 XBRL Specifications

As explained previously XBRL is an extension of XML, basically XBRL international used XML to define XBRL components and elements and the result is XBRL specifications.
As of date of this document, the relevant current XBRL specifications recommendations are as follows:

  • XBRL: Core XBRL Specs.
  • Dimensions: The XBRL Dimensions specification enables the reporting of multi-dimensional facts against dimensions defined in an XBRL taxonomy.
  • Extensible Enumerations: Allows for constraining the allowed values for primary reporting concepts (choices from specific list).
  • Formula: XBRL Formula provides a standard mechanism for defining rules in a taxonomy that can be applied against instance documents.
  • Generic Links: A link type with no predefined semantics or constraints. This can be used used as a building block for other specifications.
  • Generic Preferred Label: This specification introduces the preferred label feature for all relationships.
  • Global Ledger: XBRL Specs for transactional reporting.
  • Infrastructure: Specifications in this section are used to support the development of XBRL specifications and registries.
  • Inline XBRL: Inline XBRL, or iXBRL, provides a mechanism for embedding XBRL tags in HTML documents.
  • Registries: Registries provide a centralise list of definitions, allowing implementers to re-use suitable definitions created by others.
  • Table Linkbase: Provides a mechanism for taxonomy authors to define a tabular layout of facts. The resulting tables can be used for both presentation and data entry.
  • Taxonomy & Report Packages: Taxonomy Packages provide a standardised mechanism for providing documentation about the content of a taxonomy.
  • Versioning: Defines an XML syntax for an XBRL versioning Report.

Link for each recommendation includes the normative schema.

3.6.3 XBRL Representation of Data

As the TDH describes it, XBRL provides a platform to give data meaning [TDH section 1.1.3 page 2]. A piece of data does not have a meaning without context or means to associate it with other data points, for example, data about a switch being on or off doesn’t have much value if we don’t know what does this switch do and when was it on or off. XBRL gives meaning to data by providing layers of context.

3.6.3.1 Some Basics

The TDH presents the an example of a monthly expenses report TDH section 2.2 page 15 of a person named “Bob”, the report is in the form of a table with rows having expenses line items, and columns having monthly amounts of expenses.

The TDH explains that expenses amounts alone do not convey much meaning unless associated with dimensions identifying additional information about the amounts, for example, who made the expenses, what is the nature of the expense, and in which periods expenses were made. The intersection of one or more of these dimensions with an amount creates a fact that has contextual meaning.

Expense Report

Expense Report Example from TDH

One of the basic concepts of XBRL design is that it identifies data points by multiple dimensions that gives enough context to the data point to be meaningful, in the case of the expense report (TDH example), an amount of $180 in row 10, is identified by dimensions Clothing as nature of expense, and January as expense period, and Bob as the person who made the expense, which creates an XBRL Fact.

Expense Report Fact

Expense Report Example with an illustrated XBRL fact from TDH

The TDH classifies dimensions that identifies facts in XBRL into 2 categories:

  1. Core Dimensions which includes:
    • Concept core dimension: A taxonomy element (dictionary/vocabulary) that provides the meaning for a fact (e.g. Fixed Assets, Revenue, Profit …), concepts are the building blocks of a taxonomy.
    • Period core dimension: Time frame or point of time relevant to the fact.
    • Reporting entity core dimension: The entity reporting the fact, also known as entity identifier
    • Unit core dimension: Unit of measurement of reported fact (e.g. USD, EURO, KM, KGM, USD/Share…), it is only required for numeric facts.
  2. Taxonomy Defined Dimensions: Concepts that exist for the purpose of grouping facts that should be interpreted in a similar way. Taxonomy Defined Dimensions do not directly define a fact but rather intersect with a fact to add further contextual or semantic information beyond what is added by the core dimensions, for example a country dimension for geographical allocation.

Core Dimensions and Taxonomy Defined Dimensions are defined in the XBRL Taxonomy or its extensions using XBRL components, and then used in an XBRL instance to report facts.

3.6.3.2 XBRL Elements Usage

XBRL specifications define a how financial report can be expressed in XBRL. This section is an overview of XBRL elements used to describe a data point.

To create an XBRL report form the monthly expenses example, first a taxonomy containing the vocabulary and linkbases needs to be created, then this taxonomy can be used to create an XBRL instance that contains the facts.

3.6.3.3 Creating XBRL Taxonomy Concept

Concepts in an XBRL taxonomy are elements that provides a meaning for a fact, concepts are defined in the XBRL Taxonomy schema. Concepts make up the dictionary/vocabulary allowed to be used by the Taxonomy.

In the case of a financial reporting taxonomy, concepts may describe numeric financial elements such as Net Profit, Assets or Liabilities, or narrative elements, like Accounting Policies, which means that a concept needs to be created for every reportable element within the domain of the taxonomy. Concepts are the backbone of the Taxonomy. Concepts structures are defined in XBRL core specifications in namespace {http://www.xbrl.org/2003/instance}. Concepts have 2 main types defined in XBRL taxonomy, item and tuple:

Note substitutionGroup: A substitution group is a feature of XML schema that allows specifying elements that can replace another element in documents generated from that schema. The replaceable element is called the head element and must be defined in the schema global scope. The elements of the substitution group must be of the same type as the head element or a type that is derived from the head element’s type.

  • item: an Item represents a single fact or business measurement, all elements representing single facts or business measurements defined in an XBRL taxonomy document and reported in an XBRL instance MUST be either (a) members of the substitution group item; or, (b) members of a substitution group originally based on item.

  • tuple: While most business facts can be independently understood, some facts are dependent on each other for proper understanding, especially if multiple occurrences of that fact are being reported. For example, in reporting the management of a company, each manager’s name has to be properly associated with the manager’s correct title. Such sets of facts (manager’s title/manager’s name) are called tuples.

Tuples have complex content and MAY contain both items and other tuples.

Both <item>and <tuple> elements are defined as abstract elements in XBRL, which means they are only meant to be heads of substitutionGroups and will never appear in an XBRL instance.

XBRL Data Types
When defining an XBRL Concept in the taxonomy, it will be in either item or tuple substitution groups, a data type must be given to the concept which determines what type of data can be stored in this element (for example, numbers, dates, strings, … etc), XBRL uses XML standard types in addition to other derived types, TDH table 2-3 page 28 shows the most common types used in XBRL:

dataType description
stringItemType Represents character strings in XML.
booleanItemType Represents the values of two-valued logic (true, false).
decimalItemType Represents a subset of real numbers, which can be represented by decimal numerals.
dateTimeItemType Represents instants of time, optionally marked with a time zone offset.
integerItemType Represents the standard mathematical concept of integer numbers by fixing the fractional digits of decimal to be 0 and prohibiting the trailing decimal point.
monetaryItemType Represents a decimal with the added constraint of a currency unit.
qNameItemType Represents a qualified XML name.

Above are just a sample of the most commonly used data types, XBRL Specifications [Section 5.1.1.3] lists more data types, also other XBRL data types are defined in XBRL Data Types Registry.

Let’s define Food concept (from the monthly expenses report), with the following characteristics:

  • Has a debit balance since it is an expense,
  • Its value Cannot be null (absent value), it can have a value of 0 though,
  • It is a monetary item, meaning that it needs to have a numeric value and a unit according to XBRL specifications.
Concept is defined in the taxonomy SCHEMA as follows:
<!-- From taxonomy schema file (.xsd) -->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:expenses="http://www.expenses.com/taxonomy"
  xmlns:xbrli="http://www.xbrl.org/2003/instance"
  attributeFormDefault="unqualified" elementFormDefault="qualified"
  targetNamespace="http://www.expenses.com/taxonomy">
    
    <element 
      xbrli:name="Food"
      xbrli:periodType="duration"
      xbrli:balance="debit"
      nillable="false"
      abstract="false"
      type="xbrli:monetaryItemType"
      substitustionGroup="xbrli:item"
      id="expense_Food"/>
        
</xs:schema>

Notes:

  • Namespace http://www.xbrl.org/2003/instance prefixed as xbrli was declared for XBRL specification schema to be able to use elements form that namespace.
  • The taxonomy namespace http://www.expenses.com/taxonomy and prefixed as expenses
  • duration was selected for @xbrli:periodType XBRL attribute, because this is an expense that occurs during a specified period (not a balance at a moment of time).
  • xbrli:monetaryItemType was assigned to @type to reflect the type of data expected to be reported for this concept.
  • Each element must have a unique id.
  • Because we referred to XBRL specification, this schema document can be validated against XBRL specifications.

3.6.3.4 XBRL Instance Document

Instance document is the actual report containing facts and reported values, it is constructed using XBRL constructs. The root element of XBRL instance document is <xbrl>, and it is defined in XBRL specifications in the namespace {http://www.xbrl.org/2003/instance}, a diagram for the xbrl element declarations is as follows:

XBRL Type

XBRL Type Declaration

According to XBRL specifications; <xbrl> allowed child elements are as follows:

A. Links to schema and declaration used to construct the report:

  • <SchemaRef>: An XML simple link to location of the entry point of the taxonomy relevant to this report. This element is defined in namespace {http://www.xbrl.org/2003/linkbase}.
  • <linkbaseRef>: An XML simple type link to location of linkbase relevant to this report. this element is defined in namespace {http://www.xbrl.org/2003/linkbase} (See section 3.7.4 Linkbases).
  • <roleRef>: An XML simple type link to location of declaration of a roleType used in this report. Element is defined in namespace {http://www.xbrl.org/2003/linkbase}
  • <arcroleRef>: An XML simple type link to location of declaration of a arcroleType used in this report. Element is defined in namespace {http://www.xbrl.org/2003/linkbase}

B. Elements used to carry the information of current report:

3.6.3.4.1 Creating XBRL instance Context

In Bob’s report; Food expenses for January 2020 was $900, note here that we attached 3 pieces of additional information to the expense amount:

  1. Food the concept core dimension,
  2. Bob the owner of the expense,
  3. January 2020 the period core dimension.

We already defined the Food concept in the taxonomy, to attach the owner of the expenses and the period we need to use XBRL context element.

context is an XBRL element used in XBRL instance document (report) and referenced by one or more fact(s) in the XBRL report. It contains information about period, entity, and taxonomy defined dimension relating to this context, following is a diagram of context type declaration:

Context Type

Context Type Declaration

We can define a context for Bob owner, and January 2020 period as follows:

<!-- defined in instance document -->
<xbrl xmlns="http://www.xbrl.org/2003/instance"
      xmlns:expenses="http://www.expenses.com/taxonomy"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xml:lang="en-US">
    <!-- ... at least one link:schemaRef element goes here ... -->
    <context id="01">
      <entity>
        <identifier scheme="http://www.example.com/bob">Bob</identifier>
      </entity>
      <period>
        <startDate>2020-01-01</startDate>
        <endDate>2020-01-31</endDate>
      </period>
    </context>
</xbrl> 

Notes XBRL instance document

  • XBRL instance document root element must be element <xbrl>
  • Instance references taxonomy namespace to be able to use elements defined in that taxonomy.
  • Instance references XBRL schema (with no prefix) to be able to use XBRL constructs.
  • Because of the references above, this XBRL instance document can be validated against XBRL specifications and taxonomy.
3.6.3.4.2 Creating XBRL instance unit
XBRL requires that numeric type facts has a reference to a unit [see XBRL specs 4.6.2]. And since Food concept is a monetaryItemType type which is a numeric type, therefore any fact using Food concept must refer to a unit in the instance document. A unit must be created before a fact can be created for the Food. Following is a diagram for the declaration of the unit type in XBRL specifications:

Unit Type

Unit Type Declaration

We declare a unit for United States Dollars using iso4217 taxonomy USD element as follows:

<!-- Added to previous instant document as child to <xbrl> element -->
<unit id="usd" xmlns:iso4217="http://www.xbrl.org/2003/iso4217">
  <measure>iso4217:USD</measure>
</unit>
3.6.3.4.3 Creating XBRL instance fact

All core dimensions are defined, Food concept core dimension is defined in XBRL Taxonomy and have a context with id=01 (holding the period and entity core dimensions) and unit core dimension with id="usd" in instance document, we can create a fact for Bob’s Food expenses for the period of January 2020 for the amount of 900 United States Dollars as follows:

<!-- Added to previous instant document as child to <xbrl> element -->
<expenses:Food
  contextRef="01" 
  decimals="0" 
  id="fact_001" 
  unitRef="usd">900</expenses:Food>

3.6.3.5 XBRL Dimensions

XBRL provides tools for reporting multidimensional facts, core dimensions (Concept, period, reporting entity and unit) are available from the XBRL base specifications, in addition to core dimensions taxonomy defined dimensions can be used to express complex multidimensional structures. XBRL Dimensions Specifications.

3.6.3.5.1 Additional Dimensions from base XBRL

XBRL element context has 2 additional features that can provide dimensionality to a fact, the <segment> and <scenario> as follows:

  • <segment>: is defined in XBRL specifications as “an optional container for additional mark-up that the preparer of an XBRL Instance SHOULD use to identify the business segment more completely in cases where the Entity identifier is insufficient.” <segment> is element is also used to incorporate taxonomy defined dimension using XBRL Dimensions Specifications.
    Note: segment is a child element of the <entity> element (which in turn is a child element of the <context> element).

  • <scenario>: XBRL specifications describes this element as “Business facts can be reported as actual, budgeted, restated, pro forma, etc. For internal reporting purposes, there can be an even greater variety of additional metadata that preparers want to associate with items. The optional element allows additional valid mark-up (see note above regarding segment) to be included for this purpose.”

Segment and Scenario Example

In the monthly expense report example, assume that Bob has 2 locations to track expenses for home and office (segments), also assume that Bob tracks budget and actuals (scenarios), to be able to include these dimensions in our report we need first to create an extension taxonomy to include these elements as follows:

<!-- Report specific taxonomy extension -->
<schema targetNamespace="http://www.expenses.com/taxonomy" 
        xmlns:expenses="http://www.expenses.com/taxonomy" 
        xmlns="http://www.w3.org/2001/XMLSchema" 
        xmlns:xbrli="http://www.xbrl.org/2003/instance">
          
    <!-- Type for segments -->
    <simpleType name="locationsType">
        <restriction base="token">
            <enumeration value="home"/>
            <enumeration value="office"/>
        </restriction>
    </simpleType>
          
    <!-- report specific segment sub-element -->
    <element name="locations" type="expenses:locationsType" />
          
    <!-- Type for scenarios -->
    <simpleType name="actualBudgetType">
        <restriction base="token">
            <enumeration value="actual"/>
            <enumeration value="budget"/>
        </restriction>
    </simpleType>
    <!-- report specific scneario sub-element -->
    <element name="actualBudget" type="expenses:actualBudgetType" />
</schema>

Note

Elements contained by the <scenario> element MUST NOT be defined in the http://www.xbrl.org/2003/instance namespace. Also, they MUST NOT be in the substitution group for elements defined in the http://www.xbrl.org/2003/instance namespace. The element MUST NOT be empty.

To report facts using locations and/or budget vs actual elements, namespace http://bobreport.com/xbrl/taxonomy must be referenced in our instance report to be able access these elements, then we need to create contexts that reference these elements, and finally we can reference these contexts in the reported facts as follows:

<!-- Added to previous instant document as children to <xbrl> element -->
  <xbrl ....... xmlns:expenses="http://www.expenses.com/taxonomy">
  <!-- ... at least one link:schemaRef element goes here ... -->
    <context id="02">
      <entity>
        <identifier scheme="http://www.example.com/bob">Bob</identifier>
        <segment>
          <expenses:locations>expenses:home</expenses:location>
      </segment>
      </entity>
      <period>
        <startDate>2020-01-01</startDate>
        <endDate>2020-01-31</endDate>
      </period>
      <scenario>
          <expenses:actualBudget>expenses:actual</expenses:actualBudget>
      </scenario>
    </context>

Now having context id=02 we can reference the facts that include actual figures for location home in our instance report.

3.6.3.5.2 Taxonomy defined dimensions

Taxonomy defined dimensions enable creation of complex structures in XBRL taxonomy and reports. This is achieved through the interactions between concepts and linkbases, this is best described in TDH section 2.2.5 page 21 as follows:

A taxonomy-defined dimension is a grouping of concepts that is used to add organizational structure to facts. These dimensional concepts should not be directly associated with a data point but rather are employed to indicate additional contextual information beyond the simple semantic identifier or what is provided through any of the other core dimensions. Expanding the expense example by attributing the monthly expenses to two people in the same household creates a level of complexity that cannot be easily represented with only concepts. Previously, there were only two dimensions: expenses (as rows) and months (as columns).

XBRL Dimensions terminology

  • Dimension: A qualifying characteristic that is used to uniquely define a data point (other than core dimensions) for example a “Geography Dimension”.
  • Domain: A set of related values, an example of domains for use on a “Geography Dimension” would be “Countries”, “Continents” or “States”.
  • Domain member: An element representing one of the possibilities within a domain.
  • Cube: A cube is defined by combining a set of dimensions with a set of concepts. Cubes are often referred to as “hypercubes”, as unlike a physical, 3-dimensional cube, a hypercube may have any number of dimensions.

All the above constructs are defined as concepts, but with special values for the @type and @substitutionGroup attributes, these special values are defined in the XBRL Dimensions Specifications.

The TDH in this section, splits the monthly expenses by Bob’s children, with each month split into 2 columns for each of Bob’s children. Assume that we want to organize this information in XBRL by doing the following:

  • Create a grouping concept or header called expenses to group all the expenses together,
  • Create persons dimension, and then create a domain for bobChildrenDomain and domain member for each child referenced in the report.

This can be implemented in XBRL as follows:

<!-- Report specific taxonomy extension -->
<schema targetNamespace="http://bobreport.com/xbrl/taxonomy" 
        xmlns:bob="http://bobreport.com/xbrl/taxonomy" 
        xmlns="http://www.w3.org/2001/XMLSchema" 
        xmlns:xbrli="http://www.xbrl.org/2003/instance"
        xmlns:xbrldt="http://xbrl.org/2005/xbrldt"
        xmlns:dtr-types="http://www.xbrl.org/dtr/type/2020-01-21">
        <!-- note above we included xbrl dimensions specs to have access to its elements -->
        
        <!-- create a grouping expense element -->
        <element abstract="true" id="expenses_abstract" name="ExpensesAbstract" 
                 nillable="true" xbrli:balance="debit" substitutionGroup="xbrli:item" 
                 type="xbrli:monetaryItemType" xbrli:periodType="duration"/>
        
        <!-- create persons dimension -->
        <element abstract="true" id="dim_01_persons" name="personsDim" 
                 nillable="true" substitutionGroup="xbrldt:dimensionItem" 
                 type="xbrli:stringItemType" xbrli:periodType="duration"/>
                 
        <!-- create children domain -->        
        <element abstract="true" id="domain_01_children" name="ChildrenDomain" 
                nillable="true" substitutionGroup="xbrli:item" 
                type="dtr-types:domainItemType" xbrli:periodType="duration"/>
                  
          <!-- create domain member for each child -->
          <element abstract="true" id="members_01_childOneMember" name="ChildOneMember"
              nillable="true" substitutionGroup="xbrli:item" 
              type="dtr-types:domainItemType" xbrli:periodType="duration"/>
          
          <element abstract="true" id="members_02_childTwoMember" name="ChildTwoMember"
              nillable="true" substitutionGroup="xbrli:item" 
              type="dtr-types:domainItemType" xbrli:periodType="duration"/>
</schema>
<!-- note attributes use from dtr-types and xbrldt namespaces>

Notes All elements defined above has the @abstract attribute as ture, this means that this element is not allowed to be used in XBRL instance document to report facts, this element is only for organization purposes.

Now we can reference the dimension in the in the instance document through <context> element as follows:

<!-- Added to previous instant document as children to <xbrl> element -->
  <xbrl ....... xmlns:bob="http://bobreport.com/xbrl/taxonomy"
                xmlns:xbrldi="http://xbrl.org/2006/xbrldi">
  <!-- ... at least one link:schemaRef element goes here ... -->
  <!-- ... Must Have a linkbaseRef for the definition link ... -->
    <context id="03">
      <entity>
        <identifier scheme="http://www.example.com/bob">Bob</identifier>
      </entity>
      <period>
        <startDate>2020-01-01</startDate>
        <endDate>2020-01-31</endDate>
      </period>
  
      <segment>
          <bob:locations>bob:home</bob:location>
          <xbrldi:explicitMember
                  dimension="bob:personsDim">bob:ChildOneMember
          </xbrldi:explicitMember>
      </segment>
  
      <scenario>
          <bob:actualBudget>bob:actual</bob:actualBudget>
      </scenario>
  
    </context>

Now facts reporting actual expenses, for home location, relating to child one for January 2020 can use the above context and have all expenses grouped under one heading using the ExpensesAbstract element.

Notes There are two types of members explicit members, and typed member. explicit members are explicitly defined and linked to a domain in the taxonomy and no other members can be used with that domain except the defined members. On the other hand typed members, only type of the member is defined in the taxonomy, and any value can be used if it matched the type.

Keep in mind that XBRL dimensions specifications rely heavily on the linking mechanisms provided by XBRL through linkbases, which will be the next topic.

3.6.4 XBRL Linkbases

XBRL linkbases (based on XML XLink) provides for a mechanism to create relationships between elements and other internal or external resources to create a meaningful self-describing data structure.

3.6.4.1 The basics

XBRL uses XML XLink specifications, generally speaking, there are two main categories of links:

  • Simple Links: A simple link in XLink creates a unidirectional hyperlink from one element to another through a URI. The element containing the link (the source element) is linked to a destination element, this link DOES NOT provide a link back from destination the source element. This is similar to HTML hyperlinking.

  • Extended Links: Provide for multiple resources at the source or destination to be connected via multiple arcs. An arc contains information about the source, destination, and the behavior of a link between the two. The source and the destination are defined by labels. Through one or more arcs, extended links achieve complex connections among multiple resources. Like simple links, extended links can define relationships between elements within the same namespace or across different namespaces.

It is important to note that Extended Links creates relationships between elements using arcs that describes the behavior of the relationship.

XBRL specifications defines several types of links based on XLink specs, most common links and arcs are [based on XBRL Glossary]:

  • Presentation Links: An extended link providing for the organisation of taxonomy elements into a hierarchical structure with the aim of providing a means of visualizing or navigating the taxonomy. [At a technical level, the presentation tree is defined using the parent-child arcrole in the XBRL specification]

  • Calculation Links: An extended link providing relationships between concepts in a taxonomy for the purpose of describing and validating simple totals and subtotals. [At a technical level, these relationships are defined using the summation-item arcrole in the XBRL specification]

  • Label links: An extended link providing a relationship between concept and human readable description of a taxonomy component. XBRL labels can be defined in multiple languages and can be of multiple types, such as a “standard label”, which provides a concise name for the component, or a “documentation label” which provides a more complete definition of the component. Example of arcroles label, terseLabel, periodStartLabel, periodEndLabel, totalLabel

  • Definition Links: An extended providing for relationships that arranges pairs of concepts in a specific semantic relationship. These relationships may be above and beyond calculation or presentation relationships. Concept core dimensions cannot be used in a definition relationship, and is primarily used for dimensional relationships in XBRL Dimensions specifications. Example arcroles hypercube-dimension, dimenstion-domain, domain-member, dimenstion-defualt

  • Reference link: An extended link providing for relation between elements of the taxonomy and external reference such as accounting standards, or laws. Example arcrole concept-reference.

  • Formula link: An extended link providing relations necessary to define formulae (XBRL Formula Specification) used in validating XBRL instances. Example arcrole variable-set, variable-set-filter.

  • Table Linkbase: an extended link providing relations needed for tabular view of a taxonomy or report that is used for presentation or data entry purposes. XBRL reporting templates can support complex, multi-dimensional reports, such as those seen in prudential reporting, and provide a user-friendly view of the data. XBRL reporting templates are typically used in closed reporting programs, where a template is prescribed by the collector. [At a technical level, XBRL reporting templates are defined using the Table Linkbase specification]

  • footnote links: A footnote adds further explanatory information to a statement or fact. In XBRL, footnotes are created through relationships between note text and facts using the footnote relationships. One instance of footnote text can be linked to multiple facts. The note core ID dimension is the dimension on the fact that associates the fact with one or more footnotes arcs.

  • Generic Links: A link type with no predefined semantics or constraints. This can be used as a building block for other specifications, such as Generic Labels 1.0 and Generic References 1.0 to define relationships with particular semantics.

3.6.5 Example - Income Statement Taxonomy and Linkbases

In this section we will create taxonomy and linkbases for a simple Income Statement.

3.6.5.1 Form

We want to create taxonomy and links for a Income Statement that looks as follows:

Year Ended
(In EGP) 31-12-2020 31-12-2019
Revenue
Product 2,000 2,500
Service 3,000 1,500
Total Revenue 5,000 4,000
Cost of Revenue
Product 1,000 1,250
Service 2,000 1,000
Total Cost of Revenue 3,000 2,250
Gross Profit 2,000 1,750
Expenses 500 420
Net Profit 1,500 1,330

3.6.5.2 Taxonomy

First we create our schema/taxonomy as follows: (see file)

<?xml version="1.0" encoding="utf-8"?>
<!-- edited with XMLSpy v2021 rel. 3 (x64) (http://www.altova.com) by Sherif (None) -->
<xs:schema targetNamespace="http://xyz.abc/IncomeStatementExample" elementFormDefault="qualified" attributeFormDefault="unqualified" xmlns:altovaext="http://www.altova.com/xslt-extensions" xmlns:altova-xfi="http://www.altova.com/xslt-extensions/xbrl" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xl="http://www.xbrl.org/2003/XLink" xmlns:xbrli="http://www.xbrl.org/2003/instance" xmlns:link="http://www.xbrl.org/2003/linkbase" xmlns:xfi="http://www.xbrl.org/2008/function/instance" xmlns:dtr="http://www.xbrl.org/2009/dtr" xmlns:xff="http://www.xbrl.org/2010/function/formula" xmlns:dtr-types="http://www.xbrl.org/dtr/type/2020-01-21" xmlns:nonnum="http://www.xbrl.org/dtr/type/non-numeric" xmlns:xbrldt="http://xbrl.org/2005/xbrldt" xmlns:ea="http://xbrl.org/2008/assertion/existence" xmlns:bf="http://xbrl.org/2008/filter/boolean" xmlns:cf="http://xbrl.org/2008/filter/concept" xmlns:df="http://xbrl.org/2008/filter/dimension" xmlns:formula="http://xbrl.org/2008/formula" xmlns:gen="http://xbrl.org/2008/generic" xmlns:label="http://xbrl.org/2008/label" xmlns:reference="http://xbrl.org/2008/reference" xmlns:variable="http://xbrl.org/2008/variable" xmlns:crf="http://xbrl.org/2010/filter/concept-relation" xmlns:msg="http://xbrl.org/2010/message" xmlns:valm="http://xbrl.org/2010/message/validation" xmlns:table="http://xbrl.org/2014/table" xmlns:sev="http://xbrl.org/2016/assertion-severity" xmlns:example="http://xyz.abc/IncomeStatementExample">
    <xs:annotation>
        <xs:documentation>
        Schema/Taxonomy for Income Statement Example
      </xs:documentation>
        <xs:appinfo>
            <link:linkbaseRef xlink:type="simple" xlink:arcrole="http://www.w3.org/1999/xlink/properties/linkbase" xlink:href="is_tab.xml"/>
            <link:roleType id="BlockedConceptsSegmentRole" roleURI="http://xyz.abc/role/BlockedConceptsSegment">
                <link:definition>Prevents default use of line items (i.e. when not explicitly allowed) for segment</link:definition>
                <link:usedOn>link:definitionLink</link:usedOn>
            </link:roleType>
            <link:linkbaseRef xlink:type="simple" xlink:arcrole="http://www.w3.org/1999/xlink/properties/linkbase" xlink:href="is_for.xml"/>
            <link:roleType id="roleType_IncomeStatement" roleURI="http://xyz.abc/role/IncomeStatement">
                <link:definition>10000 - Statement - Income Statement</link:definition>
                <link:usedOn>link:calculationLink</link:usedOn>
                <link:usedOn>link:definitionLink</link:usedOn>
                <link:usedOn>link:presentationLink</link:usedOn>
            </link:roleType>
            <link:linkbaseRef xlink:type="simple" xlink:role="http://www.xbrl.org/2003/role/labelLinkbaseRef" xlink:arcrole="http://www.w3.org/1999/xlink/properties/linkbase" xlink:href="is_lab_en.xml"/>
            <link:linkbaseRef xlink:type="simple" xlink:role="http://www.xbrl.org/2003/role/labelLinkbaseRef" xlink:arcrole="http://www.w3.org/1999/xlink/properties/linkbase" xlink:href="is_lab_ar.xml"/>
            <link:linkbaseRef xlink:type="simple" xlink:role="http://www.xbrl.org/2003/role/presentationLinkbaseRef" xlink:arcrole="http://www.w3.org/1999/xlink/properties/linkbase" xlink:href="is_pre.xml"/>
            <link:linkbaseRef xlink:type="simple" xlink:role="http://www.xbrl.org/2003/role/definitionLinkbaseRef" xlink:arcrole="http://www.w3.org/1999/xlink/properties/linkbase" xlink:href="is_def.xml"/>
            <link:linkbaseRef xlink:type="simple" xlink:role="http://www.xbrl.org/2003/role/calculationLinkbaseRef" xlink:arcrole="http://www.w3.org/1999/xlink/properties/linkbase" xlink:href="is_cal.xml"/>
            <link:linkbaseRef xlink:type="simple" xlink:arcrole="http://www.w3.org/1999/xlink/properties/linkbase" xlink:href="gla_ar.xml"/>
        </xs:appinfo>
    </xs:annotation>
    <xs:import namespace="http://www.xbrl.org/2003/instance" schemaLocation="http://www.xbrl.org/2003/xbrl-instance-2003-12-31.xsd"/>
    <xs:import namespace="http://www.xbrl.org/dtr/type/non-numeric" schemaLocation="http://www.xbrl.org/dtr/type/nonNumeric-2009-12-16.xsd"/>
    <xs:import namespace="http://xbrl.org/2005/xbrldt" schemaLocation="http://www.xbrl.org/2005/xbrldt-2005.xsd"/>
    <xs:import namespace="http://www.xbrl.org/dtr/type/2020-01-21" schemaLocation="https://www.xbrl.org/dtr/type/2020-01-21/types.xsd"/>
    <xs:element name="GrossMarginPercentConcept" id="id_element1" type="dtr-types:percentItemType" substitutionGroup="xbrli:item" nillable="true" abstract="false" xbrli:periodType="duration"/>
    <xs:element name="SharesOutstandingConcept" id="example_SharesOutstandingConcept" type="xbrli:sharesItemType" substitutionGroup="xbrli:item" nillable="true" abstract="false" xbrli:periodType="duration"/>
    <xs:element name="EarningPerShareConcept" id="example_EarningPerShareConcept" type="dtr-types:perShareItemType" substitutionGroup="xbrli:item" nillable="true" abstract="false" xbrli:periodType="duration"/>
    <xs:element name="CostOfRevenueConcept" id="example_CostOfRevenueConcept" type="xbrli:monetaryItemType" substitutionGroup="xbrli:item" abstract="false" xbrli:balance="debit" xbrli:periodType="duration"/>
    <xs:element name="ExpensesConcept" id="example_ExpensesConcept" type="xbrli:monetaryItemType" substitutionGroup="xbrli:item" abstract="false" xbrli:balance="debit" xbrli:periodType="duration"/>
    <xs:element name="GrossProfitConcept" id="example_GrossProfitConcept" type="xbrli:monetaryItemType" substitutionGroup="xbrli:item" abstract="false" xbrli:balance="credit" xbrli:periodType="duration"/>
    <xs:element name="IncomeStatementConceptAbstract" id="example_IncomeStatementConceptAbstract" type="xbrli:stringItemType" substitutionGroup="xbrli:item" nillable="true" abstract="true" xbrli:periodType="duration"/>
    <xs:element name="IncomeStatementTable" id="example_IncomeStatementTable" type="xbrli:stringItemType" substitutionGroup="xbrldt:hypercubeItem" nillable="true" abstract="true" xbrli:periodType="duration"/>
    <xs:element name="NetProfitConcept" id="example_NetProfitConcept" type="xbrli:monetaryItemType" substitutionGroup="xbrli:item" abstract="false" xbrli:balance="credit" xbrli:periodType="duration"/>
    <xs:element name="ProductMember" id="example_ProductMember" type="nonnum:domainItemType" substitutionGroup="xbrli:item" nillable="true" abstract="true" xbrli:periodType="duration"/>
    <xs:element name="ProductServiceAxis" id="example_ProductServiceAxis" type="xbrli:stringItemType" substitutionGroup="xbrldt:dimensionItem" nillable="true" abstract="true" xbrli:periodType="duration"/>
    <xs:element name="ProductServiceDomain" id="example_ProductServiceDomain" type="nonnum:domainItemType" substitutionGroup="xbrli:item" nillable="true" abstract="true" xbrli:periodType="duration"/>
    <xs:element name="RevenueConcept" id="example_RevenueConcept" type="xbrli:monetaryItemType" substitutionGroup="xbrli:item" abstract="false" xbrli:balance="credit" xbrli:periodType="duration"/>
    <xs:element name="ServiceMember" id="example_ServiceMember" type="nonnum:domainItemType" substitutionGroup="xbrli:item" nillable="true" abstract="true" xbrli:periodType="duration"/>
    <xs:element name="StatementLineItems" id="example_StatementLineItems" type="xbrli:stringItemType" substitutionGroup="xbrli:item" nillable="true" abstract="true" xbrli:periodType="duration"/>
    <xs:element name="BlockedLineItemsAbstract" id="example_BlockedLineItemsAbstract" type="xbrli:stringItemType" substitutionGroup="xbrli:item" nillable="true" abstract="true" xbrli:periodType="instant"/>
    <xs:element name="BlockedLineItemsTable" id="example_BlockedLineItemsTable" type="xbrli:stringItemType" substitutionGroup="xbrldt:hypercubeItem" nillable="true" abstract="true" xbrli:periodType="duration"/>
    <xs:element name="EmptyAxis" id="example_EmptyAxis" type="xbrli:stringItemType" substitutionGroup="xbrldt:dimensionItem" nillable="true" abstract="true" xbrli:periodType="duration"/>
    <xs:element name="BlockedConcept" id="example_BlockedConcept" type="xbrli:monetaryItemType" substitutionGroup="xbrli:item" abstract="false" xbrli:balance="credit" xbrli:periodType="duration"/>
</xs:schema>

Note that the root element for the entry point of the taxonomy is <schema> as any XML schema document.

The schema/taxonomy document relevant components can be analyzed as follows:

3.6.5.2.1 Imports

Importing other schemas and taxonomies to be used in our taxonomy using <import> element as follows:

tag namespace schemaLocation description
import http://www.xbrl.org/2003/instance http://www.xbrl.org/2003/xbrl-instance-2003-12-31.xsd Imports base XBRL instance types
import http://www.xbrl.org/dtr/type/non-numeric http://www.xbrl.org/dtr/type/nonNumeric-2009-12-16.xsd Imports nonNumeric types
import http://xbrl.org/2005/xbrldt http://www.xbrl.org/2005/xbrldt-2005.xsd Imports XBRL Dimensions
import http://www.xbrl.org/dtr/type/2020-01-21 https://www.xbrl.org/dtr/type/2020-01-21/types.xsd Imports data type registry

Within <annotation> schema element we can add documentation describing the document in addition to some information to be used by the processor through the <appinfo>, these information includes but not limited to; defining extended link roles and linkbase references (references to linkbase files).

3.6.5.2.2 Role Types

Defining Extended LinkRoles using <roleType> element as in our example as follows:
The extended link role for the income Statement has URI http://xyz.abc/role/IncomeStatement and can be used on presentation, calculation and definition links:

<link:roleType id="roleType_IncomeStatement" roleURI="http://xyz.abc/role/IncomeStatement">
    <link:definition>10000 - Statement - Income Statement</link:definition>
                <link:usedOn>link:calculationLink</link:usedOn>
                <link:usedOn>link:definitionLink</link:usedOn>
                <link:usedOn>link:presentationLink</link:usedOn>
</link:roleType>

Note the extended link role needs to have a unique @id and @roleURI attributes.

3.6.5.2.3 Linkbases references

Linking to Linkbases files using <linkbaseRef> element as in our example as follows:

tag type arcrole href role description
linkbaseRef simple http://.../linkbase is_tab.xml http://.../NA Table Linkbase
linkbaseRef simple http://.../linkbase is_for.xml http://.../NA Fromula Linkbase (for validation)
linkbaseRef simple http://.../linkbase is_lab_en.xml http://.../labelLinkbaseRef English Labels linkbase
linkbaseRef simple http://.../linkbase is_lab_ar.xml http://.../labelLinkbaseRef Arabic Labels linkbase
linkbaseRef simple http://.../linkbase is_pre.xml http://.../presentationLinkbaseRef Presentation linkbase
linkbaseRef simple http://.../linkbase is_def.xml http://.../definitionLinkbaseRef Definition linkbase (Dimensions)
linkbaseRef simple http://.../linkbase is_cal.xml http://.../calculationLinkbaseRef Calculation linkbase
linkbaseRef simple http://.../linkbase gla_ar.xml http://.../NA Arabic ELR definition


3.6.5.2.4 Taxonomy elements/vocabulary:

The <element> tag is used to define concepts, either concept core dimensions or taxonomy defined dimensions as follows:

tag name id type substitutionGroup nillable abstract periodType balance
Concept Core Dimensions
element GrossMarginPercentConcept id_element1 dtr-types:percentItemType xbrli:item true false duration NA
element SharesOutstandingConcept example_SharesOutstandingConcept xbrli:sharesItemType xbrli:item true false duration NA
element EarningPerShareConcept example_EarningPerShareConcept dtr-types:perShareItemType xbrli:item true false duration NA
element CostOfRevenueConcept example_CostOfRevenueConcept xbrli:monetaryItemType xbrli:item NA false duration debit
element ExpensesConcept example_ExpensesConcept xbrli:monetaryItemType xbrli:item NA false duration debit
element GrossProfitConcept example_GrossProfitConcept xbrli:monetaryItemType xbrli:item NA false duration credit
element NetProfitConcept example_NetProfitConcept xbrli:monetaryItemType xbrli:item NA false duration credit
element RevenueConcept example_RevenueConcept xbrli:monetaryItemType xbrli:item NA false duration credit
element BlockedConcept example_BlockedConcept xbrli:monetaryItemType xbrli:item NA false duration credit
Taxonomy Defined Dimensions
element IncomeStatementConceptAbstract example_IncomeStatementConceptAbstract xbrli:stringItemType xbrli:item true true duration NA
element IncomeStatementTable example_IncomeStatementTable xbrli:stringItemType xbrldt:hypercubeItem true true duration NA
element ProductMember example_ProductMember nonnum:domainItemType xbrli:item true true duration NA
element ProductServiceAxis example_ProductServiceAxis xbrli:stringItemType xbrldt:dimensionItem true true duration NA
element ProductServiceDomain example_ProductServiceDomain nonnum:domainItemType xbrli:item true true duration NA
element ServiceMember example_ServiceMember nonnum:domainItemType xbrli:item true true duration NA
element StatementLineItems example_StatementLineItems xbrli:stringItemType xbrli:item true true duration NA
element BlockedLineItemsAbstract example_BlockedLineItemsAbstract xbrli:stringItemType xbrli:item true true instant NA
element BlockedLineItemsTable example_BlockedLineItemsTable xbrli:stringItemType xbrldt:hypercubeItem true true duration NA
element EmptyAxis example_EmptyAxis xbrli:stringItemType xbrldt:dimensionItem true true duration NA


3.6.5.3 Presentation linkbase

Presentation linkbase is used to define concepts relationships in terms of presentation and rendering, in other words it organizes concepts by defining the order and grouping of concepts within the taxonomy, also it is used for rendering a taxonomy in a human readable format.

Presentation linkbase XML file:(see file)

<?xml version="1.0" encoding="utf-8"?>
<link:linkbase xsi:schemaLocation="http://www.xbrl.org/2003/linkbase http://www.xbrl.org/2003/xbrl-linkbase-2003-12-31.xsd" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:link="http://www.xbrl.org/2003/linkbase">
    <link:documentation>Presentation linkbase for income statement example</link:documentation>
    <link:roleRef roleURI="http://xyz.abc/role/IncomeStatement" xlink:type="simple" xlink:href="is.xsd#roleType_IncomeStatement"/>
    <link:presentationLink xlink:type="extended" xlink:role="http://xyz.abc/role/IncomeStatement">
        <link:presentationArc order="7.0" xlink:type="arc" xlink:arcrole="http://www.xbrl.org/2003/arcrole/parent-child" xlink:from="example_StatementLineItems" xlink:to="example_SharesOutstandingConcept"/>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_SharesOutstandingConcept" xlink:label="example_SharesOutstandingConcept"/>
        <link:presentationArc order="6.0" xlink:type="arc" xlink:arcrole="http://www.xbrl.org/2003/arcrole/parent-child" xlink:from="example_StatementLineItems" xlink:to="example_EarningPerShareConcept"/>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_EarningPerShareConcept" xlink:label="example_EarningPerShareConcept"/>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_IncomeStatementConceptAbstract" xlink:label="example_IncomeStatementConceptAbstract"/>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_IncomeStatementTable" xlink:label="example_IncomeStatementTable"/>
        <link:presentationArc order="1.0" xlink:type="arc" xlink:arcrole="http://www.xbrl.org/2003/arcrole/parent-child" xlink:from="example_IncomeStatementConceptAbstract" xlink:to="example_IncomeStatementTable"/>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_ProductServiceAxis" xlink:label="example_ProductServiceAxis"/>
        <link:presentationArc order="1.0" xlink:type="arc" xlink:arcrole="http://www.xbrl.org/2003/arcrole/parent-child" xlink:from="example_IncomeStatementTable" xlink:to="example_ProductServiceAxis"/>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_ProductServiceDomain" xlink:label="example_ProductServiceDomain"/>
        <link:presentationArc order="1.0" xlink:type="arc" xlink:arcrole="http://www.xbrl.org/2003/arcrole/parent-child" xlink:from="example_ProductServiceAxis" xlink:to="example_ProductServiceDomain"/>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_ProductMember" xlink:label="example_ProductMember"/>
        <link:presentationArc order="1.0" xlink:type="arc" xlink:arcrole="http://www.xbrl.org/2003/arcrole/parent-child" xlink:from="example_ProductServiceDomain" xlink:to="example_ProductMember"/>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_ServiceMember" xlink:label="example_ServiceMember"/>
        <link:presentationArc order="2.0" xlink:type="arc" xlink:arcrole="http://www.xbrl.org/2003/arcrole/parent-child" xlink:from="example_ProductServiceDomain" xlink:to="example_ServiceMember"/>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_StatementLineItems" xlink:label="example_StatementLineItems"/>
        <link:presentationArc order="2.0" xlink:type="arc" xlink:arcrole="http://www.xbrl.org/2003/arcrole/parent-child" xlink:from="example_IncomeStatementTable" xlink:to="example_StatementLineItems"/>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_RevenueConcept" xlink:label="example_RevenueConcept"/>
        <link:presentationArc order="1.0" preferredLabel="http://www.xbrl.org/2003/role/totalLabel" xlink:type="arc" xlink:arcrole="http://www.xbrl.org/2003/arcrole/parent-child" xlink:from="example_StatementLineItems" xlink:to="example_RevenueConcept"/>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_CostOfRevenueConcept" xlink:label="example_CostOfRevenueConcept"/>
        <link:presentationArc order="2.0" preferredLabel="http://www.xbrl.org/2003/role/totalLabel" xlink:type="arc" xlink:arcrole="http://www.xbrl.org/2003/arcrole/parent-child" xlink:from="example_StatementLineItems" xlink:to="example_CostOfRevenueConcept"/>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_GrossProfitConcept" xlink:label="example_GrossProfitConcept"/>
        <link:presentationArc order="3.0" xlink:type="arc" xlink:arcrole="http://www.xbrl.org/2003/arcrole/parent-child" xlink:from="example_StatementLineItems" xlink:to="example_GrossProfitConcept"/>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_ExpensesConcept" xlink:label="example_ExpensesConcept"/>
        <link:presentationArc order="4.0" xlink:type="arc" xlink:arcrole="http://www.xbrl.org/2003/arcrole/parent-child" xlink:from="example_StatementLineItems" xlink:to="example_ExpensesConcept"/>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_NetProfitConcept" xlink:label="example_NetProfitConcept"/>
        <link:presentationArc order="5.0" xlink:type="arc" xlink:arcrole="http://www.xbrl.org/2003/arcrole/parent-child" xlink:from="example_StatementLineItems" xlink:to="example_NetProfitConcept"/>
    </link:presentationLink>
</link:linkbase>

Note that the root element is <linkbase>, which can have only four types of children elements (see linkbase element)

The presentation linkbase relevant components can be analyzed as follows:

3.6.5.3.1 roleRef

Element <roleRef> references the <roleType> declaration in the schema and is repeated for each roleType declared, following is the roleRef from our example:

tag roleURI type href description
roleRef http://xyz.abc/role/IncomeStatement simple is.xsd#roleType_IncomeStatement See roleType
3.6.5.3.2 Relations (arcs)

As mentioned the network of relations is a tree structure with a root, in our case for linkrole http://xyz.abc/role/IncomeStatement the root element is Income Statement [Abstract] that is meant to group together all Income statement elements, the network can be described in a table as follows (@from and @to refers to locators ids):

tag order type arcrole from to preferredLabel
presentationArc 1.0 arc http://www.xbrl.org/2003/arcrole/parent-child example_IncomeStatementConceptAbstract example_IncomeStatementTable NA
presentationArc 1.0 arc http://www.xbrl.org/2003/arcrole/parent-child example_IncomeStatementTable example_ProductServiceAxis NA
presentationArc 2.0 arc http://www.xbrl.org/2003/arcrole/parent-child example_IncomeStatementTable example_StatementLineItems NA
presentationArc 1.0 arc http://www.xbrl.org/2003/arcrole/parent-child example_ProductServiceAxis example_ProductServiceDomain NA
presentationArc 1.0 arc http://www.xbrl.org/2003/arcrole/parent-child example_ProductServiceDomain example_ProductMember NA
presentationArc 2.0 arc http://www.xbrl.org/2003/arcrole/parent-child example_ProductServiceDomain example_ServiceMember NA
presentationArc 1.0 arc http://www.xbrl.org/2003/arcrole/parent-child example_StatementLineItems example_RevenueConcept http://www.xbrl.org/2003/role/totalLabel
presentationArc 2.0 arc http://www.xbrl.org/2003/arcrole/parent-child example_StatementLineItems example_CostOfRevenueConcept http://www.xbrl.org/2003/role/totalLabel
presentationArc 3.0 arc http://www.xbrl.org/2003/arcrole/parent-child example_StatementLineItems example_GrossProfitConcept NA
presentationArc 4.0 arc http://www.xbrl.org/2003/arcrole/parent-child example_StatementLineItems example_ExpensesConcept NA
presentationArc 5.0 arc http://www.xbrl.org/2003/arcrole/parent-child example_StatementLineItems example_NetProfitConcept NA
presentationArc 6.0 arc http://www.xbrl.org/2003/arcrole/parent-child example_StatementLineItems example_EarningPerShareConcept NA
presentationArc 7.0 arc http://www.xbrl.org/2003/arcrole/parent-child example_StatementLineItems example_SharesOutstandingConcept NA

Notes

  • <presentationArc> is used to establish presentation relationships in a presentation network.
  • parent-child arcrole is used for presentation relationship
  • @preferredLabel is used on presentationArc to determine which label role to display (see label linkbase)
  • @order is used on presentationArc to determine the order of appearance of concept when presented.
3.6.5.3.3 Hierarchical View

A hierarchical view of presentation link (Concepts labels are used):

Concept Label* Order within Group depth
10000 - Statement - Income Statement Container
Income Statement [Abstract] 1 Root
Income Statement [Table] 1 2
Product And Service [Axis] 1 3
Product And Service [Domain] 1 4
Product [Member] 1 5
Service [Member] 2 5
Statement [Line Items] 2 3
Total Revenues 1 4
Total Costs of Revenues 2 4
Gross Profit 3 4
Expenses 4 4
Net Profit 5 4
Earnings Per Share 6 4
Shares Outstanding 7 4
* Concepts preferred labels are used in this table

A logical view of the presentation link role will be as follows:

Presentation Link Diagram

Presentation Link Diagram (figure created using draw.io)

3.6.5.4 Calculation linkbase

Calculation linkbase is used to describe calculation relationships between concepts in terms of totals and subtotals, it is important to keep in mind that XBRL itself does not do any calculations, it just describe the calculation relationship between concepts.

Calculation linkbase XML file (see file):

<?xml version="1.0" encoding="utf-8"?>
<link:linkbase xsi:schemaLocation="http://www.xbrl.org/2003/linkbase http://www.xbrl.org/2003/xbrl-linkbase-2003-12-31.xsd" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:link="http://www.xbrl.org/2003/linkbase">
    <link:roleRef roleURI="http://xyz.abc/role/IncomeStatement" xlink:type="simple" xlink:href="is.xsd#roleType_IncomeStatement"/>
    <link:calculationLink xlink:type="extended" xlink:role="http://xyz.abc/role/IncomeStatement">
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_GrossProfitConcept" xlink:label="example_GrossProfitConcept"/>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_RevenueConcept" xlink:label="example_RevenueConcept"/>
        <link:calculationArc order="1.0" weight="1.0" xlink:type="arc" xlink:arcrole="http://www.xbrl.org/2003/arcrole/summation-item" xlink:from="example_GrossProfitConcept" xlink:to="example_RevenueConcept"/>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_CostOfRevenueConcept" xlink:label="example_CostOfRevenueConcept"/>
        <link:calculationArc order="1.0" weight="-1.0" xlink:type="arc" xlink:arcrole="http://www.xbrl.org/2003/arcrole/summation-item" xlink:from="example_GrossProfitConcept" xlink:to="example_CostOfRevenueConcept"/>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_NetProfitConcept" xlink:label="example_NetProfitConcept"/>
        <link:calculationArc order="1.0" weight="1.0" xlink:type="arc" xlink:arcrole="http://www.xbrl.org/2003/arcrole/summation-item" xlink:from="example_NetProfitConcept" xlink:to="example_GrossProfitConcept"/>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_ExpensesConcept" xlink:label="example_ExpensesConcept"/>
        <link:calculationArc order="1.0" weight="-1.0" xlink:type="arc" xlink:arcrole="http://www.xbrl.org/2003/arcrole/summation-item" xlink:from="example_NetProfitConcept" xlink:to="example_ExpensesConcept"/>
    </link:calculationLink>
</link:linkbase>

Calculation linkbase relevant components can be analyzed as follows:

3.6.5.4.1 roleRef

Element <roleRef> references the <roleType> declaration in the schema and is repeated for each roleType declared, following is the `roleRef`` from our example:

tag roleURI type href description
roleRef http://xyz.abc/role/IncomeStatement simple is.xsd#roleType_IncomeStatement See roleType
3.6.5.4.2 Relations (arcs)

The root element in case of calculation relationship is usually the grand total of all other calculations, in our Income Statement the root element is Net Profit for linkrole http://xyz.abc/role/IncomeStatement, the network can be described in a table as follows (@from and @to refers to locators ids):

tag order weight type arcrole from to
calculationArc 1.0 1.0 arc http://www.xbrl.org/2003/arcrole/summation-item example_GrossProfitConcept example_RevenueConcept
calculationArc 1.0 -1.0 arc http://www.xbrl.org/2003/arcrole/summation-item example_GrossProfitConcept example_CostOfRevenueConcept
calculationArc 1.0 1.0 arc http://www.xbrl.org/2003/arcrole/summation-item example_NetProfitConcept example_GrossProfitConcept
calculationArc 1.0 -1.0 arc http://www.xbrl.org/2003/arcrole/summation-item example_NetProfitConcept example_ExpensesConcept

Notes

  • <calculationArc> is used to establish calculation relationships in a calculation network.
  • summation-item arcrole is used for calculation relationship
  • @weight is used on calculationArc to determine if this concept is to be added (@weight=1.0) or subtracted (@weight=-1.0), the concept attribute @balance is used in conjunction with the @weight to determine the appropriate arithmetic operation.
  • @order is used on calculationArc to determine the order of appearance of concept when the calculation relationship is presented.
3.6.5.4.3 Hierarchical View

A hierarchical view of calculation link (Concepts labels are used):

Concept Label* Weight Balance depth
10000 - Statement - Income Statement Container
Net Profit credit Root
(1) Gross Profit 1.0 credit 1
(1) Revenue 1.0 credit 2
(-1) Cost of Revenue -1.0 debit 2
(-1) Expenses -1.0 debit 1
* Concepts preferred labels are used in this table

3.6.5.5 Label linkbase

Label linkbase is an example of Resource Link, it is used to create relationships between concepts and their labels, label here is the Resource. Each concept can have multiple labels describing the concept in different roles, examples of label roles beginning balance or ending balance, also a concept can have labels in multiple languages.

Label link uses <labelArc> to link a concept to its labels, and uses @arcrole http://www.xbrl.org/2003/arcrole/concept-label.

3.6.5.5.1 Label Roles

Each label (resource) is defined using the element <label> from namespace {http://www.xbrl.org/2003/linkbase}. The @role and @xml:lang attributes on the <label> element are used to identify the role of the label and its language. XBRL specifications specify some standard label roles, some of them are as follows:

role meaning
Omitted role attribute OR http://www.xbrl.org/2003/role/label Standard label for a Concept.
http://www.xbrl.org/2003/role/terseLabel Short label for a Concept, often omitting text that should be inferable when the concept is reported in the context of other related concepts.
http://www.xbrl.org/2003/role/verboseLabel Extended label for a Concept, making sure not to omit text that is required to enable the label to be understood on a stand alone basis.
http://www.xbrl.org/2003/role/totalLabel The label for a Concept for use in presenting values associated with the concept when it is being reported as the total of a set of other values.
http://www.xbrl.org/2003/role/periodStartLabel http://www.xbrl.org/2003/role/periodEndLabel http://www.xbrl.org/2003/role/periodEndLabel The label for a Concept with periodType="instant" for use in presenting values associated with the concept when it is being reported as a start (end) of period value.
http://www.xbrl.org/2003/role/documentation Documentation of a Concept, providing an explanation of its meaning and its appropriate usage and any other documentation deemed necessary.
... ...

For the full list of roles (See XBRL Specifications Table 8).

In this example the English labels and Arabic labels are stored in separate files (is_lab_en.xml and is_lab_ar.xml), files displayed below:

Arabic linkbase XML file:(see file)

<?xml version="1.0" encoding="utf-8"?>
<link:linkbase 
      xmlns:xlink="http://www.w3.org/1999/xlink" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xmlns:link="http://www.xbrl.org/2003/linkbase"
      xmlns:label="http://xbrl.org/2008/label"
      xsi:schemaLocation="
      http://www.w3.org/1999/xlink http://www.xbrl.org/2003/xlink-2003-12-31.xsd
      http://www.xbrl.org/2003/linkbase http://www.xbrl.org/2003/xbrl-linkbase-2003-12-31.xsd

      " 
      >
    <link:labelLink xlink:type="extended" xlink:role="http://www.xbrl.org/2003/role/link">
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_IncomeStatementConceptAbstract" xlink:label="example_IncomeStatementConceptAbstract"/>
        <link:labelArc order="1.0" xlink:type="arc" xlink:arcrole="http://www.xbrl.org/2003/arcrole/concept-label" xlink:from="example_IncomeStatementConceptAbstract" xlink:to="label_example_IncomeStatementConceptAbstract"/>
        <link:label xlink:type="resource" xlink:role="http://www.xbrl.org/2003/role/label" xlink:label="label_example_IncomeStatementConceptAbstract" xml:lang="ar">قائمة الدخل [ملخص]</link:label>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_IncomeStatementTable" xlink:label="example_IncomeStatementTable"/>
        <link:labelArc order="1.0" xlink:type="arc" xlink:arcrole="http://www.xbrl.org/2003/arcrole/concept-label" xlink:from="example_IncomeStatementTable" xlink:to="label_example_IncomeStatementTable"/>
        <link:label xlink:type="resource" xlink:role="http://www.xbrl.org/2003/role/label" xlink:label="label_example_IncomeStatementTable" xml:lang="ar">قائمة الدخل [جدول]</link:label>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_ProductServiceAxis" xlink:label="example_ProductServiceAxis"/>
        <link:labelArc order="1.0" xlink:type="arc" xlink:arcrole="http://www.xbrl.org/2003/arcrole/concept-label" xlink:from="example_ProductServiceAxis" xlink:to="label_example_ProductServiceAxis"/>
        <link:label xlink:type="resource" xlink:role="http://www.xbrl.org/2003/role/label" xlink:label="label_example_ProductServiceAxis" xml:lang="ar">منتجات وخدمات [محور]</link:label>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_ProductServiceDomain" xlink:label="example_ProductServiceDomain"/>
        <link:labelArc order="1.0" xlink:type="arc" xlink:arcrole="http://www.xbrl.org/2003/arcrole/concept-label" xlink:from="example_ProductServiceDomain" xlink:to="label_example_ProductServiceDomain"/>
        <link:label xlink:type="resource" xlink:role="http://www.xbrl.org/2003/role/label" xlink:label="label_example_ProductServiceDomain" xml:lang="ar">منتجات وخدمات [نطاق]</link:label>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_ProductMember" xlink:label="example_ProductMember"/>
        <link:labelArc order="1.0" xlink:type="arc" xlink:arcrole="http://www.xbrl.org/2003/arcrole/concept-label" xlink:from="example_ProductMember" xlink:to="label_example_ProductMember"/>
        <link:label xlink:type="resource" xlink:role="http://www.xbrl.org/2003/role/label" xlink:label="label_example_ProductMember" xml:lang="ar">منتجات [عضو]</link:label>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_ServiceMember" xlink:label="example_ServiceMember"/>
        <link:labelArc order="1.0" xlink:type="arc" xlink:arcrole="http://www.xbrl.org/2003/arcrole/concept-label" xlink:from="example_ServiceMember" xlink:to="label_example_ServiceMember"/>
        <link:label xlink:type="resource" xlink:role="http://www.xbrl.org/2003/role/label" xlink:label="label_example_ServiceMember" xml:lang="ar">خدمات [عضو]</link:label>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_StatementLineItems" xlink:label="example_StatementLineItems"/>
        <link:labelArc order="1.0" xlink:type="arc" xlink:arcrole="http://www.xbrl.org/2003/arcrole/concept-label" xlink:from="example_StatementLineItems" xlink:to="label_example_StatementLineItems"/>
        <link:label xlink:type="resource" xlink:role="http://www.xbrl.org/2003/role/label" xlink:label="label_example_StatementLineItems" xml:lang="ar">قائمة [بنود]</link:label>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_RevenueConcept" xlink:label="example_RevenueConcept"/>
        <link:labelArc order="1.0" xlink:type="arc" xlink:arcrole="http://www.xbrl.org/2003/arcrole/concept-label" xlink:from="example_RevenueConcept" xlink:to="label_example_RevenueConcept"/>
        <link:label xlink:type="resource" xlink:role="http://www.xbrl.org/2003/role/label" xlink:label="label_example_RevenueConcept" xml:lang="ar">ايرادات</link:label>
        <link:label xlink:type="resource" xlink:role="http://www.xbrl.org/2003/role/totalLabel" xlink:label="label_example_RevenueConcept" xml:lang="ar">اجمالي الايرادات</link:label>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_CostOfRevenueConcept" xlink:label="example_CostOfRevenueConcept"/>
        <link:labelArc order="1.0" xlink:type="arc" xlink:arcrole="http://www.xbrl.org/2003/arcrole/concept-label" xlink:from="example_CostOfRevenueConcept" xlink:to="label_example_CostOfRevenueConcept"/>
        <link:label xlink:type="resource" xlink:role="http://www.xbrl.org/2003/role/label" xlink:label="label_example_CostOfRevenueConcept" xml:lang="ar">تكلفة الايرادات</link:label>
        <link:label xlink:type="resource" xlink:role="http://www.xbrl.org/2003/role/totalLabel" xlink:label="label_example_CostOfRevenueConcept" xml:lang="ar">اجمالي تكلفة الايرادات</link:label>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_GrossProfitConcept" xlink:label="example_GrossProfitConcept"/>
        <link:labelArc order="1.0" xlink:type="arc" xlink:arcrole="http://www.xbrl.org/2003/arcrole/concept-label" xlink:from="example_GrossProfitConcept" xlink:to="label_example_GrossProfitConcept"/>
        <link:label xlink:type="resource" xlink:role="http://www.xbrl.org/2003/role/label" xlink:label="label_example_GrossProfitConcept" xml:lang="ar">مجمل الربح</link:label>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_ExpensesConcept" xlink:label="example_ExpensesConcept"/>
        <link:labelArc order="1.0" xlink:type="arc" xlink:arcrole="http://www.xbrl.org/2003/arcrole/concept-label" xlink:from="example_ExpensesConcept" xlink:to="label_example_ExpensesConcept"/>
        <link:label xlink:type="resource" xlink:role="http://www.xbrl.org/2003/role/label" xlink:label="label_example_ExpensesConcept" xml:lang="ar">تكاليف</link:label>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_NetProfitConcept" xlink:label="example_NetProfitConcept"/>
        <link:labelArc order="1.0" xlink:type="arc" xlink:arcrole="http://www.xbrl.org/2003/arcrole/concept-label" xlink:from="example_NetProfitConcept" xlink:to="label_example_NetProfitConcept"/>
        <link:label xlink:type="resource" xlink:role="http://www.xbrl.org/2003/role/label" xlink:label="label_example_NetProfitConcept" xml:lang="ar">صافي الربح</link:label>
    <link:labelArc xlink:type="arc" xlink:arcrole="http://www.xbrl.org/2003/arcrole/concept-label" xlink:from="example_EarningPerShareConcept" xlink:to="label_example_EarningPerShareConcept"/>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_EarningPerShareConcept" xlink:label="example_EarningPerShareConcept"/>
        <link:label xlink:type="resource" xlink:role="http://www.xbrl.org/2003/role/label" xlink:label="label_example_EarningPerShareConcept" xml:lang="ar">ربح السهم</link:label>
    <link:labelArc xlink:type="arc" xlink:arcrole="http://www.xbrl.org/2003/arcrole/concept-label" xlink:from="example_SharesOutstandingConcept" xlink:to="label_example_SharesOutstandingConcept"/>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_SharesOutstandingConcept" xlink:label="example_SharesOutstandingConcept"/>
        <link:label xlink:type="resource" xlink:role="http://www.xbrl.org/2003/role/label" xlink:label="label_example_SharesOutstandingConcept" xml:lang="ar">الاسهم المتداولة</link:label>
    </link:labelLink>
</link:linkbase>

English linkbase XML file: (see file)

<?xml version="1.0" encoding="utf-8"?>
<link:linkbase xsi:schemaLocation="http://www.xbrl.org/2003/linkbase http://www.xbrl.org/2003/xbrl-linkbase-2003-12-31.xsd" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:link="http://www.xbrl.org/2003/linkbase">
    <link:labelLink xlink:type="extended" xlink:role="http://www.xbrl.org/2003/role/link">
        <link:labelArc xlink:type="arc" xlink:arcrole="http://www.xbrl.org/2003/arcrole/concept-label" xlink:from="example_EarningPerShareConcept" xlink:to="label_example_EarningPerShareConcept"/>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_EarningPerShareConcept" xlink:label="example_EarningPerShareConcept"/>
        <link:label xlink:type="resource" xlink:role="http://www.xbrl.org/2003/role/label" xlink:label="label_example_EarningPerShareConcept" xml:lang="en">Earnings Per Share</link:label>
        <link:labelArc xlink:type="arc" xlink:arcrole="http://www.xbrl.org/2003/arcrole/concept-label" xlink:from="example_SharesOutstandingConcept" xlink:to="label_example_SharesOutstandingConcept"/>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_SharesOutstandingConcept" xlink:label="example_SharesOutstandingConcept"/>
        <link:label xlink:type="resource" xlink:role="http://www.xbrl.org/2003/role/label" xlink:label="label_example_SharesOutstandingConcept" xml:lang="en">Shares Outstanding</link:label>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_IncomeStatementConceptAbstract" xlink:label="example_IncomeStatementConceptAbstract"/>
        <link:labelArc order="1.0" xlink:type="arc" xlink:arcrole="http://www.xbrl.org/2003/arcrole/concept-label" xlink:from="example_IncomeStatementConceptAbstract" xlink:to="label_example_IncomeStatementConceptAbstract"/>
        <link:label xlink:type="resource" xlink:role="http://www.xbrl.org/2003/role/label" xlink:label="label_example_IncomeStatementConceptAbstract" xml:lang="en">Income Statement [Abstract]</link:label>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_IncomeStatementTable" xlink:label="example_IncomeStatementTable"/>
        <link:labelArc order="1.0" xlink:type="arc" xlink:arcrole="http://www.xbrl.org/2003/arcrole/concept-label" xlink:from="example_IncomeStatementTable" xlink:to="label_example_IncomeStatementTable"/>
        <link:label xlink:type="resource" xlink:role="http://www.xbrl.org/2003/role/label" xlink:label="label_example_IncomeStatementTable" xml:lang="en">Income Statement [Table]</link:label>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_ProductServiceAxis" xlink:label="example_ProductServiceAxis"/>
        <link:labelArc order="1.0" xlink:type="arc" xlink:arcrole="http://www.xbrl.org/2003/arcrole/concept-label" xlink:from="example_ProductServiceAxis" xlink:to="label_example_ProductServiceAxis"/>
        <link:label xlink:type="resource" xlink:role="http://www.xbrl.org/2003/role/label" xlink:label="label_example_ProductServiceAxis" xml:lang="en">Product And Service [Axis]</link:label>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_ProductServiceDomain" xlink:label="example_ProductServiceDomain"/>
        <link:labelArc order="1.0" xlink:type="arc" xlink:arcrole="http://www.xbrl.org/2003/arcrole/concept-label" xlink:from="example_ProductServiceDomain" xlink:to="label_example_ProductServiceDomain"/>
        <link:label xlink:type="resource" xlink:role="http://www.xbrl.org/2003/role/label" xlink:label="label_example_ProductServiceDomain" xml:lang="en">Product And Service [Domain]</link:label>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_ProductMember" xlink:label="example_ProductMember"/>
        <link:labelArc order="1.0" xlink:type="arc" xlink:arcrole="http://www.xbrl.org/2003/arcrole/concept-label" xlink:from="example_ProductMember" xlink:to="label_example_ProductMember"/>
        <link:label xlink:type="resource" xlink:role="http://www.xbrl.org/2003/role/label" xlink:label="label_example_ProductMember" xml:lang="en">Product [Member]</link:label>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_ServiceMember" xlink:label="example_ServiceMember"/>
        <link:labelArc order="1.0" xlink:type="arc" xlink:arcrole="http://www.xbrl.org/2003/arcrole/concept-label" xlink:from="example_ServiceMember" xlink:to="label_example_ServiceMember"/>
        <link:label xlink:type="resource" xlink:role="http://www.xbrl.org/2003/role/label" xlink:label="label_example_ServiceMember" xml:lang="en">Service [Member]</link:label>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_StatementLineItems" xlink:label="example_StatementLineItems"/>
        <link:labelArc order="1.0" xlink:type="arc" xlink:arcrole="http://www.xbrl.org/2003/arcrole/concept-label" xlink:from="example_StatementLineItems" xlink:to="label_example_StatementLineItems"/>
        <link:label xlink:type="resource" xlink:role="http://www.xbrl.org/2003/role/label" xlink:label="label_example_StatementLineItems" xml:lang="en">Statement [Line Items]</link:label>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_RevenueConcept" xlink:label="example_RevenueConcept"/>
        <link:labelArc order="1.0" xlink:type="arc" xlink:arcrole="http://www.xbrl.org/2003/arcrole/concept-label" xlink:from="example_RevenueConcept" xlink:to="label_example_RevenueConcept"/>
        <link:label xlink:type="resource" xlink:role="http://www.xbrl.org/2003/role/label" xlink:label="label_example_RevenueConcept" xml:lang="en">Revenue</link:label>
        <link:label xlink:type="resource" xlink:role="http://www.xbrl.org/2003/role/totalLabel" xlink:label="label_example_RevenueConcept" xml:lang="en">Total Revenues</link:label>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_CostOfRevenueConcept" xlink:label="example_CostOfRevenueConcept"/>
        <link:labelArc order="1.0" xlink:type="arc" xlink:arcrole="http://www.xbrl.org/2003/arcrole/concept-label" xlink:from="example_CostOfRevenueConcept" xlink:to="label_example_CostOfRevenueConcept"/>
        <link:label xlink:type="resource" xlink:role="http://www.xbrl.org/2003/role/label" xlink:label="label_example_CostOfRevenueConcept" xml:lang="en">Cost of Revenue</link:label>
        <link:label xlink:type="resource" xlink:role="http://www.xbrl.org/2003/role/totalLabel" xlink:label="label_example_CostOfRevenueConcept" xml:lang="en">Total Costs of Revenues</link:label>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_GrossProfitConcept" xlink:label="example_GrossProfitConcept"/>
        <link:labelArc order="1.0" xlink:type="arc" xlink:arcrole="http://www.xbrl.org/2003/arcrole/concept-label" xlink:from="example_GrossProfitConcept" xlink:to="label_example_GrossProfitConcept"/>
        <link:label xlink:type="resource" xlink:role="http://www.xbrl.org/2003/role/label" xlink:label="label_example_GrossProfitConcept" xml:lang="en">Gross Profit</link:label>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_ExpensesConcept" xlink:label="example_ExpensesConcept"/>
        <link:labelArc order="1.0" xlink:type="arc" xlink:arcrole="http://www.xbrl.org/2003/arcrole/concept-label" xlink:from="example_ExpensesConcept" xlink:to="label_example_ExpensesConcept"/>
        <link:label xlink:type="resource" xlink:role="http://www.xbrl.org/2003/role/label" xlink:label="label_example_ExpensesConcept" xml:lang="en">Expenses</link:label>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_NetProfitConcept" xlink:label="example_NetProfitConcept"/>
        <link:labelArc order="1.0" xlink:type="arc" xlink:arcrole="http://www.xbrl.org/2003/arcrole/concept-label" xlink:from="example_NetProfitConcept" xlink:to="label_example_NetProfitConcept"/>
        <link:label xlink:type="resource" xlink:role="http://www.xbrl.org/2003/role/label" xlink:label="label_example_NetProfitConcept" xml:lang="en">Net Profit</link:label>
    </link:labelLink>
</link:linkbase>
3.6.5.5.2 roleRef

Element <roleRef> was not used with label link because we do not need to partition the label links by roles (we can do that but was not done in this case), instead the default standard link role http://www.xbrl.org/2003/role/link was used on the labelLink element.

Since label link is a resource link, it does not have a root element, it just links the concept to the resources.

3.6.5.5.3 Label Resources

Table showing label resource declarations:

tag type role id_label lang Label
label resource http://www.xbrl.org/2003/role/label label_example_EarningPerShareConcept en Earnings Per Share
label resource http://www.xbrl.org/2003/role/label label_example_SharesOutstandingConcept en Shares Outstanding
label resource http://www.xbrl.org/2003/role/label label_example_IncomeStatementConceptAbstract en Income Statement [Abstract]
label resource http://www.xbrl.org/2003/role/label label_example_IncomeStatementTable en Income Statement [Table]
label resource http://www.xbrl.org/2003/role/label label_example_ProductServiceAxis en Product And Service [Axis]
label resource http://www.xbrl.org/2003/role/label label_example_ProductServiceDomain en Product And Service [Domain]
label resource http://www.xbrl.org/2003/role/label label_example_ProductMember en Product [Member]
label resource http://www.xbrl.org/2003/role/label label_example_ServiceMember en Service [Member]
label resource http://www.xbrl.org/2003/role/label label_example_StatementLineItems en Statement [Line Items]
label resource http://www.xbrl.org/2003/role/label label_example_RevenueConcept en Revenue
label resource http://www.xbrl.org/2003/role/totalLabel label_example_RevenueConcept en Total Revenues
label resource http://www.xbrl.org/2003/role/label label_example_CostOfRevenueConcept en Cost of Revenue
label resource http://www.xbrl.org/2003/role/totalLabel label_example_CostOfRevenueConcept en Total Costs of Revenues
label resource http://www.xbrl.org/2003/role/label label_example_GrossProfitConcept en Gross Profit
label resource http://www.xbrl.org/2003/role/label label_example_ExpensesConcept en Expenses
label resource http://www.xbrl.org/2003/role/label label_example_NetProfitConcept en Net Profit

Notes

  • Arabic Labels are not shown here due to encoding issues, please see file here.
  • @lang is used to specify the language of the label, this will help switching between label languages in any XBRL processor.
  • @role is used to specify label role, one concept can have many labels but each label should have unique label role.

3.6.5.6 Definition linkbase

Definition Link is used to define relations between concepts that goes beyond calculation or presentation links. Element <definitionLink> is used for the definition network for a linkrRole specified by @role attribute of the <definitionLink> element, <definitionArc> is used to establish the relation between the concepts pairs for the relation specified by the @role attribute of the <definitionArc> element.

XBRL specifications defines some standard definition arcRoles (see XBRL specification section 5.2.6.2), and here are the definitions from THD section 3.4.4.3:

  1. General-special - This relationship indicates that one concept of a pair is a more specialized form of another concept. For instance, in the widget example, the widget type AngularWidgets can be general (referring to any widget type that has angles), while the widget type TriangularWidgets is more specific.
  2. Essence-alias - This relationship indicates that one concept of a pair essentially has the same meaning as the other concept. For example, one reporting entity may use the concept Widgets to refer to its product, and another may prefer the concept Gizmos, but the underlying meaning, that these concepts are products, is the same. The essence-alias definition reflects a change in terminology rather than semantic meaning.
  3. Requires-element - This relationship indicates that the value of one concept is required when the value of the other concept in the pair is present. For example, in the widget report with both concept core dimensions WidgetsSold and PricePerWidget, PricePerWidget requires a value for WidgetsSold.
  4. Similar-tuples - This relationship is operationally the same as the essence-alias definition but reserved for usage with tuples. Tuples are not commonly used.

Additionally, the XBRL Dimensions Specification allows for more definition types. These types are used to define the relationships pertaining to the components of a dimension in XBRL. The definitions exist between a concept and a taxonomy-defined dimension to define the hierarchical relationship between them. Examples of each can be seen in Figure 3-10.

  1. Dimension-default - This relationship indicates that the concept is the default value for the taxonomy-defined dimension.
  2. Dimension-domain - This relationship indicates that the concept represents the domain of the taxonomy-defined dimension.
  3. Domain-member - This relationship indicates that one concept is a member of the domain of the other concept that is part of a taxonomy-defined dimension. This relationship can exist between many concepts. For example, a Northeast member may belong to a GeographicLocation axis, but comprising this Northeast member is a group of northeastern states in the US. These each have the domain-member relationship with the Northeast concept.

In addition to the above, XBRL Dimensions Specifications defines the following relations:

  • all and notAll: together also referred to as has hypercube is a relation between a primary item declaration and a hypercube item, the all relations means that the primary item can be used with all the dimensions included in the hypercube, notAll means that the primary item cannot be used with any dimension in the hypercube. In addition to defining dimensional relation

  • The @closed attribute of a hypercube that takes a true/false value, if true it specifies that all taxonomy-defined dimensions in the hypercube must intersect on a fact in order for that fact to be part of the hypercube, if false any of the taxonomy-defined dimensions in the hypercube can intersect on a fact in order for that fact to be part of the hypercube.

  • hypercube-dimension a relation between a hypercube and a dimension.

  • Sometimes authors of an extension taxonomy may want to prohibit the use of some primary items from an imported taxonomy, one of the ways to so is by linking the prohibited items to an empty hypercube (a hypercube with one dimension that does not have any members), and this will result in a validation error if any of these concepts is used.

In our example, definition linkbase contains only dimensional relationship to create the income statement table with Product And Service dimensions.

Definition linkbase XML file:(see file)

<?xml version="1.0" encoding="utf-8"?>
<link:linkbase xsi:schemaLocation="http://www.xbrl.org/2003/linkbase http://www.xbrl.org/2003/xbrl-linkbase-2003-12-31.xsd" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:link="http://www.xbrl.org/2003/linkbase" xmlns:xbrldt="http://xbrl.org/2005/xbrldt">
    <link:roleRef roleURI="http://xyz.abc/role/IncomeStatement" xlink:type="simple" xlink:href="is.xsd#roleType_IncomeStatement"/>
    <link:roleRef roleURI="http://xyz.abc/role/BlockedConceptsSegment" xlink:type="simple" xlink:href="is.xsd#BlockedConceptsSegmentRole"/>
    <link:arcroleRef arcroleURI="http://xbrl.org/int/dim/arcrole/hypercube-dimension" xlink:type="simple" xlink:href="http://www.xbrl.org/2005/xbrldt-2005.xsd#hypercube-dimension"/>
    <link:arcroleRef arcroleURI="http://xbrl.org/int/dim/arcrole/dimension-domain" xlink:type="simple" xlink:href="http://www.xbrl.org/2005/xbrldt-2005.xsd#dimension-domain"/>
    <link:arcroleRef arcroleURI="http://xbrl.org/int/dim/arcrole/domain-member" xlink:type="simple" xlink:href="http://www.xbrl.org/2005/xbrldt-2005.xsd#domain-member"/>
    <link:arcroleRef arcroleURI="http://xbrl.org/int/dim/arcrole/all" xlink:type="simple" xlink:href="http://www.xbrl.org/2005/xbrldt-2005.xsd#all"/>
    <link:arcroleRef arcroleURI="http://xbrl.org/int/dim/arcrole/dimension-default" xlink:type="simple" xlink:href="http://www.xbrl.org/2005/xbrldt-2005.xsd#dimension-default"/>
    <link:definitionLink xlink:type="extended" xlink:role="http://xyz.abc/role/IncomeStatement">
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_IncomeStatementConceptAbstract" xlink:label="example_IncomeStatementConceptAbstract"/>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_StatementLineItems" xlink:label="example_StatementLineItems"/>
        <link:definitionArc order="1.0" xlink:type="arc" xlink:arcrole="http://xbrl.org/int/dim/arcrole/domain-member" xlink:from="example_IncomeStatementConceptAbstract" xlink:to="example_StatementLineItems"/>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_IncomeStatementTable" xlink:label="example_IncomeStatementTable"/>
        <link:definitionArc order="1.0" xlink:type="arc" xlink:arcrole="http://xbrl.org/int/dim/arcrole/all" xlink:from="example_StatementLineItems" xlink:to="example_IncomeStatementTable" xbrldt:closed="true" xbrldt:contextElement="segment"/>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_ProductServiceAxis" xlink:label="example_ProductServiceAxis"/>
        <link:definitionArc order="1.0" xlink:type="arc" xlink:arcrole="http://xbrl.org/int/dim/arcrole/hypercube-dimension" xlink:from="example_IncomeStatementTable" xlink:to="example_ProductServiceAxis"/>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_ProductServiceDomain" xlink:label="example_ProductServiceDomain"/>
        <link:definitionArc order="1.0" xlink:type="arc" xlink:arcrole="http://xbrl.org/int/dim/arcrole/dimension-domain" xlink:from="example_ProductServiceAxis" xlink:to="example_ProductServiceDomain"/>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_ProductMember" xlink:label="example_ProductMember"/>
        <link:definitionArc order="2.0" xlink:type="arc" xlink:arcrole="http://xbrl.org/int/dim/arcrole/domain-member" xlink:from="example_ProductServiceDomain" xlink:to="example_ProductMember"/>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_ServiceMember" xlink:label="example_ServiceMember"/>
        <link:definitionArc order="3.0" xlink:type="arc" xlink:arcrole="http://xbrl.org/int/dim/arcrole/domain-member" xlink:from="example_ProductServiceDomain" xlink:to="example_ServiceMember"/>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_RevenueConcept" xlink:label="example_RevenueConcept"/>
        <link:definitionArc order="2.0" xlink:type="arc" xlink:arcrole="http://xbrl.org/int/dim/arcrole/domain-member" xlink:from="example_StatementLineItems" xlink:to="example_RevenueConcept"/>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_CostOfRevenueConcept" xlink:label="example_CostOfRevenueConcept"/>
        <link:definitionArc order="3.0" xlink:type="arc" xlink:arcrole="http://xbrl.org/int/dim/arcrole/domain-member" xlink:from="example_StatementLineItems" xlink:to="example_CostOfRevenueConcept"/>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_GrossProfitConcept" xlink:label="example_GrossProfitConcept"/>
        <link:definitionArc order="4.0" xlink:type="arc" xlink:arcrole="http://xbrl.org/int/dim/arcrole/domain-member" xlink:from="example_StatementLineItems" xlink:to="example_GrossProfitConcept"/>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_ExpensesConcept" xlink:label="example_ExpensesConcept"/>
        <link:definitionArc order="5.0" xlink:type="arc" xlink:arcrole="http://xbrl.org/int/dim/arcrole/domain-member" xlink:from="example_StatementLineItems" xlink:to="example_ExpensesConcept"/>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_NetProfitConcept" xlink:label="example_NetProfitConcept"/>
        <link:definitionArc order="6.0" xlink:type="arc" xlink:arcrole="http://xbrl.org/int/dim/arcrole/domain-member" xlink:from="example_StatementLineItems" xlink:to="example_NetProfitConcept"/>
    </link:definitionLink>
    <link:definitionLink xlink:type="extended" xlink:role="http://xyz.abc/role/IncomeStatement">
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_ProductServiceAxis" xlink:label="example_ProductServiceAxis"/>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_ProductServiceDomain" xlink:label="example_ProductServiceDomain"/>
        <link:definitionArc order="3.0" xlink:type="arc" xlink:arcrole="http://xbrl.org/int/dim/arcrole/dimension-default" xlink:from="example_ProductServiceAxis" xlink:to="example_ProductServiceDomain"/>
    </link:definitionLink>
    <!-- To test concept blocking -->
    <!-- <link:definitionLink xlink:type="extended" xlink:role="http://xyz.abc/role/BlockedConceptsSegment">
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_BlockedLineItemsAbstract" xlink:label="example_BlockedLineItemsAbstract"/>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_BlockedLineItemsTable" xlink:label="example_BlockedLineItemsTable"/>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_EmptyAxis" xlink:label="example_EmptyAxis"/>
        <link:loc xlink:type="locator" xlink:href="is.xsd#example_BlockedConcept" xlink:label="example_BlockedConcept"/>
        <link:definitionArc order="1.0" xlink:type="arc" xlink:arcrole="http://xbrl.org/int/dim/arcrole/all" xlink:from="example_BlockedLineItemsAbstract" xlink:to="example_BlockedLineItemsTable" xbrldt:closed="true" xbrldt:contextElement="segment"/>
        <link:definitionArc order="1.0" xlink:type="arc" xlink:arcrole="http://xbrl.org/int/dim/arcrole/hypercube-dimension" xlink:from="example_BlockedLineItemsTable" xlink:to="example_EmptyAxis"/>
        <link:definitionArc order="1.0" xlink:type="arc" xlink:arcrole="http://xbrl.org/int/dim/arcrole/domain-member" xlink:from="example_BlockedLineItemsAbstract" xlink:to="example_BlockedConcept"/>
    </link:definitionLink> -->
</link:linkbase>
3.6.5.6.1 roleRef and arcroleRef

Element <roleRef> references the <roleType> declaration in the schema and is repeated for each roleType declared, following is the `roleRef`` from our example:

tag roleURI type href arcroleURI
roleRef http://xyz.abc/role/IncomeStatement simple is.xsd#roleType_IncomeStatement NA
roleRef http://xyz.abc/role/BlockedConceptsSegment simple is.xsd#BlockedConceptsSegmentRole NA
arcroleRef NA simple http://www.xbrl.org/2005/xbrldt-2005.xsd#hypercube-dimension http://xbrl.org/int/dim/arcrole/hypercube-dimension
arcroleRef NA simple http://www.xbrl.org/2005/xbrldt-2005.xsd#dimension-domain http://xbrl.org/int/dim/arcrole/dimension-domain
arcroleRef NA simple http://www.xbrl.org/2005/xbrldt-2005.xsd#domain-member http://xbrl.org/int/dim/arcrole/domain-member
arcroleRef NA simple http://www.xbrl.org/2005/xbrldt-2005.xsd#all http://xbrl.org/int/dim/arcrole/all
arcroleRef NA simple http://www.xbrl.org/2005/xbrldt-2005.xsd#dimension-default http://xbrl.org/int/dim/arcrole/dimension-default

Note arcroleRef is used to reference arcroles declared in XBRL Dimensions specifications.

3.6.5.6.2 Relations (arcs)

In this example only relations from XBRL dimensions are used in the definition linkbase for the linkrole http://xyz.abc/role/IncomeStatement. The dimensional relations are somewhat similar to presentation relations in form, but with different processing instructions. The root element is also Income Statement [Abstract] that is meant to group together all Income statement hypercubes, the network can be described in a table as follows (@from and @to refers to locators ids):

tag order type arcrole from to closed contextElement
definitionArc 1.0 arc http://xbrl.org/int/dim/arcrole/domain-member example_IncomeStatementConceptAbstract example_StatementLineItems NA NA
definitionArc 1.0 arc http://xbrl.org/int/dim/arcrole/hypercube-dimension example_IncomeStatementTable example_ProductServiceAxis NA NA
definitionArc 1.0 arc http://xbrl.org/int/dim/arcrole/dimension-domain example_ProductServiceAxis example_ProductServiceDomain NA NA
definitionArc 3.0 arc http://xbrl.org/int/dim/arcrole/dimension-default example_ProductServiceAxis example_ProductServiceDomain NA NA
definitionArc 2.0 arc http://xbrl.org/int/dim/arcrole/domain-member example_ProductServiceDomain example_ProductMember NA NA
definitionArc 3.0 arc http://xbrl.org/int/dim/arcrole/domain-member example_ProductServiceDomain example_ServiceMember NA NA
definitionArc 1.0 arc http://xbrl.org/int/dim/arcrole/all example_StatementLineItems example_IncomeStatementTable true segment
definitionArc 2.0 arc http://xbrl.org/int/dim/arcrole/domain-member example_StatementLineItems example_RevenueConcept NA NA
definitionArc 3.0 arc http://xbrl.org/int/dim/arcrole/domain-member example_StatementLineItems example_CostOfRevenueConcept NA NA
definitionArc 4.0 arc http://xbrl.org/int/dim/arcrole/domain-member example_StatementLineItems example_GrossProfitConcept NA NA
definitionArc 5.0 arc http://xbrl.org/int/dim/arcrole/domain-member example_StatementLineItems example_ExpensesConcept NA NA
definitionArc 6.0 arc http://xbrl.org/int/dim/arcrole/domain-member example_StatementLineItems example_NetProfitConcept NA NA

Notes

  • <definitionArc> is used to establish dimensional relationships.
  • arcroles used are defined in XBRL Dimensions specifications.
  • @closed and @contexElement on <definitionArc> relation between example_StatementLineItems and example_IncomeStatementTable with role http://xbrl.org/int/dim/arcrole/all are used to specify that all taxonomy-defined dimensions in the hypercube must intersect on a fact in order for that fact to be part of the hypercube, and the dimensions must be segment dimensions (i.e. linked through context segment).
  • @order is used on definitionArc to determine the order of appearance of concept when presented.
3.6.5.6.3 Hierarchical View

A hierarchical view of presentation link (Concepts labels are used):

Concept Label* arcrole depth
10000 - Statement - Income Statement Container
Income Statement [Abstract] Root
Statement [Line Items] domain-member 1
Income Statement [Table] all 2
Product And Service [Axis] hypercube-dimension 3
Product And Service [Domain] dimension-domain 4
Product [Member] domain-member 5
Service [Member] domain-member 5
Revenue domain-member 2
Cost of Revenue domain-member 2
Gross Profit domain-member 2
Expenses domain-member 2
Net Profit domain-member 2
* Concepts preferred labels are used in this table

3.6.5.7 Instance Document

Instance document is where current report data is reported using XBRL syntax (see section 3.7.3.4). In our example we can analyze the components of our instance document as follows:(see instance file)

3.6.5.7.1 References

In our example, the instance document has only on reference <schemaRef>, whih is a mandatory element that must exist atleast once as child to <xbrl> element.

tag href type
schemaRef is.xsd simple
3.6.5.7.2 contexts

As mentioned, <context> is an element used only in XBRL instance document, it acts as a container for some core dimension and taxonomy defined dimensions, and it is referenced by facts in an instance document to give contextual meaning to the fact.

In our example, following contexts were defined in the instance document:

tag id Entity Identifier Entity Identifier Schema Entity Segment Dim Entity Segment Member Period startDate Period endDate Period Instant
context c-01 Example-IS http://www.any.gov/identifier NA NA 2020-01-01 2020-12-30 NA
context c-02 Example-IS http://www.any.gov/identifier example:ProductServiceAxis example:ProductMember 2020-01-01 2020-12-30 NA
context c-03 Example-IS http://www.any.gov/identifier example:ProductServiceAxis example:ServiceMember 2020-01-01 2020-12-30 NA
context c-04 Example-IS http://www.any.gov/identifier NA NA 2019-01-01 2019-12-30 NA
context c-05 Example-IS http://www.any.gov/identifier example:ProductServiceAxis example:ProductMember 2019-01-01 2019-12-30 NA
context c-06 Example-IS http://www.any.gov/identifier example:ProductServiceAxis example:ServiceMember 2019-01-01 2019-12-30 NA
context c-07 Example-IS http://www.any.gov/identifier NA NA NA NA 2020-12-31
context c-08 Example-IS http://www.any.gov/identifier NA NA NA NA 2019-12-31

Notes
* Each context must have unique ID.
* Each context must contain one <entity> element that identifies the reporting entity, <entity> element may contain a segment element that references a dimension and a domain member for dimensional relations.
* Each context must have a <period> element that identifies the instant or duration for a reported fact, also note there is a period type forever used for facts that do not have a specific period dimension, for example, the name of the founder of a company can be a fact that does not have specific period.

3.6.5.7.3 Units

XBRL specification requires all numeric facts to have a unit of measurement (see XBRL specifications section 4.6.2). In our instance document, following units were declared to be referenced by facts:

tag id measure Divide Numerator Divide Denominator
unit u-01 iso4217:EGP NA NA
unit u-02 NA iso4217:EGP shares
unit u-03 shares NA NA

Note: The unit referenced by a fact needs to be compatible with the the type of that fact, for example EarningsPerShare concept will usually have a perShareItemType and the unit should be a per share also.

3.6.5.7.4 Facts

Details of facts in the instance is as follows:

tag contextRef decimals id unitRef value
RevenueConcept c-01 2 facts.r_f001.value u-01 5000
RevenueConcept c-02 2 facts.r_f002.value u-01 2000
RevenueConcept c-03 2 facts.r_f003.value u-01 3000
CostOfRevenueConcept c-01 2 facts.r_f004.value u-01 3000
CostOfRevenueConcept c-02 2 facts.r_f005.value u-01 1000
CostOfRevenueConcept c-03 2 facts.r_f006.value u-01 2000
GrossProfitConcept c-01 2 facts.r_f007.value u-01 2000
GrossProfitConcept c-02 2 facts.r_f008.value u-01 1000
GrossProfitConcept c-03 2 facts.r_f009.value u-01 1000
ExpensesConcept c-01 2 facts.r_f010.value u-01 500
NetProfitConcept c-01 2 facts.r_f011.value u-01 1500
RevenueConcept c-04 2 facts.r_f012.value u-01 4000
RevenueConcept c-05 2 facts.r_f013.value u-01 2500
RevenueConcept c-06 2 facts.r_f014.value u-01 1500
CostOfRevenueConcept c-04 2 facts.r_f015.value u-01 2250
CostOfRevenueConcept c-05 2 facts.r_f016.value u-01 1250
CostOfRevenueConcept c-06 2 facts.r_f017.value u-01 1000
GrossProfitConcept c-04 2 facts.r_f018.value u-01 1750
GrossProfitConcept c-05 2 facts.r_f019.value u-01 1250
GrossProfitConcept c-06 2 facts.r_f020.value u-01 500
ExpensesConcept c-04 2 facts.r_f021.value u-01 420
NetProfitConcept c-04 2 facts.r_f022.value u-01 1330

Notes of fact attributes @decimal and @precision:

A Numeric Item MUST have either a @precision attribute or a @decimals attribute unless it is of the fractionItemType or of a type that is derived by restriction from fractionItemType or has a nil value, in which case, it MUST NOT have either a @precision attribute or a @decimals attribute.
  • @decimal: This attribute MUST be an integer or the value “INF” that specifies the number of decimal places to which the value of the fact represented may be considered accurate, possibly as a result of rounding or truncation, a negative integer means that the value is truncated, for example if @decimal=-6 then the value is in Millions. (See XBRL Specifications 4.6.5).
  • @precision: This attribute MUST be a non-negative integer or the string “INF” that conveys the arithmetic precision of a measurement. If a numeric fact has a @precision attribute that has the value “n” then it is correct to “n” significant figures (See XBRL Specifications 4.6.4).

Also see support recommendation for precision and decimal.

3.6.6 XBRL Validation

3.6.6.1 Validation in XBRL Specification

XBRL Specifications requires that XBRL Instance, XBRL Linkbases and XBRL Taxonomy Schema must comply with the specifications, and this compliance is ensured through Validation process XBRL specifications section 3.4.

Many of XBRL syntax is expressed using XML Schema, as a result, a part of the validation process can be performed using XML Schema validation, other parts must be handled by other validation technologies.

3.6.6.2 Two layers of validation

Generally speaking there are two layers of validation, Basic Validation and Business Rules validation (terminology may differ here, but meaning will remains the same).

3.6.6.2.1 Basic Vaildation

Checks for syntax and XBRL specifications rules compliance, the basic validation rules will be the same in all situations, since it just checking for compliance with XBRL specifications. Basic validation includes many facets as follows:

  • Syntax Validation: Checks if validity of format and validity against a schema.
  • Data Type Validation: checks the data type of the value matches the data type of its concept core dimension. For example, ensuring that strings are not reported against concepts which should take numeric values.
  • Concept Relationship-based Validation: These are validation based on XBRL links, as described in TDH section 6.1.3 page 87:
These include, but are not limited to, relationships defined by calculation, definition, and presentation linkbases. The relationship arcs connecting concepts can aid developers (and preparers) in ensuring both the semantic logic of the relationship and that the concepts involved are used properly.
3.6.6.2.2 Business Rules Validation

On the other hand Business Rules Validation checks for compliance with rules specific to the taxonomy, and those will differ depending on the taxonomy authors’ objectives and rules. This makes it necessary to come up with custom validations that checks for compliance with specific business rules.

Custom rule validation can be built into validation software, as an example, Arelle has multiple plugins that validates different sets of specific business rules, such as Edgar Filing Manual (EFM) rules (SEC rules), IFRS rules, Eurpean Banking Authority (EBA) rules, … etc.

Arelle Validation Options

Arelle Validation Options

XBRL provides standardized tools to help in setting custom rules, these are XBRL Formulae, and XULE (based on XBRL Formula specifications).

XBRL Formula
XBRL Formula specifications provide XBRL constructs that instructs XBRL processor to preform certain procedures on an XBRL Instance. TDH section 6.2.1 page 88 describes XBRL Formula as follows:

XBRL formulas provide a standardized method for defining validation rules for XBRL reports that go beyond what is provided through calculations and other concept relationships. Through formulas, the validation rules can be embedded in the taxonomy itself. This allows the taxonomy to be easily disseminated with its validation rules, which reduces the chance for preparers to misinterpret them or have difficulty locating them. XBRL formula rules are placed in their own linkbase, often termed the assertion or formula linkbase. XBRL software capable of reading and interpreting this linkbase can apply the rules and display the results to preparers.

So in addition to the linkbases we talked about previously, a taxonomy can have a Formula Linkbase. XBRL formula can do four things (four processing models):

  • Value assertion: Checks fact variable against some criteria, for example, Cash balance is greater than zero.
  • Existence Assertion: Checks for the existence for specific fact exist in an XBRL Instance, for example, when there is a rule to report a specific fact, such as company identification number.
  • Formula: Formulas are constructs in a formula linkbase that cause production of fact items, for example calculate liquidity ratio. This useful in data extraction from an instance document even though this is not the intended use of formula.
  • Consistency Assertion: A consistency assertion specifies how to determine whether an output fact, produced by the associated formula matches reported facts, for example is Liabilities $10 and Equity is $5, we expect Assets to be $15 (equality is determined within a tolerance margin).
Figures 2 and 3 in XBRL Formula Overview summarizes the processing models as follows:

Four processing models effects

Four processing models effects source XBRL Formula overview

Examples for each processing model

Examples for each processing model source XBRL Formula overview

IFRS Taxonomy is an example of a taxonomy that uses formula to validate custom rules for XBRL filings based on the IFRS Taxonomy. IFRS formula linkbase guide found here.

XULE
XULE is an expression syntax that allows the querying of XBRL reports and taxonomies using a XULE processor, it is described in [TDH section 6.2.2 page 99] as follows:

Developed by XBRL US, XULE is an expression syntax that allows the querying of XBRL reports and taxonomies using a XULE processor. The primary purpose of XULE is to provide a user-friendly syntax to query and manipulate XBRL data. This can be helpful in a multitude of ways, including aiding consumers in quickly extracting specific facts from reports and supporting developers in querying XBRL taxonomies to render them as open API schemas or as iXBRL forms.

Example of the syntax for XULE:

namespace http://xyz.abc/IncomeStatementExample

// Calculate gross margin by dimension
output gross-margin
$gross-profit=@GrossProfitConcept
$revenue = @RevenueConcept
$dims = $revenue.dimensions-explicit
$lab = if (length($dims.values.label(None,'en').text)>0)
         ($dims.values.label(None,'en').text)[1]
        else "Total"
        
// Print output
"Gross Margin for {$revenue.period} {$lab} = {round( $gross-profit / $revenue, 3 )}%"

// Query all facts with value more than EGP 2000
output big-facts
{@concept where $fact > 2000}

Full guide for XULE is available here.

3.6.7 XBRL Table Linkbase

XBRL Table Linkbase specifications provides a mechanism for taxonomy authors to define a tabular layout of facts. The resulting tables can be used for both presentation and data entry.

Table linkbase is logically similar to Presentation Linkbase but with a lot more features. It allows for a standard way for defining views of concepts defined in a taxonomy, as mentioned in the specification overview:

Table linkbase enables the definition of tables with multiple axes. The components of these axes are not limited to individual items; instead, they can be defined in terms of a combination of dimensions, time period references, units, entities or any other property that can be used to identify the financial facts represented by taxonomies.

3.6.7.1 Table Models

Table linkbase specifications define 3 models Structural Model, Definition Model and layout model.Definition Model defines the content of a table in terms of concepts and aspects using relationships in DTS, Definition Model is transformed to Structural model through process of resolution, the syntax provides a direct description of the definition model. Structural Model defines the the shape of the table in terms of hierarchical breakdowns of fact space, while layout Model is the direct representation of the structure and content.

Table Models

Table Models (Source: Table Linkbase Overview 1.0)

The basic idea of XBRL Table is that it filters and presents facts in specific layout according to the table definition and structure.

Terms relevant for the XBRL table linkbase:

Fact Source: A fact source is a container for XBRL facts, for example it maybe an existing XBRL instance, fact source contains the set of facts that are to be considered for inclusion in the table.

Domain of a Table: Is the restricted fact space defined by the combination of constraints from all of the table’s breakdowns, along with any additional global constraints specified using table filters.

Axis: An axis defines an ordered mapping of XBRL fact space onto a line.

  • The x-axis SHOULD be interpreted as a horizontal arrangement of columns in a table. Columns MAY be laid out from left to right, or right to left, according to the language conventions.
  • The y-axis SHOULD be interpreted as a vertical progression of rows in a table. Rows SHOULD be laid out from top to bottom.
  • The z-axis MAY be interpreted as multiple two-dimensional tables and MAY be laid out on a two-dimensional display by presenting each table in series or by supplying controls for the user to select the data to be presented.

Breakdown: A breakdown defines a logically distinct breakdown of the fact space by sets of constraints. A breakdown is modeled as an ordered tree of structural nodes. Each of these nodes contributes zero or more constraints to the breakdown.

  • A closed breakdown is defined as a breakdown whose sequence of constraint sets can be determined independently of the facts to be included.
  • An open breakdown is defined as a breakdown whose sequence of constraint sets changes dynamically with the facts included and thus cannot be completely determined without knowledge of those facts.

Structural Node: A structural node is a node in a breakdown tree. Each node contributes zero or more constraints to the breakdown.

  • A closed structural node is a structural node with constraints fully determined by its definition and the DTS.
  • An open structural node is a structural node that does not fully define aspect value constraints and does not necessarily have a one-to-one relationship with layout nodes produced during resolution.

Definition node: A definition node is a definition of zero or more structural nodes in the structural model.

  • A closed definition node is a definition node which resolves to one or more closed structural nodes.
  • An open definition node is a definition node which resolves to an open structural node.

Table: represents a breakdown of XBRL fact space for the purpose of defining a reference view of XBRL data.

  • A closed table is defined as a table that consists only of closed breakdowns.
  • An open table is defined as a table whose constituent breakdowns include at least one open breakdown.

3.6.7.2 Table linkbase components

Table linkbase define a table in terms of relationships between components defined in table linkbase. Table linkbase uses generic link as the container link, within the generic link, a table is defined using relationships arcs and elements defined in table linkbase.

Table linkbase uses link syntax to define a table element, then links that table to an x (rows) and y (columns) axes, each axis is then linked to a breakdown element, which acts a container for filter elements that filters the facts to be shown in the table. This logic can be visualized as follows:

Table Definition Model

Table Definition Model (Source: Table Linkbase Specifications 1.0)

Following is a table linkbase that creates a table from the Income Statement example, the table memics exactly the income statement:(see Table Linkbase file)

<?xml version="1.0"?>
<link:linkbase xsi:schemaLocation="http://www.xbrl.org/2003/linkbase http://www.xbrl.org/2003/xbrl-linkbase-2003-12-31.xsd http://xbrl.org/2008/generic http://www.xbrl.org/2008/generic-link.xsd http://xbrl.org/2014/table http://www.xbrl.org/2014/table.xsd http://xbrl.org/2008/label http://www.xbrl.org/2008/generic-label.xsd http://xbrl.org/2010/filter/concept-relation http://www.xbrl.org/2010/concept-relation-filter.xsd http://xbrl.org/2008/filter/dimension http://www.xbrl.org/2008/dimension-filter.xsd" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:link="http://www.xbrl.org/2003/linkbase" xmlns:gen="http://xbrl.org/2008/generic" xmlns:label="http://xbrl.org/2008/label" xmlns:table="http://xbrl.org/2014/table" xmlns:example="http://xyz.abc/IncomeStatementExample">
    <link:arcroleRef arcroleURI="http://xbrl.org/arcrole/2014/aspect-node-filter" xlink:type="simple" xlink:href="http://www.xbrl.org/2014/table.xsd#aspect-node-filter" />
    <link:arcroleRef arcroleURI="http://xbrl.org/arcrole/2014/definition-node-subtree" xlink:type="simple" xlink:href="http://www.xbrl.org/2014/table.xsd#definition-node-subtree" />
    <link:arcroleRef arcroleURI="http://xbrl.org/arcrole/2014/breakdown-tree" xlink:type="simple" xlink:href="http://www.xbrl.org/2014/table.xsd#breakdown-tree" />
    <link:arcroleRef arcroleURI="http://xbrl.org/arcrole/2014/table-filter" xlink:type="simple" xlink:href="http://www.xbrl.org/2014/table.xsd#table-filter" />
    <link:arcroleRef arcroleURI="http://xbrl.org/arcrole/2014/table-breakdown" xlink:type="simple" xlink:href="http://www.xbrl.org/2014/table.xsd#table-breakdown" />
    <link:arcroleRef arcroleURI="http://xbrl.org/arcrole/2008/element-label" xlink:type="simple" xlink:href="http://www.xbrl.org/2008/generic-label.xsd#element-label" />
    <link:roleRef roleURI="http://www.xbrl.org/2008/role/label" xlink:type="simple" xlink:href="http://www.xbrl.org/2008/generic-label.xsd#standard-label" />
    <link:roleRef roleURI="http://www.xbrl.org/2008/role/link" xlink:type="simple" xlink:href="http://www.xbrl.org/2008/generic-link.xsd#standard-link-role" />
    <gen:link xlink:type="extended" xlink:role="http://www.xbrl.org/2008/role/link">

        <!-- Create Table -->
        <table:table id="table" xlink:type="resource" xlink:label="table" />
        
        <!-- Create first  break down for y axis-->
        <table:breakdown id="y-axis-concepts" xlink:type="resource" xlink:label="y-axis-concepts" />
        
        <!-- Link break down to table  -->
        <table:tableBreakdownArc order="2.0" axis="y" xlink:type="arc" xlink:arcrole="http://xbrl.org/arcrole/2014/table-breakdown" xlink:from="table" xlink:to="y-axis-concepts" />

        <!-- Create concept relation node for y axis (returns all parent-child relations for statementLineItems element) -->
        <table:conceptRelationshipNode id="conceptRelationshipNode" xlink:type="resource" xlink:label="conceptRelationshipNode">
            <table:relationshipSource>example:StatementLineItems</table:relationshipSource>
            <table:linkrole>http://xyz.abc/role/IncomeStatement</table:linkrole>
            <table:arcrole>http://www.xbrl.org/2003/arcrole/parent-child</table:arcrole>
            <table:formulaAxis>child</table:formulaAxis>
        </table:conceptRelationshipNode>

        <!-- Link concept relation node to y axis breakdown -->
        <table:breakdownTreeArc order="1.0" xlink:type="arc" xlink:arcrole="http://xbrl.org/arcrole/2014/breakdown-tree" xlink:from="y-axis-concepts" xlink:to="conceptRelationshipNode" />


        <!-- create another break down for x axis -->
        <table:breakdown id="x-axis-dims" parentChildOrder="children-first" xlink:type="resource" xlink:label="x-axis-dims" />
        
        <!-- Link table to x axis breakdown -->
        <table:tableBreakdownArc order="1.0" axis="x" xlink:type="arc" xlink:arcrole="http://xbrl.org/arcrole/2014/table-breakdown" xlink:from="table" xlink:to="x-axis-dims" />

        <!-- Create dimension relation node to return ProductService Domain Members -->
        <table:dimensionRelationshipNode id="dimensionRelationshipNode" xlink:type="resource" xlink:label="dimensionRelationshipNode">
            <table:relationshipSource>example:ProductServiceDomain</table:relationshipSource>
            <table:linkrole>http://xyz.abc/role/IncomeStatement</table:linkrole>
            <table:dimension>example:ProductServiceAxis</table:dimension>
            <table:formulaAxis>descendant-or-self</table:formulaAxis>
        </table:dimensionRelationshipNode>

        <!-- Link dimension relation node to x axis breakdown -->
        <table:breakdownTreeArc order="1.0" xlink:type="arc" xlink:arcrole="http://xbrl.org/arcrole/2014/breakdown-tree" xlink:from="x-axis-dims" xlink:to="dimensionRelationshipNode" />

        <!-- Create break down for z axis -->
        <table:breakdown id="z-axis-period" xlink:type="resource" xlink:label="z-axis-period" />
        <table:tableBreakdownArc order="3.0" axis="z" xlink:type="arc" xlink:arcrole="http://xbrl.org/arcrole/2014/table-breakdown" xlink:from="table" xlink:to="z-axis-period" />

        <!-- Create aspect node to return periods for z axis -->
        <table:aspectNode id="aspectNode3" xlink:type="resource" xlink:label="aspectNode3">
            <table:periodAspect />
        </table:aspectNode>

        <!-- Link aspect node to z-axis breakdown -->
        <table:breakdownTreeArc order="2.0" use="optional" xlink:type="arc" xlink:arcrole="http://xbrl.org/arcrole/2014/breakdown-tree" xlink:from="z-axis-period" xlink:to="aspectNode3" />

        <!-- Create labels -->
        <gen:arc order="2.0" xlink:type="arc" xlink:arcrole="http://xbrl.org/arcrole/2008/element-label" xlink:from="y-axis-concepts" xlink:to="label1" />
        <label:label id="label1" xlink:type="resource" xlink:role="http://www.xbrl.org/2008/role/label" xlink:label="label1" xml:lang="en">Line Items</label:label>
        <gen:arc order="1.0" xlink:type="arc" xlink:arcrole="http://xbrl.org/arcrole/2008/element-label" xlink:from="table" xlink:to="label" />
        <label:label id="label" xlink:type="resource" xlink:role="http://www.xbrl.org/2008/role/label" xlink:label="label" xml:lang="en">Data Entry</label:label>

    </gen:link>
</link:linkbase>

When the income statement instance is loaded by arelle and a table is rendered as HTML, it the output is here.

3.6.8 Inline XBRL (iXBRL)

Inline XBRL specifications provide a mechanism for embedding XBRL tags in HTML documents (xHTML is required by the specifications). This allows the XBRL benefits of tagged data to be combined with a human-readable presentation of a report, which is under the control of the preparer.

The Inline XBRL Document Set is a group of one or more Inline XBRL Documents which when comprising sufficient metadata results in one or more Target Documents when transformed according to the mapping rules prescribed in inlineXBRL specifications.

In practical terms, inline XBRL specifications define XBRL elements in the namespace {http://www.xbrl.org/2013/inlineXBRL}, these elements are used from within xHTML and form the metadata necessary to describe an XBRL instance document which is referred to as Target Document, in this context a Target Document is defined as valid XBRL instance document represented by metadata in the Inline XBRL Document Set. The target document need not to physically exist, but the metadata must be sufficient to construct the target document when transformed according to the mapping rules prescribed in inline XBRL Specification.

Inline XBRL

Inline XBRL

3.6.8.1 Inline XBRL elements

As mentioned, XBRL and Inline XBRL instance documents are usually created using specialized software that takes care of the form and sytanx and provide tools to help authors, but it is important to have some knowledge of the elements defined within the specifications.

Inline XBRL specifications define elements in namespace {xi=http://www.xbrl.org/2013/inlineXBRL}:

element description
ix:continuation used to define data that is to be treated as part of ix:footnote or ix:nonNumeric.
ix:denominator denotes an XBRL denominator element; used with ix:fraction mapped element. see ix:fraction
ix:exclude used to encapsulate data that is to be excluded from the processing of ix:footnote or ix:nonNumeric elements, The purpose of the ix:exclude element is to prevent text content from being included in the {value} properties of ix:footnote or ix:nonNumeric. It has no other use.
ix:footnote represents the link:footnote element in XBRL instance,
ix:fraction denotes an XBRL fact which is an element of type, or derived from type, fractionItemType;
ix:header contains the non-displayed portions of the Target Document, it contains xi:hidden.
ix:hidden used to contain XBRL facts that are not to be displayed in the browser
ix:nonFraction element denotes an XBRL numeric item which is an element which is not of type, nor derived from type, fractionItemType.
ix:nonNumeric element denotes an XBRL non-numeric item
ix:numerator denotes an XBRL numerator element
ix:references used to contain reference elements which are required by a given Target Document (schemaRef, linbaseRef)
ix:relationship used to define relationships between XBRL facts or between XBRL facts and footnote resources. The type of relationship is indicated by the value of the arcrole attribute, such as http://www.xbrl.org/2009/arcrole/fact-explanatoryFact for fact to fact relationships
ix:resources used to contain resource elements which are required by one or more Target Documents (ix:relationship, link:roleRef, link:arcroleRef, xbrli:context, xbrli:unit)
ix:tuple denotes an XBRL tuple

The best way to understand what inline XBRL is, is actually to see it, below are three links to one and the same inline XBRL filing for Microsoft form 10-Q for the 9 months ended 2021-03-31:

3.6.8.2 Inline XBRL Transformations

Inline XBRL is embedded in a human readable document, which means that the values are also included in the the document in human readable form that might not comply with the data types formats required by XBRL specifications, XBRL transformations deals with this problem by associating the human readable values with a format that can be translated to a machine readable value, this is done using the @format attribute for each XBRL fact in an inline XBRL document.

For example, if we have a date value of Mar. 31, 2021, this date is human readable but does not comply with XBRL required format for date ISO 8601 (YYY-MM-DD), so an @format=ixt:datemonthdayyearen is add to the fact and then XBRL processor will know how to translate this date to the ISO 8601 format. Below is the above example processed by Arelle Transformation Tester plugin:

Inline XBRL Transformations

Inline XBRL Transformations

Transformations Registries
The XBRL Transformation Registry contains the rules and metrics by which transformations in Inline XBRL are performed. These rules describe how descriptive text in Inline XBRL documents can be represented as XBRL data types.

Following is a sample of transformations from transformation registry 2:

Format Code Description
ixt:booleanfalse Any string
ixt:booleantrue Any string
ixt:datedaymonth Numeric date recurring day and month
ixt:datedaymonthen English date recurring day and month
ixt:datedaymonthyear Numeric date day month and year

3.6.9 Style Guides

Style guides are one of the supporting documents that accompany an XBRL Taxonomy. Style guides helps in achieving consistency while creating, maintaining or extending the taxonomy.

Style guides set the rules for consistent language and naming conventions, styles and organization. For example a style guide rule my set the whether to use camel case or pascal case, what characters are allowed or disallowed in labels, and so on.

Examples of style guides:

3.6.10 Three Taxonomies

In this Final section we look at three different taxonomies and have overview on the choices the taxonomy authors made, there three taxonomies are:

  • IFRS Taxonomy (2020)
  • US GAAP Taxonomy (2021)
  • European Banking Authority (EBA) Taxonomy (Framework 3.1)
IFRS Taxonomy (2020) US GAAP Taxonomy (2021) EBA Taxonomy (Framework 3.1)
Link IFRS Taxonomy Resources FASB 2021 Taxonomy EBA Reporting Frame 3.1
Design Approach Standard Based Approach: For each IFRS Standard, elements reflecting disclosure requirements are identified and modeled and organized into a taxonomy Domain Model: Partitions business concepts so to meet US GAAP Financial Reporting Taxonomy ("UGT") Requirements that defined the content scope, stakeholders, users, user goals, use cases functional requirments, technical requirments and design goals. Data Point Model (DPM): DPM is a structured representation of the data, identifying all the business concepts and its relations, as well as validation rules. It contains all the relevant technical specifications necessary for developing an IT reporting solution. The XBRL Taxonomies presents the data items, business concepts, relations and validation rules described by the DPM in the technical format of an XBRL taxonomy.
Type of reporting GAAP Reporting GAAP Reporting Regulatory Reporting
Extensibility Unrestricted extensions: The purpose is to provide a framework, general principles are set out and it is left to users to determine specific extensions applying to their case Restricted/Limited extensions: Extension is allowed with strict set of rules Limited extensions: Extension is limited to labels in specific language or introducing specific assertions, the complete set of data points is defined in base taxonomy

4 Taxonomy Development Project

In this section we explore taxonomy development projects based on the XBRL US experience laid out in TDH starting section 4 page 59.

TDH breaks down the development process into 6 main components:

  • Assessing over all project scope (and defining goals)
  • Building Transport Data Model
  • Validation
  • The Mechanics of Taxonomy Development
  • Documenting a Taxonomy
  • Taxonomy Governance

Taxonomy Development

Taxonomy Development

4.1 Assess Scope and Define Goals

The goal of XBRL taxonomy is to facilitate the structured reporting of data from preparer to consumer. Project scope and goals should consider factors that enables preparers to produce the data and consumer should be able to use the data for its intended purpose.

Functional requirements represents what a taxonomy is meant to do, while Non-functional requirements imposes constraints on system design. The main focus in this stage is to identify the effect of requirements (functional and non-functional requirements) on the scope and design goals.

Factors to consider when scoping and defining goals:

  • Policy decision, such as extensibility.
  • Functional requirements vs Non-functional requirement
  • Understand use cases, how users interact with the systems to achieve their goals.
  • Identify data to be transported, and systems that produce and consume the data.
  • Stakeholders.
  • Scope of the taxonomy (industry/sector wide or limited implementation).
  • Resources required for the project.
  • Support, maintenance requirements and change management
  • Documentation and communication
  • Balancing and prioritizing requirements from stakeholders and considering cost-benefits.
  • Measures for success, such as accuracy and timeliness of data.

4.2 Building Transport Model

To build the taxonomy (Transport model), current datasets and dimensionality should be described. Again functional requirements and non-functional requirements should be mapped to the data.

During the process of building the model, minimum dataset should be determined, minumim dataset is the dataset free of redundant or extraneous information while representing all the necessary data. Current and legacy system may be a good source for determining minimum dataset(s).

Data is modeled based on o the minimum dataset, redundant and repetitive information should be reduced to minimum, contextual information for a data point and relationships between data points are explored.

A data model is transformed to a transport model (XBRL Taxonomy), during this process data types are determined, core concept dimensions defined, choices like using explicit vs typed dimensions are made, model relationships are translated to XBRL linkbases.

Extensibility decision should be reflected in the taxonomy design and in determining allowable methods that users can extend a taxonomy, and how extensibility affects Comparability.

Other considerations include, reporting system (system receiving and processing reports), transport format.

4.3 Validation

Validation ensure robust and accurate data. There are two levels of validation in XBRL:

  • Basic Validation: Ensures reports are syntax valid, valid data types used and valid relationships used.
  • Regulatory/Industry Requirements: Ensures that business rules are applied, methods used include software validation, XBRL Formula Validation, XULE validation and Data Quality Committees (issues and maintain data quality rules).

See XBRL Validation.

4.4 The Mechanics of Taxonomy Development

Workflow
Multiple groups performing different tasks are needed to create a taxonomy, and workflow should be organized, TDH gives examples of the groups as follows:

  • Group responsible for creating data model and transforming it to taxonomy.
  • Group responsible for overseeing incorporation of regulatory/governance rules and changes.
  • Group responsible for reading reviewers’ comments and making recommendations for modifications.

The work flow might look as follows:

Taxonomy Dev Workflow

Taxonomy Dev Workflow

Preparing and Generating the Taxonomy
Determine the software to be used for generating the taxonomy, and perform the following steps:

  • Determine concepts’ labels: important for human readability and understanding taxonomy.
  • Building a taxonomy spreadsheet: spreadsheet containing concept, relations, and other information about the taxonomy, some software packages can use this spreadsheet to generate taxonomy files.

The Importance of Public Exposure
Taxonomy should undergo significant public review (where anyone can see and comment on the taxonomy), word ‘public’ here is relative to the size and scope of the taxonomy, and feedback and comments should be collected and analyzed.

4.5 Documenting a Taxonomy

Taxonomy is a powerful tool, and it can only fulfill its purpose if users know how to use it. Taxonomy documentation is extremely important, it communicates the goals of the taxonomy and means to achieve those goals to all stakeholders.

Documentation include:

  • Taxonomy White Paper: can be considered as an announcement of the taxonomy, with explanation of its purpose and justification for its development.
  • Taxonomy guide: explains the taxonomy it self and logic behind it.
  • Repairer’s guide: provides preparers with information about the taxonomy’s concepts and structures as needed to build XBRL reports.
  • Data Consumer Guide: provides information and common use cases for data consumers. TDH provide detailed examples of documentation in section 8 page 111.

4.6 Taxonomy Governance

The TDH recognizes four governance roles in the taxonomy development life cycle which spans over four phases.

Governance Roles:

  • Sponsor: Champions the development process and is able to bring together stakeholders successfully, could be a regulatory agency or standards organization.
  • Working Group: Includes representation of all stakeholders (regulator, preparers, developers, consumers…), this group perform the tasks to develop the taxonomy deliverables.
  • Steering Committee: highest committee and is led by the sponsor, provides oversight, evaluates major milestones, reviews and approves deliverables, and serves as “tie breaker” on major decisions concerning the taxonomy.
  • Taxonomy Manager: is the project manager, maintains detailed knowledge of the taxonomy and the project as a whole and provides day-to-day staff support for the taxonomy working group. Also interacts with feedback and reviews and comments, and reports to the steering committee and working group.
  • Working group and taxonomy steering committee can be consolidated and streamlined into a taxonomy committee.

The interaction of the above roles can be viewed as follows:

Governance structure

Governance structure

Taxonomy development Life cycle Phases:
The TDH recognizes four phases in the the taxonomy development life cycle, the goals and roles for each phase are as follows:

The lifecycle of taxonomy development and governance

The lifecycle of taxonomy development and governance


LS0tCnRpdGxlOiAiTm90ZXMgb24gZVh0ZW5zaWJsZSBCdXNpbmVzcyBSZXBvcnRpbmcgTGFuZ3VhZ2UgKFhCUkwpIFNwZWNpZmljYXRpb25zIgphdXRob3I6ICJTaGVyaWYgTS4gRWxHYW1hbCIKZGF0ZTogIkF1Z3VzdCAyMDIxIgpvdXRwdXQ6ICAKICBodG1sX25vdGVib29rOiAgCiAgICB0aGVtZTogZmxhdGx5CiAgICBoaWdobGlnaHQ6IGhhZGRvY2sgIAogICAgdG9jOiB5ZXMgIAogICAgdG9jX2Zsb2F0OgogICAgICBjb2xsYXBzZWQ6IGZhbHNlIAogICAgdG9jX2RlcHRoOiA1CiAgICBudW1iZXJfc2VjdGlvbnM6IHllcyAKICAgIGNvZGVfZm9sZGluZzogbm9uZSAKICAgIGZpZ19jYXB0aW9uOiB5ZXMKLS0tCjxzdHlsZT4KCi50b2NpZnktZXh0ZW5kLXBhZ2UgewogIGhlaWdodDogMCAhaW1wb3J0YW50Owp9CgojaGVhZGVyID4gZGl2ID4gYnV0dG9uIHsKICBkaXNwbGF5OiBub25lOwp9CgojaGVhZGVyLCAjcmVzLWxpbmtzLXRhYmxlIHsKICB0ZXh0LWFsaWduOiBsZWZ0Owp9CgpibG9ja3F1b3RlIHsKICAgIHBhZGRpbmc6IDEwcHggMjBweDsKICAgIG1hcmdpbjogMCAwIDIwcHg7CiAgICBmb250LXNpemU6IDEuMmVtIWltcG9ydGFudDsKICAgIGJvcmRlci1sZWZ0OiA1cHggc29saWQgI2VlZTsKfQoKI1RPQyB7CmZvbnQtc2l6ZTogc21hbGw7CndoaXRlLXNwYWNlOiBub3dyYXA7Cn0KcHJlIGNvZGUgewp3aGl0ZS1zcGFjZTogcHJlOwp9CnByZSB7Cm1heC1oZWlnaHQ6IDM1MHB4Owp9Ci5zb3VyY2VDb2RlIHsKICAgIG92ZXJmbG93OiBhdXRvOwp9CmJvZHkgewp0ZXh0LWFsaWduOiBqdXN0aWZ5O30KYmxvY2txdW90ZSB7CiAgICBmb250LXNpemU6IGluaGVyaXQ7CiAgICBmb250LXN0eWxlOiBvYmxpcXVlOwp9Cgo8L3N0eWxlPgoqKioKYGBge3Igc2V0dXAsICBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKaGVyZTo6aV9hbSgnZG9jcy9ub3Rlcy1vbi14YnJsLlJtZCcpCnNvdXJjZShoZXJlOjpoZXJlKCdSJywgJ2hlbHBlckZ1bmN0aW9ucy5SJykpCm9wdGlvbnMod2lkdGggPSAyMDApCmh0bWx0b29sczo6dGFnTGlzdChybWFya2Rvd246Omh0bWxfZGVwZW5kZW5jeV9mb250X2F3ZXNvbWUoKSkKYGBgCgojIEludHJvZHVjdGlvbiAgCgplWHRlbnNpYmxlIEJ1c2luZXNzIFJlcG9ydGluZyBMYW5ndWFnZSAoIlhCUkwiKSBpcyB0aGUgbGF0ZXN0IGFuZCBncmVhdGVzdCBtZXRob2Qgb2YgcmVwcmVzZW50aW5nIGZpbmFuY2lhbCBpbmZvcm1hdGlvbiBpbiBzdHJ1Y3R1cmVkIGZvcm1hdC4gVGhlIHVzZSBvZiBYQlJMIGlzIHN0ZWFkaWx5IGV4cGFuZGluZyBhbGxvdmVyIHRoZSB3b3JsZCwgYW5kIGl0IGlzIGJlY29taW5nIHRoZSBzdGFuZGFyZCBtZXRob2Qgb2YgZXhjaGFuZ2luZyBmaW5hbmNpYWwgcmVwb3J0cy4gICAKClRoaXMgbWF0ZXJpYWwgaXMgYSBjb2xsZWN0aW9uIG9mIG5vdGVzIG9uIFhCUkwgcHV0IHRvZ2V0aGVyIHRvIHByb3ZpZGUgYSBiYXNpYyB1bmRlcnN0YW5kaW5nIG9mIF93aGF0IGlzIFhCUkxfLCBfd2hhdCBpdCBkb2VzXywgYW5kIF9ob3cgaXQgaXMgaW1wbGVtZW50ZWRfLgoKUGFydHMgb2YgdGhpcyBtYXRlcmlhbCBkZXBlbmRzIGhlYXZpbHksIGFuZCByZWZlcnMgdG8gdGhlIFsqKl9YQlJMIFRheG9ub215IERldmVsb3BtZW50IEhhbmRib29rICgiVERIIilfKipdKGh0dHBzOi8veGJybC51cy94YnJsLXJlZmVyZW5jZS90ZGgvKSBwdWJsaXNoZWQgYnkgW1hCUkwgVVNdKGh0dHBzOi8veGJybC51cy8pIGFuZCBwdWJsaWNseSBhdmFpbGFibGUgb24gdGhlIHRoZWlyIHdlYnNpdGUuIFRoZSBUREggd2FzIGNyZWF0ZWQgYXMgYSBndWlkZSBmb3IgY3JlYXRpbmcgWEJSTCB0YXhvbm9taWVzIGJhc2VkIG9uIFhCUkwgVVMgZXhwZXJpZW5jZSwgd2hpY2ggbWFrZXMgaXQgYSB2ZXJ5IHZhbHVhYmxlIHJlc291cmNlIGZvciBhbnlvbmUgb3Igb3JnYW5pemF0aW9uIGludGVyZXN0ZWQgaW4gdGhlIGltcGxlbWVudGF0aW9uIG9mIFhCUkwuCgojIE9iamVjdGl2ZXMgb2YgdGhpcyBtYXRlcmlhbCAgCgpUaGlzIG1hdGVyaWFsIHNob3VsZCBwcm92aWRlOiAgCgoqIEJhc2ljIHVuZGVyc3RhbmRpbmcgb2YgWEJSTCBhbmQgaXRzIGNvbXBvbmVudHMuICAKKiBGYW1pbGlhcml0eSB3aXRoIGNvcmUgWEJSTCB0ZXJtaW5vbG9neS4gIAoqIEJhc2ljIHVuZGVyc3RhbmRpbmcgb2YgWEJSTCBUYXhvbm9teSBhbmQgaW5zdGFuY2UgZG9jdW1lbnQuICAKKiBCYXNpYyB1bmRlcnN0YW5kaW5nIG9mIHRoZSBwcm9jZXNzIG9mIGRldmVsb3BtZW50IG9mIGFuIFhCUkwgdGF4b25vbXkuICAKKiBVbmRlcnN0YW5kaW5nIHRoZSBlY29zeXN0ZW0gb2Ygc3RydWN0dXJlZCBmaW5hbmNpYWwgcmVwb3J0aW5nIGFuZCB0aGUgc3VwcG9ydGluZyB0ZWNobm9sb2dpZXMuICAKCioqUHJlc2VudGF0aW9uIHRoYXQgZ29lcyB3aXRoIHRoaXMgbWF0ZXJpYWwgY2FuIGJlIGFjY2Vzc2VkIFtoZXJlXShwcmVzZW50YXRpb24vWEJSTC1Ob3Rlcy1BbGwtcGRmLnBkZil7dGFyZ2V0PV9ibGFua30qKgoKIyBXaHkgWEJSTCBhbmQgd2hhdCBpcyBpdCBleGFjdGx5PwoKX19YQlJMX18gc3RhbmRzIGZvciBfZVh0ZW5zaWJsZSBCdXNpbmVzcyBSZXBvcnRpbmcgTGFuZ3VhZ2VfLCBYQlJMIGludGVybmF0aW9uYWwgZGVmaW5lcyBYQlJMIGFzOiAgCgo+WEJSTCBwcm92aWRlcyBhIGxhbmd1YWdlIGluIHdoaWNoIHJlcG9ydGluZyB0ZXJtcyBjYW4gYmUgYXV0aG9yaXRhdGl2ZWx5IGRlZmluZWQuIFRob3NlIHRlcm1zIGNhbiB0aGVuIGJlIHVzZWQgdG8gdW5pcXVlbHkgcmVwcmVzZW50IHRoZSBjb250ZW50cyBvZiBmaW5hbmNpYWwgc3RhdGVtZW50cyBvciBvdGhlciBraW5kcyBvZiBjb21wbGlhbmNlLCBwZXJmb3JtYW5jZSBhbmQgYnVzaW5lc3MgcmVwb3J0cy4gWEJSTCBsZXRzIHJlcG9ydGluZyBpbmZvcm1hdGlvbiBtb3ZlIGJldHdlZW4gb3JnYW5pemF0aW9ucyByYXBpZGx5LCBhY2N1cmF0ZWx5IGFuZCBkaWdpdGFsbHkuYHIgdHVmdGU6OnF1b3RlX2Zvb3RlcignLS0tIFtYQlJMLm9yZ10oaHR0cHM6Ly93d3cueGJybC5vcmcvdGhlLXN0YW5kYXJkL3doYXQvYW4taW50cm9kdWN0aW9uLXRvLXhicmwvI3doYXQtaXMteGJybCknKWAgIAoKCiMjIERhdGEgYW5kIFJlZ3VsYXRvcnkgUmVwb3J0aW5nICAKClRoZSBpbmNyZWFzZSBjb21wbGV4aXR5IG9mIHRyYW5zYWN0aW9ucywgcmVndWxhdG9yeSByZXF1aXJlbWVudHMsIGFuZCB2b2x1bWVzIG9mIGRhdGEgZGVyaXZlcyB0aGUgbmVlZCBmb3IgbW9yZSBlZmZpY2llbnQgYW5kIHN0cnVjdHVyZWQgbWV0aG9kcyB0byBoYW5kbGUgZGF0YSBhbmQgY29udmVydCBpdCBpbnRvIGEgcmVzb3VyY2UgcmF0aGVyIHRoYW4gYSBidXJkZW4uIAoKPGRpdj4KPGNlbnRlcj4KIVtSZWd1bGF0b3J5IERhdGEgb3ZlciB0aW1lXShgciBoZXJlOjpoZXJlKCdkb2NzJywgJ2ltYWdlcy9kYXRhLnN2ZycpYCkKPC9jZW50ZXI+CjxwIHN0eWxlPSJ0ZXh0LWFsaWduOmNlbnRlciI+CioqRGF0YSBvdmVyIHRpbWUqKgo8L3A+CjwvZGl2PgoKXyoqSG93IGRvIHdlIGNvbGxlY3QgZmluYW5jaWFsIGRhdGEqKl8KCjxkaXY+CjxjZW50ZXI+CiFbUmVndWxhdG9yeSBSZXBvcnRpbmddKGByIGhlcmU6OmhlcmUoJ2RvY3MnLCAnaW1hZ2VzL2NvbGxlY3RpbmdEYXRhLnN2ZycpYCkKPC9jZW50ZXI+CjxwIHN0eWxlPSJ0ZXh0LWFsaWduOmNlbnRlciI+CioqUmVndWxhdG9yeSBSZXBvcnRpbmcqKgo8L3A+CjwvZGl2PgoKYGBge3IgY2hhbmdlc19pbl9kYXRhX2NvbGxlY3Rpb24sIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIGV2YWw9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGZpZy5jYXA9J0hvdyB3ZSBjb2xsZWN0IERhdGEnfQpEaWFncmFtbWVSOjpnclZpeigiCgpkaWdyYXBoIHdpdGhfdGl0bGUgewoKICBncmFwaCBbc3BsaW5lcz1vcnRobywgcmFua2Rpcj1MUiwgbGFiZWw9J0NoYW5nZXMgaW4gaG93IHdlIGNvbGxlY3QgZGF0YSddCiAgCiAgbm9kZSBbc2hhcGU9Ym94LCBzdHlsZT0nZmlsbGVkJywgY29sb3I9dHJhbnNwYXJlbnQsIGZpbGxjb2xvcj0nI2Y1ZjVmNScsIGZvbnRuYW1lPUhlbHZldGljYSwgZm9udGNvbG9yPScjMmMzZTUwJ10KICAKICBhW2xhYmVsPSdQYXBlciBCYXNlZCBTdWJtaXNzaW9ucyddOyAKICBjW2xhYmVsPSdTcHJlYWRzaGVldHMgYW5kIEZsYXQgZmlsZXMnXTsgCiAgZFtsYWJlbD0nV2ViIEJhc2VkIEZvcm1zJ107IGVbbGFiZWw9WEJSTF0KICAKICBlZGdlW2NvbG9yPScjMjQyNDI0JywgcGVud2lkdGg9MC4yXQogIAogIGEgLT4gYyAtPiBkIC0+IGUKfSAgICAgICAgICAgICAgICAgCiIsIGhlaWdodD0iMTAwJSIsIHdpZHRoPSIxMDAlIikKYGBgCgoKVGhlIG1ldGhvZHMgYW5kIHByb2Nlc3NlcyBvZiBmaW5hbmNpYWwgZGF0YSBjb2xsZWN0aW9uIGV2b2x2ZWQgb3ZlciB0aW1lLCB3ZSBzdGFydGVkIHdpdGggcGFwZXIgYmFzZWQgc3VibWlzc2lvbnMsIHRoZW4gc3ByZWFkc2hlZXRzIGFuZCBmbGF0IGZpbGVzIHdlcmUgdXNlZCwgdGhlbiBlbGVjdHJvbmljIHN1Ym1pc3Npb25zIHRocm91Z2ggd2ViIGJhc2VkIHBvcnRhbHMuIFhCUkwgaXMgdGhlIG5leHQgbmV3ZXN0IHRoaW5nIGluIHRoaXMgZXZvbHV0aW9uLCBiZW5lZml0cyBvZiBYQlJMIGNhbiBiZSBzdW1tYXJpemVkIGFzIGZvbGxvd3M6IAoKPGRpdj4KPGNlbnRlcj4KIVtXaGF0IFhCUkwgUHJvdmlkZXNdKGByIGhlcmU6OmhlcmUoJ2RvY3MnLCAnaW1hZ2VzL3doeV94YnJsMi5zdmcnKWApCjwvY2VudGVyPgo8cCBzdHlsZT0idGV4dC1hbGlnbjpjZW50ZXIiPgoqKldoYXQgWEJSTCBQcm92aWRlcyoqCjwvcD4KPC9kaXY+CgoKKiBYQlJMIHByb3ZpZGVzIGZvciBhIHN0YWJsZSBzdHJ1Y3R1cmUgb2YgdGhlIGRhdGEgY29udGVudC4gIAoqIFhCUkwgc2VwYXJhdGVzIGRhdGEgY29udGVudCBmcm9tIHRoZSBmb3JtIG9mIHRoZSBzdWJtaXNzaW9uLiAKKiBYQlJMIFByb3ZpZGVzIGZvciBhdXRvbWF0aW9uLCB3aGljaCBpbmNyZWFzZXMgYWNjdXJhY3ksIGNvc3QgYW5kIHRpbWUgc2F2aW5ncy4gIAogIApBbmQgbWFueSBtb3JlIGJlbmVmaXRzIHJlbGF0aW5nIHRvIHRoZSBxdWFsaXR5IGFuZCByaWNobmVzcyBvZiBkYXRhLgoKCiMjIyBDdXJyZW50IGlzc3VlcyB0aGF0IFhCUkwgYWRkcmVzc2VzCgoqKkdlbmVyYWwgSXNzdWVzOioqICAKCiogKipNYWNoaW5lIFJlYWRhYmxlOioqIHJlcG9ydHMgd2l0aCBYQlJMIHRhZ2dpbmcgY2FuIGJlIGNvbnN1bWVkIGFuZCBhbmFseXplZCBieSBjb21wdXRlcnMgdGhyb3VnaCBYQlJMIGVuYWJsZWQgc29mdHdhcmUgKFhCUkwgUHJvY2Vzc29ycykgYXMgb3Bwb3NlZCB0byBwYXBlciBiYXNlZCBvciB1bnN0cnVjdHVyZWQgcmVwb3J0cy4gICAKKiAqKkludGVyb3BlcmFiaWxpdHk6KiogWEJSTCBpcyBzZWxmLWRlc2NyaWJpbmcgYW5kIHVzZXMgWE1MIHN5bnRheCB3aGljaCBtYWtlcyB0aGUgaW5mb3JtYXRpb24gaW4gWEJSTCBmb3JtYXQgc3lzdGVtIGluZGVwZW5kZW50LCBpbiBvdGhlciB3b3JkcywgdGhlIHNhbWUgWEJSTCBpbmZvcm1hdGlvbiBwYWNrYWdlIGNhbiBiZSBjb25zdW1lZCBieSBhbnkgc3lzdGVtIHRoYXQgaGFzIFhCUkwgZW5hYmxlZCBzb2Z0d2FyZSwgd2hpY2ggYWRkcmVzc2VzIF9jb21wYXRpYmlsaXR5XyBpc3N1ZXMuICAKKiBJdCBwcm92aWRlcyBmb3IgYSAqKmNvbW1vbiBzZXQgb2YgcnVsZXMqKiB0aGF0IGNhbiBiZSB1c2VkIGluIGV4Y2hhbmdpbmcgYW55IGZpbmFuY2lhbCBpbmZvcm1hdGlvbiwgaGVuY2UgaXQgcHJvdmlkZXMgYSBjb21tb24gbGFuZ3VhZ2UgZm9yIGV4Y2hhbmdpbmcgZGF0YSwgYWRkcmVzc2luZyBfY29tcGFyYWJpbGl0eV8gaXNzdWVzLiAgICAKKiBYQlJMIHByb3ZpZGVzIGZvciAqKmF1dG9tYXRlZCoqIG1lYW5zIG9mIGNvbXBpbGluZywgdHJhbnNtaXR0aW5nLCB2YWxpZGF0aW5nIGFuZCBhbmFseXppbmcgZmluYW5jaWFsIGRhdGEsIHdoaWNoIGluY3JlYXNlIF9lZmZpY2llbmN5XywgdGltZSBhbmQgY29zdCBzYXZpbmcgYW5kIGF0IHRoZSBzYW1lIHRpbWUgaW5jcmVhc2luZyBxdWFsaXR5IG9mIGRhdGEuICAKKiBYQlJMIHByb3ZpZGVzIGhpZ2ggcXVhbGl0eSwgKipjb250ZXh0dWFsbHkgcmljaCBmaW5hbmNpYWwgZGF0YSoqIHJhdGhlciB0aGFuIF9mcmFnbWVudGVkXyBkYXRhLiAgCiogWEJSTCBpcyBmcmVlIGFuZCAqKm9wZW5zb3VyY2UqKiBzdGFuZGFyZCwgd2l0aCAqKm5vIGxpY2Vuc2luZyBmZWVzKiosIGFkZHJlc3NlcyBpc3N1ZXMgb2YgcHJvcGl0aWF0b3J5IHN0YW5kYXJkcyBhbmQgc29mdHdhcmUsIGl0IHNob3VsZCBiZSBub3RlZCB0aGF0IFhCUkwgZW5hYmxlZCBzb2Z0d2FyZSBpcyBub3QgZnJlZS4KCgoqKlJlZ3VsYXRvciBJc3N1ZXMqKjogIAoKKiAqKkhpZ2ggdm9sdW1lcyBvZiBkYXRhIGFuZCByZXBvcnRzOioqIGFzIG1lbnRpb25lZCwgWEJSTCBwcm92aWRlcyBmb3IgYXV0b21hdGlvbiBpbiBjb2xsZWN0aW5nIGFuZCBwcm9jZXNzaW5nIGRhdGEsIHdoaWNoIGZhY2lsaXRhdGVzIGhhbmRsaW5nIGxhcmdlIHZvbHVtZXMgb2YgZGF0YSBpbiBhbiBhY2N1cmF0ZSBhbmQgZWZmaWNpZW50IG1hbm5lci4gIAoqICoqUmV2aWV3IGFuZCB2YWxpZGF0aW9uOioqIFhCUkwgZ2l2ZXMgZmluYW5jaWFsIHJlcG9ydHMgYSBzdHJ1Y3R1cmUgdGhhdCBlbmFibGVzIGNyZWF0aW9uIG9mIHZhbGlkYXRpb24gcnVsZXMgYmFzZWQgb24gcmVndWxhdGlvbnMsIGJ1c2luZXNzIHJ1bGVzIGFuZCBhbnkgb3RoZXIgY3JpdGVyaWEsIGFuZCB0aGF0IGluIHR1cm4gZW5hYmxlcyBxdWljayBjb3JyZWN0aXZlIGFjdGlvbiB0byBiZSB0YWtlbiB3aGVuIG5lZWRlZC4gICAgCiogRGF0YSBjYW4gYmUgc3RvcmVkIGZvciBjcm9zcyBjaGVja2luZyBhbmQgZnVydGhlciAqKmFuYWx5c2lzIGFuZCBjb21wYXJpc29uKiouICAKKiAqKlNpbmdsZSBzb3VyY2Ugb2YgdGhlIHRydXRoKiosIFhCUkwgc3RydWN0dXJlIGFsbG93cyBkYXRhIHRvIGJlIHVzZWQgZm9yIG1hbnkgcHVycG9zZXMsIGZvciBleGFtcGxlLCBzYW1lIHJlcG9ydCBjYW4gY29udGFpbiBkYXRhIHN0cnVjdHVyZXMgcmVxdWlyZWQgZm9yIGEgcmVndWxhdG9yLCBjZW5zdXMsIHRheGVzIC4uLgoKKipJc3N1ZXIgSXNzdWVzKio6ICAKCiogKipTaW1wbGlmaWVzIHRoZSBjb21waWxhdGlvbiBvZiByZXBvcnRzKiogcmVxdWlyZWQgYnkgbXVsdGlwbGUgcmVndWxhdG9ycyBmcm9tIHRoZSBzYW1lIGRhdGFzZXQuICAgIAoqIFhCUkwgdGF4b25vbWllcyBhbmQgdGhlIHJlbGF0ZWQgZ3VpZGVzIGlzc3VlZCBieSByZWd1bGF0b3JzIHByb3ZpZGUgZm9yICoqY2xlYXIgYW5kIHVuYW1iaWd1b3VzIHJlcG9ydGluZyByZXF1aXJlbWVudHMqKiwgYW5kIHNpbXBsaWZpZXMgY29tcGxpYW5jZS4gIAoqIFJlZHVjZXMgdGhlIGNoYW5jZSBvZiBjb3N0bHkgZXJyb3JzLgogIAoKIyMgV2hvIHVzZXMgWEJSTD8gIAoKVGhlIFhCUkwgVGF4b25vbXkgRGV2ZWxvcG1lbnQgSGFuZGJvb2sgaW4gcGFnZSA2IGxpc3RzIHN1Y2Nlc3NmdWwgaW1wbGVtZW50YXRpb24gb2YgWEJSTCBhcm91bmQgdGhlIHdvcmxkcywgdGhhdCBpbmNsdWRlczoKCiogKipVbml0ZWQgU3RhdGVzKio6IFN0b2NrIGV4Y2hhbmdlIGNvbW1pc3Npb24gKFNFQyksIGFuZCBGaW5hbmNpYWwgRGVwb3NpdG9yeSBJbnN1cmFuY2UgQ29ycG9yYXRpb24gKEZESUMpIHdpdGggdG90YWwgcmVwb3J0aW5nIGVudGl0aWVzIG9mIG92ZXIgMTcsNTAwICAKKiAqKlVuaXRlZCBLaW5nZG9tKio6IEhlciBNYWplc3R54oCZcyBSZXZlbnVlcyAmIEN1c3RvbXMgKEhNUkMpLCBhbmQgQ29tcGFuaWVzIEhvdXNlIHdpdGggcmVwb3J0aW5nIGVudGl0aWVzIG9mIG92ZXIgMiBtaWxsaW9uICAKKiAqKlNwYWluKio6IEJ1c2luZXNzIFJlZ2lzdHJhciwgQmFua2luZyBSZWd1bGF0b3IsIFNlY3VyaXRpZXMgUmVndWxhdGlvbiwgQWNjb3VudGluZyBPdmVyc2lnaHQgYW5kIFN0YXRlIEZlZGVyYWwgQ29tcHRyb2xsZXIgd2l0aCByZXBvcnRpbmcgZW50aXRpZXMgb2Ygb3ZlciA4MDAsMDAwICAKCiogKipPdGhlcnMqKjogRXVyb3BlIChFdXJvcGVhbiBTaW5nbGUgRWxlY3Ryb25pYyBGb3JtYXQgRVNFRiksIEluZGlhLCBTaW5nYXBvcmUsIFNvdXRoIEtvcmVhLCBJdGFseSwgUGVydSwgV29ybGQgYmFuayBhbmQgbWFueSBvdGhlcnMgIAoKKiAqKkdvdmVybm1lbnRzIGFuZCBnb3Zlcm5tZW50IGFnZW5jaWVzICoqYWxsb3ZlciB0aGUgd29ybGQgYXJlIHVzaW5nIFhCUkwsIGNvdW50cmllcyBsaWtlICoqTmV0aGVybGFuZHMqKiBhbmQgKipBdXN0cmFsaWEqKiBpbXBsZW1lbnRlZCBbKipTdGFuZGFyZCBCdXNpbmVzcyBSZXBvcnRpbmcgKFNCUikgcHJvZ3JhbXMqKl0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvU3RhbmRhcmRfQnVzaW5lc3NfUmVwb3J0aW5nKSB3aGljaCBhcmUgcHJvZ3JhbXMgZGVzaWduZWQgdG8gcmVkdWNlIHJlZ3VsYXRvcnkgYnVyZGVuIGZvciBidXNpbmVzc2VzIGFuZCByZWxpZXMgaGVhdmlseSBvbiBYQlJMLgoKQ3VycmVudGx5IFhCUkwgaW50ZXJuYXRpb25hbCB3ZWJzaXRlIGxpc3RzIFttb3JlIHRoYW4gMjAgWEJSTCBqdXJpc2RpY3Rpb25zXShodHRwczovL3d3dy54YnJsLm9yZy90aGUtY29uc29ydGl1bS9hYm91dC9qdXJpc2RpY3Rpb25zLykgKGEganVyaXNkaWN0aW9uIGlzIGEgbG9jYWwgcmVwcmVzZW50YXRpdmUgZm9yIFhCUkwgIGFjdGluZyBhcyB0aGUgcHJpbWFyeSBsaWFpc29uIHRvIG5hdGlvbmFsIGdvdmVybm1lbnQsIHRlY2hub2xvZ3kgZmlybXMgYW5kIGJ1c2luZXNzIGNvbW11bml0aWVzKSwgZm9sbG93aW5nIGFyZSBzb21lIG9mIHRoZSByZWd1bGF0b3JzIGltcGxlbWVudGVkIG9yIGluIHRoZSBwcm9jZXNzIG9mIGltcGxlbWVudGluZyBYQlJMOiAgCgo8ZGl2Pgo8Y2VudGVyPgohW1NvbWUgb2YgdGhlIFJlZ3VsYXRvcnMgdXNpbmcgWEJSTF0oYHIgaGVyZTo6aGVyZSgnZG9jcycsICdpbWFnZXMvd2hvLnN2ZycpYCkKPC9jZW50ZXI+CjxwIHN0eWxlPSJ0ZXh0LWFsaWduOmNlbnRlciI+CioqU29tZSBvZiB0aGUgUmVndWxhdG9ycyB1c2luZyBYQlJMKioKPC9wPgo8L2Rpdj4KCgojIyMgWEJSTCBJbXBsZW1lbnRhdGlvbnMgTWFwICAKWEJSTCB3ZWJzaXRlIHByZXNlbnRzIGEgbWFwIGFuZCBsaXN0aW5nIGZvciBYQlJMIGltcGxlbWVudGF0aW9uIHByb2plY3RzIHdvcmxkIHdpZGUgdGhhdCBjYW4gYmUgYWNjZXNzZWQgW2hlcmVdKGh0dHBzOi8vd3d3Lnhicmwub3JnL3RoZS1zdGFuZGFyZC93aHkveGJybC1wcm9qZWN0LWRpcmVjdG9yeS8pe3RhcmdldD1fYmxhbmt9ICAKCjxpZnJhbWUgc3R5bGU9ImJvcmRlcjogMDsiIHNyYz0iaHR0cHM6Ly9kYXRhc3R1ZGlvLmdvb2dsZS5jb20vZW1iZWQvcmVwb3J0aW5nLzE1U21QQVZoVGllY3JuclZVUkNxQk8yNUt0c3lhMmVDVC9wYWdlL0pwbWkiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjU1MCIgZnJhbWVib3JkZXI9IjAiIGFsbG93ZnVsbHNjcmVlbj0iYWxsb3dmdWxsc2NyZWVuIiBkYXRhLWV4dGVybmFsPSIxIj48L2lmcmFtZT4KCioqV2h5IFhCUkw/KiogSW4gc2hvcnQsIGl0IGFkZHJlc3NlcyBtb3N0IGN1cnJlbnQgaXNzdWVzIHJlbGF0aW5nIHRvIGV4Y2hhbmdlIG9mIGZpbmFuY2lhbCBkYXRhLCBpdCBpcyB3aWRlbHkgdXNlZCBhbGxvdmVyIHRoZSB3b3JsZCwgYW5kIGl0IGlzIHNpbXBseSB0aGUgbmV4dCBzdGVwIGluIHRoZSBldm9sdXRpb24gb2YgZmluYW5jaWFsIGRhdGEgZXhjaGFuZ2Ugc3lzdGVtcy4KCiMjIFdoYXQgaXMgRXh0ZW5zaWJsZSBCdXNpbmVzcyBSZXBvcnRpbmcgTGFuZ3VhZ2UgKFhCUkwpPwoKKipUaGUgU3BlY2lmaWNhdGlvbnMqKiAgIApUZWNobmljYWxseSBYQlJMIGlzIGJhc2VkIG9uIF9fWE1MX18gXyhlWHRlbnNpYmxlIE1hcmt1cCBMYW5ndWFnZSlfLCBpdCBjYW4gYmUgc2FpZCB0aGF0ICoqWEJSTCBpcyBhbiBYTUwgZXh0ZW5zaW9uKiogb3B0aW1pemVkIHRvIGRlYWwgd2l0aCBidXNpbmVzcyBpbmZvcm1hdGlvbi4gSW4gb3RoZXIgd29yZHMsICBYQlJMIGRvZXMgd2hhdCBpdCBkb2VzIGJ5IGJlaW5nIGJhc2VkIG9uICBYTUwuICAKCltYQlJMIGlzIGEgc2V0IG9mIHNwZWNpZmljYXRpb25zXShodHRwczovL3NwZWNpZmljYXRpb25zLnhicmwub3JnL3NwZWNpZmljYXRpb25zLmh0bWwpIGRldmVsb3BlZCBhbmQgbWFpbnRhaW5lZCBieSBbWEJSTCBJbnRlcm5hdGlvbmFsXShodHRwczovL3d3dy54YnJsLm9yZy8pLiBUaGUgYmFzZSBYQlJMIHNwZWNpZmljYXRpb24gKG5vdyB2ZXJzaW9uIDIuMSkgaXMgc3RhYmxlIHNpbmNlIDIwMDMsIHdpdGggYWRkaXRpb25hbCBzcGVjaWZpY2F0aW9ucyBiZWluZyBhZGRlZCB0byBhdWdtZW50IGl0IHN1Y2ggYXMgWEJSTCBEaW1lbnNpb25zLiAgCgpYQlJMIHNwZWNpZmljYXRpb24gYXJlIGZyZWVseSBhdmFpbGFibGUgd2l0aG91dCBsaWNlbnNpbmcsIG5vdGUgdGhhdCB0aGlzIGRvZXNuJ3QgYXBwbHkgZm9yIFhCUkwgZW5hYmxlZCBzb2Z0d2FyZSB3aGljaCBtaWdodCBoYXZlIGxpY2Vuc2luZyBmZWVzLiAKCioqRGF0YSBNb2RlbCoqICAKWEJSTCBzcGVjaWZpY2F0aW9ucyBhcmUgdG9vbHMgdGhhdCBlbmFibGVzIHRoZSBkZWZpbml0aW9uIG9mICBkaWN0aW9uYXJpZXMsIGRhdGEgbW9kZWxzIGFuZCBydWxlcyBjYWxsZWQgKipYQlJMIFRheG9ub21pZXMqKiwgYWxzbyBYQlJMIHNwZWNpZmljYXRpb25zIHByb3ZpZGUgdGhlIHJ1bGVzIHRvIGNyZWF0ZSBzdHJ1Y3R1cmVkIGZpbmFuY2lhbCByZXBvcnRzIGJhc2VkIG9uIFhCUkwgVGF4b25vbWllcywgdGhlc2UgZmluYW5jaWFsIHJlcG9ydHMgYXJlIGNhbGxlZCAqKlhCUkwgSW5zdGFuY2VzKiouICAKClNvIHdlIGNhbiBzYXkgdGhhdCBYQlJMIGlzIHRoZSBzZXQgb2YgcnVsZXMgdXNlZCB0byBjcmVhdGUgZGF0YSBtb2RlbHMgYW5kIHN0cnVjdHVyZXMgdGhhdCBhcmUgdGhlIGJhc2lzIGZvciBzdHJ1Y3R1cmVkIGZpbmFuY2lhbCByZXBvcnRpbmcuIAoKCioqQ29tbXVuaWNhdGlvbiBMYW5ndWFnZSoqICAKVGhlIHB1cnBvc2Ugb2YgWEJSTCBpcyB0byBlbmFibGUgZXhjaGFuZ2Ugb2Ygc3RydWN0dXJlZCBmaW5hbmNpYWwgZGF0YSBiZXR3ZWVuIHN5c3RlbXMsIHNvbWV0aW1lcyB0aGUgdGVybSAidHJhbnNwb3J0IG1vZGVsIiBpcyB1c2VkIHRvIHJlZmVyIHRvIFhCUkwuIAoKPiAiQSBfVHJhbnNwb3J0IE1vZGVsXyAgc2VydmVzIGFzIGFuIG9yZ2FuaXphdGlvbmFsIHN0cnVjdHVyZSB3aGVuIG1vdmluZyBkYXRhIGZyb20gYSBzb3VyY2UgdG8gYSBjb25zdW1lciIgYHIgdHVmdGU6OnF1b3RlX2Zvb3RlcignLS0tIFtUREggc2VjdGlvbiAyLjEuMiBwYWdlIDEwXShodHRwczovL3hicmx1cy5naXRodWIuaW8vZG9jcy90ZGguaHRtbCknKWAKCgpVbmRlcnN0YW5kaW5nIFhCUkwgc3RhcnRzIHdpdGggWE1MLCB0aGUgbmV4dCBzZWN0aW9uIGJyaWVmbHkgZXhwbG9yZXMgWE1MIGNvbmNlcHRzIHRoYXQgYXJlIHJlbGV2YW50IHRvIHVuZGVyc3RhbmRpbmcgWEJSTC4KCiMjIFhNTCBhbmQgbWFya3VwIGxhbmd1YWdlcyAKCj5FeHRlbnNpYmxlIE1hcmt1cCBMYW5ndWFnZSBpcyBhIG1hcmt1cCBsYW5ndWFnZSB0aGF0IGRlZmluZXMgYSBzZXQgb2YgcnVsZXMgZm9yIGVuY29kaW5nIGRvY3VtZW50cyBpbiBhIGZvcm1hdCB0aGF0IGlzIGJvdGggaHVtYW4tcmVhZGFibGUgYW5kIG1hY2hpbmUtcmVhZGFibGUuYHIgdHVmdGU6OnF1b3RlX2Zvb3RlcignLS0tIFtXaWtpcGVkaWEgTWFya3VwIExhbmd1YWdlc10oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvWE1MKScpYCAgCgojIyMgQmFjayBpbiB0aW1lICAKCkJlc3Qgd2F5IHRvIHVuZGVyc3RhbmQgdGhlIG1vc3QgYmFzaWMgY29uY2VwdCBvZiBtYXJrdXAgbGFuZ3VhZ2VzIGlzIHRvIHRha2UgYSBsb29rIGF0IGFuY2llbnQgRWd5cHRpYW4gd3JpdGluZ3MuCgo8Y2VudGVyPgpbIVsqKkNhcnRvdWNoZSoqXShgciBoZXJlOjpoZXJlKCdkb2NzJywgJ2ltYWdlcy9vbGQuanBnJylgKXt3aWR0aD0zMCUgaGVpZ2h0PTMwJX1dKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0NhcnRvdWNoZSl7dGFyZ2V0PV9ibGFua30gIAo8c3ViPl9bSW1hZ2UgYnkgT3NhbWEgU2h1a2lyIE11aGFtbWVkIEFtaW4gRlJDUChHbGFzZyksIENDIEJZLVNBIDQuMCA8aHR0cHM6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL2J5LXNhLzQuMD4sIHZpYSBXaWtpbWVkaWEgQ29tbW9uc11fPHN1Yj4KPC9jZW50ZXI+CgpJbiB0aGUgaW1hZ2UsIHNvbWUgb2YgdGhlIHdyaXRpbmcgaXMgZW5jYXBzdWxhdGVkIGluIGFuIG92YWwgc2hhcGUgY2FsbGVkICJDYXJ0b3VjaGUiLCBhY2NvcmRpbmcgdG8gdGhlIGNvbW1vbiB1bmRlcnN0YW5kaW5nLCB0aGlzIG1lYW5zIHRoYXQgdGhlIGVuY2Fwc3VsYXRlZCB3cml0aW5nIHJlcHJlc2VudHMgYSByb3lhbCBuYW1lLiBUaGUgYW5jaWVudCBFZ3lwdGlhbnMgY2hvb3NlIHRoaXMgbWV0aG9kIHRvIGlkZW50aWZ5IHRoZSBpbmZvcm1hdGlvbiBieSBtYXJraW5nIG9yICJ0YWdnaW5nIiBpdCBieSB0aGUgb3ZhbCBzaGFwZS4KClhNTCBhbmQgbWFya3VwIGxhbmd1YWdlcyBkbyB0aGUgc2FtZSB0aGluZywgaXQgaXMganVzdCBfdGFnZ2luZ18gb2YgaW5mb3JtYXRpb24gaW4gYSBtYWNoaW5lLXJlYWRhYmxlIGZvcm1hdCwgaW4gdGhlIGNhc2Ugb2YgWEJSTCwgdGhpcyB0YWdnaW5nIGhhcyBjb25zZXF1ZW5jZXMgd2hlbiBpdCBpcyBwcm9jZXNzZWQgYnkgYSBjb21wdXRlci4KCgpNYXJrdXAgbGFuZ3VhZ2VzIGluIGdlbmVyYWwgdGFncyB0aGUgY29udGVudCBvZiBhIGZpbGUgb3IgYSBkb2N1bWVudCBpbiBhIHdheSB0aGF0IG1ha2VzIGl0IG1hY2hpbmUgcmVhZGFibGUsIGkuZS4gd2hlbiBwcm9jZXNzZWQgYnkgYSBjb21wdXRlciwgdGhlIHRhZ3MgdGVsbCB0aGUgY29tcHV0ZXIgd2hhdCB0byBkbyB3aXRoIHRoZSBjb250ZW50LiAgCgpNYXJrdXAgbGFuZ3VhZ2VzIGhhcyBkaWZmZXJlbnQgcHVycG9zZXMsIGZvciBleGFtcGxlICoqSHlwZXIgVGV4dCBNYXJrdXAgTGFuZ3VhZ2UgKCJIVE1MIikqKiB0YWdzIHRlbGwgdGhlIGNvbXB1dGVyIGhvdyB0byBkaXNwbGF5IHRoZSBjb250ZW50cyBvZiBhIHdlYiBwYWdlLCAqKk1hdGhlbWF0aWNhbCBtYXJrdXAgbGFuZ3VhZ2UgKCJNYXRoTUwiKSoqIHRhZ3MgdGVsbHMgdGhlIGNvbXB1dGVyIGhvdyB0byByZXByZXNlbnQgbWF0aGVtYXRpY2FsIGZvcm11bGFlLCAqKlhNTCoqIHdvcmtzIHRoZSBzYW1lIHdheSBwdXJwb3NlIG9mIHN0b3JpbmgsIG9yZ2FuaXppbmcgYW5kIHRyYW5zcG9ydGluZyBjb250ZW50IGJldHdlZW4gc3lzdGVtcy4KCk1hcmt1cCBsYW5ndWFnZXMgYXJlIHVzdWFsbHkgc3lzdGVtIGluZGVwZW5kZW50LCBhbiBYTUwgZmlsZSBjcmVhdGVkIGluIGEgV2luZG93cyBzeXN0ZW0gY2FuIGJlIHJlYWQgYW5kIHBhcnNlZCBieSBhIExpbnV4IGJhc2VkIHN5c3RlbTsgYWxsIHN5c3RlbXMgYW5kIHByb2dyYW1pbmcgbGFuZ3VhZ2VzIGhhdmUgdG9vbHMgdG8gcmVhZCBhbmQgcGFyc2UgWE1MLiAgCgoKIyMgWE1MIEJhc2ljcyAgCgpYTUwgaXMgYSBzZXQgb2Ygc3BlY2lmaWNhdGlvbnMsIHJ1bGVzIGFuZCB0b29scyBmb3IgZGVzY3JpYmluZywgc3RvcmluZywgYW5kIHRyYW5zcG9ydGluZyBkYXRhIGJldHdlZW4gc3lzdGVtcy4KCkFzc3VtZSB0aGF0IHdlIHdhbnQgdG8gZW5jb2RlIGEgdGFibGUgb2YgaW52b2ljZXMgaW50byBYTUwsIGEgZnJhZ21lbnQgb2YgdGhhdCBYTUwgbWlnaHQgbG9vayBhcyBmb2xsb3dzOgoKYGBge3IgeG1sX2ludHJvX2ZyYWcsIGVjaG89RkFMU0V9IApmbl9Db2RlQ2h1bmtPdXQobGFuZyA9ICdYTUwnLCB0eHQ9Cic8dGFibGU+IAogIDxpbnZvaWNlIEN1c3RvbWVyTmFtZT0iYWJjIiBJbnZvaWNlTnVtPSIxMDEiPjU4OS45MTwvaW52b2ljZT4KICA8aW52b2ljZSBDdXN0b21lck5hbWU9Inh5eiIgSW52b2ljZU51bT0iMTAxIj4yNTcuNDI8L2ludm9pY2U+CjwvdGFibGU+JykKYGBgCiMjIyBYTUwgRm9ybQpYTUwgZG9jdW1lbnQgaXMgY29tcG9zZWQgb2YgZWxlbWVudHMsIGVhY2ggZWxlbWVudCBzdGFydHMgd2l0aCBhbiBvcGVuaW5nIHRhZyBhbmQgZW5kcyB3aXRoIGEgY2xvc2luZyB0YWcsIHRoZXJlIGNhbiBiZSB2YWx1ZXMgb3Igb3RoZXIgZWxlbWVudHMgd2l0aGluIHRoZSBvcGVuaW5nIGFuZCBjbG9zaW5nIHRhZ3MuIFRoZSBYTUwgc3RydWN0dXJlIGlzIGluIHRoZSBmb3JtIG9mIGEgdHJlZSwgaGF2aW5nIGEgcm9vdCBlbGVtZW50IGNvbnRhaW5pbmcgYWxsIG90aGVyIGVsZW1lbnRzLiAgCgpgPHRhYmxlPmAgYW5kIGA8L3RhYmxlPmAgaW4gdGhlIGFib3ZlIFhNTCBmcmFnbWVudCBhcmUgdGhlIG9wZW5pbmcgYW5kIGNsb3NpbmcgPGNvZGUgc3R5bGU9ImNvbG9yOiByZWQ7IGZvbnQtd2VpZ2h0OiBib2xkOyI+dGFnczwvY29kZT4gb2YgdGhlIHJvb3QgZWxlbWVudCBjYWxsZWQgYHRhYmxlYC4gSW4gdGhlIGFib3ZlIGZyYWdtZW50LCB0aGUgcm9vdCBlbGVtZW50IGhhcyB0d28gbmVzdGVkIGVsZW1lbnRzIGNhbGxlZCBgaW52b2ljZWAuIEVhY2ggaW52b2ljZSBvcGVuaW5nIHRhZyBjb250YWlucyBvdGhlciBpbmZvcm1hdGlvbiBpbiB0aGUgZm9ybSBvZiBrZXksIHZhbHVlIHBhaXJzIGBjdXN0b21lck5hbWU9ImFiYyIsIGludm9pY2VOdW09MTAxYCwgdGhlc2UgYXJlIGNhbGxlZCA8Y29kZSBzdHlsZT0iY29sb3I6IHJlZDsgZm9udC13ZWlnaHQ6IGJvbGQ7Ij5hdHRyaWJ1dGVzPC9jb2RlPiwgd2hpY2ggYXR0YWNoZXMgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgZWxlbWVudCBhbmQgYXJlIHVzdWFsbHkgcmVmZXJyZWQgdG8gdXNpbmcgdGhlIGBAYCBzeW1ib2wsIGFzIGluIGBAY3VzdG9tZXJOYW1lYC4gZmluYWxseSB3ZSBoYXZlIGEgdmFsdWUgYDU4OS45MWAgYmV0d2VlbiB0aGUgYGludm9pY2VgIG9wZW5pbmcgYW5kIGNsb3NpbmcgdGFnLCBpbiB0aGlzIGNhc2UgcmVwcmVzZW50aW5nIHRoZSBpbnZvaWNlIGFtb3VudC4gCgpUbyBiZSB1c2FibGUsIFhNTCBtdXN0IGJlIHdlbGwgZm9ybWVkIFhNTCwgYSB3ZWxsIGZvcm1lZCBYTUwgbXVzdCBoYXZlIHRoZSBmb2xsb3dpbmc6ICAKCiogQWxsIFhNTCBlbGVtZW50cyBtdXN0IGJlIGNvbnRhaW5lZCBpbiBvbmUgcm9vdCBlbGVtZW50ICAKKiBFYWNoIGVsZW1lbnQgbXVzdCBoYXZlIGFuIG9wZW5pbmcgYW5kIGNsb3NpbmcgdGFnICAKKiBFbGVtZW50cyBtdXN0IGJlIHByb3Blcmx5IG5lc3RlZAoqIEF0dHJpYnV0ZXMgbXVzdCBiZSBxdW90ZWQgCgpGb3IgbW9yZSBhYm91dCBYTUwgd2VsbCBmb3JtZWRuZXNzIFtzZWUgVzNTY2hvb2xzIFhNTCBUdXRvcmlhbF0oaHR0cHM6Ly93d3cudzNzY2hvb2xzLmNvbS94bWwveG1sX3ZhbGlkYXRvci5hc3Ape3RhcmdldD0iX2JsYW5rIn0gIAoKIyMjIFN0b3JpbmcgRGF0YSBpbiBYTUwgIApMZXQncyBhc3N1bWUgd2UgaGF2ZSBhIGJyYW5jaCBhbmQgaGVhZCBvZmZpY2UsIGV2ZXJ5ZGF5IHRoZSBicmFuY2ggbmVlZHMgaW5mb3JtYXRpb24gYWJvdXQgc2FsZXMgdG8gaXQncyBoZWFkIG9mZmljZSBpbiB0aGUgZm9ybSBvZiBhIHRhYmxlIG9mIGludm9pY2VzLiBUaGlzIHRhYmxlIGNhbiBiZSBleHByZXNzZWQgaW4gWE1MIGZvcm1hdCBhbmQgc2VudCBvdmVyIHRvIHRoZSBoZWFkIG9mZmljZS4gRmlyc3QgbGV0J3MgY29uc3RydWN0IHRoZSB0YWJsZSB1c2luZyBgUnNjcmlwdGAgbGFuZ3VhZ2U6ICAKCmBgYHtyIGV4YW1wbGVfMV90YmwsIHJlc3VsdHM9J2hvbGQnfQojIEdlbmVyYXRlIGEgdGFibGUsIHNhbWUgYXMgcHJldmlvdXMgdGVzdCBidXQgNTAgcm93cwpzZXQuc2VlZCg0MikKIyBOdW1iZXIgb2Ygcm93cyBpbiB0aGUgdGFibGUKdGFibGVfcm93cyA8LSAxMCAKIyBDdXN0b21lciBuYW1lcwpjdXN0b21lcl9uYW1lcyA8LSBjKCJhYmMiLCAibW5vIiwieHl6IikKIyBEYXRhIGZyYW1lCnRibF8xIDwtIGRhdGEuZnJhbWUoCiAgQ3VzdG9tZXJOYW1lID0gc2FtcGxlKGN1c3RvbWVyX25hbWVzLCB0YWJsZV9yb3dzLCByZXBsYWNlID0gVCksCiAgSW52b2ljZU51bSA9IHNvcnQoc2FtcGxlKDEwMDo5OTksIHRhYmxlX3Jvd3MpKSwKICBJbnZvaWNlRGF0ZSA9IHNvcnQoc2FtcGxlKHNlcShhcy5EYXRlKCcyMDAwLTAxLTAxJyksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzLkRhdGUoJzIwMDAtMTItMzEnKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnk9ImRheSIpLCB0YWJsZV9yb3dzKQogICAgICAgICAgICAgICAgICAgICApLAogIEludm9pY2VDdXJyZW5jeSA9IHJlcCgiQ1UiLHRhYmxlX3Jvd3MpLAogIEludm9pY2VBbXQgPSByb3VuZChydW5pZih0YWJsZV9yb3dzLCBtaW4gPSAxMDAsIG1heCA9IDEwMDApLDIpLCBzdHJpbmdzQXNGYWN0b3JzID0gRikKCiMgRGlzcGxheSBmaXJzdCBmZXcgcm93cyBvZiB0aGUgZGF0YS5mcmFtZQpoZWFkKHRibF8xKQpgYGAKTm93IGxldCdzIGNvbnZlcnQgdGhhdCB0YWJsZSB0byBYTUwgZm9ybWF0OiAgCmBgYHtyIGV4YW1wbGVfMV9tYWtlX3htbCwgcmVzdWx0cz0naG9sZCd9CiMgVGhpcyBjb2RlIGNvbnZlcnRzIHRoZSBpbnZvaWNlcyB0YWJsZSB0byBhbiBYTUwgZG9jdW1lbnQgCiMgYW5kIHNhdmVzIGl0IHRvIGZpbGUKCiMgQ3JlYXRlIFhNTCByb290IGVsZW1lbnQKeG1sX3Jvb3QgPC0geG1sMjo6eG1sX25ld19yb290KCd0YWJsZScpCgojIEF0dGFjaCBlYWNoIHJvdyBvZiB0aGUgdGFibGUgYXMgYW4gPGludm9pY2U+IGVsZW1lbnQKZm9yKHIgaW4gYXNwbGl0KHRibF8xLDEpKSB7CiAgbmQgPC0geG1sMjo6eG1sX2FkZF9jaGlsZCh4bWxfcm9vdCwgJ2ludm9pY2UnKQogIGZvcihyX24gaW4gbmFtZXMocikpewogICAgeG1sMjo6eG1sX2FkZF9jaGlsZCgueD1uZCwgLnZhbHVlID0gcl9uLCByW1tyX25dXSApCiAgfQp9CgojIFdyaXRlIHRoZSBYTUwgZG9jdW1lbnQgdG8gZmlsZQp4bWxfb3V0X3RibF8xIDwtIGhlcmU6OmhlcmUoJ2RvY3MnLCd4bWxfZmlsZXMveG1sX291dC54bWwnKQppbnZpc2libGUoeG1sMjo6d3JpdGVfeG1sKHhtbF9yb290LCB4bWxfb3V0X3RibF8xKSkKYGBgCgpUaGUgcmVzdWx0aW5nIFhNTCBmaWxlIGxvb2tzIGxpa2UgdGhpczooW3NlZSBmaWxlXSh4bWxfZmlsZXMveG1sX291dC54bWwpe3RhcmdldD1fYmxhbmt9KSAgCmBgYHtyIGV4YW1wbGVfMV9zaG93X3htbCwgZWNobz1GQUxTRX0KIyByZWFkIGFuZCBkaXNwbGF5IHRoZSBYTUwgZmlsZQpvdXRwdXQgPC0gZm5fQ29kZUNodW5rT3V0KGxhbmcgPSAiWE1MIiwgRmlsZSA9IHhtbF9vdXRfdGJsXzEpCm91dHB1dApgYGAKCgpFeGFtaW5pbmcgdGhlIHJlc3VsdGluZyBYTUwgZmlsZSwgZWFjaCBgPGludm9pY2U+YCBlbGVtZW50IGhhcyA1IGNoaWxkIGVsZW1lbnRzIGVhY2ggcmVwcmVzZW50aW5nIGEgcGllY2Ugb2YgZGF0YSBkZXNjcmliaW5nIHRoZSBpbnZvaWNlLCB3aXRoIGVhY2ggb2YgdGhvc2UgY2hpbGQgZWxlbWVudHMgc3RvcmluZyB0aGUgZGF0YSBhcyBpdHMgdmFsdWUuIElmIHRoZSBmb2N1cyBvZiB0aGlzIHRhYmxlL3JlcG9ydCBpcyBvbiB0aGUgaW52b2ljZSBhbW91bnQgYDxpbnZvaWNlQW10PmAsIHRoZW4gaXQgbWlnaHQgYmUgYmV0dGVyIHRvIGhhdmUgdGhlIGludm9pY2UgYW1vdW50IGluZm9ybWF0aW9uIGFzIHRoZSBvbmx5IHZhbHVlLCBhbmQgZXZlcnl0aGluZyBlbHNlIG1pZ2h0IGJlIGJldHRlciByZXByZXNlbnRlZCBhcyBhbiBhdHRyaWJ1dGUuIEF0dHJpYnV0ZXMgdXN1YWxseSBwcm92aWRlIGFkZGl0aW9uYWwgY29udGV4dHVhbCBpbmZvcm1hdGlvbiBhYm91dCB0aGUgZWxlbWVudCBhbmQgaXRzIHZhbHVlLCB3ZSBtYXkgY2FsbCB0aG9zZSBhdHRyaWJ1dGVzIGFzcGVjdHMgb3IgZXZlbiBkaW1lbnNpb25zLiBTbyBsZXQncyB0cnkgdG8gcmV3cml0ZSB0aGUgWE1MIGluIGEgZGlmZmVyZW50IHdheSB0byByZWZsZWN0IHRoaXM6CmBgYHtyIGV4YW1wbGVfMl9tYWtlX3htbCwgcmVzdWx0cz0naG9sZCd9CiMgUmUtd3JpdGUgdGhlIFhNTCBmaWxlIHdpdGggYXR0cmlidXRlcwoKIyBjcmVhdGUgcm9vdCBlbGVtZW50IGZvciB0aGUgbmV3IFhNTAp4bWxfcm9vdF8yIDwtIHhtbDI6OnhtbF9uZXdfcm9vdCgndGFibGUnKQoKIyBkZWZpbmUgY2hpbGRyZW4gd2l0aCBhdHRyaWJ1dGVzCmZvcihyIGluIGFzcGxpdCh0YmxfMSwxKSkgewogIG5kIDwtIHhtbDI6OnhtbF9hZGRfY2hpbGQoeG1sX3Jvb3RfMiwgJ2ludm9pY2UnLCByW1tsZW5ndGgocildXSkKICBmb3Iocl9uIGluIG5hbWVzKHIpKXsKICAgIHhtbDI6OnhtbF9hdHRycyhuZCkgPC0gclstbGVuZ3RoKHIpXQogIH0KfQoKIyBXcml0ZSB0aGUgWE1MIGRvY3VtZW50IHRvIGZpbGUKeG1sX291dF90YmxfMiA8LSBoZXJlOjpoZXJlKCdkb2NzJywneG1sX2ZpbGVzL3htbF9vdXRfMi54bWwnKQppbnZpc2libGUoeG1sMjo6d3JpdGVfeG1sKHhtbF9yb290XzIsIHhtbF9vdXRfdGJsXzIpKQpgYGAKClRoZSByZXN1bHRpbmcgTmV3IFhNTCBmaWxlIGxvb2tzIGxpa2UgdGhpczogKFtzZWUgZmlsZV0oeG1sX2ZpbGVzL3htbF9vdXRfMi54bWwpe3RhcmdldD1fYmxhbmt9KSAgCmBgYHtyIGV4YW1wbGVfMl9zaG93X3htbCwgZWNobz1GQUxTRX0KIyByZWFkIGFuZCBkaXNwbGF5IHRoZSBYTUwgZmlsZQpvdXRwdXRfMiA8LSBmbl9Db2RlQ2h1bmtPdXQobGFuZyA9ICJYTUwiLCBGaWxlID0geG1sX291dF90YmxfMikKb3V0cHV0XzIKYGBgCgpOb3cgdGhhdCB3ZSBoYXZlIG1vZGVsZWQgb3VyIGluZm9ybWF0aW9uIGluIGFuIGFjY2VwdGFibGUgZm9ybSwgd2UgY2FuIHRyeSB0byByZS1jb25zdHJ1Y3QgdGhlIHRhYmxlIGZyb20gdGhlIFhNTCwgaGVyZSBgUiBzY3JpcHRgIGB4bWwyYCBsaWJyYXJ5IGlzIHVzZWQgdG8gZG8gdGhhdCwgYnV0IGl0IGNhbiBiZSBkb25lIG9uIGFueSBzeXN0ZW0gdXNpbmcgYW55IGxhbmd1YWdlIG9yIHNvZnR3YXJlIGNhcGFibGUgb2YgcGFyc2luZyBYTUwgZmlsZXM6CmBgYHtyIGV4YW1wbGVfMl9tYWtlX3RibCwgcmVzdWx0cz0naG9sZCd9CiMgUmVhZCBYTUwgZmlsZQp4bWxfdGJsIDwtIHhtbDI6OnJlYWRfeG1sKHhtbF9vdXRfdGJsXzIpCgojIGZpbmQgYWxsIGludm9pY2UgZWxlbWVudHMKaW52b2ljZXMgPC0geG1sMjo6eG1sX2ZpbmRfYWxsKHhtbF90YmwsICcuLy9pbnZvaWNlJykKdmFsdWVzIDwtIHhtbDI6OnhtbF9maW5kX2FsbCh4bWxfdGJsLCAnLi8vaW52b2ljZS90ZXh0KCknKSAlPiUgeG1sMjo6YXNfbGlzdCgpICU+JSB1bmxpc3QoKQoKIyBleHRyYWN0IGludm9pY2UgYXR0cmlidXRlcyBhbmQgdmFsdWVzIGZyb20gYWxsIGVsZW1lbnRzIGFuZCBjb252ZXJ0IHRvIGEgZGF0YWZyYW1lCnhtbF90b190YmwgPC0geG1sMjo6eG1sX2F0dHJzKGludm9pY2VzKSAlPiUgYmluZF9yb3dzKCkgJT4lIAogIG11dGF0ZShJbnZvaWNlQW10PSBhcy5kb3VibGUodmFsdWVzKSkgJT4lIGFzLmRhdGEuZnJhbWUoKQojIENvcnJlY3QgZGF0YSB0eXBlcwp4bWxfdG9fdGJsJEludm9pY2VOdW0gPC0gYXMuaW50ZWdlcih4bWxfdG9fdGJsJEludm9pY2VOdW0pCnhtbF90b190YmwkSW52b2ljZURhdGUgPC0gYXMuRGF0ZSh4bWxfdG9fdGJsJEludm9pY2VEYXRlKQpoZWFkKHhtbF90b190YmwpCiMgQ29tcGFyZSByZXN1bHQgb2YgY29udmVyc2lvbiB0byBvcmlnaW5hbCB0YWJsZQpwYXN0ZSgiTWF0Y2hlcyBPcmlnaW5hbDogIiwgYWxsX2VxdWFsKHhtbF90b190YmwsIHRibF8xKSkgIyBTaG91bGQgcmV0dXJuIFRSVUUKCmBgYAoKIyMjIFhNTCBTY2hlbWEsIE5hbWVzcGFjZXMgYW5kIFZhbGlkYXRpb24gIApOb3cgdGhhdCB3ZSBoYXZlIGFuIFhNTCBkb2N1bWVudCBjcmVhdGVkLCB0aGUgbmV4dCBzdGVwIGlzIHRvIHNlbmQgaXQgdG8gdGhlIGRlc3RpbmF0aW9uIHN5c3RlbS4gIApBbiBpbXBvcnRhbnQgcXVlc3Rpb24gYXJpc2VzLCBob3cgZG8gd2UgbWFrZSBzdXJlIHRoYXQgdGhlIGRlc3RpbmF0aW9uL3JlY2VpdmluZyBzeXN0ZW0gaXMgYWJsZSB0byBoYW5kbGUgYW5kIHZlcmlmeSB0aGUgaW5mb3JtYXRpb24gaW4gb3VyIGRvY3VtZW50IGNvcnJlY3RseT8gRm9yIGV4YW1wbGUsIHRoZSByb290IGVsZW1lbnQgaW4gdGhlIGV4YW1wbGUgZG9jdW1lbnQgaXMgY2FsbGVkIGB0YWJsZWAsIHdoYXQgc2hvdWxkIGJlIGV4cGVjdGVkIHRvIGJlIGluY2x1ZGVkIGluIGEgdGFibGUgZWxlbWVudD8gSXMgaXQgYSB0YWJsZSBvZiBpbnZvaWNlcywgb3IgaXMgaXQgYSB0YWJsZSBhIHBpZWNlIG9mIGZ1cm5pdHVyZT8gIAoKVG8gYWRkcmVzcyB0aGUgYWJvdmUgcXVlc3Rpb25zLCBYTUwgaGFzIG1lY2hhbmlzbXMgd2hlcmVieSBlbGVtZW50cyBpbiBhbiBYTUwgZG9jdW1lbnQgY2FuIGJlIGRlc2NyaWJlZCBhbmQgdmVyaWZpZWQsIHRoZXNlIGlzIG1lY2hhbmlzbXMgbWFpbmx5IGRlcGVuZCBvbiBfX3NjaGVtYV9fLCBfX25hbWVzcGFjZXNfXyBhbmQgX190eXBlc19fLiAgCgpfX1NjaGVtYV9fIElzIGEgY29tcG9uZW50IG9mIFhNTCAoW1czQyByZWNvbW1lbmRhdGlvbl0oaHR0cHM6Ly93d3cudzMub3JnL1hNTC9TY2hlbWEpKSB1c2VkIHRvIGRlc2NyaWJlIGFuZCB2YWxpZGF0ZSBlbGVtZW50cyBpbiBhbiBYTUwgZG9jdW1lbnQuIFNjaGVtYSBjYW4gYmUgZGVzY3JpYmVkIGFzIHRoZSBibHVlcHJpbnQgb2Ygdm9jYWJ1bGFyeSB1c2VkLCB3aGF0IGFuZCBob3cgZGF0YSBpcyBzdG9yZWQgaW4gYW4gWE1MIGZpbGUsIGFuZCBpdHMgZGF0YSB0eXBlcy4gIApUaGVyZSBhcmUgZGlmZmVyZW50IHNjaGVtYSBsYW5ndWFnZXMgc3VjaCBhcyBEb2N1bWVudCBUeXBlIERlZmluaXRpb25zIChEVERzKSwgUmVsYXgtTkcsIFNjaGVtYXRyb24gYW5kIFczQyBYU0QgKFhNTCBTY2hlbWEgRGVmaW5pdGlvbnMpLiBUaGUgZm9jdXMgd2lsbCBiZSBvbiBYU0QgYXMgdGhpcyBpcyB0aGUgU2NoZW1hIGxhbmd1YWdlIHVzZWQgaW4gWEJSTC4gWFNEIC1iZWluZyB3cml0dGVuIGluIFhNTC0gaGFzIG9uZSByb290IGVsZW1lbnQgdGhhdCBjb250YWlucyBhbGwgdGhlIGRlY2xhcmF0aW9ucywgdGhlIHJvb3QgZWxlbWVudCBpcyBgPHNjaGVtYT5gIGFuZCBpdCBpcyBkZWZpbmVkIGFzIGZvbGxvd3M6ICAKPGRpdiBzdHlsZT0idGV4dC1hbGlnbjpjZW50ZXI7Ym9yZGVyLXN0eWxlOiBzb2xpZDtib3JkZXItd2lkdGg6IHRoaW47Ym9yZGVyLWNvbG9yOiAjZjdmN2Y3OyI+CiFbW1NjaGVtYSBFbGVtZW50IERlY2xhcmF0aW9uXShodHRwczovL3d3dy53My5vcmcvMjAwOS9YTUxTY2hlbWEvWE1MU2NoZW1hLnhzZCl7dGFyZ2V0PSJfYmxhbmsiIHN0eWxlPSJib3JkZXItY29sb3I6ICNjZWNlY2U7Ym9yZGVyLXN0eWxlOiBzb2xpZDtmb250LXNpemU6IGxhcmdlO2JvcmRlci13aWR0aDogdGhpbjtwYWRkaW5nOiA1cHg7In1dKGByIHBhc3RlMChoZXJlOjpoZXJlKCksJy9kb2NzL2ltYWdlcy9YTUxTY2hlbWFEaWFncmFtLnBuZycpYCl7c3R5bGU9ImRpc3BsYXk6IGJsb2NrO21hcmdpbi1sZWZ0OiBhdXRvO21hcmdpbi1yaWdodDogYXV0bzsifQo8L2Rpdj4gIAoKX19OYW1lc3BhY2VzX18gSXMgYSBjb21wb25lbnQgb2YgWE1MIChbVzNDIHJlY29tbWVuZGF0aW9uXShodHRwczovL3d3dy53My5vcmcvVFIveG1sLW5hbWVzLykpIHVzZWQgZm9yIHByb3ZpZGluZyB1bmlxdWVseSBuYW1lZCBlbGVtZW50cyBhbmQgYXR0cmlidXRlcyBpbiBhbiBYTUwgZG9jdW1lbnQuIFhNTCBkb2N1bWVudCBtYXkgY29udGFpbiBlbGVtZW50cyBmcm9tIG11bHRpcGxlIHZvY2FidWxhcmllcyAoc2NoZW1hcyksIG5hbWVzcGFjZXMgaGVscCBpbiB1bmlxdWVseSBpZGVudGlmeWluZyBlbGVtZW50cyBmcm9tIGRpZmZlcmVudCB2b2NhYnVsYXJpZXMgaGF2aW5nIGlkZW50aWNhbCBuYW1lcy4gQSBuYW1lc3BhY2UgdGFrZXMgdGhlIGZvcm0gb2YgYSBVUkksIGZvciBleGFtcGxlIGBodHRwOi8vbXluYW1lc3BhY2UuY29tLzEvMWAuIEEgbmFtZXNwYWNlIHByZWZpeCBjYW4gYmUgZGVjbGFyZWQgaW4gYW4gWE1MIGRvY3VtZW50IHRvIHJlZmVyIHRvIHNwZWNpZmljIG5hbWVzcGFjZSBVUkkgdXNpbmcgYEB4bWxuc2AgYXR0cmlidXRlLCBmb3IgZXhhbXBsZSAgYHhtbG5zOm15bnM9aHR0cDovL215bmFtZXNwYWNlLmNvbS8xLzFgLgoKX19UeXBlcyBhbmQgRGVyaXZhdGlvbiBpbiB4c2RfXyAgCkVsZW1lbnRzIGRlY2xhcmVkIGluIGFuIHhzZCBzY2hlbWEgYXJlIGJhc2VkIG9uIFhNTCBidWlsdC1pbiBkYXRhIHR5cGVzLCBvciB0eXBlcyB0aGF0IGFyZSBkZXJpdmVkIGZyb20gdGhlc2UgYnVpbHQtaW4gdHlwZXMuIFR5cGVzIGluIHhzZCBkZXRlcm1pbmVzIHRoZSB2YWx1ZSwgY29udGVudCBhbmQgY29tcG9zaXRpb24gb2YgZWxlbWVudHMsIGZvciBleGFtcGxlLCBhbiBlbGVtZW50IHRoYXQgaG9sZHMgYSBgZGF0ZWAgdmFsdWUgbWF5IHVzZSBvZiB0aGUgYnVpbHQtaW4gdHlwZSBgZGF0ZWAgYW5kIG1heSBiZSB0eXBlZCBieSBzZXR0aW5nIHRoZSBgdHlwZWAgYXR0cmlidXRlIGB0eXBlPWRhdGVgLiBXM0Mgc3BlY2lmaWNhdGlvbnMgZm9yIGRhdGEgdHlwZXMgaXMgYXZhaWxhYmxlIFtoZXJlXShodHRwczovL3d3dy53My5vcmcvVFIvMjAwMS9XRC14Zm9ybXMtMjAwMTA2MDgvc2xpY2U0Lmh0bWwpe3RhcmdldD0iX2JsYW5rIn0gYW5kIFtoZXJlXShodHRwczovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMteG1sc2NoZW1hLTItMjAwNDEwMjgvZGF0YXR5cGVzLmh0bWwpe3RhcmdldD0iX2JsYW5rIn0uIEEgZGVwaWN0aW9uIG9mIGJ1aWx0LWluIGRhdGF0eXBlcyBoaWVyYXJjaHkgPHU+ZnJvbSBXM0Mgc3BlY2lmaWNhdGlvbnM8L3U+OiAgCgo8ZGl2IHN0eWxlPSJ0ZXh0LWFsaWduOmNlbnRlcjtib3JkZXItc3R5bGU6IHNvbGlkO2JvcmRlci13aWR0aDogdGhpbjtib3JkZXItY29sb3I6ICNmN2Y3Zjc7bWFyZ2luLWJvdHRvbTogMTVweDsiPgohW1tGcm9tIFczQyB3ZWJzaXRlXShodHRwczovL3d3dy53My5vcmcvVFIvMjAwNC9SRUMteG1sc2NoZW1hLTItMjAwNDEwMjgvZGF0YXR5cGVzLmh0bWwjYnVpbHQtaW4tZGF0YXR5cGVzKXt0YXJnZXQ9Il9ibGFuayIgc3R5bGU9ImJvcmRlci1jb2xvcjogI2NlY2VjZTtib3JkZXItc3R5bGU6IHNvbGlkO2ZvbnQtc2l6ZTogbGFyZ2U7Ym9yZGVyLXdpZHRoOiB0aGluO3BhZGRpbmc6IDVweDsifV0oYHIgcGFzdGUwKGhlcmU6OmhlcmUoKSwiL2RvY3MvaW1hZ2VzL3R5cGUtaGllcmFyY2h5LmdpZiIpYCl7c3R5bGU9ImRpc3BsYXk6IGJsb2NrO21hcmdpbi1sZWZ0OiBhdXRvO21hcmdpbi1yaWdodDogYXV0bzsifQo8L2Rpdj4gIAoKXyoqTm90ZSoqIGBzdWJzdGl0dXRpb25Hcm91cGA6IEEgc3Vic3RpdHV0aW9uIGdyb3VwIGlzIGEgZmVhdHVyZSBvZiBYTUwgc2NoZW1hIHRoYXQgYWxsb3dzIHNwZWNpZnlpbmcgZWxlbWVudHMgdGhhdCBjYW4gcmVwbGFjZSBhbm90aGVyIGVsZW1lbnQgaW4gZG9jdW1lbnRzIGdlbmVyYXRlZCBmcm9tIHRoYXQgc2NoZW1hLiBUaGUgcmVwbGFjZWFibGUgZWxlbWVudCBpcyBjYWxsZWQgdGhlIGhlYWQgZWxlbWVudCBhbmQgbXVzdCBiZSBkZWZpbmVkIGluIHRoZSBzY2hlbWHigJlzIGdsb2JhbCBzY29wZS4gVGhlIGVsZW1lbnRzIG9mIHRoZSBzdWJzdGl0dXRpb24gZ3JvdXAgbXVzdCBiZSBvZiB0aGUgc2FtZSB0eXBlIGFzIHRoZSBoZWFkIGVsZW1lbnQgb3IgYSB0eXBlIHRoYXQgaXMgZGVyaXZlZCBmcm9tIHRoZSBoZWFkIGVsZW1lbnTigJlzIHR5cGUuXwoKR2l2ZW4gdGhhdCBYTUwgaW5zdGFuY2UgY2FuIGhhdmUgb25lIGFuZCBvbmx5IG9uZSByb290IGVsZW1lbnQsIHRoaXMgZWxlbWVudCB3aWxsIGluZXZpdGFibHkgaW5jbHVkZSBvdGhlciBlbGVtZW50cyB0aGF0IGhhdmUgbW9yZSBjb21wbGljYXRlZCBjb250ZW50IHRoYW4ganVzdCBob2xkaW5nIGEgdmFsdWUgb2YgYSBjZXJ0YWluIHR5cGUsIGFuZCBidWlsdC1pbiB0eXBlcyB3aWxsIG5vdCBiZSBlbm91Z2ggdG8gdHlwZSB0aGVzZSBlbGVtZW50cy4gVGhlIGFuc3dlciB0byB0aGF0IGlzIGluIHRoZSBgWGAgb2YgWE1MIHdoaWNoIHN0YW5kcyBmb3IgYGVYdGVuc2libGVgLCB4c2QgcHJvdmlkZXMgY2FwYWJpbGl0aWVzIGZvciBjcmVhdGluZyBuZXcgdHlwZXMgZGVyaXZlZCBmcm9tIGJ1aWx0LWluIHR5cGVzIG9yIG90aGVyIHR5cGVzIHRoYXQgYXJlIGFscmVhZHkgZGVyaXZlZCBmcm9tIGJ1aWx0LWluIHR5cGVzLiBfQSBTdW1tYXJ5IG9mIHR5cGUgZGVyaXZhdGlvbiBpbiBYU0QgaXMgYXMgZm9sbG93czpfIAoKYGBge3IgeG1sU2NoZW1hX3R5cGVzX2Rlcml2YXRpb25fZGlhZ3JhbSwgZWNobz1GQUxTRX0KRGlhZ3JhbW1lUjo6Z3JWaXooIgpkaWdyYXBoICd4c2QgdHlwZXMnIHsKZ3JhcGggW3NwbGluZXM9b3J0aG9dCm5vZGUgW3NoYXBlPWJveCwgc3R5bGU9J2ZpbGxlZCcsIGNvbG9yPXRyYW5zcGFyZW50LCBmaWxsY29sb3I9JyNmNWY1ZjUnLCBmb250bmFtZT1IZWx2ZXRpY2EsIGZvbnRjb2xvcj0nIzJjM2U1MCddCmFbbGFiZWw9J3hzZCBUeXBlcyddOyBiW2xhYmVsPSdQcmltaXRpdmUgJiBCdWlsdC1pbiB0eXBlcyddOyBjW2xhYmVsPXNpbXBsZVR5cGVzXTsgZFtsYWJlbD1jb21wbGV4VHlwZXNdCgpub2RlIFtzaGFwZT1ib3gsIHN0eWxlPSdmaWxsZWQscm91bmRlZCcsIGNvbG9yPXRyYW5zcGFyZW50LCBmaWxsY29sb3I9JyNmNWY1ZjUnLCBmb250bmFtZT1IZWx2ZXRpY2EsIGZvbnRjb2xvcj0nIzJjM2U1MCddCmdbbGFiZWw9J1xcbCYjODIyNjsgQmFzZWQgb24gb3RoZXIgc2ltcGxlIFR5cGVzXFxsICYjODIyNjsgQ2Fubm90IEluY2x1ZGUgYXR0cmlidXRlcyBvciBvdGhlclxcbCZuYnNwOyZuYnNwO2VsZW1lbnRzLlxcbCAnXTsKaFtsYWJlbD0nQWxsb3dlZCBlbGVtZW50czpcXGwmIzgyMjY7IDxyZXN0cmljdGlvbj5cXGwmIzgyMjY7IDxsaXN0PlxcbCYjODIyNjsgPHVuaW9uPlxcbCddOwppW2xhYmVsPSdJbmNsdWRlcyBhdHRyaWJ1dGVzIGFuZCB2YWx1ZSddOyBqW2xhYmVsPSdFbXB0eSBFbGVtZW50cyddOyBrW2xhYmVsPSdJbmNsdWRlcyBFbGVtZW50cyBPbmx5J107IGxbbGFiZWw9J01peGVkIEVsZW1lbnRzJ107Cm1bbGFiZWw9Jzxjb21wbGV4Q29udGVudD5cXG4mIzgyMjY7IDxyZXN0cmljdGlvbj5cXG4mIzgyMjY7IDxleHRlbnNpb24+J107IApuW2xhYmVsPSc8c2ltcGxlQ29udGVudD5cXG4mIzgyMjY7IDxyZXN0cmljdGlvbj5cXG4mIzgyMjY7IDxleHRlbnNpb24+J107Cm9bZml4ZWRzaXplPXRydWUsIHdpZHRoPTQuNSwgaGVpZ2h0PS44NSwgIGxhYmVsPSdcXG5jb21wbGV4VHlwZXMgd2l0aG91dCBuZWl0aGVyXFxuc2ltcGxlQ29udGVudCBvciBjb21wbGV4dENvbnRlbnQgYXJlIGltcGxpY2l0bHlcXG5jb21wbGV4dENvbnRlbnQgd2l0aCByaXN0cmljdGlvbiAoc2VlIGhlcmUpLlxcbiZuYnNwOycsIFVSTCA9ICdodHRwczovL3d3dy53My5vcmcvVFIvMjAxMS9DUi14bWxzY2hlbWExMS0xLTIwMTEwNzIxL3N0cnVjdHVyZXMuaHRtbCNkY2wuY3RkLmN0Y2MuaW1wbGljaXQnXQoKbm9kZVtzaGFwZT1ib3gsIHN0eWxlPSdmaWxsZWQsIHJvdW5kZWQnLCBjb2xvcj10cmFuc3BhcmVudCwgZmlsbGNvbG9yPScjZDFkMWQxJywgZm9udG5hbWU9SGVsdmV0aWNhLCBmb250Y29sb3I9JyMyYzNlNTAnXQoKZWRnZVtjb2xvcj0nIzI0MjQyNCcsIHBlbndpZHRoPTAuMl0KCmEgLT4gYlthcnJvd2hlYWQ9bm9uZV0KYSAtPiBjW2Fycm93aGVhZD1ub25lXQphIC0+IGRbYXJyb3doZWFkPW5vbmVdCntyYW5rID0gc2FtZTsKICBjIC0+IGJbc3R5bGU9aW52aXMsIGFycm93aGVhZD1ub25lLCBsYWJlbCA9ICcgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICddCiAgYiAtPiBkW3N0eWxlPWludmlzLCBhcnJvd2hlYWQ9bm9uZSwgbGFiZWwgPSAnICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnXQp9CnsKICBjIC0+IGdbYXJyb3doZWFkPW5vbmVdCiAgZyAtPiBoCn0KewogIGQtPiB7aSxqLGssbH1bYXJyb3doZWFkPW5vbmVdCiAgaS0+IG4KICB7aixrLGx9IC0+IG0KICAKfQp7CiAge20sbn0gLT4gb1thcnJvd2hlYWQ9bm9uZV0KfQp9ICAgICAgICAgICAgICAgICAKIiwgaGVpZ2h0PTM1MCwgd2lkdGg9IjEwMCUiKQpgYGAKCkEgdXNlZnVsIHJlc291cmNlIG9uIHRoZSB0b3BpYyBvZiBYU0QgZGF0YSB0eXBlcyBhbmQgZGVyaXZhdGlvbiBpcyBhdmFpbGFibGUgW2hlcmVdKGh0dHBzOi8vd3d3LnhtbC5jb20vcHViL2EvMjAwMS8wOC8yMi9lYXN5c2NoZW1hLmh0bWwpe3RhcmdldD0iX2JsYW5rIn0uICAKCkZvbGxvd2luZyB3aXRoIHRoZSBpbnZvaWNlcyB0YWJsZSBleGFtcGxlLCBhIHNjaGVtYSB3YXMgY3JlYXRlZCBmb3IgdGhpcyByZXBvcnQgKHVzaW5nIGFueSBzY2hlbWEgY3JlYXRpb24gc29mdHdhcmUpLCB0aGUgc2NoZW1hIGluc3VyZXMgdGhlIGZvbGxvd2luZzogIAoKKiBOYW1lc3BhY2UgYGh0dHA6Ly9teXByb2plY3QuY29tL3Rlc3QyLzFgIHdhcyBnaXZlbiB0byByZWZlciB0byB0aGUgdm9jYWJ1bGFyeSBvZiB0aGUgc2NoZW1hICAKKiBUaGUgcm9vdCBlbGVtZW50IGlzIGNhbGxlZCBgdGFibGVgIGFuZCBjb250YWlucyBvbmUgb3IgbW9yZSBgaW52b2ljZWAgZWxlbWVudCAgCiogRWFjaCBpbnZvaWNlIGVsZW1lbnQgaXMgcmVxdWlyZWQgdG8gaGF2ZSBhIHNwZWNpZmljIHNldCBvZiBhdHRyaWJ1dGVzIGFzIGZvbGxvd3M6ICAKICArIGBASW52b2ljZU51bWAgb2YgZGF0YSB0eXBlIHBvc2l0aXZlIGludGVnZXIKICArIGBASW52b2ljZURhdGVgIG9mIGRhdGEgdHlwZSBkYXRlICAKICArIGBASW52b2ljZUN1cnJlbmN5YCBhIHN0cmluZyB0aGF0IGNhbiBiZSBlaXRoZXIgIkNVIiBvciAiQ1giICAKICArIGBAQ3VzdG9tZXJOYW1lYCBvZiBkYXRhIHR5cGUgc3RyaW5nCiAgKyBGaW5hbGx5IGludm9pY2UgdmFsdWUgbXVzdCBiZSBhIHBvc2l0aXZlIG51bWJlciBvciAwICAKICAKU2NoZW1hIGZpbGUgaXMgYXMgZm9sbG93czogKFtzZWUgZmlsZV0oeG1sX2ZpbGVzL2V4YW1wbGVfMl9zY2hlbWEyLnhzZCl7dGFyZ2V0PV9ibGFua30pCmBgYHtyIGRpc2JsYXlfc2NoZW1hX2ZpbGUsIGVjaG89RkFMU0V9CmZuX0NvZGVDaHVua091dChsYW5nPSdYTUwnLCBGaWxlPWhlcmU6OmhlcmUoJ2RvY3MnLCAneG1sX2ZpbGVzL2V4YW1wbGVfMl9zY2hlbWEyLnhzZCcpKQpgYGAKClRoZSBYTUwgZmlsZSBtdXN0IHJlZmVyZW5jZSB0aGUgc2NoZW1hIHRvIGJlIGFibGUgdG8gdmFsaWRhdGUgdGhlIGZpbGUsIHRoaXMgaXMgZG9uZSB1c2luZyB0aGUgYEB4bWxuc2AgYXR0cmlidXRlIHdpdGggbmFtZXNwYWNlIHByZWZpeCAnaW52JywgYW5kIHByb3ZpZGluZyB0aGUgbG9jYXRpb24gb2YgdGhlIHNjaGVtYSBmaWxlIHVzaW5nIGBAeHM6c2NoZW1hTG9jYXRpb25gIGF0dHJpYnV0ZSwgbm90ZSB0aGF0IHRoZSBsYXRlciBhdHRyaWJ1dGUgaXMgZnJvbSBgeHM9aHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2VgIG5hbWVzcGFjZS4gVGhlIG5ldyBmaWxlIHdpdGggdGhlIHNjaGVtYSByZWZlcmVuY2UgaXMgbmFtZWQgYHhtbF9vdXRfMl9zY2hlbWEueG1sYCwgdGhlIHBhcnQgb2YgdGhlIGZpbGUgdGhhdCByZWZlcmVuY2VzIHRoZSBzY2hlbWEgbG9va3MgYXMgZm9sbG93czogIAoKYGBge3IgZGlzYmxheV9maWxlX3dpdGhfc2NoZW1hX3JlZiwgZWNobz1GQUxTRX0KZm5fQ29kZUNodW5rT3V0KGxhbmc9J1hNTCcsIHR4dD0KJzxpbnY6dGFibGUgeG1sbnM6aW52PSJodHRwOi8vbXlwcm9qZWN0LmNvbS90ZXN0Mi8xIiAKCXhtbG5zOnhzPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSIgCgl4czpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL215cHJvamVjdC5jb20vdGVzdDIvMSBleGFtcGxlXzJfc2NoZW1hMi54c2QiPicpCmBgYAoqKlZhbGlkYXRpb24gd2l0aCBubyBlcnJvcnMqKiAgCkJlZm9yZSBwcm9jZXNzaW5nIHRoZSBYTUwgZmlsZSwgdGhlIHJlY2VpdmluZyBjb21wdXRlciBjYW4gdmFsaWRhdGUgdGhlIFhNTCBmaWxlIGFnYWluc3QgdGhlIHJlZmVyZW5jZWQgc2NoZW1hLCBpbiB0aGlzIGV4YW1wbGU7IHZhbGlkYXRpb24gaXMgZG9uZSB1c2luZyBgUiBzY3JpcHRgIGB4bWwyOjp4bWxfdmFsaWRhdGUoKWAgZnVuY3Rpb24gYXMgZm9sbG93czogIApgYGB7ciB0ZXN0XzJfdmFsaWRhdGVfMCwgIHJlc3VsdHM9J2hvbGQnfQojIFJlYWQgWE1MIGluc3RhbmNlIGFuZCBzY2hlbWEKaW5zdCA8LSB4bWwyOjpyZWFkX3htbChoZXJlOjpoZXJlKCJkb2NzIiwieG1sX2ZpbGVzL3htbF9vdXRfMl9zY2hlbWEueG1sIikpCnNjaGVtYSA8LSB4bWwyOjpyZWFkX3htbChoZXJlOjpoZXJlKCJkb2NzIiwieG1sX2ZpbGVzL2V4YW1wbGVfMl9zY2hlbWEyLnhzZCIpKQoKIyBWYWxpZGF0ZSBYTUwgaW5zdGFuY2UgYWdhaW5zdCB0aGUgc2NoZW1hCnhtbDI6OnhtbF92YWxpZGF0ZShpbnN0LHNjaGVtYSkKYGBgClZhbGlkYXRpbmcgdGhlIGZpcnN0IGZpbGUgcmV0dXJucyBgVFJVRWAgd2l0aCAwIGVycm9ycywgbWVhbmluZyB0aGF0IHRoZSBmaWxlIGlzIHZhbGlkIGFjY29yZGluZyB0byB0aGUgc2NoZW1hLiAKCioqVmFsaWRhdGlvbiB3aXRoIEVycm9ycyoqICAKQW5vdGhlciBmaWxlIGlzIGNyZWF0ZWQgYW5kIG5hbWVkIGB4bWxfb3V0XzJfc2NoZW1hX2Vycm9ycy54bWxgIChbc2VlIGZpbGVdKHhtbF9maWxlcy94bWxfb3V0XzJfc2NoZW1hX2Vycm9ycy54bWwpe3RhcmdldD1fYmxhbmt9KSwgd2l0aCBzb21lIGNoYW5nZXMgYXMgZm9sbG93czogIAoKMS4gRm9yIHRoZSBmaXJzdCBpbnZvaWNlIHJlbW92ZSBgQEN1c3RvbWVyTmFtZWAgYXR0cmlidXRlICAtPiB0ZXN0IG1pc3NpbmcgYXR0cmlidXRlcyBhcmUgZGV0ZWN0ZWQuCjIuIEZvciB0aGUgc2Vjb25kIGludm9pY2UgY2hhbmdlIGBASW52b2ljZU51bWAgdmFsdWUgdG8gc3RyaW5nIGBpeGAtPiB0ZXN0IGluY29uc2lzdGVudCBhdHRyaWJ1dGUgZGF0YXR5cGUgaXMgZGV0ZWN0ZWQuICAKMy4gRm9yIHRoZSB0aGlyZCBpbnZvaWNlIGNoYW5nZSBgQEludm9pY2VDdXJyZW5jeWAgdmFsdWUgdG8gYFhaYCAtPiB0ZXN0IG9ubHkgdmFsaWQgY3VycmVuY3kgY2hvaWNlcyBhcmUgYWxsb3dlZC4gIAo0LiBpbiB0aGUgZm91cnRoIGludm9pY2UgY2hhbmdlIHRoZSB2YWx1ZSBmcm9tIGAxMzMuNjlgIHRvIGAtMTMzLjY5YCAtPiB0ZXN0IGlmIG9ubHkgcG9zaXRpdmUgaW52b2ljZSBhbW91bnQgdmFsdWVzIGFyZSBhbGxvd2VkLiAgCgpUaGVuIHdlIHJ1biB0aGUgdmFsaWRhdGlvbiBhZ2FpbiBvbiB0aGUgbW9kaWZpZWQgZmlsZSwgd2Ugc2hvdWxkIGdldCBhbiBlcnJvciB0aGlzIHRpbWU6ICAKYGBge3IgdGVzdF8yX3ZhbGlkYXRlXzEsICByZXN1bHRzPSdob2xkJ30KIyBSZWFkIFhNTCBpbnN0YW5jZSBhbmQgc2NoZW1hIgppbnN0X2VyciA8LSB4bWwyOjpyZWFkX3htbChoZXJlOjpoZXJlKCJkb2NzIiwieG1sX2ZpbGVzL3htbF9vdXRfMl9zY2hlbWFfZXJyb3JzLnhtbCIpKQpzY2hlbWEgPC0geG1sMjo6cmVhZF94bWwoaGVyZTo6aGVyZSgiZG9jcyIsInhtbF9maWxlcy9leGFtcGxlXzJfc2NoZW1hMi54c2QiKSkKCiMgVmFsaWRhdGUgWE1MIGluc3RhbmNlIGFnYWluc3QgdGhlIHNjaGVtYQp4bWwyOjp4bWxfdmFsaWRhdGUoaW5zdF9lcnIsc2NoZW1hKQoKYGBgCkFzIHNob3duIGFib3ZlLCBhIHNpbXBsZSBYTUwgdmFsaWRhdG9yICh4bWwyKSBkZXRlY3RlZCBhbGwgdGhlIGVycm9ycyBhbmQgcmVwb3J0ZWQgdGhlbS4gIAoKIyMjIFhMaW5rIGFuZCBYUG9pbnRlciAgClhMaW5rIGFuZCBYUG9pbnRlciBhcmUgWE1MIGNvbXBvbmVudHMsIHRoZXNlIGNvbXBvbmVudHMgY2FuIGJlIHVzZWQgdG8gbGluayBYTUwgZW50aXRpZXMgd2l0aGluIFhNTCBvciB0byBleHRlcm5hbCByZXNvdXJjZXMuICAKCl9fWExpbmtfXyBpcyBhIFtXM0MgcmVjb21tZW5kYXRpb25dKGh0dHBzOi8vd3d3LnczLm9yZy9UUi94bGluazExLyksIGl0IGlzICBzaW1pbGFyIHRvIGh5cGVybGluayBpbiBIVE1MOiAKCj4gWE1MIExpbmtpbmcgTGFuZ3VhZ2UgKFhMaW5rKSBWZXJzaW9uIDEuMSwgd2hpY2ggYWxsb3dzIGVsZW1lbnRzIHRvIGJlIGluc2VydGVkIGludG8gWE1MIGRvY3VtZW50cyBpbiBvcmRlciB0byBjcmVhdGUgYW5kIGRlc2NyaWJlIGxpbmtzIGJldHdlZW4gcmVzb3VyY2VzLiBJdCB1c2VzIFhNTCBzeW50YXggdG8gY3JlYXRlIHN0cnVjdHVyZXMgdGhhdCBjYW4gZGVzY3JpYmUgbGlua3Mgc2ltaWxhciB0byB0aGUgc2ltcGxlIHVuaWRpcmVjdGlvbmFsIGh5cGVybGlua3Mgb2YgdG9kYXkncyBIVE1MLCBhcyB3ZWxsIGFzIG1vcmUgc29waGlzdGljYXRlZCBsaW5rcy4gYHIgdHVmdGU6OnF1b3RlX2Zvb3RlcignLS0tIFtXMy5vcmcgWExpbmsgcmVjb21tZW5kYXRpb25dKGh0dHBzOi8vd3d3LnczLm9yZy9UUi94bGluazExLyNhYnN0cmFjdCknKWAgIAoKX19YUG9pbnRlcl9fIGlzIGEgW1czQyByZWNvbW1lbmRhdGlvbl0oaHR0cHM6Ly93d3cudzMub3JnL1RSL3hwdHIvKSBpcyBhIGNvbnN0cnVjdCB0aGF0IGFsbG93cyBmb3IgbG9jYXRpbmcgc3BlY2lmaWMgZnJhZ21lbnQgd2l0aGluIFhNTC4gIAoKSXQgaXMgaW1wb3J0YW50IHRvIGtlZXAgaW4gbWluZCB0aGF0IFhNTCBhbmQgaXRzIGNvbXBvbmVudHMgYXJlIGp1c3QgaW5zdHJ1Y3Rpb25zLCB0aGV5IGRvIG5vdGhpbmcgb3RoZXIgdGhhbiB0cmFuc3BvcnRpbmcgaW5mb3JtYXRpb24uIEZvciB0aGUgWExpbmsgYW5kIFhQb2ludGVyIGNvbXBvbmVudHMgdG8gaGF2ZSBhbiBlZmZlY3QsIGl0IG5lZWRzIHRvIGJlIHByb2Nlc3NlZCBieSBhbiBYTUwgcHJvY2Vzc29yLiAgCgpHZW5lcmFsbHkgc3BlYWtpbmcsIHRoZXJlIGFyZSB0d28gbWFpbiBjYXRlZ29yaWVzIG9mIGxpbmtzOiAgCgoqIGBTaW1wbGUgTGlua3NgOiBBIHNpbXBsZSBsaW5rIGluIFhMaW5rIGNyZWF0ZXMgYSB1bmlkaXJlY3Rpb25hbCBoeXBlcmxpbmsgZnJvbSBvbmUgZWxlbWVudCB0byBhbm90aGVyIHRocm91Z2ggYSBVUkkuIFRoZSBlbGVtZW50IGNvbnRhaW5pbmcgdGhlIGxpbmsgKHRoZSBzb3VyY2UgZWxlbWVudCkgaXMgbGlua2VkIHRvIGEgZGVzdGluYXRpb24gZWxlbWVudC4gVGhlIGRlc3RpbmF0aW9uIGVsZW1lbnQgaXMgbm90IGNvbm5lY3RlZCB0byB0aGUgc291cmNlIGVsZW1lbnQuIFRoaXMgdHlwZSBvZiBsaW5rIGNvbW1vbiBpbiBIVE1MIGh5cGVybGlua2luZywgd2hlcmUgYSBsaW5rIG9uIGEgd2Vic2l0ZSBtYXkgbGVhZCBhIHVzZXIgdG8gYW5vdGhlciB3ZWJzaXRlLiAgCgoqIGBFeHRlbmRlZCBMaW5rc2A6IFByb3ZpZGUgZm9yIG11bHRpcGxlIHJlc291cmNlcyBhdCB0aGUgc291cmNlIG9yIGRlc3RpbmF0aW9uIHRvIGJlIGNvbm5lY3RlZCB2aWEgbXVsdGlwbGUgYXJjcy4gQW4gYXJjIGNvbnRhaW5zIGluZm9ybWF0aW9uIGFib3V0IHRoZSBvcmlnaW4sIGRlc3RpbmF0aW9uLCBhbmQgdGhlIGJlaGF2aW9yIG9mIGEgbGluayBiZXR3ZWVuIHRoZSBvcmlnaW4gYW5kIGRlc3RpbmF0aW9uLiBUaGUgb3JpZ2luIHJlc291cmNlIGFuZCB0aGUgZGVzdGluYXRpb24gcmVzb3VyY2UgYXJlIGRlZmluZWQgYnkgbGFiZWxzLiAqKl9UaHJvdWdoIG9uZSBvciBtb3JlIGFyY3MsIGV4dGVuZGVkIGxpbmtzIGFjaGlldmUgY29tcGxleCBjb25uZWN0aW9ucyBhbW9uZyBtdWx0aXBsZSByZXNvdXJjZXNfKiouIExpa2Ugc2ltcGxlIGxpbmtzLCBleHRlbmRlZCBsaW5rcyBjYW4gZGVmaW5lIHJlbGF0aW9uc2hpcHMgYmV0d2VlbiBlbGVtZW50cyB3aXRoaW4gdGhlIHNhbWUgbmFtZXNwYWNlIG9yIGFjcm9zcyBkaWZmZXJlbnQgbmFtZXNwYWNlcy4gCgpGb2xsb3dpbmcgYXJlIGRpYWdyYW1zIGZvciB0aGUgdHlwZSBkZWZpbml0aW9ucyBmb3Igc2ltcGxlIGFuZCBleHRlbmRlZCBsaW5rcyBpbiBuYW1lc3BhY2UgYHtodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rfWA6Cgo8ZGl2Pgo8Y2VudGVyPgohW1NpbXBsZSBUeXBlXShgciBoZXJlOjpoZXJlKCdkb2NzJywgJ2ltYWdlcy9zaW1wbGVMaW5rVHlwZS5wbmcnKWApCjwvY2VudGVyPgo8cCBzdHlsZT0idGV4dC1hbGlnbjpjZW50ZXIiPgoqKlNpbXBsZSBUeXBlIERlY2xhcmF0aW9uKioKPC9wPgo8L2Rpdj4KPGRpdj4KPGNlbnRlcj4KIVtFeHRlbmRlZCBUeXBlXShgciBoZXJlOjpoZXJlKCdkb2NzJywgJ2ltYWdlcy9leHRlbmRlZExpbmtFbGVtZW50LnBuZycpYCkKPC9jZW50ZXI+CjxwIHN0eWxlPSJ0ZXh0LWFsaWduOmNlbnRlciI+CioqRXh0ZW5kZWQgVHlwZSBEZWNsYXJhdGlvbioqCjwvcD4KPC9kaXY+CgoKKipYTGluayBhbmQgWFBvaW50ZXIgRXhhbXBsZSoqICAKVGhlcmUgaXMgbm8gYnJvd3NlciBzdXBwb3J0IGZvciBYTUwgWExpbmssIGJ1dCB0aGUgYmVzdCB3YXkgdG8gc2ltdWxhdGUgaXQgYW5kIHVuZGVyc3RhbmQgdGhlIGlkZWEgb2YgWExpbmsgYW5kIFhQb2ludGVyIGlzIHRvIHVzZSBoeXBlcmxpbmtzLCAgQ2xpY2sgdGhpcyBsaW5rOiBbaHR0cHM6Ly93d3cudzMub3JnL1RSL3hsaW5rMTEvI2Fic3RyYWN0XShodHRwczovL3d3dy53My5vcmcvVFIveGxpbmsxMS8jYWJzdHJhY3Qpe3RhcmdldD1fYmxhbmt9ICAKCldlIHNob3VsZCBiZSB0YWtlbiB0byB0aGUgWExpbmsgcmVjb21tZW5kYXRpb24gb24gdGhlIFczQyB3ZWJzaXRlIGF0IHRoZSBsb2NhdGlvbiBvZiBgQWJzdHJhY3RgLCB3aGF0IGhhcHBlbmVkIGhlcmUgaXMgdGhhdCB0aGUgYnJvd3NlciByZWNvZ25pemVkIHRoZSBoeXBlcmxpbmsgKFhMaW5rKSBhbmQgdGhlbiB0aGUgbG9jYXRvciBnaXZlbiBhZnRlciB0aGUgYCNgIHN5bWJvbCAoWFBvaW50ZXIpIGFuZCBleGVjdXRlZCB0aGUgaW5zdHJ1Y3Rpb25zLCBhbmQgaW4gdGhpcyBjYXNlIHRoZSBpbnN0cnVjdGlvbnMgd2FzIHRvIG9wZW4gdGhlIHdlYnNpdGUgYXQgdGhlIHNwZWNpZmllZCBsb2NhdGlvbiwgc28gd2Ugd2VyZSBhYmxlIHRvIGxpbmsgZm9ybSB0aGlzIHBhZ2UgdG8gYW5vdGhlciBleHRlcm5hbCBwYWdlLiBJbiBYTUwgWExpbmsgd29ya3MgdGhlIHNhbWUgd2F5LCBpdCBsaW5rcyBlbGVtZW50cyB0byBvdGhlciBlbGVtZW50cywgb3IgZXh0ZXJuYWwgcmVzb3VyY2VzIHdpdGggc3BlY2lmaWMgaW5zdHJ1Y3Rpb25zIGJhc2VkIG9uIHRoZSBhdHRyaWJ1dGVzIGFuZCB0eXBlcyBvZiBsaW5rcyB1c2VkLgoKIyMjIENvbmNsdXNpb24gIApYTUwgbGFuZ3VhZ2UgYW5kIHN0YW5kYXJkcyB0aGF0IHByb3ZpZGVzIGZvcjogIAoKKiBGbGV4aWJpbGl0eSBpbiBkYXRhIG1vZGVsaW5nLiAgCiogTWVjaGFuaXNtcyBmb3IgY3JlYXRpbmcgdHlwZXMgYW5kIHZvY2FidWxhcmllcyAoZGljdGlvbmFyaWVzKS4gIAoqIE1lY2hhbmlzbXMgdG8gdmFsaWRhdGUgWE1MIGNvbnRlbnQuICAKKiBNZWNoYW5pc21zIHRvIGxpbmsgaW50ZXJuYWwgYW5kIGV4dGVybmFsIGNvbXBvbmVudHMuCgpJbiBhZGRpdGlvbiB0byB0aGUgYWJvdmUsIFhNTCBpcyBhIHN0YWJsZSBhbmQgd2lkZWx5IHVzZWQgbGFuZ3VhZ2UsIGFuZCBhbGwgdGhhdCBtYWRlIFhNTCBzdWl0YWJsZSBmb3VuZGF0aW9uIHRvIGJ1aWxkIFhCUkwuICAKCgojIyBIb3cgRG9lcyBYQlJMIFJlcHJlc2VudCBEYXRhICAKClRoaXMgc2VjdGlvbiBpcyBhbiBvdmVydmlldyBvZiB0aGUgY29tcG9uZW50cyBhbmQgc3BlY2lmaWNhdGlvbnMgb2YgWEJSTCwgc29tZSBiYXNpYyBjb25jZXB0cyBvZiBob3cgWEJSTCByZXByZXNlbnRzIGRhdGEsIGFuZCBYQlJMIGV4YW1wbGUuICAKCl9JdCBpcyBpbXBvcnRhbnQgdG8gdW5kZXJzdGFuZCB0aGF0IFhCUkwgdGF4b25vbWllcyBhbmQgaW5zdGFuY2UgZG9jdW1lbnRzIGFyZSB1c3VhbGx5IGNyZWF0ZWQgdXNpbmcgc3BlY2lhbGl6ZWQgc29mdHdhcmUgdGhhdCBwcm92aWRlcyBhIHVzZXIgZnJpZW5kbHkgaW50ZXJmYWNlIHdoaWxlIHRoZSBzb2Z0d2FyZSB0YWtlcyBjYXJlIG9mIHRoZSBmb3JtIGFuZCBzeW50YXggYmVoaW5kIHRoZSBzY2VuZSwgYnV0IGl0IGlzIGltcG9ydGFudCB0byBoYXZlIGtub3dsZWRnZSBvZiB0aGUgZWxlbWVudHMgYW5kIGNvbXBvbmVudHMgZGVmaW5lZCBpbiBYQlJMIHNwZWNpZmljYXRpb25zIGluIHRoZSByYXcgWE1MIGZvcm1hdC5fCgojIyMgWEJSTCBDb21wb25lbnRzICAKVGhlIGZpZ3VyZSBiZWxvdyB2aXN1YWxpemVzIHRoZSBjb21wb25lbnRzIG9mIFhCUkw6ICAKCjxkaXY+CjxjZW50ZXI+CiFbWEJSTCBDb21wb25lbnRzXShgciBoZXJlOjpoZXJlKCdkb2NzJywgJ2ltYWdlcy94YnJsX2NvbXBvbmVudHMuc3ZnJylgKQo8L2NlbnRlcj4KPHAgc3R5bGU9InRleHQtYWxpZ246Y2VudGVyIj4KKipYQlJMIENvbXBvbmVudHMqKgo8L3A+CjwvZGl2PgoKYGBge3IgeGJybF9jb21wb25lbnRzLCBlY2hvPUZBTFNFLCAgd2FybmluZz1GQUxTRSwgZXZhbD1GQUxTRSwgZmlnLmNhcD0nWEJSTCBDb21wb25lbnRzJ30KRGlhZ3JhbW1lUjo6Z3JWaXooIgoKZGlncmFwaCBtYXRyaXggewoKICBncmFwaCBbc3BsaW5lcz1vcnRobywgcmFua2Rpcj1CVCwgbGFiZWw9J1hCUkwgQ29tcG9uZW50cycsIG5vZGVzZXA9MC4wNSwgcmFua3NlcD0wLjAyLCBmb250bmFtZT1IZWx2ZXRpY2FdCiAgCiAgbm9kZSBbc2hhcGU9Ym94LCBzdHlsZT0nZmlsbGVkJywgY29sb3I9dHJhbnNwYXJlbnQsIGZpbGxjb2xvcj0nI2Y1ZjVmNScsIGZvbnRuYW1lPUhlbHZldGljYSwgZm9udGNvbG9yPScjMmMzZTUwJ10KICAKICBhW2xhYmVsPSdYTUwnLCB3aWR0aD05LjMsIGZpbGxjb2xvcj0nI2Q5ZDlkOSddOyAKICBiW2xhYmVsPSdYQlJMIFNwZWNpZmljYXRpb25zJywgd2lkdGg9OS4zLCBmaWxsY29sb3I9JyNkOWQ5ZDknXTsgCiAgY1tsYWJlbD0nZGljdGlvbmFyeS92b2NhYnVsYXJ5Jywgd2lkdGg9OS4xLCBmaWxsY29sb3I9JyNlNmU2ZTYnXTsgCiAgZFtsYWJlbD0nRXh0ZW5zaW9ucycsIHdpZHRoPTMsIGZpbGxjb2xvcj0nI2U2ZTZlNiddOyAKICBlW2xhYmVsPSdUeXBlIERlZmluaXRpb25zJywgd2lkdGg9MywgZmlsbGNvbG9yPScjZTZlNmU2J107IAogIGZbbGFiZWw9J0xpbmtiYXNlcycsIHdpZHRoPTQuNSwgZmlsbGNvbG9yPScjZTZlNmU2J107IAogIGdbbGFiZWw9J090aGVyIEltcG9ydGVkIFRheG9ub21pZXMnLCB3aWR0aD0zLCBmaWxsY29sb3I9JyNlNmU2ZTYnXTsKICBoW2xhYmVsPSdPdGhlciBSZXNvdXJjZXMnLCB3aWR0aD00LjUsIGZpbGxjb2xvcj0nI2U2ZTZlNiddOwogIGlbbGFiZWw9J1JlcG9ydCBTcGVjaWZpYyBUYXhvbm9teSBFeHRlbnNpb25zIGFuZCBMaW5rYmFzZXMgKGlmIGFsbG93ZWQpJywgd2lkdGg9OS4xLCBmaWxsY29sb3I9JyNmNWY1ZjUnXQogIGpbbGFiZWw9J1hCUkwgSW5zdGFuY2UgKFJlcG9ydCknLCB3aWR0aD05LjEsIGZpbGxjb2xvcj0nI2Y1ZjVmNSddCiAga1tsYWJlbD0nQ29uc3VtZXIgRGF0YSBNb2RlbChzKScsIGZpbGxjb2xvcj0nI2ZjZmNmYycsIHdpZHRoPTkuM10KICB4W3dpZHRoPTAsIGxhYmVsPScnLCBzdHlsZT1pbnZpc10KCiAgCiAgZWRnZVtjb2xvcj0nIzI0MjQyNCcsIHBlbndpZHRoPTAuMl0KICAKICBhIC0+IGJbc3R5bGU9aW52aXMsIGFycm93aGVhZD1ub25lXQogIGIgLT4gZFtzdHlsZT1pbnZpcywgYXJyb3doZWFkPW5vbmVdCiAgYiAtPiBlW3N0eWxlPWludmlzLCBhcnJvd2hlYWQ9bm9uZV0KICBiIC0+IGdbc3R5bGU9aW52aXMsIGFycm93aGVhZD1ub25lXQogIHN1YmdyYXBoIGNsdXN0ZXIwIHsKICAgIGdyYXBoIFtyYW5rZGlyPUJULCBsYWJlbD0nWEJSTCBUYXhvbm9teScsIGNvbG9yID0gY3JpbXNvbl07CiAgICB7IAogICAgICAgIHJhbms9c2FtZTsKICAgICAgICBnIC0+IGRbc3R5bGU9aW52aXMsIGFycm93aGVhZD1ub25lXQogICAgICAgIGcgLT4gZVtzdHlsZT1pbnZpcywgYXJyb3doZWFkPW5vbmVdCiAgICAgICAKICAgIH0KICAgIAogICAgIGQgLT4gY1tzdHlsZT1pbnZpcywgYXJyb3doZWFkPW5vbmVdCiAgICAgZSAtPiBjW3N0eWxlPWludmlzLCBhcnJvd2hlYWQ9bm9uZV0KICAgICBnIC0+IGNbc3R5bGU9aW52aXMsIGFycm93aGVhZD1ub25lXQogIAogICAgewogICAgICAgIHJhbms9c2FtZTsKICAgICAgICBoIC0+IGZbc3R5bGU9aW52aXMsIGFycm93aGVhZD1ub25lXQogICAgICAgIGggLT4geFtzdHlsZT1pbnZpcywgYXJyb3doZWFkPW5vbmVdCiAgICB9IAogICAgYyAtPiBoW3N0eWxlPWludmlzLCBhcnJvd2hlYWQ9bm9uZV0KICAgIGMgLT4gZltzdHlsZT1pbnZpcywgYXJyb3doZWFkPW5vbmVdCiAgICBjIC0+IHhbc3R5bGU9aW52aXMsIGFycm93aGVhZD1ub25lXQogIH0KICBzdWJncmFwaCBjbHVzdGVyMSB7CiAgICBncmFwaCBbcmFua2Rpcj1CVCwgbGFiZWw9J1hCUkwgUmVwb3J0IHBhY2thZ2UnLCBjb2xvciA9IGNyaW1zb25dOwogICAgaSAtPiBqW3N0eWxlPWludmlzLCBhcnJvd2hlYWQ9bm9uZV0KICB9CiAgaCAtPiBpW3N0eWxlPWludmlzLCBhcnJvd2hlYWQ9bm9uZV0KICBmIC0+IGlbc3R5bGU9aW52aXMsIGFycm93aGVhZD1ub25lXQogIHggLT4gaVtzdHlsZT1pbnZpcywgYXJyb3doZWFkPW5vbmVdCiAgaiAtPiBrW3N0eWxlPWludmlzLCBhcnJvd2hlYWQ9bm9uZV0KICAKCn0gICAgICAgICAgICAgICAgIAoiLCBoZWlnaHQ9IjEwMCUiLCB3aWR0aD0iMTAwJSIpCmBgYAoKMS4gQXQgdGhlIGJhc2UsIHdlIGhhdmUgKipYTUwqKiwgdGhlIGZvdW5kYXRpb24gZm9yIGV2ZXJ5dGhpbmcgZWxzZS4gIAoyLiBbKipYQlJMIHNwZWNpZmljYXRpb25zKipdKCN4YnJsLXNwZWNzKSBhcmUgYmFzZWQgb24gWE1MLCB0aGVzZSBzcGVjaWZpY2F0aW9ucyBwcm92aWRlIHRoZSBidWlsZGluZyBibG9ja3MgZm9yIGEgcmVwb3J0aW5nIHN5c3RlbSBiYXNlZCBvbiBYQlJMLiAgCjMuICoqWEJSTCBUYXhvbm9teSoqIGlzIHRoZSBtb3N0IGNyaXRpY2FsIGluZ3JlZGllbnQsIGl0IHVzZXMgWEJSTCBzcGVjaWZpY2F0aW9ucyB0byBidWlsZCB0aGUgc3RydWN0dXJlIGFuZCB0aGUgZGF0YSBtb2RlbCBmb3IgWEJSTCByZXBvcnRpbmcsIHdlIGNhbiB0aGluayBvZiBhIFRheG9ub215IGFzIHRoZSBTY2hlbWEgZm9yIGEgcGFydGljdWxhciByZXBvcnRpbmcgZG9tYWluLiBYQlJMIFRheG9ub215IGNvbnNpc3RzIG9mOiAgCiAgICAqIF9fRGljdGlvbmFyeS9Wb2NhYnVsYXJ5X18gb2YgZWxlbWVudHMgdG8gYmUgdXNlZCBpbiByZXBvcnRpbmcsIGluIFhCUkwgdGVybWlub2xvZ3ksIHRoZXNlIGFyZSBjYWxsZWQgXyJDb25jZXB0cyJfLiAgCiAgICAqIF9fVHlwZSBEZWZpbml0aW9uc19fIGFyZSBjb21wb25lbnRzIG9yIGV4dGVuc2lvbiBvZiBleGlzdGluZyBjb21wb25lbnRzIHRoYXQgYXJlIHRoZSBidWlsZGluZyBibG9ja3Mgb2YgQ29uY2VwdHMuICAKICAgICogX19MaW5rYmFzZXNfXyBhcmUgZ3JvdXBzIG9mIFhsaW5rcyB0aGF0IGxpbmtzIGNvbmNlcHRzIHRvZ2V0aGVyIHRvIGZvcm0gYSBsb2dpY2FsIHN0cnVjdHVyZSwgYW4gZXhhbXBsZSBvZiBsaW5rYmFzZXMgaXMgX1ByZXNlbnRhdGlvbiBMaW5rYmFzZV8sIHdoaWNoIGRlZmluZXMgb25lIG9yIG1vcmUgaGllcmFyY2hpY2FsIHN0cnVjdHVyZXMgb2YgY29uY2VwdHMuIFRoaXMgYWxsb3dzIHRoZSB0YXhvbm9teSB0byBiZSBwcm9wZXJseSBvcmdhbml6ZWQsIGFuZCBpdCBwZXJtaXRzIFhCUkwgcmVuZGVyaW5nIHNvZnR3YXJlIHRvIGNyZWF0ZSB2aXN1YWwgcmVwcmVzZW50YXRpb25zIG9mIHRoZSB0YXhvbm9teSB0aGF0IGFyZSBodW1hbi1yZWFkYWJsZSBhbmQgZWFzaWx5IG5hdmlnYWJsZS4uICAKICAgICogX19PdGhlciBJbXBvcnRlZCBUYXhvbm9taWVzX18gWEJSTCB0YXhvbm9taWVzIGNhbiBpbXBvcnQgb3RoZXIgdGF4b25vbWllcyB0byBiZSBwYXJ0IG9mIHRoZSBiYXNlIHRheG9ub215LCB0aGlzIG1lY2hhbmlzbSBhbGxvd3MgZm9yIHJldXNpbmcgZXhpc3RpbmcgdGF4b25vbWllcyByYXRoZXIgdGhhbiByZWNyZWF0aW5nIHNvbWV0aGluZyB0aGF0IGFscmVhZHkgZXhpdHMuIEFsbCB0YXhvbm9taWVzIGltcG9ydGVkIGJ5IHRoZSBiYXNlIHRheG9ub215IGFuZCBhbnkgb3RoZXIgdGF4b25vbWllcyB0aGF0IGltcG9ydGVkIHRheG9ub21pZXMgaW1wb3J0IGFsbCB0b2dldGhlciBhcmUgY2FsbGVkICoqRGlzY292ZXJhYmxlIFRheG9ub215IFNldCAoRFRTKSoqLiBBbiBleGFtcGxlIGZvciB0aGF0IGlzIHRoZSBVUy1HQUFQIHRheG9ub215IHdoaWNoIGltcG9ydHMgU3RvY2sgRXhjaGFuZ2UgQ29tbWlzc2lvbiAoU0VDKSB0YXhvbm9taWVzLiBTb21lIG9mIHRlcm1pbm9sb2d5IHJlbGV2YW50IHRvIFRheG9ub215IChbX2Jhc2VkIG9uIFhCUkwgR2xvc3NhcnldKGh0dHBzOi8vd3d3Lnhicmwub3JnL2d1aWRhbmNlL3hicmwtZ2xvc3NhcnkvKSk6ICAKICAgIAogICAgICArIF9fQmFzZSBUYXhvbm9teV9fOiBBIHRheG9ub215IHRoYXQgaXMgdXNlZCBhcyB0aGUgc3RhcnRpbmcgcG9pbnQgZm9yIGFuIGV4dGVuc2lvbiB0YXhvbm9teS4gIAogICAgICArIF9fRXh0ZW5zaW9uIFRheG9ub215X186IEEgdGF4b25vbXkgdGhhdCBpcyBjb25zdHJ1Y3RlZCB1c2luZyBvbmUgb3IgbW9yZSBvdGhlciB0YXhvbm9taWVzIChhIGJhc2UgdGF4b25vbXkpIGFzIGEgc3RhcnRpbmcgcG9pbnQuIEV4dGVuc2lvbiB0YXhvbm9taWVzIGFyZSB0eXBpY2FsbHkgY3JlYXRlZCBieSBhIGRpZmZlcmVudCBlbnRpdHkgZnJvbSB0aGUgYXV0aG9yIG9mIHRoZSBiYXNlIHRheG9ub215LiBFeHRlbnNpb24gdGF4b25vbWllcyBtYXkgYmUgY3JlYXRlZCBieSBwcmVwYXJlcnMgKHNlZSBlbnRpdHktc3BlY2lmaWMgZXh0ZW5zaW9uIHRheG9ub215KS4gIAogICAgICArIF9fRW50aXR5LXNwZWNpZmljIGV4dGVuc2lvbiB0YXhvbm9teV9fOiBBbiBleHRlbnNpb24gdGF4b25vbXkgdGhhdCBpcyBjcmVhdGVkIGJ5IHRoZSBwcmVwYXJlciBvZiBhbiBYQlJMIHJlcG9ydCBpbiBvcmRlciB0byBkaXNjbG9zZSBpbmZvcm1hdGlvbiB0aGF0IGlzIHNwZWNpZmljIHRvIHRoZSByZXBvcnRpbmcgZW50aXR5LgogICAgICArIF9fVGF4b25vbXkgRW50cnkgUG9pbnRfXzogQSB0YXhvbm9teSBlbnRyeSBwb2ludCBpZGVudGlmaWVzIGEgc3Vic2V0IChvciAidmlldyIpIG9mIGEgdGF4b25vbXkuIEZvciBleGFtcGxlLCBhIHRheG9ub215IG1heSBjYXRlciBmb3IgZGlmZmVyZW50IGluZHVzdHJpZXMgcmVwb3J0aW5nIHVuZGVyIHRoZSBzYW1lIGFjY291bnRpbmcgc3RhbmRhcmQsIGl0IG1heSBwcm92aWRlIGFuIGVudHJ5IHBvaW50IGZvciBlYWNoIGluZHVzdHJ5LiBBIHRheG9ub215IGVudHJ5IHBvaW50IGlzIGlkZW50aWZpZWQgYnkgYSB1bmlxdWUgVVJMIChvciBzZXQgb2YgVVJMcyksIGFuZCBpcyByZWZlcmVuY2VkIGJ5IGFuIFhCUkwgcmVwb3J0IG9yIGFuIGV4dGVuc2lvbiB0YXhvbm9teS4gIAogICAgKiBfX0V4dGVuc2lvbnNfXyBhbnkgZXh0ZW5zaW9ucyBtYWRlIHRvIGV4aXN0aW5nIHRheG9ub21pZXMuICAKICAgICogX19PdGhlciBSZXNvdXJjZXNfXyBzdWNoIGFzIGRvY3VtZW50YXRpb24gYW5kIHJlZmVyZW5jZXMgbWF5IGJlIGluY2x1ZGVkIGluIGFuIFhCUkwgVGF4b25vbXkuICAKNC4gKipYQlJMIFJlcG9ydCoqIGNvbnNpc3RzIG9mOiAgCiAgICAKICAgICogX1NjaGVtYV8gY29udGFpbmluZyBhbnkgZXh0ZW5zaW9ucyB0byB0aGUgYmFzZSB0YXhvbm9teSBpZiBleHRlbnNpb24gaXMgYWxsb3dlZC4gIAogICAgKiBfTGlua2Jhc2VzXyByZWxldmFudCB0byB0aGUgcmVwb3J0LiAgCiAgICAqIF9JbnN0YW5jZSBEb2N1bWVudF8gY29udGFpbmluZyB0aGUgaW5mb3JtYXRpb24gZm9yIHRoZSBjdXJyZW50IHJlcG9ydC4gIAo1LiAqKkNvbnN1bWVyIERhdGEgTW9kZWwqKiBpcyB3aGVyZSB0aGUgZGF0YSB0cmFuc3BvcnRlZCBieSBYQlJMIGlzIHN0b3JlZCwgdGF4b25vbWllcyBtdXN0IGNvbnNpZGVyIGNvbnN1bWVyIGRhdGEgbmVlZHMgaW4gaXRzIGRlc2lnbi4gCgojIyMgWEJSTCBTcGVjaWZpY2F0aW9uc3sjeGJybC1zcGVjc30gIApBcyBleHBsYWluZWQgcHJldmlvdXNseSBYQlJMIGlzIGFuIGV4dGVuc2lvbiBvZiBYTUwsIGJhc2ljYWxseSBYQlJMIGludGVybmF0aW9uYWwgdXNlZCBYTUwgdG8gZGVmaW5lIFhCUkwgY29tcG9uZW50cyBhbmQgZWxlbWVudHMgYW5kIHRoZSByZXN1bHQgaXMgW1hCUkwgc3BlY2lmaWNhdGlvbnNdKGh0dHBzOi8vc3BlY2lmaWNhdGlvbnMueGJybC5vcmcvc3BlY2lmaWNhdGlvbnMuaHRtbCkuICAKQXMgb2YgZGF0ZSBvZiB0aGlzIGRvY3VtZW50LCB0aGUgcmVsZXZhbnQgY3VycmVudCBYQlJMIHNwZWNpZmljYXRpb25zIHJlY29tbWVuZGF0aW9ucyBhcmUgYXMgZm9sbG93czogCgoqIFtYQlJMXShodHRwczovL3NwZWNpZmljYXRpb25zLnhicmwub3JnL3NwZWMtZ3JvdXAtaW5kZXgtZ3JvdXAtYmFzZS1zcGVjLmh0bWwpe3RhcmdldD1fYmxhbmt9OiBDb3JlIFhCUkwgU3BlY3MuICAKKiBbRGltZW5zaW9uc10oaHR0cHM6Ly9zcGVjaWZpY2F0aW9ucy54YnJsLm9yZy9zcGVjLWdyb3VwLWluZGV4LWdyb3VwLWRpbWVuc2lvbnMuaHRtbCl7dGFyZ2V0PV9ibGFua306IFRoZSBYQlJMIERpbWVuc2lvbnMgc3BlY2lmaWNhdGlvbiBlbmFibGVzIHRoZSByZXBvcnRpbmcgb2YgbXVsdGktZGltZW5zaW9uYWwgZmFjdHMgYWdhaW5zdCBkaW1lbnNpb25zIGRlZmluZWQgaW4gYW4gWEJSTCB0YXhvbm9teS4gIAoqIFtFeHRlbnNpYmxlIEVudW1lcmF0aW9uc10oaHR0cHM6Ly9zcGVjaWZpY2F0aW9ucy54YnJsLm9yZy9zcGVjLWdyb3VwLWluZGV4LWV4dGVuc2libGUtZW51bWVyYXRpb25zLmh0bWwpe3RhcmdldD1fYmxhbmt9OiBBbGxvd3MgZm9yIGNvbnN0cmFpbmluZyB0aGUgYWxsb3dlZCB2YWx1ZXMgZm9yIHByaW1hcnkgcmVwb3J0aW5nIGNvbmNlcHRzIChjaG9pY2VzIGZyb20gc3BlY2lmaWMgbGlzdCkuICAKKiBbRm9ybXVsYV0oaHR0cHM6Ly9zcGVjaWZpY2F0aW9ucy54YnJsLm9yZy9zcGVjLWdyb3VwLWluZGV4LWZvcm11bGEuaHRtbCl7dGFyZ2V0PV9ibGFua306IFhCUkwgRm9ybXVsYSBwcm92aWRlcyBhIHN0YW5kYXJkIG1lY2hhbmlzbSBmb3IgZGVmaW5pbmcgcnVsZXMgaW4gYSB0YXhvbm9teSB0aGF0IGNhbiBiZSBhcHBsaWVkIGFnYWluc3QgaW5zdGFuY2UgZG9jdW1lbnRzLiAgCiogW0dlbmVyaWMgTGlua3NdKGh0dHBzOi8vc3BlY2lmaWNhdGlvbnMueGJybC5vcmcvc3BlYy1ncm91cC1pbmRleC1nZW5lcmljLWxpbmtzLmh0bWwpe3RhcmdldD1fYmxhbmt9OiBBIGxpbmsgdHlwZSB3aXRoIG5vIHByZWRlZmluZWQgc2VtYW50aWNzIG9yIGNvbnN0cmFpbnRzLiBUaGlzIGNhbiBiZSB1c2VkIHVzZWQgYXMgYSBidWlsZGluZyBibG9jayBmb3Igb3RoZXIgc3BlY2lmaWNhdGlvbnMuICAKKiBbR2VuZXJpYyBQcmVmZXJyZWQgTGFiZWxdKGh0dHBzOi8vc3BlY2lmaWNhdGlvbnMueGJybC5vcmcvc3BlYy1ncm91cC1pbmRleC1nZW5lcmljLXByZWZlcnJlZC1sYWJlbC5odG1sKXt0YXJnZXQ9X2JsYW5rfTogVGhpcyBzcGVjaWZpY2F0aW9uIGludHJvZHVjZXMgdGhlIHByZWZlcnJlZCBsYWJlbCBmZWF0dXJlIGZvciBhbGwgcmVsYXRpb25zaGlwcy4gICAgCiogW0dsb2JhbCBMZWRnZXJdKGh0dHBzOi8vc3BlY2lmaWNhdGlvbnMueGJybC5vcmcvc3BlYy1ncm91cC1pbmRleC14YnJsLWdsLmh0bWwpe3RhcmdldD1fYmxhbmt9OiBYQlJMIFNwZWNzIGZvciB0cmFuc2FjdGlvbmFsIHJlcG9ydGluZy4gIAoqIFtJbmZyYXN0cnVjdHVyZV0oaHR0cHM6Ly9zcGVjaWZpY2F0aW9ucy54YnJsLm9yZy9zcGVjLWdyb3VwLWluZGV4LWluZnJhc3RydWN0dXJlLmh0bWwpe3RhcmdldD1fYmxhbmt9OiBTcGVjaWZpY2F0aW9ucyBpbiB0aGlzIHNlY3Rpb24gYXJlIHVzZWQgdG8gc3VwcG9ydCB0aGUgZGV2ZWxvcG1lbnQgb2YgWEJSTCBzcGVjaWZpY2F0aW9ucyBhbmQgcmVnaXN0cmllcy4gIAoqIFtJbmxpbmUgWEJSTF0oaHR0cHM6Ly9zcGVjaWZpY2F0aW9ucy54YnJsLm9yZy9zcGVjLWdyb3VwLWluZGV4LWlubGluZS14YnJsLmh0bWwpe3RhcmdldD1fYmxhbmt9OiBJbmxpbmUgWEJSTCwgb3IgaVhCUkwsIHByb3ZpZGVzIGEgbWVjaGFuaXNtIGZvciBlbWJlZGRpbmcgWEJSTCB0YWdzIGluIEhUTUwgZG9jdW1lbnRzLiAgCiogW1JlZ2lzdHJpZXNdKGh0dHBzOi8vc3BlY2lmaWNhdGlvbnMueGJybC5vcmcvc3BlYy1ncm91cC1pbmRleC1yZWdpc3RyaWVzLmh0bWwpe3RhcmdldD1fYmxhbmt9OiBSZWdpc3RyaWVzIHByb3ZpZGUgYSBjZW50cmFsaXNlIGxpc3Qgb2YgZGVmaW5pdGlvbnMsIGFsbG93aW5nIGltcGxlbWVudGVycyB0byByZS11c2Ugc3VpdGFibGUgZGVmaW5pdGlvbnMgY3JlYXRlZCBieSBvdGhlcnMuICAKKiBbVGFibGUgTGlua2Jhc2VdKGh0dHBzOi8vc3BlY2lmaWNhdGlvbnMueGJybC5vcmcvc3BlYy1ncm91cC1pbmRleC10YWJsZS1saW5rYmFzZS5odG1sKXt0YXJnZXQ9X2JsYW5rfTogUHJvdmlkZXMgYSBtZWNoYW5pc20gZm9yIHRheG9ub215IGF1dGhvcnMgdG8gZGVmaW5lIGEgdGFidWxhciBsYXlvdXQgb2YgZmFjdHMuIFRoZSByZXN1bHRpbmcgdGFibGVzIGNhbiBiZSB1c2VkIGZvciBib3RoIHByZXNlbnRhdGlvbiBhbmQgZGF0YSBlbnRyeS4gIAoqIFtUYXhvbm9teSAmIFJlcG9ydCBQYWNrYWdlc10oaHR0cHM6Ly9zcGVjaWZpY2F0aW9ucy54YnJsLm9yZy9zcGVjLWdyb3VwLWluZGV4LXRheG9ub215LXBhY2thZ2VzLmh0bWwpe3RhcmdldD1fYmxhbmt9OiBUYXhvbm9teSBQYWNrYWdlcyBwcm92aWRlIGEgc3RhbmRhcmRpc2VkIG1lY2hhbmlzbSBmb3IgcHJvdmlkaW5nIGRvY3VtZW50YXRpb24gYWJvdXQgdGhlIGNvbnRlbnQgb2YgYSB0YXhvbm9teS4gIAoqIFtWZXJzaW9uaW5nXShodHRwczovL3NwZWNpZmljYXRpb25zLnhicmwub3JnL3NwZWMtZ3JvdXAtaW5kZXgtZ3JvdXAtdmVyc2lvbmluZy5odG1sKXt0YXJnZXQ9X2JsYW5rfTogRGVmaW5lcyBhbiBYTUwgc3ludGF4IGZvciBhbiBYQlJMIHZlcnNpb25pbmcgUmVwb3J0LiAgCgpMaW5rIGZvciBlYWNoIHJlY29tbWVuZGF0aW9uIGluY2x1ZGVzIHRoZSBub3JtYXRpdmUgc2NoZW1hLiAKCiMjIyBYQlJMIFJlcHJlc2VudGF0aW9uIG9mIERhdGEgIApBcyB0aGUgVERIIGRlc2NyaWJlcyBpdCwgWEJSTCBwcm92aWRlcyBhIHBsYXRmb3JtIHRvIGdpdmUgZGF0YSBtZWFuaW5nIFtbVERIIHNlY3Rpb24gMS4xLjMgcGFnZSAyXShodHRwczovL3hicmx1cy5naXRodWIuaW8vZG9jcy90ZGguaHRtbCNhX1RvYzQ1Nzk0ODkwKV0uIEEgcGllY2Ugb2YgZGF0YSBkb2VzIG5vdCBoYXZlIGEgbWVhbmluZyB3aXRob3V0IGNvbnRleHQgb3IgbWVhbnMgdG8gYXNzb2NpYXRlIGl0IHdpdGggb3RoZXIgZGF0YSBwb2ludHMsIGZvciBleGFtcGxlLCBkYXRhIGFib3V0IGEgc3dpdGNoIGJlaW5nIG9uIG9yIG9mZiBkb2Vzbid0IGhhdmUgbXVjaCB2YWx1ZSBpZiB3ZSBkb24ndCBrbm93IHdoYXQgZG9lcyB0aGlzIHN3aXRjaCBkbyBhbmQgd2hlbiB3YXMgaXQgb24gb3Igb2ZmLiBYQlJMIGdpdmVzIG1lYW5pbmcgdG8gZGF0YSBieSBwcm92aWRpbmcgbGF5ZXJzIG9mIGNvbnRleHQuICAKCiMjIyMgX1NvbWUgQmFzaWNzXyAgClRoZSBUREggcHJlc2VudHMgdGhlIGFuIGV4YW1wbGUgb2YgYSBfbW9udGhseSBleHBlbnNlcyByZXBvcnQgW1RESCBzZWN0aW9uIDIuMiBwYWdlIDE1XShodHRwczovL3hicmx1cy5naXRodWIuaW8vZG9jcy90ZGguaHRtbCNhX1RvYzQ1Nzk0ODk0KV8gb2YgYSBwZXJzb24gbmFtZWQgIkJvYiIsIHRoZSByZXBvcnQgaXMgaW4gdGhlIGZvcm0gb2YgYSB0YWJsZSB3aXRoIHJvd3MgaGF2aW5nIGV4cGVuc2VzIGxpbmUgaXRlbXMsIGFuZCBjb2x1bW5zIGhhdmluZyBtb250aGx5IGFtb3VudHMgb2YgZXhwZW5zZXMuICAKClRoZSBUREggZXhwbGFpbnMgdGhhdCBleHBlbnNlcyBhbW91bnRzIGFsb25lIGRvIG5vdCBjb252ZXkgbXVjaCBtZWFuaW5nIHVubGVzcyBhc3NvY2lhdGVkIHdpdGggX2RpbWVuc2lvbnNfIGlkZW50aWZ5aW5nIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGFtb3VudHMsIGZvciBleGFtcGxlLCB3aG8gbWFkZSB0aGUgZXhwZW5zZXMsIHdoYXQgaXMgdGhlIG5hdHVyZSBvZiB0aGUgZXhwZW5zZSwgYW5kIGluIHdoaWNoIHBlcmlvZHMgZXhwZW5zZXMgd2VyZSBtYWRlLiBUaGUgaW50ZXJzZWN0aW9uIG9mIG9uZSBvciBtb3JlIG9mIHRoZXNlIGRpbWVuc2lvbnMgd2l0aCBhbiBhbW91bnQgY3JlYXRlcyBhIF9mYWN0XyB0aGF0IGhhcyBjb250ZXh0dWFsIG1lYW5pbmcuICAKCjxkaXY+CjxjZW50ZXI+CiFbRXhwZW5zZSBSZXBvcnRdKGByIGhlcmU6OmhlcmUoJ2RvY3MnLCAnaW1hZ2VzL3RoZF92MTBfMDA2LmpwZycpYCkKPC9jZW50ZXI+CjxwIHN0eWxlPSJ0ZXh0LWFsaWduOmNlbnRlciI+CioqRXhwZW5zZSBSZXBvcnQgRXhhbXBsZSBmcm9tIFRESCoqCjwvcD4KPC9kaXY+CgpPbmUgb2YgdGhlIGJhc2ljIGNvbmNlcHRzIG9mIFhCUkwgZGVzaWduIGlzIHRoYXQgaXQgaWRlbnRpZmllcyBkYXRhIHBvaW50cyBieSBtdWx0aXBsZSBkaW1lbnNpb25zIHRoYXQgZ2l2ZXMgZW5vdWdoIGNvbnRleHQgdG8gdGhlIGRhdGEgcG9pbnQgdG8gYmUgbWVhbmluZ2Z1bCwgaW4gdGhlIGNhc2Ugb2YgdGhlIGV4cGVuc2UgcmVwb3J0IChUREggZXhhbXBsZSksIGFuIGFtb3VudCBvZiBgJDE4MGAgaW4gcm93IDEwLCBpcyBpZGVudGlmaWVkIGJ5IGRpbWVuc2lvbnMgYENsb3RoaW5nYCBhcyBuYXR1cmUgb2YgZXhwZW5zZSwgYW5kIGBKYW51YXJ5YCBhcyBleHBlbnNlIHBlcmlvZCwgYW5kIGBCb2JgIGFzIHRoZSBwZXJzb24gd2hvIG1hZGUgdGhlIGV4cGVuc2UsIHdoaWNoIGNyZWF0ZXMgYW4gWEJSTCBgRmFjdGAuICAKCjxkaXY+CjxjZW50ZXI+CiFbRXhwZW5zZSBSZXBvcnQgRmFjdF0oYHIgaGVyZTo6aGVyZSgnZG9jcycsICdpbWFnZXMvdGhkX3YxMF8wMDguanBnJylgKQo8L2NlbnRlcj4KPHAgc3R5bGU9InRleHQtYWxpZ246Y2VudGVyIj4KKipFeHBlbnNlIFJlcG9ydCBFeGFtcGxlIHdpdGggYW4gaWxsdXN0cmF0ZWQgWEJSTCBmYWN0IGZyb20gVERIKioKPC9wPgo8L2Rpdj4KClRoZSBUREggY2xhc3NpZmllcyBkaW1lbnNpb25zIHRoYXQgaWRlbnRpZmllcyBmYWN0cyBpbiBYQlJMIGludG8gMiBjYXRlZ29yaWVzOiAgCgoxLiBgQ29yZSBEaW1lbnNpb25zYCB3aGljaCBpbmNsdWRlczogIAogICAgKyAqKl9Db25jZXB0XyoqIGNvcmUgZGltZW5zaW9uOiBBIHRheG9ub215IGVsZW1lbnQgKGRpY3Rpb25hcnkvdm9jYWJ1bGFyeSkgdGhhdCBwcm92aWRlcyB0aGUgbWVhbmluZyBmb3IgYSBmYWN0IChlLmcuIEZpeGVkIEFzc2V0cywgUmV2ZW51ZSwgUHJvZml0IC4uLiksIGNvbmNlcHRzIGFyZSB0aGUgYnVpbGRpbmcgYmxvY2tzIG9mIGEgdGF4b25vbXkuICAKICAgICsgKipfUGVyaW9kXyoqIGNvcmUgZGltZW5zaW9uOiBUaW1lIGZyYW1lIG9yIHBvaW50IG9mIHRpbWUgcmVsZXZhbnQgdG8gdGhlIGZhY3QuICAKICAgICsgKipfUmVwb3J0aW5nIGVudGl0eV8qKiAgY29yZSBkaW1lbnNpb246IFRoZSBlbnRpdHkgcmVwb3J0aW5nIHRoZSBmYWN0LCBhbHNvIGtub3duIGFzIGBlbnRpdHkgaWRlbnRpZmllcmAgIAogICAgKyAqKl9Vbml0XyoqIGNvcmUgZGltZW5zaW9uOiBVbml0IG9mIG1lYXN1cmVtZW50IG9mIHJlcG9ydGVkIGZhY3QgKGUuZy4gVVNELCBFVVJPLCBLTSwgS0dNLCBVU0QvU2hhcmUuLi4pLCBpdCBpcyBvbmx5IHJlcXVpcmVkIGZvciBudW1lcmljIGZhY3RzLiAKCjIuIGBUYXhvbm9teSBEZWZpbmVkIERpbWVuc2lvbnNgOiBDb25jZXB0cyB0aGF0IGV4aXN0IGZvciB0aGUgcHVycG9zZSBvZiBncm91cGluZyBmYWN0cyB0aGF0IHNob3VsZCBiZSBpbnRlcnByZXRlZCBpbiBhIHNpbWlsYXIgd2F5LiBUYXhvbm9teSBEZWZpbmVkIERpbWVuc2lvbnMgZG8gbm90IGRpcmVjdGx5IGRlZmluZSBhIGZhY3QgYnV0IHJhdGhlciBpbnRlcnNlY3Qgd2l0aCBhIGZhY3QgdG8gYWRkIGZ1cnRoZXIgY29udGV4dHVhbCBvciBzZW1hbnRpYyBpbmZvcm1hdGlvbiBiZXlvbmQgd2hhdCBpcyBhZGRlZCBieSB0aGUgY29yZSBkaW1lbnNpb25zLCBmb3IgZXhhbXBsZSBhIGNvdW50cnkgZGltZW5zaW9uIGZvciBnZW9ncmFwaGljYWwgYWxsb2NhdGlvbi4KCkNvcmUgRGltZW5zaW9ucyBhbmQgVGF4b25vbXkgRGVmaW5lZCBEaW1lbnNpb25zIGFyZSBkZWZpbmVkIGluIHRoZSBYQlJMIFRheG9ub215IG9yIGl0cyBleHRlbnNpb25zIHVzaW5nIFhCUkwgY29tcG9uZW50cywgYW5kIHRoZW4gdXNlZCBpbiBhbiBYQlJMIGluc3RhbmNlIHRvIHJlcG9ydCBmYWN0cy4gIAoKIyMjIyBfWEJSTCBFbGVtZW50cyBVc2FnZV8gIApYQlJMIHNwZWNpZmljYXRpb25zIGRlZmluZSBhIGhvdyBmaW5hbmNpYWwgcmVwb3J0IGNhbiBiZSBleHByZXNzZWQgaW4gWEJSTC4gVGhpcyBzZWN0aW9uIGlzIGFuIG92ZXJ2aWV3IG9mIFhCUkwgZWxlbWVudHMgdXNlZCB0byBkZXNjcmliZSBhIGRhdGEgcG9pbnQuICAKClRvIGNyZWF0ZSBhbiBYQlJMIHJlcG9ydCBmb3JtIHRoZSBtb250aGx5IGV4cGVuc2VzIGV4YW1wbGUsIGZpcnN0IGEgdGF4b25vbXkgY29udGFpbmluZyB0aGUgdm9jYWJ1bGFyeSBhbmQgbGlua2Jhc2VzIG5lZWRzIHRvIGJlIGNyZWF0ZWQsIHRoZW4gdGhpcyB0YXhvbm9teSBjYW4gYmUgdXNlZCB0byBjcmVhdGUgYW4gWEJSTCBpbnN0YW5jZSB0aGF0IGNvbnRhaW5zIHRoZSBmYWN0cy4gIAoKIyMjIyBfQ3JlYXRpbmcgWEJSTCBUYXhvbm9teSBgQ29uY2VwdGBfICAKQ29uY2VwdHMgaW4gYW4gWEJSTCB0YXhvbm9teSBhcmUgZWxlbWVudHMgdGhhdCBwcm92aWRlcyBhIG1lYW5pbmcgZm9yIGEgZmFjdCwgY29uY2VwdHMgYXJlIGRlZmluZWQgaW4gdGhlIFhCUkwgVGF4b25vbXkgc2NoZW1hLiBDb25jZXB0cyBtYWtlIHVwIHRoZSBkaWN0aW9uYXJ5L3ZvY2FidWxhcnkgYWxsb3dlZCB0byBiZSB1c2VkIGJ5IHRoZSBUYXhvbm9teS4gCgpJbiB0aGUgY2FzZSBvZiBhIGZpbmFuY2lhbCByZXBvcnRpbmcgdGF4b25vbXksIGNvbmNlcHRzIG1heSBkZXNjcmliZSBudW1lcmljIGZpbmFuY2lhbCBlbGVtZW50cyBzdWNoIGFzIGBOZXQgUHJvZml0YCwgYEFzc2V0c2Agb3IgYExpYWJpbGl0aWVzYCwgb3IgbmFycmF0aXZlIGVsZW1lbnRzLCBsaWtlIGBBY2NvdW50aW5nIFBvbGljaWVzYCwgd2hpY2ggbWVhbnMgdGhhdCBhIGNvbmNlcHQgbmVlZHMgdG8gYmUgY3JlYXRlZCBmb3IgZXZlcnkgcmVwb3J0YWJsZSBlbGVtZW50IHdpdGhpbiB0aGUgZG9tYWluIG9mIHRoZSB0YXhvbm9teS4gQ29uY2VwdHMgYXJlIHRoZSBiYWNrYm9uZSBvZiB0aGUgVGF4b25vbXkuIENvbmNlcHRzIHN0cnVjdHVyZXMgYXJlIGRlZmluZWQgaW4gWEJSTCBjb3JlIHNwZWNpZmljYXRpb25zIGluIG5hbWVzcGFjZSBge2h0dHA6Ly93d3cueGJybC5vcmcvMjAwMy9pbnN0YW5jZX1gLiBDb25jZXB0cyBoYXZlIDIgbWFpbiB0eXBlcyBkZWZpbmVkIGluIFhCUkwgdGF4b25vbXksIGBpdGVtYCBhbmQgYHR1cGxlYDogIAoKXyoqTm90ZSoqIGBzdWJzdGl0dXRpb25Hcm91cGA6IEEgc3Vic3RpdHV0aW9uIGdyb3VwIGlzIGEgZmVhdHVyZSBvZiBYTUwgc2NoZW1hIHRoYXQgYWxsb3dzIHNwZWNpZnlpbmcgZWxlbWVudHMgdGhhdCBjYW4gcmVwbGFjZSBhbm90aGVyIGVsZW1lbnQgaW4gZG9jdW1lbnRzIGdlbmVyYXRlZCBmcm9tIHRoYXQgc2NoZW1hLiBUaGUgcmVwbGFjZWFibGUgZWxlbWVudCBpcyBjYWxsZWQgdGhlIGhlYWQgZWxlbWVudCBhbmQgbXVzdCBiZSBkZWZpbmVkIGluIHRoZSBzY2hlbWEgZ2xvYmFsIHNjb3BlLiBUaGUgZWxlbWVudHMgb2YgdGhlIHN1YnN0aXR1dGlvbiBncm91cCBtdXN0IGJlIG9mIHRoZSBzYW1lIHR5cGUgYXMgdGhlIGhlYWQgZWxlbWVudCBvciBhIHR5cGUgdGhhdCBpcyBkZXJpdmVkIGZyb20gdGhlIGhlYWQgZWxlbWVudOKAmXMgdHlwZS5fCgoqIGBpdGVtYDogYW4gSXRlbSByZXByZXNlbnRzIGEgc2luZ2xlIGZhY3Qgb3IgYnVzaW5lc3MgbWVhc3VyZW1lbnQsIGFsbCBlbGVtZW50cyByZXByZXNlbnRpbmcgc2luZ2xlIGZhY3RzIG9yIGJ1c2luZXNzIG1lYXN1cmVtZW50cyBkZWZpbmVkIGluIGFuIFhCUkwgdGF4b25vbXkgZG9jdW1lbnQgYW5kIHJlcG9ydGVkIGluIGFuIFhCUkwgaW5zdGFuY2UgTVVTVCBiZSBlaXRoZXIgKGEpIG1lbWJlcnMgb2YgdGhlIHN1YnN0aXR1dGlvbiBncm91cCBpdGVtOyBvciwgKGIpIG1lbWJlcnMgb2YgYSBzdWJzdGl0dXRpb24gZ3JvdXAgb3JpZ2luYWxseSBiYXNlZCBvbiBpdGVtLiAKCiogYHR1cGxlYDogV2hpbGUgbW9zdCBidXNpbmVzcyBmYWN0cyBjYW4gYmUgaW5kZXBlbmRlbnRseSB1bmRlcnN0b29kLCBzb21lIGZhY3RzIGFyZSBkZXBlbmRlbnQgb24gZWFjaCBvdGhlciBmb3IgcHJvcGVyIHVuZGVyc3RhbmRpbmcsIGVzcGVjaWFsbHkgaWYgbXVsdGlwbGUgb2NjdXJyZW5jZXMgb2YgdGhhdCBmYWN0IGFyZSBiZWluZyByZXBvcnRlZC4gRm9yIGV4YW1wbGUsIGluIHJlcG9ydGluZyB0aGUgbWFuYWdlbWVudCBvZiBhIGNvbXBhbnksIGVhY2ggbWFuYWdlcidzIG5hbWUgaGFzIHRvIGJlIHByb3Blcmx5IGFzc29jaWF0ZWQgd2l0aCB0aGUgbWFuYWdlcidzIGNvcnJlY3QgdGl0bGUuIFN1Y2ggc2V0cyBvZiBmYWN0cyAobWFuYWdlcidzIHRpdGxlL21hbmFnZXIncyBuYW1lKSBhcmUgY2FsbGVkIHR1cGxlcy4KClR1cGxlcyBoYXZlIGNvbXBsZXggY29udGVudCBhbmQgTUFZIGNvbnRhaW4gYm90aCBpdGVtcyBhbmQgb3RoZXIgdHVwbGVzLiAKCkJvdGggYDxpdGVtPmBhbmQgYDx0dXBsZT5gIGVsZW1lbnRzIGFyZSBkZWZpbmVkIGFzIGFic3RyYWN0IGVsZW1lbnRzIGluIFhCUkwsIHdoaWNoIG1lYW5zIHRoZXkgYXJlIG9ubHkgbWVhbnQgdG8gYmUgaGVhZHMgb2Ygc3Vic3RpdHV0aW9uR3JvdXBzIGFuZCB3aWxsIG5ldmVyIGFwcGVhciBpbiBhbiBYQlJMIGluc3RhbmNlLiAgCgoqKl9YQlJMIERhdGEgVHlwZXNfKiogIApXaGVuIGRlZmluaW5nIGFuIFhCUkwgQ29uY2VwdCBpbiB0aGUgdGF4b25vbXksIGl0IHdpbGwgYmUgaW4gZWl0aGVyIGBpdGVtYCBvciBgdHVwbGVgIHN1YnN0aXR1dGlvbiBncm91cHMsIGEgZGF0YSB0eXBlIG11c3QgYmUgZ2l2ZW4gdG8gdGhlIGNvbmNlcHQgd2hpY2ggZGV0ZXJtaW5lcyB3aGF0IHR5cGUgb2YgZGF0YSBjYW4gYmUgc3RvcmVkIGluIHRoaXMgZWxlbWVudCAoZm9yIGV4YW1wbGUsIG51bWJlcnMsIGRhdGVzLCBzdHJpbmdzLCAuLi4gZXRjKSwgWEJSTCB1c2VzIFhNTCBzdGFuZGFyZCB0eXBlcyBpbiBhZGRpdGlvbiB0byBvdGhlciBkZXJpdmVkIHR5cGVzLCAqKlRESCB0YWJsZSAyLTMgcGFnZSAyOCoqIHNob3dzIHRoZSBtb3N0IGNvbW1vbiB0eXBlcyB1c2VkIGluIFhCUkw6ICAKYGBge3IgdGRoX2RhdGFfdHlwZXMsIGVjaG89RkFMU0V9Cmxpc3QoCiAgICAgICAgICAgICAgYyhgZGF0YVR5cGVgPSdzdHJpbmdJdGVtVHlwZScsIGRlc2NyaXB0aW9uPSdSZXByZXNlbnRzIGNoYXJhY3RlciBzdHJpbmdzIGluIFhNTC4nKSwKICAgICAgICAgICAgICBjKGBkYXRhVHlwZWA9J2Jvb2xlYW5JdGVtVHlwZScsIGRlc2NyaXB0aW9uPSdSZXByZXNlbnRzIHRoZSB2YWx1ZXMgb2YgdHdvLXZhbHVlZCBsb2dpYyAodHJ1ZSwgZmFsc2UpLicpLAogICAgICAgICAgICAgIGMoYGRhdGFUeXBlYD0nZGVjaW1hbEl0ZW1UeXBlJywgZGVzY3JpcHRpb249J1JlcHJlc2VudHMgYSBzdWJzZXQgb2YgcmVhbCBudW1iZXJzLCB3aGljaCBjYW4gYmUgcmVwcmVzZW50ZWQgYnkgZGVjaW1hbCBudW1lcmFscy4nKSwKICAgICAgICAgICAgICBjKGBkYXRhVHlwZWA9J2RhdGVUaW1lSXRlbVR5cGUnLCBkZXNjcmlwdGlvbj0nUmVwcmVzZW50cyBpbnN0YW50cyBvZiB0aW1lLCBvcHRpb25hbGx5IG1hcmtlZCB3aXRoIGEgdGltZSB6b25lIG9mZnNldC4nKSwKICAgICAgICAgICAgICBjKGBkYXRhVHlwZWA9J2ludGVnZXJJdGVtVHlwZScsIGRlc2NyaXB0aW9uPSdSZXByZXNlbnRzIHRoZSBzdGFuZGFyZCBtYXRoZW1hdGljYWwgY29uY2VwdCBvZiBpbnRlZ2VyIG51bWJlcnMgYnkgZml4aW5nIHRoZSBmcmFjdGlvbmFsIGRpZ2l0cyBvZiBkZWNpbWFsIHRvIGJlIDAgYW5kIHByb2hpYml0aW5nIHRoZSB0cmFpbGluZyBkZWNpbWFsIHBvaW50LicpLAogICAgICAgICAgICAgIGMoYGRhdGFUeXBlYD0nbW9uZXRhcnlJdGVtVHlwZScsIGRlc2NyaXB0aW9uPSdSZXByZXNlbnRzIGEgZGVjaW1hbCB3aXRoIHRoZSBhZGRlZCBjb25zdHJhaW50IG9mIGEgY3VycmVuY3kgdW5pdC4nKSwKICAgICAgICAgICAgICBjKGBkYXRhVHlwZWA9J3FOYW1lSXRlbVR5cGUnLCBkZXNjcmlwdGlvbj0nUmVwcmVzZW50cyBhIHF1YWxpZmllZCBYTUwgbmFtZS4nKQopICU+JSBiaW5kX3Jvd3MoKSAlPiUgCiAga25pdHI6OmthYmxlKCdodG1sJykgJT4lIGthYmxlRXh0cmE6OmthYmxlX2NsYXNzaWMoZnVsbF93aWR0aCA9IEYpICU+JSAKICBodG1sdG9vbHM6OkhUTUwoKSAlPiUgCiAgaHRtbHRvb2xzOjpkaXYoc3R5bGU9Im92ZXJmbG93LXg6YXV0bzt3aGl0ZS1zcGFjZTogbm93cmFwOyIpCmBgYAoKQWJvdmUgYXJlIGp1c3QgYSBzYW1wbGUgb2YgdGhlIG1vc3QgY29tbW9ubHkgdXNlZCBkYXRhIHR5cGVzLCBbWEJSTCBTcGVjaWZpY2F0aW9ucyBbU2VjdGlvbiA1LjEuMS4zXV0oaHR0cHM6Ly93d3cueGJybC5vcmcvU3BlY2lmaWNhdGlvbi9YQlJMLTIuMS9SRUMtMjAwMy0xMi0zMS9YQlJMLTIuMS1SRUMtMjAwMy0xMi0zMStjb3JyZWN0ZWQtZXJyYXRhLTIwMTMtMDItMjAuaHRtbCNfNS4xLjEuMykgbGlzdHMgbW9yZSBkYXRhIHR5cGVzLCBhbHNvIG90aGVyIFhCUkwgZGF0YSB0eXBlcyBhcmUgZGVmaW5lZCBpbiBbWEJSTCBEYXRhIFR5cGVzIFJlZ2lzdHJ5XShodHRwczovL3NwZWNpZmljYXRpb25zLnhicmwub3JnL3dvcmstcHJvZHVjdC1pbmRleC1yZWdpc3RyaWVzLWR0ci0xLjAuaHRtbCkuCgpMZXQncyBkZWZpbmUgYEZvb2RgIGNvbmNlcHQgKGZyb20gdGhlIG1vbnRobHkgZXhwZW5zZXMgcmVwb3J0KSwgd2l0aCB0aGUgZm9sbG93aW5nIGNoYXJhY3RlcmlzdGljczogIAoKKiBIYXMgYSBgZGViaXRgIGJhbGFuY2Ugc2luY2UgaXQgaXMgYW4gZXhwZW5zZSwgIAoqIEl0cyB2YWx1ZSBDYW5ub3QgYmUgbnVsbCAoYWJzZW50IHZhbHVlKSwgaXQgY2FuIGhhdmUgYSB2YWx1ZSBvZiBgMGAgdGhvdWdoLCAgCiogSXQgaXMgYSBtb25ldGFyeSBpdGVtLCBtZWFuaW5nIHRoYXQgaXQgbmVlZHMgdG8gaGF2ZSBhIG51bWVyaWMgdmFsdWUgYW5kIGEgdW5pdCBhY2NvcmRpbmcgdG8gWEJSTCBzcGVjaWZpY2F0aW9ucy4KCkNvbmNlcHQgaXMgZGVmaW5lZCBpbiB0aGUgdGF4b25vbXkgU0NIRU1BIGFzIGZvbGxvd3M6ICAKPGRpdiBpZD0iZXhhbXBsZV8xX3NjaGVtYV8wMSIvPgpgYGB7ciBleGFtcGxlXzFfc2NoZW1hXzAxLCBlY2hvPUZBTFNFfQpmbl9Db2RlQ2h1bmtPdXQobGFuZyA9ICd4bWwnLCB0eHQgPSAKJzwhLS0gRnJvbSB0YXhvbm9teSBzY2hlbWEgZmlsZSAoLnhzZCkgLS0+Cjx4czpzY2hlbWEgeG1sbnM6eHM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIgogIHhtbG5zOmV4cGVuc2VzPSJodHRwOi8vd3d3LmV4cGVuc2VzLmNvbS90YXhvbm9teSIKICB4bWxuczp4YnJsaT0iaHR0cDovL3d3dy54YnJsLm9yZy8yMDAzL2luc3RhbmNlIgogIGF0dHJpYnV0ZUZvcm1EZWZhdWx0PSJ1bnF1YWxpZmllZCIgZWxlbWVudEZvcm1EZWZhdWx0PSJxdWFsaWZpZWQiCiAgdGFyZ2V0TmFtZXNwYWNlPSJodHRwOi8vd3d3LmV4cGVuc2VzLmNvbS90YXhvbm9teSI+CiAgICAKICAgIDxlbGVtZW50IAogICAgICB4YnJsaTpuYW1lPSJGb29kIgogICAgICB4YnJsaTpwZXJpb2RUeXBlPSJkdXJhdGlvbiIKICAgICAgeGJybGk6YmFsYW5jZT0iZGViaXQiCiAgICAgIG5pbGxhYmxlPSJmYWxzZSIKICAgICAgYWJzdHJhY3Q9ImZhbHNlIgogICAgICB0eXBlPSJ4YnJsaTptb25ldGFyeUl0ZW1UeXBlIgogICAgICBzdWJzdGl0dXN0aW9uR3JvdXA9InhicmxpOml0ZW0iCiAgICAgIGlkPSJleHBlbnNlX0Zvb2QiLz4KICAgICAgICAKPC94czpzY2hlbWE+JykKYGBgCl9Ob3RlczpfICAKCiogTmFtZXNwYWNlIGBodHRwOi8vd3d3Lnhicmwub3JnLzIwMDMvaW5zdGFuY2VgIHByZWZpeGVkIGFzIGB4YnJsaWAgd2FzIGRlY2xhcmVkIGZvciBYQlJMIHNwZWNpZmljYXRpb24gc2NoZW1hIHRvIGJlIGFibGUgdG8gdXNlIGVsZW1lbnRzIGZvcm0gdGhhdCBuYW1lc3BhY2UuIAoqIFRoZSB0YXhvbm9teSBuYW1lc3BhY2UgYGh0dHA6Ly93d3cuZXhwZW5zZXMuY29tL3RheG9ub215YCBhbmQgcHJlZml4ZWQgYXMgYGV4cGVuc2VzYAoqIGBkdXJhdGlvbmAgd2FzIHNlbGVjdGVkIGZvciBgQHhicmxpOnBlcmlvZFR5cGVgIFhCUkwgYXR0cmlidXRlLCBiZWNhdXNlIHRoaXMgaXMgYW4gZXhwZW5zZSB0aGF0IG9jY3VycyBkdXJpbmcgYSBzcGVjaWZpZWQgcGVyaW9kIChub3QgYSBiYWxhbmNlIGF0IGEgbW9tZW50IG9mIHRpbWUpLiAgCiogYHhicmxpOm1vbmV0YXJ5SXRlbVR5cGVgIHdhcyBhc3NpZ25lZCB0byBgQHR5cGVgIHRvIHJlZmxlY3QgdGhlIHR5cGUgb2YgZGF0YSBleHBlY3RlZCB0byBiZSByZXBvcnRlZCBmb3IgdGhpcyBjb25jZXB0LiAgCiogRWFjaCBlbGVtZW50IG11c3QgaGF2ZSBhIHVuaXF1ZSBpZC4gIAoqIEJlY2F1c2Ugd2UgcmVmZXJyZWQgdG8gWEJSTCBzcGVjaWZpY2F0aW9uLCB0aGlzIHNjaGVtYSBkb2N1bWVudCBjYW4gYmUgdmFsaWRhdGVkIGFnYWluc3QgWEJSTCBzcGVjaWZpY2F0aW9ucy4KCiMjIyMgX1hCUkwgSW5zdGFuY2UgRG9jdW1lbnRfeyNpbnMtZG9jfSAgCkluc3RhbmNlIGRvY3VtZW50IGlzIHRoZSBhY3R1YWwgcmVwb3J0IGNvbnRhaW5pbmcgZmFjdHMgYW5kIHJlcG9ydGVkIHZhbHVlcywgaXQgaXMgY29uc3RydWN0ZWQgdXNpbmcgWEJSTCBjb25zdHJ1Y3RzLiBUaGUgcm9vdCBlbGVtZW50IG9mIFhCUkwgaW5zdGFuY2UgZG9jdW1lbnQgaXMgYDx4YnJsPmAsIGFuZCBpdCBpcyBkZWZpbmVkIGluIFhCUkwgc3BlY2lmaWNhdGlvbnMgaW4gdGhlIG5hbWVzcGFjZSBge2h0dHA6Ly93d3cueGJybC5vcmcvMjAwMy9pbnN0YW5jZX1gLCBhIGRpYWdyYW0gZm9yIHRoZSBgeGJybGAgZWxlbWVudCBkZWNsYXJhdGlvbnMgaXMgYXMgZm9sbG93czogIAoKPGRpdj4KPGNlbnRlcj4KIVtYQlJMIFR5cGVdKGByIGhlcmU6OmhlcmUoJ2RvY3MnLCAnaW1hZ2VzL3hicmxFbGVtZW50LmpwZycpYCkKPC9jZW50ZXI+CjxwIHN0eWxlPSJ0ZXh0LWFsaWduOmNlbnRlciI+CioqWEJSTCBUeXBlIERlY2xhcmF0aW9uKioKPC9wPgo8L2Rpdj4KCkFjY29yZGluZyB0byBYQlJMIHNwZWNpZmljYXRpb25zOyBgPHhicmw+YCBhbGxvd2VkIGNoaWxkIGVsZW1lbnRzIGFyZSBhcyBmb2xsb3dzOiAgCgoqKkEuIExpbmtzIHRvIHNjaGVtYSBhbmQgZGVjbGFyYXRpb24gdXNlZCB0byBjb25zdHJ1Y3QgdGhlIHJlcG9ydDoqKiAgCgoqIGA8U2NoZW1hUmVmPmA6IEFuIFhNTCBzaW1wbGUgbGluayB0byBsb2NhdGlvbiBvZiB0aGUgZW50cnkgcG9pbnQgb2YgdGhlIHRheG9ub215IHJlbGV2YW50IHRvIHRoaXMgcmVwb3J0LiBUaGlzIGVsZW1lbnQgaXMgZGVmaW5lZCBpbiBuYW1lc3BhY2UgYHtodHRwOi8vd3d3Lnhicmwub3JnLzIwMDMvbGlua2Jhc2V9YC4gIAoqIGA8bGlua2Jhc2VSZWY+YDogQW4gWE1MIHNpbXBsZSB0eXBlIGxpbmsgdG8gbG9jYXRpb24gb2YgbGlua2Jhc2UgcmVsZXZhbnQgdG8gdGhpcyByZXBvcnQuIHRoaXMgZWxlbWVudCBpcyBkZWZpbmVkIGluIG5hbWVzcGFjZSBge2h0dHA6Ly93d3cueGJybC5vcmcvMjAwMy9saW5rYmFzZX1gIChTZWUgc2VjdGlvbiAzLjcuNCBMaW5rYmFzZXMpLiAKKiBgPHJvbGVSZWY+YDogQW4gWE1MIHNpbXBsZSB0eXBlIGxpbmsgdG8gbG9jYXRpb24gb2YgZGVjbGFyYXRpb24gb2YgYSBgcm9sZVR5cGVgIHVzZWQgaW4gdGhpcyByZXBvcnQuIEVsZW1lbnQgaXMgZGVmaW5lZCBpbiBuYW1lc3BhY2UgYHtodHRwOi8vd3d3Lnhicmwub3JnLzIwMDMvbGlua2Jhc2V9YAoqIGA8YXJjcm9sZVJlZj5gOiBBbiBYTUwgc2ltcGxlIHR5cGUgbGluayB0byBsb2NhdGlvbiBvZiBkZWNsYXJhdGlvbiBvZiBhIGFyY3JvbGVUeXBlIHVzZWQgaW4gdGhpcyByZXBvcnQuIEVsZW1lbnQgaXMgZGVmaW5lZCBpbiBuYW1lc3BhY2UgYHtodHRwOi8vd3d3Lnhicmwub3JnLzIwMDMvbGlua2Jhc2V9YAoKKipCLiBFbGVtZW50cyB1c2VkIHRvIGNhcnJ5IHRoZSBpbmZvcm1hdGlvbiBvZiBjdXJyZW50IHJlcG9ydDoqKiAgCgojIyMjIyBfQ3JlYXRpbmcgWEJSTCBpbnN0YW5jZSBgQ29udGV4dGBfICAKSW4gYEJvYmAncyByZXBvcnQ7IGBGb29kYCBleHBlbnNlcyBmb3IgSmFudWFyeSAyMDIwIHdhcyAkOTAwLCBub3RlIGhlcmUgdGhhdCB3ZSBhdHRhY2hlZCAzIHBpZWNlcyBvZiBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRvIHRoZSBleHBlbnNlIGFtb3VudDogIAoKMS4gYEZvb2RgIHRoZSBjb25jZXB0IGNvcmUgZGltZW5zaW9uLCAKMi4gYEJvYmAgdGhlIG93bmVyIG9mIHRoZSBleHBlbnNlLAozLiBgSmFudWFyeSAyMDIwYCB0aGUgcGVyaW9kIGNvcmUgZGltZW5zaW9uLiAgCgpXZSBhbHJlYWR5IGRlZmluZWQgdGhlIGBGb29kYCBjb25jZXB0IGluIHRoZSB0YXhvbm9teSwgdG8gYXR0YWNoIHRoZSBvd25lciBvZiB0aGUgZXhwZW5zZXMgYW5kIHRoZSBwZXJpb2Qgd2UgbmVlZCB0byB1c2UgWEJSTCBgY29udGV4dGAgZWxlbWVudC4gIAoKYGNvbnRleHRgIGlzIGFuIFhCUkwgZWxlbWVudCB1c2VkIGluIFhCUkwgaW5zdGFuY2UgZG9jdW1lbnQgKHJlcG9ydCkgYW5kIHJlZmVyZW5jZWQgYnkgb25lIG9yIG1vcmUgZmFjdChzKSBpbiB0aGUgWEJSTCByZXBvcnQuIEl0IGNvbnRhaW5zIGluZm9ybWF0aW9uIGFib3V0IHBlcmlvZCwgZW50aXR5LCBhbmQgdGF4b25vbXkgZGVmaW5lZCBkaW1lbnNpb24gcmVsYXRpbmcgdG8gdGhpcyBjb250ZXh0LCBmb2xsb3dpbmcgaXMgYSBkaWFncmFtIG9mIGNvbnRleHQgdHlwZSBkZWNsYXJhdGlvbjogIAoKPGRpdj4KPGNlbnRlcj4KIVtDb250ZXh0IFR5cGVdKGByIGhlcmU6OmhlcmUoJ2RvY3MnLCAnaW1hZ2VzL2NvbnRleHRFbGVtZW50LmpwZycpYCkKPC9jZW50ZXI+CjxwIHN0eWxlPSJ0ZXh0LWFsaWduOmNlbnRlciI+CioqQ29udGV4dCBUeXBlIERlY2xhcmF0aW9uKioKPC9wPgo8L2Rpdj4KCgpXZSBjYW4gZGVmaW5lIGEgY29udGV4dCBmb3IgYEJvYmAgb3duZXIsIGFuZCBKYW51YXJ5IDIwMjAgcGVyaW9kIGFzIGZvbGxvd3M6ICAKYGBge3IgZXhhbXBsZV8xX2luc3RhbmNlXzAxLCBlY2hvPUZBTFNFfQpmbl9Db2RlQ2h1bmtPdXQobGFuZyA9ICd4bWwnLCB0eHQgPSAKJzwhLS0gZGVmaW5lZCBpbiBpbnN0YW5jZSBkb2N1bWVudCAtLT4KPHhicmwgeG1sbnM9Imh0dHA6Ly93d3cueGJybC5vcmcvMjAwMy9pbnN0YW5jZSIKICAgICAgeG1sbnM6ZXhwZW5zZXM9Imh0dHA6Ly93d3cuZXhwZW5zZXMuY29tL3RheG9ub215IgogICAgICB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiB4bWw6bGFuZz0iZW4tVVMiPgogICAgPCEtLSAuLi4gYXQgbGVhc3Qgb25lIGxpbms6c2NoZW1hUmVmIGVsZW1lbnQgZ29lcyBoZXJlIC4uLiAtLT4KICAgIDxjb250ZXh0IGlkPSIwMSI+CiAgICAgIDxlbnRpdHk+CiAgICAgICAgPGlkZW50aWZpZXIgc2NoZW1lPSJodHRwOi8vd3d3LmV4YW1wbGUuY29tL2JvYiI+Qm9iPC9pZGVudGlmaWVyPgogICAgICA8L2VudGl0eT4KICAgICAgPHBlcmlvZD4KICAgICAgICA8c3RhcnREYXRlPjIwMjAtMDEtMDE8L3N0YXJ0RGF0ZT4KICAgICAgICA8ZW5kRGF0ZT4yMDIwLTAxLTMxPC9lbmREYXRlPgogICAgICA8L3BlcmlvZD4KICAgIDwvY29udGV4dD4KPC94YnJsPiAnKQpgYGAKX05vdGVzIFhCUkwgaW5zdGFuY2UgZG9jdW1lbnRfICAKCiogWEJSTCBpbnN0YW5jZSBkb2N1bWVudCByb290IGVsZW1lbnQgbXVzdCBiZSBlbGVtZW50IGA8eGJybD5gICAKKiBJbnN0YW5jZSByZWZlcmVuY2VzIHRheG9ub215IG5hbWVzcGFjZSB0byBiZSBhYmxlIHRvIHVzZSBlbGVtZW50cyBkZWZpbmVkIGluIHRoYXQgdGF4b25vbXkuICAKKiBJbnN0YW5jZSByZWZlcmVuY2VzIFhCUkwgc2NoZW1hICh3aXRoIG5vIHByZWZpeCkgdG8gYmUgYWJsZSB0byB1c2UgWEJSTCBjb25zdHJ1Y3RzLiAgCiogQmVjYXVzZSBvZiB0aGUgcmVmZXJlbmNlcyBhYm92ZSwgdGhpcyBYQlJMIGluc3RhbmNlIGRvY3VtZW50IGNhbiBiZSB2YWxpZGF0ZWQgYWdhaW5zdCBYQlJMIHNwZWNpZmljYXRpb25zIGFuZCB0YXhvbm9teS4gIAoKIyMjIyMgX0NyZWF0aW5nIFhCUkwgaW5zdGFuY2UgYHVuaXRgXyAgClhCUkwgcmVxdWlyZXMgdGhhdCBudW1lcmljIHR5cGUgZmFjdHMgaGFzIGEgcmVmZXJlbmNlIHRvIGEgdW5pdCBbW3NlZSBYQlJMIHNwZWNzIDQuNi4yXShodHRwczovL3d3dy54YnJsLm9yZy9TcGVjaWZpY2F0aW9uL1hCUkwtMi4xL1JFQy0yMDAzLTEyLTMxL1hCUkwtMi4xLVJFQy0yMDAzLTEyLTMxK2NvcnJlY3RlZC1lcnJhdGEtMjAxMy0wMi0yMC5odG1sI180LjYuMildLiBBbmQgc2luY2UgYEZvb2RgIGNvbmNlcHQgaXMgYSBgbW9uZXRhcnlJdGVtVHlwZWAgdHlwZSB3aGljaCBpcyBhIG51bWVyaWMgdHlwZSwgdGhlcmVmb3JlIGFueSBmYWN0IHVzaW5nIGBGb29kYCBjb25jZXB0IG11c3QgcmVmZXIgdG8gYSB1bml0IGluIHRoZSBpbnN0YW5jZSBkb2N1bWVudC4gQSB1bml0IG11c3QgYmUgY3JlYXRlZCBiZWZvcmUgYSBmYWN0IGNhbiBiZSBjcmVhdGVkIGZvciB0aGUgYEZvb2RgLiAKRm9sbG93aW5nIGlzIGEgZGlhZ3JhbSBmb3IgdGhlIGRlY2xhcmF0aW9uIG9mIHRoZSB1bml0IHR5cGUgaW4gWEJSTCBzcGVjaWZpY2F0aW9uczogIAo8ZGl2Pgo8Y2VudGVyPgohW1VuaXQgVHlwZV0oYHIgaGVyZTo6aGVyZSgnZG9jcycsICdpbWFnZXMvdW5pdEVsZW1lbnQuanBnJylgKQo8L2NlbnRlcj4KPHAgc3R5bGU9InRleHQtYWxpZ246Y2VudGVyIj4KKipVbml0IFR5cGUgRGVjbGFyYXRpb24qKgo8L3A+CjwvZGl2PgoKV2UgZGVjbGFyZSBhIHVuaXQgZm9yIFVuaXRlZCBTdGF0ZXMgRG9sbGFycyB1c2luZyBgaXNvNDIxN2AgdGF4b25vbXkgYFVTRGAgZWxlbWVudCBhcyBmb2xsb3dzOiAgCmBgYHtyIGV4YW1wbGVfMV9pbnN0YW5jZV8wMiwgZWNobz1GQUxTRX0KZm5fQ29kZUNodW5rT3V0KGxhbmcgPSAneG1sJywgdHh0ID0gCic8IS0tIEFkZGVkIHRvIHByZXZpb3VzIGluc3RhbnQgZG9jdW1lbnQgYXMgY2hpbGQgdG8gPHhicmw+IGVsZW1lbnQgLS0+Cjx1bml0IGlkPSJ1c2QiIHhtbG5zOmlzbzQyMTc9Imh0dHA6Ly93d3cueGJybC5vcmcvMjAwMy9pc280MjE3Ij4KICA8bWVhc3VyZT5pc280MjE3OlVTRDwvbWVhc3VyZT4KPC91bml0PicpCmBgYAoKIyMjIyMgX0NyZWF0aW5nIFhCUkwgaW5zdGFuY2UgYGZhY3RgXyAgCkFsbCBjb3JlIGRpbWVuc2lvbnMgYXJlIGRlZmluZWQsIGBGb29kYCBjb25jZXB0IGNvcmUgZGltZW5zaW9uIGlzIGRlZmluZWQgaW4gWEJSTCBUYXhvbm9teSBhbmQgaGF2ZSBhIGNvbnRleHQgd2l0aCBgaWQ9MDFgIChob2xkaW5nIHRoZSBwZXJpb2QgYW5kIGVudGl0eSBjb3JlIGRpbWVuc2lvbnMpIGFuZCB1bml0IGNvcmUgZGltZW5zaW9uIHdpdGggYGlkPSJ1c2QiYCBpbiBpbnN0YW5jZSBkb2N1bWVudCwgd2UgY2FuIGNyZWF0ZSBhIGZhY3QgZm9yIGBCb2JgJ3MgYEZvb2RgIGV4cGVuc2VzIGZvciB0aGUgcGVyaW9kIG9mIGBKYW51YXJ5IDIwMjBgIGZvciB0aGUgYW1vdW50IG9mIGA5MDBgIFVuaXRlZCBTdGF0ZXMgRG9sbGFycyBhcyBmb2xsb3dzOiAgCmBgYHtyIGV4YW1wbGVfMV9pbnN0YW5jZV8wMywgZWNobz1GQUxTRX0KZm5fQ29kZUNodW5rT3V0KGxhbmcgPSAneG1sJywgdHh0ID0gCic8IS0tIEFkZGVkIHRvIHByZXZpb3VzIGluc3RhbnQgZG9jdW1lbnQgYXMgY2hpbGQgdG8gPHhicmw+IGVsZW1lbnQgLS0+CjxleHBlbnNlczpGb29kCiAgY29udGV4dFJlZj0iMDEiIAogIGRlY2ltYWxzPSIwIiAKICBpZD0iZmFjdF8wMDEiIAogIHVuaXRSZWY9InVzZCI+OTAwPC9leHBlbnNlczpGb29kPicpCmBgYAoKIyMjIyBfWEJSTCBEaW1lbnNpb25zXyAgClhCUkwgcHJvdmlkZXMgdG9vbHMgZm9yIHJlcG9ydGluZyBtdWx0aWRpbWVuc2lvbmFsIGZhY3RzLCBjb3JlIGRpbWVuc2lvbnMgKENvbmNlcHQsIHBlcmlvZCwgcmVwb3J0aW5nIGVudGl0eSBhbmQgdW5pdCkgYXJlIGF2YWlsYWJsZSBmcm9tIHRoZSBYQlJMIGJhc2Ugc3BlY2lmaWNhdGlvbnMsIGluIGFkZGl0aW9uIHRvIGNvcmUgZGltZW5zaW9ucyB0YXhvbm9teSBkZWZpbmVkIGRpbWVuc2lvbnMgY2FuIGJlIHVzZWQgdG8gZXhwcmVzcyBjb21wbGV4IG11bHRpZGltZW5zaW9uYWwgc3RydWN0dXJlcy4gX1tYQlJMIERpbWVuc2lvbnMgU3BlY2lmaWNhdGlvbnNdKGh0dHBzOi8vc3BlY2lmaWNhdGlvbnMueGJybC5vcmcvd29yay1wcm9kdWN0LWluZGV4LWdyb3VwLWRpbWVuc2lvbnMtZGltZW5zaW9ucy5odG1sKV8uICAKCiMjIyMjIF9BZGRpdGlvbmFsIERpbWVuc2lvbnMgZnJvbSBiYXNlIFhCUkxfICAKWEJSTCBlbGVtZW50IGBjb250ZXh0YCBoYXMgMiBhZGRpdGlvbmFsIGZlYXR1cmVzIHRoYXQgY2FuIHByb3ZpZGUgZGltZW5zaW9uYWxpdHkgdG8gYSBmYWN0LCB0aGUgYDxzZWdtZW50PmAgYW5kIGA8c2NlbmFyaW8+YCBhcyBmb2xsb3dzOiAgCgoqIGA8c2VnbWVudD5gOiBpcyBkZWZpbmVkIGluIFhCUkwgc3BlY2lmaWNhdGlvbnMgYXMgXyJhbiBvcHRpb25hbCBjb250YWluZXIgZm9yIGFkZGl0aW9uYWwgbWFyay11cCB0aGF0IHRoZSBwcmVwYXJlciBvZiBhbiBYQlJMIEluc3RhbmNlIFNIT1VMRCB1c2UgdG8gaWRlbnRpZnkgdGhlIGJ1c2luZXNzIHNlZ21lbnQgbW9yZSBjb21wbGV0ZWx5IGluIGNhc2VzIHdoZXJlIHRoZSBFbnRpdHkgaWRlbnRpZmllciBpcyBpbnN1ZmZpY2llbnQuIl8gYDxzZWdtZW50PmAgaXMgZWxlbWVudCBpcyBhbHNvIHVzZWQgdG8gaW5jb3Jwb3JhdGUgdGF4b25vbXkgZGVmaW5lZCBkaW1lbnNpb24gdXNpbmcgX1hCUkwgRGltZW5zaW9ucyBTcGVjaWZpY2F0aW9uc18uICAKKk5vdGUqOiBzZWdtZW50IGlzIGEgY2hpbGQgZWxlbWVudCBvZiB0aGUgYDxlbnRpdHk+YCBlbGVtZW50ICh3aGljaCBpbiB0dXJuIGlzIGEgY2hpbGQgZWxlbWVudCBvZiB0aGUgYDxjb250ZXh0PmAgZWxlbWVudCkuICAKCiogYDxzY2VuYXJpbz5gOiBYQlJMIHNwZWNpZmljYXRpb25zIGRlc2NyaWJlcyB0aGlzIGVsZW1lbnQgYXMgXyJCdXNpbmVzcyBmYWN0cyBjYW4gYmUgcmVwb3J0ZWQgYXMgYWN0dWFsLCBidWRnZXRlZCwgcmVzdGF0ZWQsIHBybyBmb3JtYSwgZXRjLiBGb3IgaW50ZXJuYWwgcmVwb3J0aW5nIHB1cnBvc2VzLCB0aGVyZSBjYW4gYmUgYW4gZXZlbiBncmVhdGVyIHZhcmlldHkgb2YgYWRkaXRpb25hbCBtZXRhZGF0YSB0aGF0IHByZXBhcmVycyB3YW50IHRvIGFzc29jaWF0ZSB3aXRoIGl0ZW1zLiBUaGUgb3B0aW9uYWwgPHNjZW5hcmlvPiBlbGVtZW50IGFsbG93cyBhZGRpdGlvbmFsIHZhbGlkIG1hcmstdXAgKHNlZSBub3RlIGFib3ZlIHJlZ2FyZGluZyBzZWdtZW50KSB0byBiZSBpbmNsdWRlZCBmb3IgdGhpcyBwdXJwb3NlLiJfICAKCioqU2VnbWVudCBhbmQgU2NlbmFyaW8gRXhhbXBsZSoqICAKCkluIHRoZSBtb250aGx5IGV4cGVuc2UgcmVwb3J0IGV4YW1wbGUsIGFzc3VtZSB0aGF0IGBCb2JgIGhhcyAyIGxvY2F0aW9ucyB0byB0cmFjayBleHBlbnNlcyBmb3IgYGhvbWVgIGFuZCBgb2ZmaWNlYCAoc2VnbWVudHMpLCBhbHNvIGFzc3VtZSB0aGF0IGBCb2JgIHRyYWNrcyBgYnVkZ2V0YCBhbmQgYGFjdHVhbHNgIChzY2VuYXJpb3MpLCB0byBiZSBhYmxlIHRvIGluY2x1ZGUgdGhlc2UgZGltZW5zaW9ucyBpbiBvdXIgcmVwb3J0IHdlIG5lZWQgZmlyc3QgdG8gY3JlYXRlIGFuIGV4dGVuc2lvbiB0YXhvbm9teSB0byBpbmNsdWRlIHRoZXNlIGVsZW1lbnRzIGFzIGZvbGxvd3M6CgpgYGB7ciBzZWdlbWVudF9zY2VuYXJpb194c2QsIGVjaG89RkFMU0V9CmZuX0NvZGVDaHVua091dChsYW5nID0gJ3htbCcsIHR4dCA9IAonPCEtLSBSZXBvcnQgc3BlY2lmaWMgdGF4b25vbXkgZXh0ZW5zaW9uIC0tPgo8c2NoZW1hIHRhcmdldE5hbWVzcGFjZT0iaHR0cDovL3d3dy5leHBlbnNlcy5jb20vdGF4b25vbXkiIAoJCXhtbG5zOmV4cGVuc2VzPSJodHRwOi8vd3d3LmV4cGVuc2VzLmNvbS90YXhvbm9teSIgCgkJeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIiAKCQl4bWxuczp4YnJsaT0iaHR0cDovL3d3dy54YnJsLm9yZy8yMDAzL2luc3RhbmNlIj4KCQkgIAoJPCEtLSBUeXBlIGZvciBzZWdtZW50cyAtLT4KCTxzaW1wbGVUeXBlIG5hbWU9ImxvY2F0aW9uc1R5cGUiPgoJCTxyZXN0cmljdGlvbiBiYXNlPSJ0b2tlbiI+CgkJCTxlbnVtZXJhdGlvbiB2YWx1ZT0iaG9tZSIvPgoJCQk8ZW51bWVyYXRpb24gdmFsdWU9Im9mZmljZSIvPgoJCTwvcmVzdHJpY3Rpb24+Cgk8L3NpbXBsZVR5cGU+CgkJICAKCTwhLS0gcmVwb3J0IHNwZWNpZmljIHNlZ21lbnQgc3ViLWVsZW1lbnQgLS0+Cgk8ZWxlbWVudCBuYW1lPSJsb2NhdGlvbnMiIHR5cGU9ImV4cGVuc2VzOmxvY2F0aW9uc1R5cGUiIC8+CgkJICAKCTwhLS0gVHlwZSBmb3Igc2NlbmFyaW9zIC0tPgoJPHNpbXBsZVR5cGUgbmFtZT0iYWN0dWFsQnVkZ2V0VHlwZSI+CgkJPHJlc3RyaWN0aW9uIGJhc2U9InRva2VuIj4KCQkJPGVudW1lcmF0aW9uIHZhbHVlPSJhY3R1YWwiLz4KCQkJPGVudW1lcmF0aW9uIHZhbHVlPSJidWRnZXQiLz4KCQk8L3Jlc3RyaWN0aW9uPgoJPC9zaW1wbGVUeXBlPgoJPCEtLSByZXBvcnQgc3BlY2lmaWMgc2NuZWFyaW8gc3ViLWVsZW1lbnQgLS0+Cgk8ZWxlbWVudCBuYW1lPSJhY3R1YWxCdWRnZXQiIHR5cGU9ImV4cGVuc2VzOmFjdHVhbEJ1ZGdldFR5cGUiIC8+Cjwvc2NoZW1hPicpCgpgYGAKCioqX05vdGVfKiogIAoKPiBFbGVtZW50cyBjb250YWluZWQgYnkgdGhlIGA8c2NlbmFyaW8+YCBlbGVtZW50IE1VU1QgTk9UIGJlIGRlZmluZWQgaW4gdGhlIGh0dHA6Ly93d3cueGJybC5vcmcvMjAwMy9pbnN0YW5jZSBuYW1lc3BhY2UuIEFsc28sIHRoZXkgTVVTVCBOT1QgYmUgaW4gdGhlIHN1YnN0aXR1dGlvbiBncm91cCBmb3IgZWxlbWVudHMgZGVmaW5lZCBpbiB0aGUgaHR0cDovL3d3dy54YnJsLm9yZy8yMDAzL2luc3RhbmNlIG5hbWVzcGFjZS4gVGhlIDxzY2VuYXJpbz4gZWxlbWVudCBNVVNUIE5PVCBiZSBlbXB0eS4gYHIgdHVmdGU6OnF1b3RlX2Zvb3RlcignLS0tIFtYQlJMIHNwZWNpZmljYXRpb25zXShodHRwczovL3d3dy54YnJsLm9yZy9TcGVjaWZpY2F0aW9uL1hCUkwtMi4xL1JFQy0yMDAzLTEyLTMxL1hCUkwtMi4xLVJFQy0yMDAzLTEyLTMxK2NvcnJlY3RlZC1lcnJhdGEtMjAxMy0wMi0yMC5odG1sI180LjcuNCknKWAKClRvIHJlcG9ydCBmYWN0cyB1c2luZyBsb2NhdGlvbnMgYW5kL29yIGJ1ZGdldCB2cyBhY3R1YWwgZWxlbWVudHMsIG5hbWVzcGFjZSBgaHR0cDovL2JvYnJlcG9ydC5jb20veGJybC90YXhvbm9teWAgbXVzdCBiZSByZWZlcmVuY2VkIGluIG91ciBpbnN0YW5jZSByZXBvcnQgdG8gYmUgYWJsZSBhY2Nlc3MgdGhlc2UgZWxlbWVudHMsIHRoZW4gd2UgbmVlZCB0byBjcmVhdGUgY29udGV4dHMgdGhhdCByZWZlcmVuY2UgdGhlc2UgZWxlbWVudHMsIGFuZCBmaW5hbGx5IHdlIGNhbiByZWZlcmVuY2UgdGhlc2UgY29udGV4dHMgaW4gdGhlIHJlcG9ydGVkIGZhY3RzIGFzIGZvbGxvd3M6ICAKCmBgYHtyIHNlZ21lbnRfc2NlbmFyaW9faW5zdGFuY2UsIGVjaG89RkFMU0V9CmZuX0NvZGVDaHVua091dChsYW5nID0gJ3htbCcsIHR4dCA9IAonPCEtLSBBZGRlZCB0byBwcmV2aW91cyBpbnN0YW50IGRvY3VtZW50IGFzIGNoaWxkcmVuIHRvIDx4YnJsPiBlbGVtZW50IC0tPgogIDx4YnJsIC4uLi4uLi4geG1sbnM6ZXhwZW5zZXM9Imh0dHA6Ly93d3cuZXhwZW5zZXMuY29tL3RheG9ub215Ij4KICA8IS0tIC4uLiBhdCBsZWFzdCBvbmUgbGluazpzY2hlbWFSZWYgZWxlbWVudCBnb2VzIGhlcmUgLi4uIC0tPgogICAgPGNvbnRleHQgaWQ9IjAyIj4KICAgICAgPGVudGl0eT4KICAgICAgICA8aWRlbnRpZmllciBzY2hlbWU9Imh0dHA6Ly93d3cuZXhhbXBsZS5jb20vYm9iIj5Cb2I8L2lkZW50aWZpZXI+CiAgICAgICAgPHNlZ21lbnQ+CiAgICAgICAgICA8ZXhwZW5zZXM6bG9jYXRpb25zPmV4cGVuc2VzOmhvbWU8L2V4cGVuc2VzOmxvY2F0aW9uPgogICAgICA8L3NlZ21lbnQ+CiAgICAgIDwvZW50aXR5PgogICAgICA8cGVyaW9kPgogICAgICAgIDxzdGFydERhdGU+MjAyMC0wMS0wMTwvc3RhcnREYXRlPgogICAgICAgIDxlbmREYXRlPjIwMjAtMDEtMzE8L2VuZERhdGU+CiAgICAgIDwvcGVyaW9kPgogICAgICA8c2NlbmFyaW8+CiAgICAgICAgICA8ZXhwZW5zZXM6YWN0dWFsQnVkZ2V0PmV4cGVuc2VzOmFjdHVhbDwvZXhwZW5zZXM6YWN0dWFsQnVkZ2V0PgogICAgICA8L3NjZW5hcmlvPgogICAgPC9jb250ZXh0PicpCgpgYGAKCk5vdyBoYXZpbmcgY29udGV4dCBgaWQ9MDJgIHdlIGNhbiByZWZlcmVuY2UgdGhlIGZhY3RzIHRoYXQgaW5jbHVkZSBgYWN0dWFsYCBmaWd1cmVzIGZvciBsb2NhdGlvbiBgaG9tZWAgaW4gb3VyIGluc3RhbmNlIHJlcG9ydC4gIAoKCiMjIyMjIFRheG9ub215IGRlZmluZWQgZGltZW5zaW9ucyAgIApUYXhvbm9teSBkZWZpbmVkIGRpbWVuc2lvbnMgZW5hYmxlIGNyZWF0aW9uIG9mIGNvbXBsZXggc3RydWN0dXJlcyBpbiBYQlJMIHRheG9ub215IGFuZCByZXBvcnRzLiBUaGlzIGlzIGFjaGlldmVkIHRocm91Z2ggdGhlIGludGVyYWN0aW9ucyBiZXR3ZWVuIGNvbmNlcHRzIGFuZCBsaW5rYmFzZXMsIHRoaXMgaXMgYmVzdCBkZXNjcmliZWQgaW4gVERIIHNlY3Rpb24gMi4yLjUgcGFnZSAyMSBhcyBmb2xsb3dzOiAgCgo+QSB0YXhvbm9teS1kZWZpbmVkIGRpbWVuc2lvbiBpcyBhIGdyb3VwaW5nIG9mIGNvbmNlcHRzIHRoYXQgaXMgdXNlZCB0byBhZGQgb3JnYW5pemF0aW9uYWwgc3RydWN0dXJlIHRvIGZhY3RzLiBUaGVzZSBkaW1lbnNpb25hbCBjb25jZXB0cyBzaG91bGQgbm90IGJlIGRpcmVjdGx5IGFzc29jaWF0ZWQgd2l0aCBhIGRhdGEgcG9pbnQgYnV0IHJhdGhlciBhcmUgZW1wbG95ZWQgdG8gaW5kaWNhdGUgYWRkaXRpb25hbCBjb250ZXh0dWFsIGluZm9ybWF0aW9uIGJleW9uZCB0aGUgc2ltcGxlIHNlbWFudGljIGlkZW50aWZpZXIgb3Igd2hhdCBpcyBwcm92aWRlZCB0aHJvdWdoIGFueSBvZiB0aGUgb3RoZXIgY29yZSBkaW1lbnNpb25zLiBFeHBhbmRpbmcgdGhlIGV4cGVuc2UgZXhhbXBsZSBieSBhdHRyaWJ1dGluZyB0aGUgbW9udGhseSBleHBlbnNlcyB0byB0d28gcGVvcGxlIGluIHRoZSBzYW1lIGhvdXNlaG9sZCBjcmVhdGVzIGEgbGV2ZWwgb2YgY29tcGxleGl0eSB0aGF0IGNhbm5vdCBiZSBlYXNpbHkgcmVwcmVzZW50ZWQgd2l0aCBvbmx5IGNvbmNlcHRzLiBQcmV2aW91c2x5LCB0aGVyZSB3ZXJlIG9ubHkgdHdvIGRpbWVuc2lvbnM6IGV4cGVuc2VzIChhcyByb3dzKSBhbmQgbW9udGhzIChhcyBjb2x1bW5zKS5gciB0dWZ0ZTo6cXVvdGVfZm9vdGVyKCctLS0gW1RESCBzZWN0aW9uIDIuMi44IHBhZ2UgMjRdKGh0dHBzOi8veGJybHVzLmdpdGh1Yi5pby9kb2NzL3RkaC5odG1sKScpYCAgCgoqKl9YQlJMIERpbWVuc2lvbnMgdGVybWlub2xvZ3lfKiogIAoKKiBgRGltZW5zaW9uYDogQSBxdWFsaWZ5aW5nIGNoYXJhY3RlcmlzdGljIHRoYXQgaXMgdXNlZCB0byB1bmlxdWVseSBkZWZpbmUgYSBkYXRhIHBvaW50IChvdGhlciB0aGFuIGNvcmUgZGltZW5zaW9ucykgZm9yIGV4YW1wbGUgYSAiR2VvZ3JhcGh5IERpbWVuc2lvbiIuCiogYERvbWFpbmA6IEEgc2V0IG9mIHJlbGF0ZWQgdmFsdWVzLCBhbiBleGFtcGxlIG9mIGRvbWFpbnMgZm9yIHVzZSBvbiBhICJHZW9ncmFwaHkgRGltZW5zaW9uIiB3b3VsZCBiZSAiQ291bnRyaWVzIiwgIkNvbnRpbmVudHMiIG9yICJTdGF0ZXMiLgoqIGBEb21haW4gbWVtYmVyYDogQW4gZWxlbWVudCByZXByZXNlbnRpbmcgb25lIG9mIHRoZSBwb3NzaWJpbGl0aWVzIHdpdGhpbiBhIGRvbWFpbi4gIAoqIGBDdWJlYDogQSBjdWJlIGlzIGRlZmluZWQgYnkgY29tYmluaW5nIGEgc2V0IG9mIGRpbWVuc2lvbnMgd2l0aCBhIHNldCBvZiBjb25jZXB0cy4gQ3ViZXMgYXJlIG9mdGVuIHJlZmVycmVkIHRvIGFzICJoeXBlcmN1YmVzIiwgYXMgdW5saWtlIGEgcGh5c2ljYWwsIDMtZGltZW5zaW9uYWwgY3ViZSwgYSBoeXBlcmN1YmUgbWF5IGhhdmUgYW55IG51bWJlciBvZiBkaW1lbnNpb25zLgoKQWxsIHRoZSBhYm92ZSBjb25zdHJ1Y3RzIGFyZSBkZWZpbmVkIGFzIGNvbmNlcHRzLCBidXQgd2l0aCBzcGVjaWFsIHZhbHVlcyBmb3IgdGhlIGBAdHlwZWAgYW5kIGBAc3Vic3RpdHV0aW9uR3JvdXBgIGF0dHJpYnV0ZXMsIHRoZXNlIHNwZWNpYWwgdmFsdWVzIGFyZSBkZWZpbmVkIGluIHRoZSBgWEJSTCBEaW1lbnNpb25zIFNwZWNpZmljYXRpb25zYC4gIAoKVGhlIFRESCBpbiB0aGlzIHNlY3Rpb24sIHNwbGl0cyB0aGUgbW9udGhseSBleHBlbnNlcyBieSBCb2IncyBjaGlsZHJlbiwgd2l0aCBlYWNoIG1vbnRoIHNwbGl0IGludG8gMiBjb2x1bW5zIGZvciBlYWNoIG9mIEJvYidzIGNoaWxkcmVuLiBBc3N1bWUgdGhhdCB3ZSB3YW50IHRvIG9yZ2FuaXplIHRoaXMgaW5mb3JtYXRpb24gaW4gWEJSTCBieSBkb2luZyB0aGUgZm9sbG93aW5nOiAgCgoqIENyZWF0ZSBhIGdyb3VwaW5nIGNvbmNlcHQgb3IgaGVhZGVyIGNhbGxlZCBgZXhwZW5zZXNgIHRvIGdyb3VwIGFsbCB0aGUgZXhwZW5zZXMgdG9nZXRoZXIsICAKKiBDcmVhdGUgYHBlcnNvbnNgIGRpbWVuc2lvbiwgYW5kIHRoZW4gY3JlYXRlIGEgYGRvbWFpbmAgZm9yIGBib2JDaGlsZHJlbkRvbWFpbmAgYW5kIGBkb21haW4gbWVtYmVyYCBmb3IgZWFjaCBjaGlsZCByZWZlcmVuY2VkIGluIHRoZSByZXBvcnQuICAKClRoaXMgY2FuIGJlIGltcGxlbWVudGVkIGluIFhCUkwgYXMgZm9sbG93czogIApgYGB7ciBkaW1lbnNpb25fc2NoZW1hLCBlY2hvPUZBTFNFfQpmbl9Db2RlQ2h1bmtPdXQobGFuZyA9ICd4bWwnLCB0eHQgPSAKJzwhLS0gUmVwb3J0IHNwZWNpZmljIHRheG9ub215IGV4dGVuc2lvbiAtLT4KPHNjaGVtYSB0YXJnZXROYW1lc3BhY2U9Imh0dHA6Ly9ib2JyZXBvcnQuY29tL3hicmwvdGF4b25vbXkiIAoJCXhtbG5zOmJvYj0iaHR0cDovL2JvYnJlcG9ydC5jb20veGJybC90YXhvbm9teSIgCgkJeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIiAKCQl4bWxuczp4YnJsaT0iaHR0cDovL3d3dy54YnJsLm9yZy8yMDAzL2luc3RhbmNlIgoJCXhtbG5zOnhicmxkdD0iaHR0cDovL3hicmwub3JnLzIwMDUveGJybGR0IgoJCXhtbG5zOmR0ci10eXBlcz0iaHR0cDovL3d3dy54YnJsLm9yZy9kdHIvdHlwZS8yMDIwLTAxLTIxIj4KCQk8IS0tIG5vdGUgYWJvdmUgd2UgaW5jbHVkZWQgeGJybCBkaW1lbnNpb25zIHNwZWNzIHRvIGhhdmUgYWNjZXNzIHRvIGl0cyBlbGVtZW50cyAtLT4KCQkKCQk8IS0tIGNyZWF0ZSBhIGdyb3VwaW5nIGV4cGVuc2UgZWxlbWVudCAtLT4KCQk8ZWxlbWVudCBhYnN0cmFjdD0idHJ1ZSIgaWQ9ImV4cGVuc2VzX2Fic3RyYWN0IiBuYW1lPSJFeHBlbnNlc0Fic3RyYWN0IiAKCQkgICAgICAgICBuaWxsYWJsZT0idHJ1ZSIgeGJybGk6YmFsYW5jZT0iZGViaXQiIHN1YnN0aXR1dGlvbkdyb3VwPSJ4YnJsaTppdGVtIiAKCQkgICAgICAgICB0eXBlPSJ4YnJsaTptb25ldGFyeUl0ZW1UeXBlIiB4YnJsaTpwZXJpb2RUeXBlPSJkdXJhdGlvbiIvPgoJCQoJCTwhLS0gY3JlYXRlIHBlcnNvbnMgZGltZW5zaW9uIC0tPgoJCTxlbGVtZW50IGFic3RyYWN0PSJ0cnVlIiBpZD0iZGltXzAxX3BlcnNvbnMiIG5hbWU9InBlcnNvbnNEaW0iIAoJCSAgICAgICAgIG5pbGxhYmxlPSJ0cnVlIiBzdWJzdGl0dXRpb25Hcm91cD0ieGJybGR0OmRpbWVuc2lvbkl0ZW0iIAoJCSAgICAgICAgIHR5cGU9InhicmxpOnN0cmluZ0l0ZW1UeXBlIiB4YnJsaTpwZXJpb2RUeXBlPSJkdXJhdGlvbiIvPgoJCSAgICAgICAgIAoJCTwhLS0gY3JlYXRlIGNoaWxkcmVuIGRvbWFpbiAtLT4gICAgICAgIAoJCTxlbGVtZW50IGFic3RyYWN0PSJ0cnVlIiBpZD0iZG9tYWluXzAxX2NoaWxkcmVuIiBuYW1lPSJDaGlsZHJlbkRvbWFpbiIgCgkJICAgICAgICBuaWxsYWJsZT0idHJ1ZSIgc3Vic3RpdHV0aW9uR3JvdXA9InhicmxpOml0ZW0iIAoJCSAgICAgICAgdHlwZT0iZHRyLXR5cGVzOmRvbWFpbkl0ZW1UeXBlIiB4YnJsaTpwZXJpb2RUeXBlPSJkdXJhdGlvbiIvPgoJCSAgICAgICAgICAKCQkgIDwhLS0gY3JlYXRlIGRvbWFpbiBtZW1iZXIgZm9yIGVhY2ggY2hpbGQgLS0+CgkJICA8ZWxlbWVudCBhYnN0cmFjdD0idHJ1ZSIgaWQ9Im1lbWJlcnNfMDFfY2hpbGRPbmVNZW1iZXIiIG5hbWU9IkNoaWxkT25lTWVtYmVyIgoJCSAgICAgIG5pbGxhYmxlPSJ0cnVlIiBzdWJzdGl0dXRpb25Hcm91cD0ieGJybGk6aXRlbSIgCgkJICAgICAgdHlwZT0iZHRyLXR5cGVzOmRvbWFpbkl0ZW1UeXBlIiB4YnJsaTpwZXJpb2RUeXBlPSJkdXJhdGlvbiIvPgoJCSAgCgkJICA8ZWxlbWVudCBhYnN0cmFjdD0idHJ1ZSIgaWQ9Im1lbWJlcnNfMDJfY2hpbGRUd29NZW1iZXIiIG5hbWU9IkNoaWxkVHdvTWVtYmVyIgoJCSAgICAgIG5pbGxhYmxlPSJ0cnVlIiBzdWJzdGl0dXRpb25Hcm91cD0ieGJybGk6aXRlbSIgCgkJICAgICAgdHlwZT0iZHRyLXR5cGVzOmRvbWFpbkl0ZW1UeXBlIiB4YnJsaTpwZXJpb2RUeXBlPSJkdXJhdGlvbiIvPgo8L3NjaGVtYT4KPCEtLSBub3RlIGF0dHJpYnV0ZXMgdXNlIGZyb20gZHRyLXR5cGVzIGFuZCB4YnJsZHQgbmFtZXNwYWNlcz4nKQoKYGBgCiAgCioqX05vdGVzXyoqIEFsbCBlbGVtZW50cyBkZWZpbmVkIGFib3ZlIGhhcyB0aGUgYEBhYnN0cmFjdGAgYXR0cmlidXRlIGFzIGB0dXJlYCwgdGhpcyBtZWFucyB0aGF0IHRoaXMgZWxlbWVudCBpcyBub3QgYWxsb3dlZCB0byBiZSB1c2VkIGluIFhCUkwgaW5zdGFuY2UgZG9jdW1lbnQgdG8gcmVwb3J0IGZhY3RzLCB0aGlzIGVsZW1lbnQgaXMgb25seSBmb3Igb3JnYW5pemF0aW9uIHB1cnBvc2VzLgoKTm93IHdlIGNhbiByZWZlcmVuY2UgdGhlIGRpbWVuc2lvbiBpbiB0aGUgaW4gdGhlIGluc3RhbmNlIGRvY3VtZW50IHRocm91Z2ggYDxjb250ZXh0PmAgZWxlbWVudCBhcyBmb2xsb3dzOiAgCmBgYHtyIGRpbV9pbnN0YW5jZSwgZWNobz1GQUxTRX0KZm5fQ29kZUNodW5rT3V0KGxhbmcgPSAneG1sJywgdHh0ID0gCic8IS0tIEFkZGVkIHRvIHByZXZpb3VzIGluc3RhbnQgZG9jdW1lbnQgYXMgY2hpbGRyZW4gdG8gPHhicmw+IGVsZW1lbnQgLS0+CiAgPHhicmwgLi4uLi4uLiB4bWxuczpib2I9Imh0dHA6Ly9ib2JyZXBvcnQuY29tL3hicmwvdGF4b25vbXkiCiAgICAgICAgICAgICAgICB4bWxuczp4YnJsZGk9Imh0dHA6Ly94YnJsLm9yZy8yMDA2L3hicmxkaSI+CiAgPCEtLSAuLi4gYXQgbGVhc3Qgb25lIGxpbms6c2NoZW1hUmVmIGVsZW1lbnQgZ29lcyBoZXJlIC4uLiAtLT4KICA8IS0tIC4uLiBNdXN0IEhhdmUgYSBsaW5rYmFzZVJlZiBmb3IgdGhlIGRlZmluaXRpb24gbGluayAuLi4gLS0+CiAgICA8Y29udGV4dCBpZD0iMDMiPgogICAgICA8ZW50aXR5PgogICAgICAgIDxpZGVudGlmaWVyIHNjaGVtZT0iaHR0cDovL3d3dy5leGFtcGxlLmNvbS9ib2IiPkJvYjwvaWRlbnRpZmllcj4KICAgICAgPC9lbnRpdHk+CiAgICAgIDxwZXJpb2Q+CiAgICAgICAgPHN0YXJ0RGF0ZT4yMDIwLTAxLTAxPC9zdGFydERhdGU+CiAgICAgICAgPGVuZERhdGU+MjAyMC0wMS0zMTwvZW5kRGF0ZT4KICAgICAgPC9wZXJpb2Q+CiAgCiAgICAgIDxzZWdtZW50PgogICAgICAgICAgPGJvYjpsb2NhdGlvbnM+Ym9iOmhvbWU8L2JvYjpsb2NhdGlvbj4KICAgICAgICAgIDx4YnJsZGk6ZXhwbGljaXRNZW1iZXIKICAgICAgICAgICAgICAgICAgZGltZW5zaW9uPSJib2I6cGVyc29uc0RpbSI+Ym9iOkNoaWxkT25lTWVtYmVyCiAgICAgICAgICA8L3hicmxkaTpleHBsaWNpdE1lbWJlcj4KICAgICAgPC9zZWdtZW50PgogIAogICAgICA8c2NlbmFyaW8+CiAgICAgICAgICA8Ym9iOmFjdHVhbEJ1ZGdldD5ib2I6YWN0dWFsPC9ib2I6YWN0dWFsQnVkZ2V0PgogICAgICA8L3NjZW5hcmlvPgogIAogICAgPC9jb250ZXh0PicpCgpgYGAKCk5vdyBmYWN0cyByZXBvcnRpbmcgYWN0dWFsIGV4cGVuc2VzLCBmb3IgaG9tZSBsb2NhdGlvbiwgcmVsYXRpbmcgdG8gY2hpbGQgb25lIGZvciBKYW51YXJ5IDIwMjAgY2FuIHVzZSB0aGUgYWJvdmUgY29udGV4dCBhbmQgaGF2ZSBhbGwgZXhwZW5zZXMgZ3JvdXBlZCB1bmRlciBvbmUgaGVhZGluZyB1c2luZyB0aGUgYEV4cGVuc2VzQWJzdHJhY3RgIGVsZW1lbnQuCgoqKl9Ob3Rlc18qKiBUaGVyZSBhcmUgdHdvIHR5cGVzIG9mIG1lbWJlcnMgYGV4cGxpY2l0IG1lbWJlcnNgLCBhbmQgYHR5cGVkIG1lbWJlcmAuIGBleHBsaWNpdCBtZW1iZXJzYCBhcmUgZXhwbGljaXRseSBkZWZpbmVkIGFuZCBsaW5rZWQgdG8gYSBkb21haW4gaW4gdGhlIHRheG9ub215IGFuZCBubyBvdGhlciBtZW1iZXJzIGNhbiBiZSB1c2VkIHdpdGggdGhhdCBkb21haW4gZXhjZXB0IHRoZSBkZWZpbmVkIG1lbWJlcnMuIE9uIHRoZSBvdGhlciBoYW5kIGB0eXBlZCBtZW1iZXJzYCwgb25seSB0eXBlIG9mIHRoZSBtZW1iZXIgaXMgZGVmaW5lZCBpbiB0aGUgdGF4b25vbXksIGFuZCBhbnkgdmFsdWUgY2FuIGJlIHVzZWQgaWYgaXQgbWF0Y2hlZCB0aGUgdHlwZS4gIAoKS2VlcCBpbiBtaW5kIHRoYXQgWEJSTCBkaW1lbnNpb25zIHNwZWNpZmljYXRpb25zIHJlbHkgaGVhdmlseSBvbiB0aGUgbGlua2luZyBtZWNoYW5pc21zIHByb3ZpZGVkIGJ5IFhCUkwgdGhyb3VnaCBsaW5rYmFzZXMsIHdoaWNoIHdpbGwgYmUgdGhlIG5leHQgdG9waWMuICAKCiMjIyBYQlJMIExpbmtiYXNlcyAgCgpYQlJMIGxpbmtiYXNlcyAoYmFzZWQgb24gWE1MIFhMaW5rKSBwcm92aWRlcyBmb3IgYSBtZWNoYW5pc20gdG8gY3JlYXRlIHJlbGF0aW9uc2hpcHMgYmV0d2VlbiBlbGVtZW50cyBhbmQgb3RoZXIgaW50ZXJuYWwgb3IgZXh0ZXJuYWwgcmVzb3VyY2VzIHRvIGNyZWF0ZSBhIG1lYW5pbmdmdWwgc2VsZi1kZXNjcmliaW5nIGRhdGEgc3RydWN0dXJlLiAgCgojIyMjIFRoZSBiYXNpY3MgIApYQlJMIHVzZXMgWE1MIFhMaW5rIHNwZWNpZmljYXRpb25zLCBnZW5lcmFsbHkgc3BlYWtpbmcsIHRoZXJlIGFyZSB0d28gbWFpbiBjYXRlZ29yaWVzIG9mIGxpbmtzOiAgCgoqIGBTaW1wbGUgTGlua3NgOiBBIHNpbXBsZSBsaW5rIGluIFhMaW5rIGNyZWF0ZXMgYSB1bmlkaXJlY3Rpb25hbCBoeXBlcmxpbmsgZnJvbSBvbmUgZWxlbWVudCB0byBhbm90aGVyIHRocm91Z2ggYSBVUkkuIFRoZSBlbGVtZW50IGNvbnRhaW5pbmcgdGhlIGxpbmsgKHRoZSBzb3VyY2UgZWxlbWVudCkgaXMgbGlua2VkIHRvIGEgZGVzdGluYXRpb24gZWxlbWVudCwgdGhpcyBsaW5rICoqRE9FUyBOT1QqKiBwcm92aWRlIGEgbGluayBiYWNrIGZyb20gZGVzdGluYXRpb24gdGhlIHNvdXJjZSBlbGVtZW50LiBUaGlzIGlzIHNpbWlsYXIgdG8gSFRNTCBoeXBlcmxpbmtpbmcuICAKCiogYEV4dGVuZGVkIExpbmtzYDogUHJvdmlkZSBmb3IgbXVsdGlwbGUgcmVzb3VyY2VzIGF0IHRoZSBzb3VyY2Ugb3IgZGVzdGluYXRpb24gdG8gYmUgY29ubmVjdGVkIHZpYSBtdWx0aXBsZSBhcmNzLiBBbiBhcmMgY29udGFpbnMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHNvdXJjZSwgZGVzdGluYXRpb24sIGFuZCB0aGUgYmVoYXZpb3Igb2YgYSBsaW5rIGJldHdlZW4gdGhlIHR3by4gVGhlIHNvdXJjZSBhbmQgdGhlIGRlc3RpbmF0aW9uIGFyZSBkZWZpbmVkIGJ5IGxhYmVscy4gKipfVGhyb3VnaCBvbmUgb3IgbW9yZSBhcmNzLCBleHRlbmRlZCBsaW5rcyBhY2hpZXZlIGNvbXBsZXggY29ubmVjdGlvbnMgYW1vbmcgbXVsdGlwbGUgcmVzb3VyY2VzXyoqLiBMaWtlIHNpbXBsZSBsaW5rcywgZXh0ZW5kZWQgbGlua3MgY2FuIGRlZmluZSByZWxhdGlvbnNoaXBzIGJldHdlZW4gZWxlbWVudHMgd2l0aGluIHRoZSBzYW1lIG5hbWVzcGFjZSBvciBhY3Jvc3MgZGlmZmVyZW50IG5hbWVzcGFjZXMuICAKCkl0IGlzIGltcG9ydGFudCB0byBub3RlIHRoYXQgKipFeHRlbmRlZCBMaW5rcyoqIGNyZWF0ZXMgcmVsYXRpb25zaGlwcyBiZXR3ZWVuIGVsZW1lbnRzIHVzaW5nIGBhcmNzYCB0aGF0IGRlc2NyaWJlcyB0aGUgYmVoYXZpb3Igb2YgdGhlIHJlbGF0aW9uc2hpcC4KClhCUkwgc3BlY2lmaWNhdGlvbnMgZGVmaW5lcyBzZXZlcmFsIHR5cGVzIG9mIGxpbmtzIGJhc2VkIG9uIFhMaW5rIHNwZWNzLCBtb3N0IGNvbW1vbiBsaW5rcyBhbmQgYXJjcyBhcmUgW1tiYXNlZCBvbiBYQlJMIEdsb3NzYXJ5XShodHRwczovL3d3dy54YnJsLm9yZy9ndWlkYW5jZS94YnJsLWdsb3NzYXJ5KV06ICAKCiogYFByZXNlbnRhdGlvbiBMaW5rc2A6IEFuIGV4dGVuZGVkIGxpbmsgcHJvdmlkaW5nIGZvciB0aGUgb3JnYW5pc2F0aW9uIG9mIHRheG9ub215IGVsZW1lbnRzIGludG8gYSBoaWVyYXJjaGljYWwgc3RydWN0dXJlIHdpdGggdGhlIGFpbSBvZiBwcm92aWRpbmcgYSBtZWFucyBvZiB2aXN1YWxpemluZyBvciBuYXZpZ2F0aW5nIHRoZSB0YXhvbm9teS4gW0F0IGEgdGVjaG5pY2FsIGxldmVsLCB0aGUgcHJlc2VudGF0aW9uIHRyZWUgaXMgZGVmaW5lZCB1c2luZyB0aGUgYHBhcmVudC1jaGlsZCBhcmNyb2xlYCBpbiB0aGUgWEJSTCBzcGVjaWZpY2F0aW9uXQoKKiBgQ2FsY3VsYXRpb24gTGlua3NgOiBBbiBleHRlbmRlZCBsaW5rIHByb3ZpZGluZyByZWxhdGlvbnNoaXBzIGJldHdlZW4gY29uY2VwdHMgaW4gYSB0YXhvbm9teSBmb3IgdGhlIHB1cnBvc2Ugb2YgZGVzY3JpYmluZyBhbmQgdmFsaWRhdGluZyBzaW1wbGUgdG90YWxzIGFuZCBzdWJ0b3RhbHMuIFtBdCBhIHRlY2huaWNhbCBsZXZlbCwgdGhlc2UgcmVsYXRpb25zaGlwcyBhcmUgZGVmaW5lZCB1c2luZyB0aGUgYHN1bW1hdGlvbi1pdGVtIGFyY3JvbGVgIGluIHRoZSBYQlJMIHNwZWNpZmljYXRpb25dICAKCiogYExhYmVsIGxpbmtzYDogQW4gZXh0ZW5kZWQgbGluayBwcm92aWRpbmcgYSByZWxhdGlvbnNoaXAgYmV0d2VlbiBjb25jZXB0IGFuZCBodW1hbiByZWFkYWJsZSBkZXNjcmlwdGlvbiBvZiBhIHRheG9ub215IGNvbXBvbmVudC4gWEJSTCBsYWJlbHMgY2FuIGJlIGRlZmluZWQgaW4gbXVsdGlwbGUgbGFuZ3VhZ2VzIGFuZCBjYW4gYmUgb2YgbXVsdGlwbGUgdHlwZXMsIHN1Y2ggYXMgYSAic3RhbmRhcmQgbGFiZWwiLCB3aGljaCBwcm92aWRlcyBhIGNvbmNpc2UgbmFtZSBmb3IgdGhlIGNvbXBvbmVudCwgb3IgYSAiZG9jdW1lbnRhdGlvbiBsYWJlbCIgd2hpY2ggcHJvdmlkZXMgYSBtb3JlIGNvbXBsZXRlIGRlZmluaXRpb24gb2YgdGhlIGNvbXBvbmVudC4gRXhhbXBsZSBvZiBhcmNyb2xlcyBgbGFiZWxgLCBgdGVyc2VMYWJlbGAsIGBwZXJpb2RTdGFydExhYmVsYCwgYHBlcmlvZEVuZExhYmVsYCwgYHRvdGFsTGFiZWxgCgoqIGBEZWZpbml0aW9uIExpbmtzYDogQW4gZXh0ZW5kZWQgcHJvdmlkaW5nIGZvciByZWxhdGlvbnNoaXBzIHRoYXQgYXJyYW5nZXMgcGFpcnMgb2YgY29uY2VwdHMgaW4gYSBzcGVjaWZpYyBzZW1hbnRpYyByZWxhdGlvbnNoaXAuIFRoZXNlIHJlbGF0aW9uc2hpcHMgbWF5IGJlIGFib3ZlIGFuZCBiZXlvbmQgY2FsY3VsYXRpb24gb3IgcHJlc2VudGF0aW9uIHJlbGF0aW9uc2hpcHMuIENvbmNlcHQgY29yZSBkaW1lbnNpb25zIGNhbm5vdCBiZSB1c2VkIGluIGEgZGVmaW5pdGlvbiByZWxhdGlvbnNoaXAsIGFuZCBpcyBwcmltYXJpbHkgdXNlZCBmb3IgZGltZW5zaW9uYWwgcmVsYXRpb25zaGlwcyBpbiBYQlJMIERpbWVuc2lvbnMgc3BlY2lmaWNhdGlvbnMuIEV4YW1wbGUgYXJjcm9sZXMgYGh5cGVyY3ViZS1kaW1lbnNpb25gLCBgZGltZW5zdGlvbi1kb21haW5gLCBgZG9tYWluLW1lbWJlcmAsIGBkaW1lbnN0aW9uLWRlZnVhbHRgICAKCiogYFJlZmVyZW5jZSBsaW5rYDogQW4gZXh0ZW5kZWQgbGluayBwcm92aWRpbmcgZm9yIHJlbGF0aW9uIGJldHdlZW4gZWxlbWVudHMgb2YgdGhlIHRheG9ub215IGFuZCBleHRlcm5hbCByZWZlcmVuY2Ugc3VjaCBhcyBhY2NvdW50aW5nIHN0YW5kYXJkcywgb3IgbGF3cy4gRXhhbXBsZSBhcmNyb2xlIGBjb25jZXB0LXJlZmVyZW5jZWAuICAKCiogYEZvcm11bGEgbGlua2A6IEFuIGV4dGVuZGVkIGxpbmsgcHJvdmlkaW5nIHJlbGF0aW9ucyBuZWNlc3NhcnkgdG8gZGVmaW5lIGZvcm11bGFlIChYQlJMIEZvcm11bGEgU3BlY2lmaWNhdGlvbikgdXNlZCBpbiB2YWxpZGF0aW5nIFhCUkwgaW5zdGFuY2VzLiBFeGFtcGxlIGFyY3JvbGUgYHZhcmlhYmxlLXNldGAsIGB2YXJpYWJsZS1zZXQtZmlsdGVyYC4gIAoKKiBgVGFibGUgTGlua2Jhc2VgOiBhbiBleHRlbmRlZCBsaW5rIHByb3ZpZGluZyByZWxhdGlvbnMgbmVlZGVkIGZvciB0YWJ1bGFyIHZpZXcgb2YgYSB0YXhvbm9teSBvciByZXBvcnQgdGhhdCBpcyB1c2VkIGZvciBwcmVzZW50YXRpb24gb3IgZGF0YSBlbnRyeSBwdXJwb3Nlcy4gWEJSTCByZXBvcnRpbmcgdGVtcGxhdGVzIGNhbiBzdXBwb3J0IGNvbXBsZXgsIG11bHRpLWRpbWVuc2lvbmFsIHJlcG9ydHMsIHN1Y2ggYXMgdGhvc2Ugc2VlbiBpbiBwcnVkZW50aWFsIHJlcG9ydGluZywgYW5kIHByb3ZpZGUgYSB1c2VyLWZyaWVuZGx5IHZpZXcgb2YgdGhlIGRhdGEuIFhCUkwgcmVwb3J0aW5nIHRlbXBsYXRlcyBhcmUgdHlwaWNhbGx5IHVzZWQgaW4gY2xvc2VkIHJlcG9ydGluZyBwcm9ncmFtcywgd2hlcmUgYSB0ZW1wbGF0ZSBpcyBwcmVzY3JpYmVkIGJ5IHRoZSBjb2xsZWN0b3IuIFtBdCBhIHRlY2huaWNhbCBsZXZlbCwgWEJSTCByZXBvcnRpbmcgdGVtcGxhdGVzIGFyZSBkZWZpbmVkIHVzaW5nIHRoZSBUYWJsZSBMaW5rYmFzZSBzcGVjaWZpY2F0aW9uXSAKCiogYGZvb3Rub3RlIGxpbmtzYDogQSBmb290bm90ZSBhZGRzIGZ1cnRoZXIgZXhwbGFuYXRvcnkgaW5mb3JtYXRpb24gdG8gYSBzdGF0ZW1lbnQgb3IgZmFjdC4gSW4gWEJSTCwgZm9vdG5vdGVzIGFyZSBjcmVhdGVkIHRocm91Z2ggcmVsYXRpb25zaGlwcyBiZXR3ZWVuIG5vdGUgdGV4dCBhbmQgZmFjdHMgdXNpbmcgdGhlIGZvb3Rub3RlIHJlbGF0aW9uc2hpcHMuIE9uZSBpbnN0YW5jZSBvZiBmb290bm90ZSB0ZXh0IGNhbiBiZSBsaW5rZWQgdG8gbXVsdGlwbGUgZmFjdHMuIFRoZSBub3RlIGNvcmUgSUQgZGltZW5zaW9uIGlzIHRoZSBkaW1lbnNpb24gb24gdGhlIGZhY3QgdGhhdCBhc3NvY2lhdGVzIHRoZSBmYWN0IHdpdGggb25lIG9yIG1vcmUgZm9vdG5vdGVzIGFyY3MuCgoqIGBHZW5lcmljIExpbmtzYDogQSBsaW5rIHR5cGUgd2l0aCBubyBwcmVkZWZpbmVkIHNlbWFudGljcyBvciBjb25zdHJhaW50cy4gVGhpcyBjYW4gYmUgdXNlZCBhcyBhIGJ1aWxkaW5nIGJsb2NrIGZvciBvdGhlciBzcGVjaWZpY2F0aW9ucywgc3VjaCBhcyBHZW5lcmljIExhYmVscyAxLjAgYW5kIEdlbmVyaWMgUmVmZXJlbmNlcyAxLjAgdG8gZGVmaW5lIHJlbGF0aW9uc2hpcHMgd2l0aCBwYXJ0aWN1bGFyIHNlbWFudGljcy4KCiMjIyMgRXh0ZW5kZWQgTGlua3MgVXNhZ2UgaW4gWEJSTCAgCkxpbmtzIGFyZSB1c2VkIGluIFhCUkwgdG8gY3JlYXRlIHJlbGF0aW9ucyBiZXR3ZWVuIGFuZCBhbW9uZyBjb25jZXB0cyBpbiBvcmRlciB0byBnaXZlIG1lYW5pbmcgdG8gb3RoZXJ3aXNlIHNjYXR0ZXJlZCBkYXRhLiBJbiBYQlJMIGxpbmtzIGFyZSBvcmdhbml6ZWQgYnkgdHlwZSAocHJlc2VudGF0aW9uLCBjYWxjdWxhdGlvbiwgZGVmaW5pdGlvbiwgbGFiZWwsIGZvcm11bGEsIHRhYmxlLCAuLi4pLiBXaXRoaW4gZWFjaCB0eXBlIGxpbmtzIGFyZSBmdXJ0aGVyIHBhcnRpdGlvbmVkIGludG8gYG5ldHdvcmtzIG9mIHJlbGF0aW9uc2hpcHNgIHVzaW5nIGBFeHRlbmRlZCBMaW5rIFJvbGVzYCwgZm9yIGV4YW1wbGUgaW4gYSBwcmVzZW50YXRpb24gbGluaywgYW4gZXh0ZW5kZWQgbGluayByb2xlIG1heSBiZSBkZWZpbmVkIGZvciBCYWxhbmNlIFNoZWV0IHRvIGdyb3VwIHRvZ2V0aGVyIHJlbGF0aW9uc2hpcHMgZm9yIEJhbGFuY2UgU2hlZXQgcHJlc2VudGF0aW9uLCBhbm90aGVyIGV4dGVuZGVkIGxpbmsgcm9sZSBtYXkgYmUgZGVmaW5lZCBmb3IgSW5jb21lIFN0YXRlbWVudCB0byBncm91cCB0b2dldGhlciByZWxhdGlvbnNoaXBzIGZvciBJbmNvbWUgU3RhdGVtZW50IHByZXNlbnRhdGlvbnMgYW5kIHNvIG9uLiBTYW1lIGBFeHRlbmRlZCBsaW5rIHJvbGVgIGNhbiBiZSB1c2VkIGFzIHRoZSBoZWFkIG9mIGEgbmV0d29yayBvZiByZWxhdGlvbnMgYWNyb3NzIG11bHRpcGxlIGxpbmsgdHlwZXMsIGZvciBleGFtcGxlLCBhbiBleHRlbmRlZCBsaW5rIHJvbGUgbWF5IGJlIGNyZWF0ZWQgdG8gZ3JvdXAgYmFsYW5jZSBzaGVldCBuZXR3b3JrIG9mIHJlbGF0aW9ucyBhbmQgY2FuIGJlIHVzZWQgd2l0aGluIHByZXNlbnRhdGlvbiwgY2FsY3VsYXRpb24gYW5kIGRlZmluaXRpb24gbGlua3MuCgpUaGUgbmV0d29ya3Mgb2YgcmVsYXRpb25zIChncm91cGVkIGJ5IGV4dGVuZGVkIGxpbmsgcm9sZXMpIHRvZ2V0aGVyIGNhbGxlZCBhIGBsaW5rYmFzZWAsIGhlbmNlIHRoZSBgYmFzZWAgaW4gbGlua2Jhc2UgKFByZXNlbnRhdGlvbiBsaW5rYmFzZSwgQ2FsY3VsYXRpb24gbGlua2Jhc2UsIC4uLiksIGFsc28gbGlua2Jhc2VzIGNhbiBiZSBzdG9yZWQgYWNyb3NzIG11bHRpcGxlIGZpbGVzIG9yIGEgc2luZ2xlIGZpbGUgZGVwZW5kaW5nIG9uIHRoZSBvdmVyYWxsIG9yZ2FuaXphdGlvbiBvZiB0aGUgdGF4b25vbXkuIFRoaXMgc2V0dXAgY2FuIGJlIHZpc3VhbGl6ZWQgYXMgZm9sbG93czogIAoKPGRpdj4KPGNlbnRlcj4KIVtMaW5rYmFzZSBPdmVydmlld10oYHIgaGVyZTo6aGVyZSgnZG9jcycsICdpbWFnZXMvbGlua3NPdmVyVmlldy5wbmcnKWApCjwvY2VudGVyPgo8cCBzdHlsZT0idGV4dC1hbGlnbjpjZW50ZXIiPgoqKkxpbmtiYXNlIE92ZXJ2aWV3ICoqW18oZmlndXJlIGNyZWF0ZWQgdXNpbmcgZHJhdy5pbylfXShodHRwczovL2FwcC5kaWFncmFtcy5uZXQvKQo8L3A+CjwvZGl2PgoKKipfTGlua3MgVXNhZ2UgaW4gWEJSTF8qKiAgCkxpbmtiYXNlcyBhcmUgY3JlYXRlZCBpbiBgLnhtbGAgZmlsZXMsIGFuZCByZWZlcmVuY2VkIGluIHRoZSBYQlJMIHRheG9ub215IHNjaGVtYSB1c2luZyBYQlJMIGA8bGlua2Jhc2VSZWY+YCBlbGVtZW50LiBgRXh0ZW5kZWQgTGluayBSb2xlc2AgYXJlIGRlY2xhcmVkIGluIFhCUkwgdGF4b25vbXkgYW5kIHVzaW5nIGB7aHR0cDovL3d3dy54YnJsLm9yZy8yMDAzL2xpbmtiYXNlfXJvbGVUeXBlYCBlbGVtZW50LCBhbmQgdGhlbiByZWZlcmVuY2VkIGluIHRoZSBsaW5rYmFzZSBmaWxlcyAocmVmZXJlbmNlZCBiYWNrIGZyb20gbGlua2Jhc2UgZmlsZXMgdG8gdGF4b25vbXkpLCB1c2luZyBlbGVtZW50IGB7aHR0cDovL3d3dy54YnJsLm9yZy8yMDAzL2xpbmtiYXNlfXJvbGVSZWZgIHdoaWNoIGlzIGFjY2Vzc2VkIGJ5IGxpbmsgY29uc3RydWN0b3IgIHRvIGNyZWF0ZSB0aGUgbmV0d29yayBvZiByZWxhdGlvbnMgZm9yIHRoaXMgbGluayBSb2xlLCBhcyBzaG93biBpbiB0aGUgZmlndXJlIGJlbG93LiAgCgo8ZGl2Pgo8Y2VudGVyPgohW0xpbmtiYXNlIFNjaGVtYSByZWZlcmVuY2VdKGByIGhlcmU6OmhlcmUoJ2RvY3MnLCAnaW1hZ2VzL2xpbmtiYXNlLnBuZycpYCkKPC9jZW50ZXI+CjxwIHN0eWxlPSJ0ZXh0LWFsaWduOmNlbnRlciI+CioqTGlua2Jhc2UgU2NoZW1hIHJlZmVyZW5jZSAqKltfKGZpZ3VyZSBjcmVhdGVkIHVzaW5nIGRyYXcuaW8pX10oaHR0cHM6Ly9hcHAuZGlhZ3JhbXMubmV0LykKPC9wPgo8L2Rpdj4gIAoKUm9vdCBlbGVtZW50IG9mIGEgbGlua2Jhc2UgZmlsZSBpcyBgPGxpbmtiYXNlPmAgbmFtZXNwYWNlIGBodHRwOi8vd3d3Lnhicmwub3JnLzIwMDMvbGlua2Jhc2VgLCB0aGUgYWxsb3dlZCBjaGlsZHJlbiBmb3IgYDxsaW5rYmFzZT5gIGFyZTogIAoKPGRpdj4KPGNlbnRlciBpZD0ibGlua2Jhc2UtZWxlbWVudC1pbWciPgohW2xpbmtiYXNlIGVsZW1lbnRdKGByIGhlcmU6OmhlcmUoJ2RvY3MnLCAnaW1hZ2VzL2xpbmtiYXNlRWxlbWVudC5qcGcnKWApCjwvY2VudGVyPgo8cCBzdHlsZT0idGV4dC1hbGlnbjpjZW50ZXIiPgoqKmxpbmtiYXNlIGVsZW1lbnQqKgo8L3A+CjwvZGl2PgoKKiBgPGRvY3VtZW50YXRpb24+YDogRG9jdW1lbnRhdGlvbiBmb3IgdGhlIGxpbmtiYXNlCiogYDxyb2xlUmVmPmAgOiBSZWZlcmVuY2UgdGhlIGxpbmtyb2xlcyBkZWNsYXJlZCBpbiBzY2hlbWEgKHNlZSBbcm9sZVR5cGVzXSgjcm9sZS10eXBlcykpLiAgCiogYDxhcmNyb2xlUmVkPmA6IFJlZmVyZW5jZSB0aGUgYXJjcm9sZXMgZGVjbGFyZWQgaW4gc2NoZW1hIGlmIGFueSAobm9uZSBpbiB0aGlzIGV4YW1wbGUpLiAgCiogYDxleHRlbmRlZD5gOiBFbGVtZW50IGluIHN1YnN0aXR1dGlvbiBncm91cCBgZXh0ZW5kZWRgIHdpdGggYmFzZSB0eXBlIGBleHRlbmRlZFR5cGVgLCBzdWNoIGFzIGA8cHJlc2VudGF0aW9uTGluaz5gLCBgPGNhbGN1bGF0aW9uTGluaz5gLCAuLi4gCgoqKk5vdGUqKiAgClhCUkwgZGVmaW5lcyBvbmUgc3RhbmRhcmQgbGlua1JvbGUgYGh0dHA6Ly93d3cueGJybC5vcmcvMjAwMy9yb2xlL2xpbmtgIGFuZCBpdCBpcyB1c2VkIGFzIGRlZmF1bHQuCgpUaGUgbGluayByb2xlIChuZXR3b3JrIG9mIHJlbGF0aW9ucykgaXMgZGVmaW5lZCB1c2luZyB0aGUgZWxlbWVudHMgYmFzZWQgb24gdGhlIGBleHRlbmRlZGAgdHlwZSBhcyB0aGUgY29udGFpbmVyIGZvciB0aGUgdGhlIHJlbGF0aW9uc2hpcHMsIHRoZW4gY29uY2VwdHMgcGFydGljaXBhdGluZyBpbiB0aGUgbmV0d29yayBhcmUgZmlyc3QgbG9jYXRlZCB1c2luZyB0aGUgYDxsaW5rOmxvYz5gIGVsZW1lbnQsIHdoaWNoIGlkZW50aWZpZXMgdGhlIGxvY2F0aW9uIG9mIHRoZSBlbGVtZW50IG9yIHJlc291cmNlIHVzaW5nIFhMaW5rIGFuZCBYUG9pbnRlciBzeW50YXguIFRoZW4gdGhlIGRlc2lyZWQgcmVsYXRpb24gaXMgZXN0YWJsaXNoZWQgYmV0d2VlbiBsb2NhdG9ycyAoYXMgcHJveHkgZm9yIHRoZSB0YXJnZXQgY29uY2VwdCBvciByZXNvdXJjZSkgdXNpbmcgdGhlIHJlbGV2YW50IGBhcmMgdHlwZWAsIGZvciBleGFtcGxlIGEgcHJlc2VudGF0aW9uIGxpbmsgd2lsbCB1c2UgYGxpbms6cHJlc2VudGF0aW9uQXJjYCBlbGVtZW50IHRvIGVzdGFibGlzaCB0aGUgcmVsYXRpb24gYmV0d2VlbiBsb2NhdG9ycy4gIAo8ZGl2Pgo8Y2VudGVyPgohW0xpbmtiYXNlXShgciBoZXJlOjpoZXJlKCdkb2NzJywgJ2ltYWdlcy9saW5rcy5wbmcnKWApCjwvY2VudGVyPgo8cCBzdHlsZT0idGV4dC1hbGlnbjpjZW50ZXIiPgoqKkxpbmtiYXNlICoqW18oZmlndXJlIGNyZWF0ZWQgdXNpbmcgZHJhdy5pbylfXShodHRwczovL2FwcC5kaWFncmFtcy5uZXQvKQo8L3A+CjwvZGl2PgoKVGhlIHJlbGF0aW9uc2hpcHMgd2l0aGluIGEgbGluayByb2xlIChhbHNvIHJlZmVycmVkIHRvIGFzIG5ldHdvcmtzKSBpbiBjYXNlIG9mICoqTm9uZSoqIHJlc291cmNlIGxpbmtzICBhcmUgaW4gaGllcmFyY2hpY2FsIHRyZWUgZm9ybSB3aXRoIG9uZSByb290IHRoYXQgaGFzIGJyYW5jaGVzLCBhbmQgdGhlbiBlYWNoIGJyYW5jaCBtYXkgYmUgdGhlIHJvb3QgdG8gb3RoZXIgYnJhbmNoZXMsIGFuZCBzbyBvbiB1bnRpbCB0aGUgbGVhZiBsZXZlbC4KCiMjIyBFeGFtcGxlIC0gIEluY29tZSBTdGF0ZW1lbnQgVGF4b25vbXkgYW5kIExpbmtiYXNlcyAgCkluIHRoaXMgc2VjdGlvbiB3ZSB3aWxsIGNyZWF0ZSB0YXhvbm9teSBhbmQgbGlua2Jhc2VzIGZvciBhIHNpbXBsZSBJbmNvbWUgU3RhdGVtZW50LgoKIyMjIyBGb3JtICAgCldlIHdhbnQgdG8gY3JlYXRlIHRheG9ub215IGFuZCBsaW5rcyBmb3IgYSBgSW5jb21lIFN0YXRlbWVudGAgdGhhdCBsb29rcyBhcyBmb2xsb3dzOiAgCgpgYGB7ciBleGFtcGxlX2lzLCBlY2hvPUZBTFNFLCAgd2FybmluZz1GQUxTRSwgZmlnLmNhcD0nRXhhbXBsZSBJbmNvbWUgU3RhdGVtZW50J30KCmRmX2lzIDwtIGRhdGEuZnJhbWUoCiAgYT0gYygnUmV2ZW51ZScsICdQcm9kdWN0JywgJ1NlcnZpY2UnLAogICAgICAgJ1RvdGFsIFJldmVudWUnLCcgQ29zdCBvZiBSZXZlbnVlJywgJ1Byb2R1Y3QnLAogICAgICAgJ1NlcnZpY2UnLCAnVG90YWwgQ29zdCBvZiBSZXZlbnVlJywgJ0dyb3NzIFByb2ZpdCcsIAogICAgICAgJ0V4cGVuc2VzJywgJ05ldCBQcm9maXQnKSwKICBiID0gYygnJywgJzIsMDAwJywnMywwMDAnLCc1LDAwMCcsJycsICcxLDAwMCcsICcyLDAwMCcsICczLDAwMCcsICcyLDAwMCcsICc1MDAnLCAnMSw1MDAnKSwKICBjID0gYygnJywgJzIsNTAwJywnMSw1MDAnLCc0LDAwMCcsJycsICcxLDI1MCcsICcxLDAwMCcsICcyLDI1MCcsICcxLDc1MCcsICc0MjAnLCAnMSwzMzAnKQopCgp0YmwgPC0ga25pdHI6OmthYmxlKGRmX2lzLCAnaHRtbCcsIAogICAgICAgICAgY29sLm5hbWVzID0gYygnKEluIEVHUCknLCAnMzEtMTItMjAyMCcsICczMS0xMi0yMDE5JyksIGFsaWduPWMoJ2wnLCAncicsICdyJykpICU+JSAKICBrYWJsZUV4dHJhOjpyb3dfc3BlYyhjKDEsNSksIGJvbGQgPSBUUlVFKSAlPiUgIAogIGthYmxlRXh0cmE6OnJvd19zcGVjKGMoNCw4KSwgZXh0cmFfY3NzID0gImJvcmRlci10b3A6IDFweCBzb2xpZDsKICAgICAgICAgICAgICAgICAgICAgICBib3JkZXItYm90dG9tOiAxcHggc29saWQiLCBib2xkID0gVFJVRSkgJT4lICAKICBrYWJsZUV4dHJhOjpyb3dfc3BlYyg5LCBleHRyYV9jc3MgPSAiYm9yZGVyLXRvcDogMXB4IHNvbGlkIiwgYm9sZCA9IFRSVUUpICU+JSAKICBrYWJsZUV4dHJhOjpyb3dfc3BlYygxMSwgZXh0cmFfY3NzID0gImJvcmRlci10b3A6IDFweCBzb2xpZDsKICAgICAgICAgICAgICAgICAgICAgICBib3JkZXItYm90dG9tOiAzcHggZG91YmxlIiwgYm9sZCA9IFRSVUUpICU+JQogIGthYmxlRXh0cmE6OmFkZF9pbmRlbnQoYygyLDMsNiw3KSkgJT4lCiAga2FibGVFeHRyYTo6a2FibGVfY2xhc3NpYyhmdWxsX3dpZHRoID0gRikgJT4lIAogIGthYmxlRXh0cmE6OmFkZF9oZWFkZXJfYWJvdmUoYygnJywgICdZZWFyIEVuZGVkJz0yKSkKdGJsCgpgYGAKIyMjIyBUYXhvbm9teSAgCkZpcnN0IHdlIGNyZWF0ZSBvdXIgc2NoZW1hL3RheG9ub215IGFzIGZvbGxvd3M6IChbc2VlIGZpbGVdKHhtbF9maWxlcy9pbmNvbWVTdGF0ZW1lbnRFeGFtcGxlL2lzLnhzZCl7dGFyZ2V0PV9ibGFua30pICAKYGBge3IgaXNfZXhhbXBsZV9zY2hlbWEsIGVjaG89RkFMU0V9CmZuX0NvZGVDaHVua091dChsYW5nPSd4bWwnLCBGaWxlID0gaGVyZTo6aGVyZSgnZG9jcycsJ3htbF9maWxlcy9pbmNvbWVTdGF0ZW1lbnRFeGFtcGxlL2lzLnhzZCcpKQpgYGAKCk5vdGUgdGhhdCB0aGUgcm9vdCBlbGVtZW50IGZvciB0aGUgZW50cnkgcG9pbnQgb2YgdGhlIHRheG9ub215IGlzIGA8c2NoZW1hPmAgYXMgYW55IFhNTCBzY2hlbWEgZG9jdW1lbnQuICAKCioqVGhlIHNjaGVtYS90YXhvbm9teSBkb2N1bWVudCByZWxldmFudCBjb21wb25lbnRzIGNhbiBiZSBhbmFseXplZCBhcyBmb2xsb3dzOioqICAKCiMjIyMjIEltcG9ydHMKX0ltcG9ydGluZyBvdGhlciBzY2hlbWFzIGFuZCB0YXhvbm9taWVzIHRvIGJlIHVzZWQgaW4gb3VyIHRheG9ub215IHVzaW5nIGA8aW1wb3J0PmAgZWxlbWVudCBhcyBmb2xsb3dzOl8gIApgYGB7ciBpc194c2RfaW1wb3J0cywgZWNobz1GQUxTRX0KaXNfeHNkIDwtIHhtbDI6OnJlYWRfeG1sKGhlcmU6OmhlcmUoJ2RvY3MnLCd4bWxfZmlsZXMvaW5jb21lU3RhdGVtZW50RXhhbXBsZS9pcy54c2QnKSkKCmltcG9ydHMgPC0geG1sMjo6eG1sX2ZpbmRfYWxsKGlzX3hzZCwnLi8vKltsb2NhbC1uYW1lKCk9ImltcG9ydCJdJykgJT4lCiAgbWFwKGZ1bmN0aW9uKHgpIHsKICAgIGModGFnPXhtbDI6OnhtbF9uYW1lKHgpLCB4bWwyOjp4bWxfYXR0cnMoeCkpCiAgfSkgJT4lIGJpbmRfcm93cygpICU+JSBtdXRhdGUoZGVzY3JpcHRpb249YygKICAgICdJbXBvcnRzIGJhc2UgWEJSTCBpbnN0YW5jZSB0eXBlcycsICdJbXBvcnRzIG5vbk51bWVyaWMgdHlwZXMnLCAnSW1wb3J0cyBYQlJMIERpbWVuc2lvbnMnLCAnSW1wb3J0cyBkYXRhIHR5cGUgcmVnaXN0cnknCiAgKSkKCmtuaXRyOjprYWJsZShpbXBvcnRzKSAlPiUga2FibGVFeHRyYTo6a2FibGVfY2xhc3NpYygpCmBgYAoKCldpdGhpbiBgPGFubm90YXRpb24+YCBzY2hlbWEgZWxlbWVudCB3ZSBjYW4gYWRkIGRvY3VtZW50YXRpb24gZGVzY3JpYmluZyB0aGUgZG9jdW1lbnQgaW4gYWRkaXRpb24gdG8gc29tZSBpbmZvcm1hdGlvbiB0byBiZSB1c2VkIGJ5IHRoZSBwcm9jZXNzb3IgdGhyb3VnaCB0aGUgYDxhcHBpbmZvPmAsIHRoZXNlIGluZm9ybWF0aW9uIGluY2x1ZGVzIGJ1dCBub3QgbGltaXRlZCB0bzsgZGVmaW5pbmcgZXh0ZW5kZWQgbGluayByb2xlcyBhbmQgbGlua2Jhc2UgcmVmZXJlbmNlcyAocmVmZXJlbmNlcyB0byBsaW5rYmFzZSBmaWxlcykuIAoKIyMjIyMgUm9sZSBUeXBlc3sjcm9sZS10eXBlc30gIApfRGVmaW5pbmcgRXh0ZW5kZWQgTGlua1JvbGVzIHVzaW5nIGA8cm9sZVR5cGU+YCBlbGVtZW50IGFzIGluIG91ciBleGFtcGxlIGFzIGZvbGxvd3M6XyAgClRoZSBgZXh0ZW5kZWQgbGluayByb2xlYCBmb3IgdGhlIGBpbmNvbWUgU3RhdGVtZW50YCBoYXMgVVJJIDx1PioqYGh0dHA6Ly94eXouYWJjL3JvbGUvSW5jb21lU3RhdGVtZW50YCoqPC91PiBhbmQgY2FuIGJlIHVzZWQgb24gYHByZXNlbnRhdGlvbmAsIGBjYWxjdWxhdGlvbmAgYW5kIGBkZWZpbml0aW9uYCBsaW5rczogIApgYGB7ciBpc19leGFtcGxlX2xpbmtyb2xlLCBlY2hvPUZBTFNFfQpmbl9Db2RlQ2h1bmtPdXQobGFuZyA9ICd4bWwnLCB0eHQgPSAKJzxsaW5rOnJvbGVUeXBlIGlkPSJyb2xlVHlwZV9JbmNvbWVTdGF0ZW1lbnQiIHJvbGVVUkk9Imh0dHA6Ly94eXouYWJjL3JvbGUvSW5jb21lU3RhdGVtZW50Ij4KICAgIDxsaW5rOmRlZmluaXRpb24+MTAwMDAgLSBTdGF0ZW1lbnQgLSBJbmNvbWUgU3RhdGVtZW50PC9saW5rOmRlZmluaXRpb24+CiAgICAgICAgICAgICAgICA8bGluazp1c2VkT24+bGluazpjYWxjdWxhdGlvbkxpbms8L2xpbms6dXNlZE9uPgogICAgICAgICAgICAgICAgPGxpbms6dXNlZE9uPmxpbms6ZGVmaW5pdGlvbkxpbms8L2xpbms6dXNlZE9uPgogICAgICAgICAgICAgICAgPGxpbms6dXNlZE9uPmxpbms6cHJlc2VudGF0aW9uTGluazwvbGluazp1c2VkT24+CjwvbGluazpyb2xlVHlwZT4nKQpgYGAKX05vdGVfIHRoZSBleHRlbmRlZCBsaW5rIHJvbGUgbmVlZHMgdG8gaGF2ZSBhIHVuaXF1ZSBgQGlkYCBhbmQgYEByb2xlVVJJYCBhdHRyaWJ1dGVzLiAgCgojIyMjIyBMaW5rYmFzZXMgcmVmZXJlbmNlcwpfTGlua2luZyB0byBMaW5rYmFzZXMgZmlsZXMgdXNpbmcgYDxsaW5rYmFzZVJlZj5gIGVsZW1lbnQgYXMgaW4gb3VyIGV4YW1wbGUgYXMgZm9sbG93czpfICAKYGBge3IgaXNfeHNkX2xpbmtiYXNlUmVmLCBlY2hvPUZBTFNFfQpsaW5rYmFzZVJlZnMgPC0geG1sMjo6eG1sX2ZpbmRfYWxsKGlzX3hzZCwnLi8vKltsb2NhbC1uYW1lKCk9ImxpbmtiYXNlUmVmIl0nKSAlPiUKICBtYXAoZnVuY3Rpb24oeCkgewogICAgYyh0YWc9eG1sMjo6eG1sX25hbWUoeCksIHhtbDI6OnhtbF9hdHRycyh4KSkKICB9KSAlPiUgYmluZF9yb3dzKCkgJT4lIG11dGF0ZShkZXNjcmlwdGlvbj1jKCdUYWJsZSBMaW5rYmFzZScsJ0Zyb211bGEgTGlua2Jhc2UgKGZvciB2YWxpZGF0aW9uKScsCiAgICAnRW5nbGlzaCBMYWJlbHMgbGlua2Jhc2UnLCAnQXJhYmljIExhYmVscyBsaW5rYmFzZScsICdQcmVzZW50YXRpb24gbGlua2Jhc2UnLCAKICAgICdEZWZpbml0aW9uIGxpbmtiYXNlIChEaW1lbnNpb25zKScsICdDYWxjdWxhdGlvbiBsaW5rYmFzZScsICdBcmFiaWMgRUxSIGRlZmluaXRpb24nKSwKICBhcmNyb2xlPSBwYXN0ZTAoJ2h0dHA6Ly8uLi4vJywgYmFzZW5hbWUoYXJjcm9sZSkpLAogIHJvbGU9IHBhc3RlMCgnaHR0cDovLy4uLi8nLCBiYXNlbmFtZShyb2xlKSkKICAKICApCgprMCA8LSBrbml0cjo6a2FibGUobGlua2Jhc2VSZWZzKSAlPiUga2FibGVFeHRyYTo6a2FibGVfY2xhc3NpYygpCgpodG1sdG9vbHM6OmRpdihodG1sdG9vbHM6OkhUTUwoazApLCBzdHlsZT0ib3ZlcmZsb3cteDphdXRvIikKYGBgCjwvYnI+CgojIyMjIyBUYXhvbm9teSBlbGVtZW50cy92b2NhYnVsYXJ5OiAgClRoZSBgPGVsZW1lbnQ+YCB0YWcgaXMgdXNlZCB0byBkZWZpbmUgY29uY2VwdHMsIGVpdGhlciBjb25jZXB0IGNvcmUgZGltZW5zaW9ucyBvciB0YXhvbm9teSBkZWZpbmVkIGRpbWVuc2lvbnMgYXMgZm9sbG93czogIApgYGB7ciBpc194c2RfZWxlbWVudHMsIGVjaG89RkFMU0V9CmVsZW1lbnRzIDwtIHhtbDI6OnhtbF9maW5kX2FsbChpc194c2QsJy4vLypbbG9jYWwtbmFtZSgpPSJlbGVtZW50Il0nKSAlPiUKICBtYXAoZnVuY3Rpb24oeCkgewogICAgYyh0YWc9eG1sMjo6eG1sX25hbWUoeCksIHhtbDI6OnhtbF9hdHRycyh4KSkKICB9KSAlPiUgYmluZF9yb3dzKCkgJT4lIGFycmFuZ2UoYWJzdHJhY3QpCnRydWVSb3dzIDwtIHdoaWNoKGlmX2Vsc2UoZWxlbWVudHMkYWJzdHJhY3Q9PSd0cnVlJywgVFJVRSwgRkFMU0UpKQpmYWxzZVJvd3MgPC0gd2hpY2goaWZfZWxzZShlbGVtZW50cyRhYnN0cmFjdD09J2ZhbHNlJywgVFJVRSwgRkFMU0UpKQprIDwtICBrbml0cjo6a2FibGUoZWxlbWVudHMpICU+JSAKICBrYWJsZUV4dHJhOjpwYWNrX3Jvd3MoJ0NvbmNlcHQgQ29yZSBEaW1lbnNpb25zJywgZmFsc2VSb3dzWzFdLCBmYWxzZVJvd3NbbGVuZ3RoKGZhbHNlUm93cyldLGxhYmVsX3Jvd19jc3MgPSAiZm9udC1zdHlsZTogaXRhbGljO2JvcmRlci1ib3R0b206IDFweCBzb2xpZDsiKSAlPiUKICAgIGthYmxlRXh0cmE6OnBhY2tfcm93cygnVGF4b25vbXkgRGVmaW5lZCBEaW1lbnNpb25zJywgdHJ1ZVJvd3NbMV0sIHRydWVSb3dzW2xlbmd0aCh0cnVlUm93cyldLGxhYmVsX3Jvd19jc3MgPSAiZm9udC1zdHlsZTogaXRhbGljO2JvcmRlci1ib3R0b206IDFweCBzb2xpZDsiKSAlPiUgCiAga2FibGVFeHRyYTo6a2FibGVfY2xhc3NpYygpIApodG1sdG9vbHM6OmRpdihodG1sdG9vbHM6OkhUTUwoayksIHN0eWxlPSJvdmVyZmxvdy14OmF1dG8iKQpgYGAKPC9icj4KCiMjIyMgUHJlc2VudGF0aW9uIGxpbmtiYXNlICAKUHJlc2VudGF0aW9uIGxpbmtiYXNlIGlzIHVzZWQgdG8gZGVmaW5lIGNvbmNlcHRzIHJlbGF0aW9uc2hpcHMgaW4gdGVybXMgb2YgcHJlc2VudGF0aW9uIGFuZCByZW5kZXJpbmcsIGluIG90aGVyIHdvcmRzIGl0IG9yZ2FuaXplcyBjb25jZXB0cyBieSBkZWZpbmluZyB0aGUgb3JkZXIgYW5kIGdyb3VwaW5nIG9mIGNvbmNlcHRzIHdpdGhpbiB0aGUgdGF4b25vbXksIGFsc28gaXQgaXMgdXNlZCBmb3IgcmVuZGVyaW5nIGEgdGF4b25vbXkgaW4gYSBodW1hbiByZWFkYWJsZSBmb3JtYXQuIAoKUHJlc2VudGF0aW9uIGxpbmtiYXNlIFhNTCBmaWxlOihbc2VlIGZpbGVdKHhtbF9maWxlcy9pbmNvbWVTdGF0ZW1lbnRFeGFtcGxlL2lzX3ByZS54bWwpe3RhcmdldD1fYmxhbmt9KSAgCmBgYHtyIGlzX2V4YW1wbGVfcHJlX2xpbmssIGVjaG89RkFMU0V9CmZuX0NvZGVDaHVua091dChsYW5nPSd4bWwnLCBGaWxlID0gaGVyZTo6aGVyZSgnZG9jcycsJ3htbF9maWxlcy9pbmNvbWVTdGF0ZW1lbnRFeGFtcGxlL2lzX3ByZS54bWwnKSkKYGBgCiAgCk5vdGUgdGhhdCB0aGUgcm9vdCBlbGVtZW50IGlzIGA8bGlua2Jhc2U+YCwgd2hpY2ggY2FuIGhhdmUgb25seSBmb3VyIHR5cGVzIG9mIGNoaWxkcmVuIGVsZW1lbnRzIChzZWUgW2xpbmtiYXNlIGVsZW1lbnRdKCNsaW5rYmFzZS1lbGVtZW50LWltZykpCgoqKlRoZSBwcmVzZW50YXRpb24gbGlua2Jhc2UgcmVsZXZhbnQgY29tcG9uZW50cyBjYW4gYmUgYW5hbHl6ZWQgYXMgZm9sbG93czoqKiAgCgojIyMjIyByb2xlUmVmICAKRWxlbWVudCBgPHJvbGVSZWY+YCByZWZlcmVuY2VzIHRoZSBgPHJvbGVUeXBlPmAgZGVjbGFyYXRpb24gaW4gdGhlIHNjaGVtYSBhbmQgaXMgcmVwZWF0ZWQgZm9yIGVhY2ggYHJvbGVUeXBlYCBkZWNsYXJlZCwgZm9sbG93aW5nIGlzIHRoZSBgcm9sZVJlZmAgZnJvbSBvdXIgZXhhbXBsZTogIApgYGB7ciBpc19wcmVfcm9sZVR5cGUsIGVjaG89RkFMU0V9CmlzX3ByZSA8LSB4bWwyOjpyZWFkX3htbChoZXJlOjpoZXJlKCdkb2NzJywneG1sX2ZpbGVzL2luY29tZVN0YXRlbWVudEV4YW1wbGUvaXNfcHJlLnhtbCcpKQoKcm9sZVJlZiA8LSB4bWwyOjp4bWxfZmluZF9hbGwoaXNfcHJlLCcuLy8qW2xvY2FsLW5hbWUoKT0icm9sZVJlZiJdJykgJT4lCiAgbWFwKGZ1bmN0aW9uKHgpIHsKICAgIGModGFnPXhtbDI6OnhtbF9uYW1lKHgpLCB4bWwyOjp4bWxfYXR0cnMoeCkpCiAgfSkgJT4lIGJpbmRfcm93cygpICU+JSBtdXRhdGUoZGVzY3JpcHRpb249YyhrYWJsZUV4dHJhOjp0ZXh0X3NwZWMoJ1NlZSByb2xlVHlwZScsIGxpbmsgPSAnI3JvbGUtdHlwZXMnKSkpCgprMTEgPC0ga25pdHI6OmthYmxlKHJvbGVSZWYsIGVzY2FwZSA9IEYpICU+JSBrYWJsZUV4dHJhOjprYWJsZV9jbGFzc2ljKCkKaHRtbHRvb2xzOjpkaXYoaHRtbHRvb2xzOjpIVE1MKGsxMSksIHN0eWxlPSJvdmVyZmxvdy14OmF1dG8iKQpgYGAKIyMjIyMgUmVsYXRpb25zIChhcmNzKSAgCkFzIG1lbnRpb25lZCB0aGUgbmV0d29yayBvZiByZWxhdGlvbnMgaXMgYSB0cmVlIHN0cnVjdHVyZSB3aXRoIGEgcm9vdCwgaW4gb3VyIGNhc2UgZm9yIGxpbmtyb2xlIGBodHRwOi8veHl6LmFiYy9yb2xlL0luY29tZVN0YXRlbWVudGAgdGhlIHJvb3QgZWxlbWVudCBpcyBgSW5jb21lIFN0YXRlbWVudCBbQWJzdHJhY3RdYCB0aGF0IGlzIG1lYW50IHRvIGdyb3VwIHRvZ2V0aGVyIGFsbCBJbmNvbWUgc3RhdGVtZW50IGVsZW1lbnRzLCB0aGUgbmV0d29yayBjYW4gYmUgZGVzY3JpYmVkIGluIGEgdGFibGUgYXMgZm9sbG93cyAoYEBmcm9tYCBhbmQgYEB0b2AgcmVmZXJzIHRvIGxvY2F0b3JzIGlkcyk6ICAKYGBge3IgaXNfcHJlX25ldHdvcmssIGVjaG89RkFMU0V9Cm5ldHdvcmsgPC0geG1sMjo6eG1sX2ZpbmRfYWxsKGlzX3ByZSwnLi8vKltsb2NhbC1uYW1lKCk9InByZXNlbnRhdGlvbkFyYyJdJykgJT4lCiAgbWFwKGZ1bmN0aW9uKHgpIHsKICAgIGModGFnPXhtbDI6OnhtbF9uYW1lKHgpLCB4bWwyOjp4bWxfYXR0cnMoeCkpCiAgfSkgJT4lIGJpbmRfcm93cygpICU+JSBhcnJhbmdlKGZyb20sIG9yZGVyKQoKa25pdHI6OmthYmxlKG5ldHdvcmssIGVzY2FwZSA9IEYpICU+JSBrYWJsZUV4dHJhOjprYWJsZV9jbGFzc2ljKCkgJT4lIAogIGh0bWx0b29sczo6SFRNTCgpICU+JSBodG1sdG9vbHM6OmRpdihzdHlsZT0ib3ZlcmZsb3cteDphdXRvO3doaXRlLXNwYWNlOiBub3dyYXA7IikKYGBgCgpfTm90ZXNfICAKCiogYDxwcmVzZW50YXRpb25BcmM+YCBpcyB1c2VkIHRvIGVzdGFibGlzaCBwcmVzZW50YXRpb24gcmVsYXRpb25zaGlwcyBpbiBhIHByZXNlbnRhdGlvbiBuZXR3b3JrLiAgCiogYHBhcmVudC1jaGlsZGAgYXJjcm9sZSBpcyB1c2VkIGZvciBwcmVzZW50YXRpb24gcmVsYXRpb25zaGlwICAKKiBgQHByZWZlcnJlZExhYmVsYCBpcyB1c2VkIG9uIGBwcmVzZW50YXRpb25BcmNgIHRvIGRldGVybWluZSB3aGljaCBsYWJlbCByb2xlIHRvIGRpc3BsYXkgKHNlZSBsYWJlbCBsaW5rYmFzZSkgIAoqIGBAb3JkZXJgIGlzIHVzZWQgb24gYHByZXNlbnRhdGlvbkFyY2AgdG8gZGV0ZXJtaW5lIHRoZSBvcmRlciBvZiBhcHBlYXJhbmNlIG9mIGNvbmNlcHQgd2hlbiBwcmVzZW50ZWQuICAKCiMjIyMjIEhpZXJhcmNoaWNhbCBWaWV3ICAKKipBIGhpZXJhcmNoaWNhbCB2aWV3IG9mIHByZXNlbnRhdGlvbiBsaW5rIChDb25jZXB0cyBsYWJlbHMgYXJlIHVzZWQpKio6IApgYGB7ciBpc19wcmVfbmV0d29ya19oaWVyLCBlY2hvPUZBTFNFfQpkYXRhLmZyYW1lKGBDb25jZXB0IExhYmVsYD0gYygKJzEwMDAwIC0gU3RhdGVtZW50IC0gSW5jb21lIFN0YXRlbWVudCcsCidJbmNvbWUgU3RhdGVtZW50IFtBYnN0cmFjdF0nLAonSW5jb21lIFN0YXRlbWVudCBbVGFibGVdJywKJ1Byb2R1Y3QgQW5kIFNlcnZpY2UgW0F4aXNdJywKJ1Byb2R1Y3QgQW5kIFNlcnZpY2UgW0RvbWFpbl0nLAonUHJvZHVjdCBbTWVtYmVyXScsCidTZXJ2aWNlIFtNZW1iZXJdJywKJ1N0YXRlbWVudCBbTGluZSBJdGVtc10nLAonVG90YWwgUmV2ZW51ZXMnLAonVG90YWwgQ29zdHMgb2YgUmV2ZW51ZXMnLAonR3Jvc3MgUHJvZml0JywKJ0V4cGVuc2VzJywKJ05ldCBQcm9maXQnLAonRWFybmluZ3MgUGVyIFNoYXJlJywKJ1NoYXJlcyBPdXRzdGFuZGluZycpLApvcmRlcj1jKCcnLDEsMSwxLDEsMSwyLDIsMSwyLDMsNCw1LDYsNyksCmRlcHRoPWMoJ0NvbnRhaW5lcicsJ1Jvb3QnLCcyJywnMycsJzQnLCc1JywnNScsJzMnLCc0JywnNCcsJzQnLCc0JywnNCcsJzQnLCc0JykpICU+JSBrbml0cjo6a2FibGUoY29sLm5hbWVzID0gYyhwYXN0ZTAoJ0NvbmNlcHQgTGFiZWwnLCBrYWJsZUV4dHJhOjpmb290bm90ZV9tYXJrZXJfc3ltYm9sKDEpKSwnT3JkZXIgd2l0aGluIEdyb3VwJywgJ2RlcHRoJyksIGFsaWduID0gYygnbCcsICdjJywgJ3InKSwgZXNjYXBlID0gRikgJT4lIGthYmxlRXh0cmE6OmthYmxlX2NsYXNzaWMoKSAlPiUgCiAga2FibGVFeHRyYTo6YWRkX2luZGVudChwb3NpdGlvbnMgPSAyLCBsZXZlbF9vZl9pbmRlbnQgPTEgKSAlPiUgCiAga2FibGVFeHRyYTo6YWRkX2luZGVudChwb3NpdGlvbnMgPSAzLCBsZXZlbF9vZl9pbmRlbnQgPTIgKSAlPiUgCiAga2FibGVFeHRyYTo6YWRkX2luZGVudChwb3NpdGlvbnMgPSBjKDQsOCksIGxldmVsX29mX2luZGVudCA9MyApICU+JSAKICBrYWJsZUV4dHJhOjphZGRfaW5kZW50KHBvc2l0aW9ucyA9IGMoNSw5OjE1KSwgbGV2ZWxfb2ZfaW5kZW50ID00KSAlPiUgCiAga2FibGVFeHRyYTo6YWRkX2luZGVudChwb3NpdGlvbnMgPSBjKDYsNyksIGxldmVsX29mX2luZGVudCA9NSkgJT4lIAogIGthYmxlRXh0cmE6OmZvb3Rub3RlKHN5bWJvbD0iQ29uY2VwdHMgcHJlZmVycmVkIGxhYmVscyBhcmUgdXNlZCBpbiB0aGlzIHRhYmxlIikKCgpgYGAKCgoqKkEgbG9naWNhbCB2aWV3IG9mIHRoZSBwcmVzZW50YXRpb24gbGluayByb2xlIHdpbGwgYmUgYXMgZm9sbG93czoqKgoKPGRpdj4KPGNlbnRlcj4KIVtQcmVzZW50YXRpb24gTGluayBEaWFncmFtXShgciBoZXJlOjpoZXJlKCdkb2NzJywgJ2ltYWdlcy9wcmVzZW50YXRpb25saW5rLnBuZycpYCkKPC9jZW50ZXI+CjxwIHN0eWxlPSJ0ZXh0LWFsaWduOmNlbnRlciI+CioqUHJlc2VudGF0aW9uIExpbmsgRGlhZ3JhbSAqKltfKGZpZ3VyZSBjcmVhdGVkIHVzaW5nIGRyYXcuaW8pX10oaHR0cHM6Ly9hcHAuZGlhZ3JhbXMubmV0LykKPC9wPgo8L2Rpdj4gIAoKIyMjIyBDYWxjdWxhdGlvbiBsaW5rYmFzZSAgCkNhbGN1bGF0aW9uIGxpbmtiYXNlIGlzIHVzZWQgdG8gZGVzY3JpYmUgY2FsY3VsYXRpb24gcmVsYXRpb25zaGlwcyBiZXR3ZWVuIGNvbmNlcHRzIGluIHRlcm1zIG9mIHRvdGFscyBhbmQgc3VidG90YWxzLCBpdCBpcyBpbXBvcnRhbnQgdG8ga2VlcCBpbiBtaW5kIHRoYXQgWEJSTCBpdHNlbGYgZG9lcyBub3QgZG8gYW55IGNhbGN1bGF0aW9ucywgaXQganVzdCBkZXNjcmliZSB0aGUgY2FsY3VsYXRpb24gcmVsYXRpb25zaGlwIGJldHdlZW4gY29uY2VwdHMuIAoKQ2FsY3VsYXRpb24gbGlua2Jhc2UgWE1MIGZpbGUgKFtzZWUgZmlsZV0oeG1sX2ZpbGVzL2luY29tZVN0YXRlbWVudEV4YW1wbGUvaXNfY2FsLnhtbCl7dGFyZ2V0PV9ibGFua30pOiAgCmBgYHtyIGlzX2V4YW1wbGVfY2FsX2xpbmssIGVjaG89RkFMU0V9CmZuX0NvZGVDaHVua091dChsYW5nPSd4bWwnLCBGaWxlID0gaGVyZTo6aGVyZSgnZG9jcycsJ3htbF9maWxlcy9pbmNvbWVTdGF0ZW1lbnRFeGFtcGxlL2lzX2NhbC54bWwnKSkKYGBgCiAgCioqQ2FsY3VsYXRpb24gbGlua2Jhc2UgcmVsZXZhbnQgY29tcG9uZW50cyBjYW4gYmUgYW5hbHl6ZWQgYXMgZm9sbG93czoqKiAgCgojIyMjIyByb2xlUmVmICAKRWxlbWVudCBgPHJvbGVSZWY+YCByZWZlcmVuY2VzIHRoZSBgPHJvbGVUeXBlPmAgZGVjbGFyYXRpb24gaW4gdGhlIHNjaGVtYSBhbmQgaXMgcmVwZWF0ZWQgZm9yIGVhY2ggYHJvbGVUeXBlYCBkZWNsYXJlZCwgZm9sbG93aW5nIGlzIHRoZSBgcm9sZVJlZmBgIGZyb20gb3VyIGV4YW1wbGU6ICAKYGBge3IgaXNfY2FsX3JvbGVUeXBlLCBlY2hvPUZBTFNFfQppc19jYWwgPC0geG1sMjo6cmVhZF94bWwoaGVyZTo6aGVyZSgnZG9jcycsJ3htbF9maWxlcy9pbmNvbWVTdGF0ZW1lbnRFeGFtcGxlL2lzX2NhbC54bWwnKSkKCnJvbGVSZWYgPC0geG1sMjo6eG1sX2ZpbmRfYWxsKGlzX2NhbCwnLi8vKltsb2NhbC1uYW1lKCk9InJvbGVSZWYiXScpICU+JQogIG1hcChmdW5jdGlvbih4KSB7CiAgICBjKHRhZz14bWwyOjp4bWxfbmFtZSh4KSwgeG1sMjo6eG1sX2F0dHJzKHgpKQogIH0pICU+JSBiaW5kX3Jvd3MoKSAlPiUgbXV0YXRlKGRlc2NyaXB0aW9uPWMoa2FibGVFeHRyYTo6dGV4dF9zcGVjKCdTZWUgcm9sZVR5cGUnLCBsaW5rID0gJyNyb2xlLXR5cGVzJykpKQoKazExIDwtIGtuaXRyOjprYWJsZShyb2xlUmVmLCBlc2NhcGUgPSBGKSAlPiUga2FibGVFeHRyYTo6a2FibGVfY2xhc3NpYygpCmh0bWx0b29sczo6ZGl2KGh0bWx0b29sczo6SFRNTChrMTEpLCBzdHlsZT0ib3ZlcmZsb3cteDphdXRvIikKYGBgCgojIyMjIyBSZWxhdGlvbnMgKGFyY3MpICAKVGhlIHJvb3QgZWxlbWVudCBpbiBjYXNlIG9mIGNhbGN1bGF0aW9uIHJlbGF0aW9uc2hpcCBpcyB1c3VhbGx5IHRoZSBncmFuZCB0b3RhbCBvZiBhbGwgb3RoZXIgY2FsY3VsYXRpb25zLCBpbiBvdXIgYEluY29tZSBTdGF0ZW1lbnRgIHRoZSByb290IGVsZW1lbnQgaXMgYE5ldCBQcm9maXRgIGZvciBsaW5rcm9sZSBgaHR0cDovL3h5ei5hYmMvcm9sZS9JbmNvbWVTdGF0ZW1lbnRgLCB0aGUgbmV0d29yayBjYW4gYmUgZGVzY3JpYmVkIGluIGEgdGFibGUgYXMgZm9sbG93cyAoYEBmcm9tYCBhbmQgYEB0b2AgcmVmZXJzIHRvIGxvY2F0b3JzIGlkcyk6ICAKYGBge3IgaXNfY2FsX25ldHdvcmssIGVjaG89RkFMU0V9Cm5ldHdvcmtfY2FsIDwtIHhtbDI6OnhtbF9maW5kX2FsbChpc19jYWwsJy4vLypbbG9jYWwtbmFtZSgpPSJjYWxjdWxhdGlvbkFyYyJdJykgJT4lCiAgbWFwKGZ1bmN0aW9uKHgpIHsKICAgIGModGFnPXhtbDI6OnhtbF9uYW1lKHgpLCB4bWwyOjp4bWxfYXR0cnMoeCkpCiAgfSkgJT4lIGJpbmRfcm93cygpICU+JSBhcnJhbmdlKGZyb20sIG9yZGVyKQoKa25pdHI6OmthYmxlKG5ldHdvcmtfY2FsLCBlc2NhcGUgPSBGKSAlPiUga2FibGVFeHRyYTo6a2FibGVfY2xhc3NpYygpICU+JSAKICBodG1sdG9vbHM6OkhUTUwoKSAlPiUgaHRtbHRvb2xzOjpkaXYoc3R5bGU9Im92ZXJmbG93LXg6YXV0bzt3aGl0ZS1zcGFjZTogbm93cmFwOyIpCmBgYAoKX05vdGVzXyAgCgoqIGA8Y2FsY3VsYXRpb25BcmM+YCBpcyB1c2VkIHRvIGVzdGFibGlzaCBjYWxjdWxhdGlvbiByZWxhdGlvbnNoaXBzIGluIGEgY2FsY3VsYXRpb24gbmV0d29yay4gIAoqIGBzdW1tYXRpb24taXRlbWAgYXJjcm9sZSBpcyB1c2VkIGZvciBjYWxjdWxhdGlvbiByZWxhdGlvbnNoaXAgIAoqIGBAd2VpZ2h0YCBpcyB1c2VkIG9uIGBjYWxjdWxhdGlvbkFyY2AgdG8gZGV0ZXJtaW5lIGlmIHRoaXMgY29uY2VwdCBpcyB0byBiZSBhZGRlZCAoYEB3ZWlnaHQ9MS4wYCkgb3Igc3VidHJhY3RlZCAoYEB3ZWlnaHQ9LTEuMGApLCB0aGUgY29uY2VwdCBhdHRyaWJ1dGUgYEBiYWxhbmNlYCBpcyB1c2VkIGluIGNvbmp1bmN0aW9uIHdpdGggdGhlIGBAd2VpZ2h0YCB0byBkZXRlcm1pbmUgdGhlIGFwcHJvcHJpYXRlIGFyaXRobWV0aWMgb3BlcmF0aW9uLiAgCiogYEBvcmRlcmAgaXMgdXNlZCBvbiBgY2FsY3VsYXRpb25BcmNgIHRvIGRldGVybWluZSB0aGUgb3JkZXIgb2YgYXBwZWFyYW5jZSBvZiBjb25jZXB0IHdoZW4gdGhlIGNhbGN1bGF0aW9uIHJlbGF0aW9uc2hpcCBpcyBwcmVzZW50ZWQuICAKCiMjIyMjIEhpZXJhcmNoaWNhbCBWaWV3ICAKKipBIGhpZXJhcmNoaWNhbCB2aWV3IG9mIGNhbGN1bGF0aW9uIGxpbmsgKENvbmNlcHRzIGxhYmVscyBhcmUgdXNlZCkqKjogCmBgYHtyIGlzX2NhbF9uZXR3b3JrX2hpZXIsIGVjaG89RkFMU0V9CmRhdGEuZnJhbWUoYENvbmNlcHQgTGFiZWxgPSBjKAonMTAwMDAgLSBTdGF0ZW1lbnQgLSBJbmNvbWUgU3RhdGVtZW50JywKJ05ldCBQcm9maXQnLAonKDEpIEdyb3NzIFByb2ZpdCcsCicoMSkgUmV2ZW51ZScsCicoLTEpIENvc3Qgb2YgUmV2ZW51ZScsCicoLTEpIEV4cGVuc2VzJyksCndlaWdodD1jKCcnLCcnLCcxLjAnLCcxLjAnLCctMS4wJywnLTEuMCcpLApiYWxhbmNlPWMoJycsICdjcmVkaXQnLCAnY3JlZGl0JywgJ2NyZWRpdCcsJ2RlYml0JywgJ2RlYml0JyksCmRlcHRoPWMoJ0NvbnRhaW5lcicsJ1Jvb3QnLCcxJywnMicsJzInLCcxJykpICU+JSBrbml0cjo6a2FibGUoY29sLm5hbWVzID0gYyhwYXN0ZTAoJ0NvbmNlcHQgTGFiZWwnLCBrYWJsZUV4dHJhOjpmb290bm90ZV9tYXJrZXJfc3ltYm9sKDEpKSwnV2VpZ2h0JywnQmFsYW5jZScsICdkZXB0aCcpLCBhbGlnbiA9IGMoJ2wnLCAnYycsJ2MnICwncicpLCBlc2NhcGUgPSBGKSAlPiUga2FibGVFeHRyYTo6a2FibGVfY2xhc3NpYygpICU+JSAKICBrYWJsZUV4dHJhOjphZGRfaW5kZW50KHBvc2l0aW9ucyA9IDIsIGxldmVsX29mX2luZGVudCA9MSApICU+JSAKICBrYWJsZUV4dHJhOjphZGRfaW5kZW50KHBvc2l0aW9ucyA9IGMoMyw2KSwgbGV2ZWxfb2ZfaW5kZW50ID0yICkgJT4lIAogIGthYmxlRXh0cmE6OmFkZF9pbmRlbnQocG9zaXRpb25zID0gYyg0LDUpLCBsZXZlbF9vZl9pbmRlbnQgPTMgKSAlPiUKICBrYWJsZUV4dHJhOjpmb290bm90ZShzeW1ib2w9IkNvbmNlcHRzIHByZWZlcnJlZCBsYWJlbHMgYXJlIHVzZWQgaW4gdGhpcyB0YWJsZSIpCgoKYGBgCgojIyMjIExhYmVsIGxpbmtiYXNlICAKTGFiZWwgbGlua2Jhc2UgaXMgYW4gZXhhbXBsZSBvZiBgUmVzb3VyY2UgTGlua2AsIGl0IGlzIHVzZWQgdG8gY3JlYXRlIHJlbGF0aW9uc2hpcHMgYmV0d2VlbiBjb25jZXB0cyBhbmQgdGhlaXIgbGFiZWxzLCBsYWJlbCBoZXJlIGlzIHRoZSBgUmVzb3VyY2VgLiBFYWNoIGNvbmNlcHQgY2FuIGhhdmUgbXVsdGlwbGUgbGFiZWxzIGRlc2NyaWJpbmcgdGhlIGNvbmNlcHQgaW4gZGlmZmVyZW50IHJvbGVzLCBleGFtcGxlcyBvZiBsYWJlbCByb2xlcyBiZWdpbm5pbmcgYmFsYW5jZSBvciBlbmRpbmcgYmFsYW5jZSwgYWxzbyBhIGNvbmNlcHQgY2FuIGhhdmUgbGFiZWxzIGluIG11bHRpcGxlIGxhbmd1YWdlcy4gIAoKTGFiZWwgbGluayB1c2VzIGA8bGFiZWxBcmM+YCB0byBsaW5rIGEgY29uY2VwdCB0byBpdHMgbGFiZWxzLCBhbmQgdXNlcyBgQGFyY3JvbGVgIGBodHRwOi8vd3d3Lnhicmwub3JnLzIwMDMvYXJjcm9sZS9jb25jZXB0LWxhYmVsYC4gIAoKIyMjIyMgTGFiZWwgUm9sZXMgIApFYWNoIGxhYmVsIChyZXNvdXJjZSkgaXMgZGVmaW5lZCB1c2luZyB0aGUgZWxlbWVudCBgPGxhYmVsPmAgZnJvbSBuYW1lc3BhY2UgYHtodHRwOi8vd3d3Lnhicmwub3JnLzIwMDMvbGlua2Jhc2V9YC4gVGhlIGBAcm9sZWAgYW5kIGBAeG1sOmxhbmdgIGF0dHJpYnV0ZXMgb24gdGhlIGA8bGFiZWw+YCBlbGVtZW50IGFyZSB1c2VkIHRvIGlkZW50aWZ5IHRoZSByb2xlIG9mIHRoZSBsYWJlbCBhbmQgaXRzIGxhbmd1YWdlLiBYQlJMIHNwZWNpZmljYXRpb25zIHNwZWNpZnkgc29tZSBzdGFuZGFyZCBsYWJlbCBgcm9sZXNgLCBzb21lIG9mIHRoZW0gYXJlIGFzIGZvbGxvd3M6ICAgCgpgYGB7ciBpc19sYWJfY2FzaCwgZWNobz1GQUxTRX0KZGF0YS5mcmFtZSgKICByb2xlID0gYygKICAgICc8c3Bhbj5PbWl0dGVkIHJvbGUgYXR0cmlidXRlIE9SPC9zcGFuPgogICAgPHNwYW4+aHR0cDovL3d3dy54YnJsLm9yZy8yMDAzL3JvbGUvbGFiZWw8L3NwYW4+JywKICAgICdodHRwOi8vd3d3Lnhicmwub3JnLzIwMDMvcm9sZS90ZXJzZUxhYmVsJywKICAgICdodHRwOi8vd3d3Lnhicmwub3JnLzIwMDMvcm9sZS92ZXJib3NlTGFiZWwnLAogICAgJ2h0dHA6Ly93d3cueGJybC5vcmcvMjAwMy9yb2xlL3RvdGFsTGFiZWwnLAogICAgJwogICAgPHNwYW4+aHR0cDovL3d3dy54YnJsLm9yZy8yMDAzL3JvbGUvcGVyaW9kU3RhcnRMYWJlbDwvc3Bhbj4KICAgIDxzcGFuPmh0dHA6Ly93d3cueGJybC5vcmcvMjAwMy9yb2xlL3BlcmlvZEVuZExhYmVsPC9zcGFuPiAKICAgICcsICdodHRwOi8vd3d3Lnhicmwub3JnLzIwMDMvcm9sZS9kb2N1bWVudGF0aW9uJywgJy4uLicKICApLAogIG1lYW5pbmcgPSBjKAogICAgJ1N0YW5kYXJkIGxhYmVsIGZvciBhIENvbmNlcHQuJywKICAgICdTaG9ydCBsYWJlbCBmb3IgYSBDb25jZXB0LCBvZnRlbiBvbWl0dGluZyB0ZXh0IHRoYXQgc2hvdWxkIGJlIGluZmVyYWJsZSB3aGVuIHRoZSBjb25jZXB0IGlzIHJlcG9ydGVkIGluIHRoZSBjb250ZXh0IG9mIG90aGVyIHJlbGF0ZWQgY29uY2VwdHMuJywKICAgICdFeHRlbmRlZCBsYWJlbCBmb3IgYSBDb25jZXB0LCBtYWtpbmcgc3VyZSBub3QgdG8gb21pdCB0ZXh0IHRoYXQgaXMgcmVxdWlyZWQgdG8gZW5hYmxlIHRoZSBsYWJlbCB0byBiZSB1bmRlcnN0b29kIG9uIGEgc3RhbmQgYWxvbmUgYmFzaXMuJywKICAgICdUaGUgbGFiZWwgZm9yIGEgQ29uY2VwdCBmb3IgdXNlIGluIHByZXNlbnRpbmcgdmFsdWVzIGFzc29jaWF0ZWQgd2l0aCB0aGUgY29uY2VwdCB3aGVuIGl0IGlzIGJlaW5nIHJlcG9ydGVkIGFzIHRoZSB0b3RhbCBvZiBhIHNldCBvZiBvdGhlciB2YWx1ZXMuJywKICAgICcgaHR0cDovL3d3dy54YnJsLm9yZy8yMDAzL3JvbGUvcGVyaW9kRW5kTGFiZWwJVGhlIGxhYmVsIGZvciBhIENvbmNlcHQgd2l0aCBwZXJpb2RUeXBlPSJpbnN0YW50IiBmb3IgdXNlIGluIHByZXNlbnRpbmcgdmFsdWVzIGFzc29jaWF0ZWQgd2l0aCB0aGUgY29uY2VwdCB3aGVuIGl0IGlzIGJlaW5nIHJlcG9ydGVkIGFzIGEgc3RhcnQgKGVuZCkgb2YgcGVyaW9kIHZhbHVlLicsCiAgICAnRG9jdW1lbnRhdGlvbiBvZiBhIENvbmNlcHQsIHByb3ZpZGluZyBhbiBleHBsYW5hdGlvbiBvZiBpdHMgbWVhbmluZyBhbmQgaXRzIGFwcHJvcHJpYXRlIHVzYWdlIGFuZCBhbnkgb3RoZXIgZG9jdW1lbnRhdGlvbiBkZWVtZWQgbmVjZXNzYXJ5LicsCiAgICAnLi4uJwogICAgCiAgKQopICU+JSBrbml0cjo6a2FibGUoZXNjYXBlID0gRikgJT4lIGthYmxlRXh0cmE6OmthYmxlX2NsYXNzaWMoKSAlPiUgCiAga2FibGVFeHRyYTo6cm93X3NwZWMoMTo1LCBleHRyYV9jc3MgPSAiYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkIGxpZ2h0Z3JheSIpCmBgYApGb3IgdGhlIGZ1bGwgbGlzdCBvZiByb2xlcyAoW1NlZSBYQlJMIFNwZWNpZmljYXRpb25zIFRhYmxlIDhdKGh0dHBzOi8vd3d3Lnhicmwub3JnL1NwZWNpZmljYXRpb24vWEJSTC0yLjEvUkVDLTIwMDMtMTItMzEvWEJSTC0yLjEtUkVDLTIwMDMtMTItMzErY29ycmVjdGVkLWVycmF0YS0yMDEzLTAyLTIwLmh0bWwjXzUuMi4yLjIuMil7dGFyZ2V0PV9ibGFua30pLgoKSW4gdGhpcyBleGFtcGxlIHRoZSBFbmdsaXNoIGxhYmVscyBhbmQgQXJhYmljIGxhYmVscyBhcmUgc3RvcmVkIGluIHNlcGFyYXRlIGZpbGVzIChgaXNfbGFiX2VuLnhtbGAgYW5kIGBpc19sYWJfYXIueG1sYCksIGZpbGVzIGRpc3BsYXllZCBiZWxvdzogIAoKQXJhYmljIGxpbmtiYXNlIFhNTCBmaWxlOihbc2VlIGZpbGVdKHhtbF9maWxlcy9pbmNvbWVTdGF0ZW1lbnRFeGFtcGxlL2lzX2xhYl9hci54bWwpe3RhcmdldD1fYmxhbmt9KSAgCmBgYHtyIGlzX2V4YW1wbGVfbGFiX2FyLCBlY2hvPUZBTFNFfQpmbl9Db2RlQ2h1bmtPdXQobGFuZz0neG1sJywgRmlsZSA9IGhlcmU6OmhlcmUoJ2RvY3MnLCd4bWxfZmlsZXMvaW5jb21lU3RhdGVtZW50RXhhbXBsZS9pc19sYWJfYXIueG1sJykpCmBgYAoKCkVuZ2xpc2ggbGlua2Jhc2UgWE1MIGZpbGU6IChbc2VlIGZpbGVdKHhtbF9maWxlcy9pbmNvbWVTdGF0ZW1lbnRFeGFtcGxlL2lzX2xhYl9lbi54bWwpe3RhcmdldD1fYmxhbmt9KSAgCmBgYHtyIGlzX2V4YW1wbGVfbGFiX2VuLCBlY2hvPUZBTFNFfQpmbl9Db2RlQ2h1bmtPdXQobGFuZz0neG1sJywgRmlsZSA9IGhlcmU6OmhlcmUoJ2RvY3MnLCd4bWxfZmlsZXMvaW5jb21lU3RhdGVtZW50RXhhbXBsZS9pc19sYWJfZW4ueG1sJykpCmBgYAoKIyMjIyMgcm9sZVJlZiAgCkVsZW1lbnQgYDxyb2xlUmVmPmAgd2FzIG5vdCB1c2VkIHdpdGggbGFiZWwgbGluayBiZWNhdXNlIHdlIGRvIG5vdCBuZWVkIHRvIHBhcnRpdGlvbiB0aGUgbGFiZWwgbGlua3MgYnkgcm9sZXMgKHdlIGNhbiBkbyB0aGF0IGJ1dCB3YXMgbm90IGRvbmUgaW4gdGhpcyBjYXNlKSwgaW5zdGVhZCB0aGUgZGVmYXVsdCBzdGFuZGFyZCBsaW5rIHJvbGUgYGh0dHA6Ly93d3cueGJybC5vcmcvMjAwMy9yb2xlL2xpbmtgIHdhcyB1c2VkIG9uIHRoZSBgbGFiZWxMaW5rYCBlbGVtZW50LgoKU2luY2UgbGFiZWwgbGluayBpcyBhIHJlc291cmNlIGxpbmssIGl0IGRvZXMgbm90IGhhdmUgYSByb290IGVsZW1lbnQsIGl0IGp1c3QgbGlua3MgdGhlIGNvbmNlcHQgdG8gdGhlIHJlc291cmNlcy4gIAoKIyMjIyMgTGFiZWwgUmVzb3VyY2VzICAKVGFibGUgc2hvd2luZyBsYWJlbCByZXNvdXJjZSBkZWNsYXJhdGlvbnM6CmBgYHtyIGlzX2xhYl9uZXR3b3JrLCBlY2hvPUZBTFNFfQpsYWJfZW4gPC0geG1sMjo6cmVhZF94bWwoaGVyZTo6aGVyZSgnZG9jcycsJ3htbF9maWxlcy9pbmNvbWVTdGF0ZW1lbnRFeGFtcGxlL2lzX2xhYl9lbi54bWwnKSkgJT4lIAogIHhtbDI6OnhtbF9maW5kX2FsbCgnLi8vKltsb2NhbC1uYW1lKCk9ImxhYmVsIl0nKSAlPiUKICBtYXAoZnVuY3Rpb24oeCkgewogICAgYyh0YWc9eG1sMjo6eG1sX25hbWUoeCksIHhtbDI6OnhtbF9hdHRycyh4KSwgTGFiZWw9eG1sMjo6eG1sX3RleHQoeCkpCiAgfSkgJT4lIGJpbmRfcm93cygpCgojIGxhYl9hciA8LSB4bWwyOjpyZWFkX1hNTChoZXJlOjpoZXJlKCdYTUxfZmlsZXMvaW5jb21lU3RhdGVtZW50RXhhbXBsZScsJ2lzX2xhYl9hci5YTUwnKSkgJT4lIAojICAgeG1sMjo6WE1MX2ZpbmRfYWxsKCcuLy8qW2xvY2FsLW5hbWUoKT0ibGFiZWwiXScpICU+JQojICAgbWFwKGZ1bmN0aW9uKHgpIHsKIyAgICAgYyh0YWc9eG1sMjo6WE1MX25hbWUoeCksIHhtbDI6OlhNTF9hdHRycyh4KSwgTGFiZWw9eG1sMjo6WE1MX3RleHQoeCkpCiMgICB9KSAlPiUgYmluZF9yb3dzKCkKCiMgbGlzdChsYWJfYXIsbGFiX2VuKSAlPiUgYmluZF9yb3dzKCkgJT4lIG11dGF0ZShMYWJlbD0pCm5hbWVzKGxhYl9lbilbNF0gPC0gImlkX2xhYmVsIgpsYWJfZW4gJT4lCmtuaXRyOjprYWJsZSgnaHRtbCcsIGVzY2FwZSA9VCkgJT4lIGthYmxlRXh0cmE6OmthYmxlX2NsYXNzaWMoKSAlPiUKICBodG1sdG9vbHM6OkhUTUwoKSAlPiUgaHRtbHRvb2xzOjpkaXYoc3R5bGU9Im92ZXJmbG93LXg6YXV0bzt3aGl0ZS1zcGFjZTogbm93cmFwOyIpCmBgYAoKX05vdGVzXyAgCgoqIEFyYWJpYyBMYWJlbHMgYXJlIG5vdCBzaG93biBoZXJlIGR1ZSB0byBlbmNvZGluZyBpc3N1ZXMsIHBsZWFzZSBzZWUgZmlsZSBbaGVyZV0oeG1sX2ZpbGVzL2luY29tZVN0YXRlbWVudEV4YW1wbGUvaXNfbGFiX2FyLnhtbCkuICAKKiBgQGxhbmdgIGlzIHVzZWQgdG8gc3BlY2lmeSB0aGUgbGFuZ3VhZ2Ugb2YgdGhlIGxhYmVsLCB0aGlzIHdpbGwgaGVscCBzd2l0Y2hpbmcgYmV0d2VlbiBsYWJlbCBsYW5ndWFnZXMgaW4gYW55IFhCUkwgcHJvY2Vzc29yLiAgCiogYEByb2xlYCBpcyB1c2VkIHRvIHNwZWNpZnkgbGFiZWwgcm9sZSwgb25lIGNvbmNlcHQgY2FuIGhhdmUgbWFueSBsYWJlbHMgYnV0IGVhY2ggbGFiZWwgc2hvdWxkIGhhdmUgdW5pcXVlIGxhYmVsIHJvbGUuICAKCgojIyMjIERlZmluaXRpb24gbGlua2Jhc2UgIApEZWZpbml0aW9uIExpbmsgaXMgdXNlZCB0byBkZWZpbmUgcmVsYXRpb25zIGJldHdlZW4gY29uY2VwdHMgdGhhdCBnb2VzIGJleW9uZCBjYWxjdWxhdGlvbiBvciBwcmVzZW50YXRpb24gbGlua3MuIEVsZW1lbnQgYDxkZWZpbml0aW9uTGluaz5gIGlzIHVzZWQgZm9yIHRoZSBkZWZpbml0aW9uIG5ldHdvcmsgZm9yIGEgbGlua3JSb2xlIHNwZWNpZmllZCBieSBgQHJvbGVgIGF0dHJpYnV0ZSBvZiB0aGUgYDxkZWZpbml0aW9uTGluaz5gIGVsZW1lbnQsIGA8ZGVmaW5pdGlvbkFyYz5gIGlzIHVzZWQgdG8gZXN0YWJsaXNoIHRoZSByZWxhdGlvbiBiZXR3ZWVuIHRoZSBjb25jZXB0cyBwYWlycyBmb3IgdGhlIHJlbGF0aW9uIHNwZWNpZmllZCBieSB0aGUgYEByb2xlYCBhdHRyaWJ1dGUgb2YgdGhlIGA8ZGVmaW5pdGlvbkFyYz5gIGVsZW1lbnQuICAKClhCUkwgc3BlY2lmaWNhdGlvbnMgZGVmaW5lcyBzb21lIHN0YW5kYXJkIGRlZmluaXRpb24gYGFyY1JvbGVzYCAoW3NlZSBYQlJMIHNwZWNpZmljYXRpb24gc2VjdGlvbiA1LjIuNi4yXShodHRwczovL3d3dy54YnJsLm9yZy9TcGVjaWZpY2F0aW9uL1hCUkwtMi4xL1JFQy0yMDAzLTEyLTMxL1hCUkwtMi4xLVJFQy0yMDAzLTEyLTMxK2NvcnJlY3RlZC1lcnJhdGEtMjAxMy0wMi0yMC5odG1sI181LjIuNi4yKSksIGFuZCBoZXJlIGFyZSB0aGUgZGVmaW5pdGlvbnMgZnJvbSBfVEhEIHNlY3Rpb24gMy40LjQuM186ICAKCj4xLglHZW5lcmFsLXNwZWNpYWwgLSBUaGlzIHJlbGF0aW9uc2hpcCBpbmRpY2F0ZXMgdGhhdCBvbmUgY29uY2VwdCBvZiBhIHBhaXIgaXMgYSBtb3JlIHNwZWNpYWxpemVkIGZvcm0gb2YgYW5vdGhlciBjb25jZXB0LiBGb3IgaW5zdGFuY2UsIGluIHRoZSB3aWRnZXQgZXhhbXBsZSwgdGhlIHdpZGdldCB0eXBlIEFuZ3VsYXJXaWRnZXRzIGNhbiBiZSBnZW5lcmFsIChyZWZlcnJpbmcgdG8gYW55IHdpZGdldCB0eXBlIHRoYXQgaGFzIGFuZ2xlcyksIHdoaWxlIHRoZSB3aWRnZXQgdHlwZSBUcmlhbmd1bGFyV2lkZ2V0cyBpcyBtb3JlIHNwZWNpZmljLgo+Mi4JRXNzZW5jZS1hbGlhcyAtIFRoaXMgcmVsYXRpb25zaGlwIGluZGljYXRlcyB0aGF0IG9uZSBjb25jZXB0IG9mIGEgcGFpciBlc3NlbnRpYWxseSBoYXMgdGhlIHNhbWUgbWVhbmluZyBhcyB0aGUgb3RoZXIgY29uY2VwdC4gRm9yIGV4YW1wbGUsIG9uZSByZXBvcnRpbmcgZW50aXR5IG1heSB1c2UgdGhlIGNvbmNlcHQgV2lkZ2V0cyB0byByZWZlciB0byBpdHMgcHJvZHVjdCwgYW5kIGFub3RoZXIgbWF5IHByZWZlciB0aGUgY29uY2VwdCBHaXptb3MsIGJ1dCB0aGUgdW5kZXJseWluZyBtZWFuaW5nLCB0aGF0IHRoZXNlIGNvbmNlcHRzIGFyZSBwcm9kdWN0cywgaXMgdGhlIHNhbWUuIFRoZSBlc3NlbmNlLWFsaWFzIGRlZmluaXRpb24gcmVmbGVjdHMgYSBjaGFuZ2UgaW4gdGVybWlub2xvZ3kgcmF0aGVyIHRoYW4gc2VtYW50aWMgbWVhbmluZy4KPjMuCVJlcXVpcmVzLWVsZW1lbnQgLSBUaGlzIHJlbGF0aW9uc2hpcCBpbmRpY2F0ZXMgdGhhdCB0aGUgdmFsdWUgb2Ygb25lIGNvbmNlcHQgaXMgcmVxdWlyZWQgd2hlbiB0aGUgdmFsdWUgb2YgdGhlIG90aGVyIGNvbmNlcHQgaW4gdGhlIHBhaXIgaXMgcHJlc2VudC4gRm9yIGV4YW1wbGUsIGluIHRoZSB3aWRnZXQgcmVwb3J0IHdpdGggYm90aCBjb25jZXB0IGNvcmUgZGltZW5zaW9ucyBXaWRnZXRzU29sZCBhbmQgUHJpY2VQZXJXaWRnZXQsIFByaWNlUGVyV2lkZ2V0IHJlcXVpcmVzIGEgdmFsdWUgZm9yIFdpZGdldHNTb2xkLgo+NC4JU2ltaWxhci10dXBsZXMgLSBUaGlzIHJlbGF0aW9uc2hpcCBpcyBvcGVyYXRpb25hbGx5IHRoZSBzYW1lIGFzIHRoZSBlc3NlbmNlLWFsaWFzIGRlZmluaXRpb24gYnV0IHJlc2VydmVkIGZvciB1c2FnZSB3aXRoIHR1cGxlcy4gVHVwbGVzIGFyZSBub3QgY29tbW9ubHkgdXNlZC4gIAo+Cj5BZGRpdGlvbmFsbHksIHRoZSBYQlJMIERpbWVuc2lvbnMgU3BlY2lmaWNhdGlvbiBhbGxvd3MgZm9yIG1vcmUgZGVmaW5pdGlvbiB0eXBlcy4gVGhlc2UgdHlwZXMgYXJlIHVzZWQgdG8gZGVmaW5lIHRoZSByZWxhdGlvbnNoaXBzIHBlcnRhaW5pbmcgdG8gdGhlIGNvbXBvbmVudHMgb2YgYSBkaW1lbnNpb24gaW4gWEJSTC4gVGhlIGRlZmluaXRpb25zIGV4aXN0IGJldHdlZW4gYSBjb25jZXB0IGFuZCBhIHRheG9ub215LWRlZmluZWQgZGltZW5zaW9uIHRvIGRlZmluZSB0aGUgaGllcmFyY2hpY2FsIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRoZW0uIEV4YW1wbGVzIG9mIGVhY2ggY2FuIGJlIHNlZW4gaW4gRmlndXJlIDMtMTAuCj4KPjEuCURpbWVuc2lvbi1kZWZhdWx0IC0gVGhpcyByZWxhdGlvbnNoaXAgaW5kaWNhdGVzIHRoYXQgdGhlIGNvbmNlcHQgaXMgdGhlIGRlZmF1bHQgdmFsdWUgZm9yIHRoZSB0YXhvbm9teS1kZWZpbmVkIGRpbWVuc2lvbi4KPjIuCURpbWVuc2lvbi1kb21haW4gLSBUaGlzIHJlbGF0aW9uc2hpcCBpbmRpY2F0ZXMgdGhhdCB0aGUgY29uY2VwdCByZXByZXNlbnRzIHRoZSBkb21haW4gb2YgdGhlIHRheG9ub215LWRlZmluZWQgZGltZW5zaW9uLgo+My4JRG9tYWluLW1lbWJlciAtIFRoaXMgcmVsYXRpb25zaGlwIGluZGljYXRlcyB0aGF0IG9uZSBjb25jZXB0IGlzIGEgbWVtYmVyIG9mIHRoZSBkb21haW4gb2YgdGhlIG90aGVyIGNvbmNlcHQgdGhhdCBpcyBwYXJ0IG9mIGEgdGF4b25vbXktZGVmaW5lZCBkaW1lbnNpb24uIFRoaXMgcmVsYXRpb25zaGlwIGNhbiBleGlzdCBiZXR3ZWVuIG1hbnkgY29uY2VwdHMuIEZvciBleGFtcGxlLCBhIE5vcnRoZWFzdCBtZW1iZXIgbWF5IGJlbG9uZyB0byBhIEdlb2dyYXBoaWNMb2NhdGlvbiBheGlzLCBidXQgY29tcHJpc2luZyB0aGlzIE5vcnRoZWFzdCBtZW1iZXIgaXMgYSBncm91cCBvZiBub3J0aGVhc3Rlcm4gc3RhdGVzIGluIHRoZSBVUy4gVGhlc2UgZWFjaCBoYXZlIHRoZSBkb21haW4tbWVtYmVyIHJlbGF0aW9uc2hpcCB3aXRoIHRoZSBOb3J0aGVhc3QgY29uY2VwdC4KPmByIHR1ZnRlOjpxdW90ZV9mb290ZXIoJy0tLSBbVERIIHNlY3Rpb24gMy40LjQuMyBwYWdlIDUwXShodHRwczovL3hicmx1cy5naXRodWIuaW8vZG9jcy90ZGguaHRtbCknKWAKCkluIGFkZGl0aW9uIHRvIHRoZSBhYm92ZSwgWEJSTCBEaW1lbnNpb25zIFNwZWNpZmljYXRpb25zIGRlZmluZXMgdGhlIGZvbGxvd2luZyByZWxhdGlvbnM6ICAKCiogYGFsbCBhbmQgbm90QWxsYDogdG9nZXRoZXIgYWxzbyByZWZlcnJlZCB0byBhcyBgaGFzIGh5cGVyY3ViZWAgaXMgYSByZWxhdGlvbiBiZXR3ZWVuIGEgcHJpbWFyeSBpdGVtIGRlY2xhcmF0aW9uIGFuZCBhIGh5cGVyY3ViZSBpdGVtLCB0aGUgYGFsbGAgcmVsYXRpb25zIG1lYW5zIHRoYXQgdGhlIHByaW1hcnkgaXRlbSBjYW4gYmUgdXNlZCB3aXRoIGFsbCB0aGUgZGltZW5zaW9ucyBpbmNsdWRlZCBpbiB0aGUgaHlwZXJjdWJlLCBgbm90QWxsYCBtZWFucyB0aGF0IHRoZSBwcmltYXJ5IGl0ZW0gY2Fubm90IGJlIHVzZWQgd2l0aCBhbnkgZGltZW5zaW9uIGluIHRoZSBoeXBlcmN1YmUuIEluIGFkZGl0aW9uIHRvIGRlZmluaW5nIGRpbWVuc2lvbmFsIHJlbGF0aW9uCgoqIFRoZSBgQGNsb3NlZGAgYXR0cmlidXRlIG9mIGEgaHlwZXJjdWJlIHRoYXQgdGFrZXMgYSB0cnVlL2ZhbHNlIHZhbHVlLCBpZiB0cnVlIGl0IHNwZWNpZmllcyB0aGF0IGFsbCB0YXhvbm9teS1kZWZpbmVkIGRpbWVuc2lvbnMgaW4gdGhlIGh5cGVyY3ViZSBtdXN0IGludGVyc2VjdCBvbiBhIGZhY3QgaW4gb3JkZXIgZm9yIHRoYXQgZmFjdCB0byBiZSBwYXJ0IG9mIHRoZSBoeXBlcmN1YmUsIGlmIGZhbHNlIGFueSBvZiB0aGUgdGF4b25vbXktZGVmaW5lZCBkaW1lbnNpb25zIGluIHRoZSBoeXBlcmN1YmUgY2FuIGludGVyc2VjdCBvbiBhIGZhY3QgaW4gb3JkZXIgZm9yIHRoYXQgZmFjdCB0byBiZSBwYXJ0IG9mIHRoZSBoeXBlcmN1YmUuICAKCiogYGh5cGVyY3ViZS1kaW1lbnNpb25gIGEgcmVsYXRpb24gYmV0d2VlbiBhIGh5cGVyY3ViZSBhbmQgYSBkaW1lbnNpb24uICAKCiogU29tZXRpbWVzIGF1dGhvcnMgb2YgYW4gZXh0ZW5zaW9uIHRheG9ub215IG1heSB3YW50IHRvIHByb2hpYml0IHRoZSB1c2Ugb2Ygc29tZSBwcmltYXJ5IGl0ZW1zIGZyb20gYW4gaW1wb3J0ZWQgdGF4b25vbXksIG9uZSBvZiB0aGUgd2F5cyB0byBzbyBpcyBieSBsaW5raW5nIHRoZSBwcm9oaWJpdGVkIGl0ZW1zIHRvIGFuIGVtcHR5IGh5cGVyY3ViZSAoYSBoeXBlcmN1YmUgd2l0aCBvbmUgZGltZW5zaW9uIHRoYXQgZG9lcyBub3QgaGF2ZSBhbnkgbWVtYmVycyksIGFuZCB0aGlzIHdpbGwgcmVzdWx0IGluIGEgdmFsaWRhdGlvbiBlcnJvciBpZiBhbnkgb2YgdGhlc2UgY29uY2VwdHMgaXMgdXNlZC4KCkluIG91ciBleGFtcGxlLCBkZWZpbml0aW9uIGxpbmtiYXNlIGNvbnRhaW5zIG9ubHkgZGltZW5zaW9uYWwgcmVsYXRpb25zaGlwIHRvIGNyZWF0ZSB0aGUgaW5jb21lIHN0YXRlbWVudCB0YWJsZSB3aXRoIFByb2R1Y3QgQW5kIFNlcnZpY2UgZGltZW5zaW9ucy4gIAoKRGVmaW5pdGlvbiBsaW5rYmFzZSBYTUwgZmlsZTooW3NlZSBmaWxlXSh4bWxfZmlsZXMvaW5jb21lU3RhdGVtZW50RXhhbXBsZS9pc19kZWYueG1sKXt0YXJnZXQ9X2JsYW5rfSkgIApgYGB7ciBpc19leGFtcGxlX2RlZl9saW5rLCBlY2hvPUZBTFNFfQpmbl9Db2RlQ2h1bmtPdXQobGFuZz0neG1sJywgRmlsZSA9IGhlcmU6OmhlcmUoJ2RvY3MnLCd4bWxfZmlsZXMvaW5jb21lU3RhdGVtZW50RXhhbXBsZS9pc19kZWYueG1sJykpCmBgYAogIAojIyMjIyByb2xlUmVmIGFuZCBhcmNyb2xlUmVmICAKRWxlbWVudCBgPHJvbGVSZWY+YCByZWZlcmVuY2VzIHRoZSBgPHJvbGVUeXBlPmAgZGVjbGFyYXRpb24gaW4gdGhlIHNjaGVtYSBhbmQgaXMgcmVwZWF0ZWQgZm9yIGVhY2ggYHJvbGVUeXBlYCBkZWNsYXJlZCwgZm9sbG93aW5nIGlzIHRoZSBgcm9sZVJlZmBgIGZyb20gb3VyIGV4YW1wbGU6ICAKYGBge3IgaXNfZGVmX3JvbGVUeXBlLCBlY2hvPUZBTFNFfQppc19kZWYgPC0geG1sMjo6cmVhZF94bWwoaGVyZTo6aGVyZSgnZG9jcycsJ3htbF9maWxlcy9pbmNvbWVTdGF0ZW1lbnRFeGFtcGxlL2lzX2RlZi54bWwnKSkKCnJvbGVSZWYgPC0geG1sMjo6eG1sX2ZpbmRfYWxsKGlzX2RlZiwnLi8vKltsb2NhbC1uYW1lKCk9InJvbGVSZWYiIG9yIGxvY2FsLW5hbWUoKT0iYXJjcm9sZVJlZiJdJykgJT4lCiAgbWFwKGZ1bmN0aW9uKHgpIHsKICAgIGModGFnPXhtbDI6OnhtbF9uYW1lKHgpLCB4bWwyOjp4bWxfYXR0cnMoeCkpCiAgfSkgJT4lIGJpbmRfcm93cygpCgprbml0cjo6a2FibGUocm9sZVJlZiwgZXNjYXBlID0gRikgJT4lIAogIGthYmxlRXh0cmE6OmthYmxlX2NsYXNzaWMoKSAlPiUgCiAgaHRtbHRvb2xzOjpIVE1MKCkgJT4lIAogIGh0bWx0b29sczo6ZGl2KHN0eWxlPSJvdmVyZmxvdy14OmF1dG87d2hpdGUtc3BhY2U6IG5vd3JhcDsiKQpgYGAKX05vdGVfIGBhcmNyb2xlUmVmYCBpcyB1c2VkIHRvIHJlZmVyZW5jZSBhcmNyb2xlcyBkZWNsYXJlZCBpbiBYQlJMIERpbWVuc2lvbnMgc3BlY2lmaWNhdGlvbnMuCgojIyMjIyBSZWxhdGlvbnMgKGFyY3MpICAKSW4gdGhpcyBleGFtcGxlIG9ubHkgcmVsYXRpb25zIGZyb20gWEJSTCBkaW1lbnNpb25zIGFyZSB1c2VkIGluIHRoZSBkZWZpbml0aW9uIGxpbmtiYXNlIGZvciB0aGUgbGlua3JvbGUgYGh0dHA6Ly94eXouYWJjL3JvbGUvSW5jb21lU3RhdGVtZW50YC4gVGhlIGRpbWVuc2lvbmFsIHJlbGF0aW9ucyBhcmUgc29tZXdoYXQgc2ltaWxhciB0byBwcmVzZW50YXRpb24gcmVsYXRpb25zIGluIGZvcm0sIGJ1dCB3aXRoIGRpZmZlcmVudCBwcm9jZXNzaW5nIGluc3RydWN0aW9ucy4gVGhlIHJvb3QgZWxlbWVudCBpcyBhbHNvIGBJbmNvbWUgU3RhdGVtZW50IFtBYnN0cmFjdF1gIHRoYXQgaXMgbWVhbnQgdG8gZ3JvdXAgdG9nZXRoZXIgYWxsIEluY29tZSBzdGF0ZW1lbnQgaHlwZXJjdWJlcywgdGhlIG5ldHdvcmsgY2FuIGJlIGRlc2NyaWJlZCBpbiBhIHRhYmxlIGFzIGZvbGxvd3MgKGBAZnJvbWAgYW5kIGBAdG9gIHJlZmVycyB0byBsb2NhdG9ycyBpZHMpOiAgCmBgYHtyIGlzX2RlZl9uZXR3b3JrLCBlY2hvPUZBTFNFfQpuZXR3b3JrIDwtIHhtbDI6OnhtbF9maW5kX2FsbChpc19kZWYsJy4vLypbbG9jYWwtbmFtZSgpPSJkZWZpbml0aW9uQXJjIl0nKSAlPiUKICBtYXAoZnVuY3Rpb24oeCkgewogICAgYyh0YWc9eG1sMjo6eG1sX25hbWUoeCksIHhtbDI6OnhtbF9hdHRycyh4KSkKICB9KSAlPiUgYmluZF9yb3dzKCkgJT4lIGFycmFuZ2UoZnJvbSwgb3JkZXIpCgprbml0cjo6a2FibGUobmV0d29yaywgZXNjYXBlID0gRikgJT4lIGthYmxlRXh0cmE6OmthYmxlX2NsYXNzaWMoKSAlPiUgCiAgaHRtbHRvb2xzOjpIVE1MKCkgJT4lIGh0bWx0b29sczo6ZGl2KHN0eWxlPSJvdmVyZmxvdy14OmF1dG87d2hpdGUtc3BhY2U6IG5vd3JhcDsiKQpgYGAKCl9Ob3Rlc18gIAoKKiBgPGRlZmluaXRpb25BcmM+YCBpcyB1c2VkIHRvIGVzdGFibGlzaCBkaW1lbnNpb25hbCByZWxhdGlvbnNoaXBzLiAgCiogYGFyY3JvbGVzYCB1c2VkIGFyZSBkZWZpbmVkIGluIFhCUkwgRGltZW5zaW9ucyBzcGVjaWZpY2F0aW9ucy4KKiBgQGNsb3NlZGAgYW5kIGBAY29udGV4RWxlbWVudGAgb24gYDxkZWZpbml0aW9uQXJjPmAgcmVsYXRpb24gYmV0d2VlbiBgZXhhbXBsZV9TdGF0ZW1lbnRMaW5lSXRlbXNgIGFuZCBgZXhhbXBsZV9JbmNvbWVTdGF0ZW1lbnRUYWJsZWAgd2l0aCByb2xlIGBodHRwOi8veGJybC5vcmcvaW50L2RpbS9hcmNyb2xlL2FsbGAgYXJlIHVzZWQgdG8gc3BlY2lmeSB0aGF0IGFsbCB0YXhvbm9teS1kZWZpbmVkIGRpbWVuc2lvbnMgaW4gdGhlIGh5cGVyY3ViZSBtdXN0IGludGVyc2VjdCBvbiBhIGZhY3QgaW4gb3JkZXIgZm9yIHRoYXQgZmFjdCB0byBiZSBwYXJ0IG9mIHRoZSBoeXBlcmN1YmUsIGFuZCB0aGUgZGltZW5zaW9ucyBtdXN0IGJlIGBzZWdtZW50YCBkaW1lbnNpb25zIChpLmUuIGxpbmtlZCB0aHJvdWdoIGNvbnRleHQgc2VnbWVudCkuIAoqIGBAb3JkZXJgIGlzIHVzZWQgb24gYGRlZmluaXRpb25BcmNgIHRvIGRldGVybWluZSB0aGUgb3JkZXIgb2YgYXBwZWFyYW5jZSBvZiBjb25jZXB0IHdoZW4gcHJlc2VudGVkLiAgCgojIyMjIyBIaWVyYXJjaGljYWwgVmlldyAgCioqQSBoaWVyYXJjaGljYWwgdmlldyBvZiBwcmVzZW50YXRpb24gbGluayAoQ29uY2VwdHMgbGFiZWxzIGFyZSB1c2VkKSoqOiAKYGBge3IgaXNfZGVmX25ldHdvcmtfaGllciwgZWNobz1GQUxTRX0KCmxpc3QoCmMoJzEwMDAwIC0gU3RhdGVtZW50IC0gSW5jb21lIFN0YXRlbWVudCcsICcnLCAnQ29udGFpbmVyJyksCmMoJ0luY29tZSBTdGF0ZW1lbnQgW0Fic3RyYWN0XScsICcnLCAnUm9vdCcpLApjKCdTdGF0ZW1lbnQgW0xpbmUgSXRlbXNdJywgJ2RvbWFpbi1tZW1iZXInLCAnMScpLApjKCdJbmNvbWUgU3RhdGVtZW50IFtUYWJsZV0nLCAnYWxsJywgJzInKSwKYygnUHJvZHVjdCBBbmQgU2VydmljZSBbQXhpc10nLCAnaHlwZXJjdWJlLWRpbWVuc2lvbicsICczJyksCmMoJ1Byb2R1Y3QgQW5kIFNlcnZpY2UgW0RvbWFpbl0nLCAnZGltZW5zaW9uLWRvbWFpbicsICc0JyksCmMoJ1Byb2R1Y3QgW01lbWJlcl0nLCAnZG9tYWluLW1lbWJlcicsICc1JyksCmMoJ1NlcnZpY2UgW01lbWJlcl0nLCAnZG9tYWluLW1lbWJlcicsICc1JyksCmMoJ1JldmVudWUnLCAnZG9tYWluLW1lbWJlcicsICcyJyksCmMoJ0Nvc3Qgb2YgUmV2ZW51ZScsICdkb21haW4tbWVtYmVyJywgJzInKSwKYygnR3Jvc3MgUHJvZml0JywgJ2RvbWFpbi1tZW1iZXInLCAnMicpLApjKCdFeHBlbnNlcycsICdkb21haW4tbWVtYmVyJywgJzInKSwKYygnTmV0IFByb2ZpdCcsICdkb21haW4tbWVtYmVyJywgJzInKQoKKSAlPiUgbWFwKGZ1bmN0aW9uKHgpe25hbWVzKHgpIDwtIGMoJ0NvbmNlcHQgTGFibGUnLCAnYXJjcm9sZScsICdkZXB0aCcpOyByZXR1cm4oeCl9KSAlPiUgCiAgYmluZF9yb3dzKCkgJT4lIAprbml0cjo6a2FibGUoY29sLm5hbWVzID0gYyhwYXN0ZTAoJ0NvbmNlcHQgTGFiZWwnLCBrYWJsZUV4dHJhOjpmb290bm90ZV9tYXJrZXJfc3ltYm9sKDEpKSwnYXJjcm9sZScsICdkZXB0aCcpLCBhbGlnbiA9IGMoJ2wnLCAnbCcsICdyJyksIGVzY2FwZSA9IEYpICU+JSBrYWJsZUV4dHJhOjprYWJsZV9jbGFzc2ljKCkgJT4lIAogIGthYmxlRXh0cmE6OmFkZF9pbmRlbnQocG9zaXRpb25zID0gMiwgbGV2ZWxfb2ZfaW5kZW50ID0xICkgJT4lIAogIGthYmxlRXh0cmE6OmFkZF9pbmRlbnQocG9zaXRpb25zID0gMywgbGV2ZWxfb2ZfaW5kZW50ID0yICkgJT4lIAogIGthYmxlRXh0cmE6OmFkZF9pbmRlbnQocG9zaXRpb25zID0gYyg0LDk6MTMpLCBsZXZlbF9vZl9pbmRlbnQgPTMgKSAlPiUgCiAga2FibGVFeHRyYTo6YWRkX2luZGVudChwb3NpdGlvbnMgPSA1LCBsZXZlbF9vZl9pbmRlbnQgPTQpICU+JSAKICBrYWJsZUV4dHJhOjphZGRfaW5kZW50KHBvc2l0aW9ucyA9IDYsIGxldmVsX29mX2luZGVudCA9NSkgJT4lIAogIGthYmxlRXh0cmE6OmFkZF9pbmRlbnQocG9zaXRpb25zID0gYyg3LDgpLCBsZXZlbF9vZl9pbmRlbnQgPTYpICU+JSAKICBrYWJsZUV4dHJhOjpmb290bm90ZShzeW1ib2w9IkNvbmNlcHRzIHByZWZlcnJlZCBsYWJlbHMgYXJlIHVzZWQgaW4gdGhpcyB0YWJsZSIpCgoKYGBgCgojIyMjIEluc3RhbmNlIERvY3VtZW50ICAKSW5zdGFuY2UgZG9jdW1lbnQgaXMgd2hlcmUgY3VycmVudCByZXBvcnQgZGF0YSBpcyByZXBvcnRlZCB1c2luZyBYQlJMIHN5bnRheCAoW3NlZSBzZWN0aW9uIDMuNy4zLjRdKCNpbnMtZG9jKSkuIEluIG91ciBleGFtcGxlIHdlIGNhbiBhbmFseXplIHRoZSBjb21wb25lbnRzIG9mIG91ciBpbnN0YW5jZSBkb2N1bWVudCBhcyBmb2xsb3dzOihbc2VlIGluc3RhbmNlIGZpbGVdKHhtbF9maWxlcy9pbmNvbWVTdGF0ZW1lbnRFeGFtcGxlL2luc3RhbmNlLnhtbCl7dGFyZ2V0PV9ibGFua30pICAKCiMjIyMjIFJlZmVyZW5jZXMgIApJbiBvdXIgZXhhbXBsZSwgdGhlIGluc3RhbmNlIGRvY3VtZW50IGhhcyBvbmx5IG9uIHJlZmVyZW5jZSBgPHNjaGVtYVJlZj5gLCB3aGloIGlzIGEgbWFuZGF0b3J5IGVsZW1lbnQgdGhhdCBtdXN0IGV4aXN0IGF0bGVhc3Qgb25jZSBhcyBjaGlsZCB0byBgPHhicmw+YCBlbGVtZW50LgpgYGB7ciBleGFtcGxlX2luc3RfZG9jLCBlY2hvPUZBTFNFfQppbnN0IDwtIHhtbDI6OnJlYWRfeG1sKGhlcmU6OmhlcmUoJ2RvY3MnLCd4bWxfZmlsZXMvaW5jb21lU3RhdGVtZW50RXhhbXBsZS9pbnN0YW5jZS54bWwnKSkKCnJlZnMgPC0geG1sMjo6eG1sX2ZpbmRfYWxsKGluc3QsJy4vLypbY29udGFpbnMobG9jYWwtbmFtZSgpLCAiUmVmIildJykgJT4lCiAgbWFwKGZ1bmN0aW9uKHgpIHsKICAgIGModGFnPXhtbDI6OnhtbF9uYW1lKHgpLCB4bWwyOjp4bWxfYXR0cnMoeCkpCiAgfSkgJT4lIGJpbmRfcm93cygpCgprbml0cjo6a2FibGUocmVmcywgZXNjYXBlID0gRikgJT4lIAogIGthYmxlRXh0cmE6OmthYmxlX2NsYXNzaWMoKSAlPiUgCiAgaHRtbHRvb2xzOjpIVE1MKCkgJT4lIAogIGh0bWx0b29sczo6ZGl2KHN0eWxlPSJvdmVyZmxvdy14OmF1dG87d2hpdGUtc3BhY2U6IG5vd3JhcDsiKQoKYGBgCgojIyMjIyBjb250ZXh0cyAKQXMgbWVudGlvbmVkLCBgPGNvbnRleHQ+YCBpcyBhbiBlbGVtZW50IHVzZWQgb25seSBpbiBYQlJMIGluc3RhbmNlIGRvY3VtZW50LCBpdCBhY3RzIGFzIGEgY29udGFpbmVyIGZvciBzb21lIGNvcmUgZGltZW5zaW9uIGFuZCB0YXhvbm9teSBkZWZpbmVkIGRpbWVuc2lvbnMsIGFuZCBpdCBpcyByZWZlcmVuY2VkIGJ5IGZhY3RzIGluIGFuIGluc3RhbmNlIGRvY3VtZW50IHRvIGdpdmUgY29udGV4dHVhbCBtZWFuaW5nIHRvIHRoZSBmYWN0LiAgCgpJbiBvdXIgZXhhbXBsZSwgZm9sbG93aW5nIGNvbnRleHRzIHdlcmUgZGVmaW5lZCBpbiB0aGUgaW5zdGFuY2UgZG9jdW1lbnQ6CmBgYHtyIGV4YW1wbGVfaW5zdF9jb250ZXh0cywgZWNobz1GQUxTRX0KCmNvbnRleHRzIDwtIHhtbDI6OnhtbF9maW5kX2FsbChpbnN0LCcuLy8qW2xvY2FsLW5hbWUoKT0iY29udGV4dCJdJykgJT4lCiAgbWFwKGZ1bmN0aW9uKHgpIHsKICAgIGModGFnPXhtbDI6OnhtbF9uYW1lKHgpLCAKICAgICAgaWQ9eG1sMjo6eG1sX2F0dHIoeCwgJ2lkJyksCiAgICAgIGBFbnRpdHkgSWRlbnRpZmllcmA9IGFzLmNoYXJhY3Rlcih4bWwyOjp4bWxfZmluZF9maXJzdCh4LCAnLi8vKltsb2NhbC1uYW1lKCk9ImlkZW50aWZpZXIiXS90ZXh0KCknKSksCiAgICAgIGBFbnRpdHkgSWRlbnRpZmllciBTY2hlbWFgPWFzLmNoYXJhY3Rlcih4bWwyOjp4bWxfYXR0cih4bWwyOjp4bWxfZmluZF9maXJzdCh4LCAnLi8vKltsb2NhbC1uYW1lKCk9ImlkZW50aWZpZXIiXScpLCAnc2NoZW1lJykpLAogICAgICBgRW50aXR5IFNlZ21lbnQgRGltYD1hcy5jaGFyYWN0ZXIoeG1sMjo6eG1sX2F0dHIoeG1sMjo6eG1sX2ZpbmRfZmlyc3QoeCwgJy4vLypbbG9jYWwtbmFtZSgpPSJleHBsaWNpdE1lbWJlciJdJyksICdkaW1lbnNpb24nKSksCiAgICAgIGBFbnRpdHkgU2VnbWVudCBNZW1iZXJgPWFzLmNoYXJhY3Rlcih4bWwyOjp4bWxfZmluZF9maXJzdCh4LCAnLi8vKltsb2NhbC1uYW1lKCk9ImV4cGxpY2l0TWVtYmVyIl0vdGV4dCgpJykpLAogICAgICBgUGVyaW9kIHN0YXJ0RGF0ZWA9YXMuY2hhcmFjdGVyKHhtbDI6OnhtbF9maW5kX2ZpcnN0KHgsICcuLy8qW2xvY2FsLW5hbWUoKT0ic3RhcnREYXRlIl0vdGV4dCgpJykpLAogICAgICBgUGVyaW9kIGVuZERhdGVgPWFzLmNoYXJhY3Rlcih4bWwyOjp4bWxfZmluZF9maXJzdCh4LCAnLi8vKltsb2NhbC1uYW1lKCk9ImVuZERhdGUiXS90ZXh0KCknKSksCiAgICAgIGBQZXJpb2QgSW5zdGFudGA9YXMuY2hhcmFjdGVyKHhtbDI6OnhtbF9maW5kX2ZpcnN0KHgsICcuLy8qW2xvY2FsLW5hbWUoKT0iaW5zdGFudCJdL3RleHQoKScpKQogICAgICApCiAgfSkgJT4lIGJpbmRfcm93cygpCgprbml0cjo6a2FibGUoY29udGV4dHMsIGVzY2FwZSA9IEYpICU+JSAKICBrYWJsZUV4dHJhOjprYWJsZV9jbGFzc2ljKCkgJT4lIAogIGh0bWx0b29sczo6SFRNTCgpICU+JSAKICBodG1sdG9vbHM6OmRpdihzdHlsZT0ib3ZlcmZsb3cteDphdXRvO3doaXRlLXNwYWNlOiBub3dyYXA7IikKCmBgYApfTm90ZXNfICAKKiBFYWNoIGNvbnRleHQgbXVzdCBoYXZlIHVuaXF1ZSBJRC4gIAoqIEVhY2ggY29udGV4dCBtdXN0IGNvbnRhaW4gb25lIGA8ZW50aXR5PmAgZWxlbWVudCB0aGF0IGlkZW50aWZpZXMgdGhlIHJlcG9ydGluZyBlbnRpdHksIGA8ZW50aXR5PmAgZWxlbWVudCBtYXkgY29udGFpbiBhIHNlZ21lbnQgZWxlbWVudCB0aGF0IHJlZmVyZW5jZXMgYSBkaW1lbnNpb24gYW5kIGEgZG9tYWluIG1lbWJlciBmb3IgZGltZW5zaW9uYWwgcmVsYXRpb25zLiAgCiogRWFjaCBjb250ZXh0IG11c3QgaGF2ZSBhIGA8cGVyaW9kPmAgZWxlbWVudCB0aGF0IGlkZW50aWZpZXMgdGhlIGluc3RhbnQgb3IgZHVyYXRpb24gZm9yIGEgcmVwb3J0ZWQgZmFjdCwgYWxzbyBub3RlIHRoZXJlIGlzIGEgcGVyaW9kIHR5cGUgYGZvcmV2ZXJgIHVzZWQgZm9yIGZhY3RzIHRoYXQgZG8gbm90IGhhdmUgYSBzcGVjaWZpYyBwZXJpb2QgZGltZW5zaW9uLCBmb3IgZXhhbXBsZSwgdGhlIG5hbWUgb2YgdGhlIGZvdW5kZXIgb2YgYSBjb21wYW55IGNhbiBiZSBhIGZhY3QgdGhhdCBkb2VzIG5vdCBoYXZlIHNwZWNpZmljIHBlcmlvZC4gIAoKIyMjIyMgVW5pdHMgIApYQlJMIHNwZWNpZmljYXRpb24gcmVxdWlyZXMgYWxsIG51bWVyaWMgZmFjdHMgdG8gaGF2ZSBhIHVuaXQgb2YgbWVhc3VyZW1lbnQgKFtzZWUgWEJSTCBzcGVjaWZpY2F0aW9ucyBzZWN0aW9uIDQuNi4yXShodHRwczovL3d3dy54YnJsLm9yZy9TcGVjaWZpY2F0aW9uL1hCUkwtMi4xL1JFQy0yMDAzLTEyLTMxL1hCUkwtMi4xLVJFQy0yMDAzLTEyLTMxK2NvcnJlY3RlZC1lcnJhdGEtMjAxMy0wMi0yMC5odG1sI180LjYuMikpLiBJbiBvdXIgaW5zdGFuY2UgZG9jdW1lbnQsIGZvbGxvd2luZyB1bml0cyB3ZXJlIGRlY2xhcmVkIHRvIGJlIHJlZmVyZW5jZWQgYnkgZmFjdHM6ICAKYGBge3IgZXhhbXBsZV9pbnN0X3VuaXRzLCBlY2hvPUZBTFNFfQoKeHVuaXRzIDwtIHhtbDI6OnhtbF9maW5kX2FsbChpbnN0LCcuLy8qW2xvY2FsLW5hbWUoKT0idW5pdCJdJykgJT4lCiAgICBtYXAoZnVuY3Rpb24oeCkgewogICAgYyh0YWc9eG1sMjo6eG1sX25hbWUoeCksIHhtbDI6OnhtbF9hdHRycyh4KSwgCiAgICAgIG1lYXN1cmU9YXMuY2hhcmFjdGVyKHhtbDI6OnhtbF9maW5kX2ZpcnN0KHgsICcuLypbbG9jYWwtbmFtZSgpPSJtZWFzdXJlIl0vdGV4dCgpJykpLAogICAgICBgRGl2aWRlIE51bWVyYXRvcmAgPSBhcy5jaGFyYWN0ZXIoeG1sMjo6eG1sX2ZpbmRfZmlyc3QoeCwgJy4vLypbbG9jYWwtbmFtZSgpPSJ1bml0TnVtZXJhdG9yIl0vKltsb2NhbC1uYW1lKCk9Im1lYXN1cmUiXS90ZXh0KCknKSksCiAgICAgIGBEaXZpZGUgRGVub21pbmF0b3JgPWFzLmNoYXJhY3Rlcih4bWwyOjp4bWxfZmluZF9maXJzdCh4LCAnLi8vKltsb2NhbC1uYW1lKCk9InVuaXREZW5vbWluYXRvciJdLypbbG9jYWwtbmFtZSgpPSJtZWFzdXJlIl0vdGV4dCgpJykpCiAgICAgIAogICAgICApCiAgfSkgJT4lIGJpbmRfcm93cygpCgprbml0cjo6a2FibGUoeHVuaXRzLCBlc2NhcGUgPSBGKSAlPiUgCiAga2FibGVFeHRyYTo6a2FibGVfY2xhc3NpYygpICU+JSAKICBodG1sdG9vbHM6OkhUTUwoKSAlPiUgCiAgaHRtbHRvb2xzOjpkaXYoc3R5bGU9Im92ZXJmbG93LXg6YXV0bzt3aGl0ZS1zcGFjZTogbm93cmFwOyIpCgpgYGAKX05vdGU6XyBUaGUgdW5pdCByZWZlcmVuY2VkIGJ5IGEgZmFjdCBuZWVkcyB0byBiZSBjb21wYXRpYmxlIHdpdGggdGhlIHRoZSB0eXBlIG9mIHRoYXQgZmFjdCwgZm9yIGV4YW1wbGUgYEVhcm5pbmdzUGVyU2hhcmVgIGNvbmNlcHQgd2lsbCB1c3VhbGx5IGhhdmUgYSBgcGVyU2hhcmVJdGVtVHlwZWAgYW5kIHRoZSB1bml0IHNob3VsZCBiZSBhIHBlciBzaGFyZSBhbHNvLiAgCgojIyMjIyBGYWN0cyAKRGV0YWlscyBvZiBmYWN0cyBpbiB0aGUgaW5zdGFuY2UgaXMgYXMgZm9sbG93czogIApgYGB7ciBleGFtcGxlX2luc3RfZmFjdHMsIGVjaG89RkFMU0V9CmZhY3QgPC0gIHhtbDI6OnhtbF9maW5kX2FsbChpbnN0LCcuLypbbm90KGxvY2FsLW5hbWUoKT0idW5pdCIgb3IgbG9jYWwtbmFtZSgpPSJjb250ZXh0IiBvciBsb2NhbC1uYW1lKCk9InNjaGVtYVJlZiIgb3IgbG9jYWwtbmFtZSgpPSJmb290bm90ZUxpbmsiKV0nKSAlPiUgCiAgbWFwKGZ1bmN0aW9uKHgpIHsKICAgIGModGFnPXhtbDI6OnhtbF9uYW1lKHgpLCB4bWwyOjp4bWxfYXR0cnMoeCksIHZhbHVlPXhtbDI6OnhtbF90ZXh0KHgpKQogIH0pICU+JSBiaW5kX3Jvd3MoKQoKa25pdHI6OmthYmxlKGZhY3QsIGVzY2FwZSA9IEYpICU+JSAKICBrYWJsZUV4dHJhOjprYWJsZV9jbGFzc2ljKCkgJT4lIAogIGh0bWx0b29sczo6SFRNTCgpICU+JSAKICBodG1sdG9vbHM6OmRpdihzdHlsZT0ib3ZlcmZsb3cteDphdXRvO3doaXRlLXNwYWNlOiBub3dyYXA7IikKCmBgYApfTm90ZXMgb2YgZmFjdCBhdHRyaWJ1dGVzIGBAZGVjaW1hbGAgYW5kIGBAcHJlY2lzaW9uYDpfICAKCj5BIE51bWVyaWMgSXRlbSBNVVNUIGhhdmUgZWl0aGVyIGEgQHByZWNpc2lvbiBhdHRyaWJ1dGUgb3IgYSBAZGVjaW1hbHMgYXR0cmlidXRlIHVubGVzcyBpdCBpcyBvZiB0aGUgZnJhY3Rpb25JdGVtVHlwZSBvciBvZiBhIHR5cGUgdGhhdCBpcyBkZXJpdmVkIGJ5IHJlc3RyaWN0aW9uIGZyb20gZnJhY3Rpb25JdGVtVHlwZSBvciBoYXMgYSBuaWwgdmFsdWUsIGluIHdoaWNoIGNhc2UsIGl0IE1VU1QgTk9UIGhhdmUgZWl0aGVyIGEgQHByZWNpc2lvbiBhdHRyaWJ1dGUgb3IgYSBAZGVjaW1hbHMgYXR0cmlidXRlLiBgciB0dWZ0ZTo6cXVvdGVfZm9vdGVyKCctLS0gW1hCUkwgU3BlY2lmaWNhdGlvbnMgNC42LjNdKGh0dHBzOi8vd3d3Lnhicmwub3JnL1NwZWNpZmljYXRpb24vWEJSTC0yLjEvUkVDLTIwMDMtMTItMzEvWEJSTC0yLjEtUkVDLTIwMDMtMTItMzErY29ycmVjdGVkLWVycmF0YS0yMDEzLTAyLTIwLmh0bWwjXzQuNi4zKScpYCAgCgoqIGBAZGVjaW1hbGA6IFRoaXMgYXR0cmlidXRlIE1VU1QgYmUgYW4gaW50ZWdlciBvciB0aGUgdmFsdWUgIklORiIgdGhhdCBzcGVjaWZpZXMgdGhlIG51bWJlciBvZiBkZWNpbWFsIHBsYWNlcyB0byB3aGljaCB0aGUgdmFsdWUgb2YgdGhlIGZhY3QgcmVwcmVzZW50ZWQgbWF5IGJlIGNvbnNpZGVyZWQgYWNjdXJhdGUsIHBvc3NpYmx5IGFzIGEgcmVzdWx0IG9mIHJvdW5kaW5nIG9yIHRydW5jYXRpb24sIGEgbmVnYXRpdmUgaW50ZWdlciBtZWFucyB0aGF0IHRoZSB2YWx1ZSBpcyB0cnVuY2F0ZWQsIGZvciBleGFtcGxlIGlmIGBAZGVjaW1hbD0tNmAgdGhlbiB0aGUgdmFsdWUgaXMgaW4gTWlsbGlvbnMuIChbU2VlIFhCUkwgU3BlY2lmaWNhdGlvbnMgNC42LjVdKGh0dHBzOi8vd3d3Lnhicmwub3JnL1NwZWNpZmljYXRpb24vWEJSTC0yLjEvUkVDLTIwMDMtMTItMzEvWEJSTC0yLjEtUkVDLTIwMDMtMTItMzErY29ycmVjdGVkLWVycmF0YS0yMDEzLTAyLTIwLmh0bWwjXzQuNi41KSkuICAKKiBgQHByZWNpc2lvbmA6IFRoaXMgYXR0cmlidXRlIE1VU1QgYmUgYSBub24tbmVnYXRpdmUgaW50ZWdlciBvciB0aGUgc3RyaW5nICJJTkYiIHRoYXQgY29udmV5cyB0aGUgYXJpdGhtZXRpYyBwcmVjaXNpb24gb2YgYSBtZWFzdXJlbWVudC4gSWYgYSBudW1lcmljIGZhY3QgaGFzIGEgQHByZWNpc2lvbiBhdHRyaWJ1dGUgdGhhdCBoYXMgdGhlIHZhbHVlICJuIiB0aGVuIGl0IGlzIGNvcnJlY3QgdG8gIm4iIHNpZ25pZmljYW50IGZpZ3VyZXMgKFtTZWUgWEJSTCBTcGVjaWZpY2F0aW9ucyA0LjYuNF0oaHR0cHM6Ly93d3cueGJybC5vcmcvU3BlY2lmaWNhdGlvbi9YQlJMLTIuMS9SRUMtMjAwMy0xMi0zMS9YQlJMLTIuMS1SRUMtMjAwMy0xMi0zMStjb3JyZWN0ZWQtZXJyYXRhLTIwMTMtMDItMjAuaHRtbCNfNC42LjQpKS4gIAoKW0Fsc28gc2VlIHN1cHBvcnQgcmVjb21tZW5kYXRpb24gZm9yIHByZWNpc2lvbiBhbmQgZGVjaW1hbF0oaHR0cHM6Ly93d3cueGJybC5vcmcvV0dOL3ByZWNpc2lvbi1kZWNpbWFscy11bml0cy9XR04tMjAxNy0wMS0xMS9wcmVjaXNpb24tZGVjaW1hbHMtdW5pdHMtV0dOLTIwMTctMDEtMTEuaHRtbCkuIAoKIyMjIFhCUkwgVmFsaWRhdGlvbnsjeGJybC12YWxpZGF0aW9ufSAgCgojIyMjIFZhbGlkYXRpb24gaW4gWEJSTCBTcGVjaWZpY2F0aW9uICAKWEJSTCBTcGVjaWZpY2F0aW9ucyByZXF1aXJlcyB0aGF0IGBYQlJMIEluc3RhbmNlYCwgYFhCUkwgTGlua2Jhc2VzYCBhbmQgYFhCUkwgVGF4b25vbXkgU2NoZW1hYCBtdXN0IGNvbXBseSB3aXRoIHRoZSBzcGVjaWZpY2F0aW9ucywgYW5kIHRoaXMgY29tcGxpYW5jZSBpcyBlbnN1cmVkIHRocm91Z2ggYFZhbGlkYXRpb24gcHJvY2Vzc2AgWEJSTCBbc3BlY2lmaWNhdGlvbnMgc2VjdGlvbiAzLjRdKGh0dHBzOi8vd3d3Lnhicmwub3JnL1NwZWNpZmljYXRpb24vWEJSTC0yLjEvUkVDLTIwMDMtMTItMzEvWEJSTC0yLjEtUkVDLTIwMDMtMTItMzErY29ycmVjdGVkLWVycmF0YS0yMDEzLTAyLTIwLmh0bWwjXzMuNCkuIAoKTWFueSBvZiBYQlJMIHN5bnRheCBpcyBleHByZXNzZWQgdXNpbmcgWE1MIFNjaGVtYSwgYXMgYSByZXN1bHQsIGEgcGFydCBvZiB0aGUgdmFsaWRhdGlvbiBwcm9jZXNzIGNhbiBiZSBwZXJmb3JtZWQgdXNpbmcgWE1MIFNjaGVtYSB2YWxpZGF0aW9uLCBvdGhlciBwYXJ0cyBtdXN0IGJlIGhhbmRsZWQgYnkgb3RoZXIgdmFsaWRhdGlvbiB0ZWNobm9sb2dpZXMuICAKCiMjIyMgVHdvIGxheWVycyBvZiB2YWxpZGF0aW9uCkdlbmVyYWxseSBzcGVha2luZyB0aGVyZSBhcmUgdHdvIGxheWVycyBvZiB2YWxpZGF0aW9uLCBgQmFzaWMgVmFsaWRhdGlvbmAgYW5kIGBCdXNpbmVzcyBSdWxlcyB2YWxpZGF0aW9uYCBfKHRlcm1pbm9sb2d5IG1heSBkaWZmZXIgaGVyZSwgYnV0IG1lYW5pbmcgd2lsbCByZW1haW5zIHRoZSBzYW1lKV8uCgojIyMjIyBCYXNpYyBWYWlsZGF0aW9uICAKQ2hlY2tzIGZvciBzeW50YXggYW5kIFhCUkwgc3BlY2lmaWNhdGlvbnMgcnVsZXMgY29tcGxpYW5jZSwgdGhlIGJhc2ljIHZhbGlkYXRpb24gcnVsZXMgd2lsbCBiZSB0aGUgc2FtZSBpbiBhbGwgc2l0dWF0aW9ucywgc2luY2UgaXQganVzdCBjaGVja2luZyBmb3IgY29tcGxpYW5jZSB3aXRoIFhCUkwgc3BlY2lmaWNhdGlvbnMuIEJhc2ljIHZhbGlkYXRpb24gaW5jbHVkZXMgbWFueSBmYWNldHMgYXMgZm9sbG93czogIAoKKiBgU3ludGF4IFZhbGlkYXRpb25gOiBDaGVja3MgaWYgdmFsaWRpdHkgb2YgZm9ybWF0IGFuZCB2YWxpZGl0eSBhZ2FpbnN0IGEgc2NoZW1hLiAgCiogYERhdGEgVHlwZSBWYWxpZGF0aW9uYDogY2hlY2tzIHRoZSBkYXRhIHR5cGUgb2YgdGhlIHZhbHVlIG1hdGNoZXMgdGhlIGRhdGEgdHlwZSBvZiBpdHMgY29uY2VwdCBjb3JlIGRpbWVuc2lvbi4gRm9yIGV4YW1wbGUsIGVuc3VyaW5nIHRoYXQgc3RyaW5ncyBhcmUgbm90IHJlcG9ydGVkIGFnYWluc3QgY29uY2VwdHMgd2hpY2ggc2hvdWxkIHRha2UgbnVtZXJpYyB2YWx1ZXMuICAKKiBgQ29uY2VwdCBSZWxhdGlvbnNoaXAtYmFzZWQgVmFsaWRhdGlvbmA6IFRoZXNlIGFyZSB2YWxpZGF0aW9uIGJhc2VkIG9uIFhCUkwgbGlua3MsIGFzIGRlc2NyaWJlZCBpbiBfVERIIHNlY3Rpb24gNi4xLjMgcGFnZSA4N186ICAKCj5UaGVzZSBpbmNsdWRlLCBidXQgYXJlIG5vdCBsaW1pdGVkIHRvLCByZWxhdGlvbnNoaXBzIGRlZmluZWQgYnkgY2FsY3VsYXRpb24sIGRlZmluaXRpb24sIGFuZCBwcmVzZW50YXRpb24gbGlua2Jhc2VzLiBUaGUgcmVsYXRpb25zaGlwIGFyY3MgY29ubmVjdGluZyBjb25jZXB0cyBjYW4gYWlkIGRldmVsb3BlcnMgKGFuZCBwcmVwYXJlcnMpIGluIGVuc3VyaW5nIGJvdGggdGhlIHNlbWFudGljIGxvZ2ljIG9mIHRoZSByZWxhdGlvbnNoaXAgYW5kIHRoYXQgdGhlIGNvbmNlcHRzIGludm9sdmVkIGFyZSB1c2VkIHByb3Blcmx5LmByIHR1ZnRlOjpxdW90ZV9mb290ZXIoJy0tLSBbVERIIHNlY3Rpb24gNi4xLjMgcGFnZSA4N10oaHR0cHM6Ly94YnJsdXMuZ2l0aHViLmlvL2RvY3MvdGRoLmh0bWwpJylgICAKCiMjIyMjIEJ1c2luZXNzIFJ1bGVzIFZhbGlkYXRpb24KT24gdGhlIG90aGVyIGhhbmQgYEJ1c2luZXNzIFJ1bGVzIFZhbGlkYXRpb25gIGNoZWNrcyBmb3IgY29tcGxpYW5jZSB3aXRoIHJ1bGVzIHNwZWNpZmljIHRvIHRoZSB0YXhvbm9teSwgYW5kIHRob3NlIHdpbGwgZGlmZmVyIGRlcGVuZGluZyBvbiB0aGUgdGF4b25vbXkgYXV0aG9ycycgb2JqZWN0aXZlcyBhbmQgcnVsZXMuIFRoaXMgbWFrZXMgaXQgbmVjZXNzYXJ5IHRvIGNvbWUgdXAgd2l0aCBjdXN0b20gdmFsaWRhdGlvbnMgdGhhdCBjaGVja3MgZm9yIGNvbXBsaWFuY2Ugd2l0aCBzcGVjaWZpYyBidXNpbmVzcyBydWxlcy4gCgpDdXN0b20gcnVsZSB2YWxpZGF0aW9uIGNhbiBiZSBidWlsdCBpbnRvIHZhbGlkYXRpb24gc29mdHdhcmUsIGFzIGFuIGV4YW1wbGUsIGBBcmVsbGVgIGhhcyBtdWx0aXBsZSBwbHVnaW5zIHRoYXQgdmFsaWRhdGVzIGRpZmZlcmVudCBzZXRzIG9mIHNwZWNpZmljIGJ1c2luZXNzIHJ1bGVzLCBzdWNoIGFzIGBFZGdhciBGaWxpbmcgTWFudWFsIChFRk0pYCBydWxlcyAoU0VDIHJ1bGVzKSwgYElGUlNgIHJ1bGVzLCBgRXVycGVhbiBCYW5raW5nIEF1dGhvcml0eSAoRUJBKWAgcnVsZXMsIC4uLiBldGMuIAo8ZGl2Pgo8Y2VudGVyPgohW0FyZWxsZSBWYWxpZGF0aW9uIE9wdGlvbnNdKGByIGhlcmU6OmhlcmUoJ2RvY3MnLCAnaW1hZ2VzL2FyZWxsZURTVmFsaWRhdGlvbi5wbmcnKWApCjwvY2VudGVyPgo8cCBzdHlsZT0idGV4dC1hbGlnbjpjZW50ZXIiPgoqKkFyZWxsZSBWYWxpZGF0aW9uIE9wdGlvbnMqKgo8L3A+CjwvZGl2PgoKWEJSTCBwcm92aWRlcyBzdGFuZGFyZGl6ZWQgdG9vbHMgdG8gaGVscCBpbiBzZXR0aW5nIGN1c3RvbSBydWxlcywgdGhlc2UgYXJlIGBYQlJMIEZvcm11bGFlYCwgYW5kIGBYVUxFYCAoW2Jhc2VkIG9uIFhCUkwgRm9ybXVsYSBzcGVjaWZpY2F0aW9uc10oaHR0cHM6Ly9zcGVjaWZpY2F0aW9ucy54YnJsLm9yZy93b3JrLXByb2R1Y3QtaW5kZXgtZm9ybXVsYS1mb3JtdWxhLTEuMC5odG1sKSkuCgoqKlhCUkwgRm9ybXVsYSoqICAKWEJSTCBGb3JtdWxhIHNwZWNpZmljYXRpb25zIHByb3ZpZGUgWEJSTCBjb25zdHJ1Y3RzIHRoYXQgaW5zdHJ1Y3RzIFhCUkwgcHJvY2Vzc29yIHRvIHByZWZvcm0gY2VydGFpbiBwcm9jZWR1cmVzIG9uIGFuIFhCUkwgSW5zdGFuY2UuIFRESCBzZWN0aW9uIDYuMi4xIHBhZ2UgODggZGVzY3JpYmVzIFhCUkwgRm9ybXVsYSBhcyBmb2xsb3dzOiAgCgo+WEJSTCBmb3JtdWxhcyBwcm92aWRlIGEgc3RhbmRhcmRpemVkIG1ldGhvZCBmb3IgZGVmaW5pbmcgdmFsaWRhdGlvbiBydWxlcyBmb3IgWEJSTCByZXBvcnRzIHRoYXQgZ28gYmV5b25kIHdoYXQgaXMgcHJvdmlkZWQgdGhyb3VnaCBjYWxjdWxhdGlvbnMgYW5kIG90aGVyIGNvbmNlcHQgcmVsYXRpb25zaGlwcy4gVGhyb3VnaCBmb3JtdWxhcywgdGhlIHZhbGlkYXRpb24gcnVsZXMgY2FuIGJlIGVtYmVkZGVkIGluIHRoZSB0YXhvbm9teSBpdHNlbGYuIFRoaXMgYWxsb3dzIHRoZSB0YXhvbm9teSB0byBiZSBlYXNpbHkgZGlzc2VtaW5hdGVkIHdpdGggaXRzIHZhbGlkYXRpb24gcnVsZXMsIHdoaWNoIHJlZHVjZXMgdGhlIGNoYW5jZSBmb3IgcHJlcGFyZXJzIHRvIG1pc2ludGVycHJldCB0aGVtIG9yIGhhdmUgZGlmZmljdWx0eSBsb2NhdGluZyB0aGVtLiBYQlJMIGZvcm11bGEgcnVsZXMgYXJlIHBsYWNlZCBpbiB0aGVpciBvd24gbGlua2Jhc2UsIG9mdGVuIHRlcm1lZCB0aGUgYXNzZXJ0aW9uIG9yIGZvcm11bGEgbGlua2Jhc2UuIFhCUkwgc29mdHdhcmUgY2FwYWJsZSBvZiByZWFkaW5nIGFuZCBpbnRlcnByZXRpbmcgdGhpcyBsaW5rYmFzZSBjYW4gYXBwbHkgdGhlIHJ1bGVzIGFuZCBkaXNwbGF5IHRoZSByZXN1bHRzIHRvIHByZXBhcmVycy5gciB0dWZ0ZTo6cXVvdGVfZm9vdGVyKCctLS0gW1RESCBzZWN0aW9uIDYuMi4xIHBhZ2UgODhdKGh0dHBzOi8veGJybHVzLmdpdGh1Yi5pby9kb2NzL3RkaC5odG1sKScpYCAKClNvIGluIGFkZGl0aW9uIHRvIHRoZSBsaW5rYmFzZXMgd2UgdGFsa2VkIGFib3V0IHByZXZpb3VzbHksIGEgdGF4b25vbXkgY2FuIGhhdmUgYSBgRm9ybXVsYSBMaW5rYmFzZWAuIFhCUkwgZm9ybXVsYSBjYW4gZG8gZm91ciB0aGluZ3MgKGZvdXIgcHJvY2Vzc2luZyBtb2RlbHMpOiAgCgoqIGBWYWx1ZSBhc3NlcnRpb25gOiBDaGVja3MgZmFjdCB2YXJpYWJsZSBhZ2FpbnN0IHNvbWUgY3JpdGVyaWEsIGZvciBleGFtcGxlLCBDYXNoIGJhbGFuY2UgaXMgZ3JlYXRlciB0aGFuIHplcm8uICAKKiBgRXhpc3RlbmNlIEFzc2VydGlvbmA6IENoZWNrcyBmb3IgdGhlIGV4aXN0ZW5jZSBmb3Igc3BlY2lmaWMgZmFjdCBleGlzdCBpbiBhbiBYQlJMIEluc3RhbmNlLCBmb3IgZXhhbXBsZSwgd2hlbiB0aGVyZSBpcyBhIHJ1bGUgdG8gcmVwb3J0IGEgc3BlY2lmaWMgZmFjdCwgc3VjaCBhcyBjb21wYW55IGlkZW50aWZpY2F0aW9uIG51bWJlci4gIAoqIGBGb3JtdWxhYDogRm9ybXVsYXMgYXJlIGNvbnN0cnVjdHMgaW4gYSBmb3JtdWxhIGxpbmtiYXNlIHRoYXQgY2F1c2UgcHJvZHVjdGlvbiBvZiBmYWN0IGl0ZW1zLCBmb3IgZXhhbXBsZSBjYWxjdWxhdGUgbGlxdWlkaXR5IHJhdGlvLiBUaGlzIHVzZWZ1bCBpbiBkYXRhIGV4dHJhY3Rpb24gZnJvbSBhbiBpbnN0YW5jZSBkb2N1bWVudCBldmVuIHRob3VnaCB0aGlzIGlzIG5vdCB0aGUgaW50ZW5kZWQgdXNlIG9mIGZvcm11bGEuICAKKiBgQ29uc2lzdGVuY3kgQXNzZXJ0aW9uYDogQSBjb25zaXN0ZW5jeSBhc3NlcnRpb24gc3BlY2lmaWVzIGhvdyB0byBkZXRlcm1pbmUgd2hldGhlciBhbiBvdXRwdXQgZmFjdCwgcHJvZHVjZWQgYnkgdGhlIGFzc29jaWF0ZWQgZm9ybXVsYSBtYXRjaGVzIHJlcG9ydGVkIGZhY3RzLCBmb3IgZXhhbXBsZSBpcyBMaWFiaWxpdGllcyBcJDEwIGFuZCBFcXVpdHkgaXMgXCQ1LCB3ZSBleHBlY3QgQXNzZXRzIHRvIGJlIFwkMTUgKGVxdWFsaXR5IGlzIGRldGVybWluZWQgd2l0aGluIGEgdG9sZXJhbmNlIG1hcmdpbikuICAKCltGaWd1cmVzIDIgYW5kIDMgaW4gWEJSTCBGb3JtdWxhIE92ZXJ2aWV3XShodHRwczovL3d3dy54YnJsLm9yZy93Z24veGJybC1mb3JtdWxhLW92ZXJ2aWV3L3B3ZC0yMDExLTEyLTIxL3hicmwtZm9ybXVsYS1vdmVydmlldy13Z24tcHdkLTIwMTEtMTItMjEuaHRtbCNmaWd1cmUtZm9ybXVsYS1wcm9jZXNzaW5nLW1vZGVscykgc3VtbWFyaXplcyB0aGUgcHJvY2Vzc2luZyBtb2RlbHMgYXMgZm9sbG93czogIAo8ZGl2Pgo8Y2VudGVyPgohW0ZvdXIgcHJvY2Vzc2luZyBtb2RlbHMgZWZmZWN0c10oYHIgaGVyZTo6aGVyZSgnZG9jcycsICdpbWFnZXMvcHJvY2Vzc2luZy1tb2RlbHMucG5nJylgKQo8L2NlbnRlcj4KPHAgc3R5bGU9InRleHQtYWxpZ246Y2VudGVyIj4KKipGb3VyIHByb2Nlc3NpbmcgbW9kZWxzIGVmZmVjdHMgKipbc291cmNlIFhCUkwgRm9ybXVsYSBvdmVydmlld10oaHR0cHM6Ly93d3cueGJybC5vcmcvd2duL3hicmwtZm9ybXVsYS1vdmVydmlldy9wd2QtMjAxMS0xMi0yMS94YnJsLWZvcm11bGEtb3ZlcnZpZXctd2duLXB3ZC0yMDExLTEyLTIxLmh0bWwjZmlndXJlLWZvcm11bGEtcHJvY2Vzc2luZy1tb2RlbHMpCjwvcD4KPC9kaXY+CjxkaXY+CjxjZW50ZXI+CiFbRXhhbXBsZXMgZm9yIGVhY2ggcHJvY2Vzc2luZyBtb2RlbF0oYHIgaGVyZTo6aGVyZSgnZG9jcycsICdpbWFnZXMvcHJvY2Vzc2luZy1tb2RlbC1leGFtcGxlcy5wbmcnKWApCjwvY2VudGVyPgo8cCBzdHlsZT0idGV4dC1hbGlnbjpjZW50ZXIiPgoqKkV4YW1wbGVzIGZvciBlYWNoIHByb2Nlc3NpbmcgbW9kZWwgKipbc291cmNlIFhCUkwgRm9ybXVsYSBvdmVydmlld10oaHR0cHM6Ly93d3cueGJybC5vcmcvd2duL3hicmwtZm9ybXVsYS1vdmVydmlldy9wd2QtMjAxMS0xMi0yMS94YnJsLWZvcm11bGEtb3ZlcnZpZXctd2duLXB3ZC0yMDExLTEyLTIxLmh0bWwjZmlndXJlLWZvcm11bGEtcHJvY2Vzc2luZy1tb2RlbHMpCjwvcD4KPC9kaXY+CgpgSUZSUyBUYXhvbm9teWAgaXMgYW4gZXhhbXBsZSBvZiBhIHRheG9ub215IHRoYXQgdXNlcyBmb3JtdWxhIHRvIHZhbGlkYXRlIGN1c3RvbSBydWxlcyBmb3IgWEJSTCBmaWxpbmdzIGJhc2VkIG9uIHRoZSBJRlJTIFRheG9ub215LiBbSUZSUyBmb3JtdWxhIGxpbmtiYXNlIGd1aWRlIGZvdW5kIGhlcmVdKGh0dHBzOi8vd3d3LmlmcnMub3JnL2NvbnRlbnQvZGFtL2lmcnMvc3RhbmRhcmRzL3RheG9ub215L2dlbmVyYWwtcmVzb3VyY2VzL2Zvcm11bGEtZG9jdW1lbnRhdGlvbi0yMDIwLnBkZikuICAKCioqWFVMRSoqICAKWFVMRSBpcyBhbiBleHByZXNzaW9uIHN5bnRheCB0aGF0IGFsbG93cyB0aGUgcXVlcnlpbmcgb2YgWEJSTCByZXBvcnRzIGFuZCB0YXhvbm9taWVzIHVzaW5nIGEgWFVMRSBwcm9jZXNzb3IsIGl0IGlzIGRlc2NyaWJlZCBpbiAqKltUREggc2VjdGlvbiA2LjIuMiBwYWdlIDk5XSoqIGFzIGZvbGxvd3M6ICAKCj5EZXZlbG9wZWQgYnkgWEJSTCBVUywgWFVMRSBpcyBhbiBleHByZXNzaW9uIHN5bnRheCB0aGF0IGFsbG93cyB0aGUgcXVlcnlpbmcgb2YgWEJSTCByZXBvcnRzIGFuZCB0YXhvbm9taWVzIHVzaW5nIGEgWFVMRSBwcm9jZXNzb3IuIFRoZSBwcmltYXJ5IHB1cnBvc2Ugb2YgWFVMRSBpcyB0byBwcm92aWRlIGEgdXNlci1mcmllbmRseSBzeW50YXggdG8gcXVlcnkgYW5kIG1hbmlwdWxhdGUgWEJSTCBkYXRhLiBUaGlzIGNhbiBiZSBoZWxwZnVsIGluIGEgbXVsdGl0dWRlIG9mIHdheXMsIGluY2x1ZGluZyBhaWRpbmcgY29uc3VtZXJzIGluIHF1aWNrbHkgZXh0cmFjdGluZyBzcGVjaWZpYyBmYWN0cyBmcm9tIHJlcG9ydHMgYW5kIHN1cHBvcnRpbmcgZGV2ZWxvcGVycyBpbiBxdWVyeWluZyBYQlJMIHRheG9ub21pZXMgdG8gcmVuZGVyIHRoZW0gYXMgb3BlbiBBUEkgc2NoZW1hcyBvciBhcyBpWEJSTCBmb3Jtcy5gciB0dWZ0ZTo6cXVvdGVfZm9vdGVyKCctLS0gW1RESCBzZWN0aW9uIDYuMi4yIHBhZ2UgOTldKGh0dHBzOi8veGJybHVzLmdpdGh1Yi5pby9kb2NzL3RkaC5odG1sKScpYCAgCgpFeGFtcGxlIG9mIHRoZSBzeW50YXggZm9yIGBYVUxFYDoKYGBgYysrCm5hbWVzcGFjZSBodHRwOi8veHl6LmFiYy9JbmNvbWVTdGF0ZW1lbnRFeGFtcGxlCgovLyBDYWxjdWxhdGUgZ3Jvc3MgbWFyZ2luIGJ5IGRpbWVuc2lvbgpvdXRwdXQgZ3Jvc3MtbWFyZ2luCiRncm9zcy1wcm9maXQ9QEdyb3NzUHJvZml0Q29uY2VwdAokcmV2ZW51ZSA9IEBSZXZlbnVlQ29uY2VwdAokZGltcyA9ICRyZXZlbnVlLmRpbWVuc2lvbnMtZXhwbGljaXQKJGxhYiA9IGlmIChsZW5ndGgoJGRpbXMudmFsdWVzLmxhYmVsKE5vbmUsJ2VuJykudGV4dCk+MCkKCQkgKCRkaW1zLnZhbHVlcy5sYWJlbChOb25lLCdlbicpLnRleHQpWzFdCgkJZWxzZSAiVG90YWwiCgkJCi8vIFByaW50IG91dHB1dAoiR3Jvc3MgTWFyZ2luIGZvciB7JHJldmVudWUucGVyaW9kfSB7JGxhYn0gPSB7cm91bmQoICRncm9zcy1wcm9maXQgLyAkcmV2ZW51ZSwgMyApfSUiCgovLyBRdWVyeSBhbGwgZmFjdHMgd2l0aCB2YWx1ZSBtb3JlIHRoYW4gRUdQIDIwMDAKb3V0cHV0IGJpZy1mYWN0cwp7QGNvbmNlcHQgd2hlcmUgJGZhY3QgPiAyMDAwfQpgYGAKCltGdWxsIGd1aWRlIGZvciBYVUxFIGlzIGF2YWlsYWJsZSBoZXJlXShodHRwczovL3hicmwudXMvd3AtY29udGVudC91cGxvYWRzLzIwMTkvMTAvWHVsZVYxLjEucGRmKS4gIAoKCiMjIyBYQlJMIFRhYmxlIExpbmtiYXNlICAKWEJSTCBbVGFibGUgTGlua2Jhc2Ugc3BlY2lmaWNhdGlvbnNdKGh0dHBzOi8vc3BlY2lmaWNhdGlvbnMueGJybC5vcmcvc3BlYy1ncm91cC1pbmRleC10YWJsZS1saW5rYmFzZS5odG1sKSBwcm92aWRlcyBhIG1lY2hhbmlzbSBmb3IgdGF4b25vbXkgYXV0aG9ycyB0byBkZWZpbmUgYSB0YWJ1bGFyIGxheW91dCBvZiBmYWN0cy4gVGhlIHJlc3VsdGluZyB0YWJsZXMgY2FuIGJlIHVzZWQgZm9yIGJvdGggcHJlc2VudGF0aW9uIGFuZCBkYXRhIGVudHJ5LiAgCgpUYWJsZSBsaW5rYmFzZSBpcyBsb2dpY2FsbHkgc2ltaWxhciB0byBQcmVzZW50YXRpb24gTGlua2Jhc2UgYnV0IHdpdGggYSBsb3QgbW9yZSBmZWF0dXJlcy4gSXQgYWxsb3dzIGZvciBhIHN0YW5kYXJkIHdheSBmb3IgZGVmaW5pbmcgdmlld3Mgb2YgY29uY2VwdHMgZGVmaW5lZCBpbiBhIHRheG9ub215LCBhcyBtZW50aW9uZWQgaW4gdGhlIHNwZWNpZmljYXRpb24gb3ZlcnZpZXc6IAoKPlRhYmxlIGxpbmtiYXNlIGVuYWJsZXMgdGhlIGRlZmluaXRpb24gb2YgdGFibGVzIHdpdGggbXVsdGlwbGUgYXhlcy4gVGhlIGNvbXBvbmVudHMgb2YgdGhlc2UgYXhlcyBhcmUgbm90IGxpbWl0ZWQgdG8gaW5kaXZpZHVhbCBpdGVtczsgaW5zdGVhZCwgdGhleSBjYW4gYmUgZGVmaW5lZCBpbiB0ZXJtcyBvZiBhIGNvbWJpbmF0aW9uIG9mIGRpbWVuc2lvbnMsIHRpbWUgcGVyaW9kIHJlZmVyZW5jZXMsIHVuaXRzLCBlbnRpdGllcyBvciBhbnkgb3RoZXIgcHJvcGVydHkgdGhhdCBjYW4gYmUgdXNlZCB0byBpZGVudGlmeSB0aGUgZmluYW5jaWFsIGZhY3RzIHJlcHJlc2VudGVkIGJ5IHRheG9ub21pZXMuYHIgdHVmdGU6OnF1b3RlX2Zvb3RlcignLS0tIFtYQlJMIFRhYmxlIExpbmtiYXNlIE92ZXJ2aWV3XShodHRwczovL3d3dy54YnJsLm9yZy93Z24vdGFibGUtbGlua2Jhc2Utb3ZlcnZpZXcvd2duLTIwMTQtMDMtMTgvdGFibGUtbGlua2Jhc2Utb3ZlcnZpZXctd2duLTIwMTQtMDMtMTguaHRtbCNpbnRyb2R1Y3Rpb24pJylgICAKCiMjIyMgVGFibGUgTW9kZWxzICAKVGFibGUgbGlua2Jhc2Ugc3BlY2lmaWNhdGlvbnMgZGVmaW5lIDMgbW9kZWxzIGBTdHJ1Y3R1cmFsIE1vZGVsYCwgYERlZmluaXRpb24gTW9kZWxgIGFuZCBgbGF5b3V0IG1vZGVsYC5gRGVmaW5pdGlvbiBNb2RlbGAgZGVmaW5lcyB0aGUgY29udGVudCBvZiBhIHRhYmxlIGluIHRlcm1zIG9mIGNvbmNlcHRzIGFuZCBhc3BlY3RzIHVzaW5nIHJlbGF0aW9uc2hpcHMgaW4gRFRTLCBEZWZpbml0aW9uIE1vZGVsIGlzIHRyYW5zZm9ybWVkIHRvIFN0cnVjdHVyYWwgbW9kZWwgdGhyb3VnaCBwcm9jZXNzIG9mIGByZXNvbHV0aW9uYCwgdGhlIHN5bnRheCBwcm92aWRlcyBhIGRpcmVjdCBkZXNjcmlwdGlvbiBvZiB0aGUgZGVmaW5pdGlvbiBtb2RlbC4gYFN0cnVjdHVyYWwgTW9kZWxgIGRlZmluZXMgdGhlIHRoZSBzaGFwZSBvZiB0aGUgdGFibGUgaW4gdGVybXMgb2YgaGllcmFyY2hpY2FsIGJyZWFrZG93bnMgb2YgZmFjdCBzcGFjZSwgd2hpbGUgIGBsYXlvdXQgTW9kZWxgIGlzIHRoZSBkaXJlY3QgcmVwcmVzZW50YXRpb24gb2YgdGhlIHN0cnVjdHVyZSBhbmQgY29udGVudC4gCgo8ZGl2Pgo8Y2VudGVyPgohW1RhYmxlIE1vZGVsc10oYHIgaGVyZTo6aGVyZSgnZG9jcycsICdpbWFnZXMvdGFibGUtbW9kZWxzLnBuZycpYCkKPC9jZW50ZXI+CjxwIHN0eWxlPSJ0ZXh0LWFsaWduOmNlbnRlciI+CioqVGFibGUgTW9kZWxzICoqWyhTb3VyY2U6IFRhYmxlIExpbmtiYXNlIE92ZXJ2aWV3IDEuMCldKGh0dHBzOi8vd3d3Lnhicmwub3JnL3dnbi90YWJsZS1saW5rYmFzZS1vdmVydmlldy93Z24tMjAxNC0wMy0xOC90YWJsZS1saW5rYmFzZS1vdmVydmlldy13Z24tMjAxNC0wMy0xOC5odG1sI2ZpZ3VyZS1tb2RlbHMpCjwvcD4KPC9kaXY+CgpUaGUgYmFzaWMgaWRlYSBvZiBYQlJMIFRhYmxlIGlzIHRoYXQgaXQgZmlsdGVycyBhbmQgcHJlc2VudHMgZmFjdHMgaW4gc3BlY2lmaWMgbGF5b3V0IGFjY29yZGluZyB0byB0aGUgdGFibGUgZGVmaW5pdGlvbiBhbmQgc3RydWN0dXJlLiAKClRlcm1zIHJlbGV2YW50IGZvciB0aGUgWEJSTCB0YWJsZSBsaW5rYmFzZTogIAoKYEZhY3QgU291cmNlYDogQSBmYWN0IHNvdXJjZSBpcyBhIGNvbnRhaW5lciBmb3IgWEJSTCBmYWN0cywgZm9yIGV4YW1wbGUgaXQgbWF5YmUgYW4gZXhpc3RpbmcgWEJSTCBpbnN0YW5jZSwgZmFjdCBzb3VyY2UgY29udGFpbnMgdGhlIHNldCBvZiBmYWN0cyB0aGF0IGFyZSB0byBiZSBjb25zaWRlcmVkIGZvciBpbmNsdXNpb24gaW4gdGhlIHRhYmxlLiAgCgpgRG9tYWluIG9mIGEgVGFibGVgOiBJcyB0aGUgcmVzdHJpY3RlZCBmYWN0IHNwYWNlIGRlZmluZWQgYnkgdGhlIGNvbWJpbmF0aW9uIG9mIGNvbnN0cmFpbnRzIGZyb20gYWxsIG9mIHRoZSB0YWJsZSdzIGJyZWFrZG93bnMsIGFsb25nIHdpdGggYW55IGFkZGl0aW9uYWwgZ2xvYmFsIGNvbnN0cmFpbnRzIHNwZWNpZmllZCB1c2luZyB0YWJsZSBmaWx0ZXJzLgoKYEF4aXNgOiBBbiBheGlzIGRlZmluZXMgYW4gb3JkZXJlZCBtYXBwaW5nIG9mIFhCUkwgZmFjdCBzcGFjZSBvbnRvIGEgbGluZS4gIAoKICAqIFRoZSB4LWF4aXMgU0hPVUxEIGJlIGludGVycHJldGVkIGFzIGEgaG9yaXpvbnRhbCBhcnJhbmdlbWVudCBvZiBjb2x1bW5zIGluIGEgdGFibGUuIENvbHVtbnMgTUFZIGJlIGxhaWQgb3V0IGZyb20gbGVmdCB0byByaWdodCwgb3IgcmlnaHQgdG8gbGVmdCwgYWNjb3JkaW5nIHRvIHRoZSBsYW5ndWFnZSBjb252ZW50aW9ucy4gIAogICogVGhlIHktYXhpcyBTSE9VTEQgYmUgaW50ZXJwcmV0ZWQgYXMgYSB2ZXJ0aWNhbCBwcm9ncmVzc2lvbiBvZiByb3dzIGluIGEgdGFibGUuIFJvd3MgU0hPVUxEIGJlIGxhaWQgb3V0IGZyb20gdG9wIHRvIGJvdHRvbS4gIAogICogVGhlIHotYXhpcyBNQVkgYmUgaW50ZXJwcmV0ZWQgYXMgbXVsdGlwbGUgdHdvLWRpbWVuc2lvbmFsIHRhYmxlcyBhbmQgTUFZIGJlIGxhaWQgb3V0IG9uIGEgdHdvLWRpbWVuc2lvbmFsIGRpc3BsYXkgYnkgcHJlc2VudGluZyBlYWNoIHRhYmxlIGluIHNlcmllcyBvciBieSBzdXBwbHlpbmcgY29udHJvbHMgZm9yIHRoZSB1c2VyIHRvIHNlbGVjdCB0aGUgZGF0YSB0byBiZSBwcmVzZW50ZWQuICAKCmBCcmVha2Rvd25gOiBBIGJyZWFrZG93biBkZWZpbmVzIGEgbG9naWNhbGx5IGRpc3RpbmN0IGJyZWFrZG93biBvZiB0aGUgZmFjdCBzcGFjZSBieSBzZXRzIG9mIGNvbnN0cmFpbnRzLiBBIGJyZWFrZG93biBpcyBtb2RlbGVkIGFzIGFuIG9yZGVyZWQgdHJlZSBvZiBgc3RydWN0dXJhbCBub2Rlc2AuIEVhY2ggb2YgdGhlc2Ugbm9kZXMgY29udHJpYnV0ZXMgemVybyBvciBtb3JlIGNvbnN0cmFpbnRzIHRvIHRoZSBicmVha2Rvd24uICAKCiAgKiBBIGNsb3NlZCBicmVha2Rvd24gaXMgZGVmaW5lZCBhcyBhIGJyZWFrZG93biB3aG9zZSBzZXF1ZW5jZSBvZiBjb25zdHJhaW50IHNldHMgY2FuIGJlIGRldGVybWluZWQgaW5kZXBlbmRlbnRseSBvZiB0aGUgZmFjdHMgdG8gYmUgaW5jbHVkZWQuICAKICAqIEFuIG9wZW4gYnJlYWtkb3duIGlzIGRlZmluZWQgYXMgYSBicmVha2Rvd24gd2hvc2Ugc2VxdWVuY2Ugb2YgY29uc3RyYWludCBzZXRzIGNoYW5nZXMgZHluYW1pY2FsbHkgd2l0aCB0aGUgZmFjdHMgaW5jbHVkZWQgYW5kIHRodXMgY2Fubm90IGJlIGNvbXBsZXRlbHkgZGV0ZXJtaW5lZCB3aXRob3V0IGtub3dsZWRnZSBvZiB0aG9zZSBmYWN0cy4gIAogIApgU3RydWN0dXJhbCBOb2RlYDogQSBzdHJ1Y3R1cmFsIG5vZGUgaXMgYSBub2RlIGluIGEgYnJlYWtkb3duIHRyZWUuIEVhY2ggbm9kZSBjb250cmlidXRlcyB6ZXJvIG9yIG1vcmUgY29uc3RyYWludHMgdG8gdGhlIGJyZWFrZG93bi4gIAoKICAqIEEgY2xvc2VkIHN0cnVjdHVyYWwgbm9kZSBpcyBhIHN0cnVjdHVyYWwgbm9kZSB3aXRoIGNvbnN0cmFpbnRzIGZ1bGx5IGRldGVybWluZWQgYnkgaXRzIGRlZmluaXRpb24gYW5kIHRoZSBEVFMuICAKICAqIEFuIG9wZW4gc3RydWN0dXJhbCBub2RlIGlzIGEgc3RydWN0dXJhbCBub2RlIHRoYXQgZG9lcyBub3QgZnVsbHkgZGVmaW5lIGFzcGVjdCB2YWx1ZSBjb25zdHJhaW50cyBhbmQgZG9lcyBub3QgbmVjZXNzYXJpbHkgaGF2ZSBhIG9uZS10by1vbmUgcmVsYXRpb25zaGlwIHdpdGggbGF5b3V0IG5vZGVzIHByb2R1Y2VkIGR1cmluZyByZXNvbHV0aW9uLgoKYERlZmluaXRpb24gbm9kZWA6IEEgZGVmaW5pdGlvbiBub2RlIGlzIGEgZGVmaW5pdGlvbiBvZiB6ZXJvIG9yIG1vcmUgc3RydWN0dXJhbCBub2RlcyBpbiB0aGUgc3RydWN0dXJhbCBtb2RlbC4gIAoKICAqIEEgY2xvc2VkIGRlZmluaXRpb24gbm9kZSBpcyBhIGRlZmluaXRpb24gbm9kZSB3aGljaCByZXNvbHZlcyB0byBvbmUgb3IgbW9yZSBjbG9zZWQgc3RydWN0dXJhbCBub2Rlcy4gIAogICogQW4gb3BlbiBkZWZpbml0aW9uIG5vZGUgaXMgYSBkZWZpbml0aW9uIG5vZGUgd2hpY2ggcmVzb2x2ZXMgdG8gYW4gb3BlbiBzdHJ1Y3R1cmFsIG5vZGUuICAKICAKYFRhYmxlYDogcmVwcmVzZW50cyBhIGJyZWFrZG93biBvZiBYQlJMIGZhY3Qgc3BhY2UgZm9yIHRoZSBwdXJwb3NlIG9mIGRlZmluaW5nIGEgcmVmZXJlbmNlIHZpZXcgb2YgWEJSTCBkYXRhLiAgCgogICogQSBjbG9zZWQgdGFibGUgaXMgZGVmaW5lZCBhcyBhIHRhYmxlIHRoYXQgY29uc2lzdHMgb25seSBvZiBjbG9zZWQgYnJlYWtkb3ducy4gIAogICogQW4gb3BlbiB0YWJsZSBpcyBkZWZpbmVkIGFzIGEgdGFibGUgd2hvc2UgY29uc3RpdHVlbnQgYnJlYWtkb3ducyBpbmNsdWRlIGF0IGxlYXN0IG9uZSBvcGVuIGJyZWFrZG93bi4gIAogIAojIyMjIFRhYmxlIGxpbmtiYXNlIGNvbXBvbmVudHMgClRhYmxlIGxpbmtiYXNlIGRlZmluZSBhIHRhYmxlIGluIHRlcm1zIG9mIHJlbGF0aW9uc2hpcHMgYmV0d2VlbiBjb21wb25lbnRzIGRlZmluZWQgaW4gdGFibGUgbGlua2Jhc2UuIFRhYmxlIGxpbmtiYXNlIHVzZXMgYGdlbmVyaWMgbGlua2AgYXMgdGhlIGNvbnRhaW5lciBsaW5rLCB3aXRoaW4gdGhlIGdlbmVyaWMgbGluaywgYSB0YWJsZSBpcyBkZWZpbmVkIHVzaW5nIHJlbGF0aW9uc2hpcHMgYGFyY3NgIGFuZCBlbGVtZW50cyBkZWZpbmVkIGluIHRhYmxlIGxpbmtiYXNlLiAgCgpUYWJsZSBsaW5rYmFzZSB1c2VzIGxpbmsgc3ludGF4IHRvIGRlZmluZSBhIHRhYmxlIGVsZW1lbnQsIHRoZW4gbGlua3MgdGhhdCB0YWJsZSB0byBhbiB4IChyb3dzKSBhbmQgeSAoY29sdW1ucykgYXhlcywgZWFjaCBheGlzIGlzIHRoZW4gbGlua2VkIHRvIGEgYnJlYWtkb3duIGVsZW1lbnQsIHdoaWNoIGFjdHMgYSBjb250YWluZXIgZm9yIGZpbHRlciBlbGVtZW50cyB0aGF0IGZpbHRlcnMgdGhlIGZhY3RzIHRvIGJlIHNob3duIGluIHRoZSB0YWJsZS4gVGhpcyBsb2dpYyBjYW4gYmUgdmlzdWFsaXplZCBhcyBmb2xsb3dzOiAgCgoKPGRpdj4KPGNlbnRlcj4KIVtUYWJsZSBEZWZpbml0aW9uIE1vZGVsXShgciBoZXJlOjpoZXJlKCdkb2NzJywgJ2ltYWdlcy9kZWZpbml0aW9uLW1vZGVsLnBuZycpYCkKPC9jZW50ZXI+CjxwIHN0eWxlPSJ0ZXh0LWFsaWduOmNlbnRlciI+CioqVGFibGUgRGVmaW5pdGlvbiBNb2RlbCAqKlsoU291cmNlOiBUYWJsZSBMaW5rYmFzZSBTcGVjaWZpY2F0aW9ucyAxLjApXShodHRwczovL3d3dy54YnJsLm9yZy9TcGVjaWZpY2F0aW9uL3RhYmxlLWxpbmtiYXNlL1JFQy0yMDE0LTAzLTE4K2VycmF0YS0yMDE4LTA3LTE3L3RhYmxlLWxpbmtiYXNlLVJFQy0yMDE0LTAzLTE4K2NvcnJlY3RlZC1lcnJhdGEtMjAxOC0wNy0xNy5odG1sI2ZpZ3VyZS14YnJsLWRlZmluaXRpb24tbW9kZWwpCjwvcD4KPC9kaXY+CgoKRm9sbG93aW5nIGlzIGEgdGFibGUgbGlua2Jhc2UgdGhhdCBjcmVhdGVzIGEgdGFibGUgZnJvbSB0aGUgSW5jb21lIFN0YXRlbWVudCBleGFtcGxlLCB0aGUgdGFibGUgbWVtaWNzIGV4YWN0bHkgdGhlIGluY29tZSBzdGF0ZW1lbnQ6KFtzZWUgVGFibGUgTGlua2Jhc2UgZmlsZV0oeG1sX2ZpbGVzL2luY29tZVN0YXRlbWVudEV4YW1wbGUvaXNfdGFiLnhtbCl7dGFyZ2V0PV9ibGFua30pIApgYGB7ciB0YWJfbGIsIGVjaG89RkFMU0V9IApmbl9Db2RlQ2h1bmtPdXQobGFuZyA9ICdYTUwnLCBGaWxlID0gaGVyZTo6aGVyZSgnZG9jcycsJ3htbF9maWxlcy9pbmNvbWVTdGF0ZW1lbnRFeGFtcGxlL2lzX3RhYi54bWwnKSkKYGBgCgpXaGVuIHRoZSBgaW5jb21lIHN0YXRlbWVudCBpbnN0YW5jZWAgaXMgbG9hZGVkIGJ5IGFyZWxsZSBhbmQgYSB0YWJsZSBpcyByZW5kZXJlZCBhcyBIVE1MLCBpdCB0aGUgb3V0cHV0IGlzIFtoZXJlXSh4bWxfZmlsZXMvaW5jb21lU3RhdGVtZW50RXhhbXBsZS9vdXRwdXQtdGFibGUuaHRtbCl7dGFyZ2V0PV9ibGFua30uICAKCiMjIyBJbmxpbmUgWEJSTCAoaVhCUkwpICAKCltJbmxpbmUgWEJSTCBzcGVjaWZpY2F0aW9uc10oaHR0cHM6Ly9zcGVjaWZpY2F0aW9ucy54YnJsLm9yZy9zcGVjLWdyb3VwLWluZGV4LWlubGluZS14YnJsLmh0bWwpIHByb3ZpZGUgYSBtZWNoYW5pc20gZm9yIGVtYmVkZGluZyBYQlJMIHRhZ3MgaW4gSFRNTCBkb2N1bWVudHMgKHhIVE1MIGlzIHJlcXVpcmVkIGJ5IHRoZSBzcGVjaWZpY2F0aW9ucykuIFRoaXMgYWxsb3dzIHRoZSBYQlJMIGJlbmVmaXRzIG9mIHRhZ2dlZCBkYXRhIHRvIGJlIGNvbWJpbmVkIHdpdGggYSBodW1hbi1yZWFkYWJsZSBwcmVzZW50YXRpb24gb2YgYSByZXBvcnQsIHdoaWNoIGlzIHVuZGVyIHRoZSBjb250cm9sIG9mIHRoZSBwcmVwYXJlci4gCgpUaGUgSW5saW5lIFhCUkwgYERvY3VtZW50IFNldGAgaXMgYSBncm91cCBvZiBvbmUgb3IgbW9yZSBJbmxpbmUgWEJSTCBEb2N1bWVudHMgd2hpY2ggd2hlbiBjb21wcmlzaW5nIHN1ZmZpY2llbnQgbWV0YWRhdGEgcmVzdWx0cyBpbiBvbmUgb3IgbW9yZSBUYXJnZXQgRG9jdW1lbnRzIHdoZW4gdHJhbnNmb3JtZWQgYWNjb3JkaW5nIHRvIHRoZSBtYXBwaW5nIHJ1bGVzIHByZXNjcmliZWQgaW4gaW5saW5lWEJSTCBzcGVjaWZpY2F0aW9ucy4KCkluIHByYWN0aWNhbCB0ZXJtcywgaW5saW5lIFhCUkwgc3BlY2lmaWNhdGlvbnMgZGVmaW5lIFhCUkwgZWxlbWVudHMgaW4gdGhlIG5hbWVzcGFjZSBge2h0dHA6Ly93d3cueGJybC5vcmcvMjAxMy9pbmxpbmVYQlJMfWAsIHRoZXNlIGVsZW1lbnRzIGFyZSB1c2VkIGZyb20gd2l0aGluIHhIVE1MIGFuZCBmb3JtIHRoZSBtZXRhZGF0YSBuZWNlc3NhcnkgdG8gZGVzY3JpYmUgYW4gWEJSTCBpbnN0YW5jZSBkb2N1bWVudCB3aGljaCBpcyByZWZlcnJlZCB0byBhcyBgVGFyZ2V0IERvY3VtZW50YCwgaW4gdGhpcyBjb250ZXh0IGEgYFRhcmdldCBEb2N1bWVudGAgaXMgZGVmaW5lZCBhcyBgdmFsaWQgWEJSTCBpbnN0YW5jZSBkb2N1bWVudCByZXByZXNlbnRlZCBieSBtZXRhZGF0YSBpbiB0aGUgSW5saW5lIFhCUkwgRG9jdW1lbnQgU2V0YC4gVGhlIHRhcmdldCBkb2N1bWVudCBuZWVkIG5vdCB0byBwaHlzaWNhbGx5IGV4aXN0LCBidXQgdGhlIG1ldGFkYXRhIG11c3QgYmUgc3VmZmljaWVudCB0byBjb25zdHJ1Y3QgdGhlIHRhcmdldCBkb2N1bWVudCB3aGVuIHRyYW5zZm9ybWVkIGFjY29yZGluZyB0byB0aGUgbWFwcGluZyBydWxlcyBwcmVzY3JpYmVkIGluIGlubGluZSBYQlJMIFNwZWNpZmljYXRpb24uIAoKPGRpdj4KPGNlbnRlcj4KIVtJbmxpbmUgWEJSTF0oYHIgaGVyZTo6aGVyZSgnZG9jcycsICdpbWFnZXMvaW5saW5lWEJSTC5wbmcnKWApCjwvY2VudGVyPgo8cCBzdHlsZT0idGV4dC1hbGlnbjpjZW50ZXIiPgoqKklubGluZSBYQlJMKioKPC9wPgo8L2Rpdj4KCiMjIyMgSW5saW5lIFhCUkwgZWxlbWVudHMgIApBcyBtZW50aW9uZWQsIFhCUkwgYW5kIElubGluZSBYQlJMIGluc3RhbmNlIGRvY3VtZW50cyBhcmUgdXN1YWxseSBjcmVhdGVkIHVzaW5nIHNwZWNpYWxpemVkIHNvZnR3YXJlIHRoYXQgdGFrZXMgY2FyZSBvZiB0aGUgZm9ybSBhbmQgc3l0YW54IGFuZCBwcm92aWRlIHRvb2xzIHRvIGhlbHAgYXV0aG9ycywgYnV0IGl0IGlzIGltcG9ydGFudCB0byBoYXZlIHNvbWUga25vd2xlZGdlIG9mIHRoZSBlbGVtZW50cyBkZWZpbmVkIHdpdGhpbiB0aGUgc3BlY2lmaWNhdGlvbnMuCgpJbmxpbmUgWEJSTCBzcGVjaWZpY2F0aW9ucyBkZWZpbmUgZWxlbWVudHMgaW4gbmFtZXNwYWNlIGB7eGk9aHR0cDovL3d3dy54YnJsLm9yZy8yMDEzL2lubGluZVhCUkx9YDoKYGBge3IgaXhicmxfZWxlbWVudHMsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIHJlc3VsdHM9J2FzaXMnfQpkYXRhLmZyYW1lKAogIGVsZW1lbnQ9YygiaXg6Y29udGludWF0aW9uIiwKICAgICAgICAgICAgIml4OmRlbm9taW5hdG9yIiwKICAgICAgICAgICAgIml4OmV4Y2x1ZGUiLAogICAgICAgICAgICAiaXg6Zm9vdG5vdGUiLAogICAgICAgICAgICAiaXg6ZnJhY3Rpb24iLAogICAgICAgICAgICAiaXg6aGVhZGVyIiwKICAgICAgICAgICAgIml4OmhpZGRlbiIsCiAgICAgICAgICAgICJpeDpub25GcmFjdGlvbiIsCiAgICAgICAgICAgICJpeDpub25OdW1lcmljIiwKICAgICAgICAgICAgIml4Om51bWVyYXRvciIsCiAgICAgICAgICAgICJpeDpyZWZlcmVuY2VzIiwKICAgICAgICAgICAgIml4OnJlbGF0aW9uc2hpcCIsCiAgICAgICAgICAgICJpeDpyZXNvdXJjZXMiLAogICAgICAgICAgICAiaXg6dHVwbGUiKSwKICBkZXNjcmlwdGlvbj1jKAogICAgJ3VzZWQgdG8gZGVmaW5lIGRhdGEgdGhhdCBpcyB0byBiZSB0cmVhdGVkIGFzIHBhcnQgb2YgaXg6Zm9vdG5vdGUgb3IgaXg6bm9uTnVtZXJpYy4nLAogICAgJ2Rlbm90ZXMgYW4gWEJSTCBkZW5vbWluYXRvciBlbGVtZW50OyB1c2VkIHdpdGggaXg6ZnJhY3Rpb24gbWFwcGVkIGVsZW1lbnQuIHNlZSBpeDpmcmFjdGlvbicsCiAgICAndXNlZCB0byBlbmNhcHN1bGF0ZSBkYXRhIHRoYXQgaXMgdG8gYmUgZXhjbHVkZWQgZnJvbSB0aGUgcHJvY2Vzc2luZyBvZiBpeDpmb290bm90ZSBvciBpeDpub25OdW1lcmljIGVsZW1lbnRzLCBUaGUgcHVycG9zZSBvZiB0aGUgaXg6ZXhjbHVkZSBlbGVtZW50IGlzIHRvIHByZXZlbnQgdGV4dCBjb250ZW50IGZyb20gYmVpbmcgaW5jbHVkZWQgaW4gdGhlIHt2YWx1ZX0gcHJvcGVydGllcyBvZiBpeDpmb290bm90ZSBvciBpeDpub25OdW1lcmljLiBJdCBoYXMgbm8gb3RoZXIgdXNlLicsCiAgICAncmVwcmVzZW50cyB0aGUgbGluazpmb290bm90ZSBlbGVtZW50IGluIFhCUkwgaW5zdGFuY2UsJywKICAgICdkZW5vdGVzIGFuIFhCUkwgZmFjdCB3aGljaCBpcyBhbiBlbGVtZW50IG9mIHR5cGUsIG9yIGRlcml2ZWQgZnJvbSB0eXBlLCBmcmFjdGlvbkl0ZW1UeXBlOycsCiAgICAnY29udGFpbnMgdGhlIG5vbi1kaXNwbGF5ZWQgcG9ydGlvbnMgb2YgdGhlIFRhcmdldCBEb2N1bWVudCwgaXQgY29udGFpbnMgeGk6aGlkZGVuLicsCiAgICAndXNlZCB0byBjb250YWluIFhCUkwgZmFjdHMgdGhhdCBhcmUgbm90IHRvIGJlIGRpc3BsYXllZCBpbiB0aGUgYnJvd3NlcicsCiAgICAnZWxlbWVudCBkZW5vdGVzIGFuIFhCUkwgbnVtZXJpYyBpdGVtIHdoaWNoIGlzIGFuIGVsZW1lbnQgd2hpY2ggaXMgbm90IG9mIHR5cGUsIG5vciBkZXJpdmVkIGZyb20gdHlwZSwgZnJhY3Rpb25JdGVtVHlwZS4nLAogICAgJ2VsZW1lbnQgZGVub3RlcyBhbiBYQlJMIG5vbi1udW1lcmljIGl0ZW0nLAogICAgJ2Rlbm90ZXMgYW4gWEJSTCBudW1lcmF0b3IgZWxlbWVudCcsCiAgICAndXNlZCB0byBjb250YWluIHJlZmVyZW5jZSBlbGVtZW50cyB3aGljaCBhcmUgcmVxdWlyZWQgYnkgYSBnaXZlbiBUYXJnZXQgRG9jdW1lbnQgKHNjaGVtYVJlZiwgbGluYmFzZVJlZiknLAogICAgJ3VzZWQgdG8gZGVmaW5lIHJlbGF0aW9uc2hpcHMgYmV0d2VlbiBYQlJMIGZhY3RzIG9yIGJldHdlZW4gWEJSTCBmYWN0cyBhbmQgZm9vdG5vdGUgcmVzb3VyY2VzLiBUaGUgdHlwZSBvZiByZWxhdGlvbnNoaXAgaXMgaW5kaWNhdGVkIGJ5IHRoZSB2YWx1ZSBvZiB0aGUgYXJjcm9sZSBhdHRyaWJ1dGUsIHN1Y2ggYXMgaHR0cDovL3d3dy54YnJsLm9yZy8yMDA5L2FyY3JvbGUvZmFjdC1leHBsYW5hdG9yeUZhY3QgZm9yIGZhY3QgdG8gZmFjdCByZWxhdGlvbnNoaXBzJywKICAgICd1c2VkIHRvIGNvbnRhaW4gcmVzb3VyY2UgZWxlbWVudHMgd2hpY2ggYXJlIHJlcXVpcmVkIGJ5IG9uZSBvciBtb3JlIFRhcmdldCBEb2N1bWVudHMgKGl4OnJlbGF0aW9uc2hpcCwgbGluazpyb2xlUmVmLCBsaW5rOmFyY3JvbGVSZWYsIHhicmxpOmNvbnRleHQsIHhicmxpOnVuaXQpJywKICAgICdkZW5vdGVzIGFuIFhCUkwgdHVwbGUnCiAgKQopICU+JSAKICBrbml0cjo6a2FibGUoJ2h0bWwnKSAlPiUgCiAga2FibGVFeHRyYTo6a2FibGVfY2xhc3NpYyhmdWxsX3dpZHRoID0gRikgJT4lIAogIGthYmxlRXh0cmE6OnJvd19zcGVjKDE6MTQsIGV4dHJhX2NzcyA9ICJib3JkZXItYm90dG9tOiAxcHggc29saWQgbGlnaHRncmF5IikgJT4lIAogIGh0bWx0b29sczo6SFRNTCgpICMlPiUgCiAgIyBodG1sdG9vbHM6OmRpdihzdHlsZT0ib3ZlcmZsb3cteDphdXRvO3doaXRlLXNwYWNlOiBub3dyYXA7IikKCmBgYAoKVGhlIGJlc3Qgd2F5IHRvIHVuZGVyc3RhbmQgd2hhdCBpbmxpbmUgWEJSTCBpcywgaXMgYWN0dWFsbHkgdG8gc2VlIGl0LCBiZWxvdyBhcmUgdGhyZWUgbGlua3MgdG8gb25lIGFuZCB0aGUgc2FtZSBpbmxpbmUgWEJSTCBmaWxpbmcgZm9yIGBNaWNyb3NvZnRgIGZvcm0gYDEwLVFgIGZvciB0aGUgOSBtb250aHMgZW5kZWQgYDIwMjEtMDMtMzFgOiAgCgoqIFtVc3VhbCBGb3JtIHdpdGhvdXQgaW5saW5lIFhCUkwgVmlld2VyXShodHRwczovL3d3dy5zZWMuZ292L0FyY2hpdmVzL2VkZ2FyL2RhdGEvNzg5MDE5LzAwMDE1NjQ1OTAyMTAyMDg5MS9tc2Z0LTEwcV8yMDIxMDMzMS5odG0pe3RhcmdldD1fYmxhbmt9ICAKKiBXaXRoIHRoZSBhYm92ZSBsaW5rIG9wZW4sIHJpZ2h0IGNsaWNrIGFueXdoZXJlIGFuZCBzZWxlY3QgYFZpZXcgcGFnZSBzb3VyY2VgIChpZiB1c2luZyBDaHJvbWUpLCB0aGF0IHdpbGwgc2hvdyB0aGUgc291cmNlIGNvZGUgZm9yIHRoZSBmb3JtLCBub3QgdGhlIHVzZSBvZiB0aGUgYWJvdmUgZWxlbWVudHMgZW1iZWRkZWQgaW4gdGhlIHhIVE1MLiAgICAKKiBbRm9ybSB2aWV3ZWQgdXNpbmcgRURHQVIgaW5saW5lIFhCUkwgdmlld2VyXShodHRwczovL3d3dy5zZWMuZ292L2l4P2RvYz0vQXJjaGl2ZXMvZWRnYXIvZGF0YS83ODkwMTkvMDAwMTU2NDU5MDIxMDIwODkxL21zZnQtMTBxXzIwMjEwMzMxLmh0bSl7dGFyZ2V0PV9ibGFua30gIAoKIyMjIyBJbmxpbmUgWEJSTCBUcmFuc2Zvcm1hdGlvbnMgIApJbmxpbmUgWEJSTCBpcyBlbWJlZGRlZCBpbiBhIGh1bWFuIHJlYWRhYmxlIGRvY3VtZW50LCB3aGljaCBtZWFucyB0aGF0IHRoZSB2YWx1ZXMgYXJlIGFsc28gaW5jbHVkZWQgaW4gdGhlIHRoZSBkb2N1bWVudCBpbiBodW1hbiByZWFkYWJsZSBmb3JtIHRoYXQgbWlnaHQgbm90IGNvbXBseSB3aXRoIHRoZSBkYXRhIHR5cGVzIGZvcm1hdHMgcmVxdWlyZWQgYnkgWEJSTCBzcGVjaWZpY2F0aW9ucywgWEJSTCB0cmFuc2Zvcm1hdGlvbnMgZGVhbHMgd2l0aCB0aGlzIHByb2JsZW0gYnkgYXNzb2NpYXRpbmcgdGhlIGh1bWFuIHJlYWRhYmxlIHZhbHVlcyB3aXRoIGEgZm9ybWF0IHRoYXQgY2FuIGJlIHRyYW5zbGF0ZWQgdG8gYSBtYWNoaW5lIHJlYWRhYmxlIHZhbHVlLCB0aGlzIGlzIGRvbmUgdXNpbmcgdGhlIGBAZm9ybWF0YCBhdHRyaWJ1dGUgZm9yIGVhY2ggWEJSTCBmYWN0IGluIGFuIGlubGluZSBYQlJMIGRvY3VtZW50LiAKCkZvciBleGFtcGxlLCBpZiB3ZSBoYXZlIGEgZGF0ZSB2YWx1ZSBvZiBgTWFyLiAzMSwgMjAyMWAsIHRoaXMgZGF0ZSBpcyBodW1hbiByZWFkYWJsZSBidXQgZG9lcyBub3QgY29tcGx5IHdpdGggWEJSTCByZXF1aXJlZCBmb3JtYXQgZm9yIGRhdGUgYElTTyA4NjAxYCAoWVlZLU1NLUREKSwgc28gYW4gYEBmb3JtYXQ9aXh0OmRhdGVtb250aGRheXllYXJlbmAgaXMgYWRkIHRvIHRoZSBmYWN0IGFuZCB0aGVuIFhCUkwgcHJvY2Vzc29yIHdpbGwga25vdyBob3cgdG8gdHJhbnNsYXRlIHRoaXMgZGF0ZSB0byB0aGUgYElTTyA4NjAxYCBmb3JtYXQuIEJlbG93IGlzIHRoZSBhYm92ZSBleGFtcGxlIHByb2Nlc3NlZCBieSBgQXJlbGxlIFRyYW5zZm9ybWF0aW9uIFRlc3RlciBwbHVnaW5gOiAgCgo8ZGl2Pgo8Y2VudGVyPgohW0lubGluZSBYQlJMIFRyYW5zZm9ybWF0aW9uc10oYHIgaGVyZTo6aGVyZSgnZG9jcycsICdpbWFnZXMvYXJlbGxlVHJhbnNmb3JtLnBuZycpYCkKPC9jZW50ZXI+CjxwIHN0eWxlPSJ0ZXh0LWFsaWduOmNlbnRlciI+CioqSW5saW5lIFhCUkwgVHJhbnNmb3JtYXRpb25zKioKPC9wPgo8L2Rpdj4gIAoKKipUcmFuc2Zvcm1hdGlvbnMgUmVnaXN0cmllcyoqICAKW1RoZSBYQlJMIFRyYW5zZm9ybWF0aW9uIFJlZ2lzdHJ5XShodHRwczovL3NwZWNpZmljYXRpb25zLnhicmwub3JnL3NwZWMtZ3JvdXAtaW5kZXgtaW5saW5lLXhicmwuaHRtbCkgY29udGFpbnMgdGhlIHJ1bGVzIGFuZCBtZXRyaWNzIGJ5IHdoaWNoIHRyYW5zZm9ybWF0aW9ucyBpbiBJbmxpbmUgWEJSTCBhcmUgcGVyZm9ybWVkLiBUaGVzZSBydWxlcyBkZXNjcmliZSBob3cgZGVzY3JpcHRpdmUgdGV4dCBpbiBJbmxpbmUgWEJSTCBkb2N1bWVudHMgY2FuIGJlIHJlcHJlc2VudGVkIGFzIFhCUkwgZGF0YSB0eXBlcy4gIAoKRm9sbG93aW5nIGlzIGEgc2FtcGxlIG9mIHRyYW5zZm9ybWF0aW9ucyBmcm9tIFt0cmFuc2Zvcm1hdGlvbiByZWdpc3RyeSAyXShodHRwczovL3d3dy54YnJsLm9yZy9TcGVjaWZpY2F0aW9uL2lubGluZVhCUkwtdHJhbnNmb3JtYXRpb25SZWdpc3RyeS9SRUMtMjAxMS0wNy0zMStlcnJhdGEtMjAxOS0wNC0xNy9pbmxpbmVYQlJMLXRyYW5zZm9ybWF0aW9uUmVnaXN0cnktUkVDLTIwMTEtMDctMzErY29ycmVjdGVkLWVycmF0YS0yMDE5LTA0LTE3Lmh0bWwpOiAgCmBgYHtyIHRyYW5zX3JlZywgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KaHRtbHRhYjo6aHRtbHRhYignaHR0cHM6Ly93d3cueGJybC5vcmcvU3BlY2lmaWNhdGlvbi9pbmxpbmVYQlJMLXRyYW5zZm9ybWF0aW9uUmVnaXN0cnkvUkVDLTIwMTEtMDctMzErZXJyYXRhLTIwMTktMDQtMTcvaW5saW5lWEJSTC10cmFuc2Zvcm1hdGlvblJlZ2lzdHJ5LVJFQy0yMDExLTA3LTMxK2NvcnJlY3RlZC1lcnJhdGEtMjAxOS0wNC0xNy5odG1sJywgd2hpY2ggPSAnLy8qW0BpZD0iZXgtdHJhbnNmb3JtYXRpb25zIl0vL3RhYmxlJylbMTo1LCAxOjJdICU+JSAKICAgIGtuaXRyOjprYWJsZSgnaHRtbCcscm93Lm5hbWVzID0gRkFMU0UpICU+JSBrYWJsZUV4dHJhOjprYWJsZV9jbGFzc2ljXzIoZnVsbF93aWR0aCA9IEYpICU+JSAKICBodG1sdG9vbHM6OkhUTUwoKSAlPiUgCiAgaHRtbHRvb2xzOjpkaXYoc3R5bGU9Im92ZXJmbG93LXg6YXV0bzt3aGl0ZS1zcGFjZTogbm93cmFwOyIpCgpgYGAKCiMjIyBTdHlsZSBHdWlkZXMgIApTdHlsZSBndWlkZXMgYXJlIG9uZSBvZiB0aGUgc3VwcG9ydGluZyBkb2N1bWVudHMgdGhhdCBhY2NvbXBhbnkgYW4gWEJSTCBUYXhvbm9teS4gU3R5bGUgZ3VpZGVzIGhlbHBzCWluCWFjaGlldmluZwljb25zaXN0ZW5jeQl3aGlsZQljcmVhdGluZywJbWFpbnRhaW5pbmcJb3IJZXh0ZW5kaW5nIHRoZQl0YXhvbm9teS4gIAoKU3R5bGUgZ3VpZGVzIHNldCB0aGUgcnVsZXMgZm9yIGNvbnNpc3RlbnQgbGFuZ3VhZ2UgYW5kIG5hbWluZyBjb252ZW50aW9ucywgc3R5bGVzIGFuZCBvcmdhbml6YXRpb24uIEZvciBleGFtcGxlIGEgc3R5bGUgZ3VpZGUgcnVsZSBteSBzZXQgdGhlIHdoZXRoZXIgdG8gdXNlIGNhbWVsIGNhc2Ugb3IgcGFzY2FsIGNhc2UsIHdoYXQgY2hhcmFjdGVycyBhcmUgYWxsb3dlZCBvciBkaXNhbGxvd2VkIGluIGxhYmVscywgYW5kIHNvIG9uLiAgIAoKKipFeGFtcGxlcyBvZiBzdHlsZSBndWlkZXM6KiogIAoKKiBbKipJRlJTIFRheG9ub215IFN0eWxlIEd1aWRlKiogXyhUaGUgSUZSUyBUYXhvbm9teSBBcmNoaXRlY3R1cmUgLSBBcHBlbmRpeCBBIC0gcGFnZSAzMylfXShodHRwczovL3d3dy5pZnJzLm9yZy9jb250ZW50L2RhbS9pZnJzL3N0YW5kYXJkcy90YXhvbm9teS9nZW5lcmFsLXJlc291cmNlcy9pZnJzLXRheG9ub215LWFyY2hpdGVjdHVyZS9pZnJzLXRheG9ub215LWFyY2hpdGVjdHVyZS0yMDIwLnBkZil7dGFyZ2V0PV9ibGFua30gIAoKKiBbKipYQlJMIFVTIFN0eWxlIEd1aWRlKipdKGh0dHBzOi8veGJybC51cy93cC1jb250ZW50L3VwbG9hZHMvMjAxNy8wOS9zdHlsZS1ndWlkZS0yMDE3MDkwNy5wZGYpe3RhcmdldD1fYmxhbmt9CgoKIyMjIFRocmVlIFRheG9ub21pZXMgIApJbiB0aGlzIEZpbmFsIHNlY3Rpb24gd2UgbG9vayBhdCB0aHJlZSBkaWZmZXJlbnQgdGF4b25vbWllcyBhbmQgaGF2ZSBvdmVydmlldyBvbiB0aGUgY2hvaWNlcyB0aGUgdGF4b25vbXkgYXV0aG9ycyBtYWRlLCB0aGVyZSB0aHJlZSB0YXhvbm9taWVzIGFyZTogIAoKKiAqKklGUlMgVGF4b25vbXkgKDIwMjApKioKKiAqKlVTIEdBQVAgVGF4b25vbXkgKDIwMjEpKiogIAoqICoqRXVyb3BlYW4gQmFua2luZyBBdXRob3JpdHkgKEVCQSkgVGF4b25vbXkgKEZyYW1ld29yayAzLjEpKiogIAoKYGBge3IgdGhyZWVfdGF4b25vbXlfdGFibGUsIGVjaG89RkFMU0UsIHJlc3VsdHM9J2FzaXMnfSAgCgp0aXRsZXMgPC0gYygKICAnJywKICAnSUZSUyBUYXhvbm9teSAoMjAyMCknLAogICdVUyBHQUFQIFRheG9ub215ICgyMDIxKScsCiAgJ0VCQSBUYXhvbm9teSAoRnJhbWV3b3JrIDMuMSknCikKCmwgPC0gbGlzdCgKICBjKAogICAgYDFgPSdMaW5rJywKICAgIGAyYD1odG1sdG9vbHM6OmEoJ0lGUlMgVGF4b25vbXkgUmVzb3VyY2VzJywgaHJlZj0naHR0cHM6Ly93d3cuaWZycy5vcmcvaXNzdWVkLXN0YW5kYXJkcy9pZnJzLXRheG9ub215LyNnZW5lcmFsLXJlc291cmNlcycsIHRhcmdldD0nX2JsYW5rJykgJT4lIGFzLmNoYXJhY3RlcigpLAogICAgYDNgPWh0bWx0b29sczo6YSgnRkFTQiAyMDIxIFRheG9ub215JywgaHJlZj0naHR0cHM6Ly93d3cuZmFzYi5vcmcvanNwL0ZBU0IvUGFnZS9TZWN0aW9uUGFnZSZjaWQ9MTE3NjE3NTcyMTYyOCcsIHRhcmdldD0nX2JsYW5rJykgJT4lIGFzLmNoYXJhY3RlcigpLAogICAgYDRgPWh0bWx0b29sczo6YSgnRUJBIFJlcG9ydGluZyBGcmFtZSAzLjEnLCBocmVmPSdodHRwczovL3d3dy5lYmEuZXVyb3BhLmV1L3Jpc2stYW5hbHlzaXMtYW5kLWRhdGEvcmVwb3J0aW5nLWZyYW1ld29ya3MvcmVwb3J0aW5nLWZyYW1ld29yay0zLjEnLCB0YXJnZXQ9J19ibGFuaycpICU+JSBhcy5jaGFyYWN0ZXIoKQogICksCiAgYygKICAgIGAxYD0nRGVzaWduIEFwcHJvYWNoJywKICAgIGAyYD0nPGI+U3RhbmRhcmQgQmFzZWQgQXBwcm9hY2g6PC9iPiBGb3IgZWFjaCBJRlJTIFN0YW5kYXJkLCBlbGVtZW50cyByZWZsZWN0aW5nIGRpc2Nsb3N1cmUgcmVxdWlyZW1lbnRzIGFyZSBpZGVudGlmaWVkIGFuZCBtb2RlbGVkIGFuZCBvcmdhbml6ZWQgaW50byBhIHRheG9ub215JywKICAgIGAzYD0nPGI+RG9tYWluIE1vZGVsOjwvYj4gUGFydGl0aW9ucyBidXNpbmVzcyBjb25jZXB0cyBzbyB0byBtZWV0IFVTIEdBQVAgRmluYW5jaWFsIFJlcG9ydGluZyBUYXhvbm9teSAoIlVHVCIpIFJlcXVpcmVtZW50cyB0aGF0IGRlZmluZWQgdGhlIGNvbnRlbnQgc2NvcGUsIHN0YWtlaG9sZGVycywgdXNlcnMsIHVzZXIgZ29hbHMsIHVzZSBjYXNlcyBmdW5jdGlvbmFsIHJlcXVpcm1lbnRzLCB0ZWNobmljYWwgcmVxdWlybWVudHMgYW5kIGRlc2lnbiBnb2Fscy4nLAogICAgYDRgPSc8Yj5EYXRhIFBvaW50IE1vZGVsIChEUE0pOjwvYj4gRFBNIGlzIGEgc3RydWN0dXJlZCByZXByZXNlbnRhdGlvbiBvZiB0aGUgZGF0YSwgaWRlbnRpZnlpbmcgYWxsIHRoZSBidXNpbmVzcyBjb25jZXB0cyBhbmQgaXRzIHJlbGF0aW9ucywgYXMgd2VsbCBhcyB2YWxpZGF0aW9uIHJ1bGVzLiBJdCBjb250YWlucyBhbGwgdGhlIHJlbGV2YW50IHRlY2huaWNhbCBzcGVjaWZpY2F0aW9ucyBuZWNlc3NhcnkgZm9yIGRldmVsb3BpbmcgYW4gSVQgcmVwb3J0aW5nIHNvbHV0aW9uLiBUaGUgWEJSTCBUYXhvbm9taWVzIHByZXNlbnRzIHRoZSBkYXRhIGl0ZW1zLCBidXNpbmVzcyBjb25jZXB0cywgcmVsYXRpb25zIGFuZCB2YWxpZGF0aW9uIHJ1bGVzIGRlc2NyaWJlZCBieSB0aGUgRFBNIGluIHRoZSB0ZWNobmljYWwgZm9ybWF0IG9mIGFuIFhCUkwgdGF4b25vbXkuJwogICksCiAgYygKICAgIGAxYD0gJ1R5cGUgb2YgcmVwb3J0aW5nJywKICAgIGAyYD0gJ0dBQVAgUmVwb3J0aW5nJywKICAgIGAzYD0gJ0dBQVAgUmVwb3J0aW5nJywKICAgIGA0YD0gJ1JlZ3VsYXRvcnkgUmVwb3J0aW5nJwogICksCiAgYygKICAgIGAxYD0gJ0V4dGVuc2liaWxpdHknLAogICAgYDJgPSAnPGI+VW5yZXN0cmljdGVkCWV4dGVuc2lvbnM6PC9iPiBUaGUgcHVycG9zZSBpcyB0byBwcm92aWRlIGEgZnJhbWV3b3JrLCBnZW5lcmFsIHByaW5jaXBsZXMgYXJlIHNldCBvdXQgYW5kIGl0IGlzIGxlZnQgdG8gdXNlcnMgdG8gZGV0ZXJtaW5lIHNwZWNpZmljIGV4dGVuc2lvbnMgYXBwbHlpbmcgdG8gdGhlaXIgY2FzZScsCiAgICBgM2A9ICc8Yj5SZXN0cmljdGVkL0xpbWl0ZWQgZXh0ZW5zaW9uczo8L2I+IEV4dGVuc2lvbiBpcyBhbGxvd2VkIHdpdGggc3RyaWN0IHNldCBvZiBydWxlcycsCiAgICBgNGA9ICc8Yj5MaW1pdGVkIGV4dGVuc2lvbnM6PC9iPiBFeHRlbnNpb24gaXMgbGltaXRlZCB0byBsYWJlbHMgaW4gc3BlY2lmaWMgbGFuZ3VhZ2Ugb3IgaW50cm9kdWNpbmcgc3BlY2lmaWMgYXNzZXJ0aW9ucywgdGhlIGNvbXBsZXRlIHNldCBvZiBkYXRhIHBvaW50cyBpcyBkZWZpbmVkIGluIGJhc2UgdGF4b25vbXknCiAgKQogIAopICU+JSBiaW5kX3Jvd3MoKQoKICBrbml0cjo6a2FibGUobCwgZm9ybWF0ID0gJ2h0bWwnLCBjb2wubmFtZXMgPSB0aXRsZXMsIGVzY2FwZSA9IEYpICU+JSAKICBrYWJsZUV4dHJhOjprYWJsZV9jbGFzc2ljKCkgJT4lIAogIGthYmxlRXh0cmE6OnJvd19zcGVjKDE6NCwgZXh0cmFfY3NzID0gImJvcmRlci1ib3R0b206IDFweCBzb2xpZCBsaWdodGdyYXkiKQoKICAKCgpgYGAKCiMgVGF4b25vbXkgRGV2ZWxvcG1lbnQgUHJvamVjdCAgCkluIHRoaXMgc2VjdGlvbiB3ZSBleHBsb3JlIHRheG9ub215IGRldmVsb3BtZW50IHByb2plY3RzIGJhc2VkIG9uIHRoZSBYQlJMIFVTIGV4cGVyaWVuY2UgbGFpZCBvdXQgaW4gVERIIHN0YXJ0aW5nIHNlY3Rpb24gNCBwYWdlIDU5LiAKClRESCBicmVha3MgZG93biB0aGUgZGV2ZWxvcG1lbnQgcHJvY2VzcyBpbnRvIDYgbWFpbiBjb21wb25lbnRzOiAgCgoqIEFzc2Vzc2luZyBvdmVyIGFsbCBwcm9qZWN0IHNjb3BlIChhbmQgZGVmaW5pbmcgZ29hbHMpICAKKiBCdWlsZGluZyBUcmFuc3BvcnQgRGF0YSBNb2RlbCAgCiogVmFsaWRhdGlvbiAKKiBUaGUgTWVjaGFuaWNzIG9mIFRheG9ub215IERldmVsb3BtZW50CiogRG9jdW1lbnRpbmcgYSBUYXhvbm9teSAgCiogVGF4b25vbXkgR292ZXJuYW5jZSAgCgo8ZGl2Pgo8Y2VudGVyPgohW1RheG9ub215IERldmVsb3BtZW50XShgciBoZXJlOjpoZXJlKCdkb2NzJywgJ2ltYWdlcy9UYXhEZXZGVy5wbmcnKWApCjwvY2VudGVyPgo8cCBzdHlsZT0idGV4dC1hbGlnbjpjZW50ZXIiPgoqKlRheG9ub215IERldmVsb3BtZW50KioKPC9wPgo8L2Rpdj4gCgojIyBBc3Nlc3MgU2NvcGUgYW5kIERlZmluZSBHb2FscwpUaGUgZ29hbCBvZiBYQlJMIHRheG9ub215IGlzIHRvIGZhY2lsaXRhdGUgdGhlIHN0cnVjdHVyZWQgcmVwb3J0aW5nIG9mIGRhdGEgZnJvbSBwcmVwYXJlciB0byBjb25zdW1lci4gUHJvamVjdCBzY29wZSBhbmQgZ29hbHMgc2hvdWxkIGNvbnNpZGVyIGZhY3RvcnMgdGhhdCBlbmFibGVzIHByZXBhcmVycyB0byBwcm9kdWNlIHRoZSBkYXRhIGFuZCBjb25zdW1lciBzaG91bGQgYmUgYWJsZSB0byB1c2UgdGhlIGRhdGEgZm9yIGl0cyBpbnRlbmRlZCBwdXJwb3NlLiAgCgpgRnVuY3Rpb25hbCByZXF1aXJlbWVudHNgIHJlcHJlc2VudHMgd2hhdCBhIHRheG9ub215IGlzIG1lYW50IHRvIGRvLCB3aGlsZSBgTm9uLWZ1bmN0aW9uYWxgIHJlcXVpcmVtZW50cyBpbXBvc2VzIGNvbnN0cmFpbnRzIG9uIHN5c3RlbSBkZXNpZ24uIFRoZSBtYWluIGZvY3VzIGluIHRoaXMgc3RhZ2UgaXMgdG8gaWRlbnRpZnkgdGhlIGVmZmVjdCBvZiByZXF1aXJlbWVudHMgKGZ1bmN0aW9uYWwgYW5kIG5vbi1mdW5jdGlvbmFsIHJlcXVpcmVtZW50cykgb24gdGhlIHNjb3BlIGFuZCBkZXNpZ24gZ29hbHMuICAKCioqRmFjdG9ycyB0byBjb25zaWRlciB3aGVuIHNjb3BpbmcgYW5kIGRlZmluaW5nIGdvYWxzOioqCgoqIFBvbGljeSBkZWNpc2lvbiwgc3VjaCBhcyBleHRlbnNpYmlsaXR5LiAgCiogRnVuY3Rpb25hbCByZXF1aXJlbWVudHMgdnMgTm9uLWZ1bmN0aW9uYWwgcmVxdWlyZW1lbnQgIAoqIFVuZGVyc3RhbmQgdXNlIGNhc2VzLCBob3cgdXNlcnMgaW50ZXJhY3Qgd2l0aCB0aGUgc3lzdGVtcyB0byBhY2hpZXZlIHRoZWlyIGdvYWxzLiAgCiogSWRlbnRpZnkgZGF0YSB0byBiZSB0cmFuc3BvcnRlZCwgYW5kIHN5c3RlbXMgdGhhdCBwcm9kdWNlIGFuZCBjb25zdW1lIHRoZSBkYXRhLiAgCiogU3Rha2Vob2xkZXJzLiAgCiogU2NvcGUgb2YgdGhlIHRheG9ub215IChpbmR1c3RyeS9zZWN0b3Igd2lkZSBvciBsaW1pdGVkIGltcGxlbWVudGF0aW9uKS4gIAoqIFJlc291cmNlcyByZXF1aXJlZCBmb3IgdGhlIHByb2plY3QuCiogU3VwcG9ydCwgbWFpbnRlbmFuY2UgcmVxdWlyZW1lbnRzIGFuZCBjaGFuZ2UgbWFuYWdlbWVudAoqIERvY3VtZW50YXRpb24gYW5kIGNvbW11bmljYXRpb24KKiBCYWxhbmNpbmcgYW5kIHByaW9yaXRpemluZyByZXF1aXJlbWVudHMgZnJvbSBzdGFrZWhvbGRlcnMgYW5kIGNvbnNpZGVyaW5nIGNvc3QtYmVuZWZpdHMuCiogTWVhc3VyZXMgZm9yIHN1Y2Nlc3MsIHN1Y2ggYXMgYWNjdXJhY3kgYW5kIHRpbWVsaW5lc3Mgb2YgZGF0YS4gCgojIyBCdWlsZGluZyBUcmFuc3BvcnQgTW9kZWwgIApUbyBidWlsZCB0aGUgdGF4b25vbXkgKFRyYW5zcG9ydCBtb2RlbCksIGN1cnJlbnQgZGF0YXNldHMgYW5kIGRpbWVuc2lvbmFsaXR5IHNob3VsZCBiZSBkZXNjcmliZWQuIEFnYWluIGZ1bmN0aW9uYWwgcmVxdWlyZW1lbnRzIGFuZCBub24tZnVuY3Rpb25hbCByZXF1aXJlbWVudHMgc2hvdWxkIGJlIG1hcHBlZCB0byB0aGUgZGF0YS4KCkR1cmluZyB0aGUgcHJvY2VzcyBvZiBidWlsZGluZyB0aGUgbW9kZWwsIGBtaW5pbXVtIGRhdGFzZXRgIHNob3VsZCBiZSBkZXRlcm1pbmVkLCBgbWludW1pbSBkYXRhc2V0YCBpcyB0aGUgZGF0YXNldCBmcmVlIG9mIHJlZHVuZGFudCBvciBleHRyYW5lb3VzIGluZm9ybWF0aW9uIHdoaWxlIHJlcHJlc2VudGluZyBhbGwgdGhlIG5lY2Vzc2FyeSBkYXRhLiBDdXJyZW50IGFuZCBsZWdhY3kgc3lzdGVtIG1heSBiZSBhIGdvb2Qgc291cmNlIGZvciBkZXRlcm1pbmluZyBtaW5pbXVtIGRhdGFzZXQocykuIAoKRGF0YSBpcyBtb2RlbGVkIGJhc2VkIG9uIG8gdGhlIG1pbmltdW0gZGF0YXNldCwgcmVkdW5kYW50IGFuZCByZXBldGl0aXZlIGluZm9ybWF0aW9uIHNob3VsZCBiZSByZWR1Y2VkIHRvIG1pbmltdW0sIGNvbnRleHR1YWwgaW5mb3JtYXRpb24gZm9yIGEgZGF0YSBwb2ludCBhbmQgcmVsYXRpb25zaGlwcyBiZXR3ZWVuIGRhdGEgcG9pbnRzIGFyZSBleHBsb3JlZC4gIAoKQSBkYXRhIG1vZGVsIGlzIHRyYW5zZm9ybWVkIHRvIGEgdHJhbnNwb3J0IG1vZGVsIChYQlJMIFRheG9ub215KSwgZHVyaW5nIHRoaXMgcHJvY2VzcyBkYXRhIHR5cGVzIGFyZSBkZXRlcm1pbmVkLCBjb3JlIGNvbmNlcHQgZGltZW5zaW9ucyBkZWZpbmVkLCBjaG9pY2VzIGxpa2UgdXNpbmcgZXhwbGljaXQgdnMgdHlwZWQgZGltZW5zaW9ucyBhcmUgbWFkZSwgbW9kZWwgcmVsYXRpb25zaGlwcyBhcmUgdHJhbnNsYXRlZCB0byBYQlJMIGxpbmtiYXNlcy4gIAoKRXh0ZW5zaWJpbGl0eSBkZWNpc2lvbiBzaG91bGQgYmUgcmVmbGVjdGVkIGluIHRoZSB0YXhvbm9teSBkZXNpZ24gYW5kIGluIGRldGVybWluaW5nIGFsbG93YWJsZSBtZXRob2RzIHRoYXQgdXNlcnMgY2FuIGV4dGVuZCBhIHRheG9ub215LCBhbmQgaG93IGV4dGVuc2liaWxpdHkgYWZmZWN0cyBDb21wYXJhYmlsaXR5LiAgCgpPdGhlciBjb25zaWRlcmF0aW9ucyBpbmNsdWRlLCByZXBvcnRpbmcgc3lzdGVtIChzeXN0ZW0gcmVjZWl2aW5nIGFuZCBwcm9jZXNzaW5nIHJlcG9ydHMpLCB0cmFuc3BvcnQgZm9ybWF0LiAgCgojIyBWYWxpZGF0aW9uIApWYWxpZGF0aW9uIGVuc3VyZSByb2J1c3QgYW5kIGFjY3VyYXRlIGRhdGEuIFRoZXJlIGFyZSB0d28gbGV2ZWxzIG9mIHZhbGlkYXRpb24gaW4gWEJSTDogIAoKKiBCYXNpYyBWYWxpZGF0aW9uOiBFbnN1cmVzIHJlcG9ydHMgYXJlIHN5bnRheCB2YWxpZCwgdmFsaWQgZGF0YSB0eXBlcyB1c2VkIGFuZCB2YWxpZCByZWxhdGlvbnNoaXBzIHVzZWQuIAoqIFJlZ3VsYXRvcnkvSW5kdXN0cnkgUmVxdWlyZW1lbnRzOiBFbnN1cmVzIHRoYXQgYnVzaW5lc3MgcnVsZXMgYXJlIGFwcGxpZWQsIG1ldGhvZHMgdXNlZCBpbmNsdWRlIHNvZnR3YXJlIHZhbGlkYXRpb24sIFhCUkwgRm9ybXVsYSBWYWxpZGF0aW9uLCBYVUxFIHZhbGlkYXRpb24gYW5kIERhdGEgUXVhbGl0eSBDb21taXR0ZWVzIChpc3N1ZXMgYW5kIG1haW50YWluIGRhdGEgcXVhbGl0eSBydWxlcykuICAKCltTZWUgWEJSTCBWYWxpZGF0aW9uXSgjeGJybC12YWxpZGF0aW9uKS4gIAoKCiMjIFRoZSBNZWNoYW5pY3Mgb2YgVGF4b25vbXkgRGV2ZWxvcG1lbnQgIApfV29ya2Zsb3dfICAKTXVsdGlwbGUgZ3JvdXBzIHBlcmZvcm1pbmcgZGlmZmVyZW50IHRhc2tzIGFyZSBuZWVkZWQgdG8gY3JlYXRlIGEgdGF4b25vbXksIGFuZCB3b3JrZmxvdyBzaG91bGQgYmUgb3JnYW5pemVkLCBUREggZ2l2ZXMgZXhhbXBsZXMgb2YgdGhlIGdyb3VwcyBhcyBmb2xsb3dzOiAgCgoqIEdyb3VwIHJlc3BvbnNpYmxlIGZvciBjcmVhdGluZyBkYXRhIG1vZGVsIGFuZCB0cmFuc2Zvcm1pbmcgaXQgdG8gdGF4b25vbXkuICAKKiBHcm91cCByZXNwb25zaWJsZSBmb3Igb3ZlcnNlZWluZyBpbmNvcnBvcmF0aW9uIG9mIHJlZ3VsYXRvcnkvZ292ZXJuYW5jZSBydWxlcyBhbmQgY2hhbmdlcy4gIAoqIEdyb3VwIHJlc3BvbnNpYmxlIGZvciByZWFkaW5nIHJldmlld2VycycgY29tbWVudHMgYW5kIG1ha2luZyByZWNvbW1lbmRhdGlvbnMgZm9yIG1vZGlmaWNhdGlvbnMuICAKClRoZSB3b3JrIGZsb3cgbWlnaHQgbG9vayBhcyBmb2xsb3dzOiAgCgoKPGRpdj4KPGNlbnRlcj4KIVtUYXhvbm9teSBEZXYgV29ya2Zsb3ddKGByIGhlcmU6OmhlcmUoJ2RvY3MnLCAnaW1hZ2VzL3dvcmtmbG93LmpwZycpYCkKPC9jZW50ZXI+CjxwIHN0eWxlPSJ0ZXh0LWFsaWduOmNlbnRlciI+CioqVGF4b25vbXkgRGV2IFdvcmtmbG93KioKPC9wPgo8L2Rpdj4gCgpfUHJlcGFyaW5nIGFuZCBHZW5lcmF0aW5nIHRoZSBUYXhvbm9teV8gIApEZXRlcm1pbmUgdGhlIHNvZnR3YXJlIHRvIGJlIHVzZWQgZm9yIGdlbmVyYXRpbmcgdGhlIHRheG9ub215LCBhbmQgcGVyZm9ybSB0aGUgZm9sbG93aW5nIHN0ZXBzOiAgCgoqIERldGVybWluZSBjb25jZXB0cycgbGFiZWxzOiBpbXBvcnRhbnQgZm9yIGh1bWFuIHJlYWRhYmlsaXR5IGFuZCB1bmRlcnN0YW5kaW5nIHRheG9ub215LiAgCiogQnVpbGRpbmcgYSB0YXhvbm9teSBzcHJlYWRzaGVldDogc3ByZWFkc2hlZXQgY29udGFpbmluZyBjb25jZXB0LCByZWxhdGlvbnMsIGFuZCBvdGhlciBpbmZvcm1hdGlvbiBhYm91dCB0aGUgdGF4b25vbXksIHNvbWUgc29mdHdhcmUgcGFja2FnZXMgY2FuIHVzZSB0aGlzIHNwcmVhZHNoZWV0IHRvIGdlbmVyYXRlIHRheG9ub215IGZpbGVzLiAgCgpfVGhlIEltcG9ydGFuY2Ugb2YgUHVibGljIEV4cG9zdXJlXyAgClRheG9ub215IHNob3VsZCB1bmRlcmdvIHNpZ25pZmljYW50IHB1YmxpYyByZXZpZXcgKHdoZXJlIGFueW9uZSBjYW4gc2VlIGFuZCBjb21tZW50IG9uIHRoZSB0YXhvbm9teSksIHdvcmQgJ3B1YmxpYycgaGVyZSBpcyByZWxhdGl2ZSB0byB0aGUgc2l6ZSBhbmQgc2NvcGUgb2YgdGhlIHRheG9ub215LCBhbmQgZmVlZGJhY2sgYW5kIGNvbW1lbnRzIHNob3VsZCBiZSBjb2xsZWN0ZWQgYW5kIGFuYWx5emVkLiAgCgoKIyMgRG9jdW1lbnRpbmcgYSBUYXhvbm9teSAgClRheG9ub215IGlzIGEgcG93ZXJmdWwgdG9vbCwgYW5kIGl0IGNhbiBvbmx5IGZ1bGZpbGwgaXRzIHB1cnBvc2UgaWYgdXNlcnMga25vdyBob3cgdG8gdXNlIGl0LiBUYXhvbm9teSBkb2N1bWVudGF0aW9uIGlzIGV4dHJlbWVseSBpbXBvcnRhbnQsIGl0IGNvbW11bmljYXRlcyB0aGUgZ29hbHMgb2YgdGhlIHRheG9ub215IGFuZCBtZWFucyB0byBhY2hpZXZlIHRob3NlIGdvYWxzIHRvIGFsbCBzdGFrZWhvbGRlcnMuICAKCkRvY3VtZW50YXRpb24gaW5jbHVkZTogIAoKKiBUYXhvbm9teSBXaGl0ZSBQYXBlcjogY2FuIGJlIGNvbnNpZGVyZWQgYXMgYW4gYW5ub3VuY2VtZW50IG9mIHRoZSB0YXhvbm9teSwgd2l0aCBleHBsYW5hdGlvbiBvZiBpdHMgcHVycG9zZSBhbmQganVzdGlmaWNhdGlvbiBmb3IgaXRzIGRldmVsb3BtZW50LiAgCiogVGF4b25vbXkgZ3VpZGU6IGV4cGxhaW5zIHRoZSB0YXhvbm9teSBpdCBzZWxmIGFuZCBsb2dpYyBiZWhpbmQgaXQuICAKKiBSZXBhaXJlcidzIGd1aWRlOiBwcm92aWRlcyBwcmVwYXJlcnMgd2l0aCBpbmZvcm1hdGlvbiBhYm91dCB0aGUgdGF4b25vbXkncyBjb25jZXB0cyBhbmQgc3RydWN0dXJlcyBhcyBuZWVkZWQgdG8gYnVpbGQgWEJSTCByZXBvcnRzLiAgCiogRGF0YSBDb25zdW1lciBHdWlkZTogcHJvdmlkZXMgaW5mb3JtYXRpb24gYW5kIGNvbW1vbiB1c2UgY2FzZXMgZm9yIGRhdGEgY29uc3VtZXJzLiAKVERIIHByb3ZpZGUgZGV0YWlsZWQgZXhhbXBsZXMgb2YgZG9jdW1lbnRhdGlvbiBpbiBzZWN0aW9uIDggcGFnZSAxMTEuICAKCiMjIFRheG9ub215IEdvdmVybmFuY2UgIApUaGUgVERIIHJlY29nbml6ZXMgZm91ciBnb3Zlcm5hbmNlIHJvbGVzIGluIHRoZSB0YXhvbm9teSBkZXZlbG9wbWVudCBsaWZlIGN5Y2xlIHdoaWNoIHNwYW5zIG92ZXIgZm91ciBwaGFzZXMuICAKCl9Hb3Zlcm5hbmNlIFJvbGVzXzogIAoKKiBgU3BvbnNvcmA6IENoYW1waW9ucyB0aGUgZGV2ZWxvcG1lbnQgcHJvY2VzcyBhbmQgaXMgYWJsZSB0byBicmluZyB0b2dldGhlciBzdGFrZWhvbGRlcnMgc3VjY2Vzc2Z1bGx5LCBjb3VsZCBiZSBhIHJlZ3VsYXRvcnkgYWdlbmN5IG9yIHN0YW5kYXJkcyBvcmdhbml6YXRpb24uICAKKiBgV29ya2luZyBHcm91cGA6IEluY2x1ZGVzIHJlcHJlc2VudGF0aW9uIG9mIGFsbCBzdGFrZWhvbGRlcnMgKHJlZ3VsYXRvciwgcHJlcGFyZXJzLCBkZXZlbG9wZXJzLCBjb25zdW1lcnMuLi4pLCB0aGlzIGdyb3VwIHBlcmZvcm0gdGhlIHRhc2tzIHRvIGRldmVsb3AgdGhlIHRheG9ub215IGRlbGl2ZXJhYmxlcy4gIAoqIGBTdGVlcmluZyBDb21taXR0ZWVgOiBoaWdoZXN0IGNvbW1pdHRlZSBhbmQgaXMgbGVkIGJ5IHRoZSBzcG9uc29yLCBwcm92aWRlcyBvdmVyc2lnaHQsIGV2YWx1YXRlcyBtYWpvciBtaWxlc3RvbmVzLCByZXZpZXdzIGFuZCBhcHByb3ZlcyBkZWxpdmVyYWJsZXMsIGFuZCBzZXJ2ZXMgYXMgInRpZSBicmVha2VyIiBvbiBtYWpvciBkZWNpc2lvbnMgY29uY2VybmluZyB0aGUgdGF4b25vbXkuICAKKiBgVGF4b25vbXkgTWFuYWdlcmA6IGlzIHRoZSBwcm9qZWN0IG1hbmFnZXIsIG1haW50YWlucyBkZXRhaWxlZCBrbm93bGVkZ2Ugb2YgdGhlIHRheG9ub215IGFuZCB0aGUgcHJvamVjdCBhcyBhIHdob2xlIGFuZCBwcm92aWRlcyBkYXktdG8tZGF5IHN0YWZmIHN1cHBvcnQgZm9yIHRoZSB0YXhvbm9teSB3b3JraW5nIGdyb3VwLiBBbHNvIGludGVyYWN0cyB3aXRoIGZlZWRiYWNrIGFuZCByZXZpZXdzIGFuZCBjb21tZW50cywgYW5kIHJlcG9ydHMgdG8gdGhlIHN0ZWVyaW5nIGNvbW1pdHRlZSBhbmQgd29ya2luZyBncm91cC4gIAoqIFdvcmtpbmcgZ3JvdXAgYW5kIHRheG9ub215IHN0ZWVyaW5nIGNvbW1pdHRlZSBjYW4gYmUgY29uc29saWRhdGVkIGFuZCBzdHJlYW1saW5lZCBpbnRvIGEgYHRheG9ub215IGNvbW1pdHRlZWAuIAoKVGhlIGludGVyYWN0aW9uIG9mIHRoZSBhYm92ZSByb2xlcyBjYW4gYmUgdmlld2VkIGFzIGZvbGxvd3M6ICAKCjxkaXY+CjxjZW50ZXI+CiFbR292ZXJuYW5jZSBzdHJ1Y3R1cmVdKGByIGhlcmU6OmhlcmUoJ2RvY3MnLCAnaW1hZ2VzL2dvdjEuanBnJylgKQo8L2NlbnRlcj4KPHAgc3R5bGU9InRleHQtYWxpZ246Y2VudGVyIj4KKipHb3Zlcm5hbmNlIHN0cnVjdHVyZSoqCjwvcD4KPC9kaXY+IAoKX1RheG9ub215IGRldmVsb3BtZW50IExpZmUgY3ljbGUgUGhhc2VzXzogIApUaGUgVERIIHJlY29nbml6ZXMgZm91ciBwaGFzZXMgaW4gdGhlIHRoZSB0YXhvbm9teSBkZXZlbG9wbWVudCBsaWZlIGN5Y2xlLCB0aGUgZ29hbHMgYW5kIHJvbGVzIGZvciBlYWNoIHBoYXNlIGFyZSBhcyBmb2xsb3dzOiAgCgo8ZGl2Pgo8Y2VudGVyPgohW1RoZSBsaWZlY3ljbGUgb2YgdGF4b25vbXkgZGV2ZWxvcG1lbnQgYW5kIGdvdmVybmFuY2VdKGByIGhlcmU6OmhlcmUoJ2RvY3MnLCAnaW1hZ2VzL2xpZmVDeWNsZS5qcGcnKWApCjwvY2VudGVyPgo8cCBzdHlsZT0idGV4dC1hbGlnbjpjZW50ZXIiPgoqKlRoZSBsaWZlY3ljbGUgb2YgdGF4b25vbXkgZGV2ZWxvcG1lbnQgYW5kIGdvdmVybmFuY2UqKgo8L3A+CjwvZGl2PiAgCgotLS0KIyBMaW5rcyBhbmQgUmVzb3VyY2VzICAKYGBge3IgcmVzX3RhYmxlLCBlY2hvPUZBTFNFLCByZXN1bHRzPSdhc2lzJywgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KcmVzb3VyY2VzX2xpbmtzIDwtIHJlYWRyOjpyZWFkX2NzdihoZXJlOjpoZXJlKCJkb2NzIiwicmVzb3VyY2VzX2xpbmtzLmNzdiIpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xfdHlwZXMgPSBjb2xzKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dCA9IGNvbF9jaGFyYWN0ZXIoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVybCA9IGNvbF9jaGFyYWN0ZXIoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHIgPSBjb2xfY2hhcmFjdGVyKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEZXNjcmlwdGlvbiA9IGNvbF9jaGFyYWN0ZXIoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkpICU+JSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgbXV0YXRlKExpbms9cG1hcCguLCB+aHRtbHRvb2xzOjpIVE1MKGFzLmNoYXJhY3RlcihodG1sdG9vbHM6OmEoaHJlZj0uLjIsIHRhcmdldD0uLjMsIC4uMSkpKSkgJT4lIHVubGlzdCgpKSAlPiUgCiAgc2VsZWN0KExpbmssIERlc2NyaXB0aW9uKQpEVDo6ZGF0YXRhYmxlKHJlc291cmNlc19saW5rcywgcm93bmFtZXMgPSBGQUxTRSwgZXNjYXBlID0gRkFMU0UsIAogICAgICAgICAgICAgIGVsZW1lbnRJZCA9ICdyZXMtbGlua3MtdGFibGUnLAogICAgICAgICAgICAgIG9wdGlvbnMgPSBsaXN0KHBhZ2luZz1GQUxTRSkKICAgICAgICAgICAgICApCmBgYAoKCjxzY3JpcHQ+CmZ1bmN0aW9uIGluSWZyYW1lICgpIHsKICAgIHRyeSB7CiAgICAgICAgcmV0dXJuIHdpbmRvdy5zZWxmICE9PSB3aW5kb3cudG9wOwogICAgfSBjYXRjaCAoZSkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9OwokKCBkb2N1bWVudCApLnJlYWR5KGZ1bmN0aW9uKCkgewogICAgaWYgKCFpbklmcmFtZSAoKSl7CiAgICBjb25zb2xlLmxvZygndG9jIHZpc2libGUnKTsKICAgIH0gZWxzZSB7CiAgICAKICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2JvZHkgPiBkaXYuY29udGFpbmVyLWZsdWlkLm1haW4tY29udGFpbmVyID4gZGl2ID4gZGl2LmNvbC14cy0xMi5jb2wtc20tNC5jb2wtbWQtMycpLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7CiAgICAKICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdib2R5ID4gZGl2LmNvbnRhaW5lci1mbHVpZC5tYWluLWNvbnRhaW5lciA+IGRpdiA+IGRpdi50b2MtY29udGVudC5jb2wteHMtMTIuY29sLXNtLTguY29sLW1kLTknKS5zdHlsZS5jc3NUZXh0PSJ3aWR0aDoxMDAlOyBwYWRkaW5nLWxlZnQ6IHVuc2V0OyBwYWRkaW5nLXJpZ2h0OnVuc2V0OyI7CiAgICAgICAgY29uc29sZS5sb2coJ3RvYyBpcyBoaWRkZW4nKTsKICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjaGVhZGVyJykuc3R5bGUuZGlzcGxheT0ibm9uZSI7CiAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignYm9keSA+IGRpdi5jb250YWluZXItZmx1aWQubWFpbi1jb250YWluZXIgPiBkaXYgPiBkaXYudG9jLWNvbnRlbnQuY29sLXhzLTEyLmNvbC1zbS04LmNvbC1tZC05ID4gaHInKS5zdHlsZS5kaXNwbGF5PSJub25lIgogICAgIGNvbnNvbGUubG9nKCdoZWFkZXIgaGlkZGVuJyk7CiAgICAgICAgCiAgICAgICAgCndpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdsb2FkJywgZnVuY3Rpb24oKSB7CglsZXQgbWVzc2FnZSA9IHsgaGVpZ2h0OiBkb2N1bWVudC5ib2R5LnNjcm9sbEhlaWdodCwgd2lkdGg6IGRvY3VtZW50LmJvZHkuc2Nyb2xsV2lkdGggfTsJCgoJLy8gd2luZG93LnRvcCByZWZlcnMgdG8gcGFyZW50IHdpbmRvdwoJd2luZG93LnRvcC5wb3N0TWVzc2FnZShtZXNzYWdlLCAiKiIpOwoJY29uc29sZS5sb2cobWVzc2FnZSk7Cn0pOwogICAgICAgIAp9Owp9KTsKPC9zY3JpcHQ+Cg==