Objectif du TD

Le but ici est de se familliariser avec le language R, et la gestion de base de données. techniquement :

Importation de données financière et premières manipulations

1. instructions basiques

R est un language de programmation qui permet de gérer des bases existantes mais aussi d’en créer. On dit qu’il est orienter “objet”, c’est à dire que l’on va allouer des nom à chaque objet que l’on créer. Lancer les instruction simples suivantes :

A=3
B=2
A
B
A+B
C = A-B
C
A*C
A/B
A^2

les resultats, si besoin sont les suivants :

[1] 3
[1] 2
[1] 5
[1] 1
[1] 3
[1] 1.5
[1] 9

Si vous avez compris le concept d’objet, il faut comprendre ensuite que R peut gérer à très grand combre d’ojet complexe. Nous allons en voir 2 : les vecteurs et les dataframe (des table structurées)

1.1 Les vecteurs

Un vecteurs est un ensemble de chiffres alloué à un seul objet. Pour en créer un on introduit la commande c(). Voici un exemple :

v1 = c(1,2,3,4,5)
v2 = c(1,1,1,1,1)

On peut évidement faire des calculs simples. Exercice :

v1 + v2
[1] 2 3 4 5 6
v1-v2
[1] 0 1 2 3 4
v1*A
[1]  3  6  9 12 15
v3 = v1+v2
v4 = v3*B
v4
[1]  4  6  8 10 12

J’éspère que vous avez compris la logique. On va réaliser des calculs financiers, qui vous aiderons à faire vos TD sous R plutôt que sous Excel.

Exercice 1

On considère 2 titre financiers W et RF, dont les rentabilités sont les suivantes :

  • W à une rentabilité trimestrielle de 2% le premiers, -4% le second, 6% le troisièmme et 1% le derniers trimestre.
  • RF est un titre sans risque de 0,5% mensuelle.

Créer les vecteurs W et RF puis :

  • Calculer la valeur acquise au bout d’un an pour 1euros investi
  • Calculer la rentabilité moyenne pour W
  • Calculer leurs rentabilités annuelle
  • Calculer leurs rentabilité mensuelles

Elements de réponse. Le but étant de comprendre comment programmer avec des vecteurs et aller plus vite.

# On créer des vecteurs :
W = c(0.02, -0.04, 0.06, 0.01)
RF = 0.005
# vous pouvez appliquer directement la formule vue en cours en temps discret : 
(1.02)*(0.96)*(1.06)*(1.01)
# ou pour avoir la rentabilité moyenne : 
((1.02)*(0.96)*(1.06)*(1.01))^(1/4) - 1
#Cependant, on peut raccourcir le travail on créant des vecteurs. Voici un exemple :
W1 = 1+W
W1
W11 = prod(W1)
W11
#ou carrément :
prod(1+W)
#ou encore : 
W2 = prod(1+W)^(1/4)-1
ra = (1+W2)^4
W2
ra

Commenter les résultats et faites le reste de l’exercice.

1.2 Opération sur vecteurs

R est donc aussi une puissante calculatrice. Tout les opérateurs classiques sont disponibles. Il existe également des fonction qui permettent d’extraires des informations sur les vecteurs.

Opération

lancer les opérations suivantes et commentez :

##En utilisant le vecteurs W, on peut faire les opérations suivantes : 
sum(W) 
cumsum(W)
cumprod(1+W)
diff(W)
(W)^2
W**2
log(1+W)
exp(W)
diff(log(1+W))

Exercice 2

Soit un vecteur de prix mensuel P : c(10, 11, 9.5, 10.5, 12, 11.7, 10.8, 12, 13.1, 14,12.2, 10). Calculer averc le code le plus court possible (vous avez le droit à plusieurs essaie) les éléments suivants :

  1. la moyenne du prix sur l’année (11.4)
  2. la variance et l’ecart type du prix (1.814 et 1.347)

Information sur les vecteurs

Evidement, on peut extraire les information du vecteur analysé : les statistiques desciptives mais aussi leurs coordonnées.

P
mean(P)
var(P)
sd(P)
median(P)
quantile(P,0.25)
quantile(P,0.75)
max(P)
min(P)
range(P)
length(P)
summary(P)

