Introduction
SQLite is a popular software library that provides a relational database management system (RDBMS) that is designed to be embedded into software applications. It is a self-contained, serverless, zero-configuration, transactional SQL database engine. SQLite is a file-based database system, which means that the entire database is stored in a single file on the file system of the host computer.
SQLite supports most of the standard SQL syntax and provides a lightweight and fast alternative to larger, more complex database systems. It is a widely used database technology in embedded systems, mobile applications, desktop software, and web applications. SQLite is often used for small to medium-sized applications or as a local data store for larger applications that use a more powerful database server for remote data storage and retrieval.
Serverless Architecture
When we say that SQLite is “serverless”, it means that it doesn’t require a separate server process to be running in order to access and manipulate the data in the database. Instead, SQLite is designed to be embedded directly into the application that uses it. This means that the database operations are performed directly by the application, without the need for a separate server process to be running in the background.
Additionally, SQLite is a “file-based” database system, which means that the entire database is stored in a single file on the file system of the host computer. This makes it easy to move the database between different machines or to back it up, since it’s just a matter of copying the file. The file-based approach also makes it easy to set up and use SQLite, since there is no need to install or configure a separate database server or create a separate database instance.
SQLite being serverless and file-based makes it a lightweight, self-contained, and easy-to-use database system that can be embedded into a wide range of applications, without the need for a separate database server or complex setup.
Creating a New Database
Creating a new database is SQLite is simple: open a database file that does not exist and SQLite will create a new database with that file name.
% sqlite3 customerDB.sqlitedb
SQLite database files can have any extension, but .sqlitedb and .db are most common.
Worked Example
In the worked example below, we create a new database using a creation script through the management console os SQLite. The script is generic and standard SQL, so it will work just as well on any other relational database, including MySQL, Oracle, and SQL Server. After creation of the database, sample data is added to the database via the script, although this could have also been done via imports of CSV files. Finally, we execute a set of queries against the sample data in the database.
Create Database
Download the organization database creation script: create-orgdb.sql. A script is a plain text file containing SQL statements.
Using either the command line tools sqlite3 or the cloud version of SQLite, source (run) the script to execute all of the SQL statements in the script. This will create the database with sample data.
Inspect the tables in the database either by studying the SQL creation code or listing the tables. It is a useful practice to visualize the database structure by drawing an Entity-Relationship or UML diagram.
The tutorial below will show you how to create the database, connect to it, and inspect the tables. Watch it only after you attempted to do this yourself. It assumes that you have the SQLite tools installed locally on your computer.
Build Queries
Once you are familiar with the database, use the interactive command line tool to build SQL queries for the following questions:
Query 1
Find the distinct number of workers who work in the HR department and who earn more than ₹225,000.
Click for Solution
select distinct count(*) as 'NumWorkers'
from Worker as w
where w.department = 'HR'
and w.salary > 250000;
Query 2
Find the last name and title of all workers and the department they work in who earn less than the average salary.
Click for Solution
select last_name, worker_title
from Worker AS w JOIN Title AS t ON (w.WORKER_ID = t.WORKER_REF_ID)
and w.salary < (select avg(salary) from Worker);
Query 3
What is the average salary paid for all workers in each department? List the department, the average salary for the department, and the number of workers in each department. Name the average column ‘AvgSal’ and the number of workers column to ‘Num’.
Click for Solution
select department, AVG(salary) as 'AvgSalary', count(*) as 'NumWorkers'
from Worker
group by department;
Query 4
What is the total compensation for each worker (salary and bonus) on a per monthly basis? List the name of the worker, their title, and the their monthly compensation (annual compensation divided by 12). Change the header for compensation to ‘MonthlyComp’ and round it to the nearest whole number.
Click for Solution
select last_name, ((salary + bonus_amount) / 12) as 'MonthlyComp'
from Worker as w join Bonus as b on (w.WORKER_ID = b.WORKER_REF_ID)
Query 5
List the full names of all workers in all capital letters who did not get a bonus.
Click for Solution
select upper(last_name || ", " || first_name) as 'FullName'
from Worker
where worker_id not in (select worker_ref_id from Bonus)
order by last_name;
Query 6
What are the full names of all workers who have ‘Manager’ in their title. Do not “hard code” the titles; use string searching.
Click for Solution
select upper(last_name || ", " || first_name) as 'FullName', t.WORKER_TITLE
from Worker w, Title t
WHERE w.WORKER_ID = t.WORKER_REF_ID
and t.WORKER_TITLE LIKE '%Manager%';
Tutorial
Conclusion
Management consoles, available for every database, are an essential tool for database development and administration. Some are command-line oriented and some have graphical user interfaces. Some even allow database design through integrated diagramming tools.
Aside from allowing us to create databases and perform ad hoc queries, the provide a number of additional benefits.
Centralized control: A management console provides a centralized interface for managing and monitoring a database, allowing administrators to configure and monitor the database more easily and efficiently.
Efficient performance monitoring: A management console provides real-time monitoring of the database’s performance, enabling administrators to quickly identify and troubleshoot performance issues. This can help improve the overall performance of the database, reducing downtime and improving the end user experience.
Enhanced security: A management console can help to enhance the security of a database by providing tools to manage users and permissions, set up auditing, and monitor the database for suspicious activity. This can help prevent unauthorized access to the database and protect sensitive data.
Automated backup and recovery: Many management consoles include tools for automated backup and recovery of the database, helping to ensure data is protected in the event of a disaster or other unforeseen circumstances.
Simplified administration: A management console can simplify database administration by providing a graphical user interface that simplifies complex database tasks. This can help reduce the need for specialized skills or knowledge, making it easier for a wider range of staff to manage and maintain the database.
Overall, a management console for a database can help streamline database management, facilitate ad hoc querying, improve performance and security, and simplify administration, making it an essential tool for database development.
This lesson showed how to install and use the management console for SQLite.
Errata
None collected yet. Let us know.
LS0tCnRpdGxlOiAiSW50ZXJhY3Rpbmcgd2l0aCBTUUxpdGUgdGhyb3VnaCBDb25zb2xlIGFuZCBTY3JpcHRzIgpwYXJhbXM6CiAgY2F0ZWdvcnk6IDcwCiAgbnVtYmVyOiA4MDMKICB0aW1lOiA2MAogIGxldmVsOiBpbnRlcm1lZGlhdGUKICB0YWdzOiAic3FsaXRlLHNjcmlwdHMiCiAgZGVzY3JpcHRpb246ICJFeHBsYWlucyBob3cgdG8gY3JlYXRlIGRhdGFiYXNlcyB0aHJvdWdoIFNRTGl0ZSBTUUwgc2NyaXB0cy4gU2hvd3MKICAgICAgICAgICAgICAgIGhvdyB0byBpbnN0YWxsIGFuZCB1c2UgbWFuYWdlbWVudCBjb25zb2xlIHRocm91Z2ggdGVybWluIHNoZWxsLiIKZGF0ZTogIjxzbWFsbD5gciBTeXMuRGF0ZSgpYDwvc21hbGw+IgphdXRob3I6ICI8c21hbGw+TWFydGluIFNjaGVkbGJhdWVyPC9zbWFsbD4iCmVtYWlsOiAibS5zY2hlZGxiYXVlckBuZXUuZWR1IgphZmZpbGl0YXRpb246ICJOb3J0aGVhc3Rlcm4gVW5pdmVyc2l0eSIKb3V0cHV0OiAKICBib29rZG93bjo6aHRtbF9kb2N1bWVudDI6CiAgICB0b2M6IHRydWUKICAgIHRvY19kZXB0aDogMwogICAgdG9jX2Zsb2F0OiB0cnVlCiAgICBjb2xsYXBzZWQ6IGZhbHNlCiAgICBudW1iZXJfc2VjdGlvbnM6IGZhbHNlCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICB0aGVtZTogc3BhY2VsYWIKICAgIGhpZ2hsaWdodDogdGFuZ28KLS0tCgotLS0KdGl0bGU6ICI8c21hbGw+YHIgcGFyYW1zJGNhdGVnb3J5YC5gciBwYXJhbXMkbnVtYmVyYDwvc21hbGw+PGJyLz48c3BhbiBzdHlsZT0nY29sb3I6ICMyRTQwNTM7IGZvbnQtc2l6ZTogMC45ZW0nPmByIHJtYXJrZG93bjo6bWV0YWRhdGEkdGl0bGVgPC9zcGFuPiIKLS0tCgpgYGB7ciBjb2RlPXhmdW46OnJlYWRfdXRmOChwYXN0ZTAoaGVyZTo6aGVyZSgpLCcvUi9faW5zZXJ0MkRCLlInKSksIGluY2x1ZGUgPSBGQUxTRSwgY2FjaGU9VFJVRX0KYGBgCgojIyBJbnRyb2R1Y3Rpb24KClNRTGl0ZSBpcyBhIHBvcHVsYXIgc29mdHdhcmUgbGlicmFyeSB0aGF0IHByb3ZpZGVzIGEgcmVsYXRpb25hbCBkYXRhYmFzZSBtYW5hZ2VtZW50IHN5c3RlbSAoUkRCTVMpIHRoYXQgaXMgZGVzaWduZWQgdG8gYmUgZW1iZWRkZWQgaW50byBzb2Z0d2FyZSBhcHBsaWNhdGlvbnMuIEl0IGlzIGEgc2VsZi1jb250YWluZWQsIHNlcnZlcmxlc3MsIHplcm8tY29uZmlndXJhdGlvbiwgdHJhbnNhY3Rpb25hbCBTUUwgZGF0YWJhc2UgZW5naW5lLiBTUUxpdGUgaXMgYSBmaWxlLWJhc2VkIGRhdGFiYXNlIHN5c3RlbSwgd2hpY2ggbWVhbnMgdGhhdCB0aGUgZW50aXJlIGRhdGFiYXNlIGlzIHN0b3JlZCBpbiBhIHNpbmdsZSBmaWxlIG9uIHRoZSBmaWxlIHN5c3RlbSBvZiB0aGUgaG9zdCBjb21wdXRlci4KClNRTGl0ZSBzdXBwb3J0cyBtb3N0IG9mIHRoZSBzdGFuZGFyZCBTUUwgc3ludGF4IGFuZCBwcm92aWRlcyBhIGxpZ2h0d2VpZ2h0IGFuZCBmYXN0IGFsdGVybmF0aXZlIHRvIGxhcmdlciwgbW9yZSBjb21wbGV4IGRhdGFiYXNlIHN5c3RlbXMuIEl0IGlzIGEgd2lkZWx5IHVzZWQgZGF0YWJhc2UgdGVjaG5vbG9neSBpbiBlbWJlZGRlZCBzeXN0ZW1zLCBtb2JpbGUgYXBwbGljYXRpb25zLCBkZXNrdG9wIHNvZnR3YXJlLCBhbmQgd2ViIGFwcGxpY2F0aW9ucy4gU1FMaXRlIGlzIG9mdGVuIHVzZWQgZm9yIHNtYWxsIHRvIG1lZGl1bS1zaXplZCBhcHBsaWNhdGlvbnMgb3IgYXMgYSBsb2NhbCBkYXRhIHN0b3JlIGZvciBsYXJnZXIgYXBwbGljYXRpb25zIHRoYXQgdXNlIGEgbW9yZSBwb3dlcmZ1bCBkYXRhYmFzZSBzZXJ2ZXIgZm9yIHJlbW90ZSBkYXRhIHN0b3JhZ2UgYW5kIHJldHJpZXZhbC4KCiMjIFNlcnZlcmxlc3MgQXJjaGl0ZWN0dXJlCgpXaGVuIHdlIHNheSB0aGF0IFNRTGl0ZSBpcyAic2VydmVybGVzcyIsIGl0IG1lYW5zIHRoYXQgaXQgZG9lc24ndCByZXF1aXJlIGEgc2VwYXJhdGUgc2VydmVyIHByb2Nlc3MgdG8gYmUgcnVubmluZyBpbiBvcmRlciB0byBhY2Nlc3MgYW5kIG1hbmlwdWxhdGUgdGhlIGRhdGEgaW4gdGhlIGRhdGFiYXNlLiBJbnN0ZWFkLCBTUUxpdGUgaXMgZGVzaWduZWQgdG8gYmUgZW1iZWRkZWQgZGlyZWN0bHkgaW50byB0aGUgYXBwbGljYXRpb24gdGhhdCB1c2VzIGl0LiBUaGlzIG1lYW5zIHRoYXQgdGhlIGRhdGFiYXNlIG9wZXJhdGlvbnMgYXJlIHBlcmZvcm1lZCBkaXJlY3RseSBieSB0aGUgYXBwbGljYXRpb24sIHdpdGhvdXQgdGhlIG5lZWQgZm9yIGEgc2VwYXJhdGUgc2VydmVyIHByb2Nlc3MgdG8gYmUgcnVubmluZyBpbiB0aGUgYmFja2dyb3VuZC4KCkFkZGl0aW9uYWxseSwgU1FMaXRlIGlzIGEgImZpbGUtYmFzZWQiIGRhdGFiYXNlIHN5c3RlbSwgd2hpY2ggbWVhbnMgdGhhdCB0aGUgZW50aXJlIGRhdGFiYXNlIGlzIHN0b3JlZCBpbiBhIHNpbmdsZSBmaWxlIG9uIHRoZSBmaWxlIHN5c3RlbSBvZiB0aGUgaG9zdCBjb21wdXRlci4gVGhpcyBtYWtlcyBpdCBlYXN5IHRvIG1vdmUgdGhlIGRhdGFiYXNlIGJldHdlZW4gZGlmZmVyZW50IG1hY2hpbmVzIG9yIHRvIGJhY2sgaXQgdXAsIHNpbmNlIGl0J3MganVzdCBhIG1hdHRlciBvZiBjb3B5aW5nIHRoZSBmaWxlLiBUaGUgZmlsZS1iYXNlZCBhcHByb2FjaCBhbHNvIG1ha2VzIGl0IGVhc3kgdG8gc2V0IHVwIGFuZCB1c2UgU1FMaXRlLCBzaW5jZSB0aGVyZSBpcyBubyBuZWVkIHRvIGluc3RhbGwgb3IgY29uZmlndXJlIGEgc2VwYXJhdGUgZGF0YWJhc2Ugc2VydmVyIG9yIGNyZWF0ZSBhIHNlcGFyYXRlIGRhdGFiYXNlIGluc3RhbmNlLgoKU1FMaXRlIGJlaW5nIHNlcnZlcmxlc3MgYW5kIGZpbGUtYmFzZWQgbWFrZXMgaXQgYSBsaWdodHdlaWdodCwgc2VsZi1jb250YWluZWQsIGFuZCBlYXN5LXRvLXVzZSBkYXRhYmFzZSBzeXN0ZW0gdGhhdCBjYW4gYmUgZW1iZWRkZWQgaW50byBhIHdpZGUgcmFuZ2Ugb2YgYXBwbGljYXRpb25zLCB3aXRob3V0IHRoZSBuZWVkIGZvciBhIHNlcGFyYXRlIGRhdGFiYXNlIHNlcnZlciBvciBjb21wbGV4IHNldHVwLgoKIyMgSW5zdGFsbGluZyBTUUxpdGUgQ29tbWFuZCBMaW5lIFRvb2xzCgpUaGUgdG9vbHMgYmVsb3cgZG8gbm90IG5lZWQgdG8gYmUgaW5zdGFsbGVkIHdoZW4gYWNjZXNzaW5nIGEgU1FMaXRlIGRhdGFiYXNlIGZyb20gYW4gYXBwbGljYXRpb24gd3JpdHRlbiBpbiBKYXZhLCBDKyssIFIsIFB5dGhvbiwgYW5kIG1vc3Qgb3RoZXIgbGFuZ3VhZ2VzLiBUaGVzZSBsYW5ndWFnZSBpbmNsdWRlIGEgcGFja2FnZSBvciBsaWJyYXJ5IHRoYXQgY29udGFpbnMgYWxsIHRoZSBjb2RlIG5lY2Vzc2FyeSB0byBhY2Nlc3MgYSBTUUxpdGUgZGF0YWJhc2UuCgpIb3dldmVyLCB0byBydW4gc2NyaXB0cywgeW91IG11c3QgaW5zdGFsbCB0aGUgY29tbWFuZCBsaW5lIHRvb2xzLiBPZiBjb3Vyc2UsIHlvdSBjYW4gYWNjZXNzIHRoZSBzYW1lIGRhdGFiYXNlIGZyb20gYW4gYXBwbGljYXRpb24sIFIgcHJvZ3JhbXMsIFIgTm90ZWJvb2tzLCBhbmQgdGhlIGNvbW1hbmQgbGluZS4gVGhpcyBpcyBvZnRlbiB1c2VmdWwgdG8gaW5zcGVjdCBhIGRhdGFiYXNlIHRoYXQncyBjcmVhdGVkIGJ5IGFuIGFwcGxpY2F0aW9uLgoKVGhlIHByb2Nlc3Mgb2YgaW5zdGFsbGluZyBTUUxpdGUgY2FuIHZhcnkgZGVwZW5kaW5nIG9uIHlvdXIgb3BlcmF0aW5nIHN5c3RlbSBhbmQgaG93IHlvdSBwbGFuIHRvIHVzZSBpdC4gSGVyZSBhcmUgc29tZSBnZW5lcmFsIHN0ZXBzIHRvIGZvbGxvdzoKCiMjIyBJbnN0YWxsaW5nIFNRTGl0ZSBvbiBXaW5kb3dzCgotICAgR28gdG8gdGhlIFNRTGl0ZSBkb3dubG9hZCBwYWdlOiA8aHR0cHM6Ly93d3cuc3FsaXRlLm9yZy9kb3dubG9hZC5odG1sPgotICAgVW5kZXIgdGhlICJQcmVjb21waWxlZCBCaW5hcmllcyBmb3IgV2luZG93cyIgc2VjdGlvbiwgZG93bmxvYWQgdGhlIGFwcHJvcHJpYXRlIHZlcnNpb24gb2YgU1FMaXRlIGZvciB5b3VyIFdpbmRvd3Mgb3BlcmF0aW5nIHN5c3RlbSAoMzItYml0IG9yIDY0LWJpdCkuCi0gICBVbnppcCB0aGUgZG93bmxvYWRlZCBmaWxlIGFuZCBleHRyYWN0IHRoZSBjb250ZW50cyB0byBhIGRpcmVjdG9yeSBvbiB5b3VyIGNvbXB1dGVyLgotICAgQWRkIHRoZSBkaXJlY3Rvcnkgd2hlcmUgeW91IGV4dHJhY3RlZCBTUUxpdGUgdG8gdGhlIHN5c3RlbSdzIFBBVEggZW52aXJvbm1lbnQgdmFyaWFibGUuCgojIyMgSW5zdGFsbGluZyBTUUxpdGUgb24gTWFjCgotICAgSW5zdGFsbCBIb21lYnJldywgaWYgeW91IGRvbid0IGhhdmUgaXQgYWxyZWFkeSwgYnkgZm9sbG93aW5nIHRoZSBpbnN0cnVjdGlvbnMgb24gdGhlIEhvbWVicmV3IHdlYnNpdGU6IDxodHRwczovL2JyZXcuc2gvPgotICAgT3BlbiBhIHRlcm1pbmFsIHdpbmRvdyBhbmQgcnVuIHRoZSBmb2xsb3dpbmcgY29tbWFuZDogYnJldyBpbnN0YWxsIHNxbGl0ZQotICAgV2FpdCBmb3IgSG9tZWJyZXcgdG8gZG93bmxvYWQgYW5kIGluc3RhbGwgU1FMaXRlLgoKIyMjIEluc3RhbGxpbmcgU1FMaXRlIG9uIExpbnV4CgotICAgT3BlbiBhIHRlcm1pbmFsIHdpbmRvdyBhbmQgcnVuIHRoZSBmb2xsb3dpbmcgY29tbWFuZCB0byB1cGRhdGUgdGhlIHBhY2thZ2UgbGlzdDoKCiAgICBbc3VkbyBhcHQtZ2V0IHVwZGF0ZV17c3R5bGU9ImZvbnQtZmFtaWx5OkNvdXJpZXIifQoKLSAgIFJ1biB0aGUgZm9sbG93aW5nIGNvbW1hbmQgdG8gaW5zdGFsbCBTUUxpdGU6CgogICAgW3N1ZG8gYXB0LWdldCBpbnN0YWxsIHNxbGl0ZTNde3N0eWxlPSJmb250LWZhbWlseTpDb3VyaWVyIn0KCi0gICBXYWl0IGZvciB0aGUgaW5zdGFsbGF0aW9uIHRvIGNvbXBsZXRlLgoKQWZ0ZXIgaW5zdGFsbGF0aW9uLCB5b3UgY2FuIHN0YXJ0IHVzaW5nIFNRTGl0ZSBieSBydW5uaW5nIHRoZSBbc3FsaXRlM117c3R5bGU9ImZvbnQtZmFtaWx5OkNvdXJpZXIifSBjb21tYW5kIGluIHlvdXIgdGVybWluYWwgb3IgY29tbWFuZCBwcm9tcHQuIFRoaXMgd2lsbCBsYXVuY2ggdGhlIFNRTGl0ZSBzaGVsbCwgd2hlcmUgeW91IGNhbiBjcmVhdGUsIG9wZW4sIGFuZCBtYW5pcHVsYXRlIFNRTGl0ZSBkYXRhYmFzZXMuCgojIyMgQ2xvdWQgU1FMaXRlCgpBcyBhbiBhbHRlcm5hdGl2ZSB0byBpbnN0YWxsaW5nIFNRTGl0ZSBsb2NhbGx5LCB5b3UgY2FuIHVwbG9hZCBTUUxpdGUgZGF0YWJhc2UgZmlsZXMgdG8gW3NxbGl0ZW9ubGluZS5jb21dKGh0dHA6Ly9zcWxpdGVvbmxpbmUuY29tKSwgb3IsIHVzZSBbc3FsaXRlb25saW5lLmNvbV0oaHR0cDovL3NxbGl0ZW9ubGluZS5jb20pIHRvIGNyZWF0ZSBkYXRhYmFzZXMsIHJ1biBzY3JpcHRzLCBhbmQgZG93bmxvYWQgZGF0YWJhc2UgZmlsZXMuCgojIyBDcmVhdGluZyBhIE5ldyBEYXRhYmFzZQoKQ3JlYXRpbmcgYSBuZXcgZGF0YWJhc2UgaXMgU1FMaXRlIGlzIHNpbXBsZTogb3BlbiBhIGRhdGFiYXNlIGZpbGUgdGhhdCBkb2VzIG5vdCBleGlzdCBhbmQgU1FMaXRlIHdpbGwgY3JlYXRlIGEgbmV3IGRhdGFiYXNlIHdpdGggdGhhdCBmaWxlIG5hbWUuCgpbJSBzcWxpdGUzIGN1c3RvbWVyREIuc3FsaXRlZGJde3N0eWxlPSJmb250LWZhbWlseTpDb3VyaWVyIn0KClNRTGl0ZSBkYXRhYmFzZSBmaWxlcyBjYW4gaGF2ZSBhbnkgZXh0ZW5zaW9uLCBidXQgKi5zcWxpdGVkYiogYW5kICouZGIqIGFyZSBtb3N0IGNvbW1vbi4KCiMjIFdvcmtlZCBFeGFtcGxlCgpJbiB0aGUgd29ya2VkIGV4YW1wbGUgYmVsb3csIHdlIGNyZWF0ZSBhIG5ldyBkYXRhYmFzZSB1c2luZyBhIGNyZWF0aW9uIHNjcmlwdCB0aHJvdWdoIHRoZSBtYW5hZ2VtZW50IGNvbnNvbGUgb3MgU1FMaXRlLiBUaGUgc2NyaXB0IGlzIGdlbmVyaWMgYW5kIHN0YW5kYXJkIFNRTCwgc28gaXQgd2lsbCB3b3JrIGp1c3QgYXMgd2VsbCBvbiBhbnkgb3RoZXIgcmVsYXRpb25hbCBkYXRhYmFzZSwgaW5jbHVkaW5nIE15U1FMLCBPcmFjbGUsIGFuZCBTUUwgU2VydmVyLiBBZnRlciBjcmVhdGlvbiBvZiB0aGUgZGF0YWJhc2UsIHNhbXBsZSBkYXRhIGlzIGFkZGVkIHRvIHRoZSBkYXRhYmFzZSB2aWEgdGhlIHNjcmlwdCwgYWx0aG91Z2ggdGhpcyBjb3VsZCBoYXZlIGFsc28gYmVlbiBkb25lIHZpYSBpbXBvcnRzIG9mIENTViBmaWxlcy4gRmluYWxseSwgd2UgZXhlY3V0ZSBhIHNldCBvZiBxdWVyaWVzIGFnYWluc3QgdGhlIHNhbXBsZSBkYXRhIGluIHRoZSBkYXRhYmFzZS4KCiMjIyBDcmVhdGUgRGF0YWJhc2UKCkRvd25sb2FkIHRoZSBvcmdhbml6YXRpb24gZGF0YWJhc2UgY3JlYXRpb24gc2NyaXB0OiBbY3JlYXRlLW9yZ2RiLnNxbF0oY3JlYXRlLW9yZ2RiLnNxbCkuIEEgc2NyaXB0IGlzIGEgcGxhaW4gdGV4dCBmaWxlIGNvbnRhaW5pbmcgU1FMIHN0YXRlbWVudHMuCgpVc2luZyBlaXRoZXIgdGhlIGNvbW1hbmQgbGluZSB0b29scyAqc3FsaXRlMyogb3IgdGhlIFtjbG91ZCB2ZXJzaW9uIG9mIFNRTGl0ZV0oaHR0cDovL3NxbGl0ZW9ubGluZS5jb20pLCBzb3VyY2UgKHJ1bikgdGhlIHNjcmlwdCB0byBleGVjdXRlIGFsbCBvZiB0aGUgU1FMIHN0YXRlbWVudHMgaW4gdGhlIHNjcmlwdC4gVGhpcyB3aWxsIGNyZWF0ZSB0aGUgZGF0YWJhc2Ugd2l0aCBzYW1wbGUgZGF0YS4KCkluc3BlY3QgdGhlIHRhYmxlcyBpbiB0aGUgZGF0YWJhc2UgZWl0aGVyIGJ5IHN0dWR5aW5nIHRoZSBTUUwgY3JlYXRpb24gY29kZSBvciBsaXN0aW5nIHRoZSB0YWJsZXMuIEl0IGlzIGEgdXNlZnVsIHByYWN0aWNlIHRvIHZpc3VhbGl6ZSB0aGUgZGF0YWJhc2Ugc3RydWN0dXJlIGJ5IGRyYXdpbmcgYW4gRW50aXR5LVJlbGF0aW9uc2hpcCBvciBVTUwgZGlhZ3JhbS4KClRoZSB0dXRvcmlhbCBiZWxvdyB3aWxsIHNob3cgeW91IGhvdyB0byBjcmVhdGUgdGhlIGRhdGFiYXNlLCBjb25uZWN0IHRvIGl0LCBhbmQgaW5zcGVjdCB0aGUgdGFibGVzLiBXYXRjaCBpdCBvbmx5IGFmdGVyIHlvdSBhdHRlbXB0ZWQgdG8gZG8gdGhpcyB5b3Vyc2VsZi4gSXQgYXNzdW1lcyB0aGF0IHlvdSBoYXZlIHRoZSBTUUxpdGUgdG9vbHMgaW5zdGFsbGVkIGxvY2FsbHkgb24geW91ciBjb21wdXRlci4KCjxpZnJhbWUgc3JjPSJodHRwczovL3BsYXllci52aW1lby5jb20vdmlkZW8vNzk5OTg5OTU5P2g9MDYzNTdjODA1ZiZhbXA7dGl0bGU9MCZhbXA7YnlsaW5lPTAmYW1wO3BvcnRyYWl0PTAmYW1wO3NwZWVkPTAmYW1wO2JhZGdlPTAmYW1wO2F1dG9wYXVzZT0wJmFtcDtwbGF5ZXJfaWQ9MCZhbXA7YXBwX2lkPTU4NDc5IiB3aWR0aD0iNDgwIiBoZWlnaHQ9IjMxOCIgZnJhbWVib3JkZXI9IjEiIGFsbG93PSJhdXRvcGxheTsgZnVsbHNjcmVlbjsgcGljdHVyZS1pbi1waWN0dXJlIiBhbGxvd2Z1bGxzY3JlZW4gdGl0bGU9Ildvcmtpbmcgd2l0aCBTUUxpdGUgTWFuYWdlbWVudCBDb25zb2xlIiBkYXRhLWV4dGVybmFsPSIxIj4KCjwvaWZyYW1lPgoKIyMjIEJ1aWxkIFF1ZXJpZXMKCk9uY2UgeW91IGFyZSBmYW1pbGlhciB3aXRoIHRoZSBkYXRhYmFzZSwgdXNlIHRoZSBpbnRlcmFjdGl2ZSBjb21tYW5kIGxpbmUgdG9vbCB0byBidWlsZCBTUUwgcXVlcmllcyBmb3IgdGhlIGZvbGxvd2luZyBxdWVzdGlvbnM6CgojIyMjIFF1ZXJ5IDEKCipGaW5kIHRoZSBkaXN0aW5jdCBudW1iZXIgb2Ygd29ya2VycyB3aG8gd29yayBpbiB0aGUgSFIgZGVwYXJ0bWVudCBhbmQgd2hvIGVhcm4gbW9yZSB0aGFuIOKCuTIyNSwwMDAuKgoKYGBgez1odG1sfQo8cD4KICA8YSBjbGFzcz0iYnRuIGJ0bi1wcmltYXJ5IiBkYXRhLXRvZ2dsZT0iY29sbGFwc2UiIGhyZWY9IiNjb2xsYXBzZS1saWQtNzAtODAzLVExIiByb2xlPSJidXR0b24iIGFyaWEtZXhwYW5kZWQ9ImZhbHNlIiBhcmlhLWNvbnRyb2xzPSJjb2xsYXBzZUV4YW1wbGUiPgogICAgQ2xpY2sgZm9yIFNvbHV0aW9uCiAgPC9hPgo8L3A+CjxkaXYgY2xhc3M9ImNvbGxhcHNlIiBpZD0iY29sbGFwc2UtbGlkLTcwLTgwMy1RMSI+CiAgPGRpdiBjbGFzcz0iY2FyZCBjYXJkLWJvZHkiPgogICAgPHByZT4Kc2VsZWN0IGRpc3RpbmN0IGNvdW50KCopIGFzICdOdW1Xb3JrZXJzJwogIGZyb20gV29ya2VyIGFzIHcKIHdoZXJlIHcuZGVwYXJ0bWVudCA9ICdIUicKICAgYW5kIHcuc2FsYXJ5ID4gMjUwMDAwOwogICAgPC9wcmU+CiAgPC9kaXY+CjwvZGl2PgpgYGAKIyMjIyBRdWVyeSAyCgoqRmluZCB0aGUgbGFzdCBuYW1lIGFuZCB0aXRsZSBvZiBhbGwgd29ya2VycyBhbmQgdGhlIGRlcGFydG1lbnQgdGhleSB3b3JrIGluIHdobyBlYXJuIGxlc3MgdGhhbiB0aGUgYXZlcmFnZSBzYWxhcnkuKgoKYGBgez1odG1sfQo8cD4KICA8YSBjbGFzcz0iYnRuIGJ0bi1wcmltYXJ5IiBkYXRhLXRvZ2dsZT0iY29sbGFwc2UiIGhyZWY9IiNjb2xsYXBzZS1saWQtNzAtODAzLVEyIiByb2xlPSJidXR0b24iIGFyaWEtZXhwYW5kZWQ9ImZhbHNlIiBhcmlhLWNvbnRyb2xzPSJjb2xsYXBzZUV4YW1wbGUiPgogICAgQ2xpY2sgZm9yIFNvbHV0aW9uCiAgPC9hPgo8L3A+CjxkaXYgY2xhc3M9ImNvbGxhcHNlIiBpZD0iY29sbGFwc2UtbGlkLTcwLTgwMy1RMiI+CiAgPGRpdiBjbGFzcz0iY2FyZCBjYXJkLWJvZHkiPgogICAgPHByZT4Kc2VsZWN0IGxhc3RfbmFtZSwgd29ya2VyX3RpdGxlCiAgZnJvbSBXb3JrZXIgQVMgdyBKT0lOIFRpdGxlIEFTIHQgT04gKHcuV09SS0VSX0lEID0gdC5XT1JLRVJfUkVGX0lEKQogICBhbmQgdy5zYWxhcnkgPCAoc2VsZWN0IGF2ZyhzYWxhcnkpIGZyb20gV29ya2VyKTsKICAgIDwvcHJlPgogIDwvZGl2Pgo8L2Rpdj4KYGBgCiMjIyMgUXVlcnkgMwoKKldoYXQgaXMgdGhlIGF2ZXJhZ2Ugc2FsYXJ5IHBhaWQgZm9yIGFsbCB3b3JrZXJzIGluIGVhY2ggZGVwYXJ0bWVudD8gTGlzdCB0aGUgZGVwYXJ0bWVudCwgdGhlIGF2ZXJhZ2Ugc2FsYXJ5IGZvciB0aGUgZGVwYXJ0bWVudCwgYW5kIHRoZSBudW1iZXIgb2Ygd29ya2VycyBpbiBlYWNoIGRlcGFydG1lbnQuIE5hbWUgdGhlIGF2ZXJhZ2UgY29sdW1uICdBdmdTYWwnIGFuZCB0aGUgbnVtYmVyIG9mIHdvcmtlcnMgY29sdW1uIHRvICdOdW0nLioKCmBgYHs9aHRtbH0KPHA+CiAgPGEgY2xhc3M9ImJ0biBidG4tcHJpbWFyeSIgZGF0YS10b2dnbGU9ImNvbGxhcHNlIiBocmVmPSIjY29sbGFwc2UtbGlkLTcwLTgwMy1RMyIgcm9sZT0iYnV0dG9uIiBhcmlhLWV4cGFuZGVkPSJmYWxzZSIgYXJpYS1jb250cm9scz0iY29sbGFwc2VFeGFtcGxlIj4KICAgIENsaWNrIGZvciBTb2x1dGlvbgogIDwvYT4KPC9wPgo8ZGl2IGNsYXNzPSJjb2xsYXBzZSIgaWQ9ImNvbGxhcHNlLWxpZC03MC04MDMtUTMiPgogIDxkaXYgY2xhc3M9ImNhcmQgY2FyZC1ib2R5Ij4KICAgIDxwcmU+CnNlbGVjdCBkZXBhcnRtZW50LCBBVkcoc2FsYXJ5KSBhcyAnQXZnU2FsYXJ5JywgY291bnQoKikgYXMgJ051bVdvcmtlcnMnCiAgZnJvbSBXb3JrZXIKIGdyb3VwIGJ5IGRlcGFydG1lbnQ7CiAgICA8L3ByZT4KICA8L2Rpdj4KPC9kaXY+CmBgYAojIyMjIFF1ZXJ5IDQKCipXaGF0IGlzIHRoZSB0b3RhbCBjb21wZW5zYXRpb24gZm9yIGVhY2ggd29ya2VyIChzYWxhcnkgYW5kIGJvbnVzKSBvbiBhIHBlciBtb250aGx5IGJhc2lzPyBMaXN0IHRoZSBuYW1lIG9mIHRoZSB3b3JrZXIsIHRoZWlyIHRpdGxlLCBhbmQgdGhlIHRoZWlyIG1vbnRobHkgY29tcGVuc2F0aW9uIChhbm51YWwgY29tcGVuc2F0aW9uIGRpdmlkZWQgYnkgMTIpLiBDaGFuZ2UgdGhlIGhlYWRlciBmb3IgY29tcGVuc2F0aW9uIHRvICdNb250aGx5Q29tcCcgYW5kIHJvdW5kIGl0IHRvIHRoZSBuZWFyZXN0IHdob2xlIG51bWJlci4qCgpgYGB7PWh0bWx9CjxwPgogIDxhIGNsYXNzPSJidG4gYnRuLXByaW1hcnkiIGRhdGEtdG9nZ2xlPSJjb2xsYXBzZSIgaHJlZj0iI2NvbGxhcHNlLWxpZC03MC04MDMtUTQiIHJvbGU9ImJ1dHRvbiIgYXJpYS1leHBhbmRlZD0iZmFsc2UiIGFyaWEtY29udHJvbHM9ImNvbGxhcHNlRXhhbXBsZSI+CiAgICBDbGljayBmb3IgU29sdXRpb24KICA8L2E+CjwvcD4KPGRpdiBjbGFzcz0iY29sbGFwc2UiIGlkPSJjb2xsYXBzZS1saWQtNzAtODAzLVE0Ij4KICA8ZGl2IGNsYXNzPSJjYXJkIGNhcmQtYm9keSI+CiAgICA8cHJlPgpzZWxlY3QgbGFzdF9uYW1lLCAoKHNhbGFyeSArIGJvbnVzX2Ftb3VudCkgLyAxMikgYXMgJ01vbnRobHlDb21wJwogIGZyb20gV29ya2VyIGFzIHcgam9pbiBCb251cyBhcyBiIG9uICh3LldPUktFUl9JRCA9IGIuV09SS0VSX1JFRl9JRCkKICAgIDwvcHJlPgogIDwvZGl2Pgo8L2Rpdj4KYGBgCiMjIyMgUXVlcnkgNQoKKkxpc3QgdGhlIGZ1bGwgbmFtZXMgb2YgYWxsIHdvcmtlcnMgaW4gYWxsIGNhcGl0YWwgbGV0dGVycyB3aG8gZGlkIG5vdCBnZXQgYSBib251cy4qCgpgYGB7PWh0bWx9CjxwPgogIDxhIGNsYXNzPSJidG4gYnRuLXByaW1hcnkiIGRhdGEtdG9nZ2xlPSJjb2xsYXBzZSIgaHJlZj0iI2NvbGxhcHNlLWxpZC03MC04MDMtUTUiIHJvbGU9ImJ1dHRvbiIgYXJpYS1leHBhbmRlZD0iZmFsc2UiIGFyaWEtY29udHJvbHM9ImNvbGxhcHNlRXhhbXBsZSI+CiAgICBDbGljayBmb3IgU29sdXRpb24KICA8L2E+CjwvcD4KPGRpdiBjbGFzcz0iY29sbGFwc2UiIGlkPSJjb2xsYXBzZS1saWQtNzAtODAzLVE1Ij4KICA8ZGl2IGNsYXNzPSJjYXJkIGNhcmQtYm9keSI+CiAgICA8cHJlPgpzZWxlY3QgdXBwZXIobGFzdF9uYW1lIHx8ICIsICIgfHwgZmlyc3RfbmFtZSkgYXMgJ0Z1bGxOYW1lJwogIGZyb20gV29ya2VyCiB3aGVyZSB3b3JrZXJfaWQgbm90IGluIChzZWxlY3Qgd29ya2VyX3JlZl9pZCBmcm9tIEJvbnVzKQogb3JkZXIgYnkgbGFzdF9uYW1lOwogICAgPC9wcmU+CiAgPC9kaXY+CjwvZGl2PgpgYGAKIyMjIyBRdWVyeSA2CgoqV2hhdCBhcmUgdGhlIGZ1bGwgbmFtZXMgb2YgYWxsIHdvcmtlcnMgd2hvIGhhdmUgJ01hbmFnZXInIGluIHRoZWlyIHRpdGxlLiBEbyBub3QgImhhcmQgY29kZSIgdGhlIHRpdGxlczsgdXNlIHN0cmluZyBzZWFyY2hpbmcuKgoKYGBgez1odG1sfQo8cD4KICA8YSBjbGFzcz0iYnRuIGJ0bi1wcmltYXJ5IiBkYXRhLXRvZ2dsZT0iY29sbGFwc2UiIGhyZWY9IiNjb2xsYXBzZS1saWQtNzAtODAzLVE2IiByb2xlPSJidXR0b24iIGFyaWEtZXhwYW5kZWQ9ImZhbHNlIiBhcmlhLWNvbnRyb2xzPSJjb2xsYXBzZUV4YW1wbGUiPgogICAgQ2xpY2sgZm9yIFNvbHV0aW9uCiAgPC9hPgo8L3A+CjxkaXYgY2xhc3M9ImNvbGxhcHNlIiBpZD0iY29sbGFwc2UtbGlkLTcwLTgwMy1RNiI+CiAgPGRpdiBjbGFzcz0iY2FyZCBjYXJkLWJvZHkiPgogICAgPHByZT4Kc2VsZWN0IHVwcGVyKGxhc3RfbmFtZSB8fCAiLCAiIHx8IGZpcnN0X25hbWUpIGFzICdGdWxsTmFtZScsIHQuV09SS0VSX1RJVExFCiAgZnJvbSBXb3JrZXIgdywgVGl0bGUgdCAKIFdIRVJFIHcuV09SS0VSX0lEID0gdC5XT1JLRVJfUkVGX0lECiAgIGFuZCB0LldPUktFUl9USVRMRSBMSUtFICclTWFuYWdlciUnOwogICAgPC9wcmU+CiAgPC9kaXY+CjwvZGl2PgpgYGAKIyMjIFR1dG9yaWFsCgo8aWZyYW1lIHNyYz0iaHR0cHM6Ly9wbGF5ZXIudmltZW8uY29tL3ZpZGVvLzgwMDUyODE1Nz9oPWUzNTk4ODUwMWYmYW1wO3RpdGxlPTAmYW1wO2J5bGluZT0wJmFtcDtwb3J0cmFpdD0wJmFtcDtzcGVlZD0wJmFtcDtiYWRnZT0wJmFtcDthdXRvcGF1c2U9MCZhbXA7cGxheWVyX2lkPTAmYW1wO2FwcF9pZD01ODQ3OSIgd2lkdGg9IjQ4MCIgaGVpZ2h0PSIzMDUiIGZyYW1lYm9yZGVyPSIwIiBhbGxvdz0iYXV0b3BsYXk7IGZ1bGxzY3JlZW47IHBpY3R1cmUtaW4tcGljdHVyZSIgYWxsb3dmdWxsc2NyZWVuIHRpdGxlPSJTUUwgUXVlcmllczogRXhhbXBsZXMiIGRhdGEtZXh0ZXJuYWw9IjEiPgoKPC9pZnJhbWU+CgojIyBDb25jbHVzaW9uCgpNYW5hZ2VtZW50IGNvbnNvbGVzLCBhdmFpbGFibGUgZm9yIGV2ZXJ5IGRhdGFiYXNlLCBhcmUgYW4gZXNzZW50aWFsIHRvb2wgZm9yIGRhdGFiYXNlIGRldmVsb3BtZW50IGFuZCBhZG1pbmlzdHJhdGlvbi4gU29tZSBhcmUgY29tbWFuZC1saW5lIG9yaWVudGVkIGFuZCBzb21lIGhhdmUgZ3JhcGhpY2FsIHVzZXIgaW50ZXJmYWNlcy4gU29tZSBldmVuIGFsbG93IGRhdGFiYXNlIGRlc2lnbiB0aHJvdWdoIGludGVncmF0ZWQgZGlhZ3JhbW1pbmcgdG9vbHMuCgpBc2lkZSBmcm9tIGFsbG93aW5nIHVzIHRvIGNyZWF0ZSBkYXRhYmFzZXMgYW5kIHBlcmZvcm0gKmFkIGhvYyogcXVlcmllcywgdGhlIHByb3ZpZGUgYSBudW1iZXIgb2YgYWRkaXRpb25hbCBiZW5lZml0cy4KCi0gICAqKkNlbnRyYWxpemVkIGNvbnRyb2wqKjogQSBtYW5hZ2VtZW50IGNvbnNvbGUgcHJvdmlkZXMgYSBjZW50cmFsaXplZCBpbnRlcmZhY2UgZm9yIG1hbmFnaW5nIGFuZCBtb25pdG9yaW5nIGEgZGF0YWJhc2UsIGFsbG93aW5nIGFkbWluaXN0cmF0b3JzIHRvIGNvbmZpZ3VyZSBhbmQgbW9uaXRvciB0aGUgZGF0YWJhc2UgbW9yZSBlYXNpbHkgYW5kIGVmZmljaWVudGx5LgoKLSAgICoqRWZmaWNpZW50IHBlcmZvcm1hbmNlIG1vbml0b3JpbmcqKjogQSBtYW5hZ2VtZW50IGNvbnNvbGUgcHJvdmlkZXMgcmVhbC10aW1lIG1vbml0b3Jpbmcgb2YgdGhlIGRhdGFiYXNlJ3MgcGVyZm9ybWFuY2UsIGVuYWJsaW5nIGFkbWluaXN0cmF0b3JzIHRvIHF1aWNrbHkgaWRlbnRpZnkgYW5kIHRyb3VibGVzaG9vdCBwZXJmb3JtYW5jZSBpc3N1ZXMuIFRoaXMgY2FuIGhlbHAgaW1wcm92ZSB0aGUgb3ZlcmFsbCBwZXJmb3JtYW5jZSBvZiB0aGUgZGF0YWJhc2UsIHJlZHVjaW5nIGRvd250aW1lIGFuZCBpbXByb3ZpbmcgdGhlIGVuZCB1c2VyIGV4cGVyaWVuY2UuCgotICAgKipFbmhhbmNlZCBzZWN1cml0eSoqOiBBIG1hbmFnZW1lbnQgY29uc29sZSBjYW4gaGVscCB0byBlbmhhbmNlIHRoZSBzZWN1cml0eSBvZiBhIGRhdGFiYXNlIGJ5IHByb3ZpZGluZyB0b29scyB0byBtYW5hZ2UgdXNlcnMgYW5kIHBlcm1pc3Npb25zLCBzZXQgdXAgYXVkaXRpbmcsIGFuZCBtb25pdG9yIHRoZSBkYXRhYmFzZSBmb3Igc3VzcGljaW91cyBhY3Rpdml0eS4gVGhpcyBjYW4gaGVscCBwcmV2ZW50IHVuYXV0aG9yaXplZCBhY2Nlc3MgdG8gdGhlIGRhdGFiYXNlIGFuZCBwcm90ZWN0IHNlbnNpdGl2ZSBkYXRhLgoKLSAgICoqQXV0b21hdGVkIGJhY2t1cCBhbmQgcmVjb3ZlcnkqKjogTWFueSBtYW5hZ2VtZW50IGNvbnNvbGVzIGluY2x1ZGUgdG9vbHMgZm9yIGF1dG9tYXRlZCBiYWNrdXAgYW5kIHJlY292ZXJ5IG9mIHRoZSBkYXRhYmFzZSwgaGVscGluZyB0byBlbnN1cmUgZGF0YSBpcyBwcm90ZWN0ZWQgaW4gdGhlIGV2ZW50IG9mIGEgZGlzYXN0ZXIgb3Igb3RoZXIgdW5mb3Jlc2VlbiBjaXJjdW1zdGFuY2VzLgoKLSAgICoqU2ltcGxpZmllZCBhZG1pbmlzdHJhdGlvbioqOiBBIG1hbmFnZW1lbnQgY29uc29sZSBjYW4gc2ltcGxpZnkgZGF0YWJhc2UgYWRtaW5pc3RyYXRpb24gYnkgcHJvdmlkaW5nIGEgZ3JhcGhpY2FsIHVzZXIgaW50ZXJmYWNlIHRoYXQgc2ltcGxpZmllcyBjb21wbGV4IGRhdGFiYXNlIHRhc2tzLiBUaGlzIGNhbiBoZWxwIHJlZHVjZSB0aGUgbmVlZCBmb3Igc3BlY2lhbGl6ZWQgc2tpbGxzIG9yIGtub3dsZWRnZSwgbWFraW5nIGl0IGVhc2llciBmb3IgYSB3aWRlciByYW5nZSBvZiBzdGFmZiB0byBtYW5hZ2UgYW5kIG1haW50YWluIHRoZSBkYXRhYmFzZS4KCk92ZXJhbGwsIGEgbWFuYWdlbWVudCBjb25zb2xlIGZvciBhIGRhdGFiYXNlIGNhbiBoZWxwIHN0cmVhbWxpbmUgZGF0YWJhc2UgbWFuYWdlbWVudCwgZmFjaWxpdGF0ZSAqYWQgaG9jKiBxdWVyeWluZywgaW1wcm92ZSBwZXJmb3JtYW5jZSBhbmQgc2VjdXJpdHksIGFuZCBzaW1wbGlmeSBhZG1pbmlzdHJhdGlvbiwgbWFraW5nIGl0IGFuIGVzc2VudGlhbCB0b29sIGZvciBkYXRhYmFzZSBkZXZlbG9wbWVudC4KClRoaXMgbGVzc29uIHNob3dlZCBob3cgdG8gaW5zdGFsbCBhbmQgdXNlIHRoZSBtYW5hZ2VtZW50IGNvbnNvbGUgZm9yIFNRTGl0ZS4KCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMgRmlsZXMgJiBSZXNvdXJjZXMKCmBgYHtyIHppcEZpbGVzLCBlY2hvPUZBTFNFfQp6aXBOYW1lID0gc3ByaW50ZigiTGVzc29uRmlsZXMtJXMtJXMuemlwIiwgCiAgICAgICAgICAgICAgICAgcGFyYW1zJGNhdGVnb3J5LAogICAgICAgICAgICAgICAgIHBhcmFtcyRudW1iZXIpCgp0ZXh0QUxpbmsgPSBwYXN0ZTAoIkFsbCBGaWxlcyBmb3IgTGVzc29uICIsIAogICAgICAgICAgICAgICBwYXJhbXMkY2F0ZWdvcnksIi4iLHBhcmFtcyRudW1iZXIpCgojIGRvd25sb2FkRmlsZXNMaW5rKCkgaXMgaW5jbHVkZWQgZnJvbSBfaW5zZXJ0MkRCLlIKa25pdHI6OnJhd19odG1sKGRvd25sb2FkRmlsZXNMaW5rKCIuIiwgemlwTmFtZSwgdGV4dEFMaW5rKSkKYGBgCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMjIFJlZmVyZW5jZXMKCltDb21tYW5kIExpbmUgU2hlbGwgRm9yIFNRTGl0ZV0oaHR0cHM6Ly93d3cuc3FsaXRlLm9yZy9jbGkuaHRtbCkKCiMjIEVycmF0YQoKTm9uZSBjb2xsZWN0ZWQgeWV0LiBMZXQgdXMga25vdy4KCmBgYHs9aHRtbH0KPHNjcmlwdCBzcmM9Imh0dHBzOi8vZm9ybS5qb3Rmb3JtLmNvbS9zdGF0aWMvZmVlZGJhY2syLmpzIiB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiPgogIG5ldyBKb3Rmb3JtRmVlZGJhY2soewogICAgZm9ybUlkOiAiMjEyMTg3MDcyNzg0MTU3IiwKICAgIGJ1dHRvblRleHQ6ICJGZWVkYmFjayIsCiAgICBiYXNlOiAiaHR0cHM6Ly9mb3JtLmpvdGZvcm0uY29tLyIsCiAgICBiYWNrZ3JvdW5kOiAiI0Y1OTIwMiIsCiAgICBmb250Q29sb3I6ICIjRkZGRkZGIiwKICAgIGJ1dHRvblNpZGU6ICJsZWZ0IiwKICAgIGJ1dHRvbkFsaWduOiAiY2VudGVyIiwKICAgIHR5cGU6IGZhbHNlLAogICAgd2lkdGg6IDcwMCwKICAgIGhlaWdodDogNTAwLAogICAgaXNDYXJkRm9ybTogZmFsc2UKICB9KTsKPC9zY3JpcHQ+CmBgYApgYGB7ciBjb2RlPXhmdW46OnJlYWRfdXRmOChwYXN0ZTAoaGVyZTo6aGVyZSgpLCcvUi9fZGVwbG95S25pdC5SJykpLCBpbmNsdWRlID0gRkFMU0V9CmBgYAo=