con <- dbConnect(RSQLite::SQLite(), "OrdersDB.sqlitedb.db")

Q1: What are the names and phone numbers of all shippers, sorted by name?

SELECT ShipperName, Phone 
FROM Shippers 
ORDER BY ShipperName 
LIMIT 10 

Q2: What are the number of customers for each country? List the country and the number of customers renamed to ‘NumCust’.

SELECT Country, COUNT(CUSTOMERID) AS NumCust 
FROM Customers 
GROUP BY Country 
LIMIT 10

Q3: List the number of products by supplier ID and name, ordered from most to least, restricted to those suppliers who sell at least five products.

SELECT s.SupplierID, s.SupplierName, COUNT(p.Productname) AS NumProducts 
FROM Suppliers s 
JOIN Products p ON (s.SupplierID = p.SupplierID) 
GROUP BY s.SupplierID,s.SupplierName 
HAVING COUNT(p.Productname) >= 5 
ORDER BY NumProducts DESC

Q4: Who placed the most recent order (by order date)? List the customer’s ID, customer name, contact name, and date.

SELECT c.CustomerID, c.CustomerName, c.ContactName, o.orderDate
FROM Customers c
JOIN Orders o ON (c.CustomerID = o.CustomerID)
ORDER BY o.OrderDate DESC
LIMIT 1

Q5: What are the total number of unique orders delivered by each shipper, ordered alphabetically by shipper name?

SELECT s.ShipperName, COUNT(DISTINCT o.OrderID) AS NumOrders
FROM Shippers s
JOIN Orders o ON (s.ShipperID = o.ShipperID)
GROUP BY s.ShipperName 
ORDER BY s.ShipperName 
LIMIT 10

Q6: How many employees never worked with a single customer, i.e., they appear in the Employees table but not in the Orders table?

SELECT COUNT(e.EmployeeID) AS NumEmployees
FROM Employees e
LEFT JOIN Orders o ON e.EmployeeID = o.EmployeeID
WHERE o.EmployeeID IS NULL

Q7: How many products contain “Louisiana” at the beginning of the name of the product?

SELECT COUNT(ProductID) as NumProducts
FROM Products
WHERE Productname LIKE "Louisiana%"

Q8: What is the total number of distinct countries to which at least one order was shipped?

SELECT COUNT(DISTINCT c.Country) AS NumCountries
FROM Orders o
JOIN Customers c ON o.CustomerID = c.CustomerID

Q9: What is the total amount (in terms of revenue) as well as the total number of orders sold by each employee? List the employee name, the total amount sold, and the total number of orders.

SELECT e.FirstName || ' ' || e.LastName AS EmployeeName,
       SUM(p.Price * od.Quantity) AS TotalAmount,
       COUNT(DISTINCT o.OrderID) AS TotalOrders
FROM Employees e
JOIN Orders o ON e.EmployeeID = o.EmployeeID
JOIN OrderDetails od ON o.OrderID = od.OrderID
JOIN Products p ON od.ProductID = p.ProductID
GROUP BY e.EmployeeID, e.LastName, e.FirstName
LIMIT 10

Q10: Which supplier sells the least number of different products but supplies at least one product?

SELECT s.SupplierID, s.SupplierName, COUNT(DISTINCT p.ProductID) AS NumProducts
FROM Suppliers s
JOIN Products p ON s.SupplierID = p.SupplierID
GROUP BY s.SupplierID, s.SupplierName
HAVING NumProducts = (
    SELECT MIN(cnt) 
    FROM (
        SELECT COUNT(DISTINCT ProductID) AS cnt 
        FROM Products 
        GROUP BY SupplierID
    )
)

Q11: Which product was ordered most often in terms of quantity ordered? List the product name and ID.

SELECT p.ProductID, p.ProductName, SUM(o.Quantity) AS TotalQuantity
FROM OrderDetails o
JOIN Products p ON o.ProductID = p.ProductID
GROUP BY p.ProductID, p.ProductName
ORDER BY TotalQuantity DESC
LIMIT 1

Q12: Which product generated the most revenue? List the product ID and name.

SELECT p.ProductID, p.Productname, SUM(o.Quantity * p.Price)  AS Revenue
FROM Products p
JOIN OrderDetails o ON (p.ProductID = o.ProductID)
GROUP BY p.ProductID, p.Productname
ORDER BY Revenue DESC
LIMIT 1

