The dataset I am exploring is the English language keystroke pairs in the Microsoft Research Spelling-Correction Data collected through MTurk. Each keystroke pair consists of a user’s spelling error and their correction. There are 44,104 keystroke pairs in the dataset, so I decided to look at smaller categories within the data to make it more manageable.

library(tidyverse)
errors <- read.delim("C:/Users/delee/OneDrive/Desktop/all_keystroke_pairs.txt", quote = "")
View(errors)

Error Frequency by Number

First, I filtered the data for errors that were corrected to number terms from one to ten. Notably, this discounts keystroke pairs in which both the error and the correction are misspelled number terms. Many items in this dataset are pairs in which the typer still did not spell a word correctly in their second attempt (who among us), but we don’t know what they were trying to type in these cases.

I had to do some finagling to order the data correctly. Even when I managed to get them in numerical order in the dataset by introducing a column of the corresponding digits, they appeared in alphabetical order in the visualization. I went through a lot of grief trying to correct this, and eventually Leyla helped me out by recommending a line of code involving factors and levels.

number_errors_vector <- c("one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten")
number_errors <- errors %>%
  filter(correction %in% c("one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten")) %>%
  mutate(digit = case_when(
    endsWith(correction, "one") ~ "01",
    endsWith(correction, "two") ~ "02",
    endsWith(correction, "three") ~ "03",
    endsWith(correction, "four") ~ "04",
    endsWith(correction, "five") ~ "05",
    endsWith(correction, "six") ~ "06",
    endsWith(correction, "seven") ~ "07",
    endsWith(correction, "eight") ~ "08", 
    endsWith(correction, "nine") ~ "09",
    endsWith(correction, "ten") ~ "10"))
number_errors$digit <- as.numeric(as.character(number_errors$digit))
number_errors <- number_errors[order(number_errors$digit), ]
number_errors$correction <- factor(number_errors$correction,levels = unique(number_errors$correction),ordered = T)
View(number_errors)
ggplot(number_errors) +
  geom_bar(aes(x = correction, fill = correction)) +
  labs(title = "Error Frequency by Number",
       x = "Numbers",
       y = "Frequency") +
  theme(legend.position = "none", panel.background = element_rect(fill = "pink"))

It looks like “two” is the most-misspelled number term by a long shot, with over 150 misspellings in the dataset. There is also a major drop off in misspellings of numbers after three, which I can only assume can be attributed to people using digits in favor of spelled-out number terms for higher numbers. I think it makes more sense that there would be an overall lower frequency for larger number terms as opposed to a higher accuracy rate in typing them.

Error Frequency by Color

Then I turned to color terms. I opted to stick to the widely- (though I’m sure not universally-) agreed-upon eleven basic color terms in English, partially because many non-basic color terms in English derive from nouns with the same spelling, meaning it would be hard to tell whether or not the typer was using the word as a color term. The only basic color term where that issue arises is orange, but I decided I could live with that.

Here, I added two columns to the dataset: one with digits so I could get the data in the desired order, and one with shortened keys for each color name so that they could all fit comfortably and legibly as labels on the bar graph.

color_errors_vector <- c("pink", "red", "orange", "yellow", "green", "blue", "purple", "brown", "black", "grey", "gray", "white")
color_errors <- errors %>%
  filter(correction %in% c("pink", "red", "orange", "yellow", "green", "blue", "purple", "brown", "black", "grey", "gray", "white")) %>%
  mutate(color_lab = case_when(
    correction == "pink" ~ "Pi",
    correction == "red" ~ "R",
    correction == "orange" ~ "O",
    correction == "yellow" ~ "Y",
    correction == "green" ~ "Green",
    correction == "blue" ~ "Blue",
    correction == "purple" ~ "Pu",
    correction == "brown" ~ "Br", 
    correction == "black" ~ "Bla",
    correction == "grey" | correction == "gray" ~ "Grey",
    correction == "white" ~ "W")) %>%
  mutate(color_id = case_when(
    correction == "pink" ~ "01",
    correction == "red" ~ "02",
    correction == "orange" ~ "03",
    correction == "yellow" ~ "04",
    correction == "green" ~ "05",
    correction == "blue" ~ "06",
    correction == "purple" ~ "07",
    correction == "brown" ~ "08", 
    correction == "black" ~ "09",
    correction == "grey" | correction == "gray" ~ "10",
    correction == "white" ~ "11"))
color_errors$color_id <- as.numeric(as.character(color_errors$color_id))
color_errors <- color_errors[order(color_errors$color_id), ]
color_errors$color_lab <- factor(color_errors$color_lab,levels = unique(color_errors$color_lab),ordered = T)
View(color_errors)
ggplot(color_errors) +
  geom_bar(aes(x = color_lab, fill = correction)) +
  labs(title = "Error Frequency by Color",
       x = "Colors",
       y = "Frequency") +
  theme(legend.position = "none", panel.background = element_rect(fill = "#1D2257")) +
  scale_fill_manual("legend", values = c("pink" = "#FB7189", "red" = "#F03621", "orange" = "#F68f1d", "yellow" = "#FBD236", "green" = "#539232", "blue" = "#3D8FC6", "purple" = "#772B7F", "brown" = "#7D451E", "black" = "black", "white" = "white", "gray" = "gray", "grey" = "grey"))

