Overview

This project will begin on Friday, June 5 and conclude with a 15 minute presentation one week later on Friday, June 12. Students will be paired into groups of two and randomly assigned one of 8 sports datasets. The goal of this project is to practice understanding the data structure of a dataset, generating hypothesis and using exploratory data analysis and data visualization to attempt to answer these hypothesis.

Deliverables

Each team is expected to produce slides to accompany their 15 minute presentation with the following information:

Timeline

There will be two submission deadlines:

Tuesday, June 9 @ 4:00pm EST - Each student will push their individual code for the project thus far to their GitHub accounts for review. We will then provide feedback on the code submitted.

Friday, June 12 @ 12:00pm EST - Slides and full code must be completed and ready for presentation. Send your slides to Nick’s email . All code and visualizations must be done in R, but the slides may be created in any program.

Data

EDA projects data overview

There are eight different datasets for the EDA projects:

MLB batted ball data

Each row in the top_hitters_2019_batted_balls.csv dataset corresponds to a single batted ball by one of the top five hitters in the 2019 MLB season: Mike Trout, Christian Yelich, Cody Bellinger, Josh Bell, or Joey Gallo. Each batted ball contains the following information:

  • hit_x, hit_y - the x,y coordinates for each batted ball,
  • exit_velocity - speed (miles per hour) off the bat that the ball was hit,
  • launch_angle - angle (in degrees) off the bat that the ball was hit where 0 means parallel to the field, so positive means in the air and negative means towards the ground,
  • batted_ball_type - categorical label for type of batted ball, either fly_ball, ground_ball, line_drive, or popup,
  • outcome - categorical event denoting the outcome of the batted ball. The following are positive events from the perspective of the batter Christian Yelich: single, double, triple, home_run, sac_fly, and field_error. The following are negative events from his perspective: douple_play, field_out, fielders_choice_out, force_out, and grounded_into_double_play,
  • pitch_type - two letter abbreviation denoting the type of pitch that was thrown,
  • player - last name of hitter: either trout, yelich, bellinger, bell, or gallo.
  • batter_stand - handedness of hitter, either L (left) or R (right), note that Josh Bell is the only switch hitter in this data (i.e. switches between L and R depending on the pitcher),
  • hit_distance - recorded distance in feet that the ball traveled.

The two letter pitch_type abbreviations represent the following types of pitches that can be summarized by two groups, (1) fastballs:

  • FF - four-seam fastball (most common pitch in baseball),
  • FT - two-seam fastball (more movement than FF),
  • FC - cutter (look up Mariano Rivera),
  • FS, SI, or SF = sinker / split-fingered,

and (2) offspeed pitches:

  • SL - slider,
  • CH - changeup,
  • CB or CU - curveball,
  • KC - knuckle-curve,
  • KN - knuckleball,
  • EP - eephus.

Note that the batted ball data may not contain all of the different pitch types. The list above is just a comprehensive one if someone wants to look at more pitch-level data from the MLB. This data is in the same format as the Trout batted ball data example.

NFL team season summary data

Each row in the nfl_teams_season_summary.csv dataset corresponds to a single NFL team in a single regular season. The column names are organized below by the type of information they contain, with the first set of columns being self-explanatory:

  • meta - team (three letter abbreviation), season, division,
  • season outcomes - points_scored, points_allowed, wins, losses, ties.

The remaining columns correspond to offensive and defensive summaries of the team’s performance in the season separated by pass and run plays. We have the following offensive passing statistics:

  • pass_off_epa_per_att = expected points added (EPA) per pass attempt on offense,
  • pass_off_total_epa = total EPA from passing plays on offense
  • pass_off_total_yards_gained = total yards gained from passing plays on offense,
  • pass_off_yards_gained_per_att = yards per pass attempt on offense.

The remaining columns (e.g. run_off_epa_per_att, pass_def_epa_per_att, etc) convey the same statistics but switching the type of play: either pass_ or run_, and displaying offensive (_off_) versus the team’s defensive (_def_) statistics.

The EPA variables are advanced NFL statistics, conveying how much value a team is adding over the average team in a given situation. It’s on a points scale instead of the typically used yards, because not all yards are created equal in American football (10 yard gain on 3rd and 15 is much less valuable than a 2 yard gain on 4th and 1). For offensive stats the higher the EPA the better, but for defensive stats the lower (more negative) the EPA the better.

WNBA Championship game 5

Each row in the wnba_championship_game_five.csv dataset corresponds to an event taking place during game 5 of the WNBA Finals on October 10, 2019, between the Washington Mystics and Connecticut Sun. Each event contains the following information:

  • period - period of WNBA game in which event took place,
  • clock - time remaining in period, in MM:SS format (M = minutes, S = seconds),
  • was_score, con_score - score for the Washington Mystics (was) and Connecticut Sun (con) respectively,
  • description - a full string description of the event,
  • team - abbreviation (either was or con) of the team with the event (eg the team taking the shot),
  • event - the type of event, either: field_goal_attempt, free_throw_attempt, rebound, foul, or turnover
  • x_loc, y_loc - the x,y coordinates for each event where x_loc denotes the left to right location of the event with respect to the hoop (0, 0) and y_loc denotes the vertical location of the event. All event locations represent approaching the same direction. Free throw attempt coordinates are not correct, and rebound coordinates correlate to the shot location instead of the location of the rebound,
  • field_goal_type - categorical label of shot, either two_pointer or three_pointer,
  • shot_made - binary indicator denoting whether the shot was made (1) or not (0),
  • assisted - binary indicator denoting whether the made field goal was assisted (1) or not (0),
  • shooting_foul - binary indicator denoting whether or not a shooting foul occurred (1) or not (0),
  • distance_from_hoop - distance in feet from hoop that the event took place,
  • shot_angle - the angle from the hoop that the event took place,
  • shot_type - one of jump, layup, or hook

Age of Empires 2: Definitive Edition ranked 1v1 & team game leaderboard

Each row in the aoe2_leaderboard_sample.csv dataset corresponds to a single Aoe2: DE ranked player. Individual players will have up to two total rows if they have a Team and 1v1 ranking. 10 games played per format is the only requirement to earn an offical ranking. The column names are organized below by order in which they appear in the data set.

  • profile_id - unique numeric key for each player account,
  • name - player username,
  • rank - player ranking on either 1v1 or Team leaderboard,
  • rating - player’s current numeric rating. Similar to a chess ELO,
  • country - nation player account is registered under. Uses alpha-2 nation codes. Full list here,
  • games - total number of games played,
  • wins - games won,
  • losses - games lost, includes games dropped,
  • drops - games were a player has disconnected and received an automatic loss,
  • game_type - Either 1v1 or Teams, the leaderboards for each are separate.

Team ratings and 1v1 rating are ranked separetely, and so it is possible to have a higher rating and a lower ranking if comparing 1v1 ranking against Team ranking.

NTT Data IndyCar 2019 season race results

Each row in the indycar_2019.csv dataset corresponds to a single race entry (driver-team-race combination) in the 2019 NTT Data IndyCar Series season. The season consisted of 17 races and was contested between 36 total drivers. Each driver race entry contains the following information:

  • date - the date the race occured,
  • race_id - the name of the particular race,
  • start - what position the driver started in,
  • finish - what position the driver finished the race in,
  • points - championship points earned in the event. Indianapolis 500 & the Grand Prix of Monterey were double points races,
  • drive_id - the name of the driver,
  • team_id - the name of the team entry / team owner,
  • track_type - what type of track the race was run at,
  • chassis_engine_tires - the combination of chassis, engine and tire brand the car was entered with.

Notes on the final two variables:

  • track_type - P refers to oval circuits, S refers to temporary street circuits, and R refers to permanent road courses
  • chassis_engine_tires - all entries use a Dallara chassis and Firestone tires. The only difference is the engine. ‘D/C/F’ refers to Dallara-Chevrolet-Firestone, while ‘D/H/F’ refers to Dallara-Honda-Firestone

NWSL player season statistics 2017-2019

Each row in the nwsl_season_stats.csv dataset corresponds to one field player-season-team statistics. Players who changed teams in the middle of a season will have one row per team played for in that season. The data set contains data for all field players who participated in at least one match from 2017 to 2019. The columns are as follows:

  • player_id - unique numeric key identifying player,
  • name - player first and last name,
  • season - the season which the statistics refer to,
  • team_id - three character abbreviation of the player’s team,
  • nation - three character abbreviation for the player’s’ nationality,
  • pos - the players position,
  • matches - matches played,
  • starts - matches in which the player was in the starting 11,
  • minutes - total minutes played,
  • goals - goals scored,
  • assists - assists earned,
  • yellow_cards - yellow cards earned,
  • red_cards - red cards earned.

Players can play multiple positions throughout a season. The abbreviations for the pos variable mean the following:

  • FW - forward (or striker)
  • MF - midfielder
  • DF - defender

