Projet

Général

Profil

Demande #4373 » index.html

Version FR du fichier index - Frédéric Couchet, 28/03/2020 17:37

 
1
<!DOCTYPE html>
2
<html>
3
  <head>
4
    <meta charset="utf-8">
5
    <!-- Favicon as generated by realfavicongenerator.net (slightly modified for webpack) -->
6
    <link rel="apple-touch-icon" sizes="180x180" href="ee7a19054eb87597c4b8e4664823ebfd.png">
7
    <link rel="icon" type="image/png" href="195ad531e2d729dbb80bb4524be18d78.png" sizes="32x32">
8
    <link rel="icon" type="image/png" href="cf02aba975e911ef9823610d908b32f5.png" sizes="16x16">
9
    <link rel="manifest" href="e72996a6d1ed5d1d7962c27c10c08fa6.json">
10
    <link rel="mask-icon" href="18e00168e2eeff800227594e26818681.svg" color="#5bbad5">
11
    <link rel="shortcut icon" href="7e20ba1e3b8980a164c5f557a0470919.ico">
12
    <meta name="apple-mobile-web-app-title" content="Mumble">
13
    <meta name="application-name" content="Mumble">
14
    <meta name="msapplication-config" content="8b61e99b17ef88afd479b3fc990e5b9d.xml">
15
    <meta name="theme-color" content="#ffffff">
16

    
17
    <script src="config.js"></script>
18
    <script src="config.local.js"></script>
19
    <script src="theme.js"></script>
20
    <script src="matrix.js"></script>
21
  </head>
22
  <body>
23
    <div class="loading-container" data-bind="css: { loaded: true }">
24
      <div class="loading-circle" data-bind="css: { loaded: true }"></div>
25
    </div>
26
    <div id="container" style="display: none" data-bind="visible: true,
27
                                                         css: { minimal: minimalView }">
28
      <!-- ko with: connectDialog --> 
29
      <div class="connect-dialog dialog" data-bind="visible: visible() && !joinOnly()">
30
          <div class="dialog-header">
31
            Connexion au serveur
32
          </div>
33
          <form data-bind="submit: connect">
34
            <table>
35
                <tr data-bind="if: $root.config.connectDialog.address">
36
                  <td>Addresse</td>
37
                  <td><input id="address" type="text" data-bind="value: address" required></td>
38
                </tr>
39
                <tr data-bind="if: $root.config.connectDialog.port">
40
                  <td>Port</td>
41
                  <td><input id="port" type="text" data-bind="value: port" required></td>
42
                </tr>
43
                <tr data-bind="if: $root.config.connectDialog.token">
44
                  <td>Jeton</td>
45
                  <td><input id="token" type="text" data-bind="value: token"></td>
46
                </tr>
47
                <tr data-bind="if: $root.config.connectDialog.username">
48
                  <td>Pseudo ou nom</td>
49
                  <td><input id="username" type="text" data-bind="value: username" required></td>
50
                </tr>
51
                <tr data-bind="if: $root.config.connectDialog.password">
52
                  <td>Mot de passe</td>
53
                  <td><input id="password" type="password" data-bind="value: password"></td>
54
                </tr>
55
                <tr data-bind="if: $root.config.connectDialog.channelName">
56
                  <td>Salon</td>
57
                  <td><input  id="channelName" type="text" data-bind="value: channelName"></td>
58
                </tr>
59
            </table>
60
            <div class="dialog-footer">
61
              <input class="dialog-close" type="button" data-bind="click: hide" value="Cancel">
62
              <input class="dialog-submit" type="submit" value="Connect">
63
            </div>
64
          </form>
65
        </div>
66
      <!-- /ko -->
67
      <!-- ko with: connectDialog -->
68
      <div class="join-dialog dialog" data-bind="visible: visible() && joinOnly()">
69
          <div class="dialog-header">
70
            Mumble Voice Conference
71
          </div>
72
          <form data-bind="submit: connect">
73
            <input class="dialog-submit" type="submit" value="Join Conference">
74
          </form>
75
        </div>
76
      <!-- /ko -->
77
      <!-- ko with: connectErrorDialog -->
78

    
79

    
80
      <div class="connect-dialog error-dialog dialog" data-bind="visible: visible()">
