Quelques ressources générales

Introduction à R et au tidyverse de Julien Barnier

https://juba.github.io/tidyverse

R for Data Science de Garrett Grolemund & Hadley Wickham

http://r4ds.had.co.nz/


Qu’est-ce qu’un notebook ?

Ce document que vous avez ouvert dans RStudio ou dans un navigateur web est un notebook.


C’est un format de document permettant de présenter du texte, du code, et les résultats de l’exécution du code.


Dans la recherche scientifique, ce format permet de répliquer une expérience.

Il est en passe de devenir un standard.


Le système de notebooks le plus répandu est Jupyter, qui fonctionne avec le langage de programmation Python mais permet également de gérer d’autres langages de programmation tel R.


Ici, nous utilisons des notebooks au format prévu par RStudio.

Un notebook peut se décliner en plusieurs formats.


Le code apparaît systématiquement dans une case sur fond gris.

Le résultat du code apparaît ensuite dans une case sur fond blanc.

for (i in 1:3) print(LETTERS[i])
[1] "A"
[1] "B"
[1] "C"

En ouvrant le notebook dans RStudio, vous aurez la possibilité de modifier le code et de le réexécuter.


Par exemple, dans le code ci-dessous, nous sauvons la valeur “2” dans la variable “a” et la valeur “e” dans la variable “b”. Puis nous élevons a à la puissance b, c’est-à-dire 2 à la puissance 3.

Le résultat s’affiche en-dessous.

a <- 2
b <- 3
a^b
[1] 8

Essayez de modifier les valeurs, puis cliquez sur la flèche verte pour voir le résultat.


R, qu’est-ce ?

R est un langage de programmation à l’origine prévu pour faire de l’analyse statistique sur la base du langage propriétaire S. Son usage s’est répandu bien au-delà.


R peut par exemple être lancé dans un terminal.

Mais R désigne également une interface de programmation que l’on nomme R GUI, “GUI” signifiant “Graphical User Interface”.

R GUI est un logiciel libre.


… et RStudio ?

RStudio est un environnement permettant de programmer en R, c’est-à-dire un peu plus qu’une simple interface graphique.


En plus d’afficher une console (là où le code est exécuté) et une fenêtre de script (là où l’on rédige le code que l’on veut réutiliser), RStudio permet par exemple de connaître en tout temps les variables enregistrées en mémoire, ou encore d’utiliser un notebook comme celui-ci.


Dans ce module de cours, nous allons travailler avec RStudio.


Exemples de base

4 + 3         ## Une simple addition
[1] 7
2^2 + 3*4     ## Priorité des opérations
[1] 16

z = 12.5      ## Sauvegarde d'une valeur dans une variable
z <- 12.5     ## Privilégier l'utilisation de la flèche <-
z
[1] 12.5

x <- 12.5
y <- 7.5
x + y
[1] 20

y = sqrt(4)    ## Fonction racine carrée
y
[1] 2

ls()    ## Les variables sauvées dans l'environnement de travail
 [1] "a"              "A"              "A."             "A1"             "Aa"            
 [6] "AA"             "args"           "b"              "bete_humaine"   "c"             
[11] "comparisons"    "corpus"         "d"              "df"             "dfil"          
[16] "dist.mat"       "dn"             "e"              "fifa"           "fifa.corpus"   
[21] "fit"            "gg"             "gg_basic"       "gg_mieux"       "gg_minimal"    
[26] "i"              "is.wholenumber" "j"              "m"              "M1"            
[31] "n"              "nA"             "perm"           "points"         "sA"            
[36] "sy"             "tA"             "td.mat"         "team_rstats"    "tweets"        
[41] "V1"             "V2"             "x"              "X"              "x_char"        
[46] "X."             "X2"             "XX"             "y"              "z"             
rm(y)   ## On retire la variable "y"
ls()
 [1] "a"              "A"              "A."             "A1"             "Aa"            
 [6] "AA"             "args"           "b"              "bete_humaine"   "c"             
[11] "comparisons"    "corpus"         "d"              "df"             "dfil"          
[16] "dist.mat"       "dn"             "e"              "fifa"           "fifa.corpus"   
[21] "fit"            "gg"             "gg_basic"       "gg_mieux"       "gg_minimal"    
[26] "i"              "is.wholenumber" "j"              "m"              "M1"            
[31] "n"              "nA"             "perm"           "points"         "sA"            
[36] "sy"             "tA"             "td.mat"         "team_rstats"    "tweets"        
[41] "V1"             "V2"             "x"              "X"              "x_char"        
[46] "X."             "X2"             "XX"             "z"             

class(z)                     ## Le type d'une variable
[1] "numeric"

help(exp)                     ## La page d'aide d'une variable
?exp                          ## Idem
help.search("linear model")   ## Chercher dans les pages d'aide

Dans ce notebook comme dans les scripts que vous trouverez en ligne, les fonctions sortent du chapeau comme si de rien n’était.

Ne vous faites pas d’illusions:


C’est pour cette raison qu’il ne faut jamais hésiter à faire une recherche


Chaînes de caractères

b <- "unil"
c <- "patient 1"
nchar(b)
[1] 4
nchar(c)
[1] 9
paste(b, c, collapse = "")
[1] "unil patient 1"

Éléments logiques

  • TRUE et FALSE

Mais aussi…

  • NA, NaN
  • Inf

1/0
[1] Inf
x <- Inf
x - x
[1] NaN

“NA” signifie “Not available”.

“NaN” signifie “Not a Number”.


Opérateurs arithmétiques

  • +
  • -
  • *
  • /
  • ˆ
  • %%
  • %/%
  • %*%

Operateurs de comparaisons

1 == 1
[1] TRUE
1 == 2
[1] FALSE
1 != 1 
[1] FALSE

1 != 2
[1] TRUE
1 < 1
[1] FALSE
1 <= 1
[1] TRUE

Opérateurs logiques

a <- (1 < 2)
a
[1] TRUE
!a
[1] FALSE

b <- (2 > 3)
a & b
[1] FALSE
a | b
[1] TRUE

Comment connaître le type d’une variable ?

a <- 1
b <- 1:5
class(a)
[1] "numeric"
class(b)
[1] "integer"

c <- "hello"
d <- 1 > 2
class(c)
[1] "character"
class(d)
[1] "logical"

Quelle est la “taille” de l’objet ?

length(a)
[1] 1
length(b)
[1] 5
length(c)
[1] 1
length(d)
[1] 1

str fournit une description de l’objet

str(a)
 num 1
str(b)
 int [1:5] 1 2 3 4 5
str(c)
 chr "hello"
str(d)
 logi FALSE

Classes (de base)

Vecteurs

x <- c(5,4,5,6,7,8) 
x
[1] 5 4 5 6 7 8
x_char = c("a","b","c") 
x_char
[1] "a" "b" "c"

Accéder directement à un élément d’un vecteur

x
[1] 5 4 5 6 7 8
x[2]
[1] 4
x[c(2,4)]
[1] 4 6

x
[1] 5 4 5 6 7 8
x[c(-2,-4)]
[1] 5 5 7 8

Manipuler des vecteurs

x[6] = 10
x
[1]  5  4  5  6  7 10

a = c(3,4,5,6)
a[c(2,3)] = 0
a
[1] 3 0 0 6

a[c(2,3)] = c(8,7)
a
[1] 3 8 7 6

c(1,2,3) + c(3,4,5)
[1] 4 6 8

4 * c(1,2,3)
[1]  4  8 12
c(2,5) < 4
[1]  TRUE FALSE

Attention lorsque deux éléments ne sont pas de même taille !

c(1,2) + c(3,4,5,6)
[1] 4 6 6 8

Attention lorsque l’un n’est pas multiple de l’autre !

c(1,2) + c(2,3,4)
longer object length is not a multiple of shorter object length
[1] 3 5 5

Data frames

df <- data.frame(age = c(24, 26, 49, 52, 14), 
                 taille = c(160, 180, 178, 180, 150))
df

Comment fonctionnent les packages ?

Lorsqu’on démarre une session dans RStudio (ou dans R/R GUI), une série de fonctions sont immédiatement disponibles, telles les opérations mathématiques de base et quelques fonctions permettant de faire de l’analyse statistique ou de la visualisation.


Ensuite, en fonction de ses besoins, on charge dans R des packages supplémentaires, c’est-à-dire des ensembles de fonctions créées et réunies autour d’un but commun.

Chaque package disponible pour R est open source (normalement).


Il existe plus de 10’000 packages sur la plateforme CRAN et encore de nombreux autres en dehors, par exemple sur GitHub.


Un package doit être installé une et une seule fois. Cela se fait avec la fonction install.packages

Un package doit être chargé à chaque utilisation de R. Cela se fait avec la fonction library


Si le package est mis à jour, lancer la fonction install.packages permettra de l’actualiser.

Il est possible de gérer les packages, y compris de les installer, dans le menu Tools > Install packages…


Des exemples de packages


L’installation des packages nécessaires pour faire tourner le code de ce notebook est en général réalisée automatiquement grâce aux deux lignes de code suivantes.


Si le package est déjà installé, le programme saute à la seconde ligne et se contente de charger le package. Si ce n’est pas le cas, il s’occupe d’abord de l’installer (ligne 1) puis le charge.

if (!require(rtweet)) install.packages("rtweet") ## installation
Loading required package: rtweet
Welcome to rtweet v0.4.0!
library(rtweet)                                   ## chargement

rtweet est un package permettant de récupérer et d’analyser des tweets (ces courts messages postés sur Twitter).


Dans cet exemple, on charge les 100 derniers tweets contenant le mot “unil”.

Il est probable qu’un warning s’affiche.

tweets <- search_tweets("unil", n = 100)
Please set env var TWITTER_PAT to your Twitter personal access token(s)Searching for tweets...
Finished collecting tweets!

Un aperçu de ces tweets.

tweets

Visualisons les dates d’envoi des tweets.


Tout d’abord, on charge le package ggplot2 qui fournit de nouvelles fonctions pour faire de la visualisation.

if (!require(ggplot2)) install.packages("ggplot2")
Loading required package: ggplot2
library(ggplot2)

Puis on crée un histogramme avec nos données (la colonne “created_at” dans le tableau ci-dessus).

Voici le résultat brut.


gg_basic <- ggplot(tweets, aes(x = created_at)) +
       geom_histogram()

gg_basic


On peut l’améliorer en ajoutant des options.

gg_mieux <- ggplot(tweets, aes(x = created_at)) +
       geom_histogram(binwidth = 3600) +
       scale_x_datetime(date_breaks = "3 hour", 
                        date_minor_breaks = "1 hour", 
                        date_labels = "%m-%d %Hh", 
                        name = "Date de création du tweet") +
       scale_y_continuous(name = "Nombre de tweets")

gg_mieux


Avec le thème “minimal”.

gg_minimal <- gg_mieux + theme_minimal()

gg_minimal


Cheat sheets

Pour de nombreuses tâches en R, on trouve des feuilles de triche.

Par exemple, il en existe une pour ggplot2.

https://github.com/rstudio/cheatsheets/raw/master/data-visualization-2.1.pdf


Gutenberg

Il existe un package pour télécharger les contenus de https://www.gutenberg.org/

if (!require(gutenbergr)) install.packages("gutenbergr")
Loading required package: gutenbergr
library(gutenbergr)

Nous avons besoin au passage du package dplyr pour utiliser les %>% (“pipes”).

Les pipes permettent de rédiger du code s’exécutant de gauche à droite. Il devient ainsi plus lisible.

if (!require(dplyr)) install.packages("dplyr")            
Loading required package: dplyr

Attaching package: ‘dplyr’

The following objects are masked from ‘package:stats’:

    filter, lag

The following objects are masked from ‘package:base’:

    intersect, setdiff, setequal, union
library(dplyr)                                            

Pour plus d’informations sur les pipes.

http://r4ds.had.co.nz/pipes.html#piping-alternatives

Au passage: ce livre est une excellente ressource (gratuite) sur R.


Pas immédiat de naviguer dans la base de données Gutenberg avec ce package.

Explorons son fonctionnement avec la fonction help(package="gutenbergr")


La fonction gutenberg_metadata réunit les métadonnées de la base et va nous permettre de faire notre choix parmi les oeuvres.

head(gutenberg_metadata)

On choisit Émile Zola (attention, l’orthographe doit être exacte).

gutenberg_metadata %>%
  filter(author == "Zola, Émile")

Pour faire une recherche sans connaître la dénomination exacte de l’auteur-e dans la base de données.

Tout d’abord nous chargeons un package pour utiliser des expressions régulières qui soit meilleur que ce qui est proposé de base.

if (!require(stringr)) install.packages("stringr")
Loading required package: stringr
library(stringr)

Puis on cherche juste Zola cette fois.

gutenberg_works(str_detect(author, "Zola"))

L’ID de La Bête Humaine est 5154. On le télécharge.

bete_humaine <- gutenberg_download(5154)  ## La Bête Humaine, d'Émile Zola
Determining mirror for Project Gutenberg from http://www.gutenberg.org/robot/harvest
Using mirror http://aleph.gutenberg.org

Un aperçu de ce que nous avons obtenu avec la fonction str.

str(bete_humaine)
Classes ‘tbl_df’, ‘tbl’ and 'data.frame':   15324 obs. of  2 variables:
 $ gutenberg_id: int  5154 5154 5154 5154 5154 5154 5154 5154 5154 5154 ...
 $ text        : chr  "This is #17 in Zola's \"Les Rougon-Macquart\" series." "" "We thank the Bibliotheque Nationale de France that has made available" "the image files at www://gallica.bnf.fr, authorizing the preparation" ...