T20 women’s cricket career bowling statistics

Each row in the womens_cricket_bowling.csv dataset corresponds to one active players career bowling statistics for T20 cricket. T20, or Twenty20 cricket, restricts innings to a maximum of 20 overs to shorten game length. The column definitions are as follows:

  • player - player name,
  • country - player nationality,
  • start - players first season,
  • end - players most recent season. All players last played in either 2019 or 2020,
  • matches - matches played,
  • innings - total innings bowled,
  • overs - the number of overs bowled. An over consists of six consecutive balls bowled,
  • maidens - the number of maiden overs, which is an over in which the bowler conceded zero runs,
  • runs - the number of runs conceded,
  • wickets - the number of wickets taken,
  • average - the average number of runs conceded per wicket taken,
  • economy - the average number of runs conceded per over,
  • strike_rate - the average number of balls bowled per wicket taken.

NHL 2015-16 Stanley Cup Final game 6 play by play

Each row in the nhl_pit_sj_game6.csv data set corresponds to a single event during game 6 of the 2015-16 Stanley Cup Final, played on June 12, 2016. Events include shots, hits, penalties, turnovers, faceoffs and stoppages. The column definitions are as follows:

  • period - game period,
  • period_time - time within period, counting up from 0:00 to 20:00,
  • event - the class of event the row describes. possible values include: period_end, period_start, goal, shot, blocked_shot, missed_shot, giveaway, takeaway, stoppage, faceoff, hit,
  • team - the team the event corresponds to
  • description - a brief description of the event
  • player_one - this column has different meanings depending on the event, it is as follows:

    • event = goal, shot, blocked_shot, or missed_shot - player_one refers to the shooter of the puck,
    • event = hit - player_one refers to the player who did the hitting,
    • event = takeaway or giveaway - player_one refers to the player who committed the giveaway or takeaway
    • event = faceoff - player_one refers to the player who won the faceoff
    • event = penalty - player_one refers to the player who committed the penalty,
    • event = anything else - player_one is NA
  • player_two - this column has different meanings depending on the event, it is as follows:

    • event = hit - player_two refers to the player who was hit,
    • event = faceoff - player_two refers to the player who lost the faceoff,
    • event = penalty - player_two refers to the player who drew the penalty,
    • event = blocked_shot - player_two refers to the player who blocked the shot,
    • event = anything else - player_two is NA
  • event_type - refers to the type of penalty, type of shot attempt (except for missed shots). Is NA otherwise,
  • x_cord, y_cord - the x,y coordinates for each event where x_cord denotes the left to right location of the event with respect to the center ice (0, 0) and y_cord denotes the vertical location of the event. The net is located at (89, 0), and all event locations represent approaching the same direction,
  • empty_net - TRUE if a goal was scored with the net empty, FALSE if a goal was scored on a goaltender. NA if not a goal event,
  • pit_score - the Pittsburgh Penguins score at the time of the event,
  • sjs_score - the San Jose Sharks score at the time of the event,
  • shot_attempt - 1 if the event constitues an attempted shot on goal, 0 otherwise.