81
          <div class="dialog-header">
82
            Failed to connect
83
          </div>
84
          <form data-bind="submit: connect">
85
            <table>
86
                <tr>
87
                  <td colspan=2>
88
                    <!-- ko if: type() == 0 || type() == 8 -->
89
                    The connection has been refused.
90
                    <!-- /ko -->
91
                    <!-- ko if: type() == 1 -->
92
                    The server uses an incompatible version.
93
                    <!-- /ko -->
94
                    <!-- ko if: type() == 2 -->
95
                    Your user name was rejected. Maybe try a different one?
96
                    <!-- /ko -->
97
                    <!-- ko if: type() == 3 -->
98
                    The given password is incorrect.
99
                    The user name you have chosen requires a special one.
100
                    <!-- /ko -->
101
                    <!-- ko if: type() == 4 -->
102
                    The given password is incorrect.
103
                    <!-- /ko -->
104
                    <!-- ko if: type() == 5 -->
105
                    The user name you have chosen is already in use.
106
                    <!-- /ko -->
107
                    <!-- ko if: type() == 6 -->
108
                    The server is full.
109
                    <!-- /ko -->
110
                    <!-- ko if: type() == 7 -->
111
                    The server requires you to provide a client certificate
112
                    which is not supported by this web application.
113
                    <!-- /ko -->
114
                    <br>
115
                    The server reports:
116
                    <br>
117
                    "<span class="connect-error-reason" data-bind="text: reason"></span>"
118
                  </td>
119
                </tr>
120
                <tr data-bind="if: type() == 2 || type() == 3 || type() == 5">
121
                  <td>Username</td>
122
                  <td><input id="username" type="text" data-bind="value: username" required></td>
123
                </tr>
124
                <tr data-bind="if: type() == 3 || type() == 4">
125
                  <td>Password</td>
126
                  <td><input id="password" type="password" data-bind="value: password" required></td>
127
                </tr>
128
            </table>
129
            <div class="dialog-footer">
130
              <input class="dialog-close" type="button" value="Cancel"
131
                     data-bind="click: hide, visible: !joinOnly()">
132
              <input class="dialog-submit" type="submit" value="Retry">
133
            </div>
134
          </form>
135
        </div>
136
      <!-- /ko -->
137
      <!-- ko with: connectionInfo -->
138
      <div class="connection-info-dialog dialog" data-bind="visible: visible">
139
        <div class="dialog-header">
140
          Information de connexion
141
        </div>
142
        <div class="dialog-content">
143
          <h3>Version</h3>
144
          <!-- ko with: serverVersion -->
145
          Protocol
146
          <span data-bind="text: major + '.' + minor + '.' + patch"></span>.
147
          <br>
148
          <br>
149
          <span data-bind="text: release"></span>
150
          <br>
151
          <span data-bind="text: os"></span>
152
          <span data-bind="text: osVersion"></span>
153
          <br>
154
          <!-- /ko -->
155
          <!-- ko if: !serverVersion() -->
156
          Unknown
157
          <!-- /ko -->
158

    
159
          <h3>Control channel</h3>
160
          <span data-bind="text: latencyMs().toFixed(2)"></span> ms average latency
161
          (<span data-bind="text: latencyDeviation().toFixed(2)"></span> deviation)
162
          <br>
163
          <br>
164
          Remote host <span data-bind="text: remoteHost"></span>
165
          (port <span data-bind="text: remotePort"></span>)
166
          <br>
167

    
168
          <h3>Audio bandwidth</h3>
169
          Maximum <span data-bind="text: (maxBitrate()/1000).toFixed(1)"></span> kbits/s
170
          (<span data-bind="text: (maxBandwidth()/1000).toFixed(1)"></span> kbits/s with overhead)
171
          <br>
172
          Current <span data-bind="text: (currentBitrate()/1000).toFixed(1)"></span> kbits/s
173
          (<span data-bind="text: (currentBandwidth()/1000).toFixed(1)"></span> kbits/s with overhead)
174
          <br>
175
          Codec: <span data-bind="text: codec"></span>
176
        </div>
177
        <div class="dialog-footer">
178
          <input class="dialog-close" type="button" data-bind="click: hide" value="OK">
