published by Qingyun Wu

Import all the libraries needed and load all the csv data source:

library(ggplot2)
Want to understand how all the pieces fit together? Buy the ggplot2 book: http://ggplot2.org/book/
library(ggmap)
Google Maps API Terms of Service: http://developers.google.com/maps/terms.
Please cite ggmap if you use it: see citation('ggmap') for details.
library(gridExtra)
library(lubridate)
data_407_day = read.csv("RTL150407_day.csv", header=T)
data_407_night = read.csv("RTL150407_night.csv", header=T)
data_1208_day = read.csv("RTL151208_day.csv", header=T)
data_1208_night = read.csv("RTL151208_night.csv", header=T)

FLIGHT PATH

The following four graphs show differences in path (latitude, longitude and altitude) over time.

We can clearly see that altitude is differed by the color from red to blue, and the line in the map shows the path of the flight.

fight_mapplot <- function(fightpath) {
  SMO <- data.frame(label = "SMO", lon=-118.456667, lat=34.010167)
  smo <- c(SMO$lon, SMO$lat)
  map.google <- get_map(smo, zoom = 12)  # get map around SMO
  p <- ggmap(map.google)
  return (p + geom_point(data = SMO, aes(x=lon, y=lat), color="red", size=5, alpha=.5) 
          + geom_path(data = fightpath, aes(x = lon, y = lat, color=alt), alpha=.5) 
          + scale_colour_gradient(limits=c(1000, 11000), low="red", high="blue"))
}
fight_mapplot(data_407_day) + labs(title = "Daytime Fight Path on 04/07/2015")
Map from URL : http://maps.googleapis.com/maps/api/staticmap?center=34.010167,-118.456667&zoom=12&size=640x640&scale=2&maptype=terrain&language=en-EN&sensor=false

fight_mapplot(data_407_night) + labs(title = "Nighttime Fight Path on 04/07/2015")
Map from URL : http://maps.googleapis.com/maps/api/staticmap?center=34.010167,-118.456667&zoom=12&size=640x640&scale=2&maptype=terrain&language=en-EN&sensor=false

fight_mapplot(data_1208_day) + labs(title = "Daytime Fight Path on 12/08/2015")
Map from URL : http://maps.googleapis.com/maps/api/staticmap?center=34.010167,-118.456667&zoom=12&size=640x640&scale=2&maptype=terrain&language=en-EN&sensor=false

fight_mapplot(data_1208_night) + labs(title = "Nighttime Fight Path on 12/08/2015")
Map from URL : http://maps.googleapis.com/maps/api/staticmap?center=34.010167,-118.456667&zoom=12&size=640x640&scale=2&maptype=terrain&language=en-EN&sensor=false

BAR CHART

The following four graph are bar charts to show number of different fight which distance from SMO is between 10000 to 50000km over time. The function extractTime can do all the work, and I use ggplot2 to make the barchart.

For example, in the first graph, we can see 9:30 to 10:00 has the most number of flight which conform our regulation.

extractTime <- function(oridf, start, end) {
  oridf$timestamp = as.POSIXct(oridf$timestamp, format = "%Y-%m-%d %H:%M:%S")
  start = as.POSIXct(start, format = "%Y-%m-%d %H:%M:%S")
  end = as.POSIXct(end, format = "%Y-%m-%d %H:%M:%S")
  gain <- ymd_hms("2015-03-02 11:30:00", tz="America/Los_Angeles")-ymd_hms("2015-03-02 11:00:00", tz="America/Los_Angeles")
  newdf <- subset(oridf, timestamp >= start & timestamp < end, select=c(code, alt))
  udf <- data.frame(code = unique(newdf$code))
  tmpoend <- start + gain
  result <- data.frame()
  while (tmpoend <= end) {
    intervaltime <- subset(oridf, timestamp >= start 
                           & timestamp <= tmpoend
                           & dist >= 10000
                           & dist <= 50000,
                           select=(c(code,dist)))
    count <- length(unique(intervaltime$code))
    entry <- data.frame(starttime = start, flightsnum = count)
    result <- rbind(result, entry)
    start <- tmpoend
    tmpoend <- tmpoend + gain
  }
  result$starttime <- strftime(result$starttime, format = "%H:%M")
  return(result)
}
finaldata <- extractTime(data_407_day, "2015-04-07 06:30:00","2015-04-07 12:00:00")
require(ggplot2)
install.packages('gcookbook')
trying URL 'https://cran.rstudio.com/bin/macosx/el-capitan/contrib/3.4/gcookbook_1.0.tgz'
Content type 'application/x-gzip' length 4002525 bytes (3.8 MB)
==================================================
downloaded 3.8 MB

