Caroline Patenaude
Bibliothécaire - Bibliothèque des lettres et sciences humaines

Script Colab | Script R



Deux principales familles de fonctions graphiques

  1. Fonctions natives
  2. Fonctions GGplot2


1. Quatre graphiques de base: plot(), hist(), boxplot(), barplot()


1.1. La fonction générique plot() - le graphique produit dépend du type d’objet fourni


1.1.1. Variable qualitative = Graphique à barres


1.1.3. Table d’effectifs (ou proportions) = Graphique à barres


Fonctions de base s’accompagnent de nombreux arguments dont plusieurs peuvent être utilisés pour tous les graphiques


1.1.4. Variables quanti/quanti = Nuage de points

##   [1] "white"                "aliceblue"            "antiquewhite"        
##   [4] "antiquewhite1"        "antiquewhite2"        "antiquewhite3"       
##   [7] "antiquewhite4"        "aquamarine"           "aquamarine1"         
##  [10] "aquamarine2"          "aquamarine3"          "aquamarine4"         
##  [13] "azure"                "azure1"               "azure2"              
##  [16] "azure3"               "azure4"               "beige"               
##  [19] "bisque"               "bisque1"              "bisque2"             
##  [22] "bisque3"              "bisque4"              "black"               
##  [25] "blanchedalmond"       "blue"                 "blue1"               
##  [28] "blue2"                "blue3"                "blue4"               
##  [31] "blueviolet"           "brown"                "brown1"              
##  [34] "brown2"               "brown3"               "brown4"              
##  [37] "burlywood"            "burlywood1"           "burlywood2"          
##  [40] "burlywood3"           "burlywood4"           "cadetblue"           
##  [43] "cadetblue1"           "cadetblue2"           "cadetblue3"          
##  [46] "cadetblue4"           "chartreuse"           "chartreuse1"         
##  [49] "chartreuse2"          "chartreuse3"          "chartreuse4"         
##  [52] "chocolate"            "chocolate1"           "chocolate2"          
##  [55] "chocolate3"           "chocolate4"           "coral"               
##  [58] "coral1"               "coral2"               "coral3"              
##  [61] "coral4"               "cornflowerblue"       "cornsilk"            
##  [64] "cornsilk1"            "cornsilk2"            "cornsilk3"           
##  [67] "cornsilk4"            "cyan"                 "cyan1"               
##  [70] "cyan2"                "cyan3"                "cyan4"               
##  [73] "darkblue"             "darkcyan"             "darkgoldenrod"       
##  [76] "darkgoldenrod1"       "darkgoldenrod2"       "darkgoldenrod3"      
##  [79] "darkgoldenrod4"       "darkgray"             "darkgreen"           
##  [82] "darkgrey"             "darkkhaki"            "darkmagenta"         
##  [85] "darkolivegreen"       "darkolivegreen1"      "darkolivegreen2"     
##  [88] "darkolivegreen3"      "darkolivegreen4"      "darkorange"          
##  [91] "darkorange1"          "darkorange2"          "darkorange3"         
##  [94] "darkorange4"          "darkorchid"           "darkorchid1"         
##  [97] "darkorchid2"          "darkorchid3"          "darkorchid4"         
## [100] "darkred"              "darksalmon"           "darkseagreen"        
## [103] "darkseagreen1"        "darkseagreen2"        "darkseagreen3"       
## [106] "darkseagreen4"        "darkslateblue"        "darkslategray"       
## [109] "darkslategray1"       "darkslategray2"       "darkslategray3"      
## [112] "darkslategray4"       "darkslategrey"        "darkturquoise"       
## [115] "darkviolet"           "deeppink"             "deeppink1"           
## [118] "deeppink2"            "deeppink3"            "deeppink4"           
## [121] "deepskyblue"          "deepskyblue1"         "deepskyblue2"        
## [124] "deepskyblue3"         "deepskyblue4"         "dimgray"             
## [127] "dimgrey"              "dodgerblue"           "dodgerblue1"         
## [130] "dodgerblue2"          "dodgerblue3"          "dodgerblue4"         
## [133] "firebrick"            "firebrick1"           "firebrick2"          
## [136] "firebrick3"           "firebrick4"           "floralwhite"         
## [139] "forestgreen"          "gainsboro"            "ghostwhite"          
## [142] "gold"                 "gold1"                "gold2"               
## [145] "gold3"                "gold4"                "goldenrod"           
## [148] "goldenrod1"           "goldenrod2"           "goldenrod3"          
## [151] "goldenrod4"           "gray"                 "gray0"               
## [154] "gray1"                "gray2"                "gray3"               
## [157] "gray4"                "gray5"                "gray6"               
## [160] "gray7"                "gray8"                "gray9"               
## [163] "gray10"               "gray11"               "gray12"              
## [166] "gray13"               "gray14"               "gray15"              
## [169] "gray16"               "gray17"               "gray18"              
## [172] "gray19"               "gray20"               "gray21"              
## [175] "gray22"               "gray23"               "gray24"              
## [178] "gray25"               "gray26"               "gray27"              
## [181] "gray28"               "gray29"               "gray30"              
## [184] "gray31"               "gray32"               "gray33"              
## [187] "gray34"               "gray35"               "gray36"              
## [190] "gray37"               "gray38"               "gray39"              
## [193] "gray40"               "gray41"               "gray42"              
## [196] "gray43"               "gray44"               "gray45"              
## [199] "gray46"               "gray47"               "gray48"              
## [202] "gray49"               "gray50"               "gray51"              
## [205] "gray52"               "gray53"               "gray54"              
## [208] "gray55"               "gray56"               "gray57"              
## [211] "gray58"               "gray59"               "gray60"              
## [214] "gray61"               "gray62"               "gray63"              
## [217] "gray64"               "gray65"               "gray66"              
## [220] "gray67"               "gray68"               "gray69"              
## [223] "gray70"               "gray71"               "gray72"              
## [226] "gray73"               "gray74"               "gray75"              
## [229] "gray76"               "gray77"               "gray78"              
## [232] "gray79"               "gray80"               "gray81"              
## [235] "gray82"               "gray83"               "gray84"              
## [238] "gray85"               "gray86"               "gray87"              
## [241] "gray88"               "gray89"               "gray90"              
## [244] "gray91"               "gray92"               "gray93"              
## [247] "gray94"               "gray95"               "gray96"              
## [250] "gray97"               "gray98"               "gray99"              
## [253] "gray100"              "green"                "green1"              
## [256] "green2"               "green3"               "green4"              
## [259] "greenyellow"          "grey"                 "grey0"               
## [262] "grey1"                "grey2"                "grey3"               
## [265] "grey4"                "grey5"                "grey6"               
## [268] "grey7"                "grey8"                "grey9"               
## [271] "grey10"               "grey11"               "grey12"              
## [274] "grey13"               "grey14"               "grey15"              
## [277] "grey16"               "grey17"               "grey18"              
## [280] "grey19"               "grey20"               "grey21"              
## [283] "grey22"               "grey23"               "grey24"              
## [286] "grey25"               "grey26"               "grey27"              
## [289] "grey28"               "grey29"               "grey30"              
## [292] "grey31"               "grey32"               "grey33"              
## [295] "grey34"               "grey35"               "grey36"              
## [298] "grey37"               "grey38"               "grey39"              
## [301] "grey40"               "grey41"               "grey42"              
## [304] "grey43"               "grey44"               "grey45"              
## [307] "grey46"               "grey47"               "grey48"              
## [310] "grey49"               "grey50"               "grey51"              
## [313] "grey52"               "grey53"               "grey54"              
## [316] "grey55"               "grey56"               "grey57"              
## [319] "grey58"               "grey59"               "grey60"              
## [322] "grey61"               "grey62"               "grey63"              
## [325] "grey64"               "grey65"               "grey66"              
## [328] "grey67"               "grey68"               "grey69"              
## [331] "grey70"               "grey71"               "grey72"              
## [334] "grey73"               "grey74"               "grey75"              
## [337] "grey76"               "grey77"               "grey78"              
## [340] "grey79"               "grey80"               "grey81"              
## [343] "grey82"               "grey83"               "grey84"              
## [346] "grey85"               "grey86"               "grey87"              
## [349] "grey88"               "grey89"               "grey90"              
## [352] "grey91"               "grey92"               "grey93"              
## [355] "grey94"               "grey95"               "grey96"              
## [358] "grey97"               "grey98"               "grey99"              
## [361] "grey100"              "honeydew"             "honeydew1"           
## [364] "honeydew2"            "honeydew3"            "honeydew4"           
## [367] "hotpink"              "hotpink1"             "hotpink2"            
## [370] "hotpink3"             "hotpink4"             "indianred"           
## [373] "indianred1"           "indianred2"           "indianred3"          
## [376] "indianred4"           "ivory"                "ivory1"              
## [379] "ivory2"               "ivory3"               "ivory4"              
## [382] "khaki"                "khaki1"               "khaki2"              
## [385] "khaki3"               "khaki4"               "lavender"            
## [388] "lavenderblush"        "lavenderblush1"       "lavenderblush2"      
## [391] "lavenderblush3"       "lavenderblush4"       "lawngreen"           
## [394] "lemonchiffon"         "lemonchiffon1"        "lemonchiffon2"       
## [397] "lemonchiffon3"        "lemonchiffon4"        "lightblue"           
## [400] "lightblue1"           "lightblue2"           "lightblue3"          
## [403] "lightblue4"           "lightcoral"           "lightcyan"           
## [406] "lightcyan1"           "lightcyan2"           "lightcyan3"          
## [409] "lightcyan4"           "lightgoldenrod"       "lightgoldenrod1"     
## [412] "lightgoldenrod2"      "lightgoldenrod3"      "lightgoldenrod4"     
## [415] "lightgoldenrodyellow" "lightgray"            "lightgreen"          
## [418] "lightgrey"            "lightpink"            "lightpink1"          
## [421] "lightpink2"           "lightpink3"           "lightpink4"          
## [424] "lightsalmon"          "lightsalmon1"         "lightsalmon2"        
## [427] "lightsalmon3"         "lightsalmon4"         "lightseagreen"       
## [430] "lightskyblue"         "lightskyblue1"        "lightskyblue2"       
## [433] "lightskyblue3"        "lightskyblue4"        "lightslateblue"      
## [436] "lightslategray"       "lightslategrey"       "lightsteelblue"      
## [439] "lightsteelblue1"      "lightsteelblue2"      "lightsteelblue3"     
## [442] "lightsteelblue4"      "lightyellow"          "lightyellow1"        
## [445] "lightyellow2"         "lightyellow3"         "lightyellow4"        
## [448] "limegreen"            "linen"                "magenta"             
## [451] "magenta1"             "magenta2"             "magenta3"            
## [454] "magenta4"             "maroon"               "maroon1"             
## [457] "maroon2"              "maroon3"              "maroon4"             
## [460] "mediumaquamarine"     "mediumblue"           "mediumorchid"        
## [463] "mediumorchid1"        "mediumorchid2"        "mediumorchid3"       
## [466] "mediumorchid4"        "mediumpurple"         "mediumpurple1"       
## [469] "mediumpurple2"        "mediumpurple3"        "mediumpurple4"       
## [472] "mediumseagreen"       "mediumslateblue"      "mediumspringgreen"   
## [475] "mediumturquoise"      "mediumvioletred"      "midnightblue"        
## [478] "mintcream"            "mistyrose"            "mistyrose1"          
## [481] "mistyrose2"           "mistyrose3"           "mistyrose4"          
## [484] "moccasin"             "navajowhite"          "navajowhite1"        
## [487] "navajowhite2"         "navajowhite3"         "navajowhite4"        
## [490] "navy"                 "navyblue"             "oldlace"             
## [493] "olivedrab"            "olivedrab1"           "olivedrab2"          
## [496] "olivedrab3"           "olivedrab4"           "orange"              
## [499] "orange1"              "orange2"              "orange3"             
## [502] "orange4"              "orangered"            "orangered1"          
## [505] "orangered2"           "orangered3"           "orangered4"          
## [508] "orchid"               "orchid1"              "orchid2"             
## [511] "orchid3"              "orchid4"              "palegoldenrod"       
## [514] "palegreen"            "palegreen1"           "palegreen2"          
## [517] "palegreen3"           "palegreen4"           "paleturquoise"       
## [520] "paleturquoise1"       "paleturquoise2"       "paleturquoise3"      
## [523] "paleturquoise4"       "palevioletred"        "palevioletred1"      
## [526] "palevioletred2"       "palevioletred3"       "palevioletred4"      
## [529] "papayawhip"           "peachpuff"            "peachpuff1"          
## [532] "peachpuff2"           "peachpuff3"           "peachpuff4"          
## [535] "peru"                 "pink"                 "pink1"               
## [538] "pink2"                "pink3"                "pink4"               
## [541] "plum"                 "plum1"                "plum2"               
## [544] "plum3"                "plum4"                "powderblue"          
## [547] "purple"               "purple1"              "purple2"             
## [550] "purple3"              "purple4"              "red"                 
## [553] "red1"                 "red2"                 "red3"                
## [556] "red4"                 "rosybrown"            "rosybrown1"          
## [559] "rosybrown2"           "rosybrown3"           "rosybrown4"          
## [562] "royalblue"            "royalblue1"           "royalblue2"          
## [565] "royalblue3"           "royalblue4"           "saddlebrown"         
## [568] "salmon"               "salmon1"              "salmon2"             
## [571] "salmon3"              "salmon4"              "sandybrown"          
## [574] "seagreen"             "seagreen1"            "seagreen2"           
## [577] "seagreen3"            "seagreen4"            "seashell"            
## [580] "seashell1"            "seashell2"            "seashell3"           
## [583] "seashell4"            "sienna"               "sienna1"             
## [586] "sienna2"              "sienna3"              "sienna4"             
## [589] "skyblue"              "skyblue1"             "skyblue2"            
## [592] "skyblue3"             "skyblue4"             "slateblue"           
## [595] "slateblue1"           "slateblue2"           "slateblue3"          
## [598] "slateblue4"           "slategray"            "slategray1"          
## [601] "slategray2"           "slategray3"           "slategray4"          
## [604] "slategrey"            "snow"                 "snow1"               
## [607] "snow2"                "snow3"                "snow4"               
## [610] "springgreen"          "springgreen1"         "springgreen2"        
## [613] "springgreen3"         "springgreen4"         "steelblue"           
## [616] "steelblue1"           "steelblue2"           "steelblue3"          
## [619] "steelblue4"           "tan"                  "tan1"                
## [622] "tan2"                 "tan3"                 "tan4"                
## [625] "thistle"              "thistle1"             "thistle2"            
## [628] "thistle3"             "thistle4"             "tomato"              
## [631] "tomato1"              "tomato2"              "tomato3"             
## [634] "tomato4"              "turquoise"            "turquoise1"          
## [637] "turquoise2"           "turquoise3"           "turquoise4"          
## [640] "violet"               "violetred"            "violetred1"          
## [643] "violetred2"           "violetred3"           "violetred4"          
## [646] "wheat"                "wheat1"               "wheat2"              
## [649] "wheat3"               "wheat4"               "whitesmoke"          
## [652] "yellow"               "yellow1"              "yellow2"             
## [655] "yellow3"              "yellow4"              "yellowgreen"