LS0tCnRpdGxlOiAiRURBIFByb2plY3QgUmVxdWlyZW1lbnRzIGFuZCBEYXRhIgpvdXRwdXQ6IGh0bWxfZG9jdW1lbnQKLS0tCgpgYGB7ciwgZWNobyA9IEZBTFNFfQpvcHRpb25zKHRpbnl0ZXgudmVyYm9zZSA9IFRSVUUpCgpgYGAKCiMjIyBPdmVydmlldwoKVGhpcyBwcm9qZWN0IHdpbGwgYmVnaW4gb24gRnJpZGF5LCBKdW5lIDUgYW5kIGNvbmNsdWRlIHdpdGggYSAxNSBtaW51dGUgcHJlc2VudGF0aW9uIG9uZSB3ZWVrIGxhdGVyIG9uIEZyaWRheSwgSnVuZSAxMi4gIFN0dWRlbnRzIHdpbGwgYmUgcGFpcmVkIGludG8gZ3JvdXBzIG9mIHR3byBhbmQgcmFuZG9tbHkgYXNzaWduZWQgb25lIG9mIDggc3BvcnRzIGRhdGFzZXRzLiBUaGUgZ29hbCBvZiB0aGlzIHByb2plY3QgaXMgdG8gcHJhY3RpY2UgdW5kZXJzdGFuZGluZyB0aGUgZGF0YSBzdHJ1Y3R1cmUgb2YgYSBkYXRhc2V0LCBnZW5lcmF0aW5nIGh5cG90aGVzaXMgYW5kIHVzaW5nIGV4cGxvcmF0b3J5IGRhdGEgYW5hbHlzaXMgYW5kIGRhdGEgdmlzdWFsaXphdGlvbiB0byBhdHRlbXB0IHRvIGFuc3dlciB0aGVzZSBoeXBvdGhlc2lzLgoKIyMjIERlbGl2ZXJhYmxlcwoKRWFjaCB0ZWFtIGlzIGV4cGVjdGVkIHRvIHByb2R1Y2Ugc2xpZGVzIHRvIGFjY29tcGFueSB0aGVpciAxNSBtaW51dGUgcHJlc2VudGF0aW9uIHdpdGggdGhlIGZvbGxvd2luZyBpbmZvcm1hdGlvbjoKCiogRXhwbGFuYXRpb24gb2YgdGhlIGRhdGEgc3RydWN0dXJlIG9mIHRoZSBkYXRhc2V0CiogVGhyZWUgaHlwb3RoZXNlcyBhYm91dCB0aGUgZGF0YXNldAoqIFRocmVlIGRhdGEgdmlzdWFsaXphdGlvbnMgZXhwbG9yaW5nIHRoZSBoeXBvdGhlc2lzLCBhdCBsZWFzdCB0d28gb2Ygd2hpY2ggbXVzdCBiZSBtdWx0aXZhcmlhdGUuICBFYWNoIHZpc3VhbGl6YXRpb24gbXVzdCBiZSBpbiBhIGRpZmZlcmVudCBmb3JtYXQgZnJvbSB0aGUgb3RoZXIgdHdvLCBhbmQgeW91IG11c3QgaGF2ZSBhdCBsZWFzdCBvbmUgY2F0ZWdvcmljYWwgYW5kIG9uZSBjb250aW51b3VzIHZpc3VhbGl6YXRpb24uCiogT25lIGNsdXN0ZXJpbmcgZXhhbXBsZQoqIENvbmNsdXNpb25zIHJlYWNoZWQgZm9yIHRoZSBoeXBvdGhlc2lzIHVzaW5nIHRoZSBkYXRhIHZpc3VhbGl6YXRpb25zCgojIyMgVGltZWxpbmUKClRoZXJlIHdpbGwgYmUgdHdvIHN1Ym1pc3Npb24gZGVhZGxpbmVzOgoKKipUdWVzZGF5LCBKdW5lIDkgQCA0OjAwcG0gRVNUKiogLSBFYWNoIHN0dWRlbnQgd2lsbCBwdXNoIHRoZWlyIGluZGl2aWR1YWwgY29kZSBmb3IgdGhlIHByb2plY3QgdGh1cyBmYXIgdG8gdGhlaXIgR2l0SHViIGFjY291bnRzIGZvciByZXZpZXcuIFdlIHdpbGwgdGhlbiBwcm92aWRlIGZlZWRiYWNrIG9uIHRoZSBjb2RlIHN1Ym1pdHRlZC4KCioqRnJpZGF5LCBKdW5lIDEyIEAgMTI6MDBwbSBFU1QqKiAtIFNsaWRlcyBhbmQgZnVsbCBjb2RlIG11c3QgYmUgY29tcGxldGVkIGFuZCByZWFkeSBmb3IgcHJlc2VudGF0aW9uLiAgU2VuZCB5b3VyIHNsaWRlcyB0byBOaWNrJ3MgZW1haWwgbmNpdHJvbmVAcGl0dHNidXJnaHBlbmd1aW5zLmNvbSAuICBBbGwgY29kZSBhbmQgdmlzdWFsaXphdGlvbnMgbXVzdCBiZSBkb25lIGluIGBSYCwgYnV0IHRoZSBzbGlkZXMgbWF5IGJlIGNyZWF0ZWQgaW4gYW55IHByb2dyYW0uCgojIyBEYXRhCgojIyMgRURBIHByb2plY3RzIGRhdGEgb3ZlcnZpZXcKClRoZXJlIGFyZSBlaWdodCBkaWZmZXJlbnQgZGF0YXNldHMgZm9yIHRoZSBFREEgcHJvamVjdHM6CiAgCi0gW3RvcF9oaXR0ZXJzXzIwMTlfYmF0dGVkX2JhbGxzLmNzdl0oaHR0cDovL3d3dy5zdGF0LmNtdS5lZHUvY21zYWMvc3VyZS9tYXRlcmlhbHMvZGF0YS9lZGFfcHJvamVjdHMvdG9wX2hpdHRlcnNfMjAxOV9iYXR0ZWRfYmFsbHMuY3N2KSAtIGxvY2F0aW9uIG9mIGFsbCBiYXR0ZWQgYmFsbHMgYnkgZml2ZSBvZiB0aGUgYmVzdCBoaXR0ZXJzIGluIHRoZSAyMDE5IE1MQiBzZWFzb24uIERhdGEgZ2VuZXJhdGVkIGJ5IE1MQkFNIFN0YXRjYXN0IGFuZCBhY2Nlc3NlZCBjb3VydGVzeSBvZiBbYmFzZWJhbGwtc2F2YW50XShodHRwczovL2Jhc2ViYWxsc2F2YW50Lm1sYi5jb20vKSB2aWEgdGhlIFtgYmFzZWJhbGxyYCBwYWNrYWdlXShodHRwOi8vYmlsbHBldHRpLmdpdGh1Yi5pby9iYXNlYmFsbHIvKSwKLSBbbmZsX3RlYW1zX3NlYXNvbl9zdW1tYXJ5LmNzdl0oaHR0cDovL3d3dy5zdGF0LmNtdS5lZHUvY21zYWMvc3VyZS9tYXRlcmlhbHMvZGF0YS9lZGFfcHJvamVjdHMvbmZsX3RlYW1zX3NlYXNvbl9zdW1tYXJ5LmNzdikgLSBzdW1tYXJ5IG9mIHJlZ3VsYXIgc2Vhc29uIHBlcmZvcm1hbmNlIGZvciBlYWNoIE5GTCB0ZWFtIHNpbmNlIDIwMDksIGRhdGEgYWNjZXNzZWQgdmlhIFtgbmZsc2NyYXBSYF0oaHR0cHM6Ly9naXRodWIuY29tL21ha3NpbWhvcm93aXR6L25mbHNjcmFwUiksCi0gW3duYmFfY2hhbXBpb25zaGlwX2dhbWVfZml2ZS5jc3ZdKGh0dHA6Ly93d3cuc3RhdC5jbXUuZWR1L2Ntc2FjL3N1cmUvbWF0ZXJpYWxzL2RhdGEvZWRhX3Byb2plY3RzL3duYmFfY2hhbXBpb25zaGlwX2dhbWVfZml2ZS5jc3YpIC0gYWxsIHNob3QgYW5kIHR1cm5vdmVyIGxvY2F0aW9ucywgYXMgd2VsbCBhcyByZWJvdW5kcyBhbmQgZnJlZSB0aHJvd3MsIGZyb20gZ2FtZSA1IG9mIHRoZSAyMDE5IFdOQkEgRmluYWxzIG9uIE9jdG9iZXIgMTAsIDIwMTksIGNvdXJ0ZXN5IG9mIFtXTkJBIHN0YXRzXShodHRwczovL3N0YXRzLnduYmEuY29tLykgdmlhIHRoZSBbYHB5X2JhbGxgIHBhY2thZ2VdKGh0dHBzOi8vZ2l0aHViLmNvbS9iYXNrZXRiYWxscmVsYXRpdml0eS9weV9iYWxsKSwKLSBbYW9lMl9sZWFkZXJib2FyZF9zYW1wbGUuY3N2XShodHRwOi8vd3d3LnN0YXQuY211LmVkdS9jbXNhYy9zdXJlL21hdGVyaWFscy9kYXRhL2VkYV9wcm9qZWN0cy9hb2UyX2xlYWRlcmJvYXJkX3NhbXBsZS5jc3YpIC0gc2FtcGxlIG9mIEFnZSBvZiBFbXBpcmVzIDI6IERlZmluaXRpdmUgRWRpdGlvbiBSYW5rZWQgMXYxIGFuZCBUZWFtIEdhbWUgbGVhZGVyYm9hcmRzLiAgRGF0YSBhY2Nlc3NlZCB1c2luZyB0aGUgW0FvZTIubmV0XShodHRwczovL2FvZTIubmV0LykgQVBJLgotIFtpbmR5Y2FyXzIwMTkuY3N2XShodHRwOi8vd3d3LnN0YXQuY211LmVkdS9jbXNhYy9zdXJlL21hdGVyaWFscy9kYXRhL2VkYV9wcm9qZWN0cy9pbmR5Y2FyXzIwMTkuY3N2KSAtIENvbXBsZXRlIHJhY2UgcmVzdWx0cyBmb3IgdGhlIDIwMTkgTlRUIERhdGEgSW5keUNhciBTZXJpZXMgc2Vhc29uLiAgRGF0YSBhY3F1aXJlZCBmcm9tIFtyYWNpbmctcmVmZXJlbmNlLmluZm9dKGh0dHBzOi8vd3d3LnJhY2luZy1yZWZlcmVuY2UuaW5mbykKLSBbbndzbF9zZWFzb25fc3RhdHMuY3N2XShodHRwOi8vd3d3LnN0YXQuY211LmVkdS9jbXNhYy9zdXJlL21hdGVyaWFscy9kYXRhL2VkYV9wcm9qZWN0cy9ud3NsX3NlYXNvbl9zdGF0cy5jc3YpIC0gTmF0aW9uYWwgV29tZW5zIFNvY2NlciBMZWFndWUgKE5XU0wpIDIwMTctMjAxOSBmaWVsZCBwbGF5ZXIgc2Vhc29uIHN0YXRpc3RpY3MuICBEYXRhIGFjY2Vzc2VkIHZpYSB0aGUgW2Bud3NsUmAgcGFja2FnZV0oaHR0cHM6Ly9naXRodWIuY29tL2Fkcm9yMS9ud3NsUiksCi0gW3dvbWVuc19jcmlja2V0X2Jvd2xpbmcuY3N2XShodHRwOi8vd3d3LnN0YXQuY211LmVkdS9jbXNhYy9zdXJlL21hdGVyaWFscy9kYXRhL2VkYV9wcm9qZWN0cy93b21lbnNfY3JpY2tldF9ib3dsaW5nLmNzdikgLSBXb21lbidzIENyaWNrZXQgY2FyZWVyIFQyMCBib3dsaW5nIHN0YXRpc3RpY3MgZm9yIGFsbCBhY3RpdmUgcGxheWVycywgZGF0YSBhY2Nlc2VkIHZpYSB0aGUgW2Bjcmlja2V0ZGF0YWAgcGFja2FnZV0oaHR0cHM6Ly9kb2NzLnJvcGVuc2NpLm9yZy9jcmlja2V0ZGF0YS8pLAotIFtuaGxfcGl0X3NqX2dhbWU2LmNzdl0oaHR0cDovL3d3dy5zdGF0LmNtdS5lZHUvY21zYWMvc3VyZS9tYXRlcmlhbHMvZGF0YS9lZGFfcHJvamVjdHMvbmhsX3BpdF9zal9nYW1lNi5jc3YpIC0gTkhMIHBsYXkgYnkgcGxheSBkYXRhIGZvciBnYW1lIDYgb2YgdGhlIDIwMTUtMTYgU3RhbmxleSBDdXAgRmluYWwgYmV0d2VlbiB0aGUgUGl0dHNidXJnaCBQZW5ndWlucyBhbmQgU2FuIEpvc2UgU2hhcmtzLiAgRGF0YSBhY2Nlc2VkIHZpYSB0aGUgW2BuaGxhcGlgIHBhY2thZ2VdKGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy9uaGxhcGkvaW5kZXguaHRtbCkuCgoKIyMjIE1MQiBiYXR0ZWQgYmFsbCBkYXRhCgpFYWNoIHJvdyBpbiB0aGUgW3RvcF9oaXR0ZXJzXzIwMTlfYmF0dGVkX2JhbGxzLmNzdl0oaHR0cDovL3d3dy5zdGF0LmNtdS5lZHUvY21zYWMvc3VyZS9tYXRlcmlhbHMvZGF0YS9lZGFfcHJvamVjdHMvdG9wX2hpdHRlcnNfMjAxOV9iYXR0ZWRfYmFsbHMuY3N2KSBkYXRhc2V0IGNvcnJlc3BvbmRzIHRvIGEgCnNpbmdsZSBiYXR0ZWQgYmFsbCBieSBvbmUgb2YgdGhlIHRvcCBmaXZlIGhpdHRlcnMgaW4gdGhlIDIwMTkgTUxCIHNlYXNvbjogTWlrZSBUcm91dCwgQ2hyaXN0aWFuIFllbGljaCwgQ29keSBCZWxsaW5nZXIsIEpvc2ggQmVsbCwgb3IgSm9leSBHYWxsby4gRWFjaCBiYXR0ZWQgYmFsbApjb250YWlucyB0aGUgZm9sbG93aW5nIGluZm9ybWF0aW9uOgoKLSBgaGl0X3hgLCBgaGl0X3lgIC0gdGhlIHgseSBjb29yZGluYXRlcyBmb3IgZWFjaCBiYXR0ZWQgYmFsbCwKLSBgZXhpdF92ZWxvY2l0eWAgLSBzcGVlZCAobWlsZXMgcGVyIGhvdXIpIG9mZiB0aGUgYmF0IHRoYXQgdGhlIGJhbGwgd2FzIGhpdCwKLSBgbGF1bmNoX2FuZ2xlYCAtIGFuZ2xlIChpbiBkZWdyZWVzKSBvZmYgdGhlIGJhdCB0aGF0IHRoZSBiYWxsIHdhcyBoaXQgd2hlcmUgMCBtZWFucyBwYXJhbGxlbCB0byB0aGUgZmllbGQsIHNvIHBvc2l0aXZlIG1lYW5zIGluIHRoZSBhaXIgYW5kIG5lZ2F0aXZlIG1lYW5zIHRvd2FyZHMgdGhlIGdyb3VuZCwKLSBgYmF0dGVkX2JhbGxfdHlwZWAgLSBjYXRlZ29yaWNhbCBsYWJlbCBmb3IgdHlwZSBvZiBiYXR0ZWQgYmFsbCwgZWl0aGVyIGBmbHlfYmFsbGAsIGBncm91bmRfYmFsbGAsIGBsaW5lX2RyaXZlYCwgb3IgYHBvcHVwYCwKLSBgb3V0Y29tZWAgLSBjYXRlZ29yaWNhbCBldmVudCBkZW5vdGluZyB0aGUgb3V0Y29tZSBvZiB0aGUgYmF0dGVkIGJhbGwuIFRoZSBmb2xsb3dpbmcgYXJlIF9fcG9zaXRpdmVfXyBldmVudHMgZnJvbSB0aGUgcGVyc3BlY3RpdmUgb2YgdGhlIGJhdHRlciBDaHJpc3RpYW4gWWVsaWNoOiBgc2luZ2xlYCwgYGRvdWJsZWAsIGB0cmlwbGVgLCBgaG9tZV9ydW5gLCBgc2FjX2ZseWAsIGFuZCBgZmllbGRfZXJyb3JgLiBUaGUgZm9sbG93aW5nIGFyZSBfX25lZ2F0aXZlX18gZXZlbnRzIGZyb20gaGlzIHBlcnNwZWN0aXZlOiBgZG91cGxlX3BsYXlgLCBgZmllbGRfb3V0YCwgYGZpZWxkZXJzX2Nob2ljZV9vdXRgLCBgZm9yY2Vfb3V0YCwgYW5kIGBncm91bmRlZF9pbnRvX2RvdWJsZV9wbGF5YCwKLSBgcGl0Y2hfdHlwZWAgLSB0d28gbGV0dGVyIGFiYnJldmlhdGlvbiBkZW5vdGluZyB0aGUgdHlwZSBvZiBwaXRjaCB0aGF0IHdhcyB0aHJvd24sCi0gYHBsYXllcmAgLSBsYXN0IG5hbWUgb2YgaGl0dGVyOiBlaXRoZXIgYHRyb3V0YCwgYHllbGljaGAsIGBiZWxsaW5nZXJgLCBgYmVsbGAsIG9yIGBnYWxsb2AuCi0gYGJhdHRlcl9zdGFuZGAgLSBoYW5kZWRuZXNzIG9mIGhpdHRlciwgZWl0aGVyIGBMYCAobGVmdCkgb3IgYFJgIChyaWdodCksIG5vdGUgdGhhdCBKb3NoIEJlbGwgaXMgdGhlIG9ubHkgc3dpdGNoIGhpdHRlciBpbiB0aGlzIGRhdGEgKGkuZS4gc3dpdGNoZXMgYmV0d2VlbiBgTGAgYW5kIGBSYCBkZXBlbmRpbmcgb24gdGhlIHBpdGNoZXIpLAotIGBoaXRfZGlzdGFuY2VgIC0gcmVjb3JkZWQgZGlzdGFuY2UgaW4gZmVldCB0aGF0IHRoZSBiYWxsIHRyYXZlbGVkLgoKVGhlIHR3byBsZXR0ZXIgYHBpdGNoX3R5cGVgIGFiYnJldmlhdGlvbnMgcmVwcmVzZW50IHRoZSBmb2xsb3dpbmcgdHlwZXMgb2YgcGl0Y2hlcwp0aGF0IGNhbiBiZSBzdW1tYXJpemVkIGJ5IHR3byBncm91cHMsICgxKSBfX2Zhc3RiYWxsc19fOgoKLSBgRkZgIC0gZm91ci1zZWFtIGZhc3RiYWxsIChtb3N0IGNvbW1vbiBwaXRjaCBpbiBiYXNlYmFsbCksCi0gYEZUYCAtIHR3by1zZWFtIGZhc3RiYWxsIChtb3JlIG1vdmVtZW50IHRoYW4gYEZGYCksCi0gYEZDYCAtIGN1dHRlciAobG9vayB1cCBbTWFyaWFubyBSaXZlcmFdKGh0dHBzOi8vYmxlYWNoZXJyZXBvcnQuY29tL2FydGljbGVzLzE3MzczOTYtdmlzdWFsLWJyZWFrZG93bi1vZi10aGUtcmlzZS1kb21pbmFuY2Utb2YtbWFyaWFuby1yaXZlcmFzLWN1dHRlcikpLAotIGBGU2AsIGBTSWAsIG9yIGBTRmAgPSBzaW5rZXIgLyBzcGxpdC1maW5nZXJlZCwKCmFuZCAoMikgX19vZmZzcGVlZCBwaXRjaGVzX186CgotIGBTTGAgLSBzbGlkZXIsCi0gYENIYCAtIGNoYW5nZXVwLAotIGBDQmAgb3IgYENVYCAtIGN1cnZlYmFsbCwKLSBgS0NgIC0ga251Y2tsZS1jdXJ2ZSwKLSBgS05gIC0ga251Y2tsZWJhbGwsCi0gYEVQYCAtIGVlcGh1cy4KCk5vdGUgdGhhdCB0aGUgYmF0dGVkIGJhbGwgZGF0YSBtYXkgbm90IGNvbnRhaW4gYWxsIG9mIHRoZSBkaWZmZXJlbnQgcGl0Y2ggdHlwZXMuIFRoZSBsaXN0IGFib3ZlIGlzIGp1c3QgYSBjb21wcmVoZW5zaXZlIG9uZSBpZiBzb21lb25lIHdhbnRzIHRvIGxvb2sgYXQgbW9yZSBwaXRjaC1sZXZlbCBkYXRhIGZyb20gdGhlIE1MQi4gVGhpcyBkYXRhIGlzIGluIHRoZSBzYW1lIGZvcm1hdCBhcyB0aGUgW1Ryb3V0IGJhdHRlZCBiYWxsIGRhdGEgZXhhbXBsZV0oaHR0cDovL3d3dy5zdGF0LmNtdS5lZHUvY21zYWMvc3VyZS9tYXRlcmlhbHMvZGF0YS94eV9leGFtcGxlcy90cm91dF8yMDE5X2JhdHRlZF9iYWxscy5jc3YpLgoKIyMjIE5GTCB0ZWFtIHNlYXNvbiBzdW1tYXJ5IGRhdGEKCkVhY2ggcm93IGluIHRoZSBbbmZsX3RlYW1zX3NlYXNvbl9zdW1tYXJ5LmNzdl0oaHR0cDovL3d3dy5zdGF0LmNtdS5lZHUvY21zYWMvc3VyZS9tYXRlcmlhbHMvZGF0YS9lZGFfcHJvamVjdHMvbmZsX3RlYW1zX3NlYXNvbl9zdW1tYXJ5LmNzdikgZGF0YXNldCBjb3JyZXNwb25kcyB0byBhIHNpbmdsZSBORkwgdGVhbSBpbiBhIHNpbmdsZSByZWd1bGFyIHNlYXNvbi4gVGhlIGNvbHVtbiBuYW1lcyBhcmUgb3JnYW5pemVkIGJlbG93IGJ5IHRoZSB0eXBlIG9mIGluZm9ybWF0aW9uIHRoZXkgY29udGFpbiwgd2l0aCB0aGUgZmlyc3Qgc2V0IG9mIGNvbHVtbnMgYmVpbmcgc2VsZi1leHBsYW5hdG9yeToKCi0gbWV0YSAtIGB0ZWFtYCAodGhyZWUgbGV0dGVyIGFiYnJldmlhdGlvbiksIGBzZWFzb25gLCBgZGl2aXNpb25gLAotIHNlYXNvbiBvdXRjb21lcyAtIGBwb2ludHNfc2NvcmVkYCwgYHBvaW50c19hbGxvd2VkYCwgYHdpbnNgLCBgbG9zc2VzYCwgYHRpZXNgLgoKVGhlIHJlbWFpbmluZyBjb2x1bW5zIGNvcnJlc3BvbmQgdG8gb2ZmZW5zaXZlIGFuZCBkZWZlbnNpdmUgc3VtbWFyaWVzIG9mIHRoZSB0ZWFtJ3MKcGVyZm9ybWFuY2UgaW4gdGhlIHNlYXNvbiBzZXBhcmF0ZWQgYnkgcGFzcyBhbmQgcnVuIHBsYXlzLiBXZSBoYXZlIHRoZSBmb2xsb3dpbmcKb2ZmZW5zaXZlIHBhc3Npbmcgc3RhdGlzdGljczoKICAKLSBgcGFzc19vZmZfZXBhX3Blcl9hdHRgID0gZXhwZWN0ZWQgcG9pbnRzIGFkZGVkIChFUEEpIHBlciBwYXNzIGF0dGVtcHQgb24gb2ZmZW5zZSwKLSBgcGFzc19vZmZfdG90YWxfZXBhYCA9IHRvdGFsIEVQQSBmcm9tIHBhc3NpbmcgcGxheXMgb24gb2ZmZW5zZQotIGBwYXNzX29mZl90b3RhbF95YXJkc19nYWluZWRgID0gdG90YWwgeWFyZHMgZ2FpbmVkIGZyb20gcGFzc2luZyBwbGF5cyBvbiBvZmZlbnNlLAotIGBwYXNzX29mZl95YXJkc19nYWluZWRfcGVyX2F0dGAgPSB5YXJkcyBwZXIgcGFzcyBhdHRlbXB0IG9uIG9mZmVuc2UuCgpUaGUgcmVtYWluaW5nIGNvbHVtbnMgKGUuZy4gYHJ1bl9vZmZfZXBhX3Blcl9hdHRgLCBgcGFzc19kZWZfZXBhX3Blcl9hdHRgLCBldGMpIGNvbnZleQp0aGUgc2FtZSBzdGF0aXN0aWNzIGJ1dCBzd2l0Y2hpbmcgdGhlIHR5cGUgb2YgcGxheTogZWl0aGVyIGBwYXNzX2Agb3IgYHJ1bl9gLCBhbmQKZGlzcGxheWluZyBvZmZlbnNpdmUgKGBfb2ZmX2ApIHZlcnN1cyB0aGUgdGVhbSdzIGRlZmVuc2l2ZSAoYF9kZWZfYCkgc3RhdGlzdGljcy4KClRoZSBFUEEgdmFyaWFibGVzIGFyZSBfYWR2YW5jZWRfIE5GTCBzdGF0aXN0aWNzLCBjb252ZXlpbmcgaG93IG11Y2ggdmFsdWUgYSB0ZWFtIGlzCmFkZGluZyBvdmVyIHRoZSBhdmVyYWdlIHRlYW0gaW4gYSBnaXZlbiBzaXR1YXRpb24uIEl0J3Mgb24gYSBwb2ludHMgc2NhbGUgaW5zdGVhZApvZiB0aGUgdHlwaWNhbGx5IHVzZWQgeWFyZHMsIGJlY2F1c2Ugbm90IGFsbCB5YXJkcyBhcmUgY3JlYXRlZCBlcXVhbCBpbiBBbWVyaWNhbiBmb290YmFsbAooMTAgeWFyZCBnYWluIG9uIDNyZCBhbmQgMTUgaXMgbXVjaCBsZXNzIHZhbHVhYmxlIHRoYW4gYSAyIHlhcmQgZ2FpbiBvbiA0dGggYW5kIDEpLgpfX0ZvciBvZmZlbnNpdmUgc3RhdHMgdGhlIGhpZ2hlciB0aGUgRVBBIHRoZSBiZXR0ZXIsIGJ1dCBmb3IgZGVmZW5zaXZlIHN0YXRzIHRoZQpsb3dlciAobW9yZSBuZWdhdGl2ZSkgdGhlIEVQQSB0aGUgYmV0dGVyX18uIAoKIyMjIFdOQkEgQ2hhbXBpb25zaGlwIGdhbWUgNQoKRWFjaCByb3cgaW4gdGhlIFt3bmJhX2NoYW1waW9uc2hpcF9nYW1lX2ZpdmUuY3N2XShodHRwOi8vd3d3LnN0YXQuY211LmVkdS9jbXNhYy9zdXJlL21hdGVyaWFscy9kYXRhL2VkYV9wcm9qZWN0cy93bmJhX2NoYW1waW9uc2hpcF9nYW1lX2ZpdmUuY3N2KSBkYXRhc2V0IGNvcnJlc3BvbmRzIHRvIGFuIGV2ZW50IHRha2luZyBwbGFjZSBkdXJpbmcgW2dhbWUgNSBvZiB0aGUgV05CQSBGaW5hbHMgb24gT2N0b2JlciAxMCwgMjAxOV0oaHR0cHM6Ly9zdGF0cy53bmJhLmNvbS9nYW1lLzEwNDE5MDA0MDUvKSwgYmV0d2VlbiB0aGUgV2FzaGluZ3RvbiBNeXN0aWNzIGFuZCBDb25uZWN0aWN1dCBTdW4uIEVhY2ggZXZlbnQgY29udGFpbnMgdGhlIGZvbGxvd2luZyBpbmZvcm1hdGlvbjoKICAKLSBgcGVyaW9kYCAtIHBlcmlvZCBvZiBXTkJBIGdhbWUgaW4gd2hpY2ggZXZlbnQgdG9vayBwbGFjZSwgCi0gYGNsb2NrYCAtIHRpbWUgcmVtYWluaW5nIGluIGBwZXJpb2RgLCBpbiBNTTpTUyBmb3JtYXQgKE0gPSBtaW51dGVzLCBTID0gc2Vjb25kcyksCi0gYHdhc19zY29yZWAsIGBjb25fc2NvcmVgIC0gc2NvcmUgZm9yIHRoZSBXYXNoaW5ndG9uIE15c3RpY3MgKHdhcykgYW5kIENvbm5lY3RpY3V0IFN1biAoY29uKSByZXNwZWN0aXZlbHksCi0gYGRlc2NyaXB0aW9uYCAtIGEgZnVsbCBzdHJpbmcgZGVzY3JpcHRpb24gb2YgdGhlIGV2ZW50LAotIGB0ZWFtYCAtIGFiYnJldmlhdGlvbiAoZWl0aGVyIGB3YXNgIG9yIGBjb25gKSBvZiB0aGUgdGVhbSB3aXRoIHRoZSBldmVudCAoZWcgdGhlIHRlYW0gdGFraW5nIHRoZSBzaG90KSwKKiBgZXZlbnRgIC0gdGhlIHR5cGUgb2YgZXZlbnQsIGVpdGhlcjogYGZpZWxkX2dvYWxfYXR0ZW1wdGAsIGBmcmVlX3Rocm93X2F0dGVtcHRgLCBgcmVib3VuZGAsIGBmb3VsYCwgb3IgYHR1cm5vdmVyYAoqIGB4X2xvY2AsIGB5X2xvY2AgLSB0aGUgeCx5IGNvb3JkaW5hdGVzIGZvciBlYWNoIGV2ZW50IHdoZXJlIGB4X2xvY2AgZGVub3Rlcwp0aGUgbGVmdCB0byByaWdodCBsb2NhdGlvbiBvZiB0aGUgZXZlbnQgd2l0aCByZXNwZWN0IHRvIHRoZSBob29wICgwLCAwKSBhbmQgYHlfbG9jYCBkZW5vdGVzCnRoZSB2ZXJ0aWNhbCBsb2NhdGlvbiBvZiB0aGUgZXZlbnQuIEFsbCBldmVudCBsb2NhdGlvbnMgcmVwcmVzZW50IGFwcHJvYWNoaW5nIHRoZQpzYW1lIGRpcmVjdGlvbi4gIEZyZWUgdGhyb3cgYXR0ZW1wdCBjb29yZGluYXRlcyBhcmUgbm90IGNvcnJlY3QsIGFuZCByZWJvdW5kIGNvb3JkaW5hdGVzIGNvcnJlbGF0ZSB0byB0aGUgc2hvdCBsb2NhdGlvbiBpbnN0ZWFkIG9mIHRoZSBsb2NhdGlvbiBvZiB0aGUgcmVib3VuZCwKKiBgZmllbGRfZ29hbF90eXBlYCAtIGNhdGVnb3JpY2FsIGxhYmVsIG9mIHNob3QsIGVpdGhlciBgdHdvX3BvaW50ZXJgIG9yIGB0aHJlZV9wb2ludGVyYCwKKiBgc2hvdF9tYWRlYCAtIGJpbmFyeSBpbmRpY2F0b3IgZGVub3Rpbmcgd2hldGhlciB0aGUgc2hvdCB3YXMgbWFkZSAoMSkgb3Igbm90ICgwKSwKKiBgYXNzaXN0ZWRgIC0gYmluYXJ5IGluZGljYXRvciBkZW5vdGluZyB3aGV0aGVyIHRoZSBtYWRlIGZpZWxkIGdvYWwgd2FzIGFzc2lzdGVkICgxKSBvciBub3QgKDApLAoqIGBzaG9vdGluZ19mb3VsYCAtIGJpbmFyeSBpbmRpY2F0b3IgZGVub3Rpbmcgd2hldGhlciBvciBub3QgYSBzaG9vdGluZyBmb3VsIG9jY3VycmVkICgxKSBvciBub3QgKDApLAoqIGBkaXN0YW5jZV9mcm9tX2hvb3BgIC0gZGlzdGFuY2UgaW4gZmVldCBmcm9tIGhvb3AgdGhhdCB0aGUgZXZlbnQgdG9vayBwbGFjZSwKKiBgc2hvdF9hbmdsZWAgLSB0aGUgYW5nbGUgZnJvbSB0aGUgaG9vcCB0aGF0IHRoZSBldmVudCB0b29rIHBsYWNlLAoqIGBzaG90X3R5cGVgIC0gb25lIG9mIGBqdW1wYCwgYGxheXVwYCwgb3IgYGhvb2tgCgojIyMgQWdlIG9mIEVtcGlyZXMgMjogRGVmaW5pdGl2ZSBFZGl0aW9uIHJhbmtlZCAxdjEgJiB0ZWFtIGdhbWUgbGVhZGVyYm9hcmQKCkVhY2ggcm93IGluIHRoZSBbYW9lMl9sZWFkZXJib2FyZF9zYW1wbGUuY3N2XShodHRwOi8vd3d3LnN0YXQuY211LmVkdS9jbXNhYy9zdXJlL21hdGVyaWFscy9kYXRhL2VkYV9wcm9qZWN0cy9hb2UyX2xlYWRlcmJvYXJkX3NhbXBsZS5jc3YpIGRhdGFzZXQgY29ycmVzcG9uZHMgdG8gYSBzaW5nbGUgQW9lMjogREUgcmFua2VkIHBsYXllci4gSW5kaXZpZHVhbCBwbGF5ZXJzIHdpbGwgaGF2ZSB1cCB0byB0d28gdG90YWwgcm93cyBpZiB0aGV5IGhhdmUgYSBUZWFtIGFuZCAxdjEgcmFua2luZy4gIDEwIGdhbWVzIHBsYXllZCBwZXIgZm9ybWF0IGlzIHRoZSBvbmx5IHJlcXVpcmVtZW50IHRvIGVhcm4gYW4gb2ZmaWNhbCByYW5raW5nLiAgVGhlIGNvbHVtbiBuYW1lcyBhcmUgb3JnYW5pemVkIGJlbG93IGJ5IG9yZGVyIGluIHdoaWNoIHRoZXkgYXBwZWFyIGluIHRoZSBkYXRhIHNldC4KICAKKiBgcHJvZmlsZV9pZGAgLSB1bmlxdWUgbnVtZXJpYyBrZXkgZm9yIGVhY2ggcGxheWVyIGFjY291bnQsCiogYG5hbWVgIC0gcGxheWVyIHVzZXJuYW1lLAoqIGByYW5rYCAtIHBsYXllciByYW5raW5nIG9uIGVpdGhlciAxdjEgb3IgVGVhbSBsZWFkZXJib2FyZCwKKiBgcmF0aW5nYCAtIHBsYXllcidzIGN1cnJlbnQgbnVtZXJpYyByYXRpbmcuICBTaW1pbGFyIHRvIGEgY2hlc3MgRUxPLAoqIGBjb3VudHJ5YCAtIG5hdGlvbiBwbGF5ZXIgYWNjb3VudCBpcyByZWdpc3RlcmVkIHVuZGVyLiAgVXNlcyBhbHBoYS0yIG5hdGlvbiBjb2Rlcy4gIEZ1bGwgbGlzdCBbaGVyZV0oaHR0cHM6Ly93d3cubmF0aW9uc29ubGluZS5vcmcvb25ld29ybGQvY291bnRyeV9jb2RlX2xpc3QuaHRtKSwKKiBgZ2FtZXNgIC0gdG90YWwgbnVtYmVyIG9mIGdhbWVzIHBsYXllZCwKKiBgd2luc2AgLSBnYW1lcyB3b24sCiogYGxvc3Nlc2AgLSBnYW1lcyBsb3N0LCBpbmNsdWRlcyBnYW1lcyBkcm9wcGVkLAoqIGBkcm9wc2AgLSBnYW1lcyB3ZXJlIGEgcGxheWVyIGhhcyBkaXNjb25uZWN0ZWQgYW5kIHJlY2VpdmVkIGFuIGF1dG9tYXRpYyBsb3NzLAoqIGBnYW1lX3R5cGVgIC0gRWl0aGVyIDF2MSBvciBUZWFtcywgdGhlIGxlYWRlcmJvYXJkcyBmb3IgZWFjaCBhcmUgc2VwYXJhdGUuCgpUZWFtIHJhdGluZ3MgYW5kIDF2MSByYXRpbmcgYXJlIHJhbmtlZCBzZXBhcmV0ZWx5LCBhbmQgc28gaXQgaXMgcG9zc2libGUgdG8gaGF2ZSBhIGhpZ2hlciByYXRpbmcgYW5kIGEgbG93ZXIgcmFua2luZyBpZiBjb21wYXJpbmcgMXYxIHJhbmtpbmcgYWdhaW5zdCBUZWFtIHJhbmtpbmcuCgojIyMgTlRUIERhdGEgSW5keUNhciAyMDE5IHNlYXNvbiByYWNlIHJlc3VsdHMKCkVhY2ggcm93IGluIHRoZSBbaW5keWNhcl8yMDE5LmNzdl0oaHR0cDovL3d3dy5zdGF0LmNtdS5lZHUvY21zYWMvc3VyZS9tYXRlcmlhbHMvZGF0YS9lZGFfcHJvamVjdHMvaW5keWNhcl8yMDE5LmNzdikgZGF0YXNldCBjb3JyZXNwb25kcyB0byBhIHNpbmdsZSByYWNlIGVudHJ5IChkcml2ZXItdGVhbS1yYWNlIGNvbWJpbmF0aW9uKSBpbiB0aGUKMjAxOSBOVFQgRGF0YSBJbmR5Q2FyIFNlcmllcyBzZWFzb24uICBUaGUgc2Vhc29uIGNvbnNpc3RlZCBvZiAxNyByYWNlcyBhbmQgd2FzIGNvbnRlc3RlZCBiZXR3ZWVuIDM2IHRvdGFsIGRyaXZlcnMuCkVhY2ggZHJpdmVyIHJhY2UgZW50cnkgY29udGFpbnMgdGhlIGZvbGxvd2luZyBpbmZvcm1hdGlvbjoKCiogYGRhdGVgIC0gdGhlIGRhdGUgdGhlIHJhY2Ugb2NjdXJlZCwKKiBgcmFjZV9pZGAgLSB0aGUgbmFtZSBvZiB0aGUgcGFydGljdWxhciByYWNlLAoqIGBzdGFydGAgLSB3aGF0IHBvc2l0aW9uIHRoZSBkcml2ZXIgc3RhcnRlZCBpbiwKKiBgZmluaXNoYCAtIHdoYXQgcG9zaXRpb24gdGhlIGRyaXZlciBmaW5pc2hlZCB0aGUgcmFjZSBpbiwKKiBgcG9pbnRzYCAtIGNoYW1waW9uc2hpcCBwb2ludHMgZWFybmVkIGluIHRoZSBldmVudC4gIEluZGlhbmFwb2xpcyA1MDAgJiB0aGUgR3JhbmQgUHJpeCBvZiBNb250ZXJleSB3ZXJlIGRvdWJsZSBwb2ludHMgcmFjZXMsCiogYGRyaXZlX2lkYCAtIHRoZSBuYW1lIG9mIHRoZSBkcml2ZXIsCiogYHRlYW1faWRgIC0gdGhlIG5hbWUgb2YgdGhlIHRlYW0gZW50cnkgLyB0ZWFtIG93bmVyLAoqIGB0cmFja190eXBlYCAtIHdoYXQgdHlwZSBvZiB0cmFjayB0aGUgcmFjZSB3YXMgcnVuIGF0LAoqIGBjaGFzc2lzX2VuZ2luZV90aXJlc2AgLSB0aGUgY29tYmluYXRpb24gb2YgY2hhc3NpcywgZW5naW5lIGFuZCB0aXJlIGJyYW5kIHRoZSBjYXIgd2FzIGVudGVyZWQgd2l0aC4KCgpOb3RlcyBvbiB0aGUgZmluYWwgdHdvIHZhcmlhYmxlczoKCiogYHRyYWNrX3R5cGVgIC0gUCByZWZlcnMgdG8gb3ZhbCBjaXJjdWl0cywgUyByZWZlcnMgdG8gdGVtcG9yYXJ5IHN0cmVldCBjaXJjdWl0cywgYW5kIFIgcmVmZXJzIHRvIHBlcm1hbmVudCByb2FkIGNvdXJzZXMKKiBgY2hhc3Npc19lbmdpbmVfdGlyZXNgIC0gYWxsIGVudHJpZXMgdXNlIGEgRGFsbGFyYSBjaGFzc2lzIGFuZCBGaXJlc3RvbmUgdGlyZXMuICBUaGUgb25seSBkaWZmZXJlbmNlIGlzIHRoZSBlbmdpbmUuCiAgJ0QvQy9GJyByZWZlcnMgdG8gRGFsbGFyYS1DaGV2cm9sZXQtRmlyZXN0b25lLCB3aGlsZSAnRC9IL0YnIHJlZmVycyB0byBEYWxsYXJhLUhvbmRhLUZpcmVzdG9uZQogIAojIyMgTldTTCBwbGF5ZXIgc2Vhc29uIHN0YXRpc3RpY3MgMjAxNy0yMDE5CgpFYWNoIHJvdyBpbiB0aGUgW253c2xfc2Vhc29uX3N0YXRzLmNzdl0oaHR0cDovL3d3dy5zdGF0LmNtdS5lZHUvY21zYWMvc3VyZS9tYXRlcmlhbHMvZGF0YS9lZGFfcHJvamVjdHMvbndzbF9zZWFzb25fc3RhdHMuY3N2KSBkYXRhc2V0IGNvcnJlc3BvbmRzIHRvIG9uZSBmaWVsZCBwbGF5ZXItc2Vhc29uLXRlYW0gc3RhdGlzdGljcy4gUGxheWVycyB3aG8gY2hhbmdlZCB0ZWFtcyBpbiB0aGUgbWlkZGxlIG9mIGEgc2Vhc29uIHdpbGwgaGF2ZSBvbmUgcm93IHBlciB0ZWFtIHBsYXllZCBmb3IgaW4gdGhhdCBzZWFzb24uIFRoZSBkYXRhIHNldCBjb250YWlucyBkYXRhIGZvciBhbGwgZmllbGQgcGxheWVycyB3aG8gcGFydGljaXBhdGVkIGluIGF0IGxlYXN0IG9uZSBtYXRjaCBmcm9tIDIwMTcgdG8gMjAxOS4gIFRoZSBjb2x1bW5zIGFyZSBhcyBmb2xsb3dzOgoKKiBgcGxheWVyX2lkYCAtIHVuaXF1ZSBudW1lcmljIGtleSBpZGVudGlmeWluZyBwbGF5ZXIsCiogYG5hbWVgIC0gcGxheWVyIGZpcnN0IGFuZCBsYXN0IG5hbWUsCiogYHNlYXNvbmAgLSB0aGUgc2Vhc29uIHdoaWNoIHRoZSBzdGF0aXN0aWNzIHJlZmVyIHRvLAoqIGB0ZWFtX2lkYCAtIHRocmVlIGNoYXJhY3RlciBhYmJyZXZpYXRpb24gb2YgdGhlIHBsYXllcidzIHRlYW0sCiogYG5hdGlvbmAgLSB0aHJlZSBjaGFyYWN0ZXIgYWJicmV2aWF0aW9uIGZvciB0aGUgcGxheWVyJ3MnIG5hdGlvbmFsaXR5LAoqIGBwb3NgIC0gdGhlIHBsYXllcnMgcG9zaXRpb24sCiogYG1hdGNoZXNgIC0gbWF0Y2hlcyBwbGF5ZWQsCiogYHN0YXJ0c2AgLSBtYXRjaGVzIGluIHdoaWNoIHRoZSBwbGF5ZXIgd2FzIGluIHRoZSBzdGFydGluZyAxMSwKKiBgbWludXRlc2AgLSB0b3RhbCBtaW51dGVzIHBsYXllZCwKKiBgZ29hbHNgIC0gZ29hbHMgc2NvcmVkLAoqIGBhc3Npc3RzYCAtIGFzc2lzdHMgZWFybmVkLAoqIGB5ZWxsb3dfY2FyZHNgIC0geWVsbG93IGNhcmRzIGVhcm5lZCwKKiBgcmVkX2NhcmRzYCAtIHJlZCBjYXJkcyBlYXJuZWQuCgpQbGF5ZXJzIGNhbiBwbGF5IG11bHRpcGxlIHBvc2l0aW9ucyB0aHJvdWdob3V0IGEgc2Vhc29uLgpUaGUgYWJicmV2aWF0aW9ucyBmb3IgdGhlIGBwb3NgIHZhcmlhYmxlIG1lYW4gdGhlIGZvbGxvd2luZzoKCiogYEZXYCAtIGZvcndhcmQgKG9yIHN0cmlrZXIpCiogYE1GYCAtIG1pZGZpZWxkZXIKKiBgREZgIC0gZGVmZW5kZXIKCiMjIyBUMjAgd29tZW4ncyBjcmlja2V0IGNhcmVlciBib3dsaW5nIHN0YXRpc3RpY3MKCkVhY2ggcm93IGluIHRoZSBbd29tZW5zX2NyaWNrZXRfYm93bGluZy5jc3ZdKGh0dHA6Ly93d3cuc3RhdC5jbXUuZWR1L2Ntc2FjL3N1cmUvbWF0ZXJpYWxzL2RhdGEvZWRhX3Byb2plY3RzL3dvbWVuc19jcmlja2V0X2Jvd2xpbmcuY3N2KSBkYXRhc2V0IGNvcnJlc3BvbmRzIHRvIG9uZSBhY3RpdmUgcGxheWVycyBjYXJlZXIgYm93bGluZyBzdGF0aXN0aWNzIGZvciBUMjAgY3JpY2tldC4gIFQyMCwgb3IgVHdlbnR5MjAgY3JpY2tldCwgcmVzdHJpY3RzIGlubmluZ3MgdG8gYSBtYXhpbXVtIG9mIDIwIG92ZXJzIHRvIHNob3J0ZW4gZ2FtZSBsZW5ndGguICBUaGUgY29sdW1uIGRlZmluaXRpb25zIGFyZSBhcyBmb2xsb3dzOgoKKiBgcGxheWVyYCAtIHBsYXllciBuYW1lLAoqIGBjb3VudHJ5YCAtIHBsYXllciBuYXRpb25hbGl0eSwKKiBgc3RhcnRgIC0gcGxheWVycyBmaXJzdCBzZWFzb24sCiogYGVuZGAgLSBwbGF5ZXJzIG1vc3QgcmVjZW50IHNlYXNvbi4gIEFsbCBwbGF5ZXJzIGxhc3QgcGxheWVkIGluIGVpdGhlciAyMDE5IG9yIDIwMjAsCiogYG1hdGNoZXNgIC0gbWF0Y2hlcyBwbGF5ZWQsCiogYGlubmluZ3NgIC0gdG90YWwgaW5uaW5ncyBib3dsZWQsCiogYG92ZXJzYCAtIHRoZSBudW1iZXIgb2Ygb3ZlcnMgYm93bGVkLiAgQW4gb3ZlciBjb25zaXN0cyBvZiBzaXggY29uc2VjdXRpdmUgYmFsbHMgYm93bGVkLAoqIGBtYWlkZW5zYCAtIHRoZSBudW1iZXIgb2YgbWFpZGVuIG92ZXJzLCB3aGljaCBpcyBhbiBvdmVyIGluIHdoaWNoIHRoZSBib3dsZXIgY29uY2VkZWQgemVybyBydW5zLAoqIGBydW5zYCAtIHRoZSBudW1iZXIgb2YgcnVucyBjb25jZWRlZCwKKiBgd2lja2V0c2AgLSB0aGUgbnVtYmVyIG9mIHdpY2tldHMgdGFrZW4sCiogYGF2ZXJhZ2VgIC0gdGhlIGF2ZXJhZ2UgbnVtYmVyIG9mIHJ1bnMgY29uY2VkZWQgcGVyIHdpY2tldCB0YWtlbiwKKiBgZWNvbm9teWAgLSB0aGUgYXZlcmFnZSBudW1iZXIgb2YgcnVucyBjb25jZWRlZCBwZXIgb3ZlciwKKiBgc3RyaWtlX3JhdGVgIC0gdGhlIGF2ZXJhZ2UgbnVtYmVyIG9mIGJhbGxzIGJvd2xlZCBwZXIgd2lja2V0IHRha2VuLgoKIyMjIE5ITCAyMDE1LTE2IFN0YW5sZXkgQ3VwIEZpbmFsIGdhbWUgNiBwbGF5IGJ5IHBsYXkKCkVhY2ggcm93IGluIHRoZSBbbmhsX3BpdF9zal9nYW1lNi5jc3ZdKGh0dHA6Ly93d3cuc3RhdC5jbXUuZWR1L2Ntc2FjL3N1cmUvbWF0ZXJpYWxzL2RhdGEvZWRhX3Byb2plY3RzL25obF9waXRfc2pfZ2FtZTYuY3N2KSBkYXRhIHNldCBjb3JyZXNwb25kcyB0byBhIHNpbmdsZSBldmVudCBkdXJpbmcgZ2FtZSA2IG9mIHRoZSAyMDE1LTE2IFN0YW5sZXkgQ3VwIEZpbmFsLCBwbGF5ZWQgb24gSnVuZSAxMiwgMjAxNi4gIEV2ZW50cyBpbmNsdWRlIHNob3RzLCBoaXRzLCBwZW5hbHRpZXMsIHR1cm5vdmVycywgZmFjZW9mZnMgYW5kIHN0b3BwYWdlcy4gIFRoZSBjb2x1bW4gZGVmaW5pdGlvbnMgYXJlIGFzIGZvbGxvd3M6CgoqIGBwZXJpb2RgIC0gZ2FtZSBwZXJpb2QsCiogYHBlcmlvZF90aW1lYCAtIHRpbWUgd2l0aGluIHBlcmlvZCwgY291bnRpbmcgdXAgZnJvbSAwOjAwIHRvIDIwOjAwLAoqIGBldmVudGAgLSB0aGUgY2xhc3Mgb2YgZXZlbnQgdGhlIHJvdyBkZXNjcmliZXMuICBwb3NzaWJsZSB2YWx1ZXMgaW5jbHVkZToKYHBlcmlvZF9lbmRgLCBgcGVyaW9kX3N0YXJ0YCwgYGdvYWxgLCBgc2hvdGAsIGBibG9ja2VkX3Nob3RgLCBgbWlzc2VkX3Nob3RgLCBgZ2l2ZWF3YXlgLCBgdGFrZWF3YXlgLCAKYHN0b3BwYWdlYCwgYGZhY2VvZmZgLCBgaGl0YCwKKiBgdGVhbWAgLSB0aGUgdGVhbSB0aGUgZXZlbnQgY29ycmVzcG9uZHMgdG8KKiBgZGVzY3JpcHRpb25gIC0gYSBicmllZiBkZXNjcmlwdGlvbiBvZiB0aGUgZXZlbnQKKiBgcGxheWVyX29uZWAgLSB0aGlzIGNvbHVtbiBoYXMgZGlmZmVyZW50IG1lYW5pbmdzIGRlcGVuZGluZyBvbiB0aGUgYGV2ZW50YCwgaXQgaXMgYXMgZm9sbG93czoKCiAgKiBgZXZlbnRgID0gYGdvYWxgLCBgc2hvdGAsIGBibG9ja2VkX3Nob3RgLCBvciBgbWlzc2VkX3Nob3RgIC0gYHBsYXllcl9vbmVgIHJlZmVycyB0byB0aGUgc2hvb3RlciBvZiB0aGUgcHVjaywKICAqIGBldmVudGAgPSBgaGl0YCAtIGBwbGF5ZXJfb25lYCByZWZlcnMgdG8gdGhlIHBsYXllciB3aG8gZGlkIHRoZSBoaXR0aW5nLAogICogYGV2ZW50YCA9IGB0YWtlYXdheWAgb3IgYGdpdmVhd2F5YCAtIGBwbGF5ZXJfb25lYCByZWZlcnMgdG8gdGhlIHBsYXllciB3aG8gY29tbWl0dGVkIHRoZSBnaXZlYXdheSBvciB0YWtlYXdheQogICogYGV2ZW50YCA9IGBmYWNlb2ZmYCAtIGBwbGF5ZXJfb25lYCByZWZlcnMgdG8gdGhlIHBsYXllciB3aG8gd29uIHRoZSBmYWNlb2ZmCiAgKiBgZXZlbnRgID0gYHBlbmFsdHlgIC0gYHBsYXllcl9vbmVgIHJlZmVycyB0byB0aGUgcGxheWVyIHdobyBjb21taXR0ZWQgdGhlIHBlbmFsdHksCiAgKiBgZXZlbnRgID0gYW55dGhpbmcgZWxzZSAtIGBwbGF5ZXJfb25lYCBpcyBOQQogIAogIAoqIGBwbGF5ZXJfdHdvYCAtIHRoaXMgY29sdW1uIGhhcyBkaWZmZXJlbnQgbWVhbmluZ3MgZGVwZW5kaW5nIG9uIHRoZSBgZXZlbnRgLCBpdCBpcyBhcyBmb2xsb3dzOgoKICAqIGBldmVudGAgPSBgaGl0YCAtIGBwbGF5ZXJfdHdvYCByZWZlcnMgdG8gdGhlIHBsYXllciB3aG8gd2FzIGhpdCwKICAqIGBldmVudGAgPSBgZmFjZW9mZmAgLSBgcGxheWVyX3R3b2AgcmVmZXJzIHRvIHRoZSBwbGF5ZXIgd2hvIGxvc3QgdGhlIGZhY2VvZmYsCiAgKiBgZXZlbnRgID0gYHBlbmFsdHlgIC0gYHBsYXllcl90d29gIHJlZmVycyB0byB0aGUgcGxheWVyIHdobyBkcmV3IHRoZSBwZW5hbHR5LAogICogYGV2ZW50YCA9IGBibG9ja2VkX3Nob3RgIC0gYHBsYXllcl90d29gIHJlZmVycyB0byB0aGUgcGxheWVyIHdobyBibG9ja2VkIHRoZSBzaG90LAogICogYGV2ZW50YCA9IGFueXRoaW5nIGVsc2UgLSBgcGxheWVyX3R3b2AgaXMgTkEKICAKKiBgZXZlbnRfdHlwZWAgLSByZWZlcnMgdG8gdGhlIHR5cGUgb2YgcGVuYWx0eSwgdHlwZSBvZiBzaG90IGF0dGVtcHQgKGV4Y2VwdCBmb3IgbWlzc2VkIHNob3RzKS4gIElzIE5BIG90aGVyd2lzZSwKKiBgeF9jb3JkYCwgYHlfY29yZGAgLSB0aGUgeCx5IGNvb3JkaW5hdGVzIGZvciBlYWNoIGV2ZW50IHdoZXJlIGB4X2NvcmRgIGRlbm90ZXMKdGhlIGxlZnQgdG8gcmlnaHQgbG9jYXRpb24gb2YgdGhlIGV2ZW50IHdpdGggcmVzcGVjdCB0byB0aGUgY2VudGVyIGljZSAoMCwgMCkgYW5kIGB5X2NvcmRgIGRlbm90ZXMKdGhlIHZlcnRpY2FsIGxvY2F0aW9uIG9mIHRoZSBldmVudC4gIFRoZSBuZXQgaXMgbG9jYXRlZCBhdCAoODksIDApLCBhbmQgYWxsIGV2ZW50IGxvY2F0aW9ucyByZXByZXNlbnQgYXBwcm9hY2hpbmcgdGhlCnNhbWUgZGlyZWN0aW9uLAoqICBgZW1wdHlfbmV0YCAtIFRSVUUgaWYgYSBnb2FsIHdhcyBzY29yZWQgd2l0aCB0aGUgbmV0IGVtcHR5LCBGQUxTRSBpZiBhIGdvYWwgd2FzIHNjb3JlZCBvbiBhIGdvYWx0ZW5kZXIuICBOQSBpZiBub3QgYSBnb2FsIGV2ZW50LAoqIGBwaXRfc2NvcmVgIC0gdGhlIFBpdHRzYnVyZ2ggUGVuZ3VpbnMgc2NvcmUgYXQgdGhlIHRpbWUgb2YgdGhlIGV2ZW50LAoqIGBzanNfc2NvcmVgIC0gdGhlIFNhbiBKb3NlIFNoYXJrcyBzY29yZSBhdCB0aGUgdGltZSBvZiB0aGUgZXZlbnQsCiogYHNob3RfYXR0ZW1wdGAgLSAxIGlmIHRoZSBldmVudCBjb25zdGl0dWVzIGFuIGF0dGVtcHRlZCBzaG90IG9uIGdvYWwsIDAgb3RoZXJ3aXNlLgoKCgoK