1 Philadelphia Shooting Data Analysis

In order to visualize the spatial distribution of shootings in Philadelphia, PA, the City of Philadelphia Shooting Victim data as obtained from the Philadelphia Open Data project. This report includes a listing of city-wide shooting victims, including Police Officer-involved shootings, from 2015 - current day. In order to aggregate this data by neighborhood and or block, two GeoJSON files were read in for use respectively.

This data is available for public use at OpenPhillyData

str(philly_block)
Classes 'sf' and 'data.frame':  17555 obs. of  8 variables:
 $ geoid           : chr  "421010041013000" "421010041013001" "421010041013002" "421010041013003" ...
 $ cr_geoid        : int  1254 1254 1254 1254 1254 1254 1254 1254 1254 1254 ...
 $ name            : chr  "Greenwich" "Greenwich" "Greenwich" "Greenwich" ...
 $ original_id     : chr  NA NA NA NA ...
 $ pop100          : chr  "120" "139" "145" "0" ...
 $ hu100           : chr  "53" "50" "53" "0" ...
 $ state_place_fips: chr  "4260000" "4260000" "4260000" "4260000" ...
 $ geometry        :sfc_MULTIPOLYGON of length 17555; first list element: List of 1
  ..$ :List of 1
  .. ..$ : num [1:5, 1:2] -75.2 -75.2 -75.2 -75.2 -75.2 ...
  ..- attr(*, "class")= chr [1:3] "XY" "MULTIPOLYGON" "sfg"
 - attr(*, "sf_column")= chr "geometry"
 - attr(*, "agr")= Factor w/ 3 levels "constant","aggregate",..: NA NA NA NA NA NA NA
  ..- attr(*, "names")= chr [1:7] "geoid" "cr_geoid" "name" "original_id" ...
str(philly_neighbor)
Classes 'sf' and 'data.frame':  158 obs. of  9 variables:
 $ name      : chr  "PENNYPACK_PARK" "OVERBROOK" "GERMANTOWN_SOUTHWEST" "EAST_PARKSIDE" ...
 $ listname  : chr  "Pennypack Park" "Overbrook" "Germantown, Southwest" "East Parkside" ...
 $ mapname   : chr  "Pennypack Park" "Overbrook" "Southwest Germantown" "East Parkside" ...
 $ shape_leng: num  87084 57005 14881 10886 13042 ...
 $ shape_area: num  60140756 76924995 14418666 4231000 6949968 ...
 $ cartodb_id: int  9 138 59 129 49 6 17 47 50 44 ...
 $ created_at: POSIXct, format: "2013-03-19 13:41:50" "2013-03-19 13:41:50" ...
 $ updated_at: POSIXct, format: "2013-03-19 13:41:50" "2013-03-19 13:41:50" ...
 $ geometry  :sfc_MULTIPOLYGON of length 158; first list element: List of 1
  ..$ :List of 1
  .. ..$ : num [1:1607, 1:2] -75.1 -75.1 -75.1 -75.1 -75.1 ...
  ..- attr(*, "class")= chr [1:3] "XY" "MULTIPOLYGON" "sfg"
 - attr(*, "sf_column")= chr "geometry"
 - attr(*, "agr")= Factor w/ 3 levels "constant","aggregate",..: NA NA NA NA NA NA NA NA
  ..- attr(*, "names")= chr [1:8] "name" "listname" "mapname" "shape_leng" ...