bete_humaine$text[100]
[1] "son nom, le fit se pencher.  Et il reconnut, au-dessous, sur la"
bete_humaine$text[101]
[1] "terrasse du quatri\xe8me, un jeune homme d'une trentaine d'ann\xe9es,"
bete_humaine$text[102]
[1] "Henri Dauvergne, conducteur-chef, qui habitait l\xe0 en compagnie de"

R et la statistique textuelle

La fondation qui gère le langage R propose une série de task views, c’est-à-dire de guides de packages disponibles pour des thèmes donnés.


En particulier, une task view est disponible pour le traitement automatique du langage naturel (en anglais natural language processing ou NLP).

Je vous invite à la consulter pour trouver le package qui saura répondre à vos questions.


Le package tm

Le package tm est le package de référence à utiliser pour faire de la statistique textuelle en R.

Plusieurs autres packages ont ensuite été construits à partir de tm et nécessitent la présence de celui-ci afin de fonctionner.

Cela assure l’utilisation d’un format commun.


Où trouver des réponses ?


Loading required package: readr
Loading required package: RTextTools
Loading required package: textreuse

Attaching package: ‘textreuse’

The following object is masked from ‘package:readr’:

    tokenize

Loading required package: lsa
Loading required package: SnowballC

Attaching package: ‘SnowballC’

The following objects are masked from ‘package:RTextTools’:

    getStemLanguages, wordStem


Attaching package: ‘lsa’

The following object is masked from ‘package:dplyr’:

    query

Nous allons découvrir ce package avec un corpus de tests de jeux de football issus de la presse spécialisée.

fifa <- read.csv2("https://gist.githubusercontent.com/yrochat/844247a0a985f54fb69f09fdc02bfb15/raw/011092f37b6b4529951541b434e802bf995fc6e5/fifa.csv", stringsAsFactors = FALSE) ## le fichier à importer

Un aperçu du tableau.

fifa

Analyse rapide de plagiat

fifa.corpus <- TextReuseCorpus(text = fifa$texte, tokenizer = tokenize_ngrams)
Loading, tokenizing, and hashing 36 documents.

  |                                                                                                  
  |                                                                                            |   0%
  |                                                                                                  
  |===                                                                                         |   3%
  |                                                                                                  
  |=====                                                                                       |   6%
  |                                                                                                  
  |========                                                                                    |   8%
  |                                                                                                  
  |==========                                                                                  |  11%
  |                                                                                                  
  |=============                                                                               |  14%
  |                                                                                                  
  |===============                                                                             |  17%
  |                                                                                                  
  |==================                                                                          |  19%
  |                                                                                                  
  |====================                                                                        |  22%
  |                                                                                                  
  |=======================                                                                     |  25%
  |                                                                                                  
  |==========================                                                                  |  28%
  |                                                                                                  
  |============================                                                                |  31%
  |                                                                                                  
  |===============================                                                             |  33%
  |                                                                                                  
  |=================================                                                           |  36%
  |                                                                                                  
  |====================================                                                        |  39%
  |                                                                                                  
  |======================================                                                      |  42%
  |                                                                                                  
  |=========================================                                                   |  44%
  |                                                                                                  
  |===========================================                                                 |  47%
  |                                                                                                  
  |==============================================                                              |  50%
  |                                                                                                  
  |=================================================                                           |  53%
  |                                                                                                  
  |===================================================                                         |  56%
  |                                                                                                  
  |======================================================                                      |  58%
  |                                                                                                  
  |========================================================                                    |  61%
  |                                                                                                  
  |===========================================================                                 |  64%
  |                                                                                                  
  |=============================================================                               |  67%
  |                                                                                                  
  |================================================================                            |  69%
  |                                                                                                  
  |==================================================================                          |  72%
  |                                                                                                  
  |=====================================================================                       |  75%
  |                                                                                                  
  |========================================================================                    |  78%
  |                                                                                                  
  |==========================================================================                  |  81%
  |                                                                                                  
  |=============================================================================               |  83%
  |                                                                                                  
  |===============================================================================             |  86%
  |                                                                                                  
  |==================================================================================          |  89%
  |                                                                                                  
  |====================================================================================        |  92%
  |                                                                                                  
  |=======================================================================================     |  94%
  |                                                                                                  
  |=========================================================================================   |  97%
  |                                                                                                  
  |============================================================================================| 100%
fifa.corpus
TextReuseCorpus
Number of documents: 36 
hash_func : hash_string 
tokenizer : tokenize_ngrams 

Une comparaison des textes deux à deux.

comparisons <- pairwise_compare(fifa.corpus, jaccard_similarity)
Making 630 comparisons.

  |                                                                                                  
  |                                                                                            |   0%
  |                                                                                                  
  |=                                                                                           |   1%
  |                                                                                                  
  |=                                                                                           |   2%
  |                                                                                                  
  |==                                                                                          |   2%
  |                                                                                                  
  |==                                                                                          |   3%
  |                                                                                                  
  |===                                                                                         |   3%
  |                                                                                                  
  |===                                                                                         |   4%
  |                                                                                                  
  |====                                                                                        |   4%
  |                                                                                                  
  |====                                                                                        |   5%
  |                                                                                                  
  |=====                                                                                       |   5%
  |                                                                                                  
  |=====                                                                                       |   6%
  |                                                                                                  
  |======                                                                                      |   6%
  |                                                                                                  
  |======                                                                                      |   7%
  |                                                                                                  
  |=======                                                                                     |   7%
  |                                                                                                  
  |=======                                                                                     |   8%
  |                                                                                                  
  |========                                                                                    |   8%
  |                                                                                                  
  |========                                                                                    |   9%
  |                                                                                                  
  |=========                                                                                   |   9%
  |                                                                                                  
  |=========                                                                                   |  10%
  |                                                                                                  
  |==========                                                                                  |  10%
  |                                                                                                  
  |==========                                                                                  |  11%
  |                                                                                                  
  |===========                                                                                 |  11%
  |                                                                                                  
  |===========                                                                                 |  12%
  |                                                                                                  
  |============                                                                                |  13%
  |                                                                                                  
  |=============                                                                               |  14%
  |                                                                                                  
  |=============                                                                               |  15%
  |                                                                                                  
  |==============                                                                              |  15%
  |                                                                                                  
  |==============                                                                              |  16%
  |                                                                                                  
  |===============                                                                             |  16%
  |                                                                                                  
  |===============                                                                             |  17%
  |                                                                                                  
  |================                                                                            |  17%
  |                                                                                                  
  |================                                                                            |  18%
  |                                                                                                  
  |=================                                                                           |  18%
  |                                                                                                  
  |=================                                                                           |  19%
  |                                                                                                  
  |==================                                                                          |  19%
  |                                                                                                  
  |==================                                                                          |  20%
  |                                                                                                  
  |===================                                                                         |  20%
  |                                                                                                  
  |===================                                                                         |  21%
  |                                                                                                  
  |====================                                                                        |  21%
  |                                                                                                  
  |====================                                                                        |  22%
  |                                                                                                  
  |=====================                                                                       |  22%
  |                                                                                                  
  |=====================                                                                       |  23%
  |                                                                                                  
  |======================                                                                      |  23%
  |                                                                                                  
  |======================                                                                      |  24%
  |                                                                                                  
  |=======================                                                                     |  25%
  |                                                                                                  
  |========================                                                                    |  26%
  |                                                                                                  
  |========================                                                                    |  27%
  |                                                                                                  
  |=========================                                                                   |  27%
  |                                                                                                  
  |=========================                                                                   |  28%
  |                                                                                                  
  |==========================                                                                  |  28%
  |                                                                                                  
  |==========================                                                                  |  29%
  |                                                                                                  
  |===========================                                                                 |  29%
  |                                                                                                  
  |===========================                                                                 |  30%
  |                                                                                                  
  |============================                                                                |  30%
  |                                                                                                  
  |============================                                                                |  31%
  |                                                                                                  
  |=============================                                                               |  31%
  |                                                                                                  
  |=============================                                                               |  32%
  |                                                                                                  
  |==============================                                                              |  32%
  |                                                                                                  
  |==============================                                                              |  33%
  |                                                                                                  
  |===============================                                                             |  33%
  |                                                                                                  
  |===============================                                                             |  34%
  |                                                                                                  
  |================================                                                            |  34%
  |                                                                                                  
  |================================                                                            |  35%
  |                                                                                                  
  |=================================                                                           |  35%
  |                                                                                                  
  |=================================                                                           |  36%
  |                                                                                                  
  |==================================                                                          |  37%
  |                                                                                                  
  |===================================                                                         |  38%
  |                                                                                                  
  |===================================                                                         |  39%
  |                                                                                                  
  |====================================                                                        |  39%
  |                                                                                                  
  |====================================                                                        |  40%
  |                                                                                                  
  |=====================================                                                       |  40%
  |                                                                                                  
  |=====================================                                                       |  41%
  |                                                                                                  
  |======================================                                                      |  41%
  |                                                                                                  
  |======================================                                                      |  42%
  |                                                                                                  
  |=======================================                                                     |  42%
  |                                                                                                  
  |=======================================                                                     |  43%
  |                                                                                                  
  |========================================                                                    |  43%
  |                                                                                                  
  |========================================                                                    |  44%
  |                                                                                                  
  |=========================================                                                   |  44%
  |                                                                                                  
  |=========================================                                                   |  45%
  |                                                                                                  
  |==========================================                                                  |  45%
  |                                                                                                  
  |==========================================                                                  |  46%
  |                                                                                                  
  |===========================================                                                 |  46%
  |                                                                                                  
  |===========================================                                                 |  47%
  |                                                                                                  
  |============================================                                                |  47%
  |                                                                                                  
  |============================================                                                |  48%
  |                                                                                                  
  |=============================================                                               |  48%
  |                                                                                                  
  |=============================================                                               |  49%
  |                                                                                                  
  |==============================================                                              |  50%
  |                                                                                                  
  |===============================================                                             |  51%
  |                                                                                                  
  |===============================================                                             |  52%
  |                                                                                                  
  |================================================                                            |  52%
  |                                                                                                  
  |================================================                                            |  53%
  |                                                                                                  
  |=================================================                                           |  53%
  |                                                                                                  
  |=================================================                                           |  54%
  |                                                                                                  
  |==================================================                                          |  54%
  |                                                                                                  
  |==================================================                                          |  55%
  |                                                                                                  
  |===================================================                                         |  55%
  |                                                                                                  
  |===================================================                                         |  56%
  |                                                                                                  
  |====================================================                                        |  56%
  |                                                                                                  
  |====================================================                                        |  57%
  |                                                                                                  
  |=====================================================                                       |  57%
  |                                                                                                  
  |=====================================================                                       |  58%
  |                                                                                                  
  |======================================================                                      |  58%
  |                                                                                                  
  |======================================================                                      |  59%
  |                                                                                                  
  |=======================================================                                     |  59%
  |                                                                                                  
  |=======================================================                                     |  60%
  |                                                                                                  
  |========================================================                                    |  60%
  |                                                                                                  
  |========================================================                                    |  61%
  |                                                                                                  
  |=========================================================                                   |  61%
  |                                                                                                  
  |=========================================================                                   |  62%
  |                                                                                                  
  |==========================================================                                  |  63%
  |                                                                                                  
  |===========================================================                                 |  64%
  |                                                                                                  
  |===========================================================                                 |  65%
  |                                                                                                  
  |============================================================                                |  65%
  |                                                                                                  
  |============================================================                                |  66%
  |                                                                                                  
  |=============================================================                               |  66%
  |                                                                                                  
  |=============================================================                               |  67%
  |                                                                                                  
  |==============================================================                              |  67%
  |                                                                                                  
  |==============================================================                              |  68%
  |                                                                                                  
  |===============================================================                             |  68%
  |                                                                                                  
  |===============================================================                             |  69%
  |                                                                                                  
  |================================================================                            |  69%
  |                                                                                                  
  |================================================================                            |  70%
  |                                                                                                  
  |=================================================================                           |  70%
  |                                                                                                  
  |=================================================================                           |  71%
  |                                                                                                  
  |==================================================================                          |  71%
  |                                                                                                  
  |==================================================================                          |  72%
  |                                                                                                  
  |===================================================================                         |  72%
  |                                                                                                  
  |===================================================================                         |  73%
  |                                                                                                  
  |====================================================================                        |  73%
  |                                                                                                  
  |====================================================================                        |  74%
  |                                                                                                  
  |=====================================================================                       |  75%
  |                                                                                                  
  |======================================================================                      |  76%
  |                                                                                                  
  |======================================================================                      |  77%
  |                                                                                                  
  |=======================================================================                     |  77%
  |                                                                                                  
  |=======================================================================                     |  78%
  |                                                                                                  
  |========================================================================                    |  78%
  |                                                                                                  
  |========================================================================                    |  79%
  |                                                                                                  
  |=========================================================================                   |  79%
  |                                                                                                  
  |=========================================================================                   |  80%
  |                                                                                                  
  |==========================================================================                  |  80%
  |                                                                                                  
  |==========================================================================                  |  81%
  |                                                                                                  
  |===========================================================================                 |  81%
  |                                                                                                  
  |===========================================================================                 |  82%
  |                                                                                                  
  |============================================================================                |  82%
  |                                                                                                  
  |============================================================================                |  83%
  |                                                                                                  
  |=============================================================================               |  83%
  |                                                                                                  
  |=============================================================================               |  84%
  |                                                                                                  
  |==============================================================================              |  84%
  |                                                                                                  
  |==============================================================================              |  85%
  |                                                                                                  
  |===============================================================================             |  85%
  |                                                                                                  
  |===============================================================================             |  86%
  |                                                                                                  
  |================================================================================            |  87%
  |                                                                                                  
  |=================================================================================           |  88%
  |                                                                                                  
  |=================================================================================           |  89%
  |                                                                                                  
  |==================================================================================          |  89%
  |                                                                                                  
  |==================================================================================          |  90%
  |                                                                                                  
  |===================================================================================         |  90%
  |                                                                                                  
  |===================================================================================         |  91%
  |                                                                                                  
  |====================================================================================        |  91%
  |                                                                                                  
  |====================================================================================        |  92%
  |                                                                                                  
  |=====================================================================================       |  92%
  |                                                                                                  
  |=====================================================================================       |  93%
  |                                                                                                  
  |======================================================================================      |  93%
  |                                                                                                  
  |======================================================================================      |  94%
  |                                                                                                  
  |=======================================================================================     |  94%
  |                                                                                                  
  |=======================================================================================     |  95%
  |                                                                                                  
  |========================================================================================    |  95%
  |                                                                                                  
  |========================================================================================    |  96%
  |                                                                                                  
  |=========================================================================================   |  96%
  |                                                                                                  
  |=========================================================================================   |  97%
  |                                                                                                  
  |==========================================================================================  |  97%
  |                                                                                                  
  |==========================================================================================  |  98%
  |                                                                                                  
  |=========================================================================================== |  98%
  |                                                                                                  
  |=========================================================================================== |  99%
  |                                                                                                  
  |============================================================================================| 100%