Un vecteur, c’est aussi un ensemble de données ordonnées. Dans l’exemple de P, sa taille est de 12. On peut donc chercher les valeurs selon les coordonnées, par la notation P[i] i étant la coordonnées spécifique à la valeurs. Ainsi, si je veux la 7^e valeur de P, le code est le suivant : P[7]. Voici quelques exemple à interpréter :

P
P[2]
P[3:9]
P[-2]
n=12
P[2:n]
P[2:(n-1)]
P[-(2:5)]
P[c(2,4,6,8,10)]
P[-c(7,11,12)]

quelques raccourcis pour la création de vecteurs

Enfin, il existe des fonction génériques qui peremettent de créer rapidement des vecteurs.

la fonction rep pour replicate :

T1 = rep(1,4)
T2 = rep(2,4)
T1;T2
Trim = rep(1:4, each=4)
Trim
lettre = c("A","B","C","D")
rep(lettre, each=4)

Créer une sequence de chiffre (ou de valeurs)

seq(from = 0, to = 12, by = 2)
seq(0,12,2)
seq(1,12,1)
c(1:12)
seq(0,100,25)
seq(as.Date("2000/1/31"), by = "month", length.out = 12)

Exercice 3

En reprenant le vecteur de prix P, calculer :

  • la rentabilité en temps discret
  • la même en temps continue
  • la différence entre les deux rentablités, interpréter
  • la rentabilité annuelle (toutes les manières possibles)
  • la rentabilité mensuelle moyenne
P
#Pour le calcul des rentabilité en temps discret et continu, on êut le faire de deux manière. 
#Avec les coordonnées : 
(P[2:12]-P[1:11])/P[1:11]
log(P[2:12]/P[1:11])
# De façon plus rapide : 
diff(P)
P[-12]
Rt = diff(P)/P[-12];Rt
rt = diff(log(P));rt
#rentabilité annuelle :
#On peut les calculer avec les coordoonées, ou la différence entre le 1er et le second mois : 
RAnn = (P[12] - P[1])/P[1];RAnn
#Avec les rentabilités simples : 
prod(1+Rt)-1
#Avec les rentabilités continue : 
sum(rt)
#rentabilités mensuelle moyenne :
(prod(1+Rt))^(1/12) - 1
mean(rt)
mean(rt)^12

Importation et format des données

Avec les onglet “Environement” puis “Import Dataset”, importer dans RStudio la base de données msft (Microsoft). Suivez le guide et commenter. Vous devrez obtenir la table suivante :

Interprétez ce tableau. On va travailler avec les données en clotûre. Pour ce faire, on va simplifier le tableau. Les éléments de programation sont les suivantes.