str(philly_shooting_raw)
Classes 'sf' and 'data.frame':  15277 obs. of  22 variables:
 $ objectid         : int  12728033 12728034 12728035 12728036 12728037 12728038 12728039 12728040 12728041 12728042 ...
 $ year             : int  2016 2016 2018 2020 2018 2019 2019 2019 2022 2016 ...
 $ dc_key           : chr  "201615054780.0" "201615117555.0" "201815093657.0" "202015094989.0" ...
 $ code             : chr  "400" "300" "400" "400" ...
 $ date_            : POSIXct, format: "2016-06-06 20:00:00" "2016-12-03 19:00:00" ...
 $ time             : chr  "12:15:00" "05:43:00" "21:02:00" "17:12:00" ...
 $ race             : chr  "B" "B" "B" "B" ...
 $ sex              : chr  "M" "M" "M" "M" ...
 $ age              : chr  "19" "38" "31" "23" ...
 $ wound            : chr  "Hand" "Chest" "Multiple" "Hand" ...
 $ officer_involved : chr  "N" "N" "N" "N" ...
 $ offender_injured : chr  "N" "N" "N" "N" ...
 $ offender_deceased: chr  "N" "N" "N" "N" ...
 $ location         : chr  "4600 BLOCK Frankford Ave" "4600 BLOCK Frankford Ave" "4600 BLOCK Frankford Ave" "4600 BLOCK FRANKFORD AVE" ...
 $ latino           : int  0 0 0 0 0 1 1 0 0 0 ...
 $ point_x          : num  -75.1 -75.1 -75.1 -75.1 -75.1 ...
 $ point_y          : num  40 40 40 40 40 ...
 $ dist             : chr  "15" "15" "15" "15" ...
 $ inside           : int  0 0 0 0 0 0 0 0 0 0 ...
 $ outside          : int  1 1 1 1 1 1 1 1 1 1 ...
 $ fatal            : int  0 0 1 0 0 0 0 0 1 0 ...
 $ geometry         :sfc_POINT of length 15277; first list element:  'XY' num  -75.1 40
 - attr(*, "sf_column")= chr "geometry"
 - attr(*, "agr")= Factor w/ 3 levels "constant","aggregate",..: NA NA NA NA NA NA NA NA NA NA ...
  ..- attr(*, "names")= chr [1:21] "objectid" "year" "dc_key" "code" ...
 - attr(*, "na.action")= 'omit' Named int [1:278] 197 287 622 716 770 783 789 883 961 992 ...
  ..- attr(*, "names")= chr [1:278] "197" "287" "622" "716" ...
## Define a color palette
pal <- colorFactor(c("red", "gold"), domain = c(TRUE, FALSE))

The data was read in, and classifications updated to either logical or numeric as needed for improved analysis. Uneccessary columns (objectID, DC_Key, and Geometry) removed.

str(philly_shooting)
Classes 'sf' and 'data.frame':  15277 obs. of  20 variables:
 $ year             : int  2016 2016 2018 2020 2018 2019 2019 2019 2022 2016 ...
 $ code             : num  400 300 400 400 400 400 400 400 100 400 ...
 $ date_            : POSIXct, format: "2016-06-06 20:00:00" "2016-12-03 19:00:00" ...
 $ time             : chr  "12:15:00" "05:43:00" "21:02:00" "17:12:00" ...
 $ race             : chr  "B" "B" "B" "B" ...
 $ sex              : chr  "M" "M" "M" "M" ...
 $ age              : chr  "19" "38" "31" "23" ...
 $ wound            : chr  "Hand" "Chest" "Multiple" "Hand" ...
 $ officer_involved : chr  "N" "N" "N" "N" ...
 $ offender_injured : chr  "N" "N" "N" "N" ...
 $ offender_deceased: chr  "N" "N" "N" "N" ...
 $ location         : chr  "4600 BLOCK Frankford Ave" "4600 BLOCK Frankford Ave" "4600 BLOCK Frankford Ave" "4600 BLOCK FRANKFORD AVE" ...
 $ latino           : logi  FALSE FALSE FALSE FALSE FALSE TRUE ...
 $ point_x          : num  -75.1 -75.1 -75.1 -75.1 -75.1 ...
 $ point_y          : num  40 40 40 40 40 ...
 $ dist             : chr  "15" "15" "15" "15" ...
 $ inside           : logi  FALSE FALSE FALSE FALSE FALSE FALSE ...
 $ outside          : logi  TRUE TRUE TRUE TRUE TRUE TRUE ...
 $ fatal            : logi  FALSE FALSE TRUE FALSE FALSE FALSE ...
 $ geometry         :sfc_POINT of length 15277; first list element:  'XY' num  -75.1 40
 - attr(*, "sf_column")= chr "geometry"
 - attr(*, "agr")= Factor w/ 3 levels "constant","aggregate",..: NA NA NA NA NA NA NA NA NA NA ...
  ..- attr(*, "names")= chr [1:19] "year" "code" "date_" "time" ...