comparisons
       doc-1       doc-2       doc-3       doc-4       doc-5       doc-6       doc-7       doc-8
doc-1     NA 0.007072439 0.008833522 0.009059090 0.007747197 0.006614964 0.005476190 0.007758812
doc-2     NA          NA 0.004126142 0.008636483 0.006198347 0.005076142 0.006975269 0.008357349
doc-3     NA          NA          NA 0.008946044 0.005785124 0.005152979 0.006870491 0.007118539
doc-4     NA          NA          NA          NA 0.010355030 0.007909605 0.007756563 0.008721723
doc-5     NA          NA          NA          NA          NA 0.006131550 0.006474397 0.008894879
doc-6     NA          NA          NA          NA          NA          NA 0.008374040 0.008474576
doc-7     NA          NA          NA          NA          NA          NA          NA 0.014089232
doc-8     NA          NA          NA          NA          NA          NA          NA          NA
doc-9     NA          NA          NA          NA          NA          NA          NA          NA
doc-10    NA          NA          NA          NA          NA          NA          NA          NA
doc-11    NA          NA          NA          NA          NA          NA          NA          NA
doc-12    NA          NA          NA          NA          NA          NA          NA          NA
doc-13    NA          NA          NA          NA          NA          NA          NA          NA
doc-14    NA          NA          NA          NA          NA          NA          NA          NA
doc-15    NA          NA          NA          NA          NA          NA          NA          NA
doc-16    NA          NA          NA          NA          NA          NA          NA          NA
doc-17    NA          NA          NA          NA          NA          NA          NA          NA
doc-18    NA          NA          NA          NA          NA          NA          NA          NA
doc-19    NA          NA          NA          NA          NA          NA          NA          NA
doc-20    NA          NA          NA          NA          NA          NA          NA          NA
doc-21    NA          NA          NA          NA          NA          NA          NA          NA
doc-22    NA          NA          NA          NA          NA          NA          NA          NA
doc-23    NA          NA          NA          NA          NA          NA          NA          NA
doc-24    NA          NA          NA          NA          NA          NA          NA          NA
doc-25    NA          NA          NA          NA          NA          NA          NA          NA
doc-26    NA          NA          NA          NA          NA          NA          NA          NA
doc-27    NA          NA          NA          NA          NA          NA          NA          NA
             doc-9      doc-10      doc-11      doc-12      doc-13      doc-14      doc-15
doc-1  0.009190764 0.007102273 0.007395787 0.006197521 0.006743941 0.005184851 0.005017104
doc-2  0.007876313 0.004699248 0.004662005 0.006057547 0.004308024 0.003234343 0.003584229
doc-3  0.008165829 0.008512087 0.005967337 0.007541072 0.003166379 0.004121750 0.005162956
doc-4  0.008549366 0.007685486 0.008008837 0.008184882 0.005626598 0.008089261 0.005646527
doc-5  0.009552402 0.009064327 0.004625850 0.008583691 0.002775675 0.005224086 0.006141820
doc-6  0.005393401 0.008284432 0.008934269 0.006528836 0.009082918 0.004821601 0.004903563
doc-7  0.008804605 0.008121078 0.014680778 0.008910606 0.006184292 0.007549760 0.006631763
doc-8  0.011332312 0.010254714 0.007953503 0.008949724 0.006188467 0.006485485 0.005644403
doc-9           NA 0.007025761 0.010883085 0.009592326 0.007413744 0.005944931 0.006043257
doc-10          NA          NA 0.011792453 0.006823998 0.004587156 0.005081301 0.006560773
doc-11          NA          NA          NA 0.014484979 0.009736541 0.009122366 0.007341207
doc-12          NA          NA          NA          NA 0.007936508 0.008073197 0.009013931
doc-13          NA          NA          NA          NA          NA 0.010715320 0.005851375
doc-14          NA          NA          NA          NA          NA          NA 0.006127056
doc-15          NA          NA          NA          NA          NA          NA          NA
doc-16          NA          NA          NA          NA          NA          NA          NA
doc-17          NA          NA          NA          NA          NA          NA          NA
doc-18          NA          NA          NA          NA          NA          NA          NA
doc-19          NA          NA          NA          NA          NA          NA          NA
doc-20          NA          NA          NA          NA          NA          NA          NA
doc-21          NA          NA          NA          NA          NA          NA          NA
doc-22          NA          NA          NA          NA          NA          NA          NA
doc-23          NA          NA          NA          NA          NA          NA          NA
doc-24          NA          NA          NA          NA          NA          NA          NA
doc-25          NA          NA          NA          NA          NA          NA          NA
doc-26          NA          NA          NA          NA          NA          NA          NA
doc-27          NA          NA          NA          NA          NA          NA          NA
            doc-16      doc-17      doc-18      doc-19      doc-20      doc-21      doc-22
doc-1  0.002431315 0.003037835 0.006544798 0.004661099 0.004832029 0.006208426 0.003238492
doc-2  0.004572175 0.002715283 0.004118858 0.005850804 0.003931055 0.004026460 0.002743066
doc-3  0.002478754 0.001712329 0.005395113 0.005700959 0.003590078 0.002780352 0.003625577
doc-4  0.002140018 0.001437298 0.002773925 0.005809900 0.004563605 0.005171475 0.004602992
doc-5  0.003931055 0.001061571 0.003017005 0.005059798 0.003943662 0.004302232 0.005977797
doc-6  0.002515271 0.002616659 0.002243590 0.004709576 0.006969798 0.005332497 0.005691329
doc-7  0.003473562 0.002853067 0.006856359 0.004955947 0.004946996 0.006677796 0.003208556
doc-8  0.003432887 0.002473207 0.007105344 0.006332320 0.003485425 0.006938160 0.004804612
doc-9  0.003835425 0.005473684 0.005000000 0.005888377 0.005473278 0.005801527 0.004546931
doc-10 0.004198473 0.004694836 0.004739336 0.003817835 0.003140265 0.004948862 0.003173484
doc-11 0.004547044 0.005914660 0.006587202 0.005383235 0.005810200 0.007046569 0.004557292
doc-12 0.004714202 0.006204757 0.003212851 0.006317690 0.004398021 0.008436594 0.005828476
doc-13 0.003819223 0.004526594 0.004893495 0.004300048 0.006218537 0.003655793 0.004473606
doc-14 0.003183587 0.005143592 0.003796267 0.004653568 0.005550114 0.004324992 0.001642036
doc-15 0.003966823 0.003062117 0.001283285 0.004980341 0.004311774 0.004395604 0.005028495
doc-16          NA 0.008028098 0.003182461 0.002541655 0.004024881 0.003442341 0.002215657
doc-17          NA          NA 0.002135839 0.002622091 0.004010695 0.004558641 0.004518753
doc-18          NA          NA          NA 0.008824293 0.003910068 0.006499536 0.006930693
doc-19          NA          NA          NA          NA 0.005299417 0.010448522 0.003198294
doc-20          NA          NA          NA          NA          NA 0.008298755 0.011282051
doc-21          NA          NA          NA          NA          NA          NA 0.008054124
doc-22          NA          NA          NA          NA          NA          NA          NA
doc-23          NA          NA          NA          NA          NA          NA          NA
doc-24          NA          NA          NA          NA          NA          NA          NA
doc-25          NA          NA          NA          NA          NA          NA          NA
doc-26          NA          NA          NA          NA          NA          NA          NA
doc-27          NA          NA          NA          NA          NA          NA          NA
            doc-23      doc-24      doc-25      doc-26      doc-27      doc-28      doc-29
doc-1  0.004000000 0.005186146 0.005736138 0.005704971 0.005174129 0.006552007 0.006070417
doc-2  0.005313765 0.005048187 0.004530281 0.003871967 0.004012036 0.003371369 0.004093118
doc-3  0.005664958 0.001938454 0.004556962 0.003027801 0.003202562 0.003322259 0.004915347
doc-4  0.006266570 0.006148441 0.004322111 0.004666012 0.004777831 0.003945746 0.005849379
doc-5  0.007405638 0.005435964 0.005640794 0.003886325 0.004492788 0.005377658 0.004578313
doc-6  0.006277293 0.004909180 0.004091025 0.005862647 0.003508772 0.005331089 0.006917543
doc-7  0.006620610 0.006185567 0.007277628 0.007378985 0.004841925 0.006824926 0.007007299
doc-8  0.007118376 0.006428571 0.009448036 0.006194452 0.004696061 0.008138904 0.006940737
doc-9  0.005592543 0.005287191 0.005760080 0.007092199 0.005812417 0.005476451 0.006207827
doc-10 0.005128205 0.006651317 0.005336179 0.009378664 0.007644394 0.005284792 0.007527504
doc-11 0.007754011 0.007722008 0.009569378 0.009865717 0.010638298 0.009920088 0.009495388
doc-12 0.010084428 0.005760614 0.006864482 0.007154782 0.008368201 0.005743001 0.004955168
doc-13 0.004961548 0.003150315 0.004212497 0.003287810 0.005418719 0.005348956 0.004769076
doc-14 0.004034427 0.003636364 0.003029538 0.003575358 0.003733333 0.001932634 0.005182761
doc-15 0.004365621 0.005163511 0.005384615 0.003347280 0.004057344 0.007038288 0.005257333
doc-16 0.004435245 0.003693931 0.004696133 0.002723971 0.006754772 0.006110602 0.002994909
doc-17 0.005188516 0.003635262 0.002549395 0.003913198 0.004445964 0.003581662 0.004922644
doc-18 0.004033342 0.003392295 0.005821311 0.004126547 0.004000000 0.006655574 0.006828735
doc-19 0.006336275 0.006218905 0.004931389 0.005067957 0.006292135 0.006022701 0.007097070
doc-20 0.004690949 0.003719316 0.008313848 0.003951454 0.006027397 0.006545248 0.006442577
doc-21 0.009801325 0.005960897 0.007458976 0.006751283 0.007867821 0.008430786 0.009656652
doc-22 0.006410256 0.005505506 0.007324091 0.006563927 0.003305785 0.006601607 0.007350862
doc-23          NA 0.010967742 0.012505583 0.008624820 0.008864007 0.006243996 0.009270264
doc-24          NA          NA 0.012085211 0.009621693 0.006808511 0.006348511 0.009984806
doc-25          NA          NA          NA 0.009986382 0.007948775 0.007963595 0.009905448
doc-26          NA          NA          NA          NA 0.011447651 0.007360157 0.009704027
doc-27          NA          NA          NA          NA          NA 0.009567089 0.007063810
            doc-30      doc-31      doc-32       doc-33      doc-34      doc-35      doc-36
doc-1  0.003047232 0.004210526 0.003981090 0.0035297312 0.003068340 0.005422503 0.005650945
doc-2  0.003456619 0.001446655 0.004369748 0.0011337868 0.002753737 0.002356406 0.004771260
doc-3  0.001884659 0.003578529 0.003291880 0.0008326395 0.003047453 0.001585791 0.004518072
doc-4  0.004529279 0.003377237 0.004408060 0.0031667840 0.002185792 0.003898635 0.005049163
doc-5  0.003187759 0.002662230 0.001859888 0.0041652204 0.003593245 0.003853565 0.003674541
doc-6  0.003066309 0.003637833 0.005582434 0.0046768707 0.002658396 0.002895753 0.004574565
doc-7  0.006636251 0.005701754 0.006007209 0.0050878816 0.002902758 0.003084304 0.008447044
doc-8  0.007326007 0.003067485 0.004250797 0.0024096386 0.002930096 0.004326329 0.004985337
doc-9  0.005947955 0.004687500 0.003956835 0.0016339869 0.003841229 0.002815139 0.005349183
doc-10 0.003674969 0.004755728 0.004741209 0.0027297543 0.002859867 0.005096840 0.003200000
doc-11 0.005588674 0.003521127 0.009793254 0.0036945813 0.004282655 0.004711055 0.006559332
doc-12 0.007469655 0.004532211 0.004839685 0.0030262273 0.003480682 0.003221477 0.004878049
doc-13 0.008116334 0.004941758 0.004258107 0.0022050717 0.003054601 0.002303484 0.003566529
doc-14 0.007186082 0.007569721 0.004753199 0.0020798669 0.004786771 0.005084207 0.003003003
doc-15 0.005778120 0.004868154 0.004845322 0.0042607584 0.005345212 0.002901354 0.003969466
doc-16 0.006052745 0.004580852 0.003745318 0.0077783179 0.006119327 0.003549876 0.002670227
doc-17 0.002730748 0.004129794 0.005759162 0.0031705770 0.005427408 0.003436426 0.002393299
doc-18 0.003767898 0.004765687 0.004751462 0.0033305579 0.003039514 0.008606949 0.006022282
doc-19 0.005358738 0.003714020 0.004934688 0.0028901734 0.003318951 0.003364389 0.003217025
doc-20 0.005082095 0.003293536 0.005679667 0.0056423611 0.006811989 0.002284595 0.004950495
doc-21 0.005869406 0.003849115 0.004976893 0.0060655075 0.005897220 0.007771215 0.005588235
doc-22 0.005142405 0.004171882 0.002672776 0.0035103115 0.003211009 0.005621693 0.003117207
doc-23 0.004674353 0.001945525 0.004248862 0.0047361299 0.004198740 0.004856989 0.006709677
doc-24 0.004148230 0.003155479 0.004867496 0.0059577003 0.001834301 0.004132231 0.005837030
doc-25 0.007562536 0.003616637 0.003676471 0.0037523452 0.003225806 0.005836082 0.008769793
doc-26 0.005443484 0.004343468 0.002486789 0.0027797081 0.002518892 0.004969630 0.005267316
doc-27 0.004319654 0.004505954 0.003605769 0.0040147206 0.003112033 0.002670227 0.006656426
 [ reached getOption("max.print") -- omitted 9 rows ]