tar: Failed to set default locale

The downloaded binary packages are in
    /var/folders/pk/x3_vr3nn6ydbk8ydx01nqs5c0000gn/T//RtmpKGnfET/downloaded_packages
library(gcookbook)

Attaching package: 'gcookbook'

The following object is masked from 'package:ggmap':

    wind
library(ggplot2)
#ggplot(finaldata, aes(starttime, flightsnum)) + geom_line() + geom_point()
#ggplot() + geom_line(data=finaldata, aes(x=starttime, y=flightsnum))+geom_point()
#ggplot(data = finaldata, aes(y = flightsnum, x = starttime)) + geom_line()
ggplot(data=finaldata, aes(y = flightsnum, x = starttime)) +
  geom_bar(stat="identity", aes(fill=factor(starttime))) + 
  xlab("time") + 
  ylab("flights numbers") + labs(title = "Number of Selected Distance Flight on 04/07/2015 Day Time")

finaldata <- extractTime(data_407_night, "2015-04-07 00:00:00","2015-04-07 06:30:00")
ggplot(data=finaldata, aes(y = flightsnum, x = starttime)) +
  geom_bar(stat="identity", aes(fill=factor(starttime))) + 
  xlab("time") + 
  ylab("flights number") + labs(title = "Number of Selected Distance Flight on 04/07/2015 Night Time")

finaldata <- extractTime(data_1208_day, "2015-12-08 06:30:00","2015-12-08 12:00:00")
ggplot(data=finaldata, aes(y = flightsnum, x = starttime)) +
  geom_bar(stat="identity", aes(fill=factor(starttime))) + 
  xlab("time") + 
  ylab("flights number") + labs(title = "Number of Selected Distance Flight on 12/08/2015 Day Time")

finaldata <- extractTime(data_1208_night, "2015-12-08 00:00:00","2015-12-08 06:30:00")
ggplot(data=finaldata, aes(y = flightsnum, x = starttime)) +
  geom_bar(stat="identity", aes(fill=factor(starttime))) + 
  xlab("time") + 
  ylab("flights number") + labs(title = "Number of Selected Distance Flight on 12/08/2015 Night Time")

LINE CHART

The following two charts are to compare number of flights between two choosen days over time:

finaldata1 <- extractTime(data_407_day, "2015-04-07 06:30:00","2015-04-07 12:00:00")
finaldata2 <- extractTime(data_1208_day, "2015-12-08 06:30:00","2015-12-08 12:00:00")
ggplot() +
  geom_line(data=finaldata1, aes(x = starttime, y=flightsnum, group=5, color="daytime 04/07")) + 
  geom_line(data=finaldata2, aes(x = starttime, y=flightsnum, group=5, color="daytime 12/08")) +
  xlab("time") + 
  ylab("flights number") + labs(title = "Compare Number of Selected Distance Flight of Two Days")

finaldata1 <- extractTime(data_407_night, "2015-04-07 00:00:00","2015-04-07 06:30:00")
finaldata2 <- extractTime(data_1208_night, "2015-12-08 00:00:00","2015-12-08 06:30:00")
ggplot() +
  geom_line(data=finaldata1, aes(x = starttime, y=flightsnum, group=5, color="nighttime 04/07")) + 
  geom_line(data=finaldata2, aes(x = starttime, y=flightsnum, group=5, color="nighttime 12/08")) +
  xlab("time") + 
  ylab("flights number") + labs(title = "Compare Number of Selected Distance Flight of Two Nights")

PIE CHART

Compare unique flight numbers between two choosen days using bar chart. You can see each day’s flight number percentages on the graph. It can be obvious that flight number on 2015-12-08 is much more than 2015-04-07.

install.packages('plotrix')
trying URL 'https://cran.rstudio.com/bin/macosx/el-capitan/contrib/3.4/plotrix_3.6-6.tgz'
Content type 'application/x-gzip' length 679987 bytes (664 KB)
==================================================
downloaded 664 KB

tar: Failed to set default locale

The downloaded binary packages are in
    /var/folders/pk/x3_vr3nn6ydbk8ydx01nqs5c0000gn/T//RtmpKGnfET/downloaded_packages
