NinjaFirewall (WP Edition) - Version 4.4

Version Description

  • The "Full WAF" mode can be configured to exclude some directories. That can be done from the "NinjaFirewall > Dashboard" page by clicking on the new "Configure" button. There's no need to use the ".htninja" script to exclude folders anymore. That can be useful to exclude third-party applications that rely on PHP sessions and could behave erratically with the "Full WAF" mode (e.g., Piwik/Matomo, phpMyAdmin, forums etc).
  • You can easily downgrade from "Full WAF" mode to "WordPress WAF" mode by clicking the "Configure" button in the "NinjaFirewall > Dashboard" page.
  • Added a warning about the "X-XSS-Protection" HTTP header in the "Firewall Policies" section: although NinjaFirewall still supports it, it is now deprecated and only used by Safari. Consider using "Content-Security-Policy" (CSP) instead.
  • When reactivating NinjaFirewall from the "Plugins" page, it will verify that the path to the firewall file is correct or, if necessary, will adjust it (e.g., after a server migration etc).
  • NinjaFirewall will display a warning in its "Dashboard" page if the .user.ini or php.ini file is readable.
  • The configuation backup files are now base64-encoded to prevent being wrongly flagged by some hosting companies antivirus.
  • NinjaFirewall will hightlight in red colour in the "Plugins" page any plugin that has a pending security update. See https://nin.link/nfsecupdates/ for more details.
  • The cache used to store information about pending security updates will be automatically flushed.
  • On old multisite installations, the firewall will no longer block access to the "/wp-includes/ms-files.php" script.
  • The firewall can now detect user roles even before WordPress is loaded.
  • Updated Charts.js to v3.4.1.
  • WP+ Edition (Premium): Updated GeoIP databases.
  • Many additional small fixes and adjustments.
Download this release

Release Info

Developer nintechnet
Plugin Icon 128x128 NinjaFirewall (WP Edition)
Version 4.4
Comparing to
See all releases

Code changes from version 4.3.4 to 4.4

languages/ninjafirewall-fr_FR.mo CHANGED
Binary file
languages/ninjafirewall-fr_FR.po CHANGED
@@ -4,8 +4,8 @@ msgid ""
4
  msgstr ""
5
  "Project-Id-Version: Stable (latest release)\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/ninjafirewall\n"
7
- "POT-Creation-Date: 2021-05-28 18:29+0700\n"
8
- "PO-Revision-Date: 2021-05-28 18:30+0700\n"
9
  "Last-Translator: NinTechNet <contact@nintechnet.com>\n"
10
  "Language-Team: NinTechNet <nintechnet.com>\n"
11
  "Language: fr_FR\n"
@@ -16,7 +16,7 @@ msgstr ""
16
  "X-Poedit-SourceCharset: UTF-8\n"
17
  "Plural-Forms: nplurals=2; plural=(n > 1);\n"
18
 
19
- #: lib/anti_malware.php:24 ninjafirewall.php:835
20
  msgid "Anti-Malware"
21
  msgstr "Anti-Malware"
22
 
@@ -29,13 +29,12 @@ msgstr ""
29
  "la place, nous avons maintenant un tout nouveau plugin antivirus :"
30
 
31
  #: lib/anti_malware.php:29
32
- #, php-format
33
- msgid ""
34
- "It is awesome and includes many great features: <a href=\"%s\">check it out!"
35
- "</a>"
36
- msgstr ""
37
- "Il est beaucoup mieux et comprend de nombreuses fonctionnalités : <a href="
38
- "\"%s\">En savoir plus</a>"
39
 
40
  #: lib/anti_malware.php:30
41
  msgid "Download it from wordpress.org!"
@@ -105,23 +104,32 @@ msgstr "Oops! Le mode Full WAF n'est pas encore activé."
105
  msgid "NinjaFirewall (WP Edition)"
106
  msgstr "NinjaFirewall (WP Edition)"
107
 
108
- #: lib/dashboard.php:128 ninjafirewall.php:813
 
 
 
 
 
 
 
 
 
109
  msgid "Dashboard"
110
  msgstr "Tableau de Bord"
111
 
112
- #: lib/dashboard.php:129
113
  msgid "Statistics"
114
  msgstr "Statistiques"
115
 
116
- #: lib/dashboard.php:130 lib/help.php:53
117
  msgid "About..."
118
  msgstr "À Propos..."
119
 
120
- #: lib/dashboard.php:142
121
  msgid "Thank you for using NinjaFirewall."
122
  msgstr "Merci d'utiliser NinjaFirewall."
123
 
124
- #: lib/dashboard.php:143
125
  #, php-format
126
  msgid ""
127
  "Every page of NinjaFirewall has a contextual help: whenever you need help "
@@ -132,19 +140,19 @@ msgstr ""
132
  "besoin d'aide au sujet d'une option ou d'un menu, cliquez sur l'onglet %s "
133
  "situé en haut à droite de la page correspondante."
134
 
135
- #: lib/dashboard.php:143
136
  msgid "Help"
137
  msgstr "Aide"
138
 
139
- #: lib/dashboard.php:145
140
  msgid "Got it!"
141
  msgstr "J'ai compris !"
142
 
143
- #: lib/dashboard.php:161 lib/help.php:36
144
  msgid "Firewall Dashboard"
145
  msgstr "Tableau de Bord du Pare-feu"
146
 
147
- #: lib/dashboard.php:170
148
  msgid ""
149
  "It seems that you may have another instance of NinjaFirewall running in a "
150
  "parent directory. Make sure to follow these instructions:"
@@ -152,7 +160,7 @@ msgstr ""
152
  "Il semble qu'une autre instance de NinjaFirewall est installée dans un "
153
  "répertoire parent. Assurez-vous de suivre ces instructions:"
154
 
155
- #: lib/dashboard.php:172
156
  msgid ""
157
  "Temporarily disable the firewall in the parent folder by renaming its PHP "
158
  "INI or .htaccess file."
@@ -160,11 +168,11 @@ msgstr ""
160
  "Désactivez temporairement le pare-feu dans le répertoire parent en renommant "
161
  "son fichier PHP INI ou .htaccess."
162
 
163
- #: lib/dashboard.php:174
164
  msgid "Install NinjaFirewall on this site in Full WAF mode."
165
  msgstr "Installez NinjaFirewall sur ce site, en mode Full WAF."
166
 
167
- #: lib/dashboard.php:176
168
  msgid ""
169
  "Restore the PHP INI or .htaccess in the parent folder to re-enable the "
170
  "firewall."
@@ -172,25 +180,25 @@ msgstr ""
172
  "Restaurez le fichier PHP INI ou .htaccess dans le dossier parent pour "
173
  "réactiver le pare-feu."
174
 
175
- #: lib/dashboard.php:182
176
  msgid "Unknown error"
177
  msgstr "Erreur inconnue"
178
 
179
- #: lib/dashboard.php:186 lib/dashboard.php:194
180
  msgid "Firewall"
181
  msgstr "Pare-feu"
182
 
183
- #: lib/dashboard.php:195 lib/dashboard.php:330 lib/firewall_options.php:64
184
  #: lib/login_protection.php:203 lib/logs_live_log.php:99
185
  #: lib/monitoring_file_guard.php:70 lib/security_rules_update.php:138
186
  msgid "Enabled"
187
  msgstr "Activé"
188
 
189
- #: lib/dashboard.php:202
190
  msgid "Mode"
191
  msgstr "Mode"
192
 
193
- #: lib/dashboard.php:206
194
  #, php-format
195
  msgid ""
196
  "NinjaFirewall is running in %s mode. For better protection, activate its "
@@ -199,40 +207,36 @@ msgstr ""
199
  "NinjaFirewall fonctionne en mode %s. Pour une meilleure protection, activez "
200
  "son mode Full WAF :"
201
 
202
- #: lib/dashboard.php:206
203
- msgid "WordPress WAF"
204
- msgstr "WordPress WAF"
205
-
206
- #: lib/dashboard.php:208 lib/thickbox.php:71
207
  msgid "Activate Full WAF mode"
208
  msgstr "Activer le mode Full WAF"
209
 
210
- #: lib/dashboard.php:212
211
  #, php-format
212
  msgid "NinjaFirewall is running in %s mode."
213
  msgstr "NinjaFirewall fonctionne en mode %s."
214
 
215
- #: lib/dashboard.php:212
216
- msgid "Full WAF"
217
- msgstr "Full WAF"
218
 
219
- #: lib/dashboard.php:225 lib/firewall_options.php:76 lib/help.php:77
220
  msgid "Debugging mode"
221
  msgstr "Mode débogage"
222
 
223
- #: lib/dashboard.php:226
224
  msgid "Enabled."
225
  msgstr "Activé."
226
 
227
- #: lib/dashboard.php:226
228
  msgid "Click here to turn Debugging Mode off"
229
  msgstr "Cliquez ici pour désactiver le mode Débogage"
230
 
231
- #: lib/dashboard.php:232
232
  msgid "Edition"
233
  msgstr "Édition"
234
 
235
- #: lib/dashboard.php:233
236
  msgid ""
237
  "Need more security? Explore our supercharged premium version: NinjaFirewall "
238
  "(WP+ Edition)"
@@ -240,27 +244,27 @@ msgstr ""
240
  "Besoin de plus de sécurité ? Prenez le temps d'explorer notre version "
241
  "premium musclée : NinjaFirewall (WP+ Edition)"
242
 
243
- #: lib/dashboard.php:236
244
  msgid "Version"
245
  msgstr "Version"
246
 
247
- #: lib/dashboard.php:237
248
  msgid "Security rules:"
249
  msgstr "Règles de sécurité&nbsp;:"
250
 
251
- #: lib/dashboard.php:241
252
  msgid "PHP SAPI"
253
  msgstr "PHP SAPI"
254
 
255
- #: lib/dashboard.php:259
256
  msgid "Updates"
257
  msgstr "Mises à Jour"
258
 
259
- #: lib/dashboard.php:260
260
  msgid "Security rules updates are disabled."
261
  msgstr "La mise à jour automatique des règles de sécurité est désactivée."
262
 
263
- #: lib/dashboard.php:260
264
  msgid ""
265
  "If you want your blog to be protected against the latest threats, enable "
266
  "automatic security rules updates."
@@ -268,11 +272,11 @@ msgstr ""
268
  "Pour garder votre WordPress protégé contre les dernières vulnérabilités, "
269
  "pensez à l'activer."
270
 
271
- #: lib/dashboard.php:268 lib/dashboard.php:276
272
  msgid "Admin user"
273
  msgstr "Administrateur"
274
 
275
- #: lib/dashboard.php:269
276
  #, php-format
277
  msgid ""
278
  "You are not whitelisted. Ensure that the \"Do not block WordPress "
@@ -285,23 +289,23 @@ msgstr ""
285
  "\"%s\">Politiques du Pare-feu</a>, sinon vous pourriez être bloqué par le "
286
  "pare-feu lorsque vous travaillez depuis votre Tableau de bord."
287
 
288
- #: lib/dashboard.php:277
289
  msgid "You are whitelisted by the firewall."
290
  msgstr "Vous êtes dans la liste blanche du pare-feu."
291
 
292
- #: lib/dashboard.php:284
293
  msgid "Restrictions"
294
  msgstr "Restrictions"
295
 
296
- #: lib/dashboard.php:285
297
  msgid "Access to NinjaFirewall is restricted to specific users."
298
  msgstr "L'accès à NinjaFirewall est restreint à certains utilisateurs."
299
 
300
- #: lib/dashboard.php:296
301
  msgid "User session"
302
  msgstr "Session utilisateur"
303
 
304
- #: lib/dashboard.php:297
305
  msgid ""
306
  "It seems that the user session set by NinjaFirewall was not found by the "
307
  "firewall script."
@@ -309,7 +313,7 @@ msgstr ""
309
  "Il semble que la session d'utilisateur définie par NinjaFirewall n'a pas été "
310
  "trouvé par le script du pare-feu."
311
 
312
- #: lib/dashboard.php:305
313
  #, php-format
314
  msgid ""
315
  "the public key is invalid. Please <a href=\"%s\">check your configuration</"
@@ -318,18 +322,18 @@ msgstr ""
318
  "la clé publique est invalide. Veuillez vérifier <a href=\"%s\">votre "
319
  "configuration</a>."
320
 
321
- #: lib/dashboard.php:309
322
  msgid "No IP address restriction."
323
  msgstr "Aucune restriction d'accès par adresse IP."
324
 
325
- #: lib/dashboard.php:312
326
  #, php-format
327
  msgid "IP address %s is allowed to access NinjaFirewall's log on this server."
328
  msgstr ""
329
  "L'adresse IP %s est autorisée à accéder au journal du pare-feu de "
330
  "NinjaFirewall."
331
 
332
- #: lib/dashboard.php:315
333
  #, php-format
334
  msgid ""
335
  "the whitelisted IP is not valid. Please <a href=\"%s\">check your "
@@ -338,26 +342,26 @@ msgstr ""
338
  "l'adresse IP est invalide. Veuillez vérifier <a href=\"%s\">votre "
339
  "configuration</a>."
340
 
341
- #: lib/dashboard.php:320 lib/help.php:467 lib/logs_firewall_log.php:193
342
  #: lib/wpplus.php:170
343
  msgid "Centralized Logging"
344
  msgstr "Centralisation des Logs"
345
 
346
- #: lib/dashboard.php:324 lib/security_rules_update.php:434
347
  #, php-format
348
  msgid "Error: %s"
349
  msgstr "Erreur : %s"
350
 
351
- #: lib/dashboard.php:339
352
  msgid "Source IP"
353
  msgstr "IP source"
354
 
355
- #: lib/dashboard.php:340
356
  #, php-format
357
  msgid "You have a private IP : %s"
358
  msgstr "Vous avez l'adresse IP d'un réseau privé : %s"
359
 
360
- #: lib/dashboard.php:340
361
  #, php-format
362
  msgid ""
363
  "If your site is behind a reverse proxy or a load balancer, ensure that you "
@@ -369,11 +373,11 @@ msgstr ""
369
  "la bonne adresse IP, sinon utilisez le fichier de configuration %s de "
370
  "NinjaFirewall."
371
 
372
- #: lib/dashboard.php:348 lib/dashboard.php:358
373
  msgid "CDN detection"
374
  msgstr "Détection CDN"
375
 
376
- #: lib/dashboard.php:349
377
  #, php-format
378
  msgid ""
379
  "%s detected: you seem to be using Cloudflare CDN services. Ensure that you "
@@ -384,7 +388,7 @@ msgstr ""
384
  "vous d'avoir configuré votre serveur HTTP afin qu'il fasse suivre la bonne "
385
  "adresse IP, sinon utilisez le fichier de configuration %s de NinjaFirewall."
386
 
387
- #: lib/dashboard.php:359
388
  #, php-format
389
  msgid ""
390
  "%s detected: you seem to be using Incapsula CDN services. Ensure that you "
@@ -395,40 +399,55 @@ msgstr ""
395
  "vous d'avoir configuré votre serveur HTTP afin qu'il fasse suivre la bonne "
396
  "adresse IP, sinon utilisez le fichier de configuration %s de NinjaFirewall."
397
 
398
- #: lib/dashboard.php:368 lib/dashboard.php:377
399
  msgid "Log dir"
400
  msgstr "Répertoire du Journal"
401
 
402
- #: lib/dashboard.php:369 lib/dashboard.php:378
403
  #, php-format
404
  msgid "%s directory is not writable! Please chmod it to 0777 or equivalent."
405
  msgstr ""
406
  "Le répertoire %s est en lecture seule ! Veuillez changer ses permissions "
407
  "(0777 ou équivalent)."
408
 
409
- #: lib/dashboard.php:391
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
410
  msgid "Error log"
411
  msgstr "Journal des erreurs"
412
 
413
- #: lib/dashboard.php:392
414
  msgid "View error log"
415
  msgstr "Voir le journal des erreurs"
416
 
417
- #: lib/dashboard.php:401
418
  msgid "Optional configuration file"
419
  msgstr "Fichier de configuration"
420
 
421
- #: lib/dashboard.php:408
422
  msgid "MySQLi link identifier"
423
  msgstr "Identifiant de lien MySQLi"
424
 
425
- #: lib/dashboard.php:409
426
  msgid "A MySQLi link identifier was detected in your <code>.htninja</code>."
427
  msgstr ""
428
  "Un identifiant de lien MySQLi a été détecté dans votre fichier <code>."
429
  "htninja</code>."
430
 
431
- #: lib/dashboard.php:415
432
  msgid "Help &amp; configuration"
433
  msgstr "Aide &amp; configuration"
434
 
@@ -468,7 +487,7 @@ msgstr "Statistiques Mensuelles"
468
  msgid "Select a month"
469
  msgstr "Sélectionnez le mois"
470
 
471
- #: lib/dashboard_statistics.php:98 lib/dashboard_statistics.php:131
472
  #: lib/widget.php:66
473
  msgid "Blocked threats"
474
  msgstr "Menaces bloquées"
@@ -498,40 +517,32 @@ msgstr "Requête la plus rapide"
498
  msgid "Slowest request"
499
  msgstr "Requête la plus lente"
500
 
501
- #: lib/dashboard_statistics.php:126
502
  msgid "Critical"
503
  msgstr "Critique"
504
 
505
- #: lib/dashboard_statistics.php:127
506
  msgid "High"
507
  msgstr "Élevé"
508
 
509
- #: lib/dashboard_statistics.php:128
510
  msgid "Medium"
511
  msgstr "Moyen"
512
 
513
- #: lib/dashboard_statistics.php:184
514
  msgid "Select monthly stats to view..."
515
  msgstr "Sélectionnez les statistiques à afficher..."
516
 
517
- #: lib/event_notifications.php:34 lib/help.php:377 ninjafirewall.php:843
518
  msgid "Event Notifications"
519
  msgstr "Notifications d'Événement"
520
 
521
- #: lib/event_notifications.php:42 lib/firewall_options.php:42
522
- #: lib/firewall_policies.php:71 lib/login_protection.php:30
523
- #: lib/logs_firewall_log.php:59 lib/logs_live_log.php:79
524
- #: lib/monitoring_file_check.php:111 lib/monitoring_file_guard.php:46
525
- #: lib/network.php:52 lib/security_rules_update.php:101
526
- msgid "Your changes have been saved."
527
- msgstr "Les modifications ont été enregistrées."
528
-
529
  #: lib/event_notifications.php:52
530
  msgid "WordPress admin dashboard"
531
  msgstr "Connexion"
532
 
533
  #: lib/event_notifications.php:55 lib/event_notifications.php:119
534
- #: lib/event_notifications.php:139
535
  msgid "Send me an alert whenever"
536
  msgstr "Envoyer une alerte quand"
537
 
@@ -624,11 +635,11 @@ msgstr ""
624
  "Une importante mise à jour de sécurité est disponible pour une extension, un "
625
  "thème ou WordPress (défaut)"
626
 
627
- #: lib/event_notifications.php:136
628
  msgid "Administrator account"
629
  msgstr "Compte administrateur"
630
 
631
- #: lib/event_notifications.php:141
632
  msgid ""
633
  "An administrator account is created, modified or deleted in the database "
634
  "(default)"
@@ -636,15 +647,15 @@ msgstr ""
636
  "Un compte Administrateur est crée, modifié ou supprimé dans la base de "
637
  "données (défaut)"
638
 
639
- #: lib/event_notifications.php:148
640
  msgid "Daily report"
641
  msgstr "Rapport quotidien"
642
 
643
- #: lib/event_notifications.php:151
644
  msgid "Send me a daily activity report"
645
  msgstr "Envoyer un rapport d'activité quotidien"
646
 
647
- #: lib/event_notifications.php:153 lib/event_notifications.php:165
648
  #: lib/firewall_options.php:78 lib/firewall_options.php:113
649
  #: lib/firewall_policies.php:25 lib/login_protection.php:309
650
  #: lib/login_protection.php:324 lib/login_protection.php:345
@@ -652,7 +663,7 @@ msgstr "Envoyer un rapport d'activité quotidien"
652
  msgid "Yes"
653
  msgstr "Oui"
654
 
655
- #: lib/event_notifications.php:153 lib/event_notifications.php:165
656
  #: lib/firewall_options.php:78 lib/firewall_options.php:113
657
  #: lib/firewall_policies.php:26 lib/login_protection.php:309
658
  #: lib/login_protection.php:324 lib/login_protection.php:345
@@ -660,55 +671,49 @@ msgstr "Oui"
660
  msgid "No"
661
  msgstr "Non"
662
 
663
- #: lib/event_notifications.php:160
664
  msgid "Log"
665
  msgstr "Journal"
666
 
667
- #: lib/event_notifications.php:163
668
  msgid "Write all events to the firewall log"
669
  msgstr "Enregistrer les événements dans le journal du pare-feu"
670
 
671
- #: lib/event_notifications.php:177
672
  msgid "PHP backtrace"
673
  msgstr "Pile d'exécution de PHP"
674
 
675
- #: lib/event_notifications.php:180
676
  msgid "Attach a PHP backtrace to important notifications"
677
  msgstr ""
678
  "Ajouter aux notifications importantes la pile d'exécution de PHP en pièce "
679
  "jointe"
680
 
681
- #: lib/event_notifications.php:183
682
  msgid "Disable backtrace"
683
  msgstr "Désactiver la pile d'exécution"
684
 
685
- #: lib/event_notifications.php:184
686
  msgid "Low verbosity"
687
  msgstr "Faible verbosité"
688
 
689
- #: lib/event_notifications.php:185
690
  msgid "Medium verbosity (default)"
691
  msgstr "Verbosité moyenne (par défaut)"
692
 
693
- #: lib/event_notifications.php:186
694
  msgid "High verbosity"
695
  msgstr "Verbosité élevée"
696
 
697
- #: lib/event_notifications.php:188
698
- #, php-format
699
- msgid "<a href=\"%s\">Consult our blog</a> for more info."
700
- msgstr ""
701
- "<a href=\"%s\">Consultez notre blog pour plus d'informations à ce sujet</a>."
702
-
703
- #: lib/event_notifications.php:198 lib/event_notifications.php:228
704
  msgid "Contact email"
705
  msgstr "Adresse e-mail du contact"
706
 
707
- #: lib/event_notifications.php:201 lib/event_notifications.php:231
708
  msgid "Alerts should be sent to"
709
  msgstr "Envoyer les alertes à"
710
 
711
- #: lib/event_notifications.php:210 lib/event_notifications.php:236
712
  msgid ""
713
  "Multiple recipients must be comma-separated (e.g., <code>joe@example.org,"
714
  "alice@example.org</code>)."
@@ -716,60 +721,60 @@ msgstr ""
716
  "Plusieurs destinataires doivent être séparés par des virgules (par ex. "
717
  "<code>joe@example.org,alice@example.org</code>)."
718
 
719
- #: lib/event_notifications.php:233
720
  msgid "Only to me, the Super Admin"
721
  msgstr "Moi uniquement, le Super Admin"
722
 
723
- #: lib/event_notifications.php:233
724
  msgid "default"
725
  msgstr "défaut"
726
 
727
- #: lib/event_notifications.php:234
728
  msgid "To the administrator of the site where originated the alert"
729
  msgstr "L'Administrateur du site d’où provient l'alerte"
730
 
731
- #: lib/event_notifications.php:235
732
  msgid "Other(s):"
733
  msgstr "Autre(s) :"
734
 
735
- #: lib/event_notifications.php:247
736
  msgid "Save Event Notifications"
737
  msgstr "Sauvegarder les options"
738
 
739
- #: lib/event_notifications.php:489
740
  msgid "[NinjaFirewall] Daily Activity Report"
741
  msgstr "[NinjaFirewall] Rapport d'activité quotidien"
742
 
743
- #: lib/event_notifications.php:499
744
  #, php-format
745
  msgid "Daily activity report for: %s"
746
  msgstr "Rapport d'activité quotidien pour : %s"
747
 
748
- #: lib/event_notifications.php:500
749
  msgid "Date Range Processed: Yesterday"
750
  msgstr "Plage de date traitée : Hier"
751
 
752
- #: lib/event_notifications.php:502
753
  msgid "Blocked threats:"
754
  msgstr "Menaces bloquées :"
755
 
756
- #: lib/event_notifications.php:504
757
  msgid "critical:"
758
  msgstr "Critique :"
759
 
760
- #: lib/event_notifications.php:505
761
  msgid "high:"
762
  msgstr "Élevé :"
763
 
764
- #: lib/event_notifications.php:506
765
  msgid "medium:"
766
  msgstr "Moyen :"
767
 
768
- #: lib/event_notifications.php:508
769
  msgid "Blocked brute-force attacks:"
770
  msgstr "Attaques par force brute bloquées :"
771
 
772
- #: lib/event_notifications.php:509 lib/event_updates.php:225 lib/utils.php:1094
773
  msgid ""
774
  "This notification can be turned off from NinjaFirewall \"Event Notifications"
775
  "\" page."
@@ -790,7 +795,7 @@ msgstr ""
790
  "pour votre site Web :"
791
 
792
  #: lib/event_updates.php:163 lib/utils.php:233 lib/utils.php:318
793
- #: lib/utils.php:440 lib/utils.php:1083 lib/utils.php:1272 lib/utils.php:1544
794
  msgid "Date:"
795
  msgstr "Date :"
796
 
@@ -836,7 +841,7 @@ msgstr "Extension : %s"
836
  msgid "Theme: %s"
837
  msgstr "Theme : %s"
838
 
839
- #: lib/event_updates.php:223
840
  msgid "Don't leave your blog at risk, make sure to update as soon as possible."
841
  msgstr ""
842
  "Ne laissez pas votre blog en danger, lancez cette mise à jour dès que "
@@ -888,7 +893,7 @@ msgstr "téléchargé(e)"
888
  msgid "[NinjaFirewall] Alert: %s"
889
  msgstr "[NinjaFirewall] Alerte : %s"
890
 
891
- #: lib/events.php:203 lib/events.php:205 lib/utils.php:832
892
  msgid "-Blog:"
893
  msgstr "- Blog :"
894
 
@@ -896,19 +901,19 @@ msgstr "- Blog :"
896
  msgid "NinjaFirewall has detected the following activity on your account:"
897
  msgstr "NinjaFirewall a détecté l'activité suivante sur votre compte :"
898
 
899
- #: lib/events.php:210 lib/utils.php:837
900
  msgid "-User:"
901
  msgstr "- Nom :"
902
 
903
- #: lib/events.php:211 lib/utils.php:838
904
  msgid "-IP:"
905
  msgstr "- IP :"
906
 
907
- #: lib/events.php:212 lib/utils.php:839
908
  msgid "-Date:"
909
  msgstr "-Date :"
910
 
911
- #: lib/firewall_options.php:29 ninjafirewall.php:817
912
  msgid "Firewall Options"
913
  msgstr "Options du Pare-feu"
914
 
@@ -1063,22 +1068,27 @@ msgid "Uploaded file is either corrupted or its format is not supported (#%s)"
1063
  msgstr ""
1064
  "Le fichier importé est illisible ou son format n'est pas supporté (#%s)"
1065
 
1066
- #: lib/firewall_options.php:554 ninjafirewall.php:230
 
 
 
 
 
1067
  msgid "[NinjaFirewall] Alert: Firewall is disabled"
1068
  msgstr "[NinjaFirewall] Alerte : Le pare-feu a été désactivé"
1069
 
1070
- #: lib/firewall_options.php:556 lib/firewall_options.php:558
1071
- #: ninjafirewall.php:232 ninjafirewall.php:234
1072
  msgid "-Blog :"
1073
  msgstr "- Blog :"
1074
 
1075
- #: lib/firewall_options.php:562 ninjafirewall.php:236
1076
  msgid "Someone disabled NinjaFirewall from your WordPress admin dashboard:"
1077
  msgstr ""
1078
  "Quelqu'un a désactivé NinjaFirewall depuis votre Tableau de bord de "
1079
  "WordPress :"
1080
 
1081
- #: lib/firewall_options.php:565
1082
  msgid ""
1083
  "NinjaFirewall is disabled because someone enabled debugging mode from your "
1084
  "WordPress admin dashboard:"
@@ -1086,26 +1096,26 @@ msgstr ""
1086
  "NinjaFirewall est désactivé car quelqu'un activé son \"Mode débogage\" "
1087
  "depuis votre tableau de bord de WordPress :"
1088
 
1089
- #: lib/firewall_options.php:568
1090
  msgid "[NinjaFirewall] Alert: Firewall override settings"
1091
  msgstr "[NinjaFirewall] Alerte : Modification des paramètres du pare-feu"
1092
 
1093
- #: lib/firewall_options.php:569
1094
  msgid ""
1095
  "Someone imported a new configuration which overrode the firewall settings:"
1096
  msgstr ""
1097
  "Quelqu'un a importé une nouvelle configuration qui a modifié tous les "
1098
  "paramètres du pare-feu :"
1099
 
1100
- #: lib/firewall_options.php:575 ninjafirewall.php:237
1101
  msgid "-User :"
1102
  msgstr "- Nom :"
1103
 
1104
- #: lib/firewall_options.php:576 ninjafirewall.php:238
1105
  msgid "-IP :"
1106
  msgstr "- IP :"
1107
 
1108
- #: lib/firewall_options.php:577 ninjafirewall.php:239
1109
  msgid "-Date :"
1110
  msgstr "- Date :"
1111
 
@@ -1118,7 +1128,7 @@ msgstr ""
1118
  "Pour utiliser cette option, allez dans le <a href=\"%s\">Tableau de Bord</a> "
1119
  "et activez le mode Full WAF de NinjaFirewall."
1120
 
1121
- #: lib/firewall_policies.php:62 ninjafirewall.php:821
1122
  msgid "Firewall Policies"
1123
  msgstr "Politiques du Pare-feu"
1124
 
@@ -1259,7 +1269,7 @@ msgstr ""
1259
  "Bloquer les tentatives de publication, modification ou suppression d'un "
1260
  "article publié par des utilisateurs qui n'ont pas les bonnes capacités"
1261
 
1262
- #: lib/firewall_policies.php:411 lib/thickbox.php:86
1263
  msgid "(recommended)"
1264
  msgstr "(recommandé)"
1265
 
@@ -1540,17 +1550,25 @@ msgstr ""
1540
  "Activer cette fonction avec <code>DENY</code> pourrait bloquer certaines "
1541
  "fonctionnalités de votre blog, ses thèmes ou ses extensions."
1542
 
1543
- #: lib/firewall_policies.php:846
1544
  #, php-format
1545
- msgid "Set %s (IE/Edge, Chrome, Opera and Safari browsers)"
1546
- msgstr "Activer %s (IE/Edge, Opera, Chrome et Safari)"
1547
 
1548
- #: lib/firewall_policies.php:850 lib/firewall_policies.php:851
1549
- #: lib/firewall_policies.php:852
1550
  #, php-format
1551
  msgid "Set to %s"
1552
  msgstr "Régler sur %s"
1553
 
 
 
 
 
 
 
 
 
1554
  #: lib/firewall_policies.php:857
1555
  #, php-format
1556
  msgid "Force %s flag on all cookies to mitigate CSRF attacks"
@@ -2425,11 +2443,8 @@ msgstr ""
2425
  "l'administrateur et la page de connexion uniquement."
2426
 
2427
  #: lib/help.php:275
2428
- msgid ""
2429
- "Set <code>X-XSS-Protection</code> (IE/Edge, Chrome, Opera and Safari "
2430
- "browsers)"
2431
- msgstr ""
2432
- "Activer <code>X-XSS-Protection</code> (IE/Edge, Opera, Chrome et Safari)"
2433
 
2434
  #: lib/help.php:275
2435
  msgid ""
@@ -2441,14 +2456,6 @@ msgstr ""
2441
  "attaques XSS en empêchant un script malveillant de s'exécuter. Notez que "
2442
  "cette option est activée par défaut sur ces navigateurs."
2443
 
2444
- #: lib/help.php:276
2445
- msgid ""
2446
- "If a visitor disabled their browser's XSS filter, you cannot re-enable it "
2447
- "with that option."
2448
- msgstr ""
2449
- "Si un visiteur désactive le filtre XSS de son navigateur, vous ne pouvez pas "
2450
- "le réactiver avec cette option."
2451
-
2452
  #: lib/help.php:278
2453
  msgid ""
2454
  "Force <code>SameSite</code> flag on all cookies to mitigate CSRF attacks"
@@ -2849,7 +2856,7 @@ msgstr ""
2849
  "intercepter les requêtes HTTP envoyées à tout script PHP, même si ce dernier "
2850
  "ne fait pas partie de WordPress (logiciel tiers, backdoor, etc)."
2851
 
2852
- #: lib/help.php:360 lib/network.php:32 ninjafirewall.php:839
2853
  msgid "Network"
2854
  msgstr "Réseau"
2855
 
@@ -2902,7 +2909,7 @@ msgstr ""
2902
  "après avoir pénétré dans votre Tableau de bord de WordPress, d'y installer "
2903
  "une porte dérobée (backdoor) afin de prendre le contrôle de votre blog."
2904
 
2905
- #: lib/help.php:389 lib/login_protection.php:21 ninjafirewall.php:847
2906
  msgid "Login Protection"
2907
  msgstr "Page de Connexion"
2908
 
@@ -3687,20 +3694,18 @@ msgstr "Erreur en essayant de télécharger le fichier de langue %s (%s)"
3687
  #: lib/i18n-extra.php:51
3688
  #, php-format
3689
  msgid ""
3690
- "You are running NinjaFirewall in <i>WordPress WAF</i> mode. All URL-based "
3691
- "features such as <i>Geolocation</i> and <i>URL Access Control</i> will be "
3692
- "limited to WordPress files only (e.g., index.php, wp-login.php, xmlrpc.php, "
3693
- "admin-ajax.php, wp-load.php etc). If you want them to apply to any PHP "
3694
- "script, please <a href=\"%s\">go to the Dashboard page</a> and enable "
3695
- "NinjaFirewall's Full WAF mode."
3696
  msgstr ""
3697
- "NinjaFirewall fonctionne en mode <i>WordPress WAF</i>. Toutes les "
3698
- "fonctionnalités basées sur les URL comme la <i>Géolocalisation</i> et le "
3699
- "<i>Contrôle d'accès par URL</i> seront limitées à certains fichiers "
3700
- "WordPress uniquement (par ex. index.php, wp-login.php, xmlrpc.php, admin-"
3701
- "ajax.php, wp-load.php etc). Si vous voulez que cette option s'applique à "
3702
- "tous les fichiers PHP, allez dans le <a href=\"%s\">Tableau de Bord</a> et "
3703
- "activez son mode Full WAF."
3704
 
3705
  #: lib/i18n-extra.php:52
3706
  msgid "General"
@@ -3758,146 +3763,122 @@ msgstr ""
3758
  "suivantes"
3759
 
3760
  #: lib/i18n-extra.php:65
3761
- msgid "<code>GET</code>"
3762
- msgstr "<code>GET</code>"
3763
-
3764
- #: lib/i18n-extra.php:66
3765
- msgid "<code>POST</code>"
3766
- msgstr "<code>POST</code>"
3767
-
3768
- #: lib/i18n-extra.php:67
3769
- msgid "<code>HEAD</code>"
3770
- msgstr "<code>HEAD</code>"
3771
-
3772
- #: lib/i18n-extra.php:68
3773
- msgid "<code>PUT</code>"
3774
- msgstr "<code>PUT</code>"
3775
-
3776
- #: lib/i18n-extra.php:69
3777
- msgid "<code>DELETE</code>"
3778
- msgstr "<code>DELETE</code>"
3779
-
3780
- #: lib/i18n-extra.php:70
3781
- msgid "<code>PATCH</code>"
3782
- msgstr "<code>PATCH</code>"
3783
-
3784
- #: lib/i18n-extra.php:71
3785
  msgid "Enable Geolocation"
3786
  msgstr "Activer la Géolocalisation"
3787
 
3788
- #: lib/i18n-extra.php:72
3789
  msgid "Retrieve the ISO 3166 code from"
3790
  msgstr "Récupérer le code ISO 3166 du pays depuis"
3791
 
3792
- #: lib/i18n-extra.php:73
3793
  msgid "PHP Variable"
3794
  msgstr "Variable PHP"
3795
 
3796
- #: lib/i18n-extra.php:74
3797
  msgid "Block the following ISO 3166 codes"
3798
  msgstr "Bloquer les codes ISO 3166 suivants"
3799
 
3800
- #: lib/i18n-extra.php:75
3801
  #, php-format
3802
  msgid "Total blocked items: %s"
3803
  msgstr "Nombre d'éléments bloqués : %s"
3804
 
3805
- #: lib/i18n-extra.php:76
3806
  msgid "Geolocation should apply to the whole site or to specific URLs only?"
3807
  msgstr ""
3808
  "S'il faut appliquer la Géolocalisation à tout le site ou à certains scripts "
3809
  "uniquement ?"
3810
 
3811
- #: lib/i18n-extra.php:77
3812
  msgid "View allowed syntax"
3813
  msgstr "Afficher la syntaxe autorisée"
3814
 
3815
- #: lib/i18n-extra.php:78
3816
  #, php-format
3817
  msgid "Full or partial case-sensitive URL (e.g., %s)."
3818
  msgstr "URL complète ou partielle, sensible à la casse (ex: %s)."
3819
 
3820
- #: lib/i18n-extra.php:79
3821
  msgid "One item per line."
3822
  msgstr "Une entrée par ligne."
3823
 
3824
- #: lib/i18n-extra.php:80
3825
  msgid ""
3826
  "Leave this field empty if you want geolocation to apply to all your PHP "
3827
  "scripts."
3828
  msgstr ""
3829
  "Laissez ce champ vide pour appliquer la géolocalisation à tout le site."
3830
 
3831
- #: lib/i18n-extra.php:81
3832
- msgid "Add <code>NINJA_COUNTRY_CODE</code> to PHP headers?"
3833
- msgstr "Ajouter <code>NINJA_COUNTRY_CODE</code> aux en-têtes PHP?"
3834
 
3835
- #: lib/i18n-extra.php:82
3836
  msgid "Write event to the firewall log"
3837
  msgstr "Enregistrer l'événement dans le journal du pare-feu"
3838
 
3839
- #: lib/i18n-extra.php:83
3840
  msgid "Allow the following IP, CIDR or AS number"
3841
  msgstr "Accepter les IP, CIDR ou numéros d'AS suivants"
3842
 
3843
- #: lib/i18n-extra.php:84
3844
  #, php-format
3845
  msgid "IPv4 address: %s"
3846
  msgstr "Adresse IPv4 : %s"
3847
 
3848
- #: lib/i18n-extra.php:85
3849
  #, php-format
3850
  msgid "IPv4 CIDR: %s"
3851
  msgstr "CIDR IPv4 : %s"
3852
 
3853
- #: lib/i18n-extra.php:86
3854
  #, php-format
3855
  msgid "IPv6 address: %s"
3856
  msgstr "Adresse IPv6 : %s"
3857
 
3858
- #: lib/i18n-extra.php:87
3859
  #, php-format
3860
  msgid "IPv6 CIDR: %s"
3861
  msgstr "CIDR IPv6 : %s"
3862
 
3863
- #: lib/i18n-extra.php:88
3864
  #, php-format
3865
  msgid "Autonomous System number: %s"
3866
  msgstr "Numéro AS (Autonomous System) : %s"
3867
 
3868
- #: lib/i18n-extra.php:89
3869
  msgid "Whitelist:"
3870
  msgstr "Liste Blanche:"
3871
 
3872
- #: lib/i18n-extra.php:90
3873
  msgid "Enter one item per line."
3874
  msgstr "Une entrée par ligne."
3875
 
3876
- #: lib/i18n-extra.php:91
3877
  msgid "External Services"
3878
  msgstr "Services externes"
3879
 
3880
- #: lib/i18n-extra.php:92
3881
  msgid "Whitelist IP addresses from the following services:"
3882
  msgstr "Ajouter les adresses IP des services suivants à la liste blanche :"
3883
 
3884
- #: lib/i18n-extra.php:93
3885
  msgid "View IP addresses"
3886
  msgstr "Voir les adresses IP"
3887
 
3888
- #: lib/i18n-extra.php:94
3889
  msgid "Block the following IP, CIDR or AS number"
3890
  msgstr "Bloquer les IP, CIDR ou numéros d'AS suivants"
3891
 
3892
- #: lib/i18n-extra.php:95
3893
  msgid "Blacklist:"
3894
  msgstr "Liste noire :"
3895
 
3896
- #: lib/i18n-extra.php:96
3897
  msgid "Rate Limiting"
3898
  msgstr "Limiter le trafic"
3899
 
3900
- #: lib/i18n-extra.php:97
3901
  #, php-format
3902
  msgid ""
3903
  "Block for %s seconds any IP address with more than %s connections within a "
@@ -3906,94 +3887,89 @@ msgstr ""
3906
  "Bloquer pendant %s secondes les IP ayant plus de %s connexions en moins de "
3907
  "%s."
3908
 
3909
- #: lib/i18n-extra.php:98
3910
  msgid "5-second"
3911
  msgstr "5 secondes"
3912
 
3913
- #: lib/i18n-extra.php:99
3914
  msgid "10-second"
3915
  msgstr "10 secondes"
3916
 
3917
- #: lib/i18n-extra.php:100
3918
  msgid "15-second"
3919
  msgstr "15 secondes"
3920
 
3921
- #: lib/i18n-extra.php:101
3922
  msgid "30-second"
3923
  msgstr "30 secondes"
3924
 
3925
- #: lib/i18n-extra.php:102
3926
  msgid "Allow access to the following URL"
3927
  msgstr "Autoriser l'accès à l'URL suivante"
3928
 
3929
- #: lib/i18n-extra.php:103
3930
  #, php-format
3931
  msgid "Full or partial case-sensitive URLs (e.g., %s)."
3932
  msgstr "URL complète ou partielle, sensible à la casse (ex: %s)."
3933
 
3934
- #: lib/i18n-extra.php:104
3935
  msgid "Block access to the following URL"
3936
  msgstr "Bloquer l'accès à l'URL suivante"
3937
 
3938
- #: lib/i18n-extra.php:105
3939
  msgid "Reject the following bots"
3940
  msgstr "Rejeter les bots suivants"
3941
 
3942
- #: lib/i18n-extra.php:106
3943
  msgid "A full or partial case-insensitive string."
3944
  msgstr "Chaîne de caractère complète ou partielle, insensible à la casse."
3945
 
3946
- #: lib/i18n-extra.php:107
3947
- msgid ""
3948
- "Allowed characters are: <code>a-zA-Z</code> <code>0-9</code> <code>.</code> "
3949
- "<code>-</code> <code>_</code> <code>:</code> <code>/</code> and <code>space</"
3950
- "code>."
3951
- msgstr ""
3952
- "Cataractes autorisés : <code>a-zA-Z</code> <code>0-9</code> <code>.</code> "
3953
- "<code>-</code> <code>_</code> <code>:</code> <code>/</code> et <code>space</"
3954
- "code>."
3955
 
3956
- #: lib/i18n-extra.php:108
3957
  msgid "Blocked bots:"
3958
  msgstr "Bots bloqués :"
3959
 
3960
- #: lib/i18n-extra.php:109
3961
  msgid "The default list of bots will be restored. Continue?"
3962
  msgstr "Restaurer les valeurs par défaut de la liste des bots ?"
3963
 
3964
- #: lib/i18n-extra.php:110
3965
  msgid "Restore default bots list"
3966
  msgstr "Restaurer les valeurs par défaut"
3967
 
3968
- #: lib/i18n-extra.php:111
3969
  msgid "Do not filter the following user input"
3970
  msgstr "Ne pas filtrer l'entrée utilisateur suivante"
3971
 
3972
- #: lib/i18n-extra.php:112
3973
  msgid ""
3974
- "A <code>GET</code>, <code>POST</code> or <code>COOKIE</code> global "
3975
- "variable, followed by <code>:</code> (colon) and the case-sensitive input:"
3976
  msgstr ""
3977
- "Une variable <code>GET</code>, <code>POST</code> ou <code>COOKIE</code>, "
3978
- "suivie de <code>:</code> (deux points) et de l'entrée, sensible à la casse :"
3979
 
3980
- #: lib/i18n-extra.php:113
3981
  msgid "Unfiltered input:"
3982
  msgstr "Entrées non filtrées :"
3983
 
3984
- #: lib/i18n-extra.php:114
3985
  msgid "Block the request if the following input is present"
3986
  msgstr "Bloquer la requête si elle contient l'entrée suivante"
3987
 
3988
- #: lib/i18n-extra.php:115
3989
  msgid "Blocked input:"
3990
  msgstr "Entrées bloquées :"
3991
 
3992
- #: lib/i18n-extra.php:116
3993
  msgid "Save Access Control directives"
3994
  msgstr "Sauvegarder les options"
3995
 
3996
- #: lib/i18n-extra.php:117
3997
  msgid ""
3998
  "Warning: Your previous secret key was either corrupted or missing. A new "
3999
  "one, as well as a new public key, were created."
@@ -4001,23 +3977,23 @@ msgstr ""
4001
  "Attention : votre clé privée était soit corrompue soit manquante. Un nouveau "
4002
  "jeu de clés vient d'être créé."
4003
 
4004
- #: lib/i18n-extra.php:118
4005
  msgid "Enable Centralized Logging"
4006
  msgstr "Activer la Centralisation des Logs"
4007
 
4008
- #: lib/i18n-extra.php:119
4009
  msgid "Secret key"
4010
  msgstr "Clé privée"
4011
 
4012
- #: lib/i18n-extra.php:120
4013
  msgid "From 30 to 100 ASCII printable characters."
4014
  msgstr "De 30 à 100 caractères ASCII."
4015
 
4016
- #: lib/i18n-extra.php:121
4017
  msgid "This server's IP address"
4018
  msgstr "L'adresse IP de ce serveur"
4019
 
4020
- #: lib/i18n-extra.php:122
4021
  msgid ""
4022
  "Only this IP address (IPv4 or IPv6) will be allowed to connect to the remote "
4023
  "websites. If you don't want to restrict the access by IP, enter the <code>*</"
@@ -4027,11 +4003,11 @@ msgstr ""
4027
  "distants. Si vous ne souhaitez pas de restriction d’accès par IP, veuillez "
4028
  "entrer le caractère <code>*</code>."
4029
 
4030
- #: lib/i18n-extra.php:123
4031
  msgid "Public key"
4032
  msgstr "Clé publique"
4033
 
4034
- #: lib/i18n-extra.php:124
4035
  #, php-format
4036
  msgid ""
4037
  "Add this key to the remote websites. <a href=\"%s\">Consult our blog</a> for "
@@ -4040,11 +4016,11 @@ msgstr ""
4040
  "Vous devez configurer vos sites distants avec cette nouvelle clé. <a href="
4041
  "\"%s\">Consultez notre blog</a> pour plus d'info."
4042
 
4043
- #: lib/i18n-extra.php:125
4044
  msgid "Remote websites URL"
4045
  msgstr "URL de vos sites distants"
4046
 
4047
- #: lib/i18n-extra.php:126
4048
  msgid ""
4049
  "Enter one URL per line, including the protocol (<code>http://</code> or "
4050
  "<code>https://</code>). Only ASCII URLs are accepted."
@@ -4052,11 +4028,11 @@ msgstr ""
4052
  "Entrez une URL par ligne, en incluant le protocole (<code>http://</code> ou "
4053
  "<code>https://</code>). Seules les URL au format ASCII sont acceptées."
4054
 
4055
- #: lib/i18n-extra.php:127
4056
  msgid "Save Options"
4057
  msgstr "Sauvegarder les options"
4058
 
4059
- #: lib/i18n-extra.php:128
4060
  msgid ""
4061
  "Your changes have been saved. If you are using a caching plugin, do not "
4062
  "forget to clear its cache."
@@ -4064,19 +4040,19 @@ msgstr ""
4064
  "Vos changements ont été enregistrés. Si vous utilisez une extension de mise "
4065
  "en cache, n'oubliez pas d'effacer son cache."
4066
 
4067
- #: lib/i18n-extra.php:129
4068
  msgid "Enable antispam protection"
4069
  msgstr "Activer la protection anti-spam"
4070
 
4071
- #: lib/i18n-extra.php:130
4072
  msgid "Protection level"
4073
  msgstr "Niveau de protection"
4074
 
4075
- #: lib/i18n-extra.php:131
4076
  msgid "Low (default)"
4077
  msgstr "Bas (défaut)"
4078
 
4079
- #: lib/i18n-extra.php:132
4080
  msgid ""
4081
  "If you are using a caching plugin, consult the contextual help before "
4082
  "enabling the antispam."
@@ -4084,31 +4060,31 @@ msgstr ""
4084
  "Si vous utilisez une extension de mise en cache, veuillez consulter l'aide "
4085
  "contextuelle avant d'activer l'anti-spam."
4086
 
4087
- #: lib/i18n-extra.php:133
4088
  msgid "Apply protection to"
4089
  msgstr "Appliquer la protection au"
4090
 
4091
- #: lib/i18n-extra.php:134
4092
  msgid "Comment forms (defaut)"
4093
  msgstr "Formulaire de commentaire (défaut)"
4094
 
4095
- #: lib/i18n-extra.php:135
4096
  msgid "User Registration form"
4097
  msgstr "Formulaire d'inscription"
4098
 
4099
- #: lib/i18n-extra.php:136
4100
  msgid "Save Antispam options"
4101
  msgstr "Sauvegarder les options"
4102
 
4103
- #: lib/i18n-extra.php:137
4104
  msgid "Please enable JavaScript"
4105
  msgstr "Veuillez activer JavaScript"
4106
 
4107
- #: lib/i18n-extra.php:138
4108
  msgid "Sorry, this looks like spam to me."
4109
  msgstr "Désolé, mais cela ressemble à du spam."
4110
 
4111
- #: lib/i18n-extra.php:139
4112
  msgid ""
4113
  "Error: You must be whitelisted in order to use that feature: click on the <a "
4114
  "href=\"?page=nfsubaccess\">Access Control</a> menu and ensure that the \"Do "
@@ -4119,7 +4095,7 @@ msgstr ""
4119
  "et assurez vous que l'option \"Ne pas bloquer les utilisateurs suivants\" "
4120
  "est activée pour l'Administrateur/Super Admin."
4121
 
4122
- #: lib/i18n-extra.php:140
4123
  msgid ""
4124
  "Your license is valid until the indicated expiration date. If you don't "
4125
  "renew it after this date, NinjaFirewall will keep working and protecting "
@@ -4130,7 +4106,7 @@ msgstr ""
4130
  "et à protéger votre site comme d'habitude, mais les mises à jour / mises à "
4131
  "niveau ne pourront plus être effectuées."
4132
 
4133
- #: lib/i18n-extra.php:141
4134
  #, php-format
4135
  msgid ""
4136
  "You can renew your license from <a href=\"%s\">NinTechNet.com</a> website."
@@ -4138,11 +4114,11 @@ msgstr ""
4138
  "Vous pouvez renouveler votre licence depuis le site <a href=\"%s"
4139
  "\">NinTechNet.com</a>."
4140
 
4141
- #: lib/i18n-extra.php:142
4142
  msgid "Use shared memory"
4143
  msgstr "Utiliser la mémoire partagée"
4144
 
4145
- #: lib/i18n-extra.php:143
4146
  msgid ""
4147
  "This feature allows NinjaFirewall to use Unix shared memory segments in "
4148
  "order to speed up all operations. The firewall will no longer need to "
@@ -4161,7 +4137,7 @@ msgstr ""
4161
  "réseau multi-site, la vitesse de traitement de pare-feu va augmenter de 25% "
4162
  "à 30%."
4163
 
4164
- #: lib/i18n-extra.php:144
4165
  msgid ""
4166
  "This option requires that your PHP version was compiled with the <code>--"
4167
  "enable-shmop</code> parameter, otherwise, if it is not compatible with your "
@@ -4170,7 +4146,7 @@ msgstr ""
4170
  "Cette fonction nécessite que PHP soit compilé avec le paramètre <code>--"
4171
  "enable-shmop</code>."
4172
 
4173
- #: lib/i18n-extra.php:145
4174
  #, php-format
4175
  msgid ""
4176
  "If you are using <a href=\"%s\">GB2312</a> character set (A.K.A <code>GBK</"
@@ -4185,11 +4161,11 @@ msgstr ""
4185
  "être en mesure de nettoyer correctement les caractères multi-octets, car il "
4186
  "n'aura pas accès à la base de données."
4187
 
4188
- #: lib/i18n-extra.php:146
4189
  msgid "Language"
4190
  msgstr "Langue"
4191
 
4192
- #: lib/i18n-extra.php:147
4193
  msgid ""
4194
  "When this option is enabled, NinjaFirewall will download, if available, the "
4195
  "corresponding language files from the WordPress repo. Then, every hour, it "
@@ -4200,7 +4176,7 @@ msgstr ""
4200
  "les heures, il vérifiera s'il existe une nouvelle version et la téléchargera "
4201
  "le cas échéant."
4202
 
4203
- #: lib/i18n-extra.php:148
4204
  msgid ""
4205
  "Note that this does not apply to <code>en_US</code> and <code>fr_FR</code> "
4206
  "locales because they are already included with NinjaFirewall."
@@ -4208,7 +4184,7 @@ msgstr ""
4208
  "Notez que cela ne s'applique pas aux locales <code>en_US</code> et "
4209
  "<code>fr_FR</code> car elles sont déjà incluses avec NinjaFirewall."
4210
 
4211
- #: lib/i18n-extra.php:149
4212
  #, php-format
4213
  msgid ""
4214
  "This options lets you export you current configuration or import it from "
@@ -4222,7 +4198,7 @@ msgstr ""
4222
  "(%s), sinon il sera rejeté. Notez que l'importation effacera toute votre "
4223
  "configuration (options et règles du pare-feu), sauf votre licence WP+."
4224
 
4225
- #: lib/i18n-extra.php:150
4226
  msgid ""
4227
  "You can allow/disallow uploads, or allow uploads but block scripts (PHP, "
4228
  "CGI, Ruby, Python, bash/shell, JavaScript), C/C++ source code, binaries (MZ/"
@@ -4236,11 +4212,11 @@ msgstr ""
4236
  "systèmes (.htaccess, .htpasswd et PHP INI) et les fichiers SVG contenant du "
4237
  "Javascript ou des Événements XML."
4238
 
4239
- #: lib/i18n-extra.php:151
4240
  msgid "Maximum allowed file size"
4241
  msgstr "Taille maximale autorisée"
4242
 
4243
- #: lib/i18n-extra.php:152
4244
  msgid ""
4245
  "If you allow uploads, you can select the maximum size of an uploaded file. "
4246
  "Any file bigger than this value will be rejected. Note that if your PHP "
@@ -4252,13 +4228,13 @@ msgstr ""
4252
  "configuration de PHP utilise la directive<code>upload_max_filesize</code>, "
4253
  "celle-ci sera prioritaire."
4254
 
4255
- #: lib/i18n-extra.php:153
4256
  msgid "Decode Base64-encoded <code>POST</code> variable:"
4257
  msgstr ""
4258
  "Décoder les chaîne encodées en Base64 dans la variable <code>POST</"
4259
  "code>&nbsp;:"
4260
 
4261
- #: lib/i18n-extra.php:154
4262
  #, php-format
4263
  msgid ""
4264
  "Object Serialization is a PHP feature used by many applications to generate "
@@ -4277,7 +4253,7 @@ msgstr ""
4277
  "<code>POST</code>, les cookies, ou dans les variables <code>HTTP_REFERER</"
4278
  "code> et <code>HTTP_USER_AGENT</code>."
4279
 
4280
- #: lib/i18n-extra.php:155
4281
  msgid ""
4282
  "This option will reject any <code>GET</code> or <code>POST</code> request, "
4283
  "<code>COOKIE</code>, <code>HTTP_USER_AGENT</code>, <code>REQUEST_URI</code>, "
@@ -4291,7 +4267,7 @@ msgstr ""
4291
  "contenant le caractère ASCI 0x00 (NULL byte) sera bloquée immédiatement. Ce "
4292
  "caractère est dangereux et devrait toujours être rejeté."
4293
 
4294
- #: lib/i18n-extra.php:156
4295
  msgid ""
4296
  "This option will block any <code>GET</code> or <code>POST</code> request "
4297
  "containing the localhost IP (127.0.0.1). It can be useful to block SQL "
@@ -4302,7 +4278,7 @@ msgstr ""
4302
  "les programmes malveillants. Attention toutefois à ne pas bloquer certains "
4303
  "scripts d'installation ou de configuration si vous l'activez."
4304
 
4305
- #: lib/i18n-extra.php:157
4306
  msgid ""
4307
  "Access Control is a powerful set of directives that can be used to allow or "
4308
  "restrict access to your website based on many criteria."
@@ -4311,7 +4287,7 @@ msgstr ""
4311
  "utilisé pour autoriser ou restreindre l'accès à votre site selon de nombreux "
4312
  "critères."
4313
 
4314
- #: lib/i18n-extra.php:158
4315
  msgid ""
4316
  "To make better use of them, it is important to understand NinjaFirewall's "
4317
  "directives processing order."
@@ -4319,7 +4295,7 @@ msgstr ""
4319
  "Afin de pouvoir optimiser son utilisation, il est important de bien "
4320
  "comprendre l'ordre dans lequel NinjaFirewall traite ces directives."
4321
 
4322
- #: lib/i18n-extra.php:159
4323
  msgid ""
4324
  "Because NinjaFirewall is a PHP firewall, its Access Control options apply to "
4325
  "PHP scripts, not to static elements (e.g., images, JS, CSS etc). Depending "
@@ -4330,81 +4306,81 @@ msgstr ""
4330
  "(images, JS, CSS, etc). Selon votre configuration, elle peuvent également "
4331
  "s'appliquer aux pages HTML."
4332
 
4333
- #: lib/i18n-extra.php:160
4334
  msgid "Processing order:"
4335
  msgstr "Ordre de traitement des directives :"
4336
 
4337
- #: lib/i18n-extra.php:161
4338
  msgid "Incoming HTTP request"
4339
  msgstr "Requête HTTP entrante"
4340
 
4341
- #: lib/i18n-extra.php:162
4342
  #, php-format
4343
  msgid "%s file"
4344
  msgstr "Fichier %s"
4345
 
4346
- #: lib/i18n-extra.php:163
4347
  msgid "Login Protection."
4348
  msgstr "Page de Connexion."
4349
 
4350
- #: lib/i18n-extra.php:164
4351
  msgid "Access Control (except User Input Access Control):"
4352
  msgstr "Contrôle d'Accès (sauf Contrôle d'accès d'entrée utilisateur) :"
4353
 
4354
- #: lib/i18n-extra.php:165
4355
  msgid "Role-based Access Control."
4356
  msgstr "Contrôle d'Accès par Rôle."
4357
 
4358
- #: lib/i18n-extra.php:166
4359
  msgid "Allowed IPs."
4360
  msgstr "Adresses IP autorisées."
4361
 
4362
- #: lib/i18n-extra.php:167
4363
  msgid "Blocked IPs."
4364
  msgstr "Adresses IP bloquées."
4365
 
4366
- #: lib/i18n-extra.php:168
4367
  msgid "Allowed URLs."
4368
  msgstr "URL autorisées."
4369
 
4370
- #: lib/i18n-extra.php:169
4371
  msgid "Blocked URLs."
4372
  msgstr "URL bloquées."
4373
 
4374
- #: lib/i18n-extra.php:170
4375
  msgid "Bot Access Control."
4376
  msgstr "Contrôle d'accès par Bot."
4377
 
4378
- #: lib/i18n-extra.php:171
4379
  msgid "Geolocation."
4380
  msgstr "Géolocalisation."
4381
 
4382
- #: lib/i18n-extra.php:172
4383
  msgid "Rate Limiting."
4384
  msgstr "Limitation du trafic."
4385
 
4386
- #: lib/i18n-extra.php:173
4387
  msgid "File Guard."
4388
  msgstr "File Guard."
4389
 
4390
- #: lib/i18n-extra.php:174
4391
  msgid "NinjaFirewall built-in rules and policies + User Input Access Control."
4392
  msgstr ""
4393
  "Règles et politiques du pare-feu + Contrôle d'accès d'entrée utilisateur."
4394
 
4395
- #: lib/i18n-extra.php:175
4396
  msgid "Response body"
4397
  msgstr "Requête HTTP sortante"
4398
 
4399
- #: lib/i18n-extra.php:176
4400
  msgid "HTTP response headers (Firewall Policies)."
4401
  msgstr "En-têtes de réponse HTTP (Politiques du Pare-feu)."
4402
 
4403
- #: lib/i18n-extra.php:177
4404
  msgid "Web Filter."
4405
  msgstr "Web Filter."
4406
 
4407
- #: lib/i18n-extra.php:178
4408
  #, php-format
4409
  msgid ""
4410
  "By default, any logged in WordPress administrator will not be blocked by "
@@ -4423,13 +4399,13 @@ msgstr ""
4423
  "options de la <a href=\"%s\">Page de Connexion</a> qui, si elle sont "
4424
  "activées, seront toujours appliquées."
4425
 
4426
- #: lib/i18n-extra.php:179
4427
  msgid "You can also add other users to the whitelist, depending on their role."
4428
  msgstr ""
4429
  "Vous pouvez ajouter d'autres utilisateurs à votre liste blanche en se basant "
4430
  "sur leur Rôle."
4431
 
4432
- #: lib/i18n-extra.php:180
4433
  #, php-format
4434
  msgid ""
4435
  "this option should be used if you are behind a reverse proxy, a load "
@@ -4453,7 +4429,7 @@ msgstr ""
4453
  "sera vérifiée. Si elle ne comprend aucune IP utilisable, NinjaFirewall "
4454
  "utilisera <code>REMOTE_ADDR</code>."
4455
 
4456
- #: lib/i18n-extra.php:181
4457
  msgid ""
4458
  "This option lets you select the HTTP method(s). All Access Control "
4459
  "directives (Geolocation, IPs, bots and URLs) will only apply to the selected "
@@ -4463,20 +4439,20 @@ msgstr ""
4463
  "Contrôle d'Accès (Geolocalisation, IP, bots et URL) ne s'appliqueront qu'aux "
4464
  "méthodes sélectionnées."
4465
 
4466
- #: lib/i18n-extra.php:182
4467
  msgid ""
4468
  "It does not apply to the \"Firewall Policies\" options, which use their own "
4469
  "ones."
4470
  msgstr "Cette option ne concerne pas les \"Politiques du Pare-feu\"."
4471
 
4472
- #: lib/i18n-extra.php:183
4473
  msgid ""
4474
  "You can filter and block traffic coming from specific countries/territories."
4475
  msgstr ""
4476
  "Vous pouvez filtrer et bloquer le trafic en provenance de pays ou "
4477
  "territoires spécifiques."
4478
 
4479
- #: lib/i18n-extra.php:184
4480
  msgid ""
4481
  "This is the two-letter code that is used to define a country/territory (e."
4482
  "g., US, UK, FR, DE etc), based on the visitors IP. NinjaFirewall can either "
@@ -4489,7 +4465,7 @@ msgstr ""
4489
  "données, ou à partir d'une variable PHP prédéfinie ajoutée par votre serveur "
4490
  "HTTP (par exemple, <code>GEOIP_COUNTRY_CODE</code>)."
4491
 
4492
- #: lib/i18n-extra.php:185
4493
  #, php-format
4494
  msgid ""
4495
  "You can add/remove any country/territory from the two listboxes. For more "
@@ -4501,7 +4477,7 @@ msgstr ""
4501
  "spécifiques (A1, A2, AP, EU etc),vous pouvez consulter l'aide en ligne de <a "
4502
  "href=\"%s\">MaxMind GeoIP</a>."
4503
 
4504
- #: lib/i18n-extra.php:186
4505
  msgid ""
4506
  "Whether geolocation should apply to the whole site or to specific URLs only "
4507
  "(e.g., /wp-login.php, /xmlrpc.php etc). Leave all fields empty if you want "
@@ -4511,7 +4487,11 @@ msgstr ""
4511
  "uniquement (ex: /wp-login.php, /xmlrpc.php etc). Laissez ce champ vide pour "
4512
  "l'appliquer à tout le site."
4513
 
4514
- #: lib/i18n-extra.php:187
 
 
 
 
4515
  msgid ""
4516
  "After retrieving the two-letter country/territory code, NinjaFirewall can "
4517
  "add it to the PHP headers in the <code>$_SERVER[\"NINJA_COUNTRY_CODE\"]</"
@@ -4523,7 +4503,7 @@ msgstr ""
4523
  "code>. Si vous avez une application PHP qui nécessite de géolocaliser vos "
4524
  "visiteurs, activez cette option."
4525
 
4526
- #: lib/i18n-extra.php:188
4527
  msgid ""
4528
  "If NinjaFirewall cannot find the two-letter ISO 3166 code, it will replace "
4529
  "it with 2 hyphens (<code>--</code>)."
@@ -4531,13 +4511,13 @@ msgstr ""
4531
  "Si NinjaFirewall ne peut pas identifier le code à deux lettres ISO 3166, il "
4532
  "le remplacera par deux traits d'union (<code>--</code>)."
4533
 
4534
- #: lib/i18n-extra.php:189
4535
  msgid ""
4536
  "PHP code example to use in your theme or plugin to geolocate your visitors:"
4537
  msgstr ""
4538
  "Exemple de code PHP à ajouter à vos scripts pour géolocaliser vos visiteurs :"
4539
 
4540
- #: lib/i18n-extra.php:190
4541
  msgid ""
4542
  "NinjaFirewall includes GeoLite data created by MaxMind, available from "
4543
  "http://www.maxmind.com"
@@ -4545,11 +4525,11 @@ msgstr ""
4545
  "NinjaFirewall includes GeoLite data created by MaxMind, available from "
4546
  "http://www.maxmind.com"
4547
 
4548
- #: lib/i18n-extra.php:191
4549
  msgid "IP / URL / Bot Access Control"
4550
  msgstr "Contrôle d'Accès par IP / URL / Bots"
4551
 
4552
- #: lib/i18n-extra.php:192
4553
  msgid ""
4554
  "You can permanently allow/block an IP, a whole range of IP addresses or AS "
4555
  "numbers (Autonomous System number). IPv4 and IPv6 are fully supported by "
@@ -4559,20 +4539,20 @@ msgstr ""
4559
  "numéro AS (Autonomous System). NinjaFirewall est compatible avec l'IPv4 et "
4560
  "l'IPv6."
4561
 
4562
- #: lib/i18n-extra.php:193
4563
  msgid "Full IP:"
4564
  msgstr "IP complète :"
4565
 
4566
- #: lib/i18n-extra.php:194
4567
  #, php-format
4568
  msgid "IP ranges using CIDR notation: %s or %s."
4569
  msgstr "Plages IP utilisant la notation CIDR : %s ou %s."
4570
 
4571
- #: lib/i18n-extra.php:195
4572
  msgid "Autonomous System number:"
4573
  msgstr "Numéro AS (Autonomous System) :"
4574
 
4575
- #: lib/i18n-extra.php:196
4576
  msgid ""
4577
  "This option allows you to slow down aggressive bots, crawlers, web scrapers "
4578
  "or even small HTTP attacks. Any IP reaching the defined threshold will be "
@@ -4591,7 +4571,7 @@ msgstr ""
4591
  "adresse IP, utilisez l'option \"Contrôle d'accès par IP\". Par défaut, la "
4592
  "limitation du trafic n'est pas activée."
4593
 
4594
- #: lib/i18n-extra.php:197
4595
  msgid ""
4596
  "IPs temporarily banned by the Rate Limiting option can be unblocked "
4597
  "immediately by clicking either the \"Save Access Control Directives\" or "
@@ -4601,7 +4581,7 @@ msgstr ""
4601
  "débloquées simplement en cliquant sur les boutons \"Sauvegarder les options"
4602
  "\" ou \"Rétablir les valeurs par défaut\" situés en bas de la page."
4603
 
4604
- #: lib/i18n-extra.php:198
4605
  msgid ""
4606
  "Because NinjaFirewall can handle a lot of HTTP requests per second and block "
4607
  "IPs even before your blog is loaded, we strongly recommend that you disable "
@@ -4615,7 +4595,7 @@ msgstr ""
4615
  "seconde, NinjaFirewall vous fera économiser de la bande passante et "
4616
  "permettra de réduire la charge du serveur."
4617
 
4618
- #: lib/i18n-extra.php:199
4619
  msgid ""
4620
  "You can permanently allow/block any access to one or more PHP scripts based "
4621
  "on their path, relative to the web root (<code>SCRIPT_NAME</code>). You can "
@@ -4626,7 +4606,7 @@ msgstr ""
4626
  "(<code>SCRIPT_NAME</code>). Vous pouvez entrer l'URL complète ou partielle, "
4627
  "sensible à la casse."
4628
 
4629
- #: lib/i18n-extra.php:200
4630
  msgid ""
4631
  "<code>/foo/bar.php</code> will block any access to the <code>bar.php</code> "
4632
  "script located inside a <code>/foo/</code> directory"
@@ -4634,11 +4614,11 @@ msgstr ""
4634
  "<code>/foo/bar.php</code> autorisera/bloquera tout accès au script PHP "
4635
  "<code>bar.php</code> situé dans un répertoire <code>/foo/</code>"
4636
 
4637
- #: lib/i18n-extra.php:201
4638
  msgid "etc"
4639
  msgstr "etc"
4640
 
4641
- #: lib/i18n-extra.php:202
4642
  msgid ""
4643
  "<code>/foo/</code> will block access to all PHP scripts located inside a "
4644
  "<code>/foo/</code> directory and its sub-directories."
@@ -4646,7 +4626,7 @@ msgstr ""
4646
  "<code>/foo/</code> autorisera/bloquera l'accès à tous les scripts PHP situés "
4647
  "dans un répertoire <code>/foo/</code> et ses sous-répertoires."
4648
 
4649
- #: lib/i18n-extra.php:203
4650
  msgid ""
4651
  "Note that the \"Firewall Policies\" page already includes restrictions to "
4652
  "some WordPress directories."
@@ -4654,7 +4634,7 @@ msgstr ""
4654
  "Notez que le menu des \"Politiques du pare-feu\" comporte déjà des "
4655
  "restrictions à certains répertoires de WordPress."
4656
 
4657
- #: lib/i18n-extra.php:204
4658
  msgid ""
4659
  "You can block bots, scanners and various crawlers based on the "
4660
  "<code>HTTP_USER_AGENT</code> variable. You can enter either a full or "
@@ -4664,7 +4644,7 @@ msgstr ""
4664
  "nom (<code>HTTP_USER_AGENT</code>) ou partie de celui-ci. La chaîne de "
4665
  "caractères est insensible à la casse."
4666
 
4667
- #: lib/i18n-extra.php:205
4668
  msgid ""
4669
  "You can select to ignore or block some specific user input. It applies to "
4670
  "the <code>GET</code>, <code>POST</code> and <code>COOKIE</code> global "
@@ -4676,7 +4656,7 @@ msgstr ""
4676
  "<code>COOKIE</code>, par exemple <code>$_GET[\"foo\"]</code> ou <code>"
4677
  "$_POST[\"bar\"]</code> :"
4678
 
4679
- #: lib/i18n-extra.php:206
4680
  msgid ""
4681
  "When an input is added to the \"Unfiltered input\" list, it will not be "
4682
  "filtered or sanitised. All other input present in the request will be "
@@ -4686,7 +4666,7 @@ msgstr ""
4686
  "sera ni filtrée ni nettoyée. Toutes les autres entrées présentes dans la "
4687
  "demande seront filtrées."
4688
 
4689
- #: lib/i18n-extra.php:207
4690
  msgid ""
4691
  "When an input is added to the \"Blocked input\", NinjaFirewall will block "
4692
  "the request and close the connection if that input is found in the request."
@@ -4695,11 +4675,11 @@ msgstr ""
4695
  "bloquera la requête et fermera la connexion si cette entrée est présente "
4696
  "dans la requête."
4697
 
4698
- #: lib/i18n-extra.php:208
4699
  msgid "Log Event"
4700
  msgstr "Journaliser"
4701
 
4702
- #: lib/i18n-extra.php:209
4703
  msgid ""
4704
  "You can enable/disable firewall logging for each access control directive "
4705
  "separately."
@@ -4707,11 +4687,11 @@ msgstr ""
4707
  "Vous pouvez activer/désactiver la journalisation des directives "
4708
  "indépendamment les unes des autres."
4709
 
4710
- #: lib/i18n-extra.php:210
4711
  msgid "Web Filter"
4712
  msgstr "Web Filter"
4713
 
4714
- #: lib/i18n-extra.php:211
4715
  msgid ""
4716
  "If NinjaFirewall can hook and scan incoming requests, it can also hook the "
4717
  "response body (i.e., the output of the HTML page right before it is sent to "
@@ -4728,7 +4708,7 @@ msgstr ""
4728
  "etc), des scripts utilisés par les hackers (shell, backdoor) et même des "
4729
  "erreurs (PHP, MySQL)."
4730
 
4731
- #: lib/i18n-extra.php:212
4732
  msgid ""
4733
  "In the case of a positive detection, NinjaFirewall will not block the "
4734
  "response body but will send you an alert by email."
@@ -4736,11 +4716,11 @@ msgstr ""
4736
  "En cas de détection positive, NinjaFirewall ne bloquera pas la requête mais "
4737
  "vous enverra immédiatement une alerte par e-mail."
4738
 
4739
- #: lib/i18n-extra.php:213
4740
  msgid "Search HTML page for the following keywords"
4741
  msgstr "Rechercher les mots suivants dans la page HTML"
4742
 
4743
- #: lib/i18n-extra.php:214
4744
  msgid ""
4745
  "You can enter any keyword from 4 to 150 characters and select whether the "
4746
  "search will be case sensitive or not."
@@ -4748,11 +4728,11 @@ msgstr ""
4748
  "Vous pouvez entrer de 4 à 150 caractères et sélectionner si la recherche est "
4749
  "sensible à la casse."
4750
 
4751
- #: lib/i18n-extra.php:215
4752
  msgid "Email Alerts"
4753
  msgstr "Alertes E-mail"
4754
 
4755
- #: lib/i18n-extra.php:216
4756
  msgid ""
4757
  "You can use the notification throttling option to limit the frequency of "
4758
  "alerts sent to you (and written to the firewall log) and select whether you "
@@ -4764,7 +4744,7 @@ msgstr ""
4764
  "d'Événement \". La page HTML ayant déclenché cette alerte peut être jointe à "
4765
  "l'e-mail."
4766
 
4767
- #: lib/i18n-extra.php:217
4768
  msgid ""
4769
  "Response body filtering can be resource-intensive. Try to limit the number "
4770
  "of keywords to what you really need (less than 10) and, if possible, prefer "
@@ -4774,7 +4754,7 @@ msgstr ""
4774
  "limiter le nombre de mots-clés (moins de 10) et, si possible, préférez la "
4775
  "recherche sensible à la casse."
4776
 
4777
- #: lib/i18n-extra.php:218
4778
  msgid ""
4779
  "NinjaFirewall can protect your blog against spam without user interaction (e."
4780
  "g., CAPTCHA, math puzzles etc). The protection is totally transparent to "
@@ -4789,11 +4769,11 @@ msgstr ""
4789
  "vous utilisez une extension tierce pour créer vos formulaires, ils ne seront "
4790
  "pas protégés contre le spam."
4791
 
4792
- #: lib/i18n-extra.php:219
4793
  msgid "Protection level:"
4794
  msgstr "Niveau de protection :"
4795
 
4796
- #: lib/i18n-extra.php:220
4797
  msgid ""
4798
  "Select the level of protection. In most cases, <strong>Low</strong> should "
4799
  "be enough."
@@ -4801,21 +4781,21 @@ msgstr ""
4801
  "Sélectionnez le niveau de protection. Dans la plupart des cas \"Bas\" est "
4802
  "suffisant."
4803
 
4804
- #: lib/i18n-extra.php:221
4805
  msgid "Apply protection to:"
4806
  msgstr "Appliquer la protection à :"
4807
 
4808
- #: lib/i18n-extra.php:222
4809
  msgid "Whether to protect comment and/or registration forms."
4810
  msgstr "S'il faut protéger les formulaires de commentaire et d'inscription."
4811
 
4812
- #: lib/i18n-extra.php:223
4813
  msgid "If you are using a caching plugin, ensure you follow these steps:"
4814
  msgstr ""
4815
  "Si vous utilisez une extension de mise en cache, veuillez procéder de la "
4816
  "sorte :"
4817
 
4818
- #: lib/i18n-extra.php:224
4819
  msgid ""
4820
  "Set the Protection Level to \"Low\" only. Do not use another value, "
4821
  "otherwise the antispam could behave erratically after a while."
@@ -4823,14 +4803,14 @@ msgstr ""
4823
  "Réglez le niveau de protection sur \"Bas\" uniquement. N'utilisez pas "
4824
  "d'autre niveau, sinon l'anti-spam pourrait se comporter de façon erratique."
4825
 
4826
- #: lib/i18n-extra.php:225
4827
  msgid ""
4828
  "Flush/clear your cache immediately after enabling or disabling the antispam."
4829
  msgstr ""
4830
  "Videz / effacez votre cache immédiatement après l'activation ou la "
4831
  "désactivation de l'anti-spam."
4832
 
4833
- #: lib/i18n-extra.php:226
4834
  msgid ""
4835
  "The firewall log displays blocked and sanitised requests as well as some "
4836
  "useful information. It has 6 columns:"
@@ -4838,7 +4818,7 @@ msgstr ""
4838
  "Le journal du pare-feu affiche les requêtes HTTP qui ont été bloquées ou "
4839
  "nettoyées ainsi que d'autres informations utiles. Il a six colonnes :"
4840
 
4841
- #: lib/i18n-extra.php:227
4842
  msgid ""
4843
  "RULE : reference of the NinjaFirewall built-in security rule that triggered "
4844
  "the action. A hyphen (<code>-</code>) instead of a number means it was a "
@@ -4849,23 +4829,23 @@ msgstr ""
4849
  "d'un numéro signifie que la règle provient de votre configuration "
4850
  "personnelle de la page \"Politiques du Pare-feu\" ou \"Contrôle d'Accès\"."
4851
 
4852
- #: lib/i18n-extra.php:228
4853
  msgid "The log can also be exported as a TSV (tab-separated values) text file."
4854
  msgstr ""
4855
  "Le journal peut aussi être exporté au format TSV (valeurs séparées par des "
4856
  "tabulations)."
4857
 
4858
- #: lib/i18n-extra.php:229
4859
  msgid "Enable firewall log"
4860
  msgstr "Activer le journal du pare-feu"
4861
 
4862
- #: lib/i18n-extra.php:230
4863
  msgid "You can disable/enable the firewall log from this page."
4864
  msgstr ""
4865
  "Vous pouvez activer / désactiver le journal du pare-feu à partir de cette "
4866
  "page."
4867
 
4868
- #: lib/i18n-extra.php:231
4869
  msgid ""
4870
  "Brute-force attacks will still be written to the firewall log, even if you "
4871
  "disable it."
@@ -4873,11 +4853,11 @@ msgstr ""
4873
  "Les attaques par force brute seront toujours enregistrées dans le journal du "
4874
  "pare-feu, même si vous désactivez celui-ci."
4875
 
4876
- #: lib/i18n-extra.php:232
4877
  msgid "Auto-rotate log"
4878
  msgstr "Rotation automatique du journal"
4879
 
4880
- #: lib/i18n-extra.php:233
4881
  msgid ""
4882
  "NinjaFirewall will rotate its log automatically on the very first day of "
4883
  "each month. If your site is very busy, you may want to allow it to rotate "
@@ -4888,24 +4868,24 @@ msgstr ""
4888
  "effectuée plus tôt, dans le cas où le journal aurait atteint une certaine "
4889
  "taille (Mo)."
4890
 
4891
- #: lib/i18n-extra.php:234
4892
  msgid ""
4893
  "By default, if will rotate the log each month or earlier, if it reaches 2 "
4894
  "megabytes."
4895
  msgstr "Par défaut, cette taille est fixée à 2 Mo."
4896
 
4897
- #: lib/i18n-extra.php:235
4898
  msgid ""
4899
  "Rotated logs, if any, can be selected and viewed from the dropdown menu."
4900
  msgstr ""
4901
  "Les journaux des mois précédents sont accessibles depuis le menu déroulant "
4902
  "situé au dessus de la fenêtre."
4903
 
4904
- #: lib/i18n-extra.php:236
4905
  msgid "Syslog"
4906
  msgstr "Syslog"
4907
 
4908
- #: lib/i18n-extra.php:237
4909
  msgid ""
4910
  "In addition to the firewall log, events can also be redirected to the syslog "
4911
  "server (<code>LOG_USER</code> facility)."
@@ -4913,7 +4893,7 @@ msgstr ""
4913
  "En plus d'écrire dans son journal, le pare-feu peut aussi utiliser le "
4914
  "serveur Syslog (catégorie <code>LOG_USER</code>)."
4915
 
4916
- #: lib/i18n-extra.php:238
4917
  msgid ""
4918
  "If you have a shared hosting account, keep this option disabled as you do "
4919
  "not have any access to the server logs."
@@ -4921,11 +4901,11 @@ msgstr ""
4921
  "Si vous avez un hébergement mutualisé, laissez cette option désactivée car "
4922
  "vous n'avez pas accès aux journaux du serveur."
4923
 
4924
- #: lib/i18n-extra.php:239
4925
  msgid "The logline uses the following format:"
4926
  msgstr "Le format utilisé est le suivant :"
4927
 
4928
- #: lib/i18n-extra.php:240
4929
  msgid ""
4930
  "BB: the level of severity as it appears in the firewall log. It can be "
4931
  "<code>CRITICAL</CODE>, <CODE>HIGH</CODE>, <CODE>MEDIUM</CODE>, <CODE>INFO</"
@@ -4936,19 +4916,19 @@ msgstr ""
4936
  "<CODE>MEDIUM</CODE>, <CODE>INFO</CODE>, <CODE>UPLOAD</CODE> ou "
4937
  "<CODE>DEBUG_ON</CODE>."
4938
 
4939
- #: lib/i18n-extra.php:241
4940
  msgid "CCCCCC: the 7-digit incident ID."
4941
  msgstr "CCCCCC : le numéro d'incident à sept chiffres."
4942
 
4943
- #: lib/i18n-extra.php:242
4944
  msgid "DD: the user IPv4 or IPv6 address."
4945
  msgstr "DD : L'adresse IPv4 ou IPv6 de l'utilisateur."
4946
 
4947
- #: lib/i18n-extra.php:243
4948
  msgid "EE: the blog (sub-)domain name."
4949
  msgstr "EE : le nom de (sous-)domaine du blog."
4950
 
4951
- #: lib/i18n-extra.php:244
4952
  #, php-format
4953
  msgid ""
4954
  "This logging option does not apply to the brute-force protection which can "
@@ -4960,7 +4940,7 @@ msgstr ""
4960
  "d'authentification du serveur. Voir le menu de la <a href=\"%s\">Page de "
4961
  "Connexion</a>."
4962
 
4963
- #: lib/i18n-extra.php:245
4964
  msgid ""
4965
  "Secret key: The secret key will be used to generate your public key. Enter "
4966
  "at least 30 ASCII characters, or use the one randomly created by "
@@ -4970,7 +4950,7 @@ msgstr ""
4970
  "de 30 à 100 caractères ASCII, ou bien utilisez la clé générée aléatoirement "
4971
  "par NinjaFirewall."
4972
 
4973
- #: lib/i18n-extra.php:246
4974
  msgid ""
4975
  "This server IP address: As an additional protection layer, you can restrict "
4976
  "access to the remote website(s) to the main server IP only. You can use IPv4 "
@@ -4981,7 +4961,7 @@ msgstr ""
4981
  "à se connecter aux sites distants. Si vous ne souhaitez pas de restriction "
4982
  "d’accès par IP, veuillez entrer le caractère <code>*</code>."
4983
 
4984
- #: lib/i18n-extra.php:247
4985
  #, php-format
4986
  msgid ""
4987
  "Public key: This is the public key that you will need to upload to each "
@@ -4990,7 +4970,7 @@ msgstr ""
4990
  "Clé publique : Vous devez configurer vos sites distants avec cette clé. <a "
4991
  "href=\"%s\">Consultez notre blog</a> pour plus d'info."
4992
 
4993
- #: lib/i18n-extra.php:248
4994
  msgid ""
4995
  "Remote websites URL: Enter the full URL of your NinjaFirewall protected "
4996
  "website(s) that you want to remotely access from the main server."
@@ -4999,7 +4979,7 @@ msgstr ""
4999
  "NinjaFirewall auxquels vous souhaitez accéder à distance à partir du serveur "
5000
  "principal."
5001
 
5002
- #: lib/i18n-extra.php:249
5003
  msgid ""
5004
  "Centralized Logging will keep working even if NinjaFirewall is disabled. Use "
5005
  "the menu below if you want to disable it."
@@ -5008,172 +4988,172 @@ msgstr ""
5008
  "NinjaFirewall. Si vous souhaitez complètement désactiver cette option, "
5009
  "faites-le ci-dessous."
5010
 
5011
- #: lib/i18n-extra.php:250
5012
  msgid "Enable Web Filter"
5013
  msgstr "Activer Web Filter"
5014
 
5015
- #: lib/i18n-extra.php:251
5016
  msgid "A full or partial string."
5017
  msgstr "Chaîne de caractère complète ou partielle."
5018
 
5019
- #: lib/i18n-extra.php:252
5020
  msgid "From 4 to maximum 150 characters."
5021
  msgstr "De 4 à 150 caractères."
5022
 
5023
- #: lib/i18n-extra.php:253
5024
  msgid "Any character, except the vertical bar <code>|</code>"
5025
  msgstr "Tout caractère, sauf la barre verticale <code>|</code>"
5026
 
5027
- #: lib/i18n-extra.php:254
5028
  msgid "Keywords to search:"
5029
  msgstr "Mots-clés recherchés :"
5030
 
5031
- #: lib/i18n-extra.php:255
5032
  msgid "Case-sensitive search"
5033
  msgstr "Recherche sensible à la casse"
5034
 
5035
- #: lib/i18n-extra.php:256
5036
  #, php-format
5037
  msgid "Do not send me more than one email alert in a %s interval"
5038
  msgstr "Ne pas envoyer plus d'un e-mail par tranche de %s"
5039
 
5040
- #: lib/i18n-extra.php:257
5041
  msgid "5-minute"
5042
  msgstr "5 minutes"
5043
 
5044
- #: lib/i18n-extra.php:258
5045
  msgid "15-minute"
5046
  msgstr "15 minutes"
5047
 
5048
- #: lib/i18n-extra.php:259
5049
  msgid "30-minute"
5050
  msgstr "30 minutes"
5051
 
5052
- #: lib/i18n-extra.php:260
5053
  msgid "1-hour"
5054
  msgstr "1 heure"
5055
 
5056
- #: lib/i18n-extra.php:261
5057
  msgid "3-hour"
5058
  msgstr "3 heures"
5059
 
5060
- #: lib/i18n-extra.php:262
5061
  msgid "6-hour"
5062
  msgstr "6 heures"
5063
 
5064
- #: lib/i18n-extra.php:263
5065
  msgid "12-hour"
5066
  msgstr "12 heures"
5067
 
5068
- #: lib/i18n-extra.php:264
5069
  msgid "24-hour"
5070
  msgstr "24 heures"
5071
 
5072
- #: lib/i18n-extra.php:265
5073
  msgid ""
5074
  "Clicking the \"Save Web Filter options\" button below will reset the current "
5075
  "timer."
5076
  msgstr "Cliquer sur \"Sauvegarder les options\" réinitialisera le compteur."
5077
 
5078
- #: lib/i18n-extra.php:266
5079
  msgid "Attach the HTML page output to email alerts"
5080
  msgstr "Joindre la page HTML à l'e-mail"
5081
 
5082
- #: lib/i18n-extra.php:267
5083
  msgid "Save Web Filter options"
5084
  msgstr "Sauvegarder les options"
5085
 
5086
- #: lib/i18n-extra.php:268
5087
  msgid "Help Desk:"
5088
  msgstr "Help Desk :"
5089
 
5090
- #: lib/i18n-extra.php:269
5091
  msgid "The selected log was deleted"
5092
  msgstr "Le journal sélectionné a été supprimé"
5093
 
5094
- #: lib/i18n-extra.php:270
5095
  msgid "Export"
5096
  msgstr "Exporter"
5097
 
5098
- #: lib/i18n-extra.php:271
5099
  msgid "Delete"
5100
  msgstr "Supprimer"
5101
 
5102
- #: lib/i18n-extra.php:272
5103
  msgid "Delete log?"
5104
  msgstr "Supprimer le journal ?"
5105
 
5106
- #: lib/i18n-extra.php:273
5107
  msgid "Today"
5108
  msgstr "Aujourd'hui"
5109
 
5110
- #: lib/i18n-extra.php:274
5111
  msgid "Upload"
5112
  msgstr "Téléchargement"
5113
 
5114
- #: lib/i18n-extra.php:275
5115
  msgid "Info"
5116
  msgstr "Info"
5117
 
5118
- #: lib/i18n-extra.php:276
5119
  msgid "Debug"
5120
  msgstr "Débogage"
5121
 
5122
- #: lib/i18n-extra.php:277
5123
  msgid "IP address:"
5124
  msgstr "Adresse IP :"
5125
 
5126
- #: lib/i18n-extra.php:278
5127
  msgid "e.g., 1.2.3.4"
5128
  msgstr "ex : 1.2.3.4"
5129
 
5130
- #: lib/i18n-extra.php:279
5131
  msgid "Add IP to blacklist"
5132
  msgstr "Ajouter à la liste noire"
5133
 
5134
- #: lib/i18n-extra.php:280
5135
  msgid "Add IP to whitelist"
5136
  msgstr "Ajouter à la liste blanche"
5137
 
5138
- #: lib/i18n-extra.php:281
5139
  msgid "Add"
5140
  msgstr "Ajouter"
5141
 
5142
- #: lib/i18n-extra.php:282
5143
  msgid "The address wad added to your IP Access Control list."
5144
  msgstr "L'adresse a été ajoutée à votre liste du Contrôle d'accès par IP."
5145
 
5146
- #: lib/i18n-extra.php:283
5147
  #, php-format
5148
  msgid "1st day of the month, or if bigger than %s MB"
5149
  msgstr "Le 1er de chaque mois, ou si sa taille dépasse %s Mo"
5150
 
5151
- #: lib/i18n-extra.php:284
5152
  msgid "1st day of the month, regardless of its size"
5153
  msgstr "Le 1er de chaque mois, quelle que soit sa taille"
5154
 
5155
- #: lib/i18n-extra.php:285
5156
  msgid "Show the most recent"
5157
  msgstr "Afficher les dernières"
5158
 
5159
- #: lib/i18n-extra.php:286
5160
  msgid "lines"
5161
  msgstr "lignes"
5162
 
5163
- #: lib/i18n-extra.php:287
5164
  msgid "Write events to the Syslog server too"
5165
  msgstr "Enregistrer aussi les événements dans le journal syslog"
5166
 
5167
- #: lib/i18n-extra.php:288
5168
  msgid "Your server configuration is not compatible with this option."
5169
  msgstr ""
5170
  "La configuration de votre serveur n'est pas compatible avec cette option."
5171
 
5172
- #: lib/i18n-extra.php:289
5173
  msgid "See contextual help before enabling this option."
5174
  msgstr "Consultez l'aide contextuelle avant d'activer cette option."
5175
 
5176
- #: lib/i18n-extra.php:290
5177
  msgid ""
5178
  "The remote server rejected your request. Make sure that you uploaded the "
5179
  "correct public key."
@@ -5181,29 +5161,29 @@ msgstr ""
5181
  "Le serveur distant a rejeté votre requête. Veuillez vous assurer que la clé "
5182
  "publique est correcte."
5183
 
5184
- #: lib/i18n-extra.php:291
5185
  #, php-format
5186
  msgid "The remote server returned the following HTTP error: %s"
5187
  msgstr "Le serveur HTTP a retourné le code d'erreur suivant : %s"
5188
 
5189
- #: lib/i18n-extra.php:292
5190
  msgid "The requested log does not exist on the remote website."
5191
  msgstr "Le journal demandé n'existe pas sur le site distant."
5192
 
5193
- #: lib/i18n-extra.php:293
5194
  msgid "The remote website did not return the expected response."
5195
  msgstr "Le site distant n'a pas retourné la réponse attendue."
5196
 
5197
- #: lib/i18n-extra.php:294
5198
  msgid "Your server does not seem to be compatible with this option."
5199
  msgstr ""
5200
  "La configuration de votre serveur n'est pas compatible avec cette option."
5201
 
5202
- #: lib/i18n-extra.php:295
5203
  msgid "Load language files from the WordPress repo"
5204
  msgstr "Charger les fichiers de langue depuis le WordPress.org"
5205
 
5206
- #: lib/i18n-extra.php:296
5207
  #, php-format
5208
  msgid ""
5209
  "If available, NinjaFirewall will download the language files from <a "
@@ -5212,15 +5192,15 @@ msgstr ""
5212
  "Si disponible, NinjaFirewall téléchargera le fichier de langue à partir de "
5213
  "<a %s>translate.wordpress.org</a>."
5214
 
5215
- #: lib/i18n-extra.php:297
5216
  msgid "Error: you do not have any license."
5217
  msgstr "Erreur : vous n'avez pas de licence."
5218
 
5219
- #: lib/i18n-extra.php:298
5220
  msgid "You have a valid license."
5221
  msgstr "Votre licence est valide."
5222
 
5223
- #: lib/i18n-extra.php:299
5224
  msgid ""
5225
  "An unknown error occured while connecting to NinjaFirewall servers. Please "
5226
  "try again in a few minutes"
@@ -5228,7 +5208,7 @@ msgstr ""
5228
  "Une erreur inattendue s'est produite lors de la connexion au serveur de "
5229
  "NinjaFirewall. Merci d'essayer à nouveau dans quelques minutes"
5230
 
5231
- #: lib/i18n-extra.php:300
5232
  msgid ""
5233
  "An error occured while connecting to NinjaFirewall servers. Please try again "
5234
  "in a few minutes"
@@ -5236,90 +5216,90 @@ msgstr ""
5236
  "Une erreur inattendue s'est produite lors de la connexion au serveur de "
5237
  "NinjaFirewall. Merci d'essayer à nouveau dans quelques minutes"
5238
 
5239
- #: lib/i18n-extra.php:301
5240
  msgid "Enter a valid license to save!"
5241
  msgstr "Veuillez entrer un numéro de licence valide !"
5242
 
5243
- #: lib/i18n-extra.php:302
5244
  msgid "This is already your current license!"
5245
  msgstr "Cette licence est la même que l'actuelle !"
5246
 
5247
- #: lib/i18n-extra.php:303
5248
  msgid "Your new license has been accepted and saved."
5249
  msgstr "Votre nouvelle licence a été acceptée et sauvegardée."
5250
 
5251
- #: lib/i18n-extra.php:304
5252
  msgid "This license is not valid"
5253
  msgstr "Cette licence n'est pas valide"
5254
 
5255
- #: lib/i18n-extra.php:305
5256
  msgid "WP+ Edition License"
5257
  msgstr "Licence WP+ Edition"
5258
 
5259
- #: lib/i18n-extra.php:306
5260
  msgid "License Number"
5261
  msgstr "Numéro de Licence"
5262
 
5263
- #: lib/i18n-extra.php:307
5264
  msgid "No license found"
5265
  msgstr "Aucune licence trouvée"
5266
 
5267
- #: lib/i18n-extra.php:308
5268
  msgid "Click to check your license validity"
5269
  msgstr "Cliquez pour tester la validité de votre licence"
5270
 
5271
- #: lib/i18n-extra.php:309
5272
  msgid "Expiration date"
5273
  msgstr "Date d'expiration"
5274
 
5275
- #: lib/i18n-extra.php:310
5276
  msgid "Unknown expiration date"
5277
  msgstr "Date d'expiration inconnue"
5278
 
5279
- #: lib/i18n-extra.php:311
5280
  msgid "Use the \"Check License Validity\" button to attempt to fix this error."
5281
  msgstr ""
5282
  "Selectionnez \"Cliquez pour tester la validité de votre licence\" pour "
5283
  "tenter de réparer cette erreur."
5284
 
5285
- #: lib/i18n-extra.php:312
5286
  msgid "Your license will expire soon!"
5287
  msgstr "Votre licence va bientôt expirer !"
5288
 
5289
- #: lib/i18n-extra.php:313
5290
  msgid "Your license has expired."
5291
  msgstr "Votre licence a expiré."
5292
 
5293
- #: lib/i18n-extra.php:314
5294
  msgid "License renewal"
5295
  msgstr "Renouvellement de licence"
5296
 
5297
- #: lib/i18n-extra.php:315
5298
  msgid "Click here to get a license!"
5299
  msgstr "Cliquez ici pour obtenir une licence !"
5300
 
5301
- #: lib/i18n-extra.php:316
5302
  msgid "Enter your new license and click on the save button"
5303
  msgstr "Entrez votre licence et cliquez sur le bouton pour l'enregistrer"
5304
 
5305
- #: lib/i18n-extra.php:317
5306
  msgid "Save New License"
5307
  msgstr "Sauvegarder la Licence"
5308
 
5309
- #: lib/i18n-extra.php:318
5310
  msgid "Allow, but block dangerous files"
5311
  msgstr "Autoriser, mais bloquer les fichiers dangereux"
5312
 
5313
- #: lib/i18n-extra.php:319
5314
  msgid "See contextual help for the list of files."
5315
  msgstr ""
5316
  "Consultez l'aide contextuelle pour voir la liste des fichiers concernés."
5317
 
5318
- #: lib/i18n-extra.php:320
5319
  msgid "Apply to ZIP archives file contents"
5320
  msgstr "Appliquer au contenu des fichiers ZIP"
5321
 
5322
- #: lib/i18n-extra.php:321
5323
  msgid ""
5324
  "Keep this option disabled if you are using scripts such as Paypal IPN or "
5325
  "WordPress WP-Cron, unless you added their IP address or URL to your Access "
@@ -5329,7 +5309,7 @@ msgstr ""
5329
  "WordPress WP-Cron, sauf si vous avez ajouté leur adresse IP ou URL dans la "
5330
  "section \"Contrôle d'Accès\"."
5331
 
5332
- #: lib/i18n-extra.php:322
5333
  #, php-format
5334
  msgid ""
5335
  "Do not send a notification if the user is in the <a href=\"%s\">IP Access "
@@ -5346,12 +5326,12 @@ msgstr ""
5346
  "Erreur : Votre fichier .htaccess n'est pas accessible en écriture. Veuillez "
5347
  "modifier ses autorisations : %s"
5348
 
5349
- #: lib/install.php:110 ninjafirewall.php:649 ninjafirewall.php:653
5350
  #, php-format
5351
  msgid "Error: wrong parameter value (%s)."
5352
  msgstr "Erreur : Mauvais paramètre (%s)."
5353
 
5354
- #: lib/install.php:117 lib/install.php:211 lib/install.php:232
5355
  #, php-format
5356
  msgid ""
5357
  "Error: The following file is not writable, please change its permissions: %s"
@@ -5376,22 +5356,22 @@ msgstr ""
5376
  "Les modifications ont été annulées. Vous devriez peut-être modifier votre "
5377
  "sélection et réessayer."
5378
 
5379
- #: lib/install.php:157
5380
  #, php-format
5381
  msgid "The website front-end returned: HTTP %s %s."
5382
  msgstr "La page d'accueil du site a retourné : HTTP %s %s."
5383
 
5384
- #: lib/install.php:167
5385
  msgid "The website front-end did not return the expected page."
5386
  msgstr "Le site n'a pas retourné la page attendue."
5387
 
5388
- #: lib/install.php:176
5389
  #, php-format
5390
  msgid "The website front-end returned a fatal error: %s."
5391
  msgstr "La page d'accueil du site a retourné une erreur fatale : %s."
5392
 
5393
- #: lib/install.php:275 lib/install.php:300 lib/install.php:325
5394
- #: lib/install.php:346
5395
  msgid "File is not writable"
5396
  msgstr "Le fichier n'est pas accessible en écriture"
5397
 
@@ -5624,7 +5604,7 @@ msgstr "Erreur : le mot de passe doit comporter de 6 à 255 caractères."
5624
  msgid "Error: unable to write to the %s configuration file"
5625
  msgstr "Erreur : impossible d’écrire dans le fichier de configuration %s"
5626
 
5627
- #: lib/logs.php:36 ninjafirewall.php:851
5628
  msgid "Logs"
5629
  msgstr "Journaux"
5630
 
@@ -5748,7 +5728,7 @@ msgstr ""
5748
  "et assurez vous que l'option \"Ajouter l'Administrateur à la liste blanche\" "
5749
  "est activée."
5750
 
5751
- #: lib/logs_live_log.php:96 ninjafirewall.php:371
5752
  msgid ""
5753
  "Live Log lets you watch your blog traffic in real time. To enable it, click "
5754
  "on the button below."
@@ -5857,7 +5837,7 @@ msgstr "Sauvegarder les options"
5857
  msgid "Error: please enter the custom log format."
5858
  msgstr "Erreur : veuillez entrer le format d'affichage."
5859
 
5860
- #: lib/monitoring.php:43 ninjafirewall.php:825
5861
  msgid "Monitoring"
5862
  msgstr "Monitoring"
5863
 
@@ -6162,15 +6142,15 @@ msgstr "Erreur lors de la lecture du fichier de l'ancien instantané."
6162
  msgid "Error reading new snapshot file."
6163
  msgstr "Erreur lors de la lecture du fichier du nouvel instantané."
6164
 
6165
- #: lib/monitoring_file_check.php:748 ninjafirewall.php:470
6166
  msgid "New file"
6167
  msgstr "Nouveau fichier"
6168
 
6169
- #: lib/monitoring_file_check.php:749 ninjafirewall.php:471
6170
  msgid "Modified file"
6171
  msgstr "Fichier modifié"
6172
 
6173
- #: lib/monitoring_file_check.php:750 ninjafirewall.php:472
6174
  msgid "Deleted file"
6175
  msgstr "Fichier supprimé"
6176
 
@@ -6181,8 +6161,8 @@ msgstr "[NinjaFirewall] Alerte: Détection File Check"
6181
  #: lib/monitoring_file_check.php:777 lib/monitoring_file_check.php:779
6182
  #: lib/monitoring_file_check.php:799 lib/monitoring_file_check.php:801
6183
  #: lib/security_rules_update.php:572 lib/security_rules_update.php:574
6184
- #: lib/utils.php:225 lib/utils.php:311 lib/utils.php:435 lib/utils.php:1082
6185
- #: lib/utils.php:1261 lib/utils.php:1540
6186
  msgid "Blog:"
6187
  msgstr "Blog :"
6188
 
@@ -6257,7 +6237,7 @@ msgstr ""
6257
  msgid "Save File Guard options"
6258
  msgstr "Sauvegarder les options"
6259
 
6260
- #: lib/network.php:24 ninjafirewall.php:1112 ninjafirewall.php:1116
6261
  #, php-format
6262
  msgid "You are not allowed to perform this task (%s)."
6263
  msgstr "Vous n'êtes pas autorisé à effectuer cette tâche (%s)."
@@ -6283,7 +6263,7 @@ msgid "Save Network options"
6283
  msgstr "Sauvegarder les options"
6284
 
6285
  #: lib/security_rules.php:44 lib/security_rules_update.php:578
6286
- #: ninjafirewall.php:855
6287
  msgid "Security Rules"
6288
  msgstr "Règles de Sécurité"
6289
 
@@ -6480,7 +6460,7 @@ msgstr "Sauvegarder les options"
6480
  msgid "Check For Updates Now!"
6481
  msgstr "Vérifier les mises à jour maintenant !"
6482
 
6483
- #: lib/security_rules_update.php:233 lib/thickbox.php:52
6484
  msgid "Delete Log"
6485
  msgstr "Supprimer le journal"
6486
 
@@ -6557,80 +6537,99 @@ msgstr ""
6557
  "Cette notification peut être désactivée depuis la page \"%s\" de "
6558
  "NinjaFirewall."
6559
 
6560
- #: lib/thickbox.php:42
6561
  msgid "NinjaFirewall error log"
6562
  msgstr "Journal des erreurs de NinjaFirewall"
6563
 
6564
- #: lib/thickbox.php:52
6565
  msgid "Close Log"
6566
  msgstr "Fermer"
6567
 
6568
- #: lib/thickbox.php:76
6569
  msgid ""
6570
- "In <strong>Full WAF</strong> mode, all scripts located inside the blog "
6571
- "installation directories and sub-directories are protected by NinjaFirewall, "
6572
- "including those that aren't part of the WordPress package. It gives you the "
6573
- "highest possible level of protection: security without compromise."
6574
  msgstr ""
6575
- "En mode <strong>Full WAF</strong>, tous les scripts situés dans le "
6576
- "répertoire et sous-répertoires d'installation de votre blog sont protégés, y "
6577
- "compris ceux qui ne font pas partie de WordPress. Cela vous offre le niveau "
6578
- "de protection le plus élevé possible : La sécurité sans aucun compromis."
6579
 
6580
- #: lib/thickbox.php:78
6581
  #, php-format
6582
  msgid ""
6583
- "It works on most websites right out of the box, or may require <a href=\"%s"
6584
- "\" title=\"%s\">some very little tweaks</a>. But in a few cases, mostly "
6585
- "because of some shared hosting plans restrictions, it may simply not work at "
6586
- "all."
6587
  msgstr ""
6588
  "La plupart du temps, l'installation fonctionne sans aucun problème, ou peut "
6589
- "nécessiter <a href=\"%s\" title=\"%s\">quelques petits ajustements</a>. Mais "
6590
- "dans quelques cas, principalement en raison de certaines restrictions "
6591
- "d'hébergement partagé, il se peut que l'installation ne puisse pas "
6592
- "fonctionner du tout."
6593
 
6594
- #: lib/thickbox.php:80
6595
  msgid ""
6596
- "If this happened to you, don't worry: you could still run it in "
6597
- "<strong>WordPress WAF</strong> mode. Despite being less powerful than the "
6598
- "<b>Full WAF</b> mode, it offers a level of protection and performance much "
6599
- "higher than other security plugins."
6600
  msgstr ""
6601
  "Si cela se produisait, ne vous inquiétez pas : vous pourrez l'utiliser en "
6602
- "mode <strong>WordPress WAF</strong>. Bien que moins puissant que le mode "
6603
- "<strong>Full WAF</strong>, il offre tout de même des performances et un "
6604
- "niveau de protection très supérieur aux autres extensions de sécurité pour "
6605
- "WordPress disponibles sur le marché."
6606
 
6607
- #: lib/thickbox.php:154
6608
  msgid "Select your HTTP server and your PHP server API"
6609
  msgstr "Sélectionnez votre serveur HTTP et PHP SAPI"
6610
 
6611
- #: lib/thickbox.php:165
6612
  msgid "Other webserver + CGI/FastCGI or PHP-FPM"
6613
  msgstr "Autre serveur + CGI/FastCGI ou PHP-FPM"
6614
 
6615
- #: lib/thickbox.php:167
6616
  msgid "View PHPINFO"
6617
  msgstr "Voir PHPINFO"
6618
 
6619
- #: lib/thickbox.php:199
6620
  msgid "Select the PHP initialization file supported by your server"
6621
  msgstr ""
6622
  "Sélectionnez le type de fichier de configuration PHP utilisé par votre "
6623
  "serveur"
6624
 
6625
- #: lib/thickbox.php:211
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6626
  msgid "Let NinjaFirewall make the necessary changes (recommended)."
6627
  msgstr "Laissez NinjaFirewall faire les changements (recommandé)."
6628
 
6629
- #: lib/thickbox.php:213
6630
  msgid "I want to make the changes myself."
6631
  msgstr "Je veux faire les changements moi-même."
6632
 
6633
- #: lib/thickbox.php:215
6634
  msgid ""
6635
  "Please make the changes below, then click on the \"Finish Installation\" "
6636
  "button."
@@ -6638,7 +6637,7 @@ msgstr ""
6638
  "Veuillez faire les modifications ci-dessous, puis cliquer sur le bouton "
6639
  "\"Finaliser l'installation\"."
6640
 
6641
- #: lib/thickbox.php:222
6642
  #, php-format
6643
  msgid ""
6644
  "The %s file must be created, and the following lines of code added to it:"
@@ -6646,25 +6645,23 @@ msgstr ""
6646
  "Le fichier %s doit être créé, et les lignes suivantes doivent y être "
6647
  "ajoutées :"
6648
 
6649
- #: lib/thickbox.php:223
6650
  #, php-format
6651
  msgid "The following lines of code must be added to your existing %s file:"
6652
  msgstr "Les lignes suivantes doivent être ajoutées à votre fichier %s :"
6653
 
6654
- #: lib/thickbox.php:291
6655
- #, php-format
6656
  msgid ""
6657
  "Log in to your Openlitespeed admin dashboard, click on \"Virtual Host\", "
6658
  "select your domain, add the following instructions to the \"php.ini Override"
6659
- "\" section in the \"General\" tab, and restart Openlitespeed (see more "
6660
- "detail <a %s>here</a>):"
6661
  msgstr ""
6662
  "Connectez-vous à votre tableau de bord Openlitespeed, cliquez sur \"Virtual "
6663
  "Host\", sélectionnez votre domaine, ajoutez les instructions suivantes à la "
6664
  "section \"php.ini Override\" de l'onglet \"Général\", puis redémarrez "
6665
- "Openlitespeed (consultez <a %s>cet article</a> pour plus d'info) :"
6666
 
6667
- #: lib/thickbox.php:298
6668
  msgid ""
6669
  "Important: if one day you wanted to uninstall NinjaFirewall, do not forget "
6670
  "to remove these instructions from your Openlitespeed admin dashboard "
@@ -6676,11 +6673,11 @@ msgstr ""
6676
  "<strong>avant</strong> de désinstaller NinjaFirewall, car cet installateur "
6677
  "ne pourra pas le faire à votre place."
6678
 
6679
- #: lib/thickbox.php:314
6680
  msgid "Enable the sandbox."
6681
  msgstr "Activer l'environnement de test (sandbox)."
6682
 
6683
- #: lib/thickbox.php:314
6684
  msgid ""
6685
  "If there were a problem during the installation, NinjaFirewall would undo "
6686
  "those changes automatically for you."
@@ -6688,10 +6685,58 @@ msgstr ""
6688
  "S'il y avait un problème lors de l'installation, NinjaFirewall annulerait "
6689
  "ces modifications automatiquement pour vous."
6690
 
6691
- #: lib/thickbox.php:315
6692
  msgid "Finish Installation"
6693
  msgstr "Finaliser l'installation"
6694
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6695
  #: lib/utils.php:183 lib/utils.php:191 lib/utils.php:295
6696
  msgid "N/A"
6697
  msgstr "N/A"
@@ -6722,7 +6767,7 @@ msgstr ""
6722
  "NinjaFirewall a bloqué une tentative de modification/création d'une page ou "
6723
  "d'un article par un utilisateur qui n'avait pas les capacités nécessaires :"
6724
 
6725
- #: lib/utils.php:226 lib/utils.php:312 lib/utils.php:436 lib/utils.php:1265
6726
  msgid "Username:"
6727
  msgstr "Utilisateur :"
6728
 
@@ -6730,18 +6775,18 @@ msgstr "Utilisateur :"
6730
  msgid "Action:"
6731
  msgstr "Action :"
6732
 
6733
- #: lib/utils.php:230 lib/utils.php:315 lib/utils.php:437 lib/utils.php:1269
6734
- #: lib/utils.php:1541
6735
  msgid "User IP:"
6736
  msgstr "IP utilisateur :"
6737
 
6738
- #: lib/utils.php:242 lib/utils.php:327 lib/utils.php:449 lib/utils.php:1281
6739
- #: lib/utils.php:1536
6740
  msgid "A PHP backtrace has been attached to this message for your convenience."
6741
  msgstr ""
6742
  "La pile d'exécution de PHP est jointe à ce message pour votre commodité."
6743
 
6744
- #: lib/utils.php:244 lib/utils.php:329 lib/utils.php:1284 lib/utils.php:1546
6745
  msgid ""
6746
  "This protection (and notification) can be turned off from NinjaFirewall "
6747
  "\"Firewall Policies\" page."
@@ -6750,7 +6795,7 @@ msgstr ""
6750
  "\"Politiques du Pare-feu\" de NinjaFirewall."
6751
 
6752
  #: lib/utils.php:259 lib/utils.php:260 lib/utils.php:344 lib/utils.php:345
6753
- #: lib/utils.php:466 lib/utils.php:467 lib/utils.php:1300 lib/utils.php:1301
6754
  msgid "You are not allowed to perform this task."
6755
  msgstr "Vous n'êtes pas autorisé à effectuer cette tâche."
6756
 
@@ -6775,7 +6820,7 @@ msgid "NinjaFirewall has blocked an attempt to create a user account:"
6775
  msgstr ""
6776
  "NinjaFirewall a bloqué une tentative de création d'un compte d'utilisateur :"
6777
 
6778
- #: lib/utils.php:757
6779
  msgid ""
6780
  "Warning: Because NinjaFirewall's Login Protection is enabled, Site Health "
6781
  "may return an error message regarding the loopback test (e.g., 404 or 401 "
@@ -6786,11 +6831,11 @@ msgstr ""
6786
  "concernant le test de la requête de bouclage (ex.: code d’état HTTP 404 ou "
6787
  "401). Vous pouvez l'ignorer en toute sécurité."
6788
 
6789
- #: lib/utils.php:780 lib/utils.php:784
6790
  msgid "NinjaFirewall error"
6791
  msgstr "NinjaFirewall Erreur"
6792
 
6793
- #: lib/utils.php:781
6794
  #, php-format
6795
  msgid ""
6796
  "%s directory cannot be created. Please review your installation and ensure "
@@ -6799,7 +6844,7 @@ msgstr ""
6799
  "Le répertoire %s ne peut pas être créé. Vérifiez votre installation et "
6800
  "assurez vous que %s n'est pas en lecture seule."
6801
 
6802
- #: lib/utils.php:785
6803
  #, php-format
6804
  msgid ""
6805
  "%s directory is read-only. Please review your installation and ensure that "
@@ -6808,31 +6853,31 @@ msgstr ""
6808
  "Le répertoire %s est en lecture seule. Vérifiez votre installation et les "
6809
  "permissions de %s."
6810
 
6811
- #: lib/utils.php:800
6812
  msgid "unknown error"
6813
  msgstr "erreur inconnue"
6814
 
6815
- #: lib/utils.php:802
6816
  msgid "NinjaFirewall fatal error:"
6817
  msgstr "NinjaFirewall erreur fatale :"
6818
 
6819
- #: lib/utils.php:803
6820
  msgid "Review your installation, your site is not protected."
6821
  msgstr "Vérifiez votre installation, votre site n'est pas protégé."
6822
 
6823
- #: lib/utils.php:830
6824
  msgid "Alert: WordPress console login"
6825
  msgstr "Alerte : Connexion à WordPress"
6826
 
6827
- #: lib/utils.php:836
6828
  msgid "Someone just logged in to your WordPress admin console:"
6829
  msgstr "Quelqu'un vient de se connecter à votre Tableau de bord de WordPress:"
6830
 
6831
- #: lib/utils.php:948 lib/utils.php:975
6832
  msgid "Forbidden access"
6833
  msgstr "Accès interdit"
6834
 
6835
- #: lib/utils.php:994
6836
  #, php-format
6837
  msgid ""
6838
  "<strong>ERROR</strong>: Invalid username, email address or password.<br /><a "
@@ -6841,11 +6886,11 @@ msgstr ""
6841
  "<strong>ERREUR</strong>: Identifiant, email ou mot de passe invalide.<br /"
6842
  "><a href=\"%s\">Mot de passe perdu</a> ?"
6843
 
6844
- #: lib/utils.php:1078
6845
  msgid "[NinjaFirewall] Alert: Database changes detected"
6846
  msgstr "[NinjaFirewall] Alerte: Modification dans la base de données"
6847
 
6848
- #: lib/utils.php:1079
6849
  msgid ""
6850
  "NinjaFirewall has detected that one or more administrator accounts were "
6851
  "modified in the database:"
@@ -6853,12 +6898,12 @@ msgstr ""
6853
  "NinjaFirewall a détecté que un ou plusieurs comptes d'administrateur ont été "
6854
  "modifiés dans la base de données:"
6855
 
6856
- #: lib/utils.php:1084
6857
  #, php-format
6858
  msgid "Total administrators : %s"
6859
  msgstr "Nombre d'administrateurs : %s"
6860
 
6861
- #: lib/utils.php:1093
6862
  msgid ""
6863
  "If you cannot see any modifications in the above fields, it is possible that "
6864
  "the administrator password was changed."
@@ -6866,11 +6911,11 @@ msgstr ""
6866
  "Si vous ne voyez pas de modifications dans les données ci-dessus, il est "
6867
  "possible que le mot de passe administrateur ait été changé."
6868
 
6869
- #: lib/utils.php:1246
6870
  msgid "Blocked privilege escalation attempt"
6871
  msgstr "Tentatives d'élévation des privilèges"
6872
 
6873
- #: lib/utils.php:1259
6874
  msgid ""
6875
  "NinjaFirewall has blocked an attempt to modify a user capability by someone "
6876
  "who does not have administrative privileges:"
@@ -6878,7 +6923,7 @@ msgstr ""
6878
  "NinjaFirewall a bloqué une tentative de modification de certaines Capacités "
6879
  "par un utilisateur ne disposant pas de privilèges administratifs :"
6880
 
6881
- #: lib/utils.php:1312
6882
  msgid ""
6883
  "NinjaFirewall brute-force protection is enabled and you are temporarily "
6884
  "whitelisted."
@@ -6886,7 +6931,7 @@ msgstr ""
6886
  "La protection de NinjaFirewall contre les attaques par force brute est "
6887
  "activée. Vous êtes temporairement dans la liste blanche."
6888
 
6889
- #: lib/utils.php:1327
6890
  #, php-format
6891
  msgid ""
6892
  "Hey, it seems that you've been using NinjaFirewall for some time. If you "
@@ -6899,17 +6944,17 @@ msgstr ""
6899
  "a>. Il a fallu des milliers d'heures pour le développer, mais il suffit "
6900
  "seulement de quelques minutes pour le noter. Merci !"
6901
 
6902
- #: lib/utils.php:1508
6903
  msgid ""
6904
  "The attempt was blocked and the option was reversed to its original value."
6905
  msgstr ""
6906
  "La tentative a été bloquée et l'option a été remise à sa valeur d'origine."
6907
 
6908
- #: lib/utils.php:1513
6909
  msgid "Attempt to modify WordPress settings"
6910
  msgstr "Tentative de modification des paramètres de WordPress"
6911
 
6912
- #: lib/utils.php:1514
6913
  msgid ""
6914
  "NinjaFirewall has blocked an attempt to modify some important WordPress "
6915
  "settings by a user that does not have administrative privileges:"
@@ -6918,31 +6963,31 @@ msgstr ""
6918
  "importants de WordPress par un utilisateur ne disposant pas de privilèges "
6919
  "administratifs :"
6920
 
6921
- #: lib/utils.php:1515 lib/utils.php:1524
6922
  #, php-format
6923
  msgid "Option: %s"
6924
  msgstr "Option: %s"
6925
 
6926
- #: lib/utils.php:1516
6927
  #, php-format
6928
  msgid "Original value: %s"
6929
  msgstr "Valeur originale : %s"
6930
 
6931
- #: lib/utils.php:1517
6932
  #, php-format
6933
  msgid "Modified value: %s"
6934
  msgstr "Valeur modifiée : %s"
6935
 
6936
- #: lib/utils.php:1518 lib/utils.php:1526
6937
  #, php-format
6938
  msgid "Action taken: %s"
6939
  msgstr "Action prise : %s"
6940
 
6941
- #: lib/utils.php:1522
6942
  msgid "Code injection attempt in WordPress options table"
6943
  msgstr "Tentative d'injection de code dans la table des options de WordPress"
6944
 
6945
- #: lib/utils.php:1523
6946
  msgid ""
6947
  "NinjaFirewall has blocked an attempt to inject code in the WordPress options "
6948
  "table by a user that does not have administrative privileges:"
@@ -6951,26 +6996,35 @@ msgstr ""
6951
  "options de WordPress par un utilisateur ne disposant pas de privilèges "
6952
  "administratifs :"
6953
 
6954
- #: lib/utils.php:1525
6955
  #, php-format
6956
  msgid "Code: %s"
6957
  msgstr "Code : %s"
6958
 
6959
- #: lib/utils.php:1576
 
 
 
 
 
 
 
 
 
6960
  #, php-format
6961
  msgid "Error, cannot create the %s folder."
6962
  msgstr "Erreur, impossible de créer le répertoire %s."
6963
 
6964
- #: lib/utils.php:1576 lib/utils.php:1584 lib/utils.php:1592
6965
  msgid "Check your server permissions and try again."
6966
  msgstr "Vérifiez les autorisations de votre serveur et réessayez."
6967
 
6968
- #: lib/utils.php:1584
6969
  #, php-format
6970
  msgid "Error, the %s folder is not writable."
6971
  msgstr "Erreur, le répertoire %s est en lecture seule."
6972
 
6973
- #: lib/utils.php:1592
6974
  #, php-format
6975
  msgid "Error, cannot write %s."
6976
  msgstr "Erreur, impossible d'écrire dans %s."
@@ -7539,7 +7593,7 @@ msgstr "Vous n’êtes pas autorisé à activer NinjaFirewall."
7539
  msgid "NinjaFirewall is not compatible with Microsoft Windows."
7540
  msgstr "NinjaFirewall n'est pas compatible avec Microsoft Windows."
7541
 
7542
- #: ninjafirewall.php:322
7543
  msgid ""
7544
  "All fields will be restored to their default values and any changes you made "
7545
  "will be lost. Continue?"
@@ -7547,19 +7601,19 @@ msgstr ""
7547
  "Tous les champs vont être re-initialisés et vos changements seront perdus. "
7548
  "Continuer ?"
7549
 
7550
- #: ninjafirewall.php:326
7551
  msgid "Missing security nonce, try to reload the page."
7552
  msgstr "La nonce de sécurité est manquante, essayer de recharger cette page."
7553
 
7554
- #: ninjafirewall.php:328
7555
  msgid "Please select the HTTP server in the list."
7556
  msgstr "Sélectionnez votre serveur HTTP dans la list."
7557
 
7558
- #: ninjafirewall.php:331
7559
  msgid "Delete the firewall's error log ?"
7560
  msgstr "Supprimer le journal des erreurs ?"
7561
 
7562
- #: ninjafirewall.php:335
7563
  msgid ""
7564
  "This action will restore the selected configuration file and will override "
7565
  "all your current firewall options, policies and rules. Continue?"
@@ -7568,7 +7622,7 @@ msgstr ""
7568
  "remplacera toutes les options, politiques et règles de pare-feu actuelles. "
7569
  "Continuer ?"
7570
 
7571
- #: ninjafirewall.php:339
7572
  msgid ""
7573
  "Any character that is not a letter [a-zA-Z], a digit [0-9], a dot [.], a "
7574
  "hyphen [-] or an underscore [_] will be removed from the filename and "
@@ -7578,7 +7632,7 @@ msgstr ""
7578
  "[.], un trait d'union[-] ou un caractère de soulignement[_], sera supprimé "
7579
  "du nom du fichier et remplacé par le caractère de substitution. Continuer ?"
7580
 
7581
- #: ninjafirewall.php:341
7582
  msgid ""
7583
  "Ensure that you can access your admin console over HTTPS before enabling "
7584
  "this option, otherwise you will lock yourself out of your site. Continue?"
@@ -7587,7 +7641,7 @@ msgstr ""
7587
  "option, sinon vous risqueriez de ne plus pouvoir accéder à l'interface "
7588
  "d'administration. Continuer ?"
7589
 
7590
- #: ninjafirewall.php:343
7591
  msgid ""
7592
  "WooCommerce is running: if you block accounts creation, your customers won't "
7593
  "be able to sign up. Continue?"
@@ -7595,7 +7649,7 @@ msgstr ""
7595
  "WooCommerce est activé : si vous bloquez la création de comptes, vos clients "
7596
  "ne pourront pas s'enregistrer. Continuer ?"
7597
 
7598
- #: ninjafirewall.php:345
7599
  msgid ""
7600
  "Your blog has user registration enabled: if you block accounts creation, "
7601
  "your customers won't be able to sign up. Continue?"
@@ -7603,7 +7657,7 @@ msgstr ""
7603
  "Votre blog accepte les inscriptions : si vous bloquez la création de "
7604
  "comptes, vos clients ne pourront plus s'inscrire. Continuer ?"
7605
 
7606
- #: ninjafirewall.php:347
7607
  msgid ""
7608
  "Your multisite installation allows users to register new sites: if you "
7609
  "enable this option, they will likely get blocked when creating their blog. "
@@ -7612,143 +7666,283 @@ msgstr ""
7612
  "Les utilisateurs sont autorisés a créer des nouveaux sites : si vous activez "
7613
  "cette option, ils ne pourront plus le faire. Continuer ?"
7614
 
7615
- #: ninjafirewall.php:351
7616
  msgid "Delete the current snapshot ?"
7617
  msgstr "Supprimer l'instantané actuel ?"
7618
 
7619
- #: ninjafirewall.php:355
7620
  msgid "Invalid character."
7621
  msgstr "Caractère invalide."
7622
 
7623
- #: ninjafirewall.php:357
7624
  msgid "\"admin\" is not acceptable, please choose another user name."
7625
  msgstr ""
7626
  "\"admin\" n\\'est pas acceptable, merci de bien vouloir choisir un autre "
7627
  "identifiant."
7628
 
7629
- #: ninjafirewall.php:359
7630
  msgid "Please enter max 1024 character only."
7631
  msgstr "Veuillez ne pas entrer plus de 1 024 caractères."
7632
 
7633
- #: ninjafirewall.php:361
7634
  msgid "Select when to enable the login protection."
7635
  msgstr "Veuillez sélectionner quand activer la protection."
7636
 
7637
- #: ninjafirewall.php:363
7638
  msgid "Enter a name and a password for the HTTP authentication."
7639
  msgstr ""
7640
  "Veuillez entrer un nom d'utilisateur et mot de passe pour l'authentification "
7641
  "HTTP."
7642
 
7643
- #: ninjafirewall.php:367
7644
  msgid "Your public key is not valid."
7645
  msgstr "Votre clé publique n\\'est pas valide."
7646
 
7647
- #: ninjafirewall.php:373
7648
  msgid "No traffic yet, please wait"
7649
  msgstr "Aucun visiteur actuellement, veuillez patienter"
7650
 
7651
- #: ninjafirewall.php:375
7652
  msgid "seconds..."
7653
  msgstr "secondes..."
7654
 
7655
- #: ninjafirewall.php:377
7656
  msgid "Error: Live Log did not receive the expected response from your server:"
7657
  msgstr "Erreur : le serveur distant n\\'a pas retourné la réponse attendue :"
7658
 
7659
- #: ninjafirewall.php:379
7660
  msgid "Error: URL does not seem to exist (404 Not Found):"
7661
  msgstr "Erreur : l'URL ne semble pas exister (404 Not Found) :"
7662
 
7663
- #: ninjafirewall.php:381
7664
  msgid "Error: Cannot find your log file. Try to reload this page."
7665
  msgstr ""
7666
  "Erreur : Impossible de trouver le fichier log. Essayez de recharger cette "
7667
  "page."
7668
 
7669
- #: ninjafirewall.php:383
7670
  msgid "Error: The HTTP server returned the following error code:"
7671
  msgstr "Erreur : Le serveur HTTP a retourné le code d'erreur suivant :"
7672
 
7673
- #: ninjafirewall.php:634 ninjafirewall.php:751
7674
  msgid "Error: Security nonces do not match. Reload the page and try again."
7675
  msgstr ""
7676
  "Erreur : Les nonces de sécurité ne correspondent pas. Veuillez recharger "
7677
  "cette page."
7678
 
7679
- #: ninjafirewall.php:640
7680
  msgid "Error: NinjaFirewall is disabled"
7681
  msgstr "Erreur : NinjaFirewall est désactivé"
7682
 
7683
- #: ninjafirewall.php:645
7684
  #, php-format
7685
  msgid "Error: missing parameter (%s)."
7686
  msgstr "Erreur : Paramètre manquant (%s)."
7687
 
7688
- #: ninjafirewall.php:813
7689
  msgid "NinjaFirewall: Dashboard"
7690
  msgstr "NinjaFirewall : Tableau de Bord"
7691
 
7692
- #: ninjafirewall.php:817
7693
  msgid "NinjaFirewall: Firewall Options"
7694
  msgstr "NinjaFirewall : Options du Pare-feu"
7695
 
7696
- #: ninjafirewall.php:821
7697
  msgid "NinjaFirewall: Firewall Policies"
7698
  msgstr "NinjaFirewall : Politiques du Pare-feu"
7699
 
7700
- #: ninjafirewall.php:825
7701
  msgid "NinjaFirewall: Monitoring"
7702
  msgstr "NinjaFirewall : Monitoring"
7703
 
7704
- #: ninjafirewall.php:835
7705
  msgid "NinjaFirewall: Anti-Malware"
7706
  msgstr "NinjaFirewall : Anti-Malware"
7707
 
7708
- #: ninjafirewall.php:839
7709
  msgid "NinjaFirewall: Network"
7710
  msgstr "NinjaFirewall : Réseau"
7711
 
7712
- #: ninjafirewall.php:843
7713
  msgid "NinjaFirewall: Event Notifications"
7714
  msgstr "NinjaFirewall : Notifications d’Événement"
7715
 
7716
- #: ninjafirewall.php:847
7717
  msgid "NinjaFirewall: Log-in Protection"
7718
  msgstr "NinjaFirewall : Page de Connexion"
7719
 
7720
- #: ninjafirewall.php:851
7721
  msgid "NinjaFirewall: Logs"
7722
  msgstr "NinjaFirewall : Journaux"
7723
 
7724
- #: ninjafirewall.php:855
7725
  msgid "NinjaFirewall: Security Rules"
7726
  msgstr "NinjaFirewall : Règles de Sécurité"
7727
 
7728
- #: ninjafirewall.php:899
7729
  msgid "NinjaFirewall Settings"
7730
  msgstr "Réglages de NinjaFirewall"
7731
 
7732
- #: ninjafirewall.php:907
7733
  msgid "NinjaFirewall is enabled"
7734
  msgstr "NinjaFirewall est activé"
7735
 
7736
- #: ninjafirewall.php:1047
7737
  msgid "Access Restricted"
7738
  msgstr "Accès limité"
7739
 
7740
- #: ninjafirewall.php:1053
7741
  msgid "Settings"
7742
  msgstr "Réglages"
7743
 
7744
- #: ninjafirewall.php:1054
7745
  msgid "Upgrade to Premium"
7746
  msgstr "Passez Premium !"
7747
 
7748
- #: ninjafirewall.php:1055
7749
  msgid "Rate it!"
7750
  msgstr "Notez-le !"
7751
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7752
  #~ msgid ""
7753
  #~ "You can allow/disallow uploads, or allow uploads but block scripts (PHP, "
7754
  #~ "CGI, Ruby, Python, bash/shell), C/C++ source code, binaries (MZ/PE/NE and "
@@ -7846,16 +8040,6 @@ msgstr "Notez-le !"
7846
  #~ "NinjaFirewall nécessite au moins WordPress 3.3 mais votre version de "
7847
  #~ "WordPress est %s."
7848
 
7849
- #~ msgid ""
7850
- #~ "Log in to your Openlitespeed admin dashboard, click on \"Virtual Host\", "
7851
- #~ "select your domain, add the following instructions to the \"php.ini "
7852
- #~ "Override\" section in the \"General\" tab, and restart Openlitespeed:"
7853
- #~ msgstr ""
7854
- #~ "Connectez-vous à votre tableau de bord Openlitespeed, cliquez sur "
7855
- #~ "\"Virtual Host\", sélectionnez votre domaine, ajoutez les instructions "
7856
- #~ "suivantes à la section \"php.ini Override\" de l'onglet \"Général\", puis "
7857
- #~ "redémarrez Openlitespeed:"
7858
-
7859
  #~ msgid ""
7860
  #~ "Even if NinjaFirewall administration menu is only available to the Super "
7861
  #~ "Admin (from the main site), you can still display its status to all sites "
@@ -8839,12 +9023,6 @@ msgstr "Notez-le !"
8839
  #~ "les fichiers .htaccess. Ou peut-être devez-vous redémarrer votre serveur "
8840
  #~ "HTTP pour appliquer les changements ?"
8841
 
8842
- #~ msgid ""
8843
- #~ "The imported file is not compatible with that version of NinjaFirewall"
8844
- #~ msgstr ""
8845
- #~ "Le fichier importé n'est pas compatible avec cette version de "
8846
- #~ "NinjaFirewall"
8847
-
8848
  #~ msgid "Disable the fatal error handler <code>WP_Fatal_Error_Handler</code>:"
8849
  #~ msgstr ""
8850
  #~ "Désactiver le gestionnaire d'erreurs fatales "
@@ -9146,9 +9324,6 @@ msgstr "Notez-le !"
9146
  #~ "Il peut fonctionner en deux modes différents : <b>Full WAF</b> ou "
9147
  #~ "<b>WordPress WAF</b>."
9148
 
9149
- #~ msgid "Full WAF mode"
9150
- #~ msgstr "Mode Full WAF"
9151
-
9152
  #~ msgid ""
9153
  #~ "In <b>Full WAF</b> mode, NinjaFirewall will hook, scan, reject or "
9154
  #~ "sanitise any HTTP and HTTPS request sent to a PHP script before it "
@@ -9193,9 +9368,6 @@ msgstr "Notez-le !"
9193
  #~ "cas, principalement en raison de certaines restrictions d'hébergement "
9194
  #~ "partagé, il se peut que l'installation ne puisse pas fonctionner du tout."
9195
 
9196
- #~ msgid "WordPress WAF mode"
9197
- #~ msgstr "Mode WordPress WAF"
9198
-
9199
  #~ msgid ""
9200
  #~ "The <b>WordPress WAF</b> mode requires to load NinjaFirewall via the "
9201
  #~ "WordPress wp-config.php script. This process makes it easy to setup and "
4
  msgstr ""
5
  "Project-Id-Version: Stable (latest release)\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/ninjafirewall\n"
7
+ "POT-Creation-Date: 2021-07-25 16:01+0700\n"
8
+ "PO-Revision-Date: 2021-07-25 16:03+0700\n"
9
  "Last-Translator: NinTechNet <contact@nintechnet.com>\n"
10
  "Language-Team: NinTechNet <nintechnet.com>\n"
11
  "Language: fr_FR\n"
16
  "X-Poedit-SourceCharset: UTF-8\n"
17
  "Plural-Forms: nplurals=2; plural=(n > 1);\n"
18
 
19
+ #: lib/anti_malware.php:24 ninjafirewall.php:916
20
  msgid "Anti-Malware"
21
  msgstr "Anti-Malware"
22
 
29
  "la place, nous avons maintenant un tout nouveau plugin antivirus :"
30
 
31
  #: lib/anti_malware.php:29
32
+ msgid "It is awesome and includes many great features:"
33
+ msgstr "Il est beaucoup mieux et comprend de nombreuses fonctionnalités :"
34
+
35
+ #: lib/anti_malware.php:29
36
+ msgid "check it out!"
37
+ msgstr "En savoir plus"
 
38
 
39
  #: lib/anti_malware.php:30
40
  msgid "Download it from wordpress.org!"
104
  msgid "NinjaFirewall (WP Edition)"
105
  msgstr "NinjaFirewall (WP Edition)"
106
 
107
+ #: lib/dashboard.php:127 lib/event_notifications.php:42
108
+ #: lib/firewall_options.php:42 lib/firewall_policies.php:71
109
+ #: lib/login_protection.php:30 lib/logs_firewall_log.php:59
110
+ #: lib/logs_live_log.php:79 lib/monitoring_file_check.php:111
111
+ #: lib/monitoring_file_guard.php:46 lib/network.php:52
112
+ #: lib/security_rules_update.php:101
113
+ msgid "Your changes have been saved."
114
+ msgstr "Les modifications ont été enregistrées."
115
+
116
+ #: lib/dashboard.php:132 ninjafirewall.php:894
117
  msgid "Dashboard"
118
  msgstr "Tableau de Bord"
119
 
120
+ #: lib/dashboard.php:133
121
  msgid "Statistics"
122
  msgstr "Statistiques"
123
 
124
+ #: lib/dashboard.php:134 lib/help.php:53
125
  msgid "About..."
126
  msgstr "À Propos..."
127
 
128
+ #: lib/dashboard.php:146
129
  msgid "Thank you for using NinjaFirewall."
130
  msgstr "Merci d'utiliser NinjaFirewall."
131
 
132
+ #: lib/dashboard.php:147
133
  #, php-format
134
  msgid ""
135
  "Every page of NinjaFirewall has a contextual help: whenever you need help "
140
  "besoin d'aide au sujet d'une option ou d'un menu, cliquez sur l'onglet %s "
141
  "situé en haut à droite de la page correspondante."
142
 
143
+ #: lib/dashboard.php:147
144
  msgid "Help"
145
  msgstr "Aide"
146
 
147
+ #: lib/dashboard.php:149
148
  msgid "Got it!"
149
  msgstr "J'ai compris !"
150
 
151
+ #: lib/dashboard.php:165 lib/help.php:36
152
  msgid "Firewall Dashboard"
153
  msgstr "Tableau de Bord du Pare-feu"
154
 
155
+ #: lib/dashboard.php:174
156
  msgid ""
157
  "It seems that you may have another instance of NinjaFirewall running in a "
158
  "parent directory. Make sure to follow these instructions:"
160
  "Il semble qu'une autre instance de NinjaFirewall est installée dans un "
161
  "répertoire parent. Assurez-vous de suivre ces instructions:"
162
 
163
+ #: lib/dashboard.php:176
164
  msgid ""
165
  "Temporarily disable the firewall in the parent folder by renaming its PHP "
166
  "INI or .htaccess file."
168
  "Désactivez temporairement le pare-feu dans le répertoire parent en renommant "
169
  "son fichier PHP INI ou .htaccess."
170
 
171
+ #: lib/dashboard.php:178
172
  msgid "Install NinjaFirewall on this site in Full WAF mode."
173
  msgstr "Installez NinjaFirewall sur ce site, en mode Full WAF."
174
 
175
+ #: lib/dashboard.php:180
176
  msgid ""
177
  "Restore the PHP INI or .htaccess in the parent folder to re-enable the "
178
  "firewall."
180
  "Restaurez le fichier PHP INI ou .htaccess dans le dossier parent pour "
181
  "réactiver le pare-feu."
182
 
183
+ #: lib/dashboard.php:186
184
  msgid "Unknown error"
185
  msgstr "Erreur inconnue"
186
 
187
+ #: lib/dashboard.php:190 lib/dashboard.php:198
188
  msgid "Firewall"
189
  msgstr "Pare-feu"
190
 
191
+ #: lib/dashboard.php:199 lib/dashboard.php:337 lib/firewall_options.php:64
192
  #: lib/login_protection.php:203 lib/logs_live_log.php:99
193
  #: lib/monitoring_file_guard.php:70 lib/security_rules_update.php:138
194
  msgid "Enabled"
195
  msgstr "Activé"
196
 
197
+ #: lib/dashboard.php:206
198
  msgid "Mode"
199
  msgstr "Mode"
200
 
201
+ #: lib/dashboard.php:210
202
  #, php-format
203
  msgid ""
204
  "NinjaFirewall is running in %s mode. For better protection, activate its "
207
  "NinjaFirewall fonctionne en mode %s. Pour une meilleure protection, activez "
208
  "son mode Full WAF :"
209
 
210
+ #: lib/dashboard.php:212 lib/thickbox.php:74
 
 
 
 
211
  msgid "Activate Full WAF mode"
212
  msgstr "Activer le mode Full WAF"
213
 
214
+ #: lib/dashboard.php:216
215
  #, php-format
216
  msgid "NinjaFirewall is running in %s mode."
217
  msgstr "NinjaFirewall fonctionne en mode %s."
218
 
219
+ #: lib/dashboard.php:218
220
+ msgid "Configure"
221
+ msgstr "Configurer"
222
 
223
+ #: lib/dashboard.php:232 lib/firewall_options.php:76 lib/help.php:77
224
  msgid "Debugging mode"
225
  msgstr "Mode débogage"
226
 
227
+ #: lib/dashboard.php:233
228
  msgid "Enabled."
229
  msgstr "Activé."
230
 
231
+ #: lib/dashboard.php:233
232
  msgid "Click here to turn Debugging Mode off"
233
  msgstr "Cliquez ici pour désactiver le mode Débogage"
234
 
235
+ #: lib/dashboard.php:239
236
  msgid "Edition"
237
  msgstr "Édition"
238
 
239
+ #: lib/dashboard.php:240
240
  msgid ""
241
  "Need more security? Explore our supercharged premium version: NinjaFirewall "
242
  "(WP+ Edition)"
244
  "Besoin de plus de sécurité ? Prenez le temps d'explorer notre version "
245
  "premium musclée : NinjaFirewall (WP+ Edition)"
246
 
247
+ #: lib/dashboard.php:243
248
  msgid "Version"
249
  msgstr "Version"
250
 
251
+ #: lib/dashboard.php:244
252
  msgid "Security rules:"
253
  msgstr "Règles de sécurité&nbsp;:"
254
 
255
+ #: lib/dashboard.php:248
256
  msgid "PHP SAPI"
257
  msgstr "PHP SAPI"
258
 
259
+ #: lib/dashboard.php:266
260
  msgid "Updates"
261
  msgstr "Mises à Jour"
262
 
263
+ #: lib/dashboard.php:267
264
  msgid "Security rules updates are disabled."
265
  msgstr "La mise à jour automatique des règles de sécurité est désactivée."
266
 
267
+ #: lib/dashboard.php:267
268
  msgid ""
269
  "If you want your blog to be protected against the latest threats, enable "
270
  "automatic security rules updates."
272
  "Pour garder votre WordPress protégé contre les dernières vulnérabilités, "
273
  "pensez à l'activer."
274
 
275
+ #: lib/dashboard.php:275 lib/dashboard.php:283
276
  msgid "Admin user"
277
  msgstr "Administrateur"
278
 
279
+ #: lib/dashboard.php:276
280
  #, php-format
281
  msgid ""
282
  "You are not whitelisted. Ensure that the \"Do not block WordPress "
289
  "\"%s\">Politiques du Pare-feu</a>, sinon vous pourriez être bloqué par le "
290
  "pare-feu lorsque vous travaillez depuis votre Tableau de bord."
291
 
292
+ #: lib/dashboard.php:284
293
  msgid "You are whitelisted by the firewall."
294
  msgstr "Vous êtes dans la liste blanche du pare-feu."
295
 
296
+ #: lib/dashboard.php:291
297
  msgid "Restrictions"
298
  msgstr "Restrictions"
299
 
300
+ #: lib/dashboard.php:292
301
  msgid "Access to NinjaFirewall is restricted to specific users."
302
  msgstr "L'accès à NinjaFirewall est restreint à certains utilisateurs."
303
 
304
+ #: lib/dashboard.php:303
305
  msgid "User session"
306
  msgstr "Session utilisateur"
307
 
308
+ #: lib/dashboard.php:304
309
  msgid ""
310
  "It seems that the user session set by NinjaFirewall was not found by the "
311
  "firewall script."
313
  "Il semble que la session d'utilisateur définie par NinjaFirewall n'a pas été "
314
  "trouvé par le script du pare-feu."
315
 
316
+ #: lib/dashboard.php:312
317
  #, php-format
318
  msgid ""
319
  "the public key is invalid. Please <a href=\"%s\">check your configuration</"
322
  "la clé publique est invalide. Veuillez vérifier <a href=\"%s\">votre "
323
  "configuration</a>."
324
 
325
+ #: lib/dashboard.php:316
326
  msgid "No IP address restriction."
327
  msgstr "Aucune restriction d'accès par adresse IP."
328
 
329
+ #: lib/dashboard.php:319
330
  #, php-format
331
  msgid "IP address %s is allowed to access NinjaFirewall's log on this server."
332
  msgstr ""
333
  "L'adresse IP %s est autorisée à accéder au journal du pare-feu de "
334
  "NinjaFirewall."
335
 
336
+ #: lib/dashboard.php:322
337
  #, php-format
338
  msgid ""
339
  "the whitelisted IP is not valid. Please <a href=\"%s\">check your "
342
  "l'adresse IP est invalide. Veuillez vérifier <a href=\"%s\">votre "
343
  "configuration</a>."
344
 
345
+ #: lib/dashboard.php:327 lib/help.php:467 lib/logs_firewall_log.php:193
346
  #: lib/wpplus.php:170
347
  msgid "Centralized Logging"
348
  msgstr "Centralisation des Logs"
349
 
350
+ #: lib/dashboard.php:331 lib/security_rules_update.php:434
351
  #, php-format
352
  msgid "Error: %s"
353
  msgstr "Erreur : %s"
354
 
355
+ #: lib/dashboard.php:346
356
  msgid "Source IP"
357
  msgstr "IP source"
358
 
359
+ #: lib/dashboard.php:347
360
  #, php-format
361
  msgid "You have a private IP : %s"
362
  msgstr "Vous avez l'adresse IP d'un réseau privé : %s"
363
 
364
+ #: lib/dashboard.php:347
365
  #, php-format
366
  msgid ""
367
  "If your site is behind a reverse proxy or a load balancer, ensure that you "
373
  "la bonne adresse IP, sinon utilisez le fichier de configuration %s de "
374
  "NinjaFirewall."
375
 
376
+ #: lib/dashboard.php:355 lib/dashboard.php:365
377
  msgid "CDN detection"
378
  msgstr "Détection CDN"
379
 
380
+ #: lib/dashboard.php:356
381
  #, php-format
382
  msgid ""
383
  "%s detected: you seem to be using Cloudflare CDN services. Ensure that you "
388
  "vous d'avoir configuré votre serveur HTTP afin qu'il fasse suivre la bonne "
389
  "adresse IP, sinon utilisez le fichier de configuration %s de NinjaFirewall."
390
 
391
+ #: lib/dashboard.php:366
392
  #, php-format
393
  msgid ""
394
  "%s detected: you seem to be using Incapsula CDN services. Ensure that you "
399
  "vous d'avoir configuré votre serveur HTTP afin qu'il fasse suivre la bonne "
400
  "adresse IP, sinon utilisez le fichier de configuration %s de NinjaFirewall."
401
 
402
+ #: lib/dashboard.php:375 lib/dashboard.php:384
403
  msgid "Log dir"
404
  msgstr "Répertoire du Journal"
405
 
406
+ #: lib/dashboard.php:376 lib/dashboard.php:385
407
  #, php-format
408
  msgid "%s directory is not writable! Please chmod it to 0777 or equivalent."
409
  msgstr ""
410
  "Le répertoire %s est en lecture seule ! Veuillez changer ses permissions "
411
  "(0777 ou équivalent)."
412
 
413
+ #: lib/dashboard.php:403
414
+ #, php-format
415
+ msgid "The php.ini file is readable by web users: %s"
416
+ msgstr "Le fichier php.ini est lisible par tout le monde : %s"
417
+
418
+ #: lib/dashboard.php:403 lib/dashboard.php:415 lib/event_notifications.php:122
419
+ #: lib/event_notifications.php:189
420
+ msgid "Consult our blog for more info."
421
+ msgstr "Consultez notre blog pour plus d'informations à ce sujet."
422
+
423
+ #: lib/dashboard.php:415
424
+ #, php-format
425
+ msgid "The .user.ini file is readable by web users: %s"
426
+ msgstr "Le fichier .user.ini est lisible par tout le monde : %s"
427
+
428
+ #: lib/dashboard.php:431
429
  msgid "Error log"
430
  msgstr "Journal des erreurs"
431
 
432
+ #: lib/dashboard.php:432
433
  msgid "View error log"
434
  msgstr "Voir le journal des erreurs"
435
 
436
+ #: lib/dashboard.php:441
437
  msgid "Optional configuration file"
438
  msgstr "Fichier de configuration"
439
 
440
+ #: lib/dashboard.php:448
441
  msgid "MySQLi link identifier"
442
  msgstr "Identifiant de lien MySQLi"
443
 
444
+ #: lib/dashboard.php:449
445
  msgid "A MySQLi link identifier was detected in your <code>.htninja</code>."
446
  msgstr ""
447
  "Un identifiant de lien MySQLi a été détecté dans votre fichier <code>."
448
  "htninja</code>."
449
 
450
+ #: lib/dashboard.php:455
451
  msgid "Help &amp; configuration"
452
  msgstr "Aide &amp; configuration"
453
 
487
  msgid "Select a month"
488
  msgstr "Sélectionnez le mois"
489
 
490
+ #: lib/dashboard_statistics.php:98 lib/dashboard_statistics.php:135
491
  #: lib/widget.php:66
492
  msgid "Blocked threats"
493
  msgstr "Menaces bloquées"
517
  msgid "Slowest request"
518
  msgstr "Requête la plus lente"
519
 
520
+ #: lib/dashboard_statistics.php:130 lib/i18n-extra.php:271
521
  msgid "Critical"
522
  msgstr "Critique"
523
 
524
+ #: lib/dashboard_statistics.php:131 lib/i18n-extra.php:127
525
  msgid "High"
526
  msgstr "Élevé"
527
 
528
+ #: lib/dashboard_statistics.php:132 lib/i18n-extra.php:126
529
  msgid "Medium"
530
  msgstr "Moyen"
531
 
532
+ #: lib/dashboard_statistics.php:181
533
  msgid "Select monthly stats to view..."
534
  msgstr "Sélectionnez les statistiques à afficher..."
535
 
536
+ #: lib/event_notifications.php:34 lib/help.php:377 ninjafirewall.php:924
537
  msgid "Event Notifications"
538
  msgstr "Notifications d'Événement"
539
 
 
 
 
 
 
 
 
 
540
  #: lib/event_notifications.php:52
541
  msgid "WordPress admin dashboard"
542
  msgstr "Connexion"
543
 
544
  #: lib/event_notifications.php:55 lib/event_notifications.php:119
545
+ #: lib/event_notifications.php:140
546
  msgid "Send me an alert whenever"
547
  msgstr "Envoyer une alerte quand"
548
 
635
  "Une importante mise à jour de sécurité est disponible pour une extension, un "
636
  "thème ou WordPress (défaut)"
637
 
638
+ #: lib/event_notifications.php:137
639
  msgid "Administrator account"
640
  msgstr "Compte administrateur"
641
 
642
+ #: lib/event_notifications.php:142
643
  msgid ""
644
  "An administrator account is created, modified or deleted in the database "
645
  "(default)"
647
  "Un compte Administrateur est crée, modifié ou supprimé dans la base de "
648
  "données (défaut)"
649
 
650
+ #: lib/event_notifications.php:149
651
  msgid "Daily report"
652
  msgstr "Rapport quotidien"
653
 
654
+ #: lib/event_notifications.php:152
655
  msgid "Send me a daily activity report"
656
  msgstr "Envoyer un rapport d'activité quotidien"
657
 
658
+ #: lib/event_notifications.php:154 lib/event_notifications.php:166
659
  #: lib/firewall_options.php:78 lib/firewall_options.php:113
660
  #: lib/firewall_policies.php:25 lib/login_protection.php:309
661
  #: lib/login_protection.php:324 lib/login_protection.php:345
663
  msgid "Yes"
664
  msgstr "Oui"
665
 
666
+ #: lib/event_notifications.php:154 lib/event_notifications.php:166
667
  #: lib/firewall_options.php:78 lib/firewall_options.php:113
668
  #: lib/firewall_policies.php:26 lib/login_protection.php:309
669
  #: lib/login_protection.php:324 lib/login_protection.php:345
671
  msgid "No"
672
  msgstr "Non"
673
 
674
+ #: lib/event_notifications.php:161
675
  msgid "Log"
676
  msgstr "Journal"
677
 
678
+ #: lib/event_notifications.php:164
679
  msgid "Write all events to the firewall log"
680
  msgstr "Enregistrer les événements dans le journal du pare-feu"
681
 
682
+ #: lib/event_notifications.php:178
683
  msgid "PHP backtrace"
684
  msgstr "Pile d'exécution de PHP"
685
 
686
+ #: lib/event_notifications.php:181
687
  msgid "Attach a PHP backtrace to important notifications"
688
  msgstr ""
689
  "Ajouter aux notifications importantes la pile d'exécution de PHP en pièce "
690
  "jointe"
691
 
692
+ #: lib/event_notifications.php:184
693
  msgid "Disable backtrace"
694
  msgstr "Désactiver la pile d'exécution"
695
 
696
+ #: lib/event_notifications.php:185
697
  msgid "Low verbosity"
698
  msgstr "Faible verbosité"
699
 
700
+ #: lib/event_notifications.php:186
701
  msgid "Medium verbosity (default)"
702
  msgstr "Verbosité moyenne (par défaut)"
703
 
704
+ #: lib/event_notifications.php:187
705
  msgid "High verbosity"
706
  msgstr "Verbosité élevée"
707
 
708
+ #: lib/event_notifications.php:199 lib/event_notifications.php:229
 
 
 
 
 
 
709
  msgid "Contact email"
710
  msgstr "Adresse e-mail du contact"
711
 
712
+ #: lib/event_notifications.php:202 lib/event_notifications.php:232
713
  msgid "Alerts should be sent to"
714
  msgstr "Envoyer les alertes à"
715
 
716
+ #: lib/event_notifications.php:211 lib/event_notifications.php:237
717
  msgid ""
718
  "Multiple recipients must be comma-separated (e.g., <code>joe@example.org,"
719
  "alice@example.org</code>)."
721
  "Plusieurs destinataires doivent être séparés par des virgules (par ex. "
722
  "<code>joe@example.org,alice@example.org</code>)."
723
 
724
+ #: lib/event_notifications.php:234
725
  msgid "Only to me, the Super Admin"
726
  msgstr "Moi uniquement, le Super Admin"
727
 
728
+ #: lib/event_notifications.php:234
729
  msgid "default"
730
  msgstr "défaut"
731
 
732
+ #: lib/event_notifications.php:235
733
  msgid "To the administrator of the site where originated the alert"
734
  msgstr "L'Administrateur du site d’où provient l'alerte"
735
 
736
+ #: lib/event_notifications.php:236
737
  msgid "Other(s):"
738
  msgstr "Autre(s) :"
739
 
740
+ #: lib/event_notifications.php:248
741
  msgid "Save Event Notifications"
742
  msgstr "Sauvegarder les options"
743
 
744
+ #: lib/event_notifications.php:490
745
  msgid "[NinjaFirewall] Daily Activity Report"
746
  msgstr "[NinjaFirewall] Rapport d'activité quotidien"
747
 
748
+ #: lib/event_notifications.php:500
749
  #, php-format
750
  msgid "Daily activity report for: %s"
751
  msgstr "Rapport d'activité quotidien pour : %s"
752
 
753
+ #: lib/event_notifications.php:501
754
  msgid "Date Range Processed: Yesterday"
755
  msgstr "Plage de date traitée : Hier"
756
 
757
+ #: lib/event_notifications.php:503
758
  msgid "Blocked threats:"
759
  msgstr "Menaces bloquées :"
760
 
761
+ #: lib/event_notifications.php:505
762
  msgid "critical:"
763
  msgstr "Critique :"
764
 
765
+ #: lib/event_notifications.php:506
766
  msgid "high:"
767
  msgstr "Élevé :"
768
 
769
+ #: lib/event_notifications.php:507
770
  msgid "medium:"
771
  msgstr "Moyen :"
772
 
773
+ #: lib/event_notifications.php:509
774
  msgid "Blocked brute-force attacks:"
775
  msgstr "Attaques par force brute bloquées :"
776
 
777
+ #: lib/event_notifications.php:510 lib/event_updates.php:225 lib/utils.php:1112
778
  msgid ""
779
  "This notification can be turned off from NinjaFirewall \"Event Notifications"
780
  "\" page."
795
  "pour votre site Web :"
796
 
797
  #: lib/event_updates.php:163 lib/utils.php:233 lib/utils.php:318
798
+ #: lib/utils.php:440 lib/utils.php:1101 lib/utils.php:1290 lib/utils.php:1562
799
  msgid "Date:"
800
  msgstr "Date :"
801
 
841
  msgid "Theme: %s"
842
  msgstr "Theme : %s"
843
 
844
+ #: lib/event_updates.php:223 lib/utils.php:1625
845
  msgid "Don't leave your blog at risk, make sure to update as soon as possible."
846
  msgstr ""
847
  "Ne laissez pas votre blog en danger, lancez cette mise à jour dès que "
893
  msgid "[NinjaFirewall] Alert: %s"
894
  msgstr "[NinjaFirewall] Alerte : %s"
895
 
896
+ #: lib/events.php:203 lib/events.php:205 lib/utils.php:842
897
  msgid "-Blog:"
898
  msgstr "- Blog :"
899
 
901
  msgid "NinjaFirewall has detected the following activity on your account:"
902
  msgstr "NinjaFirewall a détecté l'activité suivante sur votre compte :"
903
 
904
+ #: lib/events.php:210 lib/utils.php:847
905
  msgid "-User:"
906
  msgstr "- Nom :"
907
 
908
+ #: lib/events.php:211 lib/utils.php:848
909
  msgid "-IP:"
910
  msgstr "- IP :"
911
 
912
+ #: lib/events.php:212 lib/utils.php:849
913
  msgid "-Date:"
914
  msgstr "-Date :"
915
 
916
+ #: lib/firewall_options.php:29 ninjafirewall.php:898
917
  msgid "Firewall Options"
918
  msgstr "Options du Pare-feu"
919
 
1068
  msgstr ""
1069
  "Le fichier importé est illisible ou son format n'est pas supporté (#%s)"
1070
 
1071
+ #: lib/firewall_options.php:412
1072
+ msgid "The imported file is not compatible with that version of NinjaFirewall"
1073
+ msgstr ""
1074
+ "Le fichier importé n'est pas compatible avec cette version de NinjaFirewall"
1075
+
1076
+ #: lib/firewall_options.php:557 ninjafirewall.php:234
1077
  msgid "[NinjaFirewall] Alert: Firewall is disabled"
1078
  msgstr "[NinjaFirewall] Alerte : Le pare-feu a été désactivé"
1079
 
1080
+ #: lib/firewall_options.php:559 lib/firewall_options.php:561
1081
+ #: ninjafirewall.php:236 ninjafirewall.php:238
1082
  msgid "-Blog :"
1083
  msgstr "- Blog :"
1084
 
1085
+ #: lib/firewall_options.php:565 ninjafirewall.php:240
1086
  msgid "Someone disabled NinjaFirewall from your WordPress admin dashboard:"
1087
  msgstr ""
1088
  "Quelqu'un a désactivé NinjaFirewall depuis votre Tableau de bord de "
1089
  "WordPress :"
1090
 
1091
+ #: lib/firewall_options.php:568
1092
  msgid ""
1093
  "NinjaFirewall is disabled because someone enabled debugging mode from your "
1094
  "WordPress admin dashboard:"
1096
  "NinjaFirewall est désactivé car quelqu'un activé son \"Mode débogage\" "
1097
  "depuis votre tableau de bord de WordPress :"
1098
 
1099
+ #: lib/firewall_options.php:571
1100
  msgid "[NinjaFirewall] Alert: Firewall override settings"
1101
  msgstr "[NinjaFirewall] Alerte : Modification des paramètres du pare-feu"
1102
 
1103
+ #: lib/firewall_options.php:572
1104
  msgid ""
1105
  "Someone imported a new configuration which overrode the firewall settings:"
1106
  msgstr ""
1107
  "Quelqu'un a importé une nouvelle configuration qui a modifié tous les "
1108
  "paramètres du pare-feu :"
1109
 
1110
+ #: lib/firewall_options.php:578 ninjafirewall.php:241
1111
  msgid "-User :"
1112
  msgstr "- Nom :"
1113
 
1114
+ #: lib/firewall_options.php:579 ninjafirewall.php:242
1115
  msgid "-IP :"
1116
  msgstr "- IP :"
1117
 
1118
+ #: lib/firewall_options.php:580 ninjafirewall.php:243
1119
  msgid "-Date :"
1120
  msgstr "- Date :"
1121
 
1128
  "Pour utiliser cette option, allez dans le <a href=\"%s\">Tableau de Bord</a> "
1129
  "et activez le mode Full WAF de NinjaFirewall."
1130
 
1131
+ #: lib/firewall_policies.php:62 ninjafirewall.php:902
1132
  msgid "Firewall Policies"
1133
  msgstr "Politiques du Pare-feu"
1134
 
1269
  "Bloquer les tentatives de publication, modification ou suppression d'un "
1270
  "article publié par des utilisateurs qui n'ont pas les bonnes capacités"
1271
 
1272
+ #: lib/firewall_policies.php:411 lib/thickbox.php:89
1273
  msgid "(recommended)"
1274
  msgstr "(recommandé)"
1275
 
1550
  "Activer cette fonction avec <code>DENY</code> pourrait bloquer certaines "
1551
  "fonctionnalités de votre blog, ses thèmes ou ses extensions."
1552
 
1553
+ #: lib/firewall_policies.php:845
1554
  #, php-format
1555
+ msgid "Set %s"
1556
+ msgstr "Activer %s"
1557
 
1558
+ #: lib/firewall_policies.php:849 lib/firewall_policies.php:850
1559
+ #: lib/firewall_policies.php:851
1560
  #, php-format
1561
  msgid "Set to %s"
1562
  msgstr "Régler sur %s"
1563
 
1564
+ #: lib/firewall_policies.php:853 lib/help.php:276
1565
+ msgid ""
1566
+ "This header is deprecated and most browsers phased out support for it. "
1567
+ "Consider using Content-Security-Policy instead."
1568
+ msgstr ""
1569
+ "Cet en-tête est obsolète et la plupart des navigateurs ne le prennent plus "
1570
+ "en charge. Utilisez Content-Security-Policy à la place."
1571
+
1572
  #: lib/firewall_policies.php:857
1573
  #, php-format
1574
  msgid "Force %s flag on all cookies to mitigate CSRF attacks"
2443
  "l'administrateur et la page de connexion uniquement."
2444
 
2445
  #: lib/help.php:275
2446
+ msgid "Set <code>X-XSS-Protection</code>"
2447
+ msgstr "Activer <code>X-XSS-Protection</code>"
 
 
 
2448
 
2449
  #: lib/help.php:275
2450
  msgid ""
2456
  "attaques XSS en empêchant un script malveillant de s'exécuter. Notez que "
2457
  "cette option est activée par défaut sur ces navigateurs."
2458
 
 
 
 
 
 
 
 
 
2459
  #: lib/help.php:278
2460
  msgid ""
2461
  "Force <code>SameSite</code> flag on all cookies to mitigate CSRF attacks"
2856
  "intercepter les requêtes HTTP envoyées à tout script PHP, même si ce dernier "
2857
  "ne fait pas partie de WordPress (logiciel tiers, backdoor, etc)."
2858
 
2859
+ #: lib/help.php:360 lib/network.php:32 ninjafirewall.php:920
2860
  msgid "Network"
2861
  msgstr "Réseau"
2862
 
2909
  "après avoir pénétré dans votre Tableau de bord de WordPress, d'y installer "
2910
  "une porte dérobée (backdoor) afin de prendre le contrôle de votre blog."
2911
 
2912
+ #: lib/help.php:389 lib/login_protection.php:21 ninjafirewall.php:928
2913
  msgid "Login Protection"
2914
  msgstr "Page de Connexion"
2915
 
3694
  #: lib/i18n-extra.php:51
3695
  #, php-format
3696
  msgid ""
3697
+ "You are running NinjaFirewall in WordPress WAF mode. All URL-based features "
3698
+ "such as Geolocation and URL Access Control will be limited to WordPress "
3699
+ "files only (e.g., index.php, wp-login.php, xmlrpc.php, admin-ajax.php, wp-"
3700
+ "load.php etc). If you want them to apply to any PHP script, please %sgo to "
3701
+ "the Dashboard page%s and enable NinjaFirewall's Full WAF mode."
 
3702
  msgstr ""
3703
+ "NinjaFirewall fonctionne en mode WordPress WAF. Toutes les fonctionnalités "
3704
+ "basées sur les URL comme la Géolocalisation et le Contrôle d'Accès par URL "
3705
+ "seront limitées à certains fichiers WordPress uniquement (par ex. index.php, "
3706
+ "wp-login.php, xmlrpc.php, admin-ajax.php, wp-load.php etc). Si vous voulez "
3707
+ "que cette option s'applique à tous les fichiers PHP, allez dans le %sTableau "
3708
+ "de Bord%s et activez son mode Full WAF."
 
3709
 
3710
  #: lib/i18n-extra.php:52
3711
  msgid "General"
3763
  "suivantes"
3764
 
3765
  #: lib/i18n-extra.php:65
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3766
  msgid "Enable Geolocation"
3767
  msgstr "Activer la Géolocalisation"
3768
 
3769
+ #: lib/i18n-extra.php:66
3770
  msgid "Retrieve the ISO 3166 code from"
3771
  msgstr "Récupérer le code ISO 3166 du pays depuis"
3772
 
3773
+ #: lib/i18n-extra.php:67
3774
  msgid "PHP Variable"
3775
  msgstr "Variable PHP"
3776
 
3777
+ #: lib/i18n-extra.php:68
3778
  msgid "Block the following ISO 3166 codes"
3779
  msgstr "Bloquer les codes ISO 3166 suivants"
3780
 
3781
+ #: lib/i18n-extra.php:69
3782
  #, php-format
3783
  msgid "Total blocked items: %s"
3784
  msgstr "Nombre d'éléments bloqués : %s"
3785
 
3786
+ #: lib/i18n-extra.php:70
3787
  msgid "Geolocation should apply to the whole site or to specific URLs only?"
3788
  msgstr ""
3789
  "S'il faut appliquer la Géolocalisation à tout le site ou à certains scripts "
3790
  "uniquement ?"
3791
 
3792
+ #: lib/i18n-extra.php:71
3793
  msgid "View allowed syntax"
3794
  msgstr "Afficher la syntaxe autorisée"
3795
 
3796
+ #: lib/i18n-extra.php:72
3797
  #, php-format
3798
  msgid "Full or partial case-sensitive URL (e.g., %s)."
3799
  msgstr "URL complète ou partielle, sensible à la casse (ex: %s)."
3800
 
3801
+ #: lib/i18n-extra.php:73
3802
  msgid "One item per line."
3803
  msgstr "Une entrée par ligne."
3804
 
3805
+ #: lib/i18n-extra.php:74
3806
  msgid ""
3807
  "Leave this field empty if you want geolocation to apply to all your PHP "
3808
  "scripts."
3809
  msgstr ""
3810
  "Laissez ce champ vide pour appliquer la géolocalisation à tout le site."
3811
 
3812
+ #: lib/i18n-extra.php:75
3813
+ msgid "Add NINJA_COUNTRY_CODE to PHP headers?"
3814
+ msgstr "Ajouter NINJA_COUNTRY_CODE aux en-têtes PHP ?"
3815
 
3816
+ #: lib/i18n-extra.php:76
3817
  msgid "Write event to the firewall log"
3818
  msgstr "Enregistrer l'événement dans le journal du pare-feu"
3819
 
3820
+ #: lib/i18n-extra.php:77
3821
  msgid "Allow the following IP, CIDR or AS number"
3822
  msgstr "Accepter les IP, CIDR ou numéros d'AS suivants"
3823
 
3824
+ #: lib/i18n-extra.php:78
3825
  #, php-format
3826
  msgid "IPv4 address: %s"
3827
  msgstr "Adresse IPv4 : %s"
3828
 
3829
+ #: lib/i18n-extra.php:79
3830
  #, php-format
3831
  msgid "IPv4 CIDR: %s"
3832
  msgstr "CIDR IPv4 : %s"
3833
 
3834
+ #: lib/i18n-extra.php:80
3835
  #, php-format
3836
  msgid "IPv6 address: %s"
3837
  msgstr "Adresse IPv6 : %s"
3838
 
3839
+ #: lib/i18n-extra.php:81
3840
  #, php-format
3841
  msgid "IPv6 CIDR: %s"
3842
  msgstr "CIDR IPv6 : %s"
3843
 
3844
+ #: lib/i18n-extra.php:82
3845
  #, php-format
3846
  msgid "Autonomous System number: %s"
3847
  msgstr "Numéro AS (Autonomous System) : %s"
3848
 
3849
+ #: lib/i18n-extra.php:83
3850
  msgid "Whitelist:"
3851
  msgstr "Liste Blanche:"
3852
 
3853
+ #: lib/i18n-extra.php:84
3854
  msgid "Enter one item per line."
3855
  msgstr "Une entrée par ligne."
3856
 
3857
+ #: lib/i18n-extra.php:85
3858
  msgid "External Services"
3859
  msgstr "Services externes"
3860
 
3861
+ #: lib/i18n-extra.php:86
3862
  msgid "Whitelist IP addresses from the following services:"
3863
  msgstr "Ajouter les adresses IP des services suivants à la liste blanche :"
3864
 
3865
+ #: lib/i18n-extra.php:87
3866
  msgid "View IP addresses"
3867
  msgstr "Voir les adresses IP"
3868
 
3869
+ #: lib/i18n-extra.php:88
3870
  msgid "Block the following IP, CIDR or AS number"
3871
  msgstr "Bloquer les IP, CIDR ou numéros d'AS suivants"
3872
 
3873
+ #: lib/i18n-extra.php:89
3874
  msgid "Blacklist:"
3875
  msgstr "Liste noire :"
3876
 
3877
+ #: lib/i18n-extra.php:90
3878
  msgid "Rate Limiting"
3879
  msgstr "Limiter le trafic"
3880
 
3881
+ #: lib/i18n-extra.php:91
3882
  #, php-format
3883
  msgid ""
3884
  "Block for %s seconds any IP address with more than %s connections within a "
3887
  "Bloquer pendant %s secondes les IP ayant plus de %s connexions en moins de "
3888
  "%s."
3889
 
3890
+ #: lib/i18n-extra.php:92
3891
  msgid "5-second"
3892
  msgstr "5 secondes"
3893
 
3894
+ #: lib/i18n-extra.php:93
3895
  msgid "10-second"
3896
  msgstr "10 secondes"
3897
 
3898
+ #: lib/i18n-extra.php:94
3899
  msgid "15-second"
3900
  msgstr "15 secondes"
3901
 
3902
+ #: lib/i18n-extra.php:95
3903
  msgid "30-second"
3904
  msgstr "30 secondes"
3905
 
3906
+ #: lib/i18n-extra.php:96
3907
  msgid "Allow access to the following URL"
3908
  msgstr "Autoriser l'accès à l'URL suivante"
3909
 
3910
+ #: lib/i18n-extra.php:97
3911
  #, php-format
3912
  msgid "Full or partial case-sensitive URLs (e.g., %s)."
3913
  msgstr "URL complète ou partielle, sensible à la casse (ex: %s)."
3914
 
3915
+ #: lib/i18n-extra.php:98
3916
  msgid "Block access to the following URL"
3917
  msgstr "Bloquer l'accès à l'URL suivante"
3918
 
3919
+ #: lib/i18n-extra.php:99
3920
  msgid "Reject the following bots"
3921
  msgstr "Rejeter les bots suivants"
3922
 
3923
+ #: lib/i18n-extra.php:100
3924
  msgid "A full or partial case-insensitive string."
3925
  msgstr "Chaîne de caractère complète ou partielle, insensible à la casse."
3926
 
3927
+ #: lib/i18n-extra.php:101
3928
+ #, php-format
3929
+ msgid "Allowed characters are: %s and %s."
3930
+ msgstr "Caractères autorisés : %s et %s."
 
 
 
 
 
3931
 
3932
+ #: lib/i18n-extra.php:102
3933
  msgid "Blocked bots:"
3934
  msgstr "Bots bloqués :"
3935
 
3936
+ #: lib/i18n-extra.php:103
3937
  msgid "The default list of bots will be restored. Continue?"
3938
  msgstr "Restaurer les valeurs par défaut de la liste des bots ?"
3939
 
3940
+ #: lib/i18n-extra.php:104
3941
  msgid "Restore default bots list"
3942
  msgstr "Restaurer les valeurs par défaut"
3943
 
3944
+ #: lib/i18n-extra.php:105
3945
  msgid "Do not filter the following user input"
3946
  msgstr "Ne pas filtrer l'entrée utilisateur suivante"
3947
 
3948
+ #: lib/i18n-extra.php:106
3949
  msgid ""
3950
+ "A GET, POST or COOKIE global variable, followed by a colon (:) and the case-"
3951
+ "sensitive input:"
3952
  msgstr ""
3953
+ "Une variable GET, POST ou COOKIE, suivie de deux points (:) et de l'entrée, "
3954
+ "sensible à la casse :"
3955
 
3956
+ #: lib/i18n-extra.php:107
3957
  msgid "Unfiltered input:"
3958
  msgstr "Entrées non filtrées :"
3959
 
3960
+ #: lib/i18n-extra.php:108
3961
  msgid "Block the request if the following input is present"
3962
  msgstr "Bloquer la requête si elle contient l'entrée suivante"
3963
 
3964
+ #: lib/i18n-extra.php:109
3965
  msgid "Blocked input:"
3966
  msgstr "Entrées bloquées :"
3967
 
3968
+ #: lib/i18n-extra.php:110
3969
  msgid "Save Access Control directives"
3970
  msgstr "Sauvegarder les options"
3971
 
3972
+ #: lib/i18n-extra.php:111
3973
  msgid ""
3974
  "Warning: Your previous secret key was either corrupted or missing. A new "
3975
  "one, as well as a new public key, were created."
3977
  "Attention : votre clé privée était soit corrompue soit manquante. Un nouveau "
3978
  "jeu de clés vient d'être créé."
3979
 
3980
+ #: lib/i18n-extra.php:112
3981
  msgid "Enable Centralized Logging"
3982
  msgstr "Activer la Centralisation des Logs"
3983
 
3984
+ #: lib/i18n-extra.php:113
3985
  msgid "Secret key"
3986
  msgstr "Clé privée"
3987
 
3988
+ #: lib/i18n-extra.php:114
3989
  msgid "From 30 to 100 ASCII printable characters."
3990
  msgstr "De 30 à 100 caractères ASCII."
3991
 
3992
+ #: lib/i18n-extra.php:115
3993
  msgid "This server's IP address"
3994
  msgstr "L'adresse IP de ce serveur"
3995
 
3996
+ #: lib/i18n-extra.php:116
3997
  msgid ""
3998
  "Only this IP address (IPv4 or IPv6) will be allowed to connect to the remote "
3999
  "websites. If you don't want to restrict the access by IP, enter the <code>*</"
4003
  "distants. Si vous ne souhaitez pas de restriction d’accès par IP, veuillez "
4004
  "entrer le caractère <code>*</code>."
4005
 
4006
+ #: lib/i18n-extra.php:117
4007
  msgid "Public key"
4008
  msgstr "Clé publique"
4009
 
4010
+ #: lib/i18n-extra.php:118
4011
  #, php-format
4012
  msgid ""
4013
  "Add this key to the remote websites. <a href=\"%s\">Consult our blog</a> for "
4016
  "Vous devez configurer vos sites distants avec cette nouvelle clé. <a href="
4017
  "\"%s\">Consultez notre blog</a> pour plus d'info."
4018
 
4019
+ #: lib/i18n-extra.php:119
4020
  msgid "Remote websites URL"
4021
  msgstr "URL de vos sites distants"
4022
 
4023
+ #: lib/i18n-extra.php:120
4024
  msgid ""
4025
  "Enter one URL per line, including the protocol (<code>http://</code> or "
4026
  "<code>https://</code>). Only ASCII URLs are accepted."
4028
  "Entrez une URL par ligne, en incluant le protocole (<code>http://</code> ou "
4029
  "<code>https://</code>). Seules les URL au format ASCII sont acceptées."
4030
 
4031
+ #: lib/i18n-extra.php:121
4032
  msgid "Save Options"
4033
  msgstr "Sauvegarder les options"
4034
 
4035
+ #: lib/i18n-extra.php:122
4036
  msgid ""
4037
  "Your changes have been saved. If you are using a caching plugin, do not "
4038
  "forget to clear its cache."
4040
  "Vos changements ont été enregistrés. Si vous utilisez une extension de mise "
4041
  "en cache, n'oubliez pas d'effacer son cache."
4042
 
4043
+ #: lib/i18n-extra.php:123
4044
  msgid "Enable antispam protection"
4045
  msgstr "Activer la protection anti-spam"
4046
 
4047
+ #: lib/i18n-extra.php:124
4048
  msgid "Protection level"
4049
  msgstr "Niveau de protection"
4050
 
4051
+ #: lib/i18n-extra.php:125
4052
  msgid "Low (default)"
4053
  msgstr "Bas (défaut)"
4054
 
4055
+ #: lib/i18n-extra.php:128
4056
  msgid ""
4057
  "If you are using a caching plugin, consult the contextual help before "
4058
  "enabling the antispam."
4060
  "Si vous utilisez une extension de mise en cache, veuillez consulter l'aide "
4061
  "contextuelle avant d'activer l'anti-spam."
4062
 
4063
+ #: lib/i18n-extra.php:129
4064
  msgid "Apply protection to"
4065
  msgstr "Appliquer la protection au"
4066
 
4067
+ #: lib/i18n-extra.php:130
4068
  msgid "Comment forms (defaut)"
4069
  msgstr "Formulaire de commentaire (défaut)"
4070
 
4071
+ #: lib/i18n-extra.php:131
4072
  msgid "User Registration form"
4073
  msgstr "Formulaire d'inscription"
4074
 
4075
+ #: lib/i18n-extra.php:132
4076
  msgid "Save Antispam options"
4077
  msgstr "Sauvegarder les options"
4078
 
4079
+ #: lib/i18n-extra.php:133
4080
  msgid "Please enable JavaScript"
4081
  msgstr "Veuillez activer JavaScript"
4082
 
4083
+ #: lib/i18n-extra.php:134
4084
  msgid "Sorry, this looks like spam to me."
4085
  msgstr "Désolé, mais cela ressemble à du spam."
4086
 
4087
+ #: lib/i18n-extra.php:135
4088
  msgid ""
4089
  "Error: You must be whitelisted in order to use that feature: click on the <a "
4090
  "href=\"?page=nfsubaccess\">Access Control</a> menu and ensure that the \"Do "
4095
  "et assurez vous que l'option \"Ne pas bloquer les utilisateurs suivants\" "
4096
  "est activée pour l'Administrateur/Super Admin."
4097
 
4098
+ #: lib/i18n-extra.php:136
4099
  msgid ""
4100
  "Your license is valid until the indicated expiration date. If you don't "
4101
  "renew it after this date, NinjaFirewall will keep working and protecting "
4106
  "et à protéger votre site comme d'habitude, mais les mises à jour / mises à "
4107
  "niveau ne pourront plus être effectuées."
4108
 
4109
+ #: lib/i18n-extra.php:137
4110
  #, php-format
4111
  msgid ""
4112
  "You can renew your license from <a href=\"%s\">NinTechNet.com</a> website."
4114
  "Vous pouvez renouveler votre licence depuis le site <a href=\"%s"
4115
  "\">NinTechNet.com</a>."
4116
 
4117
+ #: lib/i18n-extra.php:138
4118
  msgid "Use shared memory"
4119
  msgstr "Utiliser la mémoire partagée"
4120
 
4121
+ #: lib/i18n-extra.php:139
4122
  msgid ""
4123
  "This feature allows NinjaFirewall to use Unix shared memory segments in "
4124
  "order to speed up all operations. The firewall will no longer need to "
4137
  "réseau multi-site, la vitesse de traitement de pare-feu va augmenter de 25% "
4138
  "à 30%."
4139
 
4140
+ #: lib/i18n-extra.php:140
4141
  msgid ""
4142
  "This option requires that your PHP version was compiled with the <code>--"
4143
  "enable-shmop</code> parameter, otherwise, if it is not compatible with your "
4146
  "Cette fonction nécessite que PHP soit compilé avec le paramètre <code>--"
4147
  "enable-shmop</code>."
4148
 
4149
+ #: lib/i18n-extra.php:141
4150
  #, php-format
4151
  msgid ""
4152
  "If you are using <a href=\"%s\">GB2312</a> character set (A.K.A <code>GBK</"
4161
  "être en mesure de nettoyer correctement les caractères multi-octets, car il "
4162
  "n'aura pas accès à la base de données."
4163
 
4164
+ #: lib/i18n-extra.php:142
4165
  msgid "Language"
4166
  msgstr "Langue"
4167
 
4168
+ #: lib/i18n-extra.php:143
4169
  msgid ""
4170
  "When this option is enabled, NinjaFirewall will download, if available, the "
4171
  "corresponding language files from the WordPress repo. Then, every hour, it "
4176
  "les heures, il vérifiera s'il existe une nouvelle version et la téléchargera "
4177
  "le cas échéant."
4178
 
4179
+ #: lib/i18n-extra.php:144
4180
  msgid ""
4181
  "Note that this does not apply to <code>en_US</code> and <code>fr_FR</code> "
4182
  "locales because they are already included with NinjaFirewall."
4184
  "Notez que cela ne s'applique pas aux locales <code>en_US</code> et "
4185
  "<code>fr_FR</code> car elles sont déjà incluses avec NinjaFirewall."
4186
 
4187
+ #: lib/i18n-extra.php:145
4188
  #, php-format
4189
  msgid ""
4190
  "This options lets you export you current configuration or import it from "
4198
  "(%s), sinon il sera rejeté. Notez que l'importation effacera toute votre "
4199
  "configuration (options et règles du pare-feu), sauf votre licence WP+."
4200
 
4201
+ #: lib/i18n-extra.php:146
4202
  msgid ""
4203
  "You can allow/disallow uploads, or allow uploads but block scripts (PHP, "
4204
  "CGI, Ruby, Python, bash/shell, JavaScript), C/C++ source code, binaries (MZ/"
4212
  "systèmes (.htaccess, .htpasswd et PHP INI) et les fichiers SVG contenant du "
4213
  "Javascript ou des Événements XML."
4214
 
4215
+ #: lib/i18n-extra.php:147
4216
  msgid "Maximum allowed file size"
4217
  msgstr "Taille maximale autorisée"
4218
 
4219
+ #: lib/i18n-extra.php:148
4220
  msgid ""
4221
  "If you allow uploads, you can select the maximum size of an uploaded file. "
4222
  "Any file bigger than this value will be rejected. Note that if your PHP "
4228
  "configuration de PHP utilise la directive<code>upload_max_filesize</code>, "
4229
  "celle-ci sera prioritaire."
4230
 
4231
+ #: lib/i18n-extra.php:149
4232
  msgid "Decode Base64-encoded <code>POST</code> variable:"
4233
  msgstr ""
4234
  "Décoder les chaîne encodées en Base64 dans la variable <code>POST</"
4235
  "code>&nbsp;:"
4236
 
4237
+ #: lib/i18n-extra.php:150
4238
  #, php-format
4239
  msgid ""
4240
  "Object Serialization is a PHP feature used by many applications to generate "
4253
  "<code>POST</code>, les cookies, ou dans les variables <code>HTTP_REFERER</"
4254
  "code> et <code>HTTP_USER_AGENT</code>."
4255
 
4256
+ #: lib/i18n-extra.php:151
4257
  msgid ""
4258
  "This option will reject any <code>GET</code> or <code>POST</code> request, "
4259
  "<code>COOKIE</code>, <code>HTTP_USER_AGENT</code>, <code>REQUEST_URI</code>, "
4267
  "contenant le caractère ASCI 0x00 (NULL byte) sera bloquée immédiatement. Ce "
4268
  "caractère est dangereux et devrait toujours être rejeté."
4269
 
4270
+ #: lib/i18n-extra.php:152
4271
  msgid ""
4272
  "This option will block any <code>GET</code> or <code>POST</code> request "
4273
  "containing the localhost IP (127.0.0.1). It can be useful to block SQL "
4278
  "les programmes malveillants. Attention toutefois à ne pas bloquer certains "
4279
  "scripts d'installation ou de configuration si vous l'activez."
4280
 
4281
+ #: lib/i18n-extra.php:153
4282
  msgid ""
4283
  "Access Control is a powerful set of directives that can be used to allow or "
4284
  "restrict access to your website based on many criteria."
4287
  "utilisé pour autoriser ou restreindre l'accès à votre site selon de nombreux "
4288
  "critères."
4289
 
4290
+ #: lib/i18n-extra.php:154
4291
  msgid ""
4292
  "To make better use of them, it is important to understand NinjaFirewall's "
4293
  "directives processing order."
4295
  "Afin de pouvoir optimiser son utilisation, il est important de bien "
4296
  "comprendre l'ordre dans lequel NinjaFirewall traite ces directives."
4297
 
4298
+ #: lib/i18n-extra.php:155
4299
  msgid ""
4300
  "Because NinjaFirewall is a PHP firewall, its Access Control options apply to "
4301
  "PHP scripts, not to static elements (e.g., images, JS, CSS etc). Depending "
4306
  "(images, JS, CSS, etc). Selon votre configuration, elle peuvent également "
4307
  "s'appliquer aux pages HTML."
4308
 
4309
+ #: lib/i18n-extra.php:156
4310
  msgid "Processing order:"
4311
  msgstr "Ordre de traitement des directives :"
4312
 
4313
+ #: lib/i18n-extra.php:157
4314
  msgid "Incoming HTTP request"
4315
  msgstr "Requête HTTP entrante"
4316
 
4317
+ #: lib/i18n-extra.php:158
4318
  #, php-format
4319
  msgid "%s file"
4320
  msgstr "Fichier %s"
4321
 
4322
+ #: lib/i18n-extra.php:159
4323
  msgid "Login Protection."
4324
  msgstr "Page de Connexion."
4325
 
4326
+ #: lib/i18n-extra.php:160
4327
  msgid "Access Control (except User Input Access Control):"
4328
  msgstr "Contrôle d'Accès (sauf Contrôle d'accès d'entrée utilisateur) :"
4329
 
4330
+ #: lib/i18n-extra.php:161
4331
  msgid "Role-based Access Control."
4332
  msgstr "Contrôle d'Accès par Rôle."
4333
 
4334
+ #: lib/i18n-extra.php:162
4335
  msgid "Allowed IPs."
4336
  msgstr "Adresses IP autorisées."
4337
 
4338
+ #: lib/i18n-extra.php:163
4339
  msgid "Blocked IPs."
4340
  msgstr "Adresses IP bloquées."
4341
 
4342
+ #: lib/i18n-extra.php:164
4343
  msgid "Allowed URLs."
4344
  msgstr "URL autorisées."
4345
 
4346
+ #: lib/i18n-extra.php:165
4347
  msgid "Blocked URLs."
4348
  msgstr "URL bloquées."
4349
 
4350
+ #: lib/i18n-extra.php:166
4351
  msgid "Bot Access Control."
4352
  msgstr "Contrôle d'accès par Bot."
4353
 
4354
+ #: lib/i18n-extra.php:167
4355
  msgid "Geolocation."
4356
  msgstr "Géolocalisation."
4357
 
4358
+ #: lib/i18n-extra.php:168
4359
  msgid "Rate Limiting."
4360
  msgstr "Limitation du trafic."
4361
 
4362
+ #: lib/i18n-extra.php:169
4363
  msgid "File Guard."
4364
  msgstr "File Guard."
4365
 
4366
+ #: lib/i18n-extra.php:170
4367
  msgid "NinjaFirewall built-in rules and policies + User Input Access Control."
4368
  msgstr ""
4369
  "Règles et politiques du pare-feu + Contrôle d'accès d'entrée utilisateur."
4370
 
4371
+ #: lib/i18n-extra.php:171
4372
  msgid "Response body"
4373
  msgstr "Requête HTTP sortante"
4374
 
4375
+ #: lib/i18n-extra.php:172
4376
  msgid "HTTP response headers (Firewall Policies)."
4377
  msgstr "En-têtes de réponse HTTP (Politiques du Pare-feu)."
4378
 
4379
+ #: lib/i18n-extra.php:173
4380
  msgid "Web Filter."
4381
  msgstr "Web Filter."
4382
 
4383
+ #: lib/i18n-extra.php:174
4384
  #, php-format
4385
  msgid ""
4386
  "By default, any logged in WordPress administrator will not be blocked by "
4399
  "options de la <a href=\"%s\">Page de Connexion</a> qui, si elle sont "
4400
  "activées, seront toujours appliquées."
4401
 
4402
+ #: lib/i18n-extra.php:175
4403
  msgid "You can also add other users to the whitelist, depending on their role."
4404
  msgstr ""
4405
  "Vous pouvez ajouter d'autres utilisateurs à votre liste blanche en se basant "
4406
  "sur leur Rôle."
4407
 
4408
+ #: lib/i18n-extra.php:176
4409
  #, php-format
4410
  msgid ""
4411
  "this option should be used if you are behind a reverse proxy, a load "
4429
  "sera vérifiée. Si elle ne comprend aucune IP utilisable, NinjaFirewall "
4430
  "utilisera <code>REMOTE_ADDR</code>."
4431
 
4432
+ #: lib/i18n-extra.php:177
4433
  msgid ""
4434
  "This option lets you select the HTTP method(s). All Access Control "
4435
  "directives (Geolocation, IPs, bots and URLs) will only apply to the selected "
4439
  "Contrôle d'Accès (Geolocalisation, IP, bots et URL) ne s'appliqueront qu'aux "
4440
  "méthodes sélectionnées."
4441
 
4442
+ #: lib/i18n-extra.php:178
4443
  msgid ""
4444
  "It does not apply to the \"Firewall Policies\" options, which use their own "
4445
  "ones."
4446
  msgstr "Cette option ne concerne pas les \"Politiques du Pare-feu\"."
4447
 
4448
+ #: lib/i18n-extra.php:179
4449
  msgid ""
4450
  "You can filter and block traffic coming from specific countries/territories."
4451
  msgstr ""
4452
  "Vous pouvez filtrer et bloquer le trafic en provenance de pays ou "
4453
  "territoires spécifiques."
4454
 
4455
+ #: lib/i18n-extra.php:180
4456
  msgid ""
4457
  "This is the two-letter code that is used to define a country/territory (e."
4458
  "g., US, UK, FR, DE etc), based on the visitors IP. NinjaFirewall can either "
4465
  "données, ou à partir d'une variable PHP prédéfinie ajoutée par votre serveur "
4466
  "HTTP (par exemple, <code>GEOIP_COUNTRY_CODE</code>)."
4467
 
4468
+ #: lib/i18n-extra.php:181
4469
  #, php-format
4470
  msgid ""
4471
  "You can add/remove any country/territory from the two listboxes. For more "
4477
  "spécifiques (A1, A2, AP, EU etc),vous pouvez consulter l'aide en ligne de <a "
4478
  "href=\"%s\">MaxMind GeoIP</a>."
4479
 
4480
+ #: lib/i18n-extra.php:182
4481
  msgid ""
4482
  "Whether geolocation should apply to the whole site or to specific URLs only "
4483
  "(e.g., /wp-login.php, /xmlrpc.php etc). Leave all fields empty if you want "
4487
  "uniquement (ex: /wp-login.php, /xmlrpc.php etc). Laissez ce champ vide pour "
4488
  "l'appliquer à tout le site."
4489
 
4490
+ #: lib/i18n-extra.php:183
4491
+ msgid "Add <code>NINJA_COUNTRY_CODE</code> to PHP headers?"
4492
+ msgstr "Ajouter <code>NINJA_COUNTRY_CODE</code> aux en-têtes PHP?"
4493
+
4494
+ #: lib/i18n-extra.php:184
4495
  msgid ""
4496
  "After retrieving the two-letter country/territory code, NinjaFirewall can "
4497
  "add it to the PHP headers in the <code>$_SERVER[\"NINJA_COUNTRY_CODE\"]</"
4503
  "code>. Si vous avez une application PHP qui nécessite de géolocaliser vos "
4504
  "visiteurs, activez cette option."
4505
 
4506
+ #: lib/i18n-extra.php:185
4507
  msgid ""
4508
  "If NinjaFirewall cannot find the two-letter ISO 3166 code, it will replace "
4509
  "it with 2 hyphens (<code>--</code>)."
4511
  "Si NinjaFirewall ne peut pas identifier le code à deux lettres ISO 3166, il "
4512
  "le remplacera par deux traits d'union (<code>--</code>)."
4513
 
4514
+ #: lib/i18n-extra.php:186
4515
  msgid ""
4516
  "PHP code example to use in your theme or plugin to geolocate your visitors:"
4517
  msgstr ""
4518
  "Exemple de code PHP à ajouter à vos scripts pour géolocaliser vos visiteurs :"
4519
 
4520
+ #: lib/i18n-extra.php:187
4521
  msgid ""
4522
  "NinjaFirewall includes GeoLite data created by MaxMind, available from "
4523
  "http://www.maxmind.com"
4525
  "NinjaFirewall includes GeoLite data created by MaxMind, available from "
4526
  "http://www.maxmind.com"
4527
 
4528
+ #: lib/i18n-extra.php:188
4529
  msgid "IP / URL / Bot Access Control"
4530
  msgstr "Contrôle d'Accès par IP / URL / Bots"
4531
 
4532
+ #: lib/i18n-extra.php:189
4533
  msgid ""
4534
  "You can permanently allow/block an IP, a whole range of IP addresses or AS "
4535
  "numbers (Autonomous System number). IPv4 and IPv6 are fully supported by "
4539
  "numéro AS (Autonomous System). NinjaFirewall est compatible avec l'IPv4 et "
4540
  "l'IPv6."
4541
 
4542
+ #: lib/i18n-extra.php:190
4543
  msgid "Full IP:"
4544
  msgstr "IP complète :"
4545
 
4546
+ #: lib/i18n-extra.php:191
4547
  #, php-format
4548
  msgid "IP ranges using CIDR notation: %s or %s."
4549
  msgstr "Plages IP utilisant la notation CIDR : %s ou %s."
4550
 
4551
+ #: lib/i18n-extra.php:192
4552
  msgid "Autonomous System number:"
4553
  msgstr "Numéro AS (Autonomous System) :"
4554
 
4555
+ #: lib/i18n-extra.php:193
4556
  msgid ""
4557
  "This option allows you to slow down aggressive bots, crawlers, web scrapers "
4558
  "or even small HTTP attacks. Any IP reaching the defined threshold will be "
4571
  "adresse IP, utilisez l'option \"Contrôle d'accès par IP\". Par défaut, la "
4572
  "limitation du trafic n'est pas activée."
4573
 
4574
+ #: lib/i18n-extra.php:194
4575
  msgid ""
4576
  "IPs temporarily banned by the Rate Limiting option can be unblocked "
4577
  "immediately by clicking either the \"Save Access Control Directives\" or "
4581
  "débloquées simplement en cliquant sur les boutons \"Sauvegarder les options"
4582
  "\" ou \"Rétablir les valeurs par défaut\" situés en bas de la page."
4583
 
4584
+ #: lib/i18n-extra.php:195
4585
  msgid ""
4586
  "Because NinjaFirewall can handle a lot of HTTP requests per second and block "
4587
  "IPs even before your blog is loaded, we strongly recommend that you disable "
4595
  "seconde, NinjaFirewall vous fera économiser de la bande passante et "
4596
  "permettra de réduire la charge du serveur."
4597
 
4598
+ #: lib/i18n-extra.php:196
4599
  msgid ""
4600
  "You can permanently allow/block any access to one or more PHP scripts based "
4601
  "on their path, relative to the web root (<code>SCRIPT_NAME</code>). You can "
4606
  "(<code>SCRIPT_NAME</code>). Vous pouvez entrer l'URL complète ou partielle, "
4607
  "sensible à la casse."
4608
 
4609
+ #: lib/i18n-extra.php:197
4610
  msgid ""
4611
  "<code>/foo/bar.php</code> will block any access to the <code>bar.php</code> "
4612
  "script located inside a <code>/foo/</code> directory"
4614
  "<code>/foo/bar.php</code> autorisera/bloquera tout accès au script PHP "
4615
  "<code>bar.php</code> situé dans un répertoire <code>/foo/</code>"
4616
 
4617
+ #: lib/i18n-extra.php:198
4618
  msgid "etc"
4619
  msgstr "etc"
4620
 
4621
+ #: lib/i18n-extra.php:199
4622
  msgid ""
4623
  "<code>/foo/</code> will block access to all PHP scripts located inside a "
4624
  "<code>/foo/</code> directory and its sub-directories."
4626
  "<code>/foo/</code> autorisera/bloquera l'accès à tous les scripts PHP situés "
4627
  "dans un répertoire <code>/foo/</code> et ses sous-répertoires."
4628
 
4629
+ #: lib/i18n-extra.php:200
4630
  msgid ""
4631
  "Note that the \"Firewall Policies\" page already includes restrictions to "
4632
  "some WordPress directories."
4634
  "Notez que le menu des \"Politiques du pare-feu\" comporte déjà des "
4635
  "restrictions à certains répertoires de WordPress."
4636
 
4637
+ #: lib/i18n-extra.php:201
4638
  msgid ""
4639
  "You can block bots, scanners and various crawlers based on the "
4640
  "<code>HTTP_USER_AGENT</code> variable. You can enter either a full or "
4644
  "nom (<code>HTTP_USER_AGENT</code>) ou partie de celui-ci. La chaîne de "
4645
  "caractères est insensible à la casse."
4646
 
4647
+ #: lib/i18n-extra.php:202
4648
  msgid ""
4649
  "You can select to ignore or block some specific user input. It applies to "
4650
  "the <code>GET</code>, <code>POST</code> and <code>COOKIE</code> global "
4656
  "<code>COOKIE</code>, par exemple <code>$_GET[\"foo\"]</code> ou <code>"
4657
  "$_POST[\"bar\"]</code> :"
4658
 
4659
+ #: lib/i18n-extra.php:203
4660
  msgid ""
4661
  "When an input is added to the \"Unfiltered input\" list, it will not be "
4662
  "filtered or sanitised. All other input present in the request will be "
4666
  "sera ni filtrée ni nettoyée. Toutes les autres entrées présentes dans la "
4667
  "demande seront filtrées."
4668
 
4669
+ #: lib/i18n-extra.php:204
4670
  msgid ""
4671
  "When an input is added to the \"Blocked input\", NinjaFirewall will block "
4672
  "the request and close the connection if that input is found in the request."
4675
  "bloquera la requête et fermera la connexion si cette entrée est présente "
4676
  "dans la requête."
4677
 
4678
+ #: lib/i18n-extra.php:205
4679
  msgid "Log Event"
4680
  msgstr "Journaliser"
4681
 
4682
+ #: lib/i18n-extra.php:206
4683
  msgid ""
4684
  "You can enable/disable firewall logging for each access control directive "
4685
  "separately."
4687
  "Vous pouvez activer/désactiver la journalisation des directives "
4688
  "indépendamment les unes des autres."
4689
 
4690
+ #: lib/i18n-extra.php:207
4691
  msgid "Web Filter"
4692
  msgstr "Web Filter"
4693
 
4694
+ #: lib/i18n-extra.php:208
4695
  msgid ""
4696
  "If NinjaFirewall can hook and scan incoming requests, it can also hook the "
4697
  "response body (i.e., the output of the HTML page right before it is sent to "
4708
  "etc), des scripts utilisés par les hackers (shell, backdoor) et même des "
4709
  "erreurs (PHP, MySQL)."
4710
 
4711
+ #: lib/i18n-extra.php:209
4712
  msgid ""
4713
  "In the case of a positive detection, NinjaFirewall will not block the "
4714
  "response body but will send you an alert by email."
4716
  "En cas de détection positive, NinjaFirewall ne bloquera pas la requête mais "
4717
  "vous enverra immédiatement une alerte par e-mail."
4718
 
4719
+ #: lib/i18n-extra.php:210
4720
  msgid "Search HTML page for the following keywords"
4721
  msgstr "Rechercher les mots suivants dans la page HTML"
4722
 
4723
+ #: lib/i18n-extra.php:211
4724
  msgid ""
4725
  "You can enter any keyword from 4 to 150 characters and select whether the "
4726
  "search will be case sensitive or not."
4728
  "Vous pouvez entrer de 4 à 150 caractères et sélectionner si la recherche est "
4729
  "sensible à la casse."
4730
 
4731
+ #: lib/i18n-extra.php:212
4732
  msgid "Email Alerts"
4733
  msgstr "Alertes E-mail"
4734
 
4735
+ #: lib/i18n-extra.php:213
4736
  msgid ""
4737
  "You can use the notification throttling option to limit the frequency of "
4738
  "alerts sent to you (and written to the firewall log) and select whether you "
4744
  "d'Événement \". La page HTML ayant déclenché cette alerte peut être jointe à "
4745
  "l'e-mail."
4746
 
4747
+ #: lib/i18n-extra.php:214
4748
  msgid ""
4749
  "Response body filtering can be resource-intensive. Try to limit the number "
4750
  "of keywords to what you really need (less than 10) and, if possible, prefer "
4754
  "limiter le nombre de mots-clés (moins de 10) et, si possible, préférez la "
4755
  "recherche sensible à la casse."
4756
 
4757
+ #: lib/i18n-extra.php:215
4758
  msgid ""
4759
  "NinjaFirewall can protect your blog against spam without user interaction (e."
4760
  "g., CAPTCHA, math puzzles etc). The protection is totally transparent to "
4769
  "vous utilisez une extension tierce pour créer vos formulaires, ils ne seront "
4770
  "pas protégés contre le spam."
4771
 
4772
+ #: lib/i18n-extra.php:216
4773
  msgid "Protection level:"
4774
  msgstr "Niveau de protection :"
4775
 
4776
+ #: lib/i18n-extra.php:217
4777
  msgid ""
4778
  "Select the level of protection. In most cases, <strong>Low</strong> should "
4779
  "be enough."
4781
  "Sélectionnez le niveau de protection. Dans la plupart des cas \"Bas\" est "
4782
  "suffisant."
4783
 
4784
+ #: lib/i18n-extra.php:218
4785
  msgid "Apply protection to:"
4786
  msgstr "Appliquer la protection à :"
4787
 
4788
+ #: lib/i18n-extra.php:219
4789
  msgid "Whether to protect comment and/or registration forms."
4790
  msgstr "S'il faut protéger les formulaires de commentaire et d'inscription."
4791
 
4792
+ #: lib/i18n-extra.php:220
4793
  msgid "If you are using a caching plugin, ensure you follow these steps:"
4794
  msgstr ""
4795
  "Si vous utilisez une extension de mise en cache, veuillez procéder de la "
4796
  "sorte :"
4797
 
4798
+ #: lib/i18n-extra.php:221
4799
  msgid ""
4800
  "Set the Protection Level to \"Low\" only. Do not use another value, "
4801
  "otherwise the antispam could behave erratically after a while."
4803
  "Réglez le niveau de protection sur \"Bas\" uniquement. N'utilisez pas "
4804
  "d'autre niveau, sinon l'anti-spam pourrait se comporter de façon erratique."
4805
 
4806
+ #: lib/i18n-extra.php:222
4807
  msgid ""
4808
  "Flush/clear your cache immediately after enabling or disabling the antispam."
4809
  msgstr ""
4810
  "Videz / effacez votre cache immédiatement après l'activation ou la "
4811
  "désactivation de l'anti-spam."
4812
 
4813
+ #: lib/i18n-extra.php:223
4814
  msgid ""
4815
  "The firewall log displays blocked and sanitised requests as well as some "
4816
  "useful information. It has 6 columns:"
4818
  "Le journal du pare-feu affiche les requêtes HTTP qui ont été bloquées ou "
4819
  "nettoyées ainsi que d'autres informations utiles. Il a six colonnes :"
4820
 
4821
+ #: lib/i18n-extra.php:224
4822
  msgid ""
4823
  "RULE : reference of the NinjaFirewall built-in security rule that triggered "
4824
  "the action. A hyphen (<code>-</code>) instead of a number means it was a "
4829
  "d'un numéro signifie que la règle provient de votre configuration "
4830
  "personnelle de la page \"Politiques du Pare-feu\" ou \"Contrôle d'Accès\"."
4831
 
4832
+ #: lib/i18n-extra.php:225
4833
  msgid "The log can also be exported as a TSV (tab-separated values) text file."
4834
  msgstr ""
4835
  "Le journal peut aussi être exporté au format TSV (valeurs séparées par des "
4836
  "tabulations)."
4837
 
4838
+ #: lib/i18n-extra.php:226
4839
  msgid "Enable firewall log"
4840
  msgstr "Activer le journal du pare-feu"
4841
 
4842
+ #: lib/i18n-extra.php:227
4843
  msgid "You can disable/enable the firewall log from this page."
4844
  msgstr ""
4845
  "Vous pouvez activer / désactiver le journal du pare-feu à partir de cette "
4846
  "page."
4847
 
4848
+ #: lib/i18n-extra.php:228
4849
  msgid ""
4850
  "Brute-force attacks will still be written to the firewall log, even if you "
4851
  "disable it."
4853
  "Les attaques par force brute seront toujours enregistrées dans le journal du "
4854
  "pare-feu, même si vous désactivez celui-ci."
4855
 
4856
+ #: lib/i18n-extra.php:229
4857
  msgid "Auto-rotate log"
4858
  msgstr "Rotation automatique du journal"
4859
 
4860
+ #: lib/i18n-extra.php:230
4861
  msgid ""
4862
  "NinjaFirewall will rotate its log automatically on the very first day of "
4863
  "each month. If your site is very busy, you may want to allow it to rotate "
4868
  "effectuée plus tôt, dans le cas où le journal aurait atteint une certaine "
4869
  "taille (Mo)."
4870
 
4871
+ #: lib/i18n-extra.php:231
4872
  msgid ""
4873
  "By default, if will rotate the log each month or earlier, if it reaches 2 "
4874
  "megabytes."
4875
  msgstr "Par défaut, cette taille est fixée à 2 Mo."
4876
 
4877
+ #: lib/i18n-extra.php:232
4878
  msgid ""
4879
  "Rotated logs, if any, can be selected and viewed from the dropdown menu."
4880
  msgstr ""
4881
  "Les journaux des mois précédents sont accessibles depuis le menu déroulant "
4882
  "situé au dessus de la fenêtre."
4883
 
4884
+ #: lib/i18n-extra.php:233
4885
  msgid "Syslog"
4886
  msgstr "Syslog"
4887
 
4888
+ #: lib/i18n-extra.php:234
4889
  msgid ""
4890
  "In addition to the firewall log, events can also be redirected to the syslog "
4891
  "server (<code>LOG_USER</code> facility)."
4893
  "En plus d'écrire dans son journal, le pare-feu peut aussi utiliser le "
4894
  "serveur Syslog (catégorie <code>LOG_USER</code>)."
4895
 
4896
+ #: lib/i18n-extra.php:235
4897
  msgid ""
4898
  "If you have a shared hosting account, keep this option disabled as you do "
4899
  "not have any access to the server logs."
4901
  "Si vous avez un hébergement mutualisé, laissez cette option désactivée car "
4902
  "vous n'avez pas accès aux journaux du serveur."
4903
 
4904
+ #: lib/i18n-extra.php:236
4905
  msgid "The logline uses the following format:"
4906
  msgstr "Le format utilisé est le suivant :"
4907
 
4908
+ #: lib/i18n-extra.php:237
4909
  msgid ""
4910
  "BB: the level of severity as it appears in the firewall log. It can be "
4911
  "<code>CRITICAL</CODE>, <CODE>HIGH</CODE>, <CODE>MEDIUM</CODE>, <CODE>INFO</"
4916
  "<CODE>MEDIUM</CODE>, <CODE>INFO</CODE>, <CODE>UPLOAD</CODE> ou "
4917
  "<CODE>DEBUG_ON</CODE>."
4918
 
4919
+ #: lib/i18n-extra.php:238
4920
  msgid "CCCCCC: the 7-digit incident ID."
4921
  msgstr "CCCCCC : le numéro d'incident à sept chiffres."
4922
 
4923
+ #: lib/i18n-extra.php:239
4924
  msgid "DD: the user IPv4 or IPv6 address."
4925
  msgstr "DD : L'adresse IPv4 ou IPv6 de l'utilisateur."
4926
 
4927
+ #: lib/i18n-extra.php:240
4928
  msgid "EE: the blog (sub-)domain name."
4929
  msgstr "EE : le nom de (sous-)domaine du blog."
4930
 
4931
+ #: lib/i18n-extra.php:241
4932
  #, php-format
4933
  msgid ""
4934
  "This logging option does not apply to the brute-force protection which can "
4940
  "d'authentification du serveur. Voir le menu de la <a href=\"%s\">Page de "
4941
  "Connexion</a>."
4942
 
4943
+ #: lib/i18n-extra.php:242
4944
  msgid ""
4945
  "Secret key: The secret key will be used to generate your public key. Enter "
4946
  "at least 30 ASCII characters, or use the one randomly created by "
4950
  "de 30 à 100 caractères ASCII, ou bien utilisez la clé générée aléatoirement "
4951
  "par NinjaFirewall."
4952
 
4953
+ #: lib/i18n-extra.php:243
4954
  msgid ""
4955
  "This server IP address: As an additional protection layer, you can restrict "
4956
  "access to the remote website(s) to the main server IP only. You can use IPv4 "
4961
  "à se connecter aux sites distants. Si vous ne souhaitez pas de restriction "
4962
  "d’accès par IP, veuillez entrer le caractère <code>*</code>."
4963
 
4964
+ #: lib/i18n-extra.php:244
4965
  #, php-format
4966
  msgid ""
4967
  "Public key: This is the public key that you will need to upload to each "
4970
  "Clé publique : Vous devez configurer vos sites distants avec cette clé. <a "
4971
  "href=\"%s\">Consultez notre blog</a> pour plus d'info."
4972
 
4973
+ #: lib/i18n-extra.php:245
4974
  msgid ""
4975
  "Remote websites URL: Enter the full URL of your NinjaFirewall protected "
4976
  "website(s) that you want to remotely access from the main server."
4979
  "NinjaFirewall auxquels vous souhaitez accéder à distance à partir du serveur "
4980
  "principal."
4981
 
4982
+ #: lib/i18n-extra.php:246
4983
  msgid ""
4984
  "Centralized Logging will keep working even if NinjaFirewall is disabled. Use "
4985
  "the menu below if you want to disable it."
4988
  "NinjaFirewall. Si vous souhaitez complètement désactiver cette option, "
4989
  "faites-le ci-dessous."
4990
 
4991
+ #: lib/i18n-extra.php:247
4992
  msgid "Enable Web Filter"
4993
  msgstr "Activer Web Filter"
4994
 
4995
+ #: lib/i18n-extra.php:248
4996
  msgid "A full or partial string."
4997
  msgstr "Chaîne de caractère complète ou partielle."
4998
 
4999
+ #: lib/i18n-extra.php:249
5000
  msgid "From 4 to maximum 150 characters."
5001
  msgstr "De 4 à 150 caractères."
5002
 
5003
+ #: lib/i18n-extra.php:250
5004
  msgid "Any character, except the vertical bar <code>|</code>"
5005
  msgstr "Tout caractère, sauf la barre verticale <code>|</code>"
5006
 
5007
+ #: lib/i18n-extra.php:251
5008
  msgid "Keywords to search:"
5009
  msgstr "Mots-clés recherchés :"
5010
 
5011
+ #: lib/i18n-extra.php:252
5012
  msgid "Case-sensitive search"
5013
  msgstr "Recherche sensible à la casse"
5014
 
5015
+ #: lib/i18n-extra.php:253
5016
  #, php-format
5017
  msgid "Do not send me more than one email alert in a %s interval"
5018
  msgstr "Ne pas envoyer plus d'un e-mail par tranche de %s"
5019
 
5020
+ #: lib/i18n-extra.php:254
5021
  msgid "5-minute"
5022
  msgstr "5 minutes"
5023
 
5024
+ #: lib/i18n-extra.php:255
5025
  msgid "15-minute"
5026
  msgstr "15 minutes"
5027
 
5028
+ #: lib/i18n-extra.php:256
5029
  msgid "30-minute"
5030
  msgstr "30 minutes"
5031
 
5032
+ #: lib/i18n-extra.php:257
5033
  msgid "1-hour"
5034
  msgstr "1 heure"
5035
 
5036
+ #: lib/i18n-extra.php:258
5037
  msgid "3-hour"
5038
  msgstr "3 heures"
5039
 
5040
+ #: lib/i18n-extra.php:259
5041
  msgid "6-hour"
5042
  msgstr "6 heures"
5043
 
5044
+ #: lib/i18n-extra.php:260
5045
  msgid "12-hour"
5046
  msgstr "12 heures"
5047
 
5048
+ #: lib/i18n-extra.php:261
5049
  msgid "24-hour"
5050
  msgstr "24 heures"
5051
 
5052
+ #: lib/i18n-extra.php:262
5053
  msgid ""
5054
  "Clicking the \"Save Web Filter options\" button below will reset the current "
5055
  "timer."
5056
  msgstr "Cliquer sur \"Sauvegarder les options\" réinitialisera le compteur."
5057
 
5058
+ #: lib/i18n-extra.php:263
5059
  msgid "Attach the HTML page output to email alerts"
5060
  msgstr "Joindre la page HTML à l'e-mail"
5061
 
5062
+ #: lib/i18n-extra.php:264
5063
  msgid "Save Web Filter options"
5064
  msgstr "Sauvegarder les options"
5065
 
5066
+ #: lib/i18n-extra.php:265
5067
  msgid "Help Desk:"
5068
  msgstr "Help Desk :"
5069
 
5070
+ #: lib/i18n-extra.php:266
5071
  msgid "The selected log was deleted"
5072
  msgstr "Le journal sélectionné a été supprimé"
5073
 
5074
+ #: lib/i18n-extra.php:267
5075
  msgid "Export"
5076
  msgstr "Exporter"
5077
 
5078
+ #: lib/i18n-extra.php:268
5079
  msgid "Delete"
5080
  msgstr "Supprimer"
5081
 
5082
+ #: lib/i18n-extra.php:269
5083
  msgid "Delete log?"
5084
  msgstr "Supprimer le journal ?"
5085
 
5086
+ #: lib/i18n-extra.php:270
5087
  msgid "Today"
5088
  msgstr "Aujourd'hui"
5089
 
5090
+ #: lib/i18n-extra.php:272
5091
  msgid "Upload"
5092
  msgstr "Téléchargement"
5093
 
5094
+ #: lib/i18n-extra.php:273
5095
  msgid "Info"
5096
  msgstr "Info"
5097
 
5098
+ #: lib/i18n-extra.php:274
5099
  msgid "Debug"
5100
  msgstr "Débogage"
5101
 
5102
+ #: lib/i18n-extra.php:275
5103
  msgid "IP address:"
5104
  msgstr "Adresse IP :"
5105
 
5106
+ #: lib/i18n-extra.php:276
5107
  msgid "e.g., 1.2.3.4"
5108
  msgstr "ex : 1.2.3.4"
5109
 
5110
+ #: lib/i18n-extra.php:277
5111
  msgid "Add IP to blacklist"
5112
  msgstr "Ajouter à la liste noire"
5113
 
5114
+ #: lib/i18n-extra.php:278
5115
  msgid "Add IP to whitelist"
5116
  msgstr "Ajouter à la liste blanche"
5117
 
5118
+ #: lib/i18n-extra.php:279
5119
  msgid "Add"
5120
  msgstr "Ajouter"
5121
 
5122
+ #: lib/i18n-extra.php:280
5123
  msgid "The address wad added to your IP Access Control list."
5124
  msgstr "L'adresse a été ajoutée à votre liste du Contrôle d'accès par IP."
5125
 
5126
+ #: lib/i18n-extra.php:281
5127
  #, php-format
5128
  msgid "1st day of the month, or if bigger than %s MB"
5129
  msgstr "Le 1er de chaque mois, ou si sa taille dépasse %s Mo"
5130
 
5131
+ #: lib/i18n-extra.php:282
5132
  msgid "1st day of the month, regardless of its size"
5133
  msgstr "Le 1er de chaque mois, quelle que soit sa taille"
5134
 
5135
+ #: lib/i18n-extra.php:283
5136
  msgid "Show the most recent"
5137
  msgstr "Afficher les dernières"
5138
 
5139
+ #: lib/i18n-extra.php:284
5140
  msgid "lines"
5141
  msgstr "lignes"
5142
 
5143
+ #: lib/i18n-extra.php:285
5144
  msgid "Write events to the Syslog server too"
5145
  msgstr "Enregistrer aussi les événements dans le journal syslog"
5146
 
5147
+ #: lib/i18n-extra.php:286
5148
  msgid "Your server configuration is not compatible with this option."
5149
  msgstr ""
5150
  "La configuration de votre serveur n'est pas compatible avec cette option."
5151
 
5152
+ #: lib/i18n-extra.php:287
5153
  msgid "See contextual help before enabling this option."
5154
  msgstr "Consultez l'aide contextuelle avant d'activer cette option."
5155
 
5156
+ #: lib/i18n-extra.php:288
5157
  msgid ""
5158
  "The remote server rejected your request. Make sure that you uploaded the "
5159
  "correct public key."
5161
  "Le serveur distant a rejeté votre requête. Veuillez vous assurer que la clé "
5162
  "publique est correcte."
5163
 
5164
+ #: lib/i18n-extra.php:289
5165
  #, php-format
5166
  msgid "The remote server returned the following HTTP error: %s"
5167
  msgstr "Le serveur HTTP a retourné le code d'erreur suivant : %s"
5168
 
5169
+ #: lib/i18n-extra.php:290
5170
  msgid "The requested log does not exist on the remote website."
5171
  msgstr "Le journal demandé n'existe pas sur le site distant."
5172
 
5173
+ #: lib/i18n-extra.php:291
5174
  msgid "The remote website did not return the expected response."
5175
  msgstr "Le site distant n'a pas retourné la réponse attendue."
5176
 
5177
+ #: lib/i18n-extra.php:292
5178
  msgid "Your server does not seem to be compatible with this option."
5179
  msgstr ""
5180
  "La configuration de votre serveur n'est pas compatible avec cette option."
5181
 
5182
+ #: lib/i18n-extra.php:293
5183
  msgid "Load language files from the WordPress repo"
5184
  msgstr "Charger les fichiers de langue depuis le WordPress.org"
5185
 
5186
+ #: lib/i18n-extra.php:294
5187
  #, php-format
5188
  msgid ""
5189
  "If available, NinjaFirewall will download the language files from <a "
5192
  "Si disponible, NinjaFirewall téléchargera le fichier de langue à partir de "
5193
  "<a %s>translate.wordpress.org</a>."
5194
 
5195
+ #: lib/i18n-extra.php:295
5196
  msgid "Error: you do not have any license."
5197
  msgstr "Erreur : vous n'avez pas de licence."
5198
 
5199
+ #: lib/i18n-extra.php:296
5200
  msgid "You have a valid license."
5201
  msgstr "Votre licence est valide."
5202
 
5203
+ #: lib/i18n-extra.php:297
5204
  msgid ""
5205
  "An unknown error occured while connecting to NinjaFirewall servers. Please "
5206
  "try again in a few minutes"
5208
  "Une erreur inattendue s'est produite lors de la connexion au serveur de "
5209
  "NinjaFirewall. Merci d'essayer à nouveau dans quelques minutes"
5210
 
5211
+ #: lib/i18n-extra.php:298
5212
  msgid ""
5213
  "An error occured while connecting to NinjaFirewall servers. Please try again "
5214
  "in a few minutes"
5216
  "Une erreur inattendue s'est produite lors de la connexion au serveur de "
5217
  "NinjaFirewall. Merci d'essayer à nouveau dans quelques minutes"
5218
 
5219
+ #: lib/i18n-extra.php:299
5220
  msgid "Enter a valid license to save!"
5221
  msgstr "Veuillez entrer un numéro de licence valide !"
5222
 
5223
+ #: lib/i18n-extra.php:300
5224
  msgid "This is already your current license!"
5225
  msgstr "Cette licence est la même que l'actuelle !"
5226
 
5227
+ #: lib/i18n-extra.php:301
5228
  msgid "Your new license has been accepted and saved."
5229
  msgstr "Votre nouvelle licence a été acceptée et sauvegardée."
5230
 
5231
+ #: lib/i18n-extra.php:302
5232
  msgid "This license is not valid"
5233
  msgstr "Cette licence n'est pas valide"
5234
 
5235
+ #: lib/i18n-extra.php:303
5236
  msgid "WP+ Edition License"
5237
  msgstr "Licence WP+ Edition"
5238
 
5239
+ #: lib/i18n-extra.php:304
5240
  msgid "License Number"
5241
  msgstr "Numéro de Licence"
5242
 
5243
+ #: lib/i18n-extra.php:305
5244
  msgid "No license found"
5245
  msgstr "Aucune licence trouvée"
5246
 
5247
+ #: lib/i18n-extra.php:306
5248
  msgid "Click to check your license validity"
5249
  msgstr "Cliquez pour tester la validité de votre licence"
5250
 
5251
+ #: lib/i18n-extra.php:307
5252
  msgid "Expiration date"
5253
  msgstr "Date d'expiration"
5254
 
5255
+ #: lib/i18n-extra.php:308
5256
  msgid "Unknown expiration date"
5257
  msgstr "Date d'expiration inconnue"
5258
 
5259
+ #: lib/i18n-extra.php:309
5260
  msgid "Use the \"Check License Validity\" button to attempt to fix this error."
5261
  msgstr ""
5262
  "Selectionnez \"Cliquez pour tester la validité de votre licence\" pour "
5263
  "tenter de réparer cette erreur."
5264
 
5265
+ #: lib/i18n-extra.php:310
5266
  msgid "Your license will expire soon!"
5267
  msgstr "Votre licence va bientôt expirer !"
5268
 
5269
+ #: lib/i18n-extra.php:311
5270
  msgid "Your license has expired."
5271
  msgstr "Votre licence a expiré."
5272
 
5273
+ #: lib/i18n-extra.php:312
5274
  msgid "License renewal"
5275
  msgstr "Renouvellement de licence"
5276
 
5277
+ #: lib/i18n-extra.php:313
5278
  msgid "Click here to get a license!"
5279
  msgstr "Cliquez ici pour obtenir une licence !"
5280
 
5281
+ #: lib/i18n-extra.php:314
5282
  msgid "Enter your new license and click on the save button"
5283
  msgstr "Entrez votre licence et cliquez sur le bouton pour l'enregistrer"
5284
 
5285
+ #: lib/i18n-extra.php:315
5286
  msgid "Save New License"
5287
  msgstr "Sauvegarder la Licence"
5288
 
5289
+ #: lib/i18n-extra.php:316
5290
  msgid "Allow, but block dangerous files"
5291
  msgstr "Autoriser, mais bloquer les fichiers dangereux"
5292
 
5293
+ #: lib/i18n-extra.php:317
5294
  msgid "See contextual help for the list of files."
5295
  msgstr ""
5296
  "Consultez l'aide contextuelle pour voir la liste des fichiers concernés."
5297
 
5298
+ #: lib/i18n-extra.php:318
5299
  msgid "Apply to ZIP archives file contents"
5300
  msgstr "Appliquer au contenu des fichiers ZIP"
5301
 
5302
+ #: lib/i18n-extra.php:319
5303
  msgid ""
5304
  "Keep this option disabled if you are using scripts such as Paypal IPN or "
5305
  "WordPress WP-Cron, unless you added their IP address or URL to your Access "
5309
  "WordPress WP-Cron, sauf si vous avez ajouté leur adresse IP ou URL dans la "
5310
  "section \"Contrôle d'Accès\"."
5311
 
5312
+ #: lib/i18n-extra.php:320
5313
  #, php-format
5314
  msgid ""
5315
  "Do not send a notification if the user is in the <a href=\"%s\">IP Access "
5326
  "Erreur : Votre fichier .htaccess n'est pas accessible en écriture. Veuillez "
5327
  "modifier ses autorisations : %s"
5328
 
5329
+ #: lib/install.php:110 ninjafirewall.php:658 ninjafirewall.php:662
5330
  #, php-format
5331
  msgid "Error: wrong parameter value (%s)."
5332
  msgstr "Erreur : Mauvais paramètre (%s)."
5333
 
5334
+ #: lib/install.php:117 lib/install.php:222 lib/install.php:243
5335
  #, php-format
5336
  msgid ""
5337
  "Error: The following file is not writable, please change its permissions: %s"
5356
  "Les modifications ont été annulées. Vous devriez peut-être modifier votre "
5357
  "sélection et réessayer."
5358
 
5359
+ #: lib/install.php:168
5360
  #, php-format
5361
  msgid "The website front-end returned: HTTP %s %s."
5362
  msgstr "La page d'accueil du site a retourné : HTTP %s %s."
5363
 
5364
+ #: lib/install.php:178
5365
  msgid "The website front-end did not return the expected page."
5366
  msgstr "Le site n'a pas retourné la page attendue."
5367
 
5368
+ #: lib/install.php:187
5369
  #, php-format
5370
  msgid "The website front-end returned a fatal error: %s."
5371
  msgstr "La page d'accueil du site a retourné une erreur fatale : %s."
5372
 
5373
+ #: lib/install.php:286 lib/install.php:311 lib/install.php:336
5374
+ #: lib/install.php:357
5375
  msgid "File is not writable"
5376
  msgstr "Le fichier n'est pas accessible en écriture"
5377
 
5604
  msgid "Error: unable to write to the %s configuration file"
5605
  msgstr "Erreur : impossible d’écrire dans le fichier de configuration %s"
5606
 
5607
+ #: lib/logs.php:36 ninjafirewall.php:932
5608
  msgid "Logs"
5609
  msgstr "Journaux"
5610
 
5728
  "et assurez vous que l'option \"Ajouter l'Administrateur à la liste blanche\" "
5729
  "est activée."
5730
 
5731
+ #: lib/logs_live_log.php:96 ninjafirewall.php:375
5732
  msgid ""
5733
  "Live Log lets you watch your blog traffic in real time. To enable it, click "
5734
  "on the button below."
5837
  msgid "Error: please enter the custom log format."
5838
  msgstr "Erreur : veuillez entrer le format d'affichage."
5839
 
5840
+ #: lib/monitoring.php:43 ninjafirewall.php:906
5841
  msgid "Monitoring"
5842
  msgstr "Monitoring"
5843
 
6142
  msgid "Error reading new snapshot file."
6143
  msgstr "Erreur lors de la lecture du fichier du nouvel instantané."
6144
 
6145
+ #: lib/monitoring_file_check.php:748 ninjafirewall.php:479
6146
  msgid "New file"
6147
  msgstr "Nouveau fichier"
6148
 
6149
+ #: lib/monitoring_file_check.php:749 ninjafirewall.php:480
6150
  msgid "Modified file"
6151
  msgstr "Fichier modifié"
6152
 
6153
+ #: lib/monitoring_file_check.php:750 ninjafirewall.php:481
6154
  msgid "Deleted file"
6155
  msgstr "Fichier supprimé"
6156
 
6161
  #: lib/monitoring_file_check.php:777 lib/monitoring_file_check.php:779
6162
  #: lib/monitoring_file_check.php:799 lib/monitoring_file_check.php:801
6163
  #: lib/security_rules_update.php:572 lib/security_rules_update.php:574
6164
+ #: lib/utils.php:225 lib/utils.php:311 lib/utils.php:435 lib/utils.php:1100
6165
+ #: lib/utils.php:1279 lib/utils.php:1558
6166
  msgid "Blog:"
6167
  msgstr "Blog :"
6168
 
6237
  msgid "Save File Guard options"
6238
  msgstr "Sauvegarder les options"
6239
 
6240
+ #: lib/network.php:24 ninjafirewall.php:1193 ninjafirewall.php:1197
6241
  #, php-format
6242
  msgid "You are not allowed to perform this task (%s)."
6243
  msgstr "Vous n'êtes pas autorisé à effectuer cette tâche (%s)."
6263
  msgstr "Sauvegarder les options"
6264
 
6265
  #: lib/security_rules.php:44 lib/security_rules_update.php:578
6266
+ #: ninjafirewall.php:936
6267
  msgid "Security Rules"
6268
  msgstr "Règles de Sécurité"
6269
 
6460
  msgid "Check For Updates Now!"
6461
  msgstr "Vérifier les mises à jour maintenant !"
6462
 
6463
+ #: lib/security_rules_update.php:233 lib/thickbox.php:55
6464
  msgid "Delete Log"
6465
  msgstr "Supprimer le journal"
6466
 
6537
  "Cette notification peut être désactivée depuis la page \"%s\" de "
6538
  "NinjaFirewall."
6539
 
6540
+ #: lib/thickbox.php:45
6541
  msgid "NinjaFirewall error log"
6542
  msgstr "Journal des erreurs de NinjaFirewall"
6543
 
6544
+ #: lib/thickbox.php:55
6545
  msgid "Close Log"
6546
  msgstr "Fermer"
6547
 
6548
+ #: lib/thickbox.php:79
6549
  msgid ""
6550
+ "In Full WAF mode, all scripts located inside the blog installation "
6551
+ "directories and sub-directories are protected by NinjaFirewall. It gives you "
6552
+ "the highest possible level of protection: security without compromise."
 
6553
  msgstr ""
6554
+ "En mode Full WAF, tous les scripts situés dans le répertoire et sous-"
6555
+ "répertoires d'installation de votre blog sont protégés par NinjaFirewall. "
6556
+ "Cela vous offre le niveau de protection le plus élevé possible : La sécurité "
6557
+ "sans aucun compromis."
6558
 
6559
+ #: lib/thickbox.php:81
6560
  #, php-format
6561
  msgid ""
6562
+ "It works on most websites right out of the box, or may require %ssome very "
6563
+ "little tweaks%s. But in a few cases, mostly because of some shared hosting "
6564
+ "plans restrictions, it may simply not work at all."
 
6565
  msgstr ""
6566
  "La plupart du temps, l'installation fonctionne sans aucun problème, ou peut "
6567
+ "nécessiter %squelques petits ajustements%s. Mais dans quelques cas, "
6568
+ "principalement en raison de certaines restrictions d'hébergement partagé, il "
6569
+ "se peut que l'installation ne puisse pas fonctionner du tout."
 
6570
 
6571
+ #: lib/thickbox.php:83
6572
  msgid ""
6573
+ "If this happened to you, don't worry: you could still run it in WordPress "
6574
+ "WAF mode. Despite being less powerful than the Full WAF mode, it offers a "
6575
+ "level of protection and performance much higher than other security plugins."
 
6576
  msgstr ""
6577
  "Si cela se produisait, ne vous inquiétez pas : vous pourrez l'utiliser en "
6578
+ "mode WordPress WAF. Bien que moins puissant que le mode Full WAF, il offre "
6579
+ "tout de même des performances et un niveau de protection très supérieur aux "
6580
+ "autres extensions de sécurité pour WordPress disponibles sur le marché."
 
6581
 
6582
+ #: lib/thickbox.php:157
6583
  msgid "Select your HTTP server and your PHP server API"
6584
  msgstr "Sélectionnez votre serveur HTTP et PHP SAPI"
6585
 
6586
+ #: lib/thickbox.php:168
6587
  msgid "Other webserver + CGI/FastCGI or PHP-FPM"
6588
  msgstr "Autre serveur + CGI/FastCGI ou PHP-FPM"
6589
 
6590
+ #: lib/thickbox.php:170
6591
  msgid "View PHPINFO"
6592
  msgstr "Voir PHPINFO"
6593
 
6594
+ #: lib/thickbox.php:202
6595
  msgid "Select the PHP initialization file supported by your server"
6596
  msgstr ""
6597
  "Sélectionnez le type de fichier de configuration PHP utilisé par votre "
6598
  "serveur"
6599
 
6600
+ #: lib/thickbox.php:213
6601
+ msgid "Folders protected by NinjaFirewall"
6602
+ msgstr "Répertoires protégés par NinjaFirewall"
6603
+
6604
+ #: lib/thickbox.php:215 lib/thickbox.php:362
6605
+ msgid "WordPress root directory:"
6606
+ msgstr "Répertoire racine de WordPress :"
6607
+
6608
+ #: lib/thickbox.php:220 lib/thickbox.php:367
6609
+ msgid ""
6610
+ "The following folders will be protected by NinjaFirewall. If you want to "
6611
+ "exclude some of them, uncheck them in the list below:"
6612
+ msgstr ""
6613
+ "Les dossiers suivants seront protégés par NinjaFirewall. Si vous souhaitez "
6614
+ "en exclure certains, décochez-les dans la liste ci-dessous :"
6615
+
6616
+ #: lib/thickbox.php:226
6617
+ msgid ""
6618
+ "After setting up the Full WAF mode, you could come back to this page to re-"
6619
+ "configure it whenever you want."
6620
+ msgstr ""
6621
+ "Après avoir configuré le mode Full WAF, vous pourrez revenir sur cette page "
6622
+ "pour le reconfigurer quand vous le souhaitez."
6623
+
6624
+ #: lib/thickbox.php:234
6625
  msgid "Let NinjaFirewall make the necessary changes (recommended)."
6626
  msgstr "Laissez NinjaFirewall faire les changements (recommandé)."
6627
 
6628
+ #: lib/thickbox.php:236
6629
  msgid "I want to make the changes myself."
6630
  msgstr "Je veux faire les changements moi-même."
6631
 
6632
+ #: lib/thickbox.php:238
6633
  msgid ""
6634
  "Please make the changes below, then click on the \"Finish Installation\" "
6635
  "button."
6637
  "Veuillez faire les modifications ci-dessous, puis cliquer sur le bouton "
6638
  "\"Finaliser l'installation\"."
6639
 
6640
+ #: lib/thickbox.php:245
6641
  #, php-format
6642
  msgid ""
6643
  "The %s file must be created, and the following lines of code added to it:"
6645
  "Le fichier %s doit être créé, et les lignes suivantes doivent y être "
6646
  "ajoutées :"
6647
 
6648
+ #: lib/thickbox.php:246
6649
  #, php-format
6650
  msgid "The following lines of code must be added to your existing %s file:"
6651
  msgstr "Les lignes suivantes doivent être ajoutées à votre fichier %s :"
6652
 
6653
+ #: lib/thickbox.php:314
 
6654
  msgid ""
6655
  "Log in to your Openlitespeed admin dashboard, click on \"Virtual Host\", "
6656
  "select your domain, add the following instructions to the \"php.ini Override"
6657
+ "\" section in the \"General\" tab, and restart Openlitespeed:"
 
6658
  msgstr ""
6659
  "Connectez-vous à votre tableau de bord Openlitespeed, cliquez sur \"Virtual "
6660
  "Host\", sélectionnez votre domaine, ajoutez les instructions suivantes à la "
6661
  "section \"php.ini Override\" de l'onglet \"Général\", puis redémarrez "
6662
+ "Openlitespeed:"
6663
 
6664
+ #: lib/thickbox.php:321
6665
  msgid ""
6666
  "Important: if one day you wanted to uninstall NinjaFirewall, do not forget "
6667
  "to remove these instructions from your Openlitespeed admin dashboard "
6673
  "<strong>avant</strong> de désinstaller NinjaFirewall, car cet installateur "
6674
  "ne pourra pas le faire à votre place."
6675
 
6676
+ #: lib/thickbox.php:337
6677
  msgid "Enable the sandbox."
6678
  msgstr "Activer l'environnement de test (sandbox)."
6679
 
6680
+ #: lib/thickbox.php:337
6681
  msgid ""
6682
  "If there were a problem during the installation, NinjaFirewall would undo "
6683
  "those changes automatically for you."
6685
  "S'il y avait un problème lors de l'installation, NinjaFirewall annulerait "
6686
  "ces modifications automatiquement pour vous."
6687
 
6688
+ #: lib/thickbox.php:338
6689
  msgid "Finish Installation"
6690
  msgstr "Finaliser l'installation"
6691
 
6692
+ #: lib/thickbox.php:356
6693
+ msgid "Configuration"
6694
+ msgstr "Configuration"
6695
+
6696
+ #: lib/thickbox.php:360
6697
+ msgid "Full WAF mode"
6698
+ msgstr "Mode Full WAF"
6699
+
6700
+ #: lib/thickbox.php:374
6701
+ msgid "Save Changes"
6702
+ msgstr "Sauvegarder les modifications"
6703
+
6704
+ #: lib/thickbox.php:385
6705
+ msgid "WordPress WAF mode"
6706
+ msgstr "Mode WordPress WAF"
6707
+
6708
+ #: lib/thickbox.php:392
6709
+ msgid ""
6710
+ "If you want to downgrade to WordPress WAF mode, log in to your Openlitespeed "
6711
+ "admin dashboard, click on \"Virtual Host\", select your domain and remove "
6712
+ "the \"auto_prepend_file\" directive from the \"php.ini Override\" section in "
6713
+ "the \"General\" tab, and restart Openlitespeed."
6714
+ msgstr ""
6715
+ "Si vous souhaitez revenir au mode WordPress WAF, connectez-vous à votre "
6716
+ "tableau de bord Openlitespeed, cliquez sur \"Virtual Host\", sélectionnez "
6717
+ "votre domaine, enlevez la directive \"auto_prepend_file\" de la section "
6718
+ "\"php.ini Override\" de l'onglet \"Général\", puis redémarrez Openlitespeed."
6719
+
6720
+ #: lib/thickbox.php:393 lib/thickbox.php:400
6721
+ msgid "Downgrade to WordPress WAF mode"
6722
+ msgstr "Revenir au mode WordPress WAF"
6723
+
6724
+ #: lib/thickbox.php:397
6725
+ msgid "If you want to downgrade to WordPress WAF mode, click the button below."
6726
+ msgstr ""
6727
+ "Si vous souhaitez revenir au mode WordPress WAF, cliquez sur le bouton ci-"
6728
+ "dessous."
6729
+
6730
+ #: lib/thickbox.php:402
6731
+ msgid "You may have to wait five minutes for the changes to take effect."
6732
+ msgstr ""
6733
+ "Vous devrez peut-être attendre cinq minutes pour que les modifications "
6734
+ "prennent effet."
6735
+
6736
+ #: lib/thickbox.php:409
6737
+ msgid "Cancel and Close"
6738
+ msgstr "Annuler et Fermer"
6739
+
6740
  #: lib/utils.php:183 lib/utils.php:191 lib/utils.php:295
6741
  msgid "N/A"
6742
  msgstr "N/A"
6767
  "NinjaFirewall a bloqué une tentative de modification/création d'une page ou "
6768
  "d'un article par un utilisateur qui n'avait pas les capacités nécessaires :"
6769
 
6770
+ #: lib/utils.php:226 lib/utils.php:312 lib/utils.php:436 lib/utils.php:1283
6771
  msgid "Username:"
6772
  msgstr "Utilisateur :"
6773
 
6775
  msgid "Action:"
6776
  msgstr "Action :"
6777
 
6778
+ #: lib/utils.php:230 lib/utils.php:315 lib/utils.php:437 lib/utils.php:1287
6779
+ #: lib/utils.php:1559
6780
  msgid "User IP:"
6781
  msgstr "IP utilisateur :"
6782
 
6783
+ #: lib/utils.php:242 lib/utils.php:327 lib/utils.php:449 lib/utils.php:1299
6784
+ #: lib/utils.php:1554
6785
  msgid "A PHP backtrace has been attached to this message for your convenience."
6786
  msgstr ""
6787
  "La pile d'exécution de PHP est jointe à ce message pour votre commodité."
6788
 
6789
+ #: lib/utils.php:244 lib/utils.php:329 lib/utils.php:1302 lib/utils.php:1564
6790
  msgid ""
6791
  "This protection (and notification) can be turned off from NinjaFirewall "
6792
  "\"Firewall Policies\" page."
6795
  "\"Politiques du Pare-feu\" de NinjaFirewall."
6796
 
6797
  #: lib/utils.php:259 lib/utils.php:260 lib/utils.php:344 lib/utils.php:345
6798
+ #: lib/utils.php:466 lib/utils.php:467 lib/utils.php:1318 lib/utils.php:1319
6799
  msgid "You are not allowed to perform this task."
6800
  msgstr "Vous n'êtes pas autorisé à effectuer cette tâche."
6801
 
6820
  msgstr ""
6821
  "NinjaFirewall a bloqué une tentative de création d'un compte d'utilisateur :"
6822
 
6823
+ #: lib/utils.php:767
6824
  msgid ""
6825
  "Warning: Because NinjaFirewall's Login Protection is enabled, Site Health "
6826
  "may return an error message regarding the loopback test (e.g., 404 or 401 "
6831
  "concernant le test de la requête de bouclage (ex.: code d’état HTTP 404 ou "
6832
  "401). Vous pouvez l'ignorer en toute sécurité."
6833
 
6834
+ #: lib/utils.php:790 lib/utils.php:794
6835
  msgid "NinjaFirewall error"
6836
  msgstr "NinjaFirewall Erreur"
6837
 
6838
+ #: lib/utils.php:791
6839
  #, php-format
6840
  msgid ""
6841
  "%s directory cannot be created. Please review your installation and ensure "
6844
  "Le répertoire %s ne peut pas être créé. Vérifiez votre installation et "
6845
  "assurez vous que %s n'est pas en lecture seule."
6846
 
6847
+ #: lib/utils.php:795
6848
  #, php-format
6849
  msgid ""
6850
  "%s directory is read-only. Please review your installation and ensure that "
6853
  "Le répertoire %s est en lecture seule. Vérifiez votre installation et les "
6854
  "permissions de %s."
6855
 
6856
+ #: lib/utils.php:810
6857
  msgid "unknown error"
6858
  msgstr "erreur inconnue"
6859
 
6860
+ #: lib/utils.php:812
6861
  msgid "NinjaFirewall fatal error:"
6862
  msgstr "NinjaFirewall erreur fatale :"
6863
 
6864
+ #: lib/utils.php:813
6865
  msgid "Review your installation, your site is not protected."
6866
  msgstr "Vérifiez votre installation, votre site n'est pas protégé."
6867
 
6868
+ #: lib/utils.php:840
6869
  msgid "Alert: WordPress console login"
6870
  msgstr "Alerte : Connexion à WordPress"
6871
 
6872
+ #: lib/utils.php:846
6873
  msgid "Someone just logged in to your WordPress admin console:"
6874
  msgstr "Quelqu'un vient de se connecter à votre Tableau de bord de WordPress:"
6875
 
6876
+ #: lib/utils.php:966 lib/utils.php:993
6877
  msgid "Forbidden access"
6878
  msgstr "Accès interdit"
6879
 
6880
+ #: lib/utils.php:1012
6881
  #, php-format
6882
  msgid ""
6883
  "<strong>ERROR</strong>: Invalid username, email address or password.<br /><a "
6886
  "<strong>ERREUR</strong>: Identifiant, email ou mot de passe invalide.<br /"
6887
  "><a href=\"%s\">Mot de passe perdu</a> ?"
6888
 
6889
+ #: lib/utils.php:1096
6890
  msgid "[NinjaFirewall] Alert: Database changes detected"
6891
  msgstr "[NinjaFirewall] Alerte: Modification dans la base de données"
6892
 
6893
+ #: lib/utils.php:1097
6894
  msgid ""
6895
  "NinjaFirewall has detected that one or more administrator accounts were "
6896
  "modified in the database:"
6898
  "NinjaFirewall a détecté que un ou plusieurs comptes d'administrateur ont été "
6899
  "modifiés dans la base de données:"
6900
 
6901
+ #: lib/utils.php:1102
6902
  #, php-format
6903
  msgid "Total administrators : %s"
6904
  msgstr "Nombre d'administrateurs : %s"
6905
 
6906
+ #: lib/utils.php:1111
6907
  msgid ""
6908
  "If you cannot see any modifications in the above fields, it is possible that "
6909
  "the administrator password was changed."
6911
  "Si vous ne voyez pas de modifications dans les données ci-dessus, il est "
6912
  "possible que le mot de passe administrateur ait été changé."
6913
 
6914
+ #: lib/utils.php:1264
6915
  msgid "Blocked privilege escalation attempt"
6916
  msgstr "Tentatives d'élévation des privilèges"
6917
 
6918
+ #: lib/utils.php:1277
6919
  msgid ""
6920
  "NinjaFirewall has blocked an attempt to modify a user capability by someone "
6921
  "who does not have administrative privileges:"
6923
  "NinjaFirewall a bloqué une tentative de modification de certaines Capacités "
6924
  "par un utilisateur ne disposant pas de privilèges administratifs :"
6925
 
6926
+ #: lib/utils.php:1330
6927
  msgid ""
6928
  "NinjaFirewall brute-force protection is enabled and you are temporarily "
6929
  "whitelisted."
6931
  "La protection de NinjaFirewall contre les attaques par force brute est "
6932
  "activée. Vous êtes temporairement dans la liste blanche."
6933
 
6934
+ #: lib/utils.php:1345
6935
  #, php-format
6936
  msgid ""
6937
  "Hey, it seems that you've been using NinjaFirewall for some time. If you "
6944
  "a>. Il a fallu des milliers d'heures pour le développer, mais il suffit "
6945
  "seulement de quelques minutes pour le noter. Merci !"
6946
 
6947
+ #: lib/utils.php:1526
6948
  msgid ""
6949
  "The attempt was blocked and the option was reversed to its original value."
6950
  msgstr ""
6951
  "La tentative a été bloquée et l'option a été remise à sa valeur d'origine."
6952
 
6953
+ #: lib/utils.php:1531
6954
  msgid "Attempt to modify WordPress settings"
6955
  msgstr "Tentative de modification des paramètres de WordPress"
6956
 
6957
+ #: lib/utils.php:1532
6958
  msgid ""
6959
  "NinjaFirewall has blocked an attempt to modify some important WordPress "
6960
  "settings by a user that does not have administrative privileges:"
6963
  "importants de WordPress par un utilisateur ne disposant pas de privilèges "
6964
  "administratifs :"
6965
 
6966
+ #: lib/utils.php:1533 lib/utils.php:1542
6967
  #, php-format
6968
  msgid "Option: %s"
6969
  msgstr "Option: %s"
6970
 
6971
+ #: lib/utils.php:1534
6972
  #, php-format
6973
  msgid "Original value: %s"
6974
  msgstr "Valeur originale : %s"
6975
 
6976
+ #: lib/utils.php:1535
6977
  #, php-format
6978
  msgid "Modified value: %s"
6979
  msgstr "Valeur modifiée : %s"
6980
 
6981
+ #: lib/utils.php:1536 lib/utils.php:1544
6982
  #, php-format
6983
  msgid "Action taken: %s"
6984
  msgstr "Action prise : %s"
6985
 
6986
+ #: lib/utils.php:1540
6987
  msgid "Code injection attempt in WordPress options table"
6988
  msgstr "Tentative d'injection de code dans la table des options de WordPress"
6989
 
6990
+ #: lib/utils.php:1541
6991
  msgid ""
6992
  "NinjaFirewall has blocked an attempt to inject code in the WordPress options "
6993
  "table by a user that does not have administrative privileges:"
6996
  "options de WordPress par un utilisateur ne disposant pas de privilèges "
6997
  "administratifs :"
6998
 
6999
+ #: lib/utils.php:1543
7000
  #, php-format
7001
  msgid "Code: %s"
7002
  msgstr "Code : %s"
7003
 
7004
+ #: lib/utils.php:1624
7005
+ msgid "Important: NinjaFirewall has detected that this is a security update."
7006
+ msgstr ""
7007
+ "Important : NinjaFirewall a détecté que ceci est un mise à jour de sécurité."
7008
+
7009
+ #: lib/utils.php:1627
7010
+ msgid "More info about this warning."
7011
+ msgstr "En savoir plus."
7012
+
7013
+ #: lib/utils.php:1647
7014
  #, php-format
7015
  msgid "Error, cannot create the %s folder."
7016
  msgstr "Erreur, impossible de créer le répertoire %s."
7017
 
7018
+ #: lib/utils.php:1648 lib/utils.php:1657 lib/utils.php:1666
7019
  msgid "Check your server permissions and try again."
7020
  msgstr "Vérifiez les autorisations de votre serveur et réessayez."
7021
 
7022
+ #: lib/utils.php:1656
7023
  #, php-format
7024
  msgid "Error, the %s folder is not writable."
7025
  msgstr "Erreur, le répertoire %s est en lecture seule."
7026
 
7027
+ #: lib/utils.php:1665
7028
  #, php-format
7029
  msgid "Error, cannot write %s."
7030
  msgstr "Erreur, impossible d'écrire dans %s."
7593
  msgid "NinjaFirewall is not compatible with Microsoft Windows."
7594
  msgstr "NinjaFirewall n'est pas compatible avec Microsoft Windows."
7595
 
7596
+ #: ninjafirewall.php:326
7597
  msgid ""
7598
  "All fields will be restored to their default values and any changes you made "
7599
  "will be lost. Continue?"
7601
  "Tous les champs vont être re-initialisés et vos changements seront perdus. "
7602
  "Continuer ?"
7603
 
7604
+ #: ninjafirewall.php:330
7605
  msgid "Missing security nonce, try to reload the page."
7606
  msgstr "La nonce de sécurité est manquante, essayer de recharger cette page."
7607
 
7608
+ #: ninjafirewall.php:332
7609
  msgid "Please select the HTTP server in the list."
7610
  msgstr "Sélectionnez votre serveur HTTP dans la list."
7611
 
7612
+ #: ninjafirewall.php:335
7613
  msgid "Delete the firewall's error log ?"
7614
  msgstr "Supprimer le journal des erreurs ?"
7615
 
7616
+ #: ninjafirewall.php:339
7617
  msgid ""
7618
  "This action will restore the selected configuration file and will override "
7619
  "all your current firewall options, policies and rules. Continue?"
7622
  "remplacera toutes les options, politiques et règles de pare-feu actuelles. "
7623
  "Continuer ?"
7624
 
7625
+ #: ninjafirewall.php:343
7626
  msgid ""
7627
  "Any character that is not a letter [a-zA-Z], a digit [0-9], a dot [.], a "
7628
  "hyphen [-] or an underscore [_] will be removed from the filename and "
7632
  "[.], un trait d'union[-] ou un caractère de soulignement[_], sera supprimé "
7633
  "du nom du fichier et remplacé par le caractère de substitution. Continuer ?"
7634
 
7635
+ #: ninjafirewall.php:345
7636
  msgid ""
7637
  "Ensure that you can access your admin console over HTTPS before enabling "
7638
  "this option, otherwise you will lock yourself out of your site. Continue?"
7641
  "option, sinon vous risqueriez de ne plus pouvoir accéder à l'interface "
7642
  "d'administration. Continuer ?"
7643
 
7644
+ #: ninjafirewall.php:347
7645
  msgid ""
7646
  "WooCommerce is running: if you block accounts creation, your customers won't "
7647
  "be able to sign up. Continue?"
7649
  "WooCommerce est activé : si vous bloquez la création de comptes, vos clients "
7650
  "ne pourront pas s'enregistrer. Continuer ?"
7651
 
7652
+ #: ninjafirewall.php:349
7653
  msgid ""
7654
  "Your blog has user registration enabled: if you block accounts creation, "
7655
  "your customers won't be able to sign up. Continue?"
7657
  "Votre blog accepte les inscriptions : si vous bloquez la création de "
7658
  "comptes, vos clients ne pourront plus s'inscrire. Continuer ?"
7659
 
7660
+ #: ninjafirewall.php:351
7661
  msgid ""
7662
  "Your multisite installation allows users to register new sites: if you "
7663
  "enable this option, they will likely get blocked when creating their blog. "
7666
  "Les utilisateurs sont autorisés a créer des nouveaux sites : si vous activez "
7667
  "cette option, ils ne pourront plus le faire. Continuer ?"
7668
 
7669
+ #: ninjafirewall.php:355
7670
  msgid "Delete the current snapshot ?"
7671
  msgstr "Supprimer l'instantané actuel ?"
7672
 
7673
+ #: ninjafirewall.php:359
7674
  msgid "Invalid character."
7675
  msgstr "Caractère invalide."
7676
 
7677
+ #: ninjafirewall.php:361
7678
  msgid "\"admin\" is not acceptable, please choose another user name."
7679
  msgstr ""
7680
  "\"admin\" n\\'est pas acceptable, merci de bien vouloir choisir un autre "
7681
  "identifiant."
7682
 
7683
+ #: ninjafirewall.php:363
7684
  msgid "Please enter max 1024 character only."
7685
  msgstr "Veuillez ne pas entrer plus de 1 024 caractères."
7686
 
7687
+ #: ninjafirewall.php:365
7688
  msgid "Select when to enable the login protection."
7689
  msgstr "Veuillez sélectionner quand activer la protection."
7690
 
7691
+ #: ninjafirewall.php:367
7692
  msgid "Enter a name and a password for the HTTP authentication."
7693
  msgstr ""
7694
  "Veuillez entrer un nom d'utilisateur et mot de passe pour l'authentification "
7695
  "HTTP."
7696
 
7697
+ #: ninjafirewall.php:371
7698
  msgid "Your public key is not valid."
7699
  msgstr "Votre clé publique n\\'est pas valide."
7700
 
7701
+ #: ninjafirewall.php:377
7702
  msgid "No traffic yet, please wait"
7703
  msgstr "Aucun visiteur actuellement, veuillez patienter"
7704
 
7705
+ #: ninjafirewall.php:379
7706
  msgid "seconds..."
7707
  msgstr "secondes..."
7708
 
7709
+ #: ninjafirewall.php:381
7710
  msgid "Error: Live Log did not receive the expected response from your server:"
7711
  msgstr "Erreur : le serveur distant n\\'a pas retourné la réponse attendue :"
7712
 
7713
+ #: ninjafirewall.php:383
7714
  msgid "Error: URL does not seem to exist (404 Not Found):"
7715
  msgstr "Erreur : l'URL ne semble pas exister (404 Not Found) :"
7716
 
7717
+ #: ninjafirewall.php:385
7718
  msgid "Error: Cannot find your log file. Try to reload this page."
7719
  msgstr ""
7720
  "Erreur : Impossible de trouver le fichier log. Essayez de recharger cette "
7721
  "page."
7722
 
7723
+ #: ninjafirewall.php:387
7724
  msgid "Error: The HTTP server returned the following error code:"
7725
  msgstr "Erreur : Le serveur HTTP a retourné le code d'erreur suivant :"
7726
 
7727
+ #: ninjafirewall.php:643 ninjafirewall.php:763 ninjafirewall.php:832
7728
  msgid "Error: Security nonces do not match. Reload the page and try again."
7729
  msgstr ""
7730
  "Erreur : Les nonces de sécurité ne correspondent pas. Veuillez recharger "
7731
  "cette page."
7732
 
7733
+ #: ninjafirewall.php:649
7734
  msgid "Error: NinjaFirewall is disabled"
7735
  msgstr "Erreur : NinjaFirewall est désactivé"
7736
 
7737
+ #: ninjafirewall.php:654 ninjafirewall.php:768 ninjafirewall.php:798
7738
  #, php-format
7739
  msgid "Error: missing parameter (%s)."
7740
  msgstr "Erreur : Paramètre manquant (%s)."
7741
 
7742
+ #: ninjafirewall.php:894
7743
  msgid "NinjaFirewall: Dashboard"
7744
  msgstr "NinjaFirewall : Tableau de Bord"
7745
 
7746
+ #: ninjafirewall.php:898
7747
  msgid "NinjaFirewall: Firewall Options"
7748
  msgstr "NinjaFirewall : Options du Pare-feu"
7749
 
7750
+ #: ninjafirewall.php:902
7751
  msgid "NinjaFirewall: Firewall Policies"
7752
  msgstr "NinjaFirewall : Politiques du Pare-feu"
7753
 
7754
+ #: ninjafirewall.php:906
7755
  msgid "NinjaFirewall: Monitoring"
7756
  msgstr "NinjaFirewall : Monitoring"
7757
 
7758
+ #: ninjafirewall.php:916
7759
  msgid "NinjaFirewall: Anti-Malware"
7760
  msgstr "NinjaFirewall : Anti-Malware"
7761
 
7762
+ #: ninjafirewall.php:920
7763
  msgid "NinjaFirewall: Network"
7764
  msgstr "NinjaFirewall : Réseau"
7765
 
7766
+ #: ninjafirewall.php:924
7767
  msgid "NinjaFirewall: Event Notifications"
7768
  msgstr "NinjaFirewall : Notifications d’Événement"
7769
 
7770
+ #: ninjafirewall.php:928
7771
  msgid "NinjaFirewall: Log-in Protection"
7772
  msgstr "NinjaFirewall : Page de Connexion"
7773
 
7774
+ #: ninjafirewall.php:932
7775
  msgid "NinjaFirewall: Logs"
7776
  msgstr "NinjaFirewall : Journaux"
7777
 
7778
+ #: ninjafirewall.php:936
7779
  msgid "NinjaFirewall: Security Rules"
7780
  msgstr "NinjaFirewall : Règles de Sécurité"
7781
 
7782
+ #: ninjafirewall.php:980
7783
  msgid "NinjaFirewall Settings"
7784
  msgstr "Réglages de NinjaFirewall"
7785
 
7786
+ #: ninjafirewall.php:988
7787
  msgid "NinjaFirewall is enabled"
7788
  msgstr "NinjaFirewall est activé"
7789
 
7790
+ #: ninjafirewall.php:1128
7791
  msgid "Access Restricted"
7792
  msgstr "Accès limité"
7793
 
7794
+ #: ninjafirewall.php:1134
7795
  msgid "Settings"
7796
  msgstr "Réglages"
7797
 
7798
+ #: ninjafirewall.php:1135
7799
  msgid "Upgrade to Premium"
7800
  msgstr "Passez Premium !"
7801
 
7802
+ #: ninjafirewall.php:1136
7803
  msgid "Rate it!"
7804
  msgstr "Notez-le !"
7805
 
7806
+ #, php-format
7807
+ #~ msgid ""
7808
+ #~ "Log in to your Openlitespeed admin dashboard, click on \"Virtual Host\", "
7809
+ #~ "select your domain, add the following instructions to the \"php.ini "
7810
+ #~ "Override\" section in the \"General\" tab, and restart Openlitespeed (see "
7811
+ #~ "more detail <a %s>here</a>):"
7812
+ #~ msgstr ""
7813
+ #~ "Connectez-vous à votre tableau de bord Openlitespeed, cliquez sur "
7814
+ #~ "\"Virtual Host\", sélectionnez votre domaine, ajoutez les instructions "
7815
+ #~ "suivantes à la section \"php.ini Override\" de l'onglet \"Général\", puis "
7816
+ #~ "redémarrez Openlitespeed (consultez <a %s>cet article</a> pour plus "
7817
+ #~ "d'info) :"
7818
+
7819
+ #, php-format
7820
+ #~ msgid ""
7821
+ #~ "It is awesome and includes many great features: <a href=\"%s\">check it "
7822
+ #~ "out!</a>"
7823
+ #~ msgstr ""
7824
+ #~ "Il est beaucoup mieux et comprend de nombreuses fonctionnalités : <a href="
7825
+ #~ "\"%s\">En savoir plus</a>"
7826
+
7827
+ #~ msgid "WordPress WAF"
7828
+ #~ msgstr "WordPress WAF"
7829
+
7830
+ #~ msgid "Full WAF"
7831
+ #~ msgstr "Full WAF"
7832
+
7833
+ #, php-format
7834
+ #~ msgid "<a href=\"%s\">Consult our blog</a> for more info."
7835
+ #~ msgstr ""
7836
+ #~ "<a href=\"%s\">Consultez notre blog pour plus d'informations à ce sujet</"
7837
+ #~ "a>."
7838
+
7839
+ #, php-format
7840
+ #~ msgid "Set %s (IE/Edge, Chrome, Opera and Safari browsers)"
7841
+ #~ msgstr "Activer %s (IE/Edge, Opera, Chrome et Safari)"
7842
+
7843
+ #~ msgid ""
7844
+ #~ "Set <code>X-XSS-Protection</code> (IE/Edge, Chrome, Opera and Safari "
7845
+ #~ "browsers)"
7846
+ #~ msgstr ""
7847
+ #~ "Activer <code>X-XSS-Protection</code> (IE/Edge, Opera, Chrome et Safari)"
7848
+
7849
+ #~ msgid ""
7850
+ #~ "If a visitor disabled their browser's XSS filter, you cannot re-enable it "
7851
+ #~ "with that option."
7852
+ #~ msgstr ""
7853
+ #~ "Si un visiteur désactive le filtre XSS de son navigateur, vous ne pouvez "
7854
+ #~ "pas le réactiver avec cette option."
7855
+
7856
+ #, php-format
7857
+ #~ msgid ""
7858
+ #~ "You are running NinjaFirewall in <i>WordPress WAF</i> mode. All URL-based "
7859
+ #~ "features such as <i>Geolocation</i> and <i>URL Access Control</i> will be "
7860
+ #~ "limited to WordPress files only (e.g., index.php, wp-login.php, xmlrpc."
7861
+ #~ "php, admin-ajax.php, wp-load.php etc). If you want them to apply to any "
7862
+ #~ "PHP script, please <a href=\"%s\">go to the Dashboard page</a> and enable "
7863
+ #~ "NinjaFirewall's Full WAF mode."
7864
+ #~ msgstr ""
7865
+ #~ "NinjaFirewall fonctionne en mode <i>WordPress WAF</i>. Toutes les "
7866
+ #~ "fonctionnalités basées sur les URL comme la <i>Géolocalisation</i> et le "
7867
+ #~ "<i>Contrôle d'accès par URL</i> seront limitées à certains fichiers "
7868
+ #~ "WordPress uniquement (par ex. index.php, wp-login.php, xmlrpc.php, admin-"
7869
+ #~ "ajax.php, wp-load.php etc). Si vous voulez que cette option s'applique à "
7870
+ #~ "tous les fichiers PHP, allez dans le <a href=\"%s\">Tableau de Bord</a> "
7871
+ #~ "et activez son mode Full WAF."
7872
+
7873
+ #~ msgid "<code>GET</code>"
7874
+ #~ msgstr "<code>GET</code>"
7875
+
7876
+ #~ msgid "<code>POST</code>"
7877
+ #~ msgstr "<code>POST</code>"
7878
+
7879
+ #~ msgid "<code>HEAD</code>"
7880
+ #~ msgstr "<code>HEAD</code>"
7881
+
7882
+ #~ msgid "<code>PUT</code>"
7883
+ #~ msgstr "<code>PUT</code>"
7884
+
7885
+ #~ msgid "<code>DELETE</code>"
7886
+ #~ msgstr "<code>DELETE</code>"
7887
+
7888
+ #~ msgid "<code>PATCH</code>"
7889
+ #~ msgstr "<code>PATCH</code>"
7890
+
7891
+ #~ msgid ""
7892
+ #~ "Allowed characters are: <code>a-zA-Z</code> <code>0-9</code> <code>.</"
7893
+ #~ "code> <code>-</code> <code>_</code> <code>:</code> <code>/</code> and "
7894
+ #~ "<code>space</code>."
7895
+ #~ msgstr ""
7896
+ #~ "Cataractes autorisés : <code>a-zA-Z</code> <code>0-9</code> <code>.</"
7897
+ #~ "code> <code>-</code> <code>_</code> <code>:</code> <code>/</code> et "
7898
+ #~ "<code>space</code>."
7899
+
7900
+ #~ msgid ""
7901
+ #~ "A <code>GET</code>, <code>POST</code> or <code>COOKIE</code> global "
7902
+ #~ "variable, followed by <code>:</code> (colon) and the case-sensitive input:"
7903
+ #~ msgstr ""
7904
+ #~ "Une variable <code>GET</code>, <code>POST</code> ou <code>COOKIE</code>, "
7905
+ #~ "suivie de <code>:</code> (deux points) et de l'entrée, sensible à la "
7906
+ #~ "casse :"
7907
+
7908
+ #~ msgid ""
7909
+ #~ "In <strong>Full WAF</strong> mode, all scripts located inside the blog "
7910
+ #~ "installation directories and sub-directories are protected by "
7911
+ #~ "NinjaFirewall, including those that aren't part of the WordPress package. "
7912
+ #~ "It gives you the highest possible level of protection: security without "
7913
+ #~ "compromise."
7914
+ #~ msgstr ""
7915
+ #~ "En mode <strong>Full WAF</strong>, tous les scripts situés dans le "
7916
+ #~ "répertoire et sous-répertoires d'installation de votre blog sont "
7917
+ #~ "protégés, y compris ceux qui ne font pas partie de WordPress. Cela vous "
7918
+ #~ "offre le niveau de protection le plus élevé possible : La sécurité sans "
7919
+ #~ "aucun compromis."
7920
+
7921
+ #, php-format
7922
+ #~ msgid ""
7923
+ #~ "It works on most websites right out of the box, or may require <a href="
7924
+ #~ "\"%s\" title=\"%s\">some very little tweaks</a>. But in a few cases, "
7925
+ #~ "mostly because of some shared hosting plans restrictions, it may simply "
7926
+ #~ "not work at all."
7927
+ #~ msgstr ""
7928
+ #~ "La plupart du temps, l'installation fonctionne sans aucun problème, ou "
7929
+ #~ "peut nécessiter <a href=\"%s\" title=\"%s\">quelques petits ajustements</"
7930
+ #~ "a>. Mais dans quelques cas, principalement en raison de certaines "
7931
+ #~ "restrictions d'hébergement partagé, il se peut que l'installation ne "
7932
+ #~ "puisse pas fonctionner du tout."
7933
+
7934
+ #~ msgid ""
7935
+ #~ "If this happened to you, don't worry: you could still run it in "
7936
+ #~ "<strong>WordPress WAF</strong> mode. Despite being less powerful than the "
7937
+ #~ "<b>Full WAF</b> mode, it offers a level of protection and performance "
7938
+ #~ "much higher than other security plugins."
7939
+ #~ msgstr ""
7940
+ #~ "Si cela se produisait, ne vous inquiétez pas : vous pourrez l'utiliser en "
7941
+ #~ "mode <strong>WordPress WAF</strong>. Bien que moins puissant que le mode "
7942
+ #~ "<strong>Full WAF</strong>, il offre tout de même des performances et un "
7943
+ #~ "niveau de protection très supérieur aux autres extensions de sécurité "
7944
+ #~ "pour WordPress disponibles sur le marché."
7945
+
7946
  #~ msgid ""
7947
  #~ "You can allow/disallow uploads, or allow uploads but block scripts (PHP, "
7948
  #~ "CGI, Ruby, Python, bash/shell), C/C++ source code, binaries (MZ/PE/NE and "
8040
  #~ "NinjaFirewall nécessite au moins WordPress 3.3 mais votre version de "
8041
  #~ "WordPress est %s."
8042
 
 
 
 
 
 
 
 
 
 
 
8043
  #~ msgid ""
8044
  #~ "Even if NinjaFirewall administration menu is only available to the Super "
8045
  #~ "Admin (from the main site), you can still display its status to all sites "
9023
  #~ "les fichiers .htaccess. Ou peut-être devez-vous redémarrer votre serveur "
9024
  #~ "HTTP pour appliquer les changements ?"
9025
 
 
 
 
 
 
 
9026
  #~ msgid "Disable the fatal error handler <code>WP_Fatal_Error_Handler</code>:"
9027
  #~ msgstr ""
9028
  #~ "Désactiver le gestionnaire d'erreurs fatales "
9324
  #~ "Il peut fonctionner en deux modes différents : <b>Full WAF</b> ou "
9325
  #~ "<b>WordPress WAF</b>."
9326
 
 
 
 
9327
  #~ msgid ""
9328
  #~ "In <b>Full WAF</b> mode, NinjaFirewall will hook, scan, reject or "
9329
  #~ "sanitise any HTTP and HTTPS request sent to a PHP script before it "
9368
  #~ "cas, principalement en raison de certaines restrictions d'hébergement "
9369
  #~ "partagé, il se peut que l'installation ne puisse pas fonctionner du tout."
9370
 
 
 
 
9371
  #~ msgid ""
9372
  #~ "The <b>WordPress WAF</b> mode requires to load NinjaFirewall via the "
9373
  #~ "WordPress wp-config.php script. This process makes it easy to setup and "
languages/ninjafirewall.pot CHANGED
@@ -2,7 +2,7 @@
2
  msgid ""
3
  msgstr ""
4
  "Project-Id-Version: Stable (latest release)\n"
5
- "POT-Creation-Date: 2021-05-28 18:29+0700\n"
6
  "PO-Revision-Date: 2018-04-05 22:52+0700\n"
7
  "Last-Translator: NinTechNet <contact@nintechnet.com>\n"
8
  "Language-Team: \n"
@@ -14,11 +14,12 @@ msgstr ""
14
  "X-Poedit-Basepath: ..\n"
15
  "Plural-Forms: nplurals=2; plural=(n > 1);\n"
16
  "X-Poedit-SourceCharset: UTF-8\n"
17
- "X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c;esc_attr_e\n"
 
18
  "X-Poedit-SearchPath-0: .\n"
19
  "X-Poedit-SearchPathExcluded-0: /languages\n"
20
 
21
- #: lib/anti_malware.php:24 ninjafirewall.php:835
22
  msgid "Anti-Malware"
23
  msgstr ""
24
 
@@ -29,10 +30,11 @@ msgid ""
29
  msgstr ""
30
 
31
  #: lib/anti_malware.php:29
32
- #, php-format
33
- msgid ""
34
- "It is awesome and includes many great features: <a href=\"%s\">check it out!"
35
- "</a>"
 
36
  msgstr ""
37
 
38
  #: lib/anti_malware.php:30
@@ -87,23 +89,32 @@ msgstr ""
87
  msgid "NinjaFirewall (WP Edition)"
88
  msgstr ""
89
 
90
- #: lib/dashboard.php:128 ninjafirewall.php:813
 
 
 
 
 
 
 
 
 
91
  msgid "Dashboard"
92
  msgstr ""
93
 
94
- #: lib/dashboard.php:129
95
  msgid "Statistics"
96
  msgstr ""
97
 
98
- #: lib/dashboard.php:130 lib/help.php:53
99
  msgid "About..."
100
  msgstr ""
101
 
102
- #: lib/dashboard.php:142
103
  msgid "Thank you for using NinjaFirewall."
104
  msgstr ""
105
 
106
- #: lib/dashboard.php:143
107
  #, php-format
108
  msgid ""
109
  "Every page of NinjaFirewall has a contextual help: whenever you need help "
@@ -111,135 +122,131 @@ msgid ""
111
  "corner of the corresponding page."
112
  msgstr ""
113
 
114
- #: lib/dashboard.php:143
115
  msgid "Help"
116
  msgstr ""
117
 
118
- #: lib/dashboard.php:145
119
  msgid "Got it!"
120
  msgstr ""
121
 
122
- #: lib/dashboard.php:161 lib/help.php:36
123
  msgid "Firewall Dashboard"
124
  msgstr ""
125
 
126
- #: lib/dashboard.php:170
127
  msgid ""
128
  "It seems that you may have another instance of NinjaFirewall running in a "
129
  "parent directory. Make sure to follow these instructions:"
130
  msgstr ""
131
 
132
- #: lib/dashboard.php:172
133
  msgid ""
134
  "Temporarily disable the firewall in the parent folder by renaming its PHP "
135
  "INI or .htaccess file."
136
  msgstr ""
137
 
138
- #: lib/dashboard.php:174
139
  msgid "Install NinjaFirewall on this site in Full WAF mode."
140
  msgstr ""
141
 
142
- #: lib/dashboard.php:176
143
  msgid ""
144
  "Restore the PHP INI or .htaccess in the parent folder to re-enable the "
145
  "firewall."
146
  msgstr ""
147
 
148
- #: lib/dashboard.php:182
149
  msgid "Unknown error"
150
  msgstr ""
151
 
152
- #: lib/dashboard.php:186 lib/dashboard.php:194
153
  msgid "Firewall"
154
  msgstr ""
155
 
156
- #: lib/dashboard.php:195 lib/dashboard.php:330 lib/firewall_options.php:64
157
  #: lib/login_protection.php:203 lib/logs_live_log.php:99
158
  #: lib/monitoring_file_guard.php:70 lib/security_rules_update.php:138
159
  msgid "Enabled"
160
  msgstr ""
161
 
162
- #: lib/dashboard.php:202
163
  msgid "Mode"
164
  msgstr ""
165
 
166
- #: lib/dashboard.php:206
167
  #, php-format
168
  msgid ""
169
  "NinjaFirewall is running in %s mode. For better protection, activate its "
170
  "Full WAF mode:"
171
  msgstr ""
172
 
173
- #: lib/dashboard.php:206
174
- msgid "WordPress WAF"
175
- msgstr ""
176
-
177
- #: lib/dashboard.php:208 lib/thickbox.php:71
178
  msgid "Activate Full WAF mode"
179
  msgstr ""
180
 
181
- #: lib/dashboard.php:212
182
  #, php-format
183
  msgid "NinjaFirewall is running in %s mode."
184
  msgstr ""
185
 
186
- #: lib/dashboard.php:212
187
- msgid "Full WAF"
188
  msgstr ""
189
 
190
- #: lib/dashboard.php:225 lib/firewall_options.php:76 lib/help.php:77
191
  msgid "Debugging mode"
192
  msgstr ""
193
 
194
- #: lib/dashboard.php:226
195
  msgid "Enabled."
196
  msgstr ""
197
 
198
- #: lib/dashboard.php:226
199
  msgid "Click here to turn Debugging Mode off"
200
  msgstr ""
201
 
202
- #: lib/dashboard.php:232
203
  msgid "Edition"
204
  msgstr ""
205
 
206
- #: lib/dashboard.php:233
207
  msgid ""
208
  "Need more security? Explore our supercharged premium version: NinjaFirewall "
209
  "(WP+ Edition)"
210
  msgstr ""
211
 
212
- #: lib/dashboard.php:236
213
  msgid "Version"
214
  msgstr ""
215
 
216
- #: lib/dashboard.php:237
217
  msgid "Security rules:"
218
  msgstr ""
219
 
220
- #: lib/dashboard.php:241
221
  msgid "PHP SAPI"
222
  msgstr ""
223
 
224
- #: lib/dashboard.php:259
225
  msgid "Updates"
226
  msgstr ""
227
 
228
- #: lib/dashboard.php:260
229
  msgid "Security rules updates are disabled."
230
  msgstr ""
231
 
232
- #: lib/dashboard.php:260
233
  msgid ""
234
  "If you want your blog to be protected against the latest threats, enable "
235
  "automatic security rules updates."
236
  msgstr ""
237
 
238
- #: lib/dashboard.php:268 lib/dashboard.php:276
239
  msgid "Admin user"
240
  msgstr ""
241
 
242
- #: lib/dashboard.php:269
243
  #, php-format
244
  msgid ""
245
  "You are not whitelisted. Ensure that the \"Do not block WordPress "
@@ -248,71 +255,71 @@ msgid ""
248
  "your administration dashboard."
249
  msgstr ""
250
 
251
- #: lib/dashboard.php:277
252
  msgid "You are whitelisted by the firewall."
253
  msgstr ""
254
 
255
- #: lib/dashboard.php:284
256
  msgid "Restrictions"
257
  msgstr ""
258
 
259
- #: lib/dashboard.php:285
260
  msgid "Access to NinjaFirewall is restricted to specific users."
261
  msgstr ""
262
 
263
- #: lib/dashboard.php:296
264
  msgid "User session"
265
  msgstr ""
266
 
267
- #: lib/dashboard.php:297
268
  msgid ""
269
  "It seems that the user session set by NinjaFirewall was not found by the "
270
  "firewall script."
271
  msgstr ""
272
 
273
- #: lib/dashboard.php:305
274
  #, php-format
275
  msgid ""
276
  "the public key is invalid. Please <a href=\"%s\">check your configuration</"
277
  "a>."
278
  msgstr ""
279
 
280
- #: lib/dashboard.php:309
281
  msgid "No IP address restriction."
282
  msgstr ""
283
 
284
- #: lib/dashboard.php:312
285
  #, php-format
286
  msgid "IP address %s is allowed to access NinjaFirewall's log on this server."
287
  msgstr ""
288
 
289
- #: lib/dashboard.php:315
290
  #, php-format
291
  msgid ""
292
  "the whitelisted IP is not valid. Please <a href=\"%s\">check your "
293
  "configuration</a>."
294
  msgstr ""
295
 
296
- #: lib/dashboard.php:320 lib/help.php:467 lib/logs_firewall_log.php:193
297
  #: lib/wpplus.php:170
298
  msgid "Centralized Logging"
299
  msgstr ""
300
 
301
- #: lib/dashboard.php:324 lib/security_rules_update.php:434
302
  #, php-format
303
  msgid "Error: %s"
304
  msgstr ""
305
 
306
- #: lib/dashboard.php:339
307
  msgid "Source IP"
308
  msgstr ""
309
 
310
- #: lib/dashboard.php:340
311
  #, php-format
312
  msgid "You have a private IP : %s"
313
  msgstr ""
314
 
315
- #: lib/dashboard.php:340
316
  #, php-format
317
  msgid ""
318
  "If your site is behind a reverse proxy or a load balancer, ensure that you "
@@ -320,11 +327,11 @@ msgid ""
320
  "otherwise use the NinjaFirewall %s configuration file."
321
  msgstr ""
322
 
323
- #: lib/dashboard.php:348 lib/dashboard.php:358
324
  msgid "CDN detection"
325
  msgstr ""
326
 
327
- #: lib/dashboard.php:349
328
  #, php-format
329
  msgid ""
330
  "%s detected: you seem to be using Cloudflare CDN services. Ensure that you "
@@ -332,7 +339,7 @@ msgid ""
332
  "otherwise use the NinjaFirewall %s configuration file."
333
  msgstr ""
334
 
335
- #: lib/dashboard.php:359
336
  #, php-format
337
  msgid ""
338
  "%s detected: you seem to be using Incapsula CDN services. Ensure that you "
@@ -340,36 +347,51 @@ msgid ""
340
  "otherwise use the NinjaFirewall %s configuration file."
341
  msgstr ""
342
 
343
- #: lib/dashboard.php:368 lib/dashboard.php:377
344
  msgid "Log dir"
345
  msgstr ""
346
 
347
- #: lib/dashboard.php:369 lib/dashboard.php:378
348
  #, php-format
349
  msgid "%s directory is not writable! Please chmod it to 0777 or equivalent."
350
  msgstr ""
351
 
352
- #: lib/dashboard.php:391
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
353
  msgid "Error log"
354
  msgstr ""
355
 
356
- #: lib/dashboard.php:392
357
  msgid "View error log"
358
  msgstr ""
359
 
360
- #: lib/dashboard.php:401
361
  msgid "Optional configuration file"
362
  msgstr ""
363
 
364
- #: lib/dashboard.php:408
365
  msgid "MySQLi link identifier"
366
  msgstr ""
367
 
368
- #: lib/dashboard.php:409
369
  msgid "A MySQLi link identifier was detected in your <code>.htninja</code>."
370
  msgstr ""
371
 
372
- #: lib/dashboard.php:415
373
  msgid "Help &amp; configuration"
374
  msgstr ""
375
 
@@ -407,7 +429,7 @@ msgstr ""
407
  msgid "Select a month"
408
  msgstr ""
409
 
410
- #: lib/dashboard_statistics.php:98 lib/dashboard_statistics.php:131
411
  #: lib/widget.php:66
412
  msgid "Blocked threats"
413
  msgstr ""
@@ -437,40 +459,32 @@ msgstr ""
437
  msgid "Slowest request"
438
  msgstr ""
439
 
440
- #: lib/dashboard_statistics.php:126
441
  msgid "Critical"
442
  msgstr ""
443
 
444
- #: lib/dashboard_statistics.php:127
445
  msgid "High"
446
  msgstr ""
447
 
448
- #: lib/dashboard_statistics.php:128
449
  msgid "Medium"
450
  msgstr ""
451
 
452
- #: lib/dashboard_statistics.php:184
453
  msgid "Select monthly stats to view..."
454
  msgstr ""
455
 
456
- #: lib/event_notifications.php:34 lib/help.php:377 ninjafirewall.php:843
457
  msgid "Event Notifications"
458
  msgstr ""
459
 
460
- #: lib/event_notifications.php:42 lib/firewall_options.php:42
461
- #: lib/firewall_policies.php:71 lib/login_protection.php:30
462
- #: lib/logs_firewall_log.php:59 lib/logs_live_log.php:79
463
- #: lib/monitoring_file_check.php:111 lib/monitoring_file_guard.php:46
464
- #: lib/network.php:52 lib/security_rules_update.php:101
465
- msgid "Your changes have been saved."
466
- msgstr ""
467
-
468
  #: lib/event_notifications.php:52
469
  msgid "WordPress admin dashboard"
470
  msgstr ""
471
 
472
  #: lib/event_notifications.php:55 lib/event_notifications.php:119
473
- #: lib/event_notifications.php:139
474
  msgid "Send me an alert whenever"
475
  msgstr ""
476
 
@@ -561,25 +575,25 @@ msgid ""
561
  "(default)"
562
  msgstr ""
563
 
564
- #: lib/event_notifications.php:136
565
  msgid "Administrator account"
566
  msgstr ""
567
 
568
- #: lib/event_notifications.php:141
569
  msgid ""
570
  "An administrator account is created, modified or deleted in the database "
571
  "(default)"
572
  msgstr ""
573
 
574
- #: lib/event_notifications.php:148
575
  msgid "Daily report"
576
  msgstr ""
577
 
578
- #: lib/event_notifications.php:151
579
  msgid "Send me a daily activity report"
580
  msgstr ""
581
 
582
- #: lib/event_notifications.php:153 lib/event_notifications.php:165
583
  #: lib/firewall_options.php:78 lib/firewall_options.php:113
584
  #: lib/firewall_policies.php:25 lib/login_protection.php:309
585
  #: lib/login_protection.php:324 lib/login_protection.php:345
@@ -587,7 +601,7 @@ msgstr ""
587
  msgid "Yes"
588
  msgstr ""
589
 
590
- #: lib/event_notifications.php:153 lib/event_notifications.php:165
591
  #: lib/firewall_options.php:78 lib/firewall_options.php:113
592
  #: lib/firewall_policies.php:26 lib/login_protection.php:309
593
  #: lib/login_protection.php:324 lib/login_protection.php:345
@@ -595,111 +609,106 @@ msgstr ""
595
  msgid "No"
596
  msgstr ""
597
 
598
- #: lib/event_notifications.php:160
599
  msgid "Log"
600
  msgstr ""
601
 
602
- #: lib/event_notifications.php:163
603
  msgid "Write all events to the firewall log"
604
  msgstr ""
605
 
606
- #: lib/event_notifications.php:177
607
  msgid "PHP backtrace"
608
  msgstr ""
609
 
610
- #: lib/event_notifications.php:180
611
  msgid "Attach a PHP backtrace to important notifications"
612
  msgstr ""
613
 
614
- #: lib/event_notifications.php:183
615
  msgid "Disable backtrace"
616
  msgstr ""
617
 
618
- #: lib/event_notifications.php:184
619
  msgid "Low verbosity"
620
  msgstr ""
621
 
622
- #: lib/event_notifications.php:185
623
  msgid "Medium verbosity (default)"
624
  msgstr ""
625
 
626
- #: lib/event_notifications.php:186
627
  msgid "High verbosity"
628
  msgstr ""
629
 
630
- #: lib/event_notifications.php:188
631
- #, php-format
632
- msgid "<a href=\"%s\">Consult our blog</a> for more info."
633
- msgstr ""
634
-
635
- #: lib/event_notifications.php:198 lib/event_notifications.php:228
636
  msgid "Contact email"
637
  msgstr ""
638
 
639
- #: lib/event_notifications.php:201 lib/event_notifications.php:231
640
  msgid "Alerts should be sent to"
641
  msgstr ""
642
 
643
- #: lib/event_notifications.php:210 lib/event_notifications.php:236
644
  msgid ""
645
  "Multiple recipients must be comma-separated (e.g., <code>joe@example.org,"
646
  "alice@example.org</code>)."
647
  msgstr ""
648
 
649
- #: lib/event_notifications.php:233
650
  msgid "Only to me, the Super Admin"
651
  msgstr ""
652
 
653
- #: lib/event_notifications.php:233
654
  msgid "default"
655
  msgstr ""
656
 
657
- #: lib/event_notifications.php:234
658
  msgid "To the administrator of the site where originated the alert"
659
  msgstr ""
660
 
661
- #: lib/event_notifications.php:235
662
  msgid "Other(s):"
663
  msgstr ""
664
 
665
- #: lib/event_notifications.php:247
666
  msgid "Save Event Notifications"
667
  msgstr ""
668
 
669
- #: lib/event_notifications.php:489
670
  msgid "[NinjaFirewall] Daily Activity Report"
671
  msgstr ""
672
 
673
- #: lib/event_notifications.php:499
674
  #, php-format
675
  msgid "Daily activity report for: %s"
676
  msgstr ""
677
 
678
- #: lib/event_notifications.php:500
679
  msgid "Date Range Processed: Yesterday"
680
  msgstr ""
681
 
682
- #: lib/event_notifications.php:502
683
  msgid "Blocked threats:"
684
  msgstr ""
685
 
686
- #: lib/event_notifications.php:504
687
  msgid "critical:"
688
  msgstr ""
689
 
690
- #: lib/event_notifications.php:505
691
  msgid "high:"
692
  msgstr ""
693
 
694
- #: lib/event_notifications.php:506
695
  msgid "medium:"
696
  msgstr ""
697
 
698
- #: lib/event_notifications.php:508
699
  msgid "Blocked brute-force attacks:"
700
  msgstr ""
701
 
702
- #: lib/event_notifications.php:509 lib/event_updates.php:225 lib/utils.php:1094
703
  msgid ""
704
  "This notification can be turned off from NinjaFirewall \"Event Notifications"
705
  "\" page."
@@ -716,7 +725,7 @@ msgid ""
716
  msgstr ""
717
 
718
  #: lib/event_updates.php:163 lib/utils.php:233 lib/utils.php:318
719
- #: lib/utils.php:440 lib/utils.php:1083 lib/utils.php:1272 lib/utils.php:1544
720
  msgid "Date:"
721
  msgstr ""
722
 
@@ -762,7 +771,7 @@ msgstr ""
762
  msgid "Theme: %s"
763
  msgstr ""
764
 
765
- #: lib/event_updates.php:223
766
  msgid "Don't leave your blog at risk, make sure to update as soon as possible."
767
  msgstr ""
768
 
@@ -812,7 +821,7 @@ msgstr ""
812
  msgid "[NinjaFirewall] Alert: %s"
813
  msgstr ""
814
 
815
- #: lib/events.php:203 lib/events.php:205 lib/utils.php:832
816
  msgid "-Blog:"
817
  msgstr ""
818
 
@@ -820,19 +829,19 @@ msgstr ""
820
  msgid "NinjaFirewall has detected the following activity on your account:"
821
  msgstr ""
822
 
823
- #: lib/events.php:210 lib/utils.php:837
824
  msgid "-User:"
825
  msgstr ""
826
 
827
- #: lib/events.php:211 lib/utils.php:838
828
  msgid "-IP:"
829
  msgstr ""
830
 
831
- #: lib/events.php:212 lib/utils.php:839
832
  msgid "-Date:"
833
  msgstr ""
834
 
835
- #: lib/firewall_options.php:29 ninjafirewall.php:817
836
  msgid "Firewall Options"
837
  msgstr ""
838
 
@@ -979,43 +988,47 @@ msgstr ""
979
  msgid "Uploaded file is either corrupted or its format is not supported (#%s)"
980
  msgstr ""
981
 
982
- #: lib/firewall_options.php:554 ninjafirewall.php:230
 
 
 
 
983
  msgid "[NinjaFirewall] Alert: Firewall is disabled"
984
  msgstr ""
985
 
986
- #: lib/firewall_options.php:556 lib/firewall_options.php:558
987
- #: ninjafirewall.php:232 ninjafirewall.php:234
988
  msgid "-Blog :"
989
  msgstr ""
990
 
991
- #: lib/firewall_options.php:562 ninjafirewall.php:236
992
  msgid "Someone disabled NinjaFirewall from your WordPress admin dashboard:"
993
  msgstr ""
994
 
995
- #: lib/firewall_options.php:565
996
  msgid ""
997
  "NinjaFirewall is disabled because someone enabled debugging mode from your "
998
  "WordPress admin dashboard:"
999
  msgstr ""
1000
 
1001
- #: lib/firewall_options.php:568
1002
  msgid "[NinjaFirewall] Alert: Firewall override settings"
1003
  msgstr ""
1004
 
1005
- #: lib/firewall_options.php:569
1006
  msgid ""
1007
  "Someone imported a new configuration which overrode the firewall settings:"
1008
  msgstr ""
1009
 
1010
- #: lib/firewall_options.php:575 ninjafirewall.php:237
1011
  msgid "-User :"
1012
  msgstr ""
1013
 
1014
- #: lib/firewall_options.php:576 ninjafirewall.php:238
1015
  msgid "-IP :"
1016
  msgstr ""
1017
 
1018
- #: lib/firewall_options.php:577 ninjafirewall.php:239
1019
  msgid "-Date :"
1020
  msgstr ""
1021
 
@@ -1026,7 +1039,7 @@ msgid ""
1026
  "enable NinjaFirewall's Full WAF mode."
1027
  msgstr ""
1028
 
1029
- #: lib/firewall_policies.php:62 ninjafirewall.php:821
1030
  msgid "Firewall Policies"
1031
  msgstr ""
1032
 
@@ -1155,7 +1168,7 @@ msgid ""
1155
  "not have the right capabilities"
1156
  msgstr ""
1157
 
1158
- #: lib/firewall_policies.php:411 lib/thickbox.php:86
1159
  msgid "(recommended)"
1160
  msgstr ""
1161
 
@@ -1409,17 +1422,23 @@ msgid ""
1409
  "your blog, its themes or plugins."
1410
  msgstr ""
1411
 
1412
- #: lib/firewall_policies.php:846
1413
  #, php-format
1414
- msgid "Set %s (IE/Edge, Chrome, Opera and Safari browsers)"
1415
  msgstr ""
1416
 
1417
- #: lib/firewall_policies.php:850 lib/firewall_policies.php:851
1418
- #: lib/firewall_policies.php:852
1419
  #, php-format
1420
  msgid "Set to %s"
1421
  msgstr ""
1422
 
 
 
 
 
 
 
1423
  #: lib/firewall_policies.php:857
1424
  #, php-format
1425
  msgid "Force %s flag on all cookies to mitigate CSRF attacks"
@@ -2067,9 +2086,7 @@ msgid ""
2067
  msgstr ""
2068
 
2069
  #: lib/help.php:275
2070
- msgid ""
2071
- "Set <code>X-XSS-Protection</code> (IE/Edge, Chrome, Opera and Safari "
2072
- "browsers)"
2073
  msgstr ""
2074
 
2075
  #: lib/help.php:275
@@ -2079,12 +2096,6 @@ msgid ""
2079
  "browsers."
2080
  msgstr ""
2081
 
2082
- #: lib/help.php:276
2083
- msgid ""
2084
- "If a visitor disabled their browser's XSS filter, you cannot re-enable it "
2085
- "with that option."
2086
- msgstr ""
2087
-
2088
  #: lib/help.php:278
2089
  msgid ""
2090
  "Force <code>SameSite</code> flag on all cookies to mitigate CSRF attacks"
@@ -2363,7 +2374,7 @@ msgid ""
2363
  "package (third-party software, shell script, backdoor etc)."
2364
  msgstr ""
2365
 
2366
- #: lib/help.php:360 lib/network.php:32 ninjafirewall.php:839
2367
  msgid "Network"
2368
  msgstr ""
2369
 
@@ -2399,7 +2410,7 @@ msgid ""
2399
  "theme in order to take full control of your website."
2400
  msgstr ""
2401
 
2402
- #: lib/help.php:389 lib/login_protection.php:21 ninjafirewall.php:847
2403
  msgid "Login Protection"
2404
  msgstr ""
2405
 
@@ -3012,12 +3023,11 @@ msgstr ""
3012
  #: lib/i18n-extra.php:51
3013
  #, php-format
3014
  msgid ""
3015
- "You are running NinjaFirewall in <i>WordPress WAF</i> mode. All URL-based "
3016
- "features such as <i>Geolocation</i> and <i>URL Access Control</i> will be "
3017
- "limited to WordPress files only (e.g., index.php, wp-login.php, xmlrpc.php, "
3018
- "admin-ajax.php, wp-load.php etc). If you want them to apply to any PHP "
3019
- "script, please <a href=\"%s\">go to the Dashboard page</a> and enable "
3020
- "NinjaFirewall's Full WAF mode."
3021
  msgstr ""
3022
 
3023
  #: lib/i18n-extra.php:52
@@ -3074,358 +3084,332 @@ msgid "All Access Control directives should apply to the folowing HTTP methods"
3074
  msgstr ""
3075
 
3076
  #: lib/i18n-extra.php:65
3077
- msgid "<code>GET</code>"
3078
- msgstr ""
3079
-
3080
- #: lib/i18n-extra.php:66
3081
- msgid "<code>POST</code>"
3082
- msgstr ""
3083
-
3084
- #: lib/i18n-extra.php:67
3085
- msgid "<code>HEAD</code>"
3086
- msgstr ""
3087
-
3088
- #: lib/i18n-extra.php:68
3089
- msgid "<code>PUT</code>"
3090
- msgstr ""
3091
-
3092
- #: lib/i18n-extra.php:69
3093
- msgid "<code>DELETE</code>"
3094
- msgstr ""
3095
-
3096
- #: lib/i18n-extra.php:70
3097
- msgid "<code>PATCH</code>"
3098
- msgstr ""
3099
-
3100
- #: lib/i18n-extra.php:71
3101
  msgid "Enable Geolocation"
3102
  msgstr ""
3103
 
3104
- #: lib/i18n-extra.php:72
3105
  msgid "Retrieve the ISO 3166 code from"
3106
  msgstr ""
3107
 
3108
- #: lib/i18n-extra.php:73
3109
  msgid "PHP Variable"
3110
  msgstr ""
3111
 
3112
- #: lib/i18n-extra.php:74
3113
  msgid "Block the following ISO 3166 codes"
3114
  msgstr ""
3115
 
3116
- #: lib/i18n-extra.php:75
3117
  #, php-format
3118
  msgid "Total blocked items: %s"
3119
  msgstr ""
3120
 
3121
- #: lib/i18n-extra.php:76
3122
  msgid "Geolocation should apply to the whole site or to specific URLs only?"
3123
  msgstr ""
3124
 
3125
- #: lib/i18n-extra.php:77
3126
  msgid "View allowed syntax"
3127
  msgstr ""
3128
 
3129
- #: lib/i18n-extra.php:78
3130
  #, php-format
3131
  msgid "Full or partial case-sensitive URL (e.g., %s)."
3132
  msgstr ""
3133
 
3134
- #: lib/i18n-extra.php:79
3135
  msgid "One item per line."
3136
  msgstr ""
3137
 
3138
- #: lib/i18n-extra.php:80
3139
  msgid ""
3140
  "Leave this field empty if you want geolocation to apply to all your PHP "
3141
  "scripts."
3142
  msgstr ""
3143
 
3144
- #: lib/i18n-extra.php:81
3145
- msgid "Add <code>NINJA_COUNTRY_CODE</code> to PHP headers?"
3146
  msgstr ""
3147
 
3148
- #: lib/i18n-extra.php:82
3149
  msgid "Write event to the firewall log"
3150
  msgstr ""
3151
 
3152
- #: lib/i18n-extra.php:83
3153
  msgid "Allow the following IP, CIDR or AS number"
3154
  msgstr ""
3155
 
3156
- #: lib/i18n-extra.php:84
3157
  #, php-format
3158
  msgid "IPv4 address: %s"
3159
  msgstr ""
3160
 
3161
- #: lib/i18n-extra.php:85
3162
  #, php-format
3163
  msgid "IPv4 CIDR: %s"
3164
  msgstr ""
3165
 
3166
- #: lib/i18n-extra.php:86
3167
  #, php-format
3168
  msgid "IPv6 address: %s"
3169
  msgstr ""
3170
 
3171
- #: lib/i18n-extra.php:87
3172
  #, php-format
3173
  msgid "IPv6 CIDR: %s"
3174
  msgstr ""
3175
 
3176
- #: lib/i18n-extra.php:88
3177
  #, php-format
3178
  msgid "Autonomous System number: %s"
3179
  msgstr ""
3180
 
3181
- #: lib/i18n-extra.php:89
3182
  msgid "Whitelist:"
3183
  msgstr ""
3184
 
3185
- #: lib/i18n-extra.php:90
3186
  msgid "Enter one item per line."
3187
  msgstr ""
3188
 
3189
- #: lib/i18n-extra.php:91
3190
  msgid "External Services"
3191
  msgstr ""
3192
 
3193
- #: lib/i18n-extra.php:92
3194
  msgid "Whitelist IP addresses from the following services:"
3195
  msgstr ""
3196
 
3197
- #: lib/i18n-extra.php:93
3198
  msgid "View IP addresses"
3199
  msgstr ""
3200
 
3201
- #: lib/i18n-extra.php:94
3202
  msgid "Block the following IP, CIDR or AS number"
3203
  msgstr ""
3204
 
3205
- #: lib/i18n-extra.php:95
3206
  msgid "Blacklist:"
3207
  msgstr ""
3208
 
3209
- #: lib/i18n-extra.php:96
3210
  msgid "Rate Limiting"
3211
  msgstr ""
3212
 
3213
- #: lib/i18n-extra.php:97
3214
  #, php-format
3215
  msgid ""
3216
  "Block for %s seconds any IP address with more than %s connections within a "
3217
  "%s interval."
3218
  msgstr ""
3219
 
3220
- #: lib/i18n-extra.php:98
3221
  msgid "5-second"
3222
  msgstr ""
3223
 
3224
- #: lib/i18n-extra.php:99
3225
  msgid "10-second"
3226
  msgstr ""
3227
 
3228
- #: lib/i18n-extra.php:100
3229
  msgid "15-second"
3230
  msgstr ""
3231
 
3232
- #: lib/i18n-extra.php:101
3233
  msgid "30-second"
3234
  msgstr ""
3235
 
3236
- #: lib/i18n-extra.php:102
3237
  msgid "Allow access to the following URL"
3238
  msgstr ""
3239
 
3240
- #: lib/i18n-extra.php:103
3241
  #, php-format
3242
  msgid "Full or partial case-sensitive URLs (e.g., %s)."
3243
  msgstr ""
3244
 
3245
- #: lib/i18n-extra.php:104
3246
  msgid "Block access to the following URL"
3247
  msgstr ""
3248
 
3249
- #: lib/i18n-extra.php:105
3250
  msgid "Reject the following bots"
3251
  msgstr ""
3252
 
3253
- #: lib/i18n-extra.php:106
3254
  msgid "A full or partial case-insensitive string."
3255
  msgstr ""
3256
 
3257
- #: lib/i18n-extra.php:107
3258
- msgid ""
3259
- "Allowed characters are: <code>a-zA-Z</code> <code>0-9</code> <code>.</code> "
3260
- "<code>-</code> <code>_</code> <code>:</code> <code>/</code> and <code>space</"
3261
- "code>."
3262
  msgstr ""
3263
 
3264
- #: lib/i18n-extra.php:108
3265
  msgid "Blocked bots:"
3266
  msgstr ""
3267
 
3268
- #: lib/i18n-extra.php:109
3269
  msgid "The default list of bots will be restored. Continue?"
3270
  msgstr ""
3271
 
3272
- #: lib/i18n-extra.php:110
3273
  msgid "Restore default bots list"
3274
  msgstr ""
3275
 
3276
- #: lib/i18n-extra.php:111
3277
  msgid "Do not filter the following user input"
3278
  msgstr ""
3279
 
3280
- #: lib/i18n-extra.php:112
3281
  msgid ""
3282
- "A <code>GET</code>, <code>POST</code> or <code>COOKIE</code> global "
3283
- "variable, followed by <code>:</code> (colon) and the case-sensitive input:"
3284
  msgstr ""
3285
 
3286
- #: lib/i18n-extra.php:113
3287
  msgid "Unfiltered input:"
3288
  msgstr ""
3289
 
3290
- #: lib/i18n-extra.php:114
3291
  msgid "Block the request if the following input is present"
3292
  msgstr ""
3293
 
3294
- #: lib/i18n-extra.php:115
3295
  msgid "Blocked input:"
3296
  msgstr ""
3297
 
3298
- #: lib/i18n-extra.php:116
3299
  msgid "Save Access Control directives"
3300
  msgstr ""
3301
 
3302
- #: lib/i18n-extra.php:117
3303
  msgid ""
3304
  "Warning: Your previous secret key was either corrupted or missing. A new "
3305
  "one, as well as a new public key, were created."
3306
  msgstr ""
3307
 
3308
- #: lib/i18n-extra.php:118
3309
  msgid "Enable Centralized Logging"
3310
  msgstr ""
3311
 
3312
- #: lib/i18n-extra.php:119
3313
  msgid "Secret key"
3314
  msgstr ""
3315
 
3316
- #: lib/i18n-extra.php:120
3317
  msgid "From 30 to 100 ASCII printable characters."
3318
  msgstr ""
3319
 
3320
- #: lib/i18n-extra.php:121
3321
  msgid "This server's IP address"
3322
  msgstr ""
3323
 
3324
- #: lib/i18n-extra.php:122
3325
  msgid ""
3326
  "Only this IP address (IPv4 or IPv6) will be allowed to connect to the remote "
3327
  "websites. If you don't want to restrict the access by IP, enter the <code>*</"
3328
  "code> character instead."
3329
  msgstr ""
3330
 
3331
- #: lib/i18n-extra.php:123
3332
  msgid "Public key"
3333
  msgstr ""
3334
 
3335
- #: lib/i18n-extra.php:124
3336
  #, php-format
3337
  msgid ""
3338
  "Add this key to the remote websites. <a href=\"%s\">Consult our blog</a> for "
3339
  "more info."
3340
  msgstr ""
3341
 
3342
- #: lib/i18n-extra.php:125
3343
  msgid "Remote websites URL"
3344
  msgstr ""
3345
 
3346
- #: lib/i18n-extra.php:126
3347
  msgid ""
3348
  "Enter one URL per line, including the protocol (<code>http://</code> or "
3349
  "<code>https://</code>). Only ASCII URLs are accepted."
3350
  msgstr ""
3351
 
3352
- #: lib/i18n-extra.php:127
3353
  msgid "Save Options"
3354
  msgstr ""
3355
 
3356
- #: lib/i18n-extra.php:128
3357
  msgid ""
3358
  "Your changes have been saved. If you are using a caching plugin, do not "
3359
  "forget to clear its cache."
3360
  msgstr ""
3361
 
3362
- #: lib/i18n-extra.php:129
3363
  msgid "Enable antispam protection"
3364
  msgstr ""
3365
 
3366
- #: lib/i18n-extra.php:130
3367
  msgid "Protection level"
3368
  msgstr ""
3369
 
3370
- #: lib/i18n-extra.php:131
3371
  msgid "Low (default)"
3372
  msgstr ""
3373
 
3374
- #: lib/i18n-extra.php:132
3375
  msgid ""
3376
  "If you are using a caching plugin, consult the contextual help before "
3377
  "enabling the antispam."
3378
  msgstr ""
3379
 
3380
- #: lib/i18n-extra.php:133
3381
  msgid "Apply protection to"
3382
  msgstr ""
3383
 
3384
- #: lib/i18n-extra.php:134
3385
  msgid "Comment forms (defaut)"
3386
  msgstr ""
3387
 
3388
- #: lib/i18n-extra.php:135
3389
  msgid "User Registration form"
3390
  msgstr ""
3391
 
3392
- #: lib/i18n-extra.php:136
3393
  msgid "Save Antispam options"
3394
  msgstr ""
3395
 
3396
- #: lib/i18n-extra.php:137
3397
  msgid "Please enable JavaScript"
3398
  msgstr ""
3399
 
3400
- #: lib/i18n-extra.php:138
3401
  msgid "Sorry, this looks like spam to me."
3402
  msgstr ""
3403
 
3404
- #: lib/i18n-extra.php:139
3405
  msgid ""
3406
  "Error: You must be whitelisted in order to use that feature: click on the <a "
3407
  "href=\"?page=nfsubaccess\">Access Control</a> menu and ensure that the \"Do "
3408
  "not block the following users\" option is enabled for the Admin/Super Admin."
3409
  msgstr ""
3410
 
3411
- #: lib/i18n-extra.php:140
3412
  msgid ""
3413
  "Your license is valid until the indicated expiration date. If you don't "
3414
  "renew it after this date, NinjaFirewall will keep working and protecting "
3415
  "your website as usual, but updates/upgrades will stop."
3416
  msgstr ""
3417
 
3418
- #: lib/i18n-extra.php:141
3419
  #, php-format
3420
  msgid ""
3421
  "You can renew your license from <a href=\"%s\">NinTechNet.com</a> website."
3422
  msgstr ""
3423
 
3424
- #: lib/i18n-extra.php:142
3425
  msgid "Use shared memory"
3426
  msgstr ""
3427
 
3428
- #: lib/i18n-extra.php:143
3429
  msgid ""
3430
  "This feature allows NinjaFirewall to use Unix shared memory segments in "
3431
  "order to speed up all operations. The firewall will no longer need to "
@@ -3435,14 +3419,14 @@ msgid ""
3435
  "processing speed from 25% to 30%, prevent blocking I/O and slow queries."
3436
  msgstr ""
3437
 
3438
- #: lib/i18n-extra.php:144
3439
  msgid ""
3440
  "This option requires that your PHP version was compiled with the <code>--"
3441
  "enable-shmop</code> parameter, otherwise, if it is not compatible with your "
3442
  "server/hosting environment, it will be disabled."
3443
  msgstr ""
3444
 
3445
- #: lib/i18n-extra.php:145
3446
  #, php-format
3447
  msgid ""
3448
  "If you are using <a href=\"%s\">GB2312</a> character set (A.K.A <code>GBK</"
@@ -3452,24 +3436,24 @@ msgid ""
3452
  "used by that charset."
3453
  msgstr ""
3454
 
3455
- #: lib/i18n-extra.php:146
3456
  msgid "Language"
3457
  msgstr ""
3458
 
3459
- #: lib/i18n-extra.php:147
3460
  msgid ""
3461
  "When this option is enabled, NinjaFirewall will download, if available, the "
3462
  "corresponding language files from the WordPress repo. Then, every hour, it "
3463
  "will check if there's a new version and will download it."
3464
  msgstr ""
3465
 
3466
- #: lib/i18n-extra.php:148
3467
  msgid ""
3468
  "Note that this does not apply to <code>en_US</code> and <code>fr_FR</code> "
3469
  "locales because they are already included with NinjaFirewall."
3470
  msgstr ""
3471
 
3472
- #: lib/i18n-extra.php:149
3473
  #, php-format
3474
  msgid ""
3475
  "This options lets you export you current configuration or import it from "
@@ -3479,7 +3463,7 @@ msgid ""
3479
  "configuration, except your current license."
3480
  msgstr ""
3481
 
3482
- #: lib/i18n-extra.php:150
3483
  msgid ""
3484
  "You can allow/disallow uploads, or allow uploads but block scripts (PHP, "
3485
  "CGI, Ruby, Python, bash/shell, JavaScript), C/C++ source code, binaries (MZ/"
@@ -3487,11 +3471,11 @@ msgid ""
3487
  "SVG files containing Javascript/XML events."
3488
  msgstr ""
3489
 
3490
- #: lib/i18n-extra.php:151
3491
  msgid "Maximum allowed file size"
3492
  msgstr ""
3493
 
3494
- #: lib/i18n-extra.php:152
3495
  msgid ""
3496
  "If you allow uploads, you can select the maximum size of an uploaded file. "
3497
  "Any file bigger than this value will be rejected. Note that if your PHP "
@@ -3499,11 +3483,11 @@ msgid ""
3499
  "be used before NinjaFirewall."
3500
  msgstr ""
3501
 
3502
- #: lib/i18n-extra.php:153
3503
  msgid "Decode Base64-encoded <code>POST</code> variable:"
3504
  msgstr ""
3505
 
3506
- #: lib/i18n-extra.php:154
3507
  #, php-format
3508
  msgid ""
3509
  "Object Serialization is a PHP feature used by many applications to generate "
@@ -3514,7 +3498,7 @@ msgid ""
3514
  "request, cookies, user agent and referrer variables."
3515
  msgstr ""
3516
 
3517
- #: lib/i18n-extra.php:155
3518
  msgid ""
3519
  "This option will reject any <code>GET</code> or <code>POST</code> request, "
3520
  "<code>COOKIE</code>, <code>HTTP_USER_AGENT</code>, <code>REQUEST_URI</code>, "
@@ -3523,106 +3507,106 @@ msgid ""
3523
  "is dangerous and should always be rejected."
3524
  msgstr ""
3525
 
3526
- #: lib/i18n-extra.php:156
3527
  msgid ""
3528
  "This option will block any <code>GET</code> or <code>POST</code> request "
3529
  "containing the localhost IP (127.0.0.1). It can be useful to block SQL "
3530
  "dumpers and various hacker's shell scripts."
3531
  msgstr ""
3532
 
3533
- #: lib/i18n-extra.php:157
3534
  msgid ""
3535
  "Access Control is a powerful set of directives that can be used to allow or "
3536
  "restrict access to your website based on many criteria."
3537
  msgstr ""
3538
 
3539
- #: lib/i18n-extra.php:158
3540
  msgid ""
3541
  "To make better use of them, it is important to understand NinjaFirewall's "
3542
  "directives processing order."
3543
  msgstr ""
3544
 
3545
- #: lib/i18n-extra.php:159
3546
  msgid ""
3547
  "Because NinjaFirewall is a PHP firewall, its Access Control options apply to "
3548
  "PHP scripts, not to static elements (e.g., images, JS, CSS etc). Depending "
3549
  "on your configuration, they can also apply to HTML pages."
3550
  msgstr ""
3551
 
3552
- #: lib/i18n-extra.php:160
3553
  msgid "Processing order:"
3554
  msgstr ""
3555
 
3556
- #: lib/i18n-extra.php:161
3557
  msgid "Incoming HTTP request"
3558
  msgstr ""
3559
 
3560
- #: lib/i18n-extra.php:162
3561
  #, php-format
3562
  msgid "%s file"
3563
  msgstr ""
3564
 
3565
- #: lib/i18n-extra.php:163
3566
  msgid "Login Protection."
3567
  msgstr ""
3568
 
3569
- #: lib/i18n-extra.php:164
3570
  msgid "Access Control (except User Input Access Control):"
3571
  msgstr ""
3572
 
3573
- #: lib/i18n-extra.php:165
3574
  msgid "Role-based Access Control."
3575
  msgstr ""
3576
 
3577
- #: lib/i18n-extra.php:166
3578
  msgid "Allowed IPs."
3579
  msgstr ""
3580
 
3581
- #: lib/i18n-extra.php:167
3582
  msgid "Blocked IPs."
3583
  msgstr ""
3584
 
3585
- #: lib/i18n-extra.php:168
3586
  msgid "Allowed URLs."
3587
  msgstr ""
3588
 
3589
- #: lib/i18n-extra.php:169
3590
  msgid "Blocked URLs."
3591
  msgstr ""
3592
 
3593
- #: lib/i18n-extra.php:170
3594
  msgid "Bot Access Control."
3595
  msgstr ""
3596
 
3597
- #: lib/i18n-extra.php:171
3598
  msgid "Geolocation."
3599
  msgstr ""
3600
 
3601
- #: lib/i18n-extra.php:172
3602
  msgid "Rate Limiting."
3603
  msgstr ""
3604
 
3605
- #: lib/i18n-extra.php:173
3606
  msgid "File Guard."
3607
  msgstr ""
3608
 
3609
- #: lib/i18n-extra.php:174
3610
  msgid "NinjaFirewall built-in rules and policies + User Input Access Control."
3611
  msgstr ""
3612
 
3613
- #: lib/i18n-extra.php:175
3614
  msgid "Response body"
3615
  msgstr ""
3616
 
3617
- #: lib/i18n-extra.php:176
3618
  msgid "HTTP response headers (Firewall Policies)."
3619
  msgstr ""
3620
 
3621
- #: lib/i18n-extra.php:177
3622
  msgid "Web Filter."
3623
  msgstr ""
3624
 
3625
- #: lib/i18n-extra.php:178
3626
  #, php-format
3627
  msgid ""
3628
  "By default, any logged in WordPress administrator will not be blocked by "
@@ -3634,11 +3618,11 @@ msgid ""
3634
  "enforced."
3635
  msgstr ""
3636
 
3637
- #: lib/i18n-extra.php:179
3638
  msgid "You can also add other users to the whitelist, depending on their role."
3639
  msgstr ""
3640
 
3641
- #: lib/i18n-extra.php:180
3642
  #, php-format
3643
  msgid ""
3644
  "this option should be used if you are behind a reverse proxy, a load "
@@ -3652,25 +3636,25 @@ msgid ""
3652
  "NinjaFirewall will fall back to <code>REMOTE_ADDR</code>."
3653
  msgstr ""
3654
 
3655
- #: lib/i18n-extra.php:181
3656
  msgid ""
3657
  "This option lets you select the HTTP method(s). All Access Control "
3658
  "directives (Geolocation, IPs, bots and URLs) will only apply to the selected "
3659
  "methods."
3660
  msgstr ""
3661
 
3662
- #: lib/i18n-extra.php:182
3663
  msgid ""
3664
  "It does not apply to the \"Firewall Policies\" options, which use their own "
3665
  "ones."
3666
  msgstr ""
3667
 
3668
- #: lib/i18n-extra.php:183
3669
  msgid ""
3670
  "You can filter and block traffic coming from specific countries/territories."
3671
  msgstr ""
3672
 
3673
- #: lib/i18n-extra.php:184
3674
  msgid ""
3675
  "This is the two-letter code that is used to define a country/territory (e."
3676
  "g., US, UK, FR, DE etc), based on the visitors IP. NinjaFirewall can either "
@@ -3678,7 +3662,7 @@ msgid ""
3678
  "your HTTP server (e.g., <code>GEOIP_COUNTRY_CODE</code>)."
3679
  msgstr ""
3680
 
3681
- #: lib/i18n-extra.php:185
3682
  #, php-format
3683
  msgid ""
3684
  "You can add/remove any country/territory from the two listboxes. For more "
@@ -3686,14 +3670,18 @@ msgid ""
3686
  "want to consult <a href=\"%s\">the MaxMind GeoIP online help</a>."
3687
  msgstr ""
3688
 
3689
- #: lib/i18n-extra.php:186
3690
  msgid ""
3691
  "Whether geolocation should apply to the whole site or to specific URLs only "
3692
  "(e.g., /wp-login.php, /xmlrpc.php etc). Leave all fields empty if you want "
3693
  "it to apply to the whole site."
3694
  msgstr ""
3695
 
3696
- #: lib/i18n-extra.php:187
 
 
 
 
3697
  msgid ""
3698
  "After retrieving the two-letter country/territory code, NinjaFirewall can "
3699
  "add it to the PHP headers in the <code>$_SERVER[\"NINJA_COUNTRY_CODE\"]</"
@@ -3701,48 +3689,48 @@ msgid ""
3701
  "visitors location, simply use that variable."
3702
  msgstr ""
3703
 
3704
- #: lib/i18n-extra.php:188
3705
  msgid ""
3706
  "If NinjaFirewall cannot find the two-letter ISO 3166 code, it will replace "
3707
  "it with 2 hyphens (<code>--</code>)."
3708
  msgstr ""
3709
 
3710
- #: lib/i18n-extra.php:189
3711
  msgid ""
3712
  "PHP code example to use in your theme or plugin to geolocate your visitors:"
3713
  msgstr ""
3714
 
3715
- #: lib/i18n-extra.php:190
3716
  msgid ""
3717
  "NinjaFirewall includes GeoLite data created by MaxMind, available from "
3718
  "http://www.maxmind.com"
3719
  msgstr ""
3720
 
3721
- #: lib/i18n-extra.php:191
3722
  msgid "IP / URL / Bot Access Control"
3723
  msgstr ""
3724
 
3725
- #: lib/i18n-extra.php:192
3726
  msgid ""
3727
  "You can permanently allow/block an IP, a whole range of IP addresses or AS "
3728
  "numbers (Autonomous System number). IPv4 and IPv6 are fully supported by "
3729
  "NinjaFirewall."
3730
  msgstr ""
3731
 
3732
- #: lib/i18n-extra.php:193
3733
  msgid "Full IP:"
3734
  msgstr ""
3735
 
3736
- #: lib/i18n-extra.php:194
3737
  #, php-format
3738
  msgid "IP ranges using CIDR notation: %s or %s."
3739
  msgstr ""
3740
 
3741
- #: lib/i18n-extra.php:195
3742
  msgid "Autonomous System number:"
3743
  msgstr ""
3744
 
3745
- #: lib/i18n-extra.php:196
3746
  msgid ""
3747
  "This option allows you to slow down aggressive bots, crawlers, web scrapers "
3748
  "or even small HTTP attacks. Any IP reaching the defined threshold will be "
@@ -3755,14 +3743,14 @@ msgid ""
3755
  "turned off."
3756
  msgstr ""
3757
 
3758
- #: lib/i18n-extra.php:197
3759
  msgid ""
3760
  "IPs temporarily banned by the Rate Limiting option can be unblocked "
3761
  "immediately by clicking either the \"Save Access Control Directives\" or "
3762
  "\"Restore Default Values\" buttons at the bottom of this page."
3763
  msgstr ""
3764
 
3765
- #: lib/i18n-extra.php:198
3766
  msgid ""
3767
  "Because NinjaFirewall can handle a lot of HTTP requests per second and block "
3768
  "IPs even before your blog is loaded, we strongly recommend that you disable "
@@ -3772,43 +3760,43 @@ msgid ""
3772
  "during an attack."
3773
  msgstr ""
3774
 
3775
- #: lib/i18n-extra.php:199
3776
  msgid ""
3777
  "You can permanently allow/block any access to one or more PHP scripts based "
3778
  "on their path, relative to the web root (<code>SCRIPT_NAME</code>). You can "
3779
  "enter either a full or partial path (case-sensitive)."
3780
  msgstr ""
3781
 
3782
- #: lib/i18n-extra.php:200
3783
  msgid ""
3784
  "<code>/foo/bar.php</code> will block any access to the <code>bar.php</code> "
3785
  "script located inside a <code>/foo/</code> directory"
3786
  msgstr ""
3787
 
3788
- #: lib/i18n-extra.php:201
3789
  msgid "etc"
3790
  msgstr ""
3791
 
3792
- #: lib/i18n-extra.php:202
3793
  msgid ""
3794
  "<code>/foo/</code> will block access to all PHP scripts located inside a "
3795
  "<code>/foo/</code> directory and its sub-directories."
3796
  msgstr ""
3797
 
3798
- #: lib/i18n-extra.php:203
3799
  msgid ""
3800
  "Note that the \"Firewall Policies\" page already includes restrictions to "
3801
  "some WordPress directories."
3802
  msgstr ""
3803
 
3804
- #: lib/i18n-extra.php:204
3805
  msgid ""
3806
  "You can block bots, scanners and various crawlers based on the "
3807
  "<code>HTTP_USER_AGENT</code> variable. You can enter either a full or "
3808
  "partial name (case-insensitive)."
3809
  msgstr ""
3810
 
3811
- #: lib/i18n-extra.php:205
3812
  msgid ""
3813
  "You can select to ignore or block some specific user input. It applies to "
3814
  "the <code>GET</code>, <code>POST</code> and <code>COOKIE</code> global "
@@ -3816,34 +3804,34 @@ msgid ""
3816
  "\"]</code>:"
3817
  msgstr ""
3818
 
3819
- #: lib/i18n-extra.php:206
3820
  msgid ""
3821
  "When an input is added to the \"Unfiltered input\" list, it will not be "
3822
  "filtered or sanitised. All other input present in the request will be "
3823
  "filtered."
3824
  msgstr ""
3825
 
3826
- #: lib/i18n-extra.php:207
3827
  msgid ""
3828
  "When an input is added to the \"Blocked input\", NinjaFirewall will block "
3829
  "the request and close the connection if that input is found in the request."
3830
  msgstr ""
3831
 
3832
- #: lib/i18n-extra.php:208
3833
  msgid "Log Event"
3834
  msgstr ""
3835
 
3836
- #: lib/i18n-extra.php:209
3837
  msgid ""
3838
  "You can enable/disable firewall logging for each access control directive "
3839
  "separately."
3840
  msgstr ""
3841
 
3842
- #: lib/i18n-extra.php:210
3843
  msgid "Web Filter"
3844
  msgstr ""
3845
 
3846
- #: lib/i18n-extra.php:211
3847
  msgid ""
3848
  "If NinjaFirewall can hook and scan incoming requests, it can also hook the "
3849
  "response body (i.e., the output of the HTML page right before it is sent to "
@@ -3853,27 +3841,27 @@ msgid ""
3853
  "hackers shell script, redirections and even errors (PHP/MySQL errors)."
3854
  msgstr ""
3855
 
3856
- #: lib/i18n-extra.php:212
3857
  msgid ""
3858
  "In the case of a positive detection, NinjaFirewall will not block the "
3859
  "response body but will send you an alert by email."
3860
  msgstr ""
3861
 
3862
- #: lib/i18n-extra.php:213
3863
  msgid "Search HTML page for the following keywords"
3864
  msgstr ""
3865
 
3866
- #: lib/i18n-extra.php:214
3867
  msgid ""
3868
  "You can enter any keyword from 4 to 150 characters and select whether the "
3869
  "search will be case sensitive or not."
3870
  msgstr ""
3871
 
3872
- #: lib/i18n-extra.php:215
3873
  msgid "Email Alerts"
3874
  msgstr ""
3875
 
3876
- #: lib/i18n-extra.php:216
3877
  msgid ""
3878
  "You can use the notification throttling option to limit the frequency of "
3879
  "alerts sent to you (and written to the firewall log) and select whether you "
@@ -3882,14 +3870,14 @@ msgid ""
3882
  "in the \"Event Notifications\" menu."
3883
  msgstr ""
3884
 
3885
- #: lib/i18n-extra.php:217
3886
  msgid ""
3887
  "Response body filtering can be resource-intensive. Try to limit the number "
3888
  "of keywords to what you really need (less than 10) and, if possible, prefer "
3889
  "case sensitive to case insensitive filtering."
3890
  msgstr ""
3891
 
3892
- #: lib/i18n-extra.php:218
3893
  msgid ""
3894
  "NinjaFirewall can protect your blog against spam without user interaction (e."
3895
  "g., CAPTCHA, math puzzles etc). The protection is totally transparent to "
@@ -3898,132 +3886,132 @@ msgid ""
3898
  "generate your forms, they will not be protected against spam."
3899
  msgstr ""
3900
 
3901
- #: lib/i18n-extra.php:219
3902
  msgid "Protection level:"
3903
  msgstr ""
3904
 
3905
- #: lib/i18n-extra.php:220
3906
  msgid ""
3907
  "Select the level of protection. In most cases, <strong>Low</strong> should "
3908
  "be enough."
3909
  msgstr ""
3910
 
3911
- #: lib/i18n-extra.php:221
3912
  msgid "Apply protection to:"
3913
  msgstr ""
3914
 
3915
- #: lib/i18n-extra.php:222
3916
  msgid "Whether to protect comment and/or registration forms."
3917
  msgstr ""
3918
 
3919
- #: lib/i18n-extra.php:223
3920
  msgid "If you are using a caching plugin, ensure you follow these steps:"
3921
  msgstr ""
3922
 
3923
- #: lib/i18n-extra.php:224
3924
  msgid ""
3925
  "Set the Protection Level to \"Low\" only. Do not use another value, "
3926
  "otherwise the antispam could behave erratically after a while."
3927
  msgstr ""
3928
 
3929
- #: lib/i18n-extra.php:225
3930
  msgid ""
3931
  "Flush/clear your cache immediately after enabling or disabling the antispam."
3932
  msgstr ""
3933
 
3934
- #: lib/i18n-extra.php:226
3935
  msgid ""
3936
  "The firewall log displays blocked and sanitised requests as well as some "
3937
  "useful information. It has 6 columns:"
3938
  msgstr ""
3939
 
3940
- #: lib/i18n-extra.php:227
3941
  msgid ""
3942
  "RULE : reference of the NinjaFirewall built-in security rule that triggered "
3943
  "the action. A hyphen (<code>-</code>) instead of a number means it was a "
3944
  "rule from the \"Firewall Policies\" or \"Access Control\" pages."
3945
  msgstr ""
3946
 
3947
- #: lib/i18n-extra.php:228
3948
  msgid "The log can also be exported as a TSV (tab-separated values) text file."
3949
  msgstr ""
3950
 
3951
- #: lib/i18n-extra.php:229
3952
  msgid "Enable firewall log"
3953
  msgstr ""
3954
 
3955
- #: lib/i18n-extra.php:230
3956
  msgid "You can disable/enable the firewall log from this page."
3957
  msgstr ""
3958
 
3959
- #: lib/i18n-extra.php:231
3960
  msgid ""
3961
  "Brute-force attacks will still be written to the firewall log, even if you "
3962
  "disable it."
3963
  msgstr ""
3964
 
3965
- #: lib/i18n-extra.php:232
3966
  msgid "Auto-rotate log"
3967
  msgstr ""
3968
 
3969
- #: lib/i18n-extra.php:233
3970
  msgid ""
3971
  "NinjaFirewall will rotate its log automatically on the very first day of "
3972
  "each month. If your site is very busy, you may want to allow it to rotate "
3973
  "the log when it reaches a certain size (MB) as well."
3974
  msgstr ""
3975
 
3976
- #: lib/i18n-extra.php:234
3977
  msgid ""
3978
  "By default, if will rotate the log each month or earlier, if it reaches 2 "
3979
  "megabytes."
3980
  msgstr ""
3981
 
3982
- #: lib/i18n-extra.php:235
3983
  msgid ""
3984
  "Rotated logs, if any, can be selected and viewed from the dropdown menu."
3985
  msgstr ""
3986
 
3987
- #: lib/i18n-extra.php:236
3988
  msgid "Syslog"
3989
  msgstr ""
3990
 
3991
- #: lib/i18n-extra.php:237
3992
  msgid ""
3993
  "In addition to the firewall log, events can also be redirected to the syslog "
3994
  "server (<code>LOG_USER</code> facility)."
3995
  msgstr ""
3996
 
3997
- #: lib/i18n-extra.php:238
3998
  msgid ""
3999
  "If you have a shared hosting account, keep this option disabled as you do "
4000
  "not have any access to the server logs."
4001
  msgstr ""
4002
 
4003
- #: lib/i18n-extra.php:239
4004
  msgid "The logline uses the following format:"
4005
  msgstr ""
4006
 
4007
- #: lib/i18n-extra.php:240
4008
  msgid ""
4009
  "BB: the level of severity as it appears in the firewall log. It can be "
4010
  "<code>CRITICAL</CODE>, <CODE>HIGH</CODE>, <CODE>MEDIUM</CODE>, <CODE>INFO</"
4011
  "CODE>, <CODE>UPLOAD</CODE> or <CODE>DEBUG_ON</CODE>."
4012
  msgstr ""
4013
 
4014
- #: lib/i18n-extra.php:241
4015
  msgid "CCCCCC: the 7-digit incident ID."
4016
  msgstr ""
4017
 
4018
- #: lib/i18n-extra.php:242
4019
  msgid "DD: the user IPv4 or IPv6 address."
4020
  msgstr ""
4021
 
4022
- #: lib/i18n-extra.php:243
4023
  msgid "EE: the blog (sub-)domain name."
4024
  msgstr ""
4025
 
4026
- #: lib/i18n-extra.php:244
4027
  #, php-format
4028
  msgid ""
4029
  "This logging option does not apply to the brute-force protection which can "
@@ -4031,14 +4019,14 @@ msgid ""
4031
  "the <a href=\"%s\">Login Protection</a> page."
4032
  msgstr ""
4033
 
4034
- #: lib/i18n-extra.php:245
4035
  msgid ""
4036
  "Secret key: The secret key will be used to generate your public key. Enter "
4037
  "at least 30 ASCII characters, or use the one randomly created by "
4038
  "NinjaFirewall."
4039
  msgstr ""
4040
 
4041
- #: lib/i18n-extra.php:246
4042
  msgid ""
4043
  "This server IP address: As an additional protection layer, you can restrict "
4044
  "access to the remote website(s) to the main server IP only. You can use IPv4 "
@@ -4046,331 +4034,331 @@ msgid ""
4046
  "character instead."
4047
  msgstr ""
4048
 
4049
- #: lib/i18n-extra.php:247
4050
  #, php-format
4051
  msgid ""
4052
  "Public key: This is the public key that you will need to upload to each "
4053
  "remote website (<a href=\"%s\">consult our blog</a> for more info about it)."
4054
  msgstr ""
4055
 
4056
- #: lib/i18n-extra.php:248
4057
  msgid ""
4058
  "Remote websites URL: Enter the full URL of your NinjaFirewall protected "
4059
  "website(s) that you want to remotely access from the main server."
4060
  msgstr ""
4061
 
4062
- #: lib/i18n-extra.php:249
4063
  msgid ""
4064
  "Centralized Logging will keep working even if NinjaFirewall is disabled. Use "
4065
  "the menu below if you want to disable it."
4066
  msgstr ""
4067
 
4068
- #: lib/i18n-extra.php:250
4069
  msgid "Enable Web Filter"
4070
  msgstr ""
4071
 
4072
- #: lib/i18n-extra.php:251
4073
  msgid "A full or partial string."
4074
  msgstr ""
4075
 
4076
- #: lib/i18n-extra.php:252
4077
  msgid "From 4 to maximum 150 characters."
4078
  msgstr ""
4079
 
4080
- #: lib/i18n-extra.php:253
4081
  msgid "Any character, except the vertical bar <code>|</code>"
4082
  msgstr ""
4083
 
4084
- #: lib/i18n-extra.php:254
4085
  msgid "Keywords to search:"
4086
  msgstr ""
4087
 
4088
- #: lib/i18n-extra.php:255
4089
  msgid "Case-sensitive search"
4090
  msgstr ""
4091
 
4092
- #: lib/i18n-extra.php:256
4093
  #, php-format
4094
  msgid "Do not send me more than one email alert in a %s interval"
4095
  msgstr ""
4096
 
4097
- #: lib/i18n-extra.php:257
4098
  msgid "5-minute"
4099
  msgstr ""
4100
 
4101
- #: lib/i18n-extra.php:258
4102
  msgid "15-minute"
4103
  msgstr ""
4104
 
4105
- #: lib/i18n-extra.php:259
4106
  msgid "30-minute"
4107
  msgstr ""
4108
 
4109
- #: lib/i18n-extra.php:260
4110
  msgid "1-hour"
4111
  msgstr ""
4112
 
4113
- #: lib/i18n-extra.php:261
4114
  msgid "3-hour"
4115
  msgstr ""
4116
 
4117
- #: lib/i18n-extra.php:262
4118
  msgid "6-hour"
4119
  msgstr ""
4120
 
4121
- #: lib/i18n-extra.php:263
4122
  msgid "12-hour"
4123
  msgstr ""
4124
 
4125
- #: lib/i18n-extra.php:264
4126
  msgid "24-hour"
4127
  msgstr ""
4128
 
4129
- #: lib/i18n-extra.php:265
4130
  msgid ""
4131
  "Clicking the \"Save Web Filter options\" button below will reset the current "
4132
  "timer."
4133
  msgstr ""
4134
 
4135
- #: lib/i18n-extra.php:266
4136
  msgid "Attach the HTML page output to email alerts"
4137
  msgstr ""
4138
 
4139
- #: lib/i18n-extra.php:267
4140
  msgid "Save Web Filter options"
4141
  msgstr ""
4142
 
4143
- #: lib/i18n-extra.php:268
4144
  msgid "Help Desk:"
4145
  msgstr ""
4146
 
4147
- #: lib/i18n-extra.php:269
4148
  msgid "The selected log was deleted"
4149
  msgstr ""
4150
 
4151
- #: lib/i18n-extra.php:270
4152
  msgid "Export"
4153
  msgstr ""
4154
 
4155
- #: lib/i18n-extra.php:271
4156
  msgid "Delete"
4157
  msgstr ""
4158
 
4159
- #: lib/i18n-extra.php:272
4160
  msgid "Delete log?"
4161
  msgstr ""
4162
 
4163
- #: lib/i18n-extra.php:273
4164
  msgid "Today"
4165
  msgstr ""
4166
 
4167
- #: lib/i18n-extra.php:274
4168
  msgid "Upload"
4169
  msgstr ""
4170
 
4171
- #: lib/i18n-extra.php:275
4172
  msgid "Info"
4173
  msgstr ""
4174
 
4175
- #: lib/i18n-extra.php:276
4176
  msgid "Debug"
4177
  msgstr ""
4178
 
4179
- #: lib/i18n-extra.php:277
4180
  msgid "IP address:"
4181
  msgstr ""
4182
 
4183
- #: lib/i18n-extra.php:278
4184
  msgid "e.g., 1.2.3.4"
4185
  msgstr ""
4186
 
4187
- #: lib/i18n-extra.php:279
4188
  msgid "Add IP to blacklist"
4189
  msgstr ""
4190
 
4191
- #: lib/i18n-extra.php:280
4192
  msgid "Add IP to whitelist"
4193
  msgstr ""
4194
 
4195
- #: lib/i18n-extra.php:281
4196
  msgid "Add"
4197
  msgstr ""
4198
 
4199
- #: lib/i18n-extra.php:282
4200
  msgid "The address wad added to your IP Access Control list."
4201
  msgstr ""
4202
 
4203
- #: lib/i18n-extra.php:283
4204
  #, php-format
4205
  msgid "1st day of the month, or if bigger than %s MB"
4206
  msgstr ""
4207
 
4208
- #: lib/i18n-extra.php:284
4209
  msgid "1st day of the month, regardless of its size"
4210
  msgstr ""
4211
 
4212
- #: lib/i18n-extra.php:285
4213
  msgid "Show the most recent"
4214
  msgstr ""
4215
 
4216
- #: lib/i18n-extra.php:286
4217
  msgid "lines"
4218
  msgstr ""
4219
 
4220
- #: lib/i18n-extra.php:287
4221
  msgid "Write events to the Syslog server too"
4222
  msgstr ""
4223
 
4224
- #: lib/i18n-extra.php:288
4225
  msgid "Your server configuration is not compatible with this option."
4226
  msgstr ""
4227
 
4228
- #: lib/i18n-extra.php:289
4229
  msgid "See contextual help before enabling this option."
4230
  msgstr ""
4231
 
4232
- #: lib/i18n-extra.php:290
4233
  msgid ""
4234
  "The remote server rejected your request. Make sure that you uploaded the "
4235
  "correct public key."
4236
  msgstr ""
4237
 
4238
- #: lib/i18n-extra.php:291
4239
  #, php-format
4240
  msgid "The remote server returned the following HTTP error: %s"
4241
  msgstr ""
4242
 
4243
- #: lib/i18n-extra.php:292
4244
  msgid "The requested log does not exist on the remote website."
4245
  msgstr ""
4246
 
4247
- #: lib/i18n-extra.php:293
4248
  msgid "The remote website did not return the expected response."
4249
  msgstr ""
4250
 
4251
- #: lib/i18n-extra.php:294
4252
  msgid "Your server does not seem to be compatible with this option."
4253
  msgstr ""
4254
 
4255
- #: lib/i18n-extra.php:295
4256
  msgid "Load language files from the WordPress repo"
4257
  msgstr ""
4258
 
4259
- #: lib/i18n-extra.php:296
4260
  #, php-format
4261
  msgid ""
4262
  "If available, NinjaFirewall will download the language files from <a "
4263
  "%s>translate.wordpress.org</a>."
4264
  msgstr ""
4265
 
4266
- #: lib/i18n-extra.php:297
4267
  msgid "Error: you do not have any license."
4268
  msgstr ""
4269
 
4270
- #: lib/i18n-extra.php:298
4271
  msgid "You have a valid license."
4272
  msgstr ""
4273
 
4274
- #: lib/i18n-extra.php:299
4275
  msgid ""
4276
  "An unknown error occured while connecting to NinjaFirewall servers. Please "
4277
  "try again in a few minutes"
4278
  msgstr ""
4279
 
4280
- #: lib/i18n-extra.php:300
4281
  msgid ""
4282
  "An error occured while connecting to NinjaFirewall servers. Please try again "
4283
  "in a few minutes"
4284
  msgstr ""
4285
 
4286
- #: lib/i18n-extra.php:301
4287
  msgid "Enter a valid license to save!"
4288
  msgstr ""
4289
 
4290
- #: lib/i18n-extra.php:302
4291
  msgid "This is already your current license!"
4292
  msgstr ""
4293
 
4294
- #: lib/i18n-extra.php:303
4295
  msgid "Your new license has been accepted and saved."
4296
  msgstr ""
4297
 
4298
- #: lib/i18n-extra.php:304
4299
  msgid "This license is not valid"
4300
  msgstr ""
4301
 
4302
- #: lib/i18n-extra.php:305
4303
  msgid "WP+ Edition License"
4304
  msgstr ""
4305
 
4306
- #: lib/i18n-extra.php:306
4307
  msgid "License Number"
4308
  msgstr ""
4309
 
4310
- #: lib/i18n-extra.php:307
4311
  msgid "No license found"
4312
  msgstr ""
4313
 
4314
- #: lib/i18n-extra.php:308
4315
  msgid "Click to check your license validity"
4316
  msgstr ""
4317
 
4318
- #: lib/i18n-extra.php:309
4319
  msgid "Expiration date"
4320
  msgstr ""
4321
 
4322
- #: lib/i18n-extra.php:310
4323
  msgid "Unknown expiration date"
4324
  msgstr ""
4325
 
4326
- #: lib/i18n-extra.php:311
4327
  msgid "Use the \"Check License Validity\" button to attempt to fix this error."
4328
  msgstr ""
4329
 
4330
- #: lib/i18n-extra.php:312
4331
  msgid "Your license will expire soon!"
4332
  msgstr ""
4333
 
4334
- #: lib/i18n-extra.php:313
4335
  msgid "Your license has expired."
4336
  msgstr ""
4337
 
4338
- #: lib/i18n-extra.php:314
4339
  msgid "License renewal"
4340
  msgstr ""
4341
 
4342
- #: lib/i18n-extra.php:315
4343
  msgid "Click here to get a license!"
4344
  msgstr ""
4345
 
4346
- #: lib/i18n-extra.php:316
4347
  msgid "Enter your new license and click on the save button"
4348
  msgstr ""
4349
 
4350
- #: lib/i18n-extra.php:317
4351
  msgid "Save New License"
4352
  msgstr ""
4353
 
4354
- #: lib/i18n-extra.php:318
4355
  msgid "Allow, but block dangerous files"
4356
  msgstr ""
4357
 
4358
- #: lib/i18n-extra.php:319
4359
  msgid "See contextual help for the list of files."
4360
  msgstr ""
4361
 
4362
- #: lib/i18n-extra.php:320
4363
  msgid "Apply to ZIP archives file contents"
4364
  msgstr ""
4365
 
4366
- #: lib/i18n-extra.php:321
4367
  msgid ""
4368
  "Keep this option disabled if you are using scripts such as Paypal IPN or "
4369
  "WordPress WP-Cron, unless you added their IP address or URL to your Access "
4370
  "Control whitelist."
4371
  msgstr ""
4372
 
4373
- #: lib/i18n-extra.php:322
4374
  #, php-format
4375
  msgid ""
4376
  "Do not send a notification if the user is in the <a href=\"%s\">IP Access "
@@ -4383,12 +4371,12 @@ msgid ""
4383
  "Error: Your .htaccess file is not writable, please change its permissions: %s"
4384
  msgstr ""
4385
 
4386
- #: lib/install.php:110 ninjafirewall.php:649 ninjafirewall.php:653
4387
  #, php-format
4388
  msgid "Error: wrong parameter value (%s)."
4389
  msgstr ""
4390
 
4391
- #: lib/install.php:117 lib/install.php:211 lib/install.php:232
4392
  #, php-format
4393
  msgid ""
4394
  "Error: The following file is not writable, please change its permissions: %s"
@@ -4407,22 +4395,22 @@ msgid ""
4407
  "again."
4408
  msgstr ""
4409
 
4410
- #: lib/install.php:157
4411
  #, php-format
4412
  msgid "The website front-end returned: HTTP %s %s."
4413
  msgstr ""
4414
 
4415
- #: lib/install.php:167
4416
  msgid "The website front-end did not return the expected page."
4417
  msgstr ""
4418
 
4419
- #: lib/install.php:176
4420
  #, php-format
4421
  msgid "The website front-end returned a fatal error: %s."
4422
  msgstr ""
4423
 
4424
- #: lib/install.php:275 lib/install.php:300 lib/install.php:325
4425
- #: lib/install.php:346
4426
  msgid "File is not writable"
4427
  msgstr ""
4428
 
@@ -4625,7 +4613,7 @@ msgstr ""
4625
  msgid "Error: unable to write to the %s configuration file"
4626
  msgstr ""
4627
 
4628
- #: lib/logs.php:36 ninjafirewall.php:851
4629
  msgid "Logs"
4630
  msgstr ""
4631
 
@@ -4734,7 +4722,7 @@ msgid ""
4734
  "Administrator to the whitelist\" option is enabled."
4735
  msgstr ""
4736
 
4737
- #: lib/logs_live_log.php:96 ninjafirewall.php:371
4738
  msgid ""
4739
  "Live Log lets you watch your blog traffic in real time. To enable it, click "
4740
  "on the button below."
@@ -4835,7 +4823,7 @@ msgstr ""
4835
  msgid "Error: please enter the custom log format."
4836
  msgstr ""
4837
 
4838
- #: lib/monitoring.php:43 ninjafirewall.php:825
4839
  msgid "Monitoring"
4840
  msgstr ""
4841
 
@@ -5127,15 +5115,15 @@ msgstr ""
5127
  msgid "Error reading new snapshot file."
5128
  msgstr ""
5129
 
5130
- #: lib/monitoring_file_check.php:748 ninjafirewall.php:470
5131
  msgid "New file"
5132
  msgstr ""
5133
 
5134
- #: lib/monitoring_file_check.php:749 ninjafirewall.php:471
5135
  msgid "Modified file"
5136
  msgstr ""
5137
 
5138
- #: lib/monitoring_file_check.php:750 ninjafirewall.php:472
5139
  msgid "Deleted file"
5140
  msgstr ""
5141
 
@@ -5146,8 +5134,8 @@ msgstr ""
5146
  #: lib/monitoring_file_check.php:777 lib/monitoring_file_check.php:779
5147
  #: lib/monitoring_file_check.php:799 lib/monitoring_file_check.php:801
5148
  #: lib/security_rules_update.php:572 lib/security_rules_update.php:574
5149
- #: lib/utils.php:225 lib/utils.php:311 lib/utils.php:435 lib/utils.php:1082
5150
- #: lib/utils.php:1261 lib/utils.php:1540
5151
  msgid "Blog:"
5152
  msgstr ""
5153
 
@@ -5211,7 +5199,7 @@ msgstr ""
5211
  msgid "Save File Guard options"
5212
  msgstr ""
5213
 
5214
- #: lib/network.php:24 ninjafirewall.php:1112 ninjafirewall.php:1116
5215
  #, php-format
5216
  msgid "You are not allowed to perform this task (%s)."
5217
  msgstr ""
@@ -5235,7 +5223,7 @@ msgid "Save Network options"
5235
  msgstr ""
5236
 
5237
  #: lib/security_rules.php:44 lib/security_rules_update.php:578
5238
- #: ninjafirewall.php:855
5239
  msgid "Security Rules"
5240
  msgstr ""
5241
 
@@ -5412,7 +5400,7 @@ msgstr ""
5412
  msgid "Check For Updates Now!"
5413
  msgstr ""
5414
 
5415
- #: lib/security_rules_update.php:233 lib/thickbox.php:52
5416
  msgid "Delete Log"
5417
  msgstr ""
5418
 
@@ -5480,90 +5468,105 @@ msgstr ""
5480
  msgid "This notification can be turned off from NinjaFirewall \"%s\" page."
5481
  msgstr ""
5482
 
5483
- #: lib/thickbox.php:42
5484
  msgid "NinjaFirewall error log"
5485
  msgstr ""
5486
 
5487
- #: lib/thickbox.php:52
5488
  msgid "Close Log"
5489
  msgstr ""
5490
 
5491
- #: lib/thickbox.php:76
5492
  msgid ""
5493
- "In <strong>Full WAF</strong> mode, all scripts located inside the blog "
5494
- "installation directories and sub-directories are protected by NinjaFirewall, "
5495
- "including those that aren't part of the WordPress package. It gives you the "
5496
- "highest possible level of protection: security without compromise."
5497
  msgstr ""
5498
 
5499
- #: lib/thickbox.php:78
5500
  #, php-format
5501
  msgid ""
5502
- "It works on most websites right out of the box, or may require <a href=\"%s"
5503
- "\" title=\"%s\">some very little tweaks</a>. But in a few cases, mostly "
5504
- "because of some shared hosting plans restrictions, it may simply not work at "
5505
- "all."
5506
  msgstr ""
5507
 
5508
- #: lib/thickbox.php:80
5509
  msgid ""
5510
- "If this happened to you, don't worry: you could still run it in "
5511
- "<strong>WordPress WAF</strong> mode. Despite being less powerful than the "
5512
- "<b>Full WAF</b> mode, it offers a level of protection and performance much "
5513
- "higher than other security plugins."
5514
  msgstr ""
5515
 
5516
- #: lib/thickbox.php:154
5517
  msgid "Select your HTTP server and your PHP server API"
5518
  msgstr ""
5519
 
5520
- #: lib/thickbox.php:165
5521
  msgid "Other webserver + CGI/FastCGI or PHP-FPM"
5522
  msgstr ""
5523
 
5524
- #: lib/thickbox.php:167
5525
  msgid "View PHPINFO"
5526
  msgstr ""
5527
 
5528
- #: lib/thickbox.php:199
5529
  msgid "Select the PHP initialization file supported by your server"
5530
  msgstr ""
5531
 
5532
- #: lib/thickbox.php:211
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5533
  msgid "Let NinjaFirewall make the necessary changes (recommended)."
5534
  msgstr ""
5535
 
5536
- #: lib/thickbox.php:213
5537
  msgid "I want to make the changes myself."
5538
  msgstr ""
5539
 
5540
- #: lib/thickbox.php:215
5541
  msgid ""
5542
  "Please make the changes below, then click on the \"Finish Installation\" "
5543
  "button."
5544
  msgstr ""
5545
 
5546
- #: lib/thickbox.php:222
5547
  #, php-format
5548
  msgid ""
5549
  "The %s file must be created, and the following lines of code added to it:"
5550
  msgstr ""
5551
 
5552
- #: lib/thickbox.php:223
5553
  #, php-format
5554
  msgid "The following lines of code must be added to your existing %s file:"
5555
  msgstr ""
5556
 
5557
- #: lib/thickbox.php:291
5558
- #, php-format
5559
  msgid ""
5560
  "Log in to your Openlitespeed admin dashboard, click on \"Virtual Host\", "
5561
  "select your domain, add the following instructions to the \"php.ini Override"
5562
- "\" section in the \"General\" tab, and restart Openlitespeed (see more "
5563
- "detail <a %s>here</a>):"
5564
  msgstr ""
5565
 
5566
- #: lib/thickbox.php:298
5567
  msgid ""
5568
  "Important: if one day you wanted to uninstall NinjaFirewall, do not forget "
5569
  "to remove these instructions from your Openlitespeed admin dashboard "
@@ -5571,20 +5574,60 @@ msgid ""
5571
  "could not do it for you."
5572
  msgstr ""
5573
 
5574
- #: lib/thickbox.php:314
5575
  msgid "Enable the sandbox."
5576
  msgstr ""
5577
 
5578
- #: lib/thickbox.php:314
5579
  msgid ""
5580
  "If there were a problem during the installation, NinjaFirewall would undo "
5581
  "those changes automatically for you."
5582
  msgstr ""
5583
 
5584
- #: lib/thickbox.php:315
5585
  msgid "Finish Installation"
5586
  msgstr ""
5587
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5588
  #: lib/utils.php:183 lib/utils.php:191 lib/utils.php:295
5589
  msgid "N/A"
5590
  msgstr ""
@@ -5613,7 +5656,7 @@ msgid ""
5613
  "doesn't have the right capabilities:"
5614
  msgstr ""
5615
 
5616
- #: lib/utils.php:226 lib/utils.php:312 lib/utils.php:436 lib/utils.php:1265
5617
  msgid "Username:"
5618
  msgstr ""
5619
 
@@ -5621,24 +5664,24 @@ msgstr ""
5621
  msgid "Action:"
5622
  msgstr ""
5623
 
5624
- #: lib/utils.php:230 lib/utils.php:315 lib/utils.php:437 lib/utils.php:1269
5625
- #: lib/utils.php:1541
5626
  msgid "User IP:"
5627
  msgstr ""
5628
 
5629
- #: lib/utils.php:242 lib/utils.php:327 lib/utils.php:449 lib/utils.php:1281
5630
- #: lib/utils.php:1536
5631
  msgid "A PHP backtrace has been attached to this message for your convenience."
5632
  msgstr ""
5633
 
5634
- #: lib/utils.php:244 lib/utils.php:329 lib/utils.php:1284 lib/utils.php:1546
5635
  msgid ""
5636
  "This protection (and notification) can be turned off from NinjaFirewall "
5637
  "\"Firewall Policies\" page."
5638
  msgstr ""
5639
 
5640
  #: lib/utils.php:259 lib/utils.php:260 lib/utils.php:344 lib/utils.php:345
5641
- #: lib/utils.php:466 lib/utils.php:467 lib/utils.php:1300 lib/utils.php:1301
5642
  msgid "You are not allowed to perform this task."
5643
  msgstr ""
5644
 
@@ -5660,100 +5703,100 @@ msgstr ""
5660
  msgid "NinjaFirewall has blocked an attempt to create a user account:"
5661
  msgstr ""
5662
 
5663
- #: lib/utils.php:757
5664
  msgid ""
5665
  "Warning: Because NinjaFirewall's Login Protection is enabled, Site Health "
5666
  "may return an error message regarding the loopback test (e.g., 404 or 401 "
5667
  "HTTP status code). You can safely ignore it."
5668
  msgstr ""
5669
 
5670
- #: lib/utils.php:780 lib/utils.php:784
5671
  msgid "NinjaFirewall error"
5672
  msgstr ""
5673
 
5674
- #: lib/utils.php:781
5675
  #, php-format
5676
  msgid ""
5677
  "%s directory cannot be created. Please review your installation and ensure "
5678
  "that %s is writable."
5679
  msgstr ""
5680
 
5681
- #: lib/utils.php:785
5682
  #, php-format
5683
  msgid ""
5684
  "%s directory is read-only. Please review your installation and ensure that "
5685
  "%s is writable."
5686
  msgstr ""
5687
 
5688
- #: lib/utils.php:800
5689
  msgid "unknown error"
5690
  msgstr ""
5691
 
5692
- #: lib/utils.php:802
5693
  msgid "NinjaFirewall fatal error:"
5694
  msgstr ""
5695
 
5696
- #: lib/utils.php:803
5697
  msgid "Review your installation, your site is not protected."
5698
  msgstr ""
5699
 
5700
- #: lib/utils.php:830
5701
  msgid "Alert: WordPress console login"
5702
  msgstr ""
5703
 
5704
- #: lib/utils.php:836
5705
  msgid "Someone just logged in to your WordPress admin console:"
5706
  msgstr ""
5707
 
5708
- #: lib/utils.php:948 lib/utils.php:975
5709
  msgid "Forbidden access"
5710
  msgstr ""
5711
 
5712
- #: lib/utils.php:994
5713
  #, php-format
5714
  msgid ""
5715
  "<strong>ERROR</strong>: Invalid username, email address or password.<br /><a "
5716
  "href=\"%s\">Lost your password</a>?"
5717
  msgstr ""
5718
 
5719
- #: lib/utils.php:1078
5720
  msgid "[NinjaFirewall] Alert: Database changes detected"
5721
  msgstr ""
5722
 
5723
- #: lib/utils.php:1079
5724
  msgid ""
5725
  "NinjaFirewall has detected that one or more administrator accounts were "
5726
  "modified in the database:"
5727
  msgstr ""
5728
 
5729
- #: lib/utils.php:1084
5730
  #, php-format
5731
  msgid "Total administrators : %s"
5732
  msgstr ""
5733
 
5734
- #: lib/utils.php:1093
5735
  msgid ""
5736
  "If you cannot see any modifications in the above fields, it is possible that "
5737
  "the administrator password was changed."
5738
  msgstr ""
5739
 
5740
- #: lib/utils.php:1246
5741
  msgid "Blocked privilege escalation attempt"
5742
  msgstr ""
5743
 
5744
- #: lib/utils.php:1259
5745
  msgid ""
5746
  "NinjaFirewall has blocked an attempt to modify a user capability by someone "
5747
  "who does not have administrative privileges:"
5748
  msgstr ""
5749
 
5750
- #: lib/utils.php:1312
5751
  msgid ""
5752
  "NinjaFirewall brute-force protection is enabled and you are temporarily "
5753
  "whitelisted."
5754
  msgstr ""
5755
 
5756
- #: lib/utils.php:1327
5757
  #, php-format
5758
  msgid ""
5759
  "Hey, it seems that you've been using NinjaFirewall for some time. If you "
@@ -5762,71 +5805,79 @@ msgid ""
5762
  "rate it. Thank you!"
5763
  msgstr ""
5764
 
5765
- #: lib/utils.php:1508
5766
  msgid ""
5767
  "The attempt was blocked and the option was reversed to its original value."
5768
  msgstr ""
5769
 
5770
- #: lib/utils.php:1513
5771
  msgid "Attempt to modify WordPress settings"
5772
  msgstr ""
5773
 
5774
- #: lib/utils.php:1514
5775
  msgid ""
5776
  "NinjaFirewall has blocked an attempt to modify some important WordPress "
5777
  "settings by a user that does not have administrative privileges:"
5778
  msgstr ""
5779
 
5780
- #: lib/utils.php:1515 lib/utils.php:1524
5781
  #, php-format
5782
  msgid "Option: %s"
5783
  msgstr ""
5784
 
5785
- #: lib/utils.php:1516
5786
  #, php-format
5787
  msgid "Original value: %s"
5788
  msgstr ""
5789
 
5790
- #: lib/utils.php:1517
5791
  #, php-format
5792
  msgid "Modified value: %s"
5793
  msgstr ""
5794
 
5795
- #: lib/utils.php:1518 lib/utils.php:1526
5796
  #, php-format
5797
  msgid "Action taken: %s"
5798
  msgstr ""
5799
 
5800
- #: lib/utils.php:1522
5801
  msgid "Code injection attempt in WordPress options table"
5802
  msgstr ""
5803
 
5804
- #: lib/utils.php:1523
5805
  msgid ""
5806
  "NinjaFirewall has blocked an attempt to inject code in the WordPress options "
5807
  "table by a user that does not have administrative privileges:"
5808
  msgstr ""
5809
 
5810
- #: lib/utils.php:1525
5811
  #, php-format
5812
  msgid "Code: %s"
5813
  msgstr ""
5814
 
5815
- #: lib/utils.php:1576
 
 
 
 
 
 
 
 
5816
  #, php-format
5817
  msgid "Error, cannot create the %s folder."
5818
  msgstr ""
5819
 
5820
- #: lib/utils.php:1576 lib/utils.php:1584 lib/utils.php:1592
5821
  msgid "Check your server permissions and try again."
5822
  msgstr ""
5823
 
5824
- #: lib/utils.php:1584
5825
  #, php-format
5826
  msgid "Error, the %s folder is not writable."
5827
  msgstr ""
5828
 
5829
- #: lib/utils.php:1592
5830
  #, php-format
5831
  msgid "Error, cannot write %s."
5832
  msgstr ""
@@ -6260,187 +6311,187 @@ msgstr ""
6260
  msgid "NinjaFirewall is not compatible with Microsoft Windows."
6261
  msgstr ""
6262
 
6263
- #: ninjafirewall.php:322
6264
  msgid ""
6265
  "All fields will be restored to their default values and any changes you made "
6266
  "will be lost. Continue?"
6267
  msgstr ""
6268
 
6269
- #: ninjafirewall.php:326
6270
  msgid "Missing security nonce, try to reload the page."
6271
  msgstr ""
6272
 
6273
- #: ninjafirewall.php:328
6274
  msgid "Please select the HTTP server in the list."
6275
  msgstr ""
6276
 
6277
- #: ninjafirewall.php:331
6278
  msgid "Delete the firewall's error log ?"
6279
  msgstr ""
6280
 
6281
- #: ninjafirewall.php:335
6282
  msgid ""
6283
  "This action will restore the selected configuration file and will override "
6284
  "all your current firewall options, policies and rules. Continue?"
6285
  msgstr ""
6286
 
6287
- #: ninjafirewall.php:339
6288
  msgid ""
6289
  "Any character that is not a letter [a-zA-Z], a digit [0-9], a dot [.], a "
6290
  "hyphen [-] or an underscore [_] will be removed from the filename and "
6291
  "replaced with the substitution character. Continue?"
6292
  msgstr ""
6293
 
6294
- #: ninjafirewall.php:341
6295
  msgid ""
6296
  "Ensure that you can access your admin console over HTTPS before enabling "
6297
  "this option, otherwise you will lock yourself out of your site. Continue?"
6298
  msgstr ""
6299
 
6300
- #: ninjafirewall.php:343
6301
  msgid ""
6302
  "WooCommerce is running: if you block accounts creation, your customers won't "
6303
  "be able to sign up. Continue?"
6304
  msgstr ""
6305
 
6306
- #: ninjafirewall.php:345
6307
  msgid ""
6308
  "Your blog has user registration enabled: if you block accounts creation, "
6309
  "your customers won't be able to sign up. Continue?"
6310
  msgstr ""
6311
 
6312
- #: ninjafirewall.php:347
6313
  msgid ""
6314
  "Your multisite installation allows users to register new sites: if you "
6315
  "enable this option, they will likely get blocked when creating their blog. "
6316
  "Continue?"
6317
  msgstr ""
6318
 
6319
- #: ninjafirewall.php:351
6320
  msgid "Delete the current snapshot ?"
6321
  msgstr ""
6322
 
6323
- #: ninjafirewall.php:355
6324
  msgid "Invalid character."
6325
  msgstr ""
6326
 
6327
- #: ninjafirewall.php:357
6328
  msgid "\"admin\" is not acceptable, please choose another user name."
6329
  msgstr ""
6330
 
6331
- #: ninjafirewall.php:359
6332
  msgid "Please enter max 1024 character only."
6333
  msgstr ""
6334
 
6335
- #: ninjafirewall.php:361
6336
  msgid "Select when to enable the login protection."
6337
  msgstr ""
6338
 
6339
- #: ninjafirewall.php:363
6340
  msgid "Enter a name and a password for the HTTP authentication."
6341
  msgstr ""
6342
 
6343
- #: ninjafirewall.php:367
6344
  msgid "Your public key is not valid."
6345
  msgstr ""
6346
 
6347
- #: ninjafirewall.php:373
6348
  msgid "No traffic yet, please wait"
6349
  msgstr ""
6350
 
6351
- #: ninjafirewall.php:375
6352
  msgid "seconds..."
6353
  msgstr ""
6354
 
6355
- #: ninjafirewall.php:377
6356
  msgid "Error: Live Log did not receive the expected response from your server:"
6357
  msgstr ""
6358
 
6359
- #: ninjafirewall.php:379
6360
  msgid "Error: URL does not seem to exist (404 Not Found):"
6361
  msgstr ""
6362
 
6363
- #: ninjafirewall.php:381
6364
  msgid "Error: Cannot find your log file. Try to reload this page."
6365
  msgstr ""
6366
 
6367
- #: ninjafirewall.php:383
6368
  msgid "Error: The HTTP server returned the following error code:"
6369
  msgstr ""
6370
 
6371
- #: ninjafirewall.php:634 ninjafirewall.php:751
6372
  msgid "Error: Security nonces do not match. Reload the page and try again."
6373
  msgstr ""
6374
 
6375
- #: ninjafirewall.php:640
6376
  msgid "Error: NinjaFirewall is disabled"
6377
  msgstr ""
6378
 
6379
- #: ninjafirewall.php:645
6380
  #, php-format
6381
  msgid "Error: missing parameter (%s)."
6382
  msgstr ""
6383
 
6384
- #: ninjafirewall.php:813
6385
  msgid "NinjaFirewall: Dashboard"
6386
  msgstr ""
6387
 
6388
- #: ninjafirewall.php:817
6389
  msgid "NinjaFirewall: Firewall Options"
6390
  msgstr ""
6391
 
6392
- #: ninjafirewall.php:821
6393
  msgid "NinjaFirewall: Firewall Policies"
6394
  msgstr ""
6395
 
6396
- #: ninjafirewall.php:825
6397
  msgid "NinjaFirewall: Monitoring"
6398
  msgstr ""
6399
 
6400
- #: ninjafirewall.php:835
6401
  msgid "NinjaFirewall: Anti-Malware"
6402
  msgstr ""
6403
 
6404
- #: ninjafirewall.php:839
6405
  msgid "NinjaFirewall: Network"
6406
  msgstr ""
6407
 
6408
- #: ninjafirewall.php:843
6409
  msgid "NinjaFirewall: Event Notifications"
6410
  msgstr ""
6411
 
6412
- #: ninjafirewall.php:847
6413
  msgid "NinjaFirewall: Log-in Protection"
6414
  msgstr ""
6415
 
6416
- #: ninjafirewall.php:851
6417
  msgid "NinjaFirewall: Logs"
6418
  msgstr ""
6419
 
6420
- #: ninjafirewall.php:855
6421
  msgid "NinjaFirewall: Security Rules"
6422
  msgstr ""
6423
 
6424
- #: ninjafirewall.php:899
6425
  msgid "NinjaFirewall Settings"
6426
  msgstr ""
6427
 
6428
- #: ninjafirewall.php:907
6429
  msgid "NinjaFirewall is enabled"
6430
  msgstr ""
6431
 
6432
- #: ninjafirewall.php:1047
6433
  msgid "Access Restricted"
6434
  msgstr ""
6435
 
6436
- #: ninjafirewall.php:1053
6437
  msgid "Settings"
6438
  msgstr ""
6439
 
6440
- #: ninjafirewall.php:1054
6441
  msgid "Upgrade to Premium"
6442
  msgstr ""
6443
 
6444
- #: ninjafirewall.php:1055
6445
  msgid "Rate it!"
6446
  msgstr ""
2
  msgid ""
3
  msgstr ""
4
  "Project-Id-Version: Stable (latest release)\n"
5
+ "POT-Creation-Date: 2021-07-25 16:01+0700\n"
6
  "PO-Revision-Date: 2018-04-05 22:52+0700\n"
7
  "Last-Translator: NinTechNet <contact@nintechnet.com>\n"
8
  "Language-Team: \n"
14
  "X-Poedit-Basepath: ..\n"
15
  "Plural-Forms: nplurals=2; plural=(n > 1);\n"
16
  "X-Poedit-SourceCharset: UTF-8\n"
17
+ "X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c;esc_attr_e;esc_attr__;"
18
+ "esc_html__;esc_html_e\n"
19
  "X-Poedit-SearchPath-0: .\n"
20
  "X-Poedit-SearchPathExcluded-0: /languages\n"
21
 
22
+ #: lib/anti_malware.php:24 ninjafirewall.php:916
23
  msgid "Anti-Malware"
24
  msgstr ""
25
 
30
  msgstr ""
31
 
32
  #: lib/anti_malware.php:29
33
+ msgid "It is awesome and includes many great features:"
34
+ msgstr ""
35
+
36
+ #: lib/anti_malware.php:29
37
+ msgid "check it out!"
38
  msgstr ""
39
 
40
  #: lib/anti_malware.php:30
89
  msgid "NinjaFirewall (WP Edition)"
90
  msgstr ""
91
 
92
+ #: lib/dashboard.php:127 lib/event_notifications.php:42
93
+ #: lib/firewall_options.php:42 lib/firewall_policies.php:71
94
+ #: lib/login_protection.php:30 lib/logs_firewall_log.php:59
95
+ #: lib/logs_live_log.php:79 lib/monitoring_file_check.php:111
96
+ #: lib/monitoring_file_guard.php:46 lib/network.php:52
97
+ #: lib/security_rules_update.php:101
98
+ msgid "Your changes have been saved."
99
+ msgstr ""
100
+
101
+ #: lib/dashboard.php:132 ninjafirewall.php:894
102
  msgid "Dashboard"
103
  msgstr ""
104
 
105
+ #: lib/dashboard.php:133
106
  msgid "Statistics"
107
  msgstr ""
108
 
109
+ #: lib/dashboard.php:134 lib/help.php:53
110
  msgid "About..."
111
  msgstr ""
112
 
113
+ #: lib/dashboard.php:146
114
  msgid "Thank you for using NinjaFirewall."
115
  msgstr ""
116
 
117
+ #: lib/dashboard.php:147
118
  #, php-format
119
  msgid ""
120
  "Every page of NinjaFirewall has a contextual help: whenever you need help "
122
  "corner of the corresponding page."
123
  msgstr ""
124
 
125
+ #: lib/dashboard.php:147
126
  msgid "Help"
127
  msgstr ""
128
 
129
+ #: lib/dashboard.php:149
130
  msgid "Got it!"
131
  msgstr ""
132
 
133
+ #: lib/dashboard.php:165 lib/help.php:36
134
  msgid "Firewall Dashboard"
135
  msgstr ""
136
 
137
+ #: lib/dashboard.php:174
138
  msgid ""
139
  "It seems that you may have another instance of NinjaFirewall running in a "
140
  "parent directory. Make sure to follow these instructions:"
141
  msgstr ""
142
 
143
+ #: lib/dashboard.php:176
144
  msgid ""
145
  "Temporarily disable the firewall in the parent folder by renaming its PHP "
146
  "INI or .htaccess file."
147
  msgstr ""
148
 
149
+ #: lib/dashboard.php:178
150
  msgid "Install NinjaFirewall on this site in Full WAF mode."
151
  msgstr ""
152
 
153
+ #: lib/dashboard.php:180
154
  msgid ""
155
  "Restore the PHP INI or .htaccess in the parent folder to re-enable the "
156
  "firewall."
157
  msgstr ""
158
 
159
+ #: lib/dashboard.php:186
160
  msgid "Unknown error"
161
  msgstr ""
162
 
163
+ #: lib/dashboard.php:190 lib/dashboard.php:198
164
  msgid "Firewall"
165
  msgstr ""
166
 
167
+ #: lib/dashboard.php:199 lib/dashboard.php:337 lib/firewall_options.php:64
168
  #: lib/login_protection.php:203 lib/logs_live_log.php:99
169
  #: lib/monitoring_file_guard.php:70 lib/security_rules_update.php:138
170
  msgid "Enabled"
171
  msgstr ""
172
 
173
+ #: lib/dashboard.php:206
174
  msgid "Mode"
175
  msgstr ""
176
 
177
+ #: lib/dashboard.php:210
178
  #, php-format
179
  msgid ""
180
  "NinjaFirewall is running in %s mode. For better protection, activate its "
181
  "Full WAF mode:"
182
  msgstr ""
183
 
184
+ #: lib/dashboard.php:212 lib/thickbox.php:74
 
 
 
 
185
  msgid "Activate Full WAF mode"
186
  msgstr ""
187
 
188
+ #: lib/dashboard.php:216
189
  #, php-format
190
  msgid "NinjaFirewall is running in %s mode."
191
  msgstr ""
192
 
193
+ #: lib/dashboard.php:218
194
+ msgid "Configure"
195
  msgstr ""
196
 
197
+ #: lib/dashboard.php:232 lib/firewall_options.php:76 lib/help.php:77
198
  msgid "Debugging mode"
199
  msgstr ""
200
 
201
+ #: lib/dashboard.php:233
202
  msgid "Enabled."
203
  msgstr ""
204
 
205
+ #: lib/dashboard.php:233
206
  msgid "Click here to turn Debugging Mode off"
207
  msgstr ""
208
 
209
+ #: lib/dashboard.php:239
210
  msgid "Edition"
211
  msgstr ""
212
 
213
+ #: lib/dashboard.php:240
214
  msgid ""
215
  "Need more security? Explore our supercharged premium version: NinjaFirewall "
216
  "(WP+ Edition)"
217
  msgstr ""
218
 
219
+ #: lib/dashboard.php:243
220
  msgid "Version"
221
  msgstr ""
222
 
223
+ #: lib/dashboard.php:244
224
  msgid "Security rules:"
225
  msgstr ""
226
 
227
+ #: lib/dashboard.php:248
228
  msgid "PHP SAPI"
229
  msgstr ""
230
 
231
+ #: lib/dashboard.php:266
232
  msgid "Updates"
233
  msgstr ""
234
 
235
+ #: lib/dashboard.php:267
236
  msgid "Security rules updates are disabled."
237
  msgstr ""
238
 
239
+ #: lib/dashboard.php:267
240
  msgid ""
241
  "If you want your blog to be protected against the latest threats, enable "
242
  "automatic security rules updates."
243
  msgstr ""
244
 
245
+ #: lib/dashboard.php:275 lib/dashboard.php:283
246
  msgid "Admin user"
247
  msgstr ""
248
 
249
+ #: lib/dashboard.php:276
250
  #, php-format
251
  msgid ""
252
  "You are not whitelisted. Ensure that the \"Do not block WordPress "
255
  "your administration dashboard."
256
  msgstr ""
257
 
258
+ #: lib/dashboard.php:284
259
  msgid "You are whitelisted by the firewall."
260
  msgstr ""
261
 
262
+ #: lib/dashboard.php:291
263
  msgid "Restrictions"
264
  msgstr ""
265
 
266
+ #: lib/dashboard.php:292
267
  msgid "Access to NinjaFirewall is restricted to specific users."
268
  msgstr ""
269
 
270
+ #: lib/dashboard.php:303
271
  msgid "User session"
272
  msgstr ""
273
 
274
+ #: lib/dashboard.php:304
275
  msgid ""
276
  "It seems that the user session set by NinjaFirewall was not found by the "
277
  "firewall script."
278
  msgstr ""
279
 
280
+ #: lib/dashboard.php:312
281
  #, php-format
282
  msgid ""
283
  "the public key is invalid. Please <a href=\"%s\">check your configuration</"
284
  "a>."
285
  msgstr ""
286
 
287
+ #: lib/dashboard.php:316
288
  msgid "No IP address restriction."
289
  msgstr ""
290
 
291
+ #: lib/dashboard.php:319
292
  #, php-format
293
  msgid "IP address %s is allowed to access NinjaFirewall's log on this server."
294
  msgstr ""
295
 
296
+ #: lib/dashboard.php:322
297
  #, php-format
298
  msgid ""
299
  "the whitelisted IP is not valid. Please <a href=\"%s\">check your "
300
  "configuration</a>."
301
  msgstr ""
302
 
303
+ #: lib/dashboard.php:327 lib/help.php:467 lib/logs_firewall_log.php:193
304
  #: lib/wpplus.php:170
305
  msgid "Centralized Logging"
306
  msgstr ""
307
 
308
+ #: lib/dashboard.php:331 lib/security_rules_update.php:434
309
  #, php-format
310
  msgid "Error: %s"
311
  msgstr ""
312
 
313
+ #: lib/dashboard.php:346
314
  msgid "Source IP"
315
  msgstr ""
316
 
317
+ #: lib/dashboard.php:347
318
  #, php-format
319
  msgid "You have a private IP : %s"
320
  msgstr ""
321
 
322
+ #: lib/dashboard.php:347
323
  #, php-format
324
  msgid ""
325
  "If your site is behind a reverse proxy or a load balancer, ensure that you "
327
  "otherwise use the NinjaFirewall %s configuration file."
328
  msgstr ""
329
 
330
+ #: lib/dashboard.php:355 lib/dashboard.php:365
331
  msgid "CDN detection"
332
  msgstr ""
333
 
334
+ #: lib/dashboard.php:356
335
  #, php-format
336
  msgid ""
337
  "%s detected: you seem to be using Cloudflare CDN services. Ensure that you "
339
  "otherwise use the NinjaFirewall %s configuration file."
340
  msgstr ""
341
 
342
+ #: lib/dashboard.php:366
343
  #, php-format
344
  msgid ""
345
  "%s detected: you seem to be using Incapsula CDN services. Ensure that you "
347
  "otherwise use the NinjaFirewall %s configuration file."
348
  msgstr ""
349
 
350
+ #: lib/dashboard.php:375 lib/dashboard.php:384
351
  msgid "Log dir"
352
  msgstr ""
353
 
354
+ #: lib/dashboard.php:376 lib/dashboard.php:385
355
  #, php-format
356
  msgid "%s directory is not writable! Please chmod it to 0777 or equivalent."
357
  msgstr ""
358
 
359
+ #: lib/dashboard.php:403
360
+ #, php-format
361
+ msgid "The php.ini file is readable by web users: %s"
362
+ msgstr ""
363
+
364
+ #: lib/dashboard.php:403 lib/dashboard.php:415 lib/event_notifications.php:122
365
+ #: lib/event_notifications.php:189
366
+ msgid "Consult our blog for more info."
367
+ msgstr ""
368
+
369
+ #: lib/dashboard.php:415
370
+ #, php-format
371
+ msgid "The .user.ini file is readable by web users: %s"
372
+ msgstr ""
373
+
374
+ #: lib/dashboard.php:431
375
  msgid "Error log"
376
  msgstr ""
377
 
378
+ #: lib/dashboard.php:432
379
  msgid "View error log"
380
  msgstr ""
381
 
382
+ #: lib/dashboard.php:441
383
  msgid "Optional configuration file"
384
  msgstr ""
385
 
386
+ #: lib/dashboard.php:448
387
  msgid "MySQLi link identifier"
388
  msgstr ""
389
 
390
+ #: lib/dashboard.php:449
391
  msgid "A MySQLi link identifier was detected in your <code>.htninja</code>."
392
  msgstr ""
393
 
394
+ #: lib/dashboard.php:455
395
  msgid "Help &amp; configuration"
396
  msgstr ""
397
 
429
  msgid "Select a month"
430
  msgstr ""
431
 
432
+ #: lib/dashboard_statistics.php:98 lib/dashboard_statistics.php:135
433
  #: lib/widget.php:66
434
  msgid "Blocked threats"
435
  msgstr ""
459
  msgid "Slowest request"
460
  msgstr ""
461
 
462
+ #: lib/dashboard_statistics.php:130 lib/i18n-extra.php:271
463
  msgid "Critical"
464
  msgstr ""
465
 
466
+ #: lib/dashboard_statistics.php:131 lib/i18n-extra.php:127
467
  msgid "High"
468
  msgstr ""
469
 
470
+ #: lib/dashboard_statistics.php:132 lib/i18n-extra.php:126
471
  msgid "Medium"
472
  msgstr ""
473
 
474
+ #: lib/dashboard_statistics.php:181
475
  msgid "Select monthly stats to view..."
476
  msgstr ""
477
 
478
+ #: lib/event_notifications.php:34 lib/help.php:377 ninjafirewall.php:924
479
  msgid "Event Notifications"
480
  msgstr ""
481
 
 
 
 
 
 
 
 
 
482
  #: lib/event_notifications.php:52
483
  msgid "WordPress admin dashboard"
484
  msgstr ""
485
 
486
  #: lib/event_notifications.php:55 lib/event_notifications.php:119
487
+ #: lib/event_notifications.php:140
488
  msgid "Send me an alert whenever"
489
  msgstr ""
490
 
575
  "(default)"
576
  msgstr ""
577
 
578
+ #: lib/event_notifications.php:137
579
  msgid "Administrator account"
580
  msgstr ""
581
 
582
+ #: lib/event_notifications.php:142
583
  msgid ""
584
  "An administrator account is created, modified or deleted in the database "
585
  "(default)"
586
  msgstr ""
587
 
588
+ #: lib/event_notifications.php:149
589
  msgid "Daily report"
590
  msgstr ""
591
 
592
+ #: lib/event_notifications.php:152
593
  msgid "Send me a daily activity report"
594
  msgstr ""
595
 
596
+ #: lib/event_notifications.php:154 lib/event_notifications.php:166
597
  #: lib/firewall_options.php:78 lib/firewall_options.php:113
598
  #: lib/firewall_policies.php:25 lib/login_protection.php:309
599
  #: lib/login_protection.php:324 lib/login_protection.php:345
601
  msgid "Yes"
602
  msgstr ""
603
 
604
+ #: lib/event_notifications.php:154 lib/event_notifications.php:166
605
  #: lib/firewall_options.php:78 lib/firewall_options.php:113
606
  #: lib/firewall_policies.php:26 lib/login_protection.php:309
607
  #: lib/login_protection.php:324 lib/login_protection.php:345
609
  msgid "No"
610
  msgstr ""
611
 
612
+ #: lib/event_notifications.php:161
613
  msgid "Log"
614
  msgstr ""
615
 
616
+ #: lib/event_notifications.php:164
617
  msgid "Write all events to the firewall log"
618
  msgstr ""
619
 
620
+ #: lib/event_notifications.php:178
621
  msgid "PHP backtrace"
622
  msgstr ""
623
 
624
+ #: lib/event_notifications.php:181
625
  msgid "Attach a PHP backtrace to important notifications"
626
  msgstr ""
627
 
628
+ #: lib/event_notifications.php:184
629
  msgid "Disable backtrace"
630
  msgstr ""
631
 
632
+ #: lib/event_notifications.php:185
633
  msgid "Low verbosity"
634
  msgstr ""
635
 
636
+ #: lib/event_notifications.php:186
637
  msgid "Medium verbosity (default)"
638
  msgstr ""
639
 
640
+ #: lib/event_notifications.php:187
641
  msgid "High verbosity"
642
  msgstr ""
643
 
644
+ #: lib/event_notifications.php:199 lib/event_notifications.php:229
 
 
 
 
 
645
  msgid "Contact email"
646
  msgstr ""
647
 
648
+ #: lib/event_notifications.php:202 lib/event_notifications.php:232
649
  msgid "Alerts should be sent to"
650
  msgstr ""
651
 
652
+ #: lib/event_notifications.php:211 lib/event_notifications.php:237
653
  msgid ""
654
  "Multiple recipients must be comma-separated (e.g., <code>joe@example.org,"
655
  "alice@example.org</code>)."
656
  msgstr ""
657
 
658
+ #: lib/event_notifications.php:234
659
  msgid "Only to me, the Super Admin"
660
  msgstr ""
661
 
662
+ #: lib/event_notifications.php:234
663
  msgid "default"
664
  msgstr ""
665
 
666
+ #: lib/event_notifications.php:235
667
  msgid "To the administrator of the site where originated the alert"
668
  msgstr ""
669
 
670
+ #: lib/event_notifications.php:236
671
  msgid "Other(s):"
672
  msgstr ""
673
 
674
+ #: lib/event_notifications.php:248
675
  msgid "Save Event Notifications"
676
  msgstr ""
677
 
678
+ #: lib/event_notifications.php:490
679
  msgid "[NinjaFirewall] Daily Activity Report"
680
  msgstr ""
681
 
682
+ #: lib/event_notifications.php:500
683
  #, php-format
684
  msgid "Daily activity report for: %s"
685
  msgstr ""
686
 
687
+ #: lib/event_notifications.php:501
688
  msgid "Date Range Processed: Yesterday"
689
  msgstr ""
690
 
691
+ #: lib/event_notifications.php:503
692
  msgid "Blocked threats:"
693
  msgstr ""
694
 
695
+ #: lib/event_notifications.php:505
696
  msgid "critical:"
697
  msgstr ""
698
 
699
+ #: lib/event_notifications.php:506
700
  msgid "high:"
701
  msgstr ""
702
 
703
+ #: lib/event_notifications.php:507
704
  msgid "medium:"
705
  msgstr ""
706
 
707
+ #: lib/event_notifications.php:509
708
  msgid "Blocked brute-force attacks:"
709
  msgstr ""
710
 
711
+ #: lib/event_notifications.php:510 lib/event_updates.php:225 lib/utils.php:1112
712
  msgid ""
713
  "This notification can be turned off from NinjaFirewall \"Event Notifications"
714
  "\" page."
725
  msgstr ""
726
 
727
  #: lib/event_updates.php:163 lib/utils.php:233 lib/utils.php:318
728
+ #: lib/utils.php:440 lib/utils.php:1101 lib/utils.php:1290 lib/utils.php:1562
729
  msgid "Date:"
730
  msgstr ""
731
 
771
  msgid "Theme: %s"
772
  msgstr ""
773
 
774
+ #: lib/event_updates.php:223 lib/utils.php:1625
775
  msgid "Don't leave your blog at risk, make sure to update as soon as possible."
776
  msgstr ""
777
 
821
  msgid "[NinjaFirewall] Alert: %s"
822
  msgstr ""
823
 
824
+ #: lib/events.php:203 lib/events.php:205 lib/utils.php:842
825
  msgid "-Blog:"
826
  msgstr ""
827
 
829
  msgid "NinjaFirewall has detected the following activity on your account:"
830
  msgstr ""
831
 
832
+ #: lib/events.php:210 lib/utils.php:847
833
  msgid "-User:"
834
  msgstr ""
835
 
836
+ #: lib/events.php:211 lib/utils.php:848
837
  msgid "-IP:"
838
  msgstr ""
839
 
840
+ #: lib/events.php:212 lib/utils.php:849
841
  msgid "-Date:"
842
  msgstr ""
843
 
844
+ #: lib/firewall_options.php:29 ninjafirewall.php:898
845
  msgid "Firewall Options"
846
  msgstr ""
847
 
988
  msgid "Uploaded file is either corrupted or its format is not supported (#%s)"
989
  msgstr ""
990
 
991
+ #: lib/firewall_options.php:412
992
+ msgid "The imported file is not compatible with that version of NinjaFirewall"
993
+ msgstr ""
994
+
995
+ #: lib/firewall_options.php:557 ninjafirewall.php:234
996
  msgid "[NinjaFirewall] Alert: Firewall is disabled"
997
  msgstr ""
998
 
999
+ #: lib/firewall_options.php:559 lib/firewall_options.php:561
1000
+ #: ninjafirewall.php:236 ninjafirewall.php:238
1001
  msgid "-Blog :"
1002
  msgstr ""
1003
 
1004
+ #: lib/firewall_options.php:565 ninjafirewall.php:240
1005
  msgid "Someone disabled NinjaFirewall from your WordPress admin dashboard:"
1006
  msgstr ""
1007
 
1008
+ #: lib/firewall_options.php:568
1009
  msgid ""
1010
  "NinjaFirewall is disabled because someone enabled debugging mode from your "
1011
  "WordPress admin dashboard:"
1012
  msgstr ""
1013
 
1014
+ #: lib/firewall_options.php:571
1015
  msgid "[NinjaFirewall] Alert: Firewall override settings"
1016
  msgstr ""
1017
 
1018
+ #: lib/firewall_options.php:572
1019
  msgid ""
1020
  "Someone imported a new configuration which overrode the firewall settings:"
1021
  msgstr ""
1022
 
1023
+ #: lib/firewall_options.php:578 ninjafirewall.php:241
1024
  msgid "-User :"
1025
  msgstr ""
1026
 
1027
+ #: lib/firewall_options.php:579 ninjafirewall.php:242
1028
  msgid "-IP :"
1029
  msgstr ""
1030
 
1031
+ #: lib/firewall_options.php:580 ninjafirewall.php:243
1032
  msgid "-Date :"
1033
  msgstr ""
1034
 
1039
  "enable NinjaFirewall's Full WAF mode."
1040
  msgstr ""
1041
 
1042
+ #: lib/firewall_policies.php:62 ninjafirewall.php:902
1043
  msgid "Firewall Policies"
1044
  msgstr ""
1045
 
1168
  "not have the right capabilities"
1169
  msgstr ""
1170
 
1171
+ #: lib/firewall_policies.php:411 lib/thickbox.php:89
1172
  msgid "(recommended)"
1173
  msgstr ""
1174
 
1422
  "your blog, its themes or plugins."
1423
  msgstr ""
1424
 
1425
+ #: lib/firewall_policies.php:845
1426
  #, php-format
1427
+ msgid "Set %s"
1428
  msgstr ""
1429
 
1430
+ #: lib/firewall_policies.php:849 lib/firewall_policies.php:850
1431
+ #: lib/firewall_policies.php:851
1432
  #, php-format
1433
  msgid "Set to %s"
1434
  msgstr ""
1435
 
1436
+ #: lib/firewall_policies.php:853 lib/help.php:276
1437
+ msgid ""
1438
+ "This header is deprecated and most browsers phased out support for it. "
1439
+ "Consider using Content-Security-Policy instead."
1440
+ msgstr ""
1441
+
1442
  #: lib/firewall_policies.php:857
1443
  #, php-format
1444
  msgid "Force %s flag on all cookies to mitigate CSRF attacks"
2086
  msgstr ""
2087
 
2088
  #: lib/help.php:275
2089
+ msgid "Set <code>X-XSS-Protection</code>"
 
 
2090
  msgstr ""
2091
 
2092
  #: lib/help.php:275
2096
  "browsers."
2097
  msgstr ""
2098
 
 
 
 
 
 
 
2099
  #: lib/help.php:278
2100
  msgid ""
2101
  "Force <code>SameSite</code> flag on all cookies to mitigate CSRF attacks"
2374
  "package (third-party software, shell script, backdoor etc)."
2375
  msgstr ""
2376
 
2377
+ #: lib/help.php:360 lib/network.php:32 ninjafirewall.php:920
2378
  msgid "Network"
2379
  msgstr ""
2380
 
2410
  "theme in order to take full control of your website."
2411
  msgstr ""
2412
 
2413
+ #: lib/help.php:389 lib/login_protection.php:21 ninjafirewall.php:928
2414
  msgid "Login Protection"
2415
  msgstr ""
2416
 
3023
  #: lib/i18n-extra.php:51
3024
  #, php-format
3025
  msgid ""
3026
+ "You are running NinjaFirewall in WordPress WAF mode. All URL-based features "
3027
+ "such as Geolocation and URL Access Control will be limited to WordPress "
3028
+ "files only (e.g., index.php, wp-login.php, xmlrpc.php, admin-ajax.php, wp-"
3029
+ "load.php etc). If you want them to apply to any PHP script, please %sgo to "
3030
+ "the Dashboard page%s and enable NinjaFirewall's Full WAF mode."
 
3031
  msgstr ""
3032
 
3033
  #: lib/i18n-extra.php:52
3084
  msgstr ""
3085
 
3086
  #: lib/i18n-extra.php:65
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3087
  msgid "Enable Geolocation"
3088
  msgstr ""
3089
 
3090
+ #: lib/i18n-extra.php:66
3091
  msgid "Retrieve the ISO 3166 code from"
3092
  msgstr ""
3093
 
3094
+ #: lib/i18n-extra.php:67
3095
  msgid "PHP Variable"
3096
  msgstr ""
3097
 
3098
+ #: lib/i18n-extra.php:68
3099
  msgid "Block the following ISO 3166 codes"
3100
  msgstr ""
3101
 
3102
+ #: lib/i18n-extra.php:69
3103
  #, php-format
3104
  msgid "Total blocked items: %s"
3105
  msgstr ""
3106
 
3107
+ #: lib/i18n-extra.php:70
3108
  msgid "Geolocation should apply to the whole site or to specific URLs only?"
3109
  msgstr ""
3110
 
3111
+ #: lib/i18n-extra.php:71
3112
  msgid "View allowed syntax"
3113
  msgstr ""
3114
 
3115
+ #: lib/i18n-extra.php:72
3116
  #, php-format
3117
  msgid "Full or partial case-sensitive URL (e.g., %s)."
3118
  msgstr ""
3119
 
3120
+ #: lib/i18n-extra.php:73
3121
  msgid "One item per line."
3122
  msgstr ""
3123
 
3124
+ #: lib/i18n-extra.php:74
3125
  msgid ""
3126
  "Leave this field empty if you want geolocation to apply to all your PHP "
3127
  "scripts."
3128
  msgstr ""
3129
 
3130
+ #: lib/i18n-extra.php:75
3131
+ msgid "Add NINJA_COUNTRY_CODE to PHP headers?"
3132
  msgstr ""
3133
 
3134
+ #: lib/i18n-extra.php:76
3135
  msgid "Write event to the firewall log"
3136
  msgstr ""
3137
 
3138
+ #: lib/i18n-extra.php:77
3139
  msgid "Allow the following IP, CIDR or AS number"
3140
  msgstr ""
3141
 
3142
+ #: lib/i18n-extra.php:78
3143
  #, php-format
3144
  msgid "IPv4 address: %s"
3145
  msgstr ""
3146
 
3147
+ #: lib/i18n-extra.php:79
3148
  #, php-format
3149
  msgid "IPv4 CIDR: %s"
3150
  msgstr ""
3151
 
3152
+ #: lib/i18n-extra.php:80
3153
  #, php-format
3154
  msgid "IPv6 address: %s"
3155
  msgstr ""
3156
 
3157
+ #: lib/i18n-extra.php:81
3158
  #, php-format
3159
  msgid "IPv6 CIDR: %s"
3160
  msgstr ""
3161
 
3162
+ #: lib/i18n-extra.php:82
3163
  #, php-format
3164
  msgid "Autonomous System number: %s"
3165
  msgstr ""
3166
 
3167
+ #: lib/i18n-extra.php:83
3168
  msgid "Whitelist:"
3169
  msgstr ""
3170
 
3171
+ #: lib/i18n-extra.php:84
3172
  msgid "Enter one item per line."
3173
  msgstr ""
3174
 
3175
+ #: lib/i18n-extra.php:85
3176
  msgid "External Services"
3177
  msgstr ""
3178
 
3179
+ #: lib/i18n-extra.php:86
3180
  msgid "Whitelist IP addresses from the following services:"
3181
  msgstr ""
3182
 
3183
+ #: lib/i18n-extra.php:87
3184
  msgid "View IP addresses"
3185
  msgstr ""
3186
 
3187
+ #: lib/i18n-extra.php:88
3188
  msgid "Block the following IP, CIDR or AS number"
3189
  msgstr ""
3190
 
3191
+ #: lib/i18n-extra.php:89
3192
  msgid "Blacklist:"
3193
  msgstr ""
3194
 
3195
+ #: lib/i18n-extra.php:90
3196
  msgid "Rate Limiting"
3197
  msgstr ""
3198
 
3199
+ #: lib/i18n-extra.php:91
3200
  #, php-format
3201
  msgid ""
3202
  "Block for %s seconds any IP address with more than %s connections within a "
3203
  "%s interval."
3204
  msgstr ""
3205
 
3206
+ #: lib/i18n-extra.php:92
3207
  msgid "5-second"
3208
  msgstr ""
3209
 
3210
+ #: lib/i18n-extra.php:93
3211
  msgid "10-second"
3212
  msgstr ""
3213
 
3214
+ #: lib/i18n-extra.php:94
3215
  msgid "15-second"
3216
  msgstr ""
3217
 
3218
+ #: lib/i18n-extra.php:95
3219
  msgid "30-second"
3220
  msgstr ""
3221
 
3222
+ #: lib/i18n-extra.php:96
3223
  msgid "Allow access to the following URL"
3224
  msgstr ""
3225
 
3226
+ #: lib/i18n-extra.php:97
3227
  #, php-format
3228
  msgid "Full or partial case-sensitive URLs (e.g., %s)."
3229
  msgstr ""
3230
 
3231
+ #: lib/i18n-extra.php:98
3232
  msgid "Block access to the following URL"
3233
  msgstr ""
3234
 
3235
+ #: lib/i18n-extra.php:99
3236
  msgid "Reject the following bots"
3237
  msgstr ""
3238
 
3239
+ #: lib/i18n-extra.php:100
3240
  msgid "A full or partial case-insensitive string."
3241
  msgstr ""
3242
 
3243
+ #: lib/i18n-extra.php:101
3244
+ #, php-format
3245
+ msgid "Allowed characters are: %s and %s."
 
 
3246
  msgstr ""
3247
 
3248
+ #: lib/i18n-extra.php:102
3249
  msgid "Blocked bots:"
3250
  msgstr ""
3251
 
3252
+ #: lib/i18n-extra.php:103
3253
  msgid "The default list of bots will be restored. Continue?"
3254
  msgstr ""
3255
 
3256
+ #: lib/i18n-extra.php:104
3257
  msgid "Restore default bots list"
3258
  msgstr ""
3259
 
3260
+ #: lib/i18n-extra.php:105
3261
  msgid "Do not filter the following user input"
3262
  msgstr ""
3263
 
3264
+ #: lib/i18n-extra.php:106
3265
  msgid ""
3266
+ "A GET, POST or COOKIE global variable, followed by a colon (:) and the case-"
3267
+ "sensitive input:"
3268
  msgstr ""
3269
 
3270
+ #: lib/i18n-extra.php:107
3271
  msgid "Unfiltered input:"
3272
  msgstr ""
3273
 
3274
+ #: lib/i18n-extra.php:108
3275
  msgid "Block the request if the following input is present"
3276
  msgstr ""
3277
 
3278
+ #: lib/i18n-extra.php:109
3279
  msgid "Blocked input:"
3280
  msgstr ""
3281
 
3282
+ #: lib/i18n-extra.php:110
3283
  msgid "Save Access Control directives"
3284
  msgstr ""
3285
 
3286
+ #: lib/i18n-extra.php:111
3287
  msgid ""
3288
  "Warning: Your previous secret key was either corrupted or missing. A new "
3289
  "one, as well as a new public key, were created."
3290
  msgstr ""
3291
 
3292
+ #: lib/i18n-extra.php:112
3293
  msgid "Enable Centralized Logging"
3294
  msgstr ""
3295
 
3296
+ #: lib/i18n-extra.php:113
3297
  msgid "Secret key"
3298
  msgstr ""
3299
 
3300
+ #: lib/i18n-extra.php:114
3301
  msgid "From 30 to 100 ASCII printable characters."
3302
  msgstr ""
3303
 
3304
+ #: lib/i18n-extra.php:115
3305
  msgid "This server's IP address"
3306
  msgstr ""
3307
 
3308
+ #: lib/i18n-extra.php:116
3309
  msgid ""
3310
  "Only this IP address (IPv4 or IPv6) will be allowed to connect to the remote "
3311
  "websites. If you don't want to restrict the access by IP, enter the <code>*</"
3312
  "code> character instead."
3313
  msgstr ""
3314
 
3315
+ #: lib/i18n-extra.php:117
3316
  msgid "Public key"
3317
  msgstr ""
3318
 
3319
+ #: lib/i18n-extra.php:118
3320
  #, php-format
3321
  msgid ""
3322
  "Add this key to the remote websites. <a href=\"%s\">Consult our blog</a> for "
3323
  "more info."
3324
  msgstr ""
3325
 
3326
+ #: lib/i18n-extra.php:119
3327
  msgid "Remote websites URL"
3328
  msgstr ""
3329
 
3330
+ #: lib/i18n-extra.php:120
3331
  msgid ""
3332
  "Enter one URL per line, including the protocol (<code>http://</code> or "
3333
  "<code>https://</code>). Only ASCII URLs are accepted."
3334
  msgstr ""
3335
 
3336
+ #: lib/i18n-extra.php:121
3337
  msgid "Save Options"
3338
  msgstr ""
3339
 
3340
+ #: lib/i18n-extra.php:122
3341
  msgid ""
3342
  "Your changes have been saved. If you are using a caching plugin, do not "
3343
  "forget to clear its cache."
3344
  msgstr ""
3345
 
3346
+ #: lib/i18n-extra.php:123
3347
  msgid "Enable antispam protection"
3348
  msgstr ""
3349
 
3350
+ #: lib/i18n-extra.php:124
3351
  msgid "Protection level"
3352
  msgstr ""
3353
 
3354
+ #: lib/i18n-extra.php:125
3355
  msgid "Low (default)"
3356
  msgstr ""
3357
 
3358
+ #: lib/i18n-extra.php:128
3359
  msgid ""
3360
  "If you are using a caching plugin, consult the contextual help before "
3361
  "enabling the antispam."
3362
  msgstr ""
3363
 
3364
+ #: lib/i18n-extra.php:129
3365
  msgid "Apply protection to"
3366
  msgstr ""
3367
 
3368
+ #: lib/i18n-extra.php:130
3369
  msgid "Comment forms (defaut)"
3370
  msgstr ""
3371
 
3372
+ #: lib/i18n-extra.php:131
3373
  msgid "User Registration form"
3374
  msgstr ""
3375
 
3376
+ #: lib/i18n-extra.php:132
3377
  msgid "Save Antispam options"
3378
  msgstr ""
3379
 
3380
+ #: lib/i18n-extra.php:133
3381
  msgid "Please enable JavaScript"
3382
  msgstr ""
3383
 
3384
+ #: lib/i18n-extra.php:134
3385
  msgid "Sorry, this looks like spam to me."
3386
  msgstr ""
3387
 
3388
+ #: lib/i18n-extra.php:135
3389
  msgid ""
3390
  "Error: You must be whitelisted in order to use that feature: click on the <a "
3391
  "href=\"?page=nfsubaccess\">Access Control</a> menu and ensure that the \"Do "
3392
  "not block the following users\" option is enabled for the Admin/Super Admin."
3393
  msgstr ""
3394
 
3395
+ #: lib/i18n-extra.php:136
3396
  msgid ""
3397
  "Your license is valid until the indicated expiration date. If you don't "
3398
  "renew it after this date, NinjaFirewall will keep working and protecting "
3399
  "your website as usual, but updates/upgrades will stop."
3400
  msgstr ""
3401
 
3402
+ #: lib/i18n-extra.php:137
3403
  #, php-format
3404
  msgid ""
3405
  "You can renew your license from <a href=\"%s\">NinTechNet.com</a> website."
3406
  msgstr ""
3407
 
3408
+ #: lib/i18n-extra.php:138
3409
  msgid "Use shared memory"
3410
  msgstr ""
3411
 
3412
+ #: lib/i18n-extra.php:139
3413
  msgid ""
3414
  "This feature allows NinjaFirewall to use Unix shared memory segments in "
3415
  "order to speed up all operations. The firewall will no longer need to "
3419
  "processing speed from 25% to 30%, prevent blocking I/O and slow queries."
3420
  msgstr ""
3421
 
3422
+ #: lib/i18n-extra.php:140
3423
  msgid ""
3424
  "This option requires that your PHP version was compiled with the <code>--"
3425
  "enable-shmop</code> parameter, otherwise, if it is not compatible with your "
3426
  "server/hosting environment, it will be disabled."
3427
  msgstr ""
3428
 
3429
+ #: lib/i18n-extra.php:141
3430
  #, php-format
3431
  msgid ""
3432
  "If you are using <a href=\"%s\">GB2312</a> character set (A.K.A <code>GBK</"
3436
  "used by that charset."
3437
  msgstr ""
3438
 
3439
+ #: lib/i18n-extra.php:142
3440
  msgid "Language"
3441
  msgstr ""
3442
 
3443
+ #: lib/i18n-extra.php:143
3444
  msgid ""
3445
  "When this option is enabled, NinjaFirewall will download, if available, the "
3446
  "corresponding language files from the WordPress repo. Then, every hour, it "
3447
  "will check if there's a new version and will download it."
3448
  msgstr ""
3449
 
3450
+ #: lib/i18n-extra.php:144
3451
  msgid ""
3452
  "Note that this does not apply to <code>en_US</code> and <code>fr_FR</code> "
3453
  "locales because they are already included with NinjaFirewall."
3454
  msgstr ""
3455
 
3456
+ #: lib/i18n-extra.php:145
3457
  #, php-format
3458
  msgid ""
3459
  "This options lets you export you current configuration or import it from "
3463
  "configuration, except your current license."
3464
  msgstr ""
3465
 
3466
+ #: lib/i18n-extra.php:146
3467
  msgid ""
3468
  "You can allow/disallow uploads, or allow uploads but block scripts (PHP, "
3469
  "CGI, Ruby, Python, bash/shell, JavaScript), C/C++ source code, binaries (MZ/"
3471
  "SVG files containing Javascript/XML events."
3472
  msgstr ""
3473
 
3474
+ #: lib/i18n-extra.php:147
3475
  msgid "Maximum allowed file size"
3476
  msgstr ""
3477
 
3478
+ #: lib/i18n-extra.php:148
3479
  msgid ""
3480
  "If you allow uploads, you can select the maximum size of an uploaded file. "
3481
  "Any file bigger than this value will be rejected. Note that if your PHP "
3483
  "be used before NinjaFirewall."
3484
  msgstr ""
3485
 
3486
+ #: lib/i18n-extra.php:149
3487
  msgid "Decode Base64-encoded <code>POST</code> variable:"
3488
  msgstr ""
3489
 
3490
+ #: lib/i18n-extra.php:150
3491
  #, php-format
3492
  msgid ""
3493
  "Object Serialization is a PHP feature used by many applications to generate "
3498
  "request, cookies, user agent and referrer variables."
3499
  msgstr ""
3500
 
3501
+ #: lib/i18n-extra.php:151
3502
  msgid ""
3503
  "This option will reject any <code>GET</code> or <code>POST</code> request, "
3504
  "<code>COOKIE</code>, <code>HTTP_USER_AGENT</code>, <code>REQUEST_URI</code>, "
3507
  "is dangerous and should always be rejected."
3508
  msgstr ""
3509
 
3510
+ #: lib/i18n-extra.php:152
3511
  msgid ""
3512
  "This option will block any <code>GET</code> or <code>POST</code> request "
3513
  "containing the localhost IP (127.0.0.1). It can be useful to block SQL "
3514
  "dumpers and various hacker's shell scripts."
3515
  msgstr ""
3516
 
3517
+ #: lib/i18n-extra.php:153
3518
  msgid ""
3519
  "Access Control is a powerful set of directives that can be used to allow or "
3520
  "restrict access to your website based on many criteria."
3521
  msgstr ""
3522
 
3523
+ #: lib/i18n-extra.php:154
3524
  msgid ""
3525
  "To make better use of them, it is important to understand NinjaFirewall's "
3526
  "directives processing order."
3527
  msgstr ""
3528
 
3529
+ #: lib/i18n-extra.php:155
3530
  msgid ""
3531
  "Because NinjaFirewall is a PHP firewall, its Access Control options apply to "
3532
  "PHP scripts, not to static elements (e.g., images, JS, CSS etc). Depending "
3533
  "on your configuration, they can also apply to HTML pages."
3534
  msgstr ""
3535
 
3536
+ #: lib/i18n-extra.php:156
3537
  msgid "Processing order:"
3538
  msgstr ""
3539
 
3540
+ #: lib/i18n-extra.php:157
3541
  msgid "Incoming HTTP request"
3542
  msgstr ""
3543
 
3544
+ #: lib/i18n-extra.php:158
3545
  #, php-format
3546
  msgid "%s file"
3547
  msgstr ""
3548
 
3549
+ #: lib/i18n-extra.php:159
3550
  msgid "Login Protection."
3551
  msgstr ""
3552
 
3553
+ #: lib/i18n-extra.php:160
3554
  msgid "Access Control (except User Input Access Control):"
3555
  msgstr ""
3556
 
3557
+ #: lib/i18n-extra.php:161
3558
  msgid "Role-based Access Control."
3559
  msgstr ""
3560
 
3561
+ #: lib/i18n-extra.php:162
3562
  msgid "Allowed IPs."
3563
  msgstr ""
3564
 
3565
+ #: lib/i18n-extra.php:163
3566
  msgid "Blocked IPs."
3567
  msgstr ""
3568
 
3569
+ #: lib/i18n-extra.php:164
3570
  msgid "Allowed URLs."
3571
  msgstr ""
3572
 
3573
+ #: lib/i18n-extra.php:165
3574
  msgid "Blocked URLs."
3575
  msgstr ""
3576
 
3577
+ #: lib/i18n-extra.php:166
3578
  msgid "Bot Access Control."
3579
  msgstr ""
3580
 
3581
+ #: lib/i18n-extra.php:167
3582
  msgid "Geolocation."
3583
  msgstr ""
3584
 
3585
+ #: lib/i18n-extra.php:168
3586
  msgid "Rate Limiting."
3587
  msgstr ""
3588
 
3589
+ #: lib/i18n-extra.php:169
3590
  msgid "File Guard."
3591
  msgstr ""
3592
 
3593
+ #: lib/i18n-extra.php:170
3594
  msgid "NinjaFirewall built-in rules and policies + User Input Access Control."
3595
  msgstr ""
3596
 
3597
+ #: lib/i18n-extra.php:171
3598
  msgid "Response body"
3599
  msgstr ""
3600
 
3601
+ #: lib/i18n-extra.php:172
3602
  msgid "HTTP response headers (Firewall Policies)."
3603
  msgstr ""
3604
 
3605
+ #: lib/i18n-extra.php:173
3606
  msgid "Web Filter."
3607
  msgstr ""
3608
 
3609
+ #: lib/i18n-extra.php:174
3610
  #, php-format
3611
  msgid ""
3612
  "By default, any logged in WordPress administrator will not be blocked by "
3618
  "enforced."
3619
  msgstr ""
3620
 
3621
+ #: lib/i18n-extra.php:175
3622
  msgid "You can also add other users to the whitelist, depending on their role."
3623
  msgstr ""
3624
 
3625
+ #: lib/i18n-extra.php:176
3626
  #, php-format
3627
  msgid ""
3628
  "this option should be used if you are behind a reverse proxy, a load "
3636
  "NinjaFirewall will fall back to <code>REMOTE_ADDR</code>."
3637
  msgstr ""
3638
 
3639
+ #: lib/i18n-extra.php:177
3640
  msgid ""
3641
  "This option lets you select the HTTP method(s). All Access Control "
3642
  "directives (Geolocation, IPs, bots and URLs) will only apply to the selected "
3643
  "methods."
3644
  msgstr ""
3645
 
3646
+ #: lib/i18n-extra.php:178
3647
  msgid ""
3648
  "It does not apply to the \"Firewall Policies\" options, which use their own "
3649
  "ones."
3650
  msgstr ""
3651
 
3652
+ #: lib/i18n-extra.php:179
3653
  msgid ""
3654
  "You can filter and block traffic coming from specific countries/territories."
3655
  msgstr ""
3656
 
3657
+ #: lib/i18n-extra.php:180
3658
  msgid ""
3659
  "This is the two-letter code that is used to define a country/territory (e."
3660
  "g., US, UK, FR, DE etc), based on the visitors IP. NinjaFirewall can either "
3662
  "your HTTP server (e.g., <code>GEOIP_COUNTRY_CODE</code>)."
3663
  msgstr ""
3664
 
3665
+ #: lib/i18n-extra.php:181
3666
  #, php-format
3667
  msgid ""
3668
  "You can add/remove any country/territory from the two listboxes. For more "
3670
  "want to consult <a href=\"%s\">the MaxMind GeoIP online help</a>."
3671
  msgstr ""
3672
 
3673
+ #: lib/i18n-extra.php:182
3674
  msgid ""
3675
  "Whether geolocation should apply to the whole site or to specific URLs only "
3676
  "(e.g., /wp-login.php, /xmlrpc.php etc). Leave all fields empty if you want "
3677
  "it to apply to the whole site."
3678
  msgstr ""
3679
 
3680
+ #: lib/i18n-extra.php:183
3681
+ msgid "Add <code>NINJA_COUNTRY_CODE</code> to PHP headers?"
3682
+ msgstr ""
3683
+
3684
+ #: lib/i18n-extra.php:184
3685
  msgid ""
3686
  "After retrieving the two-letter country/territory code, NinjaFirewall can "
3687
  "add it to the PHP headers in the <code>$_SERVER[\"NINJA_COUNTRY_CODE\"]</"
3689
  "visitors location, simply use that variable."
3690
  msgstr ""
3691
 
3692
+ #: lib/i18n-extra.php:185
3693
  msgid ""
3694
  "If NinjaFirewall cannot find the two-letter ISO 3166 code, it will replace "
3695
  "it with 2 hyphens (<code>--</code>)."
3696
  msgstr ""
3697
 
3698
+ #: lib/i18n-extra.php:186
3699
  msgid ""
3700
  "PHP code example to use in your theme or plugin to geolocate your visitors:"
3701
  msgstr ""
3702
 
3703
+ #: lib/i18n-extra.php:187
3704
  msgid ""
3705
  "NinjaFirewall includes GeoLite data created by MaxMind, available from "
3706
  "http://www.maxmind.com"
3707
  msgstr ""
3708
 
3709
+ #: lib/i18n-extra.php:188
3710
  msgid "IP / URL / Bot Access Control"
3711
  msgstr ""
3712
 
3713
+ #: lib/i18n-extra.php:189
3714
  msgid ""
3715
  "You can permanently allow/block an IP, a whole range of IP addresses or AS "
3716
  "numbers (Autonomous System number). IPv4 and IPv6 are fully supported by "
3717
  "NinjaFirewall."
3718
  msgstr ""
3719
 
3720
+ #: lib/i18n-extra.php:190
3721
  msgid "Full IP:"
3722
  msgstr ""
3723
 
3724
+ #: lib/i18n-extra.php:191
3725
  #, php-format
3726
  msgid "IP ranges using CIDR notation: %s or %s."
3727
  msgstr ""
3728
 
3729
+ #: lib/i18n-extra.php:192
3730
  msgid "Autonomous System number:"
3731
  msgstr ""
3732
 
3733
+ #: lib/i18n-extra.php:193
3734
  msgid ""
3735
  "This option allows you to slow down aggressive bots, crawlers, web scrapers "
3736
  "or even small HTTP attacks. Any IP reaching the defined threshold will be "
3743
  "turned off."
3744
  msgstr ""
3745
 
3746
+ #: lib/i18n-extra.php:194
3747
  msgid ""
3748
  "IPs temporarily banned by the Rate Limiting option can be unblocked "
3749
  "immediately by clicking either the \"Save Access Control Directives\" or "
3750
  "\"Restore Default Values\" buttons at the bottom of this page."
3751
  msgstr ""
3752
 
3753
+ #: lib/i18n-extra.php:195
3754
  msgid ""
3755
  "Because NinjaFirewall can handle a lot of HTTP requests per second and block "
3756
  "IPs even before your blog is loaded, we strongly recommend that you disable "
3760
  "during an attack."
3761
  msgstr ""
3762
 
3763
+ #: lib/i18n-extra.php:196
3764
  msgid ""
3765
  "You can permanently allow/block any access to one or more PHP scripts based "
3766
  "on their path, relative to the web root (<code>SCRIPT_NAME</code>). You can "
3767
  "enter either a full or partial path (case-sensitive)."
3768
  msgstr ""
3769
 
3770
+ #: lib/i18n-extra.php:197
3771
  msgid ""
3772
  "<code>/foo/bar.php</code> will block any access to the <code>bar.php</code> "
3773
  "script located inside a <code>/foo/</code> directory"
3774
  msgstr ""
3775
 
3776
+ #: lib/i18n-extra.php:198
3777
  msgid "etc"
3778
  msgstr ""
3779
 
3780
+ #: lib/i18n-extra.php:199
3781
  msgid ""
3782
  "<code>/foo/</code> will block access to all PHP scripts located inside a "
3783
  "<code>/foo/</code> directory and its sub-directories."
3784
  msgstr ""
3785
 
3786
+ #: lib/i18n-extra.php:200
3787
  msgid ""
3788
  "Note that the \"Firewall Policies\" page already includes restrictions to "
3789
  "some WordPress directories."
3790
  msgstr ""
3791
 
3792
+ #: lib/i18n-extra.php:201
3793
  msgid ""
3794
  "You can block bots, scanners and various crawlers based on the "
3795
  "<code>HTTP_USER_AGENT</code> variable. You can enter either a full or "
3796
  "partial name (case-insensitive)."
3797
  msgstr ""
3798
 
3799
+ #: lib/i18n-extra.php:202
3800
  msgid ""
3801
  "You can select to ignore or block some specific user input. It applies to "
3802
  "the <code>GET</code>, <code>POST</code> and <code>COOKIE</code> global "
3804
  "\"]</code>:"
3805
  msgstr ""
3806
 
3807
+ #: lib/i18n-extra.php:203
3808
  msgid ""
3809
  "When an input is added to the \"Unfiltered input\" list, it will not be "
3810
  "filtered or sanitised. All other input present in the request will be "
3811
  "filtered."
3812
  msgstr ""
3813
 
3814
+ #: lib/i18n-extra.php:204
3815
  msgid ""
3816
  "When an input is added to the \"Blocked input\", NinjaFirewall will block "
3817
  "the request and close the connection if that input is found in the request."
3818
  msgstr ""
3819
 
3820
+ #: lib/i18n-extra.php:205
3821
  msgid "Log Event"
3822
  msgstr ""
3823
 
3824
+ #: lib/i18n-extra.php:206
3825
  msgid ""
3826
  "You can enable/disable firewall logging for each access control directive "
3827
  "separately."
3828
  msgstr ""
3829
 
3830
+ #: lib/i18n-extra.php:207
3831
  msgid "Web Filter"
3832
  msgstr ""
3833
 
3834
+ #: lib/i18n-extra.php:208
3835
  msgid ""
3836
  "If NinjaFirewall can hook and scan incoming requests, it can also hook the "
3837
  "response body (i.e., the output of the HTML page right before it is sent to "
3841
  "hackers shell script, redirections and even errors (PHP/MySQL errors)."
3842
  msgstr ""
3843
 
3844
+ #: lib/i18n-extra.php:209
3845
  msgid ""
3846
  "In the case of a positive detection, NinjaFirewall will not block the "
3847
  "response body but will send you an alert by email."
3848
  msgstr ""
3849
 
3850
+ #: lib/i18n-extra.php:210
3851
  msgid "Search HTML page for the following keywords"
3852
  msgstr ""
3853
 
3854
+ #: lib/i18n-extra.php:211
3855
  msgid ""
3856
  "You can enter any keyword from 4 to 150 characters and select whether the "
3857
  "search will be case sensitive or not."
3858
  msgstr ""
3859
 
3860
+ #: lib/i18n-extra.php:212
3861
  msgid "Email Alerts"
3862
  msgstr ""
3863
 
3864
+ #: lib/i18n-extra.php:213
3865
  msgid ""
3866
  "You can use the notification throttling option to limit the frequency of "
3867
  "alerts sent to you (and written to the firewall log) and select whether you "
3870
  "in the \"Event Notifications\" menu."
3871
  msgstr ""
3872
 
3873
+ #: lib/i18n-extra.php:214
3874
  msgid ""
3875
  "Response body filtering can be resource-intensive. Try to limit the number "
3876
  "of keywords to what you really need (less than 10) and, if possible, prefer "
3877
  "case sensitive to case insensitive filtering."
3878
  msgstr ""
3879
 
3880
+ #: lib/i18n-extra.php:215
3881
  msgid ""
3882
  "NinjaFirewall can protect your blog against spam without user interaction (e."
3883
  "g., CAPTCHA, math puzzles etc). The protection is totally transparent to "
3886
  "generate your forms, they will not be protected against spam."
3887
  msgstr ""
3888
 
3889
+ #: lib/i18n-extra.php:216
3890
  msgid "Protection level:"
3891
  msgstr ""
3892
 
3893
+ #: lib/i18n-extra.php:217
3894
  msgid ""
3895
  "Select the level of protection. In most cases, <strong>Low</strong> should "
3896
  "be enough."
3897
  msgstr ""
3898
 
3899
+ #: lib/i18n-extra.php:218
3900
  msgid "Apply protection to:"
3901
  msgstr ""
3902
 
3903
+ #: lib/i18n-extra.php:219
3904
  msgid "Whether to protect comment and/or registration forms."
3905
  msgstr ""
3906
 
3907
+ #: lib/i18n-extra.php:220
3908
  msgid "If you are using a caching plugin, ensure you follow these steps:"
3909
  msgstr ""
3910
 
3911
+ #: lib/i18n-extra.php:221
3912
  msgid ""
3913
  "Set the Protection Level to \"Low\" only. Do not use another value, "
3914
  "otherwise the antispam could behave erratically after a while."
3915
  msgstr ""
3916
 
3917
+ #: lib/i18n-extra.php:222
3918
  msgid ""
3919
  "Flush/clear your cache immediately after enabling or disabling the antispam."
3920
  msgstr ""
3921
 
3922
+ #: lib/i18n-extra.php:223
3923
  msgid ""
3924
  "The firewall log displays blocked and sanitised requests as well as some "
3925
  "useful information. It has 6 columns:"
3926
  msgstr ""
3927
 
3928
+ #: lib/i18n-extra.php:224
3929
  msgid ""
3930
  "RULE : reference of the NinjaFirewall built-in security rule that triggered "
3931
  "the action. A hyphen (<code>-</code>) instead of a number means it was a "
3932
  "rule from the \"Firewall Policies\" or \"Access Control\" pages."
3933
  msgstr ""
3934
 
3935
+ #: lib/i18n-extra.php:225
3936
  msgid "The log can also be exported as a TSV (tab-separated values) text file."
3937
  msgstr ""
3938
 
3939
+ #: lib/i18n-extra.php:226
3940
  msgid "Enable firewall log"
3941
  msgstr ""
3942
 
3943
+ #: lib/i18n-extra.php:227
3944
  msgid "You can disable/enable the firewall log from this page."
3945
  msgstr ""
3946
 
3947
+ #: lib/i18n-extra.php:228
3948
  msgid ""
3949
  "Brute-force attacks will still be written to the firewall log, even if you "
3950
  "disable it."
3951
  msgstr ""
3952
 
3953
+ #: lib/i18n-extra.php:229
3954
  msgid "Auto-rotate log"
3955
  msgstr ""
3956
 
3957
+ #: lib/i18n-extra.php:230
3958
  msgid ""
3959
  "NinjaFirewall will rotate its log automatically on the very first day of "
3960
  "each month. If your site is very busy, you may want to allow it to rotate "
3961
  "the log when it reaches a certain size (MB) as well."
3962
  msgstr ""
3963
 
3964
+ #: lib/i18n-extra.php:231
3965
  msgid ""
3966
  "By default, if will rotate the log each month or earlier, if it reaches 2 "
3967
  "megabytes."
3968
  msgstr ""
3969
 
3970
+ #: lib/i18n-extra.php:232
3971
  msgid ""
3972
  "Rotated logs, if any, can be selected and viewed from the dropdown menu."
3973
  msgstr ""
3974
 
3975
+ #: lib/i18n-extra.php:233
3976
  msgid "Syslog"
3977
  msgstr ""
3978
 
3979
+ #: lib/i18n-extra.php:234
3980
  msgid ""
3981
  "In addition to the firewall log, events can also be redirected to the syslog "
3982
  "server (<code>LOG_USER</code> facility)."
3983
  msgstr ""
3984
 
3985
+ #: lib/i18n-extra.php:235
3986
  msgid ""
3987
  "If you have a shared hosting account, keep this option disabled as you do "
3988
  "not have any access to the server logs."
3989
  msgstr ""
3990
 
3991
+ #: lib/i18n-extra.php:236
3992
  msgid "The logline uses the following format:"
3993
  msgstr ""
3994
 
3995
+ #: lib/i18n-extra.php:237
3996
  msgid ""
3997
  "BB: the level of severity as it appears in the firewall log. It can be "
3998
  "<code>CRITICAL</CODE>, <CODE>HIGH</CODE>, <CODE>MEDIUM</CODE>, <CODE>INFO</"
3999
  "CODE>, <CODE>UPLOAD</CODE> or <CODE>DEBUG_ON</CODE>."
4000
  msgstr ""
4001
 
4002
+ #: lib/i18n-extra.php:238
4003
  msgid "CCCCCC: the 7-digit incident ID."
4004
  msgstr ""
4005
 
4006
+ #: lib/i18n-extra.php:239
4007
  msgid "DD: the user IPv4 or IPv6 address."
4008
  msgstr ""
4009
 
4010
+ #: lib/i18n-extra.php:240
4011
  msgid "EE: the blog (sub-)domain name."
4012
  msgstr ""
4013
 
4014
+ #: lib/i18n-extra.php:241
4015
  #, php-format
4016
  msgid ""
4017
  "This logging option does not apply to the brute-force protection which can "
4019
  "the <a href=\"%s\">Login Protection</a> page."
4020
  msgstr ""
4021
 
4022
+ #: lib/i18n-extra.php:242
4023
  msgid ""
4024
  "Secret key: The secret key will be used to generate your public key. Enter "
4025
  "at least 30 ASCII characters, or use the one randomly created by "
4026
  "NinjaFirewall."
4027
  msgstr ""
4028
 
4029
+ #: lib/i18n-extra.php:243
4030
  msgid ""
4031
  "This server IP address: As an additional protection layer, you can restrict "
4032
  "access to the remote website(s) to the main server IP only. You can use IPv4 "
4034
  "character instead."
4035
  msgstr ""
4036
 
4037
+ #: lib/i18n-extra.php:244
4038
  #, php-format
4039
  msgid ""
4040
  "Public key: This is the public key that you will need to upload to each "
4041
  "remote website (<a href=\"%s\">consult our blog</a> for more info about it)."
4042
  msgstr ""
4043
 
4044
+ #: lib/i18n-extra.php:245
4045
  msgid ""
4046
  "Remote websites URL: Enter the full URL of your NinjaFirewall protected "
4047
  "website(s) that you want to remotely access from the main server."
4048
  msgstr ""
4049
 
4050
+ #: lib/i18n-extra.php:246
4051
  msgid ""
4052
  "Centralized Logging will keep working even if NinjaFirewall is disabled. Use "
4053
  "the menu below if you want to disable it."
4054
  msgstr ""
4055
 
4056
+ #: lib/i18n-extra.php:247
4057
  msgid "Enable Web Filter"
4058
  msgstr ""
4059
 
4060
+ #: lib/i18n-extra.php:248
4061
  msgid "A full or partial string."
4062
  msgstr ""
4063
 
4064
+ #: lib/i18n-extra.php:249
4065
  msgid "From 4 to maximum 150 characters."
4066
  msgstr ""
4067
 
4068
+ #: lib/i18n-extra.php:250
4069
  msgid "Any character, except the vertical bar <code>|</code>"
4070
  msgstr ""
4071
 
4072
+ #: lib/i18n-extra.php:251
4073
  msgid "Keywords to search:"
4074
  msgstr ""
4075
 
4076
+ #: lib/i18n-extra.php:252
4077
  msgid "Case-sensitive search"
4078
  msgstr ""
4079
 
4080
+ #: lib/i18n-extra.php:253
4081
  #, php-format
4082
  msgid "Do not send me more than one email alert in a %s interval"
4083
  msgstr ""
4084
 
4085
+ #: lib/i18n-extra.php:254
4086
  msgid "5-minute"
4087
  msgstr ""
4088
 
4089
+ #: lib/i18n-extra.php:255
4090
  msgid "15-minute"
4091
  msgstr ""
4092
 
4093
+ #: lib/i18n-extra.php:256
4094
  msgid "30-minute"
4095
  msgstr ""
4096
 
4097
+ #: lib/i18n-extra.php:257
4098
  msgid "1-hour"
4099
  msgstr ""
4100
 
4101
+ #: lib/i18n-extra.php:258
4102
  msgid "3-hour"
4103
  msgstr ""
4104
 
4105
+ #: lib/i18n-extra.php:259
4106
  msgid "6-hour"
4107
  msgstr ""
4108
 
4109
+ #: lib/i18n-extra.php:260
4110
  msgid "12-hour"
4111
  msgstr ""
4112
 
4113
+ #: lib/i18n-extra.php:261
4114
  msgid "24-hour"
4115
  msgstr ""
4116
 
4117
+ #: lib/i18n-extra.php:262
4118
  msgid ""
4119
  "Clicking the \"Save Web Filter options\" button below will reset the current "
4120
  "timer."
4121
  msgstr ""
4122
 
4123
+ #: lib/i18n-extra.php:263
4124
  msgid "Attach the HTML page output to email alerts"
4125
  msgstr ""
4126
 
4127
+ #: lib/i18n-extra.php:264
4128
  msgid "Save Web Filter options"
4129
  msgstr ""
4130
 
4131
+ #: lib/i18n-extra.php:265
4132
  msgid "Help Desk:"
4133
  msgstr ""
4134
 
4135
+ #: lib/i18n-extra.php:266
4136
  msgid "The selected log was deleted"
4137
  msgstr ""
4138
 
4139
+ #: lib/i18n-extra.php:267
4140
  msgid "Export"
4141
  msgstr ""
4142
 
4143
+ #: lib/i18n-extra.php:268
4144
  msgid "Delete"
4145
  msgstr ""
4146
 
4147
+ #: lib/i18n-extra.php:269
4148
  msgid "Delete log?"
4149
  msgstr ""
4150
 
4151
+ #: lib/i18n-extra.php:270
4152
  msgid "Today"
4153
  msgstr ""
4154
 
4155
+ #: lib/i18n-extra.php:272
4156
  msgid "Upload"
4157
  msgstr ""
4158
 
4159
+ #: lib/i18n-extra.php:273
4160
  msgid "Info"
4161
  msgstr ""
4162
 
4163
+ #: lib/i18n-extra.php:274
4164
  msgid "Debug"
4165
  msgstr ""
4166
 
4167
+ #: lib/i18n-extra.php:275
4168
  msgid "IP address:"
4169
  msgstr ""
4170
 
4171
+ #: lib/i18n-extra.php:276
4172
  msgid "e.g., 1.2.3.4"
4173
  msgstr ""
4174
 
4175
+ #: lib/i18n-extra.php:277
4176
  msgid "Add IP to blacklist"
4177
  msgstr ""
4178
 
4179
+ #: lib/i18n-extra.php:278
4180
  msgid "Add IP to whitelist"
4181
  msgstr ""
4182
 
4183
+ #: lib/i18n-extra.php:279
4184
  msgid "Add"
4185
  msgstr ""
4186
 
4187
+ #: lib/i18n-extra.php:280
4188
  msgid "The address wad added to your IP Access Control list."
4189
  msgstr ""
4190
 
4191
+ #: lib/i18n-extra.php:281
4192
  #, php-format
4193
  msgid "1st day of the month, or if bigger than %s MB"
4194
  msgstr ""
4195
 
4196
+ #: lib/i18n-extra.php:282
4197
  msgid "1st day of the month, regardless of its size"
4198
  msgstr ""
4199
 
4200
+ #: lib/i18n-extra.php:283
4201
  msgid "Show the most recent"
4202
  msgstr ""
4203
 
4204
+ #: lib/i18n-extra.php:284
4205
  msgid "lines"
4206
  msgstr ""
4207
 
4208
+ #: lib/i18n-extra.php:285
4209
  msgid "Write events to the Syslog server too"
4210
  msgstr ""
4211
 
4212
+ #: lib/i18n-extra.php:286
4213
  msgid "Your server configuration is not compatible with this option."
4214
  msgstr ""
4215
 
4216
+ #: lib/i18n-extra.php:287
4217
  msgid "See contextual help before enabling this option."
4218
  msgstr ""
4219
 
4220
+ #: lib/i18n-extra.php:288
4221
  msgid ""
4222
  "The remote server rejected your request. Make sure that you uploaded the "
4223
  "correct public key."
4224
  msgstr ""
4225
 
4226
+ #: lib/i18n-extra.php:289
4227
  #, php-format
4228
  msgid "The remote server returned the following HTTP error: %s"
4229
  msgstr ""
4230
 
4231
+ #: lib/i18n-extra.php:290
4232
  msgid "The requested log does not exist on the remote website."
4233
  msgstr ""
4234
 
4235
+ #: lib/i18n-extra.php:291
4236
  msgid "The remote website did not return the expected response."
4237
  msgstr ""
4238
 
4239
+ #: lib/i18n-extra.php:292
4240
  msgid "Your server does not seem to be compatible with this option."
4241
  msgstr ""
4242
 
4243
+ #: lib/i18n-extra.php:293
4244
  msgid "Load language files from the WordPress repo"
4245
  msgstr ""
4246
 
4247
+ #: lib/i18n-extra.php:294
4248
  #, php-format
4249
  msgid ""
4250
  "If available, NinjaFirewall will download the language files from <a "
4251
  "%s>translate.wordpress.org</a>."
4252
  msgstr ""
4253
 
4254
+ #: lib/i18n-extra.php:295
4255
  msgid "Error: you do not have any license."
4256
  msgstr ""
4257
 
4258
+ #: lib/i18n-extra.php:296
4259
  msgid "You have a valid license."
4260
  msgstr ""
4261
 
4262
+ #: lib/i18n-extra.php:297
4263
  msgid ""
4264
  "An unknown error occured while connecting to NinjaFirewall servers. Please "
4265
  "try again in a few minutes"
4266
  msgstr ""
4267
 
4268
+ #: lib/i18n-extra.php:298
4269
  msgid ""
4270
  "An error occured while connecting to NinjaFirewall servers. Please try again "
4271
  "in a few minutes"
4272
  msgstr ""
4273
 
4274
+ #: lib/i18n-extra.php:299
4275
  msgid "Enter a valid license to save!"
4276
  msgstr ""
4277
 
4278
+ #: lib/i18n-extra.php:300
4279
  msgid "This is already your current license!"
4280
  msgstr ""
4281
 
4282
+ #: lib/i18n-extra.php:301
4283
  msgid "Your new license has been accepted and saved."
4284
  msgstr ""
4285
 
4286
+ #: lib/i18n-extra.php:302
4287
  msgid "This license is not valid"
4288
  msgstr ""
4289
 
4290
+ #: lib/i18n-extra.php:303
4291
  msgid "WP+ Edition License"
4292
  msgstr ""
4293
 
4294
+ #: lib/i18n-extra.php:304
4295
  msgid "License Number"
4296
  msgstr ""
4297
 
4298
+ #: lib/i18n-extra.php:305
4299
  msgid "No license found"
4300
  msgstr ""
4301
 
4302
+ #: lib/i18n-extra.php:306
4303
  msgid "Click to check your license validity"
4304
  msgstr ""
4305
 
4306
+ #: lib/i18n-extra.php:307
4307
  msgid "Expiration date"
4308
  msgstr ""
4309
 
4310
+ #: lib/i18n-extra.php:308
4311
  msgid "Unknown expiration date"
4312
  msgstr ""
4313
 
4314
+ #: lib/i18n-extra.php:309
4315
  msgid "Use the \"Check License Validity\" button to attempt to fix this error."
4316
  msgstr ""
4317
 
4318
+ #: lib/i18n-extra.php:310
4319
  msgid "Your license will expire soon!"
4320
  msgstr ""
4321
 
4322
+ #: lib/i18n-extra.php:311
4323
  msgid "Your license has expired."
4324
  msgstr ""
4325
 
4326
+ #: lib/i18n-extra.php:312
4327
  msgid "License renewal"
4328
  msgstr ""
4329
 
4330
+ #: lib/i18n-extra.php:313
4331
  msgid "Click here to get a license!"
4332
  msgstr ""
4333
 
4334
+ #: lib/i18n-extra.php:314
4335
  msgid "Enter your new license and click on the save button"
4336
  msgstr ""
4337
 
4338
+ #: lib/i18n-extra.php:315
4339
  msgid "Save New License"
4340
  msgstr ""
4341
 
4342
+ #: lib/i18n-extra.php:316
4343
  msgid "Allow, but block dangerous files"
4344
  msgstr ""
4345
 
4346
+ #: lib/i18n-extra.php:317
4347
  msgid "See contextual help for the list of files."
4348
  msgstr ""
4349
 
4350
+ #: lib/i18n-extra.php:318
4351
  msgid "Apply to ZIP archives file contents"
4352
  msgstr ""
4353
 
4354
+ #: lib/i18n-extra.php:319
4355
  msgid ""
4356
  "Keep this option disabled if you are using scripts such as Paypal IPN or "
4357
  "WordPress WP-Cron, unless you added their IP address or URL to your Access "
4358
  "Control whitelist."
4359
  msgstr ""
4360
 
4361
+ #: lib/i18n-extra.php:320
4362
  #, php-format
4363
  msgid ""
4364
  "Do not send a notification if the user is in the <a href=\"%s\">IP Access "
4371
  "Error: Your .htaccess file is not writable, please change its permissions: %s"
4372
  msgstr ""
4373
 
4374
+ #: lib/install.php:110 ninjafirewall.php:658 ninjafirewall.php:662
4375
  #, php-format
4376
  msgid "Error: wrong parameter value (%s)."
4377
  msgstr ""
4378
 
4379
+ #: lib/install.php:117 lib/install.php:222 lib/install.php:243
4380
  #, php-format
4381
  msgid ""
4382
  "Error: The following file is not writable, please change its permissions: %s"
4395
  "again."
4396
  msgstr ""
4397
 
4398
+ #: lib/install.php:168
4399
  #, php-format
4400
  msgid "The website front-end returned: HTTP %s %s."
4401
  msgstr ""
4402
 
4403
+ #: lib/install.php:178
4404
  msgid "The website front-end did not return the expected page."
4405
  msgstr ""
4406
 
4407
+ #: lib/install.php:187
4408
  #, php-format
4409
  msgid "The website front-end returned a fatal error: %s."
4410
  msgstr ""
4411
 
4412
+ #: lib/install.php:286 lib/install.php:311 lib/install.php:336
4413
+ #: lib/install.php:357
4414
  msgid "File is not writable"
4415
  msgstr ""
4416
 
4613
  msgid "Error: unable to write to the %s configuration file"
4614
  msgstr ""
4615
 
4616
+ #: lib/logs.php:36 ninjafirewall.php:932
4617
  msgid "Logs"
4618
  msgstr ""
4619
 
4722
  "Administrator to the whitelist\" option is enabled."
4723
  msgstr ""
4724
 
4725
+ #: lib/logs_live_log.php:96 ninjafirewall.php:375
4726
  msgid ""
4727
  "Live Log lets you watch your blog traffic in real time. To enable it, click "
4728
  "on the button below."
4823
  msgid "Error: please enter the custom log format."
4824
  msgstr ""
4825
 
4826
+ #: lib/monitoring.php:43 ninjafirewall.php:906
4827
  msgid "Monitoring"
4828
  msgstr ""
4829
 
5115
  msgid "Error reading new snapshot file."
5116
  msgstr ""
5117
 
5118
+ #: lib/monitoring_file_check.php:748 ninjafirewall.php:479
5119
  msgid "New file"
5120
  msgstr ""
5121
 
5122
+ #: lib/monitoring_file_check.php:749 ninjafirewall.php:480
5123
  msgid "Modified file"
5124
  msgstr ""
5125
 
5126
+ #: lib/monitoring_file_check.php:750 ninjafirewall.php:481
5127
  msgid "Deleted file"
5128
  msgstr ""
5129
 
5134
  #: lib/monitoring_file_check.php:777 lib/monitoring_file_check.php:779
5135
  #: lib/monitoring_file_check.php:799 lib/monitoring_file_check.php:801
5136
  #: lib/security_rules_update.php:572 lib/security_rules_update.php:574
5137
+ #: lib/utils.php:225 lib/utils.php:311 lib/utils.php:435 lib/utils.php:1100
5138
+ #: lib/utils.php:1279 lib/utils.php:1558
5139
  msgid "Blog:"
5140
  msgstr ""
5141
 
5199
  msgid "Save File Guard options"
5200
  msgstr ""
5201
 
5202
+ #: lib/network.php:24 ninjafirewall.php:1193 ninjafirewall.php:1197
5203
  #, php-format
5204
  msgid "You are not allowed to perform this task (%s)."
5205
  msgstr ""
5223
  msgstr ""
5224
 
5225
  #: lib/security_rules.php:44 lib/security_rules_update.php:578
5226
+ #: ninjafirewall.php:936
5227
  msgid "Security Rules"
5228
  msgstr ""
5229
 
5400
  msgid "Check For Updates Now!"
5401
  msgstr ""
5402
 
5403
+ #: lib/security_rules_update.php:233 lib/thickbox.php:55
5404
  msgid "Delete Log"
5405
  msgstr ""
5406
 
5468
  msgid "This notification can be turned off from NinjaFirewall \"%s\" page."
5469
  msgstr ""
5470
 
5471
+ #: lib/thickbox.php:45
5472
  msgid "NinjaFirewall error log"
5473
  msgstr ""
5474
 
5475
+ #: lib/thickbox.php:55
5476
  msgid "Close Log"
5477
  msgstr ""
5478
 
5479
+ #: lib/thickbox.php:79
5480
  msgid ""
5481
+ "In Full WAF mode, all scripts located inside the blog installation "
5482
+ "directories and sub-directories are protected by NinjaFirewall. It gives you "
5483
+ "the highest possible level of protection: security without compromise."
 
5484
  msgstr ""
5485
 
5486
+ #: lib/thickbox.php:81
5487
  #, php-format
5488
  msgid ""
5489
+ "It works on most websites right out of the box, or may require %ssome very "
5490
+ "little tweaks%s. But in a few cases, mostly because of some shared hosting "
5491
+ "plans restrictions, it may simply not work at all."
 
5492
  msgstr ""
5493
 
5494
+ #: lib/thickbox.php:83
5495
  msgid ""
5496
+ "If this happened to you, don't worry: you could still run it in WordPress "
5497
+ "WAF mode. Despite being less powerful than the Full WAF mode, it offers a "
5498
+ "level of protection and performance much higher than other security plugins."
 
5499
  msgstr ""
5500
 
5501
+ #: lib/thickbox.php:157
5502
  msgid "Select your HTTP server and your PHP server API"
5503
  msgstr ""
5504
 
5505
+ #: lib/thickbox.php:168
5506
  msgid "Other webserver + CGI/FastCGI or PHP-FPM"
5507
  msgstr ""
5508
 
5509
+ #: lib/thickbox.php:170
5510
  msgid "View PHPINFO"
5511
  msgstr ""
5512
 
5513
+ #: lib/thickbox.php:202
5514
  msgid "Select the PHP initialization file supported by your server"
5515
  msgstr ""
5516
 
5517
+ #: lib/thickbox.php:213
5518
+ msgid "Folders protected by NinjaFirewall"
5519
+ msgstr ""
5520
+
5521
+ #: lib/thickbox.php:215 lib/thickbox.php:362
5522
+ msgid "WordPress root directory:"
5523
+ msgstr ""
5524
+
5525
+ #: lib/thickbox.php:220 lib/thickbox.php:367
5526
+ msgid ""
5527
+ "The following folders will be protected by NinjaFirewall. If you want to "
5528
+ "exclude some of them, uncheck them in the list below:"
5529
+ msgstr ""
5530
+
5531
+ #: lib/thickbox.php:226
5532
+ msgid ""
5533
+ "After setting up the Full WAF mode, you could come back to this page to re-"
5534
+ "configure it whenever you want."
5535
+ msgstr ""
5536
+
5537
+ #: lib/thickbox.php:234
5538
  msgid "Let NinjaFirewall make the necessary changes (recommended)."
5539
  msgstr ""
5540
 
5541
+ #: lib/thickbox.php:236
5542
  msgid "I want to make the changes myself."
5543
  msgstr ""
5544
 
5545
+ #: lib/thickbox.php:238
5546
  msgid ""
5547
  "Please make the changes below, then click on the \"Finish Installation\" "
5548
  "button."
5549
  msgstr ""
5550
 
5551
+ #: lib/thickbox.php:245
5552
  #, php-format
5553
  msgid ""
5554
  "The %s file must be created, and the following lines of code added to it:"
5555
  msgstr ""
5556
 
5557
+ #: lib/thickbox.php:246
5558
  #, php-format
5559
  msgid "The following lines of code must be added to your existing %s file:"
5560
  msgstr ""
5561
 
5562
+ #: lib/thickbox.php:314
 
5563
  msgid ""
5564
  "Log in to your Openlitespeed admin dashboard, click on \"Virtual Host\", "
5565
  "select your domain, add the following instructions to the \"php.ini Override"
5566
+ "\" section in the \"General\" tab, and restart Openlitespeed:"
 
5567
  msgstr ""
5568
 
5569
+ #: lib/thickbox.php:321
5570
  msgid ""
5571
  "Important: if one day you wanted to uninstall NinjaFirewall, do not forget "
5572
  "to remove these instructions from your Openlitespeed admin dashboard "
5574
  "could not do it for you."
5575
  msgstr ""
5576
 
5577
+ #: lib/thickbox.php:337
5578
  msgid "Enable the sandbox."
5579
  msgstr ""
5580
 
5581
+ #: lib/thickbox.php:337
5582
  msgid ""
5583
  "If there were a problem during the installation, NinjaFirewall would undo "
5584
  "those changes automatically for you."
5585
  msgstr ""
5586
 
5587
+ #: lib/thickbox.php:338
5588
  msgid "Finish Installation"
5589
  msgstr ""
5590
 
5591
+ #: lib/thickbox.php:356
5592
+ msgid "Configuration"
5593
+ msgstr ""
5594
+
5595
+ #: lib/thickbox.php:360
5596
+ msgid "Full WAF mode"
5597
+ msgstr ""
5598
+
5599
+ #: lib/thickbox.php:374
5600
+ msgid "Save Changes"
5601
+ msgstr ""
5602
+
5603
+ #: lib/thickbox.php:385
5604
+ msgid "WordPress WAF mode"
5605
+ msgstr ""
5606
+
5607
+ #: lib/thickbox.php:392
5608
+ msgid ""
5609
+ "If you want to downgrade to WordPress WAF mode, log in to your Openlitespeed "
5610
+ "admin dashboard, click on \"Virtual Host\", select your domain and remove "
5611
+ "the \"auto_prepend_file\" directive from the \"php.ini Override\" section in "
5612
+ "the \"General\" tab, and restart Openlitespeed."
5613
+ msgstr ""
5614
+
5615
+ #: lib/thickbox.php:393 lib/thickbox.php:400
5616
+ msgid "Downgrade to WordPress WAF mode"
5617
+ msgstr ""
5618
+
5619
+ #: lib/thickbox.php:397
5620
+ msgid "If you want to downgrade to WordPress WAF mode, click the button below."
5621
+ msgstr ""
5622
+
5623
+ #: lib/thickbox.php:402
5624
+ msgid "You may have to wait five minutes for the changes to take effect."
5625
+ msgstr ""
5626
+
5627
+ #: lib/thickbox.php:409
5628
+ msgid "Cancel and Close"
5629
+ msgstr ""
5630
+
5631
  #: lib/utils.php:183 lib/utils.php:191 lib/utils.php:295
5632
  msgid "N/A"
5633
  msgstr ""
5656
  "doesn't have the right capabilities:"
5657
  msgstr ""
5658
 
5659
+ #: lib/utils.php:226 lib/utils.php:312 lib/utils.php:436 lib/utils.php:1283
5660
  msgid "Username:"
5661
  msgstr ""
5662
 
5664
  msgid "Action:"
5665
  msgstr ""
5666
 
5667
+ #: lib/utils.php:230 lib/utils.php:315 lib/utils.php:437 lib/utils.php:1287
5668
+ #: lib/utils.php:1559
5669
  msgid "User IP:"
5670
  msgstr ""
5671
 
5672
+ #: lib/utils.php:242 lib/utils.php:327 lib/utils.php:449 lib/utils.php:1299
5673
+ #: lib/utils.php:1554
5674
  msgid "A PHP backtrace has been attached to this message for your convenience."
5675
  msgstr ""
5676
 
5677
+ #: lib/utils.php:244 lib/utils.php:329 lib/utils.php:1302 lib/utils.php:1564
5678
  msgid ""
5679
  "This protection (and notification) can be turned off from NinjaFirewall "
5680
  "\"Firewall Policies\" page."
5681
  msgstr ""
5682
 
5683
  #: lib/utils.php:259 lib/utils.php:260 lib/utils.php:344 lib/utils.php:345
5684
+ #: lib/utils.php:466 lib/utils.php:467 lib/utils.php:1318 lib/utils.php:1319
5685
  msgid "You are not allowed to perform this task."
5686
  msgstr ""
5687
 
5703
  msgid "NinjaFirewall has blocked an attempt to create a user account:"
5704
  msgstr ""
5705
 
5706
+ #: lib/utils.php:767
5707
  msgid ""
5708
  "Warning: Because NinjaFirewall's Login Protection is enabled, Site Health "
5709
  "may return an error message regarding the loopback test (e.g., 404 or 401 "
5710
  "HTTP status code). You can safely ignore it."
5711
  msgstr ""
5712
 
5713
+ #: lib/utils.php:790 lib/utils.php:794
5714
  msgid "NinjaFirewall error"
5715
  msgstr ""
5716
 
5717
+ #: lib/utils.php:791
5718
  #, php-format
5719
  msgid ""
5720
  "%s directory cannot be created. Please review your installation and ensure "
5721
  "that %s is writable."
5722
  msgstr ""
5723
 
5724
+ #: lib/utils.php:795
5725
  #, php-format
5726
  msgid ""
5727
  "%s directory is read-only. Please review your installation and ensure that "
5728
  "%s is writable."
5729
  msgstr ""
5730
 
5731
+ #: lib/utils.php:810
5732
  msgid "unknown error"
5733
  msgstr ""
5734
 
5735
+ #: lib/utils.php:812
5736
  msgid "NinjaFirewall fatal error:"
5737
  msgstr ""
5738
 
5739
+ #: lib/utils.php:813
5740
  msgid "Review your installation, your site is not protected."
5741
  msgstr ""
5742
 
5743
+ #: lib/utils.php:840
5744
  msgid "Alert: WordPress console login"
5745
  msgstr ""
5746
 
5747
+ #: lib/utils.php:846
5748
  msgid "Someone just logged in to your WordPress admin console:"
5749
  msgstr ""
5750
 
5751
+ #: lib/utils.php:966 lib/utils.php:993
5752
  msgid "Forbidden access"
5753
  msgstr ""
5754
 
5755
+ #: lib/utils.php:1012
5756
  #, php-format
5757
  msgid ""
5758
  "<strong>ERROR</strong>: Invalid username, email address or password.<br /><a "
5759
  "href=\"%s\">Lost your password</a>?"
5760
  msgstr ""
5761
 
5762
+ #: lib/utils.php:1096
5763
  msgid "[NinjaFirewall] Alert: Database changes detected"
5764
  msgstr ""
5765
 
5766
+ #: lib/utils.php:1097
5767
  msgid ""
5768
  "NinjaFirewall has detected that one or more administrator accounts were "
5769
  "modified in the database:"
5770
  msgstr ""
5771
 
5772
+ #: lib/utils.php:1102
5773
  #, php-format
5774
  msgid "Total administrators : %s"
5775
  msgstr ""
5776
 
5777
+ #: lib/utils.php:1111
5778
  msgid ""
5779
  "If you cannot see any modifications in the above fields, it is possible that "
5780
  "the administrator password was changed."
5781
  msgstr ""
5782
 
5783
+ #: lib/utils.php:1264
5784
  msgid "Blocked privilege escalation attempt"
5785
  msgstr ""
5786
 
5787
+ #: lib/utils.php:1277
5788
  msgid ""
5789
  "NinjaFirewall has blocked an attempt to modify a user capability by someone "
5790
  "who does not have administrative privileges:"
5791
  msgstr ""
5792
 
5793
+ #: lib/utils.php:1330
5794
  msgid ""
5795
  "NinjaFirewall brute-force protection is enabled and you are temporarily "
5796
  "whitelisted."
5797
  msgstr ""
5798
 
5799
+ #: lib/utils.php:1345
5800
  #, php-format
5801
  msgid ""
5802
  "Hey, it seems that you've been using NinjaFirewall for some time. If you "
5805
  "rate it. Thank you!"
5806
  msgstr ""
5807
 
5808
+ #: lib/utils.php:1526
5809
  msgid ""
5810
  "The attempt was blocked and the option was reversed to its original value."
5811
  msgstr ""
5812
 
5813
+ #: lib/utils.php:1531
5814
  msgid "Attempt to modify WordPress settings"
5815
  msgstr ""
5816
 
5817
+ #: lib/utils.php:1532
5818
  msgid ""
5819
  "NinjaFirewall has blocked an attempt to modify some important WordPress "
5820
  "settings by a user that does not have administrative privileges:"
5821
  msgstr ""
5822
 
5823
+ #: lib/utils.php:1533 lib/utils.php:1542
5824
  #, php-format
5825
  msgid "Option: %s"
5826
  msgstr ""
5827
 
5828
+ #: lib/utils.php:1534
5829
  #, php-format
5830
  msgid "Original value: %s"
5831
  msgstr ""
5832
 
5833
+ #: lib/utils.php:1535
5834
  #, php-format
5835
  msgid "Modified value: %s"
5836
  msgstr ""
5837
 
5838
+ #: lib/utils.php:1536 lib/utils.php:1544
5839
  #, php-format
5840
  msgid "Action taken: %s"
5841
  msgstr ""
5842
 
5843
+ #: lib/utils.php:1540
5844
  msgid "Code injection attempt in WordPress options table"
5845
  msgstr ""
5846
 
5847
+ #: lib/utils.php:1541
5848
  msgid ""
5849
  "NinjaFirewall has blocked an attempt to inject code in the WordPress options "
5850
  "table by a user that does not have administrative privileges:"
5851
  msgstr ""
5852
 
5853
+ #: lib/utils.php:1543
5854
  #, php-format
5855
  msgid "Code: %s"
5856
  msgstr ""
5857
 
5858
+ #: lib/utils.php:1624
5859
+ msgid "Important: NinjaFirewall has detected that this is a security update."
5860
+ msgstr ""
5861
+
5862
+ #: lib/utils.php:1627
5863
+ msgid "More info about this warning."
5864
+ msgstr ""
5865
+
5866
+ #: lib/utils.php:1647
5867
  #, php-format
5868
  msgid "Error, cannot create the %s folder."
5869
  msgstr ""
5870
 
5871
+ #: lib/utils.php:1648 lib/utils.php:1657 lib/utils.php:1666
5872
  msgid "Check your server permissions and try again."
5873
  msgstr ""
5874
 
5875
+ #: lib/utils.php:1656
5876
  #, php-format
5877
  msgid "Error, the %s folder is not writable."
5878
  msgstr ""
5879
 
5880
+ #: lib/utils.php:1665
5881
  #, php-format
5882
  msgid "Error, cannot write %s."
5883
  msgstr ""
6311
  msgid "NinjaFirewall is not compatible with Microsoft Windows."
6312
  msgstr ""
6313
 
6314
+ #: ninjafirewall.php:326
6315
  msgid ""
6316
  "All fields will be restored to their default values and any changes you made "
6317
  "will be lost. Continue?"
6318
  msgstr ""
6319
 
6320
+ #: ninjafirewall.php:330
6321
  msgid "Missing security nonce, try to reload the page."
6322
  msgstr ""
6323
 
6324
+ #: ninjafirewall.php:332
6325
  msgid "Please select the HTTP server in the list."
6326
  msgstr ""
6327
 
6328
+ #: ninjafirewall.php:335
6329
  msgid "Delete the firewall's error log ?"
6330
  msgstr ""
6331
 
6332
+ #: ninjafirewall.php:339
6333
  msgid ""
6334
  "This action will restore the selected configuration file and will override "
6335
  "all your current firewall options, policies and rules. Continue?"
6336
  msgstr ""
6337
 
6338
+ #: ninjafirewall.php:343
6339
  msgid ""
6340
  "Any character that is not a letter [a-zA-Z], a digit [0-9], a dot [.], a "
6341
  "hyphen [-] or an underscore [_] will be removed from the filename and "
6342
  "replaced with the substitution character. Continue?"
6343
  msgstr ""
6344
 
6345
+ #: ninjafirewall.php:345
6346
  msgid ""
6347
  "Ensure that you can access your admin console over HTTPS before enabling "
6348
  "this option, otherwise you will lock yourself out of your site. Continue?"
6349
  msgstr ""
6350
 
6351
+ #: ninjafirewall.php:347
6352
  msgid ""
6353
  "WooCommerce is running: if you block accounts creation, your customers won't "
6354
  "be able to sign up. Continue?"
6355
  msgstr ""
6356
 
6357
+ #: ninjafirewall.php:349
6358
  msgid ""
6359
  "Your blog has user registration enabled: if you block accounts creation, "
6360
  "your customers won't be able to sign up. Continue?"
6361
  msgstr ""
6362
 
6363
+ #: ninjafirewall.php:351
6364
  msgid ""
6365
  "Your multisite installation allows users to register new sites: if you "
6366
  "enable this option, they will likely get blocked when creating their blog. "
6367
  "Continue?"
6368
  msgstr ""
6369
 
6370
+ #: ninjafirewall.php:355
6371
  msgid "Delete the current snapshot ?"
6372
  msgstr ""
6373
 
6374
+ #: ninjafirewall.php:359
6375
  msgid "Invalid character."
6376
  msgstr ""
6377
 
6378
+ #: ninjafirewall.php:361
6379
  msgid "\"admin\" is not acceptable, please choose another user name."
6380
  msgstr ""
6381
 
6382
+ #: ninjafirewall.php:363
6383
  msgid "Please enter max 1024 character only."
6384
  msgstr ""
6385
 
6386
+ #: ninjafirewall.php:365
6387
  msgid "Select when to enable the login protection."
6388
  msgstr ""
6389
 
6390
+ #: ninjafirewall.php:367
6391
  msgid "Enter a name and a password for the HTTP authentication."
6392
  msgstr ""
6393
 
6394
+ #: ninjafirewall.php:371
6395
  msgid "Your public key is not valid."
6396
  msgstr ""
6397
 
6398
+ #: ninjafirewall.php:377
6399
  msgid "No traffic yet, please wait"
6400
  msgstr ""
6401
 
6402
+ #: ninjafirewall.php:379
6403
  msgid "seconds..."
6404
  msgstr ""
6405
 
6406
+ #: ninjafirewall.php:381
6407
  msgid "Error: Live Log did not receive the expected response from your server:"
6408
  msgstr ""
6409
 
6410
+ #: ninjafirewall.php:383
6411
  msgid "Error: URL does not seem to exist (404 Not Found):"
6412
  msgstr ""
6413
 
6414
+ #: ninjafirewall.php:385
6415
  msgid "Error: Cannot find your log file. Try to reload this page."
6416
  msgstr ""
6417
 
6418
+ #: ninjafirewall.php:387
6419
  msgid "Error: The HTTP server returned the following error code:"
6420
  msgstr ""
6421
 
6422
+ #: ninjafirewall.php:643 ninjafirewall.php:763 ninjafirewall.php:832
6423
  msgid "Error: Security nonces do not match. Reload the page and try again."
6424
  msgstr ""
6425
 
6426
+ #: ninjafirewall.php:649
6427
  msgid "Error: NinjaFirewall is disabled"
6428
  msgstr ""
6429
 
6430
+ #: ninjafirewall.php:654 ninjafirewall.php:768 ninjafirewall.php:798
6431
  #, php-format
6432
  msgid "Error: missing parameter (%s)."
6433
  msgstr ""
6434
 
6435
+ #: ninjafirewall.php:894
6436
  msgid "NinjaFirewall: Dashboard"
6437
  msgstr ""
6438
 
6439
+ #: ninjafirewall.php:898
6440
  msgid "NinjaFirewall: Firewall Options"
6441
  msgstr ""
6442
 
6443
+ #: ninjafirewall.php:902
6444
  msgid "NinjaFirewall: Firewall Policies"
6445
  msgstr ""
6446
 
6447
+ #: ninjafirewall.php:906
6448
  msgid "NinjaFirewall: Monitoring"
6449
  msgstr ""
6450
 
6451
+ #: ninjafirewall.php:916
6452
  msgid "NinjaFirewall: Anti-Malware"
6453
  msgstr ""
6454
 
6455
+ #: ninjafirewall.php:920
6456
  msgid "NinjaFirewall: Network"
6457
  msgstr ""
6458
 
6459
+ #: ninjafirewall.php:924
6460
  msgid "NinjaFirewall: Event Notifications"
6461
  msgstr ""
6462
 
6463
+ #: ninjafirewall.php:928
6464
  msgid "NinjaFirewall: Log-in Protection"
6465
  msgstr ""
6466
 
6467
+ #: ninjafirewall.php:932
6468
  msgid "NinjaFirewall: Logs"
6469
  msgstr ""
6470
 
6471
+ #: ninjafirewall.php:936
6472
  msgid "NinjaFirewall: Security Rules"
6473
  msgstr ""
6474
 
6475
+ #: ninjafirewall.php:980
6476
  msgid "NinjaFirewall Settings"
6477
  msgstr ""
6478
 
6479
+ #: ninjafirewall.php:988
6480
  msgid "NinjaFirewall is enabled"
6481
  msgstr ""
6482
 
6483
+ #: ninjafirewall.php:1128
6484
  msgid "Access Restricted"
6485
  msgstr ""
6486
 
6487
+ #: ninjafirewall.php:1134
6488
  msgid "Settings"
6489
  msgstr ""
6490
 
6491
+ #: ninjafirewall.php:1135
6492
  msgid "Upgrade to Premium"
6493
  msgstr ""
6494
 
6495
+ #: ninjafirewall.php:1136
6496
  msgid "Rate it!"
6497
  msgstr ""
lib/anti_malware.php CHANGED
@@ -14,22 +14,22 @@
14
  | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15
  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16
  | GNU General Public License for more details. |
17
- +---------------------------------------------------------------------+ i18n+ / sa
18
  */
19
 
20
  if (! defined( 'NFW_ENGINE_VERSION' ) ) { die( 'Forbidden' ); }
21
 
22
  ?>
23
  <div class="wrap">
24
- <h1><img style="vertical-align:top;width:33px;height:33px;" src="<?php echo plugins_url( '/ninjafirewall/images/ninjafirewall_32.png' ) ?>">&nbsp;<?php _e('Anti-Malware', 'ninjafirewall') ?></h1>
25
 
26
  <div class="card">
27
- <p><?php _e('Oops...! We have removed the "Anti-Malware" from NinjaFirewall. Instead, we have now a brand new and much better antivirus plugin:', 'ninjafirewall') ?></p>
28
  <center><img src="<?php echo plugins_url() ?>/ninjafirewall/images/ninjascanner.png"></center>
29
- <p><?php printf( __('It is awesome and includes many great features: <a href="%s">check it out!</a>', 'ninjafirewall'), 'https://blog.nintechnet.com/ninjascanner-powerful-antivirus-scanner-for-wordpress/' ) ?></p>
30
- <p><a href="https://wordpress.org/plugins/ninjascanner/"><?php _e('Download it from wordpress.org!', 'ninjafirewall') ?></a></p>
31
  <br /><hr /><br />
32
- <p><?php _e('After installing NinjaScanner, click on "NinjaScanner &gt; Settings &gt; Advanced Users Settings" and enable the "Integrate NinjaScanner with NinjaFirewall" option. That will replace this page with NinjaScanner\'s own menu instead:', 'ninjafirewall') ?></p>
33
  <br />
34
  <center><img src="<?php echo plugins_url() ?>/ninjafirewall/images/ns_integration.png"></center>
35
  <br />
14
  | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15
  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16
  | GNU General Public License for more details. |
17
+ +---------------------------------------------------------------------+ i18n++ / sa
18
  */
19
 
20
  if (! defined( 'NFW_ENGINE_VERSION' ) ) { die( 'Forbidden' ); }
21
 
22
  ?>
23
  <div class="wrap">
24
+ <h1><img style="vertical-align:top;width:33px;height:33px;" src="<?php echo plugins_url( '/ninjafirewall/images/ninjafirewall_32.png' ) ?>">&nbsp;<?php esc_html_e('Anti-Malware', 'ninjafirewall') ?></h1>
25
 
26
  <div class="card">
27
+ <p><?php esc_html_e('Oops...! We have removed the "Anti-Malware" from NinjaFirewall. Instead, we have now a brand new and much better antivirus plugin:', 'ninjafirewall') ?></p>
28
  <center><img src="<?php echo plugins_url() ?>/ninjafirewall/images/ninjascanner.png"></center>
29
+ <p><?php esc_html_e('It is awesome and includes many great features:', 'ninjafirewall' ) ?> <a href="https://blog.nintechnet.com/ninjascanner-powerful-antivirus-scanner-for-wordpress/" target="_blank"><?php esc_html_e('check it out!', 'ninjafirewall') ?></a></p>
30
+ <p><a href="https://wordpress.org/plugins/ninjascanner/" target="_blank"><?php esc_html_e('Download it from wordpress.org!', 'ninjafirewall') ?></a></p>
31
  <br /><hr /><br />
32
+ <p><?php esc_html_e('After installing NinjaScanner, click on "NinjaScanner &gt; Settings &gt; Advanced Users Settings" and enable the "Integrate NinjaScanner with NinjaFirewall" option. That will replace this page with NinjaScanner\'s own menu instead:', 'ninjafirewall') ?></p>
33
  <br />
34
  <center><img src="<?php echo plugins_url() ?>/ninjafirewall/images/ns_integration.png"></center>
35
  <br />
lib/dashboard.php CHANGED
@@ -122,6 +122,10 @@ if (! empty( $_POST['delete-error-log'] ) ){
122
  // Display a one-time notice after two weeks of use
123
  nfw_rate_notice( $nfw_options );
124
 
 
 
 
 
125
  ?>
126
  <br />
127
  <h2 class="nav-tab-wrapper wp-clearfix" style="cursor:pointer">
@@ -199,17 +203,20 @@ if (! empty( $_POST['delete-error-log'] ) ){
199
 
200
  ?>
201
  <tr>
202
- <th scope="row" class="row-med"><?php _e('Mode', 'ninjafirewall') ?></th>
203
  <td>
204
  <?php
205
  if ( defined( 'NFW_WPWAF' ) ) {
206
- printf( __('NinjaFirewall is running in %s mode. For better protection, activate its Full WAF mode:', 'ninjafirewall'), '<a href="https://blog.nintechnet.com/full_waf-vs-wordpress_waf/">'. __('WordPress WAF', 'ninjafirewall') .'</a>');
207
  ?>
208
- <p><input type="button" id="nfw-thickbox" value="<?php _e('Activate Full WAF mode', 'ninjafirewall') ?>" class="button-secondary"></p>
209
  <?php
210
  } else {
211
  if (! NF_DISABLED ) {
212
- printf( __('NinjaFirewall is running in %s mode.', 'ninjafirewall'), __('Full WAF', 'ninjafirewall') );
 
 
 
213
  } else {
214
  echo '-';
215
  }
@@ -364,7 +371,7 @@ if (! empty( $_POST['delete-error-log'] ) ){
364
 
365
  if (! is_writable( NFW_LOG_DIR . '/nfwlog' ) ) {
366
  ?>
367
- <tr>
368
  <th scope="row" class="row-med"><?php _e('Log dir', 'ninjafirewall') ?></th>
369
  <td><span class="dashicons dashicons-dismiss nfw-danger"></span> <?php printf( __('%s directory is not writable! Please chmod it to 0777 or equivalent.', 'ninjafirewall'), '<code>'. htmlspecialchars(NFW_LOG_DIR) .'/nfwlog/</code>') ?></td>
370
  </tr>
@@ -373,13 +380,46 @@ if (! empty( $_POST['delete-error-log'] ) ){
373
 
374
  if (! is_writable( NFW_LOG_DIR . '/nfwlog/cache') ) {
375
  ?>
376
- <tr>
377
  <th scope="row" class="row-med"><?php _e('Log dir', 'ninjafirewall') ?></th>
378
  <td><span class="dashicons dashicons-dismiss nfw-danger"></span> <?php printf(__('%s directory is not writable! Please chmod it to 0777 or equivalent.', 'ninjafirewall'), '<code>'. htmlspecialchars(NFW_LOG_DIR) . '/nfwlog/cache/</code>') ?></td>
379
  </tr>
380
  <?php
381
  }
382
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
383
  // Error log
384
  $log = NFW_LOG_DIR . '/nfwlog/error_log.php';
385
  if ( file_exists( $log ) ) {
@@ -432,10 +472,55 @@ if (! empty( $_POST['delete-error-log'] ) ){
432
  </div>
433
  <?php
434
 
435
- if ( defined( 'NFW_WPWAF' ) || ! empty( $errlog_content ) ) {
436
- // Load the thickbox dialogbox if we're running in WordPress WAF mode and/or error log
437
- require __DIR__ .'/thickbox.php';
438
- }
 
 
 
439
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
440
  // ---------------------------------------------------------------------
441
  // EOF
122
  // Display a one-time notice after two weeks of use
123
  nfw_rate_notice( $nfw_options );
124
 
125
+ // Full WAF settings change
126
+ if (! empty( $_GET['nfwafconfig'] ) ) {
127
+ echo '<div class="updated notice is-dismissible"><p>' . esc_html__('Your changes have been saved.', 'ninjafirewall') . '</p></div>';
128
+ }
129
  ?>
130
  <br />
131
  <h2 class="nav-tab-wrapper wp-clearfix" style="cursor:pointer">
203
 
204
  ?>
205
  <tr>
206
+ <th scope="row" class="row-med"><?php esc_html_e('Mode', 'ninjafirewall') ?></th>
207
  <td>
208
  <?php
209
  if ( defined( 'NFW_WPWAF' ) ) {
210
+ printf( esc_html__('NinjaFirewall is running in %s mode. For better protection, activate its Full WAF mode:', 'ninjafirewall'), '<a href="https://blog.nintechnet.com/full_waf-vs-wordpress_waf/" target="_blank">WordPress WAF</a>');
211
  ?>
212
+ <p><input type="button" id="nfw-activate-thickbox" value="<?php esc_attr_e('Activate Full WAF mode', 'ninjafirewall') ?>" class="button-secondary"></p>
213
  <?php
214
  } else {
215
  if (! NF_DISABLED ) {
216
+ printf( esc_html__('NinjaFirewall is running in %s mode.', 'ninjafirewall'), '<a href="https://blog.nintechnet.com/full_waf-vs-wordpress_waf/" target="_blank">Full WAF</a>');
217
+ ?>
218
+ <p><input type="button" id="nfw-configure-thickbox" value="<?php esc_attr_e('Configure', 'ninjafirewall') ?>" class="button-secondary"></p>
219
+ <?php
220
  } else {
221
  echo '-';
222
  }
371
 
372
  if (! is_writable( NFW_LOG_DIR . '/nfwlog' ) ) {
373
  ?>
374
+ <tr>
375
  <th scope="row" class="row-med"><?php _e('Log dir', 'ninjafirewall') ?></th>
376
  <td><span class="dashicons dashicons-dismiss nfw-danger"></span> <?php printf( __('%s directory is not writable! Please chmod it to 0777 or equivalent.', 'ninjafirewall'), '<code>'. htmlspecialchars(NFW_LOG_DIR) .'/nfwlog/</code>') ?></td>
377
  </tr>
380
 
381
  if (! is_writable( NFW_LOG_DIR . '/nfwlog/cache') ) {
382
  ?>
383
+ <tr>
384
  <th scope="row" class="row-med"><?php _e('Log dir', 'ninjafirewall') ?></th>
385
  <td><span class="dashicons dashicons-dismiss nfw-danger"></span> <?php printf(__('%s directory is not writable! Please chmod it to 0777 or equivalent.', 'ninjafirewall'), '<code>'. htmlspecialchars(NFW_LOG_DIR) . '/nfwlog/cache/</code>') ?></td>
386
  </tr>
387
  <?php
388
  }
389
 
390
+
391
+ if (! defined('NF_DISABLE_PHPINICHECK') && ! defined('NFW_WPWAF') ) {
392
+
393
+ // Note: any potential PHP session will be closed below.
394
+
395
+ // Make sure the PHP INI is not viewable by webusers
396
+ if ( file_exists( ABSPATH .'php.ini' ) ) {
397
+ @session_write_close();
398
+ $res = nfw_is_inireadable( 'php.ini' );
399
+ if ( $res !== false ) {
400
+ ?>
401
+ <tr>
402
+ <th scope="row" class="row-med">PHP INI</th>
403
+ <td><span class="dashicons dashicons-dismiss nfw-danger"></span> <?php printf( esc_html__('The php.ini file is readable by web users: %s', 'ninjafirewall'), '<code>'. htmlspecialchars( $res ) .'</code>' ) ?> <br /><a href="https://blog.nintechnet.com/protecting-ninjafirewalls-php-ini-file/" target="_blank"><?php esc_html_e('Consult our blog for more info.', 'ninjafirewall') ?></a></td>
404
+ </tr>
405
+ <?php
406
+ }
407
+ }
408
+ if ( file_exists( ABSPATH .'.user.ini' ) ) {
409
+ $res = nfw_is_inireadable( '.user.ini' );
410
+ @session_write_close();
411
+ if ( $res !== false ) {
412
+ ?>
413
+ <tr>
414
+ <th scope="row" class="row-med">PHP INI</th>
415
+ <td><span class="dashicons dashicons-dismiss nfw-danger"></span> <?php printf( esc_html__('The .user.ini file is readable by web users: %s', 'ninjafirewall'), '<code>'. htmlspecialchars( $res ) .'</code>' ) ?><br /><a href="https://blog.nintechnet.com/protecting-ninjafirewalls-php-ini-file/" target="_blank"><?php esc_html_e('Consult our blog for more info.', 'ninjafirewall') ?></a></td>
416
+ </tr>
417
+ <?php
418
+ }
419
+ }
420
+
421
+ }
422
+
423
  // Error log
424
  $log = NFW_LOG_DIR . '/nfwlog/error_log.php';
425
  if ( file_exists( $log ) ) {
472
  </div>
473
  <?php
474
 
475
+ // Load thickbox
476
+ require __DIR__ .'/thickbox.php';
477
+
478
+ // ---------------------------------------------------------------------
479
+ // Verify if PHP INI file is readable by web users.
480
+
481
+ function nfw_is_inireadable( $ini ) {
482
 
483
+ if ( is_multisite() ) {
484
+ $url = network_home_url('/') . $ini;
485
+ } else {
486
+ $url = home_url('/') . $ini;
487
+ }
488
+ global $wp_version;
489
+ $opts = array(
490
+ 'http' => array(
491
+ // We only care about the returned HTTP code
492
+ 'ignore_errors' => true,
493
+ // Max 2 seconds
494
+ 'timeout' => 2,
495
+ 'method' => "GET",
496
+ 'header' =>
497
+ "Accept-language: en-US,en;q=0.5\r\n" .
498
+ "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" .
499
+ "User-Agent: Mozilla/5.0 (compatible; NinjaFirewall/". NFW_ENGINE_VERSION ."; WordPress/$wp_version)\r\n",
500
+ )
501
+ );
502
+
503
+ $addr = $_SERVER['SERVER_ADDR'];
504
+ if (! filter_var( $addr, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE ) ) {
505
+ // We don't want a fatal error if we're running on localhost e.g., dev site etc
506
+ $opts['ssl']['verify_peer'] = false;
507
+ $opts['ssl']['verify_peer_name'] = false;
508
+ }
509
+ $context = stream_context_create( $opts );
510
+ // As we don't want monitoring/debugging plugins to throw a warning or error
511
+ // in the backend because the server returned a 403 error, we don't use
512
+ // the WordPress's API
513
+ @file_get_contents( $url, false, $context );
514
+ if ( empty( $http_response_header ) ) {
515
+ nfw_log_error( 'nfw_is_inireadable: connection error' );
516
+ return false;
517
+ }
518
+ $response = explode( ' ', $http_response_header[0] );
519
+ if (! empty( $response[1] ) && (int) $response[1] == 200 ) {
520
+ return $url;
521
+ }
522
+ return false;
523
+
524
+ }
525
  // ---------------------------------------------------------------------
526
  // EOF
lib/dashboard_about.php CHANGED
@@ -26,11 +26,11 @@ if (! defined( 'NFW_ENGINE_VERSION' ) ) { die( 'Forbidden' ); }
26
  <br />
27
  <font style="font-size: 1.1em;">
28
  <ul style="list-style: disc;">
29
- <li><?php _e('Our blog:', 'ninjafirewall') ?> <a href="https://blog.nintechnet.com/">https://blog.nintechnet.com/</a></li>
30
- <li><?php _e('Stay informed about the latest vulnerabilities in WordPress plugins and themes:', 'ninjafirewall') ?> <a href="https://twitter.com/nintechnet">https://twitter.com/nintechnet</a></li>
31
- <li><a href="https://blog.nintechnet.com/ninjafirewall-general-data-protection-regulation-compliance/"><?php _e('GDPR Compliance', 'ninjafirewall') ?></a></li>
32
- <li><a href="https://wordpress.org/support/view/plugin-reviews/ninjafirewall?rate=5#postform"><?php _e('Rate it on WordPress.org!', 'ninjafirewall') ?></a> <img style="vertical-align:middle" src="<?php echo plugins_url() ?>/ninjafirewall/images/rate.png" /></li>
33
- <li><a href="https://nintechnet.com/referral/"><?php _e('NinjaFirewall Referral Program', 'ninjafirewall') ?></a></li>
34
  </ul>
35
  </font>
36
  </div>
26
  <br />
27
  <font style="font-size: 1.1em;">
28
  <ul style="list-style: disc;">
29
+ <li><?php esc_html_e('Our blog:', 'ninjafirewall') ?> <a href="https://blog.nintechnet.com/">https://blog.nintechnet.com/</a></li>
30
+ <li><?php esc_html_e('Stay informed about the latest vulnerabilities in WordPress plugins and themes:', 'ninjafirewall') ?> <a href="https://twitter.com/nintechnet">https://twitter.com/nintechnet</a></li>
31
+ <li><a href="https://blog.nintechnet.com/ninjafirewall-general-data-protection-regulation-compliance/"><?php esc_html_e('GDPR Compliance', 'ninjafirewall') ?></a></li>
32
+ <li><a href="https://wordpress.org/support/view/plugin-reviews/ninjafirewall?rate=5#postform"><?php esc_html_e('Rate it on WordPress.org!', 'ninjafirewall') ?></a> <img style="vertical-align:middle" src="<?php echo plugins_url() ?>/ninjafirewall/images/rate.png" /></li>
33
+ <li><a href="https://nintechnet.com/referral/"><?php esc_html_e('NinjaFirewall Referral Program', 'ninjafirewall') ?></a></li>
34
  </ul>
35
  </font>
36
  </div>
lib/dashboard_statistics.php CHANGED
@@ -14,7 +14,7 @@
14
  | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15
  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16
  | GNU General Public License for more details. |
17
- +---------------------------------------------------------------------+ i18n+ / sa / 2
18
  */
19
 
20
  if (! defined( 'NFW_ENGINE_VERSION' ) ) { die( 'Forbidden' ); }
@@ -73,7 +73,7 @@ $c = $critical; $h = $high; $m = $medium;
73
  if ( $total == 1 ) { $fast = $slow; }
74
 
75
  if (! $total ) {
76
- echo '<div class="nfw-notice nfw-notice-orange"><p>' . __('You do not have any stats for the selected month yet.', 'ninjafirewall') . '</p></div>';
77
  $fast = 0;
78
  } else {
79
  $coef = 100 / $total;
@@ -88,77 +88,74 @@ if (! $total ) {
88
  }
89
  }
90
 
91
- ?><h3><?php _e('Monthly Statistics', 'ninjafirewall') ?></h3>
92
  <table class="form-table nfw-table">
93
  <tr>
94
- <th scope="row" class="row-med"><?php _e('Select a month', 'ninjafirewall') ?></th>
95
  <td style="vertical-align: middle;"><?php echo summary_stats_combo( $statx ) ?></td>
96
  </tr>
97
  <tr>
98
- <th scope="row" class="row-med"><?php _e('Blocked threats', 'ninjafirewall') ?></th>
99
  <td><?php echo $total ?></td>
100
  </tr>
101
  <tr>
102
- <th scope="row" class="row-med"><?php _e('Threats level', 'ninjafirewall') ?></th>
103
  <td><canvas id="nfw_stats"></canvas></td>
104
  </tr>
105
  <tr>
106
- <th scope="row" class="row-med"><h3><?php _e('Benchmarks', 'ninjafirewall') ?></h3></th>
107
  <td>&nbsp;</td><td>&nbsp;</td>
108
  </tr>
109
  <tr>
110
- <th scope="row" class="row-med"><?php _e('Average time per request', 'ninjafirewall') ?></th>
111
- <td><?php echo $speed ?> <?php _e('seconds', 'ninjafirewall') ?></td>
112
  </tr>
113
  <tr>
114
- <th scope="row" class="row-med"><?php _e('Fastest request', 'ninjafirewall') ?></th>
115
- <td><?php echo round( $fast, 4) ?> <?php _e('seconds', 'ninjafirewall') ?></td>
116
  </tr>
117
  <tr>
118
- <th scope="row" class="row-med"><?php _e('Slowest request', 'ninjafirewall') ?></th>
119
- <td><?php echo round( $slow, 4) ?> <?php _e('seconds', 'ninjafirewall') ?></td>
120
  </tr>
121
  </table>
122
 
123
- <script>
124
- var horizontalBarChartData = {
125
- labels: [
126
- "<?php echo __('Critical', 'ninjafirewall') .' '. $critical ?>%",
127
- "<?php echo __('High', 'ninjafirewall') .' '. $high ?>%",
128
- "<?php echo __('Medium', 'ninjafirewall') .' '. $medium ?>%"
129
- ],
130
- datasets: [{
131
- label: '<?php _e('Blocked threats', 'ninjafirewall') ?>',
132
- backgroundColor: ["#c9302c", "#ec971f","#ECE81F"],
133
- data: [<?php echo "{$c}, {$h}, {$m}" ?>],
134
- borderColor: ['#8C2C2A', '#c9302c', '#ec971f'],
135
- borderWidth: 1
136
- } ]
137
- };
138
- window.onload = function() {
139
- var ctx = document.getElementById('nfw_stats').getContext("2d");
140
- window.myHorizontalBar = new Chart(ctx, {
141
- type: 'horizontalBar',
142
- data: horizontalBarChartData,
143
- options: {
144
- tooltips: {
145
- backgroundColor: '#333',
146
- },
 
 
 
 
147
  legend: {
148
- display: false,
149
  },
150
- responsive: true,
151
- scales: {
152
- xAxes: [{
153
- ticks: {
154
- beginAtZero: true
155
- }
156
- }]
157
- }
158
  }
159
- });
160
- };
161
- </script>
 
162
  <?php
163
 
164
  // ---------------------------------------------------------------------
@@ -181,7 +178,7 @@ function summary_stats_combo( $statx ) {
181
 
182
  $ret = '<form>
183
  <select class="input" name="statx" onChange="return nfwjs_stat_redir(this.value);">
184
- <option value="">' . __('Select monthly stats to view...', 'ninjafirewall') . '</option>';
185
  foreach ( $avail_logs as $file => $text ) {
186
  $ret .= '<option value="'. $file .'"';
187
  if ($file === $statx ) {
14
  | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15
  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16
  | GNU General Public License for more details. |
17
+ +---------------------------------------------------------------------+ i18n++ / sa / 2
18
  */
19
 
20
  if (! defined( 'NFW_ENGINE_VERSION' ) ) { die( 'Forbidden' ); }
73
  if ( $total == 1 ) { $fast = $slow; }
74
 
75
  if (! $total ) {
76
+ echo '<div class="nfw-notice nfw-notice-orange"><p>' . esc_html__('You do not have any stats for the selected month yet.', 'ninjafirewall') . '</p></div>';
77
  $fast = 0;
78
  } else {
79
  $coef = 100 / $total;
88
  }
89
  }
90
 
91
+ ?><h3><?php esc_html_e('Monthly Statistics', 'ninjafirewall') ?></h3>
92
  <table class="form-table nfw-table">
93
  <tr>
94
+ <th scope="row" class="row-med"><?php esc_html_e('Select a month', 'ninjafirewall') ?></th>
95
  <td style="vertical-align: middle;"><?php echo summary_stats_combo( $statx ) ?></td>
96
  </tr>
97
  <tr>
98
+ <th scope="row" class="row-med"><?php esc_html_e('Blocked threats', 'ninjafirewall') ?></th>
99
  <td><?php echo $total ?></td>
100
  </tr>
101
  <tr>
102
+ <th scope="row" class="row-med"><?php esc_html_e('Threats level', 'ninjafirewall') ?></th>
103
  <td><canvas id="nfw_stats"></canvas></td>
104
  </tr>
105
  <tr>
106
+ <th scope="row" class="row-med"><h3><?php esc_html_e('Benchmarks', 'ninjafirewall') ?></h3></th>
107
  <td>&nbsp;</td><td>&nbsp;</td>
108
  </tr>
109
  <tr>
110
+ <th scope="row" class="row-med"><?php esc_html_e('Average time per request', 'ninjafirewall') ?></th>
111
+ <td><?php echo $speed ?> <?php esc_html_e('seconds', 'ninjafirewall') ?></td>
112
  </tr>
113
  <tr>
114
+ <th scope="row" class="row-med"><?php esc_html_e('Fastest request', 'ninjafirewall') ?></th>
115
+ <td><?php echo round( $fast, 4) ?> <?php esc_html_e('seconds', 'ninjafirewall') ?></td>
116
  </tr>
117
  <tr>
118
+ <th scope="row" class="row-med"><?php esc_html_e('Slowest request', 'ninjafirewall') ?></th>
119
+ <td><?php echo round( $slow, 4) ?> <?php esc_html_e('seconds', 'ninjafirewall') ?></td>
120
  </tr>
121
  </table>
122
 
123
+ <script type="text/javascript">
124
+ window.onload = function() {
125
+ var ctx = document.getElementById('nfw_stats').getContext('2d');
126
+ var myChart = new Chart(ctx, {
127
+ type: 'bar',
128
+ data: {
129
+ labels: [
130
+ "<?php echo esc_attr__('Critical', 'ninjafirewall') .' '. $critical ?>%",
131
+ "<?php echo esc_attr__('High', 'ninjafirewall') .' '. $high ?>%",
132
+ "<?php echo esc_attr__('Medium', 'ninjafirewall') .' '. $medium ?>%"
133
+ ],
134
+ datasets: [{
135
+ label: '<?php esc_attr_e('Blocked threats', 'nfwplus') ?>',
136
+ data: [<?php echo "{$c}, {$h}, {$m}" ?>],
137
+ backgroundColor: ['#c9302c', '#ec971f', '#ECE81F'],
138
+ borderColor: ['#8C2C2A', '#c9302c', '#ec971f'],
139
+ borderWidth: 1
140
+ }]
141
+ },
142
+ options: {
143
+ indexAxis: 'y',
144
+ scales: {
145
+ y: {
146
+ beginAtZero: true
147
+ }
148
+ },
149
+ responsive: true,
150
+ plugins: {
151
  legend: {
152
+ display: false
153
  },
 
 
 
 
 
 
 
 
154
  }
155
+ }
156
+ });
157
+ }
158
+ </script>
159
  <?php
160
 
161
  // ---------------------------------------------------------------------
178
 
179
  $ret = '<form>
180
  <select class="input" name="statx" onChange="return nfwjs_stat_redir(this.value);">
181
+ <option value="">' . esc_html__('Select monthly stats to view...', 'ninjafirewall') . '</option>';
182
  foreach ( $avail_logs as $file => $text ) {
183
  $ret .= '<option value="'. $file .'"';
184
  if ($file === $statx ) {
lib/event_notifications.php CHANGED
@@ -119,6 +119,7 @@ if (! isset( $nfw_options['a_0'] ) ) {
119
  <th scope="row" class="row-med"><?php _e('Send me an alert whenever', 'ninjafirewall') ?></th>
120
  <td>
121
  <p><label><input type="checkbox" name="nfw_options[secupdates]" value="1"<?php checked( $nfw_options['secupdates'], 1) ?>>&nbsp;<?php _e('An important security update is available for a plugin, theme or WordPress (default)', 'ninjafirewall') ?></label></p>
 
122
  </td>
123
  </tr>
124
  </table>
@@ -185,7 +186,7 @@ if (! isset( $nfw_options['a_0'] ) ) {
185
  <option value="1"<?php selected( $nfw_options['a_61'], 1) ?>><?php _e('Medium verbosity (default)', 'ninjafirewall') ?></option>
186
  <option value="2"<?php selected( $nfw_options['a_61'], 2) ?>><?php _e('High verbosity', 'ninjafirewall') ?></option>
187
  </select>
188
- <p><span class="description"><?php printf( __('<a href="%s">Consult our blog</a> for more info.', 'ninjafirewall'), 'https://blog.nintechnet.com/ninjafirewall-wp-edition-adds-php-backtrace-to-email-notifications/' ) ?></span></p>
189
  </td>
190
  </tr>
191
  </table>
119
  <th scope="row" class="row-med"><?php _e('Send me an alert whenever', 'ninjafirewall') ?></th>
120
  <td>
121
  <p><label><input type="checkbox" name="nfw_options[secupdates]" value="1"<?php checked( $nfw_options['secupdates'], 1) ?>>&nbsp;<?php _e('An important security update is available for a plugin, theme or WordPress (default)', 'ninjafirewall') ?></label></p>
122
+ <p><span class="description"><a href="https://blog.nintechnet.com/how-to-get-informed-about-the-latest-security-updates-in-your-wordpress-plugins-and-themes/" target="_blank"><?php esc_html_e('Consult our blog for more info.', 'ninjafirewall') ?></a>
123
  </td>
124
  </tr>
125
  </table>
186
  <option value="1"<?php selected( $nfw_options['a_61'], 1) ?>><?php _e('Medium verbosity (default)', 'ninjafirewall') ?></option>
187
  <option value="2"<?php selected( $nfw_options['a_61'], 2) ?>><?php _e('High verbosity', 'ninjafirewall') ?></option>
188
  </select>
189
+ <p><span class="description"><a href="https://blog.nintechnet.com/ninjafirewall-wp-edition-adds-php-backtrace-to-email-notifications/" target="_blank"><?php esc_html_e('Consult our blog for more info.', 'ninjafirewall') ?></a>
190
  </td>
191
  </tr>
192
  </table>
lib/firewall.php CHANGED
@@ -276,11 +276,6 @@ if (! empty($nfw_['nfw_options']['wp_dir']) && preg_match( '`' . $nfw_['nfw_opti
276
 
277
  nfw_check_upload();
278
 
279
- $nfw_['user_can'] = false;
280
- if ( isset( $_SESSION['nfw_user_can'] ) ) {
281
- $nfw_['user_can'] = nfw_check_postpage();
282
- }
283
-
284
  // Fetch rules
285
  $ret = nfw_get_data( 'nfw_rules' );
286
  if ( $ret !== true ) {
@@ -288,11 +283,7 @@ if ( $ret !== true ) {
288
  return;
289
  }
290
 
291
- if ( $nfw_['user_can'] == false ) {
292
- nfw_check_request( $nfw_['nfw_rules'], $nfw_['nfw_options'] );
293
- } else {
294
- nfw_check_admin_request();
295
- }
296
 
297
  if (! empty($nfw_['nfw_options']['get_sanitise']) && ! empty($_GET) ){
298
  $_GET = nfw_sanitise( $_GET, 1, 'GET');
@@ -390,7 +381,7 @@ function nfw_connect() {
390
  }
391
  fclose($nfw_['fh']);
392
  unset($wp_config);
393
- if ( (! isset($nfw_['DB_NAME'])) || (! isset($nfw_['DB_USER'])) || (! isset($nfw_['DB_PASSWORD'])) || (! isset($nfw_['DB_HOST'])) || (! isset($nfw_['table_prefix'])) ) {
394
  return 3;
395
  }
396
 
@@ -472,50 +463,6 @@ function nfw_get_data( $what ) {
472
  }
473
  }
474
 
475
- // =====================================================================
476
-
477
- function nfw_check_postpage() {
478
-
479
- if ( empty( $_SERVER['REQUEST_URI'] ) || $_SERVER['REQUEST_METHOD'] != 'POST' ||
480
- ! in_array( $_SESSION['nfw_user_can'], array( 'edit_pages', 'edit_posts' ) ) ) {
481
-
482
- return false;
483
- }
484
- $path = parse_url( $_SERVER['REQUEST_URI'], PHP_URL_PATH );
485
- if ( $path == null ) {
486
-
487
- return false;
488
- }
489
-
490
- if ( $path == '/wp-admin/post.php' ) {
491
- if ( isset( $_POST['post_type'] ) && isset( $_POST['action'] ) && $_POST['action'] == 'editpost' ) {
492
- if ( $_POST['post_type'] == 'page' && $_SESSION['nfw_user_can'] == 'edit_pages' ) {
493
- return true;
494
- }
495
- if ( $_POST['post_type'] == 'post' && ( $_SESSION['nfw_user_can'] == 'edit_posts' || $_SESSION['nfw_user_can'] == 'edit_pages' ) ) {
496
- return true;
497
- }
498
- }
499
- return false;
500
- }
501
-
502
- if ( strpos( $path, '/wp-json/wp/v2/pages/' ) === 0 ) {
503
- if ( $_SESSION['nfw_user_can'] == 'edit_pages' ) {
504
- define('NFW_ALLOWRESTAPI', true);
505
- return true;
506
- }
507
- return false;
508
- }
509
- if ( strpos( $path, '/wp-json/wp/v2/posts/' ) === 0 ) {
510
- if ( $_SESSION['nfw_user_can'] == 'edit_posts' ) {
511
- define('NFW_ALLOWRESTAPI', true);
512
- return true;
513
- }
514
- }
515
-
516
- return false;
517
- }
518
-
519
  // =====================================================================
520
  // Check for HTTPS.
521
 
@@ -952,6 +899,16 @@ function nfw_matching( $where, $key, $nfw_rules, $rules, $subid, $id, $nfw_optio
952
  $val = $GLOBALS['_'.$where][$key];
953
  }
954
 
 
 
 
 
 
 
 
 
 
 
955
  if ( is_array($val) ) {
956
  if ( isset( $nfw_['flattened'][$where][$key] ) ) {
957
  $val = $nfw_['flattened'][$where][$key];
@@ -1089,6 +1046,9 @@ function nfw_normalize( $string, $nfw_rules ) {
1089
  }
1090
 
1091
  $norm = rawurldecode( $string );
 
 
 
1092
  if (! $norm ) {
1093
  return $string;
1094
  }
276
 
277
  nfw_check_upload();
278
 
 
 
 
 
 
279
  // Fetch rules
280
  $ret = nfw_get_data( 'nfw_rules' );
281
  if ( $ret !== true ) {
283
  return;
284
  }
285
 
286
+ nfw_check_request( $nfw_['nfw_rules'], $nfw_['nfw_options'] );
 
 
 
 
287
 
288
  if (! empty($nfw_['nfw_options']['get_sanitise']) && ! empty($_GET) ){
289
  $_GET = nfw_sanitise( $_GET, 1, 'GET');
381
  }
382
  fclose($nfw_['fh']);
383
  unset($wp_config);
384
+ if (! isset($nfw_['DB_NAME']) || ! isset($nfw_['DB_USER']) || ! isset($nfw_['DB_PASSWORD']) || ! isset($nfw_['DB_HOST']) || ! isset($nfw_['table_prefix']) ) {
385
  return 3;
386
  }
387
 
463
  }
464
  }
465
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
466
  // =====================================================================
467
  // Check for HTTPS.
468
 
899
  $val = $GLOBALS['_'.$where][$key];
900
  }
901
 
902
+ // Check if the user has the required capability, if any
903
+ if ( isset( $rules['cpb'] ) && isset( $_SESSION['allcaps'] ) ) {
904
+ $caps = explode( '|', $rules['cpb'] );
905
+ foreach( $caps as $cap ) {
906
+ if (! empty( $_SESSION['allcaps'][$cap] ) ) {
907
+ return 0;
908
+ }
909
+ }
910
+ }
911
+
912
  if ( is_array($val) ) {
913
  if ( isset( $nfw_['flattened'][$where][$key] ) ) {
914
  $val = $nfw_['flattened'][$where][$key];
1046
  }
1047
 
1048
  $norm = rawurldecode( $string );
1049
+ if ( strpos( $norm, '%' ) !== false ) {
1050
+ $norm = rawurldecode( $norm );
1051
+ }
1052
  if (! $norm ) {
1053
  return $string;
1054
  }
lib/firewall_options.php CHANGED
@@ -378,6 +378,12 @@ function nf_sub_options_import( $file ) {
378
  return sprintf($err_msg, 1);
379
  }
380
  $data = str_replace( '<?php exit; ?>', '', $data );
 
 
 
 
 
 
381
  @list ($nfw_options, $rules, $bf) = @explode("\n:-:\n", $data . "\n:-:\n");
382
 
383
  // Detect and remove potential Unicode BOM:
@@ -399,15 +405,12 @@ function nf_sub_options_import( $file ) {
399
  return sprintf($err_msg, 3);
400
  }
401
 
402
-
403
  // Make sure the major version numbers match (3.x, 4.x etc):
404
- //~ 2019-06-26: **temporary**: disabled while updating from version 3.x to 4.x
405
- //~ list ( $major_current ) = explode( '.', NFW_ENGINE_VERSION );
406
  list ( $major_import ) = explode( '.', $nfw_options['engine_version'] );
407
- //~ if ( $major_current != $major_import ) {
408
- //~ return __('The imported file is not compatible with that version of NinjaFirewall', 'ninjafirewall');
409
- //~ }
410
- //~ 2019-06-26: **temporary**: version 3.x to 4.x update
411
  if ( $major_import < '4' ) {
412
  if ( empty( $nfw_options['allow_local_ip'] ) ) {
413
  $nfw_options['allow_local_ip'] = 1;
378
  return sprintf($err_msg, 1);
379
  }
380
  $data = str_replace( '<?php exit; ?>', '', $data );
381
+ // Is it base64-encoded (since 4.3.5)?
382
+ if ( $data[0] == 'B' ) {
383
+ // Decode it
384
+ $data = ltrim( $data, 'B' );
385
+ $data = base64_decode( $data );
386
+ }
387
  @list ($nfw_options, $rules, $bf) = @explode("\n:-:\n", $data . "\n:-:\n");
388
 
389
  // Detect and remove potential Unicode BOM:
405
  return sprintf($err_msg, 3);
406
  }
407
 
 
408
  // Make sure the major version numbers match (3.x, 4.x etc):
409
+ list ( $major_current ) = explode( '.', NFW_ENGINE_VERSION );
 
410
  list ( $major_import ) = explode( '.', $nfw_options['engine_version'] );
411
+ if ( $major_current != $major_import ) {
412
+ return esc_html__('The imported file is not compatible with that version of NinjaFirewall', 'ninjafirewall');
413
+ }
 
414
  if ( $major_import < '4' ) {
415
  if ( empty( $nfw_options['allow_local_ip'] ) ) {
416
  $nfw_options['allow_local_ip'] = 1;
lib/firewall_policies.php CHANGED
@@ -841,9 +841,8 @@ wp_nonce_field('policies_save', 'nfwnonce', 0);
841
  <p class="description"><?php _e('Setting this option to <code>DENY</code> may break some functionality on your blog, its themes or plugins.', 'ninjafirewall') ?></p>
842
  </td>
843
  </tr>
844
-
845
  <tr>
846
- <th scope="row" class="row-med"><?php printf( __("Set %s (IE/Edge, Chrome, Opera and Safari browsers)", 'ninjafirewall'), '<a href="https://blog.nintechnet.com/securing-wordpress-with-a-web-application-firewall-ninjafirewall/#advanced-policies" target="_blank" rel="noreferrer noopener">X-XSS-Protection</a>') ?></th>
847
  <td>
848
  <select name="nfw_options[x_xss_protection]" <?php disabled( $err, 1 ) ?>>
849
  <option value="3"<?php selected( $nfw_options['response_headers'][3], 3 ) ?>><?php echo $no; ?></option>
@@ -851,6 +850,7 @@ wp_nonce_field('policies_save', 'nfwnonce', 0);
851
  <option value="2"<?php selected( $nfw_options['response_headers'][3], 2 ) ?>><?php printf( __('Set to %s', 'ninjafirewall'), '"1"'); ?></option>
852
  <option value="1"<?php selected( $nfw_options['response_headers'][3], 1 ) ?>><?php printf( __('Set to %s', 'ninjafirewall'), '"1; mode=block"') ?></option>
853
  </select>
 
854
  </td>
855
  </tr>
856
  <tr>
@@ -1423,7 +1423,7 @@ function nf_sub_policies_save() {
1423
  $tmp .= '/wp-admin/(?:css|images|includes|js)/|';
1424
  }
1425
  if ( isset( $_POST['nfw_options']['wp_inc']) ) {
1426
- $tmp .= '/wp-includes/(?:(?:css|images|js(?!/tinymce/wp-tinymce\.php)|theme-compat)/|[^/]+\.php)|';
1427
  }
1428
  if ( isset( $_POST['nfw_options']['wp_upl']) ) {
1429
  $tmp .= '/' . basename(WP_CONTENT_DIR) .'/(?:uploads|blogs\.dir)/|';
@@ -1685,7 +1685,7 @@ function nf_sub_policies_default() {
1685
  $nfw_options['php_path_t'] = 1;
1686
  $nfw_options['php_path_i'] = 1;
1687
  $nfw_options['wp_dir'] = '/wp-admin/(?:css|images|includes|js)/|' .
1688
- '/wp-includes/(?:(?:css|images|js(?!/tinymce/wp-tinymce\.php)|theme-compat)/|[^/]+\.php)|' .
1689
  '/'. basename(WP_CONTENT_DIR) .'/(?:uploads|blogs\.dir)/';
1690
  $nfw_options['disallow_creation']= 0;
1691
  $nfw_options['disallow_settings']= 1;
841
  <p class="description"><?php _e('Setting this option to <code>DENY</code> may break some functionality on your blog, its themes or plugins.', 'ninjafirewall') ?></p>
842
  </td>
843
  </tr>
 
844
  <tr>
845
+ <th scope="row" class="row-med"><?php printf( __('Set %s', 'ninjafirewall'), '<a href="https://blog.nintechnet.com/securing-wordpress-with-a-web-application-firewall-ninjafirewall/#advanced-policies" target="_blank" rel="noreferrer noopener">X-XSS-Protection</a>') ?></th>
846
  <td>
847
  <select name="nfw_options[x_xss_protection]" <?php disabled( $err, 1 ) ?>>
848
  <option value="3"<?php selected( $nfw_options['response_headers'][3], 3 ) ?>><?php echo $no; ?></option>
850
  <option value="2"<?php selected( $nfw_options['response_headers'][3], 2 ) ?>><?php printf( __('Set to %s', 'ninjafirewall'), '"1"'); ?></option>
851
  <option value="1"<?php selected( $nfw_options['response_headers'][3], 1 ) ?>><?php printf( __('Set to %s', 'ninjafirewall'), '"1; mode=block"') ?></option>
852
  </select>
853
+ <p class="description"><span class="dashicons dashicons-warning nfw-warning"></span> <?php esc_html_e('This header is deprecated and most browsers phased out support for it. Consider using Content-Security-Policy instead.', 'ninjafirewall') ?></p>
854
  </td>
855
  </tr>
856
  <tr>
1423
  $tmp .= '/wp-admin/(?:css|images|includes|js)/|';
1424
  }
1425
  if ( isset( $_POST['nfw_options']['wp_inc']) ) {
1426
+ $tmp .= '/wp-includes/(?!ms-files\.php)(?:(?:css|images|js(?!/tinymce/wp-tinymce\.php)|theme-compat)/|[^/]+\.php)|';
1427
  }
1428
  if ( isset( $_POST['nfw_options']['wp_upl']) ) {
1429
  $tmp .= '/' . basename(WP_CONTENT_DIR) .'/(?:uploads|blogs\.dir)/|';
1685
  $nfw_options['php_path_t'] = 1;
1686
  $nfw_options['php_path_i'] = 1;
1687
  $nfw_options['wp_dir'] = '/wp-admin/(?:css|images|includes|js)/|' .
1688
+ '/wp-includes/(?!ms-files\.php)(?:(?:css|images|js(?!/tinymce/wp-tinymce\.php)|theme-compat)/|[^/]+\.php)|' .
1689
  '/'. basename(WP_CONTENT_DIR) .'/(?:uploads|blogs\.dir)/';
1690
  $nfw_options['disallow_creation']= 0;
1691
  $nfw_options['disallow_settings']= 1;
lib/help.php CHANGED
@@ -272,8 +272,8 @@ function help_nfsubpolicies() {
272
  <p>' . __('NinjaFirewall does not support the <code>ALLOW-FROM</code> value.', 'ninjafirewall'). '</p>
273
  <p>' . __('Since v3.1.3, WordPress sets this value to <code>SAMEORIGIN</code> for the administrator and the login page only.', 'ninjafirewall'). '</p>
274
 
275
- <p><strong>' . __('Set <code>X-XSS-Protection</code> (IE/Edge, Chrome, Opera and Safari browsers)', 'ninjafirewall'). '</strong><br />' . __('This header allows browsers to identify and block XSS attacks by preventing malicious scripts from executing. It is enabled by default on all compatible browsers.', 'ninjafirewall'). '</p>'.
276
- '<p><span class="dashicons dashicons-warning nfw-warning"></span>&nbsp;' . __("If a visitor disabled their browser's XSS filter, you cannot re-enable it with that option.", 'ninjafirewall'). '</p>'.
277
 
278
  '<p><strong>' . __('Force <code>SameSite</code> flag on all cookies to mitigate CSRF attacks', 'ninjafirewall'). '</strong><br />' . __('Adding this flag to cookies helps to mitigate the risk of CSRF (cross-site request forgery) attacks because cookies can only be sent in requests originating from the same origin as the target domain.', 'ninjafirewall'). '</p>'.
279
 
272
  <p>' . __('NinjaFirewall does not support the <code>ALLOW-FROM</code> value.', 'ninjafirewall'). '</p>
273
  <p>' . __('Since v3.1.3, WordPress sets this value to <code>SAMEORIGIN</code> for the administrator and the login page only.', 'ninjafirewall'). '</p>
274
 
275
+ <p><strong>' . __('Set <code>X-XSS-Protection</code>', 'ninjafirewall'). '</strong><br />' . __('This header allows browsers to identify and block XSS attacks by preventing malicious scripts from executing. It is enabled by default on all compatible browsers.', 'ninjafirewall'). '</p>'.
276
+ '<p><span class="dashicons dashicons-warning nfw-warning"></span>&nbsp;' . __('This header is deprecated and most browsers phased out support for it. Consider using Content-Security-Policy instead.', 'ninjafirewall'). '</p>'.
277
 
278
  '<p><strong>' . __('Force <code>SameSite</code> flag on all cookies to mitigate CSRF attacks', 'ninjafirewall'). '</strong><br />' . __('Adding this flag to cookies helps to mitigate the risk of CSRF (cross-site request forgery) attacks because cookies can only be sent in requests originating from the same origin as the target domain.', 'ninjafirewall'). '</p>'.
279
 
lib/i18n-extra.php CHANGED
@@ -48,7 +48,7 @@ __('Logging is disabled.', 'ninjafirewall');
48
  __('Click here to re-enable it.', 'ninjafirewall');
49
  __('Error cannot create the language files directory (%s)', 'ninjafirewall');
50
  __('Error while downloading language file %s (%s)', 'ninjafirewall');
51
- __('You are running NinjaFirewall in <i>WordPress WAF</i> mode. All URL-based features such as <i>Geolocation</i> and <i>URL Access Control</i> will be limited to WordPress files only (e.g., index.php, wp-login.php, xmlrpc.php, admin-ajax.php, wp-load.php etc). If you want them to apply to any PHP script, please <a href="%s">go to the Dashboard page</a> and enable NinjaFirewall\'s Full WAF mode.', 'ninjafirewall');
52
  __('General', 'ninjafirewall');
53
  __('Geolocation', 'ninjafirewall');
54
  __('IP address', 'ninjafirewall');
@@ -62,12 +62,6 @@ __('Other', 'ninjafirewall');
62
  __('Your server does not seem to support the %s variable.', 'ninjafirewall');
63
  __('HTTP Methods', 'ninjafirewall');
64
  __('All Access Control directives should apply to the folowing HTTP methods', 'ninjafirewall');
65
- __('<code>GET</code>', 'ninjafirewall');
66
- __('<code>POST</code>', 'ninjafirewall');
67
- __('<code>HEAD</code>', 'ninjafirewall');
68
- __('<code>PUT</code>', 'ninjafirewall');
69
- __('<code>DELETE</code>', 'ninjafirewall');
70
- __('<code>PATCH</code>', 'ninjafirewall');
71
  __('Enable Geolocation', 'ninjafirewall');
72
  __('Retrieve the ISO 3166 code from', 'ninjafirewall');
73
  __('PHP Variable', 'ninjafirewall');
@@ -78,7 +72,7 @@ __('View allowed syntax', 'ninjafirewall');
78
  __('Full or partial case-sensitive URL (e.g., %s).', 'ninjafirewall');
79
  __('One item per line.', 'ninjafirewall');
80
  __('Leave this field empty if you want geolocation to apply to all your PHP scripts.', 'ninjafirewall');
81
- __('Add <code>NINJA_COUNTRY_CODE</code> to PHP headers?', 'ninjafirewall');
82
  __('Write event to the firewall log', 'ninjafirewall');
83
  __('Allow the following IP, CIDR or AS number', 'ninjafirewall');
84
  __('IPv4 address: %s', 'ninjafirewall');
@@ -104,12 +98,12 @@ __('Full or partial case-sensitive URLs (e.g., %s).', 'ninjafirewall');
104
  __('Block access to the following URL', 'ninjafirewall');
105
  __('Reject the following bots', 'ninjafirewall');
106
  __('A full or partial case-insensitive string.', 'ninjafirewall');
107
- __('Allowed characters are: <code>a-zA-Z</code> <code>0-9</code> <code>.</code> <code>-</code> <code>_</code> <code>:</code> <code>/</code> and <code>space</code>.', 'ninjafirewall');
108
  __('Blocked bots:', 'ninjafirewall');
109
  __('The default list of bots will be restored. Continue?', 'ninjafirewall');
110
  __('Restore default bots list', 'ninjafirewall');
111
  __('Do not filter the following user input', 'ninjafirewall');
112
- __('A <code>GET</code>, <code>POST</code> or <code>COOKIE</code> global variable, followed by <code>:</code> (colon) and the case-sensitive input:', 'ninjafirewall');
113
  __('Unfiltered input:', 'ninjafirewall');
114
  __('Block the request if the following input is present', 'ninjafirewall');
115
  __('Blocked input:', 'ninjafirewall');
@@ -129,6 +123,8 @@ __('Your changes have been saved. If you are using a caching plugin, do not forg
129
  __('Enable antispam protection', 'ninjafirewall');
130
  __('Protection level', 'ninjafirewall');
131
  __('Low (default)', 'ninjafirewall');
 
 
132
  __('If you are using a caching plugin, consult the contextual help before enabling the antispam.', 'ninjafirewall');
133
  __('Apply protection to', 'ninjafirewall');
134
  __('Comment forms (defaut)', 'ninjafirewall');
@@ -184,6 +180,7 @@ __('You can filter and block traffic coming from specific countries/territories.
184
  __('This is the two-letter code that is used to define a country/territory (e.g., US, UK, FR, DE etc), based on the visitors IP. NinjaFirewall can either retrieve it from its database, or from a predefined PHP variable added by your HTTP server (e.g., <code>GEOIP_COUNTRY_CODE</code>).', 'ninjafirewall');
185
  __('You can add/remove any country/territory from the two listboxes. For more information about some specific ISO 3166 codes (A1, A2, AP, EU etc), you may want to consult <a href="%s">the MaxMind GeoIP online help</a>.', 'ninjafirewall');
186
  __('Whether geolocation should apply to the whole site or to specific URLs only (e.g., /wp-login.php, /xmlrpc.php etc). Leave all fields empty if you want it to apply to the whole site.', 'ninjafirewall');
 
187
  __('After retrieving the two-letter country/territory code, NinjaFirewall can add it to the PHP headers in the <code>$_SERVER["NINJA_COUNTRY_CODE"]</code> variable. If you have a theme or a plugin that needs to know your visitors location, simply use that variable.', 'ninjafirewall');
188
  __('If NinjaFirewall cannot find the two-letter ISO 3166 code, it will replace it with 2 hyphens (<code>--</code>).', 'ninjafirewall');
189
  __('PHP code example to use in your theme or plugin to geolocate your visitors:', 'ninjafirewall');
@@ -271,6 +268,7 @@ __('Export', 'ninjafirewall');
271
  __('Delete', 'ninjafirewall');
272
  __('Delete log?', 'ninjafirewall');
273
  __('Today', 'ninjafirewall');
 
274
  __('Upload', 'ninjafirewall');
275
  __('Info', 'ninjafirewall');
276
  __('Debug', 'ninjafirewall');
48
  __('Click here to re-enable it.', 'ninjafirewall');
49
  __('Error cannot create the language files directory (%s)', 'ninjafirewall');
50
  __('Error while downloading language file %s (%s)', 'ninjafirewall');
51
+ __('You are running NinjaFirewall in WordPress WAF mode. All URL-based features such as Geolocation and URL Access Control will be limited to WordPress files only (e.g., index.php, wp-login.php, xmlrpc.php, admin-ajax.php, wp-load.php etc). If you want them to apply to any PHP script, please %sgo to the Dashboard page%s and enable NinjaFirewall\'s Full WAF mode.', 'ninjafirewall');
52
  __('General', 'ninjafirewall');
53
  __('Geolocation', 'ninjafirewall');
54
  __('IP address', 'ninjafirewall');
62
  __('Your server does not seem to support the %s variable.', 'ninjafirewall');
63
  __('HTTP Methods', 'ninjafirewall');
64
  __('All Access Control directives should apply to the folowing HTTP methods', 'ninjafirewall');
 
 
 
 
 
 
65
  __('Enable Geolocation', 'ninjafirewall');
66
  __('Retrieve the ISO 3166 code from', 'ninjafirewall');
67
  __('PHP Variable', 'ninjafirewall');
72
  __('Full or partial case-sensitive URL (e.g., %s).', 'ninjafirewall');
73
  __('One item per line.', 'ninjafirewall');
74
  __('Leave this field empty if you want geolocation to apply to all your PHP scripts.', 'ninjafirewall');
75
+ __('Add NINJA_COUNTRY_CODE to PHP headers?', 'ninjafirewall');
76
  __('Write event to the firewall log', 'ninjafirewall');
77
  __('Allow the following IP, CIDR or AS number', 'ninjafirewall');
78
  __('IPv4 address: %s', 'ninjafirewall');
98
  __('Block access to the following URL', 'ninjafirewall');
99
  __('Reject the following bots', 'ninjafirewall');
100
  __('A full or partial case-insensitive string.', 'ninjafirewall');
101
+ __('Allowed characters are: %s and %s.', 'ninjafirewall');
102
  __('Blocked bots:', 'ninjafirewall');
103
  __('The default list of bots will be restored. Continue?', 'ninjafirewall');
104
  __('Restore default bots list', 'ninjafirewall');
105
  __('Do not filter the following user input', 'ninjafirewall');
106
+ __('A GET, POST or COOKIE global variable, followed by a colon (:) and the case-sensitive input:', 'ninjafirewall');
107
  __('Unfiltered input:', 'ninjafirewall');
108
  __('Block the request if the following input is present', 'ninjafirewall');
109
  __('Blocked input:', 'ninjafirewall');
123
  __('Enable antispam protection', 'ninjafirewall');
124
  __('Protection level', 'ninjafirewall');
125
  __('Low (default)', 'ninjafirewall');
126
+ __('Medium', 'ninjafirewall');
127
+ __('High', 'ninjafirewall');
128
  __('If you are using a caching plugin, consult the contextual help before enabling the antispam.', 'ninjafirewall');
129
  __('Apply protection to', 'ninjafirewall');
130
  __('Comment forms (defaut)', 'ninjafirewall');
180
  __('This is the two-letter code that is used to define a country/territory (e.g., US, UK, FR, DE etc), based on the visitors IP. NinjaFirewall can either retrieve it from its database, or from a predefined PHP variable added by your HTTP server (e.g., <code>GEOIP_COUNTRY_CODE</code>).', 'ninjafirewall');
181
  __('You can add/remove any country/territory from the two listboxes. For more information about some specific ISO 3166 codes (A1, A2, AP, EU etc), you may want to consult <a href="%s">the MaxMind GeoIP online help</a>.', 'ninjafirewall');
182
  __('Whether geolocation should apply to the whole site or to specific URLs only (e.g., /wp-login.php, /xmlrpc.php etc). Leave all fields empty if you want it to apply to the whole site.', 'ninjafirewall');
183
+ __('Add <code>NINJA_COUNTRY_CODE</code> to PHP headers?', 'ninjafirewall');
184
  __('After retrieving the two-letter country/territory code, NinjaFirewall can add it to the PHP headers in the <code>$_SERVER["NINJA_COUNTRY_CODE"]</code> variable. If you have a theme or a plugin that needs to know your visitors location, simply use that variable.', 'ninjafirewall');
185
  __('If NinjaFirewall cannot find the two-letter ISO 3166 code, it will replace it with 2 hyphens (<code>--</code>).', 'ninjafirewall');
186
  __('PHP code example to use in your theme or plugin to geolocate your visitors:', 'ninjafirewall');
268
  __('Delete', 'ninjafirewall');
269
  __('Delete log?', 'ninjafirewall');
270
  __('Today', 'ninjafirewall');
271
+ __('Critical', 'ninjafirewall');
272
  __('Upload', 'ninjafirewall');
273
  __('Info', 'ninjafirewall');
274
  __('Debug', 'ninjafirewall');
lib/install.php CHANGED
@@ -145,8 +145,19 @@ function nfw_waf_sandbox() {
145
  $sandbox_error = __('NinjaFirewall detected that the requested changes seemed to crash your blog. %s', 'ninjafirewall') ."\n".
146
  __('Changes have been undone. You may need to modify your selection and try again.', 'ninjafirewall' );
147
  $headers['Cache-Control'] = 'no-cache';
 
148
  $url = home_url( '/' ) .'?'. time();
149
- $res = wp_remote_get( $url );
 
 
 
 
 
 
 
 
 
 
150
  $blogname = get_option( 'blogname' );
151
  if (! is_wp_error( $res ) ) {
152
  // Look for HTTP error
145
  $sandbox_error = __('NinjaFirewall detected that the requested changes seemed to crash your blog. %s', 'ninjafirewall') ."\n".
146
  __('Changes have been undone. You may need to modify your selection and try again.', 'ninjafirewall' );
147
  $headers['Cache-Control'] = 'no-cache';
148
+
149
  $url = home_url( '/' ) .'?'. time();
150
+ global $wp_version;
151
+ $opts = array(
152
+ 'timeout' => 20,
153
+ 'httpversion' => '1.1' ,
154
+ 'user-agent' => 'Mozilla/5.0 (compatible; NinjaFirewall/'.
155
+ NFW_ENGINE_VERSION .'; WordPress/'. $wp_version . ')',
156
+ // We don't want a fatal error if we're running on localhost e.g., dev site etc
157
+ 'sslverify' => apply_filters( 'https_local_ssl_verify', false )
158
+ );
159
+ $res = wp_remote_get( $url, $opts );
160
+
161
  $blogname = get_option( 'blogname' );
162
  if (! is_wp_error( $res ) ) {
163
  // Look for HTTP error
lib/install_default.php CHANGED
@@ -14,7 +14,7 @@
14
  | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15
  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16
  | GNU General Public License for more details. |
17
- +---------------------------------------------------------------------+ i18n+ / sa
18
  */
19
 
20
  if (! defined( 'NFW_ENGINE_VERSION' ) ) { die( 'Forbidden' ); }
@@ -78,7 +78,7 @@ function nfw_load_default_conf() {
78
  'php_path_t' => 1,
79
  'php_path_i' => 1,
80
  'wp_dir' => '/wp-admin/(?:css|images|includes|js)/|' .
81
- '/wp-includes/(?:(?:css|images|js(?!/tinymce/wp-tinymce\.php)|theme-compat)/|[^/]+\.php)|' .
82
  '/'. basename(WP_CONTENT_DIR) .'/(?:uploads|blogs\.dir)/',
83
  'no_post_themes' => 0,
84
  'force_ssl' => 0,
@@ -179,9 +179,9 @@ function nfw_load_default_conf() {
179
  @nf_sub_updates();
180
 
181
  if (! $nfw_rules = @unserialize(NFW_RULES) ) {
182
- $err_msg = __('Error: The installer cannot download the security rules from wordpress.org website.', 'ninjafirewall');
183
- $err_msg.= '<ol><li>'. __('The server may be temporarily down or you may have network connectivity problems? Please try again in a few minutes.', 'ninjafirewall') . '</li>';
184
- $err_msg.= '<li>'. __('NinjaFirewall downloads its rules over an HTTPS secure connection. Maybe your server does not support SSL? You can force NinjaFirewall to use a non-secure HTTP connection by adding the following directive to your <strong>wp-config.php</strong> file:', 'ninjafirewall') . '<p><code>define("NFW_DONT_USE_SSL", 1);</code></p></li></ol>';
185
  exit( '<font style="font-size:14px;">'. $err_msg .'</font>' );
186
  }
187
 
@@ -256,7 +256,7 @@ function nfw_create_log_dir() {
256
  </Files>";
257
 
258
  if (! is_writable(NFW_LOG_DIR) ) {
259
- $err_msg = sprintf( __('NinjaFirewall cannot create its <code>nfwlog/</code>log and cache folder; please make sure that the <code>%s</code> directory is writable', 'ninjafirewall'), htmlspecialchars( NFW_LOG_DIR ) );
260
  exit( '<font style="font-size:14px;">'. $err_msg .'</font>' );
261
  }
262
 
@@ -276,20 +276,53 @@ function nfw_create_log_dir() {
276
  "This is NinjaFirewall's logs, loader and cache directory. DO NOT alter or remove it as long as NinjaFirewall is running!\n\nIf you just uninstalled NinjaFirewall, WAIT 5 MINUTES before deleting this folder, otherwise your site will likely crash.",
277
  LOCK_EX
278
  );
 
 
 
 
 
 
 
279
 
280
- // Firewall loader:
 
 
281
  $loader = "<?php
282
  // ===============================================================//
283
  // NinjaFirewall's loader. //
284
- // DO NOT alter or remove it as long as NinjaFirewall is running! //
285
- // ===============================================================//
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
286
  if ( file_exists('". __DIR__ .'/firewall.php' . "') ) {
287
  @include_once '". __DIR__ .'/firewall.php' . "';
288
  }
289
  // EOF
290
  ";
291
  file_put_contents( NFW_LOG_DIR .'/nfwlog/ninjafirewall.php', $loader, LOCK_EX );
292
-
293
  return;
294
 
295
  }
14
  | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15
  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16
  | GNU General Public License for more details. |
17
+ +---------------------------------------------------------------------+ i18n++ / sa
18
  */
19
 
20
  if (! defined( 'NFW_ENGINE_VERSION' ) ) { die( 'Forbidden' ); }
78
  'php_path_t' => 1,
79
  'php_path_i' => 1,
80
  'wp_dir' => '/wp-admin/(?:css|images|includes|js)/|' .
81
+ '/wp-includes/(?!ms-files\.php)(?:(?:css|images|js(?!/tinymce/wp-tinymce\.php)|theme-compat)/|[^/]+\.php)|' .
82
  '/'. basename(WP_CONTENT_DIR) .'/(?:uploads|blogs\.dir)/',
83
  'no_post_themes' => 0,
84
  'force_ssl' => 0,
179
  @nf_sub_updates();
180
 
181
  if (! $nfw_rules = @unserialize(NFW_RULES) ) {
182
+ $err_msg = esc_html__('Error: The installer cannot download the security rules from wordpress.org website.', 'ninjafirewall');
183
+ $err_msg.= '<ol><li>'. esc_html__('The server may be temporarily down or you may have network connectivity problems? Please try again in a few minutes.', 'ninjafirewall') . '</li>';
184
+ $err_msg.= '<li>'. esc_html__('NinjaFirewall downloads its rules over an HTTPS secure connection. Maybe your server does not support SSL? You can force NinjaFirewall to use a non-secure HTTP connection by adding the following directive to your <strong>wp-config.php</strong> file:', 'ninjafirewall') . ' <p><code>define("NFW_DONT_USE_SSL", 1);</code></p></li></ol>';
185
  exit( '<font style="font-size:14px;">'. $err_msg .'</font>' );
186
  }
187
 
256
  </Files>";
257
 
258
  if (! is_writable(NFW_LOG_DIR) ) {
259
+ $err_msg = sprintf( esc_html__('NinjaFirewall cannot create its <code>nfwlog/</code>log and cache folder; please make sure that the <code>%s</code> directory is writable', 'ninjafirewall'), htmlspecialchars( NFW_LOG_DIR ) );
260
  exit( '<font style="font-size:14px;">'. $err_msg .'</font>' );
261
  }
262
 
276
  "This is NinjaFirewall's logs, loader and cache directory. DO NOT alter or remove it as long as NinjaFirewall is running!\n\nIf you just uninstalled NinjaFirewall, WAIT 5 MINUTES before deleting this folder, otherwise your site will likely crash.",
277
  LOCK_EX
278
  );
279
+ nfw_create_loader();
280
+ }
281
+
282
+ // ---------------------------------------------------------------------
283
+ // Create NF's loader.
284
+
285
+ function nfw_create_loader() {
286
 
287
+ $nfw_options = nfw_get_option( 'nfw_options' );
288
+
289
+ // Firewall loader
290
  $loader = "<?php
291
  // ===============================================================//
292
  // NinjaFirewall's loader. //
293
+ // DO NOT alter or remove it as long as NinjaFirewall is running. //
294
+ // If this file is corrupted or wrong, you can re-generate it //
295
+ // by deactivating and reactivating NinjaFirewall from your //
296
+ // WordPress dashboard. //
297
+ // ===============================================================//";
298
+
299
+ if (! empty( $nfw_options['exclude_waf_list'] ) ) {
300
+ $string = '';
301
+ $exclude_waf_list = json_decode( $nfw_options['exclude_waf_list'] );
302
+ foreach( $exclude_waf_list as $folder ) {
303
+ if ( is_dir( ABSPATH . $folder ) ) {
304
+ $string .= "'$folder',";
305
+ }
306
+ }
307
+ $string = rtrim( $string, ',' );
308
+ if (! empty( $string ) ) {
309
+ $loader .= "
310
+ \$nfw_exclude_waf_list = array($string);
311
+ foreach( \$nfw_exclude_waf_list as \$nfw_exclude_waf_folder ) {
312
+ if (strpos(\$_SERVER['SCRIPT_FILENAME'], \"". ABSPATH ."\$nfw_exclude_waf_folder/\") === 0) {
313
+ return;
314
+ }
315
+ }";
316
+ }
317
+ }
318
+
319
+ $loader .= "
320
  if ( file_exists('". __DIR__ .'/firewall.php' . "') ) {
321
  @include_once '". __DIR__ .'/firewall.php' . "';
322
  }
323
  // EOF
324
  ";
325
  file_put_contents( NFW_LOG_DIR .'/nfwlog/ninjafirewall.php', $loader, LOCK_EX );
 
326
  return;
327
 
328
  }
lib/thickbox.php CHANGED
@@ -25,6 +25,9 @@ add_thickbox();
25
 
26
  if ( defined( 'NFW_WPWAF' ) ) {
27
  nfw_upgrade_fullwaf();
 
 
 
28
  }
29
 
30
  if (! empty( $errlog_content ) ) {
@@ -66,18 +69,18 @@ function nfw_upgrade_fullwaf() {
66
  $NFW_ABSPATH = get_home_path();
67
 
68
  ?>
69
- <div id="nfw-thickbox-content" style="display:none;">
70
 
71
  <h2><?php _e('Activate Full WAF mode', 'ninjafirewall') ?></h2>
72
 
73
  <div id="nfwaf-step1">
74
  <p>
75
  <?php
76
- _e('In <strong>Full WAF</strong> mode, all scripts located inside the blog installation directories and sub-directories are protected by NinjaFirewall, including those that aren\'t part of the WordPress package. It gives you the highest possible level of protection: security without compromise.', 'ninjafirewall');
77
  echo '&nbsp;';
78
- printf( __('It works on most websites right out of the box, or may require <a href="%s" title="%s">some very little tweaks</a>. But in a few cases, mostly because of some shared hosting plans restrictions, it may simply not work at all.','ninjafirewall'), 'https://blog.nintechnet.com/troubleshoot-ninjafirewall-installation-problems/', 'Troubleshoot NinjaFirewall installation problems.');
79
  echo '&nbsp;';
80
- _e('If this happened to you, don\'t worry: you could still run it in <strong>WordPress WAF</strong> mode. Despite being less powerful than the <b>Full WAF</b> mode, it offers a level of protection and performance much higher than other security plugins.', 'ninjafirewall');
81
  ?>
82
  </p>
83
  <?php
@@ -158,7 +161,7 @@ function nfw_upgrade_fullwaf() {
158
  <option value="1"<?php selected($http_server, 'apachemod') ?>>Apache + PHP<?php echo PHP_MAJOR_VERSION ?> module<?php echo $s1 ?></option>
159
  <option value="2"<?php selected($http_server, 'apachecgi') ?>>Apache + CGI/FastCGI or PHP-FPM<?php echo $s2 ?></option>
160
  <option value="3"<?php selected($http_server, 'apachesuphp') ?>>Apache + suPHP</option>
161
- <option value="8"<?php selected($http_server, 'apachelsapi') ?>>Apache + LSAPI/Cloudinux<?php echo $s8 ?></option>
162
  <option value="4"<?php selected($http_server, 'nginx') ?>>Nginx + CGI/FastCGI or PHP-FPM<?php echo $s4 ?></option>
163
  <option value="5"<?php selected($http_server, 'litespeed') ?>>Litespeed<?php echo $s5 ?></option>
164
  <option value="6"<?php selected($http_server, 'openlitespeed') ?>>Openlitespeed<?php echo $s6 ?></option>
@@ -205,13 +208,33 @@ function nfw_upgrade_fullwaf() {
205
  </table>
206
  </div>
207
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
208
  <br />
209
 
210
  <div class="font-15px" id="diy-div"<?php echo $diy_div_style ?>>
211
  <p><label><input onClick="nfwjs_diy_chg(this.value)" id="diynfw" type="radio" name="diy-choice" value="nfw" checked /> <?php _e('Let NinjaFirewall make the necessary changes (recommended).', 'ninjafirewall') ?></label>
212
  <br />
213
  <label><input onClick="nfwjs_diy_chg(this.value)" type="radio" name="diy-choice" value="usr" /> <?php _e('I want to make the changes myself.', 'ninjafirewall') ?></label></p>
214
- <div id="diy-msg" style="display:none;background:#f1f1f1;border-left:4px solid #fff;-webkit-box-shadow:0 1px 1px 0 rgba(0,0,0,.1);box-shadow:0 1px 1px 0 rgba(0,0,0,.1);margin:5px 0 15px;padding:1px 12px;border-left-color:orange;">
215
  <p><?php _e('Please make the changes below, then click on the "Finish Installation" button.', 'ninjafirewall') ?></p>
216
  </div>
217
  </div>
@@ -288,12 +311,12 @@ function nfw_upgrade_fullwaf() {
288
  <tr id="tr-htaccess-openlitespeed"<?php echo $tr_htaccess_openlitespeed ?>>
289
  <td>
290
  <?php
291
- printf( __('Log in to your Openlitespeed admin dashboard, click on "Virtual Host", select your domain, add the following instructions to the "php.ini Override" section in the "General" tab, and restart Openlitespeed (see more detail <a %s>here</a>):', 'ninjafirewall' ), 'target="_blank" href="https://openlitespeed.org/mediawiki/index.php/Overriding_php.ini_Values"');
292
  ?>
293
  <br /><textarea name="txtlog" class="large-text code" rows="4" style="color:green;font-size:13px" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" wrap="off"><?php echo NFW_OPENLITESPEED_DATA ."\n"; ?></textarea>
294
  <br />
295
  <br />
296
- <div style="background:#f1f1f1;border-left:4px solid #fff;-webkit-box-shadow:0 1px 1px 0 rgba(0,0,0,.1);box-shadow:0 1px 1px 0 rgba(0,0,0,.1);margin:5px 0 15px;padding:1px 12px;border-left-color:orange;">
297
  <br>
298
  <?php _e('Important: if one day you wanted to uninstall NinjaFirewall, do not forget to remove these instructions from your Openlitespeed admin dashboard <strong>before</strong> uninstalling NinjaFirewall because this installer could not do it for you.', 'ninjafirewall') ?>
299
  <br>&nbsp;
@@ -311,7 +334,7 @@ function nfw_upgrade_fullwaf() {
311
  </table>
312
  </div>
313
  <div>
314
- <p id="enable-sandbox"><label><input type="checkbox" checked="checked" name="enable_sandbox" /> <?php _e('Enable the sandbox.', 'ninjafirewall'); ?></label><br /><i class="description"><?php _e('If there were a problem during the installation, NinjaFirewall would undo those changes automatically for you.', 'ninjafirewall') ?></i></p>
315
  <input id="btn-waf-next" type="button" class="button-primary" name="step" value="<?php _e('Finish Installation', 'ninjafirewall') ?> &#187;" onclick="nfwjs_fullwafsubmit()" />
316
  <?php wp_nonce_field('events_save', 'nfwnonce_fullwaf', 0); ?>
317
  </div>
@@ -322,5 +345,102 @@ function nfw_upgrade_fullwaf() {
322
  <?php
323
  }
324
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
325
  // ---------------------------------------------------------------------
326
  // EOF
25
 
26
  if ( defined( 'NFW_WPWAF' ) ) {
27
  nfw_upgrade_fullwaf();
28
+
29
+ } else {
30
+ nfw_configure_fullwaf();
31
  }
32
 
33
  if (! empty( $errlog_content ) ) {
69
  $NFW_ABSPATH = get_home_path();
70
 
71
  ?>
72
+ <div id="nfw-activate-thickbox-content" style="display:none">
73
 
74
  <h2><?php _e('Activate Full WAF mode', 'ninjafirewall') ?></h2>
75
 
76
  <div id="nfwaf-step1">
77
  <p>
78
  <?php
79
+ esc_html_e('In Full WAF mode, all scripts located inside the blog installation directories and sub-directories are protected by NinjaFirewall. It gives you the highest possible level of protection: security without compromise.', 'ninjafirewall');
80
  echo '&nbsp;';
81
+ printf( esc_html__('It works on most websites right out of the box, or may require %ssome very little tweaks%s. But in a few cases, mostly because of some shared hosting plans restrictions, it may simply not work at all.','ninjafirewall'), '<a href="https://blog.nintechnet.com/troubleshoot-ninjafirewall-installation-problems/" title="Troubleshoot NinjaFirewall installation problems." target="_blank">', '</a>');
82
  echo '&nbsp;';
83
+ esc_html_e('If this happened to you, don\'t worry: you could still run it in WordPress WAF mode. Despite being less powerful than the Full WAF mode, it offers a level of protection and performance much higher than other security plugins.', 'ninjafirewall');
84
  ?>
85
  </p>
86
  <?php
161
  <option value="1"<?php selected($http_server, 'apachemod') ?>>Apache + PHP<?php echo PHP_MAJOR_VERSION ?> module<?php echo $s1 ?></option>
162
  <option value="2"<?php selected($http_server, 'apachecgi') ?>>Apache + CGI/FastCGI or PHP-FPM<?php echo $s2 ?></option>
163
  <option value="3"<?php selected($http_server, 'apachesuphp') ?>>Apache + suPHP</option>
164
+ <option value="8"<?php selected($http_server, 'apachelsapi') ?>>Apache + LSAPI/Cloudlinux<?php echo $s8 ?></option>
165
  <option value="4"<?php selected($http_server, 'nginx') ?>>Nginx + CGI/FastCGI or PHP-FPM<?php echo $s4 ?></option>
166
  <option value="5"<?php selected($http_server, 'litespeed') ?>>Litespeed<?php echo $s5 ?></option>
167
  <option value="6"<?php selected($http_server, 'openlitespeed') ?>>Openlitespeed<?php echo $s6 ?></option>
208
  </table>
209
  </div>
210
 
211
+ <table class="form-table nfw-table">
212
+ <tr>
213
+ <th scope="row" class="row-med"><?php esc_html_e('Folders protected by NinjaFirewall', 'ninjafirewall') ?></th>
214
+ <td>
215
+ <?php esc_html_e('WordPress root directory:', 'ninjafirewall') ?> <code><?php echo htmlentities( ABSPATH ) ?></code>
216
+ <?php
217
+ $list = nfw_display_directories();
218
+ ?>
219
+ <br />
220
+ <p><?php esc_html_e('The following folders will be protected by NinjaFirewall. If you want to exclude some of them, uncheck them in the list below:', 'ninjafirewall') ?></p>
221
+ <div class="nfw-sub">
222
+ <table class="form-table" style="margin-top:0">
223
+ <?php echo $list ?>
224
+ </table>
225
+ </div>
226
+ <span class="description" style="color:#646970;"><?php esc_html_e('After setting up the Full WAF mode, you could come back to this page to re-configure it whenever you want.', 'ninjafirewall') ?></span>
227
+ </td>
228
+ </tr>
229
+ </table>
230
+
231
  <br />
232
 
233
  <div class="font-15px" id="diy-div"<?php echo $diy_div_style ?>>
234
  <p><label><input onClick="nfwjs_diy_chg(this.value)" id="diynfw" type="radio" name="diy-choice" value="nfw" checked /> <?php _e('Let NinjaFirewall make the necessary changes (recommended).', 'ninjafirewall') ?></label>
235
  <br />
236
  <label><input onClick="nfwjs_diy_chg(this.value)" type="radio" name="diy-choice" value="usr" /> <?php _e('I want to make the changes myself.', 'ninjafirewall') ?></label></p>
237
+ <div id="diy-msg" style="display:none;background:#FFFFFF;border-left:4px solid #fff;-webkit-box-shadow:0 1px 1px 0 rgba(0,0,0,.1);box-shadow:0 1px 1px 0 rgba(0,0,0,.1);margin:5px 0 15px;padding:1px 12px;border-left-color:orange;">
238
  <p><?php _e('Please make the changes below, then click on the "Finish Installation" button.', 'ninjafirewall') ?></p>
239
  </div>
240
  </div>
311
  <tr id="tr-htaccess-openlitespeed"<?php echo $tr_htaccess_openlitespeed ?>>
312
  <td>
313
  <?php
314
+ esc_html_e('Log in to your Openlitespeed admin dashboard, click on "Virtual Host", select your domain, add the following instructions to the "php.ini Override" section in the "General" tab, and restart Openlitespeed:', 'ninjafirewall' );
315
  ?>
316
  <br /><textarea name="txtlog" class="large-text code" rows="4" style="color:green;font-size:13px" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" wrap="off"><?php echo NFW_OPENLITESPEED_DATA ."\n"; ?></textarea>
317
  <br />
318
  <br />
319
+ <div style="background:#FFFFFF;border-left:4px solid #fff;-webkit-box-shadow:0 1px 1px 0 rgba(0,0,0,.1);box-shadow:0 1px 1px 0 rgba(0,0,0,.1);margin:5px 0 15px;padding:1px 12px;border-left-color:orange;">
320
  <br>
321
  <?php _e('Important: if one day you wanted to uninstall NinjaFirewall, do not forget to remove these instructions from your Openlitespeed admin dashboard <strong>before</strong> uninstalling NinjaFirewall because this installer could not do it for you.', 'ninjafirewall') ?>
322
  <br>&nbsp;
334
  </table>
335
  </div>
336
  <div>
337
+ <p id="enable-sandbox"><label><input type="checkbox" checked="checked" name="enable_sandbox" /> <?php _e('Enable the sandbox.', 'ninjafirewall'); ?></label><br /><span class="description" style="color: #646970;"><?php _e('If there were a problem during the installation, NinjaFirewall would undo those changes automatically for you.', 'ninjafirewall') ?></span></p>
338
  <input id="btn-waf-next" type="button" class="button-primary" name="step" value="<?php _e('Finish Installation', 'ninjafirewall') ?> &#187;" onclick="nfwjs_fullwafsubmit()" />
339
  <?php wp_nonce_field('events_save', 'nfwnonce_fullwaf', 0); ?>
340
  </div>
345
  <?php
346
  }
347
 
348
+ // ---------------------------------------------------------------------
349
+ // Configure Full WAF mode or downgrade to WP WAF mode.
350
+
351
+ function nfw_configure_fullwaf() {
352
+
353
+ ?>
354
+ <div id="nfw-configure-thickbox-content" style="display:none">
355
+
356
+ <h2><?php esc_html_e('Configuration', 'ninjafirewall') ?></h2>
357
+
358
+ <table class="form-table nfw-table">
359
+ <tr>
360
+ <th scope="row" class="row-med"><?php esc_html_e('Full WAF mode', 'ninjafirewall') ?></th>
361
+ <td>
362
+ <?php esc_html_e('WordPress root directory:', 'ninjafirewall') ?> <code><?php echo htmlentities( ABSPATH ) ?></code>
363
+ <?php
364
+ $list = nfw_display_directories();
365
+ ?>
366
+ <br />
367
+ <p><?php esc_html_e('The following folders will be protected by NinjaFirewall. If you want to exclude some of them, uncheck them in the list below:', 'ninjafirewall') ?></p>
368
+ <div class="nfw-sub">
369
+ <table class="form-table" style="margin-top:0">
370
+ <?php echo $list ?>
371
+ </table>
372
+ </div>
373
+ <br />
374
+ <input id="btn-waf-next" type="button" class="button-secondary" name="fullwaf-configure" value="<?php esc_attr_e('Save Changes', 'ninjafirewall') ?>" onclick="nfwjs_fullwafconfig(1)" />
375
+ </td>
376
+ </tr>
377
+ </table>
378
+
379
+ <br />
380
+
381
+ <?php wp_nonce_field('events_save', 'nfwnonce_fullwaf', 0); ?>
382
+
383
+ <table class="form-table nfw-table">
384
+ <tr>
385
+ <th scope="row" class="row-med"><?php esc_html_e('WordPress WAF mode', 'ninjafirewall') ?></th>
386
+ <td>
387
+ <?php
388
+ // Look for OpenLitespeed:
389
+ if ( preg_match( '/litespeed/i', PHP_SAPI ) && isset( $_SERVER['LSWS_EDITION'] ) &&
390
+ stripos( $_SERVER['LSWS_EDITION'], 'Openlitespeed') === 0 ) {
391
+
392
+ esc_html_e('If you want to downgrade to WordPress WAF mode, log in to your Openlitespeed admin dashboard, click on "Virtual Host", select your domain and remove the "auto_prepend_file" directive from the "php.ini Override" section in the "General" tab, and restart Openlitespeed.', 'ninjafirewall' ); ?>
393
+ <p><input type="button" class="button-secondary" value="<?php esc_attr_e('Downgrade to WordPress WAF mode', 'ninjafirewall') ?>" disabled /></p>
394
+ <br />
395
+ <?php
396
+ } else {
397
+ esc_html_e('If you want to downgrade to WordPress WAF mode, click the button below.', 'ninjafirewall') ?>
398
+ <br />
399
+ <br />
400
+ <input id="btn-waf-next" type="button" class="button-secondary" name="fullwaf-downgrade" value="<?php esc_attr_e('Downgrade to WordPress WAF mode', 'ninjafirewall') ?>" onclick="nfwjs_fullwafconfig(2)" />
401
+ <br />
402
+ <span class="description" style="color: #646970;"><?php esc_html_e('You may have to wait five minutes for the changes to take effect.', 'ninjafirewall') ?></span>
403
+ <?php
404
+ }
405
+ ?>
406
+ </td>
407
+ </tr>
408
+ </table>
409
+ <p><input type="button" class="button-secondary" value="<?php esc_attr_e('Cancel and Close', 'ninjafirewall') ?>" onclick="tb_remove();" /></p>
410
+ </div>
411
+
412
+ <?php
413
+ }
414
+
415
+ // ---------------------------------------------------------------------
416
+ // Display directories browser.
417
+
418
+ function nfw_display_directories() {
419
+
420
+ $nfw_options = nfw_get_option( 'nfw_options' );
421
+ $nfw_exclude_waf_list = array();
422
+ if (! empty( $nfw_options['exclude_waf_list'] ) ) {
423
+ $nfw_exclude_waf_list = json_decode( $nfw_options['exclude_waf_list'], true );
424
+ }
425
+ $absfiles = scandir( ABSPATH );
426
+ $list = '';
427
+ $row = 0;
428
+ foreach( $absfiles as $item ) {
429
+ $checked = '';
430
+ if ( $item != '.' && $item != '..' && is_dir( ABSPATH. $item ) ) {
431
+ if (! in_array( $item, $nfw_exclude_waf_list ) ) {
432
+ $checked = ' checked';
433
+ }
434
+ ++$row;
435
+ if ( $row % 2 == 0 ) {
436
+ $r_color = 'f-white';
437
+ } else {
438
+ $r_color = 'f-grey';
439
+ }
440
+ $list .= '<tr class="'. $r_color .'"><td class="dir-list"><label><input type="checkbox" name="nfw_exclude_waf_list[]" value="'. htmlspecialchars( $item ) .'"'. $checked .' /> '. htmlspecialchars( $item ) .'/</label></td></tr>';
441
+ }
442
+ }
443
+ return $list;
444
+ }
445
  // ---------------------------------------------------------------------
446
  // EOF
lib/utils.php CHANGED
@@ -512,6 +512,12 @@ function nfw_garbage_collector() {
512
  $last_file = array_pop( $glob );
513
  $data = file_get_contents( $last_file );
514
  $data = str_replace( '<?php exit; ?>', '', $data );
 
 
 
 
 
 
515
  $content = @explode("\n:-:\n", $data . "\n:-:\n");
516
  $content[0] = json_decode( $content[0], true );
517
 
@@ -631,7 +637,9 @@ function nfw_garbage_collector() {
631
  }
632
  $data = json_encode( $nfw_options ) ."\n:-:\n". json_encode($nfw_rules) ."\n:-:\n". $bd_data;
633
  $file = uniqid( 'backup_'. time() .'_', true) . '.php';
634
- @file_put_contents( $path . $file, '<?php exit; ?>' . $data, LOCK_EX );
 
 
635
  array_unshift( $glob, $path . $file );
636
  }
637
  }
@@ -659,7 +667,9 @@ function nfw_garbage_collector() {
659
  }
660
  $data = json_encode( $nfw_options ) ."\n:-:\n". json_encode($nfw_rules) ."\n:-:\n". $bd_data;
661
  $file = uniqid( 'backup_'. time() .'_', true) . '.php';
662
- @file_put_contents( $path . $file, '<?php exit; ?>' . $data, LOCK_EX );
 
 
663
  }
664
 
665
  // ------------------------------------------------------------------
@@ -932,7 +942,7 @@ add_filter('wp_is_application_passwords_available', 'nfw_no_application_password
932
  function nfwhook_rest_authentication_errors( $res ) {
933
 
934
  // Whitelisted user?
935
- if ( nfw_is_whitelisted() || isset($_SESSION['nfw_goodguy']) || defined('NFW_ALLOWRESTAPI') ) {
936
  return $res;
937
  }
938
 
@@ -941,6 +951,14 @@ function nfwhook_rest_authentication_errors( $res ) {
941
  }
942
  if ( NF_DISABLED ) { return $res; }
943
 
 
 
 
 
 
 
 
 
944
  $nfw_options = nfw_get_option( 'nfw_options' );
945
 
946
  if (! empty( $nfw_options['no_restapi']) ) {
@@ -1557,6 +1575,59 @@ function nf_monitor_options_alert( $option, $value, $old_value, $type ) {
1557
 
1558
  }
1559
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1560
  // ---------------------------------------------------------------------
1561
  // Activate WPWAF mode.
1562
 
@@ -1573,7 +1644,8 @@ function nfw_enable_wpwaf() {
1573
  if (! is_dir( WPMU_PLUGIN_DIR ) ) {
1574
  if (! @mkdir( WPMU_PLUGIN_DIR, 0755, true ) ) {
1575
  return sprintf(
1576
- __('Error, cannot create the %s folder.', 'ninjafirewall') .' '. __('Check your server permissions and try again.', 'ninjafirewall'),
 
1577
  htmlspecialchars( WPMU_PLUGIN_DIR )
1578
  );
1579
  }
@@ -1581,7 +1653,8 @@ function nfw_enable_wpwaf() {
1581
 
1582
  if (! is_writable( WPMU_PLUGIN_DIR ) ) {
1583
  return sprintf(
1584
- __('Error, the %s folder is not writable.', 'ninjafirewall') .' '. __('Check your server permissions and try again.', 'ninjafirewall'),
 
1585
  htmlspecialchars( WPMU_PLUGIN_DIR )
1586
  );
1587
  }
@@ -1589,7 +1662,8 @@ function nfw_enable_wpwaf() {
1589
  @copy( __DIR__ .'/loader.php', WPMU_PLUGIN_DIR .'/0-ninjafirewall.php' );
1590
  if (! file_exists( WPMU_PLUGIN_DIR .'/0-ninjafirewall.php' ) ) {
1591
  return sprintf(
1592
- __('Error, cannot write %s.', 'ninjafirewall') .' '. __('Check your server permissions and try again.', 'ninjafirewall'),
 
1593
  htmlspecialchars( WPMU_PLUGIN_DIR .'/0-ninjafirewall.php' )
1594
  );
1595
  }
512
  $last_file = array_pop( $glob );
513
  $data = file_get_contents( $last_file );
514
  $data = str_replace( '<?php exit; ?>', '', $data );
515
+ // Is it base64-encoded (since 4.3.5)?
516
+ if ( $data[0] == 'B' ) {
517
+ // Decode it
518
+ $data = ltrim( $data, 'B' );
519
+ $data = base64_decode( $data );
520
+ }
521
  $content = @explode("\n:-:\n", $data . "\n:-:\n");
522
  $content[0] = json_decode( $content[0], true );
523
 
637
  }
638
  $data = json_encode( $nfw_options ) ."\n:-:\n". json_encode($nfw_rules) ."\n:-:\n". $bd_data;
639
  $file = uniqid( 'backup_'. time() .'_', true) . '.php';
640
+ // Since version 4.3.5, we base64-encode the data because
641
+ // some hosts flag it as malicious
642
+ @file_put_contents( $path . $file, '<?php exit; ?>B' . base64_encode( $data ), LOCK_EX );
643
  array_unshift( $glob, $path . $file );
644
  }
645
  }
667
  }
668
  $data = json_encode( $nfw_options ) ."\n:-:\n". json_encode($nfw_rules) ."\n:-:\n". $bd_data;
669
  $file = uniqid( 'backup_'. time() .'_', true) . '.php';
670
+ // Since version 4.3.5, we base64-encode the data because
671
+ // some hosts flag it as malicious
672
+ @file_put_contents( $path . $file, '<?php exit; ?>B' . base64_encode( $data ), LOCK_EX );
673
  }
674
 
675
  // ------------------------------------------------------------------
942
  function nfwhook_rest_authentication_errors( $res ) {
943
 
944
  // Whitelisted user?
945
+ if ( nfw_is_whitelisted() || isset($_SESSION['nfw_goodguy']) ) {
946
  return $res;
947
  }
948
 
951
  }
952
  if ( NF_DISABLED ) { return $res; }
953
 
954
+ $path = parse_url( $_SERVER['REQUEST_URI'], PHP_URL_PATH );
955
+ if ( strpos( $path, '/wp-json/wp/v2/pages/' ) === 0 && current_user_can( 'edit_pages' ) ) {
956
+ return $res;
957
+ }
958
+ if ( strpos( $path, '/wp-json/wp/v2/posts/' ) === 0 && current_user_can( 'edit_posts' ) ) {
959
+ return $res;
960
+ }
961
+
962
  $nfw_options = nfw_get_option( 'nfw_options' );
963
 
964
  if (! empty( $nfw_options['no_restapi']) ) {
1575
 
1576
  }
1577
 
1578
+ // ---------------------------------------------------------------------
1579
+ // Display a red notice if there's a pending security update
1580
+ // in the plugins section.
1581
+
1582
+ function nfw_verify_secupdates() {
1583
+
1584
+ $nfw_checked = nfw_get_option( 'nfw_checked' );
1585
+ if ( empty( $nfw_checked['plugins'] ) ) {
1586
+ return;
1587
+ }
1588
+ // Check plugins updates
1589
+ if (! function_exists( 'get_plugins' ) ) {
1590
+ require_once ABSPATH .'wp-admin/includes/plugin.php';
1591
+ }
1592
+ $plugins = get_plugins();
1593
+ $cleared = 0;
1594
+ foreach( $plugins as $k => $v ) {
1595
+ // No name or no version (unlike themes, we're dealing with arrays here)
1596
+ if ( empty( $v['Name'] ) || empty( $v['Version'] ) ) {
1597
+ continue;
1598
+ }
1599
+
1600
+ if ( isset( $nfw_checked['plugins'][$k] ) ) {
1601
+ // Compare current and available versions
1602
+ if ( version_compare( $v['Version'], $nfw_checked['plugins'][$k]['version'], '<' ) ) {
1603
+ add_action( "in_plugin_update_message-{$k}", 'nfw_in_plugin_update_message', 10, 2 );
1604
+ } else {
1605
+ // Remove if from our cache
1606
+ unset( $nfw_checked['plugins'][$k] );
1607
+ $cleared = 1;
1608
+ }
1609
+
1610
+ }
1611
+ }
1612
+ // Update our list if needed
1613
+ if (! empty( $cleared ) ) {
1614
+ nfw_update_option( 'nfw_checked', $nfw_checked );
1615
+ }
1616
+ }
1617
+
1618
+ function nfw_in_plugin_update_message( $plugin_data, $r ) {
1619
+
1620
+ // We need to add our style here because ninjafirewall.css
1621
+ // is not loaded on the plugins page:
1622
+ echo '<br /><br /><span style="display:block;background-color:#FFA4A4;color:#000;padding:5px;border:1px solid red">';
1623
+
1624
+ echo esc_html__('Important: NinjaFirewall has detected that this is a security update.', 'ninjafirewall') . ' ' .
1625
+ esc_html__("Don't leave your blog at risk, make sure to update as soon as possible.", 'ninjafirewall') . ' ' .
1626
+ '<a href="https://blog.nintechnet.com/how-to-get-informed-about-the-latest-security-updates-in-your-wordpress-plugins-and-themes/" target="_blank">' .
1627
+ esc_html__('More info about this warning.', 'ninjafirewall') .
1628
+ '</a></span>';
1629
+ }
1630
+
1631
  // ---------------------------------------------------------------------
1632
  // Activate WPWAF mode.
1633
 
1644
  if (! is_dir( WPMU_PLUGIN_DIR ) ) {
1645
  if (! @mkdir( WPMU_PLUGIN_DIR, 0755, true ) ) {
1646
  return sprintf(
1647
+ esc_html__('Error, cannot create the %s folder.', 'ninjafirewall') .' '.
1648
+ esc_html__('Check your server permissions and try again.', 'ninjafirewall'),
1649
  htmlspecialchars( WPMU_PLUGIN_DIR )
1650
  );
1651
  }
1653
 
1654
  if (! is_writable( WPMU_PLUGIN_DIR ) ) {
1655
  return sprintf(
1656
+ esc_html__('Error, the %s folder is not writable.', 'ninjafirewall') .' '.
1657
+ esc_html__('Check your server permissions and try again.', 'ninjafirewall'),
1658
  htmlspecialchars( WPMU_PLUGIN_DIR )
1659
  );
1660
  }
1662
  @copy( __DIR__ .'/loader.php', WPMU_PLUGIN_DIR .'/0-ninjafirewall.php' );
1663
  if (! file_exists( WPMU_PLUGIN_DIR .'/0-ninjafirewall.php' ) ) {
1664
  return sprintf(
1665
+ esc_html__('Error, cannot write %s.', 'ninjafirewall') .' '.
1666
+ esc_html__('Check your server permissions and try again.', 'ninjafirewall'),
1667
  htmlspecialchars( WPMU_PLUGIN_DIR .'/0-ninjafirewall.php' )
1668
  );
1669
  }
lib/widget.php CHANGED
@@ -14,7 +14,7 @@
14
  | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15
  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16
  | GNU General Public License for more details. |
17
- +---------------------------------------------------------------------+ i18n+ / sa2
18
  */
19
 
20
  if (! defined( 'NFW_ENGINE_VERSION' ) ) {
@@ -26,7 +26,7 @@ if (! defined( 'NFW_ENGINE_VERSION' ) ) {
26
  // Return immediately if user is not allowed (only the admin can see the widget):
27
  if (nf_not_allowed( 0, __LINE__ ) ) { return; }
28
 
29
- wp_add_dashboard_widget( 'nfw_dashboard_welcome', __('NinjaFirewall Statistics', 'ninjafirewall'), 'nfw_stats_widget' );
30
 
31
  global $wp_meta_boxes;
32
  if ( is_multisite() ) {
@@ -63,13 +63,13 @@ function nfw_stats_widget() {
63
  echo '
64
  <table border="0" width="100%">
65
  <tr>
66
- <th width="50%" align="left"><h3>' . __('Blocked threats', 'ninjafirewall') .'</h3></th>
67
  <td width="50%" align="left">' . number_format_i18n( $total ) . '</td>
68
  </tr>
69
  <tr>
70
- <th width="50%" align="left"><h3>' . __('Threats level', 'ninjafirewall') .'</h3></th>
71
  <td width="50%" align="left">
72
- <i>' . __('Critical:', 'ninjafirewall') . ' ' . $critical . '%</i>
73
  <br />
74
  <table bgcolor="#DFDFDF" border="0" cellpadding="0" cellspacing="0" height="14" width="100%" align="left" style="height:14px;">
75
  <tr>
@@ -77,7 +77,7 @@ function nfw_stats_widget() {
77
  </tr>
78
  </table>
79
  <br />
80
- <i>' . __('High:', 'ninjafirewall') . ' ' . $high . '%</i>
81
  <br />
82
  <table bgcolor="#DFDFDF" border="0" cellpadding="0" cellspacing="0" height="14" width="100%" align="left" style="height:14px;">
83
  <tr>
@@ -85,7 +85,7 @@ function nfw_stats_widget() {
85
  </tr>
86
  </table>
87
  <br />
88
- <i>' . __('Medium:', 'ninjafirewall') . ' ' . $medium . '%</i>
89
  <br />
90
  <table bgcolor="#DFDFDF" border="0" cellpadding="0" cellspacing="0" height="14" width="100%" align="left" style="height:14px;">
91
  <tr>
@@ -95,7 +95,7 @@ function nfw_stats_widget() {
95
  </td>
96
  </tr>
97
  </table>
98
- <div align="right" class="activity-block"><a style="text-decoration:none" href="admin.php?page=NinjaFirewall&tab=statistics">' . __('View statistics', 'ninjafirewall') .'</a>&nbsp;&nbsp;-&nbsp;&nbsp;<a style="text-decoration:none" href="admin.php?page=nfsublog">' . __('View firewall log', 'ninjafirewall') .'</a></div>';
99
 
100
  // Shall we display the security news feed?
101
  $nfw_options = nfw_get_option( 'nfw_options' );
@@ -131,7 +131,7 @@ function nfw_stats_widget() {
131
  }
132
 
133
  $news = json_decode( $res['body'] );
134
- echo '<br /><div><h3 style="font-weight:600;">'. __('Latest Security News', 'ninjafirewall' ) .'</h3></div>';
135
  echo '<div class="rss-widget"><ul>';
136
  $count = 0;
137
  foreach( $news as $k => $v ) {
@@ -146,7 +146,7 @@ function nfw_stats_widget() {
146
  echo '</ul></div>';
147
  ?>
148
  <br /><p class="community-events-footer">
149
- <a href="https://blog.nintechnet.com/" target="_blank"><?php _e('More Security News', 'ninjafirewall' ) ?> <span class="screen-reader-text"><?php _e('(opens in a new tab)') ?></span><span aria-hidden="true" class="dashicons dashicons-external"></span></a> | <a href="https://nintechnet.com/" target="_blank"><?php _e('NinjaFirewall\'s Home', 'ninjafirewall' ) ?> <span class="screen-reader-text"><?php _e('(opens in a new tab)') ?></span><span aria-hidden="true" class="dashicons dashicons-external"></span></a> | <a href="https://twitter.com/nintechnet" target="_blank">Twitter <span class="screen-reader-text"><?php _e('(opens in a new tab)') ?></span><span aria-hidden="true" class="dashicons dashicons-external"></span></a>
150
  </p>
151
  <?php
152
  }
14
  | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15
  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16
  | GNU General Public License for more details. |
17
+ +---------------------------------------------------------------------+ i18n++ / sa2
18
  */
19
 
20
  if (! defined( 'NFW_ENGINE_VERSION' ) ) {
26
  // Return immediately if user is not allowed (only the admin can see the widget):
27
  if (nf_not_allowed( 0, __LINE__ ) ) { return; }
28
 
29
+ wp_add_dashboard_widget( 'nfw_dashboard_welcome', esc_html__('NinjaFirewall Statistics', 'ninjafirewall'), 'nfw_stats_widget' );
30
 
31
  global $wp_meta_boxes;
32
  if ( is_multisite() ) {
63
  echo '
64
  <table border="0" width="100%">
65
  <tr>
66
+ <th width="50%" align="left"><h3>' . esc_html__('Blocked threats', 'ninjafirewall') .'</h3></th>
67
  <td width="50%" align="left">' . number_format_i18n( $total ) . '</td>
68
  </tr>
69
  <tr>
70
+ <th width="50%" align="left"><h3>' . esc_html__('Threats level', 'ninjafirewall') .'</h3></th>
71
  <td width="50%" align="left">
72
+ <i>' . esc_html__('Critical:', 'ninjafirewall') . ' ' . $critical . '%</i>
73
  <br />
74
  <table bgcolor="#DFDFDF" border="0" cellpadding="0" cellspacing="0" height="14" width="100%" align="left" style="height:14px;">
75
  <tr>
77
  </tr>
78
  </table>
79
  <br />
80
+ <i>' . esc_html__('High:', 'ninjafirewall') . ' ' . $high . '%</i>
81
  <br />
82
  <table bgcolor="#DFDFDF" border="0" cellpadding="0" cellspacing="0" height="14" width="100%" align="left" style="height:14px;">
83
  <tr>
85
  </tr>
86
  </table>
87
  <br />
88
+ <i>' . esc_html__('Medium:', 'ninjafirewall') . ' ' . $medium . '%</i>
89
  <br />
90
  <table bgcolor="#DFDFDF" border="0" cellpadding="0" cellspacing="0" height="14" width="100%" align="left" style="height:14px;">
91
  <tr>
95
  </td>
96
  </tr>
97
  </table>
98
+ <div align="right" class="activity-block"><a style="text-decoration:none" href="admin.php?page=NinjaFirewall&tab=statistics">' . esc_html__('View statistics', 'ninjafirewall') .'</a>&nbsp;&nbsp;-&nbsp;&nbsp;<a style="text-decoration:none" href="admin.php?page=nfsublog">' . esc_html__('View firewall log', 'ninjafirewall') .'</a></div>';
99
 
100
  // Shall we display the security news feed?
101
  $nfw_options = nfw_get_option( 'nfw_options' );
131
  }
132
 
133
  $news = json_decode( $res['body'] );
134
+ echo '<br /><div><h3 style="font-weight:600;">'. esc_html__('Latest Security News', 'ninjafirewall' ) .'</h3></div>';
135
  echo '<div class="rss-widget"><ul>';
136
  $count = 0;
137
  foreach( $news as $k => $v ) {
146
  echo '</ul></div>';
147
  ?>
148
  <br /><p class="community-events-footer">
149
+ <a href="https://blog.nintechnet.com/" target="_blank"><?php esc_html_e('More Security News', 'ninjafirewall' ) ?> <span class="screen-reader-text"><?php esc_html_e('(opens in a new tab)') ?></span><span aria-hidden="true" class="dashicons dashicons-external"></span></a> | <a href="https://nintechnet.com/" target="_blank"><?php esc_html_e('NinjaFirewall\'s Home', 'ninjafirewall' ) ?> <span class="screen-reader-text"><?php esc_html_e('(opens in a new tab)') ?></span><span aria-hidden="true" class="dashicons dashicons-external"></span></a> | <a href="https://twitter.com/nintechnet" target="_blank">Twitter <span class="screen-reader-text"><?php esc_html_e('(opens in a new tab)') ?></span><span aria-hidden="true" class="dashicons dashicons-external"></span></a>
150
  </p>
151
  <?php
152
  }
ninjafirewall.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: NinjaFirewall (WP Edition)
4
  Plugin URI: https://nintechnet.com/
5
  Description: A true Web Application Firewall to protect and secure WordPress.
6
- Version: 4.3.4
7
  Author: The Ninja Technologies Network
8
  Author URI: https://nintechnet.com/
9
  License: GPLv3 or later
@@ -19,7 +19,7 @@ Domain Path: /languages
19
  | (c) NinTechNet - https://nintechnet.com/ |
20
  +---------------------------------------------------------------------+
21
  */
22
- define( 'NFW_ENGINE_VERSION', '4.3.4' );
23
  /*
24
  +---------------------------------------------------------------------+
25
  | This program is free software: you can redistribute it and/or |
@@ -116,34 +116,34 @@ function nfw_activate() {
116
 
117
  // Warn if the user does not have the 'unfiltered_html' capability:
118
  if (! current_user_can( 'unfiltered_html' ) ) {
119
- exit( __('You do not have "unfiltered_html" capability. Please enable it in order to run NinjaFirewall (or make sure you do not have "DISALLOW_UNFILTERED_HTML" in your wp-config.php script).', 'ninjafirewall'));
120
  }
121
 
122
  nf_not_allowed( 'block', __LINE__ );
123
 
124
  global $wp_version;
125
  if ( version_compare( $wp_version, '4.7.0', '<' ) ) {
126
- exit( sprintf( __('NinjaFirewall requires WordPress %s or greater but your current version is %s.', 'ninjafirewall'), '4.7.0', $wp_version) );
127
  }
128
 
129
  if ( version_compare( PHP_VERSION, '5.3.0', '<' ) ) {
130
- exit( sprintf( __('NinjaFirewall requires PHP 5.3 or greater but your current version is %s.', 'ninjafirewall'), PHP_VERSION) );
131
  }
132
 
133
  if (! function_exists('mysqli_connect') ) {
134
- exit( sprintf( __('NinjaFirewall requires the PHP %s extension.', 'ninjafirewall'), '<code>mysqli</code>') );
135
  }
136
 
137
  if ( ini_get( 'safe_mode' ) ) {
138
- exit( __('You have SAFE_MODE enabled. Please disable it, it is deprecated as of PHP 5.3.0 (see http://php.net/safe-mode).', 'ninjafirewall'));
139
  }
140
 
141
  if ( ( is_multisite() ) && (! current_user_can( 'manage_network' ) ) ) {
142
- exit( __('You are not allowed to activate NinjaFirewall.', 'ninjafirewall') );
143
  }
144
 
145
  if ( PATH_SEPARATOR == ';' ) {
146
- exit( __('NinjaFirewall is not compatible with Microsoft Windows.', 'ninjafirewall') );
147
  }
148
 
149
  if (! $nfw_options = nfw_get_option( 'nfw_options' ) ) {
@@ -153,6 +153,10 @@ function nfw_activate() {
153
  nfw_load_default_conf();
154
  // Reload them
155
  $nfw_options = nfw_get_option( 'nfw_options' );
 
 
 
 
156
  }
157
 
158
  $nfw_options['enabled'] = 1;
@@ -397,6 +401,11 @@ function nfw_admin_init() {
397
  // to prevent unauthenticated AJAX calls to trigger it):
398
  if ( is_user_logged_in() ) {
399
  nfw_session_start();
 
 
 
 
 
400
  }
401
 
402
  $nfw_options = nfw_get_option( 'nfw_options' );
@@ -405,12 +414,6 @@ function nfw_admin_init() {
405
  // Post-update adjustment:
406
  require plugin_dir_path(__FILE__) . 'lib/init_update.php';
407
 
408
- if ( current_user_can( 'edit_pages' ) ) {
409
- $_SESSION['nfw_user_can'] = 'edit_pages';
410
- } elseif ( current_user_can( 'edit_posts' ) ) {
411
- $_SESSION['nfw_user_can'] = 'edit_posts';
412
- }
413
-
414
  // --------------------------------------------
415
  // Anything below requires admin authentication
416
  // --------------------------------------------
@@ -428,6 +431,12 @@ function nfw_admin_init() {
428
  nfw_enable_wpwaf();
429
  }
430
 
 
 
 
 
 
 
431
  // Export configuration:
432
  if ( isset($_POST['nf_export']) ) {
433
  if ( empty($_POST['nfwnonce']) || ! wp_verify_nonce($_POST['nfwnonce'], 'options_save') ) {
@@ -614,8 +623,8 @@ function nfw_logout_hook() {
614
  if (isset( $_SESSION['nfw_livelog'] ) ) {
615
  unset( $_SESSION['nfw_livelog'] );
616
  }
617
- if (isset( $_SESSION['nfw_user_can'] ) ) {
618
- unset( $_SESSION['nfw_user_can'] );
619
  }
620
  }
621
 
@@ -631,29 +640,32 @@ function nfw_fullwafsetup() {
631
  nf_not_allowed( 'block', __LINE__ );
632
 
633
  if (! check_ajax_referer( 'events_save', 'nonce', false ) ) {
634
- _e('Error: Security nonces do not match. Reload the page and try again.', 'ninjafirewall');
635
  wp_die();
636
  }
637
 
638
  $nfw_options = nfw_get_option( 'nfw_options' );
639
  if ( empty( $nfw_options['enabled'] ) ) {
640
- _e('Error: NinjaFirewall is disabled', 'ninjafirewall');
641
  wp_die();
642
  }
643
 
644
  if ( empty( $_POST['httpserver'] ) ) {
645
- printf( __('Error: missing parameter (%s).', 'ninjafirewall'), 'httpserver' );
646
  wp_die();
647
  }
648
  if ( preg_match('/^[^1-8]$/', $_POST['httpserver'] ) ) {
649
- printf( __('Error: wrong parameter value (%s).', 'ninjafirewall'), 'httpserver' );
650
  wp_die();
651
  }
652
  if ( empty( $_POST['diy'] ) || ! preg_match( '/^(nfw|usr)$/', $_POST['diy'] ) ) {
653
- printf( __('Error: wrong parameter value (%s).', 'ninjafirewall'), 'diy' );
654
  wp_die();
655
  }
656
 
 
 
 
657
  // Disable the sandbox?
658
  if ( empty( $_POST['sandbox'] ) ) {
659
  define('NFW_BYPASS_SANDBOX', true);
@@ -738,6 +750,75 @@ function nfw_fullwafsetup() {
738
  wp_die();
739
  }
740
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
741
  /* ------------------------------------------------------------------ */
742
  // Welcome screen.
743
 
@@ -748,7 +829,7 @@ function nfw_welcomescreen() {
748
  nf_not_allowed( 'block', __LINE__ );
749
 
750
  if (! check_ajax_referer( 'welcome_save', 'nonce', false ) ) {
751
- _e('Error: Security nonces do not match. Reload the page and try again.', 'ninjafirewall');
752
  wp_die();
753
  }
754
  $nfw_options = nfw_get_option( 'nfw_options' );
3
  Plugin Name: NinjaFirewall (WP Edition)
4
  Plugin URI: https://nintechnet.com/
5
  Description: A true Web Application Firewall to protect and secure WordPress.
6
+ Version: 4.4
7
  Author: The Ninja Technologies Network
8
  Author URI: https://nintechnet.com/
9
  License: GPLv3 or later
19
  | (c) NinTechNet - https://nintechnet.com/ |
20
  +---------------------------------------------------------------------+
21
  */
22
+ define( 'NFW_ENGINE_VERSION', '4.4' );
23
  /*
24
  +---------------------------------------------------------------------+
25
  | This program is free software: you can redistribute it and/or |
116
 
117
  // Warn if the user does not have the 'unfiltered_html' capability:
118
  if (! current_user_can( 'unfiltered_html' ) ) {
119
+ exit( esc_html__('You do not have "unfiltered_html" capability. Please enable it in order to run NinjaFirewall (or make sure you do not have "DISALLOW_UNFILTERED_HTML" in your wp-config.php script).', 'ninjafirewall'));
120
  }
121
 
122
  nf_not_allowed( 'block', __LINE__ );
123
 
124
  global $wp_version;
125
  if ( version_compare( $wp_version, '4.7.0', '<' ) ) {
126
+ exit( sprintf( esc_html__('NinjaFirewall requires WordPress %s or greater but your current version is %s.', 'ninjafirewall'), '4.7.0', $wp_version) );
127
  }
128
 
129
  if ( version_compare( PHP_VERSION, '5.3.0', '<' ) ) {
130
+ exit( sprintf( esc_html__('NinjaFirewall requires PHP 5.3 or greater but your current version is %s.', 'ninjafirewall'), PHP_VERSION) );
131
  }
132
 
133
  if (! function_exists('mysqli_connect') ) {
134
+ exit( sprintf( esc_html__('NinjaFirewall requires the PHP %s extension.', 'ninjafirewall'), '<code>mysqli</code>') );
135
  }
136
 
137
  if ( ini_get( 'safe_mode' ) ) {
138
+ exit( esc_html__('You have SAFE_MODE enabled. Please disable it, it is deprecated as of PHP 5.3.0 (see http://php.net/safe-mode).', 'ninjafirewall'));
139
  }
140
 
141
  if ( ( is_multisite() ) && (! current_user_can( 'manage_network' ) ) ) {
142
+ exit( esc_html__('You are not allowed to activate NinjaFirewall.', 'ninjafirewall') );
143
  }
144
 
145
  if ( PATH_SEPARATOR == ';' ) {
146
+ exit( esc_html__('NinjaFirewall is not compatible with Microsoft Windows.', 'ninjafirewall') );
147
  }
148
 
149
  if (! $nfw_options = nfw_get_option( 'nfw_options' ) ) {
153
  nfw_load_default_conf();
154
  // Reload them
155
  $nfw_options = nfw_get_option( 'nfw_options' );
156
+ } else {
157
+ // (Re)create the loader
158
+ require_once __DIR__ .'/lib/install_default.php';
159
+ nfw_create_loader();
160
  }
161
 
162
  $nfw_options['enabled'] = 1;
401
  // to prevent unauthenticated AJAX calls to trigger it):
402
  if ( is_user_logged_in() ) {
403
  nfw_session_start();
404
+ // Save user's capabilities
405
+ $nf_user = wp_get_current_user();
406
+ if ( $nf_user instanceof WP_User ) {
407
+ $_SESSION['allcaps'] = $nf_user->allcaps;
408
+ }
409
  }
410
 
411
  $nfw_options = nfw_get_option( 'nfw_options' );
414
  // Post-update adjustment:
415
  require plugin_dir_path(__FILE__) . 'lib/init_update.php';
416
 
 
 
 
 
 
 
417
  // --------------------------------------------
418
  // Anything below requires admin authentication
419
  // --------------------------------------------
431
  nfw_enable_wpwaf();
432
  }
433
 
434
+ // Security update in WP plugins:
435
+ global $pagenow;
436
+ if ( $pagenow == 'plugins.php' && current_user_can( 'update_plugins' ) ) {
437
+ nfw_verify_secupdates();
438
+ }
439
+
440
  // Export configuration:
441
  if ( isset($_POST['nf_export']) ) {
442
  if ( empty($_POST['nfwnonce']) || ! wp_verify_nonce($_POST['nfwnonce'], 'options_save') ) {
623
  if (isset( $_SESSION['nfw_livelog'] ) ) {
624
  unset( $_SESSION['nfw_livelog'] );
625
  }
626
+ if (isset( $_SESSION['allcaps'] ) ) {
627
+ unset( $_SESSION['allcaps'] );
628
  }
629
  }
630
 
640
  nf_not_allowed( 'block', __LINE__ );
641
 
642
  if (! check_ajax_referer( 'events_save', 'nonce', false ) ) {
643
+ esc_html_e('Error: Security nonces do not match. Reload the page and try again.', 'ninjafirewall');
644
  wp_die();
645
  }
646
 
647
  $nfw_options = nfw_get_option( 'nfw_options' );
648
  if ( empty( $nfw_options['enabled'] ) ) {
649
+ esc_html_e('Error: NinjaFirewall is disabled', 'ninjafirewall');
650
  wp_die();
651
  }
652
 
653
  if ( empty( $_POST['httpserver'] ) ) {
654
+ printf( esc_html__('Error: missing parameter (%s).', 'ninjafirewall'), 'httpserver' );
655
  wp_die();
656
  }
657
  if ( preg_match('/^[^1-8]$/', $_POST['httpserver'] ) ) {
658
+ printf( esc_html__('Error: wrong parameter value (%s).', 'ninjafirewall'), 'httpserver' );
659
  wp_die();
660
  }
661
  if ( empty( $_POST['diy'] ) || ! preg_match( '/^(nfw|usr)$/', $_POST['diy'] ) ) {
662
+ printf( esc_html__('Error: wrong parameter value (%s).', 'ninjafirewall'), 'diy' );
663
  wp_die();
664
  }
665
 
666
+ // Retrieve the list of excluded folders, if any, and save it
667
+ nfw_save_waf_exclusionlist( $_POST['exclude_waf_list'] );
668
+
669
  // Disable the sandbox?
670
  if ( empty( $_POST['sandbox'] ) ) {
671
  define('NFW_BYPASS_SANDBOX', true);
750
  wp_die();
751
  }
752
 
753
+ /* ------------------------------------------------------------------ */
754
+ // Configure Full WAF mode or fallback to WP WAF mode. AJAX action.
755
+
756
+ add_action( 'wp_ajax_nfw_fullwafconfig', 'nfw_fullwafconfig' );
757
+
758
+ function nfw_fullwafconfig() {
759
+
760
+ nf_not_allowed( 'block', __LINE__ );
761
+
762
+ if (! check_ajax_referer( 'events_save', 'nonce', false ) ) {
763
+ esc_html_e('Error: Security nonces do not match. Reload the page and try again.', 'ninjafirewall');
764
+ wp_die();
765
+ }
766
+
767
+ if ( empty( $_POST['what'] ) || ! preg_match( '/^[12]$/', $_POST['what'] ) ) {
768
+ printf( esc_html__('Error: missing parameter (%s).', 'ninjafirewall'), 'what' );
769
+ wp_die();
770
+ }
771
+
772
+ // Downgrade to WP WAF
773
+ if ( $_POST['what'] == 2 ) {
774
+
775
+ require __DIR__ .'/lib/install.php';
776
+ nfw_get_constants();
777
+ nfw_remove_directives();
778
+
779
+ // Full WAF directories exclusion
780
+ } else {
781
+ // Retrieve the list of excluded folders, if any, and save it
782
+ nfw_save_waf_exclusionlist( $_POST['list'] );
783
+ }
784
+
785
+ wp_die(200);
786
+ }
787
+
788
+ /* ------------------------------------------------------------------ */
789
+ // Save new exclusion list.
790
+
791
+ function nfw_save_waf_exclusionlist( $input ) {
792
+
793
+ $nfw_options = nfw_get_option( 'nfw_options' );
794
+
795
+ // Retrieve the list of excluded folders, if any, and save it
796
+ $tmp_exclude_waf_list = json_decode( stripslashes( $input ) );
797
+ if ( $tmp_exclude_waf_list === false || $tmp_exclude_waf_list === null ) {
798
+ printf( esc_html__('Error: missing parameter (%s).', 'ninjafirewall'), 'list' );
799
+ wp_die();
800
+ }
801
+ $exclude_waf_list = array();
802
+ if (! empty( $tmp_exclude_waf_list ) ) {
803
+ foreach( $tmp_exclude_waf_list as $folder ) {
804
+ if ( is_dir( ABSPATH . $folder ) ) {
805
+ $exclude_waf_list[] = $folder;
806
+ }
807
+ }
808
+ }
809
+ // Update/clear the list
810
+ if (! empty( $exclude_waf_list ) ) {
811
+ $nfw_options['exclude_waf_list'] = json_encode( $exclude_waf_list );
812
+ } else {
813
+ unset( $nfw_options['exclude_waf_list'] );
814
+ }
815
+ nfw_update_option( 'nfw_options', $nfw_options);
816
+ // (Re)create the loader
817
+ require_once __DIR__ .'/lib/install_default.php';
818
+ nfw_create_loader();
819
+
820
+ }
821
+
822
  /* ------------------------------------------------------------------ */
823
  // Welcome screen.
824
 
829
  nf_not_allowed( 'block', __LINE__ );
830
 
831
  if (! check_ajax_referer( 'welcome_save', 'nonce', false ) ) {
832
+ esc_html_e('Error: Security nonces do not match. Reload the page and try again.', 'ninjafirewall');
833
  wp_die();
834
  }
835
  $nfw_options = nfw_get_option( 'nfw_options' );
readme.txt CHANGED
@@ -2,8 +2,8 @@
2
  Contributors: nintechnet, bruandet
3
  Tags: security, firewall, malware, protection, hack, antispam, virus, scanner, hacked site, brute force, seguridad, seguranca, sicherheit, sicurezza, veiligheid, classicpress
4
  Requires at least: 4.7
5
- Tested up to: 5.7
6
- Stable tag: 4.3.4
7
  Requires PHP: 5.5
8
  License: GPLv3 or later
9
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
@@ -208,6 +208,22 @@ WordPress Sicherheit Plugin.
208
 
209
  Need more security? Take the time to explore our supercharged Premium edition: [NinjaFirewall WP+ Edition](https://nintechnet.com/ninjafirewall/wp-edition/?comparison)
210
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
211
  = 4.3.4 =
212
 
213
  * Fixed a PHP fatal error ("Argument #1 must be of type array, string given") in the Events Notification page that could occur when updating a plugin.
2
  Contributors: nintechnet, bruandet
3
  Tags: security, firewall, malware, protection, hack, antispam, virus, scanner, hacked site, brute force, seguridad, seguranca, sicherheit, sicurezza, veiligheid, classicpress
4
  Requires at least: 4.7
5
+ Tested up to: 5.8
6
+ Stable tag: 4.4
7
  Requires PHP: 5.5
8
  License: GPLv3 or later
9
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
208
 
209
  Need more security? Take the time to explore our supercharged Premium edition: [NinjaFirewall WP+ Edition](https://nintechnet.com/ninjafirewall/wp-edition/?comparison)
210
 
211
+ = 4.4 =
212
+
213
+ * The "Full WAF" mode can be configured to exclude some directories. That can be done from the "NinjaFirewall > Dashboard" page by clicking on the new "Configure" button. There's no need to use the ".htninja" script to exclude folders anymore. That can be useful to exclude third-party applications that rely on PHP sessions and could behave erratically with the "Full WAF" mode (e.g., Piwik/Matomo, phpMyAdmin, forums etc).
214
+ * You can easily downgrade from "Full WAF" mode to "WordPress WAF" mode by clicking the "Configure" button in the "NinjaFirewall > Dashboard" page.
215
+ * Added a warning about the "X-XSS-Protection" HTTP header in the "Firewall Policies" section: although NinjaFirewall still supports it, it is now deprecated and only used by Safari. Consider using "Content-Security-Policy" (CSP) instead.
216
+ * When reactivating NinjaFirewall from the "Plugins" page, it will verify that the path to the firewall file is correct or, if necessary, will adjust it (e.g., after a server migration etc).
217
+ * NinjaFirewall will display a warning in its "Dashboard" page if the .user.ini or php.ini file is readable.
218
+ * The configuation backup files are now base64-encoded to prevent being wrongly flagged by some hosting companies antivirus.
219
+ * NinjaFirewall will hightlight in red colour in the "Plugins" page any plugin that has a pending security update. See [https://nin.link/nfsecupdates/](https://nin.link/nfsecupdates/) for more details.
220
+ * The cache used to store information about pending security updates will be automatically flushed.
221
+ * On old multisite installations, the firewall will no longer block access to the "/wp-includes/ms-files.php" script.
222
+ * The firewall can now detect user roles even before WordPress is loaded.
223
+ * Updated Charts.js to v3.4.1.
224
+ * WP+ Edition (Premium): Updated GeoIP databases.
225
+ * Many additional small fixes and adjustments.
226
+
227
  = 4.3.4 =
228
 
229
  * Fixed a PHP fatal error ("Argument #1 must be of type array, string given") in the Events Notification page that could occur when updating a plugin.
static/chart.min.js CHANGED
@@ -1,7 +1,13 @@
1
  /*!
2
- * Chart.js v2.9.4
3
  * https://www.chartjs.org
4
- * (c) 2020 Chart.js Contributors
5
  * Released under the MIT License
6
  */
7
- !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e(function(){try{return require("moment")}catch(t){}}()):"function"==typeof define&&define.amd?define(["require"],(function(t){return e(function(){try{return t("moment")}catch(t){}}())})):(t=t||self).Chart=e(t.moment)}(this,(function(t){"use strict";t=t&&t.hasOwnProperty("default")?t.default:t;var e={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},n=function(t,e){return t(e={exports:{}},e.exports),e.exports}((function(t){var n={};for(var i in e)e.hasOwnProperty(i)&&(n[e[i]]=i);var a=t.exports={rgb:{channels:3,labels:"rgb"},hsl:{channels:3,labels:"hsl"},hsv:{channels:3,labels:"hsv"},hwb:{channels:3,labels:"hwb"},cmyk:{channels:4,labels:"cmyk"},xyz:{channels:3,labels:"xyz"},lab:{channels:3,labels:"lab"},lch:{channels:3,labels:"lch"},hex:{channels:1,labels:["hex"]},keyword:{channels:1,labels:["keyword"]},ansi16:{channels:1,labels:["ansi16"]},ansi256:{channels:1,labels:["ansi256"]},hcg:{channels:3,labels:["h","c","g"]},apple:{channels:3,labels:["r16","g16","b16"]},gray:{channels:1,labels:["gray"]}};for(var r in a)if(a.hasOwnProperty(r)){if(!("channels"in a[r]))throw new Error("missing channels property: "+r);if(!("labels"in a[r]))throw new Error("missing channel labels property: "+r);if(a[r].labels.length!==a[r].channels)throw new Error("channel and label counts mismatch: "+r);var o=a[r].channels,s=a[r].labels;delete a[r].channels,delete a[r].labels,Object.defineProperty(a[r],"channels",{value:o}),Object.defineProperty(a[r],"labels",{value:s})}a.rgb.hsl=function(t){var e,n,i=t[0]/255,a=t[1]/255,r=t[2]/255,o=Math.min(i,a,r),s=Math.max(i,a,r),l=s-o;return s===o?e=0:i===s?e=(a-r)/l:a===s?e=2+(r-i)/l:r===s&&(e=4+(i-a)/l),(e=Math.min(60*e,360))<0&&(e+=360),n=(o+s)/2,[e,100*(s===o?0:n<=.5?l/(s+o):l/(2-s-o)),100*n]},a.rgb.hsv=function(t){var e,n,i,a,r,o=t[0]/255,s=t[1]/255,l=t[2]/255,u=Math.max(o,s,l),d=u-Math.min(o,s,l),h=function(t){return(u-t)/6/d+.5};return 0===d?a=r=0:(r=d/u,e=h(o),n=h(s),i=h(l),o===u?a=i-n:s===u?a=1/3+e-i:l===u&&(a=2/3+n-e),a<0?a+=1:a>1&&(a-=1)),[360*a,100*r,100*u]},a.rgb.hwb=function(t){var e=t[0],n=t[1],i=t[2];return[a.rgb.hsl(t)[0],100*(1/255*Math.min(e,Math.min(n,i))),100*(i=1-1/255*Math.max(e,Math.max(n,i)))]},a.rgb.cmyk=function(t){var e,n=t[0]/255,i=t[1]/255,a=t[2]/255;return[100*((1-n-(e=Math.min(1-n,1-i,1-a)))/(1-e)||0),100*((1-i-e)/(1-e)||0),100*((1-a-e)/(1-e)||0),100*e]},a.rgb.keyword=function(t){var i=n[t];if(i)return i;var a,r,o,s=1/0;for(var l in e)if(e.hasOwnProperty(l)){var u=e[l],d=(r=t,o=u,Math.pow(r[0]-o[0],2)+Math.pow(r[1]-o[1],2)+Math.pow(r[2]-o[2],2));d<s&&(s=d,a=l)}return a},a.keyword.rgb=function(t){return e[t]},a.rgb.xyz=function(t){var e=t[0]/255,n=t[1]/255,i=t[2]/255;return[100*(.4124*(e=e>.04045?Math.pow((e+.055)/1.055,2.4):e/12.92)+.3576*(n=n>.04045?Math.pow((n+.055)/1.055,2.4):n/12.92)+.1805*(i=i>.04045?Math.pow((i+.055)/1.055,2.4):i/12.92)),100*(.2126*e+.7152*n+.0722*i),100*(.0193*e+.1192*n+.9505*i)]},a.rgb.lab=function(t){var e=a.rgb.xyz(t),n=e[0],i=e[1],r=e[2];return i/=100,r/=108.883,n=(n/=95.047)>.008856?Math.pow(n,1/3):7.787*n+16/116,[116*(i=i>.008856?Math.pow(i,1/3):7.787*i+16/116)-16,500*(n-i),200*(i-(r=r>.008856?Math.pow(r,1/3):7.787*r+16/116))]},a.hsl.rgb=function(t){var e,n,i,a,r,o=t[0]/360,s=t[1]/100,l=t[2]/100;if(0===s)return[r=255*l,r,r];e=2*l-(n=l<.5?l*(1+s):l+s-l*s),a=[0,0,0];for(var u=0;u<3;u++)(i=o+1/3*-(u-1))<0&&i++,i>1&&i--,r=6*i<1?e+6*(n-e)*i:2*i<1?n:3*i<2?e+(n-e)*(2/3-i)*6:e,a[u]=255*r;return a},a.hsl.hsv=function(t){var e=t[0],n=t[1]/100,i=t[2]/100,a=n,r=Math.max(i,.01);return n*=(i*=2)<=1?i:2-i,a*=r<=1?r:2-r,[e,100*(0===i?2*a/(r+a):2*n/(i+n)),100*((i+n)/2)]},a.hsv.rgb=function(t){var e=t[0]/60,n=t[1]/100,i=t[2]/100,a=Math.floor(e)%6,r=e-Math.floor(e),o=255*i*(1-n),s=255*i*(1-n*r),l=255*i*(1-n*(1-r));switch(i*=255,a){case 0:return[i,l,o];case 1:return[s,i,o];case 2:return[o,i,l];case 3:return[o,s,i];case 4:return[l,o,i];case 5:return[i,o,s]}},a.hsv.hsl=function(t){var e,n,i,a=t[0],r=t[1]/100,o=t[2]/100,s=Math.max(o,.01);return i=(2-r)*o,n=r*s,[a,100*(n=(n/=(e=(2-r)*s)<=1?e:2-e)||0),100*(i/=2)]},a.hwb.rgb=function(t){var e,n,i,a,r,o,s,l=t[0]/360,u=t[1]/100,d=t[2]/100,h=u+d;switch(h>1&&(u/=h,d/=h),i=6*l-(e=Math.floor(6*l)),0!=(1&e)&&(i=1-i),a=u+i*((n=1-d)-u),e){default:case 6:case 0:r=n,o=a,s=u;break;case 1:r=a,o=n,s=u;break;case 2:r=u,o=n,s=a;break;case 3:r=u,o=a,s=n;break;case 4:r=a,o=u,s=n;break;case 5:r=n,o=u,s=a}return[255*r,255*o,255*s]},a.cmyk.rgb=function(t){var e=t[0]/100,n=t[1]/100,i=t[2]/100,a=t[3]/100;return[255*(1-Math.min(1,e*(1-a)+a)),255*(1-Math.min(1,n*(1-a)+a)),255*(1-Math.min(1,i*(1-a)+a))]},a.xyz.rgb=function(t){var e,n,i,a=t[0]/100,r=t[1]/100,o=t[2]/100;return n=-.9689*a+1.8758*r+.0415*o,i=.0557*a+-.204*r+1.057*o,e=(e=3.2406*a+-1.5372*r+-.4986*o)>.0031308?1.055*Math.pow(e,1/2.4)-.055:12.92*e,n=n>.0031308?1.055*Math.pow(n,1/2.4)-.055:12.92*n,i=i>.0031308?1.055*Math.pow(i,1/2.4)-.055:12.92*i,[255*(e=Math.min(Math.max(0,e),1)),255*(n=Math.min(Math.max(0,n),1)),255*(i=Math.min(Math.max(0,i),1))]},a.xyz.lab=function(t){var e=t[0],n=t[1],i=t[2];return n/=100,i/=108.883,e=(e/=95.047)>.008856?Math.pow(e,1/3):7.787*e+16/116,[116*(n=n>.008856?Math.pow(n,1/3):7.787*n+16/116)-16,500*(e-n),200*(n-(i=i>.008856?Math.pow(i,1/3):7.787*i+16/116))]},a.lab.xyz=function(t){var e,n,i,a=t[0];e=t[1]/500+(n=(a+16)/116),i=n-t[2]/200;var r=Math.pow(n,3),o=Math.pow(e,3),s=Math.pow(i,3);return n=r>.008856?r:(n-16/116)/7.787,e=o>.008856?o:(e-16/116)/7.787,i=s>.008856?s:(i-16/116)/7.787,[e*=95.047,n*=100,i*=108.883]},a.lab.lch=function(t){var e,n=t[0],i=t[1],a=t[2];return(e=360*Math.atan2(a,i)/2/Math.PI)<0&&(e+=360),[n,Math.sqrt(i*i+a*a),e]},a.lch.lab=function(t){var e,n=t[0],i=t[1];return e=t[2]/360*2*Math.PI,[n,i*Math.cos(e),i*Math.sin(e)]},a.rgb.ansi16=function(t){var e=t[0],n=t[1],i=t[2],r=1 in arguments?arguments[1]:a.rgb.hsv(t)[2];if(0===(r=Math.round(r/50)))return 30;var o=30+(Math.round(i/255)<<2|Math.round(n/255)<<1|Math.round(e/255));return 2===r&&(o+=60),o},a.hsv.ansi16=function(t){return a.rgb.ansi16(a.hsv.rgb(t),t[2])},a.rgb.ansi256=function(t){var e=t[0],n=t[1],i=t[2];return e===n&&n===i?e<8?16:e>248?231:Math.round((e-8)/247*24)+232:16+36*Math.round(e/255*5)+6*Math.round(n/255*5)+Math.round(i/255*5)},a.ansi16.rgb=function(t){var e=t%10;if(0===e||7===e)return t>50&&(e+=3.5),[e=e/10.5*255,e,e];var n=.5*(1+~~(t>50));return[(1&e)*n*255,(e>>1&1)*n*255,(e>>2&1)*n*255]},a.ansi256.rgb=function(t){if(t>=232){var e=10*(t-232)+8;return[e,e,e]}var n;return t-=16,[Math.floor(t/36)/5*255,Math.floor((n=t%36)/6)/5*255,n%6/5*255]},a.rgb.hex=function(t){var e=(((255&Math.round(t[0]))<<16)+((255&Math.round(t[1]))<<8)+(255&Math.round(t[2]))).toString(16).toUpperCase();return"000000".substring(e.length)+e},a.hex.rgb=function(t){var e=t.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);if(!e)return[0,0,0];var n=e[0];3===e[0].length&&(n=n.split("").map((function(t){return t+t})).join(""));var i=parseInt(n,16);return[i>>16&255,i>>8&255,255&i]},a.rgb.hcg=function(t){var e,n=t[0]/255,i=t[1]/255,a=t[2]/255,r=Math.max(Math.max(n,i),a),o=Math.min(Math.min(n,i),a),s=r-o;return e=s<=0?0:r===n?(i-a)/s%6:r===i?2+(a-n)/s:4+(n-i)/s+4,e/=6,[360*(e%=1),100*s,100*(s<1?o/(1-s):0)]},a.hsl.hcg=function(t){var e=t[1]/100,n=t[2]/100,i=1,a=0;return(i=n<.5?2*e*n:2*e*(1-n))<1&&(a=(n-.5*i)/(1-i)),[t[0],100*i,100*a]},a.hsv.hcg=function(t){var e=t[1]/100,n=t[2]/100,i=e*n,a=0;return i<1&&(a=(n-i)/(1-i)),[t[0],100*i,100*a]},a.hcg.rgb=function(t){var e=t[0]/360,n=t[1]/100,i=t[2]/100;if(0===n)return[255*i,255*i,255*i];var a,r=[0,0,0],o=e%1*6,s=o%1,l=1-s;switch(Math.floor(o)){case 0:r[0]=1,r[1]=s,r[2]=0;break;case 1:r[0]=l,r[1]=1,r[2]=0;break;case 2:r[0]=0,r[1]=1,r[2]=s;break;case 3:r[0]=0,r[1]=l,r[2]=1;break;case 4:r[0]=s,r[1]=0,r[2]=1;break;default:r[0]=1,r[1]=0,r[2]=l}return a=(1-n)*i,[255*(n*r[0]+a),255*(n*r[1]+a),255*(n*r[2]+a)]},a.hcg.hsv=function(t){var e=t[1]/100,n=e+t[2]/100*(1-e),i=0;return n>0&&(i=e/n),[t[0],100*i,100*n]},a.hcg.hsl=function(t){var e=t[1]/100,n=t[2]/100*(1-e)+.5*e,i=0;return n>0&&n<.5?i=e/(2*n):n>=.5&&n<1&&(i=e/(2*(1-n))),[t[0],100*i,100*n]},a.hcg.hwb=function(t){var e=t[1]/100,n=e+t[2]/100*(1-e);return[t[0],100*(n-e),100*(1-n)]},a.hwb.hcg=function(t){var e=t[1]/100,n=1-t[2]/100,i=n-e,a=0;return i<1&&(a=(n-i)/(1-i)),[t[0],100*i,100*a]},a.apple.rgb=function(t){return[t[0]/65535*255,t[1]/65535*255,t[2]/65535*255]},a.rgb.apple=function(t){return[t[0]/255*65535,t[1]/255*65535,t[2]/255*65535]},a.gray.rgb=function(t){return[t[0]/100*255,t[0]/100*255,t[0]/100*255]},a.gray.hsl=a.gray.hsv=function(t){return[0,0,t[0]]},a.gray.hwb=function(t){return[0,100,t[0]]},a.gray.cmyk=function(t){return[0,0,0,t[0]]},a.gray.lab=function(t){return[t[0],0,0]},a.gray.hex=function(t){var e=255&Math.round(t[0]/100*255),n=((e<<16)+(e<<8)+e).toString(16).toUpperCase();return"000000".substring(n.length)+n},a.rgb.gray=function(t){return[(t[0]+t[1]+t[2])/3/255*100]}}));n.rgb,n.hsl,n.hsv,n.hwb,n.cmyk,n.xyz,n.lab,n.lch,n.hex,n.keyword,n.ansi16,n.ansi256,n.hcg,n.apple,n.gray;function i(t){var e=function(){for(var t={},e=Object.keys(n),i=e.length,a=0;a<i;a++)t[e[a]]={distance:-1,parent:null};return t}(),i=[t];for(e[t].distance=0;i.length;)for(var a=i.pop(),r=Object.keys(n[a]),o=r.length,s=0;s<o;s++){var l=r[s],u=e[l];-1===u.distance&&(u.distance=e[a].distance+1,u.parent=a,i.unshift(l))}return e}function a(t,e){return function(n){return e(t(n))}}function r(t,e){for(var i=[e[t].parent,t],r=n[e[t].parent][t],o=e[t].parent;e[o].parent;)i.unshift(e[o].parent),r=a(n[e[o].parent][o],r),o=e[o].parent;return r.conversion=i,r}var o={};Object.keys(n).forEach((function(t){o[t]={},Object.defineProperty(o[t],"channels",{value:n[t].channels}),Object.defineProperty(o[t],"labels",{value:n[t].labels});var e=function(t){for(var e=i(t),n={},a=Object.keys(e),o=a.length,s=0;s<o;s++){var l=a[s];null!==e[l].parent&&(n[l]=r(l,e))}return n}(t);Object.keys(e).forEach((function(n){var i=e[n];o[t][n]=function(t){var e=function(e){if(null==e)return e;arguments.length>1&&(e=Array.prototype.slice.call(arguments));var n=t(e);if("object"==typeof n)for(var i=n.length,a=0;a<i;a++)n[a]=Math.round(n[a]);return n};return"conversion"in t&&(e.conversion=t.conversion),e}(i),o[t][n].raw=function(t){var e=function(e){return null==e?e:(arguments.length>1&&(e=Array.prototype.slice.call(arguments)),t(e))};return"conversion"in t&&(e.conversion=t.conversion),e}(i)}))}));var s=o,l={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},u={getRgba:d,getHsla:h,getRgb:function(t){var e=d(t);return e&&e.slice(0,3)},getHsl:function(t){var e=h(t);return e&&e.slice(0,3)},getHwb:c,getAlpha:function(t){var e=d(t);if(e)return e[3];if(e=h(t))return e[3];if(e=c(t))return e[3]},hexString:function(t,e){e=void 0!==e&&3===t.length?e:t[3];return"#"+v(t[0])+v(t[1])+v(t[2])+(e>=0&&e<1?v(Math.round(255*e)):"")},rgbString:function(t,e){if(e<1||t[3]&&t[3]<1)return f(t,e);return"rgb("+t[0]+", "+t[1]+", "+t[2]+")"},rgbaString:f,percentString:function(t,e){if(e<1||t[3]&&t[3]<1)return g(t,e);var n=Math.round(t[0]/255*100),i=Math.round(t[1]/255*100),a=Math.round(t[2]/255*100);return"rgb("+n+"%, "+i+"%, "+a+"%)"},percentaString:g,hslString:function(t,e){if(e<1||t[3]&&t[3]<1)return p(t,e);return"hsl("+t[0]+", "+t[1]+"%, "+t[2]+"%)"},hslaString:p,hwbString:function(t,e){void 0===e&&(e=void 0!==t[3]?t[3]:1);return"hwb("+t[0]+", "+t[1]+"%, "+t[2]+"%"+(void 0!==e&&1!==e?", "+e:"")+")"},keyword:function(t){return b[t.slice(0,3)]}};function d(t){if(t){var e=[0,0,0],n=1,i=t.match(/^#([a-fA-F0-9]{3,4})$/i),a="";if(i){a=(i=i[1])[3];for(var r=0;r<e.length;r++)e[r]=parseInt(i[r]+i[r],16);a&&(n=Math.round(parseInt(a+a,16)/255*100)/100)}else if(i=t.match(/^#([a-fA-F0-9]{6}([a-fA-F0-9]{2})?)$/i)){a=i[2],i=i[1];for(r=0;r<e.length;r++)e[r]=parseInt(i.slice(2*r,2*r+2),16);a&&(n=Math.round(parseInt(a,16)/255*100)/100)}else if(i=t.match(/^rgba?\(\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/i)){for(r=0;r<e.length;r++)e[r]=parseInt(i[r+1]);n=parseFloat(i[4])}else if(i=t.match(/^rgba?\(\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/i)){for(r=0;r<e.length;r++)e[r]=Math.round(2.55*parseFloat(i[r+1]));n=parseFloat(i[4])}else if(i=t.match(/(\w+)/)){if("transparent"==i[1])return[0,0,0,0];if(!(e=l[i[1]]))return}for(r=0;r<e.length;r++)e[r]=m(e[r],0,255);return n=n||0==n?m(n,0,1):1,e[3]=n,e}}function h(t){if(t){var e=t.match(/^hsla?\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/);if(e){var n=parseFloat(e[4]);return[m(parseInt(e[1]),0,360),m(parseFloat(e[2]),0,100),m(parseFloat(e[3]),0,100),m(isNaN(n)?1:n,0,1)]}}}function c(t){if(t){var e=t.match(/^hwb\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/);if(e){var n=parseFloat(e[4]);return[m(parseInt(e[1]),0,360),m(parseFloat(e[2]),0,100),m(parseFloat(e[3]),0,100),m(isNaN(n)?1:n,0,1)]}}}function f(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"rgba("+t[0]+", "+t[1]+", "+t[2]+", "+e+")"}function g(t,e){return"rgba("+Math.round(t[0]/255*100)+"%, "+Math.round(t[1]/255*100)+"%, "+Math.round(t[2]/255*100)+"%, "+(e||t[3]||1)+")"}function p(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"hsla("+t[0]+", "+t[1]+"%, "+t[2]+"%, "+e+")"}function m(t,e,n){return Math.min(Math.max(e,t),n)}function v(t){var e=t.toString(16).toUpperCase();return e.length<2?"0"+e:e}var b={};for(var x in l)b[l[x]]=x;var y=function(t){return t instanceof y?t:this instanceof y?(this.valid=!1,this.values={rgb:[0,0,0],hsl:[0,0,0],hsv:[0,0,0],hwb:[0,0,0],cmyk:[0,0,0,0],alpha:1},void("string"==typeof t?(e=u.getRgba(t))?this.setValues("rgb",e):(e=u.getHsla(t))?this.setValues("hsl",e):(e=u.getHwb(t))&&this.setValues("hwb",e):"object"==typeof t&&(void 0!==(e=t).r||void 0!==e.red?this.setValues("rgb",e):void 0!==e.l||void 0!==e.lightness?this.setValues("hsl",e):void 0!==e.v||void 0!==e.value?this.setValues("hsv",e):void 0!==e.w||void 0!==e.whiteness?this.setValues("hwb",e):void 0===e.c&&void 0===e.cyan||this.setValues("cmyk",e)))):new y(t);var e};y.prototype={isValid:function(){return this.valid},rgb:function(){return this.setSpace("rgb",arguments)},hsl:function(){return this.setSpace("hsl",arguments)},hsv:function(){return this.setSpace("hsv",arguments)},hwb:function(){return this.setSpace("hwb",arguments)},cmyk:function(){return this.setSpace("cmyk",arguments)},rgbArray:function(){return this.values.rgb},hslArray:function(){return this.values.hsl},hsvArray:function(){return this.values.hsv},hwbArray:function(){var t=this.values;return 1!==t.alpha?t.hwb.concat([t.alpha]):t.hwb},cmykArray:function(){return this.values.cmyk},rgbaArray:function(){var t=this.values;return t.rgb.concat([t.alpha])},hslaArray:function(){var t=this.values;return t.hsl.concat([t.alpha])},alpha:function(t){return void 0===t?this.values.alpha:(this.setValues("alpha",t),this)},red:function(t){return this.setChannel("rgb",0,t)},green:function(t){return this.setChannel("rgb",1,t)},blue:function(t){return this.setChannel("rgb",2,t)},hue:function(t){return t&&(t=(t%=360)<0?360+t:t),this.setChannel("hsl",0,t)},saturation:function(t){return this.setChannel("hsl",1,t)},lightness:function(t){return this.setChannel("hsl",2,t)},saturationv:function(t){return this.setChannel("hsv",1,t)},whiteness:function(t){return this.setChannel("hwb",1,t)},blackness:function(t){return this.setChannel("hwb",2,t)},value:function(t){return this.setChannel("hsv",2,t)},cyan:function(t){return this.setChannel("cmyk",0,t)},magenta:function(t){return this.setChannel("cmyk",1,t)},yellow:function(t){return this.setChannel("cmyk",2,t)},black:function(t){return this.setChannel("cmyk",3,t)},hexString:function(){return u.hexString(this.values.rgb)},rgbString:function(){return u.rgbString(this.values.rgb,this.values.alpha)},rgbaString:function(){return u.rgbaString(this.values.rgb,this.values.alpha)},percentString:function(){return u.percentString(this.values.rgb,this.values.alpha)},hslString:function(){return u.hslString(this.values.hsl,this.values.alpha)},hslaString:function(){return u.hslaString(this.values.hsl,this.values.alpha)},hwbString:function(){return u.hwbString(this.values.hwb,this.values.alpha)},keyword:function(){return u.keyword(this.values.rgb,this.values.alpha)},rgbNumber:function(){var t=this.values.rgb;return t[0]<<16|t[1]<<8|t[2]},luminosity:function(){for(var t=this.values.rgb,e=[],n=0;n<t.length;n++){var i=t[n]/255;e[n]=i<=.03928?i/12.92:Math.pow((i+.055)/1.055,2.4)}return.2126*e[0]+.7152*e[1]+.0722*e[2]},contrast:function(t){var e=this.luminosity(),n=t.luminosity();return e>n?(e+.05)/(n+.05):(n+.05)/(e+.05)},level:function(t){var e=this.contrast(t);return e>=7.1?"AAA":e>=4.5?"AA":""},dark:function(){var t=this.values.rgb;return(299*t[0]+587*t[1]+114*t[2])/1e3<128},light:function(){return!this.dark()},negate:function(){for(var t=[],e=0;e<3;e++)t[e]=255-this.values.rgb[e];return this.setValues("rgb",t),this},lighten:function(t){var e=this.values.hsl;return e[2]+=e[2]*t,this.setValues("hsl",e),this},darken:function(t){var e=this.values.hsl;return e[2]-=e[2]*t,this.setValues("hsl",e),this},saturate:function(t){var e=this.values.hsl;return e[1]+=e[1]*t,this.setValues("hsl",e),this},desaturate:function(t){var e=this.values.hsl;return e[1]-=e[1]*t,this.setValues("hsl",e),this},whiten:function(t){var e=this.values.hwb;return e[1]+=e[1]*t,this.setValues("hwb",e),this},blacken:function(t){var e=this.values.hwb;return e[2]+=e[2]*t,this.setValues("hwb",e),this},greyscale:function(){var t=this.values.rgb,e=.3*t[0]+.59*t[1]+.11*t[2];return this.setValues("rgb",[e,e,e]),this},clearer:function(t){var e=this.values.alpha;return this.setValues("alpha",e-e*t),this},opaquer:function(t){var e=this.values.alpha;return this.setValues("alpha",e+e*t),this},rotate:function(t){var e=this.values.hsl,n=(e[0]+t)%360;return e[0]=n<0?360+n:n,this.setValues("hsl",e),this},mix:function(t,e){var n=t,i=void 0===e?.5:e,a=2*i-1,r=this.alpha()-n.alpha(),o=((a*r==-1?a:(a+r)/(1+a*r))+1)/2,s=1-o;return this.rgb(o*this.red()+s*n.red(),o*this.green()+s*n.green(),o*this.blue()+s*n.blue()).alpha(this.alpha()*i+n.alpha()*(1-i))},toJSON:function(){return this.rgb()},clone:function(){var t,e,n=new y,i=this.values,a=n.values;for(var r in i)i.hasOwnProperty(r)&&(t=i[r],"[object Array]"===(e={}.toString.call(t))?a[r]=t.slice(0):"[object Number]"===e?a[r]=t:console.error("unexpected color value:",t));return n}},y.prototype.spaces={rgb:["red","green","blue"],hsl:["hue","saturation","lightness"],hsv:["hue","saturation","value"],hwb:["hue","whiteness","blackness"],cmyk:["cyan","magenta","yellow","black"]},y.prototype.maxes={rgb:[255,255,255],hsl:[360,100,100],hsv:[360,100,100],hwb:[360,100,100],cmyk:[100,100,100,100]},y.prototype.getValues=function(t){for(var e=this.values,n={},i=0;i<t.length;i++)n[t.charAt(i)]=e[t][i];return 1!==e.alpha&&(n.a=e.alpha),n},y.prototype.setValues=function(t,e){var n,i,a=this.values,r=this.spaces,o=this.maxes,l=1;if(this.valid=!0,"alpha"===t)l=e;else if(e.length)a[t]=e.slice(0,t.length),l=e[t.length];else if(void 0!==e[t.charAt(0)]){for(n=0;n<t.length;n++)a[t][n]=e[t.charAt(n)];l=e.a}else if(void 0!==e[r[t][0]]){var u=r[t];for(n=0;n<t.length;n++)a[t][n]=e[u[n]];l=e.alpha}if(a.alpha=Math.max(0,Math.min(1,void 0===l?a.alpha:l)),"alpha"===t)return!1;for(n=0;n<t.length;n++)i=Math.max(0,Math.min(o[t][n],a[t][n])),a[t][n]=Math.round(i);for(var d in r)d!==t&&(a[d]=s[t][d](a[t]));return!0},y.prototype.setSpace=function(t,e){var n=e[0];return void 0===n?this.getValues(t):("number"==typeof n&&(n=Array.prototype.slice.call(e)),this.setValues(t,n),this)},y.prototype.setChannel=function(t,e,n){var i=this.values[t];return void 0===n?i[e]:n===i[e]?this:(i[e]=n,this.setValues(t,i),this)},"undefined"!=typeof window&&(window.Color=y);var _=y;function k(t){return-1===["__proto__","prototype","constructor"].indexOf(t)}var w,M={noop:function(){},uid:(w=0,function(){return w++}),isNullOrUndef:function(t){return null==t},isArray:function(t){if(Array.isArray&&Array.isArray(t))return!0;var e=Object.prototype.toString.call(t);return"[object"===e.substr(0,7)&&"Array]"===e.substr(-6)},isObject:function(t){return null!==t&&"[object Object]"===Object.prototype.toString.call(t)},isFinite:function(t){return("number"==typeof t||t instanceof Number)&&isFinite(t)},valueOrDefault:function(t,e){return void 0===t?e:t},valueAtIndexOrDefault:function(t,e,n){return M.valueOrDefault(M.isArray(t)?t[e]:t,n)},callback:function(t,e,n){if(t&&"function"==typeof t.call)return t.apply(n,e)},each:function(t,e,n,i){var a,r,o;if(M.isArray(t))if(r=t.length,i)for(a=r-1;a>=0;a--)e.call(n,t[a],a);else for(a=0;a<r;a++)e.call(n,t[a],a);else if(M.isObject(t))for(r=(o=Object.keys(t)).length,a=0;a<r;a++)e.call(n,t[o[a]],o[a])},arrayEquals:function(t,e){var n,i,a,r;if(!t||!e||t.length!==e.length)return!1;for(n=0,i=t.length;n<i;++n)if(a=t[n],r=e[n],a instanceof Array&&r instanceof Array){if(!M.arrayEquals(a,r))return!1}else if(a!==r)return!1;return!0},clone:function(t){if(M.isArray(t))return t.map(M.clone);if(M.isObject(t)){for(var e=Object.create(t),n=Object.keys(t),i=n.length,a=0;a<i;++a)e[n[a]]=M.clone(t[n[a]]);return e}return t},_merger:function(t,e,n,i){if(k(t)){var a=e[t],r=n[t];M.isObject(a)&&M.isObject(r)?M.merge(a,r,i):e[t]=M.clone(r)}},_mergerIf:function(t,e,n){if(k(t)){var i=e[t],a=n[t];M.isObject(i)&&M.isObject(a)?M.mergeIf(i,a):e.hasOwnProperty(t)||(e[t]=M.clone(a))}},merge:function(t,e,n){var i,a,r,o,s,l=M.isArray(e)?e:[e],u=l.length;if(!M.isObject(t))return t;for(i=(n=n||{}).merger||M._merger,a=0;a<u;++a)if(e=l[a],M.isObject(e))for(s=0,o=(r=Object.keys(e)).length;s<o;++s)i(r[s],t,e,n);return t},mergeIf:function(t,e){return M.merge(t,e,{merger:M._mergerIf})},extend:Object.assign||function(t){return M.merge(t,[].slice.call(arguments,1),{merger:function(t,e,n){e[t]=n[t]}})},inherits:function(t){var e=this,n=t&&t.hasOwnProperty("constructor")?t.constructor:function(){return e.apply(this,arguments)},i=function(){this.constructor=n};return i.prototype=e.prototype,n.prototype=new i,n.extend=M.inherits,t&&M.extend(n.prototype,t),n.__super__=e.prototype,n},_deprecated:function(t,e,n,i){void 0!==e&&console.warn(t+': "'+n+'" is deprecated. Please use "'+i+'" instead')}},S=M;M.callCallback=M.callback,M.indexOf=function(t,e,n){return Array.prototype.indexOf.call(t,e,n)},M.getValueOrDefault=M.valueOrDefault,M.getValueAtIndexOrDefault=M.valueAtIndexOrDefault;var C={linear:function(t){return t},easeInQuad:function(t){return t*t},easeOutQuad:function(t){return-t*(t-2)},easeInOutQuad:function(t){return(t/=.5)<1?.5*t*t:-.5*(--t*(t-2)-1)},easeInCubic:function(t){return t*t*t},easeOutCubic:function(t){return(t-=1)*t*t+1},easeInOutCubic:function(t){return(t/=.5)<1?.5*t*t*t:.5*((t-=2)*t*t+2)},easeInQuart:function(t){return t*t*t*t},easeOutQuart:function(t){return-((t-=1)*t*t*t-1)},easeInOutQuart:function(t){return(t/=.5)<1?.5*t*t*t*t:-.5*((t-=2)*t*t*t-2)},easeInQuint:function(t){return t*t*t*t*t},easeOutQuint:function(t){return(t-=1)*t*t*t*t+1},easeInOutQuint:function(t){return(t/=.5)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2)},easeInSine:function(t){return 1-Math.cos(t*(Math.PI/2))},easeOutSine:function(t){return Math.sin(t*(Math.PI/2))},easeInOutSine:function(t){return-.5*(Math.cos(Math.PI*t)-1)},easeInExpo:function(t){return 0===t?0:Math.pow(2,10*(t-1))},easeOutExpo:function(t){return 1===t?1:1-Math.pow(2,-10*t)},easeInOutExpo:function(t){return 0===t?0:1===t?1:(t/=.5)<1?.5*Math.pow(2,10*(t-1)):.5*(2-Math.pow(2,-10*--t))},easeInCirc:function(t){return t>=1?t:-(Math.sqrt(1-t*t)-1)},easeOutCirc:function(t){return Math.sqrt(1-(t-=1)*t)},easeInOutCirc:function(t){return(t/=.5)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},easeInElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:1===t?1:(n||(n=.3),i<1?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),-i*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/n))},easeOutElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:1===t?1:(n||(n=.3),i<1?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),i*Math.pow(2,-10*t)*Math.sin((t-e)*(2*Math.PI)/n)+1)},easeInOutElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:2==(t/=.5)?1:(n||(n=.45),i<1?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),t<1?i*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/n)*-.5:i*Math.pow(2,-10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/n)*.5+1)},easeInBack:function(t){var e=1.70158;return t*t*((e+1)*t-e)},easeOutBack:function(t){var e=1.70158;return(t-=1)*t*((e+1)*t+e)+1},easeInOutBack:function(t){var e=1.70158;return(t/=.5)<1?t*t*((1+(e*=1.525))*t-e)*.5:.5*((t-=2)*t*((1+(e*=1.525))*t+e)+2)},easeInBounce:function(t){return 1-C.easeOutBounce(1-t)},easeOutBounce:function(t){return t<1/2.75?7.5625*t*t:t<2/2.75?7.5625*(t-=1.5/2.75)*t+.75:t<2.5/2.75?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375},easeInOutBounce:function(t){return t<.5?.5*C.easeInBounce(2*t):.5*C.easeOutBounce(2*t-1)+.5}},P={effects:C};S.easingEffects=C;var A=Math.PI,D=A/180,T=2*A,I=A/2,F=A/4,O=2*A/3,L={clear:function(t){t.ctx.clearRect(0,0,t.width,t.height)},roundedRect:function(t,e,n,i,a,r){if(r){var o=Math.min(r,a/2,i/2),s=e+o,l=n+o,u=e+i-o,d=n+a-o;t.moveTo(e,l),s<u&&l<d?(t.arc(s,l,o,-A,-I),t.arc(u,l,o,-I,0),t.arc(u,d,o,0,I),t.arc(s,d,o,I,A)):s<u?(t.moveTo(s,n),t.arc(u,l,o,-I,I),t.arc(s,l,o,I,A+I)):l<d?(t.arc(s,l,o,-A,0),t.arc(s,d,o,0,A)):t.arc(s,l,o,-A,A),t.closePath(),t.moveTo(e,n)}else t.rect(e,n,i,a)},drawPoint:function(t,e,n,i,a,r){var o,s,l,u,d,h=(r||0)*D;if(e&&"object"==typeof e&&("[object HTMLImageElement]"===(o=e.toString())||"[object HTMLCanvasElement]"===o))return t.save(),t.translate(i,a),t.rotate(h),t.drawImage(e,-e.width/2,-e.height/2,e.width,e.height),void t.restore();if(!(isNaN(n)||n<=0)){switch(t.beginPath(),e){default:t.arc(i,a,n,0,T),t.closePath();break;case"triangle":t.moveTo(i+Math.sin(h)*n,a-Math.cos(h)*n),h+=O,t.lineTo(i+Math.sin(h)*n,a-Math.cos(h)*n),h+=O,t.lineTo(i+Math.sin(h)*n,a-Math.cos(h)*n),t.closePath();break;case"rectRounded":u=n-(d=.516*n),s=Math.cos(h+F)*u,l=Math.sin(h+F)*u,t.arc(i-s,a-l,d,h-A,h-I),t.arc(i+l,a-s,d,h-I,h),t.arc(i+s,a+l,d,h,h+I),t.arc(i-l,a+s,d,h+I,h+A),t.closePath();break;case"rect":if(!r){u=Math.SQRT1_2*n,t.rect(i-u,a-u,2*u,2*u);break}h+=F;case"rectRot":s=Math.cos(h)*n,l=Math.sin(h)*n,t.moveTo(i-s,a-l),t.lineTo(i+l,a-s),t.lineTo(i+s,a+l),t.lineTo(i-l,a+s),t.closePath();break;case"crossRot":h+=F;case"cross":s=Math.cos(h)*n,l=Math.sin(h)*n,t.moveTo(i-s,a-l),t.lineTo(i+s,a+l),t.moveTo(i+l,a-s),t.lineTo(i-l,a+s);break;case"star":s=Math.cos(h)*n,l=Math.sin(h)*n,t.moveTo(i-s,a-l),t.lineTo(i+s,a+l),t.moveTo(i+l,a-s),t.lineTo(i-l,a+s),h+=F,s=Math.cos(h)*n,l=Math.sin(h)*n,t.moveTo(i-s,a-l),t.lineTo(i+s,a+l),t.moveTo(i+l,a-s),t.lineTo(i-l,a+s);break;case"line":s=Math.cos(h)*n,l=Math.sin(h)*n,t.moveTo(i-s,a-l),t.lineTo(i+s,a+l);break;case"dash":t.moveTo(i,a),t.lineTo(i+Math.cos(h)*n,a+Math.sin(h)*n)}t.fill(),t.stroke()}},_isPointInArea:function(t,e){return t.x>e.left-1e-6&&t.x<e.right+1e-6&&t.y>e.top-1e-6&&t.y<e.bottom+1e-6},clipArea:function(t,e){t.save(),t.beginPath(),t.rect(e.left,e.top,e.right-e.left,e.bottom-e.top),t.clip()},unclipArea:function(t){t.restore()},lineTo:function(t,e,n,i){var a=n.steppedLine;if(a){if("middle"===a){var r=(e.x+n.x)/2;t.lineTo(r,i?n.y:e.y),t.lineTo(r,i?e.y:n.y)}else"after"===a&&!i||"after"!==a&&i?t.lineTo(e.x,n.y):t.lineTo(n.x,e.y);t.lineTo(n.x,n.y)}else n.tension?t.bezierCurveTo(i?e.controlPointPreviousX:e.controlPointNextX,i?e.controlPointPreviousY:e.controlPointNextY,i?n.controlPointNextX:n.controlPointPreviousX,i?n.controlPointNextY:n.controlPointPreviousY,n.x,n.y):t.lineTo(n.x,n.y)}},R=L;S.clear=L.clear,S.drawRoundedRectangle=function(t){t.beginPath(),L.roundedRect.apply(L,arguments)};var z={_set:function(t,e){return S.merge(this[t]||(this[t]={}),e)}};z._set("global",{defaultColor:"rgba(0,0,0,0.1)",defaultFontColor:"#666",defaultFontFamily:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",defaultFontSize:12,defaultFontStyle:"normal",defaultLineHeight:1.2,showLines:!0});var N=z,B=S.valueOrDefault;var E={toLineHeight:function(t,e){var n=(""+t).match(/^(normal|(\d+(?:\.\d+)?)(px|em|%)?)$/);if(!n||"normal"===n[1])return 1.2*e;switch(t=+n[2],n[3]){case"px":return t;case"%":t/=100}return e*t},toPadding:function(t){var e,n,i,a;return S.isObject(t)?(e=+t.top||0,n=+t.right||0,i=+t.bottom||0,a=+t.left||0):e=n=i=a=+t||0,{top:e,right:n,bottom:i,left:a,height:e+i,width:a+n}},_parseFont:function(t){var e=N.global,n=B(t.fontSize,e.defaultFontSize),i={family:B(t.fontFamily,e.defaultFontFamily),lineHeight:S.options.toLineHeight(B(t.lineHeight,e.defaultLineHeight),n),size:n,style:B(t.fontStyle,e.defaultFontStyle),weight:null,string:""};return i.string=function(t){return!t||S.isNullOrUndef(t.size)||S.isNullOrUndef(t.family)?null:(t.style?t.style+" ":"")+(t.weight?t.weight+" ":"")+t.size+"px "+t.family}(i),i},resolve:function(t,e,n,i){var a,r,o,s=!0;for(a=0,r=t.length;a<r;++a)if(void 0!==(o=t[a])&&(void 0!==e&&"function"==typeof o&&(o=o(e),s=!1),void 0!==n&&S.isArray(o)&&(o=o[n],s=!1),void 0!==o))return i&&!s&&(i.cacheable=!1),o}},W={_factorize:function(t){var e,n=[],i=Math.sqrt(t);for(e=1;e<i;e++)t%e==0&&(n.push(e),n.push(t/e));return i===(0|i)&&n.push(i),n.sort((function(t,e){return t-e})).pop(),n},log10:Math.log10||function(t){var e=Math.log(t)*Math.LOG10E,n=Math.round(e);return t===Math.pow(10,n)?n:e}},V=W;S.log10=W.log10;var H=S,j=P,q=R,U=E,Y=V,G={getRtlAdapter:function(t,e,n){return t?function(t,e){return{x:function(n){return t+t+e-n},setWidth:function(t){e=t},textAlign:function(t){return"center"===t?t:"right"===t?"left":"right"},xPlus:function(t,e){return t-e},leftForLtr:function(t,e){return t-e}}}(e,n):{x:function(t){return t},setWidth:function(t){},textAlign:function(t){return t},xPlus:function(t,e){return t+e},leftForLtr:function(t,e){return t}}},overrideTextDirection:function(t,e){var n,i;"ltr"!==e&&"rtl"!==e||(i=[(n=t.canvas.style).getPropertyValue("direction"),n.getPropertyPriority("direction")],n.setProperty("direction",e,"important"),t.prevTextDirection=i)},restoreTextDirection:function(t){var e=t.prevTextDirection;void 0!==e&&(delete t.prevTextDirection,t.canvas.style.setProperty("direction",e[0],e[1]))}};H.easing=j,H.canvas=q,H.options=U,H.math=Y,H.rtl=G;var X=function(t){H.extend(this,t),this.initialize.apply(this,arguments)};H.extend(X.prototype,{_type:void 0,initialize:function(){this.hidden=!1},pivot:function(){var t=this;return t._view||(t._view=H.extend({},t._model)),t._start={},t},transition:function(t){var e=this,n=e._model,i=e._start,a=e._view;return n&&1!==t?(a||(a=e._view={}),i||(i=e._start={}),function(t,e,n,i){var a,r,o,s,l,u,d,h,c,f=Object.keys(n);for(a=0,r=f.length;a<r;++a)if(u=n[o=f[a]],e.hasOwnProperty(o)||(e[o]=u),(s=e[o])!==u&&"_"!==o[0]){if(t.hasOwnProperty(o)||(t[o]=s),(d=typeof u)===typeof(l=t[o]))if("string"===d){if((h=_(l)).valid&&(c=_(u)).valid){e[o]=c.mix(h,i).rgbString();continue}}else if(H.isFinite(l)&&H.isFinite(u)){e[o]=l+(u-l)*i;continue}e[o]=u}}(i,a,n,t),e):(e._view=H.extend({},n),e._start=null,e)},tooltipPosition:function(){return{x:this._model.x,y:this._model.y}},hasValue:function(){return H.isNumber(this._model.x)&&H.isNumber(this._model.y)}}),X.extend=H.inherits;var K=X,Z=K.extend({chart:null,currentStep:0,numSteps:60,easing:"",render:null,onAnimationProgress:null,onAnimationComplete:null}),$=Z;Object.defineProperty(Z.prototype,"animationObject",{get:function(){return this}}),Object.defineProperty(Z.prototype,"chartInstance",{get:function(){return this.chart},set:function(t){this.chart=t}}),N._set("global",{animation:{duration:1e3,easing:"easeOutQuart",onProgress:H.noop,onComplete:H.noop}});var J={animations:[],request:null,addAnimation:function(t,e,n,i){var a,r,o=this.animations;for(e.chart=t,e.startTime=Date.now(),e.duration=n,i||(t.animating=!0),a=0,r=o.length;a<r;++a)if(o[a].chart===t)return void(o[a]=e);o.push(e),1===o.length&&this.requestAnimationFrame()},cancelAnimation:function(t){var e=H.findIndex(this.animations,(function(e){return e.chart===t}));-1!==e&&(this.animations.splice(e,1),t.animating=!1)},requestAnimationFrame:function(){var t=this;null===t.request&&(t.request=H.requestAnimFrame.call(window,(function(){t.request=null,t.startDigest()})))},startDigest:function(){this.advance(),this.animations.length>0&&this.requestAnimationFrame()},advance:function(){for(var t,e,n,i,a=this.animations,r=0;r<a.length;)e=(t=a[r]).chart,n=t.numSteps,i=Math.floor((Date.now()-t.startTime)/t.duration*n)+1,t.currentStep=Math.min(i,n),H.callback(t.render,[e,t],e),H.callback(t.onAnimationProgress,[t],e),t.currentStep>=n?(H.callback(t.onAnimationComplete,[t],e),e.animating=!1,a.splice(r,1)):++r}},Q=H.options.resolve,tt=["push","pop","shift","splice","unshift"];function et(t,e){var n=t._chartjs;if(n){var i=n.listeners,a=i.indexOf(e);-1!==a&&i.splice(a,1),i.length>0||(tt.forEach((function(e){delete t[e]})),delete t._chartjs)}}var nt=function(t,e){this.initialize(t,e)};H.extend(nt.prototype,{datasetElementType:null,dataElementType:null,_datasetElementOptions:["backgroundColor","borderCapStyle","borderColor","borderDash","borderDashOffset","borderJoinStyle","borderWidth"],_dataElementOptions:["backgroundColor","borderColor","borderWidth","pointStyle"],initialize:function(t,e){var n=this;n.chart=t,n.index=e,n.linkScales(),n.addElements(),n._type=n.getMeta().type},updateIndex:function(t){this.index=t},linkScales:function(){var t=this.getMeta(),e=this.chart,n=e.scales,i=this.getDataset(),a=e.options.scales;null!==t.xAxisID&&t.xAxisID in n&&!i.xAxisID||(t.xAxisID=i.xAxisID||a.xAxes[0].id),null!==t.yAxisID&&t.yAxisID in n&&!i.yAxisID||(t.yAxisID=i.yAxisID||a.yAxes[0].id)},getDataset:function(){return this.chart.data.datasets[this.index]},getMeta:function(){return this.chart.getDatasetMeta(this.index)},getScaleForId:function(t){return this.chart.scales[t]},_getValueScaleId:function(){return this.getMeta().yAxisID},_getIndexScaleId:function(){return this.getMeta().xAxisID},_getValueScale:function(){return this.getScaleForId(this._getValueScaleId())},_getIndexScale:function(){return this.getScaleForId(this._getIndexScaleId())},reset:function(){this._update(!0)},destroy:function(){this._data&&et(this._data,this)},createMetaDataset:function(){var t=this.datasetElementType;return t&&new t({_chart:this.chart,_datasetIndex:this.index})},createMetaData:function(t){var e=this.dataElementType;return e&&new e({_chart:this.chart,_datasetIndex:this.index,_index:t})},addElements:function(){var t,e,n=this.getMeta(),i=this.getDataset().data||[],a=n.data;for(t=0,e=i.length;t<e;++t)a[t]=a[t]||this.createMetaData(t);n.dataset=n.dataset||this.createMetaDataset()},addElementAndReset:function(t){var e=this.createMetaData(t);this.getMeta().data.splice(t,0,e),this.updateElement(e,t,!0)},buildOrUpdateElements:function(){var t,e,n=this,i=n.getDataset(),a=i.data||(i.data=[]);n._data!==a&&(n._data&&et(n._data,n),a&&Object.isExtensible(a)&&(e=n,(t=a)._chartjs?t._chartjs.listeners.push(e):(Object.defineProperty(t,"_chartjs",{configurable:!0,enumerable:!1,value:{listeners:[e]}}),tt.forEach((function(e){var n="onData"+e.charAt(0).toUpperCase()+e.slice(1),i=t[e];Object.defineProperty(t,e,{configurable:!0,enumerable:!1,value:function(){var e=Array.prototype.slice.call(arguments),a=i.apply(this,e);return H.each(t._chartjs.listeners,(function(t){"function"==typeof t[n]&&t[n].apply(t,e)})),a}})})))),n._data=a),n.resyncElements()},_configure:function(){this._config=H.merge(Object.create(null),[this.chart.options.datasets[this._type],this.getDataset()],{merger:function(t,e,n){"_meta"!==t&&"data"!==t&&H._merger(t,e,n)}})},_update:function(t){this._configure(),this._cachedDataOpts=null,this.update(t)},update:H.noop,transition:function(t){for(var e=this.getMeta(),n=e.data||[],i=n.length,a=0;a<i;++a)n[a].transition(t);e.dataset&&e.dataset.transition(t)},draw:function(){var t=this.getMeta(),e=t.data||[],n=e.length,i=0;for(t.dataset&&t.dataset.draw();i<n;++i)e[i].draw()},getStyle:function(t){var e,n=this.getMeta(),i=n.dataset;return this._configure(),i&&void 0===t?e=this._resolveDatasetElementOptions(i||{}):(t=t||0,e=this._resolveDataElementOptions(n.data[t]||{},t)),!1!==e.fill&&null!==e.fill||(e.backgroundColor=e.borderColor),e},_resolveDatasetElementOptions:function(t,e){var n,i,a,r,o=this,s=o.chart,l=o._config,u=t.custom||{},d=s.options.elements[o.datasetElementType.prototype._type]||{},h=o._datasetElementOptions,c={},f={chart:s,dataset:o.getDataset(),datasetIndex:o.index,hover:e};for(n=0,i=h.length;n<i;++n)a=h[n],r=e?"hover"+a.charAt(0).toUpperCase()+a.slice(1):a,c[a]=Q([u[r],l[r],d[r]],f);return c},_resolveDataElementOptions:function(t,e){var n=this,i=t&&t.custom,a=n._cachedDataOpts;if(a&&!i)return a;var r,o,s,l,u=n.chart,d=n._config,h=u.options.elements[n.dataElementType.prototype._type]||{},c=n._dataElementOptions,f={},g={chart:u,dataIndex:e,dataset:n.getDataset(),datasetIndex:n.index},p={cacheable:!i};if(i=i||{},H.isArray(c))for(o=0,s=c.length;o<s;++o)f[l=c[o]]=Q([i[l],d[l],h[l]],g,e,p);else for(o=0,s=(r=Object.keys(c)).length;o<s;++o)f[l=r[o]]=Q([i[l],d[c[l]],d[l],h[l]],g,e,p);return p.cacheable&&(n._cachedDataOpts=Object.freeze(f)),f},removeHoverStyle:function(t){H.merge(t._model,t.$previousStyle||{}),delete t.$previousStyle},setHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],n=t._index,i=t.custom||{},a=t._model,r=H.getHoverColor;t.$previousStyle={backgroundColor:a.backgroundColor,borderColor:a.borderColor,borderWidth:a.borderWidth},a.backgroundColor=Q([i.hoverBackgroundColor,e.hoverBackgroundColor,r(a.backgroundColor)],void 0,n),a.borderColor=Q([i.hoverBorderColor,e.hoverBorderColor,r(a.borderColor)],void 0,n),a.borderWidth=Q([i.hoverBorderWidth,e.hoverBorderWidth,a.borderWidth],void 0,n)},_removeDatasetHoverStyle:function(){var t=this.getMeta().dataset;t&&this.removeHoverStyle(t)},_setDatasetHoverStyle:function(){var t,e,n,i,a,r,o=this.getMeta().dataset,s={};if(o){for(r=o._model,a=this._resolveDatasetElementOptions(o,!0),t=0,e=(i=Object.keys(a)).length;t<e;++t)s[n=i[t]]=r[n],r[n]=a[n];o.$previousStyle=s}},resyncElements:function(){var t=this.getMeta(),e=this.getDataset().data,n=t.data.length,i=e.length;i<n?t.data.splice(i,n-i):i>n&&this.insertElements(n,i-n)},insertElements:function(t,e){for(var n=0;n<e;++n)this.addElementAndReset(t+n)},onDataPush:function(){var t=arguments.length;this.insertElements(this.getDataset().data.length-t,t)},onDataPop:function(){this.getMeta().data.pop()},onDataShift:function(){this.getMeta().data.shift()},onDataSplice:function(t,e){this.getMeta().data.splice(t,e),this.insertElements(t,arguments.length-2)},onDataUnshift:function(){this.insertElements(0,arguments.length)}}),nt.extend=H.inherits;var it=nt,at=2*Math.PI;function rt(t,e){var n=e.startAngle,i=e.endAngle,a=e.pixelMargin,r=a/e.outerRadius,o=e.x,s=e.y;t.beginPath(),t.arc(o,s,e.outerRadius,n-r,i+r),e.innerRadius>a?(r=a/e.innerRadius,t.arc(o,s,e.innerRadius-a,i+r,n-r,!0)):t.arc(o,s,a,i+Math.PI/2,n-Math.PI/2),t.closePath(),t.clip()}function ot(t,e,n){var i="inner"===e.borderAlign;i?(t.lineWidth=2*e.borderWidth,t.lineJoin="round"):(t.lineWidth=e.borderWidth,t.lineJoin="bevel"),n.fullCircles&&function(t,e,n,i){var a,r=n.endAngle;for(i&&(n.endAngle=n.startAngle+at,rt(t,n),n.endAngle=r,n.endAngle===n.startAngle&&n.fullCircles&&(n.endAngle+=at,n.fullCircles--)),t.beginPath(),t.arc(n.x,n.y,n.innerRadius,n.startAngle+at,n.startAngle,!0),a=0;a<n.fullCircles;++a)t.stroke();for(t.beginPath(),t.arc(n.x,n.y,e.outerRadius,n.startAngle,n.startAngle+at),a=0;a<n.fullCircles;++a)t.stroke()}(t,e,n,i),i&&rt(t,n),t.beginPath(),t.arc(n.x,n.y,e.outerRadius,n.startAngle,n.endAngle),t.arc(n.x,n.y,n.innerRadius,n.endAngle,n.startAngle,!0),t.closePath(),t.stroke()}N._set("global",{elements:{arc:{backgroundColor:N.global.defaultColor,borderColor:"#fff",borderWidth:2,borderAlign:"center"}}});var st=K.extend({_type:"arc",inLabelRange:function(t){var e=this._view;return!!e&&Math.pow(t-e.x,2)<Math.pow(e.radius+e.hoverRadius,2)},inRange:function(t,e){var n=this._view;if(n){for(var i=H.getAngleFromPoint(n,{x:t,y:e}),a=i.angle,r=i.distance,o=n.startAngle,s=n.endAngle;s<o;)s+=at;for(;a>s;)a-=at;for(;a<o;)a+=at;var l=a>=o&&a<=s,u=r>=n.innerRadius&&r<=n.outerRadius;return l&&u}return!1},getCenterPoint:function(){var t=this._view,e=(t.startAngle+t.endAngle)/2,n=(t.innerRadius+t.outerRadius)/2;return{x:t.x+Math.cos(e)*n,y:t.y+Math.sin(e)*n}},getArea:function(){var t=this._view;return Math.PI*((t.endAngle-t.startAngle)/(2*Math.PI))*(Math.pow(t.outerRadius,2)-Math.pow(t.innerRadius,2))},tooltipPosition:function(){var t=this._view,e=t.startAngle+(t.endAngle-t.startAngle)/2,n=(t.outerRadius-t.innerRadius)/2+t.innerRadius;return{x:t.x+Math.cos(e)*n,y:t.y+Math.sin(e)*n}},draw:function(){var t,e=this._chart.ctx,n=this._view,i="inner"===n.borderAlign?.33:0,a={x:n.x,y:n.y,innerRadius:n.innerRadius,outerRadius:Math.max(n.outerRadius-i,0),pixelMargin:i,startAngle:n.startAngle,endAngle:n.endAngle,fullCircles:Math.floor(n.circumference/at)};if(e.save(),e.fillStyle=n.backgroundColor,e.strokeStyle=n.borderColor,a.fullCircles){for(a.endAngle=a.startAngle+at,e.beginPath(),e.arc(a.x,a.y,a.outerRadius,a.startAngle,a.endAngle),e.arc(a.x,a.y,a.innerRadius,a.endAngle,a.startAngle,!0),e.closePath(),t=0;t<a.fullCircles;++t)e.fill();a.endAngle=a.startAngle+n.circumference%at}e.beginPath(),e.arc(a.x,a.y,a.outerRadius,a.startAngle,a.endAngle),e.arc(a.x,a.y,a.innerRadius,a.endAngle,a.startAngle,!0),e.closePath(),e.fill(),n.borderWidth&&ot(e,n,a),e.restore()}}),lt=H.valueOrDefault,ut=N.global.defaultColor;N._set("global",{elements:{line:{tension:.4,backgroundColor:ut,borderWidth:3,borderColor:ut,borderCapStyle:"butt",borderDash:[],borderDashOffset:0,borderJoinStyle:"miter",capBezierPoints:!0,fill:!0}}});var dt=K.extend({_type:"line",draw:function(){var t,e,n,i=this,a=i._view,r=i._chart.ctx,o=a.spanGaps,s=i._children.slice(),l=N.global,u=l.elements.line,d=-1,h=i._loop;if(s.length){if(i._loop){for(t=0;t<s.length;++t)if(e=H.previousItem(s,t),!s[t]._view.skip&&e._view.skip){s=s.slice(t).concat(s.slice(0,t)),h=o;break}h&&s.push(s[0])}for(r.save(),r.lineCap=a.borderCapStyle||u.borderCapStyle,r.setLineDash&&r.setLineDash(a.borderDash||u.borderDash),r.lineDashOffset=lt(a.borderDashOffset,u.borderDashOffset),r.lineJoin=a.borderJoinStyle||u.borderJoinStyle,r.lineWidth=lt(a.borderWidth,u.borderWidth),r.strokeStyle=a.borderColor||l.defaultColor,r.beginPath(),(n=s[0]._view).skip||(r.moveTo(n.x,n.y),d=0),t=1;t<s.length;++t)n=s[t]._view,e=-1===d?H.previousItem(s,t):s[d],n.skip||(d!==t-1&&!o||-1===d?r.moveTo(n.x,n.y):H.canvas.lineTo(r,e._view,n),d=t);h&&r.closePath(),r.stroke(),r.restore()}}}),ht=H.valueOrDefault,ct=N.global.defaultColor;function ft(t){var e=this._view;return!!e&&Math.abs(t-e.x)<e.radius+e.hitRadius}N._set("global",{elements:{point:{radius:3,pointStyle:"circle",backgroundColor:ct,borderColor:ct,borderWidth:1,hitRadius:1,hoverRadius:4,hoverBorderWidth:1}}});var gt=K.extend({_type:"point",inRange:function(t,e){var n=this._view;return!!n&&Math.pow(t-n.x,2)+Math.pow(e-n.y,2)<Math.pow(n.hitRadius+n.radius,2)},inLabelRange:ft,inXRange:ft,inYRange:function(t){var e=this._view;return!!e&&Math.abs(t-e.y)<e.radius+e.hitRadius},getCenterPoint:function(){var t=this._view;return{x:t.x,y:t.y}},getArea:function(){return Math.PI*Math.pow(this._view.radius,2)},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y,padding:t.radius+t.borderWidth}},draw:function(t){var e=this._view,n=this._chart.ctx,i=e.pointStyle,a=e.rotation,r=e.radius,o=e.x,s=e.y,l=N.global,u=l.defaultColor;e.skip||(void 0===t||H.canvas._isPointInArea(e,t))&&(n.strokeStyle=e.borderColor||u,n.lineWidth=ht(e.borderWidth,l.elements.point.borderWidth),n.fillStyle=e.backgroundColor||u,H.canvas.drawPoint(n,i,r,o,s,a))}}),pt=N.global.defaultColor;function mt(t){return t&&void 0!==t.width}function vt(t){var e,n,i,a,r;return mt(t)?(r=t.width/2,e=t.x-r,n=t.x+r,i=Math.min(t.y,t.base),a=Math.max(t.y,t.base)):(r=t.height/2,e=Math.min(t.x,t.base),n=Math.max(t.x,t.base),i=t.y-r,a=t.y+r),{left:e,top:i,right:n,bottom:a}}function bt(t,e,n){return t===e?n:t===n?e:t}function xt(t,e,n){var i,a,r,o,s=t.borderWidth,l=function(t){var e=t.borderSkipped,n={};return e?(t.horizontal?t.base>t.x&&(e=bt(e,"left","right")):t.base<t.y&&(e=bt(e,"bottom","top")),n[e]=!0,n):n}(t);return H.isObject(s)?(i=+s.top||0,a=+s.right||0,r=+s.bottom||0,o=+s.left||0):i=a=r=o=+s||0,{t:l.top||i<0?0:i>n?n:i,r:l.right||a<0?0:a>e?e:a,b:l.bottom||r<0?0:r>n?n:r,l:l.left||o<0?0:o>e?e:o}}function yt(t,e,n){var i=null===e,a=null===n,r=!(!t||i&&a)&&vt(t);return r&&(i||e>=r.left&&e<=r.right)&&(a||n>=r.top&&n<=r.bottom)}N._set("global",{elements:{rectangle:{backgroundColor:pt,borderColor:pt,borderSkipped:"bottom",borderWidth:0}}});var _t=K.extend({_type:"rectangle",draw:function(){var t=this._chart.ctx,e=this._view,n=function(t){var e=vt(t),n=e.right-e.left,i=e.bottom-e.top,a=xt(t,n/2,i/2);return{outer:{x:e.left,y:e.top,w:n,h:i},inner:{x:e.left+a.l,y:e.top+a.t,w:n-a.l-a.r,h:i-a.t-a.b}}}(e),i=n.outer,a=n.inner;t.fillStyle=e.backgroundColor,t.fillRect(i.x,i.y,i.w,i.h),i.w===a.w&&i.h===a.h||(t.save(),t.beginPath(),t.rect(i.x,i.y,i.w,i.h),t.clip(),t.fillStyle=e.borderColor,t.rect(a.x,a.y,a.w,a.h),t.fill("evenodd"),t.restore())},height:function(){var t=this._view;return t.base-t.y},inRange:function(t,e){return yt(this._view,t,e)},inLabelRange:function(t,e){var n=this._view;return mt(n)?yt(n,t,null):yt(n,null,e)},inXRange:function(t){return yt(this._view,t,null)},inYRange:function(t){return yt(this._view,null,t)},getCenterPoint:function(){var t,e,n=this._view;return mt(n)?(t=n.x,e=(n.y+n.base)/2):(t=(n.x+n.base)/2,e=n.y),{x:t,y:e}},getArea:function(){var t=this._view;return mt(t)?t.width*Math.abs(t.y-t.base):t.height*Math.abs(t.x-t.base)},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y}}}),kt={},wt=st,Mt=dt,St=gt,Ct=_t;kt.Arc=wt,kt.Line=Mt,kt.Point=St,kt.Rectangle=Ct;var Pt=H._deprecated,At=H.valueOrDefault;function Dt(t,e,n){var i,a,r=n.barThickness,o=e.stackCount,s=e.pixels[t],l=H.isNullOrUndef(r)?function(t,e){var n,i,a,r,o=t._length;for(a=1,r=e.length;a<r;++a)o=Math.min(o,Math.abs(e[a]-e[a-1]));for(a=0,r=t.getTicks().length;a<r;++a)i=t.getPixelForTick(a),o=a>0?Math.min(o,Math.abs(i-n)):o,n=i;return o}(e.scale,e.pixels):-1;return H.isNullOrUndef(r)?(i=l*n.categoryPercentage,a=n.barPercentage):(i=r*o,a=1),{chunk:i/o,ratio:a,start:s-i/2}}N._set("bar",{hover:{mode:"label"},scales:{xAxes:[{type:"category",offset:!0,gridLines:{offsetGridLines:!0}}],yAxes:[{type:"linear"}]}}),N._set("global",{datasets:{bar:{categoryPercentage:.8,barPercentage:.9}}});var Tt=it.extend({dataElementType:kt.Rectangle,_dataElementOptions:["backgroundColor","borderColor","borderSkipped","borderWidth","barPercentage","barThickness","categoryPercentage","maxBarThickness","minBarLength"],initialize:function(){var t,e,n=this;it.prototype.initialize.apply(n,arguments),(t=n.getMeta()).stack=n.getDataset().stack,t.bar=!0,e=n._getIndexScale().options,Pt("bar chart",e.barPercentage,"scales.[x/y]Axes.barPercentage","dataset.barPercentage"),Pt("bar chart",e.barThickness,"scales.[x/y]Axes.barThickness","dataset.barThickness"),Pt("bar chart",e.categoryPercentage,"scales.[x/y]Axes.categoryPercentage","dataset.categoryPercentage"),Pt("bar chart",n._getValueScale().options.minBarLength,"scales.[x/y]Axes.minBarLength","dataset.minBarLength"),Pt("bar chart",e.maxBarThickness,"scales.[x/y]Axes.maxBarThickness","dataset.maxBarThickness")},update:function(t){var e,n,i=this.getMeta().data;for(this._ruler=this.getRuler(),e=0,n=i.length;e<n;++e)this.updateElement(i[e],e,t)},updateElement:function(t,e,n){var i=this,a=i.getMeta(),r=i.getDataset(),o=i._resolveDataElementOptions(t,e);t._xScale=i.getScaleForId(a.xAxisID),t._yScale=i.getScaleForId(a.yAxisID),t._datasetIndex=i.index,t._index=e,t._model={backgroundColor:o.backgroundColor,borderColor:o.borderColor,borderSkipped:o.borderSkipped,borderWidth:o.borderWidth,datasetLabel:r.label,label:i.chart.data.labels[e]},H.isArray(r.data[e])&&(t._model.borderSkipped=null),i._updateElementGeometry(t,e,n,o),t.pivot()},_updateElementGeometry:function(t,e,n,i){var a=this,r=t._model,o=a._getValueScale(),s=o.getBasePixel(),l=o.isHorizontal(),u=a._ruler||a.getRuler(),d=a.calculateBarValuePixels(a.index,e,i),h=a.calculateBarIndexPixels(a.index,e,u,i);r.horizontal=l,r.base=n?s:d.base,r.x=l?n?s:d.head:h.center,r.y=l?h.center:n?s:d.head,r.height=l?h.size:void 0,r.width=l?void 0:h.size},_getStacks:function(t){var e,n,i=this._getIndexScale(),a=i._getMatchingVisibleMetas(this._type),r=i.options.stacked,o=a.length,s=[];for(e=0;e<o&&(n=a[e],(!1===r||-1===s.indexOf(n.stack)||void 0===r&&void 0===n.stack)&&s.push(n.stack),n.index!==t);++e);return s},getStackCount:function(){return this._getStacks().length},getStackIndex:function(t,e){var n=this._getStacks(t),i=void 0!==e?n.indexOf(e):-1;return-1===i?n.length-1:i},getRuler:function(){var t,e,n=this._getIndexScale(),i=[];for(t=0,e=this.getMeta().data.length;t<e;++t)i.push(n.getPixelForValue(null,t,this.index));return{pixels:i,start:n._startPixel,end:n._endPixel,stackCount:this.getStackCount(),scale:n}},calculateBarValuePixels:function(t,e,n){var i,a,r,o,s,l,u,d=this.chart,h=this._getValueScale(),c=h.isHorizontal(),f=d.data.datasets,g=h._getMatchingVisibleMetas(this._type),p=h._parseValue(f[t].data[e]),m=n.minBarLength,v=h.options.stacked,b=this.getMeta().stack,x=void 0===p.start?0:p.max>=0&&p.min>=0?p.min:p.max,y=void 0===p.start?p.end:p.max>=0&&p.min>=0?p.max-p.min:p.min-p.max,_=g.length;if(v||void 0===v&&void 0!==b)for(i=0;i<_&&(a=g[i]).index!==t;++i)a.stack===b&&(r=void 0===(u=h._parseValue(f[a.index].data[e])).start?u.end:u.min>=0&&u.max>=0?u.max:u.min,(p.min<0&&r<0||p.max>=0&&r>0)&&(x+=r));return o=h.getPixelForValue(x),l=(s=h.getPixelForValue(x+y))-o,void 0!==m&&Math.abs(l)<m&&(l=m,s=y>=0&&!c||y<0&&c?o-m:o+m),{size:l,base:o,head:s,center:s+l/2}},calculateBarIndexPixels:function(t,e,n,i){var a="flex"===i.barThickness?function(t,e,n){var i,a=e.pixels,r=a[t],o=t>0?a[t-1]:null,s=t<a.length-1?a[t+1]:null,l=n.categoryPercentage;return null===o&&(o=r-(null===s?e.end-e.start:s-r)),null===s&&(s=r+r-o),i=r-(r-Math.min(o,s))/2*l,{chunk:Math.abs(s-o)/2*l/e.stackCount,ratio:n.barPercentage,start:i}}(e,n,i):Dt(e,n,i),r=this.getStackIndex(t,this.getMeta().stack),o=a.start+a.chunk*r+a.chunk/2,s=Math.min(At(i.maxBarThickness,1/0),a.chunk*a.ratio);return{base:o-s/2,head:o+s/2,center:o,size:s}},draw:function(){var t=this.chart,e=this._getValueScale(),n=this.getMeta().data,i=this.getDataset(),a=n.length,r=0;for(H.canvas.clipArea(t.ctx,t.chartArea);r<a;++r){var o=e._parseValue(i.data[r]);isNaN(o.min)||isNaN(o.max)||n[r].draw()}H.canvas.unclipArea(t.ctx)},_resolveDataElementOptions:function(){var t=this,e=H.extend({},it.prototype._resolveDataElementOptions.apply(t,arguments)),n=t._getIndexScale().options,i=t._getValueScale().options;return e.barPercentage=At(n.barPercentage,e.barPercentage),e.barThickness=At(n.barThickness,e.barThickness),e.categoryPercentage=At(n.categoryPercentage,e.categoryPercentage),e.maxBarThickness=At(n.maxBarThickness,e.maxBarThickness),e.minBarLength=At(i.minBarLength,e.minBarLength),e}}),It=H.valueOrDefault,Ft=H.options.resolve;N._set("bubble",{hover:{mode:"single"},scales:{xAxes:[{type:"linear",position:"bottom",id:"x-axis-0"}],yAxes:[{type:"linear",position:"left",id:"y-axis-0"}]},tooltips:{callbacks:{title:function(){return""},label:function(t,e){var n=e.datasets[t.datasetIndex].label||"",i=e.datasets[t.datasetIndex].data[t.index];return n+": ("+t.xLabel+", "+t.yLabel+", "+i.r+")"}}}});var Ot=it.extend({dataElementType:kt.Point,_dataElementOptions:["backgroundColor","borderColor","borderWidth","hoverBackgroundColor","hoverBorderColor","hoverBorderWidth","hoverRadius","hitRadius","pointStyle","rotation"],update:function(t){var e=this,n=e.getMeta().data;H.each(n,(function(n,i){e.updateElement(n,i,t)}))},updateElement:function(t,e,n){var i=this,a=i.getMeta(),r=t.custom||{},o=i.getScaleForId(a.xAxisID),s=i.getScaleForId(a.yAxisID),l=i._resolveDataElementOptions(t,e),u=i.getDataset().data[e],d=i.index,h=n?o.getPixelForDecimal(.5):o.getPixelForValue("object"==typeof u?u:NaN,e,d),c=n?s.getBasePixel():s.getPixelForValue(u,e,d);t._xScale=o,t._yScale=s,t._options=l,t._datasetIndex=d,t._index=e,t._model={backgroundColor:l.backgroundColor,borderColor:l.borderColor,borderWidth:l.borderWidth,hitRadius:l.hitRadius,pointStyle:l.pointStyle,rotation:l.rotation,radius:n?0:l.radius,skip:r.skip||isNaN(h)||isNaN(c),x:h,y:c},t.pivot()},setHoverStyle:function(t){var e=t._model,n=t._options,i=H.getHoverColor;t.$previousStyle={backgroundColor:e.backgroundColor,borderColor:e.borderColor,borderWidth:e.borderWidth,radius:e.radius},e.backgroundColor=It(n.hoverBackgroundColor,i(n.backgroundColor)),e.borderColor=It(n.hoverBorderColor,i(n.borderColor)),e.borderWidth=It(n.hoverBorderWidth,n.borderWidth),e.radius=n.radius+n.hoverRadius},_resolveDataElementOptions:function(t,e){var n=this,i=n.chart,a=n.getDataset(),r=t.custom||{},o=a.data[e]||{},s=it.prototype._resolveDataElementOptions.apply(n,arguments),l={chart:i,dataIndex:e,dataset:a,datasetIndex:n.index};return n._cachedDataOpts===s&&(s=H.extend({},s)),s.radius=Ft([r.radius,o.r,n._config.radius,i.options.elements.point.radius],l,e),s}}),Lt=H.valueOrDefault,Rt=Math.PI,zt=2*Rt,Nt=Rt/2;N._set("doughnut",{animation:{animateRotate:!0,animateScale:!1},hover:{mode:"single"},legendCallback:function(t){var e,n,i,a=document.createElement("ul"),r=t.data,o=r.datasets,s=r.labels;if(a.setAttribute("class",t.id+"-legend"),o.length)for(e=0,n=o[0].data.length;e<n;++e)(i=a.appendChild(document.createElement("li"))).appendChild(document.createElement("span")).style.backgroundColor=o[0].backgroundColor[e],s[e]&&i.appendChild(document.createTextNode(s[e]));return a.outerHTML},legend:{labels:{generateLabels:function(t){var e=t.data;return e.labels.length&&e.datasets.length?e.labels.map((function(n,i){var a=t.getDatasetMeta(0),r=a.controller.getStyle(i);return{text:n,fillStyle:r.backgroundColor,strokeStyle:r.borderColor,lineWidth:r.borderWidth,hidden:isNaN(e.datasets[0].data[i])||a.data[i].hidden,index:i}})):[]}},onClick:function(t,e){var n,i,a,r=e.index,o=this.chart;for(n=0,i=(o.data.datasets||[]).length;n<i;++n)(a=o.getDatasetMeta(n)).data[r]&&(a.data[r].hidden=!a.data[r].hidden);o.update()}},cutoutPercentage:50,rotation:-Nt,circumference:zt,tooltips:{callbacks:{title:function(){return""},label:function(t,e){var n=e.labels[t.index],i=": "+e.datasets[t.datasetIndex].data[t.index];return H.isArray(n)?(n=n.slice())[0]+=i:n+=i,n}}}});var Bt=it.extend({dataElementType:kt.Arc,linkScales:H.noop,_dataElementOptions:["backgroundColor","borderColor","borderWidth","borderAlign","hoverBackgroundColor","hoverBorderColor","hoverBorderWidth"],getRingIndex:function(t){for(var e=0,n=0;n<t;++n)this.chart.isDatasetVisible(n)&&++e;return e},update:function(t){var e,n,i,a,r=this,o=r.chart,s=o.chartArea,l=o.options,u=1,d=1,h=0,c=0,f=r.getMeta(),g=f.data,p=l.cutoutPercentage/100||0,m=l.circumference,v=r._getRingWeight(r.index);if(m<zt){var b=l.rotation%zt,x=(b+=b>=Rt?-zt:b<-Rt?zt:0)+m,y=Math.cos(b),_=Math.sin(b),k=Math.cos(x),w=Math.sin(x),M=b<=0&&x>=0||x>=zt,S=b<=Nt&&x>=Nt||x>=zt+Nt,C=b<=-Nt&&x>=-Nt||x>=Rt+Nt,P=b===-Rt||x>=Rt?-1:Math.min(y,y*p,k,k*p),A=C?-1:Math.min(_,_*p,w,w*p),D=M?1:Math.max(y,y*p,k,k*p),T=S?1:Math.max(_,_*p,w,w*p);u=(D-P)/2,d=(T-A)/2,h=-(D+P)/2,c=-(T+A)/2}for(i=0,a=g.length;i<a;++i)g[i]._options=r._resolveDataElementOptions(g[i],i);for(o.borderWidth=r.getMaxBorderWidth(),e=(s.right-s.left-o.borderWidth)/u,n=(s.bottom-s.top-o.borderWidth)/d,o.outerRadius=Math.max(Math.min(e,n)/2,0),o.innerRadius=Math.max(o.outerRadius*p,0),o.radiusLength=(o.outerRadius-o.innerRadius)/(r._getVisibleDatasetWeightTotal()||1),o.offsetX=h*o.outerRadius,o.offsetY=c*o.outerRadius,f.total=r.calculateTotal(),r.outerRadius=o.outerRadius-o.radiusLength*r._getRingWeightOffset(r.index),r.innerRadius=Math.max(r.outerRadius-o.radiusLength*v,0),i=0,a=g.length;i<a;++i)r.updateElement(g[i],i,t)},updateElement:function(t,e,n){var i=this,a=i.chart,r=a.chartArea,o=a.options,s=o.animation,l=(r.left+r.right)/2,u=(r.top+r.bottom)/2,d=o.rotation,h=o.rotation,c=i.getDataset(),f=n&&s.animateRotate?0:t.hidden?0:i.calculateCircumference(c.data[e])*(o.circumference/zt),g=n&&s.animateScale?0:i.innerRadius,p=n&&s.animateScale?0:i.outerRadius,m=t._options||{};H.extend(t,{_datasetIndex:i.index,_index:e,_model:{backgroundColor:m.backgroundColor,borderColor:m.borderColor,borderWidth:m.borderWidth,borderAlign:m.borderAlign,x:l+a.offsetX,y:u+a.offsetY,startAngle:d,endAngle:h,circumference:f,outerRadius:p,innerRadius:g,label:H.valueAtIndexOrDefault(c.label,e,a.data.labels[e])}});var v=t._model;n&&s.animateRotate||(v.startAngle=0===e?o.rotation:i.getMeta().data[e-1]._model.endAngle,v.endAngle=v.startAngle+v.circumference),t.pivot()},calculateTotal:function(){var t,e=this.getDataset(),n=this.getMeta(),i=0;return H.each(n.data,(function(n,a){t=e.data[a],isNaN(t)||n.hidden||(i+=Math.abs(t))})),i},calculateCircumference:function(t){var e=this.getMeta().total;return e>0&&!isNaN(t)?zt*(Math.abs(t)/e):0},getMaxBorderWidth:function(t){var e,n,i,a,r,o,s,l,u=0,d=this.chart;if(!t)for(e=0,n=d.data.datasets.length;e<n;++e)if(d.isDatasetVisible(e)){t=(i=d.getDatasetMeta(e)).data,e!==this.index&&(r=i.controller);break}if(!t)return 0;for(e=0,n=t.length;e<n;++e)a=t[e],r?(r._configure(),o=r._resolveDataElementOptions(a,e)):o=a._options,"inner"!==o.borderAlign&&(s=o.borderWidth,u=(l=o.hoverBorderWidth)>(u=s>u?s:u)?l:u);return u},setHoverStyle:function(t){var e=t._model,n=t._options,i=H.getHoverColor;t.$previousStyle={backgroundColor:e.backgroundColor,borderColor:e.borderColor,borderWidth:e.borderWidth},e.backgroundColor=Lt(n.hoverBackgroundColor,i(n.backgroundColor)),e.borderColor=Lt(n.hoverBorderColor,i(n.borderColor)),e.borderWidth=Lt(n.hoverBorderWidth,n.borderWidth)},_getRingWeightOffset:function(t){for(var e=0,n=0;n<t;++n)this.chart.isDatasetVisible(n)&&(e+=this._getRingWeight(n));return e},_getRingWeight:function(t){return Math.max(Lt(this.chart.data.datasets[t].weight,1),0)},_getVisibleDatasetWeightTotal:function(){return this._getRingWeightOffset(this.chart.data.datasets.length)}});N._set("horizontalBar",{hover:{mode:"index",axis:"y"},scales:{xAxes:[{type:"linear",position:"bottom"}],yAxes:[{type:"category",position:"left",offset:!0,gridLines:{offsetGridLines:!0}}]},elements:{rectangle:{borderSkipped:"left"}},tooltips:{mode:"index",axis:"y"}}),N._set("global",{datasets:{horizontalBar:{categoryPercentage:.8,barPercentage:.9}}});var Et=Tt.extend({_getValueScaleId:function(){return this.getMeta().xAxisID},_getIndexScaleId:function(){return this.getMeta().yAxisID}}),Wt=H.valueOrDefault,Vt=H.options.resolve,Ht=H.canvas._isPointInArea;function jt(t,e){var n=t&&t.options.ticks||{},i=n.reverse,a=void 0===n.min?e:0,r=void 0===n.max?e:0;return{start:i?r:a,end:i?a:r}}function qt(t,e,n){var i=n/2,a=jt(t,i),r=jt(e,i);return{top:r.end,right:a.end,bottom:r.start,left:a.start}}function Ut(t){var e,n,i,a;return H.isObject(t)?(e=t.top,n=t.right,i=t.bottom,a=t.left):e=n=i=a=t,{top:e,right:n,bottom:i,left:a}}N._set("line",{showLines:!0,spanGaps:!1,hover:{mode:"label"},scales:{xAxes:[{type:"category",id:"x-axis-0"}],yAxes:[{type:"linear",id:"y-axis-0"}]}});var Yt=it.extend({datasetElementType:kt.Line,dataElementType:kt.Point,_datasetElementOptions:["backgroundColor","borderCapStyle","borderColor","borderDash","borderDashOffset","borderJoinStyle","borderWidth","cubicInterpolationMode","fill"],_dataElementOptions:{backgroundColor:"pointBackgroundColor",borderColor:"pointBorderColor",borderWidth:"pointBorderWidth",hitRadius:"pointHitRadius",hoverBackgroundColor:"pointHoverBackgroundColor",hoverBorderColor:"pointHoverBorderColor",hoverBorderWidth:"pointHoverBorderWidth",hoverRadius:"pointHoverRadius",pointStyle:"pointStyle",radius:"pointRadius",rotation:"pointRotation"},update:function(t){var e,n,i=this,a=i.getMeta(),r=a.dataset,o=a.data||[],s=i.chart.options,l=i._config,u=i._showLine=Wt(l.showLine,s.showLines);for(i._xScale=i.getScaleForId(a.xAxisID),i._yScale=i.getScaleForId(a.yAxisID),u&&(void 0!==l.tension&&void 0===l.lineTension&&(l.lineTension=l.tension),r._scale=i._yScale,r._datasetIndex=i.index,r._children=o,r._model=i._resolveDatasetElementOptions(r),r.pivot()),e=0,n=o.length;e<n;++e)i.updateElement(o[e],e,t);for(u&&0!==r._model.tension&&i.updateBezierControlPoints(),e=0,n=o.length;e<n;++e)o[e].pivot()},updateElement:function(t,e,n){var i,a,r=this,o=r.getMeta(),s=t.custom||{},l=r.getDataset(),u=r.index,d=l.data[e],h=r._xScale,c=r._yScale,f=o.dataset._model,g=r._resolveDataElementOptions(t,e);i=h.getPixelForValue("object"==typeof d?d:NaN,e,u),a=n?c.getBasePixel():r.calculatePointY(d,e,u),t._xScale=h,t._yScale=c,t._options=g,t._datasetIndex=u,t._index=e,t._model={x:i,y:a,skip:s.skip||isNaN(i)||isNaN(a),radius:g.radius,pointStyle:g.pointStyle,rotation:g.rotation,backgroundColor:g.backgroundColor,borderColor:g.borderColor,borderWidth:g.borderWidth,tension:Wt(s.tension,f?f.tension:0),steppedLine:!!f&&f.steppedLine,hitRadius:g.hitRadius}},_resolveDatasetElementOptions:function(t){var e=this,n=e._config,i=t.custom||{},a=e.chart.options,r=a.elements.line,o=it.prototype._resolveDatasetElementOptions.apply(e,arguments);return o.spanGaps=Wt(n.spanGaps,a.spanGaps),o.tension=Wt(n.lineTension,r.tension),o.steppedLine=Vt([i.steppedLine,n.steppedLine,r.stepped]),o.clip=Ut(Wt(n.clip,qt(e._xScale,e._yScale,o.borderWidth))),o},calculatePointY:function(t,e,n){var i,a,r,o,s,l,u,d=this.chart,h=this._yScale,c=0,f=0;if(h.options.stacked){for(s=+h.getRightValue(t),u=(l=d._getSortedVisibleDatasetMetas()).length,i=0;i<u&&(r=l[i]).index!==n;++i)a=d.data.datasets[r.index],"line"===r.type&&r.yAxisID===h.id&&((o=+h.getRightValue(a.data[e]))<0?f+=o||0:c+=o||0);return s<0?h.getPixelForValue(f+s):h.getPixelForValue(c+s)}return h.getPixelForValue(t)},updateBezierControlPoints:function(){var t,e,n,i,a=this.chart,r=this.getMeta(),o=r.dataset._model,s=a.chartArea,l=r.data||[];function u(t,e,n){return Math.max(Math.min(t,n),e)}if(o.spanGaps&&(l=l.filter((function(t){return!t._model.skip}))),"monotone"===o.cubicInterpolationMode)H.splineCurveMonotone(l);else for(t=0,e=l.length;t<e;++t)n=l[t]._model,i=H.splineCurve(H.previousItem(l,t)._model,n,H.nextItem(l,t)._model,o.tension),n.controlPointPreviousX=i.previous.x,n.controlPointPreviousY=i.previous.y,n.controlPointNextX=i.next.x,n.controlPointNextY=i.next.y;if(a.options.elements.line.capBezierPoints)for(t=0,e=l.length;t<e;++t)n=l[t]._model,Ht(n,s)&&(t>0&&Ht(l[t-1]._model,s)&&(n.controlPointPreviousX=u(n.controlPointPreviousX,s.left,s.right),n.controlPointPreviousY=u(n.controlPointPreviousY,s.top,s.bottom)),t<l.length-1&&Ht(l[t+1]._model,s)&&(n.controlPointNextX=u(n.controlPointNextX,s.left,s.right),n.controlPointNextY=u(n.controlPointNextY,s.top,s.bottom)))},draw:function(){var t,e=this.chart,n=this.getMeta(),i=n.data||[],a=e.chartArea,r=e.canvas,o=0,s=i.length;for(this._showLine&&(t=n.dataset._model.clip,H.canvas.clipArea(e.ctx,{left:!1===t.left?0:a.left-t.left,right:!1===t.right?r.width:a.right+t.right,top:!1===t.top?0:a.top-t.top,bottom:!1===t.bottom?r.height:a.bottom+t.bottom}),n.dataset.draw(),H.canvas.unclipArea(e.ctx));o<s;++o)i[o].draw(a)},setHoverStyle:function(t){var e=t._model,n=t._options,i=H.getHoverColor;t.$previousStyle={backgroundColor:e.backgroundColor,borderColor:e.borderColor,borderWidth:e.borderWidth,radius:e.radius},e.backgroundColor=Wt(n.hoverBackgroundColor,i(n.backgroundColor)),e.borderColor=Wt(n.hoverBorderColor,i(n.borderColor)),e.borderWidth=Wt(n.hoverBorderWidth,n.borderWidth),e.radius=Wt(n.hoverRadius,n.radius)}}),Gt=H.options.resolve;N._set("polarArea",{scale:{type:"radialLinear",angleLines:{display:!1},gridLines:{circular:!0},pointLabels:{display:!1},ticks:{beginAtZero:!0}},animation:{animateRotate:!0,animateScale:!0},startAngle:-.5*Math.PI,legendCallback:function(t){var e,n,i,a=document.createElement("ul"),r=t.data,o=r.datasets,s=r.labels;if(a.setAttribute("class",t.id+"-legend"),o.length)for(e=0,n=o[0].data.length;e<n;++e)(i=a.appendChild(document.createElement("li"))).appendChild(document.createElement("span")).style.backgroundColor=o[0].backgroundColor[e],s[e]&&i.appendChild(document.createTextNode(s[e]));return a.outerHTML},legend:{labels:{generateLabels:function(t){var e=t.data;return e.labels.length&&e.datasets.length?e.labels.map((function(n,i){var a=t.getDatasetMeta(0),r=a.controller.getStyle(i);return{text:n,fillStyle:r.backgroundColor,strokeStyle:r.borderColor,lineWidth:r.borderWidth,hidden:isNaN(e.datasets[0].data[i])||a.data[i].hidden,index:i}})):[]}},onClick:function(t,e){var n,i,a,r=e.index,o=this.chart;for(n=0,i=(o.data.datasets||[]).length;n<i;++n)(a=o.getDatasetMeta(n)).data[r].hidden=!a.data[r].hidden;o.update()}},tooltips:{callbacks:{title:function(){return""},label:function(t,e){return e.labels[t.index]+": "+t.yLabel}}}});var Xt=it.extend({dataElementType:kt.Arc,linkScales:H.noop,_dataElementOptions:["backgroundColor","borderColor","borderWidth","borderAlign","hoverBackgroundColor","hoverBorderColor","hoverBorderWidth"],_getIndexScaleId:function(){return this.chart.scale.id},_getValueScaleId:function(){return this.chart.scale.id},update:function(t){var e,n,i,a=this,r=a.getDataset(),o=a.getMeta(),s=a.chart.options.startAngle||0,l=a._starts=[],u=a._angles=[],d=o.data;for(a._updateRadius(),o.count=a.countVisibleElements(),e=0,n=r.data.length;e<n;e++)l[e]=s,i=a._computeAngle(e),u[e]=i,s+=i;for(e=0,n=d.length;e<n;++e)d[e]._options=a._resolveDataElementOptions(d[e],e),a.updateElement(d[e],e,t)},_updateRadius:function(){var t=this,e=t.chart,n=e.chartArea,i=e.options,a=Math.min(n.right-n.left,n.bottom-n.top);e.outerRadius=Math.max(a/2,0),e.innerRadius=Math.max(i.cutoutPercentage?e.outerRadius/100*i.cutoutPercentage:1,0),e.radiusLength=(e.outerRadius-e.innerRadius)/e.getVisibleDatasetCount(),t.outerRadius=e.outerRadius-e.radiusLength*t.index,t.innerRadius=t.outerRadius-e.radiusLength},updateElement:function(t,e,n){var i=this,a=i.chart,r=i.getDataset(),o=a.options,s=o.animation,l=a.scale,u=a.data.labels,d=l.xCenter,h=l.yCenter,c=o.startAngle,f=t.hidden?0:l.getDistanceFromCenterForValue(r.data[e]),g=i._starts[e],p=g+(t.hidden?0:i._angles[e]),m=s.animateScale?0:l.getDistanceFromCenterForValue(r.data[e]),v=t._options||{};H.extend(t,{_datasetIndex:i.index,_index:e,_scale:l,_model:{backgroundColor:v.backgroundColor,borderColor:v.borderColor,borderWidth:v.borderWidth,borderAlign:v.borderAlign,x:d,y:h,innerRadius:0,outerRadius:n?m:f,startAngle:n&&s.animateRotate?c:g,endAngle:n&&s.animateRotate?c:p,label:H.valueAtIndexOrDefault(u,e,u[e])}}),t.pivot()},countVisibleElements:function(){var t=this.getDataset(),e=this.getMeta(),n=0;return H.each(e.data,(function(e,i){isNaN(t.data[i])||e.hidden||n++})),n},setHoverStyle:function(t){var e=t._model,n=t._options,i=H.getHoverColor,a=H.valueOrDefault;t.$previousStyle={backgroundColor:e.backgroundColor,borderColor:e.borderColor,borderWidth:e.borderWidth},e.backgroundColor=a(n.hoverBackgroundColor,i(n.backgroundColor)),e.borderColor=a(n.hoverBorderColor,i(n.borderColor)),e.borderWidth=a(n.hoverBorderWidth,n.borderWidth)},_computeAngle:function(t){var e=this,n=this.getMeta().count,i=e.getDataset(),a=e.getMeta();if(isNaN(i.data[t])||a.data[t].hidden)return 0;var r={chart:e.chart,dataIndex:t,dataset:i,datasetIndex:e.index};return Gt([e.chart.options.elements.arc.angle,2*Math.PI/n],r,t)}});N._set("pie",H.clone(N.doughnut)),N._set("pie",{cutoutPercentage:0});var Kt=Bt,Zt=H.valueOrDefault;N._set("radar",{spanGaps:!1,scale:{type:"radialLinear"},elements:{line:{fill:"start",tension:0}}});var $t=it.extend({datasetElementType:kt.Line,dataElementType:kt.Point,linkScales:H.noop,_datasetElementOptions:["backgroundColor","borderWidth","borderColor","borderCapStyle","borderDash","borderDashOffset","borderJoinStyle","fill"],_dataElementOptions:{backgroundColor:"pointBackgroundColor",borderColor:"pointBorderColor",borderWidth:"pointBorderWidth",hitRadius:"pointHitRadius",hoverBackgroundColor:"pointHoverBackgroundColor",hoverBorderColor:"pointHoverBorderColor",hoverBorderWidth:"pointHoverBorderWidth",hoverRadius:"pointHoverRadius",pointStyle:"pointStyle",radius:"pointRadius",rotation:"pointRotation"},_getIndexScaleId:function(){return this.chart.scale.id},_getValueScaleId:function(){return this.chart.scale.id},update:function(t){var e,n,i=this,a=i.getMeta(),r=a.dataset,o=a.data||[],s=i.chart.scale,l=i._config;for(void 0!==l.tension&&void 0===l.lineTension&&(l.lineTension=l.tension),r._scale=s,r._datasetIndex=i.index,r._children=o,r._loop=!0,r._model=i._resolveDatasetElementOptions(r),r.pivot(),e=0,n=o.length;e<n;++e)i.updateElement(o[e],e,t);for(i.updateBezierControlPoints(),e=0,n=o.length;e<n;++e)o[e].pivot()},updateElement:function(t,e,n){var i=this,a=t.custom||{},r=i.getDataset(),o=i.chart.scale,s=o.getPointPositionForValue(e,r.data[e]),l=i._resolveDataElementOptions(t,e),u=i.getMeta().dataset._model,d=n?o.xCenter:s.x,h=n?o.yCenter:s.y;t._scale=o,t._options=l,t._datasetIndex=i.index,t._index=e,t._model={x:d,y:h,skip:a.skip||isNaN(d)||isNaN(h),radius:l.radius,pointStyle:l.pointStyle,rotation:l.rotation,backgroundColor:l.backgroundColor,borderColor:l.borderColor,borderWidth:l.borderWidth,tension:Zt(a.tension,u?u.tension:0),hitRadius:l.hitRadius}},_resolveDatasetElementOptions:function(){var t=this,e=t._config,n=t.chart.options,i=it.prototype._resolveDatasetElementOptions.apply(t,arguments);return i.spanGaps=Zt(e.spanGaps,n.spanGaps),i.tension=Zt(e.lineTension,n.elements.line.tension),i},updateBezierControlPoints:function(){var t,e,n,i,a=this.getMeta(),r=this.chart.chartArea,o=a.data||[];function s(t,e,n){return Math.max(Math.min(t,n),e)}for(a.dataset._model.spanGaps&&(o=o.filter((function(t){return!t._model.skip}))),t=0,e=o.length;t<e;++t)n=o[t]._model,i=H.splineCurve(H.previousItem(o,t,!0)._model,n,H.nextItem(o,t,!0)._model,n.tension),n.controlPointPreviousX=s(i.previous.x,r.left,r.right),n.controlPointPreviousY=s(i.previous.y,r.top,r.bottom),n.controlPointNextX=s(i.next.x,r.left,r.right),n.controlPointNextY=s(i.next.y,r.top,r.bottom)},setHoverStyle:function(t){var e=t._model,n=t._options,i=H.getHoverColor;t.$previousStyle={backgroundColor:e.backgroundColor,borderColor:e.borderColor,borderWidth:e.borderWidth,radius:e.radius},e.backgroundColor=Zt(n.hoverBackgroundColor,i(n.backgroundColor)),e.borderColor=Zt(n.hoverBorderColor,i(n.borderColor)),e.borderWidth=Zt(n.hoverBorderWidth,n.borderWidth),e.radius=Zt(n.hoverRadius,n.radius)}});N._set("scatter",{hover:{mode:"single"},scales:{xAxes:[{id:"x-axis-1",type:"linear",position:"bottom"}],yAxes:[{id:"y-axis-1",type:"linear",position:"left"}]},tooltips:{callbacks:{title:function(){return""},label:function(t){return"("+t.xLabel+", "+t.yLabel+")"}}}}),N._set("global",{datasets:{scatter:{showLine:!1}}});var Jt={bar:Tt,bubble:Ot,doughnut:Bt,horizontalBar:Et,line:Yt,polarArea:Xt,pie:Kt,radar:$t,scatter:Yt};function Qt(t,e){return t.native?{x:t.x,y:t.y}:H.getRelativePosition(t,e)}function te(t,e){var n,i,a,r,o,s,l=t._getSortedVisibleDatasetMetas();for(i=0,r=l.length;i<r;++i)for(a=0,o=(n=l[i].data).length;a<o;++a)(s=n[a])._view.skip||e(s)}function ee(t,e){var n=[];return te(t,(function(t){t.inRange(e.x,e.y)&&n.push(t)})),n}function ne(t,e,n,i){var a=Number.POSITIVE_INFINITY,r=[];return te(t,(function(t){if(!n||t.inRange(e.x,e.y)){var o=t.getCenterPoint(),s=i(e,o);s<a?(r=[t],a=s):s===a&&r.push(t)}})),r}function ie(t){var e=-1!==t.indexOf("x"),n=-1!==t.indexOf("y");return function(t,i){var a=e?Math.abs(t.x-i.x):0,r=n?Math.abs(t.y-i.y):0;return Math.sqrt(Math.pow(a,2)+Math.pow(r,2))}}function ae(t,e,n){var i=Qt(e,t);n.axis=n.axis||"x";var a=ie(n.axis),r=n.intersect?ee(t,i):ne(t,i,!1,a),o=[];return r.length?(t._getSortedVisibleDatasetMetas().forEach((function(t){var e=t.data[r[0]._index];e&&!e._view.skip&&o.push(e)})),o):[]}var re={modes:{single:function(t,e){var n=Qt(e,t),i=[];return te(t,(function(t){if(t.inRange(n.x,n.y))return i.push(t),i})),i.slice(0,1)},label:ae,index:ae,dataset:function(t,e,n){var i=Qt(e,t);n.axis=n.axis||"xy";var a=ie(n.axis),r=n.intersect?ee(t,i):ne(t,i,!1,a);return r.length>0&&(r=t.getDatasetMeta(r[0]._datasetIndex).data),r},"x-axis":function(t,e){return ae(t,e,{intersect:!1})},point:function(t,e){return ee(t,Qt(e,t))},nearest:function(t,e,n){var i=Qt(e,t);n.axis=n.axis||"xy";var a=ie(n.axis);return ne(t,i,n.intersect,a)},x:function(t,e,n){var i=Qt(e,t),a=[],r=!1;return te(t,(function(t){t.inXRange(i.x)&&a.push(t),t.inRange(i.x,i.y)&&(r=!0)})),n.intersect&&!r&&(a=[]),a},y:function(t,e,n){var i=Qt(e,t),a=[],r=!1;return te(t,(function(t){t.inYRange(i.y)&&a.push(t),t.inRange(i.x,i.y)&&(r=!0)})),n.intersect&&!r&&(a=[]),a}}},oe=H.extend;function se(t,e){return H.where(t,(function(t){return t.pos===e}))}function le(t,e){return t.sort((function(t,n){var i=e?n:t,a=e?t:n;return i.weight===a.weight?i.index-a.index:i.weight-a.weight}))}function ue(t,e,n,i){return Math.max(t[n],e[n])+Math.max(t[i],e[i])}function de(t,e,n){var i,a,r=n.box,o=t.maxPadding;if(n.size&&(t[n.pos]-=n.size),n.size=n.horizontal?r.height:r.width,t[n.pos]+=n.size,r.getPadding){var s=r.getPadding();o.top=Math.max(o.top,s.top),o.left=Math.max(o.left,s.left),o.bottom=Math.max(o.bottom,s.bottom),o.right=Math.max(o.right,s.right)}if(i=e.outerWidth-ue(o,t,"left","right"),a=e.outerHeight-ue(o,t,"top","bottom"),i!==t.w||a!==t.h){t.w=i,t.h=a;var l=n.horizontal?[i,t.w]:[a,t.h];return!(l[0]===l[1]||isNaN(l[0])&&isNaN(l[1]))}}function he(t,e){var n=e.maxPadding;function i(t){var i={left:0,top:0,right:0,bottom:0};return t.forEach((function(t){i[t]=Math.max(e[t],n[t])})),i}return i(t?["left","right"]:["top","bottom"])}function ce(t,e,n){var i,a,r,o,s,l,u=[];for(i=0,a=t.length;i<a;++i)(o=(r=t[i]).box).update(r.width||e.w,r.height||e.h,he(r.horizontal,e)),de(e,n,r)&&(l=!0,u.length&&(s=!0)),o.fullWidth||u.push(r);return s&&ce(u,e,n)||l}function fe(t,e,n){var i,a,r,o,s=n.padding,l=e.x,u=e.y;for(i=0,a=t.length;i<a;++i)o=(r=t[i]).box,r.horizontal?(o.left=o.fullWidth?s.left:e.left,o.right=o.fullWidth?n.outerWidth-s.right:e.left+e.w,o.top=u,o.bottom=u+o.height,o.width=o.right-o.left,u=o.bottom):(o.left=l,o.right=l+o.width,o.top=e.top,o.bottom=e.top+e.h,o.height=o.bottom-o.top,l=o.right);e.x=l,e.y=u}N._set("global",{layout:{padding:{top:0,right:0,bottom:0,left:0}}});var ge,pe={defaults:{},addBox:function(t,e){t.boxes||(t.boxes=[]),e.fullWidth=e.fullWidth||!1,e.position=e.position||"top",e.weight=e.weight||0,e._layers=e._layers||function(){return[{z:0,draw:function(){e.draw.apply(e,arguments)}}]},t.boxes.push(e)},removeBox:function(t,e){var n=t.boxes?t.boxes.indexOf(e):-1;-1!==n&&t.boxes.splice(n,1)},configure:function(t,e,n){for(var i,a=["fullWidth","position","weight"],r=a.length,o=0;o<r;++o)i=a[o],n.hasOwnProperty(i)&&(e[i]=n[i])},update:function(t,e,n){if(t){var i=t.options.layout||{},a=H.options.toPadding(i.padding),r=e-a.width,o=n-a.height,s=function(t){var e=function(t){var e,n,i,a=[];for(e=0,n=(t||[]).length;e<n;++e)i=t[e],a.push({index:e,box:i,pos:i.position,horizontal:i.isHorizontal(),weight:i.weight});return a}(t),n=le(se(e,"left"),!0),i=le(se(e,"right")),a=le(se(e,"top"),!0),r=le(se(e,"bottom"));return{leftAndTop:n.concat(a),rightAndBottom:i.concat(r),chartArea:se(e,"chartArea"),vertical:n.concat(i),horizontal:a.concat(r)}}(t.boxes),l=s.vertical,u=s.horizontal,d=Object.freeze({outerWidth:e,outerHeight:n,padding:a,availableWidth:r,vBoxMaxWidth:r/2/l.length,hBoxMaxHeight:o/2}),h=oe({maxPadding:oe({},a),w:r,h:o,x:a.left,y:a.top},a);!function(t,e){var n,i,a;for(n=0,i=t.length;n<i;++n)(a=t[n]).width=a.horizontal?a.box.fullWidth&&e.availableWidth:e.vBoxMaxWidth,a.height=a.horizontal&&e.hBoxMaxHeight}(l.concat(u),d),ce(l,h,d),ce(u,h,d)&&ce(l,h,d),function(t){var e=t.maxPadding;function n(n){var i=Math.max(e[n]-t[n],0);return t[n]+=i,i}t.y+=n("top"),t.x+=n("left"),n("right"),n("bottom")}(h),fe(s.leftAndTop,h,d),h.x+=h.w,h.y+=h.h,fe(s.rightAndBottom,h,d),t.chartArea={left:h.left,top:h.top,right:h.left+h.w,bottom:h.top+h.h},H.each(s.chartArea,(function(e){var n=e.box;oe(n,t.chartArea),n.update(h.w,h.h)}))}}},me=(ge=Object.freeze({__proto__:null,default:"@keyframes chartjs-render-animation{from{opacity:.99}to{opacity:1}}.chartjs-render-monitor{animation:chartjs-render-animation 1ms}.chartjs-size-monitor,.chartjs-size-monitor-expand,.chartjs-size-monitor-shrink{position:absolute;direction:ltr;left:0;top:0;right:0;bottom:0;overflow:hidden;pointer-events:none;visibility:hidden;z-index:-1}.chartjs-size-monitor-expand>div{position:absolute;width:1000000px;height:1000000px;left:0;top:0}.chartjs-size-monitor-shrink>div{position:absolute;width:200%;height:200%;left:0;top:0}"}))&&ge.default||ge,ve="$chartjs",be="chartjs-size-monitor",xe="chartjs-render-monitor",ye="chartjs-render-animation",_e=["animationstart","webkitAnimationStart"],ke={touchstart:"mousedown",touchmove:"mousemove",touchend:"mouseup",pointerenter:"mouseenter",pointerdown:"mousedown",pointermove:"mousemove",pointerup:"mouseup",pointerleave:"mouseout",pointerout:"mouseout"};function we(t,e){var n=H.getStyle(t,e),i=n&&n.match(/^(\d+)(\.\d+)?px$/);return i?Number(i[1]):void 0}var Me=!!function(){var t=!1;try{var e=Object.defineProperty({},"passive",{get:function(){t=!0}});window.addEventListener("e",null,e)}catch(t){}return t}()&&{passive:!0};function Se(t,e,n){t.addEventListener(e,n,Me)}function Ce(t,e,n){t.removeEventListener(e,n,Me)}function Pe(t,e,n,i,a){return{type:t,chart:e,native:a||null,x:void 0!==n?n:null,y:void 0!==i?i:null}}function Ae(t){var e=document.createElement("div");return e.className=t||"",e}function De(t,e,n){var i,a,r,o,s=t[ve]||(t[ve]={}),l=s.resizer=function(t){var e=Ae(be),n=Ae(be+"-expand"),i=Ae(be+"-shrink");n.appendChild(Ae()),i.appendChild(Ae()),e.appendChild(n),e.appendChild(i),e._reset=function(){n.scrollLeft=1e6,n.scrollTop=1e6,i.scrollLeft=1e6,i.scrollTop=1e6};var a=function(){e._reset(),t()};return Se(n,"scroll",a.bind(n,"expand")),Se(i,"scroll",a.bind(i,"shrink")),e}((i=function(){if(s.resizer){var i=n.options.maintainAspectRatio&&t.parentNode,a=i?i.clientWidth:0;e(Pe("resize",n)),i&&i.clientWidth<a&&n.canvas&&e(Pe("resize",n))}},r=!1,o=[],function(){o=Array.prototype.slice.call(arguments),a=a||this,r||(r=!0,H.requestAnimFrame.call(window,(function(){r=!1,i.apply(a,o)})))}));!function(t,e){var n=t[ve]||(t[ve]={}),i=n.renderProxy=function(t){t.animationName===ye&&e()};H.each(_e,(function(e){Se(t,e,i)})),n.reflow=!!t.offsetParent,t.classList.add(xe)}(t,(function(){if(s.resizer){var e=t.parentNode;e&&e!==l.parentNode&&e.insertBefore(l,e.firstChild),l._reset()}}))}function Te(t){var e=t[ve]||{},n=e.resizer;delete e.resizer,function(t){var e=t[ve]||{},n=e.renderProxy;n&&(H.each(_e,(function(e){Ce(t,e,n)})),delete e.renderProxy),t.classList.remove(xe)}(t),n&&n.parentNode&&n.parentNode.removeChild(n)}var Ie={disableCSSInjection:!1,_enabled:"undefined"!=typeof window&&"undefined"!=typeof document,_ensureLoaded:function(t){if(!this.disableCSSInjection){var e=t.getRootNode?t.getRootNode():document;!function(t,e){var n=t[ve]||(t[ve]={});if(!n.containsStyles){n.containsStyles=!0,e="/* Chart.js */\n"+e;var i=document.createElement("style");i.setAttribute("type","text/css"),i.appendChild(document.createTextNode(e)),t.appendChild(i)}}(e.host?e:document.head,me)}},acquireContext:function(t,e){"string"==typeof t?t=document.getElementById(t):t.length&&(t=t[0]),t&&t.canvas&&(t=t.canvas);var n=t&&t.getContext&&t.getContext("2d");return n&&n.canvas===t?(this._ensureLoaded(t),function(t,e){var n=t.style,i=t.getAttribute("height"),a=t.getAttribute("width");if(t[ve]={initial:{height:i,width:a,style:{display:n.display,height:n.height,width:n.width}}},n.display=n.display||"block",null===a||""===a){var r=we(t,"width");void 0!==r&&(t.width=r)}if(null===i||""===i)if(""===t.style.height)t.height=t.width/(e.options.aspectRatio||2);else{var o=we(t,"height");void 0!==r&&(t.height=o)}}(t,e),n):null},releaseContext:function(t){var e=t.canvas;if(e[ve]){var n=e[ve].initial;["height","width"].forEach((function(t){var i=n[t];H.isNullOrUndef(i)?e.removeAttribute(t):e.setAttribute(t,i)})),H.each(n.style||{},(function(t,n){e.style[n]=t})),e.width=e.width,delete e[ve]}},addEventListener:function(t,e,n){var i=t.canvas;if("resize"!==e){var a=n[ve]||(n[ve]={});Se(i,e,(a.proxies||(a.proxies={}))[t.id+"_"+e]=function(e){n(function(t,e){var n=ke[t.type]||t.type,i=H.getRelativePosition(t,e);return Pe(n,e,i.x,i.y,t)}(e,t))})}else De(i,n,t)},removeEventListener:function(t,e,n){var i=t.canvas;if("resize"!==e){var a=((n[ve]||{}).proxies||{})[t.id+"_"+e];a&&Ce(i,e,a)}else Te(i)}};H.addEvent=Se,H.removeEvent=Ce;var Fe=Ie._enabled?Ie:{acquireContext:function(t){return t&&t.canvas&&(t=t.canvas),t&&t.getContext("2d")||null}},Oe=H.extend({initialize:function(){},acquireContext:function(){},releaseContext:function(){},addEventListener:function(){},removeEventListener:function(){}},Fe);N._set("global",{plugins:{}});var Le={_plugins:[],_cacheId:0,register:function(t){var e=this._plugins;[].concat(t).forEach((function(t){-1===e.indexOf(t)&&e.push(t)})),this._cacheId++},unregister:function(t){var e=this._plugins;[].concat(t).forEach((function(t){var n=e.indexOf(t);-1!==n&&e.splice(n,1)})),this._cacheId++},clear:function(){this._plugins=[],this._cacheId++},count:function(){return this._plugins.length},getAll:function(){return this._plugins},notify:function(t,e,n){var i,a,r,o,s,l=this.descriptors(t),u=l.length;for(i=0;i<u;++i)if("function"==typeof(s=(r=(a=l[i]).plugin)[e])&&((o=[t].concat(n||[])).push(a.options),!1===s.apply(r,o)))return!1;return!0},descriptors:function(t){var e=t.$plugins||(t.$plugins={});if(e.id===this._cacheId)return e.descriptors;var n=[],i=[],a=t&&t.config||{},r=a.options&&a.options.plugins||{};return this._plugins.concat(a.plugins||[]).forEach((function(t){if(-1===n.indexOf(t)){var e=t.id,a=r[e];!1!==a&&(!0===a&&(a=H.clone(N.global.plugins[e])),n.push(t),i.push({plugin:t,options:a||{}}))}})),e.descriptors=i,e.id=this._cacheId,i},_invalidate:function(t){delete t.$plugins}},Re={constructors:{},defaults:{},registerScaleType:function(t,e,n){this.constructors[t]=e,this.defaults[t]=H.clone(n)},getScaleConstructor:function(t){return this.constructors.hasOwnProperty(t)?this.constructors[t]:void 0},getScaleDefaults:function(t){return this.defaults.hasOwnProperty(t)?H.merge(Object.create(null),[N.scale,this.defaults[t]]):{}},updateScaleDefaults:function(t,e){this.defaults.hasOwnProperty(t)&&(this.defaults[t]=H.extend(this.defaults[t],e))},addScalesToLayout:function(t){H.each(t.scales,(function(e){e.fullWidth=e.options.fullWidth,e.position=e.options.position,e.weight=e.options.weight,pe.addBox(t,e)}))}},ze=H.valueOrDefault,Ne=H.rtl.getRtlAdapter;N._set("global",{tooltips:{enabled:!0,custom:null,mode:"nearest",position:"average",intersect:!0,backgroundColor:"rgba(0,0,0,0.8)",titleFontStyle:"bold",titleSpacing:2,titleMarginBottom:6,titleFontColor:"#fff",titleAlign:"left",bodySpacing:2,bodyFontColor:"#fff",bodyAlign:"left",footerFontStyle:"bold",footerSpacing:2,footerMarginTop:6,footerFontColor:"#fff",footerAlign:"left",yPadding:6,xPadding:6,caretPadding:2,caretSize:5,cornerRadius:6,multiKeyBackground:"#fff",displayColors:!0,borderColor:"rgba(0,0,0,0)",borderWidth:0,callbacks:{beforeTitle:H.noop,title:function(t,e){var n="",i=e.labels,a=i?i.length:0;if(t.length>0){var r=t[0];r.label?n=r.label:r.xLabel?n=r.xLabel:a>0&&r.index<a&&(n=i[r.index])}return n},afterTitle:H.noop,beforeBody:H.noop,beforeLabel:H.noop,label:function(t,e){var n=e.datasets[t.datasetIndex].label||"";return n&&(n+=": "),H.isNullOrUndef(t.value)?n+=t.yLabel:n+=t.value,n},labelColor:function(t,e){var n=e.getDatasetMeta(t.datasetIndex).data[t.index]._view;return{borderColor:n.borderColor,backgroundColor:n.backgroundColor}},labelTextColor:function(){return this._options.bodyFontColor},afterLabel:H.noop,afterBody:H.noop,beforeFooter:H.noop,footer:H.noop,afterFooter:H.noop}}});var Be={average:function(t){if(!t.length)return!1;var e,n,i=0,a=0,r=0;for(e=0,n=t.length;e<n;++e){var o=t[e];if(o&&o.hasValue()){var s=o.tooltipPosition();i+=s.x,a+=s.y,++r}}return{x:i/r,y:a/r}},nearest:function(t,e){var n,i,a,r=e.x,o=e.y,s=Number.POSITIVE_INFINITY;for(n=0,i=t.length;n<i;++n){var l=t[n];if(l&&l.hasValue()){var u=l.getCenterPoint(),d=H.distanceBetweenPoints(e,u);d<s&&(s=d,a=l)}}if(a){var h=a.tooltipPosition();r=h.x,o=h.y}return{x:r,y:o}}};function Ee(t,e){return e&&(H.isArray(e)?Array.prototype.push.apply(t,e):t.push(e)),t}function We(t){return("string"==typeof t||t instanceof String)&&t.indexOf("\n")>-1?t.split("\n"):t}function Ve(t){var e=N.global;return{xPadding:t.xPadding,yPadding:t.yPadding,xAlign:t.xAlign,yAlign:t.yAlign,rtl:t.rtl,textDirection:t.textDirection,bodyFontColor:t.bodyFontColor,_bodyFontFamily:ze(t.bodyFontFamily,e.defaultFontFamily),_bodyFontStyle:ze(t.bodyFontStyle,e.defaultFontStyle),_bodyAlign:t.bodyAlign,bodyFontSize:ze(t.bodyFontSize,e.defaultFontSize),bodySpacing:t.bodySpacing,titleFontColor:t.titleFontColor,_titleFontFamily:ze(t.titleFontFamily,e.defaultFontFamily),_titleFontStyle:ze(t.titleFontStyle,e.defaultFontStyle),titleFontSize:ze(t.titleFontSize,e.defaultFontSize),_titleAlign:t.titleAlign,titleSpacing:t.titleSpacing,titleMarginBottom:t.titleMarginBottom,footerFontColor:t.footerFontColor,_footerFontFamily:ze(t.footerFontFamily,e.defaultFontFamily),_footerFontStyle:ze(t.footerFontStyle,e.defaultFontStyle),footerFontSize:ze(t.footerFontSize,e.defaultFontSize),_footerAlign:t.footerAlign,footerSpacing:t.footerSpacing,footerMarginTop:t.footerMarginTop,caretSize:t.caretSize,cornerRadius:t.cornerRadius,backgroundColor:t.backgroundColor,opacity:0,legendColorBackground:t.multiKeyBackground,displayColors:t.displayColors,borderColor:t.borderColor,borderWidth:t.borderWidth}}function He(t,e){return"center"===e?t.x+t.width/2:"right"===e?t.x+t.width-t.xPadding:t.x+t.xPadding}function je(t){return Ee([],We(t))}var qe=K.extend({initialize:function(){this._model=Ve(this._options),this._lastActive=[]},getTitle:function(){var t=this,e=t._options,n=e.callbacks,i=n.beforeTitle.apply(t,arguments),a=n.title.apply(t,arguments),r=n.afterTitle.apply(t,arguments),o=[];return o=Ee(o,We(i)),o=Ee(o,We(a)),o=Ee(o,We(r))},getBeforeBody:function(){return je(this._options.callbacks.beforeBody.apply(this,arguments))},getBody:function(t,e){var n=this,i=n._options.callbacks,a=[];return H.each(t,(function(t){var r={before:[],lines:[],after:[]};Ee(r.before,We(i.beforeLabel.call(n,t,e))),Ee(r.lines,i.label.call(n,t,e)),Ee(r.after,We(i.afterLabel.call(n,t,e))),a.push(r)})),a},getAfterBody:function(){return je(this._options.callbacks.afterBody.apply(this,arguments))},getFooter:function(){var t=this,e=t._options.callbacks,n=e.beforeFooter.apply(t,arguments),i=e.footer.apply(t,arguments),a=e.afterFooter.apply(t,arguments),r=[];return r=Ee(r,We(n)),r=Ee(r,We(i)),r=Ee(r,We(a))},update:function(t){var e,n,i,a,r,o,s,l,u,d,h=this,c=h._options,f=h._model,g=h._model=Ve(c),p=h._active,m=h._data,v={xAlign:f.xAlign,yAlign:f.yAlign},b={x:f.x,y:f.y},x={width:f.width,height:f.height},y={x:f.caretX,y:f.caretY};if(p.length){g.opacity=1;var _=[],k=[];y=Be[c.position].call(h,p,h._eventPosition);var w=[];for(e=0,n=p.length;e<n;++e)w.push((i=p[e],a=void 0,r=void 0,o=void 0,s=void 0,l=void 0,u=void 0,d=void 0,a=i._xScale,r=i._yScale||i._scale,o=i._index,s=i._datasetIndex,l=i._chart.getDatasetMeta(s).controller,u=l._getIndexScale(),d=l._getValueScale(),{xLabel:a?a.getLabelForIndex(o,s):"",yLabel:r?r.getLabelForIndex(o,s):"",label:u?""+u.getLabelForIndex(o,s):"",value:d?""+d.getLabelForIndex(o,s):"",index:o,datasetIndex:s,x:i._model.x,y:i._model.y}));c.filter&&(w=w.filter((function(t){return c.filter(t,m)}))),c.itemSort&&(w=w.sort((function(t,e){return c.itemSort(t,e,m)}))),H.each(w,(function(t){_.push(c.callbacks.labelColor.call(h,t,h._chart)),k.push(c.callbacks.labelTextColor.call(h,t,h._chart))})),g.title=h.getTitle(w,m),g.beforeBody=h.getBeforeBody(w,m),g.body=h.getBody(w,m),g.afterBody=h.getAfterBody(w,m),g.footer=h.getFooter(w,m),g.x=y.x,g.y=y.y,g.caretPadding=c.caretPadding,g.labelColors=_,g.labelTextColors=k,g.dataPoints=w,x=function(t,e){var n=t._chart.ctx,i=2*e.yPadding,a=0,r=e.body,o=r.reduce((function(t,e){return t+e.before.length+e.lines.length+e.after.length}),0);o+=e.beforeBody.length+e.afterBody.length;var s=e.title.length,l=e.footer.length,u=e.titleFontSize,d=e.bodyFontSize,h=e.footerFontSize;i+=s*u,i+=s?(s-1)*e.titleSpacing:0,i+=s?e.titleMarginBottom:0,i+=o*d,i+=o?(o-1)*e.bodySpacing:0,i+=l?e.footerMarginTop:0,i+=l*h,i+=l?(l-1)*e.footerSpacing:0;var c=0,f=function(t){a=Math.max(a,n.measureText(t).width+c)};return n.font=H.fontString(u,e._titleFontStyle,e._titleFontFamily),H.each(e.title,f),n.font=H.fontString(d,e._bodyFontStyle,e._bodyFontFamily),H.each(e.beforeBody.concat(e.afterBody),f),c=e.displayColors?d+2:0,H.each(r,(function(t){H.each(t.before,f),H.each(t.lines,f),H.each(t.after,f)})),c=0,n.font=H.fontString(h,e._footerFontStyle,e._footerFontFamily),H.each(e.footer,f),{width:a+=2*e.xPadding,height:i}}(this,g),b=function(t,e,n,i){var a=t.x,r=t.y,o=t.caretSize,s=t.caretPadding,l=t.cornerRadius,u=n.xAlign,d=n.yAlign,h=o+s,c=l+s;return"right"===u?a-=e.width:"center"===u&&((a-=e.width/2)+e.width>i.width&&(a=i.width-e.width),a<0&&(a=0)),"top"===d?r+=h:r-="bottom"===d?e.height+h:e.height/2,"center"===d?"left"===u?a+=h:"right"===u&&(a-=h):"left"===u?a-=c:"right"===u&&(a+=c),{x:a,y:r}}(g,x,v=function(t,e){var n,i,a,r,o,s=t._model,l=t._chart,u=t._chart.chartArea,d="center",h="center";s.y<e.height?h="top":s.y>l.height-e.height&&(h="bottom");var c=(u.left+u.right)/2,f=(u.top+u.bottom)/2;"center"===h?(n=function(t){return t<=c},i=function(t){return t>c}):(n=function(t){return t<=e.width/2},i=function(t){return t>=l.width-e.width/2}),a=function(t){return t+e.width+s.caretSize+s.caretPadding>l.width},r=function(t){return t-e.width-s.caretSize-s.caretPadding<0},o=function(t){return t<=f?"top":"bottom"},n(s.x)?(d="left",a(s.x)&&(d="center",h=o(s.y))):i(s.x)&&(d="right",r(s.x)&&(d="center",h=o(s.y)));var g=t._options;return{xAlign:g.xAlign?g.xAlign:d,yAlign:g.yAlign?g.yAlign:h}}(this,x),h._chart)}else g.opacity=0;return g.xAlign=v.xAlign,g.yAlign=v.yAlign,g.x=b.x,g.y=b.y,g.width=x.width,g.height=x.height,g.caretX=y.x,g.caretY=y.y,h._model=g,t&&c.custom&&c.custom.call(h,g),h},drawCaret:function(t,e){var n=this._chart.ctx,i=this._view,a=this.getCaretPosition(t,e,i);n.lineTo(a.x1,a.y1),n.lineTo(a.x2,a.y2),n.lineTo(a.x3,a.y3)},getCaretPosition:function(t,e,n){var i,a,r,o,s,l,u=n.caretSize,d=n.cornerRadius,h=n.xAlign,c=n.yAlign,f=t.x,g=t.y,p=e.width,m=e.height;if("center"===c)s=g+m/2,"left"===h?(a=(i=f)-u,r=i,o=s+u,l=s-u):(a=(i=f+p)+u,r=i,o=s-u,l=s+u);else if("left"===h?(i=(a=f+d+u)-u,r=a+u):"right"===h?(i=(a=f+p-d-u)-u,r=a+u):(i=(a=n.caretX)-u,r=a+u),"top"===c)s=(o=g)-u,l=o;else{s=(o=g+m)+u,l=o;var v=r;r=i,i=v}return{x1:i,x2:a,x3:r,y1:o,y2:s,y3:l}},drawTitle:function(t,e,n){var i,a,r,o=e.title,s=o.length;if(s){var l=Ne(e.rtl,e.x,e.width);for(t.x=He(e,e._titleAlign),n.textAlign=l.textAlign(e._titleAlign),n.textBaseline="middle",i=e.titleFontSize,a=e.titleSpacing,n.fillStyle=e.titleFontColor,n.font=H.fontString(i,e._titleFontStyle,e._titleFontFamily),r=0;r<s;++r)n.fillText(o[r],l.x(t.x),t.y+i/2),t.y+=i+a,r+1===s&&(t.y+=e.titleMarginBottom-a)}},drawBody:function(t,e,n){var i,a,r,o,s,l,u,d,h=e.bodyFontSize,c=e.bodySpacing,f=e._bodyAlign,g=e.body,p=e.displayColors,m=0,v=p?He(e,"left"):0,b=Ne(e.rtl,e.x,e.width),x=function(e){n.fillText(e,b.x(t.x+m),t.y+h/2),t.y+=h+c},y=b.textAlign(f);for(n.textAlign=f,n.textBaseline="middle",n.font=H.fontString(h,e._bodyFontStyle,e._bodyFontFamily),t.x=He(e,y),n.fillStyle=e.bodyFontColor,H.each(e.beforeBody,x),m=p&&"right"!==y?"center"===f?h/2+1:h+2:0,s=0,u=g.length;s<u;++s){for(i=g[s],a=e.labelTextColors[s],r=e.labelColors[s],n.fillStyle=a,H.each(i.before,x),l=0,d=(o=i.lines).length;l<d;++l){if(p){var _=b.x(v);n.fillStyle=e.legendColorBackground,n.fillRect(b.leftForLtr(_,h),t.y,h,h),n.lineWidth=1,n.strokeStyle=r.borderColor,n.strokeRect(b.leftForLtr(_,h),t.y,h,h),n.fillStyle=r.backgroundColor,n.fillRect(b.leftForLtr(b.xPlus(_,1),h-2),t.y+1,h-2,h-2),n.fillStyle=a}x(o[l])}H.each(i.after,x)}m=0,H.each(e.afterBody,x),t.y-=c},drawFooter:function(t,e,n){var i,a,r=e.footer,o=r.length;if(o){var s=Ne(e.rtl,e.x,e.width);for(t.x=He(e,e._footerAlign),t.y+=e.footerMarginTop,n.textAlign=s.textAlign(e._footerAlign),n.textBaseline="middle",i=e.footerFontSize,n.fillStyle=e.footerFontColor,n.font=H.fontString(i,e._footerFontStyle,e._footerFontFamily),a=0;a<o;++a)n.fillText(r[a],s.x(t.x),t.y+i/2),t.y+=i+e.footerSpacing}},drawBackground:function(t,e,n,i){n.fillStyle=e.backgroundColor,n.strokeStyle=e.borderColor,n.lineWidth=e.borderWidth;var a=e.xAlign,r=e.yAlign,o=t.x,s=t.y,l=i.width,u=i.height,d=e.cornerRadius;n.beginPath(),n.moveTo(o+d,s),"top"===r&&this.drawCaret(t,i),n.lineTo(o+l-d,s),n.quadraticCurveTo(o+l,s,o+l,s+d),"center"===r&&"right"===a&&this.drawCaret(t,i),n.lineTo(o+l,s+u-d),n.quadraticCurveTo(o+l,s+u,o+l-d,s+u),"bottom"===r&&this.drawCaret(t,i),n.lineTo(o+d,s+u),n.quadraticCurveTo(o,s+u,o,s+u-d),"center"===r&&"left"===a&&this.drawCaret(t,i),n.lineTo(o,s+d),n.quadraticCurveTo(o,s,o+d,s),n.closePath(),n.fill(),e.borderWidth>0&&n.stroke()},draw:function(){var t=this._chart.ctx,e=this._view;if(0!==e.opacity){var n={width:e.width,height:e.height},i={x:e.x,y:e.y},a=Math.abs(e.opacity<.001)?0:e.opacity,r=e.title.length||e.beforeBody.length||e.body.length||e.afterBody.length||e.footer.length;this._options.enabled&&r&&(t.save(),t.globalAlpha=a,this.drawBackground(i,e,t,n),i.y+=e.yPadding,H.rtl.overrideTextDirection(t,e.textDirection),this.drawTitle(i,e,t),this.drawBody(i,e,t),this.drawFooter(i,e,t),H.rtl.restoreTextDirection(t,e.textDirection),t.restore())}},handleEvent:function(t){var e,n=this,i=n._options;return n._lastActive=n._lastActive||[],"mouseout"===t.type?n._active=[]:(n._active=n._chart.getElementsAtEventForMode(t,i.mode,i),i.reverse&&n._active.reverse()),(e=!H.arrayEquals(n._active,n._lastActive))&&(n._lastActive=n._active,(i.enabled||i.custom)&&(n._eventPosition={x:t.x,y:t.y},n.update(!0),n.pivot())),e}}),Ue=Be,Ye=qe;Ye.positioners=Ue;var Ge=H.valueOrDefault;function Xe(){return H.merge(Object.create(null),[].slice.call(arguments),{merger:function(t,e,n,i){if("xAxes"===t||"yAxes"===t){var a,r,o,s=n[t].length;for(e[t]||(e[t]=[]),a=0;a<s;++a)o=n[t][a],r=Ge(o.type,"xAxes"===t?"category":"linear"),a>=e[t].length&&e[t].push({}),!e[t][a].type||o.type&&o.type!==e[t][a].type?H.merge(e[t][a],[Re.getScaleDefaults(r),o]):H.merge(e[t][a],o)}else H._merger(t,e,n,i)}})}function Ke(){return H.merge(Object.create(null),[].slice.call(arguments),{merger:function(t,e,n,i){var a=e[t]||Object.create(null),r=n[t];"scales"===t?e[t]=Xe(a,r):"scale"===t?e[t]=H.merge(a,[Re.getScaleDefaults(r.type),r]):H._merger(t,e,n,i)}})}function Ze(t){var e=t.options;H.each(t.scales,(function(e){pe.removeBox(t,e)})),e=Ke(N.global,N[t.config.type],e),t.options=t.config.options=e,t.ensureScalesHaveIDs(),t.buildOrUpdateScales(),t.tooltip._options=e.tooltips,t.tooltip.initialize()}function $e(t,e,n){var i,a=function(t){return t.id===i};do{i=e+n++}while(H.findIndex(t,a)>=0);return i}function Je(t){return"top"===t||"bottom"===t}function Qe(t,e){return function(n,i){return n[t]===i[t]?n[e]-i[e]:n[t]-i[t]}}N._set("global",{elements:{},events:["mousemove","mouseout","click","touchstart","touchmove"],hover:{onHover:null,mode:"nearest",intersect:!0,animationDuration:400},onClick:null,maintainAspectRatio:!0,responsive:!0,responsiveAnimationDuration:0});var tn=function(t,e){return this.construct(t,e),this};H.extend(tn.prototype,{construct:function(t,e){var n=this;e=function(t){var e=(t=t||Object.create(null)).data=t.data||{};return e.datasets=e.datasets||[],e.labels=e.labels||[],t.options=Ke(N.global,N[t.type],t.options||{}),t}(e);var i=Oe.acquireContext(t,e),a=i&&i.canvas,r=a&&a.height,o=a&&a.width;n.id=H.uid(),n.ctx=i,n.canvas=a,n.config=e,n.width=o,n.height=r,n.aspectRatio=r?o/r:null,n.options=e.options,n._bufferedRender=!1,n._layers=[],n.chart=n,n.controller=n,tn.instances[n.id]=n,Object.defineProperty(n,"data",{get:function(){return n.config.data},set:function(t){n.config.data=t}}),i&&a?(n.initialize(),n.update()):console.error("Failed to create chart: can't acquire context from the given item")},initialize:function(){var t=this;return Le.notify(t,"beforeInit"),H.retinaScale(t,t.options.devicePixelRatio),t.bindEvents(),t.options.responsive&&t.resize(!0),t.initToolTip(),Le.notify(t,"afterInit"),t},clear:function(){return H.canvas.clear(this),this},stop:function(){return J.cancelAnimation(this),this},resize:function(t){var e=this,n=e.options,i=e.canvas,a=n.maintainAspectRatio&&e.aspectRatio||null,r=Math.max(0,Math.floor(H.getMaximumWidth(i))),o=Math.max(0,Math.floor(a?r/a:H.getMaximumHeight(i)));if((e.width!==r||e.height!==o)&&(i.width=e.width=r,i.height=e.height=o,i.style.width=r+"px",i.style.height=o+"px",H.retinaScale(e,n.devicePixelRatio),!t)){var s={width:r,height:o};Le.notify(e,"resize",[s]),n.onResize&&n.onResize(e,s),e.stop(),e.update({duration:n.responsiveAnimationDuration})}},ensureScalesHaveIDs:function(){var t=this.options,e=t.scales||{},n=t.scale;H.each(e.xAxes,(function(t,n){t.id||(t.id=$e(e.xAxes,"x-axis-",n))})),H.each(e.yAxes,(function(t,n){t.id||(t.id=$e(e.yAxes,"y-axis-",n))})),n&&(n.id=n.id||"scale")},buildOrUpdateScales:function(){var t=this,e=t.options,n=t.scales||{},i=[],a=Object.keys(n).reduce((function(t,e){return t[e]=!1,t}),{});e.scales&&(i=i.concat((e.scales.xAxes||[]).map((function(t){return{options:t,dtype:"category",dposition:"bottom"}})),(e.scales.yAxes||[]).map((function(t){return{options:t,dtype:"linear",dposition:"left"}})))),e.scale&&i.push({options:e.scale,dtype:"radialLinear",isDefault:!0,dposition:"chartArea"}),H.each(i,(function(e){var i=e.options,r=i.id,o=Ge(i.type,e.dtype);Je(i.position)!==Je(e.dposition)&&(i.position=e.dposition),a[r]=!0;var s=null;if(r in n&&n[r].type===o)(s=n[r]).options=i,s.ctx=t.ctx,s.chart=t;else{var l=Re.getScaleConstructor(o);if(!l)return;s=new l({id:r,type:o,options:i,ctx:t.ctx,chart:t}),n[s.id]=s}s.mergeTicksOptions(),e.isDefault&&(t.scale=s)})),H.each(a,(function(t,e){t||delete n[e]})),t.scales=n,Re.addScalesToLayout(this)},buildOrUpdateControllers:function(){var t,e,n=this,i=[],a=n.data.datasets;for(t=0,e=a.length;t<e;t++){var r=a[t],o=n.getDatasetMeta(t),s=r.type||n.config.type;if(o.type&&o.type!==s&&(n.destroyDatasetMeta(t),o=n.getDatasetMeta(t)),o.type=s,o.order=r.order||0,o.index=t,o.controller)o.controller.updateIndex(t),o.controller.linkScales();else{var l=Jt[o.type];if(void 0===l)throw new Error('"'+o.type+'" is not a chart type.');o.controller=new l(n,t),i.push(o.controller)}}return i},resetElements:function(){var t=this;H.each(t.data.datasets,(function(e,n){t.getDatasetMeta(n).controller.reset()}),t)},reset:function(){this.resetElements(),this.tooltip.initialize()},update:function(t){var e,n,i=this;if(t&&"object"==typeof t||(t={duration:t,lazy:arguments[1]}),Ze(i),Le._invalidate(i),!1!==Le.notify(i,"beforeUpdate")){i.tooltip._data=i.data;var a=i.buildOrUpdateControllers();for(e=0,n=i.data.datasets.length;e<n;e++)i.getDatasetMeta(e).controller.buildOrUpdateElements();i.updateLayout(),i.options.animation&&i.options.animation.duration&&H.each(a,(function(t){t.reset()})),i.updateDatasets(),i.tooltip.initialize(),i.lastActive=[],Le.notify(i,"afterUpdate"),i._layers.sort(Qe("z","_idx")),i._bufferedRender?i._bufferedRequest={duration:t.duration,easing:t.easing,lazy:t.lazy}:i.render(t)}},updateLayout:function(){var t=this;!1!==Le.notify(t,"beforeLayout")&&(pe.update(this,this.width,this.height),t._layers=[],H.each(t.boxes,(function(e){e._configure&&e._configure(),t._layers.push.apply(t._layers,e._layers())}),t),t._layers.forEach((function(t,e){t._idx=e})),Le.notify(t,"afterScaleUpdate"),Le.notify(t,"afterLayout"))},updateDatasets:function(){if(!1!==Le.notify(this,"beforeDatasetsUpdate")){for(var t=0,e=this.data.datasets.length;t<e;++t)this.updateDataset(t);Le.notify(this,"afterDatasetsUpdate")}},updateDataset:function(t){var e=this.getDatasetMeta(t),n={meta:e,index:t};!1!==Le.notify(this,"beforeDatasetUpdate",[n])&&(e.controller._update(),Le.notify(this,"afterDatasetUpdate",[n]))},render:function(t){var e=this;t&&"object"==typeof t||(t={duration:t,lazy:arguments[1]});var n=e.options.animation,i=Ge(t.duration,n&&n.duration),a=t.lazy;if(!1!==Le.notify(e,"beforeRender")){var r=function(t){Le.notify(e,"afterRender"),H.callback(n&&n.onComplete,[t],e)};if(n&&i){var o=new $({numSteps:i/16.66,easing:t.easing||n.easing,render:function(t,e){var n=H.easing.effects[e.easing],i=e.currentStep,a=i/e.numSteps;t.draw(n(a),a,i)},onAnimationProgress:n.onProgress,onAnimationComplete:r});J.addAnimation(e,o,i,a)}else e.draw(),r(new $({numSteps:0,chart:e}));return e}},draw:function(t){var e,n,i=this;if(i.clear(),H.isNullOrUndef(t)&&(t=1),i.transition(t),!(i.width<=0||i.height<=0)&&!1!==Le.notify(i,"beforeDraw",[t])){for(n=i._layers,e=0;e<n.length&&n[e].z<=0;++e)n[e].draw(i.chartArea);for(i.drawDatasets(t);e<n.length;++e)n[e].draw(i.chartArea);i._drawTooltip(t),Le.notify(i,"afterDraw",[t])}},transition:function(t){for(var e=0,n=(this.data.datasets||[]).length;e<n;++e)this.isDatasetVisible(e)&&this.getDatasetMeta(e).controller.transition(t);this.tooltip.transition(t)},_getSortedDatasetMetas:function(t){var e,n,i=[];for(e=0,n=(this.data.datasets||[]).length;e<n;++e)t&&!this.isDatasetVisible(e)||i.push(this.getDatasetMeta(e));return i.sort(Qe("order","index")),i},_getSortedVisibleDatasetMetas:function(){return this._getSortedDatasetMetas(!0)},drawDatasets:function(t){var e,n;if(!1!==Le.notify(this,"beforeDatasetsDraw",[t])){for(n=(e=this._getSortedVisibleDatasetMetas()).length-1;n>=0;--n)this.drawDataset(e[n],t);Le.notify(this,"afterDatasetsDraw",[t])}},drawDataset:function(t,e){var n={meta:t,index:t.index,easingValue:e};!1!==Le.notify(this,"beforeDatasetDraw",[n])&&(t.controller.draw(e),Le.notify(this,"afterDatasetDraw",[n]))},_drawTooltip:function(t){var e=this.tooltip,n={tooltip:e,easingValue:t};!1!==Le.notify(this,"beforeTooltipDraw",[n])&&(e.draw(),Le.notify(this,"afterTooltipDraw",[n]))},getElementAtEvent:function(t){return re.modes.single(this,t)},getElementsAtEvent:function(t){return re.modes.label(this,t,{intersect:!0})},getElementsAtXAxis:function(t){return re.modes["x-axis"](this,t,{intersect:!0})},getElementsAtEventForMode:function(t,e,n){var i=re.modes[e];return"function"==typeof i?i(this,t,n):[]},getDatasetAtEvent:function(t){return re.modes.dataset(this,t,{intersect:!0})},getDatasetMeta:function(t){var e=this.data.datasets[t];e._meta||(e._meta={});var n=e._meta[this.id];return n||(n=e._meta[this.id]={type:null,data:[],dataset:null,controller:null,hidden:null,xAxisID:null,yAxisID:null,order:e.order||0,index:t}),n},getVisibleDatasetCount:function(){for(var t=0,e=0,n=this.data.datasets.length;e<n;++e)this.isDatasetVisible(e)&&t++;return t},isDatasetVisible:function(t){var e=this.getDatasetMeta(t);return"boolean"==typeof e.hidden?!e.hidden:!this.data.datasets[t].hidden},generateLegend:function(){return this.options.legendCallback(this)},destroyDatasetMeta:function(t){var e=this.id,n=this.data.datasets[t],i=n._meta&&n._meta[e];i&&(i.controller.destroy(),delete n._meta[e])},destroy:function(){var t,e,n=this,i=n.canvas;for(n.stop(),t=0,e=n.data.datasets.length;t<e;++t)n.destroyDatasetMeta(t);i&&(n.unbindEvents(),H.canvas.clear(n),Oe.releaseContext(n.ctx),n.canvas=null,n.ctx=null),Le.notify(n,"destroy"),delete tn.instances[n.id]},toBase64Image:function(){return this.canvas.toDataURL.apply(this.canvas,arguments)},initToolTip:function(){var t=this;t.tooltip=new Ye({_chart:t,_chartInstance:t,_data:t.data,_options:t.options.tooltips},t)},bindEvents:function(){var t=this,e=t._listeners={},n=function(){t.eventHandler.apply(t,arguments)};H.each(t.options.events,(function(i){Oe.addEventListener(t,i,n),e[i]=n})),t.options.responsive&&(n=function(){t.resize()},Oe.addEventListener(t,"resize",n),e.resize=n)},unbindEvents:function(){var t=this,e=t._listeners;e&&(delete t._listeners,H.each(e,(function(e,n){Oe.removeEventListener(t,n,e)})))},updateHoverStyle:function(t,e,n){var i,a,r,o=n?"set":"remove";for(a=0,r=t.length;a<r;++a)(i=t[a])&&this.getDatasetMeta(i._datasetIndex).controller[o+"HoverStyle"](i);"dataset"===e&&this.getDatasetMeta(t[0]._datasetIndex).controller["_"+o+"DatasetHoverStyle"]()},eventHandler:function(t){var e=this,n=e.tooltip;if(!1!==Le.notify(e,"beforeEvent",[t])){e._bufferedRender=!0,e._bufferedRequest=null;var i=e.handleEvent(t);n&&(i=n._start?n.handleEvent(t):i|n.handleEvent(t)),Le.notify(e,"afterEvent",[t]);var a=e._bufferedRequest;return a?e.render(a):i&&!e.animating&&(e.stop(),e.render({duration:e.options.hover.animationDuration,lazy:!0})),e._bufferedRender=!1,e._bufferedRequest=null,e}},handleEvent:function(t){var e,n=this,i=n.options||{},a=i.hover;return n.lastActive=n.lastActive||[],"mouseout"===t.type?n.active=[]:n.active=n.getElementsAtEventForMode(t,a.mode,a),H.callback(i.onHover||i.hover.onHover,[t.native,n.active],n),"mouseup"!==t.type&&"click"!==t.type||i.onClick&&i.onClick.call(n,t.native,n.active),n.lastActive.length&&n.updateHoverStyle(n.lastActive,a.mode,!1),n.active.length&&a.mode&&n.updateHoverStyle(n.active,a.mode,!0),e=!H.arrayEquals(n.active,n.lastActive),n.lastActive=n.active,e}}),tn.instances={};var en=tn;tn.Controller=tn,tn.types={},H.configMerge=Ke,H.scaleMerge=Xe;function nn(){throw new Error("This method is not implemented: either no adapter can be found or an incomplete integration was provided.")}function an(t){this.options=t||{}}H.extend(an.prototype,{formats:nn,parse:nn,format:nn,add:nn,diff:nn,startOf:nn,endOf:nn,_create:function(t){return t}}),an.override=function(t){H.extend(an.prototype,t)};var rn={_date:an},on={formatters:{values:function(t){return H.isArray(t)?t:""+t},linear:function(t,e,n){var i=n.length>3?n[2]-n[1]:n[1]-n[0];Math.abs(i)>1&&t!==Math.floor(t)&&(i=t-Math.floor(t));var a=H.log10(Math.abs(i)),r="";if(0!==t)if(Math.max(Math.abs(n[0]),Math.abs(n[n.length-1]))<1e-4){var o=H.log10(Math.abs(t)),s=Math.floor(o)-Math.floor(a);s=Math.max(Math.min(s,20),0),r=t.toExponential(s)}else{var l=-1*Math.floor(a);l=Math.max(Math.min(l,20),0),r=t.toFixed(l)}else r="0";return r},logarithmic:function(t,e,n){var i=t/Math.pow(10,Math.floor(H.log10(t)));return 0===t?"0":1===i||2===i||5===i||0===e||e===n.length-1?t.toExponential():""}}},sn=H.isArray,ln=H.isNullOrUndef,un=H.valueOrDefault,dn=H.valueAtIndexOrDefault;function hn(t,e,n){var i,a=t.getTicks().length,r=Math.min(e,a-1),o=t.getPixelForTick(r),s=t._startPixel,l=t._endPixel;if(!(n&&(i=1===a?Math.max(o-s,l-o):0===e?(t.getPixelForTick(1)-o)/2:(o-t.getPixelForTick(r-1))/2,(o+=r<e?i:-i)<s-1e-6||o>l+1e-6)))return o}function cn(t,e,n,i){var a,r,o,s,l,u,d,h,c,f,g,p,m,v=n.length,b=[],x=[],y=[],_=0,k=0;for(a=0;a<v;++a){if(s=n[a].label,l=n[a].major?e.major:e.minor,t.font=u=l.string,d=i[u]=i[u]||{data:{},gc:[]},h=l.lineHeight,c=f=0,ln(s)||sn(s)){if(sn(s))for(r=0,o=s.length;r<o;++r)g=s[r],ln(g)||sn(g)||(c=H.measureText(t,d.data,d.gc,c,g),f+=h)}else c=H.measureText(t,d.data,d.gc,c,s),f=h;b.push(c),x.push(f),y.push(h/2),_=Math.max(c,_),k=Math.max(f,k)}function w(t){return{width:b[t]||0,height:x[t]||0,offset:y[t]||0}}return function(t,e){H.each(t,(function(t){var n,i=t.gc,a=i.length/2;if(a>e){for(n=0;n<a;++n)delete t.data[i[n]];i.splice(0,a)}}))}(i,v),p=b.indexOf(_),m=x.indexOf(k),{first:w(0),last:w(v-1),widest:w(p),highest:w(m)}}function fn(t){return t.drawTicks?t.tickMarkLength:0}function gn(t){var e,n;return t.display?(e=H.options._parseFont(t),n=H.options.toPadding(t.padding),e.lineHeight+n.height):0}function pn(t,e){return H.extend(H.options._parseFont({fontFamily:un(e.fontFamily,t.fontFamily),fontSize:un(e.fontSize,t.fontSize),fontStyle:un(e.fontStyle,t.fontStyle),lineHeight:un(e.lineHeight,t.lineHeight)}),{color:H.options.resolve([e.fontColor,t.fontColor,N.global.defaultFontColor])})}function mn(t){var e=pn(t,t.minor);return{minor:e,major:t.major.enabled?pn(t,t.major):e}}function vn(t){var e,n,i,a=[];for(n=0,i=t.length;n<i;++n)void 0!==(e=t[n])._index&&a.push(e);return a}function bn(t,e,n,i){var a,r,o,s,l=un(n,0),u=Math.min(un(i,t.length),t.length),d=0;for(e=Math.ceil(e),i&&(e=(a=i-n)/Math.floor(a/e)),s=l;s<0;)d++,s=Math.round(l+d*e);for(r=Math.max(l,0);r<u;r++)o=t[r],r===s?(o._index=r,d++,s=Math.round(l+d*e)):delete o.label}N._set("scale",{display:!0,position:"left",offset:!1,gridLines:{display:!0,color:"rgba(0,0,0,0.1)",lineWidth:1,drawBorder:!0,drawOnChartArea:!0,drawTicks:!0,tickMarkLength:10,zeroLineWidth:1,zeroLineColor:"rgba(0,0,0,0.25)",zeroLineBorderDash:[],zeroLineBorderDashOffset:0,offsetGridLines:!1,borderDash:[],borderDashOffset:0},scaleLabel:{display:!1,labelString:"",padding:{top:4,bottom:4}},ticks:{beginAtZero:!1,minRotation:0,maxRotation:50,mirror:!1,padding:0,reverse:!1,display:!0,autoSkip:!0,autoSkipPadding:0,labelOffset:0,callback:on.formatters.values,minor:{},major:{}}});var xn=K.extend({zeroLineIndex:0,getPadding:function(){return{left:this.paddingLeft||0,top:this.paddingTop||0,right:this.paddingRight||0,bottom:this.paddingBottom||0}},getTicks:function(){return this._ticks},_getLabels:function(){var t=this.chart.data;return this.options.labels||(this.isHorizontal()?t.xLabels:t.yLabels)||t.labels||[]},mergeTicksOptions:function(){},beforeUpdate:function(){H.callback(this.options.beforeUpdate,[this])},update:function(t,e,n){var i,a,r,o,s,l=this,u=l.options.ticks,d=u.sampleSize;if(l.beforeUpdate(),l.maxWidth=t,l.maxHeight=e,l.margins=H.extend({left:0,right:0,top:0,bottom:0},n),l._ticks=null,l.ticks=null,l._labelSizes=null,l._maxLabelLines=0,l.longestLabelWidth=0,l.longestTextCache=l.longestTextCache||{},l._gridLineItems=null,l._labelItems=null,l.beforeSetDimensions(),l.setDimensions(),l.afterSetDimensions(),l.beforeDataLimits(),l.determineDataLimits(),l.afterDataLimits(),l.beforeBuildTicks(),o=l.buildTicks()||[],(!(o=l.afterBuildTicks(o)||o)||!o.length)&&l.ticks)for(o=[],i=0,a=l.ticks.length;i<a;++i)o.push({value:l.ticks[i],major:!1});return l._ticks=o,s=d<o.length,r=l._convertTicksToLabels(s?function(t,e){for(var n=[],i=t.length/e,a=0,r=t.length;a<r;a+=i)n.push(t[Math.floor(a)]);return n}(o,d):o),l._configure(),l.beforeCalculateTickRotation(),l.calculateTickRotation(),l.afterCalculateTickRotation(),l.beforeFit(),l.fit(),l.afterFit(),l._ticksToDraw=u.display&&(u.autoSkip||"auto"===u.source)?l._autoSkip(o):o,s&&(r=l._convertTicksToLabels(l._ticksToDraw)),l.ticks=r,l.afterUpdate(),l.minSize},_configure:function(){var t,e,n=this,i=n.options.ticks.reverse;n.isHorizontal()?(t=n.left,e=n.right):(t=n.top,e=n.bottom,i=!i),n._startPixel=t,n._endPixel=e,n._reversePixels=i,n._length=e-t},afterUpdate:function(){H.callback(this.options.afterUpdate,[this])},beforeSetDimensions:function(){H.callback(this.options.beforeSetDimensions,[this])},setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0},afterSetDimensions:function(){H.callback(this.options.afterSetDimensions,[this])},beforeDataLimits:function(){H.callback(this.options.beforeDataLimits,[this])},determineDataLimits:H.noop,afterDataLimits:function(){H.callback(this.options.afterDataLimits,[this])},beforeBuildTicks:function(){H.callback(this.options.beforeBuildTicks,[this])},buildTicks:H.noop,afterBuildTicks:function(t){var e=this;return sn(t)&&t.length?H.callback(e.options.afterBuildTicks,[e,t]):(e.ticks=H.callback(e.options.afterBuildTicks,[e,e.ticks])||e.ticks,t)},beforeTickToLabelConversion:function(){H.callback(this.options.beforeTickToLabelConversion,[this])},convertTicksToLabels:function(){var t=this.options.ticks;this.ticks=this.ticks.map(t.userCallback||t.callback,this)},afterTickToLabelConversion:function(){H.callback(this.options.afterTickToLabelConversion,[this])},beforeCalculateTickRotation:function(){H.callback(this.options.beforeCalculateTickRotation,[this])},calculateTickRotation:function(){var t,e,n,i,a,r,o,s=this,l=s.options,u=l.ticks,d=s.getTicks().length,h=u.minRotation||0,c=u.maxRotation,f=h;!s._isVisible()||!u.display||h>=c||d<=1||!s.isHorizontal()?s.labelRotation=h:(e=(t=s._getLabelSizes()).widest.width,n=t.highest.height-t.highest.offset,i=Math.min(s.maxWidth,s.chart.width-e),e+6>(a=l.offset?s.maxWidth/d:i/(d-1))&&(a=i/(d-(l.offset?.5:1)),r=s.maxHeight-fn(l.gridLines)-u.padding-gn(l.scaleLabel),o=Math.sqrt(e*e+n*n),f=H.toDegrees(Math.min(Math.asin(Math.min((t.highest.height+6)/a,1)),Math.asin(Math.min(r/o,1))-Math.asin(n/o))),f=Math.max(h,Math.min(c,f))),s.labelRotation=f)},afterCalculateTickRotation:function(){H.callback(this.options.afterCalculateTickRotation,[this])},beforeFit:function(){H.callback(this.options.beforeFit,[this])},fit:function(){var t=this,e=t.minSize={width:0,height:0},n=t.chart,i=t.options,a=i.ticks,r=i.scaleLabel,o=i.gridLines,s=t._isVisible(),l="bottom"===i.position,u=t.isHorizontal();if(u?e.width=t.maxWidth:s&&(e.width=fn(o)+gn(r)),u?s&&(e.height=fn(o)+gn(r)):e.height=t.maxHeight,a.display&&s){var d=mn(a),h=t._getLabelSizes(),c=h.first,f=h.last,g=h.widest,p=h.highest,m=.4*d.minor.lineHeight,v=a.padding;if(u){var b=0!==t.labelRotation,x=H.toRadians(t.labelRotation),y=Math.cos(x),_=Math.sin(x),k=_*g.width+y*(p.height-(b?p.offset:0))+(b?0:m);e.height=Math.min(t.maxHeight,e.height+k+v);var w,M,S=t.getPixelForTick(0)-t.left,C=t.right-t.getPixelForTick(t.getTicks().length-1);b?(w=l?y*c.width+_*c.offset:_*(c.height-c.offset),M=l?_*(f.height-f.offset):y*f.width+_*f.offset):(w=c.width/2,M=f.width/2),t.paddingLeft=Math.max((w-S)*t.width/(t.width-S),0)+3,t.paddingRight=Math.max((M-C)*t.width/(t.width-C),0)+3}else{var P=a.mirror?0:g.width+v+m;e.width=Math.min(t.maxWidth,e.width+P),t.paddingTop=c.height/2,t.paddingBottom=f.height/2}}t.handleMargins(),u?(t.width=t._length=n.width-t.margins.left-t.margins.right,t.height=e.height):(t.width=e.width,t.height=t._length=n.height-t.margins.top-t.margins.bottom)},handleMargins:function(){var t=this;t.margins&&(t.margins.left=Math.max(t.paddingLeft,t.margins.left),t.margins.top=Math.max(t.paddingTop,t.margins.top),t.margins.right=Math.max(t.paddingRight,t.margins.right),t.margins.bottom=Math.max(t.paddingBottom,t.margins.bottom))},afterFit:function(){H.callback(this.options.afterFit,[this])},isHorizontal:function(){var t=this.options.position;return"top"===t||"bottom"===t},isFullWidth:function(){return this.options.fullWidth},getRightValue:function(t){if(ln(t))return NaN;if(("number"==typeof t||t instanceof Number)&&!isFinite(t))return NaN;if(t)if(this.isHorizontal()){if(void 0!==t.x)return this.getRightValue(t.x)}else if(void 0!==t.y)return this.getRightValue(t.y);return t},_convertTicksToLabels:function(t){var e,n,i,a=this;for(a.ticks=t.map((function(t){return t.value})),a.beforeTickToLabelConversion(),e=a.convertTicksToLabels(t)||a.ticks,a.afterTickToLabelConversion(),n=0,i=t.length;n<i;++n)t[n].label=e[n];return e},_getLabelSizes:function(){var t=this,e=t._labelSizes;return e||(t._labelSizes=e=cn(t.ctx,mn(t.options.ticks),t.getTicks(),t.longestTextCache),t.longestLabelWidth=e.widest.width),e},_parseValue:function(t){var e,n,i,a;return sn(t)?(e=+this.getRightValue(t[0]),n=+this.getRightValue(t[1]),i=Math.min(e,n),a=Math.max(e,n)):(e=void 0,n=t=+this.getRightValue(t),i=t,a=t),{min:i,max:a,start:e,end:n}},_getScaleLabel:function(t){var e=this._parseValue(t);return void 0!==e.start?"["+e.start+", "+e.end+"]":+this.getRightValue(t)},getLabelForIndex:H.noop,getPixelForValue:H.noop,getValueForPixel:H.noop,getPixelForTick:function(t){var e=this.options.offset,n=this._ticks.length,i=1/Math.max(n-(e?0:1),1);return t<0||t>n-1?null:this.getPixelForDecimal(t*i+(e?i/2:0))},getPixelForDecimal:function(t){return this._reversePixels&&(t=1-t),this._startPixel+t*this._length},getDecimalForPixel:function(t){var e=(t-this._startPixel)/this._length;return this._reversePixels?1-e:e},getBasePixel:function(){return this.getPixelForValue(this.getBaseValue())},getBaseValue:function(){var t=this.min,e=this.max;return this.beginAtZero?0:t<0&&e<0?e:t>0&&e>0?t:0},_autoSkip:function(t){var e,n,i,a,r=this.options.ticks,o=this._length,s=r.maxTicksLimit||o/this._tickSize()+1,l=r.major.enabled?function(t){var e,n,i=[];for(e=0,n=t.length;e<n;e++)t[e].major&&i.push(e);return i}(t):[],u=l.length,d=l[0],h=l[u-1];if(u>s)return function(t,e,n){var i,a,r=0,o=e[0];for(n=Math.ceil(n),i=0;i<t.length;i++)a=t[i],i===o?(a._index=i,o=e[++r*n]):delete a.label}(t,l,u/s),vn(t);if(i=function(t,e,n,i){var a,r,o,s,l=function(t){var e,n,i=t.length;if(i<2)return!1;for(n=t[0],e=1;e<i;++e)if(t[e]-t[e-1]!==n)return!1;return n}(t),u=(e.length-1)/i;if(!l)return Math.max(u,1);for(o=0,s=(a=H.math._factorize(l)).length-1;o<s;o++)if((r=a[o])>u)return r;return Math.max(u,1)}(l,t,0,s),u>0){for(e=0,n=u-1;e<n;e++)bn(t,i,l[e],l[e+1]);return a=u>1?(h-d)/(u-1):null,bn(t,i,H.isNullOrUndef(a)?0:d-a,d),bn(t,i,h,H.isNullOrUndef(a)?t.length:h+a),vn(t)}return bn(t,i),vn(t)},_tickSize:function(){var t=this.options.ticks,e=H.toRadians(this.labelRotation),n=Math.abs(Math.cos(e)),i=Math.abs(Math.sin(e)),a=this._getLabelSizes(),r=t.autoSkipPadding||0,o=a?a.widest.width+r:0,s=a?a.highest.height+r:0;return this.isHorizontal()?s*n>o*i?o/n:s/i:s*i<o*n?s/n:o/i},_isVisible:function(){var t,e,n,i=this.chart,a=this.options.display;if("auto"!==a)return!!a;for(t=0,e=i.data.datasets.length;t<e;++t)if(i.isDatasetVisible(t)&&((n=i.getDatasetMeta(t)).xAxisID===this.id||n.yAxisID===this.id))return!0;return!1},_computeGridLineItems:function(t){var e,n,i,a,r,o,s,l,u,d,h,c,f,g,p,m,v,b=this,x=b.chart,y=b.options,_=y.gridLines,k=y.position,w=_.offsetGridLines,M=b.isHorizontal(),S=b._ticksToDraw,C=S.length+(w?1:0),P=fn(_),A=[],D=_.drawBorder?dn(_.lineWidth,0,0):0,T=D/2,I=H._alignPixel,F=function(t){return I(x,t,D)};for("top"===k?(e=F(b.bottom),s=b.bottom-P,u=e-T,h=F(t.top)+T,f=t.bottom):"bottom"===k?(e=F(b.top),h=t.top,f=F(t.bottom)-T,s=e+T,u=b.top+P):"left"===k?(e=F(b.right),o=b.right-P,l=e-T,d=F(t.left)+T,c=t.right):(e=F(b.left),d=t.left,c=F(t.right)-T,o=e+T,l=b.left+P),n=0;n<C;++n)i=S[n]||{},ln(i.label)&&n<S.length||(n===b.zeroLineIndex&&y.offset===w?(g=_.zeroLineWidth,p=_.zeroLineColor,m=_.zeroLineBorderDash||[],v=_.zeroLineBorderDashOffset||0):(g=dn(_.lineWidth,n,1),p=dn(_.color,n,"rgba(0,0,0,0.1)"),m=_.borderDash||[],v=_.borderDashOffset||0),void 0!==(a=hn(b,i._index||n,w))&&(r=I(x,a,g),M?o=l=d=c=r:s=u=h=f=r,A.push({tx1:o,ty1:s,tx2:l,ty2:u,x1:d,y1:h,x2:c,y2:f,width:g,color:p,borderDash:m,borderDashOffset:v})));return A.ticksLength=C,A.borderValue=e,A},_computeLabelItems:function(){var t,e,n,i,a,r,o,s,l,u,d,h,c=this,f=c.options,g=f.ticks,p=f.position,m=g.mirror,v=c.isHorizontal(),b=c._ticksToDraw,x=mn(g),y=g.padding,_=fn(f.gridLines),k=-H.toRadians(c.labelRotation),w=[];for("top"===p?(r=c.bottom-_-y,o=k?"left":"center"):"bottom"===p?(r=c.top+_+y,o=k?"right":"center"):"left"===p?(a=c.right-(m?0:_)-y,o=m?"left":"right"):(a=c.left+(m?0:_)+y,o=m?"right":"left"),t=0,e=b.length;t<e;++t)i=(n=b[t]).label,ln(i)||(s=c.getPixelForTick(n._index||t)+g.labelOffset,u=(l=n.major?x.major:x.minor).lineHeight,d=sn(i)?i.length:1,v?(a=s,h="top"===p?((k?1:.5)-d)*u:(k?0:.5)*u):(r=s,h=(1-d)*u/2),w.push({x:a,y:r,rotation:k,label:i,font:l,textOffset:h,textAlign:o}));return w},_drawGrid:function(t){var e=this,n=e.options.gridLines;if(n.display){var i,a,r,o,s,l=e.ctx,u=e.chart,d=H._alignPixel,h=n.drawBorder?dn(n.lineWidth,0,0):0,c=e._gridLineItems||(e._gridLineItems=e._computeGridLineItems(t));for(r=0,o=c.length;r<o;++r)i=(s=c[r]).width,a=s.color,i&&a&&(l.save(),l.lineWidth=i,l.strokeStyle=a,l.setLineDash&&(l.setLineDash(s.borderDash),l.lineDashOffset=s.borderDashOffset),l.beginPath(),n.drawTicks&&(l.moveTo(s.tx1,s.ty1),l.lineTo(s.tx2,s.ty2)),n.drawOnChartArea&&(l.moveTo(s.x1,s.y1),l.lineTo(s.x2,s.y2)),l.stroke(),l.restore());if(h){var f,g,p,m,v=h,b=dn(n.lineWidth,c.ticksLength-1,1),x=c.borderValue;e.isHorizontal()?(f=d(u,e.left,v)-v/2,g=d(u,e.right,b)+b/2,p=m=x):(p=d(u,e.top,v)-v/2,m=d(u,e.bottom,b)+b/2,f=g=x),l.lineWidth=h,l.strokeStyle=dn(n.color,0),l.beginPath(),l.moveTo(f,p),l.lineTo(g,m),l.stroke()}}},_drawLabels:function(){var t=this;if(t.options.ticks.display){var e,n,i,a,r,o,s,l,u=t.ctx,d=t._labelItems||(t._labelItems=t._computeLabelItems());for(e=0,i=d.length;e<i;++e){if(o=(r=d[e]).font,u.save(),u.translate(r.x,r.y),u.rotate(r.rotation),u.font=o.string,u.fillStyle=o.color,u.textBaseline="middle",u.textAlign=r.textAlign,s=r.label,l=r.textOffset,sn(s))for(n=0,a=s.length;n<a;++n)u.fillText(""+s[n],0,l),l+=o.lineHeight;else u.fillText(s,0,l);u.restore()}}},_drawTitle:function(){var t=this,e=t.ctx,n=t.options,i=n.scaleLabel;if(i.display){var a,r,o=un(i.fontColor,N.global.defaultFontColor),s=H.options._parseFont(i),l=H.options.toPadding(i.padding),u=s.lineHeight/2,d=n.position,h=0;if(t.isHorizontal())a=t.left+t.width/2,r="bottom"===d?t.bottom-u-l.bottom:t.top+u+l.top;else{var c="left"===d;a=c?t.left+u+l.top:t.right-u-l.top,r=t.top+t.height/2,h=c?-.5*Math.PI:.5*Math.PI}e.save(),e.translate(a,r),e.rotate(h),e.textAlign="center",e.textBaseline="middle",e.fillStyle=o,e.font=s.string,e.fillText(i.labelString,0,0),e.restore()}},draw:function(t){this._isVisible()&&(this._drawGrid(t),this._drawTitle(),this._drawLabels())},_layers:function(){var t=this,e=t.options,n=e.ticks&&e.ticks.z||0,i=e.gridLines&&e.gridLines.z||0;return t._isVisible()&&n!==i&&t.draw===t._draw?[{z:i,draw:function(){t._drawGrid.apply(t,arguments),t._drawTitle.apply(t,arguments)}},{z:n,draw:function(){t._drawLabels.apply(t,arguments)}}]:[{z:n,draw:function(){t.draw.apply(t,arguments)}}]},_getMatchingVisibleMetas:function(t){var e=this,n=e.isHorizontal();return e.chart._getSortedVisibleDatasetMetas().filter((function(i){return(!t||i.type===t)&&(n?i.xAxisID===e.id:i.yAxisID===e.id)}))}});xn.prototype._draw=xn.prototype.draw;var yn=xn,_n=H.isNullOrUndef,kn=yn.extend({determineDataLimits:function(){var t,e=this,n=e._getLabels(),i=e.options.ticks,a=i.min,r=i.max,o=0,s=n.length-1;void 0!==a&&(t=n.indexOf(a))>=0&&(o=t),void 0!==r&&(t=n.indexOf(r))>=0&&(s=t),e.minIndex=o,e.maxIndex=s,e.min=n[o],e.max=n[s]},buildTicks:function(){var t=this._getLabels(),e=this.minIndex,n=this.maxIndex;this.ticks=0===e&&n===t.length-1?t:t.slice(e,n+1)},getLabelForIndex:function(t,e){var n=this.chart;return n.getDatasetMeta(e).controller._getValueScaleId()===this.id?this.getRightValue(n.data.datasets[e].data[t]):this._getLabels()[t]},_configure:function(){var t=this,e=t.options.offset,n=t.ticks;yn.prototype._configure.call(t),t.isHorizontal()||(t._reversePixels=!t._reversePixels),n&&(t._startValue=t.minIndex-(e?.5:0),t._valueRange=Math.max(n.length-(e?0:1),1))},getPixelForValue:function(t,e,n){var i,a,r,o=this;return _n(e)||_n(n)||(t=o.chart.data.datasets[n].data[e]),_n(t)||(i=o.isHorizontal()?t.x:t.y),(void 0!==i||void 0!==t&&isNaN(e))&&(a=o._getLabels(),t=H.valueOrDefault(i,t),e=-1!==(r=a.indexOf(t))?r:e,isNaN(e)&&(e=t)),o.getPixelForDecimal((e-o._startValue)/o._valueRange)},getPixelForTick:function(t){var e=this.ticks;return t<0||t>e.length-1?null:this.getPixelForValue(e[t],t+this.minIndex)},getValueForPixel:function(t){var e=Math.round(this._startValue+this.getDecimalForPixel(t)*this._valueRange);return Math.min(Math.max(e,0),this.ticks.length-1)},getBasePixel:function(){return this.bottom}}),wn={position:"bottom"};kn._defaults=wn;var Mn=H.noop,Sn=H.isNullOrUndef;var Cn=yn.extend({getRightValue:function(t){return"string"==typeof t?+t:yn.prototype.getRightValue.call(this,t)},handleTickRangeOptions:function(){var t=this,e=t.options.ticks;if(e.beginAtZero){var n=H.sign(t.min),i=H.sign(t.max);n<0&&i<0?t.max=0:n>0&&i>0&&(t.min=0)}var a=void 0!==e.min||void 0!==e.suggestedMin,r=void 0!==e.max||void 0!==e.suggestedMax;void 0!==e.min?t.min=e.min:void 0!==e.suggestedMin&&(null===t.min?t.min=e.suggestedMin:t.min=Math.min(t.min,e.suggestedMin)),void 0!==e.max?t.max=e.max:void 0!==e.suggestedMax&&(null===t.max?t.max=e.suggestedMax:t.max=Math.max(t.max,e.suggestedMax)),a!==r&&t.min>=t.max&&(a?t.max=t.min+1:t.min=t.max-1),t.min===t.max&&(t.max++,e.beginAtZero||t.min--)},getTickLimit:function(){var t,e=this.options.ticks,n=e.stepSize,i=e.maxTicksLimit;return n?t=Math.ceil(this.max/n)-Math.floor(this.min/n)+1:(t=this._computeTickLimit(),i=i||11),i&&(t=Math.min(i,t)),t},_computeTickLimit:function(){return Number.POSITIVE_INFINITY},handleDirectionalChanges:Mn,buildTicks:function(){var t=this,e=t.options.ticks,n=t.getTickLimit(),i={maxTicks:n=Math.max(2,n),min:e.min,max:e.max,precision:e.precision,stepSize:H.valueOrDefault(e.fixedStepSize,e.stepSize)},a=t.ticks=function(t,e){var n,i,a,r,o=[],s=t.stepSize,l=s||1,u=t.maxTicks-1,d=t.min,h=t.max,c=t.precision,f=e.min,g=e.max,p=H.niceNum((g-f)/u/l)*l;if(p<1e-14&&Sn(d)&&Sn(h))return[f,g];(r=Math.ceil(g/p)-Math.floor(f/p))>u&&(p=H.niceNum(r*p/u/l)*l),s||Sn(c)?n=Math.pow(10,H._decimalPlaces(p)):(n=Math.pow(10,c),p=Math.ceil(p*n)/n),i=Math.floor(f/p)*p,a=Math.ceil(g/p)*p,s&&(!Sn(d)&&H.almostWhole(d/p,p/1e3)&&(i=d),!Sn(h)&&H.almostWhole(h/p,p/1e3)&&(a=h)),r=(a-i)/p,r=H.almostEquals(r,Math.round(r),p/1e3)?Math.round(r):Math.ceil(r),i=Math.round(i*n)/n,a=Math.round(a*n)/n,o.push(Sn(d)?i:d);for(var m=1;m<r;++m)o.push(Math.round((i+m*p)*n)/n);return o.push(Sn(h)?a:h),o}(i,t);t.handleDirectionalChanges(),t.max=H.max(a),t.min=H.min(a),e.reverse?(a.reverse(),t.start=t.max,t.end=t.min):(t.start=t.min,t.end=t.max)},convertTicksToLabels:function(){var t=this;t.ticksAsNumbers=t.ticks.slice(),t.zeroLineIndex=t.ticks.indexOf(0),yn.prototype.convertTicksToLabels.call(t)},_configure:function(){var t,e=this,n=e.getTicks(),i=e.min,a=e.max;yn.prototype._configure.call(e),e.options.offset&&n.length&&(i-=t=(a-i)/Math.max(n.length-1,1)/2,a+=t),e._startValue=i,e._endValue=a,e._valueRange=a-i}}),Pn={position:"left",ticks:{callback:on.formatters.linear}};function An(t,e,n,i){var a,r,o=t.options,s=function(t,e,n){var i=[n.type,void 0===e&&void 0===n.stack?n.index:"",n.stack].join(".");return void 0===t[i]&&(t[i]={pos:[],neg:[]}),t[i]}(e,o.stacked,n),l=s.pos,u=s.neg,d=i.length;for(a=0;a<d;++a)r=t._parseValue(i[a]),isNaN(r.min)||isNaN(r.max)||n.data[a].hidden||(l[a]=l[a]||0,u[a]=u[a]||0,o.relativePoints?l[a]=100:r.min<0||r.max<0?u[a]+=r.min:l[a]+=r.max)}function Dn(t,e,n){var i,a,r=n.length;for(i=0;i<r;++i)a=t._parseValue(n[i]),isNaN(a.min)||isNaN(a.max)||e.data[i].hidden||(t.min=Math.min(t.min,a.min),t.max=Math.max(t.max,a.max))}var Tn=Cn.extend({determineDataLimits:function(){var t,e,n,i,a=this,r=a.options,o=a.chart.data.datasets,s=a._getMatchingVisibleMetas(),l=r.stacked,u={},d=s.length;if(a.min=Number.POSITIVE_INFINITY,a.max=Number.NEGATIVE_INFINITY,void 0===l)for(t=0;!l&&t<d;++t)l=void 0!==(e=s[t]).stack;for(t=0;t<d;++t)n=o[(e=s[t]).index].data,l?An(a,u,e,n):Dn(a,e,n);H.each(u,(function(t){i=t.pos.concat(t.neg),a.min=Math.min(a.min,H.min(i)),a.max=Math.max(a.max,H.max(i))})),a.min=H.isFinite(a.min)&&!isNaN(a.min)?a.min:0,a.max=H.isFinite(a.max)&&!isNaN(a.max)?a.max:1,a.handleTickRangeOptions()},_computeTickLimit:function(){var t;return this.isHorizontal()?Math.ceil(this.width/40):(t=H.options._parseFont(this.options.ticks),Math.ceil(this.height/t.lineHeight))},handleDirectionalChanges:function(){this.isHorizontal()||this.ticks.reverse()},getLabelForIndex:function(t,e){return this._getScaleLabel(this.chart.data.datasets[e].data[t])},getPixelForValue:function(t){return this.getPixelForDecimal((+this.getRightValue(t)-this._startValue)/this._valueRange)},getValueForPixel:function(t){return this._startValue+this.getDecimalForPixel(t)*this._valueRange},getPixelForTick:function(t){var e=this.ticksAsNumbers;return t<0||t>e.length-1?null:this.getPixelForValue(e[t])}}),In=Pn;Tn._defaults=In;var Fn=H.valueOrDefault,On=H.math.log10;var Ln={position:"left",ticks:{callback:on.formatters.logarithmic}};function Rn(t,e){return H.isFinite(t)&&t>=0?t:e}var zn=yn.extend({determineDataLimits:function(){var t,e,n,i,a,r,o=this,s=o.options,l=o.chart,u=l.data.datasets,d=o.isHorizontal();function h(t){return d?t.xAxisID===o.id:t.yAxisID===o.id}o.min=Number.POSITIVE_INFINITY,o.max=Number.NEGATIVE_INFINITY,o.minNotZero=Number.POSITIVE_INFINITY;var c=s.stacked;if(void 0===c)for(t=0;t<u.length;t++)if(e=l.getDatasetMeta(t),l.isDatasetVisible(t)&&h(e)&&void 0!==e.stack){c=!0;break}if(s.stacked||c){var f={};for(t=0;t<u.length;t++){var g=[(e=l.getDatasetMeta(t)).type,void 0===s.stacked&&void 0===e.stack?t:"",e.stack].join(".");if(l.isDatasetVisible(t)&&h(e))for(void 0===f[g]&&(f[g]=[]),a=0,r=(i=u[t].data).length;a<r;a++){var p=f[g];n=o._parseValue(i[a]),isNaN(n.min)||isNaN(n.max)||e.data[a].hidden||n.min<0||n.max<0||(p[a]=p[a]||0,p[a]+=n.max)}}H.each(f,(function(t){if(t.length>0){var e=H.min(t),n=H.max(t);o.min=Math.min(o.min,e),o.max=Math.max(o.max,n)}}))}else for(t=0;t<u.length;t++)if(e=l.getDatasetMeta(t),l.isDatasetVisible(t)&&h(e))for(a=0,r=(i=u[t].data).length;a<r;a++)n=o._parseValue(i[a]),isNaN(n.min)||isNaN(n.max)||e.data[a].hidden||n.min<0||n.max<0||(o.min=Math.min(n.min,o.min),o.max=Math.max(n.max,o.max),0!==n.min&&(o.minNotZero=Math.min(n.min,o.minNotZero)));o.min=H.isFinite(o.min)?o.min:null,o.max=H.isFinite(o.max)?o.max:null,o.minNotZero=H.isFinite(o.minNotZero)?o.minNotZero:null,this.handleTickRangeOptions()},handleTickRangeOptions:function(){var t=this,e=t.options.ticks;t.min=Rn(e.min,t.min),t.max=Rn(e.max,t.max),t.min===t.max&&(0!==t.min&&null!==t.min?(t.min=Math.pow(10,Math.floor(On(t.min))-1),t.max=Math.pow(10,Math.floor(On(t.max))+1)):(t.min=1,t.max=10)),null===t.min&&(t.min=Math.pow(10,Math.floor(On(t.max))-1)),null===t.max&&(t.max=0!==t.min?Math.pow(10,Math.floor(On(t.min))+1):10),null===t.minNotZero&&(t.min>0?t.minNotZero=t.min:t.max<1?t.minNotZero=Math.pow(10,Math.floor(On(t.max))):t.minNotZero=1)},buildTicks:function(){var t=this,e=t.options.ticks,n=!t.isHorizontal(),i={min:Rn(e.min),max:Rn(e.max)},a=t.ticks=function(t,e){var n,i,a=[],r=Fn(t.min,Math.pow(10,Math.floor(On(e.min)))),o=Math.floor(On(e.max)),s=Math.ceil(e.max/Math.pow(10,o));0===r?(n=Math.floor(On(e.minNotZero)),i=Math.floor(e.minNotZero/Math.pow(10,n)),a.push(r),r=i*Math.pow(10,n)):(n=Math.floor(On(r)),i=Math.floor(r/Math.pow(10,n)));var l=n<0?Math.pow(10,Math.abs(n)):1;do{a.push(r),10===++i&&(i=1,l=++n>=0?1:l),r=Math.round(i*Math.pow(10,n)*l)/l}while(n<o||n===o&&i<s);var u=Fn(t.max,r);return a.push(u),a}(i,t);t.max=H.max(a),t.min=H.min(a),e.reverse?(n=!n,t.start=t.max,t.end=t.min):(t.start=t.min,t.end=t.max),n&&a.reverse()},convertTicksToLabels:function(){this.tickValues=this.ticks.slice(),yn.prototype.convertTicksToLabels.call(this)},getLabelForIndex:function(t,e){return this._getScaleLabel(this.chart.data.datasets[e].data[t])},getPixelForTick:function(t){var e=this.tickValues;return t<0||t>e.length-1?null:this.getPixelForValue(e[t])},_getFirstTickValue:function(t){var e=Math.floor(On(t));return Math.floor(t/Math.pow(10,e))*Math.pow(10,e)},_configure:function(){var t=this,e=t.min,n=0;yn.prototype._configure.call(t),0===e&&(e=t._getFirstTickValue(t.minNotZero),n=Fn(t.options.ticks.fontSize,N.global.defaultFontSize)/t._length),t._startValue=On(e),t._valueOffset=n,t._valueRange=(On(t.max)-On(e))/(1-n)},getPixelForValue:function(t){var e=this,n=0;return(t=+e.getRightValue(t))>e.min&&t>0&&(n=(On(t)-e._startValue)/e._valueRange+e._valueOffset),e.getPixelForDecimal(n)},getValueForPixel:function(t){var e=this,n=e.getDecimalForPixel(t);return 0===n&&0===e.min?0:Math.pow(10,e._startValue+(n-e._valueOffset)*e._valueRange)}}),Nn=Ln;zn._defaults=Nn;var Bn=H.valueOrDefault,En=H.valueAtIndexOrDefault,Wn=H.options.resolve,Vn={display:!0,animate:!0,position:"chartArea",angleLines:{display:!0,color:"rgba(0,0,0,0.1)",lineWidth:1,borderDash:[],borderDashOffset:0},gridLines:{circular:!1},ticks:{showLabelBackdrop:!0,backdropColor:"rgba(255,255,255,0.75)",backdropPaddingY:2,backdropPaddingX:2,callback:on.formatters.linear},pointLabels:{display:!0,fontSize:10,callback:function(t){return t}}};function Hn(t){var e=t.ticks;return e.display&&t.display?Bn(e.fontSize,N.global.defaultFontSize)+2*e.backdropPaddingY:0}function jn(t,e,n,i,a){return t===i||t===a?{start:e-n/2,end:e+n/2}:t<i||t>a?{start:e-n,end:e}:{start:e,end:e+n}}function qn(t){return 0===t||180===t?"center":t<180?"left":"right"}function Un(t,e,n,i){var a,r,o=n.y+i/2;if(H.isArray(e))for(a=0,r=e.length;a<r;++a)t.fillText(e[a],n.x,o),o+=i;else t.fillText(e,n.x,o)}function Yn(t,e,n){90===t||270===t?n.y-=e.h/2:(t>270||t<90)&&(n.y-=e.h)}function Gn(t){return H.isNumber(t)?t:0}var Xn=Cn.extend({setDimensions:function(){var t=this;t.width=t.maxWidth,t.height=t.maxHeight,t.paddingTop=Hn(t.options)/2,t.xCenter=Math.floor(t.width/2),t.yCenter=Math.floor((t.height-t.paddingTop)/2),t.drawingArea=Math.min(t.height-t.paddingTop,t.width)/2},determineDataLimits:function(){var t=this,e=t.chart,n=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;H.each(e.data.datasets,(function(a,r){if(e.isDatasetVisible(r)){var o=e.getDatasetMeta(r);H.each(a.data,(function(e,a){var r=+t.getRightValue(e);isNaN(r)||o.data[a].hidden||(n=Math.min(r,n),i=Math.max(r,i))}))}})),t.min=n===Number.POSITIVE_INFINITY?0:n,t.max=i===Number.NEGATIVE_INFINITY?0:i,t.handleTickRangeOptions()},_computeTickLimit:function(){return Math.ceil(this.drawingArea/Hn(this.options))},convertTicksToLabels:function(){var t=this;Cn.prototype.convertTicksToLabels.call(t),t.pointLabels=t.chart.data.labels.map((function(){var e=H.callback(t.options.pointLabels.callback,arguments,t);return e||0===e?e:""}))},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},fit:function(){var t=this.options;t.display&&t.pointLabels.display?function(t){var e,n,i,a=H.options._parseFont(t.options.pointLabels),r={l:0,r:t.width,t:0,b:t.height-t.paddingTop},o={};t.ctx.font=a.string,t._pointLabelSizes=[];var s,l,u,d=t.chart.data.labels.length;for(e=0;e<d;e++){i=t.getPointPosition(e,t.drawingArea+5),s=t.ctx,l=a.lineHeight,u=t.pointLabels[e],n=H.isArray(u)?{w:H.longestText(s,s.font,u),h:u.length*l}:{w:s.measureText(u).width,h:l},t._pointLabelSizes[e]=n;var h=t.getIndexAngle(e),c=H.toDegrees(h)%360,f=jn(c,i.x,n.w,0,180),g=jn(c,i.y,n.h,90,270);f.start<r.l&&(r.l=f.start,o.l=h),f.end>r.r&&(r.r=f.end,o.r=h),g.start<r.t&&(r.t=g.start,o.t=h),g.end>r.b&&(r.b=g.end,o.b=h)}t.setReductions(t.drawingArea,r,o)}(this):this.setCenterPoint(0,0,0,0)},setReductions:function(t,e,n){var i=this,a=e.l/Math.sin(n.l),r=Math.max(e.r-i.width,0)/Math.sin(n.r),o=-e.t/Math.cos(n.t),s=-Math.max(e.b-(i.height-i.paddingTop),0)/Math.cos(n.b);a=Gn(a),r=Gn(r),o=Gn(o),s=Gn(s),i.drawingArea=Math.min(Math.floor(t-(a+r)/2),Math.floor(t-(o+s)/2)),i.setCenterPoint(a,r,o,s)},setCenterPoint:function(t,e,n,i){var a=this,r=a.width-e-a.drawingArea,o=t+a.drawingArea,s=n+a.drawingArea,l=a.height-a.paddingTop-i-a.drawingArea;a.xCenter=Math.floor((o+r)/2+a.left),a.yCenter=Math.floor((s+l)/2+a.top+a.paddingTop)},getIndexAngle:function(t){var e=this.chart,n=(t*(360/e.data.labels.length)+((e.options||{}).startAngle||0))%360;return(n<0?n+360:n)*Math.PI*2/360},getDistanceFromCenterForValue:function(t){var e=this;if(H.isNullOrUndef(t))return NaN;var n=e.drawingArea/(e.max-e.min);return e.options.ticks.reverse?(e.max-t)*n:(t-e.min)*n},getPointPosition:function(t,e){var n=this.getIndexAngle(t)-Math.PI/2;return{x:Math.cos(n)*e+this.xCenter,y:Math.sin(n)*e+this.yCenter}},getPointPositionForValue:function(t,e){return this.getPointPosition(t,this.getDistanceFromCenterForValue(e))},getBasePosition:function(t){var e=this.min,n=this.max;return this.getPointPositionForValue(t||0,this.beginAtZero?0:e<0&&n<0?n:e>0&&n>0?e:0)},_drawGrid:function(){var t,e,n,i=this,a=i.ctx,r=i.options,o=r.gridLines,s=r.angleLines,l=Bn(s.lineWidth,o.lineWidth),u=Bn(s.color,o.color);if(r.pointLabels.display&&function(t){var e=t.ctx,n=t.options,i=n.pointLabels,a=Hn(n),r=t.getDistanceFromCenterForValue(n.ticks.reverse?t.min:t.max),o=H.options._parseFont(i);e.save(),e.font=o.string,e.textBaseline="middle";for(var s=t.chart.data.labels.length-1;s>=0;s--){var l=0===s?a/2:0,u=t.getPointPosition(s,r+l+5),d=En(i.fontColor,s,N.global.defaultFontColor);e.fillStyle=d;var h=t.getIndexAngle(s),c=H.toDegrees(h);e.textAlign=qn(c),Yn(c,t._pointLabelSizes[s],u),Un(e,t.pointLabels[s],u,o.lineHeight)}e.restore()}(i),o.display&&H.each(i.ticks,(function(t,n){0!==n&&(e=i.getDistanceFromCenterForValue(i.ticksAsNumbers[n]),function(t,e,n,i){var a,r=t.ctx,o=e.circular,s=t.chart.data.labels.length,l=En(e.color,i-1),u=En(e.lineWidth,i-1);if((o||s)&&l&&u){if(r.save(),r.strokeStyle=l,r.lineWidth=u,r.setLineDash&&(r.setLineDash(e.borderDash||[]),r.lineDashOffset=e.borderDashOffset||0),r.beginPath(),o)r.arc(t.xCenter,t.yCenter,n,0,2*Math.PI);else{a=t.getPointPosition(0,n),r.moveTo(a.x,a.y);for(var d=1;d<s;d++)a=t.getPointPosition(d,n),r.lineTo(a.x,a.y)}r.closePath(),r.stroke(),r.restore()}}(i,o,e,n))})),s.display&&l&&u){for(a.save(),a.lineWidth=l,a.strokeStyle=u,a.setLineDash&&(a.setLineDash(Wn([s.borderDash,o.borderDash,[]])),a.lineDashOffset=Wn([s.borderDashOffset,o.borderDashOffset,0])),t=i.chart.data.labels.length-1;t>=0;t--)e=i.getDistanceFromCenterForValue(r.ticks.reverse?i.min:i.max),n=i.getPointPosition(t,e),a.beginPath(),a.moveTo(i.xCenter,i.yCenter),a.lineTo(n.x,n.y),a.stroke();a.restore()}},_drawLabels:function(){var t=this,e=t.ctx,n=t.options.ticks;if(n.display){var i,a,r=t.getIndexAngle(0),o=H.options._parseFont(n),s=Bn(n.fontColor,N.global.defaultFontColor);e.save(),e.font=o.string,e.translate(t.xCenter,t.yCenter),e.rotate(r),e.textAlign="center",e.textBaseline="middle",H.each(t.ticks,(function(r,l){(0!==l||n.reverse)&&(i=t.getDistanceFromCenterForValue(t.ticksAsNumbers[l]),n.showLabelBackdrop&&(a=e.measureText(r).width,e.fillStyle=n.backdropColor,e.fillRect(-a/2-n.backdropPaddingX,-i-o.size/2-n.backdropPaddingY,a+2*n.backdropPaddingX,o.size+2*n.backdropPaddingY)),e.fillStyle=s,e.fillText(r,0,-i))})),e.restore()}},_drawTitle:H.noop}),Kn=Vn;Xn._defaults=Kn;var Zn=H._deprecated,$n=H.options.resolve,Jn=H.valueOrDefault,Qn=Number.MIN_SAFE_INTEGER||-9007199254740991,ti=Number.MAX_SAFE_INTEGER||9007199254740991,ei={millisecond:{common:!0,size:1,steps:1e3},second:{common:!0,size:1e3,steps:60},minute:{common:!0,size:6e4,steps:60},hour:{common:!0,size:36e5,steps:24},day:{common:!0,size:864e5,steps:30},week:{common:!1,size:6048e5,steps:4},month:{common:!0,size:2628e6,steps:12},quarter:{common:!1,size:7884e6,steps:4},year:{common:!0,size:3154e7}},ni=Object.keys(ei);function ii(t,e){return t-e}function ai(t){return H.valueOrDefault(t.time.min,t.ticks.min)}function ri(t){return H.valueOrDefault(t.time.max,t.ticks.max)}function oi(t,e,n,i){var a=function(t,e,n){for(var i,a,r,o=0,s=t.length-1;o>=0&&o<=s;){if(a=t[(i=o+s>>1)-1]||null,r=t[i],!a)return{lo:null,hi:r};if(r[e]<n)o=i+1;else{if(!(a[e]>n))return{lo:a,hi:r};s=i-1}}return{lo:r,hi:null}}(t,e,n),r=a.lo?a.hi?a.lo:t[t.length-2]:t[0],o=a.lo?a.hi?a.hi:t[t.length-1]:t[1],s=o[e]-r[e],l=s?(n-r[e])/s:0,u=(o[i]-r[i])*l;return r[i]+u}function si(t,e){var n=t._adapter,i=t.options.time,a=i.parser,r=a||i.format,o=e;return"function"==typeof a&&(o=a(o)),H.isFinite(o)||(o="string"==typeof r?n.parse(o,r):n.parse(o)),null!==o?+o:(a||"function"!=typeof r||(o=r(e),H.isFinite(o)||(o=n.parse(o))),o)}function li(t,e){if(H.isNullOrUndef(e))return null;var n=t.options.time,i=si(t,t.getRightValue(e));return null===i?i:(n.round&&(i=+t._adapter.startOf(i,n.round)),i)}function ui(t,e,n,i){var a,r,o,s=ni.length;for(a=ni.indexOf(t);a<s-1;++a)if(o=(r=ei[ni[a]]).steps?r.steps:ti,r.common&&Math.ceil((n-e)/(o*r.size))<=i)return ni[a];return ni[s-1]}function di(t,e,n){var i,a,r=[],o={},s=e.length;for(i=0;i<s;++i)o[a=e[i]]=i,r.push({value:a,major:!1});return 0!==s&&n?function(t,e,n,i){var a,r,o=t._adapter,s=+o.startOf(e[0].value,i),l=e[e.length-1].value;for(a=s;a<=l;a=+o.add(a,1,i))(r=n[a])>=0&&(e[r].major=!0);return e}(t,r,o,n):r}var hi=yn.extend({initialize:function(){this.mergeTicksOptions(),yn.prototype.initialize.call(this)},update:function(){var t=this,e=t.options,n=e.time||(e.time={}),i=t._adapter=new rn._date(e.adapters.date);return Zn("time scale",n.format,"time.format","time.parser"),Zn("time scale",n.min,"time.min","ticks.min"),Zn("time scale",n.max,"time.max","ticks.max"),H.mergeIf(n.displayFormats,i.formats()),yn.prototype.update.apply(t,arguments)},getRightValue:function(t){return t&&void 0!==t.t&&(t=t.t),yn.prototype.getRightValue.call(this,t)},determineDataLimits:function(){var t,e,n,i,a,r,o,s=this,l=s.chart,u=s._adapter,d=s.options,h=d.time.unit||"day",c=ti,f=Qn,g=[],p=[],m=[],v=s._getLabels();for(t=0,n=v.length;t<n;++t)m.push(li(s,v[t]));for(t=0,n=(l.data.datasets||[]).length;t<n;++t)if(l.isDatasetVisible(t))if(a=l.data.datasets[t].data,H.isObject(a[0]))for(p[t]=[],e=0,i=a.length;e<i;++e)r=li(s,a[e]),g.push(r),p[t][e]=r;else p[t]=m.slice(0),o||(g=g.concat(m),o=!0);else p[t]=[];m.length&&(c=Math.min(c,m[0]),f=Math.max(f,m[m.length-1])),g.length&&(g=n>1?function(t){var e,n,i,a={},r=[];for(e=0,n=t.length;e<n;++e)a[i=t[e]]||(a[i]=!0,r.push(i));return r}(g).sort(ii):g.sort(ii),c=Math.min(c,g[0]),f=Math.max(f,g[g.length-1])),c=li(s,ai(d))||c,f=li(s,ri(d))||f,c=c===ti?+u.startOf(Date.now(),h):c,f=f===Qn?+u.endOf(Date.now(),h)+1:f,s.min=Math.min(c,f),s.max=Math.max(c+1,f),s._table=[],s._timestamps={data:g,datasets:p,labels:m}},buildTicks:function(){var t,e,n,i=this,a=i.min,r=i.max,o=i.options,s=o.ticks,l=o.time,u=i._timestamps,d=[],h=i.getLabelCapacity(a),c=s.source,f=o.distribution;for(u="data"===c||"auto"===c&&"series"===f?u.data:"labels"===c?u.labels:function(t,e,n,i){var a,r=t._adapter,o=t.options,s=o.time,l=s.unit||ui(s.minUnit,e,n,i),u=$n([s.stepSize,s.unitStepSize,1]),d="week"===l&&s.isoWeekday,h=e,c=[];if(d&&(h=+r.startOf(h,"isoWeek",d)),h=+r.startOf(h,d?"day":l),r.diff(n,e,l)>1e5*u)throw e+" and "+n+" are too far apart with stepSize of "+u+" "+l;for(a=h;a<n;a=+r.add(a,u,l))c.push(a);return a!==n&&"ticks"!==o.bounds||c.push(a),c}(i,a,r,h),"ticks"===o.bounds&&u.length&&(a=u[0],r=u[u.length-1]),a=li(i,ai(o))||a,r=li(i,ri(o))||r,t=0,e=u.length;t<e;++t)(n=u[t])>=a&&n<=r&&d.push(n);return i.min=a,i.max=r,i._unit=l.unit||(s.autoSkip?ui(l.minUnit,i.min,i.max,h):function(t,e,n,i,a){var r,o;for(r=ni.length-1;r>=ni.indexOf(n);r--)if(o=ni[r],ei[o].common&&t._adapter.diff(a,i,o)>=e-1)return o;return ni[n?ni.indexOf(n):0]}(i,d.length,l.minUnit,i.min,i.max)),i._majorUnit=s.major.enabled&&"year"!==i._unit?function(t){for(var e=ni.indexOf(t)+1,n=ni.length;e<n;++e)if(ei[ni[e]].common)return ni[e]}(i._unit):void 0,i._table=function(t,e,n,i){if("linear"===i||!t.length)return[{time:e,pos:0},{time:n,pos:1}];var a,r,o,s,l,u=[],d=[e];for(a=0,r=t.length;a<r;++a)(s=t[a])>e&&s<n&&d.push(s);for(d.push(n),a=0,r=d.length;a<r;++a)l=d[a+1],o=d[a-1],s=d[a],void 0!==o&&void 0!==l&&Math.round((l+o)/2)===s||u.push({time:s,pos:a/(r-1)});return u}(i._timestamps.data,a,r,f),i._offsets=function(t,e,n,i,a){var r,o,s=0,l=0;return a.offset&&e.length&&(r=oi(t,"time",e[0],"pos"),s=1===e.length?1-r:(oi(t,"time",e[1],"pos")-r)/2,o=oi(t,"time",e[e.length-1],"pos"),l=1===e.length?o:(o-oi(t,"time",e[e.length-2],"pos"))/2),{start:s,end:l,factor:1/(s+1+l)}}(i._table,d,0,0,o),s.reverse&&d.reverse(),di(i,d,i._majorUnit)},getLabelForIndex:function(t,e){var n=this,i=n._adapter,a=n.chart.data,r=n.options.time,o=a.labels&&t<a.labels.length?a.labels[t]:"",s=a.datasets[e].data[t];return H.isObject(s)&&(o=n.getRightValue(s)),r.tooltipFormat?i.format(si(n,o),r.tooltipFormat):"string"==typeof o?o:i.format(si(n,o),r.displayFormats.datetime)},tickFormatFunction:function(t,e,n,i){var a=this._adapter,r=this.options,o=r.time.displayFormats,s=o[this._unit],l=this._majorUnit,u=o[l],d=n[e],h=r.ticks,c=l&&u&&d&&d.major,f=a.format(t,i||(c?u:s)),g=c?h.major:h.minor,p=$n([g.callback,g.userCallback,h.callback,h.userCallback]);return p?p(f,e,n):f},convertTicksToLabels:function(t){var e,n,i=[];for(e=0,n=t.length;e<n;++e)i.push(this.tickFormatFunction(t[e].value,e,t));return i},getPixelForOffset:function(t){var e=this._offsets,n=oi(this._table,"time",t,"pos");return this.getPixelForDecimal((e.start+n)*e.factor)},getPixelForValue:function(t,e,n){var i=null;if(void 0!==e&&void 0!==n&&(i=this._timestamps.datasets[n][e]),null===i&&(i=li(this,t)),null!==i)return this.getPixelForOffset(i)},getPixelForTick:function(t){var e=this.getTicks();return t>=0&&t<e.length?this.getPixelForOffset(e[t].value):null},getValueForPixel:function(t){var e=this._offsets,n=this.getDecimalForPixel(t)/e.factor-e.end,i=oi(this._table,"pos",n,"time");return this._adapter._create(i)},_getLabelSize:function(t){var e=this.options.ticks,n=this.ctx.measureText(t).width,i=H.toRadians(this.isHorizontal()?e.maxRotation:e.minRotation),a=Math.cos(i),r=Math.sin(i),o=Jn(e.fontSize,N.global.defaultFontSize);return{w:n*a+o*r,h:n*r+o*a}},getLabelWidth:function(t){return this._getLabelSize(t).w},getLabelCapacity:function(t){var e=this,n=e.options.time,i=n.displayFormats,a=i[n.unit]||i.millisecond,r=e.tickFormatFunction(t,0,di(e,[t],e._majorUnit),a),o=e._getLabelSize(r),s=Math.floor(e.isHorizontal()?e.width/o.w:e.height/o.h);return e.options.offset&&s--,s>0?s:1}}),ci={position:"bottom",distribution:"linear",bounds:"data",adapters:{},time:{parser:!1,unit:!1,round:!1,displayFormat:!1,isoWeekday:!1,minUnit:"millisecond",displayFormats:{}},ticks:{autoSkip:!1,source:"auto",major:{enabled:!1}}};hi._defaults=ci;var fi={category:kn,linear:Tn,logarithmic:zn,radialLinear:Xn,time:hi},gi={datetime:"MMM D, YYYY, h:mm:ss a",millisecond:"h:mm:ss.SSS a",second:"h:mm:ss a",minute:"h:mm a",hour:"hA",day:"MMM D",week:"ll",month:"MMM YYYY",quarter:"[Q]Q - YYYY",year:"YYYY"};rn._date.override("function"==typeof t?{_id:"moment",formats:function(){return gi},parse:function(e,n){return"string"==typeof e&&"string"==typeof n?e=t(e,n):e instanceof t||(e=t(e)),e.isValid()?e.valueOf():null},format:function(e,n){return t(e).format(n)},add:function(e,n,i){return t(e).add(n,i).valueOf()},diff:function(e,n,i){return t(e).diff(t(n),i)},startOf:function(e,n,i){return e=t(e),"isoWeek"===n?e.isoWeekday(i).valueOf():e.startOf(n).valueOf()},endOf:function(e,n){return t(e).endOf(n).valueOf()},_create:function(e){return t(e)}}:{}),N._set("global",{plugins:{filler:{propagate:!0}}});var pi={dataset:function(t){var e=t.fill,n=t.chart,i=n.getDatasetMeta(e),a=i&&n.isDatasetVisible(e)&&i.dataset._children||[],r=a.length||0;return r?function(t,e){return e<r&&a[e]._view||null}:null},boundary:function(t){var e=t.boundary,n=e?e.x:null,i=e?e.y:null;return H.isArray(e)?function(t,n){return e[n]}:function(t){return{x:null===n?t.x:n,y:null===i?t.y:i}}}};function mi(t,e,n){var i,a=t._model||{},r=a.fill;if(void 0===r&&(r=!!a.backgroundColor),!1===r||null===r)return!1;if(!0===r)return"origin";if(i=parseFloat(r,10),isFinite(i)&&Math.floor(i)===i)return"-"!==r[0]&&"+"!==r[0]||(i=e+i),!(i===e||i<0||i>=n)&&i;switch(r){case"bottom":return"start";case"top":return"end";case"zero":return"origin";case"origin":case"start":case"end":return r;default:return!1}}function vi(t){return(t.el._scale||{}).getPointPositionForValue?function(t){var e,n,i,a,r,o=t.el._scale,s=o.options,l=o.chart.data.labels.length,u=t.fill,d=[];if(!l)return null;for(e=s.ticks.reverse?o.max:o.min,n=s.ticks.reverse?o.min:o.max,i=o.getPointPositionForValue(0,e),a=0;a<l;++a)r="start"===u||"end"===u?o.getPointPositionForValue(a,"start"===u?e:n):o.getBasePosition(a),s.gridLines.circular&&(r.cx=i.x,r.cy=i.y,r.angle=o.getIndexAngle(a)-Math.PI/2),d.push(r);return d}(t):function(t){var e,n=t.el._model||{},i=t.el._scale||{},a=t.fill,r=null;if(isFinite(a))return null;if("start"===a?r=void 0===n.scaleBottom?i.bottom:n.scaleBottom:"end"===a?r=void 0===n.scaleTop?i.top:n.scaleTop:void 0!==n.scaleZero?r=n.scaleZero:i.getBasePixel&&(r=i.getBasePixel()),null!=r){if(void 0!==r.x&&void 0!==r.y)return r;if(H.isFinite(r))return{x:(e=i.isHorizontal())?r:null,y:e?null:r}}return null}(t)}function bi(t,e,n){var i,a=t[e].fill,r=[e];if(!n)return a;for(;!1!==a&&-1===r.indexOf(a);){if(!isFinite(a))return a;if(!(i=t[a]))return!1;if(i.visible)return a;r.push(a),a=i.fill}return!1}function xi(t){var e=t.fill,n="dataset";return!1===e?null:(isFinite(e)||(n="boundary"),pi[n](t))}function yi(t){return t&&!t.skip}function _i(t,e,n,i,a){var r,o,s,l;if(i&&a){for(t.moveTo(e[0].x,e[0].y),r=1;r<i;++r)H.canvas.lineTo(t,e[r-1],e[r]);if(void 0===n[0].angle)for(t.lineTo(n[a-1].x,n[a-1].y),r=a-1;r>0;--r)H.canvas.lineTo(t,n[r],n[r-1],!0);else for(o=n[0].cx,s=n[0].cy,l=Math.sqrt(Math.pow(n[0].x-o,2)+Math.pow(n[0].y-s,2)),r=a-1;r>0;--r)t.arc(o,s,l,n[r].angle,n[r-1].angle,!0)}}function ki(t,e,n,i,a,r){var o,s,l,u,d,h,c,f,g=e.length,p=i.spanGaps,m=[],v=[],b=0,x=0;for(t.beginPath(),o=0,s=g;o<s;++o)d=n(u=e[l=o%g]._view,l,i),h=yi(u),c=yi(d),r&&void 0===f&&h&&(s=g+(f=o+1)),h&&c?(b=m.push(u),x=v.push(d)):b&&x&&(p?(h&&m.push(u),c&&v.push(d)):(_i(t,m,v,b,x),b=x=0,m=[],v=[]));_i(t,m,v,b,x),t.closePath(),t.fillStyle=a,t.fill()}var wi={id:"filler",afterDatasetsUpdate:function(t,e){var n,i,a,r,o=(t.data.datasets||[]).length,s=e.propagate,l=[];for(i=0;i<o;++i)r=null,(a=(n=t.getDatasetMeta(i)).dataset)&&a._model&&a instanceof kt.Line&&(r={visible:t.isDatasetVisible(i),fill:mi(a,i,o),chart:t,el:a}),n.$filler=r,l.push(r);for(i=0;i<o;++i)(r=l[i])&&(r.fill=bi(l,i,s),r.boundary=vi(r),r.mapper=xi(r))},beforeDatasetsDraw:function(t){var e,n,i,a,r,o,s,l=t._getSortedVisibleDatasetMetas(),u=t.ctx;for(n=l.length-1;n>=0;--n)(e=l[n].$filler)&&e.visible&&(a=(i=e.el)._view,r=i._children||[],o=e.mapper,s=a.backgroundColor||N.global.defaultColor,o&&s&&r.length&&(H.canvas.clipArea(u,t.chartArea),ki(u,r,o,a,s,i._loop),H.canvas.unclipArea(u)))}},Mi=H.rtl.getRtlAdapter,Si=H.noop,Ci=H.valueOrDefault;function Pi(t,e){return t.usePointStyle&&t.boxWidth>e?e:t.boxWidth}N._set("global",{legend:{display:!0,position:"top",align:"center",fullWidth:!0,reverse:!1,weight:1e3,onClick:function(t,e){var n=e.datasetIndex,i=this.chart,a=i.getDatasetMeta(n);a.hidden=null===a.hidden?!i.data.datasets[n].hidden:null,i.update()},onHover:null,onLeave:null,labels:{boxWidth:40,padding:10,generateLabels:function(t){var e=t.data.datasets,n=t.options.legend||{},i=n.labels&&n.labels.usePointStyle;return t._getSortedDatasetMetas().map((function(n){var a=n.controller.getStyle(i?0:void 0);return{text:e[n.index].label,fillStyle:a.backgroundColor,hidden:!t.isDatasetVisible(n.index),lineCap:a.borderCapStyle,lineDash:a.borderDash,lineDashOffset:a.borderDashOffset,lineJoin:a.borderJoinStyle,lineWidth:a.borderWidth,strokeStyle:a.borderColor,pointStyle:a.pointStyle,rotation:a.rotation,datasetIndex:n.index}}),this)}}},legendCallback:function(t){var e,n,i,a=document.createElement("ul"),r=t.data.datasets;for(a.setAttribute("class",t.id+"-legend"),e=0,n=r.length;e<n;e++)(i=a.appendChild(document.createElement("li"))).appendChild(document.createElement("span")).style.backgroundColor=r[e].backgroundColor,r[e].label&&i.appendChild(document.createTextNode(r[e].label));return a.outerHTML}});var Ai=K.extend({initialize:function(t){H.extend(this,t),this.legendHitBoxes=[],this._hoveredItem=null,this.doughnutMode=!1},beforeUpdate:Si,update:function(t,e,n){var i=this;return i.beforeUpdate(),i.maxWidth=t,i.maxHeight=e,i.margins=n,i.beforeSetDimensions(),i.setDimensions(),i.afterSetDimensions(),i.beforeBuildLabels(),i.buildLabels(),i.afterBuildLabels(),i.beforeFit(),i.fit(),i.afterFit(),i.afterUpdate(),i.minSize},afterUpdate:Si,beforeSetDimensions:Si,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:Si,beforeBuildLabels:Si,buildLabels:function(){var t=this,e=t.options.labels||{},n=H.callback(e.generateLabels,[t.chart],t)||[];e.filter&&(n=n.filter((function(n){return e.filter(n,t.chart.data)}))),t.options.reverse&&n.reverse(),t.legendItems=n},afterBuildLabels:Si,beforeFit:Si,fit:function(){var t=this,e=t.options,n=e.labels,i=e.display,a=t.ctx,r=H.options._parseFont(n),o=r.size,s=t.legendHitBoxes=[],l=t.minSize,u=t.isHorizontal();if(u?(l.width=t.maxWidth,l.height=i?10:0):(l.width=i?10:0,l.height=t.maxHeight),i){if(a.font=r.string,u){var d=t.lineWidths=[0],h=0;a.textAlign="left",a.textBaseline="middle",H.each(t.legendItems,(function(t,e){var i=Pi(n,o)+o/2+a.measureText(t.text).width;(0===e||d[d.length-1]+i+2*n.padding>l.width)&&(h+=o+n.padding,d[d.length-(e>0?0:1)]=0),s[e]={left:0,top:0,width:i,height:o},d[d.length-1]+=i+n.padding})),l.height+=h}else{var c=n.padding,f=t.columnWidths=[],g=t.columnHeights=[],p=n.padding,m=0,v=0;H.each(t.legendItems,(function(t,e){var i=Pi(n,o)+o/2+a.measureText(t.text).width;e>0&&v+o+2*c>l.height&&(p+=m+n.padding,f.push(m),g.push(v),m=0,v=0),m=Math.max(m,i),v+=o+c,s[e]={left:0,top:0,width:i,height:o}})),p+=m,f.push(m),g.push(v),l.width+=p}t.width=l.width,t.height=l.height}else t.width=l.width=t.height=l.height=0},afterFit:Si,isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},draw:function(){var t=this,e=t.options,n=e.labels,i=N.global,a=i.defaultColor,r=i.elements.line,o=t.height,s=t.columnHeights,l=t.width,u=t.lineWidths;if(e.display){var d,h=Mi(e.rtl,t.left,t.minSize.width),c=t.ctx,f=Ci(n.fontColor,i.defaultFontColor),g=H.options._parseFont(n),p=g.size;c.textAlign=h.textAlign("left"),c.textBaseline="middle",c.lineWidth=.5,c.strokeStyle=f,c.fillStyle=f,c.font=g.string;var m=Pi(n,p),v=t.legendHitBoxes,b=function(t,i){switch(e.align){case"start":return n.padding;case"end":return t-i;default:return(t-i+n.padding)/2}},x=t.isHorizontal();d=x?{x:t.left+b(l,u[0]),y:t.top+n.padding,line:0}:{x:t.left+n.padding,y:t.top+b(o,s[0]),line:0},H.rtl.overrideTextDirection(t.ctx,e.textDirection);var y=p+n.padding;H.each(t.legendItems,(function(e,i){var f=c.measureText(e.text).width,g=m+p/2+f,_=d.x,k=d.y;h.setWidth(t.minSize.width),x?i>0&&_+g+n.padding>t.left+t.minSize.width&&(k=d.y+=y,d.line++,_=d.x=t.left+b(l,u[d.line])):i>0&&k+y>t.top+t.minSize.height&&(_=d.x=_+t.columnWidths[d.line]+n.padding,d.line++,k=d.y=t.top+b(o,s[d.line]));var w=h.x(_);!function(t,e,i){if(!(isNaN(m)||m<=0)){c.save();var o=Ci(i.lineWidth,r.borderWidth);if(c.fillStyle=Ci(i.fillStyle,a),c.lineCap=Ci(i.lineCap,r.borderCapStyle),c.lineDashOffset=Ci(i.lineDashOffset,r.borderDashOffset),c.lineJoin=Ci(i.lineJoin,r.borderJoinStyle),c.lineWidth=o,c.strokeStyle=Ci(i.strokeStyle,a),c.setLineDash&&c.setLineDash(Ci(i.lineDash,r.borderDash)),n&&n.usePointStyle){var s=m*Math.SQRT2/2,l=h.xPlus(t,m/2),u=e+p/2;H.canvas.drawPoint(c,i.pointStyle,s,l,u,i.rotation)}else c.fillRect(h.leftForLtr(t,m),e,m,p),0!==o&&c.strokeRect(h.leftForLtr(t,m),e,m,p);c.restore()}}(w,k,e),v[i].left=h.leftForLtr(w,v[i].width),v[i].top=k,function(t,e,n,i){var a=p/2,r=h.xPlus(t,m+a),o=e+a;c.fillText(n.text,r,o),n.hidden&&(c.beginPath(),c.lineWidth=2,c.moveTo(r,o),c.lineTo(h.xPlus(r,i),o),c.stroke())}(w,k,e,f),x?d.x+=g+n.padding:d.y+=y})),H.rtl.restoreTextDirection(t.ctx,e.textDirection)}},_getLegendItemAt:function(t,e){var n,i,a,r=this;if(t>=r.left&&t<=r.right&&e>=r.top&&e<=r.bottom)for(a=r.legendHitBoxes,n=0;n<a.length;++n)if(t>=(i=a[n]).left&&t<=i.left+i.width&&e>=i.top&&e<=i.top+i.height)return r.legendItems[n];return null},handleEvent:function(t){var e,n=this,i=n.options,a="mouseup"===t.type?"click":t.type;if("mousemove"===a){if(!i.onHover&&!i.onLeave)return}else{if("click"!==a)return;if(!i.onClick)return}e=n._getLegendItemAt(t.x,t.y),"click"===a?e&&i.onClick&&i.onClick.call(n,t.native,e):(i.onLeave&&e!==n._hoveredItem&&(n._hoveredItem&&i.onLeave.call(n,t.native,n._hoveredItem),n._hoveredItem=e),i.onHover&&e&&i.onHover.call(n,t.native,e))}});function Di(t,e){var n=new Ai({ctx:t.ctx,options:e,chart:t});pe.configure(t,n,e),pe.addBox(t,n),t.legend=n}var Ti={id:"legend",_element:Ai,beforeInit:function(t){var e=t.options.legend;e&&Di(t,e)},beforeUpdate:function(t){var e=t.options.legend,n=t.legend;e?(H.mergeIf(e,N.global.legend),n?(pe.configure(t,n,e),n.options=e):Di(t,e)):n&&(pe.removeBox(t,n),delete t.legend)},afterEvent:function(t,e){var n=t.legend;n&&n.handleEvent(e)}},Ii=H.noop;N._set("global",{title:{display:!1,fontStyle:"bold",fullWidth:!0,padding:10,position:"top",text:"",weight:2e3}});var Fi=K.extend({initialize:function(t){H.extend(this,t),this.legendHitBoxes=[]},beforeUpdate:Ii,update:function(t,e,n){var i=this;return i.beforeUpdate(),i.maxWidth=t,i.maxHeight=e,i.margins=n,i.beforeSetDimensions(),i.setDimensions(),i.afterSetDimensions(),i.beforeBuildLabels(),i.buildLabels(),i.afterBuildLabels(),i.beforeFit(),i.fit(),i.afterFit(),i.afterUpdate(),i.minSize},afterUpdate:Ii,beforeSetDimensions:Ii,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:Ii,beforeBuildLabels:Ii,buildLabels:Ii,afterBuildLabels:Ii,beforeFit:Ii,fit:function(){var t,e=this,n=e.options,i=e.minSize={},a=e.isHorizontal();n.display?(t=(H.isArray(n.text)?n.text.length:1)*H.options._parseFont(n).lineHeight+2*n.padding,e.width=i.width=a?e.maxWidth:t,e.height=i.height=a?t:e.maxHeight):e.width=i.width=e.height=i.height=0},afterFit:Ii,isHorizontal:function(){var t=this.options.position;return"top"===t||"bottom"===t},draw:function(){var t=this,e=t.ctx,n=t.options;if(n.display){var i,a,r,o=H.options._parseFont(n),s=o.lineHeight,l=s/2+n.padding,u=0,d=t.top,h=t.left,c=t.bottom,f=t.right;e.fillStyle=H.valueOrDefault(n.fontColor,N.global.defaultFontColor),e.font=o.string,t.isHorizontal()?(a=h+(f-h)/2,r=d+l,i=f-h):(a="left"===n.position?h+l:f-l,r=d+(c-d)/2,i=c-d,u=Math.PI*("left"===n.position?-.5:.5)),e.save(),e.translate(a,r),e.rotate(u),e.textAlign="center",e.textBaseline="middle";var g=n.text;if(H.isArray(g))for(var p=0,m=0;m<g.length;++m)e.fillText(g[m],0,p,i),p+=s;else e.fillText(g,0,0,i);e.restore()}}});function Oi(t,e){var n=new Fi({ctx:t.ctx,options:e,chart:t});pe.configure(t,n,e),pe.addBox(t,n),t.titleBlock=n}var Li={},Ri=wi,zi=Ti,Ni={id:"title",_element:Fi,beforeInit:function(t){var e=t.options.title;e&&Oi(t,e)},beforeUpdate:function(t){var e=t.options.title,n=t.titleBlock;e?(H.mergeIf(e,N.global.title),n?(pe.configure(t,n,e),n.options=e):Oi(t,e)):n&&(pe.removeBox(t,n),delete t.titleBlock)}};for(var Bi in Li.filler=Ri,Li.legend=zi,Li.title=Ni,en.helpers=H,function(){function t(t,e,n){var i;return"string"==typeof t?(i=parseInt(t,10),-1!==t.indexOf("%")&&(i=i/100*e.parentNode[n])):i=t,i}function e(t){return null!=t&&"none"!==t}function n(n,i,a){var r=document.defaultView,o=H._getParentNode(n),s=r.getComputedStyle(n)[i],l=r.getComputedStyle(o)[i],u=e(s),d=e(l),h=Number.POSITIVE_INFINITY;return u||d?Math.min(u?t(s,n,a):h,d?t(l,o,a):h):"none"}H.where=function(t,e){if(H.isArray(t)&&Array.prototype.filter)return t.filter(e);var n=[];return H.each(t,(function(t){e(t)&&n.push(t)})),n},H.findIndex=Array.prototype.findIndex?function(t,e,n){return t.findIndex(e,n)}:function(t,e,n){n=void 0===n?t:n;for(var i=0,a=t.length;i<a;++i)if(e.call(n,t[i],i,t))return i;return-1},H.findNextWhere=function(t,e,n){H.isNullOrUndef(n)&&(n=-1);for(var i=n+1;i<t.length;i++){var a=t[i];if(e(a))return a}},H.findPreviousWhere=function(t,e,n){H.isNullOrUndef(n)&&(n=t.length);for(var i=n-1;i>=0;i--){var a=t[i];if(e(a))return a}},H.isNumber=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},H.almostEquals=function(t,e,n){return Math.abs(t-e)<n},H.almostWhole=function(t,e){var n=Math.round(t);return n-e<=t&&n+e>=t},H.max=function(t){return t.reduce((function(t,e){return isNaN(e)?t:Math.max(t,e)}),Number.NEGATIVE_INFINITY)},H.min=function(t){return t.reduce((function(t,e){return isNaN(e)?t:Math.min(t,e)}),Number.POSITIVE_INFINITY)},H.sign=Math.sign?function(t){return Math.sign(t)}:function(t){return 0===(t=+t)||isNaN(t)?t:t>0?1:-1},H.toRadians=function(t){return t*(Math.PI/180)},H.toDegrees=function(t){return t*(180/Math.PI)},H._decimalPlaces=function(t){if(H.isFinite(t)){for(var e=1,n=0;Math.round(t*e)/e!==t;)e*=10,n++;return n}},H.getAngleFromPoint=function(t,e){var n=e.x-t.x,i=e.y-t.y,a=Math.sqrt(n*n+i*i),r=Math.atan2(i,n);return r<-.5*Math.PI&&(r+=2*Math.PI),{angle:r,distance:a}},H.distanceBetweenPoints=function(t,e){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))},H.aliasPixel=function(t){return t%2==0?0:.5},H._alignPixel=function(t,e,n){var i=t.currentDevicePixelRatio,a=n/2;return Math.round((e-a)*i)/i+a},H.splineCurve=function(t,e,n,i){var a=t.skip?e:t,r=e,o=n.skip?e:n,s=Math.sqrt(Math.pow(r.x-a.x,2)+Math.pow(r.y-a.y,2)),l=Math.sqrt(Math.pow(o.x-r.x,2)+Math.pow(o.y-r.y,2)),u=s/(s+l),d=l/(s+l),h=i*(u=isNaN(u)?0:u),c=i*(d=isNaN(d)?0:d);return{previous:{x:r.x-h*(o.x-a.x),y:r.y-h*(o.y-a.y)},next:{x:r.x+c*(o.x-a.x),y:r.y+c*(o.y-a.y)}}},H.EPSILON=Number.EPSILON||1e-14,H.splineCurveMonotone=function(t){var e,n,i,a,r,o,s,l,u,d=(t||[]).map((function(t){return{model:t._model,deltaK:0,mK:0}})),h=d.length;for(e=0;e<h;++e)if(!(i=d[e]).model.skip){if(n=e>0?d[e-1]:null,(a=e<h-1?d[e+1]:null)&&!a.model.skip){var c=a.model.x-i.model.x;i.deltaK=0!==c?(a.model.y-i.model.y)/c:0}!n||n.model.skip?i.mK=i.deltaK:!a||a.model.skip?i.mK=n.deltaK:this.sign(n.deltaK)!==this.sign(i.deltaK)?i.mK=0:i.mK=(n.deltaK+i.deltaK)/2}for(e=0;e<h-1;++e)i=d[e],a=d[e+1],i.model.skip||a.model.skip||(H.almostEquals(i.deltaK,0,this.EPSILON)?i.mK=a.mK=0:(r=i.mK/i.deltaK,o=a.mK/i.deltaK,(l=Math.pow(r,2)+Math.pow(o,2))<=9||(s=3/Math.sqrt(l),i.mK=r*s*i.deltaK,a.mK=o*s*i.deltaK)));for(e=0;e<h;++e)(i=d[e]).model.skip||(n=e>0?d[e-1]:null,a=e<h-1?d[e+1]:null,n&&!n.model.skip&&(u=(i.model.x-n.model.x)/3,i.model.controlPointPreviousX=i.model.x-u,i.model.controlPointPreviousY=i.model.y-u*i.mK),a&&!a.model.skip&&(u=(a.model.x-i.model.x)/3,i.model.controlPointNextX=i.model.x+u,i.model.controlPointNextY=i.model.y+u*i.mK))},H.nextItem=function(t,e,n){return n?e>=t.length-1?t[0]:t[e+1]:e>=t.length-1?t[t.length-1]:t[e+1]},H.previousItem=function(t,e,n){return n?e<=0?t[t.length-1]:t[e-1]:e<=0?t[0]:t[e-1]},H.niceNum=function(t,e){var n=Math.floor(H.log10(t)),i=t/Math.pow(10,n);return(e?i<1.5?1:i<3?2:i<7?5:10:i<=1?1:i<=2?2:i<=5?5:10)*Math.pow(10,n)},H.requestAnimFrame="undefined"==typeof window?function(t){t()}:window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){return window.setTimeout(t,1e3/60)},H.getRelativePosition=function(t,e){var n,i,a=t.originalEvent||t,r=t.target||t.srcElement,o=r.getBoundingClientRect(),s=a.touches;s&&s.length>0?(n=s[0].clientX,i=s[0].clientY):(n=a.clientX,i=a.clientY);var l=parseFloat(H.getStyle(r,"padding-left")),u=parseFloat(H.getStyle(r,"padding-top")),d=parseFloat(H.getStyle(r,"padding-right")),h=parseFloat(H.getStyle(r,"padding-bottom")),c=o.right-o.left-l-d,f=o.bottom-o.top-u-h;return{x:n=Math.round((n-o.left-l)/c*r.width/e.currentDevicePixelRatio),y:i=Math.round((i-o.top-u)/f*r.height/e.currentDevicePixelRatio)}},H.getConstraintWidth=function(t){return n(t,"max-width","clientWidth")},H.getConstraintHeight=function(t){return n(t,"max-height","clientHeight")},H._calculatePadding=function(t,e,n){return(e=H.getStyle(t,e)).indexOf("%")>-1?n*parseInt(e,10)/100:parseInt(e,10)},H._getParentNode=function(t){var e=t.parentNode;return e&&"[object ShadowRoot]"===e.toString()&&(e=e.host),e},H.getMaximumWidth=function(t){var e=H._getParentNode(t);if(!e)return t.clientWidth;var n=e.clientWidth,i=n-H._calculatePadding(e,"padding-left",n)-H._calculatePadding(e,"padding-right",n),a=H.getConstraintWidth(t);return isNaN(a)?i:Math.min(i,a)},H.getMaximumHeight=function(t){var e=H._getParentNode(t);if(!e)return t.clientHeight;var n=e.clientHeight,i=n-H._calculatePadding(e,"padding-top",n)-H._calculatePadding(e,"padding-bottom",n),a=H.getConstraintHeight(t);return isNaN(a)?i:Math.min(i,a)},H.getStyle=function(t,e){return t.currentStyle?t.currentStyle[e]:document.defaultView.getComputedStyle(t,null).getPropertyValue(e)},H.retinaScale=function(t,e){var n=t.currentDevicePixelRatio=e||"undefined"!=typeof window&&window.devicePixelRatio||1;if(1!==n){var i=t.canvas,a=t.height,r=t.width;i.height=a*n,i.width=r*n,t.ctx.scale(n,n),i.style.height||i.style.width||(i.style.height=a+"px",i.style.width=r+"px")}},H.fontString=function(t,e,n){return e+" "+t+"px "+n},H.longestText=function(t,e,n,i){var a=(i=i||{}).data=i.data||{},r=i.garbageCollect=i.garbageCollect||[];i.font!==e&&(a=i.data={},r=i.garbageCollect=[],i.font=e),t.font=e;var o,s,l,u,d,h=0,c=n.length;for(o=0;o<c;o++)if(null!=(u=n[o])&&!0!==H.isArray(u))h=H.measureText(t,a,r,h,u);else if(H.isArray(u))for(s=0,l=u.length;s<l;s++)null==(d=u[s])||H.isArray(d)||(h=H.measureText(t,a,r,h,d));var f=r.length/2;if(f>n.length){for(o=0;o<f;o++)delete a[r[o]];r.splice(0,f)}return h},H.measureText=function(t,e,n,i,a){var r=e[a];return r||(r=e[a]=t.measureText(a).width,n.push(a)),r>i&&(i=r),i},H.numberOfLabelLines=function(t){var e=1;return H.each(t,(function(t){H.isArray(t)&&t.length>e&&(e=t.length)})),e},H.color=_?function(t){return t instanceof CanvasGradient&&(t=N.global.defaultColor),_(t)}:function(t){return console.error("Color.js not found!"),t},H.getHoverColor=function(t){return t instanceof CanvasPattern||t instanceof CanvasGradient?t:H.color(t).saturate(.5).darken(.1).rgbString()}}(),en._adapters=rn,en.Animation=$,en.animationService=J,en.controllers=Jt,en.DatasetController=it,en.defaults=N,en.Element=K,en.elements=kt,en.Interaction=re,en.layouts=pe,en.platform=Oe,en.plugins=Le,en.Scale=yn,en.scaleService=Re,en.Ticks=on,en.Tooltip=Ye,en.helpers.each(fi,(function(t,e){en.scaleService.registerScaleType(e,t,t._defaults)})),Li)Li.hasOwnProperty(Bi)&&en.plugins.register(Li[Bi]);en.platform.initialize();var Ei=en;return"undefined"!=typeof window&&(window.Chart=en),en.Chart=en,en.Legend=Li.legend._element,en.Title=Li.title._element,en.pluginService=en.plugins,en.PluginBase=en.Element.extend({}),en.canvasHelpers=en.helpers.canvas,en.layoutService=en.layouts,en.LinearScaleBase=Cn,en.helpers.each(["Bar","Bubble","Doughnut","Line","PolarArea","Radar","Scatter"],(function(t){en[t]=function(e,n){return new en(e,en.helpers.merge(n||{},{type:t.charAt(0).toLowerCase()+t.slice(1)}))}})),Ei}));
 
 
 
 
 
 
1
  /*!
2
+ * Chart.js v3.4.1
3
  * https://www.chartjs.org
4
+ * (c) 2021 Chart.js Contributors
5
  * Released under the MIT License
6
  */
7
+ !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).Chart=e()}(this,(function(){"use strict";const t="undefined"==typeof window?function(t){return t()}:window.requestAnimationFrame;function e(e,i,n){const o=n||(t=>Array.prototype.slice.call(t));let s=!1,a=[];return function(...n){a=o(n),s||(s=!0,t.call(window,(()=>{s=!1,e.apply(i,a)})))}}function i(t,e){let i;return function(){return e?(clearTimeout(i),i=setTimeout(t,e)):t(),e}}const n=t=>"start"===t?"left":"end"===t?"right":"center",o=(t,e,i)=>"start"===t?e:"end"===t?i:(e+i)/2,s=(t,e,i,n)=>t===(n?"left":"right")?i:"center"===t?(e+i)/2:e;var a=new class{constructor(){this._request=null,this._charts=new Map,this._running=!1,this._lastDate=void 0}_notify(t,e,i,n){const o=e.listeners[n],s=e.duration;o.forEach((n=>n({chart:t,initial:e.initial,numSteps:s,currentStep:Math.min(i-e.start,s)})))}_refresh(){const e=this;e._request||(e._running=!0,e._request=t.call(window,(()=>{e._update(),e._request=null,e._running&&e._refresh()})))}_update(t=Date.now()){const e=this;let i=0;e._charts.forEach(((n,o)=>{if(!n.running||!n.items.length)return;const s=n.items;let a,r=s.length-1,l=!1;for(;r>=0;--r)a=s[r],a._active?(a._total>n.duration&&(n.duration=a._total),a.tick(t),l=!0):(s[r]=s[s.length-1],s.pop());l&&(o.draw(),e._notify(o,n,t,"progress")),s.length||(n.running=!1,e._notify(o,n,t,"complete"),n.initial=!1),i+=s.length})),e._lastDate=t,0===i&&(e._running=!1)}_getAnims(t){const e=this._charts;let i=e.get(t);return i||(i={running:!1,initial:!0,items:[],listeners:{complete:[],progress:[]}},e.set(t,i)),i}listen(t,e,i){this._getAnims(t).listeners[e].push(i)}add(t,e){e&&e.length&&this._getAnims(t).items.push(...e)}has(t){return this._getAnims(t).items.length>0}start(t){const e=this._charts.get(t);e&&(e.running=!0,e.start=Date.now(),e.duration=e.items.reduce(((t,e)=>Math.max(t,e._duration)),0),this._refresh())}running(t){if(!this._running)return!1;const e=this._charts.get(t);return!!(e&&e.running&&e.items.length)}stop(t){const e=this._charts.get(t);if(!e||!e.items.length)return;const i=e.items;let n=i.length-1;for(;n>=0;--n)i[n].cancel();e.items=[],this._notify(t,e,Date.now(),"complete")}remove(t){return this._charts.delete(t)}};
8
+ /*!
9
+ * @kurkle/color v0.1.9
10
+ * https://github.com/kurkle/color#readme
11
+ * (c) 2020 Jukka Kurkela
12
+ * Released under the MIT License
13
+ */const r={0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,A:10,B:11,C:12,D:13,E:14,F:15,a:10,b:11,c:12,d:13,e:14,f:15},l="0123456789ABCDEF",c=t=>l[15&t],h=t=>l[(240&t)>>4]+l[15&t],d=t=>(240&t)>>4==(15&t);function u(t){var e=function(t){return d(t.r)&&d(t.g)&&d(t.b)&&d(t.a)}(t)?c:h;return t?"#"+e(t.r)+e(t.g)+e(t.b)+(t.a<255?e(t.a):""):t}function f(t){return t+.5|0}const g=(t,e,i)=>Math.max(Math.min(t,i),e);function p(t){return g(f(2.55*t),0,255)}function m(t){return g(f(255*t),0,255)}function x(t){return g(f(t/2.55)/100,0,1)}function b(t){return g(f(100*t),0,100)}const _=/^rgba?\(\s*([-+.\d]+)(%)?[\s,]+([-+.e\d]+)(%)?[\s,]+([-+.e\d]+)(%)?(?:[\s,/]+([-+.e\d]+)(%)?)?\s*\)$/;const y=/^(hsla?|hwb|hsv)\(\s*([-+.e\d]+)(?:deg)?[\s,]+([-+.e\d]+)%[\s,]+([-+.e\d]+)%(?:[\s,]+([-+.e\d]+)(%)?)?\s*\)$/;function v(t,e,i){const n=e*Math.min(i,1-i),o=(e,o=(e+t/30)%12)=>i-n*Math.max(Math.min(o-3,9-o,1),-1);return[o(0),o(8),o(4)]}function w(t,e,i){const n=(n,o=(n+t/60)%6)=>i-i*e*Math.max(Math.min(o,4-o,1),0);return[n(5),n(3),n(1)]}function M(t,e,i){const n=v(t,1,.5);let o;for(e+i>1&&(o=1/(e+i),e*=o,i*=o),o=0;o<3;o++)n[o]*=1-e-i,n[o]+=e;return n}function k(t){const e=t.r/255,i=t.g/255,n=t.b/255,o=Math.max(e,i,n),s=Math.min(e,i,n),a=(o+s)/2;let r,l,c;return o!==s&&(c=o-s,l=a>.5?c/(2-o-s):c/(o+s),r=o===e?(i-n)/c+(i<n?6:0):o===i?(n-e)/c+2:(e-i)/c+4,r=60*r+.5),[0|r,l||0,a]}function S(t,e,i,n){return(Array.isArray(e)?t(e[0],e[1],e[2]):t(e,i,n)).map(m)}function P(t,e,i){return S(v,t,e,i)}function D(t){return(t%360+360)%360}function C(t){const e=y.exec(t);let i,n=255;if(!e)return;e[5]!==i&&(n=e[6]?p(+e[5]):m(+e[5]));const o=D(+e[2]),s=+e[3]/100,a=+e[4]/100;return i="hwb"===e[1]?function(t,e,i){return S(M,t,e,i)}(o,s,a):"hsv"===e[1]?function(t,e,i){return S(w,t,e,i)}(o,s,a):P(o,s,a),{r:i[0],g:i[1],b:i[2],a:n}}const O={x:"dark",Z:"light",Y:"re",X:"blu",W:"gr",V:"medium",U:"slate",A:"ee",T:"ol",S:"or",B:"ra",C:"lateg",D:"ights",R:"in",Q:"turquois",E:"hi",P:"ro",O:"al",N:"le",M:"de",L:"yello",F:"en",K:"ch",G:"arks",H:"ea",I:"ightg",J:"wh"},T={OiceXe:"f0f8ff",antiquewEte:"faebd7",aqua:"ffff",aquamarRe:"7fffd4",azuY:"f0ffff",beige:"f5f5dc",bisque:"ffe4c4",black:"0",blanKedOmond:"ffebcd",Xe:"ff",XeviTet:"8a2be2",bPwn:"a52a2a",burlywood:"deb887",caMtXe:"5f9ea0",KartYuse:"7fff00",KocTate:"d2691e",cSO:"ff7f50",cSnflowerXe:"6495ed",cSnsilk:"fff8dc",crimson:"dc143c",cyan:"ffff",xXe:"8b",xcyan:"8b8b",xgTMnPd:"b8860b",xWay:"a9a9a9",xgYF:"6400",xgYy:"a9a9a9",xkhaki:"bdb76b",xmagFta:"8b008b",xTivegYF:"556b2f",xSange:"ff8c00",xScEd:"9932cc",xYd:"8b0000",xsOmon:"e9967a",xsHgYF:"8fbc8f",xUXe:"483d8b",xUWay:"2f4f4f",xUgYy:"2f4f4f",xQe:"ced1",xviTet:"9400d3",dAppRk:"ff1493",dApskyXe:"bfff",dimWay:"696969",dimgYy:"696969",dodgerXe:"1e90ff",fiYbrick:"b22222",flSOwEte:"fffaf0",foYstWAn:"228b22",fuKsia:"ff00ff",gaRsbSo:"dcdcdc",ghostwEte:"f8f8ff",gTd:"ffd700",gTMnPd:"daa520",Way:"808080",gYF:"8000",gYFLw:"adff2f",gYy:"808080",honeyMw:"f0fff0",hotpRk:"ff69b4",RdianYd:"cd5c5c",Rdigo:"4b0082",ivSy:"fffff0",khaki:"f0e68c",lavFMr:"e6e6fa",lavFMrXsh:"fff0f5",lawngYF:"7cfc00",NmoncEffon:"fffacd",ZXe:"add8e6",ZcSO:"f08080",Zcyan:"e0ffff",ZgTMnPdLw:"fafad2",ZWay:"d3d3d3",ZgYF:"90ee90",ZgYy:"d3d3d3",ZpRk:"ffb6c1",ZsOmon:"ffa07a",ZsHgYF:"20b2aa",ZskyXe:"87cefa",ZUWay:"778899",ZUgYy:"778899",ZstAlXe:"b0c4de",ZLw:"ffffe0",lime:"ff00",limegYF:"32cd32",lRF:"faf0e6",magFta:"ff00ff",maPon:"800000",VaquamarRe:"66cdaa",VXe:"cd",VScEd:"ba55d3",VpurpN:"9370db",VsHgYF:"3cb371",VUXe:"7b68ee",VsprRggYF:"fa9a",VQe:"48d1cc",VviTetYd:"c71585",midnightXe:"191970",mRtcYam:"f5fffa",mistyPse:"ffe4e1",moccasR:"ffe4b5",navajowEte:"ffdead",navy:"80",Tdlace:"fdf5e6",Tive:"808000",TivedBb:"6b8e23",Sange:"ffa500",SangeYd:"ff4500",ScEd:"da70d6",pOegTMnPd:"eee8aa",pOegYF:"98fb98",pOeQe:"afeeee",pOeviTetYd:"db7093",papayawEp:"ffefd5",pHKpuff:"ffdab9",peru:"cd853f",pRk:"ffc0cb",plum:"dda0dd",powMrXe:"b0e0e6",purpN:"800080",YbeccapurpN:"663399",Yd:"ff0000",Psybrown:"bc8f8f",PyOXe:"4169e1",saddNbPwn:"8b4513",sOmon:"fa8072",sandybPwn:"f4a460",sHgYF:"2e8b57",sHshell:"fff5ee",siFna:"a0522d",silver:"c0c0c0",skyXe:"87ceeb",UXe:"6a5acd",UWay:"708090",UgYy:"708090",snow:"fffafa",sprRggYF:"ff7f",stAlXe:"4682b4",tan:"d2b48c",teO:"8080",tEstN:"d8bfd8",tomato:"ff6347",Qe:"40e0d0",viTet:"ee82ee",JHt:"f5deb3",wEte:"ffffff",wEtesmoke:"f5f5f5",Lw:"ffff00",LwgYF:"9acd32"};let A;function L(t){A||(A=function(){const t={},e=Object.keys(T),i=Object.keys(O);let n,o,s,a,r;for(n=0;n<e.length;n++){for(a=r=e[n],o=0;o<i.length;o++)s=i[o],r=r.replace(s,O[s]);s=parseInt(T[a],16),t[r]=[s>>16&255,s>>8&255,255&s]}return t}(),A.transparent=[0,0,0,0]);const e=A[t.toLowerCase()];return e&&{r:e[0],g:e[1],b:e[2],a:4===e.length?e[3]:255}}function R(t,e,i){if(t){let n=k(t);n[e]=Math.max(0,Math.min(n[e]+n[e]*i,0===e?360:1)),n=P(n),t.r=n[0],t.g=n[1],t.b=n[2]}}function E(t,e){return t?Object.assign(e||{},t):t}function z(t){var e={r:0,g:0,b:0,a:255};return Array.isArray(t)?t.length>=3&&(e={r:t[0],g:t[1],b:t[2],a:255},t.length>3&&(e.a=m(t[3]))):(e=E(t,{r:0,g:0,b:0,a:1})).a=m(e.a),e}function I(t){return"r"===t.charAt(0)?function(t){const e=_.exec(t);let i,n,o,s=255;if(e){if(e[7]!==i){const t=+e[7];s=255&(e[8]?p(t):255*t)}return i=+e[1],n=+e[3],o=+e[5],i=255&(e[2]?p(i):i),n=255&(e[4]?p(n):n),o=255&(e[6]?p(o):o),{r:i,g:n,b:o,a:s}}}(t):C(t)}class F{constructor(t){if(t instanceof F)return t;const e=typeof t;let i;var n,o,s;"object"===e?i=z(t):"string"===e&&(s=(n=t).length,"#"===n[0]&&(4===s||5===s?o={r:255&17*r[n[1]],g:255&17*r[n[2]],b:255&17*r[n[3]],a:5===s?17*r[n[4]]:255}:7!==s&&9!==s||(o={r:r[n[1]]<<4|r[n[2]],g:r[n[3]]<<4|r[n[4]],b:r[n[5]]<<4|r[n[6]],a:9===s?r[n[7]]<<4|r[n[8]]:255})),i=o||L(t)||I(t)),this._rgb=i,this._valid=!!i}get valid(){return this._valid}get rgb(){var t=E(this._rgb);return t&&(t.a=x(t.a)),t}set rgb(t){this._rgb=z(t)}rgbString(){return this._valid?(t=this._rgb)&&(t.a<255?`rgba(${t.r}, ${t.g}, ${t.b}, ${x(t.a)})`:`rgb(${t.r}, ${t.g}, ${t.b})`):this._rgb;var t}hexString(){return this._valid?u(this._rgb):this._rgb}hslString(){return this._valid?function(t){if(!t)return;const e=k(t),i=e[0],n=b(e[1]),o=b(e[2]);return t.a<255?`hsla(${i}, ${n}%, ${o}%, ${x(t.a)})`:`hsl(${i}, ${n}%, ${o}%)`}(this._rgb):this._rgb}mix(t,e){const i=this;if(t){const n=i.rgb,o=t.rgb;let s;const a=e===s?.5:e,r=2*a-1,l=n.a-o.a,c=((r*l==-1?r:(r+l)/(1+r*l))+1)/2;s=1-c,n.r=255&c*n.r+s*o.r+.5,n.g=255&c*n.g+s*o.g+.5,n.b=255&c*n.b+s*o.b+.5,n.a=a*n.a+(1-a)*o.a,i.rgb=n}return i}clone(){return new F(this.rgb)}alpha(t){return this._rgb.a=m(t),this}clearer(t){return this._rgb.a*=1-t,this}greyscale(){const t=this._rgb,e=f(.3*t.r+.59*t.g+.11*t.b);return t.r=t.g=t.b=e,this}opaquer(t){return this._rgb.a*=1+t,this}negate(){const t=this._rgb;return t.r=255-t.r,t.g=255-t.g,t.b=255-t.b,this}lighten(t){return R(this._rgb,2,t),this}darken(t){return R(this._rgb,2,-t),this}saturate(t){return R(this._rgb,1,t),this}desaturate(t){return R(this._rgb,1,-t),this}rotate(t){return function(t,e){var i=k(t);i[0]=D(i[0]+e),i=P(i),t.r=i[0],t.g=i[1],t.b=i[2]}(this._rgb,t),this}}function B(t){return new F(t)}const V=t=>t instanceof CanvasGradient||t instanceof CanvasPattern;function W(t){return V(t)?t:B(t)}function N(t){return V(t)?t:B(t).saturate(.5).darken(.1).hexString()}function H(){}const j=function(){let t=0;return function(){return t++}}();function $(t){return null==t}function Y(t){if(Array.isArray&&Array.isArray(t))return!0;const e=Object.prototype.toString.call(t);return"[object"===e.substr(0,7)&&"Array]"===e.substr(-6)}function U(t){return null!==t&&"[object Object]"===Object.prototype.toString.call(t)}const X=t=>("number"==typeof t||t instanceof Number)&&isFinite(+t);function q(t,e){return X(t)?t:e}function K(t,e){return void 0===t?e:t}const G=(t,e)=>"string"==typeof t&&t.endsWith("%")?parseFloat(t)/100:t/e,Z=(t,e)=>"string"==typeof t&&t.endsWith("%")?parseFloat(t)/100*e:+t;function Q(t,e,i){if(t&&"function"==typeof t.call)return t.apply(i,e)}function J(t,e,i,n){let o,s,a;if(Y(t))if(s=t.length,n)for(o=s-1;o>=0;o--)e.call(i,t[o],o);else for(o=0;o<s;o++)e.call(i,t[o],o);else if(U(t))for(a=Object.keys(t),s=a.length,o=0;o<s;o++)e.call(i,t[a[o]],a[o])}function tt(t,e){let i,n,o,s;if(!t||!e||t.length!==e.length)return!1;for(i=0,n=t.length;i<n;++i)if(o=t[i],s=e[i],o.datasetIndex!==s.datasetIndex||o.index!==s.index)return!1;return!0}function et(t){if(Y(t))return t.map(et);if(U(t)){const e=Object.create(null),i=Object.keys(t),n=i.length;let o=0;for(;o<n;++o)e[i[o]]=et(t[i[o]]);return e}return t}function it(t){return-1===["__proto__","prototype","constructor"].indexOf(t)}function nt(t,e,i,n){if(!it(t))return;const o=e[t],s=i[t];U(o)&&U(s)?ot(o,s,n):e[t]=et(s)}function ot(t,e,i){const n=Y(e)?e:[e],o=n.length;if(!U(t))return t;const s=(i=i||{}).merger||nt;for(let a=0;a<o;++a){if(!U(e=n[a]))continue;const o=Object.keys(e);for(let n=0,a=o.length;n<a;++n)s(o[n],t,e,i)}return t}function st(t,e){return ot(t,e,{merger:at})}function at(t,e,i){if(!it(t))return;const n=e[t],o=i[t];U(n)&&U(o)?st(n,o):Object.prototype.hasOwnProperty.call(e,t)||(e[t]=et(o))}function rt(t,e){const i=t.indexOf(".",e);return-1===i?t.length:i}function lt(t,e){if(""===e)return t;let i=0,n=rt(e,i);for(;t&&n>i;)t=t[e.substr(i,n-i)],i=n+1,n=rt(e,i);return t}function ct(t){return t.charAt(0).toUpperCase()+t.slice(1)}const ht=t=>void 0!==t,dt=t=>"function"==typeof t,ut=(t,e)=>{if(t.size!==e.size)return!1;for(const i of t)if(!e.has(i))return!1;return!0},ft=Object.create(null),gt=Object.create(null);function pt(t,e){if(!e)return t;const i=e.split(".");for(let e=0,n=i.length;e<n;++e){const n=i[e];t=t[n]||(t[n]=Object.create(null))}return t}function mt(t,e,i){return"string"==typeof e?ot(pt(t,e),i):ot(pt(t,""),e)}var xt=new class{constructor(t){this.animation=void 0,this.backgroundColor="rgba(0,0,0,0.1)",this.borderColor="rgba(0,0,0,0.1)",this.color="#666",this.datasets={},this.devicePixelRatio=t=>t.chart.platform.getDevicePixelRatio(),this.elements={},this.events=["mousemove","mouseout","click","touchstart","touchmove"],this.font={family:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",size:12,style:"normal",lineHeight:1.2,weight:null},this.hover={},this.hoverBackgroundColor=(t,e)=>N(e.backgroundColor),this.hoverBorderColor=(t,e)=>N(e.borderColor),this.hoverColor=(t,e)=>N(e.color),this.indexAxis="x",this.interaction={mode:"nearest",intersect:!0},this.maintainAspectRatio=!0,this.onHover=null,this.onClick=null,this.parsing=!0,this.plugins={},this.responsive=!0,this.scale=void 0,this.scales={},this.showLine=!0,this.describe(t)}set(t,e){return mt(this,t,e)}get(t){return pt(this,t)}describe(t,e){return mt(gt,t,e)}override(t,e){return mt(ft,t,e)}route(t,e,i,n){const o=pt(this,t),s=pt(this,i),a="_"+e;Object.defineProperties(o,{[a]:{value:o[e],writable:!0},[e]:{enumerable:!0,get(){const t=this[a],e=s[n];return U(t)?Object.assign({},e,t):K(t,e)},set(t){this[a]=t}}})}}({_scriptable:t=>!t.startsWith("on"),_indexable:t=>"events"!==t,hover:{_fallback:"interaction"},interaction:{_scriptable:!1,_indexable:!1}});const bt=Math.PI,_t=2*bt,yt=_t+bt,vt=Number.POSITIVE_INFINITY,wt=bt/180,Mt=bt/2,kt=bt/4,St=2*bt/3,Pt=Math.log10,Dt=Math.sign;function Ct(t){const e=Math.round(t);t=At(t,e,t/1e3)?e:t;const i=Math.pow(10,Math.floor(Pt(t))),n=t/i;return(n<=1?1:n<=2?2:n<=5?5:10)*i}function Ot(t){const e=[],i=Math.sqrt(t);let n;for(n=1;n<i;n++)t%n==0&&(e.push(n),e.push(t/n));return i===(0|i)&&e.push(i),e.sort(((t,e)=>t-e)).pop(),e}function Tt(t){return!isNaN(parseFloat(t))&&isFinite(t)}function At(t,e,i){return Math.abs(t-e)<i}function Lt(t,e){const i=Math.round(t);return i-e<=t&&i+e>=t}function Rt(t,e,i){let n,o,s;for(n=0,o=t.length;n<o;n++)s=t[n][i],isNaN(s)||(e.min=Math.min(e.min,s),e.max=Math.max(e.max,s))}function Et(t){return t*(bt/180)}function zt(t){return t*(180/bt)}function It(t){if(!X(t))return;let e=1,i=0;for(;Math.round(t*e)/e!==t;)e*=10,i++;return i}function Ft(t,e){const i=e.x-t.x,n=e.y-t.y,o=Math.sqrt(i*i+n*n);let s=Math.atan2(n,i);return s<-.5*bt&&(s+=_t),{angle:s,distance:o}}function Bt(t,e){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))}function Vt(t,e){return(t-e+yt)%_t-bt}function Wt(t){return(t%_t+_t)%_t}function Nt(t,e,i,n){const o=Wt(t),s=Wt(e),a=Wt(i),r=Wt(s-o),l=Wt(a-o),c=Wt(o-s),h=Wt(o-a);return o===s||o===a||n&&s===a||r>l&&c<h}function Ht(t,e,i){return Math.max(e,Math.min(i,t))}function jt(t){return Ht(t,-32768,32767)}function $t(t){return!t||$(t.size)||$(t.family)?null:(t.style?t.style+" ":"")+(t.weight?t.weight+" ":"")+t.size+"px "+t.family}function Yt(t,e,i,n,o){let s=e[o];return s||(s=e[o]=t.measureText(o).width,i.push(o)),s>n&&(n=s),n}function Ut(t,e,i,n){let o=(n=n||{}).data=n.data||{},s=n.garbageCollect=n.garbageCollect||[];n.font!==e&&(o=n.data={},s=n.garbageCollect=[],n.font=e),t.save(),t.font=e;let a=0;const r=i.length;let l,c,h,d,u;for(l=0;l<r;l++)if(d=i[l],null!=d&&!0!==Y(d))a=Yt(t,o,s,a,d);else if(Y(d))for(c=0,h=d.length;c<h;c++)u=d[c],null==u||Y(u)||(a=Yt(t,o,s,a,u));t.restore();const f=s.length/2;if(f>i.length){for(l=0;l<f;l++)delete o[s[l]];s.splice(0,f)}return a}function Xt(t,e,i){const n=t.currentDevicePixelRatio,o=0!==i?Math.max(i/2,.5):0;return Math.round((e-o)*n)/n+o}function qt(t,e){(e=e||t.getContext("2d")).save(),e.resetTransform(),e.clearRect(0,0,t.width,t.height),e.restore()}function Kt(t,e,i,n){let o,s,a,r,l;const c=e.pointStyle,h=e.rotation,d=e.radius;let u=(h||0)*wt;if(c&&"object"==typeof c&&(o=c.toString(),"[object HTMLImageElement]"===o||"[object HTMLCanvasElement]"===o))return t.save(),t.translate(i,n),t.rotate(u),t.drawImage(c,-c.width/2,-c.height/2,c.width,c.height),void t.restore();if(!(isNaN(d)||d<=0)){switch(t.beginPath(),c){default:t.arc(i,n,d,0,_t),t.closePath();break;case"triangle":t.moveTo(i+Math.sin(u)*d,n-Math.cos(u)*d),u+=St,t.lineTo(i+Math.sin(u)*d,n-Math.cos(u)*d),u+=St,t.lineTo(i+Math.sin(u)*d,n-Math.cos(u)*d),t.closePath();break;case"rectRounded":l=.516*d,r=d-l,s=Math.cos(u+kt)*r,a=Math.sin(u+kt)*r,t.arc(i-s,n-a,l,u-bt,u-Mt),t.arc(i+a,n-s,l,u-Mt,u),t.arc(i+s,n+a,l,u,u+Mt),t.arc(i-a,n+s,l,u+Mt,u+bt),t.closePath();break;case"rect":if(!h){r=Math.SQRT1_2*d,t.rect(i-r,n-r,2*r,2*r);break}u+=kt;case"rectRot":s=Math.cos(u)*d,a=Math.sin(u)*d,t.moveTo(i-s,n-a),t.lineTo(i+a,n-s),t.lineTo(i+s,n+a),t.lineTo(i-a,n+s),t.closePath();break;case"crossRot":u+=kt;case"cross":s=Math.cos(u)*d,a=Math.sin(u)*d,t.moveTo(i-s,n-a),t.lineTo(i+s,n+a),t.moveTo(i+a,n-s),t.lineTo(i-a,n+s);break;case"star":s=Math.cos(u)*d,a=Math.sin(u)*d,t.moveTo(i-s,n-a),t.lineTo(i+s,n+a),t.moveTo(i+a,n-s),t.lineTo(i-a,n+s),u+=kt,s=Math.cos(u)*d,a=Math.sin(u)*d,t.moveTo(i-s,n-a),t.lineTo(i+s,n+a),t.moveTo(i+a,n-s),t.lineTo(i-a,n+s);break;case"line":s=Math.cos(u)*d,a=Math.sin(u)*d,t.moveTo(i-s,n-a),t.lineTo(i+s,n+a);break;case"dash":t.moveTo(i,n),t.lineTo(i+Math.cos(u)*d,n+Math.sin(u)*d)}t.fill(),e.borderWidth>0&&t.stroke()}}function Gt(t,e,i){return i=i||.5,t&&t.x>e.left-i&&t.x<e.right+i&&t.y>e.top-i&&t.y<e.bottom+i}function Zt(t,e){t.save(),t.beginPath(),t.rect(e.left,e.top,e.right-e.left,e.bottom-e.top),t.clip()}function Qt(t){t.restore()}function Jt(t,e,i,n,o){if(!e)return t.lineTo(i.x,i.y);if("middle"===o){const n=(e.x+i.x)/2;t.lineTo(n,e.y),t.lineTo(n,i.y)}else"after"===o!=!!n?t.lineTo(e.x,i.y):t.lineTo(i.x,e.y);t.lineTo(i.x,i.y)}function te(t,e,i,n){if(!e)return t.lineTo(i.x,i.y);t.bezierCurveTo(n?e.cp1x:e.cp2x,n?e.cp1y:e.cp2y,n?i.cp2x:i.cp1x,n?i.cp2y:i.cp1y,i.x,i.y)}function ee(t,e,i,n,o,s={}){const a=Y(e)?e:[e],r=s.strokeWidth>0&&""!==s.strokeColor;let l,c;for(t.save(),t.font=o.string,function(t,e){e.translation&&t.translate(e.translation[0],e.translation[1]);$(e.rotation)||t.rotate(e.rotation);e.color&&(t.fillStyle=e.color);e.textAlign&&(t.textAlign=e.textAlign);e.textBaseline&&(t.textBaseline=e.textBaseline)}(t,s),l=0;l<a.length;++l)c=a[l],r&&(s.strokeColor&&(t.strokeStyle=s.strokeColor),$(s.strokeWidth)||(t.lineWidth=s.strokeWidth),t.strokeText(c,i,n,s.maxWidth)),t.fillText(c,i,n,s.maxWidth),ie(t,i,n,c,s),n+=o.lineHeight;t.restore()}function ie(t,e,i,n,o){if(o.strikethrough||o.underline){const s=t.measureText(n),a=e-s.actualBoundingBoxLeft,r=e+s.actualBoundingBoxRight,l=i-s.actualBoundingBoxAscent,c=i+s.actualBoundingBoxDescent,h=o.strikethrough?(l+c)/2:c;t.strokeStyle=t.fillStyle,t.beginPath(),t.lineWidth=o.decorationWidth||2,t.moveTo(a,h),t.lineTo(r,h),t.stroke()}}function ne(t,e){const{x:i,y:n,w:o,h:s,radius:a}=e;t.arc(i+a.topLeft,n+a.topLeft,a.topLeft,-Mt,bt,!0),t.lineTo(i,n+s-a.bottomLeft),t.arc(i+a.bottomLeft,n+s-a.bottomLeft,a.bottomLeft,bt,Mt,!0),t.lineTo(i+o-a.bottomRight,n+s),t.arc(i+o-a.bottomRight,n+s-a.bottomRight,a.bottomRight,Mt,0,!0),t.lineTo(i+o,n+a.topRight),t.arc(i+o-a.topRight,n+a.topRight,a.topRight,0,-Mt,!0),t.lineTo(i+a.topLeft,n)}function oe(t,e,i){i=i||(i=>t[i]<e);let n,o=t.length-1,s=0;for(;o-s>1;)n=s+o>>1,i(n)?s=n:o=n;return{lo:s,hi:o}}const se=(t,e,i)=>oe(t,i,(n=>t[n][e]<i)),ae=(t,e,i)=>oe(t,i,(n=>t[n][e]>=i));function re(t,e,i){let n=0,o=t.length;for(;n<o&&t[n]<e;)n++;for(;o>n&&t[o-1]>i;)o--;return n>0||o<t.length?t.slice(n,o):t}const le=["push","pop","shift","splice","unshift"];function ce(t,e){t._chartjs?t._chartjs.listeners.push(e):(Object.defineProperty(t,"_chartjs",{configurable:!0,enumerable:!1,value:{listeners:[e]}}),le.forEach((e=>{const i="_onData"+ct(e),n=t[e];Object.defineProperty(t,e,{configurable:!0,enumerable:!1,value(...e){const o=n.apply(this,e);return t._chartjs.listeners.forEach((t=>{"function"==typeof t[i]&&t[i](...e)})),o}})})))}function he(t,e){const i=t._chartjs;if(!i)return;const n=i.listeners,o=n.indexOf(e);-1!==o&&n.splice(o,1),n.length>0||(le.forEach((e=>{delete t[e]})),delete t._chartjs)}function de(t){const e=new Set;let i,n;for(i=0,n=t.length;i<n;++i)e.add(t[i]);return e.size===n?t:Array.from(e)}function ue(t){let e=t.parentNode;return e&&"[object ShadowRoot]"===e.toString()&&(e=e.host),e}function fe(t,e,i){let n;return"string"==typeof t?(n=parseInt(t,10),-1!==t.indexOf("%")&&(n=n/100*e.parentNode[i])):n=t,n}const ge=t=>window.getComputedStyle(t,null);function pe(t,e){return ge(t).getPropertyValue(e)}const me=["top","right","bottom","left"];function xe(t,e,i){const n={};i=i?"-"+i:"";for(let o=0;o<4;o++){const s=me[o];n[s]=parseFloat(t[e+"-"+s+i])||0}return n.width=n.left+n.right,n.height=n.top+n.bottom,n}function be(t,e){const{canvas:i,currentDevicePixelRatio:n}=e,o=ge(i),s="border-box"===o.boxSizing,a=xe(o,"padding"),r=xe(o,"border","width"),{x:l,y:c,box:h}=function(t,e){const i=t.native||t,n=i.touches,o=n&&n.length?n[0]:i,{offsetX:s,offsetY:a}=o;let r,l,c=!1;if(((t,e,i)=>(t>0||e>0)&&(!i||!i.shadowRoot))(s,a,i.target))r=s,l=a;else{const t=e.getBoundingClientRect();r=o.clientX-t.left,l=o.clientY-t.top,c=!0}return{x:r,y:l,box:c}}(t,i),d=a.left+(h&&r.left),u=a.top+(h&&r.top);let{width:f,height:g}=e;return s&&(f-=a.width+r.width,g-=a.height+r.height),{x:Math.round((l-d)/f*i.width/n),y:Math.round((c-u)/g*i.height/n)}}const _e=t=>Math.round(10*t)/10;function ye(t,e,i,n){const o=ge(t),s=xe(o,"margin"),a=fe(o.maxWidth,t,"clientWidth")||vt,r=fe(o.maxHeight,t,"clientHeight")||vt,l=function(t,e,i){let n,o;if(void 0===e||void 0===i){const s=ue(t);if(s){const t=s.getBoundingClientRect(),a=ge(s),r=xe(a,"border","width"),l=xe(a,"padding");e=t.width-l.width-r.width,i=t.height-l.height-r.height,n=fe(a.maxWidth,s,"clientWidth"),o=fe(a.maxHeight,s,"clientHeight")}else e=t.clientWidth,i=t.clientHeight}return{width:e,height:i,maxWidth:n||vt,maxHeight:o||vt}}(t,e,i);let{width:c,height:h}=l;if("content-box"===o.boxSizing){const t=xe(o,"border","width"),e=xe(o,"padding");c-=e.width+t.width,h-=e.height+t.height}return c=Math.max(0,c-s.width),h=Math.max(0,n?Math.floor(c/n):h-s.height),c=_e(Math.min(c,a,l.maxWidth)),h=_e(Math.min(h,r,l.maxHeight)),c&&!h&&(h=_e(c/2)),{width:c,height:h}}function ve(t,e,i){const n=e||1,o=Math.floor(t.height*n),s=Math.floor(t.width*n);t.height=o/n,t.width=s/n;const a=t.canvas;return a.style&&(i||!a.style.height&&!a.style.width)&&(a.style.height=`${t.height}px`,a.style.width=`${t.width}px`),(t.currentDevicePixelRatio!==n||a.height!==o||a.width!==s)&&(t.currentDevicePixelRatio=n,a.height=o,a.width=s,t.ctx.setTransform(n,0,0,n,0,0),!0)}const we=function(){let t=!1;try{const e={get passive(){return t=!0,!1}};window.addEventListener("test",null,e),window.removeEventListener("test",null,e)}catch(t){}return t}();function Me(t,e){const i=pe(t,e),n=i&&i.match(/^(\d+)(\.\d+)?px$/);return n?+n[1]:void 0}function ke(t,e){return"native"in t?{x:t.x,y:t.y}:be(t,e)}function Se(t,e,i,n){const{controller:o,data:s,_sorted:a}=t,r=o._cachedMeta.iScale;if(r&&e===r.axis&&a&&s.length){const t=r._reversePixels?ae:se;if(!n)return t(s,e,i);if(o._sharedOptions){const n=s[0],o="function"==typeof n.getRange&&n.getRange(e);if(o){const n=t(s,e,i-o),a=t(s,e,i+o);return{lo:n.lo,hi:a.hi}}}}return{lo:0,hi:s.length-1}}function Pe(t,e,i,n,o){const s=t.getSortedVisibleDatasetMetas(),a=i[e];for(let t=0,i=s.length;t<i;++t){const{index:i,data:r}=s[t],{lo:l,hi:c}=Se(s[t],e,a,o);for(let t=l;t<=c;++t){const e=r[t];e.skip||n(e,i,t)}}}function De(t,e,i,n){const o=[];if(!Gt(e,t.chartArea,t._minPadding))return o;return Pe(t,i,e,(function(t,i,s){t.inRange(e.x,e.y,n)&&o.push({element:t,datasetIndex:i,index:s})}),!0),o}function Ce(t,e,i,n,o){const s=function(t){const e=-1!==t.indexOf("x"),i=-1!==t.indexOf("y");return function(t,n){const o=e?Math.abs(t.x-n.x):0,s=i?Math.abs(t.y-n.y):0;return Math.sqrt(Math.pow(o,2)+Math.pow(s,2))}}(i);let a=Number.POSITIVE_INFINITY,r=[];if(!Gt(e,t.chartArea,t._minPadding))return r;return Pe(t,i,e,(function(i,l,c){if(n&&!i.inRange(e.x,e.y,o))return;const h=i.getCenterPoint(o);if(!Gt(h,t.chartArea,t._minPadding))return;const d=s(e,h);d<a?(r=[{element:i,datasetIndex:l,index:c}],a=d):d===a&&r.push({element:i,datasetIndex:l,index:c})})),r}function Oe(t,e,i,n){const o=ke(e,t),s=[],a=i.axis,r="x"===a?"inXRange":"inYRange";let l=!1;return function(t,e){const i=t.getSortedVisibleDatasetMetas();let n,o,s;for(let t=0,a=i.length;t<a;++t){({index:n,data:o}=i[t]);for(let t=0,i=o.length;t<i;++t)s=o[t],s.skip||e(s,n,t)}}(t,((t,e,i)=>{t[r](o[a],n)&&s.push({element:t,datasetIndex:e,index:i}),t.inRange(o.x,o.y,n)&&(l=!0)})),i.intersect&&!l?[]:s}var Te={modes:{index(t,e,i,n){const o=ke(e,t),s=i.axis||"x",a=i.intersect?De(t,o,s,n):Ce(t,o,s,!1,n),r=[];return a.length?(t.getSortedVisibleDatasetMetas().forEach((t=>{const e=a[0].index,i=t.data[e];i&&!i.skip&&r.push({element:i,datasetIndex:t.index,index:e})})),r):[]},dataset(t,e,i,n){const o=ke(e,t),s=i.axis||"xy";let a=i.intersect?De(t,o,s,n):Ce(t,o,s,!1,n);if(a.length>0){const e=a[0].datasetIndex,i=t.getDatasetMeta(e).data;a=[];for(let t=0;t<i.length;++t)a.push({element:i[t],datasetIndex:e,index:t})}return a},point:(t,e,i,n)=>De(t,ke(e,t),i.axis||"xy",n),nearest:(t,e,i,n)=>Ce(t,ke(e,t),i.axis||"xy",i.intersect,n),x:(t,e,i,n)=>(i.axis="x",Oe(t,e,i,n)),y:(t,e,i,n)=>(i.axis="y",Oe(t,e,i,n))}};const Ae=new RegExp(/^(normal|(\d+(?:\.\d+)?)(px|em|%)?)$/),Le=new RegExp(/^(normal|italic|initial|inherit|unset|(oblique( -?[0-9]?[0-9]deg)?))$/);function Re(t,e){const i=(""+t).match(Ae);if(!i||"normal"===i[1])return 1.2*e;switch(t=+i[2],i[3]){case"px":return t;case"%":t/=100}return e*t}function Ee(t,e){const i={},n=U(e),o=n?Object.keys(e):e,s=U(t)?n?i=>K(t[i],t[e[i]]):e=>t[e]:()=>t;for(const t of o)i[t]=+s(t)||0;return i}function ze(t){return Ee(t,{top:"y",right:"x",bottom:"y",left:"x"})}function Ie(t){return Ee(t,["topLeft","topRight","bottomLeft","bottomRight"])}function Fe(t){const e=ze(t);return e.width=e.left+e.right,e.height=e.top+e.bottom,e}function Be(t,e){t=t||{},e=e||xt.font;let i=K(t.size,e.size);"string"==typeof i&&(i=parseInt(i,10));let n=K(t.style,e.style);n&&!(""+n).match(Le)&&(console.warn('Invalid font style specified: "'+n+'"'),n="");const o={family:K(t.family,e.family),lineHeight:Re(K(t.lineHeight,e.lineHeight),i),size:i,style:n,weight:K(t.weight,e.weight),string:""};return o.string=$t(o),o}function Ve(t,e,i,n){let o,s,a,r=!0;for(o=0,s=t.length;o<s;++o)if(a=t[o],void 0!==a&&(void 0!==e&&"function"==typeof a&&(a=a(e),r=!1),void 0!==i&&Y(a)&&(a=a[i%a.length],r=!1),void 0!==a))return n&&!r&&(n.cacheable=!1),a}function We(t,e){const{min:i,max:n}=t;return{min:i-Math.abs(Z(e,i)),max:n+Z(e,n)}}const Ne=["left","top","right","bottom"];function He(t,e){return t.filter((t=>t.pos===e))}function je(t,e){return t.filter((t=>-1===Ne.indexOf(t.pos)&&t.box.axis===e))}function $e(t,e){return t.sort(((t,i)=>{const n=e?i:t,o=e?t:i;return n.weight===o.weight?n.index-o.index:n.weight-o.weight}))}function Ye(t,e,i,n){return Math.max(t[i],e[i])+Math.max(t[n],e[n])}function Ue(t,e){t.top=Math.max(t.top,e.top),t.left=Math.max(t.left,e.left),t.bottom=Math.max(t.bottom,e.bottom),t.right=Math.max(t.right,e.right)}function Xe(t,e,i){const n=i.box,o=t.maxPadding;U(i.pos)||(i.size&&(t[i.pos]-=i.size),i.size=i.horizontal?n.height:n.width,t[i.pos]+=i.size),n.getPadding&&Ue(o,n.getPadding());const s=Math.max(0,e.outerWidth-Ye(o,t,"left","right")),a=Math.max(0,e.outerHeight-Ye(o,t,"top","bottom")),r=s!==t.w,l=a!==t.h;return t.w=s,t.h=a,i.horizontal?{same:r,other:l}:{same:l,other:r}}function qe(t,e){const i=e.maxPadding;function n(t){const n={left:0,top:0,right:0,bottom:0};return t.forEach((t=>{n[t]=Math.max(e[t],i[t])})),n}return n(t?["left","right"]:["top","bottom"])}function Ke(t,e,i){const n=[];let o,s,a,r,l,c;for(o=0,s=t.length,l=0;o<s;++o){a=t[o],r=a.box,r.update(a.width||e.w,a.height||e.h,qe(a.horizontal,e));const{same:s,other:h}=Xe(e,i,a);l|=s&&n.length,c=c||h,r.fullSize||n.push(a)}return l&&Ke(n,e,i)||c}function Ge(t,e,i){const n=i.padding;let o,s,a,r,l=e.x,c=e.y;for(o=0,s=t.length;o<s;++o)a=t[o],r=a.box,a.horizontal?(r.left=r.fullSize?n.left:e.left,r.right=r.fullSize?i.outerWidth-n.right:e.left+e.w,r.top=c,r.bottom=c+r.height,r.width=r.right-r.left,c=r.bottom):(r.left=l,r.right=l+r.width,r.top=r.fullSize?n.top:e.top,r.bottom=r.fullSize?i.outerHeight-n.bottom:e.top+e.h,r.height=r.bottom-r.top,l=r.right);e.x=l,e.y=c}xt.set("layout",{padding:{top:0,right:0,bottom:0,left:0}});var Ze={addBox(t,e){t.boxes||(t.boxes=[]),e.fullSize=e.fullSize||!1,e.position=e.position||"top",e.weight=e.weight||0,e._layers=e._layers||function(){return[{z:0,draw(t){e.draw(t)}}]},t.boxes.push(e)},removeBox(t,e){const i=t.boxes?t.boxes.indexOf(e):-1;-1!==i&&t.boxes.splice(i,1)},configure(t,e,i){e.fullSize=i.fullSize,e.position=i.position,e.weight=i.weight},update(t,e,i,n){if(!t)return;const o=Fe(t.options.layout.padding),s=Math.max(e-o.width,0),a=Math.max(i-o.height,0),r=function(t){const e=function(t){const e=[];let i,n,o;for(i=0,n=(t||[]).length;i<n;++i)o=t[i],e.push({index:i,box:o,pos:o.position,horizontal:o.isHorizontal(),weight:o.weight});return e}(t),i=$e(e.filter((t=>t.box.fullSize)),!0),n=$e(He(e,"left"),!0),o=$e(He(e,"right")),s=$e(He(e,"top"),!0),a=$e(He(e,"bottom")),r=je(e,"x"),l=je(e,"y");return{fullSize:i,leftAndTop:n.concat(s),rightAndBottom:o.concat(l).concat(a).concat(r),chartArea:He(e,"chartArea"),vertical:n.concat(o).concat(l),horizontal:s.concat(a).concat(r)}}(t.boxes),l=r.vertical,c=r.horizontal;J(t.boxes,(t=>{"function"==typeof t.beforeLayout&&t.beforeLayout()}));const h=l.reduce(((t,e)=>e.box.options&&!1===e.box.options.display?t:t+1),0)||1,d=Object.freeze({outerWidth:e,outerHeight:i,padding:o,availableWidth:s,availableHeight:a,vBoxMaxWidth:s/2/h,hBoxMaxHeight:a/2}),u=Object.assign({},o);Ue(u,Fe(n));const f=Object.assign({maxPadding:u,w:s,h:a,x:o.left,y:o.top},o);!function(t,e){let i,n,o;for(i=0,n=t.length;i<n;++i)o=t[i],o.horizontal?(o.width=o.box.fullSize&&e.availableWidth,o.height=e.hBoxMaxHeight):(o.width=e.vBoxMaxWidth,o.height=o.box.fullSize&&e.availableHeight)}(l.concat(c),d),Ke(r.fullSize,f,d),Ke(l,f,d),Ke(c,f,d)&&Ke(l,f,d),function(t){const e=t.maxPadding;function i(i){const n=Math.max(e[i]-t[i],0);return t[i]+=n,n}t.y+=i("top"),t.x+=i("left"),i("right"),i("bottom")}(f),Ge(r.leftAndTop,f,d),f.x+=f.w,f.y+=f.h,Ge(r.rightAndBottom,f,d),t.chartArea={left:f.left,top:f.top,right:f.left+f.w,bottom:f.top+f.h,height:f.h,width:f.w},J(r.chartArea,(e=>{const i=e.box;Object.assign(i,t.chartArea),i.update(f.w,f.h)}))}};class Qe{acquireContext(t,e){}releaseContext(t){return!1}addEventListener(t,e,i){}removeEventListener(t,e,i){}getDevicePixelRatio(){return 1}getMaximumSize(t,e,i,n){return e=Math.max(0,e||t.width),i=i||t.height,{width:e,height:Math.max(0,n?Math.floor(e/n):i)}}isAttached(t){return!0}}class Je extends Qe{acquireContext(t){return t&&t.getContext&&t.getContext("2d")||null}}const ti={touchstart:"mousedown",touchmove:"mousemove",touchend:"mouseup",pointerenter:"mouseenter",pointerdown:"mousedown",pointermove:"mousemove",pointerup:"mouseup",pointerleave:"mouseout",pointerout:"mouseout"},ei=t=>null===t||""===t;const ii=!!we&&{passive:!0};function ni(t,e,i){t.canvas.removeEventListener(e,i,ii)}function oi(t,e,i){const n=t.canvas,o=n&&ue(n)||n,s=new MutationObserver((t=>{const e=ue(o);t.forEach((t=>{for(let n=0;n<t.addedNodes.length;n++){const s=t.addedNodes[n];s!==o&&s!==e||i(t.target)}}))}));return s.observe(document,{childList:!0,subtree:!0}),s}function si(t,e,i){const n=t.canvas,o=n&&ue(n);if(!o)return;const s=new MutationObserver((t=>{t.forEach((t=>{for(let e=0;e<t.removedNodes.length;e++)if(t.removedNodes[e]===n){i();break}}))}));return s.observe(o,{childList:!0}),s}const ai=new Map;let ri=0;function li(){const t=window.devicePixelRatio;t!==ri&&(ri=t,ai.forEach(((e,i)=>{i.currentDevicePixelRatio!==t&&e()})))}function ci(t,i,n){const o=t.canvas,s=o&&ue(o);if(!s)return;const a=e(((t,e)=>{const i=s.clientWidth;n(t,e),i<s.clientWidth&&n()}),window),r=new ResizeObserver((t=>{const e=t[0],i=e.contentRect.width,n=e.contentRect.height;0===i&&0===n||a(i,n)}));return r.observe(s),function(t,e){ai.size||window.addEventListener("resize",li),ai.set(t,e)}(t,a),r}function hi(t,e,i){i&&i.disconnect(),"resize"===e&&function(t){ai.delete(t),ai.size||window.removeEventListener("resize",li)}(t)}function di(t,i,n){const o=t.canvas,s=e((e=>{null!==t.ctx&&n(function(t,e){const i=ti[t.type]||t.type,{x:n,y:o}=be(t,e);return{type:i,chart:e,native:t,x:void 0!==n?n:null,y:void 0!==o?o:null}}(e,t))}),t,(t=>{const e=t[0];return[e,e.offsetX,e.offsetY]}));return function(t,e,i){t.addEventListener(e,i,ii)}(o,i,s),s}class ui extends Qe{acquireContext(t,e){const i=t&&t.getContext&&t.getContext("2d");return i&&i.canvas===t?(function(t,e){const i=t.style,n=t.getAttribute("height"),o=t.getAttribute("width");if(t.$chartjs={initial:{height:n,width:o,style:{display:i.display,height:i.height,width:i.width}}},i.display=i.display||"block",i.boxSizing=i.boxSizing||"border-box",ei(o)){const e=Me(t,"width");void 0!==e&&(t.width=e)}if(ei(n))if(""===t.style.height)t.height=t.width/(e||2);else{const e=Me(t,"height");void 0!==e&&(t.height=e)}}(t,e),i):null}releaseContext(t){const e=t.canvas;if(!e.$chartjs)return!1;const i=e.$chartjs.initial;["height","width"].forEach((t=>{const n=i[t];$(n)?e.removeAttribute(t):e.setAttribute(t,n)}));const n=i.style||{};return Object.keys(n).forEach((t=>{e.style[t]=n[t]})),e.width=e.width,delete e.$chartjs,!0}addEventListener(t,e,i){this.removeEventListener(t,e);const n=t.$proxies||(t.$proxies={}),o={attach:oi,detach:si,resize:ci}[e]||di;n[e]=o(t,e,i)}removeEventListener(t,e){const i=t.$proxies||(t.$proxies={}),n=i[e];if(!n)return;({attach:hi,detach:hi,resize:hi}[e]||ni)(t,e,n),i[e]=void 0}getDevicePixelRatio(){return window.devicePixelRatio}getMaximumSize(t,e,i,n){return ye(t,e,i,n)}isAttached(t){const e=ue(t);return!(!e||!ue(e))}}var fi=Object.freeze({__proto__:null,BasePlatform:Qe,BasicPlatform:Je,DomPlatform:ui});const gi=t=>0===t||1===t,pi=(t,e,i)=>-Math.pow(2,10*(t-=1))*Math.sin((t-e)*_t/i),mi=(t,e,i)=>Math.pow(2,-10*t)*Math.sin((t-e)*_t/i)+1,xi={linear:t=>t,easeInQuad:t=>t*t,easeOutQuad:t=>-t*(t-2),easeInOutQuad:t=>(t/=.5)<1?.5*t*t:-.5*(--t*(t-2)-1),easeInCubic:t=>t*t*t,easeOutCubic:t=>(t-=1)*t*t+1,easeInOutCubic:t=>(t/=.5)<1?.5*t*t*t:.5*((t-=2)*t*t+2),easeInQuart:t=>t*t*t*t,easeOutQuart:t=>-((t-=1)*t*t*t-1),easeInOutQuart:t=>(t/=.5)<1?.5*t*t*t*t:-.5*((t-=2)*t*t*t-2),easeInQuint:t=>t*t*t*t*t,easeOutQuint:t=>(t-=1)*t*t*t*t+1,easeInOutQuint:t=>(t/=.5)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2),easeInSine:t=>1-Math.cos(t*Mt),easeOutSine:t=>Math.sin(t*Mt),easeInOutSine:t=>-.5*(Math.cos(bt*t)-1),easeInExpo:t=>0===t?0:Math.pow(2,10*(t-1)),easeOutExpo:t=>1===t?1:1-Math.pow(2,-10*t),easeInOutExpo:t=>gi(t)?t:t<.5?.5*Math.pow(2,10*(2*t-1)):.5*(2-Math.pow(2,-10*(2*t-1))),easeInCirc:t=>t>=1?t:-(Math.sqrt(1-t*t)-1),easeOutCirc:t=>Math.sqrt(1-(t-=1)*t),easeInOutCirc:t=>(t/=.5)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1),easeInElastic:t=>gi(t)?t:pi(t,.075,.3),easeOutElastic:t=>gi(t)?t:mi(t,.075,.3),easeInOutElastic(t){const e=.1125;return gi(t)?t:t<.5?.5*pi(2*t,e,.45):.5+.5*mi(2*t-1,e,.45)},easeInBack(t){const e=1.70158;return t*t*((e+1)*t-e)},easeOutBack(t){const e=1.70158;return(t-=1)*t*((e+1)*t+e)+1},easeInOutBack(t){let e=1.70158;return(t/=.5)<1?t*t*((1+(e*=1.525))*t-e)*.5:.5*((t-=2)*t*((1+(e*=1.525))*t+e)+2)},easeInBounce:t=>1-xi.easeOutBounce(1-t),easeOutBounce(t){const e=7.5625,i=2.75;return t<1/i?e*t*t:t<2/i?e*(t-=1.5/i)*t+.75:t<2.5/i?e*(t-=2.25/i)*t+.9375:e*(t-=2.625/i)*t+.984375},easeInOutBounce:t=>t<.5?.5*xi.easeInBounce(2*t):.5*xi.easeOutBounce(2*t-1)+.5},bi="transparent",_i={boolean:(t,e,i)=>i>.5?e:t,color(t,e,i){const n=W(t||bi),o=n.valid&&W(e||bi);return o&&o.valid?o.mix(n,i).hexString():e},number:(t,e,i)=>t+(e-t)*i};class yi{constructor(t,e,i,n){const o=e[i];n=Ve([t.to,n,o,t.from]);const s=Ve([t.from,o,n]);this._active=!0,this._fn=t.fn||_i[t.type||typeof s],this._easing=xi[t.easing]||xi.linear,this._start=Math.floor(Date.now()+(t.delay||0)),this._duration=this._total=Math.floor(t.duration),this._loop=!!t.loop,this._target=e,this._prop=i,this._from=s,this._to=n,this._promises=void 0}active(){return this._active}update(t,e,i){const n=this;if(n._active){n._notify(!1);const o=n._target[n._prop],s=i-n._start,a=n._duration-s;n._start=i,n._duration=Math.floor(Math.max(a,t.duration)),n._total+=s,n._loop=!!t.loop,n._to=Ve([t.to,e,o,t.from]),n._from=Ve([t.from,o,e])}}cancel(){const t=this;t._active&&(t.tick(Date.now()),t._active=!1,t._notify(!1))}tick(t){const e=this,i=t-e._start,n=e._duration,o=e._prop,s=e._from,a=e._loop,r=e._to;let l;if(e._active=s!==r&&(a||i<n),!e._active)return e._target[o]=r,void e._notify(!0);i<0?e._target[o]=s:(l=i/n%2,l=a&&l>1?2-l:l,l=e._easing(Math.min(1,Math.max(0,l))),e._target[o]=e._fn(s,r,l))}wait(){const t=this._promises||(this._promises=[]);return new Promise(((e,i)=>{t.push({res:e,rej:i})}))}_notify(t){const e=t?"res":"rej",i=this._promises||[];for(let t=0;t<i.length;t++)i[t][e]()}}xt.set("animation",{delay:void 0,duration:1e3,easing:"easeOutQuart",fn:void 0,from:void 0,loop:void 0,to:void 0,type:void 0});const vi=Object.keys(xt.animation);xt.describe("animation",{_fallback:!1,_indexable:!1,_scriptable:t=>"onProgress"!==t&&"onComplete"!==t&&"fn"!==t}),xt.set("animations",{colors:{type:"color",properties:["color","borderColor","backgroundColor"]},numbers:{type:"number",properties:["x","y","borderWidth","radius","tension"]}}),xt.describe("animations",{_fallback:"animation"}),xt.set("transitions",{active:{animation:{duration:400}},resize:{animation:{duration:0}},show:{animations:{colors:{from:"transparent"},visible:{type:"boolean",duration:0}}},hide:{animations:{colors:{to:"transparent"},visible:{type:"boolean",easing:"linear",fn:t=>0|t}}}});class wi{constructor(t,e){this._chart=t,this._properties=new Map,this.configure(e)}configure(t){if(!U(t))return;const e=this._properties;Object.getOwnPropertyNames(t).forEach((i=>{const n=t[i];if(!U(n))return;const o={};for(const t of vi)o[t]=n[t];(Y(n.properties)&&n.properties||[i]).forEach((t=>{t!==i&&e.has(t)||e.set(t,o)}))}))}_animateOptions(t,e){const i=e.options,n=function(t,e){if(!e)return;let i=t.options;if(!i)return void(t.options=e);i.$shared&&(t.options=i=Object.assign({},i,{$shared:!1,$animations:{}}));return i}(t,i);if(!n)return[];const o=this._createAnimations(n,i);return i.$shared&&function(t,e){const i=[],n=Object.keys(e);for(let e=0;e<n.length;e++){const o=t[n[e]];o&&o.active()&&i.push(o.wait())}return Promise.all(i)}(t.options.$animations,i).then((()=>{t.options=i}),(()=>{})),o}_createAnimations(t,e){const i=this._properties,n=[],o=t.$animations||(t.$animations={}),s=Object.keys(e),a=Date.now();let r;for(r=s.length-1;r>=0;--r){const l=s[r];if("$"===l.charAt(0))continue;if("options"===l){n.push(...this._animateOptions(t,e));continue}const c=e[l];let h=o[l];const d=i.get(l);if(h){if(d&&h.active()){h.update(d,c,a);continue}h.cancel()}d&&d.duration?(o[l]=h=new yi(d,t,l,c),n.push(h)):t[l]=c}return n}update(t,e){if(0===this._properties.size)return void Object.assign(t,e);const i=this._createAnimations(t,e);return i.length?(a.add(this._chart,i),!0):void 0}}function Mi(t,e){const i=t&&t.options||{},n=i.reverse,o=void 0===i.min?e:0,s=void 0===i.max?e:0;return{start:n?s:o,end:n?o:s}}function ki(t,e){const i=[],n=t._getSortedDatasetMetas(e);let o,s;for(o=0,s=n.length;o<s;++o)i.push(n[o].index);return i}function Si(t,e,i,n){const o=t.keys,s="single"===n.mode;let a,r,l,c;if(null!==e){for(a=0,r=o.length;a<r;++a){if(l=+o[a],l===i){if(n.all)continue;break}c=t.values[l],X(c)&&(s||0===e||Dt(e)===Dt(c))&&(e+=c)}return e}}function Pi(t,e){const i=t&&t.options.stacked;return i||void 0===i&&void 0!==e.stack}function Di(t,e,i){const n=t[e]||(t[e]={});return n[i]||(n[i]={})}function Ci(t,e,i){for(const n of e.getMatchingVisibleMetas("bar").reverse()){const e=t[n.index];if(i&&e>0||!i&&e<0)return n.index}return null}function Oi(t,e){const{chart:i,_cachedMeta:n}=t,o=i._stacks||(i._stacks={}),{iScale:s,vScale:a,index:r}=n,l=s.axis,c=a.axis,h=function(t,e,i){return`${t.id}.${e.id}.${i.stack||i.type}`}(s,a,n),d=e.length;let u;for(let t=0;t<d;++t){const i=e[t],{[l]:n,[c]:s}=i;u=(i._stacks||(i._stacks={}))[c]=Di(o,h,n),u[r]=s,u._top=Ci(u,a,!0),u._bottom=Ci(u,a,!1)}}function Ti(t,e){const i=t.scales;return Object.keys(i).filter((t=>i[t].axis===e)).shift()}function Ai(t,e){const i=t.vScale&&t.vScale.axis;if(i){e=e||t._parsed;for(const n of e){const e=n._stacks;if(!e||void 0===e[i]||void 0===e[i][t.index])return;delete e[i][t.index]}}}const Li=t=>"reset"===t||"none"===t,Ri=(t,e)=>e?t:Object.assign({},t);class Ei{constructor(t,e){this.chart=t,this._ctx=t.ctx,this.index=e,this._cachedDataOpts={},this._cachedMeta=this.getMeta(),this._type=this._cachedMeta.type,this.options=void 0,this._parsing=!1,this._data=void 0,this._objectData=void 0,this._sharedOptions=void 0,this._drawStart=void 0,this._drawCount=void 0,this.enableOptionSharing=!1,this.$context=void 0,this._syncList=[],this.initialize()}initialize(){const t=this,e=t._cachedMeta;t.configure(),t.linkScales(),e._stacked=Pi(e.vScale,e),t.addElements()}updateIndex(t){this.index!==t&&Ai(this._cachedMeta),this.index=t}linkScales(){const t=this,e=t.chart,i=t._cachedMeta,n=t.getDataset(),o=(t,e,i,n)=>"x"===t?e:"r"===t?n:i,s=i.xAxisID=K(n.xAxisID,Ti(e,"x")),a=i.yAxisID=K(n.yAxisID,Ti(e,"y")),r=i.rAxisID=K(n.rAxisID,Ti(e,"r")),l=i.indexAxis,c=i.iAxisID=o(l,s,a,r),h=i.vAxisID=o(l,a,s,r);i.xScale=t.getScaleForId(s),i.yScale=t.getScaleForId(a),i.rScale=t.getScaleForId(r),i.iScale=t.getScaleForId(c),i.vScale=t.getScaleForId(h)}getDataset(){return this.chart.data.datasets[this.index]}getMeta(){return this.chart.getDatasetMeta(this.index)}getScaleForId(t){return this.chart.scales[t]}_getOtherScale(t){const e=this._cachedMeta;return t===e.iScale?e.vScale:e.iScale}reset(){this._update("reset")}_destroy(){const t=this._cachedMeta;this._data&&he(this._data,this),t._stacked&&Ai(t)}_dataCheck(){const t=this,e=t.getDataset(),i=e.data||(e.data=[]),n=t._data;if(U(i))t._data=function(t){const e=Object.keys(t),i=new Array(e.length);let n,o,s;for(n=0,o=e.length;n<o;++n)s=e[n],i[n]={x:s,y:t[s]};return i}(i);else if(n!==i){if(n){he(n,t);const e=t._cachedMeta;Ai(e),e._parsed=[]}i&&Object.isExtensible(i)&&ce(i,t),t._syncList=[],t._data=i}}addElements(){const t=this,e=t._cachedMeta;t._dataCheck(),t.datasetElementType&&(e.dataset=new t.datasetElementType)}buildOrUpdateElements(t){const e=this,i=e._cachedMeta,n=e.getDataset();let o=!1;e._dataCheck();const s=i._stacked;i._stacked=Pi(i.vScale,i),i.stack!==n.stack&&(o=!0,Ai(i),i.stack=n.stack),e._resyncElements(t),(o||s!==i._stacked)&&Oi(e,i._parsed)}configure(){const t=this,e=t.chart.config,i=e.datasetScopeKeys(t._type),n=e.getOptionScopes(t.getDataset(),i,!0);t.options=e.createResolver(n,t.getContext()),t._parsing=t.options.parsing}parse(t,e){const i=this,{_cachedMeta:n,_data:o}=i,{iScale:s,_stacked:a}=n,r=s.axis;let l,c,h,d=0===t&&e===o.length||n._sorted,u=t>0&&n._parsed[t-1];if(!1===i._parsing)n._parsed=o,n._sorted=!0,h=o;else{h=Y(o[t])?i.parseArrayData(n,o,t,e):U(o[t])?i.parseObjectData(n,o,t,e):i.parsePrimitiveData(n,o,t,e);const s=()=>null===c[r]||u&&c[r]<u[r];for(l=0;l<e;++l)n._parsed[l+t]=c=h[l],d&&(s()&&(d=!1),u=c);n._sorted=d}a&&Oi(i,h)}parsePrimitiveData(t,e,i,n){const{iScale:o,vScale:s}=t,a=o.axis,r=s.axis,l=o.getLabels(),c=o===s,h=new Array(n);let d,u,f;for(d=0,u=n;d<u;++d)f=d+i,h[d]={[a]:c||o.parse(l[f],f),[r]:s.parse(e[f],f)};return h}parseArrayData(t,e,i,n){const{xScale:o,yScale:s}=t,a=new Array(n);let r,l,c,h;for(r=0,l=n;r<l;++r)c=r+i,h=e[c],a[r]={x:o.parse(h[0],c),y:s.parse(h[1],c)};return a}parseObjectData(t,e,i,n){const{xScale:o,yScale:s}=t,{xAxisKey:a="x",yAxisKey:r="y"}=this._parsing,l=new Array(n);let c,h,d,u;for(c=0,h=n;c<h;++c)d=c+i,u=e[d],l[c]={x:o.parse(lt(u,a),d),y:s.parse(lt(u,r),d)};return l}getParsed(t){return this._cachedMeta._parsed[t]}getDataElement(t){return this._cachedMeta.data[t]}applyStack(t,e,i){const n=this.chart,o=this._cachedMeta,s=e[t.axis];return Si({keys:ki(n,!0),values:e._stacks[t.axis]},s,o.index,{mode:i})}updateRangeFromParsed(t,e,i,n){const o=i[e.axis];let s=null===o?NaN:o;const a=n&&i._stacks[e.axis];n&&a&&(n.values=a,t.min=Math.min(t.min,s),t.max=Math.max(t.max,s),s=Si(n,o,this._cachedMeta.index,{all:!0})),t.min=Math.min(t.min,s),t.max=Math.max(t.max,s)}getMinMax(t,e){const i=this,n=i._cachedMeta,o=n._parsed,s=n._sorted&&t===n.iScale,a=o.length,r=i._getOtherScale(t),l=e&&n._stacked&&{keys:ki(i.chart,!0),values:null},c={min:Number.POSITIVE_INFINITY,max:Number.NEGATIVE_INFINITY},{min:h,max:d}=function(t){const{min:e,max:i,minDefined:n,maxDefined:o}=t.getUserBounds();return{min:n?e:Number.NEGATIVE_INFINITY,max:o?i:Number.POSITIVE_INFINITY}}(r);let u,f,g,p;function m(){return g=o[u],f=g[t.axis],p=g[r.axis],!X(f)||h>p||d<p}for(u=0;u<a&&(m()||(i.updateRangeFromParsed(c,t,g,l),!s));++u);if(s)for(u=a-1;u>=0;--u)if(!m()){i.updateRangeFromParsed(c,t,g,l);break}return c}getAllParsedValues(t){const e=this._cachedMeta._parsed,i=[];let n,o,s;for(n=0,o=e.length;n<o;++n)s=e[n][t.axis],X(s)&&i.push(s);return i}getMaxOverflow(){return!1}getLabelAndValue(t){const e=this._cachedMeta,i=e.iScale,n=e.vScale,o=this.getParsed(t);return{label:i?""+i.getLabelForValue(o[i.axis]):"",value:n?""+n.getLabelForValue(o[n.axis]):""}}_update(t){const e=this,i=e._cachedMeta;e.configure(),e._cachedDataOpts={},e.update(t||"default"),i._clip=function(t){let e,i,n,o;return U(t)?(e=t.top,i=t.right,n=t.bottom,o=t.left):e=i=n=o=t,{top:e,right:i,bottom:n,left:o,disabled:!1===t}}(K(e.options.clip,function(t,e,i){if(!1===i)return!1;const n=Mi(t,i),o=Mi(e,i);return{top:o.end,right:n.end,bottom:o.start,left:n.start}}(i.xScale,i.yScale,e.getMaxOverflow())))}update(t){}draw(){const t=this,e=t._ctx,i=t.chart,n=t._cachedMeta,o=n.data||[],s=i.chartArea,a=[],r=t._drawStart||0,l=t._drawCount||o.length-r;let c;for(n.dataset&&n.dataset.draw(e,s,r,l),c=r;c<r+l;++c){const t=o[c];t.active?a.push(t):t.draw(e,s)}for(c=0;c<a.length;++c)a[c].draw(e,s)}getStyle(t,e){const i=e?"active":"default";return void 0===t&&this._cachedMeta.dataset?this.resolveDatasetElementOptions(i):this.resolveDataElementOptions(t||0,i)}getContext(t,e,i){const n=this,o=n.getDataset();let s;if(t>=0&&t<n._cachedMeta.data.length){const e=n._cachedMeta.data[t];s=e.$context||(e.$context=function(t,e,i){return Object.assign(Object.create(t),{active:!1,dataIndex:e,parsed:void 0,raw:void 0,element:i,index:e,mode:"default",type:"data"})}(n.getContext(),t,e)),s.parsed=n.getParsed(t),s.raw=o.data[t],s.index=s.dataIndex=t}else s=n.$context||(n.$context=function(t,e){return Object.assign(Object.create(t),{active:!1,dataset:void 0,datasetIndex:e,index:e,mode:"default",type:"dataset"})}(n.chart.getContext(),n.index)),s.dataset=o,s.index=s.datasetIndex=n.index;return s.active=!!e,s.mode=i,s}resolveDatasetElementOptions(t){return this._resolveElementOptions(this.datasetElementType.id,t)}resolveDataElementOptions(t,e){return this._resolveElementOptions(this.dataElementType.id,e,t)}_resolveElementOptions(t,e="default",i){const n=this,o="active"===e,s=n._cachedDataOpts,a=t+"-"+e,r=s[a],l=n.enableOptionSharing&&ht(i);if(r)return Ri(r,l);const c=n.chart.config,h=c.datasetElementScopeKeys(n._type,t),d=o?[`${t}Hover`,"hover",t,""]:[t,""],u=c.getOptionScopes(n.getDataset(),h),f=Object.keys(xt.elements[t]),g=c.resolveNamedOptions(u,f,(()=>n.getContext(i,o)),d);return g.$shared&&(g.$shared=l,s[a]=Object.freeze(Ri(g,l))),g}_resolveAnimations(t,e,i){const n=this,o=n.chart,s=n._cachedDataOpts,a=`animation-${e}`,r=s[a];if(r)return r;let l;if(!1!==o.options.animation){const o=n.chart.config,s=o.datasetAnimationScopeKeys(n._type,e),a=o.getOptionScopes(n.getDataset(),s);l=o.createResolver(a,n.getContext(t,i,e))}const c=new wi(o,l&&l.animations);return l&&l._cacheable&&(s[a]=Object.freeze(c)),c}getSharedOptions(t){if(t.$shared)return this._sharedOptions||(this._sharedOptions=Object.assign({},t))}includeOptions(t,e){return!e||Li(t)||this.chart._animationsDisabled}updateElement(t,e,i,n){Li(n)?Object.assign(t,i):this._resolveAnimations(e,n).update(t,i)}updateSharedOptions(t,e,i){t&&!Li(e)&&this._resolveAnimations(void 0,e).update(t,i)}_setStyle(t,e,i,n){t.active=n;const o=this.getStyle(e,n);this._resolveAnimations(e,i,n).update(t,{options:!n&&this.getSharedOptions(o)||o})}removeHoverStyle(t,e,i){this._setStyle(t,i,"active",!1)}setHoverStyle(t,e,i){this._setStyle(t,i,"active",!0)}_removeDatasetHoverStyle(){const t=this._cachedMeta.dataset;t&&this._setStyle(t,void 0,"active",!1)}_setDatasetHoverStyle(){const t=this._cachedMeta.dataset;t&&this._setStyle(t,void 0,"active",!0)}_resyncElements(t){const e=this,i=e._data,n=e._cachedMeta.data;for(const[t,i,n]of e._syncList)e[t](i,n);e._syncList=[];const o=n.length,s=i.length,a=Math.min(s,o);a&&e.parse(0,a),s>o?e._insertElements(o,s-o,t):s<o&&e._removeElements(s,o-s)}_insertElements(t,e,i=!0){const n=this,o=n._cachedMeta,s=o.data,a=t+e;let r;const l=t=>{for(t.length+=e,r=t.length-1;r>=a;r--)t[r]=t[r-e]};for(l(s),r=t;r<a;++r)s[r]=new n.dataElementType;n._parsing&&l(o._parsed),n.parse(t,e),i&&n.updateElements(s,t,e,"reset")}updateElements(t,e,i,n){}_removeElements(t,e){const i=this._cachedMeta;if(this._parsing){const n=i._parsed.splice(t,e);i._stacked&&Ai(i,n)}i.data.splice(t,e)}_onDataPush(){const t=arguments.length;this._syncList.push(["_insertElements",this.getDataset().data.length-t,t])}_onDataPop(){this._syncList.push(["_removeElements",this._cachedMeta.data.length-1,1])}_onDataShift(){this._syncList.push(["_removeElements",0,1])}_onDataSplice(t,e){this._syncList.push(["_removeElements",t,e]),this._syncList.push(["_insertElements",t,arguments.length-2])}_onDataUnshift(){this._syncList.push(["_insertElements",0,arguments.length])}}Ei.defaults={},Ei.prototype.datasetElementType=null,Ei.prototype.dataElementType=null;class zi{constructor(){this.x=void 0,this.y=void 0,this.active=!1,this.options=void 0,this.$animations=void 0}tooltipPosition(t){const{x:e,y:i}=this.getProps(["x","y"],t);return{x:e,y:i}}hasValue(){return Tt(this.x)&&Tt(this.y)}getProps(t,e){const i=this,n=this.$animations;if(!e||!n)return i;const o={};return t.forEach((t=>{o[t]=n[t]&&n[t].active()?n[t]._to:i[t]})),o}}zi.defaults={},zi.defaultRoutes=void 0;const Ii=new Map;function Fi(t,e,i){return function(t,e){e=e||{};const i=t+JSON.stringify(e);let n=Ii.get(i);return n||(n=new Intl.NumberFormat(t,e),Ii.set(i,n)),n}(e,i).format(t)}const Bi={values:t=>Y(t)?t:""+t,numeric(t,e,i){if(0===t)return"0";const n=this.chart.options.locale;let o,s=t;if(i.length>1){const e=Math.max(Math.abs(i[0].value),Math.abs(i[i.length-1].value));(e<1e-4||e>1e15)&&(o="scientific"),s=function(t,e){let i=e.length>3?e[2].value-e[1].value:e[1].value-e[0].value;Math.abs(i)>=1&&t!==Math.floor(t)&&(i=t-Math.floor(t));return i}(t,i)}const a=Pt(Math.abs(s)),r=Math.max(Math.min(-1*Math.floor(a),20),0),l={notation:o,minimumFractionDigits:r,maximumFractionDigits:r};return Object.assign(l,this.options.ticks.format),Fi(t,n,l)},logarithmic(t,e,i){if(0===t)return"0";const n=t/Math.pow(10,Math.floor(Pt(t)));return 1===n||2===n||5===n?Bi.numeric.call(this,t,e,i):""}};var Vi={formatters:Bi};function Wi(t,e){const i=t.options.ticks,n=i.maxTicksLimit||function(t){const e=t.options.offset,i=t._tickSize(),n=t._length/i+(e?0:1),o=t._maxLength/i;return Math.floor(Math.min(n,o))}(t),o=i.major.enabled?function(t){const e=[];let i,n;for(i=0,n=t.length;i<n;i++)t[i].major&&e.push(i);return e}(e):[],s=o.length,a=o[0],r=o[s-1],l=[];if(s>n)return function(t,e,i,n){let o,s=0,a=i[0];for(n=Math.ceil(n),o=0;o<t.length;o++)o===a&&(e.push(t[o]),s++,a=i[s*n])}(e,l,o,s/n),l;const c=function(t,e,i){const n=function(t){const e=t.length;let i,n;if(e<2)return!1;for(n=t[0],i=1;i<e;++i)if(t[i]-t[i-1]!==n)return!1;return n}(t),o=e.length/i;if(!n)return Math.max(o,1);const s=Ot(n);for(let t=0,e=s.length-1;t<e;t++){const e=s[t];if(e>o)return e}return Math.max(o,1)}(o,e,n);if(s>0){let t,i;const n=s>1?Math.round((r-a)/(s-1)):null;for(Ni(e,l,c,$(n)?0:a-n,a),t=0,i=s-1;t<i;t++)Ni(e,l,c,o[t],o[t+1]);return Ni(e,l,c,r,$(n)?e.length:r+n),l}return Ni(e,l,c),l}function Ni(t,e,i,n,o){const s=K(n,0),a=Math.min(K(o,t.length),t.length);let r,l,c,h=0;for(i=Math.ceil(i),o&&(r=o-n,i=r/Math.floor(r/i)),c=s;c<0;)h++,c=Math.round(s+h*i);for(l=Math.max(s,0);l<a;l++)l===c&&(e.push(t[l]),h++,c=Math.round(s+h*i))}xt.set("scale",{display:!0,offset:!1,reverse:!1,beginAtZero:!1,bounds:"ticks",grace:0,grid:{display:!0,lineWidth:1,drawBorder:!0,drawOnChartArea:!0,drawTicks:!0,tickLength:8,tickWidth:(t,e)=>e.lineWidth,tickColor:(t,e)=>e.color,offset:!1,borderDash:[],borderDashOffset:0,borderWidth:1},title:{display:!1,text:"",padding:{top:4,bottom:4}},ticks:{minRotation:0,maxRotation:50,mirror:!1,textStrokeWidth:0,textStrokeColor:"",padding:3,display:!0,autoSkip:!0,autoSkipPadding:3,labelOffset:0,callback:Vi.formatters.values,minor:{},major:{},align:"center",crossAlign:"near",showLabelBackdrop:!1,backdropColor:"rgba(255, 255, 255, 0.75)",backdropPadding:2}}),xt.route("scale.ticks","color","","color"),xt.route("scale.grid","color","","borderColor"),xt.route("scale.grid","borderColor","","borderColor"),xt.route("scale.title","color","","color"),xt.describe("scale",{_fallback:!1,_scriptable:t=>!t.startsWith("before")&&!t.startsWith("after")&&"callback"!==t&&"parser"!==t,_indexable:t=>"borderDash"!==t&&"tickBorderDash"!==t}),xt.describe("scales",{_fallback:"scale"}),xt.describe("scale.ticks",{_scriptable:t=>"backdropPadding"!==t&&"callback"!==t,_indexable:t=>"backdropPadding"!==t});const Hi=(t,e,i)=>"top"===e||"left"===e?t[e]+i:t[e]-i;function ji(t,e){const i=[],n=t.length/e,o=t.length;let s=0;for(;s<o;s+=n)i.push(t[Math.floor(s)]);return i}function $i(t,e,i){const n=t.ticks.length,o=Math.min(e,n-1),s=t._startPixel,a=t._endPixel,r=1e-6;let l,c=t.getPixelForTick(o);if(!(i&&(l=1===n?Math.max(c-s,a-c):0===e?(t.getPixelForTick(1)-c)/2:(c-t.getPixelForTick(o-1))/2,c+=o<e?l:-l,c<s-r||c>a+r)))return c}function Yi(t){return t.drawTicks?t.tickLength:0}function Ui(t,e){if(!t.display)return 0;const i=Be(t.font,e),n=Fe(t.padding);return(Y(t.text)?t.text.length:1)*i.lineHeight+n.height}function Xi(t,e,i){let o=n(t);return(i&&"right"!==e||!i&&"right"===e)&&(o=(t=>"left"===t?"right":"right"===t?"left":t)(o)),o}class qi extends zi{constructor(t){super(),this.id=t.id,this.type=t.type,this.options=void 0,this.ctx=t.ctx,this.chart=t.chart,this.top=void 0,this.bottom=void 0,this.left=void 0,this.right=void 0,this.width=void 0,this.height=void 0,this._margins={left:0,right:0,top:0,bottom:0},this.maxWidth=void 0,this.maxHeight=void 0,this.paddingTop=void 0,this.paddingBottom=void 0,this.paddingLeft=void 0,this.paddingRight=void 0,this.axis=void 0,this.labelRotation=void 0,this.min=void 0,this.max=void 0,this._range=void 0,this.ticks=[],this._gridLineItems=null,this._labelItems=null,this._labelSizes=null,this._length=0,this._maxLength=0,this._longestTextCache={},this._startPixel=void 0,this._endPixel=void 0,this._reversePixels=!1,this._userMax=void 0,this._userMin=void 0,this._suggestedMax=void 0,this._suggestedMin=void 0,this._ticksLength=0,this._borderValue=0,this._cache={},this._dataLimitsCached=!1,this.$context=void 0}init(t){const e=this;e.options=t.setContext(e.getContext()),e.axis=t.axis,e._userMin=e.parse(t.min),e._userMax=e.parse(t.max),e._suggestedMin=e.parse(t.suggestedMin),e._suggestedMax=e.parse(t.suggestedMax)}parse(t,e){return t}getUserBounds(){let{_userMin:t,_userMax:e,_suggestedMin:i,_suggestedMax:n}=this;return t=q(t,Number.POSITIVE_INFINITY),e=q(e,Number.NEGATIVE_INFINITY),i=q(i,Number.POSITIVE_INFINITY),n=q(n,Number.NEGATIVE_INFINITY),{min:q(t,i),max:q(e,n),minDefined:X(t),maxDefined:X(e)}}getMinMax(t){const e=this;let i,{min:n,max:o,minDefined:s,maxDefined:a}=e.getUserBounds();if(s&&a)return{min:n,max:o};const r=e.getMatchingVisibleMetas();for(let l=0,c=r.length;l<c;++l)i=r[l].controller.getMinMax(e,t),s||(n=Math.min(n,i.min)),a||(o=Math.max(o,i.max));return{min:q(n,q(o,n)),max:q(o,q(n,o))}}getPadding(){const t=this;return{left:t.paddingLeft||0,top:t.paddingTop||0,right:t.paddingRight||0,bottom:t.paddingBottom||0}}getTicks(){return this.ticks}getLabels(){const t=this.chart.data;return this.options.labels||(this.isHorizontal()?t.xLabels:t.yLabels)||t.labels||[]}beforeLayout(){this._cache={},this._dataLimitsCached=!1}beforeUpdate(){Q(this.options.beforeUpdate,[this])}update(t,e,i){const n=this,o=n.options.ticks,s=o.sampleSize;n.beforeUpdate(),n.maxWidth=t,n.maxHeight=e,n._margins=i=Object.assign({left:0,right:0,top:0,bottom:0},i),n.ticks=null,n._labelSizes=null,n._gridLineItems=null,n._labelItems=null,n.beforeSetDimensions(),n.setDimensions(),n.afterSetDimensions(),n._maxLength=n.isHorizontal()?n.width+i.left+i.right:n.height+i.top+i.bottom,n._dataLimitsCached||(n.beforeDataLimits(),n.determineDataLimits(),n.afterDataLimits(),n._range=We(n,n.options.grace),n._dataLimitsCached=!0),n.beforeBuildTicks(),n.ticks=n.buildTicks()||[],n.afterBuildTicks();const a=s<n.ticks.length;n._convertTicksToLabels(a?ji(n.ticks,s):n.ticks),n.configure(),n.beforeCalculateLabelRotation(),n.calculateLabelRotation(),n.afterCalculateLabelRotation(),o.display&&(o.autoSkip||"auto"===o.source)&&(n.ticks=Wi(n,n.ticks),n._labelSizes=null),a&&n._convertTicksToLabels(n.ticks),n.beforeFit(),n.fit(),n.afterFit(),n.afterUpdate()}configure(){const t=this;let e,i,n=t.options.reverse;t.isHorizontal()?(e=t.left,i=t.right):(e=t.top,i=t.bottom,n=!n),t._startPixel=e,t._endPixel=i,t._reversePixels=n,t._length=i-e,t._alignToPixels=t.options.alignToPixels}afterUpdate(){Q(this.options.afterUpdate,[this])}beforeSetDimensions(){Q(this.options.beforeSetDimensions,[this])}setDimensions(){const t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0}afterSetDimensions(){Q(this.options.afterSetDimensions,[this])}_callHooks(t){const e=this;e.chart.notifyPlugins(t,e.getContext()),Q(e.options[t],[e])}beforeDataLimits(){this._callHooks("beforeDataLimits")}determineDataLimits(){}afterDataLimits(){this._callHooks("afterDataLimits")}beforeBuildTicks(){this._callHooks("beforeBuildTicks")}buildTicks(){return[]}afterBuildTicks(){this._callHooks("afterBuildTicks")}beforeTickToLabelConversion(){Q(this.options.beforeTickToLabelConversion,[this])}generateTickLabels(t){const e=this,i=e.options.ticks;let n,o,s;for(n=0,o=t.length;n<o;n++)s=t[n],s.label=Q(i.callback,[s.value,n,t],e)}afterTickToLabelConversion(){Q(this.options.afterTickToLabelConversion,[this])}beforeCalculateLabelRotation(){Q(this.options.beforeCalculateLabelRotation,[this])}calculateLabelRotation(){const t=this,e=t.options,i=e.ticks,n=t.ticks.length,o=i.minRotation||0,s=i.maxRotation;let a,r,l,c=o;if(!t._isVisible()||!i.display||o>=s||n<=1||!t.isHorizontal())return void(t.labelRotation=o);const h=t._getLabelSizes(),d=h.widest.width,u=h.highest.height,f=Ht(t.chart.width-d,0,t.maxWidth);a=e.offset?t.maxWidth/n:f/(n-1),d+6>a&&(a=f/(n-(e.offset?.5:1)),r=t.maxHeight-Yi(e.grid)-i.padding-Ui(e.title,t.chart.options.font),l=Math.sqrt(d*d+u*u),c=zt(Math.min(Math.asin(Math.min((h.highest.height+6)/a,1)),Math.asin(Math.min(r/l,1))-Math.asin(u/l))),c=Math.max(o,Math.min(s,c))),t.labelRotation=c}afterCalculateLabelRotation(){Q(this.options.afterCalculateLabelRotation,[this])}beforeFit(){Q(this.options.beforeFit,[this])}fit(){const t=this,e={width:0,height:0},{chart:i,options:{ticks:n,title:o,grid:s}}=t,a=t._isVisible(),r=t.isHorizontal();if(a){const a=Ui(o,i.options.font);if(r?(e.width=t.maxWidth,e.height=Yi(s)+a):(e.height=t.maxHeight,e.width=Yi(s)+a),n.display&&t.ticks.length){const{first:i,last:o,widest:s,highest:a}=t._getLabelSizes(),l=2*n.padding,c=Et(t.labelRotation),h=Math.cos(c),d=Math.sin(c);if(r){const i=n.mirror?0:d*s.width+h*a.height;e.height=Math.min(t.maxHeight,e.height+i+l)}else{const i=n.mirror?0:h*s.width+d*a.height;e.width=Math.min(t.maxWidth,e.width+i+l)}t._calculatePadding(i,o,d,h)}}t._handleMargins(),r?(t.width=t._length=i.width-t._margins.left-t._margins.right,t.height=e.height):(t.width=e.width,t.height=t._length=i.height-t._margins.top-t._margins.bottom)}_calculatePadding(t,e,i,n){const o=this,{ticks:{align:s,padding:a},position:r}=o.options,l=0!==o.labelRotation,c="top"!==r&&"x"===o.axis;if(o.isHorizontal()){const r=o.getPixelForTick(0)-o.left,h=o.right-o.getPixelForTick(o.ticks.length-1);let d=0,u=0;l?c?(d=n*t.width,u=i*e.height):(d=i*t.height,u=n*e.width):"start"===s?u=e.width:"end"===s?d=t.width:(d=t.width/2,u=e.width/2),o.paddingLeft=Math.max((d-r+a)*o.width/(o.width-r),0),o.paddingRight=Math.max((u-h+a)*o.width/(o.width-h),0)}else{let i=e.height/2,n=t.height/2;"start"===s?(i=0,n=t.height):"end"===s&&(i=e.height,n=0),o.paddingTop=i+a,o.paddingBottom=n+a}}_handleMargins(){const t=this;t._margins&&(t._margins.left=Math.max(t.paddingLeft,t._margins.left),t._margins.top=Math.max(t.paddingTop,t._margins.top),t._margins.right=Math.max(t.paddingRight,t._margins.right),t._margins.bottom=Math.max(t.paddingBottom,t._margins.bottom))}afterFit(){Q(this.options.afterFit,[this])}isHorizontal(){const{axis:t,position:e}=this.options;return"top"===e||"bottom"===e||"x"===t}isFullSize(){return this.options.fullSize}_convertTicksToLabels(t){const e=this;let i,n;for(e.beforeTickToLabelConversion(),e.generateTickLabels(t),i=0,n=t.length;i<n;i++)$(t[i].label)&&(t.splice(i,1),n--,i--);e.afterTickToLabelConversion()}_getLabelSizes(){const t=this;let e=t._labelSizes;if(!e){const i=t.options.ticks.sampleSize;let n=t.ticks;i<n.length&&(n=ji(n,i)),t._labelSizes=e=t._computeLabelSizes(n,n.length)}return e}_computeLabelSizes(t,e){const{ctx:i,_longestTextCache:n}=this,o=[],s=[];let a,r,l,c,h,d,u,f,g,p,m,x=0,b=0;for(a=0;a<e;++a){if(c=t[a].label,h=this._resolveTickFontOptions(a),i.font=d=h.string,u=n[d]=n[d]||{data:{},gc:[]},f=h.lineHeight,g=p=0,$(c)||Y(c)){if(Y(c))for(r=0,l=c.length;r<l;++r)m=c[r],$(m)||Y(m)||(g=Yt(i,u.data,u.gc,g,m),p+=f)}else g=Yt(i,u.data,u.gc,g,c),p=f;o.push(g),s.push(p),x=Math.max(g,x),b=Math.max(p,b)}!function(t,e){J(t,(t=>{const i=t.gc,n=i.length/2;let o;if(n>e){for(o=0;o<n;++o)delete t.data[i[o]];i.splice(0,n)}}))}(n,e);const _=o.indexOf(x),y=s.indexOf(b),v=t=>({width:o[t]||0,height:s[t]||0});return{first:v(0),last:v(e-1),widest:v(_),highest:v(y),widths:o,heights:s}}getLabelForValue(t){return t}getPixelForValue(t,e){return NaN}getValueForPixel(t){}getPixelForTick(t){const e=this.ticks;return t<0||t>e.length-1?null:this.getPixelForValue(e[t].value)}getPixelForDecimal(t){const e=this;e._reversePixels&&(t=1-t);const i=e._startPixel+t*e._length;return jt(e._alignToPixels?Xt(e.chart,i,0):i)}getDecimalForPixel(t){const e=(t-this._startPixel)/this._length;return this._reversePixels?1-e:e}getBasePixel(){return this.getPixelForValue(this.getBaseValue())}getBaseValue(){const{min:t,max:e}=this;return t<0&&e<0?e:t>0&&e>0?t:0}getContext(t){const e=this,i=e.ticks||[];if(t>=0&&t<i.length){const n=i[t];return n.$context||(n.$context=function(t,e,i){return Object.assign(Object.create(t),{tick:i,index:e,type:"tick"})}(e.getContext(),t,n))}return e.$context||(e.$context=(n=e.chart.getContext(),o=e,Object.assign(Object.create(n),{scale:o,type:"scale"})));var n,o}_tickSize(){const t=this,e=t.options.ticks,i=Et(t.labelRotation),n=Math.abs(Math.cos(i)),o=Math.abs(Math.sin(i)),s=t._getLabelSizes(),a=e.autoSkipPadding||0,r=s?s.widest.width+a:0,l=s?s.highest.height+a:0;return t.isHorizontal()?l*n>r*o?r/n:l/o:l*o<r*n?l/n:r/o}_isVisible(){const t=this.options.display;return"auto"!==t?!!t:this.getMatchingVisibleMetas().length>0}_computeGridLineItems(t){const e=this,i=e.axis,n=e.chart,o=e.options,{grid:s,position:a}=o,r=s.offset,l=e.isHorizontal(),c=e.ticks.length+(r?1:0),h=Yi(s),d=[],u=s.setContext(e.getContext()),f=u.drawBorder?u.borderWidth:0,g=f/2,p=function(t){return Xt(n,t,f)};let m,x,b,_,y,v,w,M,k,S,P,D;if("top"===a)m=p(e.bottom),v=e.bottom-h,M=m-g,S=p(t.top)+g,D=t.bottom;else if("bottom"===a)m=p(e.top),S=t.top,D=p(t.bottom)-g,v=m+g,M=e.top+h;else if("left"===a)m=p(e.right),y=e.right-h,w=m-g,k=p(t.left)+g,P=t.right;else if("right"===a)m=p(e.left),k=t.left,P=p(t.right)-g,y=m+g,w=e.left+h;else if("x"===i){if("center"===a)m=p((t.top+t.bottom)/2+.5);else if(U(a)){const t=Object.keys(a)[0],i=a[t];m=p(e.chart.scales[t].getPixelForValue(i))}S=t.top,D=t.bottom,v=m+g,M=v+h}else if("y"===i){if("center"===a)m=p((t.left+t.right)/2);else if(U(a)){const t=Object.keys(a)[0],i=a[t];m=p(e.chart.scales[t].getPixelForValue(i))}y=m-g,w=y-h,k=t.left,P=t.right}const C=K(o.ticks.maxTicksLimit,c),O=Math.max(1,Math.ceil(c/C));for(x=0;x<c;x+=O){const t=s.setContext(e.getContext(x)),i=t.lineWidth,o=t.color,a=s.borderDash||[],c=t.borderDashOffset,h=t.tickWidth,u=t.tickColor,f=t.tickBorderDash||[],g=t.tickBorderDashOffset;b=$i(e,x,r),void 0!==b&&(_=Xt(n,b,i),l?y=w=k=P=_:v=M=S=D=_,d.push({tx1:y,ty1:v,tx2:w,ty2:M,x1:k,y1:S,x2:P,y2:D,width:i,color:o,borderDash:a,borderDashOffset:c,tickWidth:h,tickColor:u,tickBorderDash:f,tickBorderDashOffset:g}))}return e._ticksLength=c,e._borderValue=m,d}_computeLabelItems(t){const e=this,i=e.axis,n=e.options,{position:o,ticks:s}=n,a=e.isHorizontal(),r=e.ticks,{align:l,crossAlign:c,padding:h,mirror:d}=s,u=Yi(n.grid),f=u+h,g=d?-h:f,p=-Et(e.labelRotation),m=[];let x,b,_,y,v,w,M,k,S,P,D,C,O="middle";if("top"===o)w=e.bottom-g,M=e._getXAxisLabelAlignment();else if("bottom"===o)w=e.top+g,M=e._getXAxisLabelAlignment();else if("left"===o){const t=e._getYAxisLabelAlignment(u);M=t.textAlign,v=t.x}else if("right"===o){const t=e._getYAxisLabelAlignment(u);M=t.textAlign,v=t.x}else if("x"===i){if("center"===o)w=(t.top+t.bottom)/2+f;else if(U(o)){const t=Object.keys(o)[0],i=o[t];w=e.chart.scales[t].getPixelForValue(i)+f}M=e._getXAxisLabelAlignment()}else if("y"===i){if("center"===o)v=(t.left+t.right)/2-f;else if(U(o)){const t=Object.keys(o)[0],i=o[t];v=e.chart.scales[t].getPixelForValue(i)}M=e._getYAxisLabelAlignment(u).textAlign}"y"===i&&("start"===l?O="top":"end"===l&&(O="bottom"));const T=e._getLabelSizes();for(x=0,b=r.length;x<b;++x){_=r[x],y=_.label;const t=s.setContext(e.getContext(x));k=e.getPixelForTick(x)+s.labelOffset,S=e._resolveTickFontOptions(x),P=S.lineHeight,D=Y(y)?y.length:1;const i=D/2,n=t.color,l=t.textStrokeColor,h=t.textStrokeWidth;let u;if(a?(v=k,C="top"===o?"near"===c||0!==p?-D*P+P/2:"center"===c?-T.highest.height/2-i*P+P:-T.highest.height+P/2:"near"===c||0!==p?P/2:"center"===c?T.highest.height/2-i*P:T.highest.height-D*P,d&&(C*=-1)):(w=k,C=(1-D)*P/2),t.showLabelBackdrop){const e=Fe(t.backdropPadding),i=T.heights[x],n=T.widths[x];let o=w+C-e.top,s=v-e.left;switch(O){case"middle":o-=i/2;break;case"bottom":o-=i}switch(M){case"center":s-=n/2;break;case"right":s-=n}u={left:s,top:o,width:n+e.width,height:i+e.height,color:t.backdropColor}}m.push({rotation:p,label:y,font:S,color:n,strokeColor:l,strokeWidth:h,textOffset:C,textAlign:M,textBaseline:O,translation:[v,w],backdrop:u})}return m}_getXAxisLabelAlignment(){const{position:t,ticks:e}=this.options;if(-Et(this.labelRotation))return"top"===t?"left":"right";let i="center";return"start"===e.align?i="left":"end"===e.align&&(i="right"),i}_getYAxisLabelAlignment(t){const e=this,{position:i,ticks:{crossAlign:n,mirror:o,padding:s}}=e.options,a=t+s,r=e._getLabelSizes().widest.width;let l,c;return"left"===i?o?(l="left",c=e.right+s):(c=e.right-a,"near"===n?l="right":"center"===n?(l="center",c-=r/2):(l="left",c=e.left)):"right"===i?o?(l="right",c=e.left+s):(c=e.left+a,"near"===n?l="left":"center"===n?(l="center",c+=r/2):(l="right",c=e.right)):l="right",{textAlign:l,x:c}}_computeLabelArea(){const t=this;if(t.options.ticks.mirror)return;const e=t.chart,i=t.options.position;return"left"===i||"right"===i?{top:0,left:t.left,bottom:e.height,right:t.right}:"top"===i||"bottom"===i?{top:t.top,left:0,bottom:t.bottom,right:e.width}:void 0}drawBackground(){const{ctx:t,options:{backgroundColor:e},left:i,top:n,width:o,height:s}=this;e&&(t.save(),t.fillStyle=e,t.fillRect(i,n,o,s),t.restore())}getLineWidthForValue(t){const e=this,i=e.options.grid;if(!e._isVisible()||!i.display)return 0;const n=e.ticks.findIndex((e=>e.value===t));if(n>=0){return i.setContext(e.getContext(n)).lineWidth}return 0}drawGrid(t){const e=this,i=e.options.grid,n=e.ctx,o=e._gridLineItems||(e._gridLineItems=e._computeGridLineItems(t));let s,a;const r=(t,e,i)=>{i.width&&i.color&&(n.save(),n.lineWidth=i.width,n.strokeStyle=i.color,n.setLineDash(i.borderDash||[]),n.lineDashOffset=i.borderDashOffset,n.beginPath(),n.moveTo(t.x,t.y),n.lineTo(e.x,e.y),n.stroke(),n.restore())};if(i.display)for(s=0,a=o.length;s<a;++s){const t=o[s];i.drawOnChartArea&&r({x:t.x1,y:t.y1},{x:t.x2,y:t.y2},t),i.drawTicks&&r({x:t.tx1,y:t.ty1},{x:t.tx2,y:t.ty2},{color:t.tickColor,width:t.tickWidth,borderDash:t.tickBorderDash,borderDashOffset:t.tickBorderDashOffset})}}drawBorder(){const t=this,{chart:e,ctx:i,options:{grid:n}}=t,o=n.setContext(t.getContext()),s=n.drawBorder?o.borderWidth:0;if(!s)return;const a=n.setContext(t.getContext(0)).lineWidth,r=t._borderValue;let l,c,h,d;t.isHorizontal()?(l=Xt(e,t.left,s)-s/2,c=Xt(e,t.right,a)+a/2,h=d=r):(h=Xt(e,t.top,s)-s/2,d=Xt(e,t.bottom,a)+a/2,l=c=r),i.save(),i.lineWidth=o.borderWidth,i.strokeStyle=o.borderColor,i.beginPath(),i.moveTo(l,h),i.lineTo(c,d),i.stroke(),i.restore()}drawLabels(t){const e=this;if(!e.options.ticks.display)return;const i=e.ctx,n=e._computeLabelArea();n&&Zt(i,n);const o=e._labelItems||(e._labelItems=e._computeLabelItems(t));let s,a;for(s=0,a=o.length;s<a;++s){const t=o[s],e=t.font,n=t.label;t.backdrop&&(i.fillStyle=t.backdrop.color,i.fillRect(t.backdrop.left,t.backdrop.top,t.backdrop.width,t.backdrop.height)),ee(i,n,0,t.textOffset,e,t)}n&&Qt(i)}drawTitle(){const{ctx:t,options:{position:e,title:i,reverse:n}}=this;if(!i.display)return;const s=Be(i.font),a=Fe(i.padding),r=i.align;let l=s.lineHeight/2;"bottom"===e?(l+=a.bottom,Y(i.text)&&(l+=s.lineHeight*(i.text.length-1))):l+=a.top;const{titleX:c,titleY:h,maxWidth:d,rotation:u}=function(t,e,i,n){const{top:s,left:a,bottom:r,right:l}=t;let c,h,d,u=0;return t.isHorizontal()?(h=o(n,a,l),d=Hi(t,i,e),c=l-a):(h=Hi(t,i,e),d=o(n,r,s),u="left"===i?-Mt:Mt),{titleX:h,titleY:d,maxWidth:c,rotation:u}}(this,l,e,r);ee(t,i.text,0,0,s,{color:i.color,maxWidth:d,rotation:u,textAlign:Xi(r,e,n),textBaseline:"middle",translation:[c,h]})}draw(t){const e=this;e._isVisible()&&(e.drawBackground(),e.drawGrid(t),e.drawBorder(),e.drawTitle(),e.drawLabels(t))}_layers(){const t=this,e=t.options,i=e.ticks&&e.ticks.z||0,n=e.grid&&e.grid.z||0;return t._isVisible()&&t.draw===qi.prototype.draw?[{z:n,draw(e){t.drawBackground(),t.drawGrid(e),t.drawTitle()}},{z:n+1,draw(){t.drawBorder()}},{z:i,draw(e){t.drawLabels(e)}}]:[{z:i,draw(e){t.draw(e)}}]}getMatchingVisibleMetas(t){const e=this,i=e.chart.getSortedVisibleDatasetMetas(),n=e.axis+"AxisID",o=[];let s,a;for(s=0,a=i.length;s<a;++s){const a=i[s];a[n]!==e.id||t&&a.type!==t||o.push(a)}return o}_resolveTickFontOptions(t){return Be(this.options.ticks.setContext(this.getContext(t)).font)}_maxDigits(){const t=this,e=t._resolveTickFontOptions(0).lineHeight;return(t.isHorizontal()?t.width:t.height)/e}}function Ki(t,e=[""],i=t,n,o=(()=>t[0])){ht(n)||(n=rn("_fallback",t));const s={[Symbol.toStringTag]:"Object",_cacheable:!0,_scopes:t,_rootScopes:i,_fallback:n,_getTarget:o,override:o=>Ki([o,...t],e,i,n)};return new Proxy(s,{deleteProperty:(e,i)=>(delete e[i],delete e._keys,delete t[0][i],!0),get:(i,n)=>tn(i,n,(()=>function(t,e,i,n){let o;for(const s of e)if(o=rn(Qi(s,t),i),ht(o))return Ji(t,o)?sn(i,n,t,o):o}(n,e,t,i))),getOwnPropertyDescriptor:(t,e)=>Reflect.getOwnPropertyDescriptor(t._scopes[0],e),getPrototypeOf:()=>Reflect.getPrototypeOf(t[0]),has:(t,e)=>ln(t).includes(e),ownKeys:t=>ln(t),set:(t,e,i)=>((t._storage||(t._storage=o()))[e]=i,delete t[e],delete t._keys,!0)})}function Gi(t,e,i,n){const o={_cacheable:!1,_proxy:t,_context:e,_subProxy:i,_stack:new Set,_descriptors:Zi(t,n),setContext:e=>Gi(t,e,i,n),override:o=>Gi(t.override(o),e,i,n)};return new Proxy(o,{deleteProperty:(e,i)=>(delete e[i],delete t[i],!0),get:(t,e,i)=>tn(t,e,(()=>function(t,e,i){const{_proxy:n,_context:o,_subProxy:s,_descriptors:a}=t;let r=n[e];dt(r)&&a.isScriptable(e)&&(r=function(t,e,i,n){const{_proxy:o,_context:s,_subProxy:a,_stack:r}=i;if(r.has(t))throw new Error("Recursion detected: "+Array.from(r).join("->")+"->"+t);r.add(t),e=e(s,a||n),r.delete(t),U(e)&&(e=sn(o._scopes,o,t,e));return e}(e,r,t,i));Y(r)&&r.length&&(r=function(t,e,i,n){const{_proxy:o,_context:s,_subProxy:a,_descriptors:r}=i;if(ht(s.index)&&n(t))e=e[s.index%e.length];else if(U(e[0])){const i=e,n=o._scopes.filter((t=>t!==i));e=[];for(const l of i){const i=sn(n,o,t,l);e.push(Gi(i,s,a&&a[t],r))}}return e}(e,r,t,a.isIndexable));Ji(e,r)&&(r=Gi(r,o,s&&s[e],a));return r}(t,e,i))),getOwnPropertyDescriptor:(e,i)=>e._descriptors.allKeys?Reflect.has(t,i)?{enumerable:!0,configurable:!0}:void 0:Reflect.getOwnPropertyDescriptor(t,i),getPrototypeOf:()=>Reflect.getPrototypeOf(t),has:(e,i)=>Reflect.has(t,i),ownKeys:()=>Reflect.ownKeys(t),set:(e,i,n)=>(t[i]=n,delete e[i],!0)})}function Zi(t,e={scriptable:!0,indexable:!0}){const{_scriptable:i=e.scriptable,_indexable:n=e.indexable,_allKeys:o=e.allKeys}=t;return{allKeys:o,scriptable:i,indexable:n,isScriptable:dt(i)?i:()=>i,isIndexable:dt(n)?n:()=>n}}const Qi=(t,e)=>t?t+ct(e):e,Ji=(t,e)=>U(e)&&"adapters"!==t;function tn(t,e,i){let n=t[e];return ht(n)||(n=i(),ht(n)&&(t[e]=n)),n}function en(t,e,i){return dt(t)?t(e,i):t}const nn=(t,e)=>!0===t?e:"string"==typeof t?lt(e,t):void 0;function on(t,e,i,n){for(const o of e){const e=nn(i,o);if(e){t.add(e);const o=en(e._fallback,i,e);if(ht(o)&&o!==i&&o!==n)return o}else if(!1===e&&ht(n)&&i!==n)return null}return!1}function sn(t,e,i,n){const o=e._rootScopes,s=en(e._fallback,i,n),a=[...t,...o],r=new Set;r.add(n);let l=an(r,a,i,s||i);return null!==l&&((!ht(s)||s===i||(l=an(r,a,s,l),null!==l))&&Ki(Array.from(r),[""],o,s,(()=>function(t,e,i){const n=t._getTarget();e in n||(n[e]={});const o=n[e];if(Y(o)&&U(i))return i;return o}(e,i,n))))}function an(t,e,i,n){for(;i;)i=on(t,e,i,n);return i}function rn(t,e){for(const i of e){if(!i)continue;const e=i[t];if(ht(e))return e}}function ln(t){let e=t._keys;return e||(e=t._keys=function(t){const e=new Set;for(const i of t)for(const t of Object.keys(i).filter((t=>!t.startsWith("_"))))e.add(t);return Array.from(e)}(t._scopes)),e}const cn=Number.EPSILON||1e-14,hn=(t,e)=>e<t.length&&!t[e].skip&&t[e],dn=t=>"x"===t?"y":"x";function un(t,e,i,n){const o=t.skip?e:t,s=e,a=i.skip?e:i,r=Bt(s,o),l=Bt(a,s);let c=r/(r+l),h=l/(r+l);c=isNaN(c)?0:c,h=isNaN(h)?0:h;const d=n*c,u=n*h;return{previous:{x:s.x-d*(a.x-o.x),y:s.y-d*(a.y-o.y)},next:{x:s.x+u*(a.x-o.x),y:s.y+u*(a.y-o.y)}}}function fn(t,e="x"){const i=dn(e),n=t.length,o=Array(n).fill(0),s=Array(n);let a,r,l,c=hn(t,0);for(a=0;a<n;++a)if(r=l,l=c,c=hn(t,a+1),l){if(c){const t=c[e]-l[e];o[a]=0!==t?(c[i]-l[i])/t:0}s[a]=r?c?Dt(o[a-1])!==Dt(o[a])?0:(o[a-1]+o[a])/2:o[a-1]:o[a]}!function(t,e,i){const n=t.length;let o,s,a,r,l,c=hn(t,0);for(let h=0;h<n-1;++h)l=c,c=hn(t,h+1),l&&c&&(At(e[h],0,cn)?i[h]=i[h+1]=0:(o=i[h]/e[h],s=i[h+1]/e[h],r=Math.pow(o,2)+Math.pow(s,2),r<=9||(a=3/Math.sqrt(r),i[h]=o*a*e[h],i[h+1]=s*a*e[h])))}(t,o,s),function(t,e,i="x"){const n=dn(i),o=t.length;let s,a,r,l=hn(t,0);for(let c=0;c<o;++c){if(a=r,r=l,l=hn(t,c+1),!r)continue;const o=r[i],h=r[n];a&&(s=(o-a[i])/3,r[`cp1${i}`]=o-s,r[`cp1${n}`]=h-s*e[c]),l&&(s=(l[i]-o)/3,r[`cp2${i}`]=o+s,r[`cp2${n}`]=h+s*e[c])}}(t,s,e)}function gn(t,e,i){return Math.max(Math.min(t,i),e)}function pn(t,e,i,n,o){let s,a,r,l;if(e.spanGaps&&(t=t.filter((t=>!t.skip))),"monotone"===e.cubicInterpolationMode)fn(t,o);else{let i=n?t[t.length-1]:t[0];for(s=0,a=t.length;s<a;++s)r=t[s],l=un(i,r,t[Math.min(s+1,a-(n?0:1))%a],e.tension),r.cp1x=l.previous.x,r.cp1y=l.previous.y,r.cp2x=l.next.x,r.cp2y=l.next.y,i=r}e.capBezierPoints&&function(t,e){let i,n,o,s,a,r=Gt(t[0],e);for(i=0,n=t.length;i<n;++i)a=s,s=r,r=i<n-1&&Gt(t[i+1],e),s&&(o=t[i],a&&(o.cp1x=gn(o.cp1x,e.left,e.right),o.cp1y=gn(o.cp1y,e.top,e.bottom)),r&&(o.cp2x=gn(o.cp2x,e.left,e.right),o.cp2y=gn(o.cp2y,e.top,e.bottom)))}(t,i)}function mn(t,e,i,n){return{x:t.x+i*(e.x-t.x),y:t.y+i*(e.y-t.y)}}function xn(t,e,i,n){return{x:t.x+i*(e.x-t.x),y:"middle"===n?i<.5?t.y:e.y:"after"===n?i<1?t.y:e.y:i>0?e.y:t.y}}function bn(t,e,i,n){const o={x:t.cp2x,y:t.cp2y},s={x:e.cp1x,y:e.cp1y},a=mn(t,o,i),r=mn(o,s,i),l=mn(s,e,i),c=mn(a,r,i),h=mn(r,l,i);return mn(c,h,i)}function _n(t,e,i){return t?function(t,e){return{x:i=>t+t+e-i,setWidth(t){e=t},textAlign:t=>"center"===t?t:"right"===t?"left":"right",xPlus:(t,e)=>t-e,leftForLtr:(t,e)=>t-e}}(e,i):{x:t=>t,setWidth(t){},textAlign:t=>t,xPlus:(t,e)=>t+e,leftForLtr:(t,e)=>t}}function yn(t,e){let i,n;"ltr"!==e&&"rtl"!==e||(i=t.canvas.style,n=[i.getPropertyValue("direction"),i.getPropertyPriority("direction")],i.setProperty("direction",e,"important"),t.prevTextDirection=n)}function vn(t,e){void 0!==e&&(delete t.prevTextDirection,t.canvas.style.setProperty("direction",e[0],e[1]))}function wn(t){return"angle"===t?{between:Nt,compare:Vt,normalize:Wt}:{between:(t,e,i)=>t>=Math.min(e,i)&&t<=Math.max(i,e),compare:(t,e)=>t-e,normalize:t=>t}}function Mn({start:t,end:e,count:i,loop:n,style:o}){return{start:t%i,end:e%i,loop:n&&(e-t+1)%i==0,style:o}}function kn(t,e,i){if(!i)return[t];const{property:n,start:o,end:s}=i,a=e.length,{compare:r,between:l,normalize:c}=wn(n),{start:h,end:d,loop:u,style:f}=function(t,e,i){const{property:n,start:o,end:s}=i,{between:a,normalize:r}=wn(n),l=e.length;let c,h,{start:d,end:u,loop:f}=t;if(f){for(d+=l,u+=l,c=0,h=l;c<h&&a(r(e[d%l][n]),o,s);++c)d--,u--;d%=l,u%=l}return u<d&&(u+=l),{start:d,end:u,loop:f,style:t.style}}(t,e,i),g=[];let p,m,x,b=!1,_=null;const y=()=>b||l(o,x,p)&&0!==r(o,x),v=()=>!b||0===r(s,p)||l(s,x,p);for(let t=h,i=h;t<=d;++t)m=e[t%a],m.skip||(p=c(m[n]),p!==x&&(b=l(p,o,s),null===_&&y()&&(_=0===r(p,o)?t:i),null!==_&&v()&&(g.push(Mn({start:_,end:t,loop:u,count:a,style:f})),_=null),i=t,x=p));return null!==_&&g.push(Mn({start:_,end:d,loop:u,count:a,style:f})),g}function Sn(t,e){const i=[],n=t.segments;for(let o=0;o<n.length;o++){const s=kn(n[o],t.points,e);s.length&&i.push(...s)}return i}function Pn(t,e){const i=t.points,n=t.options.spanGaps,o=i.length;if(!o)return[];const s=!!t._loop,{start:a,end:r}=function(t,e,i,n){let o=0,s=e-1;if(i&&!n)for(;o<e&&!t[o].skip;)o++;for(;o<e&&t[o].skip;)o++;for(o%=e,i&&(s+=o);s>o&&t[s%e].skip;)s--;return s%=e,{start:o,end:s}}(i,o,s,n);if(!0===n)return Dn([{start:a,end:r,loop:s}],i,e);return Dn(function(t,e,i,n){const o=t.length,s=[];let a,r=e,l=t[e];for(a=e+1;a<=i;++a){const i=t[a%o];i.skip||i.stop?l.skip||(n=!1,s.push({start:e%o,end:(a-1)%o,loop:n}),e=r=i.stop?a:null):(r=a,l.skip&&(e=a)),l=i}return null!==r&&s.push({start:e%o,end:r%o,loop:n}),s}(i,a,r<a?r+o:r,!!t._fullLoop&&0===a&&r===o-1),i,e)}function Dn(t,e,i){return i&&i.setContext&&e?function(t,e,i){const n=e.length,o=[];let s=t[0].start,a=s;for(const r of t){let t,l,c=e[s%n];for(a=s+1;a<=r.end;a++){const h=e[a%n];l=Cn(i.setContext({type:"segment",p0:c,p1:h})),On(l,t)&&(o.push({start:s,end:a-1,loop:r.loop,style:t}),t=l,s=a-1),c=h,t=l}s<a-1&&(o.push({start:s,end:a-1,loop:r.loop,style:l}),s=a-1)}return o}(t,e,i):t}function Cn(t){return{backgroundColor:t.backgroundColor,borderCapStyle:t.borderCapStyle,borderDash:t.borderDash,borderDashOffset:t.borderDashOffset,borderJoinStyle:t.borderJoinStyle,borderWidth:t.borderWidth,borderColor:t.borderColor}}function On(t,e){return e&&JSON.stringify(t)!==JSON.stringify(e)}var Tn=Object.freeze({__proto__:null,easingEffects:xi,color:W,getHoverColor:N,noop:H,uid:j,isNullOrUndef:$,isArray:Y,isObject:U,isFinite:X,finiteOrDefault:q,valueOrDefault:K,toPercentage:G,toDimension:Z,callback:Q,each:J,_elementsEqual:tt,clone:et,_merger:nt,merge:ot,mergeIf:st,_mergerIf:at,_deprecated:function(t,e,i,n){void 0!==e&&console.warn(t+': "'+i+'" is deprecated. Please use "'+n+'" instead')},resolveObjectKey:lt,_capitalize:ct,defined:ht,isFunction:dt,setsEqual:ut,toFontString:$t,_measureText:Yt,_longestText:Ut,_alignPixel:Xt,clearCanvas:qt,drawPoint:Kt,_isPointInArea:Gt,clipArea:Zt,unclipArea:Qt,_steppedLineTo:Jt,_bezierCurveTo:te,renderText:ee,addRoundedRectPath:ne,_lookup:oe,_lookupByKey:se,_rlookupByKey:ae,_filterBetween:re,listenArrayEvents:ce,unlistenArrayEvents:he,_arrayUnique:de,_createResolver:Ki,_attachContext:Gi,_descriptors:Zi,splineCurve:un,splineCurveMonotone:fn,_updateBezierControlPoints:pn,_getParentNode:ue,getStyle:pe,getRelativePosition:be,getMaximumSize:ye,retinaScale:ve,supportsEventListenerOptions:we,readUsedSize:Me,fontString:function(t,e,i){return e+" "+t+"px "+i},requestAnimFrame:t,throttled:e,debounce:i,_toLeftRightCenter:n,_alignStartEnd:o,_textX:s,_pointInLine:mn,_steppedInterpolation:xn,_bezierInterpolation:bn,formatNumber:Fi,toLineHeight:Re,_readValueToProps:Ee,toTRBL:ze,toTRBLCorners:Ie,toPadding:Fe,toFont:Be,resolve:Ve,_addGrace:We,PI:bt,TAU:_t,PITAU:yt,INFINITY:vt,RAD_PER_DEG:wt,HALF_PI:Mt,QUARTER_PI:kt,TWO_THIRDS_PI:St,log10:Pt,sign:Dt,niceNum:Ct,_factorize:Ot,isNumber:Tt,almostEquals:At,almostWhole:Lt,_setMinAndMaxByKey:Rt,toRadians:Et,toDegrees:zt,_decimalPlaces:It,getAngleFromPoint:Ft,distanceBetweenPoints:Bt,_angleDiff:Vt,_normalizeAngle:Wt,_angleBetween:Nt,_limitValue:Ht,_int16Range:jt,getRtlAdapter:_n,overrideTextDirection:yn,restoreTextDirection:vn,_boundSegment:kn,_boundSegments:Sn,_computeSegments:Pn});class An{constructor(t,e,i){this.type=t,this.scope=e,this.override=i,this.items=Object.create(null)}isForType(t){return Object.prototype.isPrototypeOf.call(this.type.prototype,t.prototype)}register(t){const e=this,i=Object.getPrototypeOf(t);let n;(function(t){return"id"in t&&"defaults"in t})(i)&&(n=e.register(i));const o=e.items,s=t.id,a=e.scope+"."+s;if(!s)throw new Error("class does not have id: "+t);return s in o||(o[s]=t,function(t,e,i){const n=ot(Object.create(null),[i?xt.get(i):{},xt.get(e),t.defaults]);xt.set(e,n),t.defaultRoutes&&function(t,e){Object.keys(e).forEach((i=>{const n=i.split("."),o=n.pop(),s=[t].concat(n).join("."),a=e[i].split("."),r=a.pop(),l=a.join(".");xt.route(s,o,l,r)}))}(e,t.defaultRoutes);t.descriptors&&xt.describe(e,t.descriptors)}(t,a,n),e.override&&xt.override(t.id,t.overrides)),a}get(t){return this.items[t]}unregister(t){const e=this.items,i=t.id,n=this.scope;i in e&&delete e[i],n&&i in xt[n]&&(delete xt[n][i],this.override&&delete ft[i])}}var Ln=new class{constructor(){this.controllers=new An(Ei,"datasets",!0),this.elements=new An(zi,"elements"),this.plugins=new An(Object,"plugins"),this.scales=new An(qi,"scales"),this._typedRegistries=[this.controllers,this.scales,this.elements]}add(...t){this._each("register",t)}remove(...t){this._each("unregister",t)}addControllers(...t){this._each("register",t,this.controllers)}addElements(...t){this._each("register",t,this.elements)}addPlugins(...t){this._each("register",t,this.plugins)}addScales(...t){this._each("register",t,this.scales)}getController(t){return this._get(t,this.controllers,"controller")}getElement(t){return this._get(t,this.elements,"element")}getPlugin(t){return this._get(t,this.plugins,"plugin")}getScale(t){return this._get(t,this.scales,"scale")}removeControllers(...t){this._each("unregister",t,this.controllers)}removeElements(...t){this._each("unregister",t,this.elements)}removePlugins(...t){this._each("unregister",t,this.plugins)}removeScales(...t){this._each("unregister",t,this.scales)}_each(t,e,i){const n=this;[...e].forEach((e=>{const o=i||n._getRegistryForType(e);i||o.isForType(e)||o===n.plugins&&e.id?n._exec(t,o,e):J(e,(e=>{const o=i||n._getRegistryForType(e);n._exec(t,o,e)}))}))}_exec(t,e,i){const n=ct(t);Q(i["before"+n],[],i),e[t](i),Q(i["after"+n],[],i)}_getRegistryForType(t){for(let e=0;e<this._typedRegistries.length;e++){const i=this._typedRegistries[e];if(i.isForType(t))return i}return this.plugins}_get(t,e,i){const n=e.get(t);if(void 0===n)throw new Error('"'+t+'" is not a registered '+i+".");return n}};class Rn{constructor(){this._init=[]}notify(t,e,i,n){const o=this;"beforeInit"===e&&(o._init=o._createDescriptors(t,!0),o._notify(o._init,t,"install"));const s=n?o._descriptors(t).filter(n):o._descriptors(t),a=o._notify(s,t,e,i);return"destroy"===e&&(o._notify(s,t,"stop"),o._notify(o._init,t,"uninstall")),a}_notify(t,e,i,n){n=n||{};for(const o of t){const t=o.plugin;if(!1===Q(t[i],[e,n,o.options],t)&&n.cancelable)return!1}return!0}invalidate(){$(this._cache)||(this._oldCache=this._cache,this._cache=void 0)}_descriptors(t){if(this._cache)return this._cache;const e=this._cache=this._createDescriptors(t);return this._notifyStateChanges(t),e}_createDescriptors(t,e){const i=t&&t.config,n=K(i.options&&i.options.plugins,{}),o=function(t){const e=[],i=Object.keys(Ln.plugins.items);for(let t=0;t<i.length;t++)e.push(Ln.getPlugin(i[t]));const n=t.plugins||[];for(let t=0;t<n.length;t++){const i=n[t];-1===e.indexOf(i)&&e.push(i)}return e}(i);return!1!==n||e?function(t,e,i,n){const o=[],s=t.getContext();for(let a=0;a<e.length;a++){const r=e[a],l=En(i[r.id],n);null!==l&&o.push({plugin:r,options:zn(t.config,r,l,s)})}return o}(t,o,n,e):[]}_notifyStateChanges(t){const e=this._oldCache||[],i=this._cache,n=(t,e)=>t.filter((t=>!e.some((e=>t.plugin.id===e.plugin.id))));this._notify(n(e,i),t,"stop"),this._notify(n(i,e),t,"start")}}function En(t,e){return e||!1!==t?!0===t?{}:t:null}function zn(t,e,i,n){const o=t.pluginScopeKeys(e),s=t.getOptionScopes(i,o);return t.createResolver(s,n,[""],{scriptable:!1,indexable:!1,allKeys:!0})}function In(t,e){const i=xt.datasets[t]||{};return((e.datasets||{})[t]||{}).indexAxis||e.indexAxis||i.indexAxis||"x"}function Fn(t,e){return"x"===t||"y"===t?t:e.axis||("top"===(i=e.position)||"bottom"===i?"x":"left"===i||"right"===i?"y":void 0)||t.charAt(0).toLowerCase();var i}function Bn(t){const e=t.options||(t.options={});e.plugins=K(e.plugins,{}),e.scales=function(t,e){const i=ft[t.type]||{scales:{}},n=e.scales||{},o=In(t.type,e),s=Object.create(null),a=Object.create(null);return Object.keys(n).forEach((t=>{const e=n[t],r=Fn(t,e),l=function(t,e){return t===e?"_index_":"_value_"}(r,o),c=i.scales||{};s[r]=s[r]||t,a[t]=st(Object.create(null),[{axis:r},e,c[r],c[l]])})),t.data.datasets.forEach((i=>{const o=i.type||t.type,r=i.indexAxis||In(o,e),l=(ft[o]||{}).scales||{};Object.keys(l).forEach((t=>{const e=function(t,e){let i=t;return"_index_"===t?i=e:"_value_"===t&&(i="x"===e?"y":"x"),i}(t,r),o=i[e+"AxisID"]||s[e]||e;a[o]=a[o]||Object.create(null),st(a[o],[{axis:e},n[o],l[t]])}))})),Object.keys(a).forEach((t=>{const e=a[t];st(e,[xt.scales[e.type],xt.scale])})),a}(t,e)}function Vn(t){return(t=t||{}).datasets=t.datasets||[],t.labels=t.labels||[],t}const Wn=new Map,Nn=new Set;function Hn(t,e){let i=Wn.get(t);return i||(i=e(),Wn.set(t,i),Nn.add(i)),i}const jn=(t,e,i)=>{const n=lt(e,i);void 0!==n&&t.add(n)};class $n{constructor(t){this._config=function(t){return(t=t||{}).data=Vn(t.data),Bn(t),t}(t),this._scopeCache=new Map,this._resolverCache=new Map}get type(){return this._config.type}set type(t){this._config.type=t}get data(){return this._config.data}set data(t){this._config.data=Vn(t)}get options(){return this._config.options}set options(t){this._config.options=t}get plugins(){return this._config.plugins}update(){const t=this._config;this.clearCache(),Bn(t)}clearCache(){this._scopeCache.clear(),this._resolverCache.clear()}datasetScopeKeys(t){return Hn(t,(()=>[[`datasets.${t}`,""]]))}datasetAnimationScopeKeys(t,e){return Hn(`${t}.transition.${e}`,(()=>[[`datasets.${t}.transitions.${e}`,`transitions.${e}`],[`datasets.${t}`,""]]))}datasetElementScopeKeys(t,e){return Hn(`${t}-${e}`,(()=>[[`datasets.${t}.elements.${e}`,`datasets.${t}`,`elements.${e}`,""]]))}pluginScopeKeys(t){const e=t.id;return Hn(`${this.type}-plugin-${e}`,(()=>[[`plugins.${e}`,...t.additionalOptionScopes||[]]]))}_cachedScopes(t,e){const i=this._scopeCache;let n=i.get(t);return n&&!e||(n=new Map,i.set(t,n)),n}getOptionScopes(t,e,i){const{options:n,type:o}=this,s=this._cachedScopes(t,i),a=s.get(e);if(a)return a;const r=new Set;e.forEach((e=>{t&&(r.add(t),e.forEach((e=>jn(r,t,e)))),e.forEach((t=>jn(r,n,t))),e.forEach((t=>jn(r,ft[o]||{},t))),e.forEach((t=>jn(r,xt,t))),e.forEach((t=>jn(r,gt,t)))}));const l=Array.from(r);return Nn.has(e)&&s.set(e,l),l}chartOptionScopes(){const{options:t,type:e}=this;return[t,ft[e]||{},xt.datasets[e]||{},{type:e},xt,gt]}resolveNamedOptions(t,e,i,n=[""]){const o={$shared:!0},{resolver:s,subPrefixes:a}=Yn(this._resolverCache,t,n);let r=s;if(function(t,e){const{isScriptable:i,isIndexable:n}=Zi(t);for(const o of e)if(i(o)&&dt(t[o])||n(o)&&Y(t[o]))return!0;return!1}(s,e)){o.$shared=!1;r=Gi(s,i=dt(i)?i():i,this.createResolver(t,i,a))}for(const t of e)o[t]=r[t];return o}createResolver(t,e,i=[""],n){const{resolver:o}=Yn(this._resolverCache,t,i);return U(e)?Gi(o,e,void 0,n):o}}function Yn(t,e,i){let n=t.get(e);n||(n=new Map,t.set(e,n));const o=i.join();let s=n.get(o);if(!s){s={resolver:Ki(e,i),subPrefixes:i.filter((t=>!t.toLowerCase().includes("hover")))},n.set(o,s)}return s}const Un=["top","bottom","left","right","chartArea"];function Xn(t,e){return"top"===t||"bottom"===t||-1===Un.indexOf(t)&&"x"===e}function qn(t,e){return function(i,n){return i[t]===n[t]?i[e]-n[e]:i[t]-n[t]}}function Kn(t){const e=t.chart,i=e.options.animation;e.notifyPlugins("afterRender"),Q(i&&i.onComplete,[t],e)}function Gn(t){const e=t.chart,i=e.options.animation;Q(i&&i.onProgress,[t],e)}function Zn(){return"undefined"!=typeof window&&"undefined"!=typeof document}function Qn(t){return Zn()&&"string"==typeof t?t=document.getElementById(t):t&&t.length&&(t=t[0]),t&&t.canvas&&(t=t.canvas),t}const Jn={},to=t=>{const e=Qn(t);return Object.values(Jn).filter((t=>t.canvas===e)).pop()};class eo{constructor(t,e){const n=this;this.config=e=new $n(e);const o=Qn(t),s=to(o);if(s)throw new Error("Canvas is already in use. Chart with ID '"+s.id+"' must be destroyed before the canvas can be reused.");const r=e.createResolver(e.chartOptionScopes(),n.getContext());this.platform=n._initializePlatform(o,e);const l=n.platform.acquireContext(o,r.aspectRatio),c=l&&l.canvas,h=c&&c.height,d=c&&c.width;this.id=j(),this.ctx=l,this.canvas=c,this.width=d,this.height=h,this._options=r,this._aspectRatio=this.aspectRatio,this._layers=[],this._metasets=[],this._stacks=void 0,this.boxes=[],this.currentDevicePixelRatio=void 0,this.chartArea=void 0,this._active=[],this._lastEvent=void 0,this._listeners={},this._responsiveListeners=void 0,this._sortedMetasets=[],this.scales={},this.scale=void 0,this._plugins=new Rn,this.$proxies={},this._hiddenIndices={},this.attached=!1,this._animationsDisabled=void 0,this.$context=void 0,this._doResize=i((()=>this.update("resize")),r.resizeDelay||0),Jn[n.id]=n,l&&c?(a.listen(n,"complete",Kn),a.listen(n,"progress",Gn),n._initialize(),n.attached&&n.update()):console.error("Failed to create chart: can't acquire context from the given item")}get aspectRatio(){const{options:{aspectRatio:t,maintainAspectRatio:e},width:i,height:n,_aspectRatio:o}=this;return $(t)?e&&o?o:n?i/n:null:t}get data(){return this.config.data}set data(t){this.config.data=t}get options(){return this._options}set options(t){this.config.options=t}_initialize(){const t=this;return t.notifyPlugins("beforeInit"),t.options.responsive?t.resize():ve(t,t.options.devicePixelRatio),t.bindEvents(),t.notifyPlugins("afterInit"),t}_initializePlatform(t,e){return e.platform?new e.platform:!Zn()||"undefined"!=typeof OffscreenCanvas&&t instanceof OffscreenCanvas?new Je:new ui}clear(){return qt(this.canvas,this.ctx),this}stop(){return a.stop(this),this}resize(t,e){a.running(this)?this._resizeBeforeDraw={width:t,height:e}:this._resize(t,e)}_resize(t,e){const i=this,n=i.options,o=i.canvas,s=n.maintainAspectRatio&&i.aspectRatio,a=i.platform.getMaximumSize(o,t,e,s),r=n.devicePixelRatio||i.platform.getDevicePixelRatio();i.width=a.width,i.height=a.height,i._aspectRatio=i.aspectRatio,ve(i,r,!0)&&(i.notifyPlugins("resize",{size:a}),Q(n.onResize,[i,a],i),i.attached&&i._doResize()&&i.render())}ensureScalesHaveIDs(){J(this.options.scales||{},((t,e)=>{t.id=e}))}buildOrUpdateScales(){const t=this,e=t.options,i=e.scales,n=t.scales,o=Object.keys(n).reduce(((t,e)=>(t[e]=!1,t)),{});let s=[];i&&(s=s.concat(Object.keys(i).map((t=>{const e=i[t],n=Fn(t,e),o="r"===n,s="x"===n;return{options:e,dposition:o?"chartArea":s?"bottom":"left",dtype:o?"radialLinear":s?"category":"linear"}})))),J(s,(i=>{const s=i.options,a=s.id,r=Fn(a,s),l=K(s.type,i.dtype);void 0!==s.position&&Xn(s.position,r)===Xn(i.dposition)||(s.position=i.dposition),o[a]=!0;let c=null;if(a in n&&n[a].type===l)c=n[a];else{c=new(Ln.getScale(l))({id:a,type:l,ctx:t.ctx,chart:t}),n[c.id]=c}c.init(s,e)})),J(o,((t,e)=>{t||delete n[e]})),J(n,(e=>{Ze.configure(t,e,e.options),Ze.addBox(t,e)}))}_updateMetasets(){const t=this,e=t._metasets,i=t.data.datasets.length,n=e.length;if(e.sort(((t,e)=>t.index-e.index)),n>i){for(let e=i;e<n;++e)t._destroyDatasetMeta(e);e.splice(i,n-i)}t._sortedMetasets=e.slice(0).sort(qn("order","index"))}_removeUnreferencedMetasets(){const t=this,{_metasets:e,data:{datasets:i}}=t;e.length>i.length&&delete t._stacks,e.forEach(((e,n)=>{0===i.filter((t=>t===e._dataset)).length&&t._destroyDatasetMeta(n)}))}buildOrUpdateControllers(){const t=this,e=[],i=t.data.datasets;let n,o;for(t._removeUnreferencedMetasets(),n=0,o=i.length;n<o;n++){const o=i[n];let s=t.getDatasetMeta(n);const a=o.type||t.config.type;if(s.type&&s.type!==a&&(t._destroyDatasetMeta(n),s=t.getDatasetMeta(n)),s.type=a,s.indexAxis=o.indexAxis||In(a,t.options),s.order=o.order||0,s.index=n,s.label=""+o.label,s.visible=t.isDatasetVisible(n),s.controller)s.controller.updateIndex(n),s.controller.linkScales();else{const i=Ln.getController(a),{datasetElementType:o,dataElementType:r}=xt.datasets[a];Object.assign(i.prototype,{dataElementType:Ln.getElement(r),datasetElementType:o&&Ln.getElement(o)}),s.controller=new i(t,n),e.push(s.controller)}}return t._updateMetasets(),e}_resetElements(){const t=this;J(t.data.datasets,((e,i)=>{t.getDatasetMeta(i).controller.reset()}),t)}reset(){this._resetElements(),this.notifyPlugins("reset")}update(t){const e=this,i=e.config;i.update(),e._options=i.createResolver(i.chartOptionScopes(),e.getContext()),J(e.scales,(t=>{Ze.removeBox(e,t)}));const n=e._animationsDisabled=!e.options.animation;e.ensureScalesHaveIDs(),e.buildOrUpdateScales();const o=new Set(Object.keys(e._listeners)),s=new Set(e.options.events);if(ut(o,s)&&!!this._responsiveListeners===e.options.responsive||(e.unbindEvents(),e.bindEvents()),e._plugins.invalidate(),!1===e.notifyPlugins("beforeUpdate",{mode:t,cancelable:!0}))return;const a=e.buildOrUpdateControllers();e.notifyPlugins("beforeElementsUpdate");let r=0;for(let t=0,i=e.data.datasets.length;t<i;t++){const{controller:i}=e.getDatasetMeta(t),o=!n&&-1===a.indexOf(i);i.buildOrUpdateElements(o),r=Math.max(+i.getMaxOverflow(),r)}e._minPadding=r,e._updateLayout(r),n||J(a,(t=>{t.reset()})),e._updateDatasets(t),e.notifyPlugins("afterUpdate",{mode:t}),e._layers.sort(qn("z","_idx")),e._lastEvent&&e._eventHandler(e._lastEvent,!0),e.render()}_updateLayout(t){const e=this;if(!1===e.notifyPlugins("beforeLayout",{cancelable:!0}))return;Ze.update(e,e.width,e.height,t);const i=e.chartArea,n=i.width<=0||i.height<=0;e._layers=[],J(e.boxes,(t=>{n&&"chartArea"===t.position||(t.configure&&t.configure(),e._layers.push(...t._layers()))}),e),e._layers.forEach(((t,e)=>{t._idx=e})),e.notifyPlugins("afterLayout")}_updateDatasets(t){const e=this,i="function"==typeof t;if(!1!==e.notifyPlugins("beforeDatasetsUpdate",{mode:t,cancelable:!0})){for(let n=0,o=e.data.datasets.length;n<o;++n)e._updateDataset(n,i?t({datasetIndex:n}):t);e.notifyPlugins("afterDatasetsUpdate",{mode:t})}}_updateDataset(t,e){const i=this,n=i.getDatasetMeta(t),o={meta:n,index:t,mode:e,cancelable:!0};!1!==i.notifyPlugins("beforeDatasetUpdate",o)&&(n.controller._update(e),o.cancelable=!1,i.notifyPlugins("afterDatasetUpdate",o))}render(){const t=this;!1!==t.notifyPlugins("beforeRender",{cancelable:!0})&&(a.has(t)?t.attached&&!a.running(t)&&a.start(t):(t.draw(),Kn({chart:t})))}draw(){const t=this;let e;if(t._resizeBeforeDraw){const{width:e,height:i}=t._resizeBeforeDraw;t._resize(e,i),t._resizeBeforeDraw=null}if(t.clear(),t.width<=0||t.height<=0)return;if(!1===t.notifyPlugins("beforeDraw",{cancelable:!0}))return;const i=t._layers;for(e=0;e<i.length&&i[e].z<=0;++e)i[e].draw(t.chartArea);for(t._drawDatasets();e<i.length;++e)i[e].draw(t.chartArea);t.notifyPlugins("afterDraw")}_getSortedDatasetMetas(t){const e=this._sortedMetasets,i=[];let n,o;for(n=0,o=e.length;n<o;++n){const o=e[n];t&&!o.visible||i.push(o)}return i}getSortedVisibleDatasetMetas(){return this._getSortedDatasetMetas(!0)}_drawDatasets(){const t=this;if(!1===t.notifyPlugins("beforeDatasetsDraw",{cancelable:!0}))return;const e=t.getSortedVisibleDatasetMetas();for(let i=e.length-1;i>=0;--i)t._drawDataset(e[i]);t.notifyPlugins("afterDatasetsDraw")}_drawDataset(t){const e=this,i=e.ctx,n=t._clip,o=!n.disabled,s=e.chartArea,a={meta:t,index:t.index,cancelable:!0};!1!==e.notifyPlugins("beforeDatasetDraw",a)&&(o&&Zt(i,{left:!1===n.left?0:s.left-n.left,right:!1===n.right?e.width:s.right+n.right,top:!1===n.top?0:s.top-n.top,bottom:!1===n.bottom?e.height:s.bottom+n.bottom}),t.controller.draw(),o&&Qt(i),a.cancelable=!1,e.notifyPlugins("afterDatasetDraw",a))}getElementsAtEventForMode(t,e,i,n){const o=Te.modes[e];return"function"==typeof o?o(this,t,i,n):[]}getDatasetMeta(t){const e=this.data.datasets[t],i=this._metasets;let n=i.filter((t=>t&&t._dataset===e)).pop();return n||(n={type:null,data:[],dataset:null,controller:null,hidden:null,xAxisID:null,yAxisID:null,order:e&&e.order||0,index:t,_dataset:e,_parsed:[],_sorted:!1},i.push(n)),n}getContext(){return this.$context||(this.$context={chart:this,type:"chart"})}getVisibleDatasetCount(){return this.getSortedVisibleDatasetMetas().length}isDatasetVisible(t){const e=this.data.datasets[t];if(!e)return!1;const i=this.getDatasetMeta(t);return"boolean"==typeof i.hidden?!i.hidden:!e.hidden}setDatasetVisibility(t,e){this.getDatasetMeta(t).hidden=!e}toggleDataVisibility(t){this._hiddenIndices[t]=!this._hiddenIndices[t]}getDataVisibility(t){return!this._hiddenIndices[t]}_updateDatasetVisibility(t,e){const i=this,n=e?"show":"hide",o=i.getDatasetMeta(t),s=o.controller._resolveAnimations(void 0,n);i.setDatasetVisibility(t,e),s.update(o,{visible:e}),i.update((e=>e.datasetIndex===t?n:void 0))}hide(t){this._updateDatasetVisibility(t,!1)}show(t){this._updateDatasetVisibility(t,!0)}_destroyDatasetMeta(t){const e=this,i=e._metasets&&e._metasets[t];i&&i.controller&&(i.controller._destroy(),delete e._metasets[t])}destroy(){const t=this,{canvas:e,ctx:i}=t;let n,o;for(t.stop(),a.remove(t),n=0,o=t.data.datasets.length;n<o;++n)t._destroyDatasetMeta(n);t.config.clearCache(),e&&(t.unbindEvents(),qt(e,i),t.platform.releaseContext(i),t.canvas=null,t.ctx=null),t.notifyPlugins("destroy"),delete Jn[t.id]}toBase64Image(...t){return this.canvas.toDataURL(...t)}bindEvents(){this.bindUserEvents(),this.options.responsive?this.bindResponsiveEvents():this.attached=!0}bindUserEvents(){const t=this,e=t._listeners,i=t.platform,n=function(e,i,n){e.offsetX=i,e.offsetY=n,t._eventHandler(e)};J(t.options.events,(o=>((n,o)=>{i.addEventListener(t,n,o),e[n]=o})(o,n)))}bindResponsiveEvents(){const t=this;t._responsiveListeners||(t._responsiveListeners={});const e=t._responsiveListeners,i=t.platform,n=(n,o)=>{i.addEventListener(t,n,o),e[n]=o},o=(n,o)=>{e[n]&&(i.removeEventListener(t,n,o),delete e[n])},s=(e,i)=>{t.canvas&&t.resize(e,i)};let a;const r=()=>{o("attach",r),t.attached=!0,t.resize(),n("resize",s),n("detach",a)};a=()=>{t.attached=!1,o("resize",s),n("attach",r)},i.isAttached(t.canvas)?r():a()}unbindEvents(){const t=this;J(t._listeners,((e,i)=>{t.platform.removeEventListener(t,i,e)})),t._listeners={},J(t._responsiveListeners,((e,i)=>{t.platform.removeEventListener(t,i,e)})),t._responsiveListeners=void 0}updateHoverStyle(t,e,i){const n=i?"set":"remove";let o,s,a,r;for("dataset"===e&&(o=this.getDatasetMeta(t[0].datasetIndex),o.controller["_"+n+"DatasetHoverStyle"]()),a=0,r=t.length;a<r;++a){s=t[a];const e=s&&this.getDatasetMeta(s.datasetIndex).controller;e&&e[n+"HoverStyle"](s.element,s.datasetIndex,s.index)}}getActiveElements(){return this._active||[]}setActiveElements(t){const e=this,i=e._active||[],n=t.map((({datasetIndex:t,index:i})=>{const n=e.getDatasetMeta(t);if(!n)throw new Error("No dataset found at index "+t);return{datasetIndex:t,element:n.data[i],index:i}}));!tt(n,i)&&(e._active=n,e._updateHoverStyles(n,i))}notifyPlugins(t,e,i){return this._plugins.notify(this,t,e,i)}_updateHoverStyles(t,e,i){const n=this,o=n.options.hover,s=(t,e)=>t.filter((t=>!e.some((e=>t.datasetIndex===e.datasetIndex&&t.index===e.index)))),a=s(e,t),r=i?t:s(t,e);a.length&&n.updateHoverStyle(a,o.mode,!1),r.length&&o.mode&&n.updateHoverStyle(r,o.mode,!0)}_eventHandler(t,e){const i=this,n={event:t,replay:e,cancelable:!0},o=e=>(e.options.events||this.options.events).includes(t.type);if(!1===i.notifyPlugins("beforeEvent",n,o))return;const s=i._handleEvent(t,e);return n.cancelable=!1,i.notifyPlugins("afterEvent",n,o),(s||n.changed)&&i.render(),i}_handleEvent(t,e){const i=this,{_active:n=[],options:o}=i,s=o.hover,a=e;let r=[],l=!1,c=null;return"mouseout"!==t.type&&(r=i.getElementsAtEventForMode(t,s.mode,s,a),c="click"===t.type?i._lastEvent:t),i._lastEvent=null,Gt(t,i.chartArea,i._minPadding)&&(Q(o.onHover,[t,r,i],i),"mouseup"!==t.type&&"click"!==t.type&&"contextmenu"!==t.type||Q(o.onClick,[t,r,i],i)),l=!tt(r,n),(l||e)&&(i._active=r,i._updateHoverStyles(r,n,e)),i._lastEvent=c,l}}const io=()=>J(eo.instances,(t=>t._plugins.invalidate())),no=!0;function oo(){throw new Error("This method is not implemented: Check that a complete date adapter is provided.")}Object.defineProperties(eo,{defaults:{enumerable:no,value:xt},instances:{enumerable:no,value:Jn},overrides:{enumerable:no,value:ft},registry:{enumerable:no,value:Ln},version:{enumerable:no,value:"3.4.1"},getChart:{enumerable:no,value:to},register:{enumerable:no,value:(...t)=>{Ln.add(...t),io()}},unregister:{enumerable:no,value:(...t)=>{Ln.remove(...t),io()}}});class so{constructor(t){this.options=t||{}}formats(){return oo()}parse(t,e){return oo()}format(t,e){return oo()}add(t,e,i){return oo()}diff(t,e,i){return oo()}startOf(t,e,i){return oo()}endOf(t,e){return oo()}}so.override=function(t){Object.assign(so.prototype,t)};var ao={_date:so};function ro(t){const e=function(t){if(!t._cache.$bar){const e=t.getMatchingVisibleMetas("bar");let i=[];for(let n=0,o=e.length;n<o;n++)i=i.concat(e[n].controller.getAllParsedValues(t));t._cache.$bar=de(i.sort(((t,e)=>t-e)))}return t._cache.$bar}(t);let i,n,o,s,a=t._length;const r=()=>{32767!==o&&-32768!==o&&(ht(s)&&(a=Math.min(a,Math.abs(o-s)||a)),s=o)};for(i=0,n=e.length;i<n;++i)o=t.getPixelForValue(e[i]),r();for(s=void 0,i=0,n=t.ticks.length;i<n;++i)o=t.getPixelForTick(i),r();return a}function lo(t,e,i,n){return Y(t)?function(t,e,i,n){const o=i.parse(t[0],n),s=i.parse(t[1],n),a=Math.min(o,s),r=Math.max(o,s);let l=a,c=r;Math.abs(a)>Math.abs(r)&&(l=r,c=a),e[i.axis]=c,e._custom={barStart:l,barEnd:c,start:o,end:s,min:a,max:r}}(t,e,i,n):e[i.axis]=i.parse(t,n),e}function co(t,e,i,n){const o=t.iScale,s=t.vScale,a=o.getLabels(),r=o===s,l=[];let c,h,d,u;for(c=i,h=i+n;c<h;++c)u=e[c],d={},d[o.axis]=r||o.parse(a[c],c),l.push(lo(u,d,s,c));return l}function ho(t){return t&&void 0!==t.barStart&&void 0!==t.barEnd}class uo extends Ei{parsePrimitiveData(t,e,i,n){return co(t,e,i,n)}parseArrayData(t,e,i,n){return co(t,e,i,n)}parseObjectData(t,e,i,n){const{iScale:o,vScale:s}=t,{xAxisKey:a="x",yAxisKey:r="y"}=this._parsing,l="x"===o.axis?a:r,c="x"===s.axis?a:r,h=[];let d,u,f,g;for(d=i,u=i+n;d<u;++d)g=e[d],f={},f[o.axis]=o.parse(lt(g,l),d),h.push(lo(lt(g,c),f,s,d));return h}updateRangeFromParsed(t,e,i,n){super.updateRangeFromParsed(t,e,i,n);const o=i._custom;o&&e===this._cachedMeta.vScale&&(t.min=Math.min(t.min,o.min),t.max=Math.max(t.max,o.max))}getMaxOverflow(){return 0}getLabelAndValue(t){const e=this._cachedMeta,{iScale:i,vScale:n}=e,o=this.getParsed(t),s=o._custom,a=ho(s)?"["+s.start+", "+s.end+"]":""+n.getLabelForValue(o[n.axis]);return{label:""+i.getLabelForValue(o[i.axis]),value:a}}initialize(){const t=this;t.enableOptionSharing=!0,super.initialize();t._cachedMeta.stack=t.getDataset().stack}update(t){const e=this._cachedMeta;this.updateElements(e.data,0,e.data.length,t)}updateElements(t,e,i,n){const o=this,s="reset"===n,a=o._cachedMeta.vScale,r=a.getBasePixel(),l=a.isHorizontal(),c=o._getRuler(),h=o.resolveDataElementOptions(e,n),d=o.getSharedOptions(h),u=o.includeOptions(n,d);o.updateSharedOptions(d,n,h);for(let h=e;h<e+i;h++){const e=o.getParsed(h),i=s||$(e[a.axis])?{base:r,head:r}:o._calculateBarValuePixels(h),f=o._calculateBarIndexPixels(h,c),g=(e._stacks||{})[a.axis],p={horizontal:l,base:i.base,enableBorderRadius:!g||ho(e._custom)||o.index===g._top||o.index===g._bottom,x:l?i.head:f.center,y:l?f.center:i.head,height:l?f.size:Math.abs(i.size),width:l?Math.abs(i.size):f.size};u&&(p.options=d||o.resolveDataElementOptions(h,t[h].active?"active":n)),o.updateElement(t[h],h,p,n)}}_getStacks(t,e){const i=this._cachedMeta.iScale,n=i.getMatchingVisibleMetas(this._type),o=i.options.stacked,s=n.length,a=[];let r,l;for(r=0;r<s;++r)if(l=n[r],l.controller.options.grouped){if(void 0!==e){const t=l.controller.getParsed(e)[l.controller._cachedMeta.vScale.axis];if($(t)||isNaN(t))continue}if((!1===o||-1===a.indexOf(l.stack)||void 0===o&&void 0===l.stack)&&a.push(l.stack),l.index===t)break}return a.length||a.push(void 0),a}_getStackCount(t){return this._getStacks(void 0,t).length}_getStackIndex(t,e,i){const n=this._getStacks(t,i),o=void 0!==e?n.indexOf(e):-1;return-1===o?n.length-1:o}_getRuler(){const t=this,e=t.options,i=t._cachedMeta,n=i.iScale,o=[];let s,a;for(s=0,a=i.data.length;s<a;++s)o.push(n.getPixelForValue(t.getParsed(s)[n.axis],s));const r=e.barThickness;return{min:r||ro(n),pixels:o,start:n._startPixel,end:n._endPixel,stackCount:t._getStackCount(),scale:n,grouped:e.grouped,ratio:r?1:e.categoryPercentage*e.barPercentage}}_calculateBarValuePixels(t){const e=this,{vScale:i,_stacked:n}=e._cachedMeta,{base:o,minBarLength:s}=e.options,a=e.getParsed(t),r=a._custom,l=ho(r);let c,h,d=a[i.axis],u=0,f=n?e.applyStack(i,a,n):d;f!==d&&(u=f-d,f=d),l&&(d=r.barStart,f=r.barEnd-r.barStart,0!==d&&Dt(d)!==Dt(r.barEnd)&&(u=0),u+=d);const g=$(o)||l?u:o;let p=i.getPixelForValue(g);c=this.chart.getDataVisibility(t)?i.getPixelForValue(u+f):p,h=c-p,void 0!==s&&Math.abs(h)<s&&(h=h<0?-s:s,0===d&&(p-=h/2),c=p+h);const m=o||0;if(p===i.getPixelForValue(m)){const t=i.getLineWidthForValue(m)/2;h>0?(p+=t,h-=t):h<0&&(p-=t,h+=t)}return{size:h,base:p,head:c,center:c+h/2}}_calculateBarIndexPixels(t,e){const i=this,n=e.scale,o=i.options,s=o.skipNull,a=K(o.maxBarThickness,1/0);let r,l;if(e.grouped){const n=s?i._getStackCount(t):e.stackCount,c="flex"===o.barThickness?function(t,e,i,n){const o=e.pixels,s=o[t];let a=t>0?o[t-1]:null,r=t<o.length-1?o[t+1]:null;const l=i.categoryPercentage;null===a&&(a=s-(null===r?e.end-e.start:r-s)),null===r&&(r=s+s-a);const c=s-(s-Math.min(a,r))/2*l;return{chunk:Math.abs(r-a)/2*l/n,ratio:i.barPercentage,start:c}}(t,e,o,n):function(t,e,i,n){const o=i.barThickness;let s,a;return $(o)?(s=e.min*i.categoryPercentage,a=i.barPercentage):(s=o*n,a=1),{chunk:s/n,ratio:a,start:e.pixels[t]-s/2}}(t,e,o,n),h=i._getStackIndex(i.index,i._cachedMeta.stack,s?t:void 0);r=c.start+c.chunk*h+c.chunk/2,l=Math.min(a,c.chunk*c.ratio)}else r=n.getPixelForValue(i.getParsed(t)[n.axis],t),l=Math.min(a,e.min*e.ratio);return{base:r-l/2,head:r+l/2,center:r,size:l}}draw(){const t=this,e=t._cachedMeta,i=e.vScale,n=e.data,o=n.length;let s=0;for(;s<o;++s)null!==t.getParsed(s)[i.axis]&&n[s].draw(t._ctx)}}uo.id="bar",uo.defaults={datasetElementType:!1,dataElementType:"bar",categoryPercentage:.8,barPercentage:.9,grouped:!0,animations:{numbers:{type:"number",properties:["x","y","base","width","height"]}}},uo.overrides={interaction:{mode:"index"},scales:{_index_:{type:"category",offset:!0,grid:{offset:!0}},_value_:{type:"linear",beginAtZero:!0}}};class fo extends Ei{initialize(){this.enableOptionSharing=!0,super.initialize()}parseObjectData(t,e,i,n){const{xScale:o,yScale:s}=t,{xAxisKey:a="x",yAxisKey:r="y"}=this._parsing,l=[];let c,h,d;for(c=i,h=i+n;c<h;++c)d=e[c],l.push({x:o.parse(lt(d,a),c),y:s.parse(lt(d,r),c),_custom:d&&d.r&&+d.r});return l}getMaxOverflow(){const{data:t,_parsed:e}=this._cachedMeta;let i=0;for(let n=t.length-1;n>=0;--n)i=Math.max(i,t[n].size()/2,e[n]._custom);return i>0&&i}getLabelAndValue(t){const e=this._cachedMeta,{xScale:i,yScale:n}=e,o=this.getParsed(t),s=i.getLabelForValue(o.x),a=n.getLabelForValue(o.y),r=o._custom;return{label:e.label,value:"("+s+", "+a+(r?", "+r:"")+")"}}update(t){const e=this._cachedMeta.data;this.updateElements(e,0,e.length,t)}updateElements(t,e,i,n){const o=this,s="reset"===n,{iScale:a,vScale:r}=o._cachedMeta,l=o.resolveDataElementOptions(e,n),c=o.getSharedOptions(l),h=o.includeOptions(n,c),d=a.axis,u=r.axis;for(let l=e;l<e+i;l++){const e=t[l],i=!s&&o.getParsed(l),c={},f=c[d]=s?a.getPixelForDecimal(.5):a.getPixelForValue(i[d]),g=c[u]=s?r.getBasePixel():r.getPixelForValue(i[u]);c.skip=isNaN(f)||isNaN(g),h&&(c.options=o.resolveDataElementOptions(l,e.active?"active":n),s&&(c.options.radius=0)),o.updateElement(e,l,c,n)}o.updateSharedOptions(c,n,l)}resolveDataElementOptions(t,e){const i=this.getParsed(t);let n=super.resolveDataElementOptions(t,e);n.$shared&&(n=Object.assign({},n,{$shared:!1}));const o=n.radius;return"active"!==e&&(n.radius=0),n.radius+=K(i&&i._custom,o),n}}fo.id="bubble",fo.defaults={datasetElementType:!1,dataElementType:"point",animations:{numbers:{type:"number",properties:["x","y","borderWidth","radius"]}}},fo.overrides={scales:{x:{type:"linear"},y:{type:"linear"}},plugins:{tooltip:{callbacks:{title:()=>""}}}};class go extends Ei{constructor(t,e){super(t,e),this.enableOptionSharing=!0,this.innerRadius=void 0,this.outerRadius=void 0,this.offsetX=void 0,this.offsetY=void 0}linkScales(){}parse(t,e){const i=this.getDataset().data,n=this._cachedMeta;let o,s;for(o=t,s=t+e;o<s;++o)n._parsed[o]=+i[o]}_getRotation(){return Et(this.options.rotation-90)}_getCircumference(){return Et(this.options.circumference)}_getRotationExtents(){let t=_t,e=-_t;const i=this;for(let n=0;n<i.chart.data.datasets.length;++n)if(i.chart.isDatasetVisible(n)){const o=i.chart.getDatasetMeta(n).controller,s=o._getRotation(),a=o._getCircumference();t=Math.min(t,s),e=Math.max(e,s+a)}return{rotation:t,circumference:e-t}}update(t){const e=this,i=e.chart,{chartArea:n}=i,o=e._cachedMeta,s=o.data,a=e.getMaxBorderWidth()+e.getMaxOffset(s)+e.options.spacing,r=Math.max((Math.min(n.width,n.height)-a)/2,0),l=Math.min(G(e.options.cutout,r),1),c=e._getRingWeight(e.index),{circumference:h,rotation:d}=e._getRotationExtents(),{ratioX:u,ratioY:f,offsetX:g,offsetY:p}=function(t,e,i){let n=1,o=1,s=0,a=0;if(e<_t){const r=t,l=r+e,c=Math.cos(r),h=Math.sin(r),d=Math.cos(l),u=Math.sin(l),f=(t,e,n)=>Nt(t,r,l,!0)?1:Math.max(e,e*i,n,n*i),g=(t,e,n)=>Nt(t,r,l,!0)?-1:Math.min(e,e*i,n,n*i),p=f(0,c,d),m=f(Mt,h,u),x=g(bt,c,d),b=g(bt+Mt,h,u);n=(p-x)/2,o=(m-b)/2,s=-(p+x)/2,a=-(m+b)/2}return{ratioX:n,ratioY:o,offsetX:s,offsetY:a}}(d,h,l),m=(n.width-a)/u,x=(n.height-a)/f,b=Math.max(Math.min(m,x)/2,0),_=Z(e.options.radius,b),y=(_-Math.max(_*l,0))/e._getVisibleDatasetWeightTotal();e.offsetX=g*_,e.offsetY=p*_,o.total=e.calculateTotal(),e.outerRadius=_-y*e._getRingWeightOffset(e.index),e.innerRadius=Math.max(e.outerRadius-y*c,0),e.updateElements(s,0,s.length,t)}_circumference(t,e){const i=this,n=i.options,o=i._cachedMeta,s=i._getCircumference();return e&&n.animation.animateRotate||!this.chart.getDataVisibility(t)||null===o._parsed[t]?0:i.calculateCircumference(o._parsed[t]*s/_t)}updateElements(t,e,i,n){const o=this,s="reset"===n,a=o.chart,r=a.chartArea,l=a.options.animation,c=(r.left+r.right)/2,h=(r.top+r.bottom)/2,d=s&&l.animateScale,u=d?0:o.innerRadius,f=d?0:o.outerRadius,g=o.resolveDataElementOptions(e,n),p=o.getSharedOptions(g),m=o.includeOptions(n,p);let x,b=o._getRotation();for(x=0;x<e;++x)b+=o._circumference(x,s);for(x=e;x<e+i;++x){const e=o._circumference(x,s),i=t[x],a={x:c+o.offsetX,y:h+o.offsetY,startAngle:b,endAngle:b+e,circumference:e,outerRadius:f,innerRadius:u};m&&(a.options=p||o.resolveDataElementOptions(x,i.active?"active":n)),b+=e,o.updateElement(i,x,a,n)}o.updateSharedOptions(p,n,g)}calculateTotal(){const t=this._cachedMeta,e=t.data;let i,n=0;for(i=0;i<e.length;i++){const e=t._parsed[i];null!==e&&!isNaN(e)&&this.chart.getDataVisibility(i)&&(n+=Math.abs(e))}return n}calculateCircumference(t){const e=this._cachedMeta.total;return e>0&&!isNaN(t)?_t*(Math.abs(t)/e):0}getLabelAndValue(t){const e=this._cachedMeta,i=this.chart,n=i.data.labels||[],o=Fi(e._parsed[t],i.options.locale);return{label:n[t]||"",value:o}}getMaxBorderWidth(t){const e=this;let i=0;const n=e.chart;let o,s,a,r,l;if(!t)for(o=0,s=n.data.datasets.length;o<s;++o)if(n.isDatasetVisible(o)){a=n.getDatasetMeta(o),t=a.data,r=a.controller,r!==e&&r.configure();break}if(!t)return 0;for(o=0,s=t.length;o<s;++o)l=r.resolveDataElementOptions(o),"inner"!==l.borderAlign&&(i=Math.max(i,l.borderWidth||0,l.hoverBorderWidth||0));return i}getMaxOffset(t){let e=0;for(let i=0,n=t.length;i<n;++i){const t=this.resolveDataElementOptions(i);e=Math.max(e,t.offset||0,t.hoverOffset||0)}return e}_getRingWeightOffset(t){let e=0;for(let i=0;i<t;++i)this.chart.isDatasetVisible(i)&&(e+=this._getRingWeight(i));return e}_getRingWeight(t){return Math.max(K(this.chart.data.datasets[t].weight,1),0)}_getVisibleDatasetWeightTotal(){return this._getRingWeightOffset(this.chart.data.datasets.length)||1}}go.id="doughnut",go.defaults={datasetElementType:!1,dataElementType:"arc",animation:{animateRotate:!0,animateScale:!1},animations:{numbers:{type:"number",properties:["circumference","endAngle","innerRadius","outerRadius","startAngle","x","y","offset","borderWidth","spacing"]}},cutout:"50%",rotation:0,circumference:360,radius:"100%",spacing:0,indexAxis:"r"},go.descriptors={_scriptable:t=>"spacing"!==t,_indexable:t=>"spacing"!==t},go.overrides={aspectRatio:1,plugins:{legend:{labels:{generateLabels(t){const e=t.data;if(e.labels.length&&e.datasets.length){const{labels:{pointStyle:i}}=t.legend.options;return e.labels.map(((e,n)=>{const o=t.getDatasetMeta(0).controller.getStyle(n);return{text:e,fillStyle:o.backgroundColor,strokeStyle:o.borderColor,lineWidth:o.borderWidth,pointStyle:i,hidden:!t.getDataVisibility(n),index:n}}))}return[]}},onClick(t,e,i){i.chart.toggleDataVisibility(e.index),i.chart.update()}},tooltip:{callbacks:{title:()=>"",label(t){let e=t.label;const i=": "+t.formattedValue;return Y(e)?(e=e.slice(),e[0]+=i):e+=i,e}}}}};class po extends Ei{initialize(){this.enableOptionSharing=!0,super.initialize()}update(t){const e=this,i=e._cachedMeta,{dataset:n,data:o=[],_dataset:s}=i,a=e.chart._animationsDisabled;let{start:r,count:l}=function(t,e,i){const n=e.length;let o=0,s=n;if(t._sorted){const{iScale:a,_parsed:r}=t,l=a.axis,{min:c,max:h,minDefined:d,maxDefined:u}=a.getUserBounds();d&&(o=Ht(Math.min(se(r,a.axis,c).lo,i?n:se(e,l,a.getPixelForValue(c)).lo),0,n-1)),s=u?Ht(Math.max(se(r,a.axis,h).hi+1,i?0:se(e,l,a.getPixelForValue(h)).hi+1),o,n)-o:n-o}return{start:o,count:s}}(i,o,a);e._drawStart=r,e._drawCount=l,function(t){const{xScale:e,yScale:i,_scaleRanges:n}=t,o={xmin:e.min,xmax:e.max,ymin:i.min,ymax:i.max};if(!n)return t._scaleRanges=o,!0;const s=n.xmin!==e.min||n.xmax!==e.max||n.ymin!==i.min||n.ymax!==i.max;return Object.assign(n,o),s}(i)&&(r=0,l=o.length),n._decimated=!!s._decimated,n.points=o;const c=e.resolveDatasetElementOptions(t);e.options.showLine||(c.borderWidth=0),c.segment=e.options.segment,e.updateElement(n,void 0,{animated:!a,options:c},t),e.updateElements(o,r,l,t)}updateElements(t,e,i,n){const o=this,s="reset"===n,{iScale:a,vScale:r,_stacked:l}=o._cachedMeta,c=o.resolveDataElementOptions(e,n),h=o.getSharedOptions(c),d=o.includeOptions(n,h),u=a.axis,f=r.axis,g=o.options.spanGaps,p=Tt(g)?g:Number.POSITIVE_INFINITY,m=o.chart._animationsDisabled||s||"none"===n;let x=e>0&&o.getParsed(e-1);for(let c=e;c<e+i;++c){const e=t[c],i=o.getParsed(c),g=m?e:{},b=$(i[f]),_=g[u]=a.getPixelForValue(i[u],c),y=g[f]=s||b?r.getBasePixel():r.getPixelForValue(l?o.applyStack(r,i,l):i[f],c);g.skip=isNaN(_)||isNaN(y)||b,g.stop=c>0&&i[u]-x[u]>p,g.parsed=i,d&&(g.options=h||o.resolveDataElementOptions(c,e.active?"active":n)),m||o.updateElement(e,c,g,n),x=i}o.updateSharedOptions(h,n,c)}getMaxOverflow(){const t=this,e=t._cachedMeta,i=e.dataset,n=i.options&&i.options.borderWidth||0,o=e.data||[];if(!o.length)return n;const s=o[0].size(t.resolveDataElementOptions(0)),a=o[o.length-1].size(t.resolveDataElementOptions(o.length-1));return Math.max(n,s,a)/2}draw(){const t=this._cachedMeta;t.dataset.updateControlPoints(this.chart.chartArea,t.iScale.axis),super.draw()}}po.id="line",po.defaults={datasetElementType:"line",dataElementType:"point",showLine:!0,spanGaps:!1},po.overrides={scales:{_index_:{type:"category"},_value_:{type:"linear"}}};class mo extends Ei{constructor(t,e){super(t,e),this.innerRadius=void 0,this.outerRadius=void 0}getLabelAndValue(t){const e=this._cachedMeta,i=this.chart,n=i.data.labels||[],o=Fi(e._parsed[t].r,i.options.locale);return{label:n[t]||"",value:o}}update(t){const e=this._cachedMeta.data;this._updateRadius(),this.updateElements(e,0,e.length,t)}_updateRadius(){const t=this,e=t.chart,i=e.chartArea,n=e.options,o=Math.min(i.right-i.left,i.bottom-i.top),s=Math.max(o/2,0),a=(s-Math.max(n.cutoutPercentage?s/100*n.cutoutPercentage:1,0))/e.getVisibleDatasetCount();t.outerRadius=s-a*t.index,t.innerRadius=t.outerRadius-a}updateElements(t,e,i,n){const o=this,s="reset"===n,a=o.chart,r=o.getDataset(),l=a.options.animation,c=o._cachedMeta.rScale,h=c.xCenter,d=c.yCenter,u=c.getIndexAngle(0)-.5*bt;let f,g=u;const p=360/o.countVisibleElements();for(f=0;f<e;++f)g+=o._computeAngle(f,n,p);for(f=e;f<e+i;f++){const e=t[f];let i=g,m=g+o._computeAngle(f,n,p),x=a.getDataVisibility(f)?c.getDistanceFromCenterForValue(r.data[f]):0;g=m,s&&(l.animateScale&&(x=0),l.animateRotate&&(i=m=u));const b={x:h,y:d,innerRadius:0,outerRadius:x,startAngle:i,endAngle:m,options:o.resolveDataElementOptions(f,e.active?"active":n)};o.updateElement(e,f,b,n)}}countVisibleElements(){const t=this.getDataset(),e=this._cachedMeta;let i=0;return e.data.forEach(((e,n)=>{!isNaN(t.data[n])&&this.chart.getDataVisibility(n)&&i++})),i}_computeAngle(t,e,i){return this.chart.getDataVisibility(t)?Et(this.resolveDataElementOptions(t,e).angle||i):0}}mo.id="polarArea",mo.defaults={dataElementType:"arc",animation:{animateRotate:!0,animateScale:!0},animations:{numbers:{type:"number",properties:["x","y","startAngle","endAngle","innerRadius","outerRadius"]}},indexAxis:"r",startAngle:0},mo.overrides={aspectRatio:1,plugins:{legend:{labels:{generateLabels(t){const e=t.data;if(e.labels.length&&e.datasets.length){const{labels:{pointStyle:i}}=t.legend.options;return e.labels.map(((e,n)=>{const o=t.getDatasetMeta(0).controller.getStyle(n);return{text:e,fillStyle:o.backgroundColor,strokeStyle:o.borderColor,lineWidth:o.borderWidth,pointStyle:i,hidden:!t.getDataVisibility(n),index:n}}))}return[]}},onClick(t,e,i){i.chart.toggleDataVisibility(e.index),i.chart.update()}},tooltip:{callbacks:{title:()=>"",label:t=>t.chart.data.labels[t.dataIndex]+": "+t.formattedValue}}},scales:{r:{type:"radialLinear",angleLines:{display:!1},beginAtZero:!0,grid:{circular:!0},pointLabels:{display:!1},startAngle:0}}};class xo extends go{}xo.id="pie",xo.defaults={cutout:0,rotation:0,circumference:360,radius:"100%"};class bo extends Ei{getLabelAndValue(t){const e=this._cachedMeta.vScale,i=this.getParsed(t);return{label:e.getLabels()[t],value:""+e.getLabelForValue(i[e.axis])}}update(t){const e=this,i=e._cachedMeta,n=i.dataset,o=i.data||[],s=i.iScale.getLabels();if(n.points=o,"resize"!==t){const i=e.resolveDatasetElementOptions(t);e.options.showLine||(i.borderWidth=0);const a={_loop:!0,_fullLoop:s.length===o.length,options:i};e.updateElement(n,void 0,a,t)}e.updateElements(o,0,o.length,t)}updateElements(t,e,i,n){const o=this,s=o.getDataset(),a=o._cachedMeta.rScale,r="reset"===n;for(let l=e;l<e+i;l++){const e=t[l],i=o.resolveDataElementOptions(l,e.active?"active":n),c=a.getPointPositionForValue(l,s.data[l]),h=r?a.xCenter:c.x,d=r?a.yCenter:c.y,u={x:h,y:d,angle:c.angle,skip:isNaN(h)||isNaN(d),options:i};o.updateElement(e,l,u,n)}}}bo.id="radar",bo.defaults={datasetElementType:"line",dataElementType:"point",indexAxis:"r",showLine:!0,elements:{line:{fill:"start"}}},bo.overrides={aspectRatio:1,scales:{r:{type:"radialLinear"}}};class _o extends po{}_o.id="scatter",_o.defaults={showLine:!1,fill:!1},_o.overrides={interaction:{mode:"point"},plugins:{tooltip:{callbacks:{title:()=>"",label:t=>"("+t.label+", "+t.formattedValue+")"}}},scales:{x:{type:"linear"},y:{type:"linear"}}};var yo=Object.freeze({__proto__:null,BarController:uo,BubbleController:fo,DoughnutController:go,LineController:po,PolarAreaController:mo,PieController:xo,RadarController:bo,ScatterController:_o});function vo(t,e,i){const{startAngle:n,pixelMargin:o,x:s,y:a,outerRadius:r,innerRadius:l}=e;let c=o/r;t.beginPath(),t.arc(s,a,r,n-c,i+c),l>o?(c=o/l,t.arc(s,a,l,i+c,n-c,!0)):t.arc(s,a,o,i+Mt,n-Mt),t.closePath(),t.clip()}function wo(t,e,i,n){const o=Ee(t.options.borderRadius,["outerStart","outerEnd","innerStart","innerEnd"]);const s=(i-e)/2,a=Math.min(s,n*e/2),r=t=>{const e=(i-Math.min(s,t))*n/2;return Ht(t,0,Math.min(s,e))};return{outerStart:r(o.outerStart),outerEnd:r(o.outerEnd),innerStart:Ht(o.innerStart,0,a),innerEnd:Ht(o.innerEnd,0,a)}}function Mo(t,e,i,n){return{x:i+t*Math.cos(e),y:n+t*Math.sin(e)}}function ko(t,e,i,n,o){const{x:s,y:a,startAngle:r,pixelMargin:l,innerRadius:c}=e,h=Math.max(e.outerRadius+n+i-l,0),d=c>0?c+n+i+l:0;let u=0;const f=o-r;if(n){const t=((c>0?c-n:0)+(h>0?h-n:0))/2;u=(f-(0!==t?f*t/(t+n):f))/2}const g=(f-Math.max(.001,f*h-i/bt)/h)/2,p=r+g+u,m=o-g-u,{outerStart:x,outerEnd:b,innerStart:_,innerEnd:y}=wo(e,d,h,m-p),v=h-x,w=h-b,M=p+x/v,k=m-b/w,S=d+_,P=d+y,D=p+_/S,C=m-y/P;if(t.beginPath(),t.arc(s,a,h,M,k),b>0){const e=Mo(w,k,s,a);t.arc(e.x,e.y,b,k,m+Mt)}const O=Mo(P,m,s,a);if(t.lineTo(O.x,O.y),y>0){const e=Mo(P,C,s,a);t.arc(e.x,e.y,y,m+Mt,C+Math.PI)}if(t.arc(s,a,d,m-y/d,p+_/d,!0),_>0){const e=Mo(S,D,s,a);t.arc(e.x,e.y,_,D+Math.PI,p-Mt)}const T=Mo(v,p,s,a);if(t.lineTo(T.x,T.y),x>0){const e=Mo(v,M,s,a);t.arc(e.x,e.y,x,p-Mt,M)}t.closePath()}function So(t,e,i,n,o){const{options:s}=e,a="inner"===s.borderAlign;s.borderWidth&&(a?(t.lineWidth=2*s.borderWidth,t.lineJoin="round"):(t.lineWidth=s.borderWidth,t.lineJoin="bevel"),e.fullCircles&&function(t,e,i){const{x:n,y:o,startAngle:s,pixelMargin:a,fullCircles:r}=e,l=Math.max(e.outerRadius-a,0),c=e.innerRadius+a;let h;for(i&&vo(t,e,s+_t),t.beginPath(),t.arc(n,o,c,s+_t,s,!0),h=0;h<r;++h)t.stroke();for(t.beginPath(),t.arc(n,o,l,s,s+_t),h=0;h<r;++h)t.stroke()}(t,e,a),a&&vo(t,e,o),ko(t,e,i,n,o),t.stroke())}class Po extends zi{constructor(t){super(),this.options=void 0,this.circumference=void 0,this.startAngle=void 0,this.endAngle=void 0,this.innerRadius=void 0,this.outerRadius=void 0,this.pixelMargin=0,this.fullCircles=0,t&&Object.assign(this,t)}inRange(t,e,i){const n=this.getProps(["x","y"],i),{angle:o,distance:s}=Ft(n,{x:t,y:e}),{startAngle:a,endAngle:r,innerRadius:l,outerRadius:c,circumference:h}=this.getProps(["startAngle","endAngle","innerRadius","outerRadius","circumference"],i),d=this.options.spacing/2;return(h>=_t||Nt(o,a,r))&&(s>=l+d&&s<=c+d)}getCenterPoint(t){const{x:e,y:i,startAngle:n,endAngle:o,innerRadius:s,outerRadius:a}=this.getProps(["x","y","startAngle","endAngle","innerRadius","outerRadius","circumference"],t),{offset:r,spacing:l}=this.options,c=(n+o)/2,h=(s+a+l+r)/2;return{x:e+Math.cos(c)*h,y:i+Math.sin(c)*h}}tooltipPosition(t){return this.getCenterPoint(t)}draw(t){const e=this,{options:i,circumference:n}=e,o=(i.offset||0)/2,s=(i.spacing||0)/2;if(e.pixelMargin="inner"===i.borderAlign?.33:0,e.fullCircles=n>_t?Math.floor(n/_t):0,0===n||e.innerRadius<0||e.outerRadius<0)return;t.save();let a=0;if(o){a=o/2;const i=(e.startAngle+e.endAngle)/2;t.translate(Math.cos(i)*a,Math.sin(i)*a),e.circumference>=bt&&(a=o)}t.fillStyle=i.backgroundColor,t.strokeStyle=i.borderColor;const r=function(t,e,i,n){const{fullCircles:o,startAngle:s,circumference:a}=e;let r=e.endAngle;if(o){ko(t,e,i,n,s+_t);for(let e=0;e<o;++e)t.fill();isNaN(a)||(r=s+a%_t,a%_t==0&&(r+=_t))}return ko(t,e,i,n,r),t.fill(),r}(t,e,a,s);So(t,e,a,s,r),t.restore()}}function Do(t,e,i=e){t.lineCap=K(i.borderCapStyle,e.borderCapStyle),t.setLineDash(K(i.borderDash,e.borderDash)),t.lineDashOffset=K(i.borderDashOffset,e.borderDashOffset),t.lineJoin=K(i.borderJoinStyle,e.borderJoinStyle),t.lineWidth=K(i.borderWidth,e.borderWidth),t.strokeStyle=K(i.borderColor,e.borderColor)}function Co(t,e,i){t.lineTo(i.x,i.y)}function Oo(t,e,i={}){const n=t.length,{start:o=0,end:s=n-1}=i,{start:a,end:r}=e,l=Math.max(o,a),c=Math.min(s,r),h=o<a&&s<a||o>r&&s>r;return{count:n,start:l,loop:e.loop,ilen:c<l&&!h?n+c-l:c-l}}function To(t,e,i,n){const{points:o,options:s}=e,{count:a,start:r,loop:l,ilen:c}=Oo(o,i,n),h=function(t){return t.stepped?Jt:t.tension||"monotone"===t.cubicInterpolationMode?te:Co}(s);let d,u,f,{move:g=!0,reverse:p}=n||{};for(d=0;d<=c;++d)u=o[(r+(p?c-d:d))%a],u.skip||(g?(t.moveTo(u.x,u.y),g=!1):h(t,f,u,p,s.stepped),f=u);return l&&(u=o[(r+(p?c:0))%a],h(t,f,u,p,s.stepped)),!!l}function Ao(t,e,i,n){const o=e.points,{count:s,start:a,ilen:r}=Oo(o,i,n),{move:l=!0,reverse:c}=n||{};let h,d,u,f,g,p,m=0,x=0;const b=t=>(a+(c?r-t:t))%s,_=()=>{f!==g&&(t.lineTo(m,g),t.lineTo(m,f),t.lineTo(m,p))};for(l&&(d=o[b(0)],t.moveTo(d.x,d.y)),h=0;h<=r;++h){if(d=o[b(h)],d.skip)continue;const e=d.x,i=d.y,n=0|e;n===u?(i<f?f=i:i>g&&(g=i),m=(x*m+e)/++x):(_(),t.lineTo(e,i),u=n,x=0,f=g=i),p=i}_()}function Lo(t){const e=t.options,i=e.borderDash&&e.borderDash.length;return!(t._decimated||t._loop||e.tension||"monotone"===e.cubicInterpolationMode||e.stepped||i)?Ao:To}Po.id="arc",Po.defaults={borderAlign:"center",borderColor:"#fff",borderRadius:0,borderWidth:2,offset:0,spacing:0,angle:void 0},Po.defaultRoutes={backgroundColor:"backgroundColor"};const Ro="function"==typeof Path2D;function Eo(t,e,i,n){Ro&&1===e.segments.length?function(t,e,i,n){let o=e._path;o||(o=e._path=new Path2D,e.path(o,i,n)&&o.closePath()),Do(t,e.options),t.stroke(o)}(t,e,i,n):function(t,e,i,n){const{segments:o,options:s}=e,a=Lo(e);for(const r of o)Do(t,s,r.style),t.beginPath(),a(t,e,r,{start:i,end:i+n-1})&&t.closePath(),t.stroke()}(t,e,i,n)}class zo extends zi{constructor(t){super(),this.animated=!0,this.options=void 0,this._loop=void 0,this._fullLoop=void 0,this._path=void 0,this._points=void 0,this._segments=void 0,this._decimated=!1,this._pointsUpdated=!1,t&&Object.assign(this,t)}updateControlPoints(t,e){const i=this,n=i.options;if((n.tension||"monotone"===n.cubicInterpolationMode)&&!n.stepped&&!i._pointsUpdated){const o=n.spanGaps?i._loop:i._fullLoop;pn(i._points,n,t,o,e),i._pointsUpdated=!0}}set points(t){const e=this;e._points=t,delete e._segments,delete e._path,e._pointsUpdated=!1}get points(){return this._points}get segments(){return this._segments||(this._segments=Pn(this,this.options.segment))}first(){const t=this.segments,e=this.points;return t.length&&e[t[0].start]}last(){const t=this.segments,e=this.points,i=t.length;return i&&e[t[i-1].end]}interpolate(t,e){const i=this,n=i.options,o=t[e],s=i.points,a=Sn(i,{property:e,start:o,end:o});if(!a.length)return;const r=[],l=function(t){return t.stepped?xn:t.tension||"monotone"===t.cubicInterpolationMode?bn:mn}(n);let c,h;for(c=0,h=a.length;c<h;++c){const{start:i,end:h}=a[c],d=s[i],u=s[h];if(d===u){r.push(d);continue}const f=l(d,u,Math.abs((o-d[e])/(u[e]-d[e])),n.stepped);f[e]=t[e],r.push(f)}return 1===r.length?r[0]:r}pathSegment(t,e,i){return Lo(this)(t,this,e,i)}path(t,e,i){const n=this,o=n.segments,s=Lo(n);let a=n._loop;e=e||0,i=i||n.points.length-e;for(const r of o)a&=s(t,n,r,{start:e,end:e+i-1});return!!a}draw(t,e,i,n){const o=this,s=o.options||{};(o.points||[]).length&&s.borderWidth&&(t.save(),Eo(t,o,i,n),t.restore(),o.animated&&(o._pointsUpdated=!1,o._path=void 0))}}function Io(t,e,i,n){const o=t.options,{[i]:s}=t.getProps([i],n);return Math.abs(e-s)<o.radius+o.hitRadius}zo.id="line",zo.defaults={borderCapStyle:"butt",borderDash:[],borderDashOffset:0,borderJoinStyle:"miter",borderWidth:3,capBezierPoints:!0,cubicInterpolationMode:"default",fill:!1,spanGaps:!1,stepped:!1,tension:0},zo.defaultRoutes={backgroundColor:"backgroundColor",borderColor:"borderColor"},zo.descriptors={_scriptable:!0,_indexable:t=>"borderDash"!==t&&"fill"!==t};class Fo extends zi{constructor(t){super(),this.options=void 0,this.parsed=void 0,this.skip=void 0,this.stop=void 0,t&&Object.assign(this,t)}inRange(t,e,i){const n=this.options,{x:o,y:s}=this.getProps(["x","y"],i);return Math.pow(t-o,2)+Math.pow(e-s,2)<Math.pow(n.hitRadius+n.radius,2)}inXRange(t,e){return Io(this,t,"x",e)}inYRange(t,e){return Io(this,t,"y",e)}getCenterPoint(t){const{x:e,y:i}=this.getProps(["x","y"],t);return{x:e,y:i}}size(t){let e=(t=t||this.options||{}).radius||0;e=Math.max(e,e&&t.hoverRadius||0);return 2*(e+(e&&t.borderWidth||0))}draw(t){const e=this,i=e.options;e.skip||i.radius<.1||(t.strokeStyle=i.borderColor,t.lineWidth=i.borderWidth,t.fillStyle=i.backgroundColor,Kt(t,i,e.x,e.y))}getRange(){const t=this.options||{};return t.radius+t.hitRadius}}function Bo(t,e){const{x:i,y:n,base:o,width:s,height:a}=t.getProps(["x","y","base","width","height"],e);let r,l,c,h,d;return t.horizontal?(d=a/2,r=Math.min(i,o),l=Math.max(i,o),c=n-d,h=n+d):(d=s/2,r=i-d,l=i+d,c=Math.min(n,o),h=Math.max(n,o)),{left:r,top:c,right:l,bottom:h}}function Vo(t){let e=t.options.borderSkipped;const i={};return e?(e=t.horizontal?Wo(e,"left","right",t.base>t.x):Wo(e,"bottom","top",t.base<t.y),i[e]=!0,i):i}function Wo(t,e,i,n){var o,s,a;return n?(a=i,t=No(t=(o=t)===(s=e)?a:o===a?s:o,i,e)):t=No(t,e,i),t}function No(t,e,i){return"start"===t?e:"end"===t?i:t}function Ho(t,e,i,n){return t?0:Math.max(Math.min(e,n),i)}function jo(t){const e=Bo(t),i=e.right-e.left,n=e.bottom-e.top,o=function(t,e,i){const n=t.options.borderWidth,o=Vo(t),s=ze(n);return{t:Ho(o.top,s.top,0,i),r:Ho(o.right,s.right,0,e),b:Ho(o.bottom,s.bottom,0,i),l:Ho(o.left,s.left,0,e)}}(t,i/2,n/2),s=function(t,e,i){const{enableBorderRadius:n}=t.getProps(["enableBorderRadius"]),o=t.options.borderRadius,s=Ie(o),a=Math.min(e,i),r=Vo(t),l=n||U(o);return{topLeft:Ho(!l||r.top||r.left,s.topLeft,0,a),topRight:Ho(!l||r.top||r.right,s.topRight,0,a),bottomLeft:Ho(!l||r.bottom||r.left,s.bottomLeft,0,a),bottomRight:Ho(!l||r.bottom||r.right,s.bottomRight,0,a)}}(t,i/2,n/2);return{outer:{x:e.left,y:e.top,w:i,h:n,radius:s},inner:{x:e.left+o.l,y:e.top+o.t,w:i-o.l-o.r,h:n-o.t-o.b,radius:{topLeft:Math.max(0,s.topLeft-Math.max(o.t,o.l)),topRight:Math.max(0,s.topRight-Math.max(o.t,o.r)),bottomLeft:Math.max(0,s.bottomLeft-Math.max(o.b,o.l)),bottomRight:Math.max(0,s.bottomRight-Math.max(o.b,o.r))}}}}function $o(t,e,i,n){const o=null===e,s=null===i,a=t&&!(o&&s)&&Bo(t,n);return a&&(o||e>=a.left&&e<=a.right)&&(s||i>=a.top&&i<=a.bottom)}function Yo(t,e){t.rect(e.x,e.y,e.w,e.h)}Fo.id="point",Fo.defaults={borderWidth:1,hitRadius:1,hoverBorderWidth:1,hoverRadius:4,pointStyle:"circle",radius:3,rotation:0},Fo.defaultRoutes={backgroundColor:"backgroundColor",borderColor:"borderColor"};class Uo extends zi{constructor(t){super(),this.options=void 0,this.horizontal=void 0,this.base=void 0,this.width=void 0,this.height=void 0,t&&Object.assign(this,t)}draw(t){const e=this.options,{inner:i,outer:n}=jo(this),o=(s=n.radius).topLeft||s.topRight||s.bottomLeft||s.bottomRight?ne:Yo;var s;t.save(),n.w===i.w&&n.h===i.h||(t.beginPath(),o(t,n),t.clip(),o(t,i),t.fillStyle=e.borderColor,t.fill("evenodd")),t.beginPath(),o(t,i),t.fillStyle=e.backgroundColor,t.fill(),t.restore()}inRange(t,e,i){return $o(this,t,e,i)}inXRange(t,e){return $o(this,t,null,e)}inYRange(t,e){return $o(this,null,t,e)}getCenterPoint(t){const{x:e,y:i,base:n,horizontal:o}=this.getProps(["x","y","base","horizontal"],t);return{x:o?(e+n)/2:e,y:o?i:(i+n)/2}}getRange(t){return"x"===t?this.width/2:this.height/2}}Uo.id="bar",Uo.defaults={borderSkipped:"start",borderWidth:0,borderRadius:0,enableBorderRadius:!0,pointStyle:void 0},Uo.defaultRoutes={backgroundColor:"backgroundColor",borderColor:"borderColor"};var Xo=Object.freeze({__proto__:null,ArcElement:Po,LineElement:zo,PointElement:Fo,BarElement:Uo});function qo(t){if(t._decimated){const e=t._data;delete t._decimated,delete t._data,Object.defineProperty(t,"data",{value:e})}}function Ko(t){t.data.datasets.forEach((t=>{qo(t)}))}var Go={id:"decimation",defaults:{algorithm:"min-max",enabled:!1},beforeElementsUpdate:(t,e,i)=>{if(!i.enabled)return void Ko(t);const n=t.width;t.data.datasets.forEach(((e,o)=>{const{_data:s,indexAxis:a}=e,r=t.getDatasetMeta(o),l=s||e.data;if("y"===Ve([a,t.options.indexAxis]))return;if("line"!==r.type)return;const c=t.scales[r.xAxisID];if("linear"!==c.type&&"time"!==c.type)return;if(t.options.parsing)return;let h,{start:d,count:u}=function(t,e){const i=e.length;let n,o=0;const{iScale:s}=t,{min:a,max:r,minDefined:l,maxDefined:c}=s.getUserBounds();return l&&(o=Ht(se(e,s.axis,a).lo,0,i-1)),n=c?Ht(se(e,s.axis,r).hi+1,o,i)-o:i-o,{start:o,count:n}}(r,l);if(u<=4*n)qo(e);else{switch($(s)&&(e._data=l,delete e.data,Object.defineProperty(e,"data",{configurable:!0,enumerable:!0,get:function(){return this._decimated},set:function(t){this._data=t}})),i.algorithm){case"lttb":h=function(t,e,i,n,o){const s=o.samples||n;if(s>=i)return t.slice(e,e+i);const a=[],r=(i-2)/(s-2);let l=0;const c=e+i-1;let h,d,u,f,g,p=e;for(a[l++]=t[p],h=0;h<s-2;h++){let n,o=0,s=0;const c=Math.floor((h+1)*r)+1+e,m=Math.min(Math.floor((h+2)*r)+1,i)+e,x=m-c;for(n=c;n<m;n++)o+=t[n].x,s+=t[n].y;o/=x,s/=x;const b=Math.floor(h*r)+1+e,_=Math.floor((h+1)*r)+1+e,{x:y,y:v}=t[p];for(u=f=-1,n=b;n<_;n++)f=.5*Math.abs((y-o)*(t[n].y-v)-(y-t[n].x)*(s-v)),f>u&&(u=f,d=t[n],g=n);a[l++]=d,p=g}return a[l++]=t[c],a}(l,d,u,n,i);break;case"min-max":h=function(t,e,i,n){let o,s,a,r,l,c,h,d,u,f,g=0,p=0;const m=[],x=e+i-1,b=t[e].x,_=t[x].x-b;for(o=e;o<e+i;++o){s=t[o],a=(s.x-b)/_*n,r=s.y;const e=0|a;if(e===l)r<u?(u=r,c=o):r>f&&(f=r,h=o),g=(p*g+s.x)/++p;else{const i=o-1;if(!$(c)&&!$(h)){const e=Math.min(c,h),n=Math.max(c,h);e!==d&&e!==i&&m.push({...t[e],x:g}),n!==d&&n!==i&&m.push({...t[n],x:g})}o>0&&i!==d&&m.push(t[i]),m.push(s),l=e,p=0,u=f=r,c=h=d=o}}return m}(l,d,u,n);break;default:throw new Error(`Unsupported decimation algorithm '${i.algorithm}'`)}e._decimated=h}}))},destroy(t){Ko(t)}};function Zo(t,e,i){const n=function(t){const e=t.options,i=e.fill;let n=K(i&&i.target,i);return void 0===n&&(n=!!e.backgroundColor),!1!==n&&null!==n&&(!0===n?"origin":n)}(t);if(U(n))return!isNaN(n.value)&&n;let o=parseFloat(n);return X(o)&&Math.floor(o)===o?("-"!==n[0]&&"+"!==n[0]||(o=e+o),!(o===e||o<0||o>=i)&&o):["origin","start","end","stack"].indexOf(n)>=0&&n}class Qo{constructor(t){this.x=t.x,this.y=t.y,this.radius=t.radius}pathSegment(t,e,i){const{x:n,y:o,radius:s}=this;return e=e||{start:0,end:_t},t.arc(n,o,s,e.end,e.start,!0),!i.bounds}interpolate(t){const{x:e,y:i,radius:n}=this,o=t.angle;return{x:e+Math.cos(o)*n,y:i+Math.sin(o)*n,angle:o}}}function Jo(t){return(t.scale||{}).getPointPositionForValue?function(t){const{scale:e,fill:i}=t,n=e.options,o=e.getLabels().length,s=[],a=n.reverse?e.max:e.min,r=n.reverse?e.min:e.max;let l,c,h;if(h="start"===i?a:"end"===i?r:U(i)?i.value:e.getBaseValue(),n.grid.circular)return c=e.getPointPositionForValue(0,a),new Qo({x:c.x,y:c.y,radius:e.getDistanceFromCenterForValue(h)});for(l=0;l<o;++l)s.push(e.getPointPositionForValue(l,h));return s}(t):function(t){const{scale:e={},fill:i}=t;let n,o=null;return"start"===i?o=e.bottom:"end"===i?o=e.top:U(i)?o=e.getPixelForValue(i.value):e.getBasePixel&&(o=e.getBasePixel()),X(o)?(n=e.isHorizontal(),{x:n?o:null,y:n?null:o}):null}(t)}function ts(t,e,i){for(;e>t;e--){const t=i[e];if(!isNaN(t.x)&&!isNaN(t.y))break}return e}function es(t){const{chart:e,scale:i,index:n,line:o}=t,s=[],a=o.segments,r=o.points,l=function(t,e){const i=[],n=t.getSortedVisibleDatasetMetas();for(let t=0;t<n.length;t++){const o=n[t];if(o.index===e)break;is(o)&&i.unshift(o.dataset)}return i}(e,n);l.push(ss({x:null,y:i.bottom},o));for(let t=0;t<a.length;t++){const e=a[t];for(let t=e.start;t<=e.end;t++)ns(s,r[t],l)}return new zo({points:s,options:{}})}const is=t=>"line"===t.type&&!t.hidden;function ns(t,e,i){const n=[];for(let o=0;o<i.length;o++){const s=i[o],{first:a,last:r,point:l}=os(s,e,"x");if(!(!l||a&&r))if(a)n.unshift(l);else if(t.push(l),!r)break}t.push(...n)}function os(t,e,i){const n=t.interpolate(e,i);if(!n)return{};const o=n[i],s=t.segments,a=t.points;let r=!1,l=!1;for(let t=0;t<s.length;t++){const e=s[t],n=a[e.start][i],c=a[e.end][i];if(o>=n&&o<=c){r=o===n,l=o===c;break}}return{first:r,last:l,point:n}}function ss(t,e){let i=[],n=!1;return Y(t)?(n=!0,i=t):i=function(t,e){const{x:i=null,y:n=null}=t||{},o=e.points,s=[];return e.segments.forEach((({start:t,end:e})=>{e=ts(t,e,o);const a=o[t],r=o[e];null!==n?(s.push({x:a.x,y:n}),s.push({x:r.x,y:n})):null!==i&&(s.push({x:i,y:a.y}),s.push({x:i,y:r.y}))})),s}(t,e),i.length?new zo({points:i,options:{tension:0},_loop:n,_fullLoop:n}):null}function as(t,e,i){let n=t[e].fill;const o=[e];let s;if(!i)return n;for(;!1!==n&&-1===o.indexOf(n);){if(!X(n))return n;if(s=t[n],!s)return!1;if(s.visible)return n;o.push(n),n=s.fill}return!1}function rs(t,e,i){t.beginPath(),e.path(t),t.lineTo(e.last().x,i),t.lineTo(e.first().x,i),t.closePath(),t.clip()}function ls(t,e,i,n){if(n)return;let o=e[t],s=i[t];return"angle"===t&&(o=Wt(o),s=Wt(s)),{property:t,start:o,end:s}}function cs(t,e,i,n){return t&&e?n(t[i],e[i]):t?t[i]:e?e[i]:0}function hs(t,e,i){const{top:n,bottom:o}=e.chart.chartArea,{property:s,start:a,end:r}=i||{};"x"===s&&(t.beginPath(),t.rect(a,n,r-a,o-n),t.clip())}function ds(t,e,i,n){const o=e.interpolate(i,n);o&&t.lineTo(o.x,o.y)}function us(t,e){const{line:i,target:n,property:o,color:s,scale:a}=e,r=function(t,e,i){const n=t.segments,o=t.points,s=e.points,a=[];for(const t of n){let{start:n,end:r}=t;r=ts(n,r,o);const l=ls(i,o[n],o[r],t.loop);if(!e.segments){a.push({source:t,target:l,start:o[n],end:o[r]});continue}const c=Sn(e,l);for(const e of c){const n=ls(i,s[e.start],s[e.end],e.loop),r=kn(t,o,n);for(const t of r)a.push({source:t,target:e,start:{[i]:cs(l,n,"start",Math.max)},end:{[i]:cs(l,n,"end",Math.min)}})}}return a}(i,n,o);for(const{source:e,target:l,start:c,end:h}of r){const{style:{backgroundColor:r=s}={}}=e;t.save(),t.fillStyle=r,hs(t,a,ls(o,c,h)),t.beginPath();const d=!!i.pathSegment(t,e);d?t.closePath():ds(t,n,h,o);const u=!!n.pathSegment(t,l,{move:d,reverse:!0}),f=d&&u;f||ds(t,n,c,o),t.closePath(),t.fill(f?"evenodd":"nonzero"),t.restore()}}function fs(t,e,i){const n=function(t){const{chart:e,fill:i,line:n}=t;if(X(i))return function(t,e){const i=t.getDatasetMeta(e);return i&&t.isDatasetVisible(e)?i.dataset:null}(e,i);if("stack"===i)return es(t);const o=Jo(t);return o instanceof Qo?o:ss(o,n)}(e),{line:o,scale:s,axis:a}=e,r=o.options,l=r.fill,c=r.backgroundColor,{above:h=c,below:d=c}=l||{};n&&o.points.length&&(Zt(t,i),function(t,e){const{line:i,target:n,above:o,below:s,area:a,scale:r}=e,l=i._loop?"angle":e.axis;t.save(),"x"===l&&s!==o&&(rs(t,n,a.top),us(t,{line:i,target:n,color:o,scale:r,property:l}),t.restore(),t.save(),rs(t,n,a.bottom)),us(t,{line:i,target:n,color:s,scale:r,property:l}),t.restore()}(t,{line:o,target:n,above:h,below:d,area:i,scale:s,axis:a}),Qt(t))}var gs={id:"filler",afterDatasetsUpdate(t,e,i){const n=(t.data.datasets||[]).length,o=[];let s,a,r,l;for(a=0;a<n;++a)s=t.getDatasetMeta(a),r=s.dataset,l=null,r&&r.options&&r instanceof zo&&(l={visible:t.isDatasetVisible(a),index:a,fill:Zo(r,a,n),chart:t,axis:s.controller.options.indexAxis,scale:s.vScale,line:r}),s.$filler=l,o.push(l);for(a=0;a<n;++a)l=o[a],l&&!1!==l.fill&&(l.fill=as(o,a,i.propagate))},beforeDraw(t,e,i){const n="beforeDraw"===i.drawTime,o=t.getSortedVisibleDatasetMetas(),s=t.chartArea;for(let e=o.length-1;e>=0;--e){const i=o[e].$filler;i&&(i.line.updateControlPoints(s,i.axis),n&&fs(t.ctx,i,s))}},beforeDatasetsDraw(t,e,i){if("beforeDatasetsDraw"!==i.drawTime)return;const n=t.getSortedVisibleDatasetMetas();for(let e=n.length-1;e>=0;--e){const i=n[e].$filler;i&&fs(t.ctx,i,t.chartArea)}},beforeDatasetDraw(t,e,i){const n=e.meta.$filler;n&&!1!==n.fill&&"beforeDatasetDraw"===i.drawTime&&fs(t.ctx,n,t.chartArea)},defaults:{propagate:!0,drawTime:"beforeDatasetDraw"}};const ps=(t,e)=>{let{boxHeight:i=e,boxWidth:n=e}=t;return t.usePointStyle&&(i=Math.min(i,e),n=Math.min(n,e)),{boxWidth:n,boxHeight:i,itemHeight:Math.max(e,i)}};class ms extends zi{constructor(t){super(),this._added=!1,this.legendHitBoxes=[],this._hoveredItem=null,this.doughnutMode=!1,this.chart=t.chart,this.options=t.options,this.ctx=t.ctx,this.legendItems=void 0,this.columnSizes=void 0,this.lineWidths=void 0,this.maxHeight=void 0,this.maxWidth=void 0,this.top=void 0,this.bottom=void 0,this.left=void 0,this.right=void 0,this.height=void 0,this.width=void 0,this._margins=void 0,this.position=void 0,this.weight=void 0,this.fullSize=void 0}update(t,e,i){const n=this;n.maxWidth=t,n.maxHeight=e,n._margins=i,n.setDimensions(),n.buildLabels(),n.fit()}setDimensions(){const t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=t._margins.left,t.right=t.width):(t.height=t.maxHeight,t.top=t._margins.top,t.bottom=t.height)}buildLabels(){const t=this,e=t.options.labels||{};let i=Q(e.generateLabels,[t.chart],t)||[];e.filter&&(i=i.filter((i=>e.filter(i,t.chart.data)))),e.sort&&(i=i.sort(((i,n)=>e.sort(i,n,t.chart.data)))),t.options.reverse&&i.reverse(),t.legendItems=i}fit(){const t=this,{options:e,ctx:i}=t;if(!e.display)return void(t.width=t.height=0);const n=e.labels,o=Be(n.font),s=o.size,a=t._computeTitleHeight(),{boxWidth:r,itemHeight:l}=ps(n,s);let c,h;i.font=o.string,t.isHorizontal()?(c=t.maxWidth,h=t._fitRows(a,s,r,l)+10):(h=t.maxHeight,c=t._fitCols(a,s,r,l)+10),t.width=Math.min(c,e.maxWidth||t.maxWidth),t.height=Math.min(h,e.maxHeight||t.maxHeight)}_fitRows(t,e,i,n){const o=this,{ctx:s,maxWidth:a,options:{labels:{padding:r}}}=o,l=o.legendHitBoxes=[],c=o.lineWidths=[0],h=n+r;let d=t;s.textAlign="left",s.textBaseline="middle";let u=-1,f=-h;return o.legendItems.forEach(((t,o)=>{const g=i+e/2+s.measureText(t.text).width;(0===o||c[c.length-1]+g+2*r>a)&&(d+=h,c[c.length-(o>0?0:1)]=0,f+=h,u++),l[o]={left:0,top:f,row:u,width:g,height:n},c[c.length-1]+=g+r})),d}_fitCols(t,e,i,n){const o=this,{ctx:s,maxHeight:a,options:{labels:{padding:r}}}=o,l=o.legendHitBoxes=[],c=o.columnSizes=[],h=a-t;let d=r,u=0,f=0,g=0,p=0;return o.legendItems.forEach(((t,o)=>{const a=i+e/2+s.measureText(t.text).width;o>0&&f+n+2*r>h&&(d+=u+r,c.push({width:u,height:f}),g+=u+r,p++,u=f=0),l[o]={left:g,top:f,col:p,width:a,height:n},u=Math.max(u,a),f+=n+r})),d+=u,c.push({width:u,height:f}),d}adjustHitBoxes(){const t=this;if(!t.options.display)return;const e=t._computeTitleHeight(),{legendHitBoxes:i,options:{align:n,labels:{padding:s},rtl:a}}=t;if(this.isHorizontal()){let r=0,l=o(n,t.left+s,t.right-t.lineWidths[r]);for(const a of i)r!==a.row&&(r=a.row,l=o(n,t.left+s,t.right-t.lineWidths[r])),a.top+=t.top+e+s,a.left=l,l+=a.width+s;if(a){const e=i.reduce(((t,e)=>(t[e.row]=t[e.row]||[],t[e.row].push(e),t)),{}),n=[];Object.keys(e).forEach((t=>{e[t].reverse(),n.push(...e[t])})),t.legendHitBoxes=n}}else{let a=0,r=o(n,t.top+e+s,t.bottom-t.columnSizes[a].height);for(const l of i)l.col!==a&&(a=l.col,r=o(n,t.top+e+s,t.bottom-t.columnSizes[a].height)),l.top=r,l.left+=t.left+s,r+=l.height+s}}isHorizontal(){return"top"===this.options.position||"bottom"===this.options.position}draw(){const t=this;if(t.options.display){const e=t.ctx;Zt(e,t),t._draw(),Qt(e)}}_draw(){const t=this,{options:e,columnSizes:i,lineWidths:n,ctx:a}=t,{align:r,labels:l}=e,c=xt.color,h=_n(e.rtl,t.left,t.width),d=Be(l.font),{color:u,padding:f}=l,g=d.size,p=g/2;let m;t.drawTitle(),a.textAlign=h.textAlign("left"),a.textBaseline="middle",a.lineWidth=.5,a.font=d.string;const{boxWidth:x,boxHeight:b,itemHeight:_}=ps(l,g),y=t.isHorizontal(),v=this._computeTitleHeight();m=y?{x:o(r,t.left+f,t.right-n[0]),y:t.top+f+v,line:0}:{x:t.left+f,y:o(r,t.top+v+f,t.bottom-i[0].height),line:0},yn(t.ctx,e.textDirection);const w=_+f;t.legendItems.forEach(((M,k)=>{a.strokeStyle=M.fontColor||u,a.fillStyle=M.fontColor||u;const S=a.measureText(M.text).width,P=h.textAlign(M.textAlign||(M.textAlign=l.textAlign)),D=x+p+S;let C=m.x,O=m.y;h.setWidth(t.width),y?k>0&&C+D+f>t.right&&(O=m.y+=w,m.line++,C=m.x=o(r,t.left+f,t.right-n[m.line])):k>0&&O+w>t.bottom&&(C=m.x=C+i[m.line].width+f,m.line++,O=m.y=o(r,t.top+v+f,t.bottom-i[m.line].height));!function(t,e,i){if(isNaN(x)||x<=0||isNaN(b)||b<0)return;a.save();const n=K(i.lineWidth,1);if(a.fillStyle=K(i.fillStyle,c),a.lineCap=K(i.lineCap,"butt"),a.lineDashOffset=K(i.lineDashOffset,0),a.lineJoin=K(i.lineJoin,"miter"),a.lineWidth=n,a.strokeStyle=K(i.strokeStyle,c),a.setLineDash(K(i.lineDash,[])),l.usePointStyle){const o={radius:x*Math.SQRT2/2,pointStyle:i.pointStyle,rotation:i.rotation,borderWidth:n},s=h.xPlus(t,x/2);Kt(a,o,s,e+p)}else{const o=e+Math.max((g-b)/2,0),s=h.leftForLtr(t,x),r=Ie(i.borderRadius);a.beginPath(),Object.values(r).some((t=>0!==t))?ne(a,{x:s,y:o,w:x,h:b,radius:r}):a.rect(s,o,x,b),a.fill(),0!==n&&a.stroke()}a.restore()}(h.x(C),O,M),C=s(P,C+x+p,y?C+D:t.right,e.rtl),function(t,e,i){ee(a,i.text,t,e+_/2,d,{strikethrough:i.hidden,textAlign:h.textAlign(i.textAlign)})}(h.x(C),O,M),y?m.x+=D+f:m.y+=w})),vn(t.ctx,e.textDirection)}drawTitle(){const t=this,e=t.options,i=e.title,s=Be(i.font),a=Fe(i.padding);if(!i.display)return;const r=_n(e.rtl,t.left,t.width),l=t.ctx,c=i.position,h=s.size/2,d=a.top+h;let u,f=t.left,g=t.width;if(this.isHorizontal())g=Math.max(...t.lineWidths),u=t.top+d,f=o(e.align,f,t.right-g);else{const i=t.columnSizes.reduce(((t,e)=>Math.max(t,e.height)),0);u=d+o(e.align,t.top,t.bottom-i-e.labels.padding-t._computeTitleHeight())}const p=o(c,f,f+g);l.textAlign=r.textAlign(n(c)),l.textBaseline="middle",l.strokeStyle=i.color,l.fillStyle=i.color,l.font=s.string,ee(l,i.text,p,u,s)}_computeTitleHeight(){const t=this.options.title,e=Be(t.font),i=Fe(t.padding);return t.display?e.lineHeight+i.height:0}_getLegendItemAt(t,e){const i=this;let n,o,s;if(t>=i.left&&t<=i.right&&e>=i.top&&e<=i.bottom)for(s=i.legendHitBoxes,n=0;n<s.length;++n)if(o=s[n],t>=o.left&&t<=o.left+o.width&&e>=o.top&&e<=o.top+o.height)return i.legendItems[n];return null}handleEvent(t){const e=this,i=e.options;if(!function(t,e){if("mousemove"===t&&(e.onHover||e.onLeave))return!0;if(e.onClick&&("click"===t||"mouseup"===t))return!0;return!1}(t.type,i))return;const n=e._getLegendItemAt(t.x,t.y);if("mousemove"===t.type){const a=e._hoveredItem,r=(s=n,null!==(o=a)&&null!==s&&o.datasetIndex===s.datasetIndex&&o.index===s.index);a&&!r&&Q(i.onLeave,[t,a,e],e),e._hoveredItem=n,n&&!r&&Q(i.onHover,[t,n,e],e)}else n&&Q(i.onClick,[t,n,e],e);var o,s}}var xs={id:"legend",_element:ms,start(t,e,i){const n=t.legend=new ms({ctx:t.ctx,options:i,chart:t});Ze.configure(t,n,i),Ze.addBox(t,n)},stop(t){Ze.removeBox(t,t.legend),delete t.legend},beforeUpdate(t,e,i){const n=t.legend;Ze.configure(t,n,i),n.options=i},afterUpdate(t){const e=t.legend;e.buildLabels(),e.adjustHitBoxes()},afterEvent(t,e){e.replay||t.legend.handleEvent(e.event)},defaults:{display:!0,position:"top",align:"center",fullSize:!0,reverse:!1,weight:1e3,onClick(t,e,i){const n=e.datasetIndex,o=i.chart;o.isDatasetVisible(n)?(o.hide(n),e.hidden=!0):(o.show(n),e.hidden=!1)},onHover:null,onLeave:null,labels:{color:t=>t.chart.options.color,boxWidth:40,padding:10,generateLabels(t){const e=t.data.datasets,{labels:{usePointStyle:i,pointStyle:n,textAlign:o,color:s}}=t.legend.options;return t._getSortedDatasetMetas().map((t=>{const a=t.controller.getStyle(i?0:void 0),r=Fe(a.borderWidth);return{text:e[t.index].label,fillStyle:a.backgroundColor,fontColor:s,hidden:!t.visible,lineCap:a.borderCapStyle,lineDash:a.borderDash,lineDashOffset:a.borderDashOffset,lineJoin:a.borderJoinStyle,lineWidth:(r.width+r.height)/4,strokeStyle:a.borderColor,pointStyle:n||a.pointStyle,rotation:a.rotation,textAlign:o||a.textAlign,borderRadius:0,datasetIndex:t.index}}),this)}},title:{color:t=>t.chart.options.color,display:!1,position:"center",text:""}},descriptors:{_scriptable:t=>!t.startsWith("on"),labels:{_scriptable:t=>!["generateLabels","filter","sort"].includes(t)}}};class bs extends zi{constructor(t){super(),this.chart=t.chart,this.options=t.options,this.ctx=t.ctx,this._padding=void 0,this.top=void 0,this.bottom=void 0,this.left=void 0,this.right=void 0,this.width=void 0,this.height=void 0,this.position=void 0,this.weight=void 0,this.fullSize=void 0}update(t,e){const i=this,n=i.options;if(i.left=0,i.top=0,!n.display)return void(i.width=i.height=i.right=i.bottom=0);i.width=i.right=t,i.height=i.bottom=e;const o=Y(n.text)?n.text.length:1;i._padding=Fe(n.padding);const s=o*Be(n.font).lineHeight+i._padding.height;i.isHorizontal()?i.height=s:i.width=s}isHorizontal(){const t=this.options.position;return"top"===t||"bottom"===t}_drawArgs(t){const{top:e,left:i,bottom:n,right:s,options:a}=this,r=a.align;let l,c,h,d=0;return this.isHorizontal()?(c=o(r,i,s),h=e+t,l=s-i):("left"===a.position?(c=i+t,h=o(r,n,e),d=-.5*bt):(c=s-t,h=o(r,e,n),d=.5*bt),l=n-e),{titleX:c,titleY:h,maxWidth:l,rotation:d}}draw(){const t=this,e=t.ctx,i=t.options;if(!i.display)return;const o=Be(i.font),s=o.lineHeight/2+t._padding.top,{titleX:a,titleY:r,maxWidth:l,rotation:c}=t._drawArgs(s);ee(e,i.text,0,0,o,{color:i.color,maxWidth:l,rotation:c,textAlign:n(i.align),textBaseline:"middle",translation:[a,r]})}}var _s={id:"title",_element:bs,start(t,e,i){!function(t,e){const i=new bs({ctx:t.ctx,options:e,chart:t});Ze.configure(t,i,e),Ze.addBox(t,i),t.titleBlock=i}(t,i)},stop(t){const e=t.titleBlock;Ze.removeBox(t,e),delete t.titleBlock},beforeUpdate(t,e,i){const n=t.titleBlock;Ze.configure(t,n,i),n.options=i},defaults:{align:"center",display:!1,font:{weight:"bold"},fullSize:!0,padding:10,position:"top",text:"",weight:2e3},defaultRoutes:{color:"color"},descriptors:{_scriptable:!0,_indexable:!1}};const ys=new WeakMap;var vs={id:"subtitle",start(t,e,i){const n=new bs({ctx:t.ctx,options:i,chart:t});Ze.configure(t,n,i),Ze.addBox(t,n),ys.set(t,n)},stop(t){Ze.removeBox(t,ys.get(t)),ys.delete(t)},beforeUpdate(t,e,i){const n=ys.get(t);Ze.configure(t,n,i),n.options=i},defaults:{align:"center",display:!1,font:{weight:"normal"},fullSize:!0,padding:0,position:"top",text:"",weight:1500},defaultRoutes:{color:"color"},descriptors:{_scriptable:!0,_indexable:!1}};const ws={average(t){if(!t.length)return!1;let e,i,n=0,o=0,s=0;for(e=0,i=t.length;e<i;++e){const i=t[e].element;if(i&&i.hasValue()){const t=i.tooltipPosition();n+=t.x,o+=t.y,++s}}return{x:n/s,y:o/s}},nearest(t,e){if(!t.length)return!1;let i,n,o,s=e.x,a=e.y,r=Number.POSITIVE_INFINITY;for(i=0,n=t.length;i<n;++i){const n=t[i].element;if(n&&n.hasValue()){const t=Bt(e,n.getCenterPoint());t<r&&(r=t,o=n)}}if(o){const t=o.tooltipPosition();s=t.x,a=t.y}return{x:s,y:a}}};function Ms(t,e){return e&&(Y(e)?Array.prototype.push.apply(t,e):t.push(e)),t}function ks(t){return("string"==typeof t||t instanceof String)&&t.indexOf("\n")>-1?t.split("\n"):t}function Ss(t,e){const{element:i,datasetIndex:n,index:o}=e,s=t.getDatasetMeta(n).controller,{label:a,value:r}=s.getLabelAndValue(o);return{chart:t,label:a,parsed:s.getParsed(o),raw:t.data.datasets[n].data[o],formattedValue:r,dataset:s.getDataset(),dataIndex:o,datasetIndex:n,element:i}}function Ps(t,e){const i=t._chart.ctx,{body:n,footer:o,title:s}=t,{boxWidth:a,boxHeight:r}=e,l=Be(e.bodyFont),c=Be(e.titleFont),h=Be(e.footerFont),d=s.length,u=o.length,f=n.length,g=Fe(e.padding);let p=g.height,m=0,x=n.reduce(((t,e)=>t+e.before.length+e.lines.length+e.after.length),0);if(x+=t.beforeBody.length+t.afterBody.length,d&&(p+=d*c.lineHeight+(d-1)*e.titleSpacing+e.titleMarginBottom),x){p+=f*(e.displayColors?Math.max(r,l.lineHeight):l.lineHeight)+(x-f)*l.lineHeight+(x-1)*e.bodySpacing}u&&(p+=e.footerMarginTop+u*h.lineHeight+(u-1)*e.footerSpacing);let b=0;const _=function(t){m=Math.max(m,i.measureText(t).width+b)};return i.save(),i.font=c.string,J(t.title,_),i.font=l.string,J(t.beforeBody.concat(t.afterBody),_),b=e.displayColors?a+2:0,J(n,(t=>{J(t.before,_),J(t.lines,_),J(t.after,_)})),b=0,i.font=h.string,J(t.footer,_),i.restore(),m+=g.width,{width:m,height:p}}function Ds(t,e,i,n){const{x:o,width:s}=i,{width:a,chartArea:{left:r,right:l}}=t;let c="center";return"center"===n?c=o<=(r+l)/2?"left":"right":o<=s/2?c="left":o>=a-s/2&&(c="right"),function(t,e,i,n){const{x:o,width:s}=n,a=i.caretSize+i.caretPadding;return"left"===t&&o+s+a>e.width||"right"===t&&o-s-a<0||void 0}(c,t,e,i)&&(c="center"),c}function Cs(t,e,i){const n=e.yAlign||function(t,e){const{y:i,height:n}=e;return i<n/2?"top":i>t.height-n/2?"bottom":"center"}(t,i);return{xAlign:e.xAlign||Ds(t,e,i,n),yAlign:n}}function Os(t,e,i,n){const{caretSize:o,caretPadding:s,cornerRadius:a}=t,{xAlign:r,yAlign:l}=i,c=o+s,h=a+s;let d=function(t,e){let{x:i,width:n}=t;return"right"===e?i-=n:"center"===e&&(i-=n/2),i}(e,r);const u=function(t,e,i){let{y:n,height:o}=t;return"top"===e?n+=i:n-="bottom"===e?o+i:o/2,n}(e,l,c);return"center"===l?"left"===r?d+=c:"right"===r&&(d-=c):"left"===r?d-=h:"right"===r&&(d+=h),{x:Ht(d,0,n.width-e.width),y:Ht(u,0,n.height-e.height)}}function Ts(t,e,i){const n=Fe(i.padding);return"center"===e?t.x+t.width/2:"right"===e?t.x+t.width-n.right:t.x+n.left}function As(t){return Ms([],ks(t))}function Ls(t,e){const i=e&&e.dataset&&e.dataset.tooltip&&e.dataset.tooltip.callbacks;return i?t.override(i):t}class Rs extends zi{constructor(t){super(),this.opacity=0,this._active=[],this._chart=t._chart,this._eventPosition=void 0,this._size=void 0,this._cachedAnimations=void 0,this._tooltipItems=[],this.$animations=void 0,this.$context=void 0,this.options=t.options,this.dataPoints=void 0,this.title=void 0,this.beforeBody=void 0,this.body=void 0,this.afterBody=void 0,this.footer=void 0,this.xAlign=void 0,this.yAlign=void 0,this.x=void 0,this.y=void 0,this.height=void 0,this.width=void 0,this.caretX=void 0,this.caretY=void 0,this.labelColors=void 0,this.labelPointStyles=void 0,this.labelTextColors=void 0}initialize(t){this.options=t,this._cachedAnimations=void 0,this.$context=void 0}_resolveAnimations(){const t=this,e=t._cachedAnimations;if(e)return e;const i=t._chart,n=t.options.setContext(t.getContext()),o=n.enabled&&i.options.animation&&n.animations,s=new wi(t._chart,o);return o._cacheable&&(t._cachedAnimations=Object.freeze(s)),s}getContext(){const t=this;return t.$context||(t.$context=(e=t._chart.getContext(),i=t,n=t._tooltipItems,Object.assign(Object.create(e),{tooltip:i,tooltipItems:n,type:"tooltip"})));var e,i,n}getTitle(t,e){const i=this,{callbacks:n}=e,o=n.beforeTitle.apply(i,[t]),s=n.title.apply(i,[t]),a=n.afterTitle.apply(i,[t]);let r=[];return r=Ms(r,ks(o)),r=Ms(r,ks(s)),r=Ms(r,ks(a)),r}getBeforeBody(t,e){return As(e.callbacks.beforeBody.apply(this,[t]))}getBody(t,e){const i=this,{callbacks:n}=e,o=[];return J(t,(t=>{const e={before:[],lines:[],after:[]},s=Ls(n,t);Ms(e.before,ks(s.beforeLabel.call(i,t))),Ms(e.lines,s.label.call(i,t)),Ms(e.after,ks(s.afterLabel.call(i,t))),o.push(e)})),o}getAfterBody(t,e){return As(e.callbacks.afterBody.apply(this,[t]))}getFooter(t,e){const i=this,{callbacks:n}=e,o=n.beforeFooter.apply(i,[t]),s=n.footer.apply(i,[t]),a=n.afterFooter.apply(i,[t]);let r=[];return r=Ms(r,ks(o)),r=Ms(r,ks(s)),r=Ms(r,ks(a)),r}_createItems(t){const e=this,i=e._active,n=e._chart.data,o=[],s=[],a=[];let r,l,c=[];for(r=0,l=i.length;r<l;++r)c.push(Ss(e._chart,i[r]));return t.filter&&(c=c.filter(((e,i,o)=>t.filter(e,i,o,n)))),t.itemSort&&(c=c.sort(((e,i)=>t.itemSort(e,i,n)))),J(c,(i=>{const n=Ls(t.callbacks,i);o.push(n.labelColor.call(e,i)),s.push(n.labelPointStyle.call(e,i)),a.push(n.labelTextColor.call(e,i))})),e.labelColors=o,e.labelPointStyles=s,e.labelTextColors=a,e.dataPoints=c,c}update(t,e){const i=this,n=i.options.setContext(i.getContext()),o=i._active;let s,a=[];if(o.length){const t=ws[n.position].call(i,o,i._eventPosition);a=i._createItems(n),i.title=i.getTitle(a,n),i.beforeBody=i.getBeforeBody(a,n),i.body=i.getBody(a,n),i.afterBody=i.getAfterBody(a,n),i.footer=i.getFooter(a,n);const e=i._size=Ps(i,n),r=Object.assign({},t,e),l=Cs(i._chart,n,r),c=Os(n,r,l,i._chart);i.xAlign=l.xAlign,i.yAlign=l.yAlign,s={opacity:1,x:c.x,y:c.y,width:e.width,height:e.height,caretX:t.x,caretY:t.y}}else 0!==i.opacity&&(s={opacity:0});i._tooltipItems=a,i.$context=void 0,s&&i._resolveAnimations().update(i,s),t&&n.external&&n.external.call(i,{chart:i._chart,tooltip:i,replay:e})}drawCaret(t,e,i,n){const o=this.getCaretPosition(t,i,n);e.lineTo(o.x1,o.y1),e.lineTo(o.x2,o.y2),e.lineTo(o.x3,o.y3)}getCaretPosition(t,e,i){const{xAlign:n,yAlign:o}=this,{cornerRadius:s,caretSize:a}=i,{x:r,y:l}=t,{width:c,height:h}=e;let d,u,f,g,p,m;return"center"===o?(p=l+h/2,"left"===n?(d=r,u=d-a,g=p+a,m=p-a):(d=r+c,u=d+a,g=p-a,m=p+a),f=d):(u="left"===n?r+s+a:"right"===n?r+c-s-a:this.caretX,"top"===o?(g=l,p=g-a,d=u-a,f=u+a):(g=l+h,p=g+a,d=u+a,f=u-a),m=g),{x1:d,x2:u,x3:f,y1:g,y2:p,y3:m}}drawTitle(t,e,i){const n=this,o=n.title,s=o.length;let a,r,l;if(s){const c=_n(i.rtl,n.x,n.width);for(t.x=Ts(n,i.titleAlign,i),e.textAlign=c.textAlign(i.titleAlign),e.textBaseline="middle",a=Be(i.titleFont),r=i.titleSpacing,e.fillStyle=i.titleColor,e.font=a.string,l=0;l<s;++l)e.fillText(o[l],c.x(t.x),t.y+a.lineHeight/2),t.y+=a.lineHeight+r,l+1===s&&(t.y+=i.titleMarginBottom-r)}}_drawColorBox(t,e,i,n,o){const s=this,a=s.labelColors[i],r=s.labelPointStyles[i],{boxHeight:l,boxWidth:c}=o,h=Be(o.bodyFont),d=Ts(s,"left",o),u=n.x(d),f=l<h.lineHeight?(h.lineHeight-l)/2:0,g=e.y+f;if(o.usePointStyle){const e={radius:Math.min(c,l)/2,pointStyle:r.pointStyle,rotation:r.rotation,borderWidth:1},i=n.leftForLtr(u,c)+c/2,s=g+l/2;t.strokeStyle=o.multiKeyBackground,t.fillStyle=o.multiKeyBackground,Kt(t,e,i,s),t.strokeStyle=a.borderColor,t.fillStyle=a.backgroundColor,Kt(t,e,i,s)}else{t.lineWidth=a.borderWidth||1,t.strokeStyle=a.borderColor,t.setLineDash(a.borderDash||[]),t.lineDashOffset=a.borderDashOffset||0;const e=n.leftForLtr(u,c),i=n.leftForLtr(n.xPlus(u,1),c-2),s=Ie(a.borderRadius);Object.values(s).some((t=>0!==t))?(t.beginPath(),t.fillStyle=o.multiKeyBackground,ne(t,{x:e,y:g,w:c,h:l,radius:s}),t.fill(),t.stroke(),t.fillStyle=a.backgroundColor,t.beginPath(),ne(t,{x:i,y:g+1,w:c-2,h:l-2,radius:s}),t.fill()):(t.fillStyle=o.multiKeyBackground,t.fillRect(e,g,c,l),t.strokeRect(e,g,c,l),t.fillStyle=a.backgroundColor,t.fillRect(i,g+1,c-2,l-2))}t.fillStyle=s.labelTextColors[i]}drawBody(t,e,i){const n=this,{body:o}=n,{bodySpacing:s,bodyAlign:a,displayColors:r,boxHeight:l,boxWidth:c}=i,h=Be(i.bodyFont);let d=h.lineHeight,u=0;const f=_n(i.rtl,n.x,n.width),g=function(i){e.fillText(i,f.x(t.x+u),t.y+d/2),t.y+=d+s},p=f.textAlign(a);let m,x,b,_,y,v,w;for(e.textAlign=a,e.textBaseline="middle",e.font=h.string,t.x=Ts(n,p,i),e.fillStyle=i.bodyColor,J(n.beforeBody,g),u=r&&"right"!==p?"center"===a?c/2+1:c+2:0,_=0,v=o.length;_<v;++_){for(m=o[_],x=n.labelTextColors[_],e.fillStyle=x,J(m.before,g),b=m.lines,r&&b.length&&(n._drawColorBox(e,t,_,f,i),d=Math.max(h.lineHeight,l)),y=0,w=b.length;y<w;++y)g(b[y]),d=h.lineHeight;J(m.after,g)}u=0,d=h.lineHeight,J(n.afterBody,g),t.y-=s}drawFooter(t,e,i){const n=this,o=n.footer,s=o.length;let a,r;if(s){const l=_n(i.rtl,n.x,n.width);for(t.x=Ts(n,i.footerAlign,i),t.y+=i.footerMarginTop,e.textAlign=l.textAlign(i.footerAlign),e.textBaseline="middle",a=Be(i.footerFont),e.fillStyle=i.footerColor,e.font=a.string,r=0;r<s;++r)e.fillText(o[r],l.x(t.x),t.y+a.lineHeight/2),t.y+=a.lineHeight+i.footerSpacing}}drawBackground(t,e,i,n){const{xAlign:o,yAlign:s}=this,{x:a,y:r}=t,{width:l,height:c}=i,h=n.cornerRadius;e.fillStyle=n.backgroundColor,e.strokeStyle=n.borderColor,e.lineWidth=n.borderWidth,e.beginPath(),e.moveTo(a+h,r),"top"===s&&this.drawCaret(t,e,i,n),e.lineTo(a+l-h,r),e.quadraticCurveTo(a+l,r,a+l,r+h),"center"===s&&"right"===o&&this.drawCaret(t,e,i,n),e.lineTo(a+l,r+c-h),e.quadraticCurveTo(a+l,r+c,a+l-h,r+c),"bottom"===s&&this.drawCaret(t,e,i,n),e.lineTo(a+h,r+c),e.quadraticCurveTo(a,r+c,a,r+c-h),"center"===s&&"left"===o&&this.drawCaret(t,e,i,n),e.lineTo(a,r+h),e.quadraticCurveTo(a,r,a+h,r),e.closePath(),e.fill(),n.borderWidth>0&&e.stroke()}_updateAnimationTarget(t){const e=this,i=e._chart,n=e.$animations,o=n&&n.x,s=n&&n.y;if(o||s){const n=ws[t.position].call(e,e._active,e._eventPosition);if(!n)return;const a=e._size=Ps(e,t),r=Object.assign({},n,e._size),l=Cs(i,t,r),c=Os(t,r,l,i);o._to===c.x&&s._to===c.y||(e.xAlign=l.xAlign,e.yAlign=l.yAlign,e.width=a.width,e.height=a.height,e.caretX=n.x,e.caretY=n.y,e._resolveAnimations().update(e,c))}}draw(t){const e=this,i=e.options.setContext(e.getContext());let n=e.opacity;if(!n)return;e._updateAnimationTarget(i);const o={width:e.width,height:e.height},s={x:e.x,y:e.y};n=Math.abs(n)<.001?0:n;const a=Fe(i.padding),r=e.title.length||e.beforeBody.length||e.body.length||e.afterBody.length||e.footer.length;i.enabled&&r&&(t.save(),t.globalAlpha=n,e.drawBackground(s,t,o,i),yn(t,i.textDirection),s.y+=a.top,e.drawTitle(s,t,i),e.drawBody(s,t,i),e.drawFooter(s,t,i),vn(t,i.textDirection),t.restore())}getActiveElements(){return this._active||[]}setActiveElements(t,e){const i=this,n=i._active,o=t.map((({datasetIndex:t,index:e})=>{const n=i._chart.getDatasetMeta(t);if(!n)throw new Error("Cannot find a dataset at index "+t);return{datasetIndex:t,element:n.data[e],index:e}})),s=!tt(n,o),a=i._positionChanged(o,e);(s||a)&&(i._active=o,i._eventPosition=e,i.update(!0))}handleEvent(t,e){const i=this,n=i.options,o=i._active||[];let s=!1,a=[];"mouseout"!==t.type&&(a=i._chart.getElementsAtEventForMode(t,n.mode,n,e),n.reverse&&a.reverse());const r=i._positionChanged(a,t);return s=e||!tt(a,o)||r,s&&(i._active=a,(n.enabled||n.external)&&(i._eventPosition={x:t.x,y:t.y},i.update(!0,e))),s}_positionChanged(t,e){const{caretX:i,caretY:n,options:o}=this,s=ws[o.position].call(this,t,e);return!1!==s&&(i!==s.x||n!==s.y)}}Rs.positioners=ws;var Es={id:"tooltip",_element:Rs,positioners:ws,afterInit(t,e,i){i&&(t.tooltip=new Rs({_chart:t,options:i}))},beforeUpdate(t,e,i){t.tooltip&&t.tooltip.initialize(i)},reset(t,e,i){t.tooltip&&t.tooltip.initialize(i)},afterDraw(t){const e=t.tooltip,i={tooltip:e};!1!==t.notifyPlugins("beforeTooltipDraw",i)&&(e&&e.draw(t.ctx),t.notifyPlugins("afterTooltipDraw",i))},afterEvent(t,e){if(t.tooltip){const i=e.replay;t.tooltip.handleEvent(e.event,i)&&(e.changed=!0)}},defaults:{enabled:!0,external:null,position:"average",backgroundColor:"rgba(0,0,0,0.8)",titleColor:"#fff",titleFont:{weight:"bold"},titleSpacing:2,titleMarginBottom:6,titleAlign:"left",bodyColor:"#fff",bodySpacing:2,bodyFont:{},bodyAlign:"left",footerColor:"#fff",footerSpacing:2,footerMarginTop:6,footerFont:{weight:"bold"},footerAlign:"left",padding:6,caretPadding:2,caretSize:5,cornerRadius:6,boxHeight:(t,e)=>e.bodyFont.size,boxWidth:(t,e)=>e.bodyFont.size,multiKeyBackground:"#fff",displayColors:!0,borderColor:"rgba(0,0,0,0)",borderWidth:0,animation:{duration:400,easing:"easeOutQuart"},animations:{numbers:{type:"number",properties:["x","y","width","height","caretX","caretY"]},opacity:{easing:"linear",duration:200}},callbacks:{beforeTitle:H,title(t){if(t.length>0){const e=t[0],i=e.chart.data.labels,n=i?i.length:0;if(this&&this.options&&"dataset"===this.options.mode)return e.dataset.label||"";if(e.label)return e.label;if(n>0&&e.dataIndex<n)return i[e.dataIndex]}return""},afterTitle:H,beforeBody:H,beforeLabel:H,label(t){if(this&&this.options&&"dataset"===this.options.mode)return t.label+": "+t.formattedValue||t.formattedValue;let e=t.dataset.label||"";e&&(e+=": ");const i=t.formattedValue;return $(i)||(e+=i),e},labelColor(t){const e=t.chart.getDatasetMeta(t.datasetIndex).controller.getStyle(t.dataIndex);return{borderColor:e.borderColor,backgroundColor:e.backgroundColor,borderWidth:e.borderWidth,borderDash:e.borderDash,borderDashOffset:e.borderDashOffset,borderRadius:0}},labelTextColor(){return this.options.bodyColor},labelPointStyle(t){const e=t.chart.getDatasetMeta(t.datasetIndex).controller.getStyle(t.dataIndex);return{pointStyle:e.pointStyle,rotation:e.rotation}},afterLabel:H,afterBody:H,beforeFooter:H,footer:H,afterFooter:H}},defaultRoutes:{bodyFont:"font",footerFont:"font",titleFont:"font"},descriptors:{_scriptable:t=>"filter"!==t&&"itemSort"!==t&&"external"!==t,_indexable:!1,callbacks:{_scriptable:!1,_indexable:!1},animation:{_fallback:!1},animations:{_fallback:"animation"}},additionalOptionScopes:["interaction"]},zs=Object.freeze({__proto__:null,Decimation:Go,Filler:gs,Legend:xs,SubTitle:vs,Title:_s,Tooltip:Es});function Is(t,e,i){const n=t.indexOf(e);if(-1===n)return((t,e,i)=>"string"==typeof e?t.push(e)-1:isNaN(e)?null:i)(t,e,i);return n!==t.lastIndexOf(e)?i:n}class Fs extends qi{constructor(t){super(t),this._startValue=void 0,this._valueRange=0}parse(t,e){if($(t))return null;const i=this.getLabels();return((t,e)=>null===t?null:Ht(Math.round(t),0,e))(e=isFinite(e)&&i[e]===t?e:Is(i,t,K(e,t)),i.length-1)}determineDataLimits(){const t=this,{minDefined:e,maxDefined:i}=t.getUserBounds();let{min:n,max:o}=t.getMinMax(!0);"ticks"===t.options.bounds&&(e||(n=0),i||(o=t.getLabels().length-1)),t.min=n,t.max=o}buildTicks(){const t=this,e=t.min,i=t.max,n=t.options.offset,o=[];let s=t.getLabels();s=0===e&&i===s.length-1?s:s.slice(e,i+1),t._valueRange=Math.max(s.length-(n?0:1),1),t._startValue=t.min-(n?.5:0);for(let t=e;t<=i;t++)o.push({value:t});return o}getLabelForValue(t){const e=this.getLabels();return t>=0&&t<e.length?e[t]:t}configure(){const t=this;super.configure(),t.isHorizontal()||(t._reversePixels=!t._reversePixels)}getPixelForValue(t){const e=this;return"number"!=typeof t&&(t=e.parse(t)),null===t?NaN:e.getPixelForDecimal((t-e._startValue)/e._valueRange)}getPixelForTick(t){const e=this.ticks;return t<0||t>e.length-1?null:this.getPixelForValue(e[t].value)}getValueForPixel(t){const e=this;return Math.round(e._startValue+e.getDecimalForPixel(t)*e._valueRange)}getBasePixel(){return this.bottom}}function Bs(t,e,{horizontal:i,minRotation:n}){const o=Et(n),s=(i?Math.sin(o):Math.cos(o))||.001,a=.75*e*(""+t).length;return Math.min(e/s,a)}Fs.id="category",Fs.defaults={ticks:{callback:Fs.prototype.getLabelForValue}};class Vs extends qi{constructor(t){super(t),this.start=void 0,this.end=void 0,this._startValue=void 0,this._endValue=void 0,this._valueRange=0}parse(t,e){return $(t)||("number"==typeof t||t instanceof Number)&&!isFinite(+t)?null:+t}handleTickRangeOptions(){const t=this,{beginAtZero:e}=t.options,{minDefined:i,maxDefined:n}=t.getUserBounds();let{min:o,max:s}=t;const a=t=>o=i?o:t,r=t=>s=n?s:t;if(e){const t=Dt(o),e=Dt(s);t<0&&e<0?r(0):t>0&&e>0&&a(0)}o===s&&(r(s+1),e||a(o-1)),t.min=o,t.max=s}getTickLimit(){const t=this,e=t.options.ticks;let i,{maxTicksLimit:n,stepSize:o}=e;return o?i=Math.ceil(t.max/o)-Math.floor(t.min/o)+1:(i=t.computeTickLimit(),n=n||11),n&&(i=Math.min(n,i)),i}computeTickLimit(){return Number.POSITIVE_INFINITY}buildTicks(){const t=this,e=t.options,i=e.ticks;let n=t.getTickLimit();n=Math.max(2,n);const o=function(t,e){const i=[],{bounds:n,step:o,min:s,max:a,precision:r,count:l,maxTicks:c,maxDigits:h,includeBounds:d}=t,u=o||1,f=c-1,{min:g,max:p}=e,m=!$(s),x=!$(a),b=!$(l),_=(p-g)/(h+1);let y,v,w,M,k=Ct((p-g)/f/u)*u;if(k<1e-14&&!m&&!x)return[{value:g},{value:p}];M=Math.ceil(p/k)-Math.floor(g/k),M>f&&(k=Ct(M*k/f/u)*u),$(r)||(y=Math.pow(10,r),k=Math.ceil(k*y)/y),"ticks"===n?(v=Math.floor(g/k)*k,w=Math.ceil(p/k)*k):(v=g,w=p),m&&x&&o&&Lt((a-s)/o,k/1e3)?(M=Math.round(Math.min((a-s)/k,c)),k=(a-s)/M,v=s,w=a):b?(v=m?s:v,w=x?a:w,M=l-1,k=(w-v)/M):(M=(w-v)/k,M=At(M,Math.round(M),k/1e3)?Math.round(M):Math.ceil(M));const S=Math.max(It(k),It(v));y=Math.pow(10,$(r)?S:r),v=Math.round(v*y)/y,w=Math.round(w*y)/y;let P=0;for(m&&(d&&v!==s?(i.push({value:s}),v<s&&P++,At(Math.round((v+P*k)*y)/y,s,Bs(s,_,t))&&P++):v<s&&P++);P<M;++P)i.push({value:Math.round((v+P*k)*y)/y});return x&&d&&w!==a?At(i[i.length-1].value,a,Bs(a,_,t))?i[i.length-1].value=a:i.push({value:a}):x&&w!==a||i.push({value:w}),i}({maxTicks:n,bounds:e.bounds,min:e.min,max:e.max,precision:i.precision,step:i.stepSize,count:i.count,maxDigits:t._maxDigits(),horizontal:t.isHorizontal(),minRotation:i.minRotation||0,includeBounds:!1!==i.includeBounds},t._range||t);return"ticks"===e.bounds&&Rt(o,t,"value"),e.reverse?(o.reverse(),t.start=t.max,t.end=t.min):(t.start=t.min,t.end=t.max),o}configure(){const t=this,e=t.ticks;let i=t.min,n=t.max;if(super.configure(),t.options.offset&&e.length){const t=(n-i)/Math.max(e.length-1,1)/2;i-=t,n+=t}t._startValue=i,t._endValue=n,t._valueRange=n-i}getLabelForValue(t){return Fi(t,this.chart.options.locale)}}class Ws extends Vs{determineDataLimits(){const t=this,{min:e,max:i}=t.getMinMax(!0);t.min=X(e)?e:0,t.max=X(i)?i:1,t.handleTickRangeOptions()}computeTickLimit(){const t=this,e=t.isHorizontal(),i=e?t.width:t.height,n=Et(t.options.ticks.minRotation),o=(e?Math.sin(n):Math.cos(n))||.001,s=t._resolveTickFontOptions(0);return Math.ceil(i/Math.min(40,s.lineHeight/o))}getPixelForValue(t){return null===t?NaN:this.getPixelForDecimal((t-this._startValue)/this._valueRange)}getValueForPixel(t){return this._startValue+this.getDecimalForPixel(t)*this._valueRange}}function Ns(t){return 1===t/Math.pow(10,Math.floor(Pt(t)))}Ws.id="linear",Ws.defaults={ticks:{callback:Vi.formatters.numeric}};class Hs extends qi{constructor(t){super(t),this.start=void 0,this.end=void 0,this._startValue=void 0,this._valueRange=0}parse(t,e){const i=Vs.prototype.parse.apply(this,[t,e]);if(0!==i)return X(i)&&i>0?i:null;this._zero=!0}determineDataLimits(){const t=this,{min:e,max:i}=t.getMinMax(!0);t.min=X(e)?Math.max(0,e):null,t.max=X(i)?Math.max(0,i):null,t.options.beginAtZero&&(t._zero=!0),t.handleTickRangeOptions()}handleTickRangeOptions(){const t=this,{minDefined:e,maxDefined:i}=t.getUserBounds();let n=t.min,o=t.max;const s=t=>n=e?n:t,a=t=>o=i?o:t,r=(t,e)=>Math.pow(10,Math.floor(Pt(t))+e);n===o&&(n<=0?(s(1),a(10)):(s(r(n,-1)),a(r(o,1)))),n<=0&&s(r(o,-1)),o<=0&&a(r(n,1)),t._zero&&t.min!==t._suggestedMin&&n===r(t.min,0)&&s(r(n,-1)),t.min=n,t.max=o}buildTicks(){const t=this,e=t.options,i=function(t,e){const i=Math.floor(Pt(e.max)),n=Math.ceil(e.max/Math.pow(10,i)),o=[];let s=q(t.min,Math.pow(10,Math.floor(Pt(e.min)))),a=Math.floor(Pt(s)),r=Math.floor(s/Math.pow(10,a)),l=a<0?Math.pow(10,Math.abs(a)):1;do{o.push({value:s,major:Ns(s)}),++r,10===r&&(r=1,++a,l=a>=0?1:l),s=Math.round(r*Math.pow(10,a)*l)/l}while(a<i||a===i&&r<n);const c=q(t.max,s);return o.push({value:c,major:Ns(s)}),o}({min:t._userMin,max:t._userMax},t);return"ticks"===e.bounds&&Rt(i,t,"value"),e.reverse?(i.reverse(),t.start=t.max,t.end=t.min):(t.start=t.min,t.end=t.max),i}getLabelForValue(t){return void 0===t?"0":Fi(t,this.chart.options.locale)}configure(){const t=this,e=t.min;super.configure(),t._startValue=Pt(e),t._valueRange=Pt(t.max)-Pt(e)}getPixelForValue(t){const e=this;return void 0!==t&&0!==t||(t=e.min),null===t||isNaN(t)?NaN:e.getPixelForDecimal(t===e.min?0:(Pt(t)-e._startValue)/e._valueRange)}getValueForPixel(t){const e=this,i=e.getDecimalForPixel(t);return Math.pow(10,e._startValue+i*e._valueRange)}}function js(t){const e=t.ticks;if(e.display&&t.display){const t=Fe(e.backdropPadding);return K(e.font&&e.font.size,xt.font.size)+t.height}return 0}function $s(t,e,i,n,o){return t===n||t===o?{start:e-i/2,end:e+i/2}:t<n||t>o?{start:e-i,end:e}:{start:e,end:e+i}}function Ys(t){const e={l:0,r:t.width,t:0,b:t.height-t.paddingTop},i={},n=[],o=[],s=t.getLabels().length;for(let c=0;c<s;c++){const s=t.options.pointLabels.setContext(t.getContext(c));o[c]=s.padding;const h=t.getPointPosition(c,t.drawingArea+o[c]),d=Be(s.font),u=(a=t.ctx,r=d,l=Y(l=t._pointLabels[c])?l:[l],{w:Ut(a,r.string,l),h:l.length*r.lineHeight});n[c]=u;const f=t.getIndexAngle(c),g=zt(f),p=$s(g,h.x,u.w,0,180),m=$s(g,h.y,u.h,90,270);p.start<e.l&&(e.l=p.start,i.l=f),p.end>e.r&&(e.r=p.end,i.r=f),m.start<e.t&&(e.t=m.start,i.t=f),m.end>e.b&&(e.b=m.end,i.b=f)}var a,r,l;t._setReductions(t.drawingArea,e,i),t._pointLabelItems=function(t,e,i){const n=[],o=t.getLabels().length,s=t.options,a=js(s),r=t.getDistanceFromCenterForValue(s.ticks.reverse?t.min:t.max);for(let s=0;s<o;s++){const o=0===s?a/2:0,l=t.getPointPosition(s,r+o+i[s]),c=zt(t.getIndexAngle(s)),h=e[s],d=qs(l.y,h.h,c),u=Us(c),f=Xs(l.x,h.w,u);n.push({x:l.x,y:d,textAlign:u,left:f,top:d,right:f+h.w,bottom:d+h.h})}return n}(t,n,o)}function Us(t){return 0===t||180===t?"center":t<180?"left":"right"}function Xs(t,e,i){return"right"===i?t-=e:"center"===i&&(t-=e/2),t}function qs(t,e,i){return 90===i||270===i?t-=e/2:(i>270||i<90)&&(t-=e),t}function Ks(t,e,i,n){const{ctx:o}=t;if(i)o.arc(t.xCenter,t.yCenter,e,0,_t);else{let i=t.getPointPosition(0,e);o.moveTo(i.x,i.y);for(let s=1;s<n;s++)i=t.getPointPosition(s,e),o.lineTo(i.x,i.y)}}function Gs(t){return Tt(t)?t:0}Hs.id="logarithmic",Hs.defaults={ticks:{callback:Vi.formatters.logarithmic,major:{enabled:!0}}};class Zs extends Vs{constructor(t){super(t),this.xCenter=void 0,this.yCenter=void 0,this.drawingArea=void 0,this._pointLabels=[],this._pointLabelItems=[]}setDimensions(){const t=this;t.width=t.maxWidth,t.height=t.maxHeight,t.paddingTop=js(t.options)/2,t.xCenter=Math.floor(t.width/2),t.yCenter=Math.floor((t.height-t.paddingTop)/2),t.drawingArea=Math.min(t.height-t.paddingTop,t.width)/2}determineDataLimits(){const t=this,{min:e,max:i}=t.getMinMax(!1);t.min=X(e)&&!isNaN(e)?e:0,t.max=X(i)&&!isNaN(i)?i:0,t.handleTickRangeOptions()}computeTickLimit(){return Math.ceil(this.drawingArea/js(this.options))}generateTickLabels(t){const e=this;Vs.prototype.generateTickLabels.call(e,t),e._pointLabels=e.getLabels().map(((t,i)=>{const n=Q(e.options.pointLabels.callback,[t,i],e);return n||0===n?n:""}))}fit(){const t=this,e=t.options;e.display&&e.pointLabels.display?Ys(t):t.setCenterPoint(0,0,0,0)}_setReductions(t,e,i){const n=this;let o=e.l/Math.sin(i.l),s=Math.max(e.r-n.width,0)/Math.sin(i.r),a=-e.t/Math.cos(i.t),r=-Math.max(e.b-(n.height-n.paddingTop),0)/Math.cos(i.b);o=Gs(o),s=Gs(s),a=Gs(a),r=Gs(r),n.drawingArea=Math.max(t/2,Math.min(Math.floor(t-(o+s)/2),Math.floor(t-(a+r)/2))),n.setCenterPoint(o,s,a,r)}setCenterPoint(t,e,i,n){const o=this,s=o.width-e-o.drawingArea,a=t+o.drawingArea,r=i+o.drawingArea,l=o.height-o.paddingTop-n-o.drawingArea;o.xCenter=Math.floor((a+s)/2+o.left),o.yCenter=Math.floor((r+l)/2+o.top+o.paddingTop)}getIndexAngle(t){return Wt(t*(_t/this.getLabels().length)+Et(this.options.startAngle||0))}getDistanceFromCenterForValue(t){const e=this;if($(t))return NaN;const i=e.drawingArea/(e.max-e.min);return e.options.reverse?(e.max-t)*i:(t-e.min)*i}getValueForDistanceFromCenter(t){if($(t))return NaN;const e=this,i=t/(e.drawingArea/(e.max-e.min));return e.options.reverse?e.max-i:e.min+i}getPointPosition(t,e){const i=this,n=i.getIndexAngle(t)-Mt;return{x:Math.cos(n)*e+i.xCenter,y:Math.sin(n)*e+i.yCenter,angle:n}}getPointPositionForValue(t,e){return this.getPointPosition(t,this.getDistanceFromCenterForValue(e))}getBasePosition(t){return this.getPointPositionForValue(t||0,this.getBaseValue())}getPointLabelPosition(t){const{left:e,top:i,right:n,bottom:o}=this._pointLabelItems[t];return{left:e,top:i,right:n,bottom:o}}drawBackground(){const t=this,{backgroundColor:e,grid:{circular:i}}=t.options;if(e){const n=t.ctx;n.save(),n.beginPath(),Ks(t,t.getDistanceFromCenterForValue(t._endValue),i,t.getLabels().length),n.closePath(),n.fillStyle=e,n.fill(),n.restore()}}drawGrid(){const t=this,e=t.ctx,i=t.options,{angleLines:n,grid:o}=i,s=t.getLabels().length;let a,r,l;if(i.pointLabels.display&&function(t,e){const{ctx:i,options:{pointLabels:n}}=t;for(let o=e-1;o>=0;o--){const e=n.setContext(t.getContext(o)),s=Be(e.font),{x:a,y:r,textAlign:l,left:c,top:h,right:d,bottom:u}=t._pointLabelItems[o],{backdropColor:f}=e;if(!$(f)){const t=Fe(e.backdropPadding);i.fillStyle=f,i.fillRect(c-t.left,h-t.top,d-c+t.width,u-h+t.height)}ee(i,t._pointLabels[o],a,r+s.lineHeight/2,s,{color:e.color,textAlign:l,textBaseline:"middle"})}}(t,s),o.display&&t.ticks.forEach(((e,i)=>{if(0!==i){r=t.getDistanceFromCenterForValue(e.value);const n=o.setContext(t.getContext(i-1));!function(t,e,i,n){const o=t.ctx,s=e.circular,{color:a,lineWidth:r}=e;!s&&!n||!a||!r||i<0||(o.save(),o.strokeStyle=a,o.lineWidth=r,o.setLineDash(e.borderDash),o.lineDashOffset=e.borderDashOffset,o.beginPath(),Ks(t,i,s,n),o.closePath(),o.stroke(),o.restore())}(t,n,r,s)}})),n.display){for(e.save(),a=t.getLabels().length-1;a>=0;a--){const o=n.setContext(t.getContext(a)),{color:s,lineWidth:c}=o;c&&s&&(e.lineWidth=c,e.strokeStyle=s,e.setLineDash(o.borderDash),e.lineDashOffset=o.borderDashOffset,r=t.getDistanceFromCenterForValue(i.ticks.reverse?t.min:t.max),l=t.getPointPosition(a,r),e.beginPath(),e.moveTo(t.xCenter,t.yCenter),e.lineTo(l.x,l.y),e.stroke())}e.restore()}}drawBorder(){}drawLabels(){const t=this,e=t.ctx,i=t.options,n=i.ticks;if(!n.display)return;const o=t.getIndexAngle(0);let s,a;e.save(),e.translate(t.xCenter,t.yCenter),e.rotate(o),e.textAlign="center",e.textBaseline="middle",t.ticks.forEach(((o,r)=>{if(0===r&&!i.reverse)return;const l=n.setContext(t.getContext(r)),c=Be(l.font);if(s=t.getDistanceFromCenterForValue(t.ticks[r].value),l.showLabelBackdrop){e.font=c.string,a=e.measureText(o.label).width,e.fillStyle=l.backdropColor;const t=Fe(l.backdropPadding);e.fillRect(-a/2-t.left,-s-c.size/2-t.top,a+t.width,c.size+t.height)}ee(e,o.label,0,-s,c,{color:l.color})})),e.restore()}drawTitle(){}}Zs.id="radialLinear",Zs.defaults={display:!0,animate:!0,position:"chartArea",angleLines:{display:!0,lineWidth:1,borderDash:[],borderDashOffset:0},grid:{circular:!1},startAngle:0,ticks:{showLabelBackdrop:!0,callback:Vi.formatters.numeric},pointLabels:{backdropColor:void 0,backdropPadding:2,display:!0,font:{size:10},callback:t=>t,padding:5}},Zs.defaultRoutes={"angleLines.color":"borderColor","pointLabels.color":"color","ticks.color":"color"},Zs.descriptors={angleLines:{_fallback:"grid"}};const Qs={millisecond:{common:!0,size:1,steps:1e3},second:{common:!0,size:1e3,steps:60},minute:{common:!0,size:6e4,steps:60},hour:{common:!0,size:36e5,steps:24},day:{common:!0,size:864e5,steps:30},week:{common:!1,size:6048e5,steps:4},month:{common:!0,size:2628e6,steps:12},quarter:{common:!1,size:7884e6,steps:4},year:{common:!0,size:3154e7}},Js=Object.keys(Qs);function ta(t,e){return t-e}function ea(t,e){if($(e))return null;const i=t._adapter,{parser:n,round:o,isoWeekday:s}=t._parseOpts;let a=e;return"function"==typeof n&&(a=n(a)),X(a)||(a="string"==typeof n?i.parse(a,n):i.parse(a)),null===a?null:(o&&(a="week"!==o||!Tt(s)&&!0!==s?i.startOf(a,o):i.startOf(a,"isoWeek",s)),+a)}function ia(t,e,i,n){const o=Js.length;for(let s=Js.indexOf(t);s<o-1;++s){const t=Qs[Js[s]],o=t.steps?t.steps:Number.MAX_SAFE_INTEGER;if(t.common&&Math.ceil((i-e)/(o*t.size))<=n)return Js[s]}return Js[o-1]}function na(t,e,i){if(i){if(i.length){const{lo:n,hi:o}=oe(i,e);t[i[n]>=e?i[n]:i[o]]=!0}}else t[e]=!0}function oa(t,e,i){const n=[],o={},s=e.length;let a,r;for(a=0;a<s;++a)r=e[a],o[r]=a,n.push({value:r,major:!1});return 0!==s&&i?function(t,e,i,n){const o=t._adapter,s=+o.startOf(e[0].value,n),a=e[e.length-1].value;let r,l;for(r=s;r<=a;r=+o.add(r,1,n))l=i[r],l>=0&&(e[l].major=!0);return e}(t,n,o,i):n}class sa extends qi{constructor(t){super(t),this._cache={data:[],labels:[],all:[]},this._unit="day",this._majorUnit=void 0,this._offsets={},this._normalized=!1,this._parseOpts=void 0}init(t,e){const i=t.time||(t.time={}),n=this._adapter=new ao._date(t.adapters.date);st(i.displayFormats,n.formats()),this._parseOpts={parser:i.parser,round:i.round,isoWeekday:i.isoWeekday},super.init(t),this._normalized=e.normalized}parse(t,e){return void 0===t?null:ea(this,t)}beforeLayout(){super.beforeLayout(),this._cache={data:[],labels:[],all:[]}}determineDataLimits(){const t=this,e=t.options,i=t._adapter,n=e.time.unit||"day";let{min:o,max:s,minDefined:a,maxDefined:r}=t.getUserBounds();function l(t){a||isNaN(t.min)||(o=Math.min(o,t.min)),r||isNaN(t.max)||(s=Math.max(s,t.max))}a&&r||(l(t._getLabelBounds()),"ticks"===e.bounds&&"labels"===e.ticks.source||l(t.getMinMax(!1))),o=X(o)&&!isNaN(o)?o:+i.startOf(Date.now(),n),s=X(s)&&!isNaN(s)?s:+i.endOf(Date.now(),n)+1,t.min=Math.min(o,s-1),t.max=Math.max(o+1,s)}_getLabelBounds(){const t=this.getLabelTimestamps();let e=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;return t.length&&(e=t[0],i=t[t.length-1]),{min:e,max:i}}buildTicks(){const t=this,e=t.options,i=e.time,n=e.ticks,o="labels"===n.source?t.getLabelTimestamps():t._generate();"ticks"===e.bounds&&o.length&&(t.min=t._userMin||o[0],t.max=t._userMax||o[o.length-1]);const s=t.min,a=re(o,s,t.max);return t._unit=i.unit||(n.autoSkip?ia(i.minUnit,t.min,t.max,t._getLabelCapacity(s)):function(t,e,i,n,o){for(let s=Js.length-1;s>=Js.indexOf(i);s--){const i=Js[s];if(Qs[i].common&&t._adapter.diff(o,n,i)>=e-1)return i}return Js[i?Js.indexOf(i):0]}(t,a.length,i.minUnit,t.min,t.max)),t._majorUnit=n.major.enabled&&"year"!==t._unit?function(t){for(let e=Js.indexOf(t)+1,i=Js.length;e<i;++e)if(Qs[Js[e]].common)return Js[e]}(t._unit):void 0,t.initOffsets(o),e.reverse&&a.reverse(),oa(t,a,t._majorUnit)}initOffsets(t){const e=this;let i,n,o=0,s=0;e.options.offset&&t.length&&(i=e.getDecimalForValue(t[0]),o=1===t.length?1-i:(e.getDecimalForValue(t[1])-i)/2,n=e.getDecimalForValue(t[t.length-1]),s=1===t.length?n:(n-e.getDecimalForValue(t[t.length-2]))/2);const a=t.length<3?.5:.25;o=Ht(o,0,a),s=Ht(s,0,a),e._offsets={start:o,end:s,factor:1/(o+1+s)}}_generate(){const t=this,e=t._adapter,i=t.min,n=t.max,o=t.options,s=o.time,a=s.unit||ia(s.minUnit,i,n,t._getLabelCapacity(i)),r=K(s.stepSize,1),l="week"===a&&s.isoWeekday,c=Tt(l)||!0===l,h={};let d,u,f=i;if(c&&(f=+e.startOf(f,"isoWeek",l)),f=+e.startOf(f,c?"day":a),e.diff(n,i,a)>1e5*r)throw new Error(i+" and "+n+" are too far apart with stepSize of "+r+" "+a);const g="data"===o.ticks.source&&t.getDataTimestamps();for(d=f,u=0;d<n;d=+e.add(d,r,a),u++)na(h,d,g);return d!==n&&"ticks"!==o.bounds&&1!==u||na(h,d,g),Object.keys(h).sort(((t,e)=>t-e)).map((t=>+t))}getLabelForValue(t){const e=this._adapter,i=this.options.time;return i.tooltipFormat?e.format(t,i.tooltipFormat):e.format(t,i.displayFormats.datetime)}_tickFormatFunction(t,e,i,n){const o=this,s=o.options,a=s.time.displayFormats,r=o._unit,l=o._majorUnit,c=r&&a[r],h=l&&a[l],d=i[e],u=l&&h&&d&&d.major,f=o._adapter.format(t,n||(u?h:c)),g=s.ticks.callback;return g?Q(g,[f,e,i],o):f}generateTickLabels(t){let e,i,n;for(e=0,i=t.length;e<i;++e)n=t[e],n.label=this._tickFormatFunction(n.value,e,t)}getDecimalForValue(t){const e=this;return null===t?NaN:(t-e.min)/(e.max-e.min)}getPixelForValue(t){const e=this,i=e._offsets,n=e.getDecimalForValue(t);return e.getPixelForDecimal((i.start+n)*i.factor)}getValueForPixel(t){const e=this,i=e._offsets,n=e.getDecimalForPixel(t)/i.factor-i.end;return e.min+n*(e.max-e.min)}_getLabelSize(t){const e=this,i=e.options.ticks,n=e.ctx.measureText(t).width,o=Et(e.isHorizontal()?i.maxRotation:i.minRotation),s=Math.cos(o),a=Math.sin(o),r=e._resolveTickFontOptions(0).size;return{w:n*s+r*a,h:n*a+r*s}}_getLabelCapacity(t){const e=this,i=e.options.time,n=i.displayFormats,o=n[i.unit]||n.millisecond,s=e._tickFormatFunction(t,0,oa(e,[t],e._majorUnit),o),a=e._getLabelSize(s),r=Math.floor(e.isHorizontal()?e.width/a.w:e.height/a.h)-1;return r>0?r:1}getDataTimestamps(){const t=this;let e,i,n=t._cache.data||[];if(n.length)return n;const o=t.getMatchingVisibleMetas();if(t._normalized&&o.length)return t._cache.data=o[0].controller.getAllParsedValues(t);for(e=0,i=o.length;e<i;++e)n=n.concat(o[e].controller.getAllParsedValues(t));return t._cache.data=t.normalize(n)}getLabelTimestamps(){const t=this,e=t._cache.labels||[];let i,n;if(e.length)return e;const o=t.getLabels();for(i=0,n=o.length;i<n;++i)e.push(ea(t,o[i]));return t._cache.labels=t._normalized?e:t.normalize(e)}normalize(t){return de(t.sort(ta))}}function aa(t,e,i){let n,o,s,a,r=0,l=t.length-1;i?(e>=t[r].pos&&e<=t[l].pos&&({lo:r,hi:l}=se(t,"pos",e)),({pos:n,time:s}=t[r]),({pos:o,time:a}=t[l])):(e>=t[r].time&&e<=t[l].time&&({lo:r,hi:l}=se(t,"time",e)),({time:n,pos:s}=t[r]),({time:o,pos:a}=t[l]));const c=o-n;return c?s+(a-s)*(e-n)/c:s}sa.id="time",sa.defaults={bounds:"data",adapters:{},time:{parser:!1,unit:!1,round:!1,isoWeekday:!1,minUnit:"millisecond",displayFormats:{}},ticks:{source:"auto",major:{enabled:!1}}};class ra extends sa{constructor(t){super(t),this._table=[],this._minPos=void 0,this._tableRange=void 0}initOffsets(){const t=this,e=t._getTimestampsForTable(),i=t._table=t.buildLookupTable(e);t._minPos=aa(i,t.min),t._tableRange=aa(i,t.max)-t._minPos,super.initOffsets(e)}buildLookupTable(t){const{min:e,max:i}=this,n=[],o=[];let s,a,r,l,c;for(s=0,a=t.length;s<a;++s)l=t[s],l>=e&&l<=i&&n.push(l);if(n.length<2)return[{time:e,pos:0},{time:i,pos:1}];for(s=0,a=n.length;s<a;++s)c=n[s+1],r=n[s-1],l=n[s],Math.round((c+r)/2)!==l&&o.push({time:l,pos:s/(a-1)});return o}_getTimestampsForTable(){const t=this;let e=t._cache.all||[];if(e.length)return e;const i=t.getDataTimestamps(),n=t.getLabelTimestamps();return e=i.length&&n.length?t.normalize(i.concat(n)):i.length?i:n,e=t._cache.all=e,e}getDecimalForValue(t){return(aa(this._table,t)-this._minPos)/this._tableRange}getValueForPixel(t){const e=this,i=e._offsets,n=e.getDecimalForPixel(t)/i.factor-i.end;return aa(e._table,n*e._tableRange+e._minPos,!0)}}ra.id="timeseries",ra.defaults=sa.defaults;var la=Object.freeze({__proto__:null,CategoryScale:Fs,LinearScale:Ws,LogarithmicScale:Hs,RadialLinearScale:Zs,TimeScale:sa,TimeSeriesScale:ra});return eo.register(yo,la,Xo,zs),eo.helpers={...Tn},eo._adapters=ao,eo.Animation=yi,eo.Animations=wi,eo.animator=a,eo.controllers=Ln.controllers.items,eo.DatasetController=Ei,eo.Element=zi,eo.elements=Xo,eo.Interaction=Te,eo.layouts=Ze,eo.platforms=fi,eo.Scale=qi,eo.Ticks=Vi,Object.assign(eo,yo,la,Xo,zs,fi),eo.Chart=eo,"undefined"!=typeof window&&(window.Chart=eo),eo}));
static/ninjafirewall.css CHANGED
@@ -27,6 +27,9 @@ textarea {
27
  #TB_window img#TB_Image {
28
  border: 1px solid #ccc;
29
  }
 
 
 
30
  .nfw-progress {
31
  height: 3px;
32
  width: 99%;
@@ -107,7 +110,21 @@ div.f-sub {
107
  resize:vertical;
108
  border:1px solid #ccc;
109
  }
 
 
 
 
 
 
 
 
 
 
110
 
 
 
 
 
111
  tr.f-grey {
112
  background-color:#F9F9F9;
113
  line-height:15px;
27
  #TB_window img#TB_Image {
28
  border: 1px solid #ccc;
29
  }
30
+ #TB_window, #TB_title {
31
+ background-color:#f0f0f1 !important;
32
+ }
33
  .nfw-progress {
34
  height: 3px;
35
  width: 99%;
110
  resize:vertical;
111
  border:1px solid #ccc;
112
  }
113
+ div.nfw-sub {
114
+ max-width:450px;
115
+ background-color:#fff;
116
+ padding: 0;
117
+ overflow: auto;
118
+ max-height:200px;
119
+ resize:vertical;
120
+ border:1px solid #7e8993;
121
+ border-radius: 4px;
122
+ }
123
 
124
+ td.dir-list {
125
+ line-height:1;
126
+ padding: 10px 10px;
127
+ }
128
  tr.f-grey {
129
  background-color:#F9F9F9;
130
  line-height:15px;
static/ninjafirewall.js CHANGED
@@ -54,13 +54,22 @@ function nfwjs_restore_default() {
54
  // Overview page.
55
 
56
  jQuery( document ).ready( function() {
57
- // Full WAF thickbox
58
- jQuery( '#nfw-thickbox' ).click( function() {
59
  var h = jQuery(window).height() - 100;
60
  var w = jQuery(window).width() - 100;
61
  tb_show( '', '#TB_inline?width='+ (w - 20) +
62
  '&amp;height='+ (h - 20) +
63
- '&amp;inlineId=nfw-thickbox-content', null );
 
 
 
 
 
 
 
 
 
64
  return false;
65
  } );
66
  // Error log thickbox
@@ -168,11 +177,64 @@ function nfwjs_radio_ini( what ) {
168
  }
169
  }
170
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
171
  function nfwjs_fullwafsubmit() {
172
 
173
  // Security nonce
174
  var nonce = jQuery('input[name=nfwnonce_fullwaf]').val();
175
- if ( nonce == '' ) {
176
  alert( nfwi18n.missing_nonce );
177
  return false;
178
  }
@@ -185,12 +247,19 @@ function nfwjs_fullwafsubmit() {
185
  var initype = jQuery('input[name=ini_type]:checked').val();
186
  var diy = jQuery('input[name=diy-choice]:checked').val();
187
  var sandbox = jQuery('input[name=enable_sandbox]:checked').val();
 
 
 
 
 
 
188
  // Ajax
189
  var data = {
190
  'action': 'nfw_fullwafsetup',
191
  'nonce': nonce,
192
  'httpserver': httpserver,
193
  'initype': initype,
 
194
  'diy': diy,
195
  'sandbox': sandbox
196
  };
54
  // Overview page.
55
 
56
  jQuery( document ).ready( function() {
57
+ // Full WAF activation thickbox
58
+ jQuery( '#nfw-activate-thickbox' ).click( function() {
59
  var h = jQuery(window).height() - 100;
60
  var w = jQuery(window).width() - 100;
61
  tb_show( '', '#TB_inline?width='+ (w - 20) +
62
  '&amp;height='+ (h - 20) +
63
+ '&amp;inlineId=nfw-activate-thickbox-content', null );
64
+ return false;
65
+ } );
66
+ // Full WAF configuration thickbox
67
+ jQuery( '#nfw-configure-thickbox' ).click( function() {
68
+ var h = jQuery(window).height() - 100;
69
+ var w = jQuery(window).width() - 100;
70
+ tb_show( '', '#TB_inline?width='+ (w - 20) +
71
+ '&amp;height='+ (h - 20) +
72
+ '&amp;inlineId=nfw-configure-thickbox-content', null );
73
  return false;
74
  } );
75
  // Error log thickbox
177
  }
178
  }
179
 
180
+ function nfwjs_fullwafconfig( what) {
181
+
182
+ // Security nonce
183
+ var nonce = jQuery('input[name=nfwnonce_fullwaf]').val();
184
+ if ( typeof nonce === 'undefined' || nonce == '' ) {
185
+ alert( nfwi18n.missing_nonce );
186
+ return false;
187
+ }
188
+
189
+ var data = {
190
+ 'action': 'nfw_fullwafconfig',
191
+ 'nonce': nonce
192
+ };
193
+
194
+ // Full WAF mode configuration
195
+ if ( what == 1 ) {
196
+ var exclude_waf_list = jQuery("input:checkbox[name='nfw_exclude_waf_list[]']:not(:checked)").map(function() {
197
+ return jQuery(this).val()
198
+ }).get();
199
+ data['list'] = JSON.stringify( exclude_waf_list );
200
+ data['what'] = 1;
201
+
202
+ // Downgrade to WP WAF mode
203
+ } else if ( what == 2 ) {
204
+ data['what'] = 2;
205
+
206
+ } else {
207
+ return false;
208
+ }
209
+
210
+ jQuery.ajax( {
211
+ type: "POST",
212
+ url: ajaxurl,
213
+ headers: {
214
+ 'Accept-Language':'en-US,en;q=0.5'
215
+ },
216
+ data: data,
217
+ dataType: "text",
218
+ success: function( response ) {
219
+ if ( response == '200' ) {
220
+ window.location.href = window.location.href + '&nfwafconfig=1';
221
+ } else {
222
+ alert( response );
223
+ }
224
+ },
225
+ // Display non-200 HTTP response
226
+ error: function( xhr, status, err ) {
227
+ alert( nfwi18n.http_error +' "'+ xhr.status +' '+ err +'".' );
228
+ }
229
+ });
230
+ return false;
231
+ }
232
+
233
  function nfwjs_fullwafsubmit() {
234
 
235
  // Security nonce
236
  var nonce = jQuery('input[name=nfwnonce_fullwaf]').val();
237
+ if ( typeof nonce === 'undefined' || nonce == '' ) {
238
  alert( nfwi18n.missing_nonce );
239
  return false;
240
  }
247
  var initype = jQuery('input[name=ini_type]:checked').val();
248
  var diy = jQuery('input[name=diy-choice]:checked').val();
249
  var sandbox = jQuery('input[name=enable_sandbox]:checked').val();
250
+ // Exclusion folders, if any
251
+ var exclude_waf_list = jQuery("input:checkbox[name='nfw_exclude_waf_list[]']:not(:checked)").map(function() {
252
+ return jQuery(this).val()
253
+ }).get();
254
+ exclude_waf_list_json = JSON.stringify( exclude_waf_list );
255
+
256
  // Ajax
257
  var data = {
258
  'action': 'nfw_fullwafsetup',
259
  'nonce': nonce,
260
  'httpserver': httpserver,
261
  'initype': initype,
262
+ 'exclude_waf_list': exclude_waf_list_json,
263
  'diy': diy,
264
  'sandbox': sandbox
265
  };