
Exercise 1
The following table shows sample information for three students. Each
observation represents a single student and includes details such as
their unique student ID, name, age, total credits completed, major field
of study, and year level.
This dataset demonstrates a mixture of variable types:
- Nominal: StudentID, Name, Major
- Numeric: Age (continuous), CreditsCompleted
(discrete)
- Ordinal: YearLevel (Freshman → Senior)
S001 |
Alice |
20 |
45 |
Data Sains |
Sophomore |
S002 |
Budi |
21 |
60 |
Mathematics |
Junior |
S003 |
Citra |
19 |
30 |
Statistics |
Freshman |
# 1. Create vectors for each variable
StudentID <- c("S001", "S002", "S003") # Nominal / ID
Name <- c("Alice", "Budi", "Citra") # Nominal / Name
Age <- c(20, 21, 19) # Numeric / Continuous
CreditsCompleted <- c(45, 60, 30) # Numeric / Discrete
# Nominal
Major <- c("Data Sains", "Mathematics", "Statistics")
# Ordinal
YearLevel <- factor(c("Sophomore", "Junior", "Freshman"),
levels = c("Freshman","Sophomore","Junior","Senior"),
ordered = TRUE)
# 2. Combine all vectors into a data frame
students <- data.frame(
StudentID, Name, Age, CreditsCompleted, Major, YearLevel,
stringsAsFactors = FALSE
)
# 3. Display the data frame
print(students)
## StudentID Name Age CreditsCompleted Major YearLevel
## 1 S001 Alice 20 45 Data Sains Sophomore
## 2 S002 Budi 21 60 Mathematics Junior
## 3 S003 Citra 19 30 Statistics Freshman
Exercise 2
Identify Data Types: Determine the type of data for
each of the following variables:
# Install knitr package if not already installed
# install.packages("knitr")
library(knitr)
# Create a data frame for Data Types
variables_info <- data.frame(
No = 1:5,
Variable = c(
"Number of vehicles passing through the toll road each day",
"Student height in cm",
"Employee gender (Male / Female)",
"Customer satisfaction level: Low, Medium, High",
"Respondent's favorite color: Red, Blue, Green"
),
DataType = c(
"Your Answer",
"Your Answer",
"Your Answer",
"Your Answer",
"Your Answer"
),
Subtype = c(
"Your Answer",
"Your Answer",
"Your Answer",
"Your Answer",
"Your Answer"
),
stringsAsFactors = FALSE
)
# Display the data frame as a neat table
kable(variables_info,
caption = "Table of Variables and Data Types")
Table of Variables and Data Types
1 |
Number of vehicles passing through the toll road each
day |
Your Answer |
Your Answer |
2 |
Student height in cm |
Your Answer |
Your Answer |
3 |
Employee gender (Male / Female) |
Your Answer |
Your Answer |
4 |
Customer satisfaction level: Low, Medium, High |
Your Answer |
Your Answer |
5 |
Respondent’s favorite color: Red, Blue, Green |
Your Answer |
Your Answer |
Exercise 3
Classify Data Sources: Determine whether the
following data comes from internal or external
sources, and whether it is structured or
unstructured:
# Install DT package if not already installed
# install.packages("DT")
library(DT)
# Create a data frame for data sources
data_sources <- data.frame(
No = 1:4,
DataSource = c(
"Daily sales transaction data of the company",
"Weather reports from BMKG",
"Product reviews on social media",
"Warehouse inventory reports"
),
Internal_External = c(
"Your Answer",
"Your Answer",
"Your Answer",
"Your Answer"
),
Structured_Unstructured = c(
"Your Answer",
"Your Answer",
"Your Answer",
"Your Answer"
),
stringsAsFactors = FALSE
)
# Display the data frame as a neat table
datatable(data_sources,
caption = "Table of Data Sources",
rownames = FALSE) # hides the index column
Exercise 4
Dataset Structure: Consider the following
transaction table:
2025-10-01 |
2 |
1000 |
Laptop |
High |
2025-10-01 |
5 |
20 |
Mouse |
Medium |
2025-10-02 |
1 |
1000 |
Laptop |
Low |
2025-10-02 |
3 |
30 |
Keyboard |
Medium |
2025-10-03 |
4 |
50 |
Mouse |
Medium |
2025-10-03 |
2 |
1000 |
Laptop |
High |
2025-10-04 |
6 |
25 |
Keyboard |
Low |
2025-10-04 |
1 |
1000 |
Laptop |
High |
2025-10-05 |
3 |
40 |
Mouse |
Low |
2025-10-05 |
5 |
10 |
Keyboard |
Medium |
Your Assignment Instructions: Creating a
Transactions Table above in R
Create a data frame in R called
transactions
containing the data above.
Identify which variables are numeric and which are
categorical
Calculate total revenue for each transaction by
multiplying Qty × Price
and add it as a new column
Total
.
Compute summary statistics:
- Total quantity sold for each product
- Total revenue per product
- Average price per product
Visualize the data:
- Create a barplot showing total quantity sold per
product.
- Create a pie chart showing the proportion of total
revenue per customer tier.
Optional Challenge:
- Find which date had the highest total revenue.
- Create a stacked bar chart showing quantity sold
per product by customer tier.
Hints: Use data.frame()
,
aggregate()
, barplot()
, pie()
,
and basic arithmetic operations in R.
Exercise 5
Create Your Own Data Frame:
Objective: Create a data frame in R with 30
rows containing a mix of data types: continuous, discrete,
nominal, and ordinal.
Instructions
Open RStudio or the R console.
Create a vector for each column in your data
frame:
- Date: 30 dates (can be sequential or random within
a month/year)
- Continuous: numeric values that can take decimal
values (e.g., height, weight, temperature)
- Discrete: numeric values that can only take whole
numbers (e.g., number of items, number of vehicles)
- Nominal: categorical values with no
order (e.g., color, gender, city)
- Ordinal: categorical values with a defined
order (e.g., Low, Medium, High; Beginner, Intermediate,
Expert)
Combine all vectors into a data frame called
my_data
.
Check your data frame using head()
or View()
to ensure it has 30 rows and the
columns are correct.
Optional tasks:
- Summarize each column using
summary()
- Count the frequency of each category for Nominal
and Ordinal columns using
table()
Hints
- Use
seq.Date()
or as.Date()
to generate
the Date column.
- Use
runif()
or rnorm()
for continuous
numeric data.
- Use
sample()
for discrete, nominal, and ordinal
data.
- Ensure the ordinal vector is created with
factor(..., levels = c("Low","Medium","High"), ordered = TRUE)
(or similar).
LS0tCnRpdGxlOiAiRGF0YSBFeHBsb3JhdGlvbiIgICAgICAgIyBNYWluIHRpdGxlIG9mIHRoZSBkb2N1bWVudApzdWJ0aXRsZTogIkV4ZXJjaXNlcyB+IFdlZWsgMiIgICMgU3VidGl0bGUgb3IgdG9waWMgZm9yIHdlZWsgMgphdXRob3I6ICJZb3VyIEZ1bGwgTmFtZSBIZXJlIiAgICMgUmVwbGFjZSB3aXRoIHlvdXIgZnVsbCBuYW1lCmRhdGU6ICAiYHIgZm9ybWF0KFN5cy5EYXRlKCksICclQiAlZCwgJVknKWAiICMgQXV0byBkaXNwbGF5cyB0aGUgY3VycmVudCBkYXRlCm91dHB1dDogICAgICAgICAgICAgICAgICAgICAgICAgIyBPdXRwdXQgc2VjdGlvbiBkZWZpbmVzIHRoZSBmb3JtYXQgYW5kIGxheW91dCAKICBybWRmb3JtYXRzOjpyZWFkdGhlZG93bjogICAgICAjIGh0dHBzOi8vZ2l0aHViLmNvbS9qdWJhL3JtZGZvcm1hdHMKICAgIHNlbGZfY29udGFpbmVkOiB0cnVlICAgICAgICAjIEVtYmVkcyBhbGwgcmVzb3VyY2VzIChDU1MsIEpTLCBpbWFnZXMpIAogICAgdGh1bWJuYWlsczogdHJ1ZSAgICAgICAgICAgICMgRGlzcGxheXMgaW1hZ2UgdGh1bWJuYWlscyBpbiB0aGUgZG9jCiAgICBsaWdodGJveDogdHJ1ZSAgICAgICAgICAgICAgIyBFbmFibGVzIGNsaWNrIHRvIGVubGFyZ2UgaW1hZ2VzCiAgICBnYWxsZXJ5OiB0cnVlICAgICAgICAgICAgICAgIyBHcm91cHMgaW1hZ2VzIGludG8gYW4gaW50ZXJhY3RpdmUgZ2FsbGVyeQogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlICAgICAgICMgQXV0b21hdGljYWxseSBudW1iZXJzIGFsbCBzZWN0aW9ucwogICAgbGliX2RpcjogbGlicyAgICAgICAgICAgICAgICMgRGlyZWN0b3J5IHdoZXJlIEphdmFTY3JpcHQvQ1NTIGxpYnJhcmllcwogICAgZGZfcHJpbnQ6ICJwYWdlZCIgICAgICAgICAgICMgRGlzcGxheXMgZGF0YSBmcmFtZXMgYXMgaW50ZXJhY3RpdmUgcGFnZWQgCiAgICBjb2RlX2ZvbGRpbmc6ICJzaG93IiAgICAgICAgIyBBbGxvd3MgZm9sZGluZy91bmZvbGRpbmcgUiBjb2RlIGJsb2NrcyAKICAgIGNvZGVfZG93bmxvYWQ6IHllcyAgICAgICAgICAjIEFkZHMgYSBidXR0b24gdG8gZG93bmxvYWQgYWxsIFIgY29kZQotLS0KCgo8aW1nIGlkPSJGb3RvIiBzcmM9Imh0dHBzOi8vZ2l0aHViLmNvbS9kc2NpZW5jZWxhYnMvaW1hZ2VzL2Jsb2IvbWFzdGVyL0xvZ29fRHNjaWVuY2VsYWJzX3YxLnBuZz9yYXc9dHJ1ZSIgYWx0PSJMb2dvIiBzdHlsZT0id2lkdGg6MjAwcHg7IGRpc3BsYXk6IGJsb2NrOyBtYXJnaW46IGF1dG87Ij4KCi0tLQoKIyMgRXhlcmNpc2UgMQoKVGhlIGZvbGxvd2luZyB0YWJsZSBzaG93cyBzYW1wbGUgaW5mb3JtYXRpb24gZm9yIHRocmVlIHN0dWRlbnRzLiBFYWNoIG9ic2VydmF0aW9uIHJlcHJlc2VudHMgYSBzaW5nbGUgc3R1ZGVudCBhbmQgaW5jbHVkZXMgZGV0YWlscyBzdWNoIGFzIHRoZWlyIHVuaXF1ZSBzdHVkZW50IElELCBuYW1lLCBhZ2UsIHRvdGFsIGNyZWRpdHMgY29tcGxldGVkLCBtYWpvciBmaWVsZCBvZiBzdHVkeSwgYW5kIHllYXIgbGV2ZWwuICAKClRoaXMgZGF0YXNldCBkZW1vbnN0cmF0ZXMgYSBtaXh0dXJlIG9mIHZhcmlhYmxlIHR5cGVzOiAgCgotICoqTm9taW5hbDoqKiBTdHVkZW50SUQsIE5hbWUsIE1ham9yICAKLSAqKk51bWVyaWM6KiogQWdlIChjb250aW51b3VzKSwgQ3JlZGl0c0NvbXBsZXRlZCAoZGlzY3JldGUpICAKLSAqKk9yZGluYWw6KiogWWVhckxldmVsIChGcmVzaG1hbiDihpIgU2VuaW9yKSAgCgp8IFN0dWRlbnRJRCB8IE5hbWUgICB8IEFnZSB8IENyZWRpdHNDb21wbGV0ZWQgfCBNYWpvciAgICAgICAgICAgIHwgWWVhckxldmVsIHwKfC0tLS0tLS0tLS0tfC0tLS0tLS0tfC0tLS0tfC0tLS0tLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tfAp8IFMwMDEgICAgICB8IEFsaWNlICB8IDIwICB8IDQ1ICAgICAgICAgICAgICB8IERhdGEgU2FpbnMgICAgICB8IFNvcGhvbW9yZSB8CnwgUzAwMiAgICAgIHwgQnVkaSAgIHwgMjEgIHwgNjAgICAgICAgICAgICAgIHwgTWF0aGVtYXRpY3MgICAgIHwgSnVuaW9yICAgIHwKfCBTMDAzICAgICAgfCBDaXRyYSAgfCAxOSAgfCAzMCAgICAgICAgICAgICAgfCBTdGF0aXN0aWNzICAgICAgfCBGcmVzaG1hbiAgfAoKYGBge3J9CiMgMS4gQ3JlYXRlIHZlY3RvcnMgZm9yIGVhY2ggdmFyaWFibGUKU3R1ZGVudElEIDwtIGMoIlMwMDEiLCAiUzAwMiIsICJTMDAzIikgICAgICAgIyBOb21pbmFsIC8gSUQKTmFtZSA8LSBjKCJBbGljZSIsICJCdWRpIiwgIkNpdHJhIikgICAgICAgICAgIyBOb21pbmFsIC8gTmFtZQpBZ2UgPC0gYygyMCwgMjEsIDE5KSAgICAgICAgICAgICAgICAgICAgICAgICAjIE51bWVyaWMgLyBDb250aW51b3VzCkNyZWRpdHNDb21wbGV0ZWQgPC0gYyg0NSwgNjAsIDMwKSAgICAgICAgICAgICMgTnVtZXJpYyAvIERpc2NyZXRlCgojIE5vbWluYWwKTWFqb3IgPC0gYygiRGF0YSBTYWlucyIsICJNYXRoZW1hdGljcyIsICJTdGF0aXN0aWNzIikgIAoKIyBPcmRpbmFsClllYXJMZXZlbCA8LSBmYWN0b3IoYygiU29waG9tb3JlIiwgIkp1bmlvciIsICJGcmVzaG1hbiIpLAogICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIkZyZXNobWFuIiwiU29waG9tb3JlIiwiSnVuaW9yIiwiU2VuaW9yIiksCiAgICAgICAgICAgICAgICAgICAgb3JkZXJlZCA9IFRSVUUpICAgICAgICAgIAoKIyAyLiBDb21iaW5lIGFsbCB2ZWN0b3JzIGludG8gYSBkYXRhIGZyYW1lCnN0dWRlbnRzIDwtIGRhdGEuZnJhbWUoCiAgU3R1ZGVudElELCBOYW1lLCBBZ2UsIENyZWRpdHNDb21wbGV0ZWQsIE1ham9yLCBZZWFyTGV2ZWwsCiAgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFCikKCiMgMy4gRGlzcGxheSB0aGUgZGF0YSBmcmFtZQpwcmludChzdHVkZW50cykKYGBgCgoKIyMgRXhlcmNpc2UgMgoKKipJZGVudGlmeSBEYXRhIFR5cGVzOioqIERldGVybWluZSB0aGUgdHlwZSBvZiBkYXRhIGZvciBlYWNoIG9mIHRoZSBmb2xsb3dpbmcgdmFyaWFibGVzOgoKYGBge3J9CiMgSW5zdGFsbCBrbml0ciBwYWNrYWdlIGlmIG5vdCBhbHJlYWR5IGluc3RhbGxlZAojIGluc3RhbGwucGFja2FnZXMoImtuaXRyIikKbGlicmFyeShrbml0cikKCiMgQ3JlYXRlIGEgZGF0YSBmcmFtZSBmb3IgRGF0YSBUeXBlcwp2YXJpYWJsZXNfaW5mbyA8LSBkYXRhLmZyYW1lKAogIE5vID0gMTo1LAogIFZhcmlhYmxlID0gYygKICAgICJOdW1iZXIgb2YgdmVoaWNsZXMgcGFzc2luZyB0aHJvdWdoIHRoZSB0b2xsIHJvYWQgZWFjaCBkYXkiLAogICAgIlN0dWRlbnQgaGVpZ2h0IGluIGNtIiwKICAgICJFbXBsb3llZSBnZW5kZXIgKE1hbGUgLyBGZW1hbGUpIiwKICAgICJDdXN0b21lciBzYXRpc2ZhY3Rpb24gbGV2ZWw6IExvdywgTWVkaXVtLCBIaWdoIiwKICAgICJSZXNwb25kZW50J3MgZmF2b3JpdGUgY29sb3I6IFJlZCwgQmx1ZSwgR3JlZW4iCiAgKSwKICBEYXRhVHlwZSA9IGMoCiAgICAiWW91ciBBbnN3ZXIiLAogICAgIllvdXIgQW5zd2VyIiwKICAgICJZb3VyIEFuc3dlciIsCiAgICAiWW91ciBBbnN3ZXIiLAogICAgIllvdXIgQW5zd2VyIgogICksCiAgU3VidHlwZSA9IGMoCiAgICAiWW91ciBBbnN3ZXIiLAogICAgIllvdXIgQW5zd2VyIiwKICAgICJZb3VyIEFuc3dlciIsCiAgICAiWW91ciBBbnN3ZXIiLAogICAgIllvdXIgQW5zd2VyIgogICksCiAgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFCikKCiMgRGlzcGxheSB0aGUgZGF0YSBmcmFtZSBhcyBhIG5lYXQgdGFibGUKa2FibGUodmFyaWFibGVzX2luZm8sIAogICAgICBjYXB0aW9uID0gIlRhYmxlIG9mIFZhcmlhYmxlcyBhbmQgRGF0YSBUeXBlcyIpCmBgYAotLS0KCiMjIEV4ZXJjaXNlIDMKCioqQ2xhc3NpZnkgRGF0YSBTb3VyY2VzOioqIERldGVybWluZSB3aGV0aGVyIHRoZSBmb2xsb3dpbmcgZGF0YSBjb21lcyBmcm9tICoqaW50ZXJuYWwqKiBvciAqKmV4dGVybmFsIHNvdXJjZXMqKiwgYW5kIHdoZXRoZXIgaXQgaXMgKipzdHJ1Y3R1cmVkKiogb3IgKip1bnN0cnVjdHVyZWQqKjoKCmBgYHtyfQojIEluc3RhbGwgRFQgcGFja2FnZSBpZiBub3QgYWxyZWFkeSBpbnN0YWxsZWQKIyBpbnN0YWxsLnBhY2thZ2VzKCJEVCIpCmxpYnJhcnkoRFQpCgojIENyZWF0ZSBhIGRhdGEgZnJhbWUgZm9yIGRhdGEgc291cmNlcyAKZGF0YV9zb3VyY2VzIDwtIGRhdGEuZnJhbWUoCiAgTm8gPSAxOjQsCiAgRGF0YVNvdXJjZSA9IGMoCiAgICAiRGFpbHkgc2FsZXMgdHJhbnNhY3Rpb24gZGF0YSBvZiB0aGUgY29tcGFueSIsCiAgICAiV2VhdGhlciByZXBvcnRzIGZyb20gQk1LRyIsCiAgICAiUHJvZHVjdCByZXZpZXdzIG9uIHNvY2lhbCBtZWRpYSIsCiAgICAiV2FyZWhvdXNlIGludmVudG9yeSByZXBvcnRzIgogICksCiAgSW50ZXJuYWxfRXh0ZXJuYWwgPSBjKAogICAgIllvdXIgQW5zd2VyIiwKICAgICJZb3VyIEFuc3dlciIsCiAgICAiWW91ciBBbnN3ZXIiLAogICAgIllvdXIgQW5zd2VyIgogICksCiAgU3RydWN0dXJlZF9VbnN0cnVjdHVyZWQgPSBjKAogICAgIllvdXIgQW5zd2VyIiwKICAgICJZb3VyIEFuc3dlciIsCiAgICAiWW91ciBBbnN3ZXIiLAogICAgIllvdXIgQW5zd2VyIgogICksCiAgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFCikKCiMgRGlzcGxheSB0aGUgZGF0YSBmcmFtZSBhcyBhIG5lYXQgdGFibGUKZGF0YXRhYmxlKGRhdGFfc291cmNlcywgCiAgICAgICAgICBjYXB0aW9uID0gIlRhYmxlIG9mIERhdGEgU291cmNlcyIsCiAgICAgICAgICByb3duYW1lcyA9IEZBTFNFKSAjIGhpZGVzIHRoZSBpbmRleCBjb2x1bW4KYGBgCgotLS0KCiMjIEV4ZXJjaXNlIDQKCioqRGF0YXNldCBTdHJ1Y3R1cmU6KiogQ29uc2lkZXIgdGhlIGZvbGxvd2luZyB0cmFuc2FjdGlvbiB0YWJsZToKCnwgRGF0ZSAgICAgICB8IFF0eSB8IFByaWNlIHwgUHJvZHVjdCAgfCBDdXN0b21lclRpZXIgfAp8LS0tLS0tLS0tLS0tfC0tLS0tfC0tLS0tLS18LS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLXwKfCAyMDI1LTEwLTAxIHwgMiAgIHwgMTAwMCAgfCBMYXB0b3AgICB8IEhpZ2ggICAgICAgICB8CnwgMjAyNS0xMC0wMSB8IDUgICB8IDIwICAgIHwgTW91c2UgICAgfCBNZWRpdW0gICAgICAgfAp8IDIwMjUtMTAtMDIgfCAxICAgfCAxMDAwICB8IExhcHRvcCAgIHwgTG93ICAgICAgICAgIHwKfCAyMDI1LTEwLTAyIHwgMyAgIHwgMzAgICAgfCBLZXlib2FyZCB8IE1lZGl1bSAgICAgICB8CnwgMjAyNS0xMC0wMyB8IDQgICB8IDUwICAgIHwgTW91c2UgICAgfCBNZWRpdW0gICAgICAgfAp8IDIwMjUtMTAtMDMgfCAyICAgfCAxMDAwICB8IExhcHRvcCAgIHwgSGlnaCAgICAgICAgIHwKfCAyMDI1LTEwLTA0IHwgNiAgIHwgMjUgICAgfCBLZXlib2FyZCB8IExvdyAgICAgICAgICB8CnwgMjAyNS0xMC0wNCB8IDEgICB8IDEwMDAgIHwgTGFwdG9wICAgfCBIaWdoICAgICAgICAgfAp8IDIwMjUtMTAtMDUgfCAzICAgfCA0MCAgICB8IE1vdXNlICAgIHwgTG93ICAgICAgICAgIHwKfCAyMDI1LTEwLTA1IHwgNSAgIHwgMTAgICAgfCBLZXlib2FyZCB8IE1lZGl1bSAgICAgICB8CgoKKipZb3VyIEFzc2lnbm1lbnQgSW5zdHJ1Y3Rpb25zOioqIENyZWF0aW5nIGEgVHJhbnNhY3Rpb25zIFRhYmxlIGFib3ZlIGluIFIKCjEuICoqQ3JlYXRlIGEgZGF0YSBmcmFtZSoqIGluIFIgY2FsbGVkIGB0cmFuc2FjdGlvbnNgIGNvbnRhaW5pbmcgdGhlIGRhdGEgYWJvdmUuCgoyLiBJZGVudGlmeSB3aGljaCB2YXJpYWJsZXMgYXJlIG51bWVyaWMgYW5kIHdoaWNoIGFyZSBjYXRlZ29yaWNhbAoKMy4gKipDYWxjdWxhdGUgdG90YWwgcmV2ZW51ZSoqIGZvciBlYWNoIHRyYW5zYWN0aW9uIGJ5IG11bHRpcGx5aW5nIGBRdHkgw5cgUHJpY2VgIGFuZCBhZGQgaXQgYXMgYSBuZXcgY29sdW1uIGBUb3RhbGAuCgo0LiAqKkNvbXB1dGUgc3VtbWFyeSBzdGF0aXN0aWNzKio6CiAgIC0gVG90YWwgcXVhbnRpdHkgc29sZCBmb3IgZWFjaCBwcm9kdWN0CiAgIC0gVG90YWwgcmV2ZW51ZSBwZXIgcHJvZHVjdAogICAtIEF2ZXJhZ2UgcHJpY2UgcGVyIHByb2R1Y3QKCjUuICoqVmlzdWFsaXplIHRoZSBkYXRhKio6CiAgIC0gQ3JlYXRlIGEgKipiYXJwbG90Kiogc2hvd2luZyB0b3RhbCBxdWFudGl0eSBzb2xkIHBlciBwcm9kdWN0LgogICAtIENyZWF0ZSBhICoqcGllIGNoYXJ0Kiogc2hvd2luZyB0aGUgcHJvcG9ydGlvbiBvZiB0b3RhbCByZXZlbnVlIHBlciBjdXN0b21lciB0aWVyLgoKNi4gKipPcHRpb25hbCBDaGFsbGVuZ2UqKjoKICAgLSBGaW5kIHdoaWNoICoqZGF0ZSoqIGhhZCB0aGUgaGlnaGVzdCB0b3RhbCByZXZlbnVlLgogICAtIENyZWF0ZSBhICoqc3RhY2tlZCBiYXIgY2hhcnQqKiBzaG93aW5nIHF1YW50aXR5IHNvbGQgcGVyIHByb2R1Y3QgYnkgY3VzdG9tZXIgdGllci4KCioqSGludHM6KiogVXNlIGBkYXRhLmZyYW1lKClgLCBgYWdncmVnYXRlKClgLCBgYmFycGxvdCgpYCwgYHBpZSgpYCwgYW5kIGJhc2ljIGFyaXRobWV0aWMgb3BlcmF0aW9ucyBpbiBSLgoKCiMjIEV4ZXJjaXNlIDUKCioqQ3JlYXRlIFlvdXIgT3duIERhdGEgRnJhbWU6KioKCioqT2JqZWN0aXZlOioqIENyZWF0ZSBhIGRhdGEgZnJhbWUgaW4gUiB3aXRoICoqMzAgcm93cyoqIGNvbnRhaW5pbmcgYSBtaXggb2YgZGF0YSB0eXBlczogY29udGludW91cywgZGlzY3JldGUsIG5vbWluYWwsIGFuZCBvcmRpbmFsLiAgCgojIyMgSW5zdHJ1Y3Rpb25zCgoxLiAqKk9wZW4gUlN0dWRpbyoqIG9yIHRoZSBSIGNvbnNvbGUuICAKCjIuICoqQ3JlYXRlIGEgdmVjdG9yIGZvciBlYWNoIGNvbHVtbioqIGluIHlvdXIgZGF0YSBmcmFtZTogIAoKICAgLSAqKkRhdGUqKjogMzAgZGF0ZXMgKGNhbiBiZSBzZXF1ZW50aWFsIG9yIHJhbmRvbSB3aXRoaW4gYSBtb250aC95ZWFyKSAgCiAgIC0gKipDb250aW51b3VzKio6IG51bWVyaWMgdmFsdWVzIHRoYXQgY2FuIHRha2UgZGVjaW1hbCB2YWx1ZXMgKGUuZy4sIGhlaWdodCwgd2VpZ2h0LCB0ZW1wZXJhdHVyZSkgIAogICAtICoqRGlzY3JldGUqKjogbnVtZXJpYyB2YWx1ZXMgdGhhdCBjYW4gb25seSB0YWtlIHdob2xlIG51bWJlcnMgKGUuZy4sIG51bWJlciBvZiBpdGVtcywgbnVtYmVyIG9mIHZlaGljbGVzKSAgCiAgIC0gKipOb21pbmFsKio6IGNhdGVnb3JpY2FsIHZhbHVlcyB3aXRoICoqbm8gb3JkZXIqKiAoZS5nLiwgY29sb3IsIGdlbmRlciwgY2l0eSkgIAogICAtICoqT3JkaW5hbCoqOiBjYXRlZ29yaWNhbCB2YWx1ZXMgd2l0aCBhICoqZGVmaW5lZCBvcmRlcioqIChlLmcuLCBMb3csIE1lZGl1bSwgSGlnaDsgQmVnaW5uZXIsIEludGVybWVkaWF0ZSwgRXhwZXJ0KSAgCgozLiAqKkNvbWJpbmUgYWxsIHZlY3RvcnMgaW50byBhIGRhdGEgZnJhbWUqKiBjYWxsZWQgYG15X2RhdGFgLiAgCgo0LiAqKkNoZWNrIHlvdXIgZGF0YSBmcmFtZSoqIHVzaW5nIGBoZWFkKClgIG9yIGBWaWV3KClgIHRvIGVuc3VyZSBpdCBoYXMgKiozMCByb3dzKiogYW5kIHRoZSBjb2x1bW5zIGFyZSBjb3JyZWN0LiAgCgo1LiAqKk9wdGlvbmFsIHRhc2tzKio6ICAKICAgLSBTdW1tYXJpemUgZWFjaCBjb2x1bW4gdXNpbmcgYHN1bW1hcnkoKWAgIAogICAtIENvdW50IHRoZSBmcmVxdWVuY3kgb2YgZWFjaCBjYXRlZ29yeSBmb3IgKipOb21pbmFsKiogYW5kICoqT3JkaW5hbCoqIGNvbHVtbnMgdXNpbmcgYHRhYmxlKClgICAKCiMjIyBIaW50cwoKLSBVc2UgYHNlcS5EYXRlKClgIG9yIGBhcy5EYXRlKClgIHRvIGdlbmVyYXRlIHRoZSBEYXRlIGNvbHVtbi4gIAotIFVzZSBgcnVuaWYoKWAgb3IgYHJub3JtKClgIGZvciBjb250aW51b3VzIG51bWVyaWMgZGF0YS4gIAotIFVzZSBgc2FtcGxlKClgIGZvciBkaXNjcmV0ZSwgbm9taW5hbCwgYW5kIG9yZGluYWwgZGF0YS4gIAotIEVuc3VyZSB0aGUgKipvcmRpbmFsIHZlY3RvcioqIGlzIGNyZWF0ZWQgd2l0aCBgZmFjdG9yKC4uLiwgbGV2ZWxzID0gYygiTG93IiwiTWVkaXVtIiwiSGlnaCIpLCBvcmRlcmVkID0gVFJVRSlgIChvciBzaW1pbGFyKS4gIAoKCgoKCg==