library(plotrix)
library(dplyr)

Attaching package: 'dplyr'

The following object is masked from 'package:gridExtra':

    combine

The following objects are masked from 'package:lubridate':

    intersect, setdiff, union

The following objects are masked from 'package:stats':

    filter, lag

The following objects are masked from 'package:base':

    intersect, setdiff, setequal, union
firstday <- length(unique(data_407_day$code))
firstnight <- length(unique(data_407_night$code))
firsttotal = firstday + firstnight
secondday <- length(unique(data_1208_day$code))
secondnight <- length(unique(data_1208_night$code))
secondtotal = secondday + secondnight
data <- c(firsttotal,secondtotal)
lbls <- c("2015-04-07","2015-12-08")
pct <- round(data/sum(data)*100)
lbls <- paste(lbls, pct) # add percents to labels 
lbls <- paste(lbls,"%",sep="") # ad % to labels 
pie(data,labels = lbls, col=rainbow(length(lbls)),
    main="Unique Flights Between Two Days")

LS0tCnRpdGxlOiAiSU5GNTU0IEFzc2lnbm1lbnQgNCBIb21ld29yayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQpwdWJsaXNoZWQgYnkgUWluZ3l1biBXdQoKKipJbXBvcnQgYWxsIHRoZSBsaWJyYXJpZXMgbmVlZGVkIGFuZCBsb2FkIGFsbCB0aGUgY3N2IGRhdGEgc291cmNlOioqCgpgYGB7cn0KbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGdnbWFwKQpsaWJyYXJ5KGdyaWRFeHRyYSkKbGlicmFyeShsdWJyaWRhdGUpCmRhdGFfNDA3X2RheSA9IHJlYWQuY3N2KCJSVEwxNTA0MDdfZGF5LmNzdiIsIGhlYWRlcj1UKQpkYXRhXzQwN19uaWdodCA9IHJlYWQuY3N2KCJSVEwxNTA0MDdfbmlnaHQuY3N2IiwgaGVhZGVyPVQpCmRhdGFfMTIwOF9kYXkgPSByZWFkLmNzdigiUlRMMTUxMjA4X2RheS5jc3YiLCBoZWFkZXI9VCkKZGF0YV8xMjA4X25pZ2h0ID0gcmVhZC5jc3YoIlJUTDE1MTIwOF9uaWdodC5jc3YiLCBoZWFkZXI9VCkKYGBgCiMjRkxJR0hUIFBBVEgKKipUaGUgZm9sbG93aW5nIGZvdXIgZ3JhcGhzIHNob3cgZGlmZmVyZW5jZXMgaW4gcGF0aCAobGF0aXR1ZGUsIGxvbmdpdHVkZSBhbmQgYWx0aXR1ZGUpIG92ZXIgdGltZS4qKgoKKipXZSBjYW4gY2xlYXJseSBzZWUgdGhhdCBhbHRpdHVkZSBpcyBkaWZmZXJlZCBieSB0aGUgY29sb3IgZnJvbSByZWQgdG8gYmx1ZSwgYW5kIHRoZSBsaW5lIGluIHRoZSBtYXAgc2hvd3MgdGhlIHBhdGggb2YgdGhlIGZsaWdodC4qKgoKYGBge3J9CmZpZ2h0X21hcHBsb3QgPC0gZnVuY3Rpb24oZmlnaHRwYXRoKSB7CiAgU01PIDwtIGRhdGEuZnJhbWUobGFiZWwgPSAiU01PIiwgbG9uPS0xMTguNDU2NjY3LCBsYXQ9MzQuMDEwMTY3KQogIHNtbyA8LSBjKFNNTyRsb24sIFNNTyRsYXQpCiAgbWFwLmdvb2dsZSA8LSBnZXRfbWFwKHNtbywgem9vbSA9IDEyKSAgIyBnZXQgbWFwIGFyb3VuZCBTTU8KICBwIDwtIGdnbWFwKG1hcC5nb29nbGUpCiAgcmV0dXJuIChwICsgZ2VvbV9wb2ludChkYXRhID0gU01PLCBhZXMoeD1sb24sIHk9bGF0KSwgY29sb3I9InJlZCIsIHNpemU9NSwgYWxwaGE9LjUpIAogICAgICAgICAgKyBnZW9tX3BhdGgoZGF0YSA9IGZpZ2h0cGF0aCwgYWVzKHggPSBsb24sIHkgPSBsYXQsIGNvbG9yPWFsdCksIGFscGhhPS41KSAKICAgICAgICAgICsgc2NhbGVfY29sb3VyX2dyYWRpZW50KGxpbWl0cz1jKDEwMDAsIDExMDAwKSwgbG93PSJyZWQiLCBoaWdoPSJibHVlIikpCn0KZmlnaHRfbWFwcGxvdChkYXRhXzQwN19kYXkpICsgbGFicyh0aXRsZSA9ICJEYXl0aW1lIEZpZ2h0IFBhdGggb24gMDQvMDcvMjAxNSIpCmBgYAoKYGBge3J9CmZpZ2h0X21hcHBsb3QoZGF0YV80MDdfbmlnaHQpICsgbGFicyh0aXRsZSA9ICJOaWdodHRpbWUgRmlnaHQgUGF0aCBvbiAwNC8wNy8yMDE1IikKYGBgCgpgYGB7cn0KZmlnaHRfbWFwcGxvdChkYXRhXzEyMDhfZGF5KSArIGxhYnModGl0bGUgPSAiRGF5dGltZSBGaWdodCBQYXRoIG9uIDEyLzA4LzIwMTUiKQpgYGAKCmBgYHtyfQpmaWdodF9tYXBwbG90KGRhdGFfMTIwOF9uaWdodCkgKyBsYWJzKHRpdGxlID0gIk5pZ2h0dGltZSBGaWdodCBQYXRoIG9uIDEyLzA4LzIwMTUiKQpgYGAKIyNCQVIgQ0hBUlQKCioqVGhlIGZvbGxvd2luZyBmb3VyIGdyYXBoIGFyZSBiYXIgY2hhcnRzIHRvIHNob3cgbnVtYmVyIG9mIGRpZmZlcmVudCBmaWdodCB3aGljaCBkaXN0YW5jZSBmcm9tIFNNTyBpcyBiZXR3ZWVuIDEwMDAwIHRvIDUwMDAwa20gb3ZlciB0aW1lLiBUaGUgZnVuY3Rpb24gZXh0cmFjdFRpbWUgY2FuIGRvIGFsbCB0aGUgd29yaywgYW5kIEkgdXNlIGdncGxvdDIgdG8gbWFrZSB0aGUgYmFyY2hhcnQuKiogCgoqKkZvciBleGFtcGxlLCBpbiB0aGUgZmlyc3QgZ3JhcGgsIHdlIGNhbiBzZWUgOTozMCB0byAxMDowMCBoYXMgdGhlIG1vc3QgbnVtYmVyIG9mIGZsaWdodCB3aGljaCBjb25mb3JtIG91ciByZWd1bGF0aW9uLioqCgpgYGB7cn0KZXh0cmFjdFRpbWUgPC0gZnVuY3Rpb24ob3JpZGYsIHN0YXJ0LCBlbmQpIHsKICBvcmlkZiR0aW1lc3RhbXAgPSBhcy5QT1NJWGN0KG9yaWRmJHRpbWVzdGFtcCwgZm9ybWF0ID0gIiVZLSVtLSVkICVIOiVNOiVTIikKICBzdGFydCA9IGFzLlBPU0lYY3Qoc3RhcnQsIGZvcm1hdCA9ICIlWS0lbS0lZCAlSDolTTolUyIpCiAgZW5kID0gYXMuUE9TSVhjdChlbmQsIGZvcm1hdCA9ICIlWS0lbS0lZCAlSDolTTolUyIpCiAgZ2FpbiA8LSB5bWRfaG1zKCIyMDE1LTAzLTAyIDExOjMwOjAwIiwgdHo9IkFtZXJpY2EvTG9zX0FuZ2VsZXMiKS15bWRfaG1zKCIyMDE1LTAzLTAyIDExOjAwOjAwIiwgdHo9IkFtZXJpY2EvTG9zX0FuZ2VsZXMiKQoKICBuZXdkZiA8LSBzdWJzZXQob3JpZGYsIHRpbWVzdGFtcCA+PSBzdGFydCAmIHRpbWVzdGFtcCA8IGVuZCwgc2VsZWN0PWMoY29kZSwgYWx0KSkKICB1ZGYgPC0gZGF0YS5mcmFtZShjb2RlID0gdW5pcXVlKG5ld2RmJGNvZGUpKQogIHRtcG9lbmQgPC0gc3RhcnQgKyBnYWluCiAgcmVzdWx0IDwtIGRhdGEuZnJhbWUoKQogIHdoaWxlICh0bXBvZW5kIDw9IGVuZCkgewogICAgaW50ZXJ2YWx0aW1lIDwtIHN1YnNldChvcmlkZiwgdGltZXN0YW1wID49IHN0YXJ0IAogICAgICAgICAgICAgICAgICAgICAgICAgICAmIHRpbWVzdGFtcCA8PSB0bXBvZW5kCiAgICAgICAgICAgICAgICAgICAgICAgICAgICYgZGlzdCA+PSAxMDAwMAogICAgICAgICAgICAgICAgICAgICAgICAgICAmIGRpc3QgPD0gNTAwMDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdD0oYyhjb2RlLGRpc3QpKSkKICAgIGNvdW50IDwtIGxlbmd0aCh1bmlxdWUoaW50ZXJ2YWx0aW1lJGNvZGUpKQogICAgZW50cnkgPC0gZGF0YS5mcmFtZShzdGFydHRpbWUgPSBzdGFydCwgZmxpZ2h0c251bSA9IGNvdW50KQogICAgcmVzdWx0IDwtIHJiaW5kKHJlc3VsdCwgZW50cnkpCiAgICBzdGFydCA8LSB0bXBvZW5kCiAgICB0bXBvZW5kIDwtIHRtcG9lbmQgKyBnYWluCiAgfQogIHJlc3VsdCRzdGFydHRpbWUgPC0gc3RyZnRpbWUocmVzdWx0JHN0YXJ0dGltZSwgZm9ybWF0ID0gIiVIOiVNIikKICByZXR1cm4ocmVzdWx0KQp9CmZpbmFsZGF0YSA8LSBleHRyYWN0VGltZShkYXRhXzQwN19kYXksICIyMDE1LTA0LTA3IDA2OjMwOjAwIiwiMjAxNS0wNC0wNyAxMjowMDowMCIpCgpyZXF1aXJlKGdncGxvdDIpCmluc3RhbGwucGFja2FnZXMoJ2djb29rYm9vaycpCmxpYnJhcnkoZ2Nvb2tib29rKQpsaWJyYXJ5KGdncGxvdDIpCiNnZ3Bsb3QoZmluYWxkYXRhLCBhZXMoc3RhcnR0aW1lLCBmbGlnaHRzbnVtKSkgKyBnZW9tX2xpbmUoKSArIGdlb21fcG9pbnQoKQojZ2dwbG90KCkgKyBnZW9tX2xpbmUoZGF0YT1maW5hbGRhdGEsIGFlcyh4PXN0YXJ0dGltZSwgeT1mbGlnaHRzbnVtKSkrZ2VvbV9wb2ludCgpCiNnZ3Bsb3QoZGF0YSA9IGZpbmFsZGF0YSwgYWVzKHkgPSBmbGlnaHRzbnVtLCB4ID0gc3RhcnR0aW1lKSkgKyBnZW9tX2xpbmUoKQpnZ3Bsb3QoZGF0YT1maW5hbGRhdGEsIGFlcyh5ID0gZmxpZ2h0c251bSwgeCA9IHN0YXJ0dGltZSkpICsKICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIsIGFlcyhmaWxsPWZhY3RvcihzdGFydHRpbWUpKSkgKyAKICB4bGFiKCJ0aW1lIikgKyAKICB5bGFiKCJmbGlnaHRzIG51bWJlcnMiKSArIGxhYnModGl0bGUgPSAiTnVtYmVyIG9mIFNlbGVjdGVkIERpc3RhbmNlIEZsaWdodCBvbiAwNC8wNy8yMDE1IERheSBUaW1lIikKCmBgYAoKCmBgYHtyfQpmaW5hbGRhdGEgPC0gZXh0cmFjdFRpbWUoZGF0YV80MDdfbmlnaHQsICIyMDE1LTA0LTA3IDAwOjAwOjAwIiwiMjAxNS0wNC0wNyAwNjozMDowMCIpCgpnZ3Bsb3QoZGF0YT1maW5hbGRhdGEsIGFlcyh5ID0gZmxpZ2h0c251bSwgeCA9IHN0YXJ0dGltZSkpICsKICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIsIGFlcyhmaWxsPWZhY3RvcihzdGFydHRpbWUpKSkgKyAKICB4bGFiKCJ0aW1lIikgKyAKICB5bGFiKCJmbGlnaHRzIG51bWJlciIpICsgbGFicyh0aXRsZSA9ICJOdW1iZXIgb2YgU2VsZWN0ZWQgRGlzdGFuY2UgRmxpZ2h0IG9uIDA0LzA3LzIwMTUgTmlnaHQgVGltZSIpCmBgYAoKCgoKYGBge3J9CmZpbmFsZGF0YSA8LSBleHRyYWN0VGltZShkYXRhXzEyMDhfZGF5LCAiMjAxNS0xMi0wOCAwNjozMDowMCIsIjIwMTUtMTItMDggMTI6MDA6MDAiKQoKZ2dwbG90KGRhdGE9ZmluYWxkYXRhLCBhZXMoeSA9IGZsaWdodHNudW0sIHggPSBzdGFydHRpbWUpKSArCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiLCBhZXMoZmlsbD1mYWN0b3Ioc3RhcnR0aW1lKSkpICsgCiAgeGxhYigidGltZSIpICsgCiAgeWxhYigiZmxpZ2h0cyBudW1iZXIiKSArIGxhYnModGl0bGUgPSAiTnVtYmVyIG9mIFNlbGVjdGVkIERpc3RhbmNlIEZsaWdodCBvbiAxMi8wOC8yMDE1IERheSBUaW1lIikKYGBgCgpgYGB7cn0KZmluYWxkYXRhIDwtIGV4dHJhY3RUaW1lKGRhdGFfMTIwOF9uaWdodCwgIjIwMTUtMTItMDggMDA6MDA6MDAiLCIyMDE1LTEyLTA4IDA2OjMwOjAwIikKCmdncGxvdChkYXRhPWZpbmFsZGF0YSwgYWVzKHkgPSBmbGlnaHRzbnVtLCB4ID0gc3RhcnR0aW1lKSkgKwogIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IiwgYWVzKGZpbGw9ZmFjdG9yKHN0YXJ0dGltZSkpKSArIAogIHhsYWIoInRpbWUiKSArIAogIHlsYWIoImZsaWdodHMgbnVtYmVyIikgKyBsYWJzKHRpdGxlID0gIk51bWJlciBvZiBTZWxlY3RlZCBEaXN0YW5jZSBGbGlnaHQgb24gMTIvMDgvMjAxNSBOaWdodCBUaW1lIikKYGBgCiMjTElORSBDSEFSVAoKKipUaGUgZm9sbG93aW5nIHR3byBjaGFydHMgYXJlIHRvIGNvbXBhcmUgbnVtYmVyIG9mIGZsaWdodHMgYmV0d2VlbiB0d28gY2hvb3NlbiBkYXlzIG92ZXIgdGltZToqKgoKYGBge3J9CmZpbmFsZGF0YTEgPC0gZXh0cmFjdFRpbWUoZGF0YV80MDdfZGF5LCAiMjAxNS0wNC0wNyAwNjozMDowMCIsIjIwMTUtMDQtMDcgMTI6MDA6MDAiKQpmaW5hbGRhdGEyIDwtIGV4dHJhY3RUaW1lKGRhdGFfMTIwOF9kYXksICIyMDE1LTEyLTA4IDA2OjMwOjAwIiwiMjAxNS0xMi0wOCAxMjowMDowMCIpCgpnZ3Bsb3QoKSArCiAgZ2VvbV9saW5lKGRhdGE9ZmluYWxkYXRhMSwgYWVzKHggPSBzdGFydHRpbWUsIHk9ZmxpZ2h0c251bSwgZ3JvdXA9NSwgY29sb3I9ImRheXRpbWUgMDQvMDciKSkgKyAKICBnZW9tX2xpbmUoZGF0YT1maW5hbGRhdGEyLCBhZXMoeCA9IHN0YXJ0dGltZSwgeT1mbGlnaHRzbnVtLCBncm91cD01LCBjb2xvcj0iZGF5dGltZSAxMi8wOCIpKSArCiAgeGxhYigidGltZSIpICsgCiAgeWxhYigiZmxpZ2h0cyBudW1iZXIiKSArIGxhYnModGl0bGUgPSAiQ29tcGFyZSBOdW1iZXIgb2YgU2VsZWN0ZWQgRGlzdGFuY2UgRmxpZ2h0IG9mIFR3byBEYXlzIikKYGBgCgpgYGB7cn0KZmluYWxkYXRhMSA8LSBleHRyYWN0VGltZShkYXRhXzQwN19uaWdodCwgIjIwMTUtMDQtMDcgMDA6MDA6MDAiLCIyMDE1LTA0LTA3IDA2OjMwOjAwIikKZmluYWxkYXRhMiA8LSBleHRyYWN0VGltZShkYXRhXzEyMDhfbmlnaHQsICIyMDE1LTEyLTA4IDAwOjAwOjAwIiwiMjAxNS0xMi0wOCAwNjozMDowMCIpCgpnZ3Bsb3QoKSArCiAgZ2VvbV9saW5lKGRhdGE9ZmluYWxkYXRhMSwgYWVzKHggPSBzdGFydHRpbWUsIHk9ZmxpZ2h0c251bSwgZ3JvdXA9NSwgY29sb3I9Im5pZ2h0dGltZSAwNC8wNyIpKSArIAogIGdlb21fbGluZShkYXRhPWZpbmFsZGF0YTIsIGFlcyh4ID0gc3RhcnR0aW1lLCB5PWZsaWdodHNudW0sIGdyb3VwPTUsIGNvbG9yPSJuaWdodHRpbWUgMTIvMDgiKSkgKwogIHhsYWIoInRpbWUiKSArIAogIHlsYWIoImZsaWdodHMgbnVtYmVyIikgKyBsYWJzKHRpdGxlID0gIkNvbXBhcmUgTnVtYmVyIG9mIFNlbGVjdGVkIERpc3RhbmNlIEZsaWdodCBvZiBUd28gTmlnaHRzIikKYGBgCiMjUElFIENIQVJUCgoqKkNvbXBhcmUgdW5pcXVlIGZsaWdodCBudW1iZXJzIGJldHdlZW4gdHdvIGNob29zZW4gZGF5cyB1c2luZyBiYXIgY2hhcnQuIFlvdSBjYW4gc2VlIGVhY2ggZGF5J3MgZmxpZ2h0IG51bWJlciBwZXJjZW50YWdlcyBvbiB0aGUgZ3JhcGguIEl0IGNhbiBiZSBvYnZpb3VzIHRoYXQgZmxpZ2h0IG51bWJlciBvbiAyMDE1LTEyLTA4IGlzIG11Y2ggbW9yZSB0aGFuIDIwMTUtMDQtMDcuKioKCmBgYHtyfQppbnN0YWxsLnBhY2thZ2VzKCdwbG90cml4JykKbGlicmFyeShwbG90cml4KQpsaWJyYXJ5KGRwbHlyKQpmaXJzdGRheSA8LSBsZW5ndGgodW5pcXVlKGRhdGFfNDA3X2RheSRjb2RlKSkKZmlyc3RuaWdodCA8LSBsZW5ndGgodW5pcXVlKGRhdGFfNDA3X25pZ2h0JGNvZGUpKQpmaXJzdHRvdGFsID0gZmlyc3RkYXkgKyBmaXJzdG5pZ2h0CnNlY29uZGRheSA8LSBsZW5ndGgodW5pcXVlKGRhdGFfMTIwOF9kYXkkY29kZSkpCnNlY29uZG5pZ2h0IDwtIGxlbmd0aCh1bmlxdWUoZGF0YV8xMjA4X25pZ2h0JGNvZGUpKQpzZWNvbmR0b3RhbCA9IHNlY29uZGRheSArIHNlY29uZG5pZ2h0CgpkYXRhIDwtIGMoZmlyc3R0b3RhbCxzZWNvbmR0b3RhbCkKbGJscyA8LSBjKCIyMDE1LTA0LTA3IiwiMjAxNS0xMi0wOCIpCnBjdCA8LSByb3VuZChkYXRhL3N1bShkYXRhKSoxMDApCmxibHMgPC0gcGFzdGUobGJscywgcGN0KSAjIGFkZCBwZXJjZW50cyB0byBsYWJlbHMgCmxibHMgPC0gcGFzdGUobGJscywiJSIsc2VwPSIiKSAjIGFkICUgdG8gbGFiZWxzIAoKcGllKGRhdGEsbGFiZWxzID0gbGJscywgY29sPXJhaW5ib3cobGVuZ3RoKGxibHMpKSwKICAJbWFpbj0iVW5pcXVlIEZsaWdodHMgQmV0d2VlbiBUd28gRGF5cyIpCgpgYGAKCg==