179
        </div>
180
      </div>
181
      <!-- /ko -->
182
      <!-- ko with: settingsDialog -->
183
      <div class="settings-dialog dialog" data-bind="visible: $data">
184
          <div class="dialog-header">
185
            Paramètres
186
          </div>
187
          <form data-bind="submit: $root.applySettings">
188
            <table>
189
                <tr>
190
                  <td>Transmission</td>
191
                  <td>
192
                    <select data-bind='value: voiceMode'>
193
                      <option value="cont">Continue</option>
194
                      <option value="vad">Activité vocale</option>
195
                      <option value="ptt">Appuyer pour parler</option>
196
                  </td>
197
                </tr>
198
                <tr data-bind="visible: voiceMode() == 'vad'">
199
                  <td colspan="2">
200
                    <div class="mic-volume-container">
201
                      <div class="mic-volume" data-bind="style: {
202
                          width: testVadLevel()*100 + '%',
203
                          background: testVadActive() ? 'green' : 'red'
204
                        }"></div>
205
                    </div>
206
                    <input type="range" min="0" max="1" step="0.01"
207
                           data-bind="value: vadLevel">
208
                  </td>
209
                </tr>
210
                <tr data-bind="visible: voiceMode() == 'ptt'">
211
                  <td>Combinaison de touches à utiliser</td>
212
                  <td>
213
                    <input type="button" data-bind="value: pttKeyDisplay, click: recordPttKey">
214
                  </td>
215
                </tr>
216
                <tr>
217
                  <td>Qualité audio</td>
218
                  <td><span data-bind="text: (audioBitrate()/1000).toFixed(1)"></span> kbit/s</td>
219
                </tr>
220
                <tr>
221
                  <td colspan="2">
222
                    <input type="range" min="8000" max="96000" step="8"
223
                           data-bind="value: audioBitrate, valueUpdate: 'input'">
224
                  </td>
225
                </tr>
226
                <tr>
227
                  <td>Audio par paquet</td>
228
                  <td><span data-bind="text: msPerPacket"></span> ms</td>
229
                </tr>
230
                <tr>
231
                  <td colspan="2">
232
                    <input type="range" min="10" max="60" step="10"
233
                           data-bind="value: msPerPacket, valueUpdate: 'input'">
234
                  </td>
235
                </tr>
236
                <tr>
237
                  <td colspan="2" class="bandwidth-info">
238
                    <span data-bind="text: (totalBandwidth()/1000).toFixed(1)"></span>
239
                    kbit/s
240
                    (Audio
241
                    <span data-bind="text: (audioBitrate()/1000).toFixed(1)"></span>,
242
                    Position
243
                    <span data-bind="text: (positionBandwidth()/1000).toFixed(1)"></span>,
244
                    Surcharge
245
                    <span data-bind="text: (overheadBandwidth()/1000).toFixed(1)"></span>)
246
                  </td>
247
                </tr>
248
                <tr>
249
                  <td>Afficher les avatars</td>
250
                  <td>
251
                    <select data-bind='value: showAvatars'>
252
                      <option value="always">Toujours</option>
253
                      <option value="own_channel">Même canal</option>
254
                      <option value="linked_channel">Canaux liés</option>
255
                      <option value="minimal_only">Vue minimale</option>
256
                      <option value="never">Jamais</option>
257
                  </td>
258
                </tr>
259
                <tr>
260
                    <td colspan="2">
261
                        <input type="checkbox" data-bind="checked: userCountInChannelName">
262
                        Afficher le nombre d’utilisateurs et et utilisatrices après le nom du salon
263
                    </td>
264
                </tr>
265
            </table>
266
            <div class="dialog-footer">
267
              <input class="dialog-close" type="button" data-bind="click: $root.closeSettings" value="Cancel">
268
              <input class="dialog-submit" type="submit" value="Apply">
269
            </div>
270
          </form>
271
        </div>
272
      <!-- /ko -->
273
      <img class="avatar-view" data-bind="visible: avatarView, attr: { src: avatarView },
274
                                          click: function () { avatarView(null) }"></img>
275
      <!-- ko with: userContextMenu -->
276
      <ul class="context-menu" data-bind="if: target,