Q13: What is the total amount spent by all customers who do live in either Brazil, Mexico, or Canada?

SELECT SUM(od.Quantity * p.Price) AS TotalAmount
FROM Customers c
JOIN Orders o ON c.CustomerID = o.CustomerID
JOIN OrderDetails od ON o.OrderID = od.OrderID
JOIN Products p ON od.ProductID = p.ProductID
WHERE c.Country IN ('Brazil', 'Mexico', 'Canada')

Q14: What is the difference in spending between the country to which the most was sold versus the country to which the least was sold?

SELECT MAX(TotalAmount) - MIN(TotalAmount) AS DIFFERENCE
FROM (
      SELECT c.Country, SUM(od.Quantity * p.Price) AS TotalAmount
      FROM Customers c
      JOIN Orders o ON c.CustomerID = o.CustomerID
      JOIN OrderDetails od ON o.OrderID = od.OrderID
      JOIN Products p ON od.ProductID = p.ProductID
      GROUP BY c.country
)

Q15: Which country has the least number of customers?

SELECT Country, COUNT(CustomerID) AS NumCustomers
FROM Customers
GROUP BY Country
ORDER BY NumCustomers ASC
LIMIT 1

Q16: Which employee generated the most revenue (in terms of “dollar amount” sold)?

SELECT e.EmployeeID, e.LastName, e.FirstName, SUM(p.Price * od.Quantity) AS DollarAmount
FROM Employees e
JOIN Orders o ON e.EmployeeID = o.EmployeeID
JOIN OrderDetails od ON o.OrderID = od.OrderID
JOIN Products p ON od.ProductID = p.ProductID
GROUP BY e.EmployeeID, e.LastName, e.FirstName
ORDER BY DollarAmount DESC
LIMIT 1

Q17: Which customers (name and ID) have never bought anything?

SELECT c.CustomerID, c.CustomerName
FROM Customers c
LEFT JOIN Orders o ON c.CustomerID = o.CustomerID
WHERE o.OrderID IS NULL 
LIMIT 10

Q18: What is the average order total per country? List the country and the average order total.

SELECT c.Country, AVG(OrderTotal) AS AvgOrderTotal
FROM (
    SELECT o.OrderID, o.CustomerID, SUM(p.Price * od.Quantity) AS OrderTotal
    FROM Orders o
    JOIN OrderDetails od ON o.OrderID = od.OrderID
    JOIN Products p ON od.ProductID = p.ProductID
    GROUP BY o.OrderID, o.CustomerID
) sub
JOIN Customers c ON sub.CustomerID = c.CustomerID
GROUP BY c.Country
LIMIT 10

Q19: To which customer was the second most recent order sent? List the Order ID, customer name, and country to which the order was shipped.

SELECT o.OrderID, c.CustomerName, c.Country, o.OrderDate
FROM Customers c
JOIN Orders o ON c.CustomerID = o.CustomerID
ORDER BY o.OrderDate DESC
LIMIT 1
OFFSET 1

Q20: From how many different (unique) suppliers do the products come from that have been ordered at least five times?