Les scores de ces comparaisons.

pairwise_candidates(comparisons)[order(pairwise_candidates(comparisons)$score, decreasing = TRUE),]

Les scores les plus hauts.

align_local(fifa$texte[30], fifa$texte[31])
Multiple optimal local alignments found; selecting only one of them.
TextReuse alignment
Alignment score: 10 
Document A:
très proches de la réalité

Document B:
très proches de la réalité

align_local(fifa$texte[7], fifa$texte[11])
Multiple optimal local alignments found; selecting only one of them.
TextReuse alignment
Alignment score: 10 
Document A:
la gestion des duels aériens

Document B:
la gestion des duels aériens

align_local(fifa$texte[11], fifa$texte[12])
TextReuse alignment
Alignment score: 14 
Document A:
ne donnent ### ### plus la désagréable sensation de flotter ###### sur
le terrain

Document B:
ne donnent pas non plus la ########### sensation de ####### courir sur
le terrain

align_local(fifa$texte[32], fifa$texte[33])
TextReuse alignment
Alignment score: 13 
Document A:
modes de jeu on est également #### servi ##### ###### avec des matches
amicaux les ### saisons

Document B:
modes de jeu ## est ######### tout ##### aussi étoffé avec des matches
amicaux ### des saisons

align_local(fifa$texte[7], fifa$texte[8])
TextReuse alignment
Alignment score: 13 
Document A:
soin apporté à la modélisation des plus ####### grandes ## stars ### et
à

Document B:
soin apporté à la modélisation des #### visages ####### Au ##### fur et
à

Importer des fichiers avec tm

if (!require(tm)) install.packages("tm")
library(tm)         ## text mining

On crée un corpus de textes au format de tm.

A vector source interprets each element of the vector x as a document.

corpus <- Corpus(VectorSource(fifa$texte))
corpus
<<VCorpus>>
Metadata:  corpus specific: 0, document level (indexed): 0
Content:  documents: 36

tm_map est une application qui permet de faire des transformations sur tout un corpus.

Ici, on passe tout en minuscules grâce à content_transformer(tolower).

corpus <- tm_map(corpus, content_transformer(tolower))

Ici, nous retirons la ponctuation.

corpus <- tm_map(corpus, content_transformer(removePunctuation))

Nous retirons du texte les stopwords.

corpus <- tm_map(corpus, content_transformer(function(x) removeWords(x, stopwords("french"))))

Voici la liste des stopwords en français.

stopwords("french")
  [1] "au"       "aux"      "avec"     "ce"       "ces"      "dans"     "de"       "des"     
  [9] "du"       "elle"     "en"       "et"       "eux"      "il"       "je"       "la"      
 [17] "le"       "leur"     "lui"      "ma"       "mais"     "me"       "même"     "mes"     
 [25] "moi"      "mon"      "ne"       "nos"      "notre"    "nous"     "on"       "ou"      
 [33] "par"      "pas"      "pour"     "qu"       "que"      "qui"      "sa"       "se"      
 [41] "ses"      "son"      "sur"      "ta"       "te"       "tes"      "toi"      "ton"     
 [49] "tu"       "un"       "une"      "vos"      "votre"    "vous"     "c"        "d"       
 [57] "j"        "l"        "à"        "m"        "n"        "s"        "t"        "y"       
 [65] "été"      "étée"     "étées"    "étés"     "étant"    "suis"     "es"       "est"     
 [73] "sommes"   "êtes"     "sont"     "serai"    "seras"    "sera"     "serons"   "serez"   
 [81] "seront"   "serais"   "serait"   "serions"  "seriez"   "seraient" "étais"    "était"   
 [89] "étions"   "étiez"    "étaient"  "fus"      "fut"      "fûmes"    "fûtes"    "furent"  
 [97] "sois"     "soit"     "soyons"   "soyez"    "soient"   "fusse"    "fusses"   "fût"     
[105] "fussions" "fussiez"  "fussent"  "ayant"    "eu"       "eue"      "eues"     "eus"     
[113] "ai"       "as"       "avons"    "avez"     "ont"      "aurai"    "auras"    "aura"    
[121] "aurons"   "aurez"    "auront"   "aurais"   "aurait"   "aurions"  "auriez"   "auraient"
[129] "avais"    "avait"    "avions"   "aviez"    "avaient"  "eut"      "eûmes"    "eûtes"   
[137] "eurent"   "aie"      "aies"     "ait"      "ayons"    "ayez"     "aient"    "eusse"   
[145] "eusses"   "eût"      "eussions" "eussiez"  "eussent"  "ceci"     "cela"     "celà"    
[153] "cet"      "cette"    "ici"      "ils"      "les"      "leurs"    "quel"     "quels"   
[161] "quelle"   "quelles"  "sans"     "soi"     

Nous réduisons les mots à leur racine (“stemming”).

corpus <- tm_map(corpus, stemDocument, language = "french")
corpus  # check corpus
<<VCorpus>>
Metadata:  corpus specific: 0, document level (indexed): 0
Content:  documents: 36

Matrice terme-document

td.mat <- as.matrix(TermDocumentMatrix(corpus))
td.mat
                                         Docs
Terms                                      1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20
  000                                      0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  100                                      0  1  0  0  0  1  0  0  0  1  0  0  2  0  0  0  0  0  0  0
  1000                                     0  0  0  0  0  0  0  0  0  0  0  0  0  1  0  0  0  0  0  0
  1024x768                                 0  0  0  0  0  0  0  1  0  0  0  0  0  0  0  0  0  0  0  0
  10em                                     0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  128                                      0  0  0  0  0  0  0  0  0  0  0  0  0  0  1  0  1  0  0  0
  150                                      0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  15000                                    0  1  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  15h51                                    0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  16m50                                    0  0  1  0  0  0  0  0  0  0  0  1  0  0  0  0  0  0  0  0
  1997                                     0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  1  0  0  0  0
  1998                                     0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  1  0  0  0  0
  1v1                                      0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  1
  200                                      0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  2001                                     0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  3  8  0  0  0
  2002                                     0  0  0  0  0  0  0  0  0  0  0  0  0  0  3 12  0  0  0  0
  2003                                     0  0  0  0  0  0  0  0  0  0  0  0  0  3 10  0  0  0  0  0
  2004                                     0  0  0  0  0  0  0  0  0  0  0  0  2 10  1  0  0  0  0  0
  2005                                     0  0  0  0  0  0  0  0  0  0  0  1 13  0  0  0  0  0  0  0
  2006                                     0  0  0  0  0  0  0  0  0  0  1  0  0  0  0  0  0  0  0  0
  2007                                     0  0  0  0  0  0  0  0  0  0  6  0  0  0  0  0  0  0  0  0
  2008                                     0  0  0  0  0  0  0  0  3  0  0  0  0  0  0  0  0  0  0  0
  2009                                     0  0  0  0  0  0  0  0  1  0  0  0  0  0  0  0  0  0  0  0
  20092010                                 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  2010                                     0  0  0  0  0  0  0  1  0  0  0  0  0  0  0  0  0  0  0  0
  2011                                     0  0  0  0  0  0  1  0  0  0  0  0  0  0  0  0  0  0  1  0
  2014                                     0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
                                         Docs
Terms                                     21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
  000                                      0  0  0  0  0  0  0  0  0  1  1  0  0  0  1  0
  100                                      0  0  0  1  0  1  0  0  0  0  0  0  0  0  0  1
  1000                                     0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  1024x768                                 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  10em                                     0  0  0  0  0  0  0  0  0  0  0  0  0  0  1  0
  128                                      0  0  0  0  0  0  0  1  1  0  0  0  0  0  0  0
  150                                      0  0  0  0  1  0  0  0  0  0  0  0  0  0  0  0
  15000                                    0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  15h51                                    0  0  0  0  0  0  0  0  0  0  1  0  0  0  0  0
  16m50                                    0  0  0  0  1  0  0  0  0  0  0  0  0  0  0  0
  1997                                     0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  1998                                     0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  1v1                                      0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  200                                      0  0  0  0  1  0  0  0  0  0  0  0  0  0  0  0
  2001                                     0  0  0  0  0  0  0  0  0  0  0  0  0  1  0  0
  2002                                     0  0  0  0  0  0  0  0  0  0  0  1  5  0  0  0
  2003                                     0  0  0  0  0  0  1  0  0  0  0  7  0  0  0  0
  2004                                     0  0  0  0  0  0  0  0  0  3  3  0  0  0  0  0
  2005                                     0  0  0  0  0  0  0  0  0  4  0  0  0  0  0  0
  2006                                     0  0  0  0  0  0  0  0  0  0  0  0  0  0  1  0
  2007                                     0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  2008                                     0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  2009                                     0  0  0  0  0  1  0  0  0  0  0  0  0  0  0  0
  20092010                                 0  0  0  1  0  0  0  0  0  0  0  0  0  0  0  0
  2010                                     0  0  1  0  0  0  0  0  0  0  0  0  0  0  0  0
  2011                                     0  0  0  1  0  0  0  0  0  0  0  0  0  0  0  0
  2014                                     1  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
 [ reached getOption("max.print") -- omitted 5137 rows ]

Matrice des distances

dist.mat <- dist(t(as.matrix(td.mat)))
dist.mat
          1        2        3        4        5        6        7        8        9       10       11
2  61.13101                                                                                          
3  63.22974 47.14870                                                                                 
4  58.89822 52.64979 50.08992                                                                        
5  60.67949 49.62862 50.99020 53.18834                                                               
6  63.37981 47.51842 46.65833 55.62374 46.59399                                                      
7  63.17436 46.08687 43.48563 51.51699 46.48656 40.49691                                             
8  60.02499 48.24935 49.20366 51.63332 48.42520 47.22288 45.58509                                    
9  63.28507 49.01020 49.64877 54.22177 47.90616 46.75468 44.11349 48.55924                           
10 62.05643 48.22862 45.04442 51.88449 47.48684 43.61192 42.47352 43.97727 46.04346                  
11 65.41407 51.61395 49.86983 53.25411 50.58656 49.77951 44.36215 48.18714 49.83974 45.89118         
12 64.72248 54.99091 54.74486 57.11392 52.65928 52.83938 50.93133 53.12250 54.38750 52.61179 48.66210
13 61.07373 51.27377 54.25864 55.74047 51.61395 50.84290 49.78956 48.25971 51.85557 46.63690 51.91339
14 67.02238 52.43091 53.51635 58.47222 51.41984 48.71345 47.10626 52.56425 51.85557 48.69292 52.65928
15 62.86493 48.28043 48.39421 53.99074 49.11212 47.27579 43.50862 47.31807 48.34253 45.94562 50.34878
16 67.74954 48.71345 48.41487 58.18075 51.55580 46.89350 44.07947 51.05879 49.70915 47.14870 52.22069
17 71.62402 49.30517 46.54031 58.83026 51.61395 43.64631 41.60529 51.44900 47.92703 43.34743 51.41012
18 65.21503 53.16014 51.29327 57.00877 52.22069 47.72840 48.08326 51.14685 50.77401 47.51842 52.57376
19 68.20557 58.40377 60.18305 58.31809 61.57922 61.14736 60.77006 57.08765 61.95966 58.36951 60.34070
20 63.98437 51.52669 49.29503 54.78138 53.81450 49.54796 48.05206 47.67599 51.89412 44.19276 50.80354
21 68.32276 55.23586 55.22681 57.76677 53.64699 52.35456 50.46781 51.15662 54.32311 49.24429 52.27810
22 67.46110 52.28767 52.64029 58.56620 52.29723 47.30750 47.07441 51.16640 51.02940 46.73329 53.70289
23 69.49101 60.90977 57.48913 60.11655 59.82474 58.77074 57.35852 59.26213 62.06448 57.74080 57.89646
24 69.55573 61.83041 63.87488 65.19969 61.02459 64.36614 59.57348 58.59181 63.28507 61.63603 62.20129
25 70.49113 66.04544 64.62971 64.24951 65.13831 66.18157 62.56197 61.04097 66.60330 64.04686 60.71244
26 66.09841 57.37595 56.96490 59.93330 53.37602 56.16048 54.29549 52.47857 56.79789 51.82663 52.28767
27 65.77994 54.71746 55.10898 57.70615 52.52618 53.06600 51.32251 52.42137 51.69139 49.49747 53.83308
28 66.00758 56.21388 56.70097 61.31884 52.96225 53.21654 52.93392 54.89991 52.87722 51.04900 55.24491
29 64.06247 53.87950 53.36666 57.47173 56.32051 53.00000 52.37366 53.33854 52.73519 52.08647 55.05452
         12       13       14       15       16       17       18       19       20       21       22