277
                                          style: { left: posX() + 'px',
278
                                                   top:  posY() + 'px' }">
279

    
280
        <!-- ko with: target -->
281
        <li data-bind="css: { disabled: !canChangeMute() }">
282
          Couper le son
283
        </li>
284
        <li data-bind="css: { disabled: !canChangeDeafen() }">
285
          Mettre en sourdine
286
        </li>
287
        <li data-bind="css: { disabled: !canChangePrioritySpeaker() }">
288
          Priorité de la personne qui parle
289
        </li>
290

    
291
        <li data-bind="css: { disabled: !canLocalMute() }">
292
          Couper le son localement
293
        </li>
294
        <li data-bind="css: { disabled: !canIgnoreMessages() }">
295
          Ignorer les messages
296
        </li>
297

    
298
        <li data-bind="css: { disabled: !canChangeComment() }, visible: comment">
299
          Voir les commentaires
300
        </li>
301
        <!-- ko if: $data === $root.thisUser() -->
302
        <li data-bind="css: { disabled: !canChangeComment() }, visible: true">
303
          Modifier le commentaire
304
        </li>
305
        <!-- /ko -->
306
        <!-- ko if: $data !== $root.thisUser() -->
307
        <li data-bind="css: { disabled: !canChangeComment() }, visible: comment">
308
          Effacer le commentaire
309
        </li>
310
        <!-- /ko -->
311

    
312
        <li data-bind="css: { disabled: !canChangeAvatar() }, visible: texture,
313
                       click: viewAvatar">
314
          Voir l’avatar
315
        </li>
316
        <!-- ko if: $data === $root.thisUser() -->
317
        <li data-bind="css: { disabled: !canChangeAvatar() }, visible: true,
318
                       click: changeAvatar">
319
          Modifier l'avatar
320
        </li>
321
        <!-- /ko -->
322
        <li data-bind="css: { disabled: !canChangeAvatar() }, visible: texture,
323
                       click: removeAvatar">
324
          Effacer l'avatar
325
        </li>
326

    
327
        <li data-bind="css: { disabled: true }, visible: true">
328
          Envoyer message
329
        </li>
330
        <li data-bind="css: { disabled: true }, visible: true">
331
          Information
332
        </li>
333

    
334
        <li data-bind="visible: $data === $root.thisUser(),
335
                       css: { checked: selfMute },
336
                       click: toggleMute">
337
          Me couper le son
338
        </li>
339
        <li data-bind="visible: $data === $root.thisUser(),
340
                       css: { checked: selfDeaf },
341
                       click: toggleDeaf">
342
          Me mettre en sourdine
343
        </li>
344

    
345
        <!-- ko if: $data !== $root.thisUser() -->
346
        <li data-bind="css: { disabled: true }, visible: true">
347
          Ajouter comme ami
348
        </li>
349
        <li data-bind="css: { disabled: true }, visible: false">
350
          Retirer comme ami
351
        </li>
352
        <!-- /ko -->
353

    
354
        <!-- /ko -->
355
      </ul>
356
      <!-- /ko -->
357
      <!-- ko with: channelContextMenu -->
358
      <ul class="context-menu" data-bind="if: target,
359
                                          style: { left: posX() + 'px',
360
                                                   top:  posY() + 'px' }">
361

    
362
        <!-- ko with: target -->
363
        <li data-bind="visible: users.indexOf($root.thisUser()) === -1,
364
                       css: { disabled: !canJoin() },
365
                       click: $root.requestMove.bind($root, $root.thisUser())">
366
          Rejoindre le salon
367
        </li>
368
        <li data-bind="css: { disabled: !canAdd() }">
369
          Ajouter
370
        </li>
371
        <li data-bind="css: { disabled: !canEdit() }">
372
          Modifier
373
        </li>
374
        <li data-bind="css: { disabled: !canRemove() }">
375
          Retirer
376
        </li>
377

    
378
        <li data-bind="css: { disabled: !canLink() }">
379
          Lien
380
        </li>
381
        <li data-bind="css: { disabled: !canUnlink() }">
382
          Rompre le lien
383
        </li>
384
        <li data-bind="css: { disabled: !canUnlink() }">
385
          Rompre tous les liens