1.1.5. Variables quali/quanti = Boite à moustaches


1.1.6. Variable quantitative = Graphique de densité


1.2. Diagramme à barres: fonction barplot()


1.3. Histogramme: fonction hist()


La très pratique fonction par()


1.4. Boite à moustaches


1.5. Autres graphiques divers

## [1] 288 391




2. Package graphique ggplot2 (grammar of graphics)

  • Fonctionne en superposant des composantes (couches superposées avec +)
  • ggplot() spécifie le tableau source des données
  • geom(): géométrie, ie choix du graphique (ex:geom_histogram)
  • aes(): aestetics, ie propriétés visuelles incluant l’axe des x , des y, la couleur des lignes ( colour ), …
  • Ensuite on peut personnaliser avec des titres, légendes, thèmes, facettes et tout un tas d’options

https://ggplot2.tidyverse.org/reference/ https://www.r-graph-gallery.com/ggplot2-package.html


2.1. geom_histogram = Histogramme

## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.


Le “faceting”


2.2. geom_bar - Graphique en barres


Le “mapping”


2.3. geom_point: Nuage de points

## Warning: Removed 5 rows containing missing values (geom_point).

## `geom_smooth()` using formula 'y ~ x'


2.4. geom_boxplot - boite à moustache

2.5. geom_density - densité