2                                                                                                    
3                                                                                                    
4                                                                                                    
5                                                                                                    
6                                                                                                    
7                                                                                                    
8                                                                                                    
9                                                                                                    
10                                                                                                   
11                                                                                                   
12                                                                                                   
13 50.98039                                                                                          
14 52.98113 51.92302                                                                                 
15 51.05879 49.61854 49.43683                                                                        
16 55.93747 53.57238 49.55805 45.54119                                                               
17 57.14018 53.85165 46.84015 46.75468 40.14972                                                      
18 57.68882 54.23099 49.99000 52.33546 48.69292 47.84349                                             
19 63.45865 61.69279 63.62389 61.67658 61.59545 62.96030 55.16339                                    
20 56.24055 52.23026 53.46027 50.33885 48.96938 47.91659 52.04805 57.16642                           
21 55.41660 56.23166 53.98148 54.16641 52.11526 51.90376 49.80964 56.00000 50.95096                  
22 56.35601 53.78662 50.28916 50.62608 46.70118 46.01087 48.14561 60.12487 45.42026 49.48737         
23 61.44917 62.76145 62.88879 60.83584 59.53990 60.81940 59.71599 59.42222 55.07268 57.28001 60.39868
24 64.87681 62.48200 63.41924 60.41523 63.11894 67.70524 63.99219 68.38128 60.53098 63.51378 63.92965
25 62.52999 65.52099 67.29785 63.30087 65.65821 70.02143 64.43601 63.09517 60.80296 63.07932 64.48256
26 57.89646 57.12268 54.98182 55.91959 56.09813 56.36488 54.77226 58.96609 52.98113 53.46962 55.51576
27 54.60769 54.90902 52.81098 52.65928 52.92447 53.20714 52.30679 59.23681 52.60228 51.93265 52.61179
28 56.63921 55.95534 54.94543 53.46962 54.43345 55.54278 51.74940 64.10148 55.79426 54.76313 54.93633
29 58.00862 56.12486 56.48008 53.25411 53.23533 54.11100 54.54356 60.79474 53.08484 57.06137 54.83612
         23       24       25       26       27       28       29       30       31       32       33
2                                                                                                    
3                                                                                                    
4                                                                                                    
5                                                                                                    
6                                                                                                    
7                                                                                                    
8                                                                                                    
9                                                                                                    
10                                                                                                   
11                                                                                                   
12                                                                                                   
13                                                                                                   
14                                                                                                   
15                                                                                                   
16                                                                                                   
17                                                                                                   
18                                                                                                   
19                                                                                                   
20                                                                                                   
21                                                                                                   
22                                                                                                   
23                                                                                                   
24 62.29767                                                                                          
25 54.68089 59.13544                                                                                 
26 52.57376 56.40035 54.62600                                                                        
27 56.67451 56.40035 60.31584 48.20788                                                               
28 59.84981 59.35487 64.24951 53.53504 51.73007                                                      
29 59.59027 60.69596 61.16371 57.26255 53.46962 53.11309                                             
         34       35
2                   
3                   
4                   
5                   
6                   
7                   
8                   
9                   
10                  
11                  
12                  
13                  
14                  
15                  
16                  
17                  
18                  
19                  
20                  
21                  
22                  
23                  
24                  
25                  
26                  
27                  
28                  
29                  
 [ reached getOption("max.print") -- omitted 7 rows ]

plot(hclust(dist.mat))


Classical multidimensional scaling

fit <- cmdscale(dist.mat, eig = TRUE, k = 2)    

On prépare les données pour la visualisation.

points <- data.frame(x = fit$points[, 1], y = fit$points[, 2], name = fifa$journal)

Résultat.

ggplot(points, aes(x = x, y = y)) + 
  geom_point(aes(color = name)) +
  geom_text(aes(label = name), nudge_y = 1.5)