386
        </li>
387

    
388
        <li data-bind="css: { disabled: true }">
389
          Copy Mumble URL
390
        </li>
391
        <li data-bind="css: { disabled: true }">
392
          Copy Mumble-Web URL
393
        </li>
394
        <li data-bind="css: { disabled: !canSendMessage() }">
395
          Send Message
396
        </li>
397
        <li data-bind="css: { disabled: true }">
398
          Copier l’URL Mumble
399
        </li>
400
        <li data-bind="css: { disabled: true }">
401
          Copier l’URL Mumble-Web
402
        </li>
403
        <li data-bind="css: { disabled: !canSendMessage() }">
404
          Envoyer un message
405
        </li>
406

    
407
        <!-- /ko -->
408
      </ul>
409
      <!-- /ko -->
410
      <script type="text/html" id="user-tag">
411
        <span class="user-tag" data-bind="text: name"></span>
412
      </script>
413
      <script type="text/html" id="channel-tag">
414
        <span class="channel-tag" data-bind="text: name"></span>
415
      </script>
416
      <div class="toolbar" data-bind="css: { 'toolbar-horizontal': toolbarHorizontal(),
417
                                             'toolbar-vertical': !toolbarHorizontal() }">
418
        <img class="handle-horizontal" src="f2fc230fc7d9a9b8f6f03d342f6e94b2.svg"
419
             data-bind="click: toggleToolbarOrientation">
420
        <img class="handle-vertical" src="9ae3dac014f51d714254cf522602cec0.svg"
421
             data-bind="click: toggleToolbarOrientation">
422
        <img class="tb-connect" data-bind="visible: !connectDialog.joinOnly(),
423
                                           click: connectDialog.show"
424
                      rel="connect" src="22ecf0ecde1ae2a6281265174b7fa355.svg">
425
        <img class="tb-information" rel="information" src="82747b4bbd0cfe92292f74cd27f2763e.svg"
426
             data-bind="click: connectionInfo.show,
427
                        css: { disabled: !thisUser() }">
428
        <div class="divider"></div>
429
        <img class="tb-mute" data-bind="visible: !selfMute(),
430
                              click: function () { requestMute(thisUser()) }"
431
                      rel="mute" src="8f75583a16890ab851fc3f121fc63f89.svg">
432
        <img class="tb-unmute tb-active" data-bind="visible: selfMute,
433
                              click: function () { requestUnmute(thisUser()) }"
434
                      rel="unmute" src="f54b0be1d559b03ad8d945e988ec8ed4.svg">
435
        <img class="tb-deaf" data-bind="visible: !selfDeaf(),
436
                              click: function () { requestDeaf(thisUser()) }"
437
                      rel="deaf" src="0ce7650c4d5a52a5323868f75588e1c7.svg">
438
        <img class="tb-undeaf tb-active" data-bind="visible: selfDeaf,
439
                              click: function () { requestUndeaf(thisUser()) }"
440
                      rel="undeaf" src="d5ba30b381ebc262ba3871eaed9d7102.svg">
441
        <img class="tb-record" data-bind="click: function(){}"
442
                      rel="record" src="7b86c879d50808c66816ed3338f26557.svg">
443
        <div class="divider"></div>
444
        <img class="tb-comment" data-bind="click: commentDialog.show"
445
                      rel="comment" src="077f1c5bd335be073c48c340b01f58bc.svg">
446
        <div class="divider"></div>
447
        <img class="tb-settings" data-bind="click: openSettings"
448
                      rel="settings" src="50dddae19e7bf601b168f46a1303674b.svg">
449
        <div class="divider"></div>
450
        <img class="tb-sourcecode" data-bind="click: openSourceCode"
451
                      rel="Source Code" src="71edeaefdc2f5a19dc84298669af6962.svg">
452
      </div>
453
      <div class="chat">
454
        <script type="text/html" id="log-generic">
455
          <span data-bind="text: value"></span>
456
        </script>
457
        <script type="text/html" id="log-welcome-message">