SELECT COUNT(DISTINCT p.SupplierID) AS NumSuppliers
FROM Products p
WHERE p.ProductID IN (
    SELECT od.ProductID
    FROM OrderDetails od
    GROUP BY od.ProductID
    HAVING SUM(od.Quantity) >= 5
)
dbDisconnect(con)
LS0tCnRpdGxlOiAiQVNTSUdOTUVOVCAwNi4xOiBRdWVyeSBhIERhdGFiYXNlIHdpdGggU1FMIgphdXRob3I6ICJXYW5pLCBSdXNoaWtlc2giCmRhdGU6ICIyMDI2LTAyLTE0IgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0KbGlicmFyeShEQkkpCmxpYnJhcnkoUlNRTGl0ZSkKYGBgCgpgYGB7ciBjb25uZWN0aW9ufQpjb24gPC0gZGJDb25uZWN0KFJTUUxpdGU6OlNRTGl0ZSgpLCAiT3JkZXJzREIuc3FsaXRlZGIuZGIiKQpgYGAKCiMjIyBRMTogV2hhdCBhcmUgdGhlIG5hbWVzIGFuZCBwaG9uZSBudW1iZXJzIG9mIGFsbCBzaGlwcGVycywgc29ydGVkIGJ5IG5hbWU/CgpgYGB7c3FsIGNvbm5lY3Rpb249Y29ufQpTRUxFQ1QgU2hpcHBlck5hbWUsIFBob25lIApGUk9NIFNoaXBwZXJzIApPUkRFUiBCWSBTaGlwcGVyTmFtZSAKTElNSVQgMTAgCmBgYAoKIyMjIFEyOiBXaGF0IGFyZSB0aGUgbnVtYmVyIG9mIGN1c3RvbWVycyBmb3IgZWFjaCBjb3VudHJ5PyBMaXN0IHRoZSBjb3VudHJ5IGFuZCB0aGUgbnVtYmVyIG9mIGN1c3RvbWVycyByZW5hbWVkIHRvICdOdW1DdXN0Jy4KCmBgYHtzcWwgY29ubmVjdGlvbj1jb259ClNFTEVDVCBDb3VudHJ5LCBDT1VOVChDVVNUT01FUklEKSBBUyBOdW1DdXN0IApGUk9NIEN1c3RvbWVycyAKR1JPVVAgQlkgQ291bnRyeSAKTElNSVQgMTAKYGBgCgojIyMgUTM6IExpc3QgdGhlIG51bWJlciBvZiBwcm9kdWN0cyBieSBzdXBwbGllciBJRCBhbmQgbmFtZSwgb3JkZXJlZCBmcm9tIG1vc3QgdG8gbGVhc3QsIHJlc3RyaWN0ZWQgdG8gdGhvc2Ugc3VwcGxpZXJzIHdobyBzZWxsIGF0IGxlYXN0IGZpdmUgcHJvZHVjdHMuCgpgYGB7c3FsIGNvbm5lY3Rpb249Y29ufQpTRUxFQ1Qgcy5TdXBwbGllcklELCBzLlN1cHBsaWVyTmFtZSwgQ09VTlQocC5Qcm9kdWN0bmFtZSkgQVMgTnVtUHJvZHVjdHMgCkZST00gU3VwcGxpZXJzIHMgCkpPSU4gUHJvZHVjdHMgcCBPTiAocy5TdXBwbGllcklEID0gcC5TdXBwbGllcklEKSAKR1JPVVAgQlkgcy5TdXBwbGllcklELHMuU3VwcGxpZXJOYW1lIApIQVZJTkcgQ09VTlQocC5Qcm9kdWN0bmFtZSkgPj0gNSAKT1JERVIgQlkgTnVtUHJvZHVjdHMgREVTQwpgYGAKCiMjIyBRNDogV2hvIHBsYWNlZCB0aGUgbW9zdCByZWNlbnQgb3JkZXIgKGJ5IG9yZGVyIGRhdGUpPyBMaXN0IHRoZSBjdXN0b21lcidzIElELCBjdXN0b21lciBuYW1lLCBjb250YWN0IG5hbWUsIGFuZCBkYXRlLgoKYGBge3NxbCBjb25uZWN0aW9uPWNvbn0KU0VMRUNUIGMuQ3VzdG9tZXJJRCwgYy5DdXN0b21lck5hbWUsIGMuQ29udGFjdE5hbWUsIG8ub3JkZXJEYXRlCkZST00gQ3VzdG9tZXJzIGMKSk9JTiBPcmRlcnMgbyBPTiAoYy5DdXN0b21lcklEID0gby5DdXN0b21lcklEKQpPUkRFUiBCWSBvLk9yZGVyRGF0ZSBERVNDCkxJTUlUIDEKYGBgCgojIyMgUTU6IFdoYXQgYXJlIHRoZSB0b3RhbCBudW1iZXIgb2YgdW5pcXVlIG9yZGVycyBkZWxpdmVyZWQgYnkgZWFjaCBzaGlwcGVyLCBvcmRlcmVkIGFscGhhYmV0aWNhbGx5IGJ5IHNoaXBwZXIgbmFtZT8KCmBgYHtzcWwgY29ubmVjdGlvbj1jb259ClNFTEVDVCBzLlNoaXBwZXJOYW1lLCBDT1VOVChESVNUSU5DVCBvLk9yZGVySUQpIEFTIE51bU9yZGVycwpGUk9NIFNoaXBwZXJzIHMKSk9JTiBPcmRlcnMgbyBPTiAocy5TaGlwcGVySUQgPSBvLlNoaXBwZXJJRCkKR1JPVVAgQlkgcy5TaGlwcGVyTmFtZSAKT1JERVIgQlkgcy5TaGlwcGVyTmFtZSAKTElNSVQgMTAKYGBgCgojIyMgUTY6IEhvdyBtYW55IGVtcGxveWVlcyBuZXZlciB3b3JrZWQgd2l0aCBhIHNpbmdsZSBjdXN0b21lciwgaS5lLiwgdGhleSBhcHBlYXIgaW4gdGhlIEVtcGxveWVlcyB0YWJsZSBidXQgbm90IGluIHRoZSBPcmRlcnMgdGFibGU/CgpgYGB7c3FsIGNvbm5lY3Rpb249Y29ufQpTRUxFQ1QgQ09VTlQoZS5FbXBsb3llZUlEKSBBUyBOdW1FbXBsb3llZXMKRlJPTSBFbXBsb3llZXMgZQpMRUZUIEpPSU4gT3JkZXJzIG8gT04gZS5FbXBsb3llZUlEID0gby5FbXBsb3llZUlECldIRVJFIG8uRW1wbG95ZWVJRCBJUyBOVUxMCmBgYAoKIyMjIFE3OiBIb3cgbWFueSBwcm9kdWN0cyBjb250YWluICJMb3Vpc2lhbmEiIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIG5hbWUgb2YgdGhlIHByb2R1Y3Q/CgpgYGB7c3FsIGNvbm5lY3Rpb249Y29ufQpTRUxFQ1QgQ09VTlQoUHJvZHVjdElEKSBhcyBOdW1Qcm9kdWN0cwpGUk9NIFByb2R1Y3RzCldIRVJFIFByb2R1Y3RuYW1lIExJS0UgIkxvdWlzaWFuYSUiCmBgYAoKIyMjIFE4OiBXaGF0IGlzIHRoZSB0b3RhbCBudW1iZXIgb2YgZGlzdGluY3QgY291bnRyaWVzIHRvIHdoaWNoIGF0IGxlYXN0IG9uZSBvcmRlciB3YXMgc2hpcHBlZD8KCmBgYHtzcWwgY29ubmVjdGlvbj1jb259ClNFTEVDVCBDT1VOVChESVNUSU5DVCBjLkNvdW50cnkpIEFTIE51bUNvdW50cmllcwpGUk9NIE9yZGVycyBvCkpPSU4gQ3VzdG9tZXJzIGMgT04gby5DdXN0b21lcklEID0gYy5DdXN0b21lcklECmBgYAoKIyMjIFE5OiBXaGF0IGlzIHRoZSB0b3RhbCBhbW91bnQgKGluIHRlcm1zIG9mIHJldmVudWUpIGFzIHdlbGwgYXMgdGhlIHRvdGFsIG51bWJlciBvZiBvcmRlcnMgc29sZCBieSBlYWNoIGVtcGxveWVlPyBMaXN0IHRoZSBlbXBsb3llZSBuYW1lLCB0aGUgdG90YWwgYW1vdW50IHNvbGQsIGFuZCB0aGUgdG90YWwgbnVtYmVyIG9mIG9yZGVycy4KCmBgYHtzcWwgY29ubmVjdGlvbj1jb259ClNFTEVDVCBlLkZpcnN0TmFtZSB8fCAnICcgfHwgZS5MYXN0TmFtZSBBUyBFbXBsb3llZU5hbWUsCiAgICAgICBTVU0ocC5QcmljZSAqIG9kLlF1YW50aXR5KSBBUyBUb3RhbEFtb3VudCwKICAgICAgIENPVU5UKERJU1RJTkNUIG8uT3JkZXJJRCkgQVMgVG90YWxPcmRlcnMKRlJPTSBFbXBsb3llZXMgZQpKT0lOIE9yZGVycyBvIE9OIGUuRW1wbG95ZWVJRCA9IG8uRW1wbG95ZWVJRApKT0lOIE9yZGVyRGV0YWlscyBvZCBPTiBvLk9yZGVySUQgPSBvZC5PcmRlcklECkpPSU4gUHJvZHVjdHMgcCBPTiBvZC5Qcm9kdWN0SUQgPSBwLlByb2R1Y3RJRApHUk9VUCBCWSBlLkVtcGxveWVlSUQsIGUuTGFzdE5hbWUsIGUuRmlyc3ROYW1lCkxJTUlUIDEwCmBgYAoKIyMjIFExMDogV2hpY2ggc3VwcGxpZXIgc2VsbHMgdGhlIGxlYXN0IG51bWJlciBvZiBkaWZmZXJlbnQgcHJvZHVjdHMgYnV0IHN1cHBsaWVzIGF0IGxlYXN0IG9uZSBwcm9kdWN0PwoKYGBge3NxbCBjb25uZWN0aW9uPWNvbn0KU0VMRUNUIHMuU3VwcGxpZXJJRCwgcy5TdXBwbGllck5hbWUsIENPVU5UKERJU1RJTkNUIHAuUHJvZHVjdElEKSBBUyBOdW1Qcm9kdWN0cwpGUk9NIFN1cHBsaWVycyBzCkpPSU4gUHJvZHVjdHMgcCBPTiBzLlN1cHBsaWVySUQgPSBwLlN1cHBsaWVySUQKR1JPVVAgQlkgcy5TdXBwbGllcklELCBzLlN1cHBsaWVyTmFtZQpIQVZJTkcgTnVtUHJvZHVjdHMgPSAoCiAgICBTRUxFQ1QgTUlOKGNudCkgCiAgICBGUk9NICgKICAgICAgICBTRUxFQ1QgQ09VTlQoRElTVElOQ1QgUHJvZHVjdElEKSBBUyBjbnQgCiAgICAgICAgRlJPTSBQcm9kdWN0cyAKICAgICAgICBHUk9VUCBCWSBTdXBwbGllcklECiAgICApCikKYGBgCgojIyMgUTExOiBXaGljaCBwcm9kdWN0IHdhcyBvcmRlcmVkIG1vc3Qgb2Z0ZW4gaW4gdGVybXMgb2YgcXVhbnRpdHkgb3JkZXJlZD8gTGlzdCB0aGUgcHJvZHVjdCBuYW1lIGFuZCBJRC4KCmBgYHtzcWwgY29ubmVjdGlvbj1jb259ClNFTEVDVCBwLlByb2R1Y3RJRCwgcC5Qcm9kdWN0TmFtZSwgU1VNKG8uUXVhbnRpdHkpIEFTIFRvdGFsUXVhbnRpdHkKRlJPTSBPcmRlckRldGFpbHMgbwpKT0lOIFByb2R1Y3RzIHAgT04gby5Qcm9kdWN0SUQgPSBwLlByb2R1Y3RJRApHUk9VUCBCWSBwLlByb2R1Y3RJRCwgcC5Qcm9kdWN0TmFtZQpPUkRFUiBCWSBUb3RhbFF1YW50aXR5IERFU0MKTElNSVQgMQpgYGAKCiMjIyBRMTI6IFdoaWNoIHByb2R1Y3QgZ2VuZXJhdGVkIHRoZSBtb3N0IHJldmVudWU/IExpc3QgdGhlIHByb2R1Y3QgSUQgYW5kIG5hbWUuCgpgYGB7c3FsIGNvbm5lY3Rpb249Y29ufQpTRUxFQ1QgcC5Qcm9kdWN0SUQsIHAuUHJvZHVjdG5hbWUsIFNVTShvLlF1YW50aXR5ICogcC5QcmljZSkgIEFTIFJldmVudWUKRlJPTSBQcm9kdWN0cyBwCkpPSU4gT3JkZXJEZXRhaWxzIG8gT04gKHAuUHJvZHVjdElEID0gby5Qcm9kdWN0SUQpCkdST1VQIEJZIHAuUHJvZHVjdElELCBwLlByb2R1Y3RuYW1lCk9SREVSIEJZIFJldmVudWUgREVTQwpMSU1JVCAxCmBgYAoKIyMjIFExMzogV2hhdCBpcyB0aGUgdG90YWwgYW1vdW50IHNwZW50IGJ5IGFsbCBjdXN0b21lcnMgd2hvIGRvIGxpdmUgaW4gZWl0aGVyIEJyYXppbCwgTWV4aWNvLCBvciBDYW5hZGE/CgpgYGB7c3FsIGNvbm5lY3Rpb249Y29ufQpTRUxFQ1QgU1VNKG9kLlF1YW50aXR5ICogcC5QcmljZSkgQVMgVG90YWxBbW91bnQKRlJPTSBDdXN0b21lcnMgYwpKT0lOIE9yZGVycyBvIE9OIGMuQ3VzdG9tZXJJRCA9IG8uQ3VzdG9tZXJJRApKT0lOIE9yZGVyRGV0YWlscyBvZCBPTiBvLk9yZGVySUQgPSBvZC5PcmRlcklECkpPSU4gUHJvZHVjdHMgcCBPTiBvZC5Qcm9kdWN0SUQgPSBwLlByb2R1Y3RJRApXSEVSRSBjLkNvdW50cnkgSU4gKCdCcmF6aWwnLCAnTWV4aWNvJywgJ0NhbmFkYScpCmBgYAoKIyMjIFExNDogV2hhdCBpcyB0aGUgZGlmZmVyZW5jZSBpbiBzcGVuZGluZyBiZXR3ZWVuIHRoZSBjb3VudHJ5IHRvIHdoaWNoIHRoZSBtb3N0IHdhcyBzb2xkIHZlcnN1cyB0aGUgY291bnRyeSB0byB3aGljaCB0aGUgbGVhc3Qgd2FzIHNvbGQ/CgpgYGB7c3FsIGNvbm5lY3Rpb249Y29ufQpTRUxFQ1QgTUFYKFRvdGFsQW1vdW50KSAtIE1JTihUb3RhbEFtb3VudCkgQVMgRElGRkVSRU5DRQpGUk9NICgKICAgICAgU0VMRUNUIGMuQ291bnRyeSwgU1VNKG9kLlF1YW50aXR5ICogcC5QcmljZSkgQVMgVG90YWxBbW91bnQKICAgICAgRlJPTSBDdXN0b21lcnMgYwogICAgICBKT0lOIE9yZGVycyBvIE9OIGMuQ3VzdG9tZXJJRCA9IG8uQ3VzdG9tZXJJRAogICAgICBKT0lOIE9yZGVyRGV0YWlscyBvZCBPTiBvLk9yZGVySUQgPSBvZC5PcmRlcklECiAgICAgIEpPSU4gUHJvZHVjdHMgcCBPTiBvZC5Qcm9kdWN0SUQgPSBwLlByb2R1Y3RJRAogICAgICBHUk9VUCBCWSBjLmNvdW50cnkKKQpgYGAKCiMjIyBRMTU6IFdoaWNoIGNvdW50cnkgaGFzIHRoZSBsZWFzdCBudW1iZXIgb2YgY3VzdG9tZXJzPwoKYGBge3NxbCBjb25uZWN0aW9uPWNvbn0KU0VMRUNUIENvdW50cnksIENPVU5UKEN1c3RvbWVySUQpIEFTIE51bUN1c3RvbWVycwpGUk9NIEN1c3RvbWVycwpHUk9VUCBCWSBDb3VudHJ5Ck9SREVSIEJZIE51bUN1c3RvbWVycyBBU0MKTElNSVQgMQpgYGAKCiMjIyBRMTY6IFdoaWNoIGVtcGxveWVlIGdlbmVyYXRlZCB0aGUgbW9zdCByZXZlbnVlIChpbiB0ZXJtcyBvZiAiZG9sbGFyIGFtb3VudCIgc29sZCk/CgpgYGB7c3FsIGNvbm5lY3Rpb249Y29ufQpTRUxFQ1QgZS5FbXBsb3llZUlELCBlLkxhc3ROYW1lLCBlLkZpcnN0TmFtZSwgU1VNKHAuUHJpY2UgKiBvZC5RdWFudGl0eSkgQVMgRG9sbGFyQW1vdW50CkZST00gRW1wbG95ZWVzIGUKSk9JTiBPcmRlcnMgbyBPTiBlLkVtcGxveWVlSUQgPSBvLkVtcGxveWVlSUQKSk9JTiBPcmRlckRldGFpbHMgb2QgT04gby5PcmRlcklEID0gb2QuT3JkZXJJRApKT0lOIFByb2R1Y3RzIHAgT04gb2QuUHJvZHVjdElEID0gcC5Qcm9kdWN0SUQKR1JPVVAgQlkgZS5FbXBsb3llZUlELCBlLkxhc3ROYW1lLCBlLkZpcnN0TmFtZQpPUkRFUiBCWSBEb2xsYXJBbW91bnQgREVTQwpMSU1JVCAxCmBgYAoKIyMjIFExNzogV2hpY2ggY3VzdG9tZXJzIChuYW1lIGFuZCBJRCkgaGF2ZSBuZXZlciBib3VnaHQgYW55dGhpbmc/CgpgYGB7c3FsIGNvbm5lY3Rpb249Y29ufQpTRUxFQ1QgYy5DdXN0b21lcklELCBjLkN1c3RvbWVyTmFtZQpGUk9NIEN1c3RvbWVycyBjCkxFRlQgSk9JTiBPcmRlcnMgbyBPTiBjLkN1c3RvbWVySUQgPSBvLkN1c3RvbWVySUQKV0hFUkUgby5PcmRlcklEIElTIE5VTEwgCkxJTUlUIDEwCmBgYAoKIyMjIFExODogV2hhdCBpcyB0aGUgYXZlcmFnZSBvcmRlciB0b3RhbCBwZXIgY291bnRyeT8gTGlzdCB0aGUgY291bnRyeSBhbmQgdGhlIGF2ZXJhZ2Ugb3JkZXIgdG90YWwuCgpgYGB7c3FsIGNvbm5lY3Rpb249Y29ufQpTRUxFQ1QgYy5Db3VudHJ5LCBBVkcoT3JkZXJUb3RhbCkgQVMgQXZnT3JkZXJUb3RhbApGUk9NICgKICAgIFNFTEVDVCBvLk9yZGVySUQsIG8uQ3VzdG9tZXJJRCwgU1VNKHAuUHJpY2UgKiBvZC5RdWFudGl0eSkgQVMgT3JkZXJUb3RhbAogICAgRlJPTSBPcmRlcnMgbwogICAgSk9JTiBPcmRlckRldGFpbHMgb2QgT04gby5PcmRlcklEID0gb2QuT3JkZXJJRAogICAgSk9JTiBQcm9kdWN0cyBwIE9OIG9kLlByb2R1Y3RJRCA9IHAuUHJvZHVjdElECiAgICBHUk9VUCBCWSBvLk9yZGVySUQsIG8uQ3VzdG9tZXJJRAopIHN1YgpKT0lOIEN1c3RvbWVycyBjIE9OIHN1Yi5DdXN0b21lcklEID0gYy5DdXN0b21lcklECkdST1VQIEJZIGMuQ291bnRyeQpMSU1JVCAxMApgYGAKCiMjIyBRMTk6IFRvIHdoaWNoIGN1c3RvbWVyIHdhcyB0aGUgc2Vjb25kIG1vc3QgcmVjZW50IG9yZGVyIHNlbnQ/IExpc3QgdGhlIE9yZGVyIElELCBjdXN0b21lciBuYW1lLCBhbmQgY291bnRyeSB0byB3aGljaCB0aGUgb3JkZXIgd2FzIHNoaXBwZWQuCgpgYGB7c3FsIGNvbm5lY3Rpb249Y29ufQpTRUxFQ1Qgby5PcmRlcklELCBjLkN1c3RvbWVyTmFtZSwgYy5Db3VudHJ5LCBvLk9yZGVyRGF0ZQpGUk9NIEN1c3RvbWVycyBjCkpPSU4gT3JkZXJzIG8gT04gYy5DdXN0b21lcklEID0gby5DdXN0b21lcklECk9SREVSIEJZIG8uT3JkZXJEYXRlIERFU0MKTElNSVQgMQpPRkZTRVQgMQpgYGAKCiMjIyBRMjA6IEZyb20gaG93IG1hbnkgZGlmZmVyZW50ICh1bmlxdWUpIHN1cHBsaWVycyBkbyB0aGUgcHJvZHVjdHMgY29tZSBmcm9tIHRoYXQgaGF2ZSBiZWVuIG9yZGVyZWQgYXQgbGVhc3QgZml2ZSB0aW1lcz8KCmBgYHtzcWwgY29ubmVjdGlvbj1jb259ClNFTEVDVCBDT1VOVChESVNUSU5DVCBwLlN1cHBsaWVySUQpIEFTIE51bVN1cHBsaWVycwpGUk9NIFByb2R1Y3RzIHAKV0hFUkUgcC5Qcm9kdWN0SUQgSU4gKAogICAgU0VMRUNUIG9kLlByb2R1Y3RJRAogICAgRlJPTSBPcmRlckRldGFpbHMgb2QKICAgIEdST1VQIEJZIG9kLlByb2R1Y3RJRAogICAgSEFWSU5HIFNVTShvZC5RdWFudGl0eSkgPj0gNQopCmBgYAoKYGBge3IgZGlzY29ubmVjdH0KZGJEaXNjb25uZWN0KGNvbikKYGBgCg==