Here we can see that the most-misspelled basic color term is “white”, followed closely by “black”–a duo that is often considered by artists, scientists, and other pedants not to be colors at all. Interesting! I would guess that in this case as well, it’s an issue of frequency. “Black” and “white” can be used imprecisely to describe things that are dark and light in a way that’s less strict than how the word “purple” is mostly just used to describe things that are purple. There are other applications of these words, too, beyond their color meanings, like as race descriptors.

“Grey” (and “gray”–I’ve combined the two into one column) scores the least misspellings. I wonder if the dual spellings make us think extra carefully when we type the word. Two of the “errors” corrected to “gray” were simply the with-an-E variant–it’s just as likely that the typers couldn’t make up their minds between the two spellings as the possibility that they typed the first one by accident when aiming for the other, which I consider to be the prototypical typo narrative.

Discussion

I think there are plenty of other worthwhile inquiries to be made about this data. I spoke on Monday with Kaung Zan, Michael, and Eliana about various ways of measuring the “distance” between the error and the correction, like the number of letters that are different between the two, or the distance between two keys on a keyboard in the case of letter substitution errors.

I know there are also different factors that drive us to make different kinds of errors (which I’ve been noticing much more while working on this project)–typing fast can cause us to miss a key or switch two letters around, mentally narrating as we type can cause us to substitute phonologically similar letters, and thinking about something else or hearing someone speak while we type can cause us to output something totally wrong. Trying to quantify these motivations would take a lot of guesswork, but it’s possible to measure the ways they manifest, at least in the case of more frequent and straightforward errors (e.g. elision, substitution, swapping).

Another metric to measure here could be the proportion of errors that were corrected to real, correctly-spelled words. However, there would be similar complications to the above in drawing conclusions about this set, and we would not be able to say for sure that they qualify as “true” corrections (as opposed to further errors). For example, since the data stops only after the correction immediately following the error, who’s to say what the final corrected term was? What if the typer intended to misspell the word? What if the immediate correction is a real, correctly-spelled word, but still the wrong one? What is a “real word”? What about terms in the data that include digits or punctuation? It could still be an interesting inquiry, and my hunch from scrolling through the data is that correctly-spelled corrections would prevail over incorrectly-spelled corrections.

People type differently from one another for a host of reasons including motor skills, what kind of keyboard they use, and how they learned to type. These differences may influence the kinds of errors we produce when we type. It was interesting looking at the full set of typing errors and seeing the wide range of ways we make typos, which we often quickly delete and move on from without a second thought.

I would be remiss if I didn’t mention that I think Amazon’s Mechanical Turk (the source of this dataset) and other similar digital micro-job platforms are highly exploitative operations.

Thnak yuou fr readig y ntebook :)

(^all real errors from the dataset)

Data: (2024, July 15). Microsoft Research Spelling-Correction Data. Microsoft Download Center. https://www.microsoft.com/en-us/download/details.aspx?id=52418