leaflet() %>%
  setView(lng=-75.15092, lat=40.00995, zoom = 11) %>% 
  addProviderTiles(providers$CartoDB.DarkMatter, group = "Dark w/ Labels") %>% 
  addProviderTiles(providers$CartoDB.DarkMatterNoLabels, group = "Dark w/o Labels") %>% 
  addProviderTiles(providers$Esri.WorldGrayCanvas, group = "Gray") %>% 
   addLayersControl(baseGroups = c("Dark w/ Labels", "Dark w/o Labels", "Gray"),
    options = layersControlOptions(collapsed = TRUE)) %>% 
  addControl(html = "<h5> Philadelphia Shooting Data<br>2015 - Current</h5>", position = "topleft", className = "map-title") %>% 
  addPolygons(data = philly_neighbor,
              color = 'magenta',
              fill= FALSE,
              weight = 1) %>% 
  addMiniMap() %>% 
  addCircleMarkers(data = philly_shooting,
                   radius = ~ifelse(fatal == TRUE, 5, 3),
                   color = ~pal(fatal),
                   fillOpacity = 0.5,
                   popup = ~popupTable(philly_shooting),
                   clusterOptions = markerClusterOptions(maxClusterRadius = 50)) %>% 
   addCircleMarkers(data = Crime_totals, 
                   color = "white",
                   weight = 2,
                   label = "Crime Totals by Classificaiton Code",
                   stroke = FALSE, 
                   fillOpacity = 0.95,
                   group = "code") %>% 
  addPopupImages(code_graph_img, 
                  width = 500,
                  height = 400,
                  tooltip = FALSE,
                  group = "code") 


