In this class, you will learn how to:
- Extract individual values from a data set
- Change individual values within a data set
Lets search the data frame among the computer
deck <- read.csv("C:/Users/raulr/OneDrive/Escritorio/STU/Prgram For Data Analytics/Archivos/deck.csv",stringsAsFactors=FALSE)
head(deck)
#Positive Numbers R treats positive integers just like ij notation in
linear algebra: deck[i,j] will return the value of deck that is in the
ith row and the jth column, So in this example, the value that is in the
first row, first column is “King”, then a list with the first row has
been created and named new.
deck[1, 1]
[1] "king"
deck[1, c(1, 2, 3)]
new <- deck[1, c(1, 2, 3)]
Repetition. Returns a data frame of 2 rows and 3 columns of the the
first row two times.
deck[c(1, 1), c(1, 2, 3)]
Returns a Data Frame of 2 rows and 2 columns. Of the first and second
rows and columns of the initial dataframe
deck[1:2, 1:2]
Returns a vector of the first row of first and second columns.
deck[1:2, 1]
[1] "king" "queen"
Returns a data frame of 2 rows and 1 column. So it returns the first
2 rows of the first column.
deck[1:2, 1, drop = FALSE]
#Negative Numbers With the negative sign it returns the part of the
data frame that is not inside of the interval.
deck[-(2:52), 1:3]
Illegal instruction.
#deck[c(-1, 1), 1]
#Zero The following instruction creates and empty object.
deck[0, 0]
#Blank Spaces
deck[1, ]
#Logical Values It returns just the columns that have a TRUE value
asociated with it.
deck[1, c(TRUE, TRUE, FALSE)]
Lets check the attributes function again
rows <- c(TRUE, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
F, F, F, F, F, F, F, F, F, F, F, F, F, F)
Extract elements based on the name
deck[1, c("face", "suit", "value")]
#Names You can use a blank space to tell R to extract every value in
a dimension.
# the entire value column
deck[ , "value"]
[1] 13 12 11 10 9 8 7 6 5 4 3 2 1 13 12 11 10 9 8 7 6 5 4 3 2 1 13 12 11 10 9 8 7 6 5 4 3 2
[39] 1 13 12 11 10 9 8 7 6 5 4 3 2 1
Complete the following code to make a function that returns the first
row of a data frame: Writting the name of the data frame instead of deck
will returns any first row of the data frame.
deal <- function(cards) {cards[1, ]}
deal(deck)
NA
Shuffle deck
deck2 <- deck[1:52, ]
head(deck2)
deck3 <- deck[c(2, 1, 3:52), ]
head(deck3)
#How Modify Order Change the order of the cards
#First create a vector of 52 numbers in random order and store it in an object named random.
random <- sample(1:52, size = 52)
random
[1] 11 15 44 32 13 49 39 3 38 36 46 1 47 22 37 52 43 8 35 28 33 12 9 26 4 31 48 20 19 10 30 45 7 23 34 25 42 41
[39] 27 5 6 40 2 51 18 17 14 16 50 21 24 29
deck4 <- deck[random, ]
head(deck4)
Exercise
Use the preceding ideas to write a shuffle function. shuffle should
take a data frame and return a shuffled copy of the data frame.
shuffle <- function(cards) {
random <- sample(1:52, size = 52)
cards[random, ]
}
deal(deck)
## face suit value
## king spades 13
deck2 <- shuffle(deck)
deal(deck2)
## face suit value
## jack clubs 11
#Dollar Signs and Double Brackets
Two types of object in R obey an optional second system of notation.
You can extract values from data frames and lists with the $ syntax. You
will encounter the $ syntax again and again as an R programmer, so let’s
examine how it works. To select a column from a data frame, write the
data frame’s name and the column name separated by a $. Notice that no
quotes should go around the column name:
deck$value
[1] 13 12 11 10 9 8 7 6 5 4 3 2 1 13 12 11 10 9 8 7 6 5 4 3 2 1 13 12 11 10 9 8 7 6 5 4 3 2
[39] 1 13 12 11 10 9 8 7 6 5 4 3 2 1
mean(deck$value)
[1] 7
median(deck$value)
[1] 7
To see this, make a list:
lst <- list(numbers = c(1, 2), logical = TRUE, strings = c("a", "b", "c"))
lst
$numbers
[1] 1 2
$logical
[1] TRUE
$strings
[1] "a" "b" "c"
And then subset it:
lst[1]
$numbers
[1] 1 2
The result is a smaller list with one element. That element is the
vector c(1, 2). This can be annoying because many R functions do not
work with lists. For example, sum(lst[1]) will return an error. It would
be horrible if once you stored a vector in a list, you could only ever
get it back as a list:
#sum(lst[1])
When you use the $ notation, R will return the selected values as
they are, with no list structure around them:
lst$numbers
[1] 1 2
## 1 2
You can then immediately feed the results to a function:
sum(lst$numbers)
[1] 3
## 3
If the elements in your list do not have names (or you do not wish to
use the names), you can use two brackets, instead of one, to subset the
list. This notation will do the same thing as the $ notation:
lst[[1]]
[1] 1 2
## 1 2
In other words, if you subset a list with single-bracket notation, R
will return a smaller list. If you subset a list with double-bracket
notation, R will return just the values that 74 | Chapter 4: R Notation
were inside an element of the list. You can combine this feature with
any of R’s indexing methods:
lst["numbers"]
$numbers
[1] 1 2
lst[["numbers"]]
[1] 1 2
#Changing Values in Place
vec <- c(0, 0, 0, 0, 0, 0)
vec
[1] 0 0 0 0 0 0
vec[1] <- 1000
vec
[1] 1000 0 0 0 0 0
Changing more than one value at the same time.
vec[c(1, 3, 5)] <- c(7, 9, 8)
vec
[1] 7 0 9 0 8 0
vec[4:6] <- vec[4:6] + 1
vec
[1] 7 0 9 1 9 1
Force the vector to grow.
vec[7] <- 0
vec
[1] 7 0 9 1 9 1 0
I do not know why but an error appears because r can not open the
conection. So I am going to upload the dataframe in the same way as
before.
#deck2 <- read.csv("~/Documents/Clases/sainthomas/deck.csv",stringsAsFactors=FALSE)
deck2 <- read.csv("C:/Users/raulr/OneDrive/Escritorio/STU/Prgram For Data Analytics/Archivos/deck.csv",stringsAsFactors=FALSE)
deck2$new <- 1:52
head(deck2)
Remove a column from a dataframe. Column named new has been
eliminated
deck2$new <- NULL
head(deck2)
The rows specified have been the output
deck2[c(13, 26, 39, 52), ]
Rows specified for and column number 3
deck2[c(13, 26, 39, 52), 3]
[1] 1 1 1 1
deck2$value[c(13, 26, 39, 52)]
[1] 14 14 14 14
The value has changed from 1 to 14 in each row.
LS0tDQp0aXRsZTogIldlZWsgMiBQYXJ0MiAoRXh0cmFjdGlvbikiDQphdXRob3I6ICJSYXVsIFJvY2VzIg0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCkluIHRoaXMgY2xhc3MsIHlvdSB3aWxsIGxlYXJuIGhvdyB0bzoNCg0KKiBFeHRyYWN0IGluZGl2aWR1YWwgdmFsdWVzIGZyb20gYSBkYXRhIHNldA0KKiBDaGFuZ2UgaW5kaXZpZHVhbCB2YWx1ZXMgd2l0aGluIGEgZGF0YSBzZXQNCg0KTGV0cyBzZWFyY2ggdGhlIGRhdGEgZnJhbWUgYW1vbmcgdGhlIGNvbXB1dGVyDQpgYGB7cn0NCmRlY2sgPC0gcmVhZC5jc3YoIkM6L1VzZXJzL3JhdWxyL09uZURyaXZlL0VzY3JpdG9yaW8vU1RVL1ByZ3JhbSBGb3IgRGF0YSBBbmFseXRpY3MvQXJjaGl2b3MvZGVjay5jc3YiLHN0cmluZ3NBc0ZhY3RvcnM9RkFMU0UpDQpoZWFkKGRlY2spDQpgYGANCiNQb3NpdGl2ZSBOdW1iZXJzDQpSIHRyZWF0cyBwb3NpdGl2ZSBpbnRlZ2VycyBqdXN0IGxpa2UgaWogbm90YXRpb24gaW4gbGluZWFyIGFsZ2VicmE6IGRlY2tbaSxqXSB3aWxsIHJldHVybiB0aGUNCnZhbHVlIG9mIGRlY2sgdGhhdCBpcyBpbiB0aGUgaXRoIHJvdyBhbmQgdGhlIGp0aCBjb2x1bW4sDQpTbyBpbiB0aGlzIGV4YW1wbGUsIHRoZSB2YWx1ZSB0aGF0IGlzIGluIHRoZSBmaXJzdCByb3csIGZpcnN0IGNvbHVtbiBpcyAiS2luZyIsIHRoZW4gYSBsaXN0IHdpdGggdGhlIGZpcnN0IHJvdyBoYXMgYmVlbiBjcmVhdGVkIGFuZCBuYW1lZCBuZXcuDQpgYGB7cn0NCmRlY2tbMSwgMV0NCmRlY2tbMSwgYygxLCAyLCAzKV0NCm5ldyA8LSBkZWNrWzEsIGMoMSwgMiwgMyldDQpgYGANClJlcGV0aXRpb24uDQpSZXR1cm5zIGEgZGF0YSBmcmFtZSBvZiAyIHJvd3MgYW5kIDMgY29sdW1ucyBvZiB0aGUgdGhlIGZpcnN0IHJvdyB0d28gdGltZXMuDQpgYGB7cn0NCmRlY2tbYygxLCAxKSwgYygxLCAyLCAzKV0NCmBgYA0KUmV0dXJucyBhIERhdGEgRnJhbWUgb2YgMiByb3dzIGFuZCAyIGNvbHVtbnMuIE9mIHRoZSBmaXJzdCBhbmQgc2Vjb25kIHJvd3MgYW5kIGNvbHVtbnMgb2YgdGhlIGluaXRpYWwgZGF0YWZyYW1lIA0KYGBge3J9DQpkZWNrWzE6MiwgMToyXQ0KYGBgDQpSZXR1cm5zIGEgdmVjdG9yIG9mIHRoZSBmaXJzdCByb3cgb2YgZmlyc3QgYW5kIHNlY29uZCBjb2x1bW5zLg0KYGBge3J9DQpkZWNrWzE6MiwgMV0NCmBgYA0KDQpSZXR1cm5zIGEgZGF0YSBmcmFtZSBvZiAyIHJvd3MgYW5kIDEgY29sdW1uLiBTbyBpdCByZXR1cm5zIHRoZSBmaXJzdCAyIHJvd3Mgb2YgdGhlIGZpcnN0IGNvbHVtbi4NCmBgYHtyfQ0KZGVja1sxOjIsIDEsIGRyb3AgPSBGQUxTRV0NCmBgYA0KI05lZ2F0aXZlIE51bWJlcnMNCldpdGggdGhlIG5lZ2F0aXZlIHNpZ24gaXQgcmV0dXJucyB0aGUgcGFydCBvZiB0aGUgZGF0YSBmcmFtZSB0aGF0IGlzIG5vdCBpbnNpZGUgb2YgdGhlIGludGVydmFsLg0KYGBge3J9DQpkZWNrWy0oMjo1MiksIDE6M10NCmBgYA0KSWxsZWdhbCBpbnN0cnVjdGlvbi4NCmBgYHtyfQ0KI2RlY2tbYygtMSwgMSksIDFdDQpgYGANCg0KI1plcm8gDQpUaGUgZm9sbG93aW5nIGluc3RydWN0aW9uIGNyZWF0ZXMgYW5kIGVtcHR5IG9iamVjdC4NCmBgYHtyfQ0KZGVja1swLCAwXQ0KYGBgDQoNCiNCbGFuayBTcGFjZXMgDQpgYGB7cn0NCmRlY2tbMSwgXQ0KYGBgDQojTG9naWNhbCBWYWx1ZXMNCkl0IHJldHVybnMganVzdCB0aGUgY29sdW1ucyB0aGF0IGhhdmUgYSBUUlVFIHZhbHVlIGFzb2NpYXRlZCB3aXRoIGl0Lg0KYGBge3J9DQpkZWNrWzEsIGMoVFJVRSwgVFJVRSwgRkFMU0UpXQ0KYGBgDQpMZXRzIGNoZWNrIHRoZSBhdHRyaWJ1dGVzIGZ1bmN0aW9uIGFnYWluDQpgYGB7cn0NCnJvd3MgPC0gYyhUUlVFLCBGLCBGLCBGLCBGLCBGLCBGLCBGLCBGLCBGLCBGLCBGLCBGLCBGLCBGLCBGLA0KRiwgRiwgRiwgRiwgRiwgRiwgRiwgRiwgRiwgRiwgRiwgRiwgRiwgRiwgRiwgRiwgRiwgRiwgRiwgRiwgRiwgRiwNCkYsIEYsIEYsIEYsIEYsIEYsIEYsIEYsIEYsIEYsIEYsIEYsIEYsIEYpDQpgYGANCkV4dHJhY3QgZWxlbWVudHMgYmFzZWQgb24gdGhlIG5hbWUNCmBgYHtyfQ0KZGVja1sxLCBjKCJmYWNlIiwgInN1aXQiLCAidmFsdWUiKV0NCmBgYA0KI05hbWVzIA0KWW91IGNhbiB1c2UgYSBibGFuayBzcGFjZSB0byB0ZWxsIFIgdG8gZXh0cmFjdCBldmVyeSB2YWx1ZSBpbiBhIGRpbWVuc2lvbi4NCmBgYHtyfQ0KIyB0aGUgZW50aXJlIHZhbHVlIGNvbHVtbg0KZGVja1sgLCAidmFsdWUiXQ0KYGBgDQpDb21wbGV0ZSB0aGUgZm9sbG93aW5nIGNvZGUgdG8gbWFrZSBhIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyB0aGUgZmlyc3Qgcm93IG9mIGEgZGF0YQ0KZnJhbWU6DQpXcml0dGluZyB0aGUgbmFtZSBvZiB0aGUgZGF0YSBmcmFtZSBpbnN0ZWFkIG9mIGRlY2sgd2lsbCByZXR1cm5zIGFueSBmaXJzdCByb3cgb2YgdGhlIGRhdGEgZnJhbWUuDQpgYGB7cn0NCmRlYWwgPC0gZnVuY3Rpb24oY2FyZHMpIHtjYXJkc1sxLCBdfQ0KZGVhbChkZWNrKQ0KDQpgYGANClNodWZmbGUgZGVjaw0KYGBge3J9DQpkZWNrMiA8LSBkZWNrWzE6NTIsIF0NCmhlYWQoZGVjazIpDQpgYGANCg0KYGBge3J9DQpkZWNrMyA8LSBkZWNrW2MoMiwgMSwgMzo1MiksIF0NCmhlYWQoZGVjazMpDQpgYGANCg0KI0hvdyBNb2RpZnkgT3JkZXINCkNoYW5nZSB0aGUgb3JkZXIgb2YgdGhlIGNhcmRzDQpgYGB7cn0NCiNGaXJzdCBjcmVhdGUgYSB2ZWN0b3Igb2YgNTIgbnVtYmVycyBpbiByYW5kb20gb3JkZXIgYW5kIHN0b3JlIGl0IGluIGFuIG9iamVjdCBuYW1lZCByYW5kb20uDQpyYW5kb20gPC0gc2FtcGxlKDE6NTIsIHNpemUgPSA1MikNCnJhbmRvbQ0KYGBgDQoNCg0KDQpgYGB7cn0NCmRlY2s0IDwtIGRlY2tbcmFuZG9tLCBdDQpoZWFkKGRlY2s0KQ0KYGBgDQoNCiMgRXhlcmNpc2UNClVzZSB0aGUgcHJlY2VkaW5nIGlkZWFzIHRvIHdyaXRlIGEgc2h1ZmZsZSBmdW5jdGlvbi4gc2h1ZmZsZSBzaG91bGQgdGFrZSBhIGRhdGEgZnJhbWUNCmFuZCByZXR1cm4gYSBzaHVmZmxlZCBjb3B5IG9mIHRoZSBkYXRhIGZyYW1lLg0KDQpgYGB7cn0NCnNodWZmbGUgPC0gZnVuY3Rpb24oY2FyZHMpIHsNCnJhbmRvbSA8LSBzYW1wbGUoMTo1Miwgc2l6ZSA9IDUyKQ0KY2FyZHNbcmFuZG9tLCBdDQp9DQpkZWFsKGRlY2spDQojIyBmYWNlIHN1aXQgdmFsdWUNCiMjIGtpbmcgc3BhZGVzIDEzDQpkZWNrMiA8LSBzaHVmZmxlKGRlY2spDQpkZWFsKGRlY2syKQ0KIyMgZmFjZSBzdWl0IHZhbHVlDQojIyBqYWNrIGNsdWJzIDExDQpgYGANCiNEb2xsYXIgU2lnbnMgYW5kIERvdWJsZSBCcmFja2V0cw0KYGBge3J9DQoNCmBgYA0KVHdvIHR5cGVzIG9mIG9iamVjdCBpbiBSIG9iZXkgYW4gb3B0aW9uYWwgc2Vjb25kIHN5c3RlbSBvZiBub3RhdGlvbi4gWW91IGNhbiBleHRyYWN0DQp2YWx1ZXMgZnJvbSBkYXRhIGZyYW1lcyBhbmQgbGlzdHMgd2l0aCB0aGUgJCBzeW50YXguIFlvdSB3aWxsIGVuY291bnRlciB0aGUgJCBzeW50YXggYWdhaW4NCmFuZCBhZ2FpbiBhcyBhbiBSIHByb2dyYW1tZXIsIHNvIGxldOKAmXMgZXhhbWluZSBob3cgaXQgd29ya3MuDQpUbyBzZWxlY3QgYSBjb2x1bW4gZnJvbSBhIGRhdGEgZnJhbWUsIHdyaXRlIHRoZSBkYXRhIGZyYW1l4oCZcyBuYW1lIGFuZCB0aGUgY29sdW1uIG5hbWUNCnNlcGFyYXRlZCBieSBhICQuIE5vdGljZSB0aGF0IG5vIHF1b3RlcyBzaG91bGQgZ28gYXJvdW5kIHRoZSBjb2x1bW4gbmFtZToNCmBgYHtyfQ0KZGVjayR2YWx1ZQ0KYGBgDQoNCmBgYHtyfQ0KbWVhbihkZWNrJHZhbHVlKQ0KYGBgDQoNCmBgYHtyfQ0KbWVkaWFuKGRlY2skdmFsdWUpDQpgYGANClRvIHNlZSB0aGlzLCBtYWtlIGEgbGlzdDoNCg0KYGBge3J9DQpsc3QgPC0gbGlzdChudW1iZXJzID0gYygxLCAyKSwgbG9naWNhbCA9IFRSVUUsIHN0cmluZ3MgPSBjKCJhIiwgImIiLCAiYyIpKQ0KbHN0DQpgYGANCg0KQW5kIHRoZW4gc3Vic2V0IGl0Og0KYGBge3J9DQpsc3RbMV0NCmBgYA0KDQpUaGUgcmVzdWx0IGlzIGEgc21hbGxlciBsaXN0IHdpdGggb25lIGVsZW1lbnQuIFRoYXQgZWxlbWVudCBpcyB0aGUgdmVjdG9yIGMoMSwgMikuIFRoaXMNCmNhbiBiZSBhbm5veWluZyBiZWNhdXNlIG1hbnkgUiBmdW5jdGlvbnMgZG8gbm90IHdvcmsgd2l0aCBsaXN0cy4gRm9yIGV4YW1wbGUsDQpzdW0obHN0WzFdKSB3aWxsIHJldHVybiBhbiBlcnJvci4gSXQgd291bGQgYmUgaG9ycmlibGUgaWYgb25jZSB5b3Ugc3RvcmVkIGEgdmVjdG9yIGluIGENCmxpc3QsIHlvdSBjb3VsZCBvbmx5IGV2ZXIgZ2V0IGl0IGJhY2sgYXMgYSBsaXN0Og0KDQoNCg0KDQpgYGB7cn0NCiNzdW0obHN0WzFdKQ0KDQpgYGANCldoZW4geW91IHVzZSB0aGUgJCBub3RhdGlvbiwgUiB3aWxsIHJldHVybiB0aGUgc2VsZWN0ZWQgdmFsdWVzIGFzIHRoZXkgYXJlLCB3aXRoIG5vIGxpc3QNCnN0cnVjdHVyZSBhcm91bmQgdGhlbToNCg0KDQpgYGB7cn0NCmxzdCRudW1iZXJzDQojIyAxIDINCg0KYGBgDQpZb3UgY2FuIHRoZW4gaW1tZWRpYXRlbHkgZmVlZCB0aGUgcmVzdWx0cyB0byBhIGZ1bmN0aW9uOg0KYGBge3J9DQpzdW0obHN0JG51bWJlcnMpDQojIyAzDQoNCmBgYA0KSWYgdGhlIGVsZW1lbnRzIGluIHlvdXIgbGlzdCBkbyBub3QgaGF2ZSBuYW1lcyAob3IgeW91IGRvIG5vdCB3aXNoIHRvIHVzZSB0aGUgbmFtZXMpLA0KeW91IGNhbiB1c2UgdHdvIGJyYWNrZXRzLCBpbnN0ZWFkIG9mIG9uZSwgdG8gc3Vic2V0IHRoZSBsaXN0LiBUaGlzIG5vdGF0aW9uIHdpbGwgZG8gdGhlDQpzYW1lIHRoaW5nIGFzIHRoZSAkIG5vdGF0aW9uOg0KYGBge3J9DQpsc3RbWzFdXQ0KIyMgMSAyDQpgYGANCkluIG90aGVyIHdvcmRzLCBpZiB5b3Ugc3Vic2V0IGEgbGlzdCB3aXRoIHNpbmdsZS1icmFja2V0IG5vdGF0aW9uLCBSIHdpbGwgcmV0dXJuIGEgc21hbGxlcg0KbGlzdC4gSWYgeW91IHN1YnNldCBhIGxpc3Qgd2l0aCBkb3VibGUtYnJhY2tldCBub3RhdGlvbiwgUiB3aWxsIHJldHVybiBqdXN0IHRoZSB2YWx1ZXMgdGhhdA0KNzQgfCBDaGFwdGVyIDQ6IFIgTm90YXRpb24NCndlcmUgaW5zaWRlIGFuIGVsZW1lbnQgb2YgdGhlIGxpc3QuIFlvdSBjYW4gY29tYmluZSB0aGlzIGZlYXR1cmUgd2l0aCBhbnkgb2YgUuKAmXMgaW5kZXhpbmcNCm1ldGhvZHM6DQpgYGB7cn0NCmxzdFsibnVtYmVycyJdDQpsc3RbWyJudW1iZXJzIl1dDQpgYGANCg0KDQoNCiNDaGFuZ2luZyBWYWx1ZXMgaW4gUGxhY2UNCmBgYHtyfQ0KdmVjIDwtIGMoMCwgMCwgMCwgMCwgMCwgMCkNCnZlYw0KdmVjWzFdIDwtIDEwMDANCnZlYw0KYGBgDQoNCg0KQ2hhbmdpbmcgbW9yZSB0aGFuIG9uZSB2YWx1ZSBhdCB0aGUgc2FtZSB0aW1lLg0KYGBge3J9DQp2ZWNbYygxLCAzLCA1KV0gPC0gYyg3LCA5LCA4KQ0KdmVjDQp2ZWNbNDo2XSA8LSB2ZWNbNDo2XSArIDENCnZlYw0KYGBgDQoNCkZvcmNlIHRoZSB2ZWN0b3IgdG8gZ3Jvdy4NCmBgYHtyfQ0KdmVjWzddIDwtIDANCnZlYw0KYGBgDQpJIGRvIG5vdCBrbm93IHdoeSBidXQgYW4gZXJyb3IgYXBwZWFycyBiZWNhdXNlIHIgY2FuIG5vdCBvcGVuIHRoZSBjb25lY3Rpb24uIFNvIEkgYW0gZ29pbmcgdG8gdXBsb2FkIHRoZSBkYXRhZnJhbWUgaW4gdGhlIHNhbWUgd2F5IGFzIGJlZm9yZS4NCmBgYHtyfQ0KI2RlY2syIDwtIHJlYWQuY3N2KCJ+L0RvY3VtZW50cy9DbGFzZXMvc2FpbnRob21hcy9kZWNrLmNzdiIsc3RyaW5nc0FzRmFjdG9ycz1GQUxTRSkNCmRlY2syIDwtIHJlYWQuY3N2KCJDOi9Vc2Vycy9yYXVsci9PbmVEcml2ZS9Fc2NyaXRvcmlvL1NUVS9QcmdyYW0gRm9yIERhdGEgQW5hbHl0aWNzL0FyY2hpdm9zL2RlY2suY3N2IixzdHJpbmdzQXNGYWN0b3JzPUZBTFNFKQ0KZGVjazIkbmV3IDwtIDE6NTINCmhlYWQoZGVjazIpDQpgYGANClJlbW92ZSBhIGNvbHVtbiBmcm9tIGEgZGF0YWZyYW1lLiBDb2x1bW4gbmFtZWQgbmV3IGhhcyBiZWVuIGVsaW1pbmF0ZWQNCmBgYHtyfQ0KZGVjazIkbmV3IDwtIE5VTEwNCmhlYWQoZGVjazIpDQpgYGANCg0KVGhlIHJvd3Mgc3BlY2lmaWVkIGhhdmUgYmVlbiB0aGUgb3V0cHV0DQpgYGB7cn0NCmRlY2syW2MoMTMsIDI2LCAzOSwgNTIpLCBdDQpgYGANClJvd3Mgc3BlY2lmaWVkIGZvciBhbmQgY29sdW1uIG51bWJlciAzDQpgYGB7cn0NCmRlY2syW2MoMTMsIDI2LCAzOSwgNTIpLCAzXQ0KYGBgDQoNCmBgYHtyfQ0KZGVjazIkdmFsdWVbYygxMywgMjYsIDM5LCA1MildDQpgYGANClRoZSB2YWx1ZSBoYXMgY2hhbmdlZCBmcm9tIDEgdG8gMTQgaW4gZWFjaCByb3cuDQpgYGB7cn0NCmRlY2syJHZhbHVlW2MoMTMsIDI2LCAzOSwgNTIpXSA8LSBjKDE0LCAxNCwgMTQsIDE0KQ0KYGBgDQo=