ROUT Developers
Login met ROUT
Een standaard OpenID Connect-provider met PKCE, geverifieerde e-mail en optionele badges. Geen SDK nodig: elke OIDC-bibliotheek werkt.
Snel starten
- Maak een app in de Developer Console: naam, website en terug-adressen.
- Bewaar de
client_iden het eenmalig getoondeclient_secretop je server. - Wijs je OIDC-bibliotheek naar het discovery-adres hieronder.
https://rout.be/.well-known/openid-configurationMaak eerst de starthandler en callback in jouw eigen app en test de terugkeer. Activeer pas daarna de knop. Een ROUT-app aanmaken activeert geen login in jouw website en voegt geen Google-login toe. De voorbeelden hieronder zijn server-pseudocode; gebruik een OIDC-bibliotheek voor de volledige flow.
Officiële ROUT-knoppen
Login maakt een sessie in jouw app na de bevestigde ROUT-terugkeer.
De code hieronder is de knop, niet de volledige login. Maak eerst de aangegeven handler en een exact geregistreerd terugkeeradres. Start nooit automatisch bij het openen van een pagina. Google en andere aanmeldmethodes hebben hun eigen implementatie nodig.
<!-- Implement this POST handler in YOUR app before enabling this button.
It creates state, nonce and PKCE, then redirects using OIDC discovery.
Connect requires an existing local session and never replaces that session.
Include your framework's CSRF field/protection in this form. -->
<form method="post" action="/auth/rout/login">
<button class="rout-button" type="submit">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1254" width="20" height="25" fill="currentColor" aria-hidden="true"><g><g transform="translate(0.000000,1254.000000) scale(0.100000,-0.100000)"
stroke="none"><path d="M1430 12290 c0 -5 -15 -10 -34 -10 -19 0 -38 -4 -41 -10 -3 -5 -19
-10 -35 -10 -16 0 -31 -4 -35 -9 -3 -5 -18 -12 -35 -16 -31 -7 -172 -76 -197
-97 -15 -12 -45 -31 -72 -44 -37 -19 -251 -223 -251 -240 0 -6 -7 -14 -15 -18
-8 -3 -15 -11 -15 -19 0 -7 -12 -24 -26 -38 -14 -13 -30 -33 -35 -44 -16 -32
-35 -64 -51 -82 -20 -24 -135 -261 -144 -296 -3 -15 -10 -30 -15 -33 -5 -3 -9
-16 -9 -30 0 -13 -3 -24 -8 -24 -12 0 -31 -52 -38 -103 -4 -26 -11 -50 -15
-53 -5 -3 -9 -16 -9 -30 0 -13 -4 -24 -10 -24 -5 0 -10 -15 -10 -34 0 -19 -4
-37 -9 -40 -5 -3 -12 -42 -16 -86 -4 -44 -11 -83 -16 -86 -5 -3 -9 -23 -9 -45
0 -21 -4 -39 -10 -39 -6 0 -10 -35 -10 -84 0 -47 -5 -88 -10 -91 -14 -8 -14
-422 0 -430 6 -3 10 -39 10 -80 0 -41 5 -77 10 -80 6 -3 10 -28 10 -55 0 -27
4 -51 9 -54 4 -3 12 -46 15 -96 4 -49 12 -92 17 -95 5 -4 9 -24 9 -46 0 -21 5
-39 10 -39 6 0 10 -15 10 -34 0 -19 4 -37 9 -40 5 -3 12 -33 16 -66 4 -33 11
-63 16 -66 5 -3 9 -21 9 -40 0 -19 5 -34 10 -34 6 0 10 -15 10 -33 0 -18 5
-38 10 -43 6 -6 13 -34 17 -62 3 -29 10 -52 14 -52 5 0 9 -15 9 -34 0 -19 5
-38 10 -41 6 -3 10 -19 10 -35 0 -16 5 -32 11 -35 6 -4 8 -13 5 -21 -3 -7 -1
-16 4 -19 6 -4 10 -17 10 -30 0 -13 5 -27 10 -30 6 -3 10 -17 10 -31 0 -13 4
-24 9 -24 4 0 11 -23 14 -52 4 -28 11 -56 17 -62 5 -5 10 -20 10 -33 0 -12 8
-37 19 -55 10 -18 21 -55 25 -82 4 -27 11 -56 16 -65 42 -86 51 -108 56 -142
4 -22 11 -42 15 -45 5 -3 9 -16 9 -30 0 -13 5 -24 10 -24 6 0 10 -11 10 -24 0
-14 4 -27 9 -30 5 -3 12 -23 15 -43 9 -46 28 -93 38 -93 5 0 8 -11 8 -24 0
-14 4 -28 10 -31 5 -3 10 -16 10 -29 0 -12 7 -31 15 -42 8 -10 15 -27 15 -37
0 -9 4 -25 9 -35 23 -43 41 -92 41 -111 0 -12 3 -21 8 -21 9 0 32 -49 32 -69
0 -9 7 -25 15 -35 8 -11 15 -28 15 -38 0 -9 9 -33 20 -53 11 -20 20 -41 20
-47 0 -15 52 -122 62 -126 4 -2 8 -13 8 -24 0 -19 28 -88 40 -98 5 -4 26 -48
50 -105 24 -59 57 -122 70 -135 13 -13 30 -52 30 -69 0 -10 7 -24 15 -31 8 -7
15 -18 15 -25 0 -8 4 -15 8 -17 8 -3 62 -110 62 -123 0 -4 8 -15 18 -24 18
-16 52 -81 52 -98 0 -6 9 -18 20 -28 11 -10 20 -24 20 -32 0 -7 4 -13 10 -13
5 0 18 -20 29 -43 11 -24 27 -50 36 -57 8 -7 23 -29 32 -49 9 -20 23 -40 30
-44 7 -4 13 -14 13 -21 0 -7 9 -21 20 -31 11 -10 20 -23 20 -30 0 -6 11 -22
25 -35 14 -13 25 -29 25 -35 0 -6 20 -31 45 -55 25 -24 45 -48 45 -53 0 -4 11
-18 25 -31 33 -31 33 -34 -25 -91 -28 -27 -50 -54 -50 -60 0 -6 -16 -26 -35
-45 -19 -19 -35 -39 -35 -45 0 -6 -13 -24 -30 -40 -16 -16 -30 -35 -30 -42 0
-8 -7 -16 -15 -19 -8 -4 -15 -12 -15 -18 0 -7 -11 -23 -25 -36 -14 -13 -25
-29 -25 -36 0 -6 -7 -18 -16 -25 -9 -7 -20 -22 -25 -34 -13 -30 -32 -58 -51
-76 -10 -9 -18 -19 -18 -23 0 -13 -40 -95 -48 -100 -5 -3 -30 -48 -57 -101
-27 -52 -52 -95 -57 -95 -4 0 -8 -8 -8 -17 0 -10 -21 -61 -46 -113 -57 -117
-61 -127 -69 -168 -4 -17 -11 -32 -16 -32 -5 0 -9 -11 -9 -24 0 -14 -5 -28
-10 -31 -6 -3 -10 -17 -10 -30 0 -13 -4 -26 -9 -30 -6 -3 -13 -26 -17 -50 -3
-25 -10 -45 -15 -45 -5 0 -9 -11 -9 -24 0 -14 -5 -28 -10 -31 -6 -3 -10 -17
-10 -30 0 -13 -4 -27 -10 -30 -5 -3 -10 -16 -10 -28 0 -39 -12 -97 -21 -103
-5 -3 -9 -18 -9 -34 0 -16 -4 -31 -9 -34 -4 -3 -11 -37 -15 -76 -4 -38 -11
-72 -17 -75 -5 -4 -9 -28 -9 -55 0 -27 -5 -52 -10 -55 -6 -3 -10 -33 -10 -65
0 -38 -4 -60 -13 -62 -18 -7 -18 -931 1 -949 6 -7 12 -34 12 -59 0 -25 4 -50
9 -56 5 -5 11 -29 14 -54 7 -59 30 -157 40 -166 4 -4 7 -20 7 -35 0 -15 4 -31
10 -34 6 -3 10 -17 10 -30 0 -13 4 -26 9 -29 4 -3 6 -16 4 -30 -3 -13 0 -27 6
-30 6 -4 11 -18 11 -32 0 -13 5 -24 10 -24 6 0 10 -11 10 -24 0 -14 4 -27 9
-31 5 -3 13 -19 16 -37 4 -17 16 -47 26 -65 11 -19 19 -42 19 -52 0 -10 7 -21
15 -25 8 -3 15 -14 15 -25 0 -20 40 -104 52 -109 4 -2 20 -29 35 -60 23 -48
64 -113 83 -132 8 -8 29 -43 39 -65 5 -11 21 -31 35 -44 14 -14 26 -30 26 -37
0 -7 10 -21 23 -31 12 -10 30 -29 40 -43 27 -39 313 -325 352 -351 19 -13 35
-27 35 -31 0 -5 6 -8 13 -8 8 0 24 -11 37 -25 13 -14 29 -25 35 -25 6 0 22
-11 35 -25 13 -14 28 -25 33 -25 5 0 17 -8 26 -17 18 -20 46 -39 78 -52 11 -6
24 -15 28 -21 3 -5 21 -16 39 -24 17 -7 38 -20 46 -27 16 -16 82 -49 97 -49 6
0 18 -9 28 -20 10 -11 24 -20 32 -20 7 0 13 -4 13 -10 0 -5 5 -10 12 -10 15 0
122 -52 126 -62 2 -4 8 -8 14 -8 14 0 121 -52 128 -61 3 -4 19 -10 35 -14 30
-7 75 -25 85 -35 11 -11 56 -29 88 -35 17 -4 32 -11 32 -16 0 -5 9 -9 20 -9
11 0 36 -9 55 -20 20 -11 40 -18 45 -15 5 3 11 1 15 -5 3 -5 17 -10 31 -10 13
0 24 -4 24 -10 0 -5 11 -10 24 -10 14 0 28 -4 31 -10 3 -5 17 -10 30 -10 13 0
26 -4 30 -10 3 -5 12 -7 19 -4 8 3 17 1 21 -5 3 -6 17 -11 31 -11 13 0 24 -4
24 -10 0 -5 11 -10 24 -10 14 0 27 -4 31 -9 3 -5 30 -13 60 -16 31 -4 58 -11
61 -16 3 -5 18 -9 34 -9 16 0 32 -4 35 -10 3 -5 19 -10 35 -10 16 0 31 -4 35
-9 3 -5 34 -13 70 -16 36 -4 68 -11 71 -16 3 -5 23 -9 45 -9 21 0 39 -4 39
-10 0 -5 20 -10 45 -10 25 0 45 -4 45 -9 0 -5 45 -12 100 -16 55 -4 103 -11
106 -16 3 -5 34 -9 69 -9 35 0 67 -4 70 -10 3 -6 48 -10 101 -10 56 0 94 -4
94 -10 0 -6 121 -10 344 -10 219 0 347 4 351 10 3 6 50 10 105 10 55 0 102 4
105 10 3 6 30 10 60 10 30 0 56 4 59 9 3 4 46 12 96 15 49 4 92 12 95 17 4 5
28 9 55 9 27 0 52 5 55 10 3 6 24 10 45 10 21 0 41 4 44 9 3 5 33 12 66 16 33
4 63 11 66 16 3 5 18 9 34 9 16 0 32 5 35 10 3 6 21 10 40 10 19 0 36 4 39 9
3 4 28 11 55 15 28 4 53 11 56 16 3 6 15 10 26 10 10 0 27 4 37 9 20 11 53 24
67 27 42 7 76 18 81 25 3 5 15 9 27 9 12 0 31 7 41 15 11 8 30 15 42 15 13 0
26 5 29 10 3 6 17 10 31 10 13 0 24 3 24 8 0 7 72 42 88 42 6 0 77 35 412 205
11 5 20 13 20 17 0 5 6 8 13 8 8 0 22 9 31 19 10 11 29 22 44 26 14 3 44 22
67 41 56 49 63 54 73 54 5 0 19 11 32 25 13 14 29 25 35 25 6 0 22 11 35 25
13 14 29 25 35 25 6 0 31 20 55 45 24 25 47 45 51 45 10 0 299 289 299 299 0
4 16 22 35 41 19 19 35 39 35 45 0 6 16 26 35 45 19 19 35 39 35 45 0 6 11 22
25 35 14 13 25 28 25 33 0 5 10 19 23 31 12 11 31 37 40 56 31 59 43 79 60 98
10 10 17 24 17 30 0 7 4 12 9 12 5 0 12 13 16 29 3 16 13 35 21 42 8 7 26 36
40 65 13 28 31 57 39 64 8 7 15 20 15 29 0 10 23 61 50 115 27 54 50 106 50
116 0 11 5 22 10 25 5 3 10 17 10 31 0 13 3 24 8 24 9 0 28 45 37 87 4 18 11
33 16 33 5 0 9 16 9 35 0 19 5 35 10 35 6 0 10 11 10 24 0 14 4 27 9 30 4 3 6
16 4 30 -3 13 0 27 6 30 6 4 11 18 11 31 0 13 5 27 10 30 6 3 10 19 10 35 0
16 4 31 9 34 4 3 12 46 15 96 4 49 12 92 17 95 5 4 9 28 9 56 0 27 5 49 10 49
6 0 10 31 10 74 0 41 5 78 10 81 14 8 14 442 0 450 -5 3 -10 44 -10 90 0 46
-4 87 -10 90 -5 3 -10 30 -10 60 0 30 -4 56 -9 59 -4 3 -12 46 -15 96 -4 49
-12 92 -17 95 -5 4 -9 24 -9 45 0 21 -4 42 -10 45 -5 3 -10 19 -10 35 0 16 -5
32 -11 36 -6 3 -9 17 -6 30 2 14 0 27 -4 30 -5 3 -9 18 -9 35 0 28 -3 37 -28
86 -7 13 -12 32 -12 42 0 11 -4 22 -10 26 -5 3 -7 12 -4 19 3 8 1 17 -5 21 -6
3 -11 17 -11 31 0 13 -4 24 -10 24 -5 0 -10 11 -10 24 0 14 -4 27 -9 30 -4 3
-11 23 -15 45 -6 39 -44 123 -58 129 -5 2 -8 13 -8 24 0 20 -9 43 -56 144 -13
28 -24 55 -24 61 0 16 -29 70 -45 83 -8 7 -17 27 -21 46 -3 18 -13 39 -21 45
-15 13 -53 90 -53 108 0 6 -3 11 -8 11 -4 0 -15 17 -25 38 -22 48 -38 73 -58
92 -9 8 -20 26 -24 40 -4 14 -14 33 -23 43 -16 18 -35 49 -50 82 -6 11 -22 29
-36 40 -14 11 -26 25 -26 31 0 6 -11 21 -25 34 -14 13 -25 29 -25 35 0 6 -16
26 -35 45 -19 19 -35 39 -35 45 0 5 -58 69 -130 140 -120 120 -145 155 -121
170 6 3 22 31 37 63 16 31 31 59 34 62 14 13 220 418 220 433 0 11 32 80 39
87 11 10 30 55 36 88 4 17 11 32 16 32 5 0 9 9 9 20 0 11 3 20 8 20 9 0 42 74
42 94 0 8 4 18 10 21 5 3 10 15 10 25 0 11 11 39 25 64 14 25 25 52 25 61 0 8
5 24 10 35 6 11 14 28 19 38 5 10 12 37 16 60 4 23 11 44 16 48 5 3 9 14 9 25
0 10 4 27 9 37 18 36 30 68 36 100 8 37 32 89 46 97 5 4 19 -1 31 -9 12 -9 37
-16 55 -16 18 0 33 -4 33 -10 0 -5 11 -10 24 -10 14 0 28 -4 31 -10 3 -5 19
-10 35 -10 16 0 32 -5 36 -11 4 -7 24 -9 50 -6 25 2 47 1 50 -4 7 -12 401 -12
409 1 3 5 13 6 21 3 16 -6 92 14 108 29 6 4 20 8 32 8 12 0 35 7 50 15 16 8
38 15 49 15 11 0 36 13 56 29 20 17 47 33 61 36 14 4 38 20 54 36 15 16 32 29
37 29 21 0 146 140 166 187 6 11 15 24 21 28 5 3 16 21 24 39 7 17 19 39 27
47 22 23 39 57 39 77 0 10 7 27 15 38 8 10 15 27 15 37 0 9 5 26 10 37 6 11
15 29 20 40 6 11 13 47 17 80 3 34 10 63 14 66 5 3 9 23 9 44 0 21 5 42 10 45
5 3 10 35 10 70 0 35 5 67 10 70 6 4 10 82 10 201 0 123 -4 194 -10 194 -6 0
-10 33 -10 80 0 47 -4 80 -10 80 -5 0 -10 20 -10 45 0 25 -4 45 -9 45 -5 0
-12 29 -16 65 -3 36 -11 67 -16 70 -5 4 -9 17 -9 31 0 13 -4 24 -10 24 -5 0
-10 11 -10 24 0 14 -4 27 -9 30 -5 3 -12 23 -15 43 -9 46 -28 93 -38 93 -5 0
-8 11 -8 24 0 14 -4 27 -9 30 -5 3 -12 18 -16 33 -3 15 -10 30 -14 33 -11 8
-61 115 -61 132 0 8 -9 23 -19 32 -11 10 -23 31 -26 46 -3 15 -15 36 -26 46
-10 9 -19 23 -19 31 0 7 -3 13 -8 13 -8 0 -12 8 -49 82 -12 24 -31 52 -42 62
-12 11 -21 24 -21 30 0 7 -9 18 -20 26 -11 8 -20 19 -20 25 0 7 -11 22 -25 35
-14 13 -25 29 -25 35 0 6 -11 22 -25 35 -14 13 -25 29 -25 35 0 7 -20 31 -45
54 -25 23 -45 45 -45 50 0 10 -319 331 -330 331 -3 0 -17 11 -30 25 -13 14
-29 25 -35 25 -6 0 -22 11 -35 25 -13 14 -29 25 -35 25 -6 0 -24 14 -40 30
-16 17 -35 30 -42 30 -8 0 -16 7 -19 15 -4 8 -12 15 -19 15 -6 0 -20 9 -30 20
-10 11 -22 20 -26 20 -16 0 -89 35 -89 42 0 5 -5 8 -12 8 -13 0 -121 51 -128
61 -3 4 -19 10 -35 14 -42 10 -85 29 -85 37 0 5 -11 8 -24 8 -14 0 -27 4 -31
9 -3 6 -27 13 -53 16 -26 3 -55 10 -64 16 -10 5 -29 9 -42 9 -14 0 -28 5 -31
10 -3 6 -30 10 -60 10 -30 0 -57 5 -60 10 -4 6 -88 10 -221 10 -136 0 -214 -4
-214 -10 0 -6 -26 -10 -59 -10 -33 0 -63 -4 -66 -10 -3 -5 -19 -10 -35 -10
-16 0 -31 -4 -34 -9 -3 -4 -29 -11 -57 -15 -28 -4 -58 -11 -67 -15 -76 -38
-105 -51 -115 -51 -17 0 -195 -90 -207 -105 -6 -8 -24 -17 -40 -20 -15 -3 -36
-15 -46 -26 -9 -10 -21 -19 -26 -19 -5 0 -19 -11 -32 -25 -13 -14 -27 -25 -33
-25 -5 0 -29 -20 -53 -45 -24 -25 -49 -45 -55 -45 -13 0 -135 -122 -135 -136
0 -5 -20 -30 -45 -54 -25 -24 -45 -48 -45 -53 0 -5 -8 -17 -18 -26 -24 -22
-85 -111 -101 -148 -5 -11 -14 -24 -20 -27 -5 -4 -20 -28 -32 -54 -13 -26 -29
-54 -37 -63 -18 -22 -52 -91 -52 -104 0 -6 -20 -51 -45 -99 -25 -49 -45 -97
-45 -107 0 -11 -4 -19 -9 -19 -5 0 -12 -15 -16 -32 -9 -43 -28 -88 -37 -88 -5
0 -8 -8 -8 -19 0 -10 -7 -32 -15 -47 -8 -16 -15 -37 -15 -46 0 -9 -4 -20 -10
-23 -5 -3 -10 -17 -10 -31 0 -13 -4 -24 -10 -24 -5 0 -10 -11 -10 -24 0 -14
-4 -27 -9 -30 -5 -3 -12 -26 -15 -51 -4 -24 -11 -47 -17 -50 -5 -4 -9 -17 -9
-31 0 -13 -4 -24 -10 -24 -5 0 -10 -11 -10 -24 0 -14 -4 -27 -9 -30 -5 -3 -12
-30 -16 -61 -3 -30 -11 -57 -16 -60 -5 -4 -9 -17 -9 -31 0 -13 -4 -32 -10 -42
-16 -28 -40 -111 -40 -137 0 -13 -4 -27 -10 -30 -5 -3 -10 -17 -10 -31 0 -13
-4 -24 -10 -24 -5 0 -10 -15 -10 -34 0 -19 -4 -37 -9 -40 -4 -3 -6 -16 -4 -30
3 -13 0 -27 -6 -30 -6 -4 -11 -20 -11 -36 0 -16 -4 -32 -10 -35 -5 -3 -10 -22
-10 -41 0 -19 -4 -34 -9 -34 -4 0 -11 -33 -15 -72 -4 -40 -11 -77 -16 -82 -6
-6 -10 -22 -10 -37 0 -15 -4 -31 -10 -34 -5 -3 -10 -19 -10 -35 0 -16 -4 -31
-9 -34 -5 -3 -12 -42 -16 -86 -4 -44 -11 -83 -16 -86 -5 -3 -9 -23 -9 -44 0
-21 -4 -42 -10 -45 -5 -3 -10 -23 -10 -44 0 -20 -4 -41 -9 -46 -6 -6 -13 -52
-17 -103 -4 -51 -11 -95 -15 -98 -5 -3 -9 -32 -9 -64 0 -32 -4 -62 -10 -65 -5
-3 -10 -28 -10 -54 0 -26 -4 -51 -10 -57 -5 -5 -12 -71 -16 -147 -4 -76 -11
-140 -16 -143 -4 -3 -8 -45 -8 -94 0 -49 -4 -92 -10 -95 -6 -4 -10 -62 -10
-141 l0 -134 -97 6 c-54 4 -102 10 -107 15 -13 12 -526 12 -526 1 0 -5 -48
-12 -107 -16 -59 -3 -112 -11 -117 -16 -6 -6 -27 -10 -47 -10 -21 0 -41 -4
-44 -10 -3 -5 -19 -10 -34 -10 -15 0 -31 -4 -37 -9 -5 -4 -26 -11 -46 -14
l-38 -6 0 50 c0 27 -4 49 -10 49 -6 0 -10 38 -10 93 0 52 -3 97 -7 100 -3 4
-5 38 -4 76 1 40 -2 72 -8 76 -6 3 -11 35 -11 70 0 35 -4 67 -10 70 -5 3 -10
33 -10 66 0 32 -4 59 -8 59 -5 0 -12 51 -16 112 -4 62 -11 117 -16 122 -6 6
-10 31 -10 57 0 26 -4 51 -10 54 -5 3 -10 28 -10 55 0 27 -4 51 -9 55 -5 3
-13 46 -17 95 -3 50 -11 93 -15 96 -5 3 -9 25 -9 49 0 24 -4 47 -10 50 -5 3
-10 24 -10 45 0 21 -4 41 -9 44 -5 3 -12 35 -16 71 -3 36 -11 67 -16 70 -5 4
-9 19 -9 35 0 16 -4 32 -10 35 -5 3 -10 19 -10 35 0 16 -4 31 -9 35 -5 3 -13
34 -16 70 -4 36 -11 68 -16 71 -5 3 -9 18 -9 34 0 16 -4 32 -10 35 -5 3 -10
19 -10 35 0 16 -4 31 -9 34 -5 4 -12 29 -16 58 -7 51 -10 60 -33 105 -7 13
-12 36 -12 52 0 17 -4 33 -10 36 -5 3 -12 28 -16 56 -4 27 -11 52 -15 55 -5 3
-9 14 -9 25 0 10 -4 27 -9 37 -12 22 -24 53 -27 72 -16 80 -34 130 -46 130 -5
0 -8 13 -8 30 0 26 -15 70 -41 122 -5 10 -9 27 -9 38 0 11 -4 20 -9 20 -5 0
-12 23 -16 50 -4 28 -10 50 -13 50 -10 0 -32 51 -32 71 0 10 -4 21 -10 24 -5
3 -10 14 -10 23 0 9 -7 30 -15 46 -8 15 -15 37 -15 47 0 11 -3 19 -8 19 -9 0
-28 45 -37 88 -4 17 -11 32 -16 32 -5 0 -9 8 -9 18 0 9 -20 58 -44 107 -24 50
-51 108 -61 130 -23 56 -39 89 -46 95 -8 8 -39 77 -39 88 0 5 -6 15 -14 21 -8
7 -35 54 -61 106 -25 51 -49 95 -53 97 -4 2 -20 28 -35 58 -36 71 -48 91 -69
110 -9 9 -20 28 -23 42 -4 14 -20 38 -36 54 -16 15 -29 33 -29 39 0 6 -11 22
-25 35 -14 13 -25 29 -25 36 0 6 -7 14 -15 18 -8 3 -15 11 -15 19 0 7 -16 28
-35 47 -19 19 -35 39 -35 45 0 13 -272 285 -286 285 -6 0 -21 11 -34 25 -13
14 -28 25 -33 25 -5 0 -19 10 -31 23 -11 12 -47 36 -79 52 -32 17 -67 34 -78
40 -10 5 -19 13 -19 17 0 5 -8 8 -19 8 -10 0 -32 7 -47 15 -16 8 -37 15 -46
15 -9 0 -20 5 -23 10 -3 6 -17 10 -30 10 -13 0 -27 5 -30 10 -3 6 -26 10 -50
10 -24 0 -47 5 -50 10 -4 6 -77 10 -186 10 -113 0 -179 -4 -179 -10z m225
-650 c3 -5 23 -10 43 -10 20 0 50 -7 66 -15 15 -8 37 -15 47 -15 11 0 19 -4
19 -9 0 -5 20 -19 44 -31 24 -11 50 -28 56 -36 7 -7 17 -14 24 -14 14 0 236
-221 236 -235 0 -6 14 -24 30 -40 17 -16 30 -34 30 -40 0 -6 16 -26 35 -45 19
-19 35 -40 35 -47 0 -8 7 -16 15 -19 8 -4 15 -12 15 -19 0 -6 9 -20 19 -29 11
-10 23 -31 26 -46 3 -16 13 -34 21 -41 8 -7 26 -36 40 -65 14 -30 29 -56 34
-59 12 -7 158 -304 166 -338 3 -15 10 -30 15 -33 5 -3 9 -13 9 -23 0 -21 22
-71 33 -71 4 0 7 -9 7 -21 0 -20 10 -47 51 -134 10 -22 21 -53 24 -70 6 -30
19 -63 36 -97 5 -10 9 -24 9 -32 0 -7 7 -27 15 -42 8 -16 15 -37 15 -46 0 -9
5 -20 10 -23 6 -3 10 -17 10 -31 0 -13 5 -24 10 -24 6 0 10 -11 10 -24 0 -14
4 -27 9 -31 6 -3 13 -26 17 -50 3 -25 10 -48 15 -51 5 -3 9 -18 9 -34 0 -16 5
-32 10 -35 6 -3 10 -17 10 -30 0 -13 4 -26 9 -30 6 -3 13 -26 17 -50 3 -25 10
-45 15 -45 5 0 9 -11 9 -24 0 -14 4 -27 9 -30 5 -3 11 -23 15 -43 10 -64 17
-89 37 -125 5 -10 9 -31 9 -48 0 -16 4 -30 9 -30 4 0 11 -23 14 -52 4 -28 11
-56 17 -62 5 -5 10 -25 10 -43 0 -18 5 -33 10 -33 6 0 10 -11 10 -24 0 -14 4
-27 9 -31 6 -3 13 -27 16 -53 3 -26 10 -55 16 -64 5 -10 9 -29 9 -42 0 -14 5
-28 10 -31 6 -3 10 -23 10 -44 0 -20 5 -42 11 -48 5 -5 13 -36 16 -67 3 -31
10 -59 14 -62 5 -3 9 -23 9 -44 0 -21 5 -42 10 -45 6 -3 10 -22 10 -41 0 -19
4 -34 9 -34 5 0 13 -41 17 -90 3 -50 11 -93 15 -96 5 -3 9 -27 9 -54 0 -27 5
-52 10 -55 6 -3 10 -30 10 -60 0 -30 4 -56 9 -59 5 -3 12 -58 16 -121 4 -63
11 -118 16 -121 5 -3 9 -43 9 -89 0 -46 5 -87 10 -90 6 -3 10 -44 10 -90 0
-46 4 -86 9 -89 5 -3 12 -105 16 -226 4 -121 11 -220 16 -220 5 0 9 -38 9 -84
0 -47 5 -88 10 -91 6 -3 10 -14 10 -23 0 -42 64 -135 105 -153 11 -5 27 -13
35 -17 45 -26 63 -32 90 -32 16 0 30 -4 30 -10 0 -5 16 -10 35 -10 19 0 35 5
35 10 0 6 16 10 35 10 19 0 43 4 53 9 9 6 38 13 64 16 26 3 50 10 53 16 4 5
17 9 31 9 13 0 24 5 24 10 0 6 9 10 20 10 11 0 28 4 38 10 9 5 43 12 75 15 31
4 57 11 57 16 0 5 20 9 45 9 25 0 45 5 45 10 0 6 26 10 58 10 33 0 63 5 71 13
9 9 94 12 356 12 262 0 347 -3 357 -12 6 -7 33 -13 59 -13 26 0 51 -4 54 -10
3 -6 28 -10 54 -10 26 0 52 -5 59 -12 18 -18 231 -17 268 1 43 22 113 91 132
131 9 19 21 38 26 42 7 5 12 85 14 218 2 117 8 210 13 210 5 0 9 54 9 119 0
69 4 122 10 126 6 3 10 44 10 90 0 46 4 86 9 89 5 4 12 69 16 146 4 77 12 143
16 146 5 3 9 32 9 65 0 33 4 59 10 59 6 0 10 22 10 49 0 28 4 52 9 55 4 3 12
46 15 96 4 49 12 92 17 95 5 4 9 24 9 45 0 21 5 42 10 45 6 3 10 28 10 55 0
27 5 52 11 56 6 3 9 20 7 36 -3 16 -1 31 4 34 4 3 8 20 8 39 0 19 5 37 10 40
6 3 10 24 10 45 0 21 5 42 10 45 6 3 10 19 10 35 0 16 4 31 9 34 4 3 6 16 4
30 -3 13 0 27 6 30 6 4 11 18 11 32 0 13 5 24 10 24 6 0 10 15 10 34 0 19 4
37 9 40 4 3 11 28 15 55 4 28 11 53 16 56 6 3 10 19 10 36 0 16 4 37 9 47 21
41 30 70 36 114 3 26 10 50 16 53 5 4 9 19 9 35 0 16 5 32 10 35 6 3 10 17 10
30 0 13 4 27 10 30 5 3 12 28 16 56 4 27 11 52 15 55 5 3 9 21 9 40 0 19 3 34
8 34 11 0 32 51 32 80 0 14 7 35 15 46 8 10 15 27 15 37 0 9 4 25 9 35 19 37
30 68 37 101 3 19 15 50 25 68 11 19 19 41 19 51 0 9 7 26 15 36 8 11 15 28
15 38 0 17 18 57 31 68 8 8 22 43 24 63 1 9 10 26 19 36 9 9 16 23 16 29 0 7
5 12 10 12 6 0 10 5 10 11 0 18 33 82 53 104 10 11 26 32 35 48 9 15 20 27 24
27 4 0 8 6 8 13 0 8 11 24 25 37 14 13 25 28 25 35 0 14 112 125 126 125 6 0
21 11 34 25 13 14 27 25 32 25 5 0 21 11 35 25 31 28 200 115 225 115 9 0 19
4 22 9 3 5 33 12 66 16 33 4 63 11 66 16 3 5 32 9 64 9 32 0 62 5 65 10 3 6
42 10 85 10 43 0 82 -4 85 -10 3 -5 33 -10 65 -10 32 0 61 -4 64 -9 3 -4 31
-11 62 -14 31 -3 62 -11 67 -16 6 -6 21 -11 33 -11 13 0 26 -4 29 -10 3 -5 13
-10 21 -10 20 0 94 -33 94 -42 0 -5 9 -8 20 -8 11 0 20 -3 20 -8 0 -7 4 -10
77 -46 21 -11 40 -23 43 -26 5 -5 30 -23 89 -62 14 -10 33 -21 43 -25 9 -5 52
-43 97 -85 44 -43 85 -78 91 -78 5 0 10 -7 10 -15 0 -9 8 -18 18 -22 20 -7 52
-38 52 -50 0 -5 23 -31 50 -58 28 -27 50 -54 50 -60 0 -6 16 -26 35 -45 19
-19 35 -40 35 -47 0 -7 9 -18 20 -25 11 -7 20 -20 20 -29 0 -9 7 -19 15 -23 8
-3 15 -12 15 -19 0 -8 7 -21 16 -28 9 -7 20 -22 25 -34 18 -38 38 -70 52 -80
12 -9 25 -34 58 -112 8 -18 17 -33 21 -33 5 0 8 -4 8 -10 0 -15 53 -125 62
-128 4 -2 8 -13 8 -24 0 -18 18 -67 41 -110 5 -10 9 -27 9 -37 0 -11 4 -23 10
-26 5 -3 12 -28 16 -56 4 -27 11 -52 15 -55 5 -3 9 -20 9 -39 0 -19 5 -37 10
-40 6 -3 10 -28 10 -56 0 -27 5 -49 10 -49 14 0 14 -317 0 -325 -6 -3 -10 -28
-10 -55 0 -27 -5 -52 -10 -55 -6 -3 -10 -19 -10 -35 0 -16 -4 -31 -9 -34 -5
-4 -12 -24 -16 -46 -10 -59 -28 -89 -88 -148 -57 -56 -135 -102 -173 -102 -13
0 -26 -4 -29 -10 -8 -13 -172 -13 -180 0 -3 6 -26 10 -51 10 -24 0 -44 5 -44
10 0 6 -15 10 -32 10 -18 0 -42 7 -52 15 -11 8 -30 15 -42 15 -13 0 -26 5 -29
10 -3 6 -17 10 -31 10 -13 0 -24 3 -24 8 0 4 -15 13 -32 21 -79 33 -104 46
-113 58 -10 14 -42 34 -80 52 -12 5 -27 16 -34 25 -7 9 -19 16 -26 16 -7 0
-21 11 -31 25 -10 14 -24 25 -29 25 -6 0 -29 18 -50 40 -21 22 -44 40 -49 40
-14 0 -166 152 -166 165 0 6 -27 37 -60 70 -33 33 -60 63 -60 68 0 5 -11 18
-25 29 -14 11 -25 25 -25 32 0 7 -9 21 -20 31 -11 10 -20 23 -20 30 0 6 -11
22 -25 35 -14 13 -25 29 -25 37 0 7 -4 13 -9 13 -5 0 -12 8 -15 18 -9 24 -30
59 -49 79 -8 10 -19 30 -22 46 -4 15 -15 33 -24 40 -16 12 -51 76 -51 94 0 11
-108 114 -137 131 -13 6 -32 12 -43 12 -11 0 -29 6 -40 12 -16 10 -24 10 -40
0 -11 -6 -28 -12 -39 -12 -79 0 -241 -170 -241 -253 0 -9 -4 -19 -10 -22 -5
-3 -10 -37 -10 -75 0 -38 5 -72 10 -75 6 -3 10 -17 10 -31 0 -28 31 -104 42
-104 5 0 8 -11 8 -24 0 -14 4 -27 9 -30 5 -3 12 -18 16 -33 3 -15 14 -34 23
-43 20 -18 34 -41 59 -90 19 -39 64 -103 76 -108 4 -2 7 -9 7 -16 0 -7 11 -23
25 -36 14 -13 25 -29 25 -35 0 -6 16 -26 35 -45 19 -19 35 -39 35 -44 0 -6 20
-30 44 -53 25 -24 46 -48 48 -53 4 -14 269 -280 278 -280 12 0 100 -94 100
-107 0 -6 -5 -15 -10 -18 -6 -3 -10 -14 -10 -23 0 -9 -7 -30 -15 -46 -8 -15
-15 -37 -15 -47 0 -11 -4 -19 -10 -19 -5 0 -10 -8 -10 -19 0 -10 -7 -32 -15
-47 -8 -16 -15 -37 -15 -46 0 -9 -4 -20 -10 -23 -6 -3 -10 -15 -10 -26 0 -11
-7 -31 -16 -45 -9 -13 -18 -32 -19 -42 -4 -31 -17 -62 -26 -62 -5 0 -9 -9 -9
-20 0 -11 -4 -28 -10 -38 -5 -9 -16 -35 -25 -57 -9 -22 -25 -57 -36 -78 -10
-22 -19 -44 -19 -49 0 -14 -52 -121 -61 -128 -4 -3 -10 -19 -14 -35 -7 -30
-25 -75 -35 -85 -6 -5 -19 -33 -46 -95 -10 -22 -20 -42 -23 -45 -8 -6 -40 -66
-86 -157 -20 -40 -41 -75 -46 -79 -5 -3 -21 -30 -35 -59 -14 -30 -30 -57 -35
-61 -6 -3 -14 -16 -20 -27 -9 -23 -30 -58 -39 -67 -9 -9 -30 -44 -39 -67 -6
-11 -15 -24 -20 -28 -6 -3 -20 -26 -31 -51 -11 -24 -24 -44 -28 -44 -10 0 -32
-50 -32 -71 0 -10 -4 -21 -10 -24 -5 -3 -10 -33 -10 -65 0 -32 5 -62 10 -65 6
-3 10 -15 10 -26 0 -23 20 -61 38 -72 6 -4 12 -13 12 -19 0 -14 40 -58 52 -58
5 0 29 -20 54 -45 24 -25 47 -45 51 -45 11 0 333 -323 333 -333 0 -5 16 -23
35 -41 19 -19 35 -38 35 -43 0 -6 9 -18 20 -28 11 -10 20 -23 20 -30 0 -6 11
-22 25 -35 14 -13 25 -29 25 -35 0 -6 11 -22 25 -35 14 -13 25 -29 25 -37 0
-7 3 -13 8 -13 7 0 11 -7 46 -77 11 -21 29 -51 41 -68 24 -34 75 -137 75 -152
0 -5 20 -49 45 -97 25 -49 45 -96 45 -107 0 -10 3 -19 8 -19 9 0 28 -45 37
-89 4 -19 16 -50 26 -68 11 -19 19 -44 19 -58 0 -13 4 -26 9 -29 5 -3 12 -26
15 -51 4 -24 11 -47 17 -50 5 -4 9 -17 9 -30 0 -13 5 -27 10 -30 6 -3 10 -19
10 -35 0 -16 4 -31 9 -35 6 -3 13 -37 17 -75 4 -39 11 -73 15 -76 5 -3 9 -23
9 -44 0 -21 5 -42 10 -45 6 -3 10 -28 10 -55 0 -27 5 -52 11 -55 5 -4 10 -37
11 -73 7 -484 8 -659 2 -672 -4 -8 -6 -31 -5 -51 1 -21 -2 -40 -8 -44 -6 -3
-11 -26 -11 -51 0 -24 -4 -44 -10 -44 -5 0 -10 -18 -10 -39 0 -22 -4 -42 -9
-46 -5 -3 -13 -30 -16 -60 -4 -31 -11 -58 -16 -61 -5 -3 -9 -16 -9 -30 0 -13
-3 -24 -8 -24 -10 0 -29 -47 -38 -93 -3 -20 -10 -40 -15 -43 -5 -3 -9 -13 -9
-23 0 -21 -22 -71 -32 -71 -5 0 -8 -5 -8 -12 0 -15 -52 -122 -62 -126 -4 -2
-8 -8 -8 -14 0 -17 -32 -81 -57 -113 -13 -16 -27 -34 -31 -40 -4 -5 -16 -26
-26 -45 -40 -79 -48 -92 -62 -97 -8 -3 -14 -10 -14 -17 0 -6 -10 -23 -22 -37
-26 -29 -44 -55 -57 -84 -5 -11 -28 -38 -50 -60 -23 -21 -41 -43 -41 -48 0 -5
-36 -45 -80 -89 -44 -45 -80 -85 -80 -89 0 -5 -9 -13 -20 -19 -11 -6 -45 -36
-74 -66 -30 -29 -58 -54 -63 -54 -5 0 -24 -16 -43 -35 -19 -19 -39 -35 -45
-35 -6 0 -22 -11 -35 -25 -13 -14 -28 -25 -32 -25 -8 0 -75 -46 -88 -60 -8 -9
-77 -40 -88 -40 -6 0 -17 -8 -24 -17 -13 -18 -26 -25 -103 -59 -22 -10 -42
-20 -45 -23 -5 -6 -31 -19 -95 -47 -22 -10 -42 -20 -45 -23 -10 -11 -55 -30
-87 -36 -18 -4 -33 -11 -33 -16 0 -5 -11 -9 -24 -9 -14 0 -28 -4 -31 -10 -3
-5 -17 -10 -30 -10 -13 0 -27 -5 -30 -10 -3 -6 -14 -10 -23 -10 -9 0 -30 -7
-46 -15 -15 -8 -39 -15 -52 -15 -12 0 -25 -4 -28 -9 -5 -8 -51 -22 -86 -27
-38 -5 -81 -17 -86 -25 -3 -5 -18 -9 -34 -9 -16 0 -31 -4 -34 -9 -3 -5 -37
-12 -76 -16 -39 -4 -73 -11 -76 -16 -3 -5 -20 -9 -39 -9 -19 0 -37 -4 -40 -10
-3 -5 -24 -10 -45 -10 -21 0 -41 -4 -44 -9 -4 -5 -60 -12 -126 -16 -66 -4
-123 -12 -126 -16 -3 -5 -43 -9 -89 -9 -46 0 -87 -4 -90 -10 -4 -6 -117 -10
-305 -10 -188 0 -301 4 -305 10 -3 6 -48 10 -101 10 -52 0 -94 4 -94 9 0 5
-52 12 -115 16 -63 4 -118 11 -121 16 -3 5 -23 9 -44 9 -21 0 -42 4 -45 10 -3
5 -24 10 -45 10 -21 0 -41 4 -44 9 -3 5 -40 12 -81 16 -41 4 -75 11 -75 16 0
5 -14 9 -30 9 -17 0 -38 4 -48 9 -36 20 -61 27 -125 37 -20 4 -40 10 -43 15
-3 5 -16 9 -28 9 -13 0 -37 7 -52 15 -16 8 -37 15 -46 15 -9 0 -20 5 -23 10
-3 6 -17 10 -30 10 -13 0 -27 5 -30 10 -3 6 -17 10 -29 10 -13 0 -37 7 -52 15
-16 8 -37 15 -46 15 -9 0 -20 4 -23 10 -3 5 -14 10 -24 10 -21 0 -71 22 -71
32 0 3 -15 9 -32 13 -32 6 -77 24 -88 35 -5 6 -33 19 -95 46 -22 10 -42 21
-45 24 -3 3 -23 14 -45 24 -64 28 -90 41 -95 47 -3 3 -21 13 -40 22 -37 19
-72 39 -80 47 -8 8 -44 30 -65 39 -12 5 -27 16 -34 25 -7 9 -19 16 -25 16 -7
0 -23 11 -36 25 -13 14 -29 25 -37 25 -7 0 -13 5 -13 10 0 6 -6 10 -13 10 -7
0 -28 16 -47 35 -19 19 -39 35 -45 35 -6 0 -42 31 -80 70 -38 38 -74 70 -80
70 -14 0 -107 94 -100 101 2 3 -16 25 -40 49 -25 24 -45 48 -45 53 0 9 -27 43
-86 110 -13 15 -24 30 -24 33 0 12 -41 93 -50 99 -5 3 -24 36 -41 73 -31 67
-34 74 -64 147 -9 22 -21 48 -26 57 -5 10 -9 24 -9 32 0 7 -7 27 -15 42 -8 16
-15 41 -15 56 0 15 -4 30 -10 33 -5 3 -10 19 -10 35 0 16 -5 32 -10 35 -6 3
-10 19 -10 35 0 16 -5 32 -11 35 -6 4 -9 22 -7 40 1 19 -1 37 -5 41 -4 4 -7
29 -7 55 0 26 -4 51 -10 54 -5 3 -10 35 -10 70 0 35 -4 67 -10 70 -14 8 -14
462 0 470 5 3 10 39 10 80 0 41 4 76 9 79 4 3 11 47 15 98 4 51 11 97 17 102
5 6 9 27 9 47 0 21 5 41 10 44 5 3 10 22 10 41 0 19 4 34 9 34 4 0 11 23 14
52 4 28 11 56 17 62 5 5 10 20 10 33 0 13 5 23 10 23 6 0 10 15 10 34 0 19 4
37 9 40 5 3 12 23 15 43 9 46 28 93 38 93 5 0 8 11 8 24 0 14 4 28 10 31 5 3
10 15 10 26 0 10 18 53 40 94 22 41 40 81 40 88 0 18 28 75 41 83 5 3 26 39
47 81 54 110 56 113 64 113 5 0 8 6 8 13 0 8 9 22 20 32 11 10 18 21 15 25 -2
4 9 20 25 35 17 16 30 34 30 41 0 7 11 21 25 32 14 11 25 25 25 32 0 7 11 21
25 32 14 11 25 25 25 32 0 7 16 27 35 46 19 19 35 39 35 45 0 6 25 35 55 65
30 30 55 58 55 64 0 5 43 51 95 103 52 51 98 105 101 118 3 14 10 28 15 31 5
3 9 16 9 30 0 13 5 24 10 24 6 0 10 33 10 80 0 47 -4 80 -10 80 -5 0 -10 11
-10 24 0 14 -4 27 -9 30 -5 3 -12 17 -15 31 -4 14 -31 49 -61 79 -30 30 -55
58 -55 63 0 5 -27 35 -60 68 -33 33 -60 64 -60 70 0 6 -16 26 -35 45 -19 19
-35 39 -35 45 0 6 -11 22 -25 35 -14 13 -25 28 -25 33 0 5 -11 18 -25 29 -14
11 -25 25 -25 33 0 7 -7 19 -16 26 -9 7 -20 22 -25 34 -12 28 -31 57 -49 75
-18 18 -37 47 -49 77 -6 11 -14 24 -20 27 -5 4 -21 30 -35 60 -14 29 -32 59
-41 66 -8 7 -15 17 -15 22 0 18 -34 83 -51 99 -10 8 -21 27 -24 42 -4 15 -11
30 -16 33 -5 3 -9 15 -9 27 0 13 -9 29 -20 37 -10 8 -22 28 -25 44 -6 31 -25
76 -36 86 -5 5 -22 41 -50 108 -8 17 -17 32 -21 32 -5 0 -8 11 -8 24 0 14 -4
27 -9 31 -5 3 -12 19 -16 35 -4 17 -11 30 -16 30 -5 0 -9 9 -9 20 0 11 -9 35
-20 55 -11 19 -19 39 -18 43 3 11 -36 92 -44 92 -5 0 -8 11 -8 24 0 14 -5 28
-10 31 -6 4 -8 11 -4 16 3 5 -4 26 -15 45 -12 19 -21 44 -21 54 0 10 -4 22
-10 25 -5 3 -10 14 -10 23 0 9 -7 30 -15 46 -8 15 -15 37 -15 47 0 11 -3 19
-8 19 -10 0 -29 47 -38 93 -3 20 -10 40 -15 43 -5 3 -9 14 -9 25 0 10 -4 27
-9 37 -21 39 -41 91 -41 105 0 9 -4 19 -10 22 -5 3 -10 22 -10 41 0 19 -4 34
-10 34 -5 0 -10 11 -10 24 0 14 -4 27 -9 30 -5 3 -12 26 -15 51 -4 24 -11 47
-17 50 -5 4 -9 17 -9 31 0 13 -4 24 -10 24 -5 0 -10 11 -10 24 0 14 -4 27 -9
30 -5 3 -12 26 -15 51 -4 24 -11 47 -17 50 -5 4 -9 17 -9 31 0 13 -4 24 -10
24 -5 0 -10 15 -10 33 0 18 -5 38 -10 43 -6 6 -13 34 -17 62 -3 29 -10 52 -14
52 -5 0 -9 11 -9 24 0 14 -4 28 -10 31 -5 3 -10 19 -10 35 0 16 -5 32 -11 36
-6 3 -9 17 -6 30 2 14 0 27 -4 30 -5 3 -9 21 -9 40 0 19 -4 34 -10 34 -5 0
-10 20 -10 45 0 25 -4 45 -10 45 -5 0 -10 15 -10 33 0 19 -3 37 -7 41 -4 4 -6
24 -4 45 1 22 -2 42 -8 46 -6 3 -11 26 -11 51 0 24 -4 44 -10 44 -6 0 -10 26
-10 58 0 33 -5 63 -12 70 -19 19 -19 685 0 703 6 7 12 34 12 60 0 26 5 51 10
54 6 3 10 24 10 45 0 21 5 42 11 45 6 4 8 13 5 21 -3 7 -1 16 4 19 6 4 10 22
10 41 0 19 5 34 10 34 6 0 10 16 10 35 0 19 4 35 9 35 8 0 19 28 26 65 6 28
18 55 26 55 5 0 9 11 9 24 0 14 4 28 10 31 5 3 17 23 27 43 9 20 19 39 22 42
9 7 30 42 40 65 5 11 21 31 35 44 14 14 26 29 26 35 0 14 51 66 65 66 6 0 22
11 35 25 13 14 28 25 34 25 5 0 20 9 32 21 14 13 41 22 78 26 31 3 59 10 62
14 7 12 101 11 109 -1z M6190 4813 c-19 -2 -37 -8 -40 -12 -3 -4 -21 -15 -40
-25 -19 -9 -45 -23 -58 -30 -33 -19 -82 -67 -82 -81 0 -7 -9 -20 -20 -30 -25
-22 -60 -90 -60 -115 0 -10 -4 -22 -10 -25 -5 -3 -10 -24 -10 -45 0 -21 -4
-42 -10 -45 -5 -3 -10 -26 -10 -50 0 -24 5 -47 10 -50 6 -3 10 -22 10 -41 0
-19 4 -42 10 -52 5 -9 17 -35 27 -57 38 -86 203 -215 276 -215 14 0 29 -4 32
-10 3 -5 37 -10 76 -10 39 0 69 4 69 10 0 6 13 10 29 10 72 0 242 128 256 192
4 15 11 28 16 28 5 0 9 11 9 24 0 14 5 28 10 31 6 3 10 17 10 30 0 13 3 26 8
28 12 8 -3 236 -16 249 -7 7 -12 20 -12 31 0 10 -11 33 -25 51 -14 18 -25 37
-25 43 0 6 -26 33 -57 62 -87 78 -92 81 -111 81 -10 0 -23 5 -29 11 -12 12
-173 21 -233 12z M3395 4730 c-3 -5 -17 -10 -30 -10 -26 0 -125 -48 -125 -61
0 -5 -6 -9 -14 -9 -11 0 -77 -66 -111 -112 -22 -29 -55 -100 -50 -108 3 -5 1
-11 -5 -15 -13 -8 -13 -252 0 -260 6 -4 9 -12 8 -18 -5 -27 40 -97 107 -162
86 -84 99 -92 164 -101 28 -4 54 -11 57 -15 7 -12 151 -11 159 1 3 6 13 10 22
10 52 0 233 129 233 166 0 6 9 19 20 29 11 10 20 28 20 41 0 12 6 24 13 26 9
4 12 42 12 149 0 138 -1 146 -28 202 -16 32 -38 63 -48 70 -10 6 -19 17 -19
22 0 37 -161 145 -216 145 -13 0 -26 5 -29 10 -3 6 -35 10 -70 10 -35 0 -67
-4 -70 -10z M4700 3490 c0 -5 -17 -10 -37 -10 -77 0 -192 -75 -230 -148 -30
-57 -10 -197 32 -232 8 -7 15 -18 15 -25 0 -7 11 -21 25 -31 14 -10 25 -23 25
-29 0 -12 92 -105 104 -105 4 0 22 -15 39 -33 18 -19 40 -37 50 -40 11 -4 21
-16 24 -27 3 -11 8 -20 12 -20 11 0 13 -131 3 -144 -5 -6 -12 -54 -15 -106 -3
-56 -9 -96 -16 -98 -6 -2 -11 -14 -11 -27 0 -12 -7 -29 -16 -36 -9 -7 -20 -23
-25 -36 -5 -13 -15 -23 -22 -23 -7 0 -26 -13 -42 -30 -15 -16 -41 -32 -56 -35
-16 -4 -29 -11 -29 -16 0 -12 -187 -12 -195 1 -3 6 -15 10 -27 10 -22 0 -72
25 -105 53 -15 13 -38 19 -76 19 -52 1 -58 -2 -94 -39 -21 -22 -44 -50 -50
-61 -15 -26 -17 -82 -3 -82 6 0 10 -6 10 -13 0 -19 69 -82 108 -98 17 -8 32
-17 32 -21 0 -5 4 -8 10 -8 17 0 90 -34 90 -42 0 -5 15 -8 34 -8 19 0 38 -4
41 -10 8 -13 288 -14 313 -1 39 20 108 50 130 56 12 4 22 11 22 16 0 5 6 9 13
9 8 0 22 9 32 20 10 11 23 20 29 20 6 0 33 23 61 50 l51 50 44 -45 c24 -25 49
-45 55 -45 6 0 22 -11 35 -25 13 -14 29 -25 37 -25 7 0 13 -4 13 -9 0 -5 13
-12 30 -16 16 -4 32 -11 35 -16 4 -5 17 -9 31 -9 13 0 24 -4 24 -10 0 -5 16
-10 35 -10 19 0 35 -4 35 -10 0 -13 267 -13 275 0 3 6 19 10 35 10 16 0 32 5
35 10 3 6 15 10 26 10 17 0 65 24 79 40 3 3 21 13 41 23 19 9 43 25 54 37 10
11 24 20 32 20 7 0 13 6 13 13 0 8 9 22 20 32 29 26 36 96 14 137 -31 55 -56
78 -85 78 -15 0 -31 4 -34 10 -6 9 -18 5 -65 -22 -8 -4 -25 -12 -37 -17 -11
-6 -24 -15 -28 -20 -10 -17 -91 -51 -119 -51 -14 0 -28 -4 -31 -10 -8 -12
-112 -13 -119 -1 -3 4 -22 11 -41 14 -22 4 -47 18 -64 36 -16 17 -34 31 -40
31 -6 0 -11 5 -11 11 0 7 -8 19 -18 28 -10 9 -26 34 -35 56 -10 22 -22 48 -27
57 -6 10 -10 34 -10 53 0 19 -4 35 -10 35 -6 0 -10 48 -10 125 l0 126 93 94
c113 115 165 188 167 233 0 6 5 12 10 12 13 0 13 167 1 175 -5 3 -12 18 -16
34 -10 48 -96 105 -177 118 -21 3 -38 9 -38 14 0 5 -115 9 -255 9 -163 0 -255
-4 -255 -10z"/></g></g></svg>
<span>Doorgaan met ROUT</span>
</button>
</form>
<style>
:root { --rout-button-bg: #FFFFFF; --rout-button-ink: #131211; }
.rout-button { display: inline-flex; align-items: center; justify-content: center;
gap: 10px; min-height: 44px; padding: 10px 18px; border-radius: 8px;
background: var(--rout-button-bg); color: var(--rout-button-ink);
border: 1px solid currentColor; font: inherit; cursor: pointer; }
.rout-button svg { width: 20px; height: 25px; flex-shrink: 0; }
.rout-button:focus-visible { outline: 2px solid currentColor; outline-offset: 3px; }
.rout-button:disabled { opacity: .5; cursor: not-allowed; }
</style>Code-flow met PKCE (S256)
PKCE is altijd verplicht, ook voor apps met een geheim. Terug-adressen moeten letterlijk overeenkomen met wat je registreerde (https, http enkel voor localhost, geen * en geen #).
// Server-side start handler: only run after the form's explicit POST.
// Pseudocode: use your OIDC library + framework cookie/CSRF helpers.
const clientId = process.env.ROUT_CLIENT_ID;
const redirectUri = process.env.ROUT_REDIRECT_URI; // exact registered URL in YOUR app
if (!clientId || !redirectUri) throw new Error("ROUT is not configured");
// 1. Discovery ophalen (nooit endpoints hardcoden)
const oidc = await fetch("https://rout.be/.well-known/openid-configuration").then((r) => r.json());
// 2. Per poging: verifier, state en nonce — bewaar ze in een HttpOnly-cookie
const b64 = (b) => btoa(String.fromCharCode(...new Uint8Array(b)))
.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
const verifier = b64(crypto.getRandomValues(new Uint8Array(32)));
const challenge = b64(await crypto.subtle.digest("SHA-256", new TextEncoder().encode(verifier)));
const state = crypto.randomUUID();
const nonce = crypto.randomUUID();
// 3. Doorsturen
const url = new URL(oidc.authorization_endpoint);
url.search = new URLSearchParams({
response_type: "code",
client_id: clientId,
redirect_uri: redirectUri,
scope: "openid profile email",
code_challenge: challenge,
code_challenge_method: "S256",
state, nonce,
}).toString();
// Persist verifier/state/nonce in a short-lived HttpOnly Secure SameSite=Lax cookie,
// then return a redirect to url. Never run this when the page merely loads.// Op je server, in /auth/callback/rout — na controle van state
const res = await fetch(oidc.token_endpoint, {
method: "POST",
headers: { "content-type": "application/x-www-form-urlencoded" },
body: new URLSearchParams({
grant_type: "authorization_code",
code, redirect_uri, code_verifier: verifier,
client_id: process.env.ROUT_CLIENT_ID,
client_secret: process.env.ROUT_CLIENT_SECRET, // nooit in de browser
}),
});
const { id_token, access_token } = await res.json();
// Controleer id_token via jwks_uri (ES256): iss, aud === client_id, exp en nonce.Codes zijn eenmalig en kortlevend. Het geheim stuur je mee als client_secret_post of via HTTP Basic; single-page en mobiele apps gebruiken geen geheim.
Scopes en claims
| Scope | Claims |
|---|---|
| openid | sub — vaste, unieke ROUT-ID |
| profile | name, preferred_username, picture; plus rout_handle als de app Universal Handle Sync aanzet |
email, email_verified | |
| linked_accounts | Gekoppelde sociale accounts die de gebruiker deelt |
| Rich Identity | rout_public_activity (lijst van kind, title, occurred_at) in het id_token — alleen als de app dit aanzet én de gebruiker het vakje aanvinkt |
Je eigen app bouwen
Aanbevolen opbouw voor een app die "Login met ROUT" gebruikt:
- Knop: het officiële ROUT-logo met lokale tekst ("Login met ROUT", "Se connecter avec ROUT", "Mit ROUT anmelden").
- Popup of doorsturen: open een gecentreerde popup (500 × 650). Geblokkeerd? Stuur dan gewoon door; verifier, state en nonce blijven in een HttpOnly-, Secure-, SameSite=Lax-cookie.
- Callback op het geregistreerde adres in jouw eigen app (bijvoorbeeld
/auth/callback/rout, geen ROUT-endpoint): controleer state, wissel de code in op de server, controleer het id_token (ES256 via JWKS; iss, aud, exp, nonce). - Sessie: maak je eigen sessiecookie. Tokens komen nooit in browser-JavaScript.
- Koppelen: bestaat er al een gebruiker met hetzelfde geverifieerde e-mailadres, koppel ROUT dan aan dat account (in
user_identities) in plaats van een dubbel account te maken. Anders: nieuw account metrout_id = sub. - Rich Identity: overschrijf
rout_public_activitybij elke login vanuit het id_token en wis het als de claim ontbreekt. Vertrouw nooit invoer uit de browser. - Fouten: vertaal
?error=naar een vriendelijke melding (zie foutcodes).
alter table users add column if not exists rout_id text unique;
alter table users add column if not exists email_verified boolean not null default false;
alter table users add column if not exists is_verified_person boolean not null default false;
alter table users add column if not exists is_verified_business boolean not null default false;
alter table users add column if not exists is_influencer boolean not null default false;
create table if not exists user_identities (
user_id uuid not null references users(id) on delete cascade,
provider text not null, -- 'rout'
subject text not null, -- sub-claim
primary key (provider, subject)
);Universal Handle Sync en webhooks
Zet Universal Handle Sync aan in de console om ROUT de bron van gebruikersnamen te maken. Met de scope profile krijg je dan de claim rout_handle (in het id_token en via userinfo). Gebruik die als unieke username, maar koppel gebruikers altijd op sub: een handle kan veranderen.
Handlewijzigingen gebruiken een ondertekende POST user.handle.updated naar je webhook. Controleer de header x-rout-signature: t=…,v1=… (HMAC-SHA256 over t.body, maximaal 5 minuten oud) en sla verwerkte event-id's op. Test levering voor jouw app voordat je synchronisatie als actief toont.
{
"id": "evt_01J9Z8K3QH4M2N",
"type": "user.handle.updated",
"created_at": "2026-10-10T10:40:00Z",
"client_id": "rout_your_client_id",
"data": {
"sub": "8f0c2a4e-…",
"previous_handle": "oldname",
"rout_handle": "newname"
}
}import { createHmac, timingSafeEqual } from "node:crypto";
export function verifyRoutSignature(rawBody: string, header: string, secret: string) {
const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
const t = Number(parts.t);
if (!t || Math.abs(Date.now() / 1000 - t) > 300) return false; // replay window 5 min
const expected = createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex");
const got = Buffer.from(parts.v1 ?? "", "hex");
return got.length === 32 && timingSafeEqual(got, Buffer.from(expected, "hex"));
}Hoe verificaties werken
Een badge betekent dat ROUT zelf iets heeft gecontroleerd — nooit enkel wat iemand intypte.
Google / YouTube
OAuth bij Google. ROUT krijgt een door Google bevestigd e-mailadres en, voor YouTube, het kanaal dat aan dat account hangt.
GitHub
OAuth bij GitHub. Bewijst dat de gebruiker die GitHub-account beheert; e-mail telt alleen als GitHub ze als geverifieerd markeert.
GitLab
OAuth/OIDC bij gitlab.com of een eigen GitLab-server. Zelfde regel: alleen bevestigde e-mail telt.
Bluesky / AT Protocol
OAuth bij de eigen PDS van de gebruiker. ROUT bewaart de DID (vaste identiteit), niet enkel de handle. Een eigen domein kan via /.well-known/atproto-did.
Mastodon / fediverse
OAuth bij de gekozen server. Omdat die meestal geen e-mail meegeeft, bevestigt de gebruiker zijn e-mail met een eenmalige code van 6 cijfers.
Persoon, bedrijf, influencer
Handmatig nagekeken door ROUT. Namen komen uit een goedgekeurde lijst; de gebruiker kiest er precies één.
API-overzicht
| GET | /.well-known/openid-configuration | Discovery-document (CORS open) |
| GET | /.well-known/jwks.json | Publieke ES256-sleutels voor id_token (CORS open) |
| GET | /oauth/authorize | Toestemmingsscherm; start de code-flow |
| POST | /api/public/oauth/token | Code inwisselen (PKCE S256 verplicht) |
| GET | /api/public/oauth/userinfo | Claims met Bearer access_token |
QR- en link-API-sleutels beheer je in de console.
Foutcodes en limieten
| invalid_request | 400 | Verplichte velden ontbreken of zijn ongeldig. |
| invalid_client | 401 | Onbekende app, fout geheim of IP niet toegelaten. |
| invalid_grant | 400 | Code verlopen, al gebruikt, fout redirect_uri of PKCE klopt niet. |
| unsupported_grant_type | 400 | Alleen authorization_code wordt ondersteund. |
| access_denied | — | De gebruiker weigerde toestemming (komt terug als ?error=). |
| rate_limited | 429 | Te veel pogingen. Wacht het aantal seconden uit Retry-After. |
- Token-uitwisseling: 30 per minuut per IP.
- Aanmelden en wachtwoordherstel: 10 per minuut per IP.
- Nieuwe apps: 5 per uur per account.
- Sms-codes: 5 per uur per account, 3 per nummer.