LS0tDQp0aXRsZTogIkJhbmc6IFRoZSBHZW9TcGF0aWFsIEltcGFjdCBvZiBQaGlsYWRlbHBoaWEgR3VuIFZpb2xlbmNlIg0KYXV0aG9yOiAiTmF0YWxpZSBMZVBlcmEiDQpkYXRlOiAiV2VzdCBDaGVzdGVyIFVuaXZlcnNpdHkgPGJyPlNUQSA1MDM6IERhdGEgVmlzdWFsaXphdGlvbiINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICB0b2NfZmxvYXQ6IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgdG9jX2NvbGxhcHNlZDogeWVzDQogICAgY29kZV9mb2xkaW5nOiBoaWRlDQogICAgY29kZV9kb3dubG9hZDogeWVzDQogICAgc21vb3RoX3Njcm9sbDogdHJ1ZQ0KICAgIHRoZW1lOiByZWFkYWJsZQ0KLS0tDQoNCmBgYHs9aHRtbH0NCjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+DQoNCmRpdiNUT0MgbGkgew0KICAgIGxpc3Qtc3R5bGU6bm9uZTsNCiAgICBiYWNrZ3JvdW5kLWNvbG9yOmxpZ2h0Z3JheTsNCiAgICBiYWNrZ3JvdW5kLWltYWdlOm5vbmU7DQogICAgYmFja2dyb3VuZC1yZXBlYXQ6bm9uZTsNCiAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOjA7DQogICAgZm9udC1mYW1pbHk6IEFyaWFsLCBIZWx2ZXRpY2EsIHNhbnMtc2VyaWY7DQogICAgY29sb3I6ICM3ODBjMGM7DQp9DQoNCi8qIG1vdXNlIG92ZXIgbGluayAqLw0KZGl2I1RPQyBhOmhvdmVyIHsNCiAgY29sb3I6IHJlZDsNCn0NCg0KLyogdW52aXNpdGVkIGxpbmsgKi8NCmRpdiNUT0MgYTpsaW5rIHsNCiAgY29sb3I6IGJsdWU7DQp9DQoNCg0KDQpoMS50aXRsZSB7DQogIGZvbnQtc2l6ZTogMjRweDsNCiAgY29sb3I6IERhcmtibHVlOw0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQogIGZvbnQtZmFtaWx5OiBBcmlhbCwgSGVsdmV0aWNhLCBzYW5zLXNlcmlmOw0KICBmb250LXZhcmlhbnQtY2Fwczogbm9ybWFsOw0KfQ0KaDQuc3VidGl0bGUgew0KICBmb250LXNpemU6IDE4cHg7DQogIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICBjb2xvcjogRGFya1JlZDsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KaDQuYXV0aG9yIHsgDQogICAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgY29sb3I6IERhcmtSZWQ7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCmg0LmRhdGUgeyANCiAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgY29sb3I6IERhcmtCbHVlOw0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQpoMSB7DQogICAgZm9udC1zaXplOiAyNHB4Ow0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBkYXJrcmVkOw0KICAgIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCmgyIHsNCiAgICBmb250LXNpemU6IDE4cHg7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IG5hdnk7DQogICAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KDQpoMyB7IA0KICAgIGZvbnQtc2l6ZTogMTVweDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoNCB7IC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxOHB4Ow0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBkYXJrcmVkOw0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQpoNSB7IA0KICAgIGZvbnQtc2l6ZTogMTVweDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogd2hpdGU7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCi8qIHVudmlzaXRlZCBsaW5rICovDQphOmxpbmsgew0KICBjb2xvcjogZ3JlZW47DQp9DQoNCi8qIHZpc2l0ZWQgbGluayAqLw0KYTp2aXNpdGVkIHsNCiAgY29sb3I6IGdyZWVuOw0KfQ0KDQovKiBtb3VzZSBvdmVyIGxpbmsgKi8NCmE6aG92ZXIgew0KICBjb2xvcjogcmVkOw0KfQ0KDQovKiBzZWxlY3RlZCBsaW5rICovDQphOmFjdGl2ZSB7DQogIGNvbG9yOiB5ZWxsb3c7DQp9DQoNCjwvc3R5bGU+DQpgYGANCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQojIGNvZGUgY2h1bmsgc3BlY2lmaWVzIHdoZXRoZXIgdGhlIFIgY29kZSwgd2FybmluZ3MsIGFuZCBvdXRwdXQgDQojIHdpbGwgYmUgaW5jbHVkZWQgaW4gdGhlIG91dHB1dCBmaWxlcy4NCm9wdGlvbnMocmVwb3MgPSBsaXN0KENSQU49Imh0dHA6Ly9jcmFuLnJzdHVkaW8uY29tLyIpKQ0KaWYgKCFyZXF1aXJlKCJ0aWR5dmVyc2UiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygidGlkeXZlcnNlIikNCiAgIGxpYnJhcnkodGlkeXZlcnNlKQ0KfQ0KaWYgKCFyZXF1aXJlKCJrbml0ciIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJrbml0ciIpDQogICBsaWJyYXJ5KGtuaXRyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJzZiIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJzZiIpDQogICBsaWJyYXJ5KHNmKQ0KfQ0KaWYgKCFyZXF1aXJlKCJjb3dwbG90IikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImNvd3Bsb3QiKQ0KICAgbGlicmFyeShjb3dwbG90KQ0KfQ0KaWYgKCFyZXF1aXJlKCJsYXRleDJleHAiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygibGF0ZXgyZXhwIikNCiAgIGxpYnJhcnkobGF0ZXgyZXhwKQ0KfQ0KaWYgKCFyZXF1aXJlKCJwbG90bHkiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygicGxvdGx5IikNCiAgIGxpYnJhcnkocGxvdGx5KQ0KfQ0KaWYgKCFyZXF1aXJlKCJnYXBtaW5kZXIiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygiZ2FwbWluZGVyIikNCiAgIGxpYnJhcnkoZ2FwbWluZGVyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJwbmciKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoInBuZyIpICAgICAgICAgICAgICMgSW5zdGFsbCBwbmcgcGFja2FnZQ0KICAgIGxpYnJhcnkoInBuZyIpDQp9DQppZiAoIXJlcXVpcmUoIlJDdXJsIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJSQ3VybCIpICAgICAgICAgICAjIEluc3RhbGwgUkN1cmwgcGFja2FnZQ0KICAgIGxpYnJhcnkoIlJDdXJsIikNCn0NCmlmICghcmVxdWlyZSgiY29sb3VycGlja2VyIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJjb2xvdXJwaWNrZXIiKSAgICAgICAgICAgICAgDQogICAgbGlicmFyeSgiY29sb3VycGlja2VyIikNCn0NCmlmICghcmVxdWlyZSgiZ2lmc2tpIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJnaWZza2kiKSAgICAgICAgICAgICAgDQogICAgbGlicmFyeSgiZ2lmc2tpIikNCn0NCmlmICghcmVxdWlyZSgibWFnaWNrIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJtYWdpY2siKSAgICAgICAgICAgICAgDQogICAgbGlicmFyeSgibWFnaWNrIikNCn0NCmlmICghcmVxdWlyZSgiZ3JEZXZpY2VzIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJnckRldmljZXMiKSAgICAgICAgICAgICAgDQogICAgbGlicmFyeSgiZ3JEZXZpY2VzIikNCn0NCiMjIyBnZ3Bsb3QgYW5kIGV4dGVuc2lvbnMNCmlmICghcmVxdWlyZSgiZ2dwbG90MiIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygiZ2dwbG90MiIpICAgICAgICAgICAgICANCiAgICBsaWJyYXJ5KCJnZ3Bsb3QyIikNCn0NCmlmICghcmVxdWlyZSgiZ2dhbmltYXRlIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJnZ2FuaW1hdGUiKSAgICAgICAgICAgICAgDQogICAgbGlicmFyeSgiZ2dhbmltYXRlIikNCn0NCmlmICghcmVxdWlyZSgiZ2dyaWRnZXMiKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoImdncmlkZ2VzIikgICAgICAgICAgICAgIA0KICAgIGxpYnJhcnkoImdncmlkZ2VzIikNCn0NCmlmICghcmVxdWlyZSgiZ3JhcGhpY3MiKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoImdyYXBoaWNzIikgICAgICAgICAgICAgIA0KICAgIGxpYnJhcnkoImdyYXBoaWNzIikNCn0NCmlmICghcmVxdWlyZSgib3Blbnhsc3giKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoIm9wZW54bHN4IikgICAgICAgICAgICAgIA0KICAgIGxpYnJhcnkoIm9wZW54bHN4IikNCn0NCg0KaWYgKCFyZXF1aXJlKCJsdWJyaWRhdGUiKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoImx1YnJpZGF0ZSIpICAgICAgICAgICAgICANCiAgICBsaWJyYXJ5KCJsdWJyaWRhdGUiKQ0KfQ0KaWYgKCFyZXF1aXJlKCJyanNvbiIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygicmpzb24iKSAgICAgICAgICAgICAgDQogICAgbGlicmFyeSgicmpzb24iKQ0KfQ0KaWYgKCFyZXF1aXJlKCJsZWFmbGV0IikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJsZWFmbGV0IikgICAgICAgICAgICAgIA0KICAgIGxpYnJhcnkoImxlYWZsZXQiKQ0KfQ0KaWYgKCFyZXF1aXJlKCJsZWFmcG9wIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJsZWFmcG9wIikgICAgICAgICAgICAgIA0KICAgIGxpYnJhcnkoImxlYWZwb3AiKQ0KfQ0KaWYgKCFyZXF1aXJlKCJodG1sd2lkZ2V0cyIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygiaHRtbHdpZGdldHMiKSAgICAgICAgICAgICAgDQogICAgbGlicmFyeSgiaHRtbHdpZGdldHMiKQ0KfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICB3YXJuaW5nID0gRkFMU0UsICAgDQogICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gVFJVRSwgICANCiAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gRkFMU0UsDQogICAgICAgICAgICAgICAgICAgICAgY29tbWVudCA9IE5BKQ0KYGBgDQpcDQoNCg0KIyBQaGlsYWRlbHBoaWEgU2hvb3RpbmcgRGF0YSBBbmFseXNpcw0KDQpJbiBvcmRlciB0byB2aXN1YWxpemUgdGhlIHNwYXRpYWwgZGlzdHJpYnV0aW9uIG9mIHNob290aW5ncyBpbiBQaGlsYWRlbHBoaWEsIFBBLCB0aGUgQ2l0eSBvZiBQaGlsYWRlbHBoaWEgU2hvb3RpbmcgVmljdGltIGRhdGEgYXMgb2J0YWluZWQgZnJvbSB0aGUgUGhpbGFkZWxwaGlhIE9wZW4gRGF0YSBwcm9qZWN0LiAgVGhpcyByZXBvcnQgaW5jbHVkZXMgYSBsaXN0aW5nIG9mIGNpdHktd2lkZSBzaG9vdGluZyB2aWN0aW1zLCBpbmNsdWRpbmcgUG9saWNlIE9mZmljZXItaW52b2x2ZWQgc2hvb3RpbmdzLCBmcm9tIDIwMTUgLSBjdXJyZW50IGRheS4gIEluIG9yZGVyIHRvIGFnZ3JlZ2F0ZSB0aGlzIGRhdGEgYnkgbmVpZ2hib3Job29kIGFuZCBvciBibG9jaywgdHdvIEdlb0pTT04gZmlsZXMgd2VyZSByZWFkIGluIGZvciB1c2UgcmVzcGVjdGl2ZWx5LiANCg0KVGhpcyBkYXRhIGlzIGF2YWlsYWJsZSBmb3IgcHVibGljIHVzZSBhdCA8YSBocmVmPSJodHRwczovL29wZW5kYXRhcGhpbGx5Lm9yZy9kYXRhc2V0cy8iPk9wZW5QaGlsbHlEYXRhPC9hPg0KYGBge3IgaW5jbHVkZSA9IEZBTFNFfQ0KcGhpbGx5X3Nob290aW5nX3JhdyAgPC0gbmEub21pdChzdF9yZWFkKCJodHRwczovL3Blbmdkc2NpLmdpdGh1Yi5pby9TVEE1NTNWSVovdzA4L1BoaWxseVNob290aW5ncy5nZW9qc29uIikpDQpwaGlsbHlfbmVpZ2hib3IgIDwtIHN0X3JlYWQoImh0dHBzOi8vcGVuZ2RzY2kuZ2l0aHViLmlvL1NUQTU1M1ZJWi93MDgvTmVpZ2hib3Job29kc19QaGlsYWRlbHBoaWEuZ2VvanNvbiIpDQpwaGlsbHlfYmxvY2sgIDwtIHN0X3JlYWQoImh0dHBzOi8vcGVuZ2RzY2kuZ2l0aHViLmlvL1NUQTU1M1ZJWi93MDgvUGhpbGx5TmVpZ2hib3Job29kLWJsb2Nrcy5nZW9qc29uIikNCmBgYA0KYGBge3IgZWNobyA9IFRSVUV9DQpzdHIocGhpbGx5X2Jsb2NrKQ0Kc3RyKHBoaWxseV9uZWlnaGJvcikNCnN0cihwaGlsbHlfc2hvb3RpbmdfcmF3KQ0KYGBgDQoNCmBgYHtyfQ0KDQoNCiMjIERlZmluZSBhIGNvbG9yIHBhbGV0dGUNCnBhbCA8LSBjb2xvckZhY3RvcihjKCJyZWQiLCAiZ29sZCIpLCBkb21haW4gPSBjKFRSVUUsIEZBTFNFKSkNCg0KDQpgYGANCg0KYGBge3IgaW5jbHVkZSA9IEZBTFNFfQ0KcGhpbGx5X3Nob290aW5nX3JhdyRmYXRhbCA8LSBhcy5sb2dpY2FsKHBoaWxseV9zaG9vdGluZ19yYXckZmF0YWwpDQpwaGlsbHlfc2hvb3RpbmdfcmF3JGxhdGlubyA8LSBhcy5sb2dpY2FsKHBoaWxseV9zaG9vdGluZ19yYXckbGF0aW5vKQ0KcGhpbGx5X3Nob290aW5nX3JhdyRpbnNpZGUgPC0gYXMubG9naWNhbChwaGlsbHlfc2hvb3RpbmdfcmF3JGluc2lkZSkNCnBoaWxseV9zaG9vdGluZ19yYXckb3V0c2lkZSA8LSBhcy5sb2dpY2FsKHBoaWxseV9zaG9vdGluZ19yYXckb3V0c2lkZSkNCnBoaWxseV9zaG9vdGluZ19yYXckY29kZSA8LSBhcy5udW1lcmljKHBoaWxseV9zaG9vdGluZ19yYXckY29kZSkNCmBgYA0KDQpgYGB7ciBpbmNsdWRlID0gRkFMU0V9DQpwaGlsbHlfc2hvb3RpbmcgPC0gc3Vic2V0KHBoaWxseV9zaG9vdGluZ19yYXcsIHNlbGVjdCA9IC1jKG9iamVjdGlkLCBkY19rZXksIGdlb21ldHJ5KSkNCnBoaWxseV9zaG9vdGluZyAlPiUgDQogIHJlbmFtZSgNCiAgICBTaG9vdGluZ19JbnNpZGUgPSBpbnNpZGUsDQogICAgU2hvb3RpbmdfT3V0c2lkZSA9IG91dHNpZGUsDQogICAgUG9saWNlX2Rpc3RyaWN0ID0gZGlzdCwNCiAgICBGQklfQ3JpbWVfQ29kZSA9IGNvZGUNCiAgKQ0KYGBgDQoNCg0KVGhlIGRhdGEgd2FzIHJlYWQgaW4sIGFuZCBjbGFzc2lmaWNhdGlvbnMgdXBkYXRlZCB0byBlaXRoZXIgbG9naWNhbCBvciBudW1lcmljIGFzIG5lZWRlZCBmb3IgaW1wcm92ZWQgYW5hbHlzaXMuICBVbmVjY2Vzc2FyeSBjb2x1bW5zIChvYmplY3RJRCwgRENfS2V5LCBhbmQgR2VvbWV0cnkpIHJlbW92ZWQuDQoNCg0KYGBge3IgZWNobyA9IFRSVUV9DQpzdHIocGhpbGx5X3Nob290aW5nKQ0KYGBgDQoNCmBgYHtyIGluY2x1ZGUgPSBGQUxTRX0NCnBoaWxseV9zaG9vdGluZyRjb2RlX2tleSA8LSBjdXQocGhpbGx5X3Nob290aW5nJGNvZGUsIGJyZWFrcyA9IGMoMCwgMTAwLCAyMDAsIDMwMCwgNDAwLCA1MDAsIDYwMCwgNzAwLCA4MDAsIDkwMCksICBsYWJlbHMgPSBjKCIwLTA5OTogQWRkaXRpb25hbCBWaWN0aW0iLCAiMTAwLTE5OTogSG9taWNpZGUiLCAiMjAwLTI5OTogUmFwZSIsICIzMDAtMzk5OiBSb2JiZXJ5IiwgIjQwMC00OTk6IEFnZ3JpdmF0ZWQgQXNzYXVsdCIsICI1MDAtNTk5OiBCdXJnYXJseSIsICI2MDAtNjk5OiBMYXJjZW55IiwgIjcwMC03OTk6IE1vdG9yIFZlaGljbGUgVGhlZnQiLCAiODAwLTg5OTogQXJzb24iKSwgaW5jbHVkZS5sb3dlc3QgPSBUUlVFKQ0KDQpjb2RlX2dyYXBoIDwtIGdncGxvdCgNCiAgZGF0YSA9IHBoaWxseV9zaG9vdGluZywNCiAgYWVzKHggPSBwaGlsbHlfc2hvb3RpbmckY29kZV9rZXksIGNvbG9yID0gcGhpbGx5X3Nob290aW5nJHNleCwgZmlsbCA9IHBoaWxseV9zaG9vdGluZyRzZXgpKSsNCiAgZ2VvbV9iYXIocG9zaXRpb24gPSAiZG9kZ2UiKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpKw0KICBsYWJzKHRpdGxlID0gIlBoaWxhZGVscGhpYSBTaG9vdGluZyBSZWxhdGVkIENyaW1lIFRvdGFscyBieSBGQkkgVUNSIENvZGUgTGlzdGluZyIsIHN1YnRpdGxlID0gIjIwMTUgLSBDdXJyZW50IGRhdGEgT2J0YWluZWQgRnJvbSBPcGVuRGF0YVBoaWxseSIsIGZpbGwgPSAiU2V4IG9mIFZpY3RpbXMiKSArDQogIHhsYWIoIlNob290aW5nIEZCSSBDcmltZSBDb2RlIikrDQogIHlsYWIoIlRvdGFsIFNob290aW5nIFJlbGF0ZWQgQ3JpbWVzICgyMDE1IC0gQ3VycmVudCkiKSsNCiAgZ3VpZGVzKGNvbG9yID0gIm5vbmUiKQ0KDQoNCkNyaW1lX3RvdGFscyA9IHN0X2FzX3NmKGRhdGEuZnJhbWUoeCA9IC03NS40LCB5ID0gNDAuMDA5OTUpLA0KICAgICAgICAgICAgICAgIGNvb3JkcyA9IGMoIngiLCAieSIpLA0KICAgICAgICAgICAgICAgIGNycyA9IDExMikNCmNvZGVfZ3JhcGhfaW1nID0gImh0dHBzOi8vbmxlcGVyYS5naXRodWIuaW8vc3RhNTUzL3cwOF9pbnRlcmFjdGl2ZV9tYXBzL3BvcHVwX2NvZGUuanBnIg0KDQpgYGANCg0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD0xMCwgd2FybmluZz1GQUxTRSwgbWVzc2FnZSA9IEZBTFNFfQ0KbGVhZmxldCgpICU+JQ0KICBzZXRWaWV3KGxuZz0tNzUuMTUwOTIsIGxhdD00MC4wMDk5NSwgem9vbSA9IDExKSAlPiUgDQogIGFkZFByb3ZpZGVyVGlsZXMocHJvdmlkZXJzJENhcnRvREIuRGFya01hdHRlciwgZ3JvdXAgPSAiRGFyayB3LyBMYWJlbHMiKSAlPiUgDQogIGFkZFByb3ZpZGVyVGlsZXMocHJvdmlkZXJzJENhcnRvREIuRGFya01hdHRlck5vTGFiZWxzLCBncm91cCA9ICJEYXJrIHcvbyBMYWJlbHMiKSAlPiUgDQogIGFkZFByb3ZpZGVyVGlsZXMocHJvdmlkZXJzJEVzcmkuV29ybGRHcmF5Q2FudmFzLCBncm91cCA9ICJHcmF5IikgJT4lIA0KICAgYWRkTGF5ZXJzQ29udHJvbChiYXNlR3JvdXBzID0gYygiRGFyayB3LyBMYWJlbHMiLCAiRGFyayB3L28gTGFiZWxzIiwgIkdyYXkiKSwNCiAgICBvcHRpb25zID0gbGF5ZXJzQ29udHJvbE9wdGlvbnMoY29sbGFwc2VkID0gVFJVRSkpICU+JSANCiAgYWRkQ29udHJvbChodG1sID0gIjxoNT4gUGhpbGFkZWxwaGlhIFNob290aW5nIERhdGE8YnI+MjAxNSAtIEN1cnJlbnQ8L2g1PiIsIHBvc2l0aW9uID0gInRvcGxlZnQiLCBjbGFzc05hbWUgPSAibWFwLXRpdGxlIikgJT4lIA0KICBhZGRQb2x5Z29ucyhkYXRhID0gcGhpbGx5X25laWdoYm9yLA0KICAgICAgICAgICAgICBjb2xvciA9ICdtYWdlbnRhJywNCiAgICAgICAgICAgICAgZmlsbD0gRkFMU0UsDQogICAgICAgICAgICAgIHdlaWdodCA9IDEpICU+JSANCiAgYWRkTWluaU1hcCgpICU+JSANCiAgYWRkQ2lyY2xlTWFya2VycyhkYXRhID0gcGhpbGx5X3Nob290aW5nLA0KICAgICAgICAgICAgICAgICAgIHJhZGl1cyA9IH5pZmVsc2UoZmF0YWwgPT0gVFJVRSwgNSwgMyksDQogICAgICAgICAgICAgICAgICAgY29sb3IgPSB+cGFsKGZhdGFsKSwNCiAgICAgICAgICAgICAgICAgICBmaWxsT3BhY2l0eSA9IDAuNSwNCiAgICAgICAgICAgICAgICAgICBwb3B1cCA9IH5wb3B1cFRhYmxlKHBoaWxseV9zaG9vdGluZyksDQogICAgICAgICAgICAgICAgICAgY2x1c3Rlck9wdGlvbnMgPSBtYXJrZXJDbHVzdGVyT3B0aW9ucyhtYXhDbHVzdGVyUmFkaXVzID0gNTApKSAlPiUgDQogICBhZGRDaXJjbGVNYXJrZXJzKGRhdGEgPSBDcmltZV90b3RhbHMsIA0KICAgICAgICAgICAgICAgICAgIGNvbG9yID0gIndoaXRlIiwNCiAgICAgICAgICAgICAgICAgICB3ZWlnaHQgPSAyLA0KICAgICAgICAgICAgICAgICAgIGxhYmVsID0gIkNyaW1lIFRvdGFscyBieSBDbGFzc2lmaWNhaXRvbiBDb2RlIiwNCiAgICAgICAgICAgICAgICAgICBzdHJva2UgPSBGQUxTRSwgDQogICAgICAgICAgICAgICAgICAgZmlsbE9wYWNpdHkgPSAwLjk1LA0KICAgICAgICAgICAgICAgICAgIGdyb3VwID0gImNvZGUiKSAlPiUgDQogIGFkZFBvcHVwSW1hZ2VzKGNvZGVfZ3JhcGhfaW1nLCANCiAgICAgICAgICAgICAgICAgIHdpZHRoID0gNTAwLA0KICAgICAgICAgICAgICAgICAgaGVpZ2h0ID0gNDAwLA0KICAgICAgICAgICAgICAgICAgdG9vbHRpcCA9IEZBTFNFLA0KICAgICAgICAgICAgICAgICAgZ3JvdXAgPSAiY29kZSIpIA0KICANCiANCg0KYGBgDQoNClw=