LS0tDQp0aXRsZTogIlNwZWxsaW5nIEVycm9yIEZyZXF1ZW5jeSBieSBXb3JkIENhdGVnb3J5Ig0Kb3V0cHV0Og0KICBodG1sX25vdGVib29rOg0KICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KLS0tDQoNClRoZSBkYXRhc2V0IEkgYW0gZXhwbG9yaW5nIGlzIHRoZSBFbmdsaXNoIGxhbmd1YWdlIGtleXN0cm9rZSBwYWlycyBpbiB0aGUgW01pY3Jvc29mdCBSZXNlYXJjaCBTcGVsbGluZy1Db3JyZWN0aW9uIERhdGEgY29sbGVjdGVkIHRocm91Z2ggTVR1cmtdKGh0dHBzOi8vd3d3Lm1pY3Jvc29mdC5jb20vZW4tdXMvZG93bmxvYWQvZGV0YWlscy5hc3B4P2lkPTUyNDE4KS4gRWFjaCBrZXlzdHJva2UgcGFpciBjb25zaXN0cyBvZiBhIHVzZXIncyBzcGVsbGluZyBlcnJvciBhbmQgdGhlaXIgY29ycmVjdGlvbi4gVGhlcmUgYXJlIDQ0LDEwNCBrZXlzdHJva2UgcGFpcnMgaW4gdGhlIGRhdGFzZXQsIHNvIEkgZGVjaWRlZCB0byBsb29rIGF0IHNtYWxsZXIgY2F0ZWdvcmllcyB3aXRoaW4gdGhlIGRhdGEgdG8gbWFrZSBpdCBtb3JlIG1hbmFnZWFibGUuDQpgYGB7cn0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KZXJyb3JzIDwtIHJlYWQuZGVsaW0oIkM6L1VzZXJzL2RlbGVlL09uZURyaXZlL0Rlc2t0b3AvYWxsX2tleXN0cm9rZV9wYWlycy50eHQiLCBxdW90ZSA9ICIiKQ0KVmlldyhlcnJvcnMpDQpgYGANCiMjIEVycm9yIEZyZXF1ZW5jeSBieSBOdW1iZXINCg0KRmlyc3QsIEkgZmlsdGVyZWQgdGhlIGRhdGEgZm9yIGVycm9ycyB0aGF0IHdlcmUgY29ycmVjdGVkIHRvIG51bWJlciB0ZXJtcyBmcm9tIG9uZSB0byB0ZW4uICBOb3RhYmx5LCB0aGlzIGRpc2NvdW50cyBrZXlzdHJva2UgcGFpcnMgaW4gd2hpY2ggYm90aCB0aGUgZXJyb3IgYW5kIHRoZSBjb3JyZWN0aW9uIGFyZSBtaXNzcGVsbGVkIG51bWJlciB0ZXJtcy4gIE1hbnkgaXRlbXMgaW4gdGhpcyBkYXRhc2V0IGFyZSBwYWlycyBpbiB3aGljaCB0aGUgdHlwZXIgc3RpbGwgZGlkIG5vdCBzcGVsbCBhIHdvcmQgY29ycmVjdGx5IGluIHRoZWlyIHNlY29uZCBhdHRlbXB0ICh3aG8gYW1vbmcgdXMpLCBidXQgd2UgZG9uJ3Qga25vdyB3aGF0IHRoZXkgd2VyZSB0cnlpbmcgdG8gdHlwZSBpbiB0aGVzZSBjYXNlcy4NCg0KSSBoYWQgdG8gZG8gc29tZSBmaW5hZ2xpbmcgdG8gb3JkZXIgdGhlIGRhdGEgY29ycmVjdGx5LiAgRXZlbiB3aGVuIEkgbWFuYWdlZCB0byBnZXQgdGhlbSBpbiBudW1lcmljYWwgb3JkZXIgaW4gdGhlIGRhdGFzZXQgYnkgaW50cm9kdWNpbmcgYSBjb2x1bW4gb2YgdGhlIGNvcnJlc3BvbmRpbmcgZGlnaXRzLCB0aGV5IGFwcGVhcmVkIGluIGFscGhhYmV0aWNhbCBvcmRlciBpbiB0aGUgdmlzdWFsaXphdGlvbi4gIEkgd2VudCB0aHJvdWdoIGEgbG90IG9mIGdyaWVmIHRyeWluZyB0byBjb3JyZWN0IHRoaXMsIGFuZCBldmVudHVhbGx5IExleWxhIGhlbHBlZCBtZSBvdXQgYnkgcmVjb21tZW5kaW5nIGEgbGluZSBvZiBjb2RlIGludm9sdmluZyBmYWN0b3JzIGFuZCBsZXZlbHMuDQpgYGB7cn0NCm51bWJlcl9lcnJvcnNfdmVjdG9yIDwtIGMoIm9uZSIsICJ0d28iLCAidGhyZWUiLCAiZm91ciIsICJmaXZlIiwgInNpeCIsICJzZXZlbiIsICJlaWdodCIsICJuaW5lIiwgInRlbiIpDQpudW1iZXJfZXJyb3JzIDwtIGVycm9ycyAlPiUNCiAgZmlsdGVyKGNvcnJlY3Rpb24gJWluJSBjKCJvbmUiLCAidHdvIiwgInRocmVlIiwgImZvdXIiLCAiZml2ZSIsICJzaXgiLCAic2V2ZW4iLCAiZWlnaHQiLCAibmluZSIsICJ0ZW4iKSkgJT4lDQogIG11dGF0ZShkaWdpdCA9IGNhc2Vfd2hlbigNCiAgICBlbmRzV2l0aChjb3JyZWN0aW9uLCAib25lIikgfiAiMDEiLA0KICAgIGVuZHNXaXRoKGNvcnJlY3Rpb24sICJ0d28iKSB+ICIwMiIsDQogICAgZW5kc1dpdGgoY29ycmVjdGlvbiwgInRocmVlIikgfiAiMDMiLA0KICAgIGVuZHNXaXRoKGNvcnJlY3Rpb24sICJmb3VyIikgfiAiMDQiLA0KICAgIGVuZHNXaXRoKGNvcnJlY3Rpb24sICJmaXZlIikgfiAiMDUiLA0KICAgIGVuZHNXaXRoKGNvcnJlY3Rpb24sICJzaXgiKSB+ICIwNiIsDQogICAgZW5kc1dpdGgoY29ycmVjdGlvbiwgInNldmVuIikgfiAiMDciLA0KICAgIGVuZHNXaXRoKGNvcnJlY3Rpb24sICJlaWdodCIpIH4gIjA4IiwgDQogICAgZW5kc1dpdGgoY29ycmVjdGlvbiwgIm5pbmUiKSB+ICIwOSIsDQogICAgZW5kc1dpdGgoY29ycmVjdGlvbiwgInRlbiIpIH4gIjEwIikpDQpudW1iZXJfZXJyb3JzJGRpZ2l0IDwtIGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKG51bWJlcl9lcnJvcnMkZGlnaXQpKQ0KbnVtYmVyX2Vycm9ycyA8LSBudW1iZXJfZXJyb3JzW29yZGVyKG51bWJlcl9lcnJvcnMkZGlnaXQpLCBdDQpudW1iZXJfZXJyb3JzJGNvcnJlY3Rpb24gPC0gZmFjdG9yKG51bWJlcl9lcnJvcnMkY29ycmVjdGlvbixsZXZlbHMgPSB1bmlxdWUobnVtYmVyX2Vycm9ycyRjb3JyZWN0aW9uKSxvcmRlcmVkID0gVCkNClZpZXcobnVtYmVyX2Vycm9ycykNCmdncGxvdChudW1iZXJfZXJyb3JzKSArDQogIGdlb21fYmFyKGFlcyh4ID0gY29ycmVjdGlvbiwgZmlsbCA9IGNvcnJlY3Rpb24pKSArDQogIGxhYnModGl0bGUgPSAiRXJyb3IgRnJlcXVlbmN5IGJ5IE51bWJlciIsDQogICAgICAgeCA9ICJOdW1iZXJzIiwNCiAgICAgICB5ID0gIkZyZXF1ZW5jeSIpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLCBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAicGluayIpKQ0KYGBgDQoNCkl0IGxvb2tzIGxpa2UgInR3byIgaXMgdGhlIG1vc3QtbWlzc3BlbGxlZCBudW1iZXIgdGVybSBieSBhIGxvbmcgc2hvdCwgd2l0aCBvdmVyIDE1MCBtaXNzcGVsbGluZ3MgaW4gdGhlIGRhdGFzZXQuICBUaGVyZSBpcyBhbHNvIGEgbWFqb3IgZHJvcCBvZmYgaW4gbWlzc3BlbGxpbmdzIG9mIG51bWJlcnMgYWZ0ZXIgdGhyZWUsIHdoaWNoIEkgY2FuIG9ubHkgYXNzdW1lIGNhbiBiZSBhdHRyaWJ1dGVkIHRvIHBlb3BsZSB1c2luZyBkaWdpdHMgaW4gZmF2b3Igb2Ygc3BlbGxlZC1vdXQgbnVtYmVyIHRlcm1zIGZvciBoaWdoZXIgbnVtYmVycy4gIEkgdGhpbmsgaXQgbWFrZXMgbW9yZSBzZW5zZSB0aGF0IHRoZXJlIHdvdWxkIGJlIGFuIG92ZXJhbGwgbG93ZXIgZnJlcXVlbmN5IGZvciBsYXJnZXIgbnVtYmVyIHRlcm1zIGFzIG9wcG9zZWQgdG8gYSBoaWdoZXIgYWNjdXJhY3kgcmF0ZSBpbiB0eXBpbmcgdGhlbS4NCg0KIyMgRXJyb3IgRnJlcXVlbmN5IGJ5IENvbG9yDQoNClRoZW4gSSB0dXJuZWQgdG8gY29sb3IgdGVybXMuICBJIG9wdGVkIHRvIHN0aWNrIHRvIHRoZSB3aWRlbHktICh0aG91Z2ggSSdtIHN1cmUgbm90IHVuaXZlcnNhbGx5LSkgYWdyZWVkLXVwb24gZWxldmVuIGJhc2ljIGNvbG9yIHRlcm1zIGluIEVuZ2xpc2gsIHBhcnRpYWxseSBiZWNhdXNlIG1hbnkgbm9uLWJhc2ljIGNvbG9yIHRlcm1zIGluIEVuZ2xpc2ggZGVyaXZlIGZyb20gbm91bnMgd2l0aCB0aGUgc2FtZSBzcGVsbGluZywgbWVhbmluZyBpdCB3b3VsZCBiZSBoYXJkIHRvIHRlbGwgd2hldGhlciBvciBub3QgdGhlIHR5cGVyIHdhcyB1c2luZyB0aGUgd29yZCBhcyBhIGNvbG9yIHRlcm0uICBUaGUgb25seSBiYXNpYyBjb2xvciB0ZXJtIHdoZXJlIHRoYXQgaXNzdWUgYXJpc2VzIGlzIG9yYW5nZSwgYnV0IEkgZGVjaWRlZCBJIGNvdWxkIGxpdmUgd2l0aCB0aGF0Lg0KDQpIZXJlLCBJIGFkZGVkIHR3byBjb2x1bW5zIHRvIHRoZSBkYXRhc2V0OiBvbmUgd2l0aCBkaWdpdHMgc28gSSBjb3VsZCBnZXQgdGhlIGRhdGEgaW4gdGhlIGRlc2lyZWQgb3JkZXIsIGFuZCBvbmUgd2l0aCBzaG9ydGVuZWQga2V5cyBmb3IgZWFjaCBjb2xvciBuYW1lIHNvIHRoYXQgdGhleSBjb3VsZCBhbGwgZml0IGNvbWZvcnRhYmx5IGFuZCBsZWdpYmx5IGFzIGxhYmVscyBvbiB0aGUgYmFyIGdyYXBoLg0KYGBge3J9DQpjb2xvcl9lcnJvcnNfdmVjdG9yIDwtIGMoInBpbmsiLCAicmVkIiwgIm9yYW5nZSIsICJ5ZWxsb3ciLCAiZ3JlZW4iLCAiYmx1ZSIsICJwdXJwbGUiLCAiYnJvd24iLCAiYmxhY2siLCAiZ3JleSIsICJncmF5IiwgIndoaXRlIikNCmNvbG9yX2Vycm9ycyA8LSBlcnJvcnMgJT4lDQogIGZpbHRlcihjb3JyZWN0aW9uICVpbiUgYygicGluayIsICJyZWQiLCAib3JhbmdlIiwgInllbGxvdyIsICJncmVlbiIsICJibHVlIiwgInB1cnBsZSIsICJicm93biIsICJibGFjayIsICJncmV5IiwgImdyYXkiLCAid2hpdGUiKSkgJT4lDQogIG11dGF0ZShjb2xvcl9sYWIgPSBjYXNlX3doZW4oDQogICAgY29ycmVjdGlvbiA9PSAicGluayIgfiAiUGkiLA0KICAgIGNvcnJlY3Rpb24gPT0gInJlZCIgfiAiUiIsDQogICAgY29ycmVjdGlvbiA9PSAib3JhbmdlIiB+ICJPIiwNCiAgICBjb3JyZWN0aW9uID09ICJ5ZWxsb3ciIH4gIlkiLA0KICAgIGNvcnJlY3Rpb24gPT0gImdyZWVuIiB+ICJHcmVlbiIsDQogICAgY29ycmVjdGlvbiA9PSAiYmx1ZSIgfiAiQmx1ZSIsDQogICAgY29ycmVjdGlvbiA9PSAicHVycGxlIiB+ICJQdSIsDQogICAgY29ycmVjdGlvbiA9PSAiYnJvd24iIH4gIkJyIiwgDQogICAgY29ycmVjdGlvbiA9PSAiYmxhY2siIH4gIkJsYSIsDQogICAgY29ycmVjdGlvbiA9PSAiZ3JleSIgfCBjb3JyZWN0aW9uID09ICJncmF5IiB+ICJHcmV5IiwNCiAgICBjb3JyZWN0aW9uID09ICJ3aGl0ZSIgfiAiVyIpKSAlPiUNCiAgbXV0YXRlKGNvbG9yX2lkID0gY2FzZV93aGVuKA0KICAgIGNvcnJlY3Rpb24gPT0gInBpbmsiIH4gIjAxIiwNCiAgICBjb3JyZWN0aW9uID09ICJyZWQiIH4gIjAyIiwNCiAgICBjb3JyZWN0aW9uID09ICJvcmFuZ2UiIH4gIjAzIiwNCiAgICBjb3JyZWN0aW9uID09ICJ5ZWxsb3ciIH4gIjA0IiwNCiAgICBjb3JyZWN0aW9uID09ICJncmVlbiIgfiAiMDUiLA0KICAgIGNvcnJlY3Rpb24gPT0gImJsdWUiIH4gIjA2IiwNCiAgICBjb3JyZWN0aW9uID09ICJwdXJwbGUiIH4gIjA3IiwNCiAgICBjb3JyZWN0aW9uID09ICJicm93biIgfiAiMDgiLCANCiAgICBjb3JyZWN0aW9uID09ICJibGFjayIgfiAiMDkiLA0KICAgIGNvcnJlY3Rpb24gPT0gImdyZXkiIHwgY29ycmVjdGlvbiA9PSAiZ3JheSIgfiAiMTAiLA0KICAgIGNvcnJlY3Rpb24gPT0gIndoaXRlIiB+ICIxMSIpKQ0KY29sb3JfZXJyb3JzJGNvbG9yX2lkIDwtIGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKGNvbG9yX2Vycm9ycyRjb2xvcl9pZCkpDQpjb2xvcl9lcnJvcnMgPC0gY29sb3JfZXJyb3JzW29yZGVyKGNvbG9yX2Vycm9ycyRjb2xvcl9pZCksIF0NCmNvbG9yX2Vycm9ycyRjb2xvcl9sYWIgPC0gZmFjdG9yKGNvbG9yX2Vycm9ycyRjb2xvcl9sYWIsbGV2ZWxzID0gdW5pcXVlKGNvbG9yX2Vycm9ycyRjb2xvcl9sYWIpLG9yZGVyZWQgPSBUKQ0KVmlldyhjb2xvcl9lcnJvcnMpDQpnZ3Bsb3QoY29sb3JfZXJyb3JzKSArDQogIGdlb21fYmFyKGFlcyh4ID0gY29sb3JfbGFiLCBmaWxsID0gY29ycmVjdGlvbikpICsNCiAgbGFicyh0aXRsZSA9ICJFcnJvciBGcmVxdWVuY3kgYnkgQ29sb3IiLA0KICAgICAgIHggPSAiQ29sb3JzIiwNCiAgICAgICB5ID0gIkZyZXF1ZW5jeSIpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLCBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiIzFEMjI1NyIpKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKCJsZWdlbmQiLCB2YWx1ZXMgPSBjKCJwaW5rIiA9ICIjRkI3MTg5IiwgInJlZCIgPSAiI0YwMzYyMSIsICJvcmFuZ2UiID0gIiNGNjhmMWQiLCAieWVsbG93IiA9ICIjRkJEMjM2IiwgImdyZWVuIiA9ICIjNTM5MjMyIiwgImJsdWUiID0gIiMzRDhGQzYiLCAicHVycGxlIiA9ICIjNzcyQjdGIiwgImJyb3duIiA9ICIjN0Q0NTFFIiwgImJsYWNrIiA9ICJibGFjayIsICJ3aGl0ZSIgPSAid2hpdGUiLCAiZ3JheSIgPSAiZ3JheSIsICJncmV5IiA9ICJncmV5IikpDQpgYGANCg0KSGVyZSB3ZSBjYW4gc2VlIHRoYXQgdGhlIG1vc3QtbWlzc3BlbGxlZCBiYXNpYyBjb2xvciB0ZXJtIGlzICJ3aGl0ZSIsIGZvbGxvd2VkIGNsb3NlbHkgYnkgImJsYWNrIi0tYSBkdW8gdGhhdCBpcyBvZnRlbiBjb25zaWRlcmVkIGJ5IGFydGlzdHMsIHNjaWVudGlzdHMsIGFuZCBvdGhlciBwZWRhbnRzIG5vdCB0byBiZSBjb2xvcnMgYXQgYWxsLiAgSW50ZXJlc3RpbmchICBJIHdvdWxkIGd1ZXNzIHRoYXQgaW4gdGhpcyBjYXNlIGFzIHdlbGwsIGl0J3MgYW4gaXNzdWUgb2YgZnJlcXVlbmN5LiAgIkJsYWNrIiBhbmQgIndoaXRlIiBjYW4gYmUgdXNlZCBpbXByZWNpc2VseSB0byBkZXNjcmliZSB0aGluZ3MgdGhhdCBhcmUgZGFyayBhbmQgbGlnaHQgaW4gYSB3YXkgdGhhdCdzIGxlc3Mgc3RyaWN0IHRoYW4gaG93IHRoZSB3b3JkICJwdXJwbGUiIGlzIG1vc3RseSBqdXN0IHVzZWQgdG8gZGVzY3JpYmUgdGhpbmdzIHRoYXQgYXJlIHB1cnBsZS4gIFRoZXJlIGFyZSBvdGhlciBhcHBsaWNhdGlvbnMgb2YgdGhlc2Ugd29yZHMsIHRvbywgYmV5b25kIHRoZWlyIGNvbG9yIG1lYW5pbmdzLCBsaWtlIGFzIHJhY2UgZGVzY3JpcHRvcnMuDQoNCiJHcmV5IiAoYW5kICJncmF5Ii0tSSd2ZSBjb21iaW5lZCB0aGUgdHdvIGludG8gb25lIGNvbHVtbikgc2NvcmVzIHRoZSBsZWFzdCBtaXNzcGVsbGluZ3MuICBJIHdvbmRlciBpZiB0aGUgZHVhbCBzcGVsbGluZ3MgbWFrZSB1cyB0aGluayBleHRyYSBjYXJlZnVsbHkgd2hlbiB3ZSB0eXBlIHRoZSB3b3JkLiAgVHdvIG9mIHRoZSAiZXJyb3JzIiBjb3JyZWN0ZWQgdG8gImdyYXkiIHdlcmUgc2ltcGx5IHRoZSB3aXRoLWFuLUUgdmFyaWFudC0taXQncyBqdXN0IGFzIGxpa2VseSB0aGF0IHRoZSB0eXBlcnMgY291bGRuJ3QgbWFrZSB1cCB0aGVpciBtaW5kcyBiZXR3ZWVuIHRoZSB0d28gc3BlbGxpbmdzIGFzIHRoZSBwb3NzaWJpbGl0eSB0aGF0IHRoZXkgdHlwZWQgdGhlIGZpcnN0IG9uZSBieSBhY2NpZGVudCB3aGVuIGFpbWluZyBmb3IgdGhlIG90aGVyLCB3aGljaCBJIGNvbnNpZGVyIHRvIGJlIHRoZSBwcm90b3R5cGljYWwgdHlwbyBuYXJyYXRpdmUuIA0KDQojIyBEaXNjdXNzaW9uDQoNCkkgdGhpbmsgdGhlcmUgYXJlIHBsZW50eSBvZiBvdGhlciB3b3J0aHdoaWxlIGlucXVpcmllcyB0byBiZSBtYWRlIGFib3V0IHRoaXMgZGF0YS4gIEkgc3Bva2Ugb24gTW9uZGF5IHdpdGggS2F1bmcgWmFuLCBNaWNoYWVsLCBhbmQgRWxpYW5hIGFib3V0IHZhcmlvdXMgd2F5cyBvZiBtZWFzdXJpbmcgdGhlICJkaXN0YW5jZSIgYmV0d2VlbiB0aGUgZXJyb3IgYW5kIHRoZSBjb3JyZWN0aW9uLCBsaWtlIHRoZSBudW1iZXIgb2YgbGV0dGVycyB0aGF0IGFyZSBkaWZmZXJlbnQgYmV0d2VlbiB0aGUgdHdvLCBvciB0aGUgZGlzdGFuY2UgYmV0d2VlbiB0d28ga2V5cyBvbiBhIGtleWJvYXJkIGluIHRoZSBjYXNlIG9mIGxldHRlciBzdWJzdGl0dXRpb24gZXJyb3JzLg0KDQpJIGtub3cgdGhlcmUgYXJlIGFsc28gZGlmZmVyZW50IGZhY3RvcnMgdGhhdCBkcml2ZSB1cyB0byBtYWtlIGRpZmZlcmVudCBraW5kcyBvZiBlcnJvcnMgKHdoaWNoIEkndmUgYmVlbiBub3RpY2luZyBtdWNoIG1vcmUgd2hpbGUgd29ya2luZyBvbiB0aGlzIHByb2plY3QpLS10eXBpbmcgZmFzdCBjYW4gY2F1c2UgdXMgdG8gbWlzcyBhIGtleSBvciBzd2l0Y2ggdHdvIGxldHRlcnMgYXJvdW5kLCBtZW50YWxseSBuYXJyYXRpbmcgYXMgd2UgdHlwZSBjYW4gY2F1c2UgdXMgdG8gc3Vic3RpdHV0ZSBwaG9ub2xvZ2ljYWxseSBzaW1pbGFyIGxldHRlcnMsIGFuZCB0aGlua2luZyBhYm91dCBzb21ldGhpbmcgZWxzZSBvciBoZWFyaW5nIHNvbWVvbmUgc3BlYWsgd2hpbGUgd2UgdHlwZSBjYW4gY2F1c2UgdXMgdG8gb3V0cHV0IHNvbWV0aGluZyB0b3RhbGx5IHdyb25nLiAgVHJ5aW5nIHRvIHF1YW50aWZ5IHRoZXNlIG1vdGl2YXRpb25zIHdvdWxkIHRha2UgYSBsb3Qgb2YgZ3Vlc3N3b3JrLCBidXQgaXQncyBwb3NzaWJsZSB0byBtZWFzdXJlIHRoZSB3YXlzIHRoZXkgbWFuaWZlc3QsIGF0IGxlYXN0IGluIHRoZSBjYXNlIG9mIG1vcmUgZnJlcXVlbnQgYW5kIHN0cmFpZ2h0Zm9yd2FyZCBlcnJvcnMgKGUuZy4gZWxpc2lvbiwgc3Vic3RpdHV0aW9uLCBzd2FwcGluZykuDQoNCkFub3RoZXIgbWV0cmljIHRvIG1lYXN1cmUgaGVyZSBjb3VsZCBiZSB0aGUgcHJvcG9ydGlvbiBvZiBlcnJvcnMgdGhhdCB3ZXJlIGNvcnJlY3RlZCB0byByZWFsLCBjb3JyZWN0bHktc3BlbGxlZCB3b3Jkcy4gIEhvd2V2ZXIsIHRoZXJlIHdvdWxkIGJlIHNpbWlsYXIgY29tcGxpY2F0aW9ucyB0byB0aGUgYWJvdmUgaW4gZHJhd2luZyBjb25jbHVzaW9ucyBhYm91dCB0aGlzIHNldCwgYW5kIHdlIHdvdWxkIG5vdCBiZSBhYmxlIHRvIHNheSBmb3Igc3VyZSB0aGF0IHRoZXkgcXVhbGlmeSBhcyAidHJ1ZSIgY29ycmVjdGlvbnMgKGFzIG9wcG9zZWQgdG8gZnVydGhlciBlcnJvcnMpLiAgRm9yIGV4YW1wbGUsIHNpbmNlIHRoZSBkYXRhIHN0b3BzIG9ubHkgYWZ0ZXIgdGhlIGNvcnJlY3Rpb24gaW1tZWRpYXRlbHkgZm9sbG93aW5nIHRoZSBlcnJvciwgd2hvJ3MgdG8gc2F5IHdoYXQgdGhlIGZpbmFsIGNvcnJlY3RlZCB0ZXJtIHdhcz8gIFdoYXQgaWYgdGhlIHR5cGVyIGludGVuZGVkIHRvIG1pc3NwZWxsIHRoZSB3b3JkPyAgV2hhdCBpZiB0aGUgaW1tZWRpYXRlIGNvcnJlY3Rpb24gaXMgYSByZWFsLCBjb3JyZWN0bHktc3BlbGxlZCB3b3JkLCBidXQgc3RpbGwgdGhlIHdyb25nIG9uZT8gIFdoYXQgaXMgYSAicmVhbCB3b3JkIj8gIFdoYXQgYWJvdXQgdGVybXMgaW4gdGhlIGRhdGEgdGhhdCBpbmNsdWRlIGRpZ2l0cyBvciBwdW5jdHVhdGlvbj8gIEl0IGNvdWxkIHN0aWxsIGJlIGFuIGludGVyZXN0aW5nIGlucXVpcnksIGFuZCBteSBodW5jaCBmcm9tIHNjcm9sbGluZyB0aHJvdWdoIHRoZSBkYXRhIGlzIHRoYXQgY29ycmVjdGx5LXNwZWxsZWQgY29ycmVjdGlvbnMgd291bGQgcHJldmFpbCBvdmVyIGluY29ycmVjdGx5LXNwZWxsZWQgY29ycmVjdGlvbnMuDQoNClBlb3BsZSB0eXBlIGRpZmZlcmVudGx5IGZyb20gb25lIGFub3RoZXIgZm9yIGEgaG9zdCBvZiByZWFzb25zIGluY2x1ZGluZyBtb3RvciBza2lsbHMsIHdoYXQga2luZCBvZiBrZXlib2FyZCB0aGV5IHVzZSwgYW5kIGhvdyB0aGV5IGxlYXJuZWQgdG8gdHlwZS4gIFRoZXNlIGRpZmZlcmVuY2VzIG1heSBpbmZsdWVuY2UgdGhlIGtpbmRzIG9mIGVycm9ycyB3ZSBwcm9kdWNlIHdoZW4gd2UgdHlwZS4gIEl0IHdhcyBpbnRlcmVzdGluZyBsb29raW5nIGF0IHRoZSBmdWxsIHNldCBvZiB0eXBpbmcgZXJyb3JzIGFuZCBzZWVpbmcgdGhlIHdpZGUgcmFuZ2Ugb2Ygd2F5cyB3ZSBtYWtlIHR5cG9zLCB3aGljaCB3ZSBvZnRlbiBxdWlja2x5IGRlbGV0ZSBhbmQgbW92ZSBvbiBmcm9tIHdpdGhvdXQgYSBzZWNvbmQgdGhvdWdodC4NCg0KSSB3b3VsZCBiZSByZW1pc3MgaWYgSSBkaWRuJ3QgbWVudGlvbiB0aGF0IEkgdGhpbmsgQW1hem9uJ3MgTWVjaGFuaWNhbCBUdXJrICh0aGUgc291cmNlIG9mIHRoaXMgZGF0YXNldCkgYW5kIG90aGVyIHNpbWlsYXIgZGlnaXRhbCBtaWNyby1qb2IgcGxhdGZvcm1zIGFyZSBoaWdobHkgZXhwbG9pdGF0aXZlIG9wZXJhdGlvbnMuDQoNClRobmFrIHl1b3UgZnIgcmVhZGlnIHkgbnRlYm9vayA6KQ0KDQooXmFsbCByZWFsIGVycm9ycyBmcm9tIHRoZSBkYXRhc2V0KQ0KDQpEYXRhOg0KKDIwMjQsIEp1bHkgMTUpLiAqTWljcm9zb2Z0IFJlc2VhcmNoIFNwZWxsaW5nLUNvcnJlY3Rpb24gRGF0YSouIE1pY3Jvc29mdCBEb3dubG9hZCBDZW50ZXIuIFtodHRwczovL3d3dy5taWNyb3NvZnQuY29tL2VuLXVzL2Rvd25sb2FkL2RldGFpbHMuYXNweD9pZD01MjQxOF0oaHR0cHM6Ly93d3cubWljcm9zb2Z0LmNvbS9lbi11cy9kb3dubG9hZC9kZXRhaWxzLmFzcHg/aWQ9NTI0MTgp