LS0tDQp0aXRsZTogIkNhcHN1bGUgODogR3JhcGhpcXVlcyINCm91dHB1dDogDQogIGh0bWxfZG9jdW1lbnQ6IA0KICAgIHRoZW1lOiBjZXJ1bGVhbg0KICAgIGhpZ2hsaWdodDogaGFkZG9jaw0KICAgIHRvYzogdHJ1ZQ0KICAgIHRvY19mbG9hdDogDQogICAgICBjb2xsYXBzZWQ6IGZhbHNlDQogICAgICBTbW9vdGhfc2Nyb2xsOiB0cnVlDQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KY3NzOiBoaWRlLmNzcw0KLS0tDQoNCkNhcm9saW5lIFBhdGVuYXVkZSA8YnI+IA0KKltCaWJsaW90aMOpY2FpcmUgLSBCaWJsaW90aMOocXVlIGRlcyBsZXR0cmVzIGV0IHNjaWVuY2VzIGh1bWFpbmVzXShodHRwczovL2JpYi51bW9udHJlYWwuY2EvZ3VpZGVzL2Rvbm5lZXMtc3RhdGlzdGlxdWVzLWdlb3NwYXRpYWxlcy9kb25uZWVzLXN0YXRpc3RpcXVlcykqIA0KPGJyPiANCg0KW1NjcmlwdCBDb2xhYl0oaHR0cHM6Ly9naXRodWIuY29tL0NvdXJzLUVEVWxpYi9GQVMtSVNEUy9ibG9iL21haW4vbW9kdWxlLTQvNF8zX2dyYXBoaXF1ZXMuaXB5bmIpIHwgW1NjcmlwdCBSXShodHRwczovL2dpdGh1Yi5jb20vQ291cnMtRURVbGliL0ZBUy1JU0RTL2Jsb2IvbWFpbi9tb2R1bGUtNC80LjMtZ3JhcGhpcXVlcy5SKSANCg0KPGJyPg0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSkNCmBgYA0KDQo8c2NyaXB0IHNyYz0iaGlkZU91dHB1dC5qcyI+PC9zY3JpcHQ+DQoNCmBgYHtyfQ0KIyBDaGFyZ2VtZW50IGRlcyBtb2R1bGVzIG7DqWNlc3NhaXJlcw0KbGlicmFyeShxdWVzdGlvbnIpDQpsaWJyYXJ5KGNhcikNCmxpYnJhcnkoZ2dwbG90MikNCg0KIyBBam91dGVyIGxhIGZvbmN0aW9uIGRlIHTDqWzDqWNoYXJnZW1lbnQgc2kgbsOpY2Vzc2FpcmU6DQojIGluc3RhbGwucGFja2FnZXMoInF1ZXN0aW9uciIsIGRlcGVuZGVuY2llcz1UUlVFKQ0KIyBpbnN0YWxsLnBhY2thZ2VzKCJjYXIiLCBkZXBlbmRlbmNpZXM9VFJVRSkNCiMgaW5zdGFsbC5wYWNrYWdlcygiZ2dwbG90MiIsIGRlcGVuZGVuY2llcz1UUlVFKQ0KIw0KIyBUw6lsw6ljaGFyZ2VtZW50IGRlIGxhIGJhc2UgZGUgZG9ubsOpZXMgaGR2MjAwMyBkdSBtb2R1bGUgcXVlc3Rpb25yDQojIChFeHRyYWl0IGRlIGwnZW5xdcOqdGUgIkhpc3RvaXJlIGRlIHZpZSIgZGUgbCdJbnNlZSAtIGh0dHBzOi8vd3d3Lmluc2VlLmZyL2ZyL3N0YXRpc3RpcXVlcy8yNTMyMjQ0KQ0KZGF0YShoZHYyMDAzKQ0KDQojIENvcGllIGRlIGxhIGJhc2UgZGUgZG9ubsOpZXMgZGFucyB1biBvYmpldCAoZGF0YXRhYmxlKSBub21tw6kgYmQNCmJkIDwtIGhkdjIwMDMNCmBgYA0KDQo8YnI+DQoNCiMjIERldXggcHJpbmNpcGFsZXMgZmFtaWxsZXMgZGUgZm9uY3Rpb25zIGdyYXBoaXF1ZXMNCg0KMS4gICBGb25jdGlvbnMgbmF0aXZlcw0KMi4gICBGb25jdGlvbnMgR0dwbG90Mg0KDQo8YnI+DQoNCiMjIDEuIFF1YXRyZSBncmFwaGlxdWVzIGRlIGJhc2U6IHBsb3QoKSwgaGlzdCgpLCBib3hwbG90KCksIGJhcnBsb3QoKQ0KDQo8YnI+DQoNCiMjIyAxLjEuIExhIGZvbmN0aW9uIGfDqW7DqXJpcXVlIHBsb3QoKSAtIGxlIGdyYXBoaXF1ZSBwcm9kdWl0IGTDqXBlbmQgZHUgdHlwZSBkJ29iamV0IGZvdXJuaQ0KDQo8YnI+DQoNCiMjIyMgMS4xLjEuIFZhcmlhYmxlIHF1YWxpdGF0aXZlID0gR3JhcGhpcXVlIMOgIGJhcnJlcw0KDQoNCjxkaXYgY2xhc3M9ImZvbGQgbyI+DQpgYGB7cn0NCnBsb3QoYmQkdHJhdi5zYXRpc2YpIA0KYGBgDQoNCjxicj4NCg0KIyMjIyAxLjEuMy4gVGFibGUgZCdlZmZlY3RpZnMgKG91IHByb3BvcnRpb25zKSA9IEdyYXBoaXF1ZSDDoCBiYXJyZXMNCg0KYGBge3J9DQpwbG90KHRhYmxlKGJkJGZyZXJlcy5zb2V1cnMpKQ0KYGBgDQoNCjxicj4NCg0KKipGb25jdGlvbnMgZGUgYmFzZSBzJ2FjY29tcGFnbmVudCBkZSBub21icmV1eCBhcmd1bWVudHMgZG9udCBwbHVzaWV1cnMgcGV1dmVudCDDqnRyZSB1dGlsaXPDqXMgcG91ciB0b3VzIGxlcyBncmFwaGlxdWVzKioNCg0KYGBge3J9DQpwbG90KHRhYmxlKGJkJGZyZXJlcy5zb2V1cnMpLCANCmNvbD0icmVkIiwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgY29sPSAgICBjb3VsZXVyIGRlcyBiYXJyZXMNCm1haW4gPSAiTm9tYnJlIGRlIGZyw6hyZXMgZXQgc29ldXJzIiwgICAjIG1haW49ICAgdGl0cmUgZHUgZ3JhaGlxdWUNCnlsYWIgPSAiRWZmZWN0aWYiLCAgICAgICAgICAgICAgICAgICAgICMgeWxhYj0gICB0aXRyZSBkZSBsJ2F4ZSB5DQp4bGFiPSJOb21icmUgZGUgZnLDqHJlcyBldCBzb2V1cnMiLCAgICAgIyB4bGFiPSAgIHRpdHJlIGRlIGwnYXhlIHgNCnlsaW09YygxLCA1MDApLCAgICAgICAgICAgICAgICAgICAgICAgICMgeWxpbT0gICBncmFkdWF0aW9uIGRlIGwnYXhlIHkNCnhsaW09YygwLCAyNSksICAgICAgICAgICAgICAgICAgICAgICAgICMgeGxpbT0gICBncmFkdWF0aW9uIGRlIGwnYXhlIHgNCnR5cGU9ImIiKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgdHlwZT0gICBzdHlsZSBkZSBsaWduZXMgKCJoIiwgInAiLCAibCIsICJvIiwgInMiLCAiYikNCmBgYA0KDQo8YnI+DQoNCiMjIyMgMS4xLjQuIFZhcmlhYmxlcyBxdWFudGkvcXVhbnRpID0gTnVhZ2UgZGUgcG9pbnRzDQoNCmBgYHtyfQ0KcGxvdChiZCRhZ2UsIGJkJGhldXJlcy50dikgDQpgYGANCg0KYGBge3J9DQojIE1vZGlmaWNhdGlvbnMgcG9zc2libGVzIHBhcm1pIHRhbnQgZCdhdXRyZXM6IGZhaXJlIHZhcmllciBsZXMgcG9pbnRzIHNlbG9uIGxlcyB2YWxldXJzIGQndW5lIGF1dHJlIHZhcmlhYmxlIA0KIyBwYXIgbCdham91dCBkZSBmb25jdGlvbnMgc3VwZXJwb3PDqWVzDQoNCnBsb3QoYmQkYWdlLCBiZCRoZXVyZXMudHYpICAjIHZhciBxdWFudGkvcXVhbnRpDQpwb2ludHMoYmQkYWdlW2JkJHNleGU9PSJIb21tZSJdLCBiZCRoZXVyZXMudHZbYmQkc2V4ZT09IkhvbW1lIl0sIHBjaD0xNiwgY29sPSJzdGVlbGJsdWUiKQ0KcG9pbnRzKGJkJGFnZVtiZCRzZXhlPT0iRmVtbWUiXSwgYmQkaGV1cmVzLnR2W2JkJHNleGU9PSJGZW1tZSJdLCBwY2g9MTYsIGNvbD0ib3JhbmdlIikNCmxlZ2VuZCgidG9wcmlnaHQiLCBsZWdlbmQ9YygiSG9tbWUiLCJGZW1tZSIpLCBjb2w9Yygic3RlZWxibHVlIiwib3JhbmdlIiksIHBjaD1jKDE2KSkNCg0KICAjIHBsb3QoKSAgICBudWFnZSBkZSBwb2ludHMNCiAgIyBwb2ludHMoKSAgY3LDqWF0aW9uIGQndW5lIHPDqXF1ZW5jZSBkZSBwb2ludHMgY29sb3LDqXMgc3VwZXJwb3PDqXMgZW4gZm9uY3Rpb24gZGUgdmFsZXVycyBkZSB2YXJpYWJsZXMgc8OpbGVjdGlvbm7DqWVzIHBhciBjb25kaXRpb24NCiAgIyBwY2g9ICAgICAgc3R5bGUgZGUgcG9pbnRzDQogICMgY29sPSAgICAgIGNvdWxldXIgZGVzIHBvaW50cw0KICAjIGxlZ2VuZCgpICBham91dCBkJ3VuZSBsw6lnZW5kZSBldCBzZXMgYXJndW1lbnRzIGRlIHBhcmFtw6l0cmFnZQ0KYGBgDQoNCmBgYHtyfQ0KY29sb3VycygpICMgUG91ciB2b2lyIGxhIHBhbGV0dGUgZGUgY291bGV1cnMgZGUgYmFzZQ0KYGBgDQoNCjxicj4NCg0KIyMjIyAxLjEuNS4gVmFyaWFibGVzIHF1YWxpL3F1YW50aSA9IEJvaXRlIMOgIG1vdXN0YWNoZXMNCg0KYGBge3J9DQpwbG90KGJkJHNleGUsIGJkJGhldXJlcy50dikgDQoNCiMgdmFyaWFibGUgaW5kw6lwZW5kYW50ZSDDoCBnYXVjaGUgKHgpLCBkw6lwZW5kYW50ZSDDoCBkcm9pdGUgKHkpDQojIE5vdGF0aW9uIGZvcm11bGU6IGxlcyBmb3JtdWxlcyBwYXNzZW50IGxhIHZhcmlhYmxlIHkgZW4gcHJlbWllciwgDQojIGRvbmMgbGEgbm90YXRpb24gZm9ybXVsZSBkZSBsYSBmb25jdGlvbiBnw6luw6lyaXF1ZSBwbG90KHgsIHkpIGVzdCBwbG90KHkgfiB4KQ0KYGBgDQoNCjxicj4NCg0KIyMjIyAxLjEuNi4gVmFyaWFibGUgcXVhbnRpdGF0aXZlID0gR3JhcGhpcXVlIGRlIGRlbnNpdMOpDQoNCmBgYHtyfQ0KIyBBam91dCBkZSBsYSBmb25jdGlvbiBkZSBkZW5zaXTDqSDDoCBsYSBmb25jdGlvbiBwbG90KCkNCg0KcGxvdChkZW5zaXR5KGJkJGhldXJlcy50diwgbmEucm0gPSBUUlVFKSwgbWFpbiA9ICJIZXVyZXMgZCfDqWNvdXRlIGRlIHTDqWzDqSIpDQpgYGANCg0KYGBge3J9DQojIEFqb3V0IGRlIGxhIGZvbmN0aW9uIGxpbmVzKCkgcXVpIHBlcm1ldCBkZSBzdXBlcnBvc2VyIHBsdXNpZXVycyDDqWzDqW1lbnRzIGdyYXBoaXF1ZXMNCiMgbHdkPSAgbGFyZ2V1ciBkZXMgbGlnbmVzDQoNCnBsb3QoZGVuc2l0eShiZCRhZ2VbYmQkc2V4ZSA9PSAiRmVtbWUiXSksICBsd2QgPSAzLCBjb2wgPSAicmVkIiwgbWFpbiA9ICJUaXRyZSBkdSBncmFwaGlxdWUiKQ0KbGluZXMoZGVuc2l0eShiZCRhZ2VbYmQkc2V4ZSA9PSAiSG9tbWUiXSksICBsd2QgPSAzLCBjb2wgPSAiYmx1ZSIpDQpgYGANCg0KPGJyPg0KDQojIyMgMS4yLiBEaWFncmFtbWUgw6AgYmFycmVzOiBmb25jdGlvbiBiYXJwbG90KCkNCg0KYGBge3J9DQp0Yi5lZmYgPC0gdGFibGUoYmQkdHJhdi5zYXRpcywgYmQkc2V4ZSkgIyB0YWJsZWF1IGQnZWZmZWN0aWZzDQp0Yi5wcm9wIDwtIGNwcm9wKHRiLmVmZiwgdG90YWwgPSBGQUxTRSkgIyB0YWJsZWF1IGRlIHByb3BvcnRpb25zDQpgYGANCg0KYGBge3J9DQojIEdyYXBoaXF1ZSDDoCBiYXJyZXMgYXZlYyB0YWJsZSBkJ2VmZmVjdGlmcyBzdXBlcnBvc8Opcw0KIyBsZWdlbmQgPSBsZXZlbHMgcG91ciBmYWlyZSBhcHBhcmFpdHJlIGxlcyBjYXTDqWdvcmllcyBkZSBsYSB2YXJpYWJsZSBjaG9pc2llDQoNCmJhcnBsb3QodGIuZWZmICwgbGVnZW5kID0gbGV2ZWxzKGJkJHRyYXYuc2F0aXMpKQ0KYGBgDQoNCmBgYHtyfQ0KIyBHcmFwaGlxdWUgw6AgYmFycmVzIGF2ZWMgdGFibGUgZGUgcHJvcG9ydGlvbnMNCg0KYmFycGxvdCh0Yi5wcm9wLCBiZXNpZGUgPSBUUlVFLCB4bGFiID0gIlNhdGlzZmFjdGlvbiIsIHlsYWIgPSAicG91cmNlbnRhZ2VzIiwgbGFzPTIsIHlsaW09YygwLCAxMDApLA0KY29sID0gYygiYmx1ZSIsICJncmVlbiIsICJvcmFuZ2UiKSwgbGVnZW5kID0gbGV2ZWxzKGJkJHRyYXYuc2F0aXMpKQ0KDQojIGJlc2lkZSA9IFRSVUUgIGJhcnJlcyBjw7R0ZXMgw6AgY8O0dGVzDQojIGxhcz0yICAgICAgICAgIGludGl0dWzDqXMgw6AgbGEgdmVydGljYWxlDQpgYGANCg0KPGJyPg0KDQojIyMgMS4zLiBIaXN0b2dyYW1tZTogZm9uY3Rpb24gaGlzdCgpDQoNCmBgYHtyfQ0KaGlzdChiZCRhZ2UpIA0KYGBgDQoNCmBgYHtyfQ0KIyBIaXN0b2dyYW1tZSBhdmVjIHF1ZWxxdWVzIGFyZ3VtZW50cw0KDQpoaXN0KGJkJGFnZSwgbWFpbiA9ICJBZ2UiLCBjb2w9InZpb2xldHJlZDIiLCBicmVha3MgPSA4LCB4bGFiID0gIkFnZSIsIHlsYWIgPSAiRWZmZWN0aWYiLCBsYWJlbHMgPSBUUlVFKQ0KDQoNCiAgIyBtYWluPSAgIHRpdHJlIGR1IGdyYWhpcXVlDQogICMgY29sPSAgICBjb3VsZXVyIGRlcyBiYXJyZXMNCiAgIyBicmVha3M9IG5vbWJyZSBkZSAiYmFycmVzIg0KICAjIHhsYWI9ICAgdGl0cmUgZGUgbCdheGUgeA0KICAjIHlsYWI9ICAgdGl0cmUgZGUgbCdheGUgeQ0KICAjIGxhYmVscz0gYWZmaWNoYWdlIGRlcyB2YWxldXJzDQogICMgUG91ciBham91dGVyIHVuZSBsaWduZSBkZSBkZW5zaXTDqToNCiAgICAjIyBhcmd1bWVudCBwcm9iID0gVFJVRSBhZmZpY2hhZ2UgZGUgbGEgbGlnbmUgZGUgZGVuc2l0w6kNCiAgICAjIyBmb25jdGlvbiBsaW5lcyhkZW5zaXR5KGJkJGFnZSwgbmEucm0gPSBUUlVFKSwgbHdkID0gNCwgY29sID0gImdyZWVuIikNCmBgYA0KDQo8YnI+DQoNCiMjIyMgTGEgdHLDqHMgcHJhdGlxdWUgZm9uY3Rpb24gcGFyKCkNCg0KYGBge3J9DQpwYXIobWZyb3cgPSBjKDEsIDIpLCBiZz0iZ3JheSIsIGNvbC5heGlzPSJncmVlbiIsIG1hcj1jKDUsIDUsIDUsIDUpKQ0KaGlzdChiZCRhZ2VbYmQkc3BvcnQgPT0gIk91aSJdLCBtYWluID0gIlNwb3J0aWYiLCBjb2wgPSAiY2hhcnRyZXVzZTIiKQ0KaGlzdChiZCRhZ2VbYmQkc3BvcnQgPT0gIk5vbiJdLCBtYWluID0gIk5vbiBzcG9ydGlmIiwgY29sID0gImN5YW40IikNCg0KIyBwYXIoKSAgICAgICBkaXNwb3NpdGlvbiBkZXMgZ3JhcGhpcXVlcw0KIyBiZz0gICAgICAgICBjb3VsZXVyIGR1ICJiYWNrZ3JvdW5kIg0KIyBjb2wuYXhpcz0gICBjb3VsZXVyIGRlIGxhIG51bcOpcm90YXRpb24gZGVzIGF4ZXMNCiMgbWFyPSAgICAgICAgZ3Jvc3NldXIgZGVzIG1hcmdlcw0KYGBgDQoNCjxicj4NCg0KIyMjIDEuNC4gQm9pdGUgw6AgbW91c3RhY2hlcyANCg0KYGBge3J9DQpib3hwbG90KGJkJGhldXJlcy50diwgbWFpbj0iSGV1cmVzIGQnw6ljb3V0ZSBkZSBsYSB0w6lsw6kiLCBjb2w9ImdyZWVuIiwgeGxhYiA9ICJsw6lnZW5kZSBob3Jpem9udGFsZSIsIHlsYWIgPSAiSGV1cmVzIGQnw6ljb3V0ZSIgKQ0KYGBgDQoNCmBgYHtyfQ0KIyMgQ29tcGFyZXIgZ3JvdXBlIGF2ZWMgbGEgbm90YXRpb24gImZvcm11bGUiICh5IH4geCkNCg0KYm94cGxvdChhZ2UgfiBoYXJkLnJvY2ssIGJkKQ0KYGBgDQoNCjxicj4NCg0KIyMjIDEuNS4gQXV0cmVzIGdyYXBoaXF1ZXMgZGl2ZXJzDQoNCmBgYHtyfQ0KIyBHcmFwaGlxdWUgbW9zYWlxdWUNCg0KbW9zYWljcGxvdChzcG9ydCB+IHNleGUsIGJkLCBsYXMgPSAxLCBzaGFkZSA9IFRSVUUsIG1haW49Ik5pdmVhdSBkZSBxdWFsaWZpY2F0aW9uIHNlbG9uIGxlIHNleGUiKQ0KIyBDaGFxdWUgYm9pdGUgY29ycmVzcG9uZCDDoCB1bmUgY2VsbHVsZQ0KIyBsYXJnZXVyOiBwb3VyY2VudGFnZXMgZW4gY29sb25uZXMNCiMgaGF1dGV1cjogcG91cmNlbnRhZ2VzIGVuIGxpZ25lcw0KIyBDb3VsZXVyczogcsOpc2lkdXMgZHUgY2hpMg0KYGBgDQoNCmBgYHtyfQ0KIyBkaWFncmFtbWUgUS1RIChNb2R1bGUgY2FyKQ0KDQpxcVBsb3QoYmQkaGV1cmVzLnR2LCBjb2w9Y29sb3JzKClbOV0sIGNvbC5saW5lcz1jb2xvcnMoKVszMF0sIGx3ZD00LCBwY2g9MSkgDQoNCiMgQ29tcGFyZSDDoCB1bmUgZGlzdHJpYnV0aW9uIG5vcm1hbGUsIHF1YW50aWxlIHBhciBxdWFudGlsZQ0KIyBUcmFjZSBlbiBwb2ludGlsbMOpIGwnaW50ZXJ2YWxsZSBkZSBjb25maWFuY2Ugw6AgOTUlDQojIElkZW50aWZpZSBsZXMgcG9pbnRzIGxlcyBwbHVzIMOpbG9pZ27DqXMgZGUgbGV1ciBxdWFudGlsZSBub3JtYWwNCiMgY29sPSAgICAgICBzw6lsZWN0aW9uIGRlIGNvdWxldXJzIGRlcyBwb2ludHMgcGFyIHBvc2l0aW9uIGRhbnMgbGEgcGFsZXR0ZSBjb2xvcnMoKQ0KIyBjb2wubGluZXM9IHPDqWxlY3Rpb24gZGUgY291bGV1cnMgZGVzIGxpZ25lcyBwYXIgcG9zaXRpb24gZGFucyBsYSBwYWxldHRlIGNvbG9ycygpDQojIGx3ZD0gICAgICAgbGFyZ2V1ciBkZXMgbGlnbmVzDQojIHBjaD0gICAgICAgdHlwZSBkZSBwb2ludHMNCmBgYA0KDQpgYGB7cn0NCiMgTnVhZ2UgZGUgcG9pbnRzICsgbGlnbmUgZGUgcsOpZ3Jlc3Npb24gbm9uIHBhcmFtw6l0cmlxdWUgZXQgYm9pdGVzIMOgIG1vdXN0YWNoZSBzdXIgbGVzIGF4ZXMgKE1vZHVsZSBjYXIpDQoNCnNjYXR0ZXJwbG90KGhldXJlcy50diB+IGFnZSwgIGRhdGE9YmQpIA0KYGBgDQoNCjxicj4NCg0KLS0tDQoNCjxicj4NCg0KIyMgMi4gUGFja2FnZSBncmFwaGlxdWUgZ2dwbG90MiAoZ3JhbW1hciBvZiBncmFwaGljcykNCg0KKiBGb25jdGlvbm5lIGVuIHN1cGVycG9zYW50IGRlcyBjb21wb3NhbnRlcyAoY291Y2hlcyBzdXBlcnBvc8OpZXMgYXZlYyArKQ0KKiBnZ3Bsb3QoKSBzcMOpY2lmaWUgbGUgdGFibGVhdSBzb3VyY2UgZGVzIGRvbm7DqWVzDQoqIGdlb20oKTogZ8Opb23DqXRyaWUsIGllIGNob2l4IGR1IGdyYXBoaXF1ZSAoZXg6Z2VvbV9oaXN0b2dyYW0pDQoqIGFlcygpOiBhZXN0ZXRpY3MsIGllIHByb3ByacOpdMOpcyB2aXN1ZWxsZXMgaW5jbHVhbnQgbOKAmWF4ZSBkZXMgeCAsIGRlcyB5LCBsYSBjb3VsZXVyIGRlcyBsaWduZXMgKCBjb2xvdXIgKSwgLi4uDQoqIEVuc3VpdGUgb24gcGV1dCBwZXJzb25uYWxpc2VyIGF2ZWMgZGVzIHRpdHJlcywgbMOpZ2VuZGVzLCB0aMOobWVzLCBmYWNldHRlcyBldCB0b3V0IHVuIHRhcyBkJ29wdGlvbnMNCg0KaHR0cHM6Ly9nZ3Bsb3QyLnRpZHl2ZXJzZS5vcmcvcmVmZXJlbmNlLyANCmh0dHBzOi8vd3d3LnItZ3JhcGgtZ2FsbGVyeS5jb20vZ2dwbG90Mi1wYWNrYWdlLmh0bWwgIA0KDQo8YnI+DQoNCiMjIyAyLjEuIGdlb21faGlzdG9ncmFtID0gSGlzdG9ncmFtbWUNCg0KYGBge3J9DQpnZ3Bsb3QoYmQpICsgICAgICAgICAgICAgICAgICAjIG9iamV0IGJkDQpnZW9tX2hpc3RvZ3JhbShhZXMoeCA9IGFnZSkpICAjIGhpc3RvZ3JhbW1lIGRlIGxhIHZhcmlhYmxlIGFnZQ0KDQojIEFyZ3VtZW50IGFlcygpIGltYnJpcXXDqSBpY2kgZGFucyBsZSBnZW9tKCkgbWFpcyBwZXV0IGF1c3NpIMOqdHJlIGTDqWZpbmkgYXV0cmVtZW50IGNvbW1lIGRhbnMgbGUgZ2dwbG90KCkNCmBgYA0KDQpgYGB7cn0NCmdncGxvdChiZCkgKyANCmdlb21faGlzdG9ncmFtKGFlcyh4ID0gYWdlKSwgZmlsbD0ib3JjaGlkMSIsIGNvbG91ciA9ICJ3aGl0ZSIsIGJpbndpZHRoID0gNSkgKyAgIyBhcmd1bWVudHMgZGUgY291bGV1cnMgZXQgbGFyZ2V1ciBkZXMgYmFycmVzDQpnZ3RpdGxlKCJBZ2UgZGVzIHLDqXBvbmRhbnRzIikgKyAgICMgdGl0cmUgZHUgZ3JhcGhpcXVlDQp4bGFiKCJBZ2UiKSArICAgICAgICAgICAgICAgICAgICAgIyB0aXRyZSBheGUgeA0KeWxhYigiRWZmZWN0aWZzIikgICAgICAgICAgICAgICAgICMgdGl0cmUgYXhlIHkNCmBgYA0KDQo8YnI+DQoNCiMjIyBMZSAiZmFjZXRpbmciDQoNCmBgYHtyfQ0KIyBMZSBmYWNldGluZyBwZXJtZXQgZOKAmWVmZmVjdHVlciBwbHVzaWV1cnMgZm9pcyBsZSBtw6ptZSBncmFwaGlxdWUgc2Vsb24gbGVzIHZhbGV1cnMgZOKAmXVuZSBvdSBwbHVzaWV1cnMgDQojIHZhcmlhYmxlcyBxdWFsaXRhdGl2ZXMsIGnDp2kgZmFjZXRfZ3JpZCh+c2V4ZSkuDQoNCmdncGxvdChiZCkgKyAgDQpnZW9tX2hpc3RvZ3JhbShhZXMoeCA9IGFnZSksIGZpbGw9Im9yY2hpZDEiLCBjb2xvdXIgPSAid2hpdGUiLCBicmVha3MgPSBjKDAsIDIwLCA0MCwgNjAsIDgwLCAxMDApKSArICAjIGJyZWFrcz0gbGltaXRlcyBkZXMgY2F0w6lnb3JpZXMgZCfDomdlDQpnZ3RpdGxlKCJBZ2UgZGVzIHLDqXBvbmRhbnRzIikgKyAgICMgdGl0cmUgZHUgZ3JhcGhpcXVlDQp4bGFiKCJBZ2UiKSArICAgICAgICAgICAgICAgICAgICAgIyB0aXRyZSBheGUgeA0KZmFjZXRfZ3JpZCh+c2V4ZSkgICAgICAgICAgICAgICAgICMgdmFyaWFibGUgZGUgZ3JvdXBlcw0KYGBgDQoNCjxicj4NCg0KIyMjIDIuMi4gZ2VvbV9iYXIgLSBHcmFwaGlxdWUgZW4gYmFycmVzDQoNCmBgYHtyfQ0KZ2dwbG90KGJkKSArIA0KZ2VvbV9iYXIoYWVzKHggPSB0cmF2LnNhdGlzZiksIGZpbGwgPSAidGhpc3RsZTMiLCB3aWR0aCA9IC43KSArIA0KeGxhYigiU2F0aXNmYWN0aW9uIikgKw0KeWxhYigiRWZmZWN0aWZzIikgKyANCmdndGl0bGUoIlNhdGlzZmFjdGlvbiBhdSB0cmF2YWlsIikgDQpgYGANCg0KPGJyPg0KDQojIyMgTGUgIm1hcHBpbmciDQoNCmBgYHtyfQ0KIyBQb3VyIGZhaXJlIHZhcmllciBsYSBjb3VsZXVyIGVuIGZvbmN0aW9uIGRlcyB2YWxldXJzIHByaXNlcyBwYXIgZCd1bmUgYXV0cmUgdmFyaWFibGUsIG9uIHLDqWFsaXNlIHVuICJtYXBwYWdlIg0KIyBvbiBkb2l0IGFsb3JzIHBsYWNlciBs4oCZYXR0cmlidXQgZ3JhcGhpcXVlIChpY2kgZmlsbD0pIMOgIGzigJlpbnTDqXJpZXVyIGRlIGxhIHBhcmVudGjDqHNlIGFlcygpDQoNCmdncGxvdChiZCkgKyANCmdlb21fYmFyKGFlcyh4ID0gb2NjdXAsIGZpbGwgPSBzZXhlKSkgICAgICAgICAgICAgICAgICAgICAjIHBvc2l0aW9uID0gInN0YWNrIiAtIGVmZmVjdGlmcyBkZSBncm91cGVzIHN1cGVycG9zw6lzIHBhciBkw6lmYXV0DQoNCmdncGxvdChiZCkgKyANCmdlb21fYmFyKGFlcyh4ID0gb2NjdXAsIGZpbGwgPSBzZXhlKSwgcG9zaXRpb24gPSAiZG9kZ2UiKSAjIHBvc2l0aW9uID0gImRvZGdlIiAtIGVmZmVjdGlmcyBkZSBncm91cGVzICBjw7R0ZSDDoCBjw7R0ZQ0KDQpnZ3Bsb3QoYmQpICsgDQpnZW9tX2JhcihhZXMoeCA9IG9jY3VwLCBmaWxsID0gc2V4ZSksIHBvc2l0aW9uID0gImZpbGwiKSAgIyBwb3NpdGlvbiA9ICJmaWxsIiAtIHByb3BvcnRpb25zIHN1cGVycG9zw6llcyBkZXMgZ3JvdXBlcw0KYGBgDQoNCjxicj4NCg0KIyMjIDIuMy4gZ2VvbV9wb2ludDogTnVhZ2UgZGUgcG9pbnRzDQoNCmBgYHtyfQ0KZ2dwbG90KGJkKSArIA0KZ2VvbV9wb2ludChhZXMoeCA9IGFnZSwgeSA9IGZyZXJlcy5zb2V1cnMsIGNvbG9yID0gc2V4ZSksIHNpemU9MywgcGNoPTE5KSArIA0Kc2NhbGVfY29sb3JfYnJld2VyKCJzZXhlIiwgcGFsZXR0ZSA9ICJBY2NlbnQiKSArDQp0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwgbGVnZW5kLmJveCA9ICJ2ZXJ0aWNhbCIpICMgb3UgYXBwbGlxdWVyIGRlcyB0aMOobWVzIHByw6lkw6lmaW5pcyBjb21tZSB0aGVtZV9kYXJrKCkNCg0KDQojIGNvbG9yPSDDoCBsJ2ludMOpcmlldXIgZGUgYWVzKCkgcGVybWV0IGRlIGZhaXJlIHZhcmllciBsYSBjb3VsZXVyIGRlcyBwb2ludHMgZW4gZm9uY3Rpb24gZGVzIHZhbGV1cnMgZOKAmXVuZSB0cm9pc2nDqG1lIHZhcmlhYmxlIA0KIyBNb2RpZXIgbGEgZ3Jvc3NldXIgZGVzIHBvaW50cyBhdmVjIHNpemU9IGV0IGxlIHR5cGUgYXZlYyBwY2g9DQojIEF1dHJlIHLDqXBlcnRvaXJlIGRlIGNvdWxldXJzIHNjYWxlX2NvbG9yX2JyZXdlcjogUkNvbG9yQnJld2VyOjpkaXNwbGF5LmJyZXdlci5hbGwoKQ0KIyB0aGVtZSgpIGZvbmN0aW9uIHBlcm1ldHRhbnQgZGUgcGVyc29ubmFsaXNlciBsJ2FwcGFyZW5jZSBkZXMgZ3JhcGhpcXVlczoNCiMjIHBlcm1ldCBkJ2FwcGxpcXVlciBkZXMgdGjDqG1lcyBjb21wbGV0cyAoZXg6IHRoZW1lX2RhcmsoKSkgb3UgZGVzIGNvbXBvc2FudGVzIHNww6ljaWZpcXVlcyAtIHZvaXIgYWlkZSA/dGhlbWUNCmBgYA0KDQoNCmBgYHtyfQ0KZ2dwbG90KGJkKSArIA0KZ2VvbV9wb2ludChhZXMoeCA9IGFnZSwgeSA9IGhldXJlcy50diwgY29sb3I9c2V4ZSwgc2l6ZT1oZXVyZXMudHYpLCBhbHBoYT0wLjIpICsNCnNjYWxlX3NpemUoIkhldXJlcyBkZSB0w6lsw6kiLCByYW5nZSA9IGMoMSwxMCkpICsNCnNjYWxlX3hfY29udGludW91cygiQWdlIiwgbGltaXRzID0gYygxNSwxMDApKSArDQpzY2FsZV95X2NvbnRpbnVvdXMoIkhldXJlcyBkZSB0w6lsw6kiLCBsaW1pdHMgPSBjKDAsMTUpKQ0KDQojIHNpemU9IGTDqXBsYWPDqSDDoCBsJ2ludMOpcmlldXIgZGUgZWFzIHBlcm1ldCBkZSBmYWlyZSB2YXJpZXIgbGEgZ3Jvc3NldXIgZGVzIHBvaW50cyBzZWxvbiB1bmUgdmFyaWFibGUgcXVhbnRpdGF0aXZlDQojIGFscGhhPSBtb2RpZmllciBsYSB0cmFuc3BhcmVuY2UNCiMgc2NhbGUoKSBwZXJtZXQgZGUgZMOpZmluaXIgbGVzIGxpbWl0ZXMgZGVzIMOpY2hlbGxlcyB4IGV0IHkgZXQgbGV1ciBsw6lnZW5kZSByZXNwZWN0aXZlDQpgYGANCg0KYGBge3J9DQojIGFqb3V0ZXIgdW5lIGRyb2l0ZSBkZSByw6lncmVzc2lvbiArIGxpZ25lcyBkZSBkZW5zaXTDqQ0KDQpnZ3Bsb3QoYmQsIGFlcyh4PWFnZSwgeT1mcmVyZXMuc29ldXJzKSkgKw0KICBnZW9tX3BvaW50KGNvbD0ic3RlZWxibHVlMiIpICsNCiAgZ2VvbV9zbW9vdGgobWV0aG9kPSJsbSIsIGNvbD0idGhpc3RsZTMiKSArDQogIGdlb21fZGVuc2l0eTJkKGNvbG9yID0gIm9yYW5nZSIpICsgICAgICAgDQogIHNjYWxlX3hfbG9nMTAoKQ0KYGBgDQoNCjxicj4NCg0KIyMjIDIuNC4gZ2VvbV9ib3hwbG90IC0gYm9pdGUgw6AgbW91c3RhY2hlDQoNCmBgYHtyfQ0KIyBPbiBwYXNzZSBlbiB5IGxhIHZhcmlhYmxlIHF1YW50aSBldCBlbiB4IGxhIHZhcmlhYmxlIHF1YWxpDQoNCmdncGxvdChiZCkgKyANCmdlb21fYm94cGxvdChhZXMoeCA9IHRyYXYuc2F0aXNmLCB5ID1hZ2UpLCB2YXJ3aWR0aCA9IFRSVUUsIGZpbGwgPSAibWlkbmlnaHRibHVlIiwgY29sb3IgPSAiY2hhcnRyZXVzZTEiKSArIA0KZ2d0aXRsZSgiUHJhdGlxdWUgZGUgbGEgcmVsaWdpb24iKQ0KDQojIHZhcndpZHRoID0gVFJVRSAgZmFpcmUgdmFyaWVyIGxhIGxhcmdldXIgZGUgbGEgYm9pdGUgc2Vsb24gbGVzIGVmZmVjdGlmcyBkZSBncm91cGVzDQpgYGANCg0KYGBge3J9DQojIG9uIGZhaXQgdmFyaWVyIGxhIGNvdWxldXIgc2Vsb24gdW5lIHZhcmlhYmxlIGV0IG9uICJmbGlwIiBsZSB0b3V0DQoNCmdncGxvdChiZCwgYWVzKHggPSBzZXhlLCB5ID0gZnJlcmVzLnNvZXVycywgY29sb3IgPSBzZXhlKSkgKyBnZW9tX2JveHBsb3QoKSArIGNvb3JkX2ZsaXAoKQ0KYGBgDQoNCiMjIyAyLjUuIGdlb21fZGVuc2l0eSAtIGRlbnNpdMOpDQpgYGB7cn0NCiMgRGlzdHJpYnV0aW9uIGRlIGwnw6JnZSBzZWxvbiBsZSBzZXhlIChkZW5zaXTDqSBzdXBlcnBvc8OpZSBhdmVjIHRyYW5zcGFyZW5jZSkNCg0KZ2dwbG90KGJkLCBhZXMoeCA9IGFnZSwgY29sb3IgPSBzZXhlLCBmaWxsPXNleGUpKSArIA0KZ2VvbV9kZW5zaXR5KGFscGhhPTAuNTUpDQpgYGANCg0KPGJyPg0KDQoqKioNCg0KPC9kaXY+