458
          Message de bienvenue : <span data-bind="html: message"></span> <hr /> <br />Par défaut, pour pouvoir parler il faut appuyer et maintenir appuyées les touches Ctrl et Majuscule (shift) (c&apos;est le mode Appuyer pour parler). Pour changer ce mode de transmission, pour passer par exemple en mode transmission continue, vous pouvez aller dans les paramètres (en cliquant sur la roue crantée).<br /><br />Pour rejoindre un salon il faut double-cliquer sur le nom du salon, ou faire clic-droit sur le nom du salon et choisir &quot;Rejoindre le salon&quot;. Pour quitter un salon il faut double-cliquer sur April tout en haut. <br /><br />Vous pouvez consulter <a href='https://wiki.april.org/w/Mumble#Acc.C3.A8s_avec_un_navigateur_web'>une documentation</a>.
459
        </script>
460
	</p>
461
        <script type="text/html" id="log-chat-message">
462
          <span data-bind="visible: channel">
463
            (Channel)
464
          </span>
465
          <span data-bind="template: { name: 'user-tag', data: user }"></span>:
466
          <span class="message-content" data-bind="html: message"></span>
467
        </script>
468
        <script type="text/html" id="log-chat-message-self">
469
          To
470
          <span data-bind="template: { if: $data.channel, name: 'channel-tag', data: $data.channel }">
471
          </span><span data-bind="template: { if: $data.user, name: 'user-tag', data: $data.user }">
472
          </span>:
473
          <span class="message-content" data-bind="html: message"></span>
474
        </script>
475
        <script type="text/html" id="log-disconnect">
476
        </script>
477
        <div class="log" data-bind="foreach: {
478
          data: log,
479
          afterRender: function (e) {
480
            [].forEach.call(e[1].getElementsByTagName('a'), function(e){e.target = '_blank'})
481
          }
482
        }">
483
          <div class="log-entry">
484
            <span class="log-timestamp" data-bind="text: $root.getTimeString()"></span>
485
            <!-- ko template: { data: $data, name: function(l) { return 'log-' + l.type; } } -->
486
            <!-- /ko -->
487
          </div>
488
        </div>
489
        <form data-bind="submit: submitMessageBox">
490
          <input id="message-box" type="text" data-bind="
491
              attr: { placeholder: messageBoxHint }, textInput: messageBox">
492
        </form>
493
      </div>
494
      <script type="text/html" id="channel">
495
        <div class="channel" data-bind="
496
            click: $root.select, 
497
            event: {
498
              contextmenu: openContextMenu,
499
              dblclick: $root.requestMove.bind($root, $root.thisUser())
500
            },
501
            css: {
502
              selected: $root.selected() === $data,
503
              currentChannel: users.indexOf($root.thisUser()) !== -1
504
            }">
505
          <div class="channel-status">
506
            <img class="channel-description" data-bind="visible: description"
507
                alt="description" src="077f1c5bd335be073c48c340b01f58bc.svg">
508
          </div>
509
          <div data-bind="if: description">
510
            <div class="channel-description tooltip" data-bind="html: description"></div>
511
          </div>
512
          <img class="channel-icon" src="b78ed441778f2e4ce1201a75af76594e.svg"
513
            data-bind="visible: !linked() && $root.thisUser().channel() !== $data">
514
          <img class="channel-icon-active" src="b78ed441778f2e4ce1201a75af76594e.svg"
515
            data-bind="visible: $root.thisUser().channel() === $data">
516
          <img class="channel-icon-linked" src="86d4f1d7547270ff26f08a9271e7edcb.svg"
517
            data-bind="visible: linked() && $root.thisUser().channel() !== $data">
518
          <div class="channel-name">
519
            <span data-bind="text: name"></span>
520
            <!-- ko if: $root.settings.userCountInChannelName() && userCount() !== 0 -->
521
            &nbsp;(<span data-bind="text: userCount()"></span>)
522
            <!-- /ko -->
523
          </div>
524
        </div>
525
        <!-- ko if: expanded -->
526
        <!-- ko foreach: users -->
527
        <div class="user-wrapper">
528
          <div class="user-tree"></div>
529
          <div class="user" data-bind="
530
                click: $root.select,
531
                event: {
532
                  contextmenu: openContextMenu
533
                },
534
                css: {
535
                  thisClient: $root.thisUser() === $data,
536
                  selected: $root.selected() === $data
537
                }">