class(msft)
[1] "tbl_df"     "tbl"        "data.frame"
class(msft$Date)
[1] "Date"
head(msft$Date)
[1] "2016-09-28" "2016-09-27" "2016-09-26" "2016-09-23" "2016-09-22" "2016-09-21"
head(msft$Close)
[1] 58.03 57.95 56.90 57.43 57.82 57.76
LS0tDQp0aXRsZTogIlRlY2huaXF1ZXMgcXVhbnRpdGF0aXZlIGRlIGxhIEZpbmFuY2UiDQphdXRob3I6ICJ2ZWFzbmEga2hpbSINCnN1YnRpdGxlOiAnVEQxIDogaW50cm8gw6AgUiwgZ2VzdGlvbiBkZSBiYXNlIGRlIGRvbm7DqWVzIGV0IGNhbGN1bHMgZGUgcmVudGFiaWxpdMOpcycNCm91dHB1dDoNCiAgaHRtbF9ub3RlYm9vazogZGVmYXVsdA0KLS0tDQoNCiMjI09iamVjdGlmIGR1IFREDQoNCkxlIGJ1dCBpY2kgZXN0IGRlIHNlIGZhbWlsbGlhcmlzZXIgYXZlYyBsZSBsYW5ndWFnZSBSLCBldCBsYSBnZXN0aW9uIGRlIGJhc2UgZGUgZG9ubsOpZXMuIHRlY2huaXF1ZW1lbnQgOiANCg0KLSBjb21wcmVuZHJlIGxhIG5vdGlvbiBkZSBmb3JtYXRzIGRlIGRvbm7DqWVzDQotIG1hbmlwdWxlciBsZXMgdGFibGVhdXggYXZlYyBsZXVycyBjb29yZG9ubsOpZXMgDQotIGNyw6llciBkZSBub3V2ZWxsZXMgdGFibGVzIGV0IGxldXJzIGF0dHJpYnVlciBkZXMgbm9tcyBldC9vdSBkZXMgZm9ybWF0cyBzcMOpY2lmaXF1ZXMNCi0gZmFpcmUgYXBwZWwgw6AgY2VydGFpbmVzIHZhbGV1cnMgZCd1bmUgdGFibGUNCg0KIyMjIEltcG9ydGF0aW9uIGRlIGRvbm7DqWVzIGZpbmFuY2nDqHJlIGV0IHByZW1pw6hyZXMgbWFuaXB1bGF0aW9ucw0KDQojIyMjIDEuIGluc3RydWN0aW9ucyBiYXNpcXVlcyANCg0KUiBlc3QgdW4gbGFuZ3VhZ2UgZGUgcHJvZ3JhbW1hdGlvbiBxdWkgcGVybWV0IGRlIGfDqXJlciBkZXMgYmFzZXMgZXhpc3RhbnRlcyBtYWlzIGF1c3NpIGQnZW4gY3LDqWVyLiBPbiBkaXQgcXUnaWwgZXN0IG9yaWVudGVyICJvYmpldCIsIGMnZXN0IMOgIGRpcmUgcXVlIGwnb24gdmEgYWxsb3VlciBkZXMgbm9tIMOgIGNoYXF1ZSBvYmpldCBxdWUgbCdvbiBjcsOpZXIuIExhbmNlciBsZXMgaW5zdHJ1Y3Rpb24gc2ltcGxlcyBzdWl2YW50ZXMgOiANCg0KYGBge3IsIHJlc3VsdHM9J2hpZGUnfQ0KQT0zDQpCPTINCkENCkINCkErQg0KQyA9IEEtQg0KQw0KQSpDDQpBL0INCkFeMg0KYGBgDQpsZXMgcmVzdWx0YXRzLCBzaSBiZXNvaW4gc29udCBsZXMgc3VpdmFudHMgOg0KYGBge3IsIGVjaG8gPSBGQUxTRX0NCkE9Mw0KQj0yDQpBDQpCDQpBK0INCkMgPSBBLUINCkMNCkEqQw0KQS9CDQpBXjINCmBgYA0KU2kgdm91cyBhdmV6IGNvbXByaXMgbGUgY29uY2VwdCBkJ29iamV0LCBpbCBmYXV0IGNvbXByZW5kcmUgZW5zdWl0ZSBxdWUgUiBwZXV0IGfDqXJlciDDoCB0csOocyBncmFuZCBjb21icmUgZCdvamV0IGNvbXBsZXhlLiBOb3VzIGFsbG9ucyBlbiB2b2lyIDIgOiBsZXMgdmVjdGV1cnMgZXQgbGVzIGRhdGFmcmFtZSAoZGVzIHRhYmxlIHN0cnVjdHVyw6llcykNCg0KKioxLjEgTGVzIHZlY3RldXJzKioNCg0KVW4gdmVjdGV1cnMgZXN0IHVuIGVuc2VtYmxlIGRlIGNoaWZmcmVzIGFsbG91w6kgw6AgdW4gc2V1bCBvYmpldC4gUG91ciBlbiBjcsOpZXIgdW4gb24gaW50cm9kdWl0IGxhIGNvbW1hbmRlIGBjKClgLiBWb2ljaSB1biBleGVtcGxlIDogDQpgYGB7cn0NCnYxID0gYygxLDIsMyw0LDUpDQp2MiA9IGMoMSwxLDEsMSwxKQ0KYGBgDQpPbiBwZXV0IMOpdmlkZW1lbnQgZmFpcmUgZGVzIGNhbGN1bHMgc2ltcGxlcy4gRXhlcmNpY2UgOiANCmBgYHtyfQ0KdjEgKyB2Mg0KdjEtdjINCnYxKkENCnYzID0gdjErdjINCnY0ID0gdjMqQg0KdjQNCmBgYA0KDQpKJ8Opc3DDqHJlIHF1ZSB2b3VzIGF2ZXogY29tcHJpcyBsYSBsb2dpcXVlLiBPbiB2YSByw6lhbGlzZXIgZGVzIGNhbGN1bHMgZmluYW5jaWVycywgcXVpIHZvdXMgYWlkZXJvbnMgw6AgZmFpcmUgdm9zIFREIHNvdXMgUiBwbHV0w7R0IHF1ZSBzb3VzIEV4Y2VsLiANCg0KKipFeGVyY2ljZSAxKioNCg0KT24gY29uc2lkw6hyZSAyIHRpdHJlIGZpbmFuY2llcnMgVyBldCBSRiwgZG9udCBsZXMgcmVudGFiaWxpdMOpcyBzb250IGxlcyBzdWl2YW50ZXMgOiANCg0KLSBXIMOgIHVuZSByZW50YWJpbGl0w6kgdHJpbWVzdHJpZWxsZSBkZSAyJSBsZSBwcmVtaWVycywgLTQlIGxlIHNlY29uZCwgNiUgbGUgdHJvaXNpw6htbWUgZXQgMSUgbGUgZGVybmllcnMgdHJpbWVzdHJlLiANCi0gUkYgZXN0IHVuIHRpdHJlIHNhbnMgcmlzcXVlIGRlIDAsNSUgbWVuc3VlbGxlLiANCg0KQ3LDqWVyIGxlcyB2ZWN0ZXVycyBXIGV0IFJGIHB1aXMgOiANCg0KLSBDYWxjdWxlciBsYSB2YWxldXIgYWNxdWlzZSBhdSBib3V0IGQndW4gYW4gcG91ciAxZXVyb3MgaW52ZXN0aQ0KLSBDYWxjdWxlciBsYSByZW50YWJpbGl0w6kgbW95ZW5uZSBwb3VyIFcNCi0gQ2FsY3VsZXIgbGV1cnMgcmVudGFiaWxpdMOpcyBhbm51ZWxsZQ0KLSBDYWxjdWxlciBsZXVycyByZW50YWJpbGl0w6kgbWVuc3VlbGxlcw0KDQpFbGVtZW50cyBkZSByw6lwb25zZS4gTGUgYnV0IMOpdGFudCBkZSBjb21wcmVuZHJlIGNvbW1lbnQgcHJvZ3JhbW1lciBhdmVjIGRlcyB2ZWN0ZXVycyBldCBhbGxlciBwbHVzIHZpdGUuIA0KYGBge3IsIHJlc3VsdHM9J2hpZGUnfQ0KIyBPbiBjcsOpZXIgZGVzIHZlY3RldXJzIDoNClcgPSBjKDAuMDIsIC0wLjA0LCAwLjA2LCAwLjAxKQ0KUkYgPSAwLjAwNQ0KDQojIHZvdXMgcG91dmV6IGFwcGxpcXVlciBkaXJlY3RlbWVudCBsYSBmb3JtdWxlIHZ1ZSBlbiBjb3VycyBlbiB0ZW1wcyBkaXNjcmV0IDogDQooMS4wMikqKDAuOTYpKigxLjA2KSooMS4wMSkNCiMgb3UgcG91ciBhdm9pciBsYSByZW50YWJpbGl0w6kgbW95ZW5uZSA6IA0KKCgxLjAyKSooMC45NikqKDEuMDYpKigxLjAxKSleKDEvNCkgLSAxDQoNCiNDZXBlbmRhbnQsIG9uIHBldXQgcmFjY291cmNpciBsZSB0cmF2YWlsIG9uIGNyw6lhbnQgZGVzIHZlY3RldXJzLiBWb2ljaSB1biBleGVtcGxlIDoNClcxID0gMStXDQpXMQ0KVzExID0gcHJvZChXMSkNClcxMQ0KI291IGNhcnLDqW1lbnQgOg0KcHJvZCgxK1cpDQojb3UgZW5jb3JlIDogDQpXMiA9IHByb2QoMStXKV4oMS80KS0xDQpyYSA9ICgxK1cyKV40DQpXMg0KcmENCmBgYA0KQ29tbWVudGVyIGxlcyByw6lzdWx0YXRzIGV0IGZhaXRlcyBsZSByZXN0ZSBkZSBsJ2V4ZXJjaWNlLiANCg0KKioxLjIgT3DDqXJhdGlvbiBzdXIgdmVjdGV1cnMqKg0KDQpSIGVzdCBkb25jIGF1c3NpIHVuZSBwdWlzc2FudGUgY2FsY3VsYXRyaWNlLiBUb3V0IGxlcyBvcMOpcmF0ZXVycyBjbGFzc2lxdWVzIHNvbnQgZGlzcG9uaWJsZXMuIElsIGV4aXN0ZSDDqWdhbGVtZW50IGRlcyBmb25jdGlvbiBxdWkgcGVybWV0dGVudCBkJ2V4dHJhaXJlcyBkZXMgaW5mb3JtYXRpb25zIHN1ciBsZXMgdmVjdGV1cnMuIA0KDQoqKk9ww6lyYXRpb24qKg0KDQpsYW5jZXIgbGVzIG9ww6lyYXRpb25zIHN1aXZhbnRlcyBldCBjb21tZW50ZXogOiANCg0KYGBge3IsIHJlc3VsdHM9J2hpZGUnfQ0KIyNFbiB1dGlsaXNhbnQgbGUgdmVjdGV1cnMgVywgb24gcGV1dCBmYWlyZSBsZXMgb3DDqXJhdGlvbnMgc3VpdmFudGVzIDogDQpzdW0oVykgDQpjdW1zdW0oVykNCmN1bXByb2QoMStXKQ0KZGlmZihXKQ0KKFcpXjINClcqKjINCmxvZygxK1cpDQpleHAoVykNCmRpZmYobG9nKDErVykpDQpgYGANCg0KICoqRXhlcmNpY2UgMioqDQoNClNvaXQgdW4gdmVjdGV1ciBkZSBwcml4IG1lbnN1ZWwgUCA6ICBgYygxMCwgMTEsIDkuNSwgMTAuNSwgMTIsIDExLjcsIDEwLjgsIDEyLCAxMy4xLCAxNCwxMi4yLCAxMCkgYC4gQ2FsY3VsZXIgYXZlcmMgbGUgY29kZSBsZSBwbHVzIGNvdXJ0IHBvc3NpYmxlICh2b3VzIGF2ZXogbGUgZHJvaXQgw6AgcGx1c2lldXJzIGVzc2FpZSkgbGVzIMOpbMOpbWVudHMgc3VpdmFudHMgOiANCg0KMS4gbGEgbW95ZW5uZSBkdSBwcml4IHN1ciBsJ2FubsOpZSAoMTEuNCkNCjIuIGxhIHZhcmlhbmNlIGV0IGwnZWNhcnQgdHlwZSBkdSBwcml4ICgxLjgxNCBldCAxLjM0NykNCg0KYGBge3IsIGluY2x1ZGU9RkFMU0V9DQpQID0gYygxMCwgMTEsIDkuNSwgMTAuNSwgMTIsIDExLjcsIDEwLjgsIDEyLCAxMy4xLCAxNCwxMi4yLCAxMCkNCg0KbW95LlAgPSBzdW0oUCkvMTINCnZhci5QID0gc3VtKChQIC0gbW95LlApXjIpLzExDQptb3kuUA0KdmFyLlANCih2YXIuUCleKDEvMikNCm1lYW4oUCkNCnZhcihQKQ0Kc2QoUCkNCmBgYA0KDQoqKkluZm9ybWF0aW9uIHN1ciBsZXMgdmVjdGV1cnMqKg0KDQpFdmlkZW1lbnQsIG9uIHBldXQgZXh0cmFpcmUgbGVzIGluZm9ybWF0aW9uIGR1IHZlY3RldXIgYW5hbHlzw6kgOiBsZXMgc3RhdGlzdGlxdWVzIGRlc2NpcHRpdmVzIG1haXMgYXVzc2kgbGV1cnMgY29vcmRvbm7DqWVzLiANCg0KYGBge3IsIHJlc3VsdHM9J2hpZGUnfQ0KUA0KbWVhbihQKQ0KdmFyKFApDQpzZChQKQ0KbWVkaWFuKFApDQpxdWFudGlsZShQLDAuMjUpDQpxdWFudGlsZShQLDAuNzUpDQptYXgoUCkNCm1pbihQKQ0KcmFuZ2UoUCkNCmxlbmd0aChQKQ0Kc3VtbWFyeShQKQ0KYGBgDQoNClVuIHZlY3RldXIsIGMnZXN0IGF1c3NpIHVuIGVuc2VtYmxlIGRlIGRvbm7DqWVzIG9yZG9ubsOpZXMuIERhbnMgbCdleGVtcGxlIGRlIFAsIHNhIHRhaWxsZSBlc3QgZGUgMTIuIE9uIHBldXQgZG9uYyBjaGVyY2hlciBsZXMgdmFsZXVycyBzZWxvbiBsZXMgY29vcmRvbm7DqWVzLCBwYXIgbGEgbm90YXRpb24gYFBbaV1gIGkgw6l0YW50IGxhIGNvb3Jkb25uw6llcyBzcMOpY2lmaXF1ZSDDoCBsYSB2YWxldXJzLiBBaW5zaSwgc2kgamUgdmV1eCBsYSA3XmUgdmFsZXVyIGRlIFAsIGxlIGNvZGUgZXN0IGxlIHN1aXZhbnQgOiBgUFs3XWAuIA0KVm9pY2kgcXVlbHF1ZXMgZXhlbXBsZSDDoCBpbnRlcnByw6l0ZXIgOiANCg0KYGBge3IsIHJlc3VsdHM9J2hpZGUnfQ0KUA0KUFsyXQ0KUFszOjldDQpQWy0yXQ0Kbj0xMg0KUFsyOm5dDQpQWzI6KG4tMSldDQpQWy0oMjo1KV0NClBbYygyLDQsNiw4LDEwKV0NClBbLWMoNywxMSwxMildDQoNCmBgYA0KDQoqKnF1ZWxxdWVzIHJhY2NvdXJjaXMgcG91ciBsYSBjcsOpYXRpb24gZGUgdmVjdGV1cnMqKg0KDQpFbmZpbiwgaWwgZXhpc3RlIGRlcyBmb25jdGlvbiBnw6luw6lyaXF1ZXMgcXVpIHBlcmVtZXR0ZW50IGRlIGNyw6llciByYXBpZGVtZW50IGRlcyB2ZWN0ZXVycy4gDQoNCmxhIGZvbmN0aW9uIHJlcCBwb3VyIHJlcGxpY2F0ZSA6IA0KYGBge3IsIHJlc3VsdHM9J2hpZGUnfQ0KVDEgPSByZXAoMSw0KQ0KVDIgPSByZXAoMiw0KQ0KVDE7VDINClRyaW0gPSByZXAoMTo0LCBlYWNoPTQpDQpUcmltDQpsZXR0cmUgPSBjKCJBIiwiQiIsIkMiLCJEIikNCnJlcChsZXR0cmUsIGVhY2g9NCkNCmBgYA0KQ3LDqWVyIHVuZSBzZXF1ZW5jZSBkZSBjaGlmZnJlIChvdSBkZSB2YWxldXJzKQ0KYGBge3IsIHJlc3VsdHM9J2hpZGUnfQ0Kc2VxKGZyb20gPSAwLCB0byA9IDEyLCBieSA9IDIpDQpzZXEoMCwxMiwyKQ0Kc2VxKDEsMTIsMSkNCmMoMToxMikNCnNlcSgwLDEwMCwyNSkNCmBgYA0KKipFeGVyY2ljZSAzKioNCg0KRW4gcmVwcmVuYW50IGxlIHZlY3RldXIgZGUgcHJpeCBQLCBjYWxjdWxlciA6IA0KDQotIGxhIHJlbnRhYmlsaXTDqSBlbiB0ZW1wcyBkaXNjcmV0DQotIGxhIG3Dqm1lIGVuIHRlbXBzIGNvbnRpbnVlDQotIGxhIGRpZmbDqXJlbmNlIGVudHJlIGxlcyBkZXV4IHJlbnRhYmxpdMOpcywgaW50ZXJwcsOpdGVyDQotIGxhIHJlbnRhYmlsaXTDqSBhbm51ZWxsZSAodG91dGVzIGxlcyBtYW5pw6hyZXMgcG9zc2libGVzKQ0KLSBsYSByZW50YWJpbGl0w6kgbWVuc3VlbGxlIG1veWVubmUNCg0KDQpgYGB7ciwgcmVzdWx0cz0naGlkZSd9DQpQDQojUG91ciBsZSBjYWxjdWwgZGVzIHJlbnRhYmlsaXTDqSBlbiB0ZW1wcyBkaXNjcmV0IGV0IGNvbnRpbnUsIG9uIMOqdXQgbGUgZmFpcmUgZGUgZGV1eCBtYW5pw6hyZS4gDQojQXZlYyBsZXMgY29vcmRvbm7DqWVzIDogDQooUFsyOjEyXS1QWzE6MTFdKS9QWzE6MTFdDQpsb2coUFsyOjEyXS9QWzE6MTFdKQ0KIyBEZSBmYcOnb24gcGx1cyByYXBpZGUgOiANCmRpZmYoUCkNClBbLTEyXQ0KUnQgPSBkaWZmKFApL1BbLTEyXTtSdA0KcnQgPSBkaWZmKGxvZyhQKSk7cnQNCg0KI3JlbnRhYmlsaXTDqSBhbm51ZWxsZSA6DQojT24gcGV1dCBsZXMgY2FsY3VsZXIgYXZlYyBsZXMgY29vcmRvb27DqWVzLCBvdSBsYSBkaWZmw6lyZW5jZSBlbnRyZSBsZSAxZXIgZXQgbGUgc2Vjb25kIG1vaXMgOiANClJBbm4gPSAoUFsxMl0gLSBQWzFdKS9QWzFdO1JBbm4NCiNBdmVjIGxlcyByZW50YWJpbGl0w6lzIHNpbXBsZXMgOiANCnByb2QoMStSdCktMQ0KI0F2ZWMgbGVzIHJlbnRhYmlsaXTDqXMgY29udGludWUgOiANCnN1bShydCkNCg0KI3JlbnRhYmlsaXTDqXMgbWVuc3VlbGxlIG1veWVubmUgOg0KKHByb2QoMStSdCkpXigxLzEyKSAtIDENCm1lYW4ocnQpDQptZWFuKHJ0KV4xMg0KYGBgDQoNCg0KIyMjIyBJbXBvcnRhdGlvbiBldCBmb3JtYXQgZGVzIGRvbm7DqWVzDQoNCkF2ZWMgbGVzIG9uZ2xldCAiRW52aXJvbmVtZW50IiBwdWlzICJJbXBvcnQgRGF0YXNldCIsIGltcG9ydGVyIGRhbnMgUlN0dWRpbyBsYSBiYXNlIGRlIGRvbm7DqWVzIG1zZnQgKE1pY3Jvc29mdCkuIFN1aXZleiBsZSBndWlkZSBldCBjb21tZW50ZXIuIFZvdXMgZGV2cmV6IG9idGVuaXIgbGEgdGFibGUgc3VpdmFudGUgOiANCg0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCmhlYWQobXNmdCwxMCkNCmBgYA0KDQpJbnRlcnByw6l0ZXogY2UgdGFibGVhdS4gT24gdmEgdHJhdmFpbGxlciBhdmVjIGxlcyBkb25uw6llcyBlbiBjbG90w7tyZS4gUG91ciBjZSBmYWlyZSwgb24gdmEgc2ltcGxpZmllciBsZSB0YWJsZWF1LiBMZXMgw6lsw6ltZW50cyBkZSBwcm9ncmFtYXRpb24gc29udCBsZXMgc3VpdmFudGVzLiANCg0KYGBge3J9DQpjbGFzcyhtc2Z0KQ0KY2xhc3MobXNmdCREYXRlKQ0KaGVhZChtc2Z0JERhdGUpDQpoZWFkKG1zZnQkQ2xvc2UpDQpgYGANCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0K