LS0tCnRpdGxlOiAiUiBldCBzdGF0aXN0aXF1ZSB0ZXh0dWVsbGUiCmF1dGhvcjogIllhbm5pY2sgUm9jaGF0IgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIGRmX3ByaW50OiBwYWdlZAogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQKICBzbGlkeV9wcmVzZW50YXRpb246IGRlZmF1bHQKc3VidGl0bGU6IENvdXJzIGJsb2MsIDgtOS4xMS4yMDE3LCBVTklMCkRhdGU6IDkgbm92ZW1icmUgMjAxNwotLS0KCiMjIFF1ZWxxdWVzIHJlc3NvdXJjZXMgZ8OpbsOpcmFsZXMKCioqSW50cm9kdWN0aW9uIMOgIFIgZXQgYXUgdGlkeXZlcnNlKiogZGUgSnVsaWVuIEJhcm5pZXIKCmh0dHBzOi8vanViYS5naXRodWIuaW8vdGlkeXZlcnNlCgoqKlIgZm9yIERhdGEgU2NpZW5jZSoqIGRlIEdhcnJldHQgR3JvbGVtdW5kICYgSGFkbGV5IFdpY2toYW0KCmh0dHA6Ly9yNGRzLmhhZC5jby5uei8KCi0tLQoKIyMgUXUnZXN0LWNlIHF1J3VuIG5vdGVib29rID8KCkNlIGRvY3VtZW50IHF1ZSB2b3VzIGF2ZXogb3V2ZXJ0IGRhbnMgUlN0dWRpbyBvdSBkYW5zIHVuIG5hdmlnYXRldXIgd2ViIGVzdCB1biBub3RlYm9vay4KCi0tLQoKQydlc3QgdW4gZm9ybWF0IGRlIGRvY3VtZW50IHBlcm1ldHRhbnQgZGUgcHLDqXNlbnRlciBkdSB0ZXh0ZSwgZHUgY29kZSwgZXQgbGVzIHLDqXN1bHRhdHMgZGUgbCdleMOpY3V0aW9uIGR1IGNvZGUuCgotLS0KCkRhbnMgbGEgcmVjaGVyY2hlIHNjaWVudGlmaXF1ZSwgY2UgZm9ybWF0IHBlcm1ldCBkZSByw6lwbGlxdWVyIHVuZSBleHDDqXJpZW5jZS4KCklsIGVzdCBlbiBwYXNzZSBkZSBkZXZlbmlyIHVuIHN0YW5kYXJkLgoKLS0tCgpMZSBzeXN0w6htZSBkZSBub3RlYm9va3MgbGUgcGx1cyByw6lwYW5kdSBlc3QgSnVweXRlciwgcXVpIGZvbmN0aW9ubmUgYXZlYyBsZSBsYW5nYWdlIGRlIHByb2dyYW1tYXRpb24gUHl0aG9uIG1haXMgcGVybWV0IMOpZ2FsZW1lbnQgZGUgZ8OpcmVyIGQnYXV0cmVzIGxhbmdhZ2VzIGRlIHByb2dyYW1tYXRpb24gdGVsIFIuCgotLS0KCkljaSwgbm91cyB1dGlsaXNvbnMgZGVzIG5vdGVib29rcyBhdSBmb3JtYXQgcHLDqXZ1IHBhciBSU3R1ZGlvLiAKClVuIG5vdGVib29rIHBldXQgc2UgZMOpY2xpbmVyIGVuIHBsdXNpZXVycyBmb3JtYXRzLgoKKiBMZSBmaWNoaWVyIGF1IGZvcm1hdCBgLlJtZGAgcydvdXZyZSBkYW5zIFJTdHVkaW8uIElsIGVzdCBpbnRlcmFjdGlmLgoqIExlIGZpY2hpZXIgYXUgZm9ybWF0IGAubmIuaHRtbGAgcydvdXZyZSBkYW5zIHVuIG5hdmlnYXRldXIuIElsIG4nZXN0IHBhcyBpbnRlcmFjdGlmLgoqIExlIGZpY2hpZXIgYXUgZm9ybWF0IGAuaHRtbGAgY29udGllbnQgbGVzIHNsaWRlcyAoZGFucyBsZSBjYXMgcHLDqXNlbnQpLgoKLS0tCgpMZSBjb2RlIGFwcGFyYcOudCBzeXN0w6ltYXRpcXVlbWVudCBkYW5zIHVuZSBjYXNlIHN1ciBmb25kIGdyaXMuCgpMZSByw6lzdWx0YXQgZHUgY29kZSBhcHBhcmHDrnQgZW5zdWl0ZSBkYW5zIHVuZSBjYXNlIHN1ciBmb25kIGJsYW5jLgoKYGBge3J9CmZvciAoaSBpbiAxOjMpIHByaW50KExFVFRFUlNbaV0pCmBgYAoKCi0tLQoKRW4gb3V2cmFudCBsZSBub3RlYm9vayBkYW5zIFJTdHVkaW8sIHZvdXMgYXVyZXogbGEgcG9zc2liaWxpdMOpIGRlIG1vZGlmaWVyIGxlIGNvZGUgZXQgZGUgbGUgcsOpZXjDqWN1dGVyLgoKLS0tCgpQYXIgZXhlbXBsZSwgZGFucyBsZSBjb2RlIGNpLWRlc3NvdXMsIG5vdXMgc2F1dm9ucyBsYSB2YWxldXIgIjIiIGRhbnMgbGEgdmFyaWFibGUgImEiIGV0IGxhIHZhbGV1ciAiZSIgZGFucyBsYSB2YXJpYWJsZSAiYiIuIFB1aXMgbm91cyDDqWxldm9ucyBhIMOgIGxhIHB1aXNzYW5jZSBiLCBjJ2VzdC3DoC1kaXJlIDIgw6AgbGEgcHVpc3NhbmNlIDMuIAoKTGUgcsOpc3VsdGF0IHMnYWZmaWNoZSBlbi1kZXNzb3VzLgoKYGBge3J9CmEgPC0gMgpiIDwtIDMKYV5iCmBgYAoKRXNzYXlleiBkZSBtb2RpZmllciBsZXMgdmFsZXVycywgcHVpcyBjbGlxdWV6IHN1ciBsYSBmbMOoY2hlIHZlcnRlIHBvdXIgdm9pciBsZSByw6lzdWx0YXQuCgotLS0KCiMjIFIsIHF1J2VzdC1jZSA/CgpSIGVzdCB1biBsYW5nYWdlIGRlIHByb2dyYW1tYXRpb24gw6AgbCdvcmlnaW5lIHByw6l2dSBwb3VyIGZhaXJlIGRlIGwnYW5hbHlzZSBzdGF0aXN0aXF1ZSBzdXIgbGEgYmFzZSBkdSBsYW5nYWdlIHByb3ByacOpdGFpcmUgUy4gU29uIHVzYWdlIHMnZXN0IHLDqXBhbmR1IGJpZW4gYXUtZGVsw6AuCgotLS0KClIgcGV1dCBwYXIgZXhlbXBsZSDDqnRyZSBsYW5jw6kgZGFucyB1biB0ZXJtaW5hbC4KCk1haXMgUiBkw6lzaWduZSDDqWdhbGVtZW50IHVuZSBpbnRlcmZhY2UgZGUgcHJvZ3JhbW1hdGlvbiBxdWUgbCdvbiBub21tZSBSIEdVSSwgIkdVSSIgc2lnbmlmaWFudCAiR3JhcGhpY2FsIFVzZXIgSW50ZXJmYWNlIi4KClIgR1VJIGVzdCB1biBsb2dpY2llbCBsaWJyZS4KCi0tLQoKIyMg4oCmIGV0IFJTdHVkaW8gPwoKUlN0dWRpbyBlc3QgdW4gZW52aXJvbm5lbWVudCBwZXJtZXR0YW50IGRlIHByb2dyYW1tZXIgZW4gUiwgYydlc3Qtw6AtZGlyZSB1biBwZXUgcGx1cyBxdSd1bmUgc2ltcGxlIGludGVyZmFjZSBncmFwaGlxdWUuCgotLS0KCkVuIHBsdXMgZCdhZmZpY2hlciB1bmUgY29uc29sZSAobMOgIG/DuSBsZSBjb2RlIGVzdCBleMOpY3V0w6kpIGV0IHVuZSBmZW7DqnRyZSBkZSBzY3JpcHQgKGzDoCBvw7kgbCdvbiByw6lkaWdlIGxlIGNvZGUgcXVlIGwnb24gdmV1dCByw6l1dGlsaXNlciksIFJTdHVkaW8gcGVybWV0IHBhciBleGVtcGxlIGRlIGNvbm5hw650cmUgZW4gdG91dCB0ZW1wcyBsZXMgdmFyaWFibGVzIGVucmVnaXN0csOpZXMgZW4gbcOpbW9pcmUsIG91IGVuY29yZSBkJ3V0aWxpc2VyIHVuIG5vdGVib29rIGNvbW1lIGNlbHVpLWNpLgoKLS0tCgpEYW5zIGNlIG1vZHVsZSBkZSBjb3Vycywgbm91cyBhbGxvbnMgdHJhdmFpbGxlciBhdmVjIFJTdHVkaW8uCgotLS0KCiMjIEV4ZW1wbGVzIGRlIGJhc2UKCgpgYGB7cn0KNCArIDMgICAgICAgICAjIyBVbmUgc2ltcGxlIGFkZGl0aW9uCjJeMiArIDMqNCAgICAgIyMgUHJpb3JpdMOpIGRlcyBvcMOpcmF0aW9ucwpgYGAKCi0tLS0KCmBgYHtyfQp6ID0gMTIuNSAgICAgICMjIFNhdXZlZ2FyZGUgZCd1bmUgdmFsZXVyIGRhbnMgdW5lIHZhcmlhYmxlCnogPC0gMTIuNSAgICAgIyMgUHJpdmlsw6lnaWVyIGwndXRpbGlzYXRpb24gZGUgbGEgZmzDqGNoZSA8LQp6CmBgYAoKLS0tCgpgYGB7cn0KeCA8LSAxMi41CnkgPC0gNy41CnggKyB5CmBgYAoKLS0tLQoKYGBge3J9CnkgPSBzcXJ0KDQpICAgICMjIEZvbmN0aW9uIHJhY2luZSBjYXJyw6llCnkKYGBgCgotLS0KCmBgYHtyfQpscygpICAgICMjIExlcyB2YXJpYWJsZXMgc2F1dsOpZXMgZGFucyBsJ2Vudmlyb25uZW1lbnQgZGUgdHJhdmFpbApybSh5KSAgICMjIE9uIHJldGlyZSBsYSB2YXJpYWJsZSAieSIKbHMoKQpgYGAKCi0tLS0KCmBgYHtyfQpjbGFzcyh6KSAgICAgICAgICAgICAgICAgICAgICMjIExlIHR5cGUgZCd1bmUgdmFyaWFibGUKYGBgCgotLS0KCmBgYHtyIGV2YWwgPSBGQUxTRX0KaGVscChleHApICAgICAgICAgICAgICAgICAgICAgIyMgTGEgcGFnZSBkJ2FpZGUgZCd1bmUgdmFyaWFibGUKP2V4cCAgICAgICAgICAgICAgICAgICAgICAgICAgIyMgSWRlbQpoZWxwLnNlYXJjaCgibGluZWFyIG1vZGVsIikgICAjIyBDaGVyY2hlciBkYW5zIGxlcyBwYWdlcyBkJ2FpZGUKYGBgCgotLS0KCkRhbnMgY2Ugbm90ZWJvb2sgY29tbWUgZGFucyBsZXMgc2NyaXB0cyBxdWUgdm91cyB0cm91dmVyZXogZW4gbGlnbmUsIGxlcyBmb25jdGlvbnMgc29ydGVudCBkdSBjaGFwZWF1IGNvbW1lIHNpIGRlIHJpZW4gbifDqXRhaXQuCgpOZSB2b3VzIGZhaXRlcyBwYXMgZCdpbGx1c2lvbnM6IAoKKiBJbCBhIGQnYWJvcmQgZmFsbHUgZMOpY291dnJpciBsZXVyIGV4aXN0ZW5jZS4KKiBQdWlzIGNvbXByZW5kcmUgbGV1ciBmb25jdGlvbm5lbWVudC4KKiBMZSBwbHVzIHNvdXZlbnQgZW4gZmFpc2FudCBxdWVscXVlcyBlcnJldXJzIGF1IHBhc3NhZ2UgXl4KCi0tLQoKQydlc3QgcG91ciBjZXR0ZSByYWlzb24gcXUnaWwgbmUgZmF1dCAqKmphbWFpcyoqIGjDqXNpdGVyIMOgIGZhaXJlIHVuZSByZWNoZXJjaGUgCgoqIGRhbnMgbGVzIHBhZ2VzIGQnYWlkZSBkZSBSCiAgKyBhdmVjIGA/YCBsb3JzcXUnb24gY29ubmHDrnQgbGEgZm9uY3Rpb24uCiAgKyBhdmVjIGA/P2AgbG9yc3F1J29uIG5lIGxhIGNvbm5hw650IHBhcy4KKiBlbiBsaWduZSAKICArIHN1ciBzdGFja292ZXJmbG93CiAgKyBzdXIgdW4gbW90ZXVyIGRlIHJlY2hlcmNoZQoKLS0tCgoKIyMjIENoYcOubmVzIGRlIGNhcmFjdMOocmVzCgoKYGBge3J9CmIgPC0gInVuaWwiCmMgPC0gInBhdGllbnQgMSIKbmNoYXIoYikKbmNoYXIoYykKcGFzdGUoYiwgYywgY29sbGFwc2UgPSAiIikKYGBgCgoKLS0tLQoKIyMjIMOJbMOpbWVudHMgbG9naXF1ZXMKCiogVFJVRSBldCBGQUxTRQoKTWFpcyBhdXNzaeKApgoKKiBOQSwgTmFOCiogSW5mCgotLS0tCgpgYGB7cn0KMS8wCnggPC0gSW5mCnggLSB4CmBgYAoKIk5BIiBzaWduaWZpZSAiTm90IGF2YWlsYWJsZSIuCgoiTmFOIiBzaWduaWZpZSAiTm90IGEgTnVtYmVyIi4KCi0tLS0KCiMjIyBPcMOpcmF0ZXVycyBhcml0aG3DqXRpcXVlcwoKKiBcKyAKKiBcLSAKKiBcKiAKKiAvIAoqIMuGIAoqICUlIAoqICUvJSAKKiAlKiUgCgotLS0tCgoKIyMjIE9wZXJhdGV1cnMgZGUgY29tcGFyYWlzb25zCgoKYGBge3IgZXJyb3IgPSBUUlVFfQoxID09IDEKMSA9PSAyCjEgIT0gMSAKYGBgCgotLS0KCmBgYHtyfQoxICE9IDIKMSA8IDEKMSA8PSAxCmBgYAoKLS0tLQoKIyMjIE9ww6lyYXRldXJzIGxvZ2lxdWVzCgpgYGB7cn0KYSA8LSAoMSA8IDIpCmEKIWEKYGBgCgotLS0tCgpgYGB7cn0KYiA8LSAoMiA+IDMpCmEgJiBiCmEgfCBiCmBgYAoKCiMjIENvbW1lbnQgY29ubmHDrnRyZSBsZSB0eXBlIGQndW5lIHZhcmlhYmxlID8KCmBgYHtyfQphIDwtIDEKYiA8LSAxOjUKY2xhc3MoYSkKY2xhc3MoYikKYGBgCgotLS0tCgpgYGB7cn0KYyA8LSAiaGVsbG8iCmQgPC0gMSA+IDIKY2xhc3MoYykKY2xhc3MoZCkKYGBgCgotLS0tCgpRdWVsbGUgZXN0IGxhICJ0YWlsbGUiIGRlIGwnb2JqZXQgPwoKYGBge3J9Cmxlbmd0aChhKQpsZW5ndGgoYikKbGVuZ3RoKGMpCmxlbmd0aChkKQpgYGAKCi0tLS0KCmBzdHJgIGZvdXJuaXQgdW5lIGRlc2NyaXB0aW9uIGRlIGwnb2JqZXQKCmBgYHtyfQpzdHIoYSkKc3RyKGIpCnN0cihjKQpzdHIoZCkKYGBgCgotLS0KCiMjIENsYXNzZXMgKGRlIGJhc2UpCgoqIFZlY3RldXJzCiogTGlzdGVzCiogTWF0cmljZXMKKiBUYWJsZXMKKiAqRGF0YSBmcmFtZXMqCgoKIyMgVmVjdGV1cnMKCgpgYGB7cn0KeCA8LSBjKDUsNCw1LDYsNyw4KSAKeAp4X2NoYXIgPSBjKCJhIiwiYiIsImMiKSAKeF9jaGFyCmBgYAoKLS0tLQoKQWNjw6lkZXIgZGlyZWN0ZW1lbnQgw6AgdW4gw6lsw6ltZW50IGQndW4gdmVjdGV1cgoKYGBge3J9CngKeFsyXQp4W2MoMiw0KV0KYGBgCgotLS0KYGBge3J9CngKeFtjKC0yLC00KV0KYGBgCgoKLS0tLQoKTWFuaXB1bGVyIGRlcyB2ZWN0ZXVycwoKYGBge3J9CnhbNl0gPSAxMAp4CmBgYAoKLS0tCgpgYGB7cn0KYSA9IGMoMyw0LDUsNikKYVtjKDIsMyldID0gMAphCmBgYAoKLS0tCgpgYGB7cn0KYVtjKDIsMyldID0gYyg4LDcpCmEKYGBgCgotLS0tCgpgYGB7cn0KYygxLDIsMykgKyBjKDMsNCw1KQpgYGAKCi0tLS0KCmBgYHtyfQo0ICogYygxLDIsMykKYygyLDUpIDwgNApgYGAKCi0tLS0KCkF0dGVudGlvbiBsb3JzcXVlIGRldXggw6lsw6ltZW50cyBuZSBzb250IHBhcyBkZSBtw6ptZSB0YWlsbGUgIQoKYGBge3J9CmMoMSwyKSArIGMoMyw0LDUsNikKYGBgCgotLS0tCgpBdHRlbnRpb24gbG9yc3F1ZSBsJ3VuIG4nZXN0IHBhcyBtdWx0aXBsZSBkZSBsJ2F1dHJlICEKCmBgYHtyfQpjKDEsMikgKyBjKDIsMyw0KQpgYGAKCi0tLQoKIyMgRGF0YSBmcmFtZXMKCgoKYGBge3J9CmRmIDwtIGRhdGEuZnJhbWUoYWdlID0gYygyNCwgMjYsIDQ5LCA1MiwgMTQpLCAKICAgICAgICAgICAgICAgICB0YWlsbGUgPSBjKDE2MCwgMTgwLCAxNzgsIDE4MCwgMTUwKSkKZGYKYGBgCgotLS0tCgoKIyMgQ29tbWVudCBmb25jdGlvbm5lbnQgbGVzIHBhY2thZ2VzID8KCkxvcnNxdSdvbiBkw6ltYXJyZSB1bmUgc2Vzc2lvbiBkYW5zIFJTdHVkaW8gKG91IGRhbnMgUi9SIEdVSSksIHVuZSBzw6lyaWUgZGUgZm9uY3Rpb25zIHNvbnQgaW1tw6lkaWF0ZW1lbnQgZGlzcG9uaWJsZXMsIHRlbGxlcyBsZXMgb3DDqXJhdGlvbnMgbWF0aMOpbWF0aXF1ZXMgZGUgYmFzZSBldCBxdWVscXVlcyBmb25jdGlvbnMgcGVybWV0dGFudCBkZSBmYWlyZSBkZSBsJ2FuYWx5c2Ugc3RhdGlzdGlxdWUgb3UgZGUgbGEgdmlzdWFsaXNhdGlvbi4KCi0tLQoKRW5zdWl0ZSwgZW4gZm9uY3Rpb24gZGUgc2VzIGJlc29pbnMsIG9uIGNoYXJnZSBkYW5zIFIgZGVzICpwYWNrYWdlcyogc3VwcGzDqW1lbnRhaXJlcywgYydlc3Qtw6AtZGlyZSBkZXMgZW5zZW1ibGVzIGRlIGZvbmN0aW9ucyBjcsOpw6llcyBldCByw6l1bmllcyBhdXRvdXIgZCd1biBidXQgY29tbXVuLgoKQ2hhcXVlICpwYWNrYWdlKiBkaXNwb25pYmxlIHBvdXIgUiBlc3Qgb3BlbiBzb3VyY2UgKG5vcm1hbGVtZW50KS4KCi0tLQoKSWwgZXhpc3RlIHBsdXMgZGUgMTAnMDAwICpwYWNrYWdlcyogc3VyIGxhIHBsYXRlZm9ybWUgW0NSQU5dKGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnKSBldCBlbmNvcmUgZGUgbm9tYnJldXggYXV0cmVzIGVuIGRlaG9ycywgcGFyIGV4ZW1wbGUgc3VyIEdpdEh1Yi4KCi0tLQoKVW4gcGFja2FnZSBkb2l0IMOqdHJlICoqaW5zdGFsbMOpKiogdW5lIGV0IHVuZSBzZXVsZSBmb2lzLiBDZWxhIHNlIGZhaXQgYXZlYyBsYSBmb25jdGlvbiBgaW5zdGFsbC5wYWNrYWdlc2AKClVuIHBhY2thZ2UgZG9pdCDDqnRyZSAqKmNoYXJnw6kqKiDDoCBjaGFxdWUgdXRpbGlzYXRpb24gZGUgUi4gQ2VsYSBzZSBmYWl0IGF2ZWMgbGEgZm9uY3Rpb24gYGxpYnJhcnlgCgoKLS0tCgpTaSBsZSAqcGFja2FnZSogZXN0IG1pcyDDoCBqb3VyLCAgbGFuY2VyIGxhIGZvbmN0aW9uIGBpbnN0YWxsLnBhY2thZ2VzYCBwZXJtZXR0cmEgZGUgbCdhY3R1YWxpc2VyLgoKSWwgZXN0IHBvc3NpYmxlIGRlIGfDqXJlciBsZXMgKnBhY2thZ2VzKiwgeSBjb21wcmlzIGRlIGxlcyBpbnN0YWxsZXIsIGRhbnMgbGUgbWVudSAqKlRvb2xzKiogPiAqKkluc3RhbGwgcGFja2FnZXPigKYqKgoKLS0tCgpEZXMgZXhlbXBsZXMgZGUgKnBhY2thZ2VzKgoKKiAqKnNwKiogcGVybWV0IGRlIGZhaXJlIGRlIGwnYW5hbHlzZSBkZSBkb25uw6llcyBzcGF0aWFsaXPDqWVzLgoqICoqZ2dwbG90MioqIGVzdCB1biBwYWNrYWdlIHBvcHVsYWlyZSBwb3VyIHLDqWFsaXNlciBkZXMgdmlzdWFsaXNhdGlvbnMgZGUgZG9ubsOpZXMuCiogKippZ3JhcGgqKiBlc3QgdW4gcGFja2FnZSBwZXJtZXR0YW50IGRlIGZhaXJlIGRlIGwnYW5hbHlzZSBkZSByw6lzZWF1eC4KKiAqKnNoaW55KiogcGVybWV0IGRlIGNyw6llciBkZXMgYXBwbGljYXRpb25zIHdlYi4KCi0tLQoKTCdpbnN0YWxsYXRpb24gZGVzICpwYWNrYWdlcyogbsOpY2Vzc2FpcmVzIHBvdXIgZmFpcmUgdG91cm5lciBsZSBjb2RlIGRlIGNlIG5vdGVib29rIGVzdCBlbiBnw6luw6lyYWwgcsOpYWxpc8OpZSBhdXRvbWF0aXF1ZW1lbnQgZ3LDomNlIGF1eCBkZXV4IGxpZ25lcyBkZSBjb2RlIHN1aXZhbnRlcy4gCgotLS0KClNpIGxlICpwYWNrYWdlKiBlc3QgZMOpasOgIGluc3RhbGzDqSwgbGUgcHJvZ3JhbW1lIHNhdXRlIMOgIGxhIHNlY29uZGUgbGlnbmUgZXQgc2UgY29udGVudGUgZGUgY2hhcmdlciBsZSAqcGFja2FnZSouIFNpIGNlIG4nZXN0IHBhcyBsZSBjYXMsIGlsIHMnb2NjdXBlIGQnYWJvcmQgZGUgbCdpbnN0YWxsZXIgKGxpZ25lIDEpIHB1aXMgbGUgY2hhcmdlLgoKYGBge3J9CmlmICghcmVxdWlyZShydHdlZXQpKSBpbnN0YWxsLnBhY2thZ2VzKCJydHdlZXQiKSAjIyBpbnN0YWxsYXRpb24KbGlicmFyeShydHdlZXQpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIyBjaGFyZ2VtZW50CmBgYAoKLS0tCgpgcnR3ZWV0YCBlc3QgdW4gcGFja2FnZSBwZXJtZXR0YW50IGRlIHLDqWN1cMOpcmVyIGV0IGQnYW5hbHlzZXIgZGVzIHR3ZWV0cyAoY2VzIGNvdXJ0cyBtZXNzYWdlcyBwb3N0w6lzIHN1ciBUd2l0dGVyKS4KCi0tLQoKRGFucyBjZXQgZXhlbXBsZSwgb24gY2hhcmdlIGxlcyAxMDAgZGVybmllcnMgdHdlZXRzIGNvbnRlbmFudCBsZSBtb3QgInVuaWwiLgoKSWwgZXN0IHByb2JhYmxlIHF1J3VuICp3YXJuaW5nKiBzJ2FmZmljaGUuCgpgYGB7cn0KdHdlZXRzIDwtIHNlYXJjaF90d2VldHMoInVuaWwiLCBuID0gMTAwKQpgYGAKCi0tLQoKVW4gYXBlcsOndSBkZSBjZXMgdHdlZXRzLgoKYGBge3J9CnR3ZWV0cwpgYGAKCi0tLQoKVmlzdWFsaXNvbnMgbGVzIGRhdGVzIGQnZW52b2kgZGVzIHR3ZWV0cy4KCi0tLQoKVG91dCBkJ2Fib3JkLCBvbiBjaGFyZ2UgbGUgcGFja2FnZSBnZ3Bsb3QyIHF1aSBmb3Vybml0IGRlIG5vdXZlbGxlcyBmb25jdGlvbnMgcG91ciBmYWlyZSBkZSBsYSB2aXN1YWxpc2F0aW9uLgoKYGBge3J9CmlmICghcmVxdWlyZShnZ3Bsb3QyKSkgaW5zdGFsbC5wYWNrYWdlcygiZ2dwbG90MiIpCmxpYnJhcnkoZ2dwbG90MikKYGBgCgotLS0KClB1aXMgb24gY3LDqWUgdW4gaGlzdG9ncmFtbWUgYXZlYyBub3MgZG9ubsOpZXMgKGxhIGNvbG9ubmUgImNyZWF0ZWRfYXQiIGRhbnMgbGUgdGFibGVhdSBjaS1kZXNzdXMpLgoKVm9pY2kgbGUgcsOpc3VsdGF0IGJydXQuCgotLS0KCmBgYHtyfQpnZ19iYXNpYyA8LSBnZ3Bsb3QodHdlZXRzLCBhZXMoeCA9IGNyZWF0ZWRfYXQpKSArCiAgICAgICBnZW9tX2hpc3RvZ3JhbSgpCmBgYAoKLS0tCgpgYGB7cn0KZ2dfYmFzaWMKYGBgCgotLS0KCk9uIHBldXQgbCdhbcOpbGlvcmVyIGVuIGFqb3V0YW50IGRlcyBvcHRpb25zLgoKYGBge3J9CmdnX21pZXV4IDwtIGdncGxvdCh0d2VldHMsIGFlcyh4ID0gY3JlYXRlZF9hdCkpICsKICAgICAgIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMzYwMCkgKwogICAgICAgc2NhbGVfeF9kYXRldGltZShkYXRlX2JyZWFrcyA9ICIzIGhvdXIiLCAKICAgICAgICAgICAgICAgICAgICAgICAgZGF0ZV9taW5vcl9icmVha3MgPSAiMSBob3VyIiwgCiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGVfbGFiZWxzID0gIiVtLSVkICVIaCIsIAogICAgICAgICAgICAgICAgICAgICAgICBuYW1lID0gIkRhdGUgZGUgY3LDqWF0aW9uIGR1IHR3ZWV0IikgKwogICAgICAgc2NhbGVfeV9jb250aW51b3VzKG5hbWUgPSAiTm9tYnJlIGRlIHR3ZWV0cyIpCmBgYAoKLS0tCgpgYGB7cn0KZ2dfbWlldXgKYGBgCgotLS0KCkF2ZWMgbGUgdGjDqG1lICJtaW5pbWFsIi4KCmBgYHtyfQpnZ19taW5pbWFsIDwtIGdnX21pZXV4ICsgdGhlbWVfbWluaW1hbCgpCmBgYAoKLS0tCgpgYGB7cn0KZ2dfbWluaW1hbApgYGAKCi0tLQoKIyMjIENoZWF0IHNoZWV0cwoKUG91ciBkZSBub21icmV1c2VzIHTDomNoZXMgZW4gUiwgb24gdHJvdXZlIGRlcyBbZmV1aWxsZXMgZGUgdHJpY2hlXShodHRwczovL3d3dy5yc3R1ZGlvLmNvbS9yZXNvdXJjZXMvY2hlYXRzaGVldHMvKS4KClBhciBleGVtcGxlLCBpbCBlbiBleGlzdGUgdW5lIHBvdXIgYGdncGxvdDJgLgoKaHR0cHM6Ly9naXRodWIuY29tL3JzdHVkaW8vY2hlYXRzaGVldHMvcmF3L21hc3Rlci9kYXRhLXZpc3VhbGl6YXRpb24tMi4xLnBkZgoKLS0tCgojIyMgR3V0ZW5iZXJnCgpJbCBleGlzdGUgdW4gKnBhY2thZ2UqIHBvdXIgdMOpbMOpY2hhcmdlciBsZXMgY29udGVudXMgZGUgaHR0cHM6Ly93d3cuZ3V0ZW5iZXJnLm9yZy8KCmBgYHtyfQppZiAoIXJlcXVpcmUoZ3V0ZW5iZXJncikpIGluc3RhbGwucGFja2FnZXMoImd1dGVuYmVyZ3IiKQpsaWJyYXJ5KGd1dGVuYmVyZ3IpCmBgYAoKLS0tCgpOb3VzIGF2b25zIGJlc29pbiBhdSBwYXNzYWdlIGR1IHBhY2thZ2UgYGRwbHlyYCBwb3VyIHV0aWxpc2VyIGxlcyAlPiUgKCJwaXBlcyIpLgoKTGVzICpwaXBlcyogcGVybWV0dGVudCBkZSByw6lkaWdlciBkdSBjb2RlIHMnZXjDqWN1dGFudCBkZSBnYXVjaGUgw6AgZHJvaXRlLiBJbCBkZXZpZW50IGFpbnNpIHBsdXMgbGlzaWJsZS4gCgpgYGB7cn0KaWYgKCFyZXF1aXJlKGRwbHlyKSkgaW5zdGFsbC5wYWNrYWdlcygiZHBseXIiKSAgICAgICAgICAgIApsaWJyYXJ5KGRwbHlyKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCmBgYAoKLS0tCgpQb3VyIHBsdXMgZCdpbmZvcm1hdGlvbnMgc3VyIGxlcyAqcGlwZXMqLgoKaHR0cDovL3I0ZHMuaGFkLmNvLm56L3BpcGVzLmh0bWwjcGlwaW5nLWFsdGVybmF0aXZlcwoKQXUgcGFzc2FnZTogY2UgbGl2cmUgZXN0IHVuZSBleGNlbGxlbnRlIHJlc3NvdXJjZSAoZ3JhdHVpdGUpIHN1ciBSLgoKLS0tCgpQYXMgaW1tw6lkaWF0IGRlIG5hdmlndWVyIGRhbnMgbGEgYmFzZSBkZSBkb25uw6llcyBHdXRlbmJlcmcgYXZlYyBjZSAqcGFja2FnZSouCgpFeHBsb3JvbnMgc29uIGZvbmN0aW9ubmVtZW50IGF2ZWMgbGEgZm9uY3Rpb24gYGhlbHAocGFja2FnZT0iZ3V0ZW5iZXJnciIpYAoKLS0tCgpMYSBmb25jdGlvbiBgZ3V0ZW5iZXJnX21ldGFkYXRhYCByw6l1bml0IGxlcyBtw6l0YWRvbm7DqWVzIGRlIGxhIGJhc2UgZXQgdmEgbm91cyBwZXJtZXR0cmUgZGUgZmFpcmUgbm90cmUgY2hvaXggcGFybWkgbGVzIG9ldXZyZXMuCgpgYGB7cn0KaGVhZChndXRlbmJlcmdfbWV0YWRhdGEpCmBgYAoKLS0tCgpPbiBjaG9pc2l0IMOJbWlsZSBab2xhIChhdHRlbnRpb24sIGwnb3J0aG9ncmFwaGUgZG9pdCDDqnRyZSBleGFjdGUpLgoKYGBge3J9Cmd1dGVuYmVyZ19tZXRhZGF0YSAlPiUKICBmaWx0ZXIoYXV0aG9yID09ICJab2xhLCDDiW1pbGUiKQpgYGAKCi0tLQoKUG91ciBmYWlyZSB1bmUgcmVjaGVyY2hlIHNhbnMgY29ubmHDrnRyZSBsYSBkw6lub21pbmF0aW9uIGV4YWN0ZSBkZSBsJ2F1dGV1ci1lIGRhbnMgbGEgYmFzZSBkZSBkb25uw6llcy4KClRvdXQgZCdhYm9yZCBub3VzIGNoYXJnZW9ucyB1biAqcGFja2FnZSogcG91ciB1dGlsaXNlciBkZXMgZXhwcmVzc2lvbnMgcsOpZ3VsacOocmVzIHF1aSBzb2l0IG1laWxsZXVyIHF1ZSBjZSBxdWkgZXN0IHByb3Bvc8OpIGRlIGJhc2UuCgpgYGB7cn0KaWYgKCFyZXF1aXJlKHN0cmluZ3IpKSBpbnN0YWxsLnBhY2thZ2VzKCJzdHJpbmdyIikKbGlicmFyeShzdHJpbmdyKQpgYGAKCi0tLQoKUHVpcyBvbiBjaGVyY2hlIGp1c3RlIFpvbGEgY2V0dGUgZm9pcy4KCmBgYHtyfQpndXRlbmJlcmdfd29ya3Moc3RyX2RldGVjdChhdXRob3IsICJab2xhIikpCmBgYAoKCi0tLQoKTCdJRCBkZSBMYSBCw6p0ZSBIdW1haW5lIGVzdCA1MTU0LiBPbiBsZSB0w6lsw6ljaGFyZ2UuCgpgYGB7cn0KYmV0ZV9odW1haW5lIDwtIGd1dGVuYmVyZ19kb3dubG9hZCg1MTU0KSAgIyMgTGEgQsOqdGUgSHVtYWluZSwgZCfDiW1pbGUgWm9sYQpgYGAKCi0tLQoKVW4gYXBlcsOndSBkZSBjZSBxdWUgbm91cyBhdm9ucyBvYnRlbnUgYXZlYyBsYSBmb25jdGlvbiBgc3RyYC4KCmBgYHtyfQpzdHIoYmV0ZV9odW1haW5lKQpgYGAKCi0tLQoKYGBge3J9CmJldGVfaHVtYWluZSR0ZXh0WzEwMF0KYmV0ZV9odW1haW5lJHRleHRbMTAxXQpiZXRlX2h1bWFpbmUkdGV4dFsxMDJdCmBgYAoKLS0tCgojIyBSIGV0IGxhIHN0YXRpc3RpcXVlIHRleHR1ZWxsZQoKTGEgZm9uZGF0aW9uIHF1aSBnw6hyZSBsZSBsYW5nYWdlIFIgcHJvcG9zZSB1bmUgc8OpcmllIGRlIFsqdGFzayB2aWV3cypdKGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi92aWV3cy8pLCBjJ2VzdC3DoC1kaXJlIGRlIGd1aWRlcyBkZSAqcGFja2FnZXMqIGRpc3BvbmlibGVzIHBvdXIgZGVzIHRow6htZXMgZG9ubsOpcy4KCi0tLQoKRW4gcGFydGljdWxpZXIsIHVuZSAqW3Rhc2sgdmlld10oaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3ZpZXdzL05hdHVyYWxMYW5ndWFnZVByb2Nlc3NpbmcuaHRtbCkqIGVzdCBkaXNwb25pYmxlIHBvdXIgbGUgdHJhaXRlbWVudCBhdXRvbWF0aXF1ZSBkdSBsYW5nYWdlIG5hdHVyZWwgKGVuIGFuZ2xhaXMgKm5hdHVyYWwgbGFuZ3VhZ2UgcHJvY2Vzc2luZyogb3UgKk5MUCopLgoKSmUgdm91cyBpbnZpdGUgw6AgbGEgY29uc3VsdGVyIHBvdXIgdHJvdXZlciBsZSAqcGFja2FnZSogcXVpIHNhdXJhIHLDqXBvbmRyZSDDoCB2b3MgcXVlc3Rpb25zLgoKLS0tCgojIyBMZSBwYWNrYWdlIHRtCgpMZSAqcGFja2FnZSogKip0bSoqIGVzdCBsZSBwYWNrYWdlIGRlIHLDqWbDqXJlbmNlIMOgIHV0aWxpc2VyIHBvdXIgZmFpcmUgZGUgbGEgc3RhdGlzdGlxdWUgdGV4dHVlbGxlIGVuIFIuCgpQbHVzaWV1cnMgYXV0cmVzICpwYWNrYWdlcyogb250IGVuc3VpdGUgw6l0w6kgY29uc3RydWl0cyDDoCBwYXJ0aXIgZGUgKnRtKiBldCBuw6ljZXNzaXRlbnQgbGEgcHLDqXNlbmNlIGRlIGNlbHVpLWNpIGFmaW4gZGUgZm9uY3Rpb25uZXIuCgpDZWxhIGFzc3VyZSBsJ3V0aWxpc2F0aW9uIGQndW4gZm9ybWF0IGNvbW11bi4KCi0tLQoKIyMjIE/DuSB0cm91dmVyIGRlcyByw6lwb25zZXMgPwoKKiBMZXMgcGFnZXMgZCdhaWRlCiogTGEgdGFzayB2aWV3CiogR29vZ2xlIC8gU3RhY2tvdmVyZmxvdwoqIFRleHQgTWluaW5nIHdpdGggUiBodHRwOi8vdGlkeXRleHRtaW5pbmcuY29tLyAoZ3JhdHVpdCkKKiBbVGV4dCBBbmFseXNpcyB3aXRoIFIgZm9yIFN0dWRlbnRzIG9mIExpdGVyYXR1cmVdKGh0dHA6Ly93d3cubWF0dGhld2pvY2tlcnMubmV0L3RleHQtYW5hbHlzaXMtd2l0aC1yLWZvci1zdHVkZW50cy1vZi1saXRlcmF0dXJlLykgKHBheWFudCkKKiBbQ2UgY291cnMgZGUgbCdVTklHRV0oaHR0cDovL2VkdXRlY2h3aWtpLnVuaWdlLmNoL2ZyL1R1dG9yaWVsX3RtX3RleHRfbWluaW5nX3BhY2thZ2UpCgotLS0KCmBgYHtyIGVjaG8gPSBGQUxTRSwgY2FjaGUgPSBUUlVFfQppZiAoIXJlcXVpcmUocmVhZHIpKSBpbnN0YWxsLnBhY2thZ2VzKCJyZWFkciIpCmxpYnJhcnkocmVhZHIpICAgICAgIyMgaW1wb3J0YXRpb24KaWYgKCFyZXF1aXJlKFJUZXh0VG9vbHMpKSBpbnN0YWxsLnBhY2thZ2VzKCJSVGV4dFRvb2xzIikKbGlicmFyeShSVGV4dFRvb2xzKSAjIyBjbGFzc2lmaWNhdGlvbiBkZSB0ZXh0ZXMKaWYgKCFyZXF1aXJlKHRleHRyZXVzZSkpIGluc3RhbGwucGFja2FnZXMoInRleHRyZXVzZSIpCmxpYnJhcnkodGV4dHJldXNlKSAgIyMgcGxhZ2lhdAppZiAoIXJlcXVpcmUobHNhKSkgaW5zdGFsbC5wYWNrYWdlcygibHNhIikKbGlicmFyeShsc2EpICAgICAgICAjIyBsYXRlbnQgc2VtYW50aWMgYW5hbHlzaXMKYGBgCgoKLS0tCgoKTm91cyBhbGxvbnMgZMOpY291dnJpciBjZSBwYWNrYWdlIGF2ZWMgdW4gY29ycHVzIGRlIHRlc3RzIGRlIGpldXggZGUgZm9vdGJhbGwgaXNzdXMgZGUgbGEgcHJlc3NlIHNww6ljaWFsaXPDqWUuCgpgYGB7cn0KZmlmYSA8LSByZWFkLmNzdjIoImh0dHBzOi8vZ2lzdC5naXRodWJ1c2VyY29udGVudC5jb20veXJvY2hhdC84NDQyNDdhMGE5ODVmNTRmYjY5ZjA5ZmRjMDJiZmIxNS9yYXcvMDExMDkyZjM3YjZiNDUyOTk1MTU0MWI0MzRlODAyYmY5OTVmYzZlNS9maWZhLmNzdiIsIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSkgIyMgbGUgZmljaGllciDDoCBpbXBvcnRlcgpgYGAKCi0tLQoKVW4gYXBlcsOndSBkdSB0YWJsZWF1LgoKYGBge3J9CmZpZmEKYGBgCgoKYGBge3IgZWNobyA9IEZBTFNFfQpmaWZhJGxhYmVsIDwtIHN0cl9jKGZpZmEkYXV0ZXVyLCBzdHJfc3ViKGZpZmEkYW5uZWUsIDMsIDQpLCBzZXAgPSAiXyIpICMjIG9uIGNyw6llIGNldHRlIHZhcmlhYmxlIHBvdXIgbm9tbWVyIGxlcyBwb2ludHMgZHUgZ3JhcGhlCmBgYAoKLS0tCgojIyMgQW5hbHlzZSByYXBpZGUgZGUgcGxhZ2lhdAoKYGBge3J9CmZpZmEuY29ycHVzIDwtIFRleHRSZXVzZUNvcnB1cyh0ZXh0ID0gZmlmYSR0ZXh0ZSwgdG9rZW5pemVyID0gdG9rZW5pemVfbmdyYW1zKQpmaWZhLmNvcnB1cwpgYGAKCi0tLQoKVW5lIGNvbXBhcmFpc29uIGRlcyB0ZXh0ZXMgZGV1eCDDoCBkZXV4LgoKYGBge3J9CmNvbXBhcmlzb25zIDwtIHBhaXJ3aXNlX2NvbXBhcmUoZmlmYS5jb3JwdXMsIGphY2NhcmRfc2ltaWxhcml0eSkKY29tcGFyaXNvbnMKYGBgCgotLS0KCkxlcyBzY29yZXMgZGUgY2VzIGNvbXBhcmFpc29ucy4KCmBgYHtyfQpwYWlyd2lzZV9jYW5kaWRhdGVzKGNvbXBhcmlzb25zKVtvcmRlcihwYWlyd2lzZV9jYW5kaWRhdGVzKGNvbXBhcmlzb25zKSRzY29yZSwgZGVjcmVhc2luZyA9IFRSVUUpLF0KYGBgCgotLS0KCkxlcyBzY29yZXMgbGVzIHBsdXMgaGF1dHMuCgpgYGB7cn0KYWxpZ25fbG9jYWwoZmlmYSR0ZXh0ZVszMF0sIGZpZmEkdGV4dGVbMzFdKQpgYGAKCi0tLQoKYGBge3J9CmFsaWduX2xvY2FsKGZpZmEkdGV4dGVbN10sIGZpZmEkdGV4dGVbMTFdKQpgYGAKCi0tLQoKYGBge3J9CmFsaWduX2xvY2FsKGZpZmEkdGV4dGVbMTFdLCBmaWZhJHRleHRlWzEyXSkKYGBgCgotLS0KCmBgYHtyfQphbGlnbl9sb2NhbChmaWZhJHRleHRlWzMyXSwgZmlmYSR0ZXh0ZVszM10pCmBgYAoKLS0tCgpgYGB7cn0KYWxpZ25fbG9jYWwoZmlmYSR0ZXh0ZVs3XSwgZmlmYSR0ZXh0ZVs4XSkKYGBgCgotLS0KCiMjIyBJbXBvcnRlciBkZXMgZmljaGllcnMgYXZlYyB0bQoKYGBge3J9CmlmICghcmVxdWlyZSh0bSkpIGluc3RhbGwucGFja2FnZXMoInRtIikKbGlicmFyeSh0bSkgICAgICAgICAjIyB0ZXh0IG1pbmluZwpgYGAKCi0tLQoKT24gY3LDqWUgdW4gY29ycHVzIGRlIHRleHRlcyBhdSBmb3JtYXQgZGUgdG0uCgoqQSB2ZWN0b3Igc291cmNlIGludGVycHJldHMgZWFjaCBlbGVtZW50IG9mIHRoZSB2ZWN0b3IgeCBhcyBhIGRvY3VtZW50LioKCmBgYHtyfQpjb3JwdXMgPC0gQ29ycHVzKFZlY3RvclNvdXJjZShmaWZhJHRleHRlKSkKY29ycHVzCmBgYAoKLS0tCgpgdG1fbWFwYCBlc3QgdW5lIGFwcGxpY2F0aW9uIHF1aSBwZXJtZXQgZGUgZmFpcmUgZGVzIHRyYW5zZm9ybWF0aW9ucyBzdXIgdG91dCB1biBjb3JwdXMuCgpJY2ksIG9uIHBhc3NlIHRvdXQgZW4gbWludXNjdWxlcyBncsOiY2Ugw6AgYGNvbnRlbnRfdHJhbnNmb3JtZXIodG9sb3dlcilgLgoKYGBge3J9CmNvcnB1cyA8LSB0bV9tYXAoY29ycHVzLCBjb250ZW50X3RyYW5zZm9ybWVyKHRvbG93ZXIpKQpgYGAKCi0tLQoKSWNpLCBub3VzIHJldGlyb25zIGxhIHBvbmN0dWF0aW9uLgoKYGBge3J9CmNvcnB1cyA8LSB0bV9tYXAoY29ycHVzLCBjb250ZW50X3RyYW5zZm9ybWVyKHJlbW92ZVB1bmN0dWF0aW9uKSkKYGBgCgotLS0KCk5vdXMgcmV0aXJvbnMgZHUgdGV4dGUgbGVzICpzdG9wd29yZHMqLgoKYGBge3J9CmNvcnB1cyA8LSB0bV9tYXAoY29ycHVzLCBjb250ZW50X3RyYW5zZm9ybWVyKGZ1bmN0aW9uKHgpIHJlbW92ZVdvcmRzKHgsIHN0b3B3b3JkcygiZnJlbmNoIikpKSkKYGBgCgoKLS0tCgpWb2ljaSBsYSBsaXN0ZSBkZXMgKnN0b3B3b3JkcyogZW4gZnJhbsOnYWlzLgoKYGBge3J9CnN0b3B3b3JkcygiZnJlbmNoIikKYGBgCgotLS0KCk5vdXMgcsOpZHVpc29ucyBsZXMgbW90cyDDoCBsZXVyIHJhY2luZSAoIipzdGVtbWluZyoiKS4KCmBgYHtyfQpjb3JwdXMgPC0gdG1fbWFwKGNvcnB1cywgc3RlbURvY3VtZW50LCBsYW5ndWFnZSA9ICJmcmVuY2giKQpjb3JwdXMgICMgY2hlY2sgY29ycHVzCmBgYAoKLS0tCgpNYXRyaWNlIHRlcm1lLWRvY3VtZW50CgpgYGB7cn0KdGQubWF0IDwtIGFzLm1hdHJpeChUZXJtRG9jdW1lbnRNYXRyaXgoY29ycHVzKSkKdGQubWF0CmBgYAoKLS0tCgpNYXRyaWNlIGRlcyBkaXN0YW5jZXMKCmBgYHtyfQpkaXN0Lm1hdCA8LSBkaXN0KHQoYXMubWF0cml4KHRkLm1hdCkpKQpkaXN0Lm1hdApgYGAKCi0tLQoKYGBge3J9CnBsb3QoaGNsdXN0KGRpc3QubWF0KSkKYGBgCgotLS0KCkNsYXNzaWNhbCBtdWx0aWRpbWVuc2lvbmFsIHNjYWxpbmcKCmBgYHtyfQpmaXQgPC0gY21kc2NhbGUoZGlzdC5tYXQsIGVpZyA9IFRSVUUsIGsgPSAyKSAgICAKYGBgCgotLS0KCk9uIHByw6lwYXJlIGxlcyBkb25uw6llcyBwb3VyIGxhIHZpc3VhbGlzYXRpb24uCgpgYGB7cn0KcG9pbnRzIDwtIGRhdGEuZnJhbWUoeCA9IGZpdCRwb2ludHNbLCAxXSwgeSA9IGZpdCRwb2ludHNbLCAyXSwgbmFtZSA9IGZpZmEkam91cm5hbCkKYGBgCgotLS0KClLDqXN1bHRhdC4KCmBgYHtyfQpnZ3Bsb3QocG9pbnRzLCBhZXMoeCA9IHgsIHkgPSB5KSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvciA9IG5hbWUpKSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG5hbWUpLCBudWRnZV95ID0gMS41KQpgYGAKCgo=