538
            <div class="user-status" data-bind="attr: { title: state }">
539
              <img class="user-comment" data-bind="visible: comment"
540
                  alt="comment" src="077f1c5bd335be073c48c340b01f58bc.svg">
541
              <img class="user-server-mute" data-bind="visible: mute"
542
                  alt="server mute" src="296b612d2847da52749549f73d0c3664.svg">
543
              <img class="user-suppress-mute" data-bind="visible: suppress"
544
                  alt="suppressed" src="00fd86fe12871b707998bf7214820fdd.svg">
545
              <img class="user-self-mute" data-bind="visible: selfMute" 
546
                  alt="self mute" src="9171288d67adc4805412883901d2f180.svg">
547
              <img class="user-server-deaf" data-bind="visible: deaf"
548
                  alt="server deaf" src="e0c171776518ab302b54ccc71e59a582.svg">
549
              <img class="user-self-deaf" data-bind="visible: selfDeaf"
550
                  alt="self deaf" src="d5ba30b381ebc262ba3871eaed9d7102.svg">
551
              <img class="user-authenticated" data-bind="visible: uid"
552
                  alt="authenticated" src="6d73bb785aa06bf0c436ad6f7cc6262a.svg">
553
            </div>
554
            <div data-bind="if: comment">
555
              <div class="user-comment tooltip" data-bind="html: comment"></div>
556
            </div>
557
            <!-- ko if: show_avatar() -->
558
            <img class="user-avatar" alt="avatar"
559
                 data-bind="attr: { src: texture },
560
                            css: { 'user-avatar-talk-off': talking() == 'off',
561
                                   'user-avatar-talk-on': talking() == 'on',
562
                                   'user-avatar-talk-whisper': talking() == 'whisper',
563
                                   'user-avatar-talk-shout': talking() == 'shout' }">
564
            <!-- /ko -->
565
            <!-- ko ifnot: show_avatar() -->
566
            <img class="user-talk user-talk-off" data-bind="visible: talking() == 'off'"
567
                alt="talk off" src="a65db861eecb8dcc62ad70fec489da3f.svg">
568
            <img class="user-talk user-talk-on" data-bind="visible: talking() == 'on'"
569
                alt="talk on" src="32785c1d21b0050be9168487542b8c3d.svg">
570
            <img class="user-talk user-talk-whisper" data-bind="visible: talking() == 'whisper'"
571
                alt="whisper" src="dbd9efebc73f884c5039cc3192a65dd8.svg">
572
            <img class="user-talk user-talk-shout" data-bind="visible: talking() == 'shout'"
573
                alt="shout" src="ec4d8b884ac39ef8494fb4aca6c6069f.svg">
574
            <!-- /ko -->
575
            <div class="user-name" data-bind="text: name"></div>
576
          </div>
577
        </div>
578
        <!-- /ko -->
579
        <!-- ko foreach: channels -->
580
        <div class="channel-wrapper">
581
          <!-- ko ifnot: users().length || channels().length -->
582
          <div class="channel-tree"></div>
583
          <!-- /ko -->
584
          <div class="branch" data-bind="if: users().length || channels().length">
585
            <img class="branch-open" src="d57d3d2918d0b72f0c24e9dc162c6c4a.svg"
586
                data-bind="click: expanded.bind($data, false), visible: expanded()">
587
            <img class="branch-closed" src="972a0ac8cf8526580a216210a364cc60.svg"
588
                data-bind="click: expanded.bind($data, true), visible: !expanded()">
589
          </div>
590
          <div class="channel-sub" data-bind="template: {name: 'channel', data: $data}"></div>
591
        </div>
592
        <!-- /ko -->
593
        <!-- /ko -->
594
      </script>
595
      <div class="channel-root-container" data-bind="if: root, visible: !minimalView()">
596
        <div class="channel-root" data-bind="template: {name: 'channel', data: root}"></div>
597
      </div>
598
      <div class="channel-root-container" data-bind="if: thisUser, visible: minimalView()">
599
        <div class="channel-root" data-bind="template: {name: 'channel', data: thisUser().channel}"></div>
600
      </div>
601
    </div>
602
  </body>
603
  <script src="index.js"></script>
604
</html